]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
resolved: when we receive an reply which is OPT-less or RRSIG-less, downgrade what...
authorLennart Poettering <lennart@poettering.net>
Fri, 15 Jan 2016 19:29:56 +0000 (20:29 +0100)
committerLennart Poettering <lennart@poettering.net>
Sun, 17 Jan 2016 19:47:46 +0000 (20:47 +0100)
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.

src/resolve/resolved-dns-server.c

index 6732030d653fc73815c262919bcb3cbf63a4d41d..949c0d66e11a38f762ef4907318dca4776793cc0 100644 (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;
 }