]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Add helpful function 'dns_zone_getdnsseckeys'
authorMatthijs Mekking <matthijs@isc.org>
Wed, 19 May 2021 13:32:56 +0000 (15:32 +0200)
committerMatthijs Mekking <matthijs@isc.org>
Wed, 30 Jun 2021 15:28:48 +0000 (17:28 +0200)
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.

bin/named/server.c
lib/dns/include/dns/zone.h
lib/dns/zone.c

index 42f82ba3aa9862a9b25aca87b8858ff0032c46ce..10925c3c1c7c4a9058ea16d02a8f95164d81d969 100644 (file)
@@ -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);
index 2002ea2e7742f09ecc060603e545cc1c6f5d8877..82d9e8715085feea32e740501366b85221c96f12 100644 (file)
@@ -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,
index f3acf7364cdafe2e8ca0fdaf40d54dcf4eec5563..1619b60d55d450a0c190971ef4bce602291d9261 100644 (file)
@@ -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) {