]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
More detailed errors.
authorWouter Wijngaards <wouter@nlnetlabs.nl>
Thu, 8 Oct 2009 07:23:49 +0000 (07:23 +0000)
committerWouter Wijngaards <wouter@nlnetlabs.nl>
Thu, 8 Oct 2009 07:23:49 +0000 (07:23 +0000)
git-svn-id: file:///svn/unbound/trunk@1871 be551aaa-1e26-0410-a405-d3ace91eadb9

doc/Changelog
validator/val_nsec.c
validator/val_nsec.h
validator/val_nsec3.c
validator/val_nsec3.h
validator/validator.c

index 34ec07e8b8f3026ebc4623cb94e5d3cfa4667de1..e0a03701e7c452385005edd67ec02527ec8eacf1 100644 (file)
@@ -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.
index 13d2c11668da145bf358dfafe18b82a79f0840b6..5ddb9ad2c8988140c17b4012a6f270dda8ae53fc 100644 (file)
@@ -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 */
index d3f9f0b559332490a767c5008892319aa7d0d981..659edc2ff9b5cc36662b54e6b1ae48c08f950404 100644 (file)
@@ -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.
index b8b4065f4fc83f0e2a37a4173fe3a1d70909bf02..35bc152fea9a4466622db2f864e5cc10709c04b4 100644 (file)
@@ -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; i<num; i++) {
                if(list[i]->rk.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;
index fc6792cb882a66a5956f77214f2538fa7e07ac5a..ae4326daffb62607777b29548b33f858e698b39c 100644 (file)
@@ -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.
index 75102954f9cd35f353233eba8efe9196fd38b5ec..f388e0dbc28744480771bb975e3e81b103014439 100644 (file)
@@ -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: