]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Add synth-from-dnssec namespaces for keytable entries
authorMark Andrews <marka@isc.org>
Fri, 17 Jun 2022 00:40:47 +0000 (10:40 +1000)
committerMark Andrews <marka@isc.org>
Wed, 6 Jul 2022 21:47:45 +0000 (07:47 +1000)
We do this by adding callbacks for when a node is added or deleted
from the keytable.  dns_keytable_add and dns_keytable_delete where
extended to take a callback.  dns_keytable_deletekey does not remove
the node so it was not extended.

(cherry picked from commit a5b57ed2934cd467ba9d8472dc318624b3864bd0)

bin/named/server.c
lib/dns/client.c
lib/dns/include/dns/keytable.h
lib/dns/keytable.c
lib/dns/zone.c
tests/dns/keytable_test.c

index 73dcdacbb12225f2e915f882b09c7d1e5499b835..552434379e0c8929c0f307d3f48c163bf68a2190 100644 (file)
@@ -876,6 +876,13 @@ cleanup:
        return (result);
 }
 
+static void
+sfd_add(const dns_name_t *name, void *arg) {
+       if (arg != NULL) {
+               dns_view_sfd_add(arg, name);
+       }
+}
+
 /*%
  * Parse 'key' in the context of view configuration 'vconfig'.  If successful,
  * add the key to 'secroots' if both of the following conditions are true:
@@ -889,8 +896,7 @@ cleanup:
  */
 static isc_result_t
 process_key(const cfg_obj_t *key, dns_keytable_t *secroots,
-           const dns_name_t *keyname_match, dns_resolver_t *resolver,
-           bool managed) {
+           const dns_name_t *keyname_match, dns_view_t *view, bool managed) {
        dns_fixedname_t fkeyname;
        dns_name_t *keyname = NULL;
        const char *namestr = NULL;
@@ -963,8 +969,8 @@ process_key(const cfg_obj_t *key, dns_keytable_t *secroots,
         * its owner name.  If it does not, do not load the key and log a
         * warning, but do not prevent further keys from being processed.
         */
-       if (!dns_resolver_algorithm_supported(resolver, keyname, ds.algorithm))
-       {
+       if (!dns_resolver_algorithm_supported(view->resolver, keyname,
+                                             ds.algorithm)) {
                cfg_obj_log(key, named_g_lctx, ISC_LOG_WARNING,
                            "ignoring %s for '%s': algorithm is disabled",
                            initializing ? "initial-key" : "static-key",
@@ -980,7 +986,7 @@ process_key(const cfg_obj_t *key, dns_keytable_t *secroots,
         * 'managed' and 'initializing' arguments to dns_keytable_add().
         */
        result = dns_keytable_add(secroots, initializing, initializing, keyname,
-                                 &ds);
+                                 &ds, sfd_add, view);
 
 done:
        return (result);
@@ -1008,7 +1014,7 @@ load_view_keys(const cfg_obj_t *keys, dns_view_t *view, bool managed,
                for (elt2 = cfg_list_first(keylist); elt2 != NULL;
                     elt2 = cfg_list_next(elt2)) {
                        CHECK(process_key(cfg_listelt_value(elt2), secroots,
-                                         keyname, view->resolver, managed));
+                                         keyname, view, managed));
                }
        }
 
index 4385aa1db4757df976fd994d02556f43f720dbac..bf8d69c559cc9ccc913310328a7d4f00b075e04e 100644 (file)
@@ -1311,7 +1311,7 @@ dns_client_addtrustedkey(dns_client_t *client, dns_rdataclass_t rdclass,
                                          digest, &ds));
        }
 
-       CHECK(dns_keytable_add(secroots, false, false, name, &ds));
+       CHECK(dns_keytable_add(secroots, false, false, name, &ds, NULL, NULL));
 
 cleanup:
        if (view != NULL) {
index 94db94658c1b3a33071b3926450f55c043f009dd..6095a85e3fae6e9d59303330033ba29202bc0930 100644 (file)
@@ -49,6 +49,8 @@
 
 ISC_LANG_BEGINDECLS
 
+typedef void (*dns_keytable_callback_t)(const dns_name_t *name, void *fn_arg);
+
 isc_result_t
 dns_keytable_create(isc_mem_t *mctx, dns_keytable_t **keytablep);
 /*%<
@@ -106,7 +108,8 @@ dns_keytable_detach(dns_keytable_t **keytablep);
 
 isc_result_t
 dns_keytable_add(dns_keytable_t *keytable, bool managed, bool initial,
-                dns_name_t *name, dns_rdata_ds_t *ds);
+                dns_name_t *name, dns_rdata_ds_t *ds,
+                dns_keytable_callback_t callback, void *callback_arg);
 /*%<
  * Add a key to 'keytable'. The keynode associated with 'name'
  * is updated with the DS specified in 'ds'.
@@ -167,7 +170,8 @@ dns_keytable_marksecure(dns_keytable_t *keytable, const dns_name_t *name);
  */
 
 isc_result_t
-dns_keytable_delete(dns_keytable_t *keytable, const dns_name_t *keyname);
+dns_keytable_delete(dns_keytable_t *keytable, const dns_name_t *keyname,
+                   dns_keytable_callback_t callback, void *callback_arg);
 /*%<
  * Delete all trust anchors from 'keytable' matching name 'keyname'
  *
index 324b4efc53b7ff5e60b9f2818f8f2788e1362deb..9172d51dd03220ee8178a8a1c4e4d3370a315609 100644 (file)
@@ -367,7 +367,8 @@ new_keynode(dns_rdata_ds_t *ds, dns_keytable_t *keytable, bool managed,
  */
 static isc_result_t
 insert(dns_keytable_t *keytable, bool managed, bool initial,
-       const dns_name_t *keyname, dns_rdata_ds_t *ds) {
+       const dns_name_t *keyname, dns_rdata_ds_t *ds,
+       dns_keytable_callback_t callback, void *callback_arg) {
        dns_rbtnode_t *node = NULL;
        isc_result_t result;
 
@@ -384,6 +385,9 @@ insert(dns_keytable_t *keytable, bool managed, bool initial,
                 * and attach it to the created node.
                 */
                node->data = new_keynode(ds, keytable, managed, initial);
+               if (callback != NULL) {
+                       (*callback)(keyname, callback_arg);
+               }
        } else if (result == ISC_R_EXISTS) {
                /*
                 * A node already exists for "keyname" in "keytable".
@@ -393,6 +397,9 @@ insert(dns_keytable_t *keytable, bool managed, bool initial,
                        if (knode == NULL) {
                                node->data = new_keynode(ds, keytable, managed,
                                                         initial);
+                               if (callback != NULL) {
+                                       (*callback)(keyname, callback_arg);
+                               }
                        } else {
                                add_ds(knode, ds, keytable->mctx);
                        }
@@ -407,20 +414,23 @@ insert(dns_keytable_t *keytable, bool managed, bool initial,
 
 isc_result_t
 dns_keytable_add(dns_keytable_t *keytable, bool managed, bool initial,
-                dns_name_t *name, dns_rdata_ds_t *ds) {
+                dns_name_t *name, dns_rdata_ds_t *ds,
+                dns_keytable_callback_t callback, void *callback_arg) {
        REQUIRE(ds != NULL);
        REQUIRE(!initial || managed);
 
-       return (insert(keytable, managed, initial, name, ds));
+       return (insert(keytable, managed, initial, name, ds, callback,
+                      callback_arg));
 }
 
 isc_result_t
 dns_keytable_marksecure(dns_keytable_t *keytable, const dns_name_t *name) {
-       return (insert(keytable, true, false, name, NULL));
+       return (insert(keytable, true, false, name, NULL, NULL, NULL));
 }
 
 isc_result_t
-dns_keytable_delete(dns_keytable_t *keytable, const dns_name_t *keyname) {
+dns_keytable_delete(dns_keytable_t *keytable, const dns_name_t *keyname,
+                   dns_keytable_callback_t callback, void *callback_arg) {
        isc_result_t result;
        dns_rbtnode_t *node = NULL;
 
@@ -434,6 +444,9 @@ dns_keytable_delete(dns_keytable_t *keytable, const dns_name_t *keyname) {
                if (node->data != NULL) {
                        result = dns_rbt_deletenode(keytable->table, node,
                                                    false);
+                       if (callback != NULL) {
+                               (*callback)(keyname, callback_arg);
+                       }
                } else {
                        result = ISC_R_NOTFOUND;
                }
index 03b3e26d78582077fbe1ceab1e5b03d27911b9b9..6796f8b49900b4530d8c625cfd72257ccf1dd030 100644 (file)
@@ -4282,6 +4282,23 @@ compute_tag(dns_name_t *name, dns_rdata_dnskey_t *dnskey, isc_mem_t *mctx,
        return (result);
 }
 
+/*
+ * Synth-from-dnssec callbacks to add/delete names from namespace tree.
+ */
+static void
+sfd_add(const dns_name_t *name, void *arg) {
+       if (arg != NULL) {
+               dns_view_sfd_add(arg, name);
+       }
+}
+
+static void
+sfd_del(const dns_name_t *name, void *arg) {
+       if (arg != NULL) {
+               dns_view_sfd_del(arg, name);
+       }
+}
+
 /*
  * Add key to the security roots.
  */
@@ -4306,7 +4323,8 @@ trust_key(dns_zone_t *zone, dns_name_t *keyname, dns_rdata_dnskey_t *dnskey,
                             dns_rdatatype_dnskey, dnskey, &buffer);
        CHECK(dns_ds_fromkeyrdata(keyname, &rdata, DNS_DSDIGEST_SHA256, digest,
                                  &ds));
-       CHECK(dns_keytable_add(sr, true, initial, keyname, &ds));
+       CHECK(dns_keytable_add(sr, true, initial, keyname, &ds, sfd_add,
+                              zone->view));
 
        dns_keytable_detach(&sr);
 
@@ -4351,7 +4369,7 @@ load_secroots(dns_zone_t *zone, dns_name_t *name, dns_rdataset_t *rdataset) {
 
        result = dns_view_getsecroots(zone->view, &sr);
        if (result == ISC_R_SUCCESS) {
-               dns_keytable_delete(sr, name);
+               dns_keytable_delete(sr, name, sfd_del, zone->view);
                dns_keytable_detach(&sr);
        }
 
index 0afb6bf68af5905de3ac447b1d48c9ba98e8dec1..615f90eaab8ed168244ea2e1baa33282a27c9dc4 100644 (file)
@@ -152,15 +152,14 @@ create_dsstruct(dns_name_t *name, uint16_t flags, uint8_t proto, uint8_t alg,
 /* Common setup: create a keytable and ntatable to test with a few keys */
 static void
 create_tables(void) {
-       isc_result_t result;
        unsigned char digest[ISC_MAX_MD_SIZE];
        dns_rdata_ds_t ds;
        dns_fixedname_t fn;
        dns_name_t *keyname = dns_fixedname_name(&fn);
        isc_stdtime_t now;
 
-       result = dns_test_makeview("view", false, &view);
-       assert_int_equal(result, ISC_R_SUCCESS);
+       assert_int_equal(dns_test_makeview("view", false, &view),
+                        ISC_R_SUCCESS);
 
        assert_int_equal(dns_keytable_create(mctx, &keytable), ISC_R_SUCCESS);
        assert_int_equal(
@@ -170,19 +169,21 @@ create_tables(void) {
        /* Add a normal key */
        dns_test_namefromstring("example.com", &fn);
        create_dsstruct(keyname, 257, 3, 5, keystr1, digest, &ds);
-       assert_int_equal(dns_keytable_add(keytable, false, false, keyname, &ds),
+       assert_int_equal(dns_keytable_add(keytable, false, false, keyname, &ds,
+                                         NULL, NULL),
                         ISC_R_SUCCESS);
 
        /* Add an initializing managed key */
        dns_test_namefromstring("managed.com", &fn);
        create_dsstruct(keyname, 257, 3, 5, keystr1, digest, &ds);
-       assert_int_equal(dns_keytable_add(keytable, true, true, keyname, &ds),
+       assert_int_equal(dns_keytable_add(keytable, true, true, keyname, &ds,
+                                         NULL, NULL),
                         ISC_R_SUCCESS);
 
        /* Add a null key */
-       assert_int_equal(dns_keytable_marksecure(keytable, str2name("null."
-                                                                   "example")),
-                        ISC_R_SUCCESS);
+       assert_int_equal(
+               dns_keytable_marksecure(keytable, str2name("null.example")),
+               ISC_R_SUCCESS);
 
        /* Add a negative trust anchor, duration 1 hour */
        isc_stdtime_get(&now);
@@ -230,7 +231,8 @@ ISC_RUN_TEST_IMPL(dns_keytable_add) {
         */
        dns_test_namefromstring("example.com", &fn);
        create_dsstruct(keyname, 257, 3, 5, keystr1, digest, &ds);
-       assert_int_equal(dns_keytable_add(keytable, false, false, keyname, &ds),
+       assert_int_equal(dns_keytable_add(keytable, false, false, keyname, &ds,
+                                         NULL, NULL),
                         ISC_R_SUCCESS);
        dns_keytable_detachkeynode(keytable, &keynode);
        assert_int_equal(
@@ -240,7 +242,8 @@ ISC_RUN_TEST_IMPL(dns_keytable_add) {
        /* Add another key (different keydata) */
        dns_keytable_detachkeynode(keytable, &keynode);
        create_dsstruct(keyname, 257, 3, 5, keystr2, digest, &ds);
-       assert_int_equal(dns_keytable_add(keytable, false, false, keyname, &ds),
+       assert_int_equal(dns_keytable_add(keytable, false, false, keyname, &ds,
+                                         NULL, NULL),
                         ISC_R_SUCCESS);
        assert_int_equal(
                dns_keytable_find(keytable, str2name("example.com"), &keynode),
@@ -267,7 +270,8 @@ ISC_RUN_TEST_IMPL(dns_keytable_add) {
         */
        dns_test_namefromstring("managed.com", &fn);
        create_dsstruct(keyname, 257, 3, 5, keystr2, digest, &ds);
-       assert_int_equal(dns_keytable_add(keytable, true, true, keyname, &ds),
+       assert_int_equal(dns_keytable_add(keytable, true, true, keyname, &ds,
+                                         NULL, NULL),
                         ISC_R_SUCCESS);
        assert_int_equal(
                dns_keytable_find(keytable, str2name("managed.com"), &keynode),
@@ -281,7 +285,8 @@ ISC_RUN_TEST_IMPL(dns_keytable_add) {
         * to a non-initializing key and make sure there are still two key
         * nodes for managed.com, both containing non-initializing keys.
         */
-       assert_int_equal(dns_keytable_add(keytable, true, false, keyname, &ds),
+       assert_int_equal(dns_keytable_add(keytable, true, false, keyname, &ds,
+                                         NULL, NULL),
                         ISC_R_SUCCESS);
        assert_int_equal(
                dns_keytable_find(keytable, str2name("managed.com"), &keynode),
@@ -295,7 +300,8 @@ ISC_RUN_TEST_IMPL(dns_keytable_add) {
         */
        dns_test_namefromstring("two.com", &fn);
        create_dsstruct(keyname, 257, 3, 5, keystr1, digest, &ds);
-       assert_int_equal(dns_keytable_add(keytable, true, true, keyname, &ds),
+       assert_int_equal(dns_keytable_add(keytable, true, true, keyname, &ds,
+                                         NULL, NULL),
                         ISC_R_SUCCESS);
        assert_int_equal(
                dns_keytable_find(keytable, str2name("two.com"), &keynode),
@@ -310,7 +316,8 @@ ISC_RUN_TEST_IMPL(dns_keytable_add) {
         * the initialization status should not change.
         */
        create_dsstruct(keyname, 257, 3, 5, keystr2, digest, &ds);
-       assert_int_equal(dns_keytable_add(keytable, true, false, keyname, &ds),
+       assert_int_equal(dns_keytable_add(keytable, true, false, keyname, &ds,
+                                         NULL, NULL),
                         ISC_R_SUCCESS);
        assert_int_equal(
                dns_keytable_find(keytable, str2name("two.com"), &keynode),
@@ -327,7 +334,8 @@ ISC_RUN_TEST_IMPL(dns_keytable_add) {
                         ISC_R_SUCCESS);
        dns_test_namefromstring("null.example", &fn);
        create_dsstruct(keyname, 257, 3, 5, keystr2, digest, &ds);
-       assert_int_equal(dns_keytable_add(keytable, false, false, keyname, &ds),
+       assert_int_equal(dns_keytable_add(keytable, false, false, keyname, &ds,
+                                         NULL, NULL),
                         ISC_R_SUCCESS);
        assert_int_equal(
                dns_keytable_find(keytable, str2name("null.example"), &keynode),
@@ -341,9 +349,9 @@ ISC_RUN_TEST_IMPL(dns_keytable_add) {
         * (Note: this and above checks confirm that if a name has a null key
         * that's the only key for the name).
         */
-       assert_int_equal(dns_keytable_marksecure(keytable, str2name("null."
-                                                                   "example")),
-                        ISC_R_SUCCESS);
+       assert_int_equal(
+               dns_keytable_marksecure(keytable, str2name("null.example")),
+               ISC_R_SUCCESS);
        assert_int_equal(dns_keytable_find(keytable, str2name("null.example"),
                                           &null_keynode),
                         ISC_R_SUCCESS);
@@ -359,23 +367,26 @@ ISC_RUN_TEST_IMPL(dns_keytable_delete) {
        create_tables();
 
        /* dns_keytable_delete requires exact match */
-       assert_int_equal(dns_keytable_delete(keytable, str2name("example.org")),
+       assert_int_equal(dns_keytable_delete(keytable, str2name("example.org"),
+                                            NULL, NULL),
                         ISC_R_NOTFOUND);
-       assert_int_equal(dns_keytable_delete(keytable, str2name("s.example."
-                                                               "com")),
+       assert_int_equal(dns_keytable_delete(keytable,
+                                            str2name("s.example.com"), NULL,
+                                            NULL),
                         ISC_R_NOTFOUND);
-       assert_int_equal(dns_keytable_delete(keytable, str2name("example.com")),
+       assert_int_equal(dns_keytable_delete(keytable, str2name("example.com"),
+                                            NULL, NULL),
                         ISC_R_SUCCESS);
 
        /* works also for nodes with a null key */
-       assert_int_equal(dns_keytable_delete(keytable, str2name("null."
-                                                               "example")),
+       assert_int_equal(dns_keytable_delete(keytable, str2name("null.example"),
+                                            NULL, NULL),
                         ISC_R_SUCCESS);
 
        /* or a negative trust anchor */
-       assert_int_equal(dns_ntatable_delete(ntatable, str2name("insecure."
-                                                               "example")),
-                        ISC_R_SUCCESS);
+       assert_int_equal(
+               dns_ntatable_delete(ntatable, str2name("insecure.example")),
+               ISC_R_SUCCESS);
 
        destroy_tables();
 }
@@ -426,7 +437,8 @@ ISC_RUN_TEST_IMPL(dns_keytable_deletekey) {
         * after deleting the node, any deletekey or delete attempt should
         * result in NOTFOUND.
         */
-       assert_int_equal(dns_keytable_delete(keytable, keyname), ISC_R_SUCCESS);
+       assert_int_equal(dns_keytable_delete(keytable, keyname, NULL, NULL),
+                        ISC_R_SUCCESS);
        assert_int_equal(dns_keytable_deletekey(keytable, keyname, &dnskey),
                         ISC_R_NOTFOUND);
        dns_rdata_freestruct(&dnskey);
@@ -439,7 +451,8 @@ ISC_RUN_TEST_IMPL(dns_keytable_deletekey) {
        create_keystruct(257, 3, 5, keystr1, &dnskey);
        assert_int_equal(dns_keytable_deletekey(keytable, keyname, &dnskey),
                         DNS_R_PARTIALMATCH);
-       assert_int_equal(dns_keytable_delete(keytable, keyname), ISC_R_SUCCESS);
+       assert_int_equal(dns_keytable_delete(keytable, keyname, NULL, NULL),
+                        ISC_R_SUCCESS);
        dns_rdata_freestruct(&dnskey);
 
        destroy_tables();
@@ -585,7 +598,8 @@ ISC_RUN_TEST_IMPL(dns_keytable_nta) {
 
        dns_test_namefromstring("example", &fn);
        create_dsstruct(keyname, 257, 3, 5, keystr1, digest, &ds);
-       result = dns_keytable_add(keytable, false, false, keyname, &ds),
+       result = dns_keytable_add(keytable, false, false, keyname, &ds, NULL,
+                                 NULL),
        assert_int_equal(result, ISC_R_SUCCESS);
 
        isc_stdtime_get(&now);