From: Matthijs Mekking Date: Wed, 19 May 2021 13:32:56 +0000 (+0200) Subject: Add helpful function 'dns_zone_getdnsseckeys' X-Git-Tag: v9.17.16~8^2~10 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=40331a20c4703dce5f5a260950d48e9b8ce98d30;p=thirdparty%2Fbind9.git Add helpful function 'dns_zone_getdnsseckeys' This code gathers DNSSEC keys from key files and from the DNSKEY RRset. It is used for the 'rndc dnssec -status' command, but will also be needed for "checkds". Turn it into a function. --- diff --git a/bin/named/server.c b/bin/named/server.c index 42f82ba3aa9..10925c3c1c7 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -15043,8 +15043,8 @@ named_server_dnssec(named_server_t *server, isc_lex_t *lex, isc_result_t result = ISC_R_SUCCESS; dns_zone_t *zone = NULL; dns_kasp_t *kasp = NULL; - dns_dnsseckeylist_t keys, dnskeys; - dns_dnsseckey_t *key, *key_next = NULL; + dns_dnsseckeylist_t keys; + dns_dnsseckey_t *key; char *ptr, *zonetext = NULL; const char *msg = NULL; /* variables for -checkds */ @@ -15061,11 +15061,8 @@ named_server_dnssec(named_server_t *server, isc_lex_t *lex, isc_stdtime_t now, when; isc_time_t timenow, timewhen; const char *dir; - dns_name_t *origin; dns_db_t *db = NULL; - dns_dbnode_t *node = NULL; dns_dbversion_t *version = NULL; - dns_rdataset_t keyset; /* Skip the command name. */ ptr = next_token(lex, text); @@ -15084,9 +15081,7 @@ named_server_dnssec(named_server_t *server, isc_lex_t *lex, now = isc_time_seconds(&timenow); when = now; - ISC_LIST_INIT(dnskeys); ISC_LIST_INIT(keys); - dns_rdataset_init(&keyset); if (strcasecmp(ptr, "-status") == 0) { status = true; @@ -15199,44 +15194,14 @@ named_server_dnssec(named_server_t *server, isc_lex_t *lex, /* Get DNSSEC keys. */ dir = dns_zone_getkeydirectory(zone); - origin = dns_zone_getorigin(zone); CHECK(dns_zone_getdb(zone, &db)); - CHECK(dns_db_findnode(db, origin, false, &node)); dns_db_currentversion(db, &version); - /* Get keys from private key files. */ - dns_zone_lock_keyfiles(zone); - result = dns_dnssec_findmatchingkeys(dns_zone_getorigin(zone), dir, now, - dns_zone_getmctx(zone), &keys); - dns_zone_unlock_keyfiles(zone); - if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) { - goto cleanup; - } - /* Get public keys (dnskeys). */ - result = dns_db_findrdataset(db, node, version, dns_rdatatype_dnskey, - dns_rdatatype_none, 0, &keyset, NULL); - if (result == ISC_R_SUCCESS) { - CHECK(dns_dnssec_keylistfromrdataset( - origin, dir, dns_zone_getmctx(zone), &keyset, NULL, - NULL, false, false, &dnskeys)); - } else if (result != ISC_R_NOTFOUND) { - CHECK(result); - } - /* Add new 'dnskeys' to 'keys'. */ - for (dns_dnsseckey_t *k1 = ISC_LIST_HEAD(dnskeys); k1 != NULL; - k1 = key_next) { - dns_dnsseckey_t *k2 = NULL; - key_next = ISC_LIST_NEXT(k1, link); - - for (k2 = ISC_LIST_HEAD(keys); k2 != NULL; - k2 = ISC_LIST_NEXT(k2, link)) { - if (dst_key_compare(k1->key, k2->key)) { - break; - } - } - /* No match found, add the new key. */ - if (k2 == NULL) { - ISC_LIST_UNLINK(dnskeys, k1, link); - ISC_LIST_APPEND(keys, k1, link); + LOCK(&kasp->lock); + result = dns_zone_getdnsseckeys(zone, db, version, now, &keys); + UNLOCK(&kasp->lock); + if (result != ISC_R_SUCCESS) { + if (result != ISC_R_NOTFOUND) { + goto cleanup; } } @@ -15358,12 +15323,6 @@ cleanup: (void)putnull(text); } - if (dns_rdataset_isassociated(&keyset)) { - dns_rdataset_disassociate(&keyset); - } - if (node != NULL) { - dns_db_detachnode(db, &node); - } if (version != NULL) { dns_db_closeversion(db, &version, false); } @@ -15371,11 +15330,6 @@ cleanup: dns_db_detach(&db); } - while (!ISC_LIST_EMPTY(dnskeys)) { - key = ISC_LIST_HEAD(dnskeys); - ISC_LIST_UNLINK(dnskeys, key, link); - dns_dnsseckey_destroy(dns_zone_getmctx(zone), &key); - } while (!ISC_LIST_EMPTY(keys)) { key = ISC_LIST_HEAD(keys); ISC_LIST_UNLINK(keys, key, link); diff --git a/lib/dns/include/dns/zone.h b/lib/dns/include/dns/zone.h index 2002ea2e774..82d9e871508 100644 --- a/lib/dns/include/dns/zone.h +++ b/lib/dns/include/dns/zone.h @@ -1754,6 +1754,22 @@ dns_zone_getkeydirectory(dns_zone_t *zone); * Pointer to null-terminated file name, or NULL. */ +isc_result_t +dns_zone_getdnsseckeys(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, + isc_stdtime_t now, dns_dnsseckeylist_t *keys); +/*% + * Find DNSSEC keys used for signing with dnssec-policy. Load these keys + * into 'keys'. + * + * Requires: + *\li 'zone' to be valid initialised zone. + *\li 'keys' to be an initialised DNSSEC keylist. + * + * Returns: + *\li #ISC_R_SUCCESS + *\li Error + */ + isc_result_t dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr, isc_timermgr_t *timermgr, isc_socketmgr_t *socketmgr, diff --git a/lib/dns/zone.c b/lib/dns/zone.c index f3acf7364cd..1619b60d55d 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -6624,6 +6624,85 @@ failure: return (result); } +/*% + * Find DNSSEC keys used for signing zone with dnssec-policy. Load these keys + * into 'keys'. Requires KASP to be locked. + */ +isc_result_t +dns_zone_getdnsseckeys(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, + isc_stdtime_t now, dns_dnsseckeylist_t *keys) { + isc_result_t result; + const char *dir = dns_zone_getkeydirectory(zone); + dns_dbnode_t *node = NULL; + dns_dnsseckey_t *key, *key_next; + dns_dnsseckeylist_t dnskeys; + dns_name_t *origin = dns_zone_getorigin(zone); + dns_kasp_t *kasp = dns_zone_getkasp(zone); + dns_rdataset_t keyset; + + REQUIRE(DNS_ZONE_VALID(zone)); + REQUIRE(kasp != NULL); + + ISC_LIST_INIT(dnskeys); + + CHECK(dns_db_findnode(db, origin, false, &node)); + + /* Get keys from private key files. */ + dns_zone_lock_keyfiles(zone); + result = dns_dnssec_findmatchingkeys(origin, dir, now, + dns_zone_getmctx(zone), keys); + dns_zone_unlock_keyfiles(zone); + + if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) { + goto failure; + } + + /* Get public keys (dnskeys). */ + dns_rdataset_init(&keyset); + result = dns_db_findrdataset(db, node, ver, dns_rdatatype_dnskey, + dns_rdatatype_none, 0, &keyset, NULL); + if (result == ISC_R_SUCCESS) { + CHECK(dns_dnssec_keylistfromrdataset( + origin, dir, dns_zone_getmctx(zone), &keyset, NULL, + NULL, false, false, &dnskeys)); + } else if (result != ISC_R_NOTFOUND) { + CHECK(result); + } + + /* Add new 'dnskeys' to 'keys'. */ + for (dns_dnsseckey_t *k1 = ISC_LIST_HEAD(dnskeys); k1 != NULL; + k1 = key_next) { + dns_dnsseckey_t *k2 = NULL; + key_next = ISC_LIST_NEXT(k1, link); + + for (k2 = ISC_LIST_HEAD(*keys); k2 != NULL; + k2 = ISC_LIST_NEXT(k2, link)) { + if (dst_key_compare(k1->key, k2->key)) { + break; + } + } + /* No match found, add the new key. */ + if (k2 == NULL) { + ISC_LIST_UNLINK(dnskeys, k1, link); + ISC_LIST_APPEND(*keys, k1, link); + } + } + +failure: + if (dns_rdataset_isassociated(&keyset)) { + dns_rdataset_disassociate(&keyset); + } + if (node != NULL) { + dns_db_detachnode(db, &node); + } + while (!ISC_LIST_EMPTY(dnskeys)) { + key = ISC_LIST_HEAD(dnskeys); + ISC_LIST_UNLINK(dnskeys, key, link); + dns_dnsseckey_destroy(dns_zone_getmctx(zone), &key); + } + return (result); +} + static isc_result_t offline(dns_db_t *db, dns_dbversion_t *ver, dns__zonediff_t *zonediff, dns_name_t *name, dns_ttl_t ttl, dns_rdata_t *rdata) {