X-Git-Url: https://vcs.fsf.org/?a=blobdiff_plain;ds=sidebyside;f=src%2Fsrc%2Fverify.c;h=841285fdca72364d0ca5b2dac374abebf4b9e956;hb=2525748962c69c005b3c73779b26c8883b219956;hp=010ea84f1ca38a73352c960e0d44b41d6695ce51;hpb=de3a88fb84d10cefa219ffa33effdf2af43015e4;p=exim.git diff --git a/src/src/verify.c b/src/src/verify.c index 010ea84f1..841285fdc 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.37 2006/06/30 15:36:08 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 @@ -793,6 +793,7 @@ if (addr != vaddr) vaddr->user_message = addr->user_message; vaddr->basic_errno = addr->basic_errno; vaddr->more_errno = addr->more_errno; + vaddr->p.address_data = addr->p.address_data; } return yield; } @@ -1051,7 +1052,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 +1094,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 { @@ -1261,9 +1262,12 @@ or autoreplies, and there were no errors or deferments, the message is to be discarded, usually because of the use of :blackhole: in an alias file. */ if (allok && addr_local == NULL && addr_remote == NULL) + { fprintf(f, "mail to %s is discarded\n", address); + return yield; + } -else for (addr_list = addr_local, i = 0; i < 2; addr_list = addr_remote, i++) +for (addr_list = addr_local, i = 0; i < 2; addr_list = addr_remote, i++) { while (addr_list != NULL) { @@ -1276,6 +1280,19 @@ else for (addr_list = addr_local, i = 0; i < 2; addr_list = addr_remote, i++) if(addr->p.srs_sender) fprintf(f, " [srs = %s]", addr->p.srs_sender); #endif + + /* If the address is a duplicate, show something about it. */ + + if (!testflag(addr, af_pfr)) + { + tree_node *tnode; + if ((tnode = tree_search(tree_duplicates, addr->unique)) != NULL) + fprintf(f, " [duplicate, would not be delivered]"); + else tree_add_duplicate(addr->unique, addr); + } + + /* Now show its parents */ + while (p != NULL) { fprintf(f, "\n <-- %s", p->address); @@ -1415,14 +1432,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 +1456,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 +1964,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 +2002,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 +2036,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 */ @@ -2102,15 +2141,14 @@ if (*t == 0) h.name = ss; h.address = NULL; h.mx = MX_NONE; + rc = host_find_byname(&h, NULL, NULL, FALSE); if (rc == HOST_FOUND || rc == HOST_FOUND_LOCAL) { 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 +2823,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);