From 7e66e54dcf419ff995a49250902ae71a73228373 Mon Sep 17 00:00:00 2001 From: Philip Hazel Date: Tue, 6 Dec 2005 10:25:59 +0000 Subject: [PATCH] Add disable_ipv6, tidy up calls to string_is_ip_address(). --- doc/doc-txt/ChangeLog | 4 ++- doc/doc-txt/NewStuff | 15 +++++++- doc/doc-txt/OptionLists.txt | 5 +-- src/src/acl.c | 4 +-- src/src/expand.c | 6 ++-- src/src/globals.c | 3 +- src/src/globals.h | 3 +- src/src/host.c | 51 ++++++++++++++++------------ src/src/lookups/dnsdb.c | 6 ++-- src/src/lookups/lsearch.c | 4 +-- src/src/readconf.c | 7 ++-- src/src/route.c | 4 +-- src/src/routers/dnslookup.c | 4 +-- src/src/routers/ipliteral.c | 7 ++-- src/src/routers/iplookup.c | 4 +-- src/src/routers/rf_lookup_hostlist.c | 4 +-- src/src/transports/smtp.c | 4 +-- src/src/verify.c | 8 ++--- 18 files changed, 86 insertions(+), 57 deletions(-) diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog index c95c33777..c5dd5dae9 100644 --- a/doc/doc-txt/ChangeLog +++ b/doc/doc-txt/ChangeLog @@ -1,4 +1,4 @@ -$Cambridge: exim/doc/doc-txt/ChangeLog,v 1.270 2005/12/05 14:38:18 ph10 Exp $ +$Cambridge: exim/doc/doc-txt/ChangeLog,v 1.271 2005/12/06 10:25:59 ph10 Exp $ Change log file for Exim from version 4.21 ------------------------------------------- @@ -17,6 +17,8 @@ PH/01 The code for finding all the local interface addresses on a FreeBSD PH/02 The ipliteral router was not recognizing addresses of the form user@ [ipv6:....] because it didn't know about the "ipv6:" prefix. +PH/03 Added disable_ipv6. + Exim version 4.60 ----------------- diff --git a/doc/doc-txt/NewStuff b/doc/doc-txt/NewStuff index e86afb683..604e59a9a 100644 --- a/doc/doc-txt/NewStuff +++ b/doc/doc-txt/NewStuff @@ -1,4 +1,4 @@ -$Cambridge: exim/doc/doc-txt/NewStuff,v 1.77 2005/11/21 09:51:21 ph10 Exp $ +$Cambridge: exim/doc/doc-txt/NewStuff,v 1.78 2005/12/06 10:25:59 ph10 Exp $ New Features in Exim -------------------- @@ -8,6 +8,19 @@ but have not yet made it into the main manual (which is most conveniently updated when there is a relatively large batch of changes). The doc/ChangeLog file contains a listing of all changes, including bug fixes. +Version 4.61 +------------ + +PH/01 There is a new global option called disable_ipv6, which does exactly what + its name implies. If set true, even if the Exim binary has IPv6 support, + no IPv6 activities take place. AAAA records are never looked up as a for + host names given in manual routing data or elsewhere. AAAA records that + are received from the DNS as additional data for MX records are ignored. + Any IPv6 addresses that are listed in local_interfaces, manualroute route + data, etc. are also ignored. If IP literals are enabled, the ipliteral + router declines to handle IPv6 literal addresses. + + Version 4.60 ------------ diff --git a/doc/doc-txt/OptionLists.txt b/doc/doc-txt/OptionLists.txt index 152f02fc6..ce794faca 100644 --- a/doc/doc-txt/OptionLists.txt +++ b/doc/doc-txt/OptionLists.txt @@ -1,4 +1,4 @@ -$Cambridge: exim/doc/doc-txt/OptionLists.txt,v 1.12 2005/11/15 16:10:51 ph10 Exp $ +$Cambridge: exim/doc/doc-txt/OptionLists.txt,v 1.13 2005/12/06 10:25:59 ph10 Exp $ LISTS OF EXIM OPTIONS --------------------- @@ -158,8 +158,9 @@ delivery_date_remove boolean true main directory string* unset appendfile directory_mode octal-integer 0700 appendfile directory_transport string* unset redirect 4.00 +disable_ipv6 boolean false main 4.61 disable_logging boolean false routers 4.11 -disable_logging boolean false transports 4.11 + false transports 4.11 dns_again_means_nonexist domain list unset main 1.89 dns_check_names_pattern string + main 2.11 dns_csa_search_limit integer 5 main 4.60 diff --git a/src/src/acl.c b/src/src/acl.c index 2456141bd..fb84c336e 100644 --- a/src/src/acl.c +++ b/src/src/acl.c @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/acl.c,v 1.51 2005/11/14 16:09:54 ph10 Exp $ */ +/* $Cambridge: exim/src/src/acl.c,v 1.52 2005/12/06 10:25:59 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -1146,7 +1146,7 @@ not quite kosher to treat bare domains such as EHLO 192.0.2.57 the same as address literals, but it's probably the most friendly thing to do. This is an extension to CSA, so we allow it to be turned off for proper conformance. */ -if (string_is_ip_address(domain, NULL)) +if (string_is_ip_address(domain, NULL) != 0) { if (!dns_csa_use_reverse) return CSA_UNKNOWN; dns_build_reverse(domain, target); diff --git a/src/src/expand.c b/src/src/expand.c index f171c002c..9de325d46 100644 --- a/src/src/expand.c +++ b/src/src/expand.c @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/expand.c,v 1.47 2005/11/15 10:08:25 ph10 Exp $ */ +/* $Cambridge: exim/src/src/expand.c,v 1.48 2005/12/06 10:25:59 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -1713,7 +1713,7 @@ switch(cond_type) case ECOND_ISIP4: case ECOND_ISIP6: rc = string_is_ip_address(sub[0], NULL); - *yield = ((cond_type == ECOND_ISIP)? (rc > 0) : + *yield = ((cond_type == ECOND_ISIP)? (rc != 0) : (cond_type == ECOND_ISIP4)? (rc == 4) : (rc == 6)) == testfor; break; @@ -1973,7 +1973,7 @@ switch(cond_type) goto MATCHED_SOMETHING; case ECOND_MATCH_IP: /* Match IP address in a host list */ - if (sub[0][0] != 0 && string_is_ip_address(sub[0], NULL) <= 0) + if (sub[0][0] != 0 && string_is_ip_address(sub[0], NULL) == 0) { expand_string_message = string_sprintf("\"%s\" is not an IP address", sub[0]); diff --git a/src/src/globals.c b/src/src/globals.c index 9d2feb76e..941d85a5a 100644 --- a/src/src/globals.c +++ b/src/src/globals.c @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/globals.c,v 1.42 2005/11/15 10:08:25 ph10 Exp $ */ +/* $Cambridge: exim/src/src/globals.c,v 1.43 2005/12/06 10:25:59 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -482,6 +482,7 @@ int demime_errorlevel = 0; int demime_ok = 0; uschar *demime_reason = NULL; #endif +BOOL disable_ipv6 = FALSE; BOOL disable_logging = FALSE; #ifdef EXPERIMENTAL_DOMAINKEYS diff --git a/src/src/globals.h b/src/src/globals.h index 140502a8e..c91cc67a2 100644 --- a/src/src/globals.h +++ b/src/src/globals.h @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/globals.h,v 1.30 2005/11/15 10:08:25 ph10 Exp $ */ +/* $Cambridge: exim/src/src/globals.h,v 1.31 2005/12/06 10:25:59 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -271,6 +271,7 @@ extern int demime_errorlevel; /* Severity of MIME error */ extern int demime_ok; /* Nonzero if message has been demimed */ extern uschar *demime_reason; /* Reason for broken MIME container */ #endif +extern BOOL disable_ipv6; /* Don't do any IPv6 things */ extern BOOL disable_logging; /* Disables log writing when TRUE */ #ifdef EXPERIMENTAL_DOMAINKEYS diff --git a/src/src/host.c b/src/src/host.c index a5b850007..3807ad458 100644 --- a/src/src/host.c +++ b/src/src/host.c @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/host.c,v 1.18 2005/11/21 12:04:23 ph10 Exp $ */ +/* $Cambridge: exim/src/src/host.c,v 1.19 2005/12/06 10:25:59 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -774,11 +774,16 @@ ip_address_item *next; while ((s = string_nextinlist(&list, &sep, buffer, sizeof(buffer))) != NULL) { + int ipv; int port = host_address_extract_port(s); /* Leaves just the IP address */ - if (string_is_ip_address(s, NULL) == 0) + if ((ipv = string_is_ip_address(s, NULL)) == 0) log_write(0, LOG_MAIN|LOG_PANIC_DIE, "Malformed IP address \"%s\" in %s", s, name); + /* Skip IPv6 addresses if IPv6 is disabled. */ + + if (disable_ipv6 && ipv == 6) continue; + /* This use of strcpy() is OK because we have checked that s is a valid IP address above. The field in the ip_address_item is large enough to hold an IPv6 address. */ @@ -1965,17 +1970,17 @@ if (running_in_test_harness) return HOST_FIND_AGAIN; } -/* In an IPv6 world, we need to scan for both kinds of address, so go round the -loop twice. Note that we have ensured that AF_INET6 is defined even in an IPv4 -world, which makes for slightly tidier code. However, if dns_ipv4_lookup -matches the domain, we also just do IPv4 lookups here (except when testing -standalone). */ +/* In an IPv6 world, unless IPv6 has been disabled, we need to scan for both +kinds of address, so go round the loop twice. Note that we have ensured that +AF_INET6 is defined even in an IPv4 world, which makes for slightly tidier +code. However, if dns_ipv4_lookup matches the domain, we also just do IPv4 +lookups here (except when testing standalone). */ #if HAVE_IPV6 #ifndef STAND_ALONE - if (dns_ipv4_lookup != NULL && + if (disable_ipv6 || (dns_ipv4_lookup != NULL && match_isinlist(host->name, &dns_ipv4_lookup, 0, NULL, NULL, MCL_DOMAIN, - TRUE, NULL) == OK) + TRUE, NULL) == OK)) { af = AF_INET; times = 1; } else #endif /* STAND_ALONE */ @@ -2249,18 +2254,18 @@ if (allow_ip && string_is_ip_address(host->name, NULL) != 0) return HOST_FOUND; } -/* On an IPv6 system, go round the loop up to three times, looking for A6 and -AAAA records the first two times. However, unless doing standalone testing, we -force an IPv4 lookup if the domain matches dns_ipv4_lookup is set. Since A6 -records look like being abandoned, support them only if explicitly configured -to do so. On an IPv4 system, go round the loop once only, looking only for A -records. */ +/* On an IPv6 system, unless IPv6 is disabled, go round the loop up to three +times, looking for A6 and AAAA records the first two times. However, unless +doing standalone testing, we force an IPv4 lookup if the domain matches +dns_ipv4_lookup is set. Since A6 records look like being abandoned, support +them only if explicitly configured to do so. On an IPv4 system, go round the +loop once only, looking only for A records. */ #if HAVE_IPV6 #ifndef STAND_ALONE - if (dns_ipv4_lookup != NULL && + if (disable_ipv6 || (dns_ipv4_lookup != NULL && match_isinlist(host->name, &dns_ipv4_lookup, 0, NULL, NULL, MCL_DOMAIN, - TRUE, NULL) == OK) + TRUE, NULL) == OK)) i = 0; /* look up A records only */ else #endif /* STAND_ALONE */ @@ -2893,10 +2898,14 @@ for (rr = dns_next_rr(&dnsa, &dnss, RESET_ADDITIONAL); if (rr->type != T_A #if HAVE_IPV6 - && rr->type != T_AAAA - #ifdef SUPPORT_A6 - && rr->type != T_A6 - #endif + && ( disable_ipv6 || + ( + rr->type != T_AAAA + #ifdef SUPPORT_A6 + && rr->type != T_A6 + #endif + ) + ) #endif ) continue; diff --git a/src/src/lookups/dnsdb.c b/src/src/lookups/dnsdb.c index c1a0c5a61..de62defa7 100644 --- a/src/src/lookups/dnsdb.c +++ b/src/src/lookups/dnsdb.c @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/lookups/dnsdb.c,v 1.14 2005/06/10 18:59:35 fanf2 Exp $ */ +/* $Cambridge: exim/src/src/lookups/dnsdb.c,v 1.15 2005/12/06 10:25:59 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -221,7 +221,7 @@ remaining string is valid as an IP address, set an impossible separator so that it is treated as one item. */ if (type == T_PTR && keystring[0] != '<' && - string_is_ip_address(keystring, NULL) > 0) + string_is_ip_address(keystring, NULL) != 0) sep = -1; /* Now scan the list and do a lookup for each item */ @@ -241,7 +241,7 @@ while ((domain = string_nextinlist(&keystring, &sep, buffer, sizeof(buffer))) doing the reversal is now in a separate function. */ if ((type == T_PTR || type == T_CSA) && - string_is_ip_address(domain, NULL) > 0) + string_is_ip_address(domain, NULL) != 0) { dns_build_reverse(domain, rbuffer); domain = rbuffer; diff --git a/src/src/lookups/lsearch.c b/src/src/lookups/lsearch.c index 1acfd7494..ec238d556 100644 --- a/src/src/lookups/lsearch.c +++ b/src/src/lookups/lsearch.c @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/lookups/lsearch.c,v 1.5 2005/11/15 09:44:33 ph10 Exp $ */ +/* $Cambridge: exim/src/src/lookups/lsearch.c,v 1.6 2005/12/06 10:25:59 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -378,7 +378,7 @@ iplsearch_find(void *handle, uschar *filename, uschar *keystring, int length, { do_cache = do_cache; /* Keep picky compilers happy */ if ((length == 1 && keystring[0] == '*') || - string_is_ip_address(keystring, NULL) > 0) + string_is_ip_address(keystring, NULL) != 0) { return internal_lsearch_find(handle, filename, keystring, length, result, errmsg, LSEARCH_IP); diff --git a/src/src/readconf.c b/src/src/readconf.c index 0751b7750..55f08bc0e 100644 --- a/src/src/readconf.c +++ b/src/src/readconf.c @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/readconf.c,v 1.15 2005/11/15 10:08:25 ph10 Exp $ */ +/* $Cambridge: exim/src/src/readconf.c,v 1.16 2005/12/06 10:25:59 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -194,6 +194,7 @@ static optionlist optionlist_config[] = { { "deliver_drop_privilege", opt_bool, &deliver_drop_privilege }, { "deliver_queue_load_max", opt_fixed, &deliver_queue_load_max }, { "delivery_date_remove", opt_bool, &delivery_date_remove }, + { "disable_ipv6", opt_bool, &disable_ipv6 }, { "dns_again_means_nonexist", opt_stringptr, &dns_again_means_nonexist }, { "dns_check_names_pattern", opt_stringptr, &check_dns_names_pattern }, { "dns_csa_search_limit", opt_int, &dns_csa_search_limit }, @@ -2832,9 +2833,9 @@ if (primary_hostname == NULL) struct hostent *hostdata; #if HAVE_IPV6 - if (dns_ipv4_lookup == NULL || + if (!disable_ipv6 && (dns_ipv4_lookup == NULL || match_isinlist(hostname, &dns_ipv4_lookup, 0, NULL, NULL, MCL_DOMAIN, - TRUE, NULL) != OK) + TRUE, NULL) != OK)) af = AF_INET6; #else af = AF_INET; diff --git a/src/src/route.c b/src/src/route.c index 3a36f8a8e..7ace4a3bb 100644 --- a/src/src/route.c +++ b/src/src/route.c @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/route.c,v 1.6 2005/09/12 15:09:55 ph10 Exp $ */ +/* $Cambridge: exim/src/src/route.c,v 1.7 2005/12/06 10:25:59 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -1854,7 +1854,7 @@ if (r->translate_ip_address != NULL) DEBUG(D_route) debug_printf("%s [%s] translated to %s\n", h->name, h->address, newaddress); - if (string_is_ip_address(newaddress, NULL) > 0) + if (string_is_ip_address(newaddress, NULL) != 0) { h->address = newaddress; continue; diff --git a/src/src/routers/dnslookup.c b/src/src/routers/dnslookup.c index 9abdc81e5..f27c5037e 100644 --- a/src/src/routers/dnslookup.c +++ b/src/src/routers/dnslookup.c @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/routers/dnslookup.c,v 1.8 2005/09/19 18:00:47 fanf2 Exp $ */ +/* $Cambridge: exim/src/src/routers/dnslookup.c,v 1.9 2005/12/06 10:25:59 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -323,7 +323,7 @@ for (;;) else { addr->message = US"all relevant MX records point to non-existent hosts"; - if (!allow_mx_to_ip && string_is_ip_address(h.name, NULL) > 0) + if (!allow_mx_to_ip && string_is_ip_address(h.name, NULL) != 0) { addr->user_message = string_sprintf("It appears that the DNS operator for %s\n" diff --git a/src/src/routers/ipliteral.c b/src/src/routers/ipliteral.c index 2b33a83cd..a0a24c681 100644 --- a/src/src/routers/ipliteral.c +++ b/src/src/routers/ipliteral.c @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/routers/ipliteral.c,v 1.6 2005/12/05 14:38:18 ph10 Exp $ */ +/* $Cambridge: exim/src/src/routers/ipliteral.c,v 1.7 2005/12/06 10:25:59 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -104,7 +104,7 @@ host_item *h; uschar *domain = addr->domain; uschar *ip; int len = Ustrlen(domain); -int rc; +int rc, ipv; addr_new = addr_new; /* Keep picky compilers happy */ addr_succeed = addr_succeed; @@ -124,7 +124,8 @@ ip = domain + 1; if (strncmpic(ip, US"IPV6:", 5) == 0 || strncmpic(ip, US"IPV4:", 5) == 0) ip += 5; -if (string_is_ip_address(ip, NULL) == 0) +ipv = string_is_ip_address(ip, NULL); +if (ipv == 0 || (disable_ipv6 && ipv == 6)) { domain[len-1] = ']'; return DECLINE; diff --git a/src/src/routers/iplookup.c b/src/src/routers/iplookup.c index e7fba3447..9e9239f5f 100644 --- a/src/src/routers/iplookup.c +++ b/src/src/routers/iplookup.c @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/routers/iplookup.c,v 1.4 2005/09/12 15:09:55 ph10 Exp $ */ +/* $Cambridge: exim/src/src/routers/iplookup.c,v 1.5 2005/12/06 10:25:59 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -202,7 +202,7 @@ while ((hostname = string_nextinlist(&listptr, &sep, host_buffer, host->mx = MX_NONE; host->next = NULL; - if (string_is_ip_address(host->name, NULL)) + if (string_is_ip_address(host->name, NULL) != 0) host->address = host->name; else { diff --git a/src/src/routers/rf_lookup_hostlist.c b/src/src/routers/rf_lookup_hostlist.c index 3e7eee137..d146e02c7 100644 --- a/src/src/routers/rf_lookup_hostlist.c +++ b/src/src/routers/rf_lookup_hostlist.c @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/routers/rf_lookup_hostlist.c,v 1.4 2005/08/09 13:31:53 ph10 Exp $ */ +/* $Cambridge: exim/src/src/routers/rf_lookup_hostlist.c,v 1.5 2005/12/06 10:25:59 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -103,7 +103,7 @@ for (h = addr->host_list; h != NULL; prev = h, h = next_h) /* If explicitly configured to look up by name, or if the "host name" is actually an IP address, do a byname lookup. */ - else if (lookup_type == lk_byname || string_is_ip_address(h->name, NULL) > 0) + else if (lookup_type == lk_byname || string_is_ip_address(h->name, NULL) != 0) { DEBUG(D_route|D_host_lookup) debug_printf("calling host_find_byname\n"); rc = host_find_byname(h, ignore_target_hosts, &canonical_name, TRUE); diff --git a/src/src/transports/smtp.c b/src/src/transports/smtp.c index a503d8f13..7447be179 100644 --- a/src/src/transports/smtp.c +++ b/src/src/transports/smtp.c @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/transports/smtp.c,v 1.17 2005/08/09 13:31:53 ph10 Exp $ */ +/* $Cambridge: exim/src/src/transports/smtp.c,v 1.18 2005/12/06 10:25:59 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -2260,7 +2260,7 @@ for (cutoff_retry = 0; expired && /* Find by name if so configured, or if it's an IP address. We don't just copy the IP address, because we need the test-for-local to happen. */ - if (ob->gethostbyname || string_is_ip_address(host->name, NULL) > 0) + if (ob->gethostbyname || string_is_ip_address(host->name, NULL) != 0) rc = host_find_byname(host, NULL, &canonical_name, TRUE); else { diff --git a/src/src/verify.c b/src/src/verify.c index b84044d0c..beec4b445 100644 --- a/src/src/verify.c +++ b/src/src/verify.c @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/verify.c,v 1.29 2005/11/28 10:07:55 ph10 Exp $ */ +/* $Cambridge: exim/src/src/verify.c,v 1.30 2005/12/06 10:25:59 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -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 { @@ -1983,7 +1983,7 @@ 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); /* See if there is a semicolon in the pattern */ @@ -2784,7 +2784,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); -- 2.30.2