From: Wouter Wijngaards Date: Mon, 27 Aug 2007 14:55:06 +0000 (+0000) Subject: validator also computes insecure and indeterminate for rrsets and stores X-Git-Tag: release-0.5~90 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f9cc9481e27b0635a77c90355edec43867226bd9;p=thirdparty%2Funbound.git validator also computes insecure and indeterminate for rrsets and stores that. git-svn-id: file:///svn/unbound/trunk@551 be551aaa-1e26-0410-a405-d3ace91eadb9 --- diff --git a/doc/Changelog b/doc/Changelog index dc32fb53d..5a6fd4eb6 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -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. diff --git a/services/cache/rrset.c b/services/cache/rrset.c index 4d8d661df..628a9e631 100644 --- a/services/cache/rrset.c +++ b/services/cache/rrset.c @@ -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); } diff --git a/services/cache/rrset.h b/services/cache/rrset.h index 22ae29583..3fcee79eb 100644 --- a/services/cache/rrset.h +++ b/services/cache/rrset.h @@ -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. diff --git a/validator/val_utils.c b/validator/val_utils.c index 34ac447d6..8314394a3 100644 --- a/validator/val_utils.c +++ b/validator/val_utils.c @@ -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; irrset_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; irrset_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]); + } + } +} diff --git a/validator/val_utils.h b/validator/val_utils.h index 615cb2ac0..b9d859237 100644 --- a/validator/val_utils.h +++ b/validator/val_utils.h @@ -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 */ diff --git a/validator/validator.c b/validator/validator.c index ed3ac6bb9..8c6ddad48 100644 --- a/validator/validator.c +++ b/validator/validator.c @@ -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; }