summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Kelley <simon@thekelleys.org.uk>2015-03-27 11:44:55 +0000
committerSimon Kelley <simon@thekelleys.org.uk>2015-03-27 11:44:55 +0000
commit0b8a5a30a77331974ba24a04e43e720585dfbc61 (patch)
treef0d2005a86c5fdd87285377070066e544107a391
parent150162bc37170a6edae9d488435e836b1e4e3a4e (diff)
downloaddnsmasq-0b8a5a30a77331974ba24a04e43e720585dfbc61.tar.gz
Protect against broken DNSSEC upstreams.
-rw-r--r--src/dnssec.c7
1 files changed, 5 insertions, 2 deletions
diff --git a/src/dnssec.c b/src/dnssec.c
index db5c768..14bae7e 100644
--- a/src/dnssec.c
+++ b/src/dnssec.c
@@ -1177,7 +1177,7 @@ int dnssec_validate_by_ds(time_t now, struct dns_header *header, size_t plen, ch
STAT_NO_DS It's proved there's no DS here.
STAT_NO_NS It's proved there's no DS _or_ NS here.
STAT_BOGUS no DS in reply or not signed, fails validation, bad packet.
- STAT_NEED_DNSKEY DNSKEY records to validate a DS not found, name in keyname
+ STAT_NEED_KEY DNSKEY records to validate a DS not found, name in keyname
*/
int dnssec_validate_ds(time_t now, struct dns_header *header, size_t plen, char *name, char *keyname, int class)
@@ -1208,7 +1208,10 @@ int dnssec_validate_ds(time_t now, struct dns_header *header, size_t plen, char
if (!(p = skip_section(p, ntohs(header->ancount), header, plen)))
val = STAT_BOGUS;
- if (val == STAT_BOGUS)
+ /* If the key needed to validate the DS is on the same domain as the DS, we'll
+ loop getting nowhere. Stop that now. This can happen of the DS answer comes
+ from the DS's zone, and not the parent zone. */
+ if (val == STAT_BOGUS || (val == STAT_NEED_KEY && hostname_isequal(name, keyname)))
{
log_query(F_NOEXTRA | F_UPSTREAM, name, NULL, "BOGUS DS");
return STAT_BOGUS;