From: Evan Hunt Date: Wed, 18 Sep 2019 20:04:07 +0000 (-0700) Subject: fix root key sentinel code to send the correct key ID for DS trust anchors X-Git-Tag: v9.15.6~7^2~4 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=edafbf1c0f37149f61eeb465d84c9d998c680c37;p=thirdparty%2Fbind9.git fix root key sentinel code to send the correct key ID for DS trust anchors --- diff --git a/bin/named/server.c b/bin/named/server.c index 6e96359fa74..1e15368e3ab 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -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, diff --git a/lib/ns/query.c b/lib/ns/query.c index 7adf04d96f4..7bf8df49948 100644 --- a/lib/ns/query.c +++ b/lib/ns/query.c @@ -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); }