Add synth-from-dnssec namespaces for keytable entries

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 a5b57ed293)
This commit is contained in:
Mark Andrews 2022-06-17 10:40:47 +10:00
parent 90467f4127
commit 30d4e3ee89
6 changed files with 101 additions and 46 deletions

View 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));
}
}

View 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) {

View 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'
*

View 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;
}

View 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);
}

View 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);