X-Git-Url: https://vcs.fsf.org/?a=blobdiff_plain;f=src%2Fsrc%2Fhost.c;h=3361d59123f33314ba79f70c0ac562513da99b4c;hb=2fa25efce2a183e8886d66e2f1a0ae83ac964d8e;hp=d84347cb1329b8c2712a240bd8692bda8fe36197;hpb=8743d3acaaa2262007aa2862ffecd6b19125e38d;p=exim.git diff --git a/src/src/host.c b/src/src/host.c index d84347cb1..3361d5912 100644 --- a/src/src/host.c +++ b/src/src/host.c @@ -138,7 +138,7 @@ if (!slow_lookup_log) time_msec = get_time_in_ms(); retval = dns_lookup(dnsa, name, type, fully_qualified_name); if ((time_msec = get_time_in_ms() - time_msec) > slow_lookup_log) - log_long_lookup(US"name", name, time_msec); + log_long_lookup(dns_text_type(type), name, time_msec); return retval; } @@ -1503,9 +1503,7 @@ Returns: OK, DEFER, FAIL static int host_name_lookup_byaddr(void) { -int len; -uschar *s, *t; -struct hostent *hosts; +struct hostent * hosts; struct in_addr addr; unsigned long time_msec = 0; /* init to quieten dumb static analysis */ @@ -1548,7 +1546,7 @@ hosts = gethostbyaddr(CS(&addr), sizeof(addr), AF_INET); if ( slow_lookup_log && (time_msec = get_time_in_ms() - time_msec) > slow_lookup_log ) - log_long_lookup(US"name", sender_host_address, time_msec); + log_long_lookup(US"gethostbyaddr", sender_host_address, time_msec); /* Failed to look up the host. */ @@ -1648,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(); @@ -1674,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 @@ -2034,7 +2032,7 @@ for (int i = 1; i <= times; if ( slow_lookup_log && (time_msec = get_time_in_ms() - time_msec) > slow_lookup_log) - log_long_lookup(US"name", host->name, time_msec); + log_long_lookup(US"gethostbyname", host->name, time_msec); if (hostdata == NULL) { @@ -2650,7 +2648,7 @@ if (rc != DNS_SUCCEED && whichrrs & HOST_FIND_BY_MX) if (dnssec_request) if (dns_is_secure(dnsa)) { - DEBUG(D_host_lookup) debug_printf("%s MX DNSSEC\n", host->name); + DEBUG(D_host_lookup) debug_printf("%s (MX resp) DNSSEC\n", host->name); dnssec = DS_YES; lookup_dnssec_authenticated = US"yes"; } else @@ -3156,6 +3154,79 @@ dns_init(FALSE, FALSE, FALSE); /* clear the dnssec bit for getaddrbyname */ return yield; } + + + +#ifdef SUPPORT_DANE +/* Lookup TLSA record for host/port. +Return: OK success with dnssec; DANE mode + DEFER Do not use this host now, may retry later + FAIL_FORCED No TLSA record; DANE not usable + FAIL Do not use this connection +*/ + +int +tlsa_lookup(const host_item * host, dns_answer * dnsa, BOOL dane_required) +{ +uschar buffer[300]; +const uschar * fullname = buffer; +int rc; +BOOL sec; + +/* TLSA lookup string */ +(void)sprintf(CS buffer, "_%d._tcp.%.256s", host->port, host->name); + +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 "); + +switch (rc) + { + case DNS_AGAIN: + return DEFER; /* just defer this TLS'd conn */ + + case DNS_SUCCEED: + if (sec) + { + DEBUG(D_transport) + { + dns_scan dnss; + for (dns_record * rr = dns_next_rr(dnsa, &dnss, RESET_ANSWERS); rr; + rr = dns_next_rr(dnsa, &dnss, RESET_NEXT)) + if (rr->type == T_TLSA && rr->size > 3) + { + uint16_t payload_length = rr->size - 3; + uschar s[MAX_TLSA_EXPANDED_SIZE], * sp = s, * p = US rr->data; + + sp += sprintf(CS sp, "%d ", *p++); /* usage */ + sp += sprintf(CS sp, "%d ", *p++); /* selector */ + sp += sprintf(CS sp, "%d ", *p++); /* matchtype */ + while (payload_length-- > 0 && sp-s < (MAX_TLSA_EXPANDED_SIZE - 4)) + sp += sprintf(CS sp, "%02x", *p++); + + debug_printf(" %s\n", s); + } + } + return OK; + } + log_write(0, LOG_MAIN, + "DANE error: TLSA lookup for %s not DNSSEC", host->name); + /*FALLTRHOUGH*/ + + case DNS_NODATA: /* no TLSA RR for this lookup */ + case DNS_NOMATCH: /* no records at all for this lookup */ + return dane_required ? FAIL : FAIL_FORCED; + + default: + case DNS_FAIL: + return dane_required ? FAIL : DEFER; + } +} +#endif /*SUPPORT_DANE*/ + + + /************************************************* ************************************************** * Stand-alone test program *