Commit edafbf1c authored by Evan Hunt's avatar Evan Hunt
Browse files

fix root key sentinel code to send the correct key ID for DS trust anchors

parent 8aaee265
......@@ -6824,35 +6824,55 @@ struct dotat_arg {
* reported in the TAT query.
*/
static isc_result_t
get_tat_qname(dns_name_t *dst, const dns_name_t **origin,
get_tat_qname(dns_name_t *target, dns_name_t *keyname,
dns_keytable_t *keytable, dns_keynode_t *keynode)
{
dns_keynode_t *firstnode = keynode;
dns_keynode_t *nextnode;
dns_keynode_t *nextnode = NULL;
dns_rdataset_t *dsset = NULL;
unsigned int i, n = 0;
uint16_t ids[12];
isc_textregion_t r;
char label[64];
int m;
REQUIRE(origin != NULL && *origin == NULL);
if ((dsset = dns_keynode_dsset(keynode)) != NULL) {
isc_result_t result;
do {
dst_key_t *key = dns_keynode_key(keynode);
if (key != NULL) {
*origin = dst_key_name(key);
for (result = dns_rdataset_first(dsset);
result == ISC_R_SUCCESS;
result = dns_rdataset_next(dsset))
{
dns_rdata_t rdata = DNS_RDATA_INIT;
dns_rdata_ds_t ds;
dns_rdata_reset(&rdata);
dns_rdataset_current(dsset, &rdata);
result = dns_rdata_tostruct(&rdata, &ds, NULL);
RUNTIME_CHECK(result == ISC_R_SUCCESS);
if (n < (sizeof(ids)/sizeof(ids[0]))) {
ids[n] = dst_key_id(key);
ids[n] = ds.key_tag;
n++;
}
}
nextnode = NULL;
(void)dns_keytable_nextkeynode(keytable, keynode, &nextnode);
if (keynode != firstnode) {
dns_keytable_detachkeynode(keytable, &keynode);
}
keynode = nextnode;
} while (keynode != NULL);
} else {
do {
dst_key_t *key = dns_keynode_key(keynode);
if (key != NULL) {
if (n < (sizeof(ids)/sizeof(ids[0]))) {
ids[n] = dst_key_id(key);
n++;
}
}
nextnode = NULL;
(void)dns_keytable_nextkeynode(keytable, keynode,
&nextnode);
if (keynode != firstnode) {
dns_keytable_detachkeynode(keytable, &keynode);
}
keynode = nextnode;
} while (keynode != NULL);
}
if (n == 0) {
return (DNS_R_EMPTYNAME);
......@@ -6882,16 +6902,15 @@ get_tat_qname(dns_name_t *dst, const dns_name_t **origin,
isc_textregion_consume(&r, m);
}
return (dns_name_fromstring2(dst, label, *origin, 0, NULL));
return (dns_name_fromstring2(target, label, keyname, 0, NULL));
}
static void
dotat(dns_keytable_t *keytable, dns_keynode_t *keynode,
dns_name_t *name, void *arg)
dns_name_t *keyname, void *arg)
{
struct dotat_arg *dotat_arg = arg;
char namebuf[DNS_NAME_FORMATSIZE];
const dns_name_t *origin = NULL;
dns_fixedname_t fixed, fdomain;
dns_name_t *tatname, *domain;
dns_rdataset_t nameservers;
......@@ -6904,13 +6923,11 @@ dotat(dns_keytable_t *keytable, dns_keynode_t *keynode,
REQUIRE(keynode != NULL);
REQUIRE(dotat_arg != NULL);
UNUSED(name);
view = dotat_arg->view;
task = dotat_arg->task;
tatname = dns_fixedname_initname(&fixed);
result = get_tat_qname(tatname, &origin, keytable, keynode);
result = get_tat_qname(tatname, keyname, keytable, keynode);
if (result != ISC_R_SUCCESS) {
return;
}
......@@ -6948,17 +6965,13 @@ dotat(dns_keytable_t *keytable, dns_keynode_t *keynode,
* order to eventually find the destination host to send the TAT query
* to.
*
* 'origin' holds the domain name at 'keynode', i.e. the domain name
* for which the trust anchors to be reported by this TAT query are
* defined.
*
* After the dns_view_findzonecut() call, 'domain' will hold the
* deepest zone cut we can find for 'origin' while 'nameservers' will
* deepest zone cut we can find for 'keyname' while 'nameservers' will
* hold the NS RRset at that zone cut.
*/
domain = dns_fixedname_initname(&fdomain);
dns_rdataset_init(&nameservers);
result = dns_view_findzonecut(view, origin, domain, NULL, 0, 0,
result = dns_view_findzonecut(view, keyname, domain, NULL, 0, 0,
true, true, &nameservers, NULL);
if (result == ISC_R_SUCCESS) {
result = dns_resolver_createfetch(view->resolver, tatname,
......
......@@ -6596,6 +6596,8 @@ static bool
has_ta(query_ctx_t *qctx) {
dns_keytable_t *keytable = NULL;
dns_keynode_t *keynode = NULL;
dns_rdataset_t *dsset = NULL;
dns_keytag_t sentinel = qctx->client->query.root_key_sentinel_keyid;
isc_result_t result;
result = dns_view_getsecroots(qctx->view, &keytable);
......@@ -6604,10 +6606,38 @@ has_ta(query_ctx_t *qctx) {
}
result = dns_keytable_find(keytable, dns_rootname, &keynode);
if (result != ISC_R_SUCCESS) {
if (keynode != NULL) {
dns_keytable_detachkeynode(keytable, &keynode);
}
dns_keytable_detach(&keytable);
return (false);
}
if ((dsset = dns_keynode_dsset(keynode)) != NULL) {
for (result = dns_rdataset_first(dsset);
result == ISC_R_SUCCESS;
result = dns_rdataset_next(dsset))
{
dns_rdata_t rdata = DNS_RDATA_INIT;
dns_rdata_ds_t ds;
dns_rdata_reset(&rdata);
dns_rdataset_current(dsset, &rdata);
result = dns_rdata_tostruct(&rdata, &ds, NULL);
RUNTIME_CHECK(result == ISC_R_SUCCESS);
if (ds.key_tag == sentinel) {
dns_keytable_detachkeynode(keytable, &keynode);
dns_keytable_detach(&keytable);
return (true);
}
}
}
while (result == ISC_R_SUCCESS) {
dns_keynode_t *nextnode = NULL;
dns_keytag_t keyid = dst_key_id(dns_keynode_key(keynode));
if (keyid == qctx->client->query.root_key_sentinel_keyid) {
if (keyid == sentinel) {
dns_keytable_detachkeynode(keytable, &keynode);
dns_keytable_detach(&keytable);
return (true);
......@@ -6616,8 +6646,11 @@ has_ta(query_ctx_t *qctx) {
dns_keytable_detachkeynode(keytable, &keynode);
keynode = nextnode;
}
dns_keytable_detach(&keytable);
if (keynode != NULL) {
dns_keytable_detachkeynode(keytable, &keynode);
}
dns_keytable_detach(&keytable);
return (false);
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment