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.
This commit is contained in:
Lennart Poettering 2016-01-15 20:29:56 +01:00
parent de54e62b4b
commit b64513580c
1 changed files with 22 additions and 7 deletions

View File

@ -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;
}