Gitweb:
http://git.exim.org/exim.git/commitdiff/cf2b569e3a2f8956b7045191e96bc5edfd366c78
Commit: cf2b569e3a2f8956b7045191e96bc5edfd366c78
Parent: 2eb77f91023a3279166810a7ce9f15508d244e65
Author: Jeremy Harris <jgh146exb@???>
AuthorDate: Sun Aug 10 11:49:49 2014 +0100
Committer: Jeremy Harris <jgh146exb@???>
CommitDate: Sun Aug 10 11:49:49 2014 +0100
On a host lookup name->MX->A->ip sequence, require both stages to
be dnssec before declaring the lookup was secure.
---
src/src/host.c | 51 ++++++++++++++++++++++++++++++++----------------
src/src/tls-openssl.c | 1 +
test/confs/5850 | 8 ++++--
3 files changed, 40 insertions(+), 20 deletions(-)
diff --git a/src/src/host.c b/src/src/host.c
index 00524f4..2eef0ba 100644
--- a/src/src/host.c
+++ b/src/src/host.c
@@ -2207,7 +2207,7 @@ Returns: HOST_FIND_FAILED couldn't find A record
static int
set_address_from_dns(host_item *host, host_item **lastptr,
uschar *ignore_target_hosts, BOOL allow_ip, uschar **fully_qualified_name,
- BOOL dnssec_requested, BOOL dnssec_require)
+ BOOL dnssec_request, BOOL dnssec_require)
{
dns_record *rr;
host_item *thishostlast = NULL; /* Indicates not yet filled in anything */
@@ -2268,7 +2268,7 @@ for (; i >= 0; i--)
dns_scan dnss;
int rc = dns_lookup(&dnsa, host->name, type, fully_qualified_name);
- lookup_dnssec_authenticated = !dnssec_requested ? NULL
+ lookup_dnssec_authenticated = !dnssec_request ? NULL
: dns_is_secure(&dnsa) ? US"yes" : US"no";
/* We want to return HOST_FIND_AGAIN if one of the A, A6, or AAAA lookups
@@ -2292,11 +2292,31 @@ for (; i >= 0; i--)
if (rc != DNS_NOMATCH && rc != DNS_NODATA) v6_find_again = TRUE;
continue;
}
- if (dnssec_require && !dns_is_secure(&dnsa))
+
+ if (dnssec_request)
{
- log_write(L_host_lookup_failed, LOG_MAIN, "dnssec fail on %s for %.256s",
+ if (dns_is_secure(&dnsa))
+ {
+ DEBUG(D_host_lookup) debug_printf("%s A DNSSEC\n", host->name);
+ if (host->dnssec == DS_UNK) /* set in host_find_bydns() */
+ host->dnssec = DS_YES;
+ }
+ else
+ {
+ if (dnssec_require)
+ {
+ log_write(L_host_lookup_failed, LOG_MAIN,
+ "dnssec fail on %s for %.256s",
i>1 ? "A6" : i>0 ? "AAAA" : "A", host->name);
- continue;
+ continue;
+ }
+ if (host->dnssec == DS_YES) /* set in host_find_bydns() */
+ {
+ DEBUG(D_host_lookup) debug_printf("%s A cancel DNSSEC\n", host->name);
+ host->dnssec = DS_NO;
+ lookup_dnssec_authenticated = US"no";
+ }
+ }
}
/* Lookup succeeded: fill in the given host item with the first non-ignored
@@ -2562,9 +2582,14 @@ if (rc != DNS_SUCCEED && (whichrrs & HOST_FIND_BY_MX) != 0)
if (dnssec_request)
{
if (dns_is_secure(&dnsa))
- { dnssec = DS_YES; lookup_dnssec_authenticated = US"yes"; }
+ {
+ DEBUG(D_host_lookup) debug_printf("%s MX DNSSEC\n", host->name);
+ dnssec = DS_YES; lookup_dnssec_authenticated = US"yes";
+ }
else
- { dnssec = DS_NO; lookup_dnssec_authenticated = US"no"; }
+ {
+ dnssec = DS_NO; lookup_dnssec_authenticated = US"no";
+ }
}
switch (rc)
@@ -2578,7 +2603,7 @@ if (rc != DNS_SUCCEED && (whichrrs & HOST_FIND_BY_MX) != 0)
log_write(L_host_lookup_failed, LOG_MAIN,
"dnssec fail on MX for %.256s", host->name);
rc = DNS_FAIL;
- /*FALLTRHOUGH*/
+ /*FALLTHROUGH*/
case DNS_FAIL:
case DNS_AGAIN:
@@ -2609,19 +2634,11 @@ if (rc != DNS_SUCCEED)
last = host; /* End of local chainlet */
host->mx = MX_NONE;
host->port = PORT_NONE;
- dnssec = DS_UNK;
+ host->dnssec = DS_UNK;
lookup_dnssec_authenticated = NULL;
rc = set_address_from_dns(host, &last, ignore_target_hosts, FALSE,
fully_qualified_name, dnssec_request, dnssec_require);
- if (dnssec_request)
- {
- if (dns_is_secure(&dnsa))
- { dnssec = DS_YES; lookup_dnssec_authenticated = US"yes"; }
- else
- { dnssec = DS_NO; lookup_dnssec_authenticated = US"no"; }
- }
-
/* If one or more address records have been found, check that none of them
are local. Since we know the host items all have their IP addresses
inserted, host_scan_for_local_hosts() can only return HOST_FOUND or
diff --git a/src/src/tls-openssl.c b/src/src/tls-openssl.c
index 0bd23ac..eb74605 100644
--- a/src/src/tls-openssl.c
+++ b/src/src/tls-openssl.c
@@ -1664,6 +1664,7 @@ if (host->dnssec == DS_YES)
else if (dane_required)
{
/* Hmm - what lookup, precisely? */
+ /*XXX a shame we only find this after making tcp & smtp connection */
log_write(0, LOG_MAIN, "DANE error: previous lookup not DNSSEC");
return FAIL;
}
diff --git a/test/confs/5850 b/test/confs/5850
index 53cb78a..0b132e2 100644
--- a/test/confs/5850
+++ b/test/confs/5850
@@ -37,9 +37,11 @@ tls_privatekey = ${if eq {SERVER}{server}{DIR/aux-fixed/cert1}fail}
begin routers
client:
- driver = accept
+ driver = dnslookup
condition = ${if eq {SERVER}{server}{no}{yes}}
- retry_use_local_part
+# retry_use_local_part
+ dnssec_request_domains = *
+ self = send
transport = send_to_server
server:
@@ -54,7 +56,7 @@ begin transports
send_to_server:
driver = smtp
allow_localhost
- hosts = 127.0.0.1
+# hosts = 127.0.0.1
port = PORT_D
# tls_certificate = DIR/aux-fixed/cert2
# tls_privatekey = DIR/aux-fixed/cert2