2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-31 14:35:26 +00:00

refactor dsfetched/dsfetched2 into a common function

This commit is contained in:
Evan Hunt
2019-08-07 17:26:35 -07:00
parent 3659cca624
commit ea1d4d11fc

View File

@@ -423,7 +423,6 @@ fetch_callback_validator(isc_task_t *task, isc_event_t *event) {
saved_result = result; saved_result = result;
validator_log(val, ISC_LOG_DEBUG(3), validator_log(val, ISC_LOG_DEBUG(3),
"falling back to insecurity proof"); "falling back to insecurity proof");
val->attributes |= VALATTR_INSECURITY;
result = proveunsecure(val, false, false); result = proveunsecure(val, false, false);
if (result == DNS_R_NOTINSECURE) { if (result == DNS_R_NOTINSECURE) {
result = saved_result; result = saved_result;
@@ -455,17 +454,12 @@ fetch_callback_validator(isc_task_t *task, isc_event_t *event) {
} }
} }
/*%
* We were asked to look for a DS record as part of following a key chain
* upwards. If found resume the validation process. If not found fail the
* validation process.
*/
static void static void
dsfetched(isc_task_t *task, isc_event_t *event) { dsfetched(isc_task_t *task, isc_event_t *event) {
dns_fetchevent_t *devent; dns_fetchevent_t *devent;
dns_validator_t *val; dns_validator_t *val;
dns_rdataset_t *rdataset; dns_rdataset_t *rdataset;
bool want_destroy; bool want_destroy, trustchain;
isc_result_t result; isc_result_t result;
isc_result_t eresult; isc_result_t eresult;
dns_fetch_t *fetch; dns_fetch_t *fetch;
@@ -477,6 +471,12 @@ dsfetched(isc_task_t *task, isc_event_t *event) {
rdataset = &val->frdataset; rdataset = &val->frdataset;
eresult = devent->result; eresult = devent->result;
/*
* Set to true if we're walking a chain of trust; false if
* we're attempting to prove insecurity.
*/
trustchain = ((val->attributes & VALATTR_INSECURITY) == 0);
/* Free resources which are not of interest. */ /* Free resources which are not of interest. */
if (devent->node != NULL) { if (devent->node != NULL) {
dns_db_detachnode(devent->db, &devent->node); dns_db_detachnode(devent->db, &devent->node);
@@ -487,7 +487,6 @@ dsfetched(isc_task_t *task, isc_event_t *event) {
if (dns_rdataset_isassociated(&val->fsigrdataset)) { if (dns_rdataset_isassociated(&val->fsigrdataset)) {
dns_rdataset_disassociate(&val->fsigrdataset); dns_rdataset_disassociate(&val->fsigrdataset);
} }
isc_event_free(&event);
INSIST(val->event != NULL); INSIST(val->event != NULL);
@@ -495,33 +494,98 @@ dsfetched(isc_task_t *task, isc_event_t *event) {
LOCK(&val->lock); LOCK(&val->lock);
fetch = val->fetch; fetch = val->fetch;
val->fetch = NULL; val->fetch = NULL;
if (CANCELED(val)) { if (CANCELED(val)) {
validator_done(val, ISC_R_CANCELED); validator_done(val, ISC_R_CANCELED);
} else if (eresult == ISC_R_SUCCESS) { goto done;
validator_log(val, ISC_LOG_DEBUG(3), }
"dsset with trust %s",
dns_trust_totext(rdataset->trust)); switch (eresult) {
val->dsset = &val->frdataset; case DNS_R_NXDOMAIN:
result = validatezonekey(val); case DNS_R_NCACHENXDOMAIN:
if (result != DNS_R_WAIT) { /*
validator_done(val, result); * These results only make sense if we're attempting
* an insecurity proof, not when walking a chain of trust.
*/
if (trustchain) {
goto unexpected;
} }
} else if (eresult == DNS_R_CNAME ||
eresult == DNS_R_NXRRSET || /* FALLTHROUGH */
eresult == DNS_R_NCACHENXRRSET || case ISC_R_SUCCESS:
eresult == DNS_R_SERVFAIL) /* RFC 1034 parent? */ if (trustchain) {
{ /*
validator_log(val, ISC_LOG_DEBUG(3), * We looked for a DS record as part of
"falling back to insecurity proof (%s)", * following a key chain upwards; resume following
dns_result_totext(eresult)); * the chain.
val->attributes |= VALATTR_INSECURITY; */
result = proveunsecure(val, false, false); validator_log(val, ISC_LOG_DEBUG(3),
if (result != DNS_R_WAIT) { "dsset with trust %s",
validator_done(val, result); dns_trust_totext(rdataset->trust));
val->dsset = &val->frdataset;
result = validatezonekey(val);
if (result != DNS_R_WAIT) {
validator_done(val, result);
}
} else {
/*
* There is a DS which may or may not be a zone cut.
* In either case we are still in a secure zone,
* so keep looking for the break in the chain
* of trust.
*/
result = proveunsecure(val, (eresult == ISC_R_SUCCESS),
true);
if (result != DNS_R_WAIT) {
validator_done(val, result);
}
} }
} else { break;
validator_log(val, ISC_LOG_DEBUG(3), case DNS_R_CNAME:
"dsfetched: got %s", case DNS_R_NXRRSET:
case DNS_R_NCACHENXRRSET:
case DNS_R_SERVFAIL: /* RFC 1034 parent? */
if (trustchain) {
/*
* Failed to find a DS while following the
* chain of trust; now we need to prove insecurity.
*/
validator_log(val, ISC_LOG_DEBUG(3),
"falling back to insecurity proof (%s)",
dns_result_totext(eresult));
result = proveunsecure(val, false, false);
if (result != DNS_R_WAIT) {
validator_done(val, result);
}
} else if (eresult == DNS_R_SERVFAIL) {
goto unexpected;
} else if (eresult != DNS_R_CNAME &&
isdelegation(dns_fixedname_name(&devent->foundname),
&val->frdataset, eresult))
{
/*
* Failed to find a DS while trying to prove
* insecurity. If this is a zone cut, that
* means we're insecure.
*/
result = markanswer(val, "dsfetched",
"no DS and this is a delegation");
validator_done(val, result);
} else {
/*
* Not a zone cut, so we have to keep looking for
* the break point in the chain of trust.
*/
result = proveunsecure(val, false, true);
if (result != DNS_R_WAIT) {
validator_done(val, result);
}
}
break;
default:
unexpected:
validator_log(val, ISC_LOG_DEBUG(3), "dsfetched: got %s",
isc_result_totext(eresult)); isc_result_totext(eresult));
if (eresult == ISC_R_CANCELED) { if (eresult == ISC_R_CANCELED) {
validator_done(val, eresult); validator_done(val, eresult);
@@ -529,107 +593,7 @@ dsfetched(isc_task_t *task, isc_event_t *event) {
validator_done(val, DNS_R_BROKENCHAIN); validator_done(val, DNS_R_BROKENCHAIN);
} }
} }
done:
want_destroy = exit_check(val);
UNLOCK(&val->lock);
if (fetch != NULL) {
dns_resolver_destroyfetch(&fetch);
}
if (want_destroy) {
destroy(val);
}
}
/*%
* We were asked to look for the DS record as part of proving that a
* name is unsecure.
*
* If the DS record doesn't exist and the query name corresponds to
* a delegation point we are transitioning from a secure zone to a
* unsecure zone.
*
* If the DS record exists it will be secure. We can continue looking
* for the break point in the chain of trust.
*/
static void
dsfetched2(isc_task_t *task, isc_event_t *event) {
dns_fetchevent_t *devent;
dns_validator_t *val;
dns_name_t *tname;
bool want_destroy;
isc_result_t result;
isc_result_t eresult;
dns_fetch_t *fetch;
UNUSED(task);
INSIST(event->ev_type == DNS_EVENT_FETCHDONE);
devent = (dns_fetchevent_t *)event;
val = devent->ev_arg;
eresult = devent->result;
/* Free resources which are not of interest. */
if (devent->node != NULL) {
dns_db_detachnode(devent->db, &devent->node);
}
if (devent->db != NULL) {
dns_db_detach(&devent->db);
}
if (dns_rdataset_isassociated(&val->fsigrdataset)) {
dns_rdataset_disassociate(&val->fsigrdataset);
}
INSIST(val->event != NULL);
validator_log(val, ISC_LOG_DEBUG(3), "in dsfetched2: %s",
dns_result_totext(eresult));
LOCK(&val->lock);
fetch = val->fetch;
val->fetch = NULL;
if (CANCELED(val)) {
validator_done(val, ISC_R_CANCELED);
} else if (eresult == DNS_R_CNAME ||
eresult == DNS_R_NXRRSET ||
eresult == DNS_R_NCACHENXRRSET)
{
/*
* There is no DS. If this is a delegation, we're done.
*/
tname = dns_fixedname_name(&devent->foundname);
if (eresult != DNS_R_CNAME &&
isdelegation(tname, &val->frdataset, eresult))
{
result = markanswer(val, "dsfetched2",
"no DS and this is a delegation");
validator_done(val, result);
} else {
result = proveunsecure(val, false, true);
if (result != DNS_R_WAIT) {
validator_done(val, result);
}
}
} else if (eresult == ISC_R_SUCCESS ||
eresult == DNS_R_NXDOMAIN ||
eresult == DNS_R_NCACHENXDOMAIN)
{
/*
* There is a DS which may or may not be a zone cut.
* In either case we are still in a secure zone resume
* validation.
*/
result = proveunsecure(val, (eresult == ISC_R_SUCCESS),
true);
if (result != DNS_R_WAIT) {
validator_done(val, result);
}
} else {
if (eresult == ISC_R_CANCELED) {
validator_done(val, eresult);
} else {
validator_done(val, DNS_R_NOVALIDDS);
}
}
isc_event_free(&event); isc_event_free(&event);
want_destroy = exit_check(val); want_destroy = exit_check(val);
@@ -691,7 +655,6 @@ keyvalidated(isc_task_t *task, isc_event_t *event) {
saved_result = result; saved_result = result;
validator_log(val, ISC_LOG_DEBUG(3), validator_log(val, ISC_LOG_DEBUG(3),
"falling back to insecurity proof"); "falling back to insecurity proof");
val->attributes |= VALATTR_INSECURITY;
result = proveunsecure(val, false, false); result = proveunsecure(val, false, false);
if (result == DNS_R_NOTINSECURE) { if (result == DNS_R_NOTINSECURE) {
result = saved_result; result = saved_result;
@@ -2743,7 +2706,6 @@ validate_nx(dns_validator_t *val, bool resume) {
validator_log(val, ISC_LOG_DEBUG(3), validator_log(val, ISC_LOG_DEBUG(3),
"nonexistence proof(s) not found"); "nonexistence proof(s) not found");
val->attributes |= VALATTR_INSECURITY;
return (proveunsecure(val, false, false)); return (proveunsecure(val, false, false));
} }
@@ -2983,7 +2945,7 @@ seek_ds(dns_validator_t *val, isc_result_t *resp) {
*/ */
*resp = DNS_R_WAIT; *resp = DNS_R_WAIT;
result = create_fetch(val, tname, dns_rdatatype_ds, result = create_fetch(val, tname, dns_rdatatype_ds,
dsfetched2, "proveunsecure"); dsfetched, "proveunsecure");
if (result != ISC_R_SUCCESS) { if (result != ISC_R_SUCCESS) {
*resp = result; *resp = result;
} }
@@ -3026,6 +2988,11 @@ proveunsecure(dns_validator_t *val, bool have_ds, bool resume) {
dns_name_t *secroot = dns_fixedname_initname(&fixedsecroot); dns_name_t *secroot = dns_fixedname_initname(&fixedsecroot);
unsigned int labels; unsigned int labels;
/*
* We're attempting to prove insecurity.
*/
val->attributes |= VALATTR_INSECURITY;
dns_name_copynf(val->event->name, secroot); dns_name_copynf(val->event->name, secroot);
/* /*
@@ -3159,7 +3126,6 @@ validator_start(isc_task_t *task, isc_event_t *event) {
saved_result = result; saved_result = result;
validator_log(val, ISC_LOG_DEBUG(3), validator_log(val, ISC_LOG_DEBUG(3),
"falling back to insecurity proof"); "falling back to insecurity proof");
val->attributes |= VALATTR_INSECURITY;
result = proveunsecure(val, false, false); result = proveunsecure(val, false, false);
if (result == DNS_R_NOTINSECURE) { if (result == DNS_R_NOTINSECURE) {
result = saved_result; result = saved_result;
@@ -3176,7 +3142,6 @@ validator_start(isc_task_t *task, isc_event_t *event) {
validator_log(val, ISC_LOG_DEBUG(3), validator_log(val, ISC_LOG_DEBUG(3),
"attempting insecurity proof"); "attempting insecurity proof");
val->attributes |= VALATTR_INSECURITY;
result = proveunsecure(val, false, false); result = proveunsecure(val, false, false);
if (result == DNS_R_NOTINSECURE) { if (result == DNS_R_NOTINSECURE) {
validator_log(val, ISC_LOG_INFO, validator_log(val, ISC_LOG_INFO,