From 979c462ed43bd4f53f61a0031ec22967dea83902 Mon Sep 17 00:00:00 2001 From: Jeremy Harris Date: Mon, 21 Oct 2019 17:17:37 +0100 Subject: [PATCH] Be careful about DNS response AD/AA bits for error returns --- src/src/dns.c | 18 ++++++++++------- src/src/host.c | 2 +- test/dnszones-src/db.kitterman.org | 30 +++++++++++++++++++++++++++++ test/scripts/4540-DKIM-Ed25519/4540 | 3 +-- test/stderr/0183 | 15 +++------------ test/stderr/0278 | 2 +- test/stderr/0361 | 2 +- test/stderr/0426 | 2 +- test/stderr/0463 | 4 ++-- test/stderr/0545 | 4 ++-- 10 files changed, 53 insertions(+), 29 deletions(-) create mode 100644 test/dnszones-src/db.kitterman.org diff --git a/src/src/dns.c b/src/src/dns.c index 4750f1b52..8d9ec4708 100644 --- a/src/src/dns.c +++ b/src/src/dns.c @@ -498,13 +498,13 @@ const HEADER * h = (const HEADER *) dnsa->answer; const uschar * auth_name; const uschar * trusted; +if (dnsa->answerlen < 0) return FALSE; if (h->ad) return TRUE; -/* If the resolver we ask is authoritative for the domain in question, it -* may not set the AD but the AA bit. If we explicitly trust -* the resolver for that domain (via a domainlist in dns_trust_aa), -* we return TRUE to indicate a secure answer. -*/ +/* If the resolver we ask is authoritative for the domain in question, it may +not set the AD but the AA bit. If we explicitly trust the resolver for that +domain (via a domainlist in dns_trust_aa), we return TRUE to indicate a secure +answer. */ if ( !h->aa || !dns_trust_aa @@ -540,12 +540,12 @@ h->aa = h->ad = 0; ************************************************/ BOOL -dns_is_aa(const dns_answer *dnsa) +dns_is_aa(const dns_answer * dnsa) { #ifdef DISABLE_DNSSEC return FALSE; #else -return ((const HEADER*)dnsa->answer)->aa; +return dnsa->answerlen >= 0 && ((const HEADER *)dnsa->answer)->aa; #endif } @@ -788,7 +788,10 @@ caching for successful lookups. */ if ((rc = dns_fail_cache_hit(name, type)) > 0) + { + dnsa->answerlen = -1; return rc; + } #ifdef SUPPORT_I18N /* Convert all names to a-label form before doing lookup */ @@ -857,6 +860,7 @@ if ((type == T_A || type == T_AAAA) && string_is_ip_address(name, NULL) != 0) (res_search), we call fakens_search(), which recognizes certain special domains, and interfaces to a fake nameserver for certain special zones. */ +h_errno = 0; dnsa->answerlen = f.running_in_test_harness ? fakens_search(name, type, dnsa->answer, sizeof(dnsa->answer)) : res_search(CCS name, C_IN, type, dnsa->answer, sizeof(dnsa->answer)); diff --git a/src/src/host.c b/src/src/host.c index 4081729ab..3c2b8b3c8 100644 --- a/src/src/host.c +++ b/src/src/host.c @@ -2648,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 diff --git a/test/dnszones-src/db.kitterman.org b/test/dnszones-src/db.kitterman.org new file mode 100644 index 000000000..bc4e19c7f --- /dev/null +++ b/test/dnszones-src/db.kitterman.org @@ -0,0 +1,30 @@ +; This is a testing zone file for use when testing DNS handling in Exim. This +; is a fake zone of no real use. The zone name is +; test.ex. This file is passed through the substitution mechanism before being +; used by the fakens auxiliary program. This inserts the actual IP addresses +; of the local host into the zone. + +; NOTE (1): apart from ::1, IPv6 addresses must always have 8 components. Do +; not abbreviate them by using the :: feature. Leading zeros in components may, +; however, be omitted. + +; NOTE (2): the fakens program is very simple and assumes that the buffer into +; which is puts the response is always going to be big enough. In other words, +; the expectation is for just a few RRs for each query. + +; NOTE (3): the top-level networks for testing addresses are parameterized by +; the use of V4NET and V6NET. These networks should be such that no real +; host ever uses them. +; +; Several prefixes may be used, see the source in src/fakens.c for a complete list +; and description. + +kitterman.org. NS exim.kitterman.org. +kitterman.org. SOA exim.kitterman.org. hostmaster.exim.kitterman.org 1430683638 1200 120 604800 3000 + +; Record copied 2019/10/22 + +ed25519._domainkey TXT "v=DKIM1; k=ed25519; p=yi50DjK5O9pqbFpNHklsv9lqaS0ArSYu02qp1S0DW1Y=" + + +; End diff --git a/test/scripts/4540-DKIM-Ed25519/4540 b/test/scripts/4540-DKIM-Ed25519/4540 index 504676e7c..22558dfa7 100644 --- a/test/scripts/4540-DKIM-Ed25519/4540 +++ b/test/scripts/4540-DKIM-Ed25519/4540 @@ -79,8 +79,7 @@ QUIT # # This should pass, an independently-generated sample from Scott Kitterman. -# I don't want to retain this longterm as it hits an external DNS record, -# not under the testsuite. +# We use a copied version of his DNS record. client 127.0.0.1 PORT_D ??? 220 HELO xxx diff --git a/test/stderr/0183 b/test/stderr/0183 index 3ed592301..8b3450b78 100644 --- a/test/stderr/0183 +++ b/test/stderr/0183 @@ -36,7 +36,6 @@ DNS lookup of test.again.dns (MX) gave TRY_AGAIN test.again.dns in dns_again_means_nonexist? no (option unset) returning DNS_AGAIN writing neg-cache entry for test.again.dns-MX-xxxx, ttl -1 -test.again.dns MX DNSSEC lookuphost router: defer for userx@test.again.dns message: host lookup did not complete >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -64,7 +63,6 @@ lookuphost router called for abcd@test.again.dns domain = test.again.dns test.again.dns in "*"? yes (matched "*") DNS lookup of test.again.dns-MX: using cached value DNS_AGAIN -test.again.dns MX DNSSEC lookuphost router: defer for abcd@test.again.dns message: host lookup did not complete >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -95,7 +93,7 @@ DNS lookup of ten-1.test.ex (MX) using fakens DNS lookup of ten-1.test.ex (MX) gave NO_DATA returning DNS_NODATA writing neg-cache entry for ten-1.test.ex-MX-xxxx, ttl 3000 -ten-1.test.ex MX DNSSEC +ten-1.test.ex (MX resp) DNSSEC DNS lookup of ten-1.test.ex (A) using fakens DNS lookup of ten-1.test.ex (A) succeeded fully qualified name = ten-1.test.ex @@ -195,7 +193,6 @@ lookuphost router called for xyz@ten-1.test.ex domain = ten-1.test.ex ten-1.test.ex in "*"? yes (matched "*") DNS lookup of ten-1.test.ex-MX: using cached value DNS_NODATA -ten-1.test.ex MX DNSSEC DNS lookup of ten-1.test.ex (A) using fakens DNS lookup of ten-1.test.ex (A) succeeded fully qualified name = ten-1.test.ex @@ -247,7 +244,6 @@ DNS lookup of test.fail.dns (MX) using fakens DNS lookup of test.fail.dns (MX) gave NO_RECOVERY returning DNS_FAIL writing neg-cache entry for test.fail.dns-MX-xxxx, ttl -1 -test.fail.dns MX DNSSEC lookuphost router: defer for userx@test.fail.dns message: host lookup did not complete >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -275,7 +271,6 @@ lookuphost router called for abcd@test.fail.dns domain = test.fail.dns test.fail.dns in "*"? yes (matched "*") DNS lookup of test.fail.dns-MX: using cached value DNS_FAIL -test.fail.dns MX DNSSEC lookuphost router: defer for abcd@test.fail.dns message: host lookup did not complete >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -306,7 +301,7 @@ DNS lookup of ten-1.test.ex (MX) using fakens DNS lookup of ten-1.test.ex (MX) gave NO_DATA returning DNS_NODATA writing neg-cache entry for ten-1.test.ex-MX-xxxx, ttl 3000 -ten-1.test.ex MX DNSSEC +ten-1.test.ex (MX resp) DNSSEC DNS lookup of ten-1.test.ex (A) using fakens DNS lookup of ten-1.test.ex (A) succeeded fully qualified name = ten-1.test.ex @@ -405,7 +400,6 @@ lookuphost router called for xyz@ten-1.test.ex domain = ten-1.test.ex ten-1.test.ex in "*"? yes (matched "*") DNS lookup of ten-1.test.ex-MX: using cached value DNS_NODATA -ten-1.test.ex MX DNSSEC DNS lookup of ten-1.test.ex (A) using fakens DNS lookup of ten-1.test.ex (A) succeeded fully qualified name = ten-1.test.ex @@ -485,7 +479,6 @@ lookuphost router called for abcd@nonexist.test.ex domain = nonexist.test.ex nonexist.test.ex in "*"? yes (matched "*") DNS lookup of nonexist.test.ex-MX: using cached value DNS_NOMATCH -nonexist.test.ex MX DNSSEC lookuphost router declined for abcd@nonexist.test.ex "more" is false: skipping remaining routers no more routers @@ -517,7 +510,7 @@ DNS lookup of ten-1.test.ex (MX) using fakens DNS lookup of ten-1.test.ex (MX) gave NO_DATA returning DNS_NODATA writing neg-cache entry for ten-1.test.ex-MX-xxxx, ttl 3000 -ten-1.test.ex MX DNSSEC +ten-1.test.ex (MX resp) DNSSEC DNS lookup of ten-1.test.ex (A) using fakens DNS lookup of ten-1.test.ex (A) succeeded fully qualified name = ten-1.test.ex @@ -616,7 +609,6 @@ lookuphost router called for xyz@ten-1.test.ex domain = ten-1.test.ex ten-1.test.ex in "*"? yes (matched "*") DNS lookup of ten-1.test.ex-MX: using cached value DNS_NODATA -ten-1.test.ex MX DNSSEC DNS lookup of ten-1.test.ex (A) using fakens DNS lookup of ten-1.test.ex (A) succeeded fully qualified name = ten-1.test.ex @@ -686,7 +678,6 @@ DNS lookup of test.fail.dns (MX) using fakens DNS lookup of test.fail.dns (MX) gave NO_RECOVERY returning DNS_FAIL writing neg-cache entry for test.fail.dns-MX-xxxx, ttl -1 -test.fail.dns MX DNSSEC test.fail.dns in "test.fail.dns"? yes (matched "test.fail.dns") DNS_FAIL treated as DNS_NODATA (domain in mx_fail_domains) DNS lookup of test.fail.dns (A) using fakens diff --git a/test/stderr/0278 b/test/stderr/0278 index 91223f29f..d5b4172fa 100644 --- a/test/stderr/0278 +++ b/test/stderr/0278 @@ -293,7 +293,7 @@ DNS lookup of test.ex (MX) using fakens DNS lookup of test.ex (MX) gave NO_DATA returning DNS_NODATA writing neg-cache entry for test.ex-MX-xxxx, ttl 3000 -test.ex MX DNSSEC +test.ex (MX resp) DNSSEC DNS lookup of test.ex (A) using fakens DNS lookup of test.ex (A) gave NO_DATA returning DNS_NODATA diff --git a/test/stderr/0361 b/test/stderr/0361 index 015140588..0e5ef679a 100644 --- a/test/stderr/0361 +++ b/test/stderr/0361 @@ -107,7 +107,7 @@ DNS lookup of recurse.test.ex.test.ex (MX) using fakens DNS lookup of recurse.test.ex.test.ex (MX) gave NO_DATA returning DNS_NODATA writing neg-cache entry for recurse.test.ex.test.ex-MX-xxxx, ttl 3000 -recurse.test.ex.test.ex MX DNSSEC +recurse.test.ex.test.ex (MX resp) DNSSEC DNS lookup of recurse.test.ex.test.ex (A) using fakens DNS lookup of recurse.test.ex.test.ex (A) succeeded fully qualified name = recurse.test.ex.test.ex diff --git a/test/stderr/0426 b/test/stderr/0426 index 5d0f5b605..4e49b7114 100644 --- a/test/stderr/0426 +++ b/test/stderr/0426 @@ -26,7 +26,7 @@ local_part=x domain=uppercase.test.ex calling r1 router r1 router called for x@uppercase.test.ex domain = uppercase.test.ex -uppercase.test.ex MX DNSSEC +uppercase.test.ex (MX resp) DNSSEC local host found for non-MX address fully qualified name = UpperCase.test.ex uppercase.test.ex 127.0.0.1 mx=-1 sort=xx diff --git a/test/stderr/0463 b/test/stderr/0463 index 8d50c41c6..d64eba5e9 100644 --- a/test/stderr/0463 +++ b/test/stderr/0463 @@ -30,7 +30,7 @@ DNS lookup of ten-1 (MX) using fakens DNS lookup of ten-1 (MX) gave NO_DATA returning DNS_NODATA writing neg-cache entry for ten-1-MX-xxxx, ttl 3000 -ten-1 MX DNSSEC +ten-1 (MX resp) DNSSEC DNS lookup of ten-1 (A) using fakens DNS lookup of ten-1 (A) succeeded fully qualified name = ten-1.test.ex @@ -59,7 +59,7 @@ DNS lookup of ten-1.test.ex (MX) using fakens DNS lookup of ten-1.test.ex (MX) gave NO_DATA returning DNS_NODATA writing neg-cache entry for ten-1.test.ex-MX-xxxx, ttl 3000 -ten-1.test.ex MX DNSSEC +ten-1.test.ex (MX resp) DNSSEC DNS lookup of ten-1.test.ex (A) using fakens DNS lookup of ten-1.test.ex (A) succeeded fully qualified name = ten-1.test.ex diff --git a/test/stderr/0545 b/test/stderr/0545 index 14569c6c3..93cdfc62d 100644 --- a/test/stderr/0545 +++ b/test/stderr/0545 @@ -26,7 +26,7 @@ DNS lookup of eximtesthost.test.ex (MX) using fakens DNS lookup of eximtesthost.test.ex (MX) gave NO_DATA returning DNS_NODATA writing neg-cache entry for eximtesthost.test.ex-MX-xxxx, ttl 3000 -alias-eximtesthost MX DNSSEC +alias-eximtesthost (MX resp) DNSSEC DNS lookup of alias-eximtesthost (A) using fakens DNS lookup of alias-eximtesthost (A) succeeded CNAME found: change to eximtesthost.test.ex @@ -100,7 +100,7 @@ DNS lookup of eximtesthost.test.ex (MX) using fakens DNS lookup of eximtesthost.test.ex (MX) gave NO_DATA returning DNS_NODATA writing neg-cache entry for eximtesthost.test.ex-MX-xxxx, ttl 3000 -alias-eximtesthost.test.ex MX DNSSEC +alias-eximtesthost.test.ex (MX resp) DNSSEC DNS lookup of alias-eximtesthost.test.ex (A) using fakens DNS lookup of alias-eximtesthost.test.ex (A) succeeded CNAME found: change to eximtesthost.test.ex -- 2.25.1