diff options
author | Lennart Poettering <lennart@poettering.net> | 2016-01-15 20:29:56 +0100 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2016-01-17 20:47:46 +0100 |
commit | b64513580ce627578351b76a502455e7bc62cae4 (patch) | |
tree | 1545212ce96a08644c26866c4444b9d991742a37 /src/resolve | |
parent | de54e62b4bd7856fb897c9a2ee93cc228adb2135 (diff) |
resolved: when we receive an reply which is OPT-less or RRSIG-less, downgrade what we verified
If we receive a reply that lacks the OPT RR, then this is reason to downgrade what was verified before, as it's
apparently no longer true, and the previous OPT RR we saw was only superficially OK.
Similar, if we realize that RRSIGs are not augmented, then also downgrade the feature level that was verified, as
DNSSEC is after all not supported. This check is in particular necessary, as we might notice the fact that RRSIG is not
augmented only very late, when verifying the root domain.
Also, when verifying a successful response, actually take in consideration that it might have been reported already
that RRSIG or OPT are missing in the response.
Diffstat (limited to 'src/resolve')
-rw-r--r-- | src/resolve/resolved-dns-server.c | 29 |
1 files changed, 22 insertions, 7 deletions
diff --git a/src/resolve/resolved-dns-server.c b/src/resolve/resolved-dns-server.c index 6732030d65..949c0d66e1 100644 --- a/src/resolve/resolved-dns-server.c +++ b/src/resolve/resolved-dns-server.c @@ -248,13 +248,18 @@ void dns_server_packet_received(DnsServer *s, int protocol, DnsServerFeatureLeve if (s->possible_feature_level == level) s->n_failed_udp = 0; + /* If the RRSIG data is missing, then we can only validate EDNS0 at max */ + if (s->packet_rrsig_missing && level >= DNS_SERVER_FEATURE_LEVEL_DO) + level = DNS_SERVER_FEATURE_LEVEL_DO - 1; + + /* If the OPT RR got lost, then we can only validate UDP at max */ + if (s->packet_bad_opt && level >= DNS_SERVER_FEATURE_LEVEL_EDNS0) + level = DNS_SERVER_FEATURE_LEVEL_EDNS0 - 1; + + /* Even if we successfully receive a reply to a request announcing support for large packets, + that does not mean we can necessarily receive large packets. */ if (level == DNS_SERVER_FEATURE_LEVEL_LARGE) - /* Even if we successfully receive a reply to a request announcing support for large packets, - that does not mean we can necessarily receive large packets. */ - dns_server_verified(s, DNS_SERVER_FEATURE_LEVEL_LARGE - 1); - else - /* A successful UDP reply, verifies UDP, ENDS0 and DO levels */ - dns_server_verified(s, level); + level = DNS_SERVER_FEATURE_LEVEL_LARGE - 1; } else if (protocol == IPPROTO_TCP) { @@ -262,9 +267,11 @@ void dns_server_packet_received(DnsServer *s, int protocol, DnsServerFeatureLeve s->n_failed_tcp = 0; /* Successful TCP connections are only useful to verify the TCP feature level. */ - dns_server_verified(s, DNS_SERVER_FEATURE_LEVEL_TCP); + level = DNS_SERVER_FEATURE_LEVEL_TCP; } + dns_server_verified(s, level); + /* Remember the size of the largest UDP packet we received from a server, we know that we can always announce support for packets with at least this size. */ @@ -322,6 +329,10 @@ void dns_server_packet_rrsig_missing(DnsServer *s, DnsServerFeatureLevel level) if (level < DNS_SERVER_FEATURE_LEVEL_DO) return; + /* If the RRSIG RRs are missing, we have to downgrade what we previously verified */ + if (s->verified_feature_level >= DNS_SERVER_FEATURE_LEVEL_DO) + s->verified_feature_level = DNS_SERVER_FEATURE_LEVEL_DO-1; + s->packet_rrsig_missing = true; } @@ -331,6 +342,10 @@ void dns_server_packet_bad_opt(DnsServer *s, DnsServerFeatureLevel level) { if (level < DNS_SERVER_FEATURE_LEVEL_EDNS0) return; + /* If the OPT RR got lost, we have to downgrade what we previously verified */ + if (s->verified_feature_level >= DNS_SERVER_FEATURE_LEVEL_EDNS0) + s->verified_feature_level = DNS_SERVER_FEATURE_LEVEL_EDNS0-1; + s->packet_bad_opt = true; } |