diff options
author | Lennart Poettering <lennart@poettering.net> | 2016-01-17 21:50:10 +0100 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2016-01-17 21:50:10 +0100 |
commit | 43e6779ac2ee8a8a522350eda97311c4f8487ffe (patch) | |
tree | 3879c77206a76dcaeeb9ae8f7ae3122b8b784838 /src/resolve/resolved-dns-transaction.c | |
parent | cde3d687506d0d92a5efe8a925047b4c828e6f98 (diff) |
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.
Diffstat (limited to 'src/resolve/resolved-dns-transaction.c')
-rw-r--r-- | src/resolve/resolved-dns-transaction.c | 37 |
1 files changed, 28 insertions, 9 deletions
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; |