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:
@@ -423,7 +423,6 @@ fetch_callback_validator(isc_task_t *task, isc_event_t *event) {
|
||||
saved_result = result;
|
||||
validator_log(val, ISC_LOG_DEBUG(3),
|
||||
"falling back to insecurity proof");
|
||||
val->attributes |= VALATTR_INSECURITY;
|
||||
result = proveunsecure(val, false, false);
|
||||
if (result == DNS_R_NOTINSECURE) {
|
||||
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
|
||||
dsfetched(isc_task_t *task, isc_event_t *event) {
|
||||
dns_fetchevent_t *devent;
|
||||
dns_validator_t *val;
|
||||
dns_rdataset_t *rdataset;
|
||||
bool want_destroy;
|
||||
bool want_destroy, trustchain;
|
||||
isc_result_t result;
|
||||
isc_result_t eresult;
|
||||
dns_fetch_t *fetch;
|
||||
@@ -477,6 +471,12 @@ dsfetched(isc_task_t *task, isc_event_t *event) {
|
||||
rdataset = &val->frdataset;
|
||||
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. */
|
||||
if (devent->node != NULL) {
|
||||
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)) {
|
||||
dns_rdataset_disassociate(&val->fsigrdataset);
|
||||
}
|
||||
isc_event_free(&event);
|
||||
|
||||
INSIST(val->event != NULL);
|
||||
|
||||
@@ -495,9 +494,31 @@ dsfetched(isc_task_t *task, isc_event_t *event) {
|
||||
LOCK(&val->lock);
|
||||
fetch = val->fetch;
|
||||
val->fetch = NULL;
|
||||
|
||||
if (CANCELED(val)) {
|
||||
validator_done(val, ISC_R_CANCELED);
|
||||
} else if (eresult == ISC_R_SUCCESS) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
switch (eresult) {
|
||||
case DNS_R_NXDOMAIN:
|
||||
case DNS_R_NCACHENXDOMAIN:
|
||||
/*
|
||||
* These results only make sense if we're attempting
|
||||
* an insecurity proof, not when walking a chain of trust.
|
||||
*/
|
||||
if (trustchain) {
|
||||
goto unexpected;
|
||||
}
|
||||
|
||||
/* FALLTHROUGH */
|
||||
case ISC_R_SUCCESS:
|
||||
if (trustchain) {
|
||||
/*
|
||||
* We looked for a DS record as part of
|
||||
* following a key chain upwards; resume following
|
||||
* the chain.
|
||||
*/
|
||||
validator_log(val, ISC_LOG_DEBUG(3),
|
||||
"dsset with trust %s",
|
||||
dns_trust_totext(rdataset->trust));
|
||||
@@ -506,22 +527,65 @@ dsfetched(isc_task_t *task, isc_event_t *event) {
|
||||
if (result != DNS_R_WAIT) {
|
||||
validator_done(val, result);
|
||||
}
|
||||
} else if (eresult == DNS_R_CNAME ||
|
||||
eresult == DNS_R_NXRRSET ||
|
||||
eresult == DNS_R_NCACHENXRRSET ||
|
||||
eresult == DNS_R_SERVFAIL) /* RFC 1034 parent? */
|
||||
{
|
||||
} 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);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case DNS_R_CNAME:
|
||||
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));
|
||||
val->attributes |= VALATTR_INSECURITY;
|
||||
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 {
|
||||
validator_log(val, ISC_LOG_DEBUG(3),
|
||||
"dsfetched: got %s",
|
||||
/*
|
||||
* 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));
|
||||
if (eresult == ISC_R_CANCELED) {
|
||||
validator_done(val, eresult);
|
||||
@@ -529,107 +593,7 @@ dsfetched(isc_task_t *task, isc_event_t *event) {
|
||||
validator_done(val, DNS_R_BROKENCHAIN);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
done:
|
||||
|
||||
isc_event_free(&event);
|
||||
want_destroy = exit_check(val);
|
||||
@@ -691,7 +655,6 @@ keyvalidated(isc_task_t *task, isc_event_t *event) {
|
||||
saved_result = result;
|
||||
validator_log(val, ISC_LOG_DEBUG(3),
|
||||
"falling back to insecurity proof");
|
||||
val->attributes |= VALATTR_INSECURITY;
|
||||
result = proveunsecure(val, false, false);
|
||||
if (result == DNS_R_NOTINSECURE) {
|
||||
result = saved_result;
|
||||
@@ -2743,7 +2706,6 @@ validate_nx(dns_validator_t *val, bool resume) {
|
||||
|
||||
validator_log(val, ISC_LOG_DEBUG(3),
|
||||
"nonexistence proof(s) not found");
|
||||
val->attributes |= VALATTR_INSECURITY;
|
||||
return (proveunsecure(val, false, false));
|
||||
}
|
||||
|
||||
@@ -2983,7 +2945,7 @@ seek_ds(dns_validator_t *val, isc_result_t *resp) {
|
||||
*/
|
||||
*resp = DNS_R_WAIT;
|
||||
result = create_fetch(val, tname, dns_rdatatype_ds,
|
||||
dsfetched2, "proveunsecure");
|
||||
dsfetched, "proveunsecure");
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
*resp = result;
|
||||
}
|
||||
@@ -3026,6 +2988,11 @@ proveunsecure(dns_validator_t *val, bool have_ds, bool resume) {
|
||||
dns_name_t *secroot = dns_fixedname_initname(&fixedsecroot);
|
||||
unsigned int labels;
|
||||
|
||||
/*
|
||||
* We're attempting to prove insecurity.
|
||||
*/
|
||||
val->attributes |= VALATTR_INSECURITY;
|
||||
|
||||
dns_name_copynf(val->event->name, secroot);
|
||||
|
||||
/*
|
||||
@@ -3159,7 +3126,6 @@ validator_start(isc_task_t *task, isc_event_t *event) {
|
||||
saved_result = result;
|
||||
validator_log(val, ISC_LOG_DEBUG(3),
|
||||
"falling back to insecurity proof");
|
||||
val->attributes |= VALATTR_INSECURITY;
|
||||
result = proveunsecure(val, false, false);
|
||||
if (result == DNS_R_NOTINSECURE) {
|
||||
result = saved_result;
|
||||
@@ -3176,7 +3142,6 @@ validator_start(isc_task_t *task, isc_event_t *event) {
|
||||
validator_log(val, ISC_LOG_DEBUG(3),
|
||||
"attempting insecurity proof");
|
||||
|
||||
val->attributes |= VALATTR_INSECURITY;
|
||||
result = proveunsecure(val, false, false);
|
||||
if (result == DNS_R_NOTINSECURE) {
|
||||
validator_log(val, ISC_LOG_INFO,
|
||||
|
Reference in New Issue
Block a user