From: Jeremy Harris Date: Wed, 20 Aug 2014 19:22:21 +0000 (+0100) Subject: Merge branch 'master' into dane X-Git-Tag: exim-4_85_RC1~67^2~4 X-Git-Url: https://git.exim.org/exim.git/commitdiff_plain/a1bccd48f3956b50a13a34f5aed4b72c658c61af Merge branch 'master' into dane Conflicts: doc/doc-txt/ChangeLog src/src/tls-openssl.c src/src/transports/smtp.c src/src/verify.c --- a1bccd48f3956b50a13a34f5aed4b72c658c61af diff --cc src/src/deliver.c index ab0815ed4,48d3fd7ec..d00af9c11 --- a/src/src/deliver.c +++ b/src/src/deliver.c @@@ -4133,12 -4153,9 +4161,12 @@@ for (delivery_count = 0; addr_remote ! /* The certificate verification status goes into the flags */ if (tls_out.certificate_verified) setflag(addr, af_cert_verified); +#ifdef EXPERIMENTAL_DANE + if (tls_out.dane_verified) setflag(addr, af_dane_verified); +#endif /* Use an X item only if there's something to send */ - #ifdef SUPPORT_TLS + #ifdef SUPPORT_TLS if (addr->cipher) { ptr = big_buffer; diff --cc src/src/tls-openssl.c index 343122615,c031b8e4d..735ebff06 --- a/src/src/tls-openssl.c +++ b/src/src/tls-openssl.c @@@ -1726,74 -1596,21 +1769,75 @@@ Returns: OK on succes int tls_client_start(int fd, host_item *host, address_item *addr, - void *v_ob) + transport_instance *tb) { - smtp_transport_options_block * ob = v_ob; + smtp_transport_options_block * ob = + (smtp_transport_options_block *)tb->options_block; static uschar txt[256]; -uschar *expciphers; -X509* server_cert; +uschar * expciphers; +X509 * server_cert; int rc; static uschar cipherbuf[256]; + #ifndef DISABLE_OCSP -BOOL require_ocsp = verify_check_this_host(&ob->hosts_require_ocsp, - NULL, host->name, host->address, NULL) == OK; -BOOL request_ocsp = require_ocsp ? TRUE - : verify_check_this_host(&ob->hosts_request_ocsp, - NULL, host->name, host->address, NULL) == OK; +BOOL request_ocsp = FALSE; +BOOL require_ocsp = FALSE; +#endif +#ifdef EXPERIMENTAL_DANE +dns_answer tlsa_dnsa; +BOOL dane = FALSE; +BOOL dane_required; +#endif + +#ifdef EXPERIMENTAL_DANE +tls_out.dane_verified = FALSE; +tls_out.tlsa_usage = 0; +dane_required = verify_check_this_host(&ob->hosts_require_dane, NULL, + host->name, host->address, NULL) == OK; + +if (host->dnssec == DS_YES) + { + if( dane_required + || verify_check_this_host(&ob->hosts_try_dane, NULL, + host->name, host->address, NULL) == OK + ) + if ((rc = tlsa_lookup(host, &tlsa_dnsa, dane_required, &dane)) != OK) + return rc; + } +else if (dane_required) + { + /*XXX a shame we only find this after making tcp & smtp connection */ + /* move the test earlier? */ + log_write(0, LOG_MAIN, "DANE error: previous lookup not DNSSEC"); + return FAIL; + } +#endif + +#ifndef DISABLE_OCSP + { + if ((require_ocsp = verify_check_this_host(&ob->hosts_require_ocsp, + NULL, host->name, host->address, NULL) == OK)) + request_ocsp = TRUE; + else + { +# ifdef EXPERIMENTAL_DANE + if ( dane + && ob->hosts_request_ocsp[0] == '*' + && ob->hosts_request_ocsp[1] == '\0' + ) + { + /* Unchanged from default. Use a safer one under DANE */ + request_ocsp = TRUE; + ob->hosts_request_ocsp = US"${if or { {= {0}{$tls_out_tlsa_usage}} " + " {= {4}{$tls_out_tlsa_usage}} } " + " {*}{}}"; + } + else +# endif + request_ocsp = verify_check_this_host(&ob->hosts_request_ocsp, + NULL, host->name, host->address, NULL) == OK; + } + } #endif rc = tls_init(&client_ctx, host, NULL, diff --cc src/src/transports/smtp.c index 1865adee8,0dfa01958..7b2a7d559 --- a/src/src/transports/smtp.c +++ b/src/src/transports/smtp.c @@@ -3277,17 -3276,11 +3293,17 @@@ for (cutoff_retry = 0; expired & session, so the in-clear transmission after those errors, if permitted, happens inside smtp_deliver().] */ - #ifdef SUPPORT_TLS + #ifdef SUPPORT_TLS - if (rc == DEFER && first_addr->basic_errno == ERRNO_TLSFAILURE && - ob->tls_tempfail_tryclear && - verify_check_this_host(&(ob->hosts_require_tls), NULL, host->name, - host->address, NULL) != OK) + if ( rc == DEFER + && first_addr->basic_errno == ERRNO_TLSFAILURE + && ob->tls_tempfail_tryclear + && verify_check_this_host(&(ob->hosts_require_tls), NULL, host->name, + host->address, NULL) != OK - #ifdef EXPERIMENTAL_DANE ++# ifdef EXPERIMENTAL_DANE + && verify_check_this_host(&(ob->hosts_require_dane), NULL, host->name, + host->address, NULL) != OK - #endif ++# endif + ) { log_write(0, LOG_MAIN, "TLS session failure: delivering unencrypted " "to %s [%s] (not in hosts_require_tls)", host->name, host->address); @@@ -3296,12 -3289,12 +3312,12 @@@ expanded_hosts != NULL, &message_defer, TRUE); if (rc == DEFER && first_addr->basic_errno != ERRNO_AUTHFAIL) write_logs(first_addr, host); - #ifdef EXPERIMENTAL_TPDA + # ifdef EXPERIMENTAL_TPDA if (rc == DEFER) - tpda_deferred(ob, first_addr, host); - #endif + tpda_deferred(first_addr, host); + # endif } - #endif -#endif ++#endif /*SUPPORT_TLS*/ } /* Delivery attempt finished */ diff --cc src/src/verify.c index c2ee47892,8564aacc2..edd9ad17d --- a/src/src/verify.c +++ b/src/src/verify.c @@@ -643,30 -660,27 +660,30 @@@ els /* TLS negotiation failed; give an error. Try in clear on a new connection, if the options permit it for this host. */ if (rc != OK) -- { - if ( rc == DEFER - && ob->tls_tempfail_tryclear - && !smtps - && verify_check_this_host(&(ob->hosts_require_tls), NULL, - host->name, host->address, NULL) != OK - if (rc == DEFER && ob->tls_tempfail_tryclear && !smtps && - verify_check_this_host(&(ob->hosts_require_tls), NULL, host->name, - host->address, NULL) != OK) - { - (void)close(inblock.sock); -#ifdef EXPERIMENTAL_TPDA - (void) tpda_raise_event(addr->transport->tpda_event_action, - US"tcp:close", NULL); ++ { ++ if ( rc == DEFER ++ && ob->tls_tempfail_tryclear ++ && !smtps ++ && verify_check_this_host(&(ob->hosts_require_tls), NULL, ++ host->name, host->address, NULL) != OK +#ifdef EXPERIMENTAL_DANE - && verify_check_this_host(&(ob->hosts_require_dane), NULL, - host->name, host->address, NULL) != OK ++ && verify_check_this_host(&(ob->hosts_require_dane), NULL, ++ host->name, host->address, NULL) != OK #endif - ) - { - (void)close(inblock.sock); - log_write(0, LOG_MAIN, "TLS session failure: delivering unencrypted " - "to %s [%s] (not in hosts_require_tls)", host->name, host->address); - suppress_tls = TRUE; - goto tls_retry_connection; - } - /*save_errno = ERRNO_TLSFAILURE;*/ - /*message = US"failure while setting up TLS session";*/ - send_quit = FALSE; - done= FALSE; - goto TLS_FAILED; - } ++ ) ++ { ++ (void)close(inblock.sock); + log_write(0, LOG_MAIN, "TLS session failure: delivering unencrypted " + "to %s [%s] (not in hosts_require_tls)", host->name, host->address); + suppress_tls = TRUE; + goto tls_retry_connection; + } + /*save_errno = ERRNO_TLSFAILURE;*/ + /*message = US"failure while setting up TLS session";*/ + send_quit = FALSE; + done= FALSE; + goto TLS_FAILED; + } /* TLS session is set up. Copy info for logging. */ addr->cipher = tls_out.cipher;