From 43e6779ac2ee8a8a522350eda97311c4f8487ffe Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 17 Jan 2016 21:50:10 +0100 Subject: resolved: when we find a DNAME RR, don't insist in a signed CNAME RR If we have a signed DNAME RR response, there's no need to insist on a signature for a CNAME RR response, after all it is unlikely to be signed, given the implicit synthethis of CNAME through DNAME RRs. --- src/resolve/resolved-dns-transaction.c | 37 +++++++++++++++++++++++++--------- 1 file changed, 28 insertions(+), 9 deletions(-) (limited to 'src/resolve/resolved-dns-transaction.c') diff --git a/src/resolve/resolved-dns-transaction.c b/src/resolve/resolved-dns-transaction.c index 72ef283dde..393171a2ad 100644 --- a/src/resolve/resolved-dns-transaction.c +++ b/src/resolve/resolved-dns-transaction.c @@ -1827,6 +1827,12 @@ int dns_transaction_request_dnssec_keys(DnsTransaction *t) { if (r > 0) continue; + r = dns_answer_has_dname_for_cname(t->answer, rr); + if (r < 0) + return r; + if (r > 0) + continue; + name = DNS_RESOURCE_KEY_NAME(rr->key); r = dns_name_parent(&name); if (r < 0) @@ -2719,17 +2725,30 @@ int dns_transaction_validate_dnssec(DnsTransaction *t) { if (r < 0) return r; if (r > 0) { - /* This is a primary response - * to our question, and it - * failed validation. That's - * fatal. */ - t->answer_dnssec_result = result; - return 0; + + /* Look for a matching DNAME for this CNAME */ + r = dns_answer_has_dname_for_cname(t->answer, rr); + if (r < 0) + return r; + if (r == 0) { + /* Also look among the stuff we already validated */ + r = dns_answer_has_dname_for_cname(validated, rr); + if (r < 0) + return r; + } + + if (r == 0) { + /* This is a primary response to our question, and it failed validation. That's + * fatal. */ + t->answer_dnssec_result = result; + return 0; + } + + /* This is a primary response, but we do have a DNAME RR in the RR that can replay this + * CNAME, hence rely on that, and we can remove the CNAME in favour of it. */ } - /* This is just some auxiliary - * data. Just remove the RRset and - * continue. */ + /* This is just some auxiliary data. Just remove the RRset and continue. */ r = dns_answer_remove_by_key(&t->answer, rr->key); if (r < 0) return r; -- cgit v1.2.3-54-g00ecf