X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/de3a88fb84d10cefa219ffa33effdf2af43015e4..944a9c55d5b7d3d50ea8b8fabfb7a7be5ca8693f:/src/src/verify.c diff --git a/src/src/verify.c b/src/src/verify.c index 010ea84f1..b33ebb6df 100644 --- a/src/src/verify.c +++ b/src/src/verify.c @@ -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; 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);