]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
Scrub DNSKEY, DLV and DS much more stringently.
authorWouter Wijngaards <wouter@nlnetlabs.nl>
Wed, 17 Feb 2010 16:50:04 +0000 (16:50 +0000)
committerWouter Wijngaards <wouter@nlnetlabs.nl>
Wed, 17 Feb 2010 16:50:04 +0000 (16:50 +0000)
git-svn-id: file:///svn/unbound/trunk@1985 be551aaa-1e26-0410-a405-d3ace91eadb9

doc/Changelog
iterator/iter_utils.c
iterator/iter_utils.h
iterator/iterator.c
services/cache/dns.c
util/iana_ports.inc

index 0d7e1bfd0d281550b3a685f60f8425334e60becb..5e6632055261e396374a70fcc6fa3f83346a9cd1 100644 (file)
@@ -1,3 +1,8 @@
+17 February 2010: Wouter
+       - Disregard DNSKEY from authority section for chain of trust.
+         DS records that are irrelevant to a referral scrubbed.  Anti-poison.
+       - iana portlist updated.
+
 16 February 2010: Wouter
        - Check for 'no space left on device' (or other errors) when 
          writing updated autotrust anchors and print errno to log.
index b5364b615cd893481d8b8f05abe952d59bbe42cb..2416f3abbb38040ca306f615e9ec352f9a6e3485 100644 (file)
@@ -755,3 +755,30 @@ iter_get_next_root(struct iter_hints* hints, struct iter_forwards* fwd,
        else    *c = c2;
        return 1;
 }
+
+void
+iter_scrub_ds(struct ub_packed_rrset_key* ns, struct dns_msg* msg)
+{
+       /* Only the DS record for the delegation itself is expected.
+        * We allow DS for everything between the bailiwick and the 
+        * zonecut, thus DS records must be at or above the zonecut.
+        * The answer section is already scrubbed. */
+       size_t i = msg->rep->an_numrrsets;
+       while(i < (msg->rep->an_numrrsets + msg->rep->ns_numrrsets)) {
+               struct ub_packed_rrset_key* s = msg->rep->rrsets[i];
+               if(ntohs(s->rk.type) == LDNS_RR_TYPE_DS &&
+                       !dname_subdomain_c(ns->rk.dname, s->rk.dname)) {
+                       log_nametypeclass(VERB_ALGO, "removing irrelevant DS "
+                               "from referral", s->rk.dname, 
+                               ntohs(s->rk.type), ntohs(s->rk.rrset_class));
+                       memmove(msg->rep->rrsets+i, msg->rep->rrsets+i+1,
+                               sizeof(struct ub_packed_rrset_key*) * 
+                               (msg->rep->rrset_count-i-1));
+                       msg->rep->ns_numrrsets--;
+                       msg->rep->rrset_count--;
+                       /* stay at same i, but new record */
+                       continue;
+               }
+               i++;
+       }
+}
index 747b9a64339a7a52d97b4d303e81c2c7069c25a0..85d9c1a216c257a1a175bf31c3812154e50b1e4c 100644 (file)
@@ -57,6 +57,7 @@ struct query_info;
 struct reply_info;
 struct module_qstate;
 struct sock_list;
+struct ub_packed_rrset_key;
 
 /**
  * Process config options and set iterator module state.
@@ -245,4 +246,11 @@ int iter_lookup_inzone_glue(struct module_env* env, struct delegpt* dp,
 int iter_get_next_root(struct iter_hints* hints, struct iter_forwards* fwd,
        uint16_t* c);
 
+/**
+ * Remove DS records that are inappropriate before they are cached.
+ * @param ns: RRSET that is the NS record for the referral.
+ * @param msg: the response to scrub.
+ */
+void iter_scrub_ds(struct ub_packed_rrset_key* ns, struct dns_msg* msg);
+
 #endif /* ITERATOR_ITER_UTILS_H */
index 43621bd8a1d381d650a1ee143bb2749067f59940..cc66c489593bdb8d962aae209e53e3706e62b26b 100644 (file)
@@ -1612,7 +1612,8 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
                        || !dname_subdomain_c(iq->qchase.qname, ns->rk.dname)){
                        verbose(VERB_ALGO, "bad referral, throwaway");
                        type = RESPONSE_TYPE_THROWAWAY;
-               }
+               } else
+                       iter_scrub_ds(ns, iq->response);
        }
 
        /* handle each of the type cases */
@@ -1650,11 +1651,11 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
                            * see if that equals the query name... */
                        && ( /* auth section, but sometimes in answer section*/
                          reply_find_rrset_section_ns(iq->response->rep,
-                               qstate->qinfo.qname, qstate->qinfo.qname_len,
-                               LDNS_RR_TYPE_NS, qstate->qinfo.qclass)
+                               iq->qchase.qname, iq->qchase.qname_len,
+                               LDNS_RR_TYPE_NS, iq->qchase.qclass)
                          || reply_find_rrset_section_an(iq->response->rep,
-                               qstate->qinfo.qname, qstate->qinfo.qname_len,
-                               LDNS_RR_TYPE_NS, qstate->qinfo.qclass)
+                               iq->qchase.qname, iq->qchase.qname_len,
+                               LDNS_RR_TYPE_NS, iq->qchase.qclass)
                          )
                    )) {
                        /* Store the referral under the current query */
index 25ca768132611aa7d307946a5a529a9e7077d00b..057fa3e768524e6978b8936d1ed641a03084063a 100644 (file)
@@ -698,7 +698,10 @@ dns_cache_lookup(struct module_env* env,
                struct packed_rrset_data *d = (struct packed_rrset_data*)
                        rrset->entry.data;
                if(d->trust != rrset_trust_add_noAA && 
-                       d->trust != rrset_trust_add_AA) {
+                       d->trust != rrset_trust_add_AA && 
+                       (qtype == LDNS_RR_TYPE_DS || 
+                               (d->trust != rrset_trust_auth_noAA 
+                               && d->trust != rrset_trust_auth_AA) )) {
                        struct dns_msg* msg = rrset_msg(rrset, region, now, &k);
                        if(msg) {
                                lock_rw_unlock(&rrset->entry.lock);
index 84b89b7a9d6b3ef12ebec6564c983ff8f2f58e9d..d770618ed8ecc296fd9dc8e3b15b44b7384aa2c7 100644 (file)
 7025,
 7030,
 7070,
+7071,
 7080,
 7099,
 7100,