]> git.ipfire.org Git - people/ms/dnsmasq.git/commitdiff
Protect against broken DNSSEC upstreams.
authorSimon Kelley <simon@thekelleys.org.uk>
Fri, 27 Mar 2015 11:44:55 +0000 (11:44 +0000)
committerSimon Kelley <simon@thekelleys.org.uk>
Fri, 27 Mar 2015 11:44:55 +0000 (11:44 +0000)
src/dnssec.c

index db5c768bd7510163f3982a204ce649859f5fe526..14bae7e9bf75f9be68f7760a838f37355ff915e3 100644 (file)
@@ -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;