Corrected several mis-calls of is_ip_address() that treated the result
[exim.git] / src / src / host.c
index 2809e7e07f63ee65b6b62d6e536b36e735d60633..6096055631f9d9eee370504f963da11f3cd1ce1f 100644 (file)
@@ -1,10 +1,10 @@
-/* $Cambridge: exim/src/src/host.c,v 1.2 2004/11/12 16:54:55 ph10 Exp $ */
+/* $Cambridge: exim/src/src/host.c,v 1.6 2005/01/11 15:51:02 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
 *************************************************/
 
-/* Copyright (c) University of Cambridge 1995 - 2004 */
+/* Copyright (c) University of Cambridge 1995 - 2005 */
 /* See the file NOTICE for conditions of use and distribution. */
 
 /* Functions for finding hosts, either by gethostbyname(), gethostbyaddr(), or
@@ -493,7 +493,7 @@ ip_address_item *next;
 while ((s = string_nextinlist(&list, &sep, buffer, sizeof(buffer))) != NULL)
   {
   int port = host_extract_port(s);            /* Leaves just the IP address */
-  if (!string_is_ip_address(s, NULL))
+  if (string_is_ip_address(s, NULL) == 0)
     log_write(0, LOG_MAIN|LOG_PANIC_DIE, "Malformed IP address \"%s\" in %s",
       s, name);
 
@@ -754,12 +754,18 @@ if (Ustrchr(address, ':') != NULL)
 
   if (*p == ':') p++;
 
-  /* Split the address into components separated by colons. */
+  /* Split the address into components separated by colons. The input address 
+  is supposed to be checked for syntax. There was a case where this was 
+  overlooked; to guard against that happening again, check here and crash if 
+  there is a violation. */
 
   while (*p != 0)
     {
     int len = Ustrcspn(p, ":");
     if (len == 0) nulloffset = ci;
+    if (ci > 7) log_write(0, LOG_MAIN|LOG_PANIC_DIE, 
+      "Internal error: invalid IPv6 address \"%s\" passed to host_aton()",
+      address);  
     component[ci++] = p;
     p += len;
     if (*p == ':') p++;
@@ -856,22 +862,24 @@ for (i = 0; i < count; i++)
 /* We can't use host_ntoa() because it assumes the binary values are in network
 byte order, and these are the result of host_aton(), which puts them in ints in
 host byte order. Also, we really want IPv6 addresses to be in a canonical
-format, so we output them with no abbreviation. However, we can't use the
-normal colon separator in them because it terminates keys in lsearch files, so
-use dot instead.
+format, so we output them with no abbreviation. In a number of cases we can't
+use the normal colon separator in them because it terminates keys in lsearch
+files, so we want to use dot instead. There's an argument that specifies what 
+to use for IPv6 addresses.
 
 Arguments:
   count       1 or 4 (number of ints)
   binary      points to the ints
   mask        mask value; if < 0 don't add to result
   buffer      big enough to hold the result
+  sep         component separator character for IPv6 addresses 
 
 Returns:      the number of characters placed in buffer, not counting
               the final nul.
 */
 
 int
-host_nmtoa(int count, int *binary, int mask, uschar *buffer)
+host_nmtoa(int count, int *binary, int mask, uschar *buffer, int sep)
 {
 int i, j;
 uschar *tt = buffer;
@@ -890,12 +898,12 @@ else
   for (i = 0; i < 4; i++)
     {
     j = binary[i];
-    sprintf(CS tt, "%04x.%04x.", (j >> 16) & 0xffff, j & 0xffff);
+    sprintf(CS tt, "%04x%c%04x%c", (j >> 16) & 0xffff, sep, j & 0xffff, sep);
     while (*tt) tt++;
     }
   }
 
-tt--;   /* lose final . */
+tt--;   /* lose final separator */
 
 if (mask < 0)
   *tt = 0;