From 2d5fdd539c5abd1d180dfb476ef87ae3332285ed Mon Sep 17 00:00:00 2001 From: Jeremy Harris Date: Thu, 12 May 2016 21:57:34 +0100 Subject: [PATCH] DANE: for hosts_try_dane (but not _require), on dnssec but no TLSA returned, fallback to plain TLS --- src/src/transports/smtp.c | 41 ++++++++++++++++++++++++--------------- test/log/5840 | 9 +++++++-- 2 files changed, 32 insertions(+), 18 deletions(-) diff --git a/src/src/transports/smtp.c b/src/src/transports/smtp.c index 848a4ce21..234467437 100644 --- a/src/src/transports/smtp.c +++ b/src/src/transports/smtp.c @@ -1215,6 +1215,13 @@ return FALSE; #ifdef EXPERIMENTAL_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) { @@ -1227,13 +1234,6 @@ const uschar * fullname = buffer; switch (dns_lookup(dnsa, buffer, T_TLSA, &fullname)) { - case DNS_AGAIN: - return DEFER; /* just defer this TLS'd conn */ - - default: - case DNS_FAIL: - return dane_required ? FAIL : DEFER; - case DNS_SUCCEED: if (!dns_is_secure(dnsa)) { @@ -1241,6 +1241,16 @@ switch (dns_lookup(dnsa, buffer, T_TLSA, &fullname)) return DEFER; } return OK; + + case DNS_AGAIN: + return DEFER; /* just defer this TLS'd conn */ + + case DNS_NOMATCH: + return dane_required ? FAIL : FAIL_FORCED; + + default: + case DNS_FAIL: + return dane_required ? FAIL : DEFER; } } #endif @@ -1542,17 +1552,16 @@ if (continue_hostname == NULL) if( dane_required || verify_check_given_host(&ob->hosts_try_dane, host) == OK ) - { - if ((rc = tlsa_lookup(host, &tlsa_dnsa, dane_required)) != OK) + switch (rc = tlsa_lookup(host, &tlsa_dnsa, dane_required)) { - set_errno_nohost(addrlist, ERRNO_DNSDEFER, - string_sprintf("DANE error: tlsa lookup %s", - rc == DEFER ? "DEFER" : "FAIL"), - rc, FALSE); - return rc; + case OK: dane = TRUE; break; + case FAIL_FORCED: break; + default: 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) { diff --git a/test/log/5840 b/test/log/5840 index 4e45703ca..65666a14a 100644 --- a/test/log/5840 +++ b/test/log/5840 @@ -33,8 +33,10 @@ 1999-03-02 09:44:33 10HmbI-0005vi-00 ** CALLER@dane.no.1.test.ex R=client T=send_to_server: DANE error: tlsa lookup FAIL 1999-03-02 09:44:33 10HmbI-0005vi-00 CALLER@dane.no.1.test.ex: error ignored 1999-03-02 09:44:33 10HmbI-0005vi-00 Completed -1999-03-02 09:44:33 10HmbJ-0005vi-00 H=dane.no.2.test.ex [127.0.0.1]: DANE error: tlsa lookup DEFER -1999-03-02 09:44:33 10HmbJ-0005vi-00 == CALLER@dane.no.2.test.ex R=client T=send_to_server defer (-36): DANE error: tlsa lookup DEFER +1999-03-02 09:44:33 10HmbJ-0005vi-00 [127.0.0.1] SSL verify error: depth=0 error=self signed certificate cert=/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock +1999-03-02 09:44:33 10HmbJ-0005vi-00 [127.0.0.1] SSL verify error: certificate name mismatch: "/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock" +1999-03-02 09:44:33 10HmbJ-0005vi-00 => CALLER@dane.no.2.test.ex R=client T=send_to_server H=dane.no.2.test.ex [127.0.0.1] X=TLSv1:AES256-SHA:256 CV=no DN="/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock" C="250 OK id=10HmbK-0005vi-00" +1999-03-02 09:44:33 10HmbJ-0005vi-00 Completed 1999-03-02 09:44:33 End queue run: pid=pppp -qf ******** SERVER ******** @@ -58,3 +60,6 @@ 1999-03-02 09:44:33 10HmbG-0005vi-00 => :blackhole: R=server 1999-03-02 09:44:33 10HmbG-0005vi-00 Completed 1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225 +1999-03-02 09:44:33 10HmbK-0005vi-00 <= <> H=localhost (myhost.test.ex) [127.0.0.1] P=esmtps X=TLSv1:AES256-SHA:256 CV=no S=sss id=E10HmbJ-0005vi-00@myhost.test.ex for CALLER@dane.no.2.test.ex +1999-03-02 09:44:33 10HmbK-0005vi-00 => :blackhole: R=server +1999-03-02 09:44:33 10HmbK-0005vi-00 Completed -- 2.25.1