Add support for setclassresources() in the pipe transport on FreeBSD,
[exim.git] / src / src / verify.c
index 010ea84f1ca38a73352c960e0d44b41d6695ce51..b33ebb6df9558821176fc2aafeefed040942d18b 100644 (file)
@@ -1,10 +1,10 @@
-/* $Cambridge: exim/src/src/verify.c,v 1.27 2005/09/14 09:40:55 ph10 Exp $ */
+/* $Cambridge: exim/src/src/verify.c,v 1.34 2006/02/21 16:24:19 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
 *************************************************/
 
-/* Copyright (c) University of Cambridge 1995 - 2005 */
+/* Copyright (c) University of Cambridge 1995 - 2006 */
 /* See the file NOTICE for conditions of use and distribution. */
 
 /* Functions concerned with verifying things. The original code for callout
@@ -1051,7 +1051,7 @@ while (addr_new != NULL)
 
       if (addr->transport != NULL && !addr->transport->info->local)
         {
-        (void)(addr->transport->setup)(addr->transport, addr, &tf, NULL);
+        (void)(addr->transport->setup)(addr->transport, addr, &tf, 0, 0, NULL);
 
         /* If the transport has hosts and the router does not, or if the
         transport is configured to override the router's hosts, we must build a
@@ -1093,7 +1093,7 @@ while (addr_new != NULL)
               {
               nexthost = host->next;
               if (tf.gethostbyname ||
-                  string_is_ip_address(host->name, NULL) > 0)
+                  string_is_ip_address(host->name, NULL) != 0)
                 (void)host_find_byname(host, NULL, &canonical_name, TRUE);
               else
                 {
@@ -1415,14 +1415,16 @@ for (h = header_list; h != NULL; h = h->next)
       {
       uschar *verb = US"is";
       uschar *t = ss;
+      uschar *tt = colon;
       int len;
 
       /* Arrange not to include any white space at the end in the
-      error message. */
+      error message or the header name. */
 
       while (t > s && isspace(t[-1])) t--;
+      while (tt > h->text && isspace(tt[-1])) tt--;
 
-      /* Add the address which failed to the error message, since in a
+      /* Add the address that failed to the error message, since in a
       header with very many addresses it is sometimes hard to spot
       which one is at fault. However, limit the amount of address to
       quote - cases have been seen where, for example, a missing double
@@ -1437,8 +1439,8 @@ for (h = header_list; h != NULL; h = h->next)
         }
 
       *msgptr = string_printing(
-        string_sprintf("%s: failing address in \"%.*s\" header %s: %.*s",
-          errmess, colon - h->text, h->text, verb, len, s));
+        string_sprintf("%s: failing address in \"%.*s:\" header %s: %.*s",
+          errmess, tt - h->text, h->text, verb, len, s));
 
       return FAIL;
       }
@@ -1945,7 +1947,7 @@ int maskoffset;
 BOOL iplookup = FALSE;
 BOOL isquery = FALSE;
 BOOL isiponly = cb->host_name != NULL && cb->host_name[0] == 0;
-uschar *t = ss;
+uschar *t;
 uschar *semicolon;
 uschar **aliases;
 
@@ -1983,15 +1985,33 @@ if (*ss == '@')
 /* If the pattern is an IP address, optionally followed by a bitmask count, do
 a (possibly masked) comparision with the current IP address. */
 
-if (string_is_ip_address(ss, &maskoffset) > 0)
+if (string_is_ip_address(ss, &maskoffset) != 0)
   return (host_is_in_net(cb->host_address, ss, maskoffset)? OK : FAIL);
 
+/* The pattern is not an IP address. A common error that people make is to omit
+one component of an IPv4 address, either by accident, or believing that, for
+example, 1.2.3/24 is the same as 1.2.3.0/24, or 1.2.3 is the same as 1.2.3.0,
+which it isn't. (Those applications that do accept 1.2.3 as an IP address
+interpret it as 1.2.0.3 because the final component becomes 16-bit - this is an
+ancient specification.) To aid in debugging these cases, we give a specific
+error if the pattern contains only digits and dots or contains a slash preceded
+only by digits and dots (a slash at the start indicates a file name and of
+course slashes may be present in lookups, but not preceded only by digits and
+dots). */
+
+for (t = ss; isdigit(*t) || *t == '.'; t++);
+if (*t == 0 || (*t == '/' && t != ss))
+  {
+  *error = US"malformed IPv4 address or address mask";
+  return ERROR;
+  }
+
 /* See if there is a semicolon in the pattern */
 
 semicolon = Ustrchr(ss, ';');
 
 /* If we are doing an IP address only match, then all lookups must be IP
-address lookups. */
+address lookups, even if there is no "net-". */
 
 if (isiponly)
   {
@@ -1999,19 +2019,21 @@ if (isiponly)
   }
 
 /* Otherwise, if the item is of the form net[n]-lookup;<file|query> then it is
-a lookup on a masked IP network, in textual form. The net- stuff really only
-applies to single-key lookups where the key is implicit. For query-style
-lookups the key is specified in the query. From release 4.30, the use of net-
-for query style is no longer needed, but we retain it for backward
-compatibility. */
-
-else if (Ustrncmp(ss, "net", 3) == 0 && semicolon != NULL)
+a lookup on a masked IP network, in textual form. We obey this code even if we
+have already set iplookup, so as to skip over the "net-" prefix and to set the
+mask length. The net- stuff really only applies to single-key lookups where the
+key is implicit. For query-style lookups the key is specified in the query.
+From release 4.30, the use of net- for query style is no longer needed, but we
+retain it for backward compatibility. */
+
+if (Ustrncmp(ss, "net", 3) == 0 && semicolon != NULL)
   {
   mlen = 0;
   for (t = ss + 3; isdigit(*t); t++) mlen = mlen * 10 + *t - '0';
   if (mlen == 0 && t == ss+3) mlen = -1;  /* No mask supplied */
   iplookup = (*t++ == '-');
   }
+else t = ss;
 
 /* Do the IP address lookup if that is indeed what we have */
 
@@ -2108,9 +2130,7 @@ if (*t == 0)
     host_item *hh;
     for (hh = &h; hh != NULL; hh = hh->next)
       {
-      if (Ustrcmp(hh->address, (Ustrchr(hh->address, ':') == NULL)?
-        cb->host_ipv4 : cb->host_address) == 0)
-          return OK;
+      if (host_is_in_net(hh->address, cb->host_address, 0)) return OK;
       }
     return FAIL;
     }
@@ -2785,7 +2805,7 @@ while ((domain = string_nextinlist(&list, &sep, buffer, sizeof(buffer))) != NULL
     while ((keydomain = string_nextinlist(&key, &keysep, keybuffer,
             sizeof(keybuffer))) != NULL)
       {
-      if (string_is_ip_address(keydomain, NULL) > 0)
+      if (string_is_ip_address(keydomain, NULL) != 0)
         {
         uschar keyrevadd[128];
         invert_address(keyrevadd, keydomain);