]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
resolved: check SOA authentication state when negative caching
authorLennart Poettering <lennart@poettering.net>
Fri, 18 Dec 2015 18:12:48 +0000 (19:12 +0100)
committerLennart Poettering <lennart@poettering.net>
Fri, 18 Dec 2015 18:12:48 +0000 (19:12 +0100)
We should never use the TTL of an unauthenticated SOA to cache an
authenticated RR.

src/resolve/resolved-dns-answer.c
src/resolve/resolved-dns-answer.h
src/resolve/resolved-dns-cache.c

index cb0be7d18c6223ab3d9559f63dea8a40d7237ddb..fa0e026ea7445670cc5944742735537f44523e38 100644 (file)
@@ -302,8 +302,9 @@ int dns_answer_contains_nsec_or_nsec3(DnsAnswer *a) {
         return false;
 }
 
-int dns_answer_find_soa(DnsAnswer *a, const DnsResourceKey *key, DnsResourceRecord **ret) {
+int dns_answer_find_soa(DnsAnswer *a, const DnsResourceKey *key, DnsResourceRecord **ret, DnsAnswerFlags *flags) {
         DnsResourceRecord *rr;
+        DnsAnswerFlags rr_flags;
         int r;
 
         assert(key);
@@ -312,13 +313,15 @@ int dns_answer_find_soa(DnsAnswer *a, const DnsResourceKey *key, DnsResourceReco
         if (key->type == DNS_TYPE_SOA)
                 return 0;
 
-        DNS_ANSWER_FOREACH(rr, a) {
+        DNS_ANSWER_FOREACH_FLAGS(rr, rr_flags, a) {
                 r = dns_resource_key_match_soa(key, rr->key);
                 if (r < 0)
                         return r;
                 if (r > 0) {
                         if (ret)
                                 *ret = rr;
+                        if (flags)
+                                *flags = rr_flags;
                         return 1;
                 }
         }
index 569f283d034358f1de3994d2f71d480bf423e613..c946f09f8a2e8ab710341109effd7ea1847f156b 100644 (file)
@@ -64,7 +64,7 @@ int dns_answer_contains_rr(DnsAnswer *a, DnsResourceRecord *rr, DnsAnswerFlags *
 int dns_answer_contains_key(DnsAnswer *a, const DnsResourceKey *key, DnsAnswerFlags *combined_flags);
 int dns_answer_contains_nsec_or_nsec3(DnsAnswer *a);
 
-int dns_answer_find_soa(DnsAnswer *a, const DnsResourceKey *key, DnsResourceRecord **ret);
+int dns_answer_find_soa(DnsAnswer *a, const DnsResourceKey *key, DnsResourceRecord **ret, DnsAnswerFlags *flags);
 int dns_answer_find_cname_or_dname(DnsAnswer *a, const DnsResourceKey *key, DnsResourceRecord **ret, DnsAnswerFlags *flags);
 
 int dns_answer_merge(DnsAnswer *a, DnsAnswer *b, DnsAnswer **ret);
index 31325ecc88e6f7e5f9feb113188eecdc95d37fe0..df397e1ddd8162ab812d566cc262bae3a5be0e26 100644 (file)
@@ -529,12 +529,17 @@ int dns_cache_put(
          * matching SOA record in the packet is used to to enable
          * negative caching. */
 
-        r = dns_answer_find_soa(answer, key, &soa);
+        r = dns_answer_find_soa(answer, key, &soa, &flags);
         if (r < 0)
                 goto fail;
         if (r == 0)
                 return 0;
 
+        /* Refuse using the SOA data if it is unsigned, but the key is
+         * signed */
+        if (authenticated && (flags & DNS_ANSWER_AUTHENTICATED) == 0)
+                return 0;
+
         r = dns_cache_put_negative(c, key, rcode, authenticated, timestamp, MIN(soa->soa.minimum, soa->ttl), owner_family, owner_address);
         if (r < 0)
                 goto fail;