From: Wouter Wijngaards Date: Thu, 8 Oct 2009 07:23:49 +0000 (+0000) Subject: More detailed errors. X-Git-Tag: release-1.4.0rc1~33 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7782cf2b976404d8128750fdd20602537c39a3a8;p=thirdparty%2Funbound.git More detailed errors. git-svn-id: file:///svn/unbound/trunk@1871 be551aaa-1e26-0410-a405-d3ace91eadb9 --- diff --git a/doc/Changelog b/doc/Changelog index 34ec07e8b..e0a03701e 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -1,6 +1,7 @@ 8 October 2009: Wouter - please doxygen - add val-log-level print to corner case (nameserver.epost.bg). + - more detail to errors from insecure delegation checks. 7 October 2009: Wouter - retry for validation failure in DS and prime results. Less mem use. diff --git a/validator/val_nsec.c b/validator/val_nsec.c index 13d2c1166..5ddb9ad2c 100644 --- a/validator/val_nsec.c +++ b/validator/val_nsec.c @@ -173,7 +173,7 @@ val_nsec_proves_no_ds(struct ub_packed_rrset_key* nsec, enum sec_status val_nsec_prove_nodata_dsreply(struct module_env* env, struct val_env* ve, struct query_info* qinfo, struct reply_info* rep, - struct key_entry_key* kkey, uint32_t* proof_ttl) + struct key_entry_key* kkey, uint32_t* proof_ttl, char** reason) { struct ub_packed_rrset_key* nsec = reply_find_rrset_section_ns( rep, qinfo->qname, qinfo->qname_len, LDNS_RR_TYPE_NSEC, @@ -183,7 +183,6 @@ val_nsec_prove_nodata_dsreply(struct module_env* env, struct val_env* ve, uint8_t* wc = NULL, *ce = NULL; int valid_nsec = 0; struct ub_packed_rrset_key* wc_nsec = NULL; - char* reason = NULL; /* If we have a NSEC at the same name, it must prove one * of two things @@ -191,7 +190,7 @@ val_nsec_prove_nodata_dsreply(struct module_env* env, struct val_env* ve, * 1) this is a delegation point and there is no DS * 2) this is not a delegation point */ if(nsec) { - sec = val_verify_rrset_entry(env, ve, nsec, kkey, &reason); + sec = val_verify_rrset_entry(env, ve, nsec, kkey, reason); if(sec != sec_status_secure) { verbose(VERB_ALGO, "NSEC RRset for the " "referral did not verify."); @@ -200,6 +199,7 @@ val_nsec_prove_nodata_dsreply(struct module_env* env, struct val_env* ve, sec = val_nsec_proves_no_ds(nsec, qinfo); if(sec == sec_status_bogus) { /* something was wrong. */ + *reason = "NSEC does not prove absence of DS"; return sec; } else if(sec == sec_status_insecure) { /* this wasn't a delegation point. */ @@ -221,7 +221,7 @@ val_nsec_prove_nodata_dsreply(struct module_env* env, struct val_env* ve, if(rep->rrsets[i]->rk.type != htons(LDNS_RR_TYPE_NSEC)) continue; sec = val_verify_rrset_entry(env, ve, rep->rrsets[i], kkey, - &reason); + reason); if(sec != sec_status_secure) { verbose(VERB_ALGO, "NSEC for empty non-terminal " "did not verify."); @@ -252,6 +252,7 @@ val_nsec_prove_nodata_dsreply(struct module_env* env, struct val_env* ve, if(valid_nsec) { if(wc) { /* check if this is a delegation */ + *reason = "NSEC for wildcard does not prove absence of DS"; return val_nsec_proves_no_ds(wc_nsec, qinfo); } /* valid nsec proves empty nonterminal */ diff --git a/validator/val_nsec.h b/validator/val_nsec.h index d3f9f0b55..659edc2ff 100644 --- a/validator/val_nsec.h +++ b/validator/val_nsec.h @@ -63,6 +63,7 @@ struct key_entry_key; * @param rep: reply received. * @param kkey: key entry to use for verification of signatures. * @param proof_ttl: if secure, the TTL of how long this proof lasts. + * @param reason: string explaining why bogus. * @return security status. * SECURE: proved absence of DS. * INSECURE: proved that this was not a delegation point. @@ -72,7 +73,7 @@ struct key_entry_key; enum sec_status val_nsec_prove_nodata_dsreply(struct module_env* env, struct val_env* ve, struct query_info* qinfo, struct reply_info* rep, struct key_entry_key* kkey, - uint32_t* proof_ttl); + uint32_t* proof_ttl, char** reason); /** * nsec typemap check, takes an NSEC-type bitmap as argument, checks for type. diff --git a/validator/val_nsec3.c b/validator/val_nsec3.c index b8b4065f4..35bc152fe 100644 --- a/validator/val_nsec3.c +++ b/validator/val_nsec3.c @@ -1241,15 +1241,14 @@ nsec3_prove_wildcard(struct module_env* env, struct val_env* ve, static int list_is_secure(struct module_env* env, struct val_env* ve, struct ub_packed_rrset_key** list, size_t num, - struct key_entry_key* kkey) + struct key_entry_key* kkey, char** reason) { size_t i; enum sec_status sec; - char* reason = NULL; for(i=0; irk.type != htons(LDNS_RR_TYPE_NSEC3)) continue; - sec = val_verify_rrset_entry(env, ve, list[i], kkey, &reason); + sec = val_verify_rrset_entry(env, ve, list[i], kkey, reason); if(sec != sec_status_secure) { verbose(VERB_ALGO, "NSEC3 did not verify"); return 0; @@ -1261,7 +1260,7 @@ list_is_secure(struct module_env* env, struct val_env* ve, enum sec_status nsec3_prove_nods(struct module_env* env, struct val_env* ve, struct ub_packed_rrset_key** list, size_t num, - struct query_info* qinfo, struct key_entry_key* kkey) + struct query_info* qinfo, struct key_entry_key* kkey, char** reason) { rbtree_t ct; struct nsec3_filter flt; @@ -1270,14 +1269,18 @@ nsec3_prove_nods(struct module_env* env, struct val_env* ve, int rr; log_assert(qinfo->qtype == LDNS_RR_TYPE_DS); - if(!list || num == 0 || !kkey || !key_entry_isgood(kkey)) + if(!list || num == 0 || !kkey || !key_entry_isgood(kkey)) { + *reason = "no valid NSEC3s"; return sec_status_bogus; /* no valid NSEC3s, bogus */ - if(!list_is_secure(env, ve, list, num, kkey)) + } + if(!list_is_secure(env, ve, list, num, kkey, reason)) return sec_status_bogus; /* not all NSEC3 records secure */ rbtree_init(&ct, &nsec3_hash_cmp); /* init names-to-hash cache */ filter_init(&flt, list, num, qinfo); /* init RR iterator */ - if(!flt.zone) + if(!flt.zone) { + *reason = "no NSEC3 records"; return sec_status_bogus; /* no RRs */ + } if(nsec3_iteration_count_high(ve, &flt, kkey)) return sec_status_insecure; /* iteration count too high */ @@ -1292,10 +1295,12 @@ nsec3_prove_nods(struct module_env* env, struct val_env* ve, qinfo->qname_len != 1) { verbose(VERB_ALGO, "nsec3 provenods: NSEC3 is from" " child zone, bogus"); + *reason = "NSEC3 from child zone"; return sec_status_bogus; } else if(nsec3_has_type(rrset, rr, LDNS_RR_TYPE_DS)) { verbose(VERB_ALGO, "nsec3 provenods: NSEC3 has qtype" " DS, bogus"); + *reason = "NSEC3 has DS in bitmap"; return sec_status_bogus; } /* If the NSEC3 RR doesn't have the NS bit set, then @@ -1310,6 +1315,7 @@ nsec3_prove_nods(struct module_env* env, struct val_env* ve, if(!nsec3_prove_closest_encloser(env, &flt, &ct, qinfo, 1, &ce)) { verbose(VERB_ALGO, "nsec3 provenods: did not match qname, " "nor found a proven closest encloser."); + *reason = "no NSEC3 closest encloser"; return sec_status_bogus; } @@ -1321,6 +1327,8 @@ nsec3_prove_nods(struct module_env* env, struct val_env* ve, if(!nsec3_has_optout(ce.nc_rrset, ce.nc_rr)) { verbose(VERB_ALGO, "nsec3 provenods: covering NSEC3 was not " "opt-out in an opt-out DS NOERROR/NODATA case."); + *reason = "covering NSEC3 was not opt-out in an opt-out " + "DS NOERROR/NODATA case"; return sec_status_bogus; } return sec_status_secure; diff --git a/validator/val_nsec3.h b/validator/val_nsec3.h index fc6792cb8..ae4326daf 100644 --- a/validator/val_nsec3.h +++ b/validator/val_nsec3.h @@ -183,6 +183,7 @@ nsec3_prove_wildcard(struct module_env* env, struct val_env* ve, * @param num: number of RRsets in the array to examine. * @param qinfo: query that is verified for. * @param kkey: key entry that signed the NSEC3s. + * @param reason: string for bogus result. * @return: * sec_status SECURE of the proposition is proven by the NSEC3 RRs, * BOGUS if not, INSECURE if all of the NSEC3s could be validly ignored. @@ -192,7 +193,7 @@ nsec3_prove_wildcard(struct module_env* env, struct val_env* ve, enum sec_status nsec3_prove_nods(struct module_env* env, struct val_env* ve, struct ub_packed_rrset_key** list, size_t num, - struct query_info* qinfo, struct key_entry_key* kkey); + struct query_info* qinfo, struct key_entry_key* kkey, char** reason); /** * Prove NXDOMAIN or NODATA. diff --git a/validator/validator.c b/validator/validator.c index 75102954f..f388e0dbc 100644 --- a/validator/validator.c +++ b/validator/validator.c @@ -2327,7 +2327,7 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq, /* Try to prove absence of the DS with NSEC */ sec = val_nsec_prove_nodata_dsreply( qstate->env, ve, qinfo, msg->rep, vq->key_entry, - &proof_ttl); + &proof_ttl, &reason); switch(sec) { case sec_status_secure: verbose(VERB_DETAIL, "NSEC RRset for the " @@ -2345,8 +2345,7 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq, case sec_status_bogus: verbose(VERB_DETAIL, "NSEC RRset for the " "referral did not prove no DS."); - val_errinf(qstate, vq, "NSEC DS absent proof " - "failed"); + val_errinf(qstate, vq, reason); goto return_bogus; case sec_status_unchecked: default: @@ -2356,7 +2355,7 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq, sec = nsec3_prove_nods(qstate->env, ve, msg->rep->rrsets + msg->rep->an_numrrsets, - msg->rep->ns_numrrsets, qinfo, vq->key_entry); + msg->rep->ns_numrrsets, qinfo, vq->key_entry, &reason); switch(sec) { case sec_status_secure: verbose(VERB_DETAIL, "NSEC3s for the " @@ -2374,8 +2373,7 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq, case sec_status_bogus: verbose(VERB_DETAIL, "NSEC3s for the " "referral did not prove no DS."); - val_errinf(qstate, vq, "NSEC3 DS absent proof " - "failed"); + val_errinf(qstate, vq, reason); goto return_bogus; case sec_status_insecure: case sec_status_unchecked: