3960. [bug] 'dig +sigchase' could loop forever. [RT #37220]

This commit is contained in:
Mark Andrews
2014-10-01 07:06:20 +10:00
parent fa827173df
commit c83b91fb63
8 changed files with 204 additions and 105 deletions

View File

@@ -4695,8 +4695,8 @@ get_trusted_key(isc_mem_t *mctx)
dns_rdatacallbacks_init_stdio(&callbacks);
callbacks.add = insert_trustedkey;
return (dns_master_loadfile(filename, dns_rootname, dns_rootname,
current_lookup->rdclass, 0, &callbacks,
mctx));
current_lookup->rdclass, DNS_MASTER_NOTTL,
&callbacks, mctx));
}
@@ -4896,36 +4896,36 @@ child_of_zone(dns_name_t * name, dns_name_t * zone_name,
}
isc_result_t
grandfather_pb_test(dns_name_t *zone_name, dns_rdataset_t *sigrdataset)
{
isc_result_t result;
dns_rdata_t sigrdata = DNS_RDATA_INIT;
grandfather_pb_test(dns_name_t *zone_name, dns_rdataset_t *sigrdataset) {
dns_rdata_sig_t siginfo;
dns_rdataset_t mysigrdataset;
isc_result_t result;
result = dns_rdataset_first(sigrdataset);
dns_rdataset_init(&mysigrdataset);
dns_rdataset_clone(sigrdataset, &mysigrdataset);
result = dns_rdataset_first(&mysigrdataset);
check_result(result, "empty RRSIG dataset");
dns_rdata_init(&sigrdata);
do {
dns_rdataset_current(sigrdataset, &sigrdata);
dns_rdata_t sigrdata = DNS_RDATA_INIT;
dns_rdataset_current(&mysigrdataset, &sigrdata);
result = dns_rdata_tostruct(&sigrdata, &siginfo, NULL);
check_result(result, "sigrdata tostruct siginfo");
if (dns_name_compare(&siginfo.signer, zone_name) == 0) {
dns_rdata_freestruct(&siginfo);
dns_rdata_reset(&sigrdata);
return (ISC_R_SUCCESS);
result = ISC_R_SUCCESS;
goto cleanup;
}
} while (dns_rdataset_next(&mysigrdataset) == ISC_R_SUCCESS);
dns_rdata_freestruct(&siginfo);
dns_rdata_reset(&sigrdata);
result = ISC_R_FAILURE;
cleanup:
dns_rdataset_disassociate(&mysigrdataset);
} while (dns_rdataset_next(chase_sigkeyrdataset) == ISC_R_SUCCESS);
dns_rdata_reset(&sigrdata);
return (ISC_R_FAILURE);
return (result);
}
@@ -5005,26 +5005,30 @@ contains_trusted_key(dns_name_t *name, dns_rdataset_t *rdataset,
dns_rdataset_t *sigrdataset,
isc_mem_t *mctx)
{
isc_result_t result;
dns_rdata_t rdata = DNS_RDATA_INIT;
dns_rdataset_t myrdataset;
dst_key_t *dnsseckey = NULL;
int i;
isc_result_t result;
if (name == NULL || rdataset == NULL)
return (ISC_R_FAILURE);
result = dns_rdataset_first(rdataset);
dns_rdataset_init(&myrdataset);
dns_rdataset_clone(rdataset, &myrdataset);
result = dns_rdataset_first(&myrdataset);
check_result(result, "empty rdataset");
do {
dns_rdataset_current(rdataset, &rdata);
dns_rdata_t rdata = DNS_RDATA_INIT;
dns_rdataset_current(&myrdataset, &rdata);
INSIST(rdata.type == dns_rdatatype_dnskey);
result = dns_dnssec_keyfromrdata(name, &rdata,
mctx, &dnsseckey);
check_result(result, "dns_dnssec_keyfromrdata");
for (i = 0; i < tk_list.nb_tk; i++) {
if (dst_key_compare(tk_list.key[i], dnsseckey)
== ISC_TRUE) {
@@ -5033,22 +5037,21 @@ contains_trusted_key(dns_name_t *name, dns_rdataset_t *rdataset,
printf(";; Ok, find a Trusted Key in the "
"DNSKEY RRset: %d\n",
dst_key_id(dnsseckey));
if (sigchase_verify_sig_key(name, rdataset,
dnsseckey,
sigrdataset,
mctx)
== ISC_R_SUCCESS) {
dst_key_free(&dnsseckey);
dnsseckey = NULL;
return (ISC_R_SUCCESS);
}
result = sigchase_verify_sig_key(name, rdataset,
dnsseckey,
sigrdataset,
mctx);
if (result == ISC_R_SUCCESS)
goto cleanup;
}
}
dst_key_free(&dnsseckey);
} while (dns_rdataset_next(&myrdataset) == ISC_R_SUCCESS);
dns_rdata_reset(&rdata);
if (dnsseckey != NULL)
dst_key_free(&dnsseckey);
} while (dns_rdataset_next(rdataset) == ISC_R_SUCCESS);
cleanup:
if (dnsseckey != NULL)
dst_key_free(&dnsseckey);
dns_rdataset_disassociate(&myrdataset);
return (ISC_R_NOTFOUND);
}
@@ -5059,16 +5062,20 @@ sigchase_verify_sig(dns_name_t *name, dns_rdataset_t *rdataset,
dns_rdataset_t *sigrdataset,
isc_mem_t *mctx)
{
isc_result_t result;
dns_rdata_t keyrdata = DNS_RDATA_INIT;
dns_rdataset_t mykeyrdataset;
dst_key_t *dnsseckey = NULL;
isc_result_t result;
result = dns_rdataset_first(keyrdataset);
dns_rdataset_init(&mykeyrdataset);
dns_rdataset_clone(keyrdataset, &mykeyrdataset);
result = dns_rdataset_first(&mykeyrdataset);
check_result(result, "empty DNSKEY dataset");
dns_rdata_init(&keyrdata);
do {
dns_rdataset_current(keyrdataset, &keyrdata);
dns_rdata_t keyrdata = DNS_RDATA_INIT;
dns_rdataset_current(&mykeyrdataset, &keyrdata);
INSIST(keyrdata.type == dns_rdatatype_dnskey);
result = dns_dnssec_keyfromrdata(name, &keyrdata,
@@ -5077,18 +5084,19 @@ sigchase_verify_sig(dns_name_t *name, dns_rdataset_t *rdataset,
result = sigchase_verify_sig_key(name, rdataset, dnsseckey,
sigrdataset, mctx);
if (result == ISC_R_SUCCESS) {
dns_rdata_reset(&keyrdata);
dst_key_free(&dnsseckey);
return (ISC_R_SUCCESS);
}
if (result == ISC_R_SUCCESS)
goto cleanup;
dst_key_free(&dnsseckey);
dns_rdata_reset(&keyrdata);
} while (dns_rdataset_next(chase_keyrdataset) == ISC_R_SUCCESS);
} while (dns_rdataset_next(&mykeyrdataset) == ISC_R_SUCCESS);
dns_rdata_reset(&keyrdata);
result = ISC_R_NOTFOUND;
return (ISC_R_NOTFOUND);
cleanup:
if (dnsseckey != NULL)
dst_key_free(&dnsseckey);
dns_rdataset_disassociate(&mykeyrdataset);
return (result);
}
isc_result_t
@@ -5096,16 +5104,23 @@ sigchase_verify_sig_key(dns_name_t *name, dns_rdataset_t *rdataset,
dst_key_t *dnsseckey, dns_rdataset_t *sigrdataset,
isc_mem_t *mctx)
{
isc_result_t result;
dns_rdata_t sigrdata = DNS_RDATA_INIT;
dns_rdata_sig_t siginfo;
dns_rdataset_t myrdataset;
dns_rdataset_t mysigrdataset;
isc_result_t result;
result = dns_rdataset_first(sigrdataset);
dns_rdataset_init(&myrdataset);
dns_rdataset_clone(rdataset, &myrdataset);
dns_rdataset_init(&mysigrdataset);
dns_rdataset_clone(sigrdataset, &mysigrdataset);
result = dns_rdataset_first(&mysigrdataset);
check_result(result, "empty RRSIG dataset");
dns_rdata_init(&sigrdata);
do {
dns_rdataset_current(sigrdataset, &sigrdata);
dns_rdata_t sigrdata = DNS_RDATA_INIT;
dns_rdataset_current(&mysigrdataset, &sigrdata);
result = dns_rdata_tostruct(&sigrdata, &siginfo, NULL);
check_result(result, "sigrdata tostruct siginfo");
@@ -5116,10 +5131,10 @@ sigchase_verify_sig_key(dns_name_t *name, dns_rdataset_t *rdataset,
*/
if (siginfo.keyid == dst_key_id(dnsseckey)) {
result = dns_rdataset_first(rdataset);
result = dns_rdataset_first(&myrdataset);
check_result(result, "empty DS dataset");
result = dns_dnssec_verify(name, rdataset, dnsseckey,
result = dns_dnssec_verify(name, &myrdataset, dnsseckey,
ISC_FALSE, mctx, &sigrdata);
printf(";; VERIFYING ");
@@ -5129,19 +5144,18 @@ sigchase_verify_sig_key(dns_name_t *name, dns_rdataset_t *rdataset,
printf(" with DNSKEY:%d: %s\n", dst_key_id(dnsseckey),
isc_result_totext(result));
if (result == ISC_R_SUCCESS) {
dns_rdata_reset(&sigrdata);
return (result);
}
if (result == ISC_R_SUCCESS)
goto cleanup;
}
dns_rdata_freestruct(&siginfo);
dns_rdata_reset(&sigrdata);
} while (dns_rdataset_next(&mysigrdataset) == ISC_R_SUCCESS);
} while (dns_rdataset_next(chase_sigkeyrdataset) == ISC_R_SUCCESS);
result = ISC_R_NOTFOUND;
dns_rdata_reset(&sigrdata);
cleanup:
dns_rdataset_disassociate(&myrdataset);
dns_rdataset_disassociate(&mysigrdataset);
return (ISC_R_NOTFOUND);
return (result);
}
@@ -5149,27 +5163,35 @@ isc_result_t
sigchase_verify_ds(dns_name_t *name, dns_rdataset_t *keyrdataset,
dns_rdataset_t *dsrdataset, isc_mem_t *mctx)
{
isc_result_t result;
dns_rdata_t keyrdata = DNS_RDATA_INIT;
dns_rdata_t newdsrdata = DNS_RDATA_INIT;
dns_rdata_t dsrdata = DNS_RDATA_INIT;
dns_rdata_ds_t dsinfo;
dns_rdataset_t mydsrdataset;
dns_rdataset_t mykeyrdataset;
dst_key_t *dnsseckey = NULL;
isc_result_t result;
unsigned char dsbuf[DNS_DS_BUFFERSIZE];
result = dns_rdataset_first(dsrdataset);
dns_rdataset_init(&mydsrdataset);
dns_rdataset_clone(dsrdataset, &mydsrdataset);
dns_rdataset_init(&mykeyrdataset);
dns_rdataset_clone(keyrdataset, &mykeyrdataset);
result = dns_rdataset_first(&mydsrdataset);
check_result(result, "empty DSset dataset");
do {
dns_rdataset_current(dsrdataset, &dsrdata);
dns_rdata_t dsrdata = DNS_RDATA_INIT;
dns_rdataset_current(&mydsrdataset, &dsrdata);
result = dns_rdata_tostruct(&dsrdata, &dsinfo, NULL);
check_result(result, "dns_rdata_tostruct for DS");
result = dns_rdataset_first(keyrdataset);
result = dns_rdataset_first(&mykeyrdataset);
check_result(result, "empty KEY dataset");
do {
dns_rdataset_current(keyrdataset, &keyrdata);
dns_rdata_t keyrdata = DNS_RDATA_INIT;
dns_rdataset_current(&mykeyrdataset, &keyrdata);
INSIST(keyrdata.type == dns_rdatatype_dnskey);
result = dns_dnssec_keyfromrdata(name, &keyrdata,
@@ -5181,6 +5203,7 @@ sigchase_verify_ds(dns_name_t *name, dns_rdataset_t *keyrdataset,
* id of DNSKEY referenced by the DS
*/
if (dsinfo.key_tag == dst_key_id(dnsseckey)) {
dns_rdata_t newdsrdata = DNS_RDATA_INIT;
result = dns_ds_buildrdata(name, &keyrdata,
dsinfo.digest_type,
@@ -5188,14 +5211,9 @@ sigchase_verify_ds(dns_name_t *name, dns_rdataset_t *keyrdataset,
dns_rdata_freestruct(&dsinfo);
if (result != ISC_R_SUCCESS) {
dns_rdata_reset(&keyrdata);
dns_rdata_reset(&newdsrdata);
dns_rdata_reset(&dsrdata);
dst_key_free(&dnsseckey);
dns_rdata_freestruct(&dsinfo);
printf("Oops: impossible to build"
" new DS rdata\n");
return (result);
goto cleanup;
}
@@ -5212,34 +5230,26 @@ sigchase_verify_ds(dns_name_t *name, dns_rdataset_t *keyrdataset,
dnsseckey,
chase_sigkeyrdataset,
mctx);
if (result == ISC_R_SUCCESS) {
dns_rdata_reset(&keyrdata);
dns_rdata_reset(&newdsrdata);
dns_rdata_reset(&dsrdata);
dst_key_free(&dnsseckey);
return (result);
}
if (result == ISC_R_SUCCESS)
goto cleanup;
} else {
printf(";; This DS is NOT the DS for"
" the chasing KEY: FAILED\n");
}
dns_rdata_reset(&newdsrdata);
}
dst_key_free(&dnsseckey);
dns_rdata_reset(&keyrdata);
dnsseckey = NULL;
} while (dns_rdataset_next(chase_keyrdataset) == ISC_R_SUCCESS);
dns_rdata_reset(&dsrdata);
} while (dns_rdataset_next(&mykeyrdataset) == ISC_R_SUCCESS);
} while (dns_rdataset_next(&mydsrdataset) == ISC_R_SUCCESS);
} while (dns_rdataset_next(chase_dsrdataset) == ISC_R_SUCCESS);
result = ISC_R_NOTFOUND;
dns_rdata_reset(&keyrdata);
dns_rdata_reset(&newdsrdata);
dns_rdata_reset(&dsrdata);
cleanup:
if (dnsseckey != NULL)
dst_key_free(&dnsseckey);
dns_rdataset_disassociate(&mydsrdataset);
dns_rdataset_disassociate(&mykeyrdataset);
return (ISC_R_NOTFOUND);
return (result);
}
/*
@@ -5722,7 +5732,7 @@ getneededrr(dns_message_t *msg)
dns_rdatatype_dnskey,
&chase_sigkeylookedup);
if (result == ISC_R_FAILURE) {
printf("\n;; RRSIG for DNSKEY is missing to continue"
printf("\n;; RRSIG for DNSKEY is missing to continue"
" validation : FAILED\n\n");
free_name(&chase_signame, mctx);
if (dns_name_dynamic(&chase_name))
@@ -5742,9 +5752,8 @@ getneededrr(dns_message_t *msg)
if (chase_dsrdataset == NULL) {
result = advanced_rrsearch(&chase_dsrdataset, &chase_signame,
dns_rdatatype_ds,
dns_rdatatype_any,
&chase_dslookedup);
dns_rdatatype_ds, dns_rdatatype_any,
&chase_dslookedup);
if (result == ISC_R_FAILURE) {
printf("\n;; WARNING There is no DS for the zone: ");
dns_name_print(&chase_signame, stdout);
@@ -6032,7 +6041,6 @@ prove_nx_domain(dns_message_t *msg,
result = dns_rdataset_next(nsecset)) {
dns_rdataset_current(nsecset, &nsec);
signsecset
= chase_scanname_section(msg, nsecname,
dns_rdatatype_rrsig,