X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fsrc%2Fhost.c;h=4e1cb8a4578e1fb0de4f39e08a14a8289e9e825a;hb=191d76b569c84b5664e47949727bf88ae0c978a9;hp=aa142eb9b4ef2997035f8d0e2c1beeea7682a997;hpb=30795c5e77e21e90f3c695e6274bc9b4a9b68900;p=user%2Fhenk%2Fcode%2Fexim.git diff --git a/src/src/host.c b/src/src/host.c index aa142eb9b..4e1cb8a45 100644 --- a/src/src/host.c +++ b/src/src/host.c @@ -3,6 +3,7 @@ *************************************************/ /* Copyright (c) University of Cambridge 1995 - 2018 */ +/* Copyright (c) The Exim Maintainers 2020 */ /* See the file NOTICE for conditions of use and distribution. */ /* Functions for finding hosts, either by gethostbyname(), gethostbyaddr(), or @@ -182,19 +183,18 @@ dns_scan dnss; DEBUG(D_host_lookup) debug_printf("using host_fake_gethostbyname for %s (%s)\n", name, - (af == AF_INET)? "IPv4" : "IPv6"); + af == AF_INET ? "IPv4" : "IPv6"); /* Handle unqualified "localhost" */ if (Ustrcmp(name, "localhost") == 0) - lname = (af == AF_INET)? US"127.0.0.1" : US"::1"; + lname = af == AF_INET ? US"127.0.0.1" : US"::1"; /* Handle a literal IP address */ if ((ipa = string_is_ip_address(lname, NULL)) != 0) - { - if ((ipa == 4 && af == AF_INET) || - (ipa == 6 && af == AF_INET6)) + if ( ipa == 4 && af == AF_INET + || ipa == 6 && af == AF_INET6) { int x[4]; yield = store_get(sizeof(struct hostent), FALSE); @@ -224,13 +224,12 @@ if ((ipa = string_is_ip_address(lname, NULL)) != 0) *error_num = HOST_NOT_FOUND; return NULL; } - } /* Handle a host name */ else { - int type = (af == AF_INET)? T_A:T_AAAA; + int type = af == AF_INET ? T_A:T_AAAA; int rc = dns_lookup_timerwrap(dnsa, lname, type, NULL); int count = 0; @@ -729,6 +728,7 @@ host_build_ifacelist(const uschar *list, uschar *name) int sep = 0; uschar *s; ip_address_item * yield = NULL, * last = NULL, * next; +BOOL taint = is_tainted(list); while ((s = string_nextinlist(&list, &sep, NULL, 0))) { @@ -747,7 +747,7 @@ while ((s = string_nextinlist(&list, &sep, NULL, 0))) address above. The field in the ip_address_item is large enough to hold an IPv6 address. */ - next = store_get(sizeof(ip_address_item), FALSE); + next = store_get(sizeof(ip_address_item), taint); next->next = NULL; Ustrcpy(next->address, s); next->port = port; @@ -1646,7 +1646,6 @@ int old_pool, rc; int sep = 0; uschar *save_hostname; uschar **aliases; -uschar buffer[256]; uschar *ordername; const uschar *list = host_lookup_order; dns_answer * dnsa = store_get_dns_answer(); @@ -1672,13 +1671,14 @@ if (f.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)))) +while ((ordername = string_nextinlist(&list, &sep, NULL, 0))) { if (strcmpic(ordername, US"bydns") == 0) { + uschar * name = dns_build_reverse(sender_host_address); + dns_init(FALSE, FALSE, FALSE); /* dnssec ctrl by dns_dnssec_ok glbl */ - dns_build_reverse(sender_host_address, buffer); - rc = dns_lookup_timerwrap(dnsa, buffer, T_PTR, NULL); + rc = dns_lookup_timerwrap(dnsa, name, T_PTR, NULL); /* The first record we come across is used for the name; others are considered to be aliases. We have to scan twice, in order to find out the @@ -1946,8 +1946,13 @@ host_find_byname(host_item *host, const uschar *ignore_target_hosts, int flags, int yield, times; host_item *last = NULL; BOOL temp_error = FALSE; -#if HAVE_IPV6 int af; + +#ifndef DISABLE_TLS +/* Copy the host name at this point to the value which is used for +TLS certificate name checking, before anything modifies it. */ + +host->certname = host->name; #endif /* Make sure DNS options are set as required. This appears to be necessary in @@ -1967,10 +1972,10 @@ lookups here (except when testing standalone). */ #ifdef STAND_ALONE if (disable_ipv6) #else - if (disable_ipv6 || - (dns_ipv4_lookup != NULL && - match_isinlist(host->name, CUSS &dns_ipv4_lookup, 0, NULL, NULL, - MCL_DOMAIN, TRUE, NULL) == OK)) + if ( disable_ipv6 + || dns_ipv4_lookup + && match_isinlist(host->name, CUSS &dns_ipv4_lookup, 0, NULL, NULL, + MCL_DOMAIN, TRUE, NULL) == OK) #endif { af = AF_INET; times = 1; } @@ -1980,7 +1985,7 @@ lookups here (except when testing standalone). */ /* No IPv6 support */ #else /* HAVE_IPV6 */ - times = 1; + af = AF_INET; times = 1; #endif /* HAVE_IPV6 */ /* Initialize the flag that gets set for DNS syntax check errors, so that the @@ -2022,7 +2027,7 @@ for (int i = 1; i <= times; #else /* not HAVE_IPV6 */ if (f.running_in_test_harness) - hostdata = host_fake_gethostbyname(host->name, AF_INET, &error_num); + hostdata = host_fake_gethostbyname(host->name, af, &error_num); else { hostdata = gethostbyname(CS host->name); @@ -2034,45 +2039,44 @@ for (int i = 1; i <= times; && (time_msec = get_time_in_ms() - time_msec) > slow_lookup_log) log_long_lookup(US"gethostbyname", host->name, time_msec); - if (hostdata == NULL) + if (!hostdata) { - uschar *error; + uschar * error; switch (error_num) { - case HOST_NOT_FOUND: error = US"HOST_NOT_FOUND"; break; - case TRY_AGAIN: error = US"TRY_AGAIN"; break; - case NO_RECOVERY: error = US"NO_RECOVERY"; break; - case NO_DATA: error = US"NO_DATA"; break; - #if NO_DATA != NO_ADDRESS - case NO_ADDRESS: error = US"NO_ADDRESS"; break; - #endif + case HOST_NOT_FOUND: error = US"HOST_NOT_FOUND"; break; + case TRY_AGAIN: error = US"TRY_AGAIN"; temp_error = TRUE; break; + case NO_RECOVERY: error = US"NO_RECOVERY"; temp_error = TRUE; break; + case NO_DATA: error = US"NO_DATA"; break; + #if NO_DATA != NO_ADDRESS + case NO_ADDRESS: error = US"NO_ADDRESS"; break; + #endif default: error = US"?"; break; } - DEBUG(D_host_lookup) debug_printf("%s returned %d (%s)\n", - #if HAVE_IPV6 - #if HAVE_GETIPNODEBYNAME - (af == AF_INET6)? "getipnodebyname(af=inet6)" : "getipnodebyname(af=inet)", - #else - (af == AF_INET6)? "gethostbyname2(af=inet6)" : "gethostbyname2(af=inet)", - #endif - #else - "gethostbyname", - #endif - error_num, error); + DEBUG(D_host_lookup) debug_printf("%s(af=%s) returned %d (%s)\n", + f.running_in_test_harness ? "host_fake_gethostbyname" : +#if HAVE_IPV6 +# if HAVE_GETIPNODEBYNAME + "getipnodebyname", +# else + "gethostbyname2", +# endif +#else + "gethostbyname", +#endif + af == AF_INET ? "inet" : "inet6", error_num, error); - if (error_num == TRY_AGAIN || error_num == NO_RECOVERY) temp_error = TRUE; continue; } - if ((hostdata->h_addr_list)[0] == NULL) continue; + if (!(hostdata->h_addr_list)[0]) continue; /* Replace the name with the fully qualified one if necessary, and fill in the fully_qualified_name pointer. */ - if (hostdata->h_name[0] != 0 && - Ustrcmp(host->name, hostdata->h_name) != 0) + if (hostdata->h_name[0] && Ustrcmp(host->name, hostdata->h_name) != 0) host->name = string_copy_dnsdomain(US hostdata->h_name); - if (fully_qualified_name != NULL) *fully_qualified_name = host->name; + if (fully_qualified_name) *fully_qualified_name = host->name; /* Get the list of addresses. IPv4 and IPv6 addresses can be distinguished by their different lengths. Scan the list, ignoring any that are to be @@ -2086,9 +2090,9 @@ for (int i = 1; i <= times; host_ntoa(ipv4_addr? AF_INET:AF_INET6, *addrlist, NULL, NULL); #ifndef STAND_ALONE - if (ignore_target_hosts != NULL && - verify_check_this_host(&ignore_target_hosts, NULL, host->name, - text_address, NULL) == OK) + if ( ignore_target_hosts + && verify_check_this_host(&ignore_target_hosts, NULL, host->name, + text_address, NULL) == OK) { DEBUG(D_host_lookup) debug_printf("ignored host %s [%s]\n", host->name, text_address); @@ -2096,10 +2100,10 @@ for (int i = 1; i <= times; } #endif - /* If this is the first address, last == NULL and we put the data in the + /* If this is the first address, last is NULL and we put the data in the original block. */ - if (last == NULL) + if (!last) { host->address = text_address; host->port = PORT_NONE; @@ -2116,6 +2120,9 @@ for (int i = 1; i <= times; { host_item *next = store_get(sizeof(host_item), FALSE); next->name = host->name; +#ifndef DISABLE_TLS + next->certname = host->certname; +#endif next->mx = host->mx; next->address = text_address; next->port = PORT_NONE; @@ -2134,12 +2141,12 @@ for (int i = 1; i <= times; NULL. If temp_error is set, at least one of the lookups gave a temporary error, so we pass that back. */ -if (host->address == NULL) +if (!host->address) { uschar *msg = #ifndef STAND_ALONE - (message_id[0] == 0 && smtp_in != NULL)? - string_sprintf("no IP address found for host %s (during %s)", host->name, + !message_id[0] && smtp_in + ? string_sprintf("no IP address found for host %s (during %s)", host->name, smtp_get_connection_info()) : #endif string_sprintf("no IP address found for host %s", host->name); @@ -2259,6 +2266,13 @@ BOOL v6_find_again = FALSE; BOOL dnssec_fail = FALSE; int i; +#ifndef DISABLE_TLS +/* Copy the host name at this point to the value which is used for +TLS certificate name checking, before any CNAME-following modifies it. */ + +host->certname = host->name; +#endif + /* If allow_ip is set, a name which is an IP address returns that value as its address. This is used for MX records when allow_mx_to_ip is set, for those sites that feel they have to flaunt the RFC rules. */ @@ -3179,7 +3193,7 @@ BOOL sec; rc = dns_lookup_timerwrap(dnsa, buffer, T_TLSA, &fullname); sec = dns_is_secure(dnsa); DEBUG(D_transport) - debug_printf("TLSA lookup ret %d %sDNSSEC\n", rc, sec ? "" : "not "); + debug_printf("TLSA lookup ret %s %sDNSSEC\n", dns_rc_names[rc], sec ? "" : "not "); switch (rc) {