mirror of
https://github.com/NLnetLabs/unbound.git
synced 2025-12-20 23:00:56 -05:00
More detailed errors.
git-svn-id: file:///svn/unbound/trunk@1871 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
parent
a909fa9a3a
commit
7782cf2b97
6 changed files with 29 additions and 19 deletions
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
Loading…
Reference in a new issue