From 56d69016f4fae2eda4d39c92fe13595251aaadd3 Mon Sep 17 00:00:00 2001 From: Mark Andrews Date: Thu, 13 Sep 2001 07:23:39 +0000 Subject: [PATCH] 994. [bug] If the unsecure proof fails for unsigned NS records attempt a secure proof using the NS records found as glue to find the NS records from the zone's servers along with associated glue rather than from parent servers. [RT #1706] --- CHANGES | 6 + lib/dns/include/dns/validator.h | 4 +- lib/dns/resolver.c | 6 +- lib/dns/validator.c | 241 +++++++++++++++++++++++--------- 4 files changed, 191 insertions(+), 66 deletions(-) diff --git a/CHANGES b/CHANGES index 30f04b07b1..f01edc11e2 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,9 @@ + 994. [bug] If the unsecure proof fails for unsigned NS records + attempt a secure proof using the NS records found as + glue to find the NS records from the zone's servers + along with associated glue rather than from parent + servers. [RT #1706] + 993. [func] dig: -v now reports the version. 992. [doc] dig: ~/.digrc is now documented. diff --git a/lib/dns/include/dns/validator.h b/lib/dns/include/dns/validator.h index a0d2bc4006..49fbb838e5 100644 --- a/lib/dns/include/dns/validator.h +++ b/lib/dns/include/dns/validator.h @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: validator.h,v 1.18 2001/01/09 21:53:39 bwelling Exp $ */ +/* $Id: validator.h,v 1.19 2001/09/13 07:23:39 marka Exp $ */ #ifndef DNS_VALIDATOR_H #define DNS_VALIDATOR_H 1 @@ -73,6 +73,8 @@ typedef struct dns_validatorevent { dns_rdataset_t * rdataset; dns_rdataset_t * sigrdataset; dns_message_t * message; + dns_rdataset_t nsrdataset; + dns_rdataset_t nssigrdataset; } dns_validatorevent_t; diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c index 49734ae471..aa5b201e75 100644 --- a/lib/dns/resolver.c +++ b/lib/dns/resolver.c @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: resolver.c,v 1.218 2001/07/11 01:19:56 halley Exp $ */ +/* $Id: resolver.c,v 1.219 2001/09/13 07:23:35 marka Exp $ */ #include @@ -2698,6 +2698,10 @@ validated(isc_task_t *task, isc_event_t *event) { fctx_done(fctx, result); cleanup_event: + if (dns_rdataset_isassociated(&vevent->nssigrdataset)) + dns_rdataset_disassociate(&vevent->nssigrdataset); + if (dns_rdataset_isassociated(&vevent->nsrdataset)) + dns_rdataset_disassociate(&vevent->nsrdataset); isc_event_free(&event); } diff --git a/lib/dns/validator.c b/lib/dns/validator.c index 5f10785e7d..c7902f3e1e 100644 --- a/lib/dns/validator.c +++ b/lib/dns/validator.c @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: validator.c,v 1.91 2001/08/08 22:54:45 gson Exp $ */ +/* $Id: validator.c,v 1.92 2001/09/13 07:23:37 marka Exp $ */ #include @@ -47,6 +47,7 @@ #define VALATTR_FOUNDNONEXISTENCE 0x02 #define VALATTR_TRIEDVERIFY 0x04 #define SHUTDOWN(v) (((v)->attributes & VALATTR_SHUTDOWN) != 0) +#define VALDBL 3 static void nullkeyvalidated(isc_task_t *task, isc_event_t *event); @@ -89,7 +90,6 @@ validator_done(dns_validator_t *val, isc_result_t result) { val->event->ev_action = val->action; val->event->ev_arg = val->arg; isc_task_sendanddetach(&task, (isc_event_t **)&val->event); - } static void @@ -138,15 +138,16 @@ fetch_callback_validator(isc_task_t *task, isc_event_t *event) { } if (val->event == NULL) { - validator_log(val, ISC_LOG_DEBUG(3), + validator_log(val, ISC_LOG_DEBUG(VALDBL), "fetch_callback_validator: event == NULL"); return; } - validator_log(val, ISC_LOG_DEBUG(3), "in fetch_callback_validator"); + validator_log(val, ISC_LOG_DEBUG(VALDBL), + "in fetch_callback_validator"); LOCK(&val->lock); if (eresult == ISC_R_SUCCESS) { - validator_log(val, ISC_LOG_DEBUG(3), + validator_log(val, ISC_LOG_DEBUG(VALDBL), "keyset with trust %d", rdataset->trust); /* * Only extract the dst key if the keyset is secure. @@ -162,7 +163,7 @@ fetch_callback_validator(isc_task_t *task, isc_event_t *event) { goto out; } } else { - validator_log(val, ISC_LOG_DEBUG(3), + validator_log(val, ISC_LOG_DEBUG(VALDBL), "fetch_callback_validator: got %s", dns_result_totext(eresult)); validator_done(val, eresult); @@ -205,13 +206,13 @@ fetch_callback_nullkey(isc_task_t *task, isc_event_t *event) { } if (val->event == NULL) { - validator_log(val, ISC_LOG_DEBUG(3), + validator_log(val, ISC_LOG_DEBUG(VALDBL), "fetch_callback_nullkey: event == NULL"); isc_event_free(&event); return; } - validator_log(val, ISC_LOG_DEBUG(3), "in fetch_callback_nullkey"); + validator_log(val, ISC_LOG_DEBUG(VALDBL), "in fetch_callback_nullkey"); LOCK(&val->lock); if (eresult == ISC_R_SUCCESS) { @@ -219,7 +220,7 @@ fetch_callback_nullkey(isc_task_t *task, isc_event_t *event) { /* * No null key. */ - validator_log(val, ISC_LOG_DEBUG(3), + validator_log(val, ISC_LOG_DEBUG(VALDBL), "found a keyset, no null key"); result = proveunsecure(val, ISC_TRUE); if (result != DNS_R_WAIT) @@ -234,15 +235,15 @@ fetch_callback_nullkey(isc_task_t *task, isc_event_t *event) { return; } } else { - validator_log(val, ISC_LOG_DEBUG(3), + validator_log(val, ISC_LOG_DEBUG(VALDBL), "found a keyset with a null key"); if (rdataset->trust >= dns_trust_secure) { - validator_log(val, ISC_LOG_DEBUG(3), + validator_log(val, ISC_LOG_DEBUG(VALDBL), "insecurity proof succeeded"); val->event->rdataset->trust = dns_trust_answer; validator_done(val, ISC_R_SUCCESS); } else if (!dns_rdataset_isassociated(sigrdataset)) { - validator_log(val, ISC_LOG_DEBUG(3), + validator_log(val, ISC_LOG_DEBUG(VALDBL), "insecurity proof failed"); validator_done(val, DNS_R_NOTINSECURE); } else { @@ -275,13 +276,13 @@ fetch_callback_nullkey(isc_task_t *task, isc_event_t *event) { /* * No keys. */ - validator_log(val, ISC_LOG_DEBUG(3), + validator_log(val, ISC_LOG_DEBUG(VALDBL), "no keys found"); result = proveunsecure(val, ISC_TRUE); if (result != DNS_R_WAIT) validator_done(val, result); } else { - validator_log(val, ISC_LOG_DEBUG(3), + validator_log(val, ISC_LOG_DEBUG(VALDBL), "fetch_callback_nullkey: got %s", dns_result_totext(eresult)); validator_done(val, eresult); @@ -298,6 +299,86 @@ fetch_callback_nullkey(isc_task_t *task, isc_event_t *event) { isc_event_free(&event); } +static void +fetch_callback_ns(isc_task_t *task, isc_event_t *event) { + dns_fetchevent_t *devent; + dns_validator_t *val; + dns_rdataset_t *rdataset, *sigrdataset; + isc_result_t result; + isc_result_t eresult; + + UNUSED(task); + INSIST(event->ev_type == DNS_EVENT_FETCHDONE); + devent = (dns_fetchevent_t *)event; + val = devent->ev_arg; + sigrdataset = &val->event->nssigrdataset; + rdataset = &val->event->nsrdataset; + eresult = devent->result; + + dns_resolver_destroyfetch(&val->fetch); + + if (SHUTDOWN(val)) { + dns_validator_destroy(&val); + isc_event_free(&event); + return; + } + + if (val->event == NULL) { + validator_log(val, ISC_LOG_DEBUG(VALDBL), + "fetch_callback_ns: event == NULL"); + isc_event_free(&event); + return; + } + + validator_log(val, ISC_LOG_DEBUG(VALDBL), "in fetch_callback_ns"); + + LOCK(&val->lock); + if (eresult == ISC_R_SUCCESS) { + validator_log(val, ISC_LOG_DEBUG(VALDBL), + "fetch_callback_ns: got %s %d %d\n", + dns_result_totext(eresult), + dns_rdataset_isassociated(rdataset), + dns_rdataset_isassociated(sigrdataset)); + if (dns_rdataset_isassociated(sigrdataset)) { + val->event->sigrdataset = sigrdataset; + if (dns_rdataset_isassociated(rdataset)) + val->event->rdataset = rdataset; + result = validate(val, ISC_FALSE); + } else + result = proveunsecure(val, ISC_TRUE); + if (result != DNS_R_WAIT) + validator_done(val, result); + } else if (eresult == DNS_R_NCACHENXDOMAIN || + eresult == DNS_R_NCACHENXRRSET || + eresult == DNS_R_NXDOMAIN || + eresult == DNS_R_NXRRSET) + { + /* + * No ns. + */ + validator_log(val, ISC_LOG_DEBUG(VALDBL), + "no ns found"); + result = proveunsecure(val, ISC_TRUE); + if (result != DNS_R_WAIT) + validator_done(val, result); + } else { + validator_log(val, ISC_LOG_DEBUG(VALDBL), + "fetch_callback_ns: got %s", + dns_result_totext(eresult)); + validator_done(val, eresult); + } + UNLOCK(&val->lock); + + /* + * Free stuff from the event. + */ + if (dns_rdataset_isassociated(&val->frdataset)) + dns_rdataset_disassociate(&val->frdataset); + if (dns_rdataset_isassociated(&val->fsigrdataset)) + dns_rdataset_disassociate(&val->fsigrdataset); + isc_event_free(&event); +} + static void keyvalidated(isc_task_t *task, isc_event_t *event) { dns_validatorevent_t *devent; @@ -322,10 +403,10 @@ keyvalidated(isc_task_t *task, isc_event_t *event) { if (val->event == NULL) return; - validator_log(val, ISC_LOG_DEBUG(3), "in keyvalidated"); + validator_log(val, ISC_LOG_DEBUG(VALDBL), "in keyvalidated"); LOCK(&val->lock); if (eresult == ISC_R_SUCCESS) { - validator_log(val, ISC_LOG_DEBUG(3), + validator_log(val, ISC_LOG_DEBUG(VALDBL), "keyset with trust %d", val->frdataset.trust); /* * Only extract the dst key if the keyset is secure. @@ -338,7 +419,7 @@ keyvalidated(isc_task_t *task, isc_event_t *event) { goto out; } } else { - validator_log(val, ISC_LOG_DEBUG(3), + validator_log(val, ISC_LOG_DEBUG(VALDBL), "keyvalidated: got %s", dns_result_totext(eresult)); validator_done(val, eresult); @@ -366,13 +447,13 @@ nxtprovesnonexistence(dns_validator_t *val, dns_name_t *nxtname, result = dns_rdataset_first(nxtset); if (result != ISC_R_SUCCESS) { - validator_log(val, ISC_LOG_DEBUG(3), + validator_log(val, ISC_LOG_DEBUG(VALDBL), "failure processing NXT set"); return (ISC_FALSE); } dns_rdataset_current(nxtset, &rdata); - validator_log(val, ISC_LOG_DEBUG(3), + validator_log(val, ISC_LOG_DEBUG(VALDBL), "looking for relevant nxt"); order = dns_name_compare(val->event->name, nxtname); if (order == 0) { @@ -380,17 +461,17 @@ nxtprovesnonexistence(dns_validator_t *val, dns_name_t *nxtname, * The names are the same, so look for the type present bit. */ if (val->event->type >= 128) { - validator_log(val, ISC_LOG_DEBUG(3), "invalid type %d", - val->event->type); + validator_log(val, ISC_LOG_DEBUG(VALDBL), + "invalid type %d", val->event->type); return (ISC_FALSE); } if (dns_nxt_typepresent(&rdata, val->event->type)) { - validator_log(val, ISC_LOG_DEBUG(3), + validator_log(val, ISC_LOG_DEBUG(VALDBL), "type should not be present"); return (ISC_FALSE); } - validator_log(val, ISC_LOG_DEBUG(3), "nxt bitmask ok"); + validator_log(val, ISC_LOG_DEBUG(VALDBL), "nxt bitmask ok"); } else if (order > 0) { dns_rdata_nxt_t nxt; @@ -411,7 +492,7 @@ nxtprovesnonexistence(dns_validator_t *val, dns_name_t *nxtname, dns_rdata_sig_t siginfo; result = dns_rdataset_first(signxtset); if (result != ISC_R_SUCCESS) { - validator_log(val, ISC_LOG_DEBUG(3), + validator_log(val, ISC_LOG_DEBUG(VALDBL), "failure processing SIG NXT set"); dns_rdata_freestruct(&nxt); return (ISC_FALSE); @@ -419,25 +500,25 @@ nxtprovesnonexistence(dns_validator_t *val, dns_name_t *nxtname, dns_rdataset_current(signxtset, &rdata); result = dns_rdata_tostruct(&rdata, &siginfo, NULL); if (result != ISC_R_SUCCESS) { - validator_log(val, ISC_LOG_DEBUG(3), + validator_log(val, ISC_LOG_DEBUG(VALDBL), "failure processing SIG NXT set"); dns_rdata_freestruct(&nxt); return (ISC_FALSE); } if (!dns_name_equal(&siginfo.signer, &nxt.next)) { - validator_log(val, ISC_LOG_DEBUG(3), + validator_log(val, ISC_LOG_DEBUG(VALDBL), "next name is not greater"); dns_rdata_freestruct(&nxt); return (ISC_FALSE); } - validator_log(val, ISC_LOG_DEBUG(3), + validator_log(val, ISC_LOG_DEBUG(VALDBL), "nxt points to zone apex, ok"); } dns_rdata_freestruct(&nxt); - validator_log(val, ISC_LOG_DEBUG(3), + validator_log(val, ISC_LOG_DEBUG(VALDBL), "nxt range ok"); } else { - validator_log(val, ISC_LOG_DEBUG(3), + validator_log(val, ISC_LOG_DEBUG(VALDBL), "nxt owner name is not less"); /* * The NXT owner name is greater than the supposedly @@ -474,10 +555,10 @@ authvalidated(isc_task_t *task, isc_event_t *event) { if (val->event == NULL) return; - validator_log(val, ISC_LOG_DEBUG(3), "in authvalidated"); + validator_log(val, ISC_LOG_DEBUG(VALDBL), "in authvalidated"); LOCK(&val->lock); if (eresult != ISC_R_SUCCESS) { - validator_log(val, ISC_LOG_DEBUG(3), + validator_log(val, ISC_LOG_DEBUG(VALDBL), "authvalidated: got %s", dns_result_totext(eresult)); result = nxtvalidate(val, ISC_TRUE); @@ -524,16 +605,16 @@ negauthvalidated(isc_task_t *task, isc_event_t *event) { if (val->event == NULL) return; - validator_log(val, ISC_LOG_DEBUG(3), "in negauthvalidated"); + validator_log(val, ISC_LOG_DEBUG(VALDBL), "in negauthvalidated"); LOCK(&val->lock); if (eresult == ISC_R_SUCCESS) { val->attributes |= VALATTR_FOUNDNONEXISTENCE; - validator_log(val, ISC_LOG_DEBUG(3), + validator_log(val, ISC_LOG_DEBUG(VALDBL), "nonexistence proof found"); auth_nonpending(val->event->message); validator_done(val, ISC_R_SUCCESS); } else { - validator_log(val, ISC_LOG_DEBUG(3), + validator_log(val, ISC_LOG_DEBUG(VALDBL), "negauthvalidated: got %s", dns_result_totext(eresult)); validator_done(val, eresult); @@ -574,12 +655,12 @@ nullkeyvalidated(isc_task_t *task, isc_event_t *event) { if (val->event == NULL) return; - validator_log(val, ISC_LOG_DEBUG(3), "in nullkeyvalidated"); + validator_log(val, ISC_LOG_DEBUG(VALDBL), "in nullkeyvalidated"); LOCK(&val->lock); if (eresult == ISC_R_SUCCESS) { - validator_log(val, ISC_LOG_DEBUG(3), + validator_log(val, ISC_LOG_DEBUG(VALDBL), "proved that name is in an unsecure domain"); - validator_log(val, ISC_LOG_DEBUG(3), "marking as answer"); + validator_log(val, ISC_LOG_DEBUG(VALDBL), "marking as answer"); val->event->rdataset->trust = dns_trust_answer; validator_done(val, ISC_R_SUCCESS); } else { @@ -756,7 +837,7 @@ get_key(dns_validator_t *val, dns_rdata_sig_t *siginfo) { if (event->rdataset->type == dns_rdatatype_key && namereln == dns_namereln_equal) { - validator_log(val, ISC_LOG_DEBUG(3), + validator_log(val, ISC_LOG_DEBUG(VALDBL), "keyset was self-signed but not preconfigured"); return (DNS_R_CONTINUE); } @@ -814,7 +895,7 @@ get_key(dns_validator_t *val, dns_rdata_sig_t *siginfo) { /* * See if we've got the key used in the signature. */ - validator_log(val, ISC_LOG_DEBUG(3), + validator_log(val, ISC_LOG_DEBUG(VALDBL), "keyset with trust %d", val->frdataset.trust); result = get_dst_key(val, siginfo, val->keyset); @@ -972,7 +1053,7 @@ validate(dns_validator_t *val, isc_boolean_t resume) { * We already have a sigrdataset. */ result = ISC_R_SUCCESS; - validator_log(val, ISC_LOG_DEBUG(3), "resuming validate"); + validator_log(val, ISC_LOG_DEBUG(VALDBL), "resuming validate"); } else { result = dns_rdataset_first(event->sigrdataset); } @@ -1009,7 +1090,7 @@ validate(dns_validator_t *val, isc_boolean_t resume) { if (val->key == NULL) { event->rdataset->trust = dns_trust_answer; event->sigrdataset->trust = dns_trust_answer; - validator_log(val, ISC_LOG_DEBUG(3), + validator_log(val, ISC_LOG_DEBUG(VALDBL), "marking as answer"); return (ISC_R_SUCCESS); @@ -1021,7 +1102,7 @@ validate(dns_validator_t *val, isc_boolean_t resume) { event->rdataset, val->key, ISC_FALSE, val->view->mctx, &rdata); - validator_log(val, ISC_LOG_DEBUG(3), + validator_log(val, ISC_LOG_DEBUG(VALDBL), "verify rdataset: %s", isc_result_totext(result)); if (result == ISC_R_SUCCESS) @@ -1047,7 +1128,7 @@ validate(dns_validator_t *val, isc_boolean_t resume) { } } while (1); if (result != ISC_R_SUCCESS) - validator_log(val, ISC_LOG_DEBUG(3), + validator_log(val, ISC_LOG_DEBUG(VALDBL), "failed to verify rdataset"); else { isc_uint32_t ttl; @@ -1077,17 +1158,17 @@ validate(dns_validator_t *val, isc_boolean_t resume) { if (result == ISC_R_SUCCESS) { event->rdataset->trust = dns_trust_secure; event->sigrdataset->trust = dns_trust_secure; - validator_log(val, ISC_LOG_DEBUG(3), + validator_log(val, ISC_LOG_DEBUG(VALDBL), "marking as secure"); return (result); } else - validator_log(val, ISC_LOG_DEBUG(3), + validator_log(val, ISC_LOG_DEBUG(VALDBL), "verify failure: %s", isc_result_totext(result)); } if (result != ISC_R_NOMORE) { - validator_log(val, ISC_LOG_DEBUG(3), + validator_log(val, ISC_LOG_DEBUG(VALDBL), "failed to iterate signatures: %s", isc_result_totext(result)); return (result); @@ -1110,7 +1191,8 @@ nxtvalidate(dns_validator_t *val, isc_boolean_t resume) { validator_done(val, ISC_R_NOTFOUND); } else { result = ISC_R_SUCCESS; - validator_log(val, ISC_LOG_DEBUG(3), "resuming nxtvalidate"); + validator_log(val, ISC_LOG_DEBUG(VALDBL), + "resuming nxtvalidate"); } for (; @@ -1210,11 +1292,11 @@ nxtvalidate(dns_validator_t *val, isc_boolean_t resume) { return (result); return (DNS_R_WAIT); } - validator_log(val, ISC_LOG_DEBUG(3), + validator_log(val, ISC_LOG_DEBUG(VALDBL), "nonexistence proof not found"); return (DNS_R_NOVALIDNXT); } else { - validator_log(val, ISC_LOG_DEBUG(3), + validator_log(val, ISC_LOG_DEBUG(VALDBL), "nonexistence proof found"); return (ISC_R_SUCCESS); } @@ -1254,7 +1336,8 @@ proveunsecure(dns_validator_t *val, isc_boolean_t resume) { if (!resume) val->labels = dns_name_depth(dns_fixedname_name(&secroot)) + 1; else { - validator_log(val, ISC_LOG_DEBUG(3), "resuming proveunsecure"); + validator_log(val, ISC_LOG_DEBUG(VALDBL), + "resuming proveunsecure"); val->labels++; } @@ -1278,7 +1361,7 @@ proveunsecure(dns_validator_t *val, isc_boolean_t resume) { } dns_name_format(tname, namebuf, sizeof(namebuf)); - validator_log(val, ISC_LOG_DEBUG(3), + validator_log(val, ISC_LOG_DEBUG(VALDBL), "looking for null keyset at '%s'", namebuf); @@ -1299,13 +1382,13 @@ proveunsecure(dns_validator_t *val, isc_boolean_t resume) { result = DNS_R_NOTINSECURE; goto out; } - validator_log(val, ISC_LOG_DEBUG(3), + validator_log(val, ISC_LOG_DEBUG(VALDBL), "found keyset, looking for null key"); if (!containsnullkey(val, &val->frdataset)) continue; if (val->frdataset.trust >= dns_trust_secure) { - validator_log(val, ISC_LOG_DEBUG(3), + validator_log(val, ISC_LOG_DEBUG(VALDBL), "insecurity proof succeeded"); val->event->rdataset->trust = dns_trust_answer; result = ISC_R_SUCCESS; @@ -1362,7 +1445,7 @@ proveunsecure(dns_validator_t *val, isc_boolean_t resume) { } else goto out; } - validator_log(val, ISC_LOG_DEBUG(3), "insecurity proof failed"); + validator_log(val, ISC_LOG_DEBUG(VALDBL), "insecurity proof failed"); return (DNS_R_NOTINSECURE); /* Didn't find a null key */ out: @@ -1388,7 +1471,7 @@ validator_start(isc_task_t *task, isc_event_t *event) { if (val->event == NULL) return; - validator_log(val, ISC_LOG_DEBUG(3), "starting"); + validator_log(val, ISC_LOG_DEBUG(VALDBL), "starting"); LOCK(&val->lock); @@ -1400,7 +1483,7 @@ validator_start(isc_task_t *task, isc_event_t *event) { * because we don't know if wildcards are involved yet so it * could still get complicated. */ - validator_log(val, ISC_LOG_DEBUG(3), + validator_log(val, ISC_LOG_DEBUG(VALDBL), "attempting positive response validation"); result = validate(val, ISC_FALSE); @@ -1408,7 +1491,7 @@ validator_start(isc_task_t *task, isc_event_t *event) { (val->attributes & VALATTR_TRIEDVERIFY) == 0) { saved_result = result; - validator_log(val, ISC_LOG_DEBUG(3), + validator_log(val, ISC_LOG_DEBUG(VALDBL), "falling back to insecurity proof"); result = proveunsecure(val, ISC_FALSE); if (result == DNS_R_NOTINSECURE) @@ -1416,20 +1499,49 @@ validator_start(isc_task_t *task, isc_event_t *event) { } } else if (val->event->rdataset != NULL) { /* - * This is either an unsecure subdomain or a response from - * a broken server. + * This is either an unsecure subdomain, a response from + * a broken server or an answer from a parent. */ - validator_log(val, ISC_LOG_DEBUG(3), + validator_log(val, ISC_LOG_DEBUG(VALDBL), "attempting insecurity proof"); result = proveunsecure(val, ISC_FALSE); + if (result == DNS_R_NOTINSECURE && + val->event->type == dns_rdatatype_ns) { + unsigned int options; + dns_rdataset_t *nsrdataset, *nssigrdataset; + validator_log(val, ISC_LOG_DEBUG(VALDBL), + "looking for ns sigs"); + options = 0; + /* Prevent infinite resursion. */ + options |= DNS_FETCHOPT_NOVALIDATE; + /* We don't want to match ourselves. */ + options |= DNS_FETCHOPT_UNSHARED; + nsrdataset = &val->event->nsrdataset; + nssigrdataset = &val->event->nssigrdataset; + result = dns_resolver_createfetch(val->view->resolver, + val->event->name, + dns_rdatatype_ns, + NULL, NULL, NULL, + options, + val->event->ev_sender, + fetch_callback_ns, + val, + nsrdataset, + nssigrdataset, + &val->fetch); + if (result == ISC_R_SUCCESS) + result = DNS_R_WAIT; + else + result = DNS_R_NOTINSECURE; + } } else if (val->event->rdataset == NULL && val->event->sigrdataset == NULL) { /* * This is a nonexistence validation. */ - validator_log(val, ISC_LOG_DEBUG(3), + validator_log(val, ISC_LOG_DEBUG(VALDBL), "attempting negative response validation"); result = nxtvalidate(val, ISC_FALSE); @@ -1490,6 +1602,8 @@ dns_validator_create(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type, event->rdataset = rdataset; event->sigrdataset = sigrdataset; event->message = message; + dns_rdataset_init(&event->nsrdataset); + dns_rdataset_init(&event->nssigrdataset); result = isc_mutex_init(&val->lock); if (result != ISC_R_SUCCESS) goto cleanup_event; @@ -1537,7 +1651,7 @@ dns_validator_cancel(dns_validator_t *validator) { LOCK(&validator->lock); - validator_log(validator, ISC_LOG_DEBUG(3), "dns_validator_cancel"); + validator_log(validator, ISC_LOG_DEBUG(VALDBL), "dns_validator_cancel"); if (validator->event != NULL) { validator_done(validator, ISC_R_CANCELED); @@ -1592,7 +1706,7 @@ dns_validator_destroy(dns_validator_t **validatorp) { REQUIRE(val->event == NULL); - validator_log(val, ISC_LOG_DEBUG(3), "dns_validator_destroy"); + validator_log(val, ISC_LOG_DEBUG(VALDBL), "dns_validator_destroy"); val->attributes |= VALATTR_SHUTDOWN; if (val->fetch == NULL && val->keyvalidator == NULL && @@ -1660,4 +1774,3 @@ validator_log(dns_validator_t *val, int level, const char *fmt, ...) DNS_LOGMODULE_VALIDATOR, level, fmt, ap); va_end(ap); } -