From fd009cd80e511587c6afae59da8aff14e5e18fa3 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 18 Dec 2015 19:12:48 +0100 Subject: resolved: check SOA authentication state when negative caching We should never use the TTL of an unauthenticated SOA to cache an authenticated RR. --- src/resolve/resolved-dns-answer.c | 7 +++++-- src/resolve/resolved-dns-answer.h | 2 +- src/resolve/resolved-dns-cache.c | 7 ++++++- 3 files changed, 12 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/resolve/resolved-dns-answer.c b/src/resolve/resolved-dns-answer.c index cb0be7d18c..fa0e026ea7 100644 --- a/src/resolve/resolved-dns-answer.c +++ b/src/resolve/resolved-dns-answer.c @@ -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; } } diff --git a/src/resolve/resolved-dns-answer.h b/src/resolve/resolved-dns-answer.h index 569f283d03..c946f09f8a 100644 --- a/src/resolve/resolved-dns-answer.h +++ b/src/resolve/resolved-dns-answer.h @@ -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); diff --git a/src/resolve/resolved-dns-cache.c b/src/resolve/resolved-dns-cache.c index 31325ecc88..df397e1ddd 100644 --- a/src/resolve/resolved-dns-cache.c +++ b/src/resolve/resolved-dns-cache.c @@ -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; -- cgit v1.2.3-54-g00ecf