X-Git-Url: https://vcs.fsf.org/?p=exim.git;a=blobdiff_plain;f=src%2Fsrc%2Fhost.c;h=1ef73272740865a34f05402497912b04606cf7be;hp=495a44d58a545b3a2a98372816ecd36984393036;hb=0f0c8159c43045f4ad847a0129dca7eddd313285;hpb=44649fdb169979af3c5a08b10889d1ecee48a469 diff --git a/src/src/host.c b/src/src/host.c index 495a44d58..1ef732727 100644 --- a/src/src/host.c +++ b/src/src/host.c @@ -220,6 +220,8 @@ else int rc = dns_lookup(&dnsa, lname, type, NULL); int count = 0; + lookup_dnssec_authenticated = NULL; + switch(rc) { case DNS_SUCCEED: break; @@ -1179,17 +1181,13 @@ int sep = 0; uschar buffer[32]; uschar *list = tls_in.on_connect_ports; uschar *s; +uschar *end; if (tls_in.on_connect) return TRUE; -while ((s = string_nextinlist(&list, &sep, buffer, sizeof(buffer))) != NULL) - { - uschar *end; - int lport = Ustrtol(s, &end, 10); - if (*end != 0) log_write(0, LOG_MAIN|LOG_PANIC_DIE, "tls_on_connect_ports " - "contains \"%s\", which is not a port number: exim abandoned", s); - if (lport == port) return TRUE; - } +while ((s = string_nextinlist(&list, &sep, buffer, sizeof(buffer)))) + if (Ustrtol(s, &end, 10) == port) + return TRUE; return FALSE; } @@ -1622,7 +1620,7 @@ while ((ordername = string_nextinlist(&list, &sep, buffer, sizeof(buffer))) { if (strcmpic(ordername, US"bydns") == 0) { - dns_init(FALSE, FALSE, FALSE); /*XXX dnssec? */ + dns_init(FALSE, FALSE, FALSE); /* dnssec ctrl by dns_dnssec_ok glbl */ dns_build_reverse(sender_host_address, buffer); rc = dns_lookup(&dnsa, buffer, T_PTR, NULL); @@ -1744,8 +1742,8 @@ if (sender_host_name == NULL) HDEBUG(D_host_lookup) { uschar **aliases = sender_host_aliases; - debug_printf("IP address lookup yielded %s\n", sender_host_name); - while (*aliases != NULL) debug_printf(" alias %s\n", *aliases++); + debug_printf("IP address lookup yielded \"%s\"\n", sender_host_name); + while (*aliases != NULL) debug_printf(" alias \"%s\"\n", *aliases++); } /* We need to verify that a forward lookup on the name we found does indeed @@ -2063,6 +2061,7 @@ for (i = 1; i <= times; host->port = PORT_NONE; host->status = hstatus_unknown; host->why = hwhy_unknown; + host->dnssec = DS_UNK; last = host; } @@ -2078,6 +2077,7 @@ for (i = 1; i <= times; next->port = PORT_NONE; next->status = hstatus_unknown; next->why = hwhy_unknown; + next->dnssec = DS_UNK; next->last_try = 0; next->next = last->next; last->next = next; @@ -2207,7 +2207,7 @@ Returns: HOST_FIND_FAILED couldn't find A record static int set_address_from_dns(host_item *host, host_item **lastptr, uschar *ignore_target_hosts, BOOL allow_ip, uschar **fully_qualified_name, - BOOL dnssec_require) + BOOL dnssec_request, BOOL dnssec_require) { dns_record *rr; host_item *thishostlast = NULL; /* Indicates not yet filled in anything */ @@ -2268,6 +2268,8 @@ for (; i >= 0; i--) dns_scan dnss; int rc = dns_lookup(&dnsa, host->name, type, fully_qualified_name); + lookup_dnssec_authenticated = !dnssec_request ? NULL + : dns_is_secure(&dnsa) ? US"yes" : US"no"; /* We want to return HOST_FIND_AGAIN if one of the A, A6, or AAAA lookups fails or times out, but not if another one succeeds. (In the early @@ -2290,11 +2292,31 @@ for (; i >= 0; i--) if (rc != DNS_NOMATCH && rc != DNS_NODATA) v6_find_again = TRUE; continue; } - if (dnssec_require && !dns_is_secure(&dnsa)) + + if (dnssec_request) { - log_write(L_host_lookup_failed, LOG_MAIN, "dnssec fail on %s for %.256s", + if (dns_is_secure(&dnsa)) + { + DEBUG(D_host_lookup) debug_printf("%s A DNSSEC\n", host->name); + if (host->dnssec == DS_UNK) /* set in host_find_bydns() */ + host->dnssec = DS_YES; + } + else + { + if (dnssec_require) + { + log_write(L_host_lookup_failed, LOG_MAIN, + "dnssec fail on %s for %.256s", i>1 ? "A6" : i>0 ? "AAAA" : "A", host->name); - continue; + continue; + } + if (host->dnssec == DS_YES) /* set in host_find_bydns() */ + { + DEBUG(D_host_lookup) debug_printf("%s A cancel DNSSEC\n", host->name); + host->dnssec = DS_NO; + lookup_dnssec_authenticated = US"no"; + } + } } /* Lookup succeeded: fill in the given host item with the first non-ignored @@ -2471,10 +2493,12 @@ int ind_type = 0; int yield; dns_answer dnsa; dns_scan dnss; -BOOL dnssec_request = match_isinlist(host->name, &dnssec_request_domains, - 0, NULL, NULL, MCL_DOMAIN, TRUE, NULL) == OK; BOOL dnssec_require = match_isinlist(host->name, &dnssec_require_domains, 0, NULL, NULL, MCL_DOMAIN, TRUE, NULL) == OK; +BOOL dnssec_request = dnssec_require + || match_isinlist(host->name, &dnssec_request_domains, + 0, NULL, NULL, MCL_DOMAIN, TRUE, NULL) == OK; +dnssec_status_t dnssec; /* Set the default fully qualified name to the incoming name, initialize the resolver if necessary, set up the relevant options, and initialize the flag @@ -2483,7 +2507,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_require + dnssec_request ); host_find_failed_syntax = FALSE; @@ -2505,7 +2529,18 @@ if ((whichrrs & HOST_FIND_BY_SRV) != 0) the input name, pass back the new original domain, without the prepended magic. */ + dnssec = DS_UNK; + lookup_dnssec_authenticated = NULL; rc = dns_lookup(&dnsa, buffer, ind_type, &temp_fully_qualified_name); + + if (dnssec_request) + { + if (dns_is_secure(&dnsa)) + { dnssec = DS_YES; lookup_dnssec_authenticated = US"yes"; } + else + { dnssec = DS_NO; lookup_dnssec_authenticated = US"no"; } + } + if (temp_fully_qualified_name != buffer && fully_qualified_name != NULL) *fully_qualified_name = temp_fully_qualified_name + prefix_length; @@ -2540,7 +2575,23 @@ listed as one for which we continue. */ if (rc != DNS_SUCCEED && (whichrrs & HOST_FIND_BY_MX) != 0) { ind_type = T_MX; + dnssec = DS_UNK; + lookup_dnssec_authenticated = NULL; rc = dns_lookup(&dnsa, host->name, ind_type, fully_qualified_name); + + if (dnssec_request) + { + if (dns_is_secure(&dnsa)) + { + DEBUG(D_host_lookup) debug_printf("%s MX DNSSEC\n", host->name); + dnssec = DS_YES; lookup_dnssec_authenticated = US"yes"; + } + else + { + dnssec = DS_NO; lookup_dnssec_authenticated = US"no"; + } + } + switch (rc) { case DNS_NOMATCH: @@ -2552,7 +2603,7 @@ if (rc != DNS_SUCCEED && (whichrrs & HOST_FIND_BY_MX) != 0) log_write(L_host_lookup_failed, LOG_MAIN, "dnssec fail on MX for %.256s", host->name); rc = DNS_FAIL; - /*FALLTRHOUGH*/ + /*FALLTHROUGH*/ case DNS_FAIL: case DNS_AGAIN: @@ -2583,8 +2634,10 @@ if (rc != DNS_SUCCEED) last = host; /* End of local chainlet */ host->mx = MX_NONE; host->port = PORT_NONE; + host->dnssec = DS_UNK; + lookup_dnssec_authenticated = NULL; rc = set_address_from_dns(host, &last, ignore_target_hosts, FALSE, - fully_qualified_name, dnssec_require); + fully_qualified_name, dnssec_request, dnssec_require); /* If one or more address records have been found, check that none of them are local. Since we know the host items all have their IP addresses @@ -2655,9 +2708,7 @@ for (rr = dns_next_rr(&dnsa, &dnss, RESET_ANSWERS); the same precedence to sort randomly. */ if (ind_type == T_MX) - { weight = random_number(500); - } /* SRV records are specified with a port and a weight. The weight is used in a special algorithm. However, to start with, we just use it to order the @@ -2721,6 +2772,7 @@ for (rr = dns_next_rr(&dnsa, &dnss, RESET_ANSWERS); host->sort_key = precedence * 1000 + weight; host->status = hstatus_unknown; host->why = hwhy_unknown; + host->dnssec = dnssec; last = host; } @@ -2737,6 +2789,7 @@ for (rr = dns_next_rr(&dnsa, &dnss, RESET_ANSWERS); next->sort_key = sort_key; next->status = hstatus_unknown; next->why = hwhy_unknown; + next->dnssec = dnssec; next->last_try = 0; /* Handle the case when we have to insert before the first item. */ @@ -2914,7 +2967,7 @@ for (h = host; h != last->next; h = h->next) { if (h->address != NULL) continue; /* Inserted by a multihomed host */ rc = set_address_from_dns(h, &last, ignore_target_hosts, allow_mx_to_ip, - NULL, dnssec_require); + NULL, dnssec_request, dnssec_require); if (rc != HOST_FOUND) { h->status = hstatus_unusable; @@ -3015,8 +3068,9 @@ DEBUG(D_host_lookup) yield); for (h = host; h != last->next; h = h->next) { - debug_printf(" %s %s MX=%d ", h->name, - (h->address == NULL)? US"" : h->address, h->mx); + debug_printf(" %s %s MX=%d %s", h->name, + !h->address ? US"" : h->address, h->mx, + h->dnssec == DS_YES ? US"DNSSEC " : US""); if (h->port != PORT_NONE) debug_printf("port=%d ", h->port); if (h->status >= hstatus_unusable) debug_printf("*"); debug_printf("\n");