X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/e1a3f32f604bcdf65ac20d04ddd2bc93bc9f4deb..1f155f8e69b44ee7678dd1009ae0348e5c8d768e:/src/src/host.c diff --git a/src/src/host.c b/src/src/host.c index 9c63cb95a..4772a7c6c 100644 --- a/src/src/host.c +++ b/src/src/host.c @@ -1639,8 +1639,7 @@ if (running_in_test_harness && /* Do lookups directly in the DNS or via gethostbyaddr() (or equivalent), in the order specified by the host_lookup_order option. */ -while ((ordername = string_nextinlist(&list, &sep, buffer, sizeof(buffer))) - != NULL) +while ((ordername = string_nextinlist(&list, &sep, buffer, sizeof(buffer)))) { if (strcmpic(ordername, US"bydns") == 0) { @@ -1661,8 +1660,6 @@ while ((ordername = string_nextinlist(&list, &sep, buffer, sizeof(buffer))) int count = 0; int old_pool = store_pool; - /* Ideally we'd check DNSSEC both forward and reverse, but we use the - gethost* routines for forward, so can't do that unless/until we rewrite. */ sender_host_dnssec = dns_is_secure(&dnsa); DEBUG(D_dns) debug_printf("Reverse DNS security status: %s\n", @@ -1710,8 +1707,8 @@ while ((ordername = string_nextinlist(&list, &sep, buffer, sizeof(buffer))) "empty name: treated as non-existent host name\n"); continue; } - if (sender_host_name == NULL) sender_host_name = s; - else *aptr++ = s; + if (!sender_host_name) sender_host_name = s; + else *aptr++ = s; while (*s != 0) { *s = tolower(*s); s++; } } @@ -1790,21 +1787,30 @@ for (hname = sender_host_name; hname != NULL; hname = *aliases++) int rc; BOOL ok = FALSE; host_item h; + dnssec_domains d; + h.next = NULL; h.name = hname; h.mx = MX_NONE; h.address = NULL; + d.request = sender_host_dnssec ? US"*" : NULL;; + d.require = NULL; - /* When called with the last argument FALSE, host_find_byname() won't return - HOST_FOUND_LOCAL. If the incoming address is an IPv4 address expressed in - IPv6 format, we must compare the IPv4 part to any IPv4 addresses. */ - - if ((rc = host_find_byname(&h, NULL, 0, NULL, FALSE)) == HOST_FOUND) + if ( (rc = host_find_bydns(&h, NULL, HOST_FIND_BY_A, + NULL, NULL, NULL, &d, NULL, NULL)) == HOST_FOUND + || rc == HOST_FOUND_LOCAL + ) { host_item *hh; HDEBUG(D_host_lookup) debug_printf("checking addresses for %s\n", hname); + + /* If the forward lookup was not secure we cancel the is-secure variable */ + + DEBUG(D_dns) debug_printf("Forward DNS security status: %s\n", + h.dnssec == DS_YES ? "DNSSEC verified (AD)" : "unverified"); + if (h.dnssec != DS_YES) sender_host_dnssec = FALSE; + for (hh = &h; hh != NULL; hh = hh->next) - { if (host_is_in_net(hh->address, sender_host_address, 0)) { HDEBUG(D_host_lookup) debug_printf(" %s OK\n", hh->address); @@ -1812,10 +1818,8 @@ for (hname = sender_host_name; hname != NULL; hname = *aliases++) break; } else - { HDEBUG(D_host_lookup) debug_printf(" %s\n", hh->address); - } - } + if (!ok) HDEBUG(D_host_lookup) debug_printf("no IP address for %s matched %s\n", hname, sender_host_address); @@ -1828,9 +1832,7 @@ for (hname = sender_host_name; hname != NULL; hname = *aliases++) return DEFER; } else - { HDEBUG(D_host_lookup) debug_printf("no IP addresses found for %s\n", hname); - } /* If this name is no good, and it's the sender name, set it null pro tem; if it's an alias, just remove it from the list. */ @@ -1942,7 +1944,7 @@ some circumstances when the get..byname() function actually calls the DNS. */ dns_init((flags & HOST_FIND_QUALIFY_SINGLE) != 0, (flags & HOST_FIND_SEARCH_PARENTS) != 0, - FALSE); /*XXX dnssec? */ + FALSE); /* Cannot retrieve dnssec status so do not request */ /* 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 @@ -2494,8 +2496,8 @@ Arguments: srv_service when SRV used, the service name srv_fail_domains DNS errors for these domains => assume nonexist mx_fail_domains DNS errors for these domains => assume nonexist - dnssec_request_domains => make dnssec request - dnssec_require_domains => ditto and nonexist failures + dnssec_d.request => make dnssec request: domainlist + dnssec_d.require => ditto and nonexist failures fully_qualified_name if not NULL, return fully-qualified name removed set TRUE if local host was removed from the list @@ -2513,7 +2515,7 @@ Returns: HOST_FIND_FAILED Failed to find the host or domain; int host_find_bydns(host_item *host, const uschar *ignore_target_hosts, int whichrrs, uschar *srv_service, uschar *srv_fail_domains, uschar *mx_fail_domains, - uschar *dnssec_request_domains, uschar *dnssec_require_domains, + const dnssec_domains *dnssec_d, const uschar **fully_qualified_name, BOOL *removed) { host_item *h, *last; @@ -2523,11 +2525,13 @@ int ind_type = 0; int yield; dns_answer dnsa; dns_scan dnss; -BOOL dnssec_require = match_isinlist(host->name, CUSS &dnssec_require_domains, +BOOL dnssec_require = dnssec_d + && match_isinlist(host->name, CUSS &dnssec_d->require, 0, NULL, NULL, MCL_DOMAIN, TRUE, NULL) == OK; BOOL dnssec_request = dnssec_require - || match_isinlist(host->name, CUSS &dnssec_request_domains, - 0, NULL, NULL, MCL_DOMAIN, TRUE, NULL) == OK; + || ( dnssec_d + && match_isinlist(host->name, CUSS &dnssec_d->request, + 0, NULL, NULL, MCL_DOMAIN, TRUE, NULL) == OK); dnssec_status_t dnssec; /* Set the default fully qualified name to the incoming name, initialize the @@ -2537,8 +2541,7 @@ that gets set for DNS syntax check errors. */ if (fully_qualified_name != NULL) *fully_qualified_name = host->name; dns_init((whichrrs & HOST_FIND_QUALIFY_SINGLE) != 0, (whichrrs & HOST_FIND_SEARCH_PARENTS) != 0, - dnssec_request - ); + dnssec_request); host_find_failed_syntax = FALSE; /* First, if requested, look for SRV records. The service name is given; we @@ -3203,6 +3206,7 @@ while (Ufgets(buffer, 256, stdin) != NULL) else { int flags = whichrrs; + dnssec d; h.name = buffer; h.next = NULL; @@ -3215,12 +3219,13 @@ while (Ufgets(buffer, 256, stdin) != NULL) if (qualify_single) flags |= HOST_FIND_QUALIFY_SINGLE; if (search_parents) flags |= HOST_FIND_SEARCH_PARENTS; + d.request = request_dnssec ? &h.name : NULL; + d.require = require_dnssec ? &h.name : NULL; + rc = byname ? host_find_byname(&h, NULL, flags, &fully_qualified_name, TRUE) : host_find_bydns(&h, NULL, flags, US"smtp", NULL, NULL, - request_dnssec ? &h.name : NULL, - require_dnssec ? &h.name : NULL, - &fully_qualified_name, NULL); + &d, &fully_qualified_name, NULL); if (rc == HOST_FIND_FAILED) printf("Failed\n"); else if (rc == HOST_FIND_AGAIN) printf("Again\n");