]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
validator also computes insecure and indeterminate for rrsets and stores
authorWouter Wijngaards <wouter@nlnetlabs.nl>
Mon, 27 Aug 2007 14:55:06 +0000 (14:55 +0000)
committerWouter Wijngaards <wouter@nlnetlabs.nl>
Mon, 27 Aug 2007 14:55:06 +0000 (14:55 +0000)
that.

git-svn-id: file:///svn/unbound/trunk@551 be551aaa-1e26-0410-a405-d3ace91eadb9

doc/Changelog
services/cache/rrset.c
services/cache/rrset.h
validator/val_utils.c
validator/val_utils.h
validator/validator.c

index dc32fb53d6c92e30c1a98fac20f6b3ba05daa0b1..5a6fd4eb64d0946387777d26fce762cbd4367a9e 100644 (file)
@@ -6,6 +6,8 @@
        - do not store referral in msg cache for nonRD queries.
        - store verification status in the rrset cache to speed up future
          verification.
+       - mark rrsets indeterminate and insecure if they are found to be so.
+         and store this in the cache.
 
 24 August 2007: Wouter
        - message is bogus if unsecure authority rrsets are present.
index 4d8d661df19ab029d241f253574abad6bb6de43b..628a9e63104d446cb8d001389bbaef02c549900e 100644 (file)
@@ -321,6 +321,9 @@ rrset_update_sec_status(struct rrset_cache* r,
        struct lruhash_entry* e;
        struct packed_rrset_data* cachedata;
 
+       /* hash it again to make sure it has a hash */
+       rrset->entry.hash = rrset_key_hash(&rrset->rk);
+
        e = slabhash_lookup(&r->table, rrset->entry.hash, rrset, 1);
        if(!e)
                return; /* not in the cache anymore */
@@ -330,9 +333,11 @@ rrset_update_sec_status(struct rrset_cache* r,
                return; /* rrset has changed in the meantime */
        }
        /* update the cached rrset */
-       cachedata->trust = updata->trust;
-       cachedata->security = updata->security;
-       cachedata->ttl = updata->ttl + now;
+       if(updata->security > cachedata->security) {
+               cachedata->trust = updata->trust;
+               cachedata->security = updata->security;
+               cachedata->ttl = updata->ttl + now;
+       }
        lock_rw_unlock(&e->lock);
 }
 
index 22ae295838146259a66f0c3bd51158842ea4b33f..3fcee79eb4cc38fd32b22c4c1f0c9b81506489be 100644 (file)
@@ -188,6 +188,7 @@ void rrset_array_unlock_touch(struct rrset_cache* r, struct region* scratch,
  * Update security status of an rrset. Looks up the rrset.
  * If found, checks if rdata is equal.
  * If so, it will update the security, trust and rrset-ttl values.
+ * The values are only updated if security is increased (towards secure).
  * @param r: the rrset cache. 
  * @param rrset: which rrset to attempt to update. This rrset is left 
  *     untouched. The rrset in the cache is updated in-place.
index 34ac447d6f3104fee90cbbfb3e2396e84037b8ac..8314394a3bda1c3926f6b5976d678d7d1a64433b 100644 (file)
@@ -43,6 +43,7 @@
 #include "validator/validator.h"
 #include "validator/val_kentry.h"
 #include "validator/val_sigcrypt.h"
+#include "validator/val_anchor.h"
 #include "services/cache/rrset.h"
 #include "util/data/msgreply.h"
 #include "util/data/packed_rrset.h"
@@ -609,3 +610,41 @@ val_check_nonsecure(struct val_env* ve, struct reply_info* rep)
                }
        }
 }
