diff options
author | Jeremy Harris <jgh146exb@wizmail.org> | 2016-04-24 16:53:25 +0100 |
---|---|---|
committer | Jeremy Harris <jgh146exb@wizmail.org> | 2016-04-24 16:53:25 +0100 |
commit | 4b0fe31936b336d12836875101dcac6599d127ee (patch) | |
tree | 2495b59338f71113b5fbf3b4d2659fc3e709710c /src | |
parent | c035b645ba3549472b9a835b845c2027b16a4cf2 (diff) |
DANE: Remove fallback from hosts_try_dane. If TLSA record not retrieved,
do not use this host.
Diffstat (limited to 'src')
-rw-r--r-- | src/src/dns.c | 61 | ||||
-rw-r--r-- | src/src/functions.h | 2 | ||||
-rw-r--r-- | src/src/transports/smtp.c | 48 | ||||
-rw-r--r-- | src/src/verify.c | 40 |
4 files changed, 68 insertions, 83 deletions
diff --git a/src/src/dns.c b/src/src/dns.c index 1d5384e9d..575b81560 100644 --- a/src/src/dns.c +++ b/src/src/dns.c @@ -663,8 +663,7 @@ caching for successful lookups. */ sprintf(CS node_name, "%.255s-%s-%lx", name, dns_text_type(type), (unsigned long) resp->options); -previous = tree_search(tree_dns_fails, node_name); -if (previous != NULL) +if ((previous = tree_search(tree_dns_fails, node_name))) { DEBUG(D_dns) debug_printf("DNS lookup of %.255s-%s: using cached value %s\n", name, dns_text_type(type), @@ -769,48 +768,48 @@ if (dnsa->answerlen > MAXPACKET) if (dnsa->answerlen < 0) switch (h_errno) { case HOST_NOT_FOUND: - DEBUG(D_dns) debug_printf("DNS lookup of %s (%s) gave HOST_NOT_FOUND\n" - "returning DNS_NOMATCH\n", name, dns_text_type(type)); - return dns_return(name, type, DNS_NOMATCH); + DEBUG(D_dns) debug_printf("DNS lookup of %s (%s) gave HOST_NOT_FOUND\n" + "returning DNS_NOMATCH\n", name, dns_text_type(type)); + return dns_return(name, type, DNS_NOMATCH); case TRY_AGAIN: - DEBUG(D_dns) debug_printf("DNS lookup of %s (%s) gave TRY_AGAIN\n", - name, dns_text_type(type)); + DEBUG(D_dns) debug_printf("DNS lookup of %s (%s) gave TRY_AGAIN\n", + name, dns_text_type(type)); - /* Cut this out for various test programs */ + /* Cut this out for various test programs */ #ifndef STAND_ALONE - save_domain = deliver_domain; - deliver_domain = string_copy(name); /* set $domain */ - rc = match_isinlist(name, (const uschar **)&dns_again_means_nonexist, 0, NULL, NULL, - MCL_DOMAIN, TRUE, NULL); - deliver_domain = save_domain; - if (rc != OK) - { - DEBUG(D_dns) debug_printf("returning DNS_AGAIN\n"); - return dns_return(name, type, DNS_AGAIN); - } - DEBUG(D_dns) debug_printf("%s is in dns_again_means_nonexist: returning " - "DNS_NOMATCH\n", name); - return dns_return(name, type, DNS_NOMATCH); + save_domain = deliver_domain; + deliver_domain = string_copy(name); /* set $domain */ + rc = match_isinlist(name, (const uschar **)&dns_again_means_nonexist, 0, NULL, NULL, + MCL_DOMAIN, TRUE, NULL); + deliver_domain = save_domain; + if (rc != OK) + { + DEBUG(D_dns) debug_printf("returning DNS_AGAIN\n"); + return dns_return(name, type, DNS_AGAIN); + } + DEBUG(D_dns) debug_printf("%s is in dns_again_means_nonexist: returning " + "DNS_NOMATCH\n", name); + return dns_return(name, type, DNS_NOMATCH); #else /* For stand-alone tests */ - return dns_return(name, type, DNS_AGAIN); + return dns_return(name, type, DNS_AGAIN); #endif case NO_RECOVERY: - DEBUG(D_dns) debug_printf("DNS lookup of %s (%s) gave NO_RECOVERY\n" - "returning DNS_FAIL\n", name, dns_text_type(type)); - return dns_return(name, type, DNS_FAIL); + DEBUG(D_dns) debug_printf("DNS lookup of %s (%s) gave NO_RECOVERY\n" + "returning DNS_FAIL\n", name, dns_text_type(type)); + return dns_return(name, type, DNS_FAIL); case NO_DATA: - DEBUG(D_dns) debug_printf("DNS lookup of %s (%s) gave NO_DATA\n" - "returning DNS_NODATA\n", name, dns_text_type(type)); - return dns_return(name, type, DNS_NODATA); + DEBUG(D_dns) debug_printf("DNS lookup of %s (%s) gave NO_DATA\n" + "returning DNS_NODATA\n", name, dns_text_type(type)); + return dns_return(name, type, DNS_NODATA); default: - DEBUG(D_dns) debug_printf("DNS lookup of %s (%s) gave unknown DNS error %d\n" - "returning DNS_FAIL\n", name, dns_text_type(type), h_errno); - return dns_return(name, type, DNS_FAIL); + DEBUG(D_dns) debug_printf("DNS lookup of %s (%s) gave unknown DNS error %d\n" + "returning DNS_FAIL\n", name, dns_text_type(type), h_errno); + return dns_return(name, type, DNS_FAIL); } DEBUG(D_dns) debug_printf("DNS lookup of %s (%s) succeeded\n", diff --git a/src/src/functions.h b/src/src/functions.h index 4fbabcd81..6c3c37463 100644 --- a/src/src/functions.h +++ b/src/src/functions.h @@ -71,7 +71,7 @@ extern uschar * tls_field_from_dn(uschar *, const uschar *); extern BOOL tls_is_name_for_cert(const uschar *, void *); # ifdef EXPERIMENTAL_DANE -extern int tlsa_lookup(const host_item *, dns_answer *, BOOL, BOOL *); +extern int tlsa_lookup(const host_item *, dns_answer *, BOOL); # endif #endif /*SUPPORT_TLS*/ diff --git a/src/src/transports/smtp.c b/src/src/transports/smtp.c index a8a78d945..361531a9f 100644 --- a/src/src/transports/smtp.c +++ b/src/src/transports/smtp.c @@ -1216,8 +1216,7 @@ return FALSE; #ifdef EXPERIMENTAL_DANE int -tlsa_lookup(const host_item * host, dns_answer * dnsa, - BOOL dane_required, BOOL * dane) +tlsa_lookup(const host_item * host, dns_answer * dnsa, BOOL dane_required) { /* move this out to host.c given the similarity to dns_lookup() ? */ uschar buffer[300]; @@ -1233,9 +1232,7 @@ switch (dns_lookup(dnsa, buffer, T_TLSA, &fullname)) default: case DNS_FAIL: - if (dane_required) - return FAIL; - break; + return dane_required ? FAIL : DEFER; case DNS_SUCCEED: if (!dns_is_secure(dnsa)) @@ -1243,10 +1240,8 @@ switch (dns_lookup(dnsa, buffer, T_TLSA, &fullname)) log_write(0, LOG_MAIN, "DANE error: TLSA lookup not DNSSEC"); return DEFER; } - *dane = TRUE; - break; + return OK; } -return OK; } #endif @@ -1545,18 +1540,19 @@ if (continue_hostname == NULL) if (host->dnssec == DS_YES) { - if( ( dane_required - || verify_check_given_host(&ob->hosts_try_dane, host) == OK - ) - && (rc = tlsa_lookup(host, &tlsa_dnsa, dane_required, &dane)) != OK - && dane_required /* do not error on only dane-requested */ + if( dane_required + || verify_check_given_host(&ob->hosts_try_dane, host) == OK ) { - set_errno_nohost(addrlist, ERRNO_DNSDEFER, - string_sprintf("DANE error: tlsa lookup %s", - rc == DEFER ? "DEFER" : "FAIL"), - rc, FALSE); - return rc; + if ((rc = tlsa_lookup(host, &tlsa_dnsa, dane_required)) != OK) + { + set_errno_nohost(addrlist, ERRNO_DNSDEFER, + string_sprintf("DANE error: tlsa lookup %s", + rc == DEFER ? "DEFER" : "FAIL"), + rc, FALSE); + return rc; + } + dane = TRUE; } } else if (dane_required) @@ -1564,7 +1560,7 @@ if (continue_hostname == NULL) set_errno_nohost(addrlist, ERRNO_DNSDEFER, string_sprintf("DANE error: %s lookup not DNSSEC", host->name), FAIL, FALSE); - return FAIL; + return FAIL; } if (dane) @@ -1790,8 +1786,10 @@ if ( tls_offered if (!smtp_read_response(&inblock, buffer2, sizeof(buffer2), '2', ob->command_timeout)) { - if (errno != 0 || buffer2[0] == 0 || - (buffer2[0] == '4' && !ob->tls_tempfail_tryclear)) + if ( errno != 0 + || buffer2[0] == 0 + || (buffer2[0] == '4' && !ob->tls_tempfail_tryclear) + ) { Ustrncpy(buffer, buffer2, sizeof(buffer)); goto RESPONSE_FAILED; @@ -1816,13 +1814,11 @@ if ( tls_offered if (rc != OK) { # ifdef EXPERIMENTAL_DANE - if (rc == DEFER && dane && !dane_required) + if (rc == DEFER && dane) { - log_write(0, LOG_MAIN, "DANE attempt failed;" - " trying CA-root TLS to %s [%s] (not in hosts_require_dane)", + log_write(0, LOG_MAIN, + "DANE attempt failed; no TLS connection to %s [%s]", host->name, host->address); - dane = FALSE; - goto TLS_NEGOTIATE; } # endif diff --git a/src/src/verify.c b/src/src/verify.c index f64057fd1..04c781e54 100644 --- a/src/src/verify.c +++ b/src/src/verify.c @@ -640,12 +640,14 @@ can do it there for the non-rcpt-verify case. For this we keep an addresscount. if (host->dnssec == DS_YES) { - if( ( dane_required - || verify_check_given_host(&ob->hosts_try_dane, host) == OK - ) - && (rc = tlsa_lookup(host, &tlsa_dnsa, dane_required, &dane)) != OK + if( dane_required + || verify_check_given_host(&ob->hosts_try_dane, host) == OK ) - return rc; + { + if ((rc = tlsa_lookup(host, &tlsa_dnsa, dane_required)) != OK) + return rc; + dane = TRUE; + } } else if (dane_required) { @@ -792,8 +794,10 @@ can do it there for the non-rcpt-verify case. For this we keep an addresscount. if (!smtps && !smtp_read_response(&inblock, buffer2, sizeof(buffer2), '2', ob->command_timeout)) { - if (errno != 0 || buffer2[0] == 0 || - (buffer2[0] == '4' && !ob->tls_tempfail_tryclear)) + if ( errno != 0 + || buffer2[0] == 0 + || buffer2[0] == '4' && !ob->tls_tempfail_tryclear + ) { Ustrncpy(responsebuffer, buffer2, sizeof(responsebuffer)); done= FALSE; @@ -827,24 +831,10 @@ can do it there for the non-rcpt-verify case. For this we keep an addresscount. (void) event_raise(addr->transport->event_action, US"tcp:close", NULL); # endif -# ifdef EXPERIMENTAL_DANE - if (dane) - { - if (!dane_required) - { - log_write(0, LOG_MAIN, "DANE attempt failed;" - " trying CA-root TLS to %s [%s] (not in hosts_require_dane)", - host->name, host->address); - dane = FALSE; - goto tls_negotiate; - } - } - else -# endif - if ( ob->tls_tempfail_tryclear - && !smtps - && verify_check_given_host(&ob->hosts_require_tls, host) != OK - ) + if ( ob->tls_tempfail_tryclear + && !smtps + && verify_check_given_host(&ob->hosts_require_tls, host) != OK + ) { log_write(0, LOG_MAIN, "TLS session failure:" " delivering unencrypted to %s [%s] (not in hosts_require_tls)", |