+
+void 
+val_mark_indeterminate(struct reply_info* rep, struct val_anchors* anchors, 
+       struct rrset_cache* r)
+{
+       size_t i;
+       struct packed_rrset_data* d;
+       for(i=0; i<rep->rrset_count; i++) {
+               d = (struct packed_rrset_data*)rep->rrsets[i]->entry.data;
+               if(d->security == sec_status_unchecked &&
+                  !anchors_lookup(anchors, rep->rrsets[i]->rk.dname,
+                       rep->rrsets[i]->rk.dname_len, 
+                       ntohs(rep->rrsets[i]->rk.rrset_class))) 
+               {       
+                       /* mark as indeterminate */
+                       d->security = sec_status_indeterminate;
+                       rrset_update_sec_status(r, rep->rrsets[i]);
+               }
+       }
+}
+
+void 
+val_mark_insecure(struct reply_info* rep, struct key_entry_key* kkey,
+       struct rrset_cache* r)
+{
+       size_t i;
+       struct packed_rrset_data* d;
+       log_assert(key_entry_isnull(kkey));
+       for(i=0; i<rep->rrset_count; i++) {
+               d = (struct packed_rrset_data*)rep->rrsets[i]->entry.data;
+               if(d->security == sec_status_unchecked &&
+                  dname_subdomain_c(rep->rrsets[i]->rk.dname, kkey->name)) {
+                       /* mark as insecure */
+                       d->security = sec_status_insecure;
+                       rrset_update_sec_status(r, rep->rrsets[i]);
+               }
+       }
+}
index 615cb2ac00f5528a49a000f3868969d3ec18cc58..b9d859237601e1f8411eeee3599adad677315142 100644 (file)
@@ -48,6 +48,8 @@ struct module_env;
 struct ub_packed_rrset_key;
 struct key_entry_key;
 struct region;
+struct val_anchors;
+struct rrset_cache;
 enum sec_status;
 
 /**
@@ -215,4 +217,25 @@ void val_fill_reply(struct reply_info* chase, struct reply_info* orig,
  */
 void val_check_nonsecure(struct val_env* ve, struct reply_info* rep);
 
+/**
+ * Mark all unchecked rrset entries not below a trust anchor as indeterminate.
+ * Only security==unchecked rrsets are updated.
+ * @param rep: the reply with rrsets.
+ * @param anchors: the trust anchors.
+ * @param r: rrset cache to store updated security status into.
+ */
+void val_mark_indeterminate(struct reply_info* rep, 
+       struct val_anchors* anchors, struct rrset_cache* r);
+
+/**
+ * Mark all unchecked rrset entries below a NULL key entry as insecure.
+ * Only security==unchecked rrsets are updated.
+ * @param rep: the reply with rrsets.
+ * @param kkey: key entry, key_entry_isnull() for it. A key entry that marks
+ *     the end of secure space into insecure space.
+ * @param r: rrset cache to store updated security status into.
+ */
+void val_mark_insecure(struct reply_info* rep, struct key_entry_key* kkey,
+       struct rrset_cache* r);
+
 #endif /* VALIDATOR_VAL_UTILS_H */
index ed3ac6bb9384282c37df432c2c023c8e4f26f440..8c6ddad488a442447120334eb8f89c2448921c20 100644 (file)
@@ -857,6 +857,8 @@ processInit(struct module_qstate* qstate, struct val_qstate* vq,
        enum val_classification subtype = val_classify_response(&vq->qchase, 
                vq->orig_msg->rep, vq->cname_skip);
 
+       val_mark_indeterminate(vq->chase_reply, ve->anchors, 
+               qstate->env->rrset_cache);
        vq->trust_anchor = anchors_lookup(ve->anchors, vq->qchase.qname,
                vq->qchase.qname_len, vq->qchase.qclass);
        if(vq->trust_anchor == NULL) {
@@ -906,6 +908,8 @@ processInit(struct module_qstate* qstate, struct val_qstate* vq,
                 * However, we do set the status to INSECURE, since it is 
                 * essentially proven insecure. */
                vq->chase_reply->security = sec_status_insecure;
+               val_mark_insecure(vq->chase_reply, vq->key_entry, 
+                       qstate->env->rrset_cache);
                /* go to finished state to cache this result */
                vq->state = VAL_FINISHED_STATE;
                return 1;
@@ -1042,6 +1046,8 @@ processValidate(struct module_qstate* qstate, struct val_qstate* vq,
                        verbose(VERB_ALGO, "Unsigned response was proven to "
                                "be validly INSECURE");
                        vq->chase_reply->security = sec_status_insecure;
+                       val_mark_insecure(vq->chase_reply, vq->key_entry, 
+                               qstate->env->rrset_cache);
                        return 1;
                }
                verbose(VERB_ALGO, "Could not establish validation of "
@@ -1061,6 +1067,8 @@ processValidate(struct module_qstate* qstate, struct val_qstate* vq,
        if(key_entry_isnull(vq->key_entry)) {
                verbose(VERB_ALGO, "Verified that response is INSECURE");
                vq->chase_reply->security = sec_status_insecure;
+               val_mark_insecure(vq->chase_reply, vq->key_entry, 
+                       qstate->env->rrset_cache);
                return 1;
        }