mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-30 14:07:59 +00:00
make dns_keytable_deletekey() work correctly
it now removes matching trust anchors from from the dslist while leaving the other trust anchors in place. also cleaned up the API to remove functions that were never being used.
This commit is contained in:
parent
678e2d3cfa
commit
2d249ebeae
@ -29,7 +29,7 @@
|
|||||||
#include <dst/dst.h>
|
#include <dst/dst.h>
|
||||||
|
|
||||||
isc_result_t
|
isc_result_t
|
||||||
dns_ds_fromkeyrdata(dns_name_t *owner, dns_rdata_t *key,
|
dns_ds_fromkeyrdata(const dns_name_t *owner, dns_rdata_t *key,
|
||||||
dns_dsdigest_t digest_type, unsigned char *digest,
|
dns_dsdigest_t digest_type, unsigned char *digest,
|
||||||
dns_rdata_ds_t *dsrdata)
|
dns_rdata_ds_t *dsrdata)
|
||||||
{
|
{
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
ISC_LANG_BEGINDECLS
|
ISC_LANG_BEGINDECLS
|
||||||
|
|
||||||
isc_result_t
|
isc_result_t
|
||||||
dns_ds_fromkeyrdata(dns_name_t *owner, dns_rdata_t *key,
|
dns_ds_fromkeyrdata(const dns_name_t *owner, dns_rdata_t *key,
|
||||||
dns_dsdigest_t digest_type, unsigned char *digest,
|
dns_dsdigest_t digest_type, unsigned char *digest,
|
||||||
dns_rdata_ds_t *dsrdata);
|
dns_rdata_ds_t *dsrdata);
|
||||||
/*%<
|
/*%<
|
||||||
|
@ -250,33 +250,13 @@ dns_keytable_finddeepestmatch(dns_keytable_t *keytable, const dns_name_t *name,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
dns_keytable_attachkeynode(dns_keytable_t *keytable, dns_keynode_t *source,
|
dns_keytable_detachkeynode(dns_keytable_t *keytable, dns_keynode_t **keynodep);
|
||||||
dns_keynode_t **target);
|
|
||||||
/*%<
|
/*%<
|
||||||
* Attach a keynode and and increment the active_nodes counter in a
|
* Detach a keynode found via dns_keytable_find().
|
||||||
* corresponding keytable.
|
|
||||||
*
|
*
|
||||||
* Requires:
|
* Requires:
|
||||||
*
|
*
|
||||||
*\li 'keytable' is a valid keytable.
|
*\li *keynodep is a valid keynode returned by a call to dns_keytable_find().
|
||||||
*
|
|
||||||
*\li 'source' is a valid keynode.
|
|
||||||
*
|
|
||||||
*\li 'target' is not null and '*target' is null.
|
|
||||||
*/
|
|
||||||
|
|
||||||
void
|
|
||||||
dns_keytable_detachkeynode(dns_keytable_t *keytable,
|
|
||||||
dns_keynode_t **keynodep);
|
|
||||||
/*%<
|
|
||||||
* Give back a keynode found via dns_keytable_findkeynode().
|
|
||||||
*
|
|
||||||
* Requires:
|
|
||||||
*
|
|
||||||
*\li 'keytable' is a valid keytable.
|
|
||||||
*
|
|
||||||
*\li *keynodep is a valid keynode returned by a call to
|
|
||||||
* dns_keytable_findkeynode().
|
|
||||||
*
|
*
|
||||||
* Ensures:
|
* Ensures:
|
||||||
*
|
*
|
||||||
@ -357,24 +337,6 @@ dns_keynode_trust(dns_keynode_t *keynode);
|
|||||||
* trusted: no longer an initializing key.
|
* trusted: no longer an initializing key.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
|
||||||
dns_keynode_attach(dns_keynode_t *source, dns_keynode_t **target);
|
|
||||||
/*%<
|
|
||||||
* Attach keynode 'source' to '*target'
|
|
||||||
*/
|
|
||||||
|
|
||||||
void
|
|
||||||
dns_keynode_detach(isc_mem_t *mctx, dns_keynode_t **target);
|
|
||||||
/*%<
|
|
||||||
* Detach a keynode.
|
|
||||||
*/
|
|
||||||
|
|
||||||
void
|
|
||||||
dns_keynode_detachall(isc_mem_t *mctx, dns_keynode_t **target);
|
|
||||||
/*%<
|
|
||||||
* Detach a keynode and all its succesors.
|
|
||||||
*/
|
|
||||||
|
|
||||||
isc_result_t
|
isc_result_t
|
||||||
dns_keytable_forall(dns_keytable_t *keytable,
|
dns_keytable_forall(dns_keytable_t *keytable,
|
||||||
void (*func)(dns_keytable_t *, dns_keynode_t *,
|
void (*func)(dns_keytable_t *, dns_keynode_t *,
|
||||||
|
@ -41,7 +41,6 @@ struct dns_keytable {
|
|||||||
/* Unlocked. */
|
/* Unlocked. */
|
||||||
unsigned int magic;
|
unsigned int magic;
|
||||||
isc_mem_t *mctx;
|
isc_mem_t *mctx;
|
||||||
atomic_uint_fast32_t active_nodes;
|
|
||||||
isc_refcount_t references;
|
isc_refcount_t references;
|
||||||
isc_rwlock_t rwlock;
|
isc_rwlock_t rwlock;
|
||||||
/* Locked by rwlock. */
|
/* Locked by rwlock. */
|
||||||
@ -51,20 +50,58 @@ struct dns_keytable {
|
|||||||
struct dns_keynode {
|
struct dns_keynode {
|
||||||
unsigned int magic;
|
unsigned int magic;
|
||||||
isc_refcount_t refcount;
|
isc_refcount_t refcount;
|
||||||
dst_key_t *key;
|
|
||||||
dns_rdatalist_t *dslist;
|
dns_rdatalist_t *dslist;
|
||||||
dns_rdataset_t dsset;
|
dns_rdataset_t dsset;
|
||||||
bool managed;
|
bool managed;
|
||||||
bool initial;
|
bool initial;
|
||||||
struct dns_keynode *next;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
keynode_attach(dns_keynode_t *source, dns_keynode_t **target) {
|
||||||
|
REQUIRE(VALID_KEYNODE(source));
|
||||||
|
isc_refcount_increment(&source->refcount);
|
||||||
|
*target = source;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
keynode_detach(isc_mem_t *mctx, dns_keynode_t **keynodep) {
|
||||||
|
REQUIRE(keynodep != NULL && VALID_KEYNODE(*keynodep));
|
||||||
|
dns_keynode_t *knode = *keynodep;
|
||||||
|
*keynodep = NULL;
|
||||||
|
|
||||||
|
if (isc_refcount_decrement(&knode->refcount) == 1) {
|
||||||
|
dns_rdata_t *rdata = NULL;
|
||||||
|
isc_refcount_destroy(&knode->refcount);
|
||||||
|
if (knode->dslist != NULL) {
|
||||||
|
if (dns_rdataset_isassociated(&knode->dsset)) {
|
||||||
|
dns_rdataset_disassociate(&knode->dsset);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (rdata = ISC_LIST_HEAD(knode->dslist->rdata);
|
||||||
|
rdata != NULL;
|
||||||
|
rdata = ISC_LIST_HEAD(knode->dslist->rdata))
|
||||||
|
{
|
||||||
|
ISC_LIST_UNLINK(knode->dslist->rdata,
|
||||||
|
rdata, link);
|
||||||
|
isc_mem_put(mctx, rdata->data,
|
||||||
|
DNS_DS_BUFFERSIZE);
|
||||||
|
isc_mem_put(mctx, rdata, sizeof(*rdata));
|
||||||
|
}
|
||||||
|
|
||||||
|
isc_mem_put(mctx, knode->dslist,
|
||||||
|
sizeof(*knode->dslist));
|
||||||
|
knode->dslist = NULL;
|
||||||
|
}
|
||||||
|
isc_mem_put(mctx, knode, sizeof(dns_keynode_t));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
free_keynode(void *node, void *arg) {
|
free_keynode(void *node, void *arg) {
|
||||||
dns_keynode_t *keynode = node;
|
dns_keynode_t *keynode = node;
|
||||||
isc_mem_t *mctx = arg;
|
isc_mem_t *mctx = arg;
|
||||||
|
|
||||||
dns_keynode_detachall(mctx, &keynode);
|
keynode_detach(mctx, &keynode);
|
||||||
}
|
}
|
||||||
|
|
||||||
isc_result_t
|
isc_result_t
|
||||||
@ -91,7 +128,6 @@ dns_keytable_create(isc_mem_t *mctx, dns_keytable_t **keytablep) {
|
|||||||
goto cleanup_rbt;
|
goto cleanup_rbt;
|
||||||
}
|
}
|
||||||
|
|
||||||
atomic_init(&keytable->active_nodes, 0);
|
|
||||||
isc_refcount_init(&keytable->references, 1);
|
isc_refcount_init(&keytable->references, 1);
|
||||||
|
|
||||||
keytable->mctx = NULL;
|
keytable->mctx = NULL;
|
||||||
@ -112,11 +148,6 @@ dns_keytable_create(isc_mem_t *mctx, dns_keytable_t **keytablep) {
|
|||||||
|
|
||||||
void
|
void
|
||||||
dns_keytable_attach(dns_keytable_t *source, dns_keytable_t **targetp) {
|
dns_keytable_attach(dns_keytable_t *source, dns_keytable_t **targetp) {
|
||||||
|
|
||||||
/*
|
|
||||||
* Attach *targetp to source.
|
|
||||||
*/
|
|
||||||
|
|
||||||
REQUIRE(VALID_KEYTABLE(source));
|
REQUIRE(VALID_KEYTABLE(source));
|
||||||
REQUIRE(targetp != NULL && *targetp == NULL);
|
REQUIRE(targetp != NULL && *targetp == NULL);
|
||||||
|
|
||||||
@ -133,7 +164,6 @@ dns_keytable_detach(dns_keytable_t **keytablep) {
|
|||||||
|
|
||||||
if (isc_refcount_decrement(&keytable->references) == 1) {
|
if (isc_refcount_decrement(&keytable->references) == 1) {
|
||||||
isc_refcount_destroy(&keytable->references);
|
isc_refcount_destroy(&keytable->references);
|
||||||
REQUIRE(atomic_load_acquire(&keytable->active_nodes) == 0);
|
|
||||||
dns_rbt_destroy(&keytable->table);
|
dns_rbt_destroy(&keytable->table);
|
||||||
isc_rwlock_destroy(&keytable->rwlock);
|
isc_rwlock_destroy(&keytable->rwlock);
|
||||||
keytable->magic = 0;
|
keytable->magic = 0;
|
||||||
@ -142,28 +172,12 @@ dns_keytable_detach(dns_keytable_t **keytablep) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
free_dslist(isc_mem_t *mctx, dns_keynode_t *knode) {
|
|
||||||
dns_rdata_t *rdata = NULL;
|
|
||||||
|
|
||||||
for (rdata = ISC_LIST_HEAD(knode->dslist->rdata);
|
|
||||||
rdata != NULL;
|
|
||||||
rdata = ISC_LIST_HEAD(knode->dslist->rdata))
|
|
||||||
{
|
|
||||||
ISC_LIST_UNLINK(knode->dslist->rdata, rdata, link);
|
|
||||||
isc_mem_put(mctx, rdata->data, DNS_DS_BUFFERSIZE);
|
|
||||||
isc_mem_put(mctx, rdata, sizeof(*rdata));
|
|
||||||
}
|
|
||||||
|
|
||||||
isc_mem_put(mctx, knode->dslist, sizeof(*knode->dslist));
|
|
||||||
knode->dslist = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static isc_result_t
|
static isc_result_t
|
||||||
add_ds(dns_keynode_t *knode, dns_rdata_ds_t *ds, isc_mem_t *mctx) {
|
add_ds(dns_keynode_t *knode, dns_rdata_ds_t *ds, isc_mem_t *mctx) {
|
||||||
isc_result_t result;
|
isc_result_t result;
|
||||||
dns_rdata_t *rdata = NULL;
|
dns_rdata_t *dsrdata = NULL, *rdata = NULL;
|
||||||
void *data = NULL;
|
void *data = NULL;
|
||||||
|
bool exists = false;
|
||||||
isc_buffer_t b;
|
isc_buffer_t b;
|
||||||
|
|
||||||
if (knode->dslist == NULL) {
|
if (knode->dslist == NULL) {
|
||||||
@ -173,19 +187,35 @@ add_ds(dns_keynode_t *knode, dns_rdata_ds_t *ds, isc_mem_t *mctx) {
|
|||||||
knode->dslist->type = dns_rdatatype_ds;
|
knode->dslist->type = dns_rdatatype_ds;
|
||||||
}
|
}
|
||||||
|
|
||||||
rdata = isc_mem_get(mctx, sizeof(*rdata));
|
dsrdata = isc_mem_get(mctx, sizeof(*dsrdata));
|
||||||
dns_rdata_init(rdata);
|
dns_rdata_init(dsrdata);
|
||||||
|
|
||||||
data = isc_mem_get(mctx, DNS_DS_BUFFERSIZE);
|
data = isc_mem_get(mctx, DNS_DS_BUFFERSIZE);
|
||||||
isc_buffer_init(&b, data, DNS_DS_BUFFERSIZE);
|
isc_buffer_init(&b, data, DNS_DS_BUFFERSIZE);
|
||||||
|
|
||||||
result = dns_rdata_fromstruct(rdata, dns_rdataclass_in,
|
result = dns_rdata_fromstruct(dsrdata, dns_rdataclass_in,
|
||||||
dns_rdatatype_ds, ds, &b);
|
dns_rdatatype_ds, ds, &b);
|
||||||
if (result != ISC_R_SUCCESS) {
|
if (result != ISC_R_SUCCESS) {
|
||||||
return (result);
|
return (result);
|
||||||
}
|
}
|
||||||
|
|
||||||
ISC_LIST_APPEND(knode->dslist->rdata, rdata, link);
|
for (rdata = ISC_LIST_HEAD(knode->dslist->rdata);
|
||||||
|
rdata != NULL;
|
||||||
|
rdata = ISC_LIST_NEXT(rdata, link))
|
||||||
|
{
|
||||||
|
if (dns_rdata_compare(rdata, dsrdata) == 0) {
|
||||||
|
exists = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (exists) {
|
||||||
|
isc_mem_put(mctx, dsrdata->data, DNS_DS_BUFFERSIZE);
|
||||||
|
isc_mem_put(mctx, dsrdata, sizeof(*dsrdata));
|
||||||
|
return (ISC_R_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
ISC_LIST_APPEND(knode->dslist->rdata, dsrdata, link);
|
||||||
|
|
||||||
if (dns_rdataset_isassociated(&knode->dsset)) {
|
if (dns_rdataset_isassociated(&knode->dsset)) {
|
||||||
dns_rdataset_disassociate(&knode->dsset);
|
dns_rdataset_disassociate(&knode->dsset);
|
||||||
@ -200,6 +230,51 @@ add_ds(dns_keynode_t *knode, dns_rdata_ds_t *ds, isc_mem_t *mctx) {
|
|||||||
return (ISC_R_SUCCESS);
|
return (ISC_R_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static isc_result_t
|
||||||
|
delete_ds(dns_keynode_t *knode, dns_rdata_ds_t *ds, isc_mem_t *mctx) {
|
||||||
|
isc_result_t result;
|
||||||
|
dns_rdata_t dsrdata = DNS_RDATA_INIT;
|
||||||
|
dns_rdata_t *rdata = NULL;
|
||||||
|
unsigned char data[DNS_DS_BUFFERSIZE];
|
||||||
|
bool found = false;
|
||||||
|
isc_buffer_t b;
|
||||||
|
|
||||||
|
if (knode->dslist == NULL) {
|
||||||
|
return (ISC_R_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
isc_buffer_init(&b, data, DNS_DS_BUFFERSIZE);
|
||||||
|
|
||||||
|
result = dns_rdata_fromstruct(&dsrdata, dns_rdataclass_in,
|
||||||
|
dns_rdatatype_ds, ds, &b);
|
||||||
|
if (result != ISC_R_SUCCESS) {
|
||||||
|
return (result);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (rdata = ISC_LIST_HEAD(knode->dslist->rdata);
|
||||||
|
rdata != NULL;
|
||||||
|
rdata = ISC_LIST_NEXT(rdata, link))
|
||||||
|
{
|
||||||
|
if (dns_rdata_compare(rdata, &dsrdata) == 0) {
|
||||||
|
ISC_LIST_UNLINK(knode->dslist->rdata, rdata, link);
|
||||||
|
isc_mem_put(mctx, rdata->data, DNS_DS_BUFFERSIZE);
|
||||||
|
isc_mem_put(mctx, rdata, sizeof(*rdata));
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (found) {
|
||||||
|
return (ISC_R_SUCCESS);
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* The keyname must have matched or we wouldn't be here,
|
||||||
|
* so we use DNS_R_PARTIALMATCH instead of ISC_R_NOTFOUND.
|
||||||
|
*/
|
||||||
|
return (DNS_R_PARTIALMATCH);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*%
|
/*%
|
||||||
* Create a keynode for "ds" (or a null key node if "ds" is NULL), set
|
* Create a keynode for "ds" (or a null key node if "ds" is NULL), set
|
||||||
* "managed" and "initial" as requested and attach the keynode to
|
* "managed" and "initial" as requested and attach the keynode to
|
||||||
@ -236,7 +311,6 @@ new_keynode(dns_rdata_ds_t *ds, dns_rbtnode_t *node,
|
|||||||
knode->managed = managed;
|
knode->managed = managed;
|
||||||
knode->initial = initial;
|
knode->initial = initial;
|
||||||
|
|
||||||
knode->next = node->data;
|
|
||||||
node->data = knode;
|
node->data = knode;
|
||||||
|
|
||||||
return (ISC_R_SUCCESS);
|
return (ISC_R_SUCCESS);
|
||||||
@ -265,7 +339,7 @@ insert(dns_keytable_t *keytable, bool managed, bool initial,
|
|||||||
/*
|
/*
|
||||||
* There was no node for "keyname" in "keytable" yet, so one
|
* There was no node for "keyname" in "keytable" yet, so one
|
||||||
* was created. Create a new key node for the supplied
|
* was created. Create a new key node for the supplied
|
||||||
* trust anchor (or a null key node if both "ds" is NULL)
|
* trust anchor (or a null key node if "ds" is NULL)
|
||||||
* and attach it to the created node.
|
* and attach it to the created node.
|
||||||
*/
|
*/
|
||||||
result = new_keynode(ds, node, keytable, managed, initial);
|
result = new_keynode(ds, node, keytable, managed, initial);
|
||||||
@ -305,6 +379,7 @@ dns_keytable_add(dns_keytable_t *keytable, bool managed, bool initial,
|
|||||||
{
|
{
|
||||||
REQUIRE(ds != NULL);
|
REQUIRE(ds != NULL);
|
||||||
REQUIRE(!initial || managed);
|
REQUIRE(!initial || managed);
|
||||||
|
|
||||||
return (insert(keytable, managed, initial, name, ds));
|
return (insert(keytable, managed, initial, name, ds));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -325,13 +400,15 @@ dns_keytable_delete(dns_keytable_t *keytable, const dns_name_t *keyname) {
|
|||||||
result = dns_rbt_findnode(keytable->table, keyname, NULL, &node, NULL,
|
result = dns_rbt_findnode(keytable->table, keyname, NULL, &node, NULL,
|
||||||
DNS_RBTFIND_NOOPTIONS, NULL, NULL);
|
DNS_RBTFIND_NOOPTIONS, NULL, NULL);
|
||||||
if (result == ISC_R_SUCCESS) {
|
if (result == ISC_R_SUCCESS) {
|
||||||
if (node->data != NULL)
|
if (node->data != NULL) {
|
||||||
result = dns_rbt_deletenode(keytable->table,
|
result = dns_rbt_deletenode(keytable->table,
|
||||||
node, false);
|
node, false);
|
||||||
else
|
} else {
|
||||||
result = ISC_R_NOTFOUND;
|
result = ISC_R_NOTFOUND;
|
||||||
} else if (result == DNS_R_PARTIALMATCH)
|
}
|
||||||
|
} else if (result == DNS_R_PARTIALMATCH) {
|
||||||
result = ISC_R_NOTFOUND;
|
result = ISC_R_NOTFOUND;
|
||||||
|
}
|
||||||
RWUNLOCK(&keytable->rwlock, isc_rwlocktype_write);
|
RWUNLOCK(&keytable->rwlock, isc_rwlocktype_write);
|
||||||
|
|
||||||
return (result);
|
return (result);
|
||||||
@ -343,24 +420,18 @@ dns_keytable_deletekey(dns_keytable_t *keytable, const dns_name_t *keyname,
|
|||||||
{
|
{
|
||||||
isc_result_t result;
|
isc_result_t result;
|
||||||
dns_rbtnode_t *node = NULL;
|
dns_rbtnode_t *node = NULL;
|
||||||
dns_keynode_t *knode = NULL, **kprev = NULL;
|
dns_keynode_t *knode = NULL;
|
||||||
dst_key_t *dstkey = NULL;
|
|
||||||
unsigned char data[4096];
|
|
||||||
isc_buffer_t buffer;
|
|
||||||
dns_rdata_t rdata = DNS_RDATA_INIT;
|
dns_rdata_t rdata = DNS_RDATA_INIT;
|
||||||
|
unsigned char data[4096], digest[DNS_DS_BUFFERSIZE];
|
||||||
|
dns_rdata_ds_t ds;
|
||||||
|
isc_buffer_t b;
|
||||||
|
|
||||||
REQUIRE(VALID_KEYTABLE(keytable));
|
REQUIRE(VALID_KEYTABLE(keytable));
|
||||||
REQUIRE(dnskey != NULL);
|
REQUIRE(dnskey != NULL);
|
||||||
|
|
||||||
/* Convert dnskey to DST key. */
|
isc_buffer_init(&b, data, sizeof(data));
|
||||||
isc_buffer_init(&buffer, data, sizeof(data));
|
|
||||||
dns_rdata_fromstruct(&rdata, dnskey->common.rdclass,
|
dns_rdata_fromstruct(&rdata, dnskey->common.rdclass,
|
||||||
dns_rdatatype_dnskey, dnskey, &buffer);
|
dns_rdatatype_dnskey, dnskey, &b);
|
||||||
result = dns_dnssec_keyfromrdata(keyname, &rdata, keytable->mctx,
|
|
||||||
&dstkey);
|
|
||||||
if (result != ISC_R_SUCCESS) {
|
|
||||||
return (result);
|
|
||||||
}
|
|
||||||
|
|
||||||
RWLOCK(&keytable->rwlock, isc_rwlocktype_write);
|
RWLOCK(&keytable->rwlock, isc_rwlocktype_write);
|
||||||
result = dns_rbt_findnode(keytable->table, keyname, NULL, &node, NULL,
|
result = dns_rbt_findnode(keytable->table, keyname, NULL, &node, NULL,
|
||||||
@ -379,45 +450,22 @@ dns_keytable_deletekey(dns_keytable_t *keytable, const dns_name_t *keyname,
|
|||||||
}
|
}
|
||||||
|
|
||||||
knode = node->data;
|
knode = node->data;
|
||||||
if (knode->next == NULL && knode->key != NULL &&
|
|
||||||
dst_key_compare(knode->key, dstkey))
|
if (knode->dslist == NULL) {
|
||||||
{
|
result = DNS_R_PARTIALMATCH;
|
||||||
result = dns_rbt_deletenode(keytable->table, node, false);
|
|
||||||
goto finish;
|
goto finish;
|
||||||
}
|
}
|
||||||
|
|
||||||
kprev = (dns_keynode_t **) &node->data;
|
result = dns_ds_fromkeyrdata(keyname, &rdata, DNS_DSDIGEST_SHA256,
|
||||||
while (knode != NULL) {
|
digest, &ds);
|
||||||
if (knode->key != NULL && dst_key_compare(knode->key, dstkey)) {
|
if (result != ISC_R_SUCCESS) {
|
||||||
break;
|
goto finish;
|
||||||
}
|
|
||||||
|
|
||||||
kprev = &knode->next;
|
|
||||||
knode = knode->next;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (knode != NULL) {
|
result = delete_ds(knode, &ds, keytable->mctx);
|
||||||
if (knode->key != NULL) {
|
|
||||||
dst_key_free(&knode->key);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
finish:
|
||||||
* This is equivalent to:
|
|
||||||
* dns_keynode_attach(knode->next, &tmp);
|
|
||||||
* dns_keynode_detach(kprev);
|
|
||||||
* dns_keynode_attach(tmp, &kprev);
|
|
||||||
* dns_keynode_detach(&tmp);
|
|
||||||
*/
|
|
||||||
*kprev = knode->next;
|
|
||||||
knode->next = NULL;
|
|
||||||
dns_keynode_detach(keytable->mctx, &knode);
|
|
||||||
} else {
|
|
||||||
result = DNS_R_PARTIALMATCH;
|
|
||||||
}
|
|
||||||
|
|
||||||
finish:
|
|
||||||
RWUNLOCK(&keytable->rwlock, isc_rwlocktype_write);
|
RWUNLOCK(&keytable->rwlock, isc_rwlocktype_write);
|
||||||
dst_key_free(&dstkey);
|
|
||||||
return (result);
|
return (result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -437,8 +485,7 @@ dns_keytable_find(dns_keytable_t *keytable, const dns_name_t *keyname,
|
|||||||
DNS_RBTFIND_NOOPTIONS, NULL, NULL);
|
DNS_RBTFIND_NOOPTIONS, NULL, NULL);
|
||||||
if (result == ISC_R_SUCCESS) {
|
if (result == ISC_R_SUCCESS) {
|
||||||
if (node->data != NULL) {
|
if (node->data != NULL) {
|
||||||
dns_keytable_attachkeynode(keytable, node->data,
|
keynode_attach(node->data, keynodep);
|
||||||
keynodep);
|
|
||||||
} else {
|
} else {
|
||||||
result = ISC_R_NOTFOUND;
|
result = ISC_R_NOTFOUND;
|
||||||
}
|
}
|
||||||
@ -480,26 +527,7 @@ dns_keytable_finddeepestmatch(dns_keytable_t *keytable, const dns_name_t *name,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
dns_keytable_attachkeynode(dns_keytable_t *keytable, dns_keynode_t *source,
|
dns_keytable_detachkeynode(dns_keytable_t *keytable, dns_keynode_t **keynodep) {
|
||||||
dns_keynode_t **target)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* Give back a keynode found via dns_keytable_findkeynode().
|
|
||||||
*/
|
|
||||||
|
|
||||||
REQUIRE(VALID_KEYTABLE(keytable));
|
|
||||||
REQUIRE(VALID_KEYNODE(source));
|
|
||||||
REQUIRE(target != NULL && *target == NULL);
|
|
||||||
|
|
||||||
REQUIRE(atomic_fetch_add_relaxed(&keytable->active_nodes,
|
|
||||||
1) < UINT32_MAX);
|
|
||||||
|
|
||||||
dns_keynode_attach(source, target);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
dns_keytable_detachkeynode(dns_keytable_t *keytable, dns_keynode_t **keynodep)
|
|
||||||
{
|
|
||||||
/*
|
/*
|
||||||
* Give back a keynode found via dns_keytable_findkeynode().
|
* Give back a keynode found via dns_keytable_findkeynode().
|
||||||
*/
|
*/
|
||||||
@ -507,9 +535,7 @@ dns_keytable_detachkeynode(dns_keytable_t *keytable, dns_keynode_t **keynodep)
|
|||||||
REQUIRE(VALID_KEYTABLE(keytable));
|
REQUIRE(VALID_KEYTABLE(keytable));
|
||||||
REQUIRE(keynodep != NULL && VALID_KEYNODE(*keynodep));
|
REQUIRE(keynodep != NULL && VALID_KEYNODE(*keynodep));
|
||||||
|
|
||||||
REQUIRE(atomic_fetch_sub_release(&keytable->active_nodes, 1) > 0);
|
keynode_detach(keytable->mctx, keynodep);
|
||||||
|
|
||||||
dns_keynode_detach(keytable->mctx, keynodep);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
isc_result_t
|
isc_result_t
|
||||||
@ -615,7 +641,7 @@ keynode_dslist_totext(dns_name_t *name, dns_keynode_t *keynode,
|
|||||||
|
|
||||||
dns_secalg_format(ds.algorithm, algbuf, sizeof(algbuf));
|
dns_secalg_format(ds.algorithm, algbuf, sizeof(algbuf));
|
||||||
|
|
||||||
snprintf(obuf, sizeof(obuf), "%s/%s/%d ; %s%s (DS)\n",
|
snprintf(obuf, sizeof(obuf), "%s/%s/%d ; %s%s\n",
|
||||||
namebuf, algbuf, ds.key_tag,
|
namebuf, algbuf, ds.key_tag,
|
||||||
keynode->initial ? "initializing " : "",
|
keynode->initial ? "initializing " : "",
|
||||||
keynode->managed ? "managed" : "static");
|
keynode->managed ? "managed" : "static");
|
||||||
@ -655,8 +681,6 @@ dns_keytable_totext(dns_keytable_t *keytable, isc_buffer_t **text) {
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
for (;;) {
|
for (;;) {
|
||||||
char pbuf[DST_KEY_FORMATSIZE];
|
|
||||||
|
|
||||||
dns_rbtnodechain_current(&chain, foundname, origin, &node);
|
dns_rbtnodechain_current(&chain, foundname, origin, &node);
|
||||||
|
|
||||||
knode = node->data;
|
knode = node->data;
|
||||||
@ -668,24 +692,8 @@ dns_keytable_totext(dns_keytable_t *keytable, isc_buffer_t **text) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
result = keynode_dslist_totext(fullname, knode, text);
|
result = keynode_dslist_totext(fullname, knode, text);
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (; knode != NULL; knode = knode->next) {
|
|
||||||
char obuf[DNS_NAME_FORMATSIZE + 200];
|
|
||||||
|
|
||||||
if (knode->key == NULL) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
dst_key_format(knode->key, pbuf, sizeof(pbuf));
|
|
||||||
snprintf(obuf, sizeof(obuf), "%s ; %s%s\n", pbuf,
|
|
||||||
knode->initial ? "initializing " : "",
|
|
||||||
knode->managed ? "managed" : "static");
|
|
||||||
|
|
||||||
result = putstr(text, obuf);
|
|
||||||
if (result != ISC_R_SUCCESS) {
|
if (result != ISC_R_SUCCESS) {
|
||||||
break;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -698,7 +706,7 @@ dns_keytable_totext(dns_keytable_t *keytable, isc_buffer_t **text) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
dns_rbtnodechain_invalidate(&chain);
|
dns_rbtnodechain_invalidate(&chain);
|
||||||
RWUNLOCK(&keytable->rwlock, isc_rwlocktype_read);
|
RWUNLOCK(&keytable->rwlock, isc_rwlocktype_read);
|
||||||
return (result);
|
return (result);
|
||||||
@ -731,8 +739,7 @@ dns_keytable_forall(dns_keytable_t *keytable,
|
|||||||
}
|
}
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
REQUIRE(atomic_fetch_add_relaxed(&keytable->active_nodes,
|
|
||||||
1) < UINT32_MAX);
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
dns_rbtnodechain_current(&chain, foundname, origin, &node);
|
dns_rbtnodechain_current(&chain, foundname, origin, &node);
|
||||||
if (node->data != NULL) {
|
if (node->data != NULL) {
|
||||||
@ -749,9 +756,8 @@ dns_keytable_forall(dns_keytable_t *keytable,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
REQUIRE(atomic_fetch_sub_release(&keytable->active_nodes, 1) > 0);
|
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
dns_rbtnodechain_invalidate(&chain);
|
dns_rbtnodechain_invalidate(&chain);
|
||||||
RWUNLOCK(&keytable->rwlock, isc_rwlocktype_read);
|
RWUNLOCK(&keytable->rwlock, isc_rwlocktype_read);
|
||||||
return (result);
|
return (result);
|
||||||
@ -788,43 +794,3 @@ dns_keynode_trust(dns_keynode_t *keynode) {
|
|||||||
|
|
||||||
keynode->initial = false;
|
keynode->initial = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
dns_keynode_attach(dns_keynode_t *source, dns_keynode_t **target) {
|
|
||||||
REQUIRE(VALID_KEYNODE(source));
|
|
||||||
isc_refcount_increment(&source->refcount);
|
|
||||||
*target = source;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
dns_keynode_detach(isc_mem_t *mctx, dns_keynode_t **keynodep) {
|
|
||||||
REQUIRE(keynodep != NULL && VALID_KEYNODE(*keynodep));
|
|
||||||
dns_keynode_t *knode = *keynodep;
|
|
||||||
*keynodep = NULL;
|
|
||||||
|
|
||||||
if (isc_refcount_decrement(&knode->refcount) == 1) {
|
|
||||||
isc_refcount_destroy(&knode->refcount);
|
|
||||||
if (knode->key != NULL) {
|
|
||||||
dst_key_free(&knode->key);
|
|
||||||
}
|
|
||||||
if (knode->dslist != NULL) {
|
|
||||||
if (dns_rdataset_isassociated(&knode->dsset)) {
|
|
||||||
dns_rdataset_disassociate(&knode->dsset);
|
|
||||||
}
|
|
||||||
free_dslist(mctx, knode);
|
|
||||||
}
|
|
||||||
isc_mem_put(mctx, knode, sizeof(dns_keynode_t));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
dns_keynode_detachall(isc_mem_t *mctx, dns_keynode_t **keynode) {
|
|
||||||
dns_keynode_t *next = NULL, *node = *keynode;
|
|
||||||
REQUIRE(VALID_KEYNODE(node));
|
|
||||||
while (node != NULL) {
|
|
||||||
next = node->next;
|
|
||||||
dns_keynode_detach(mctx, &node);
|
|
||||||
node = next;
|
|
||||||
}
|
|
||||||
*keynode = NULL;
|
|
||||||
}
|
|
||||||
|
@ -68,7 +68,6 @@ dns_keytable_t *keytable = NULL;
|
|||||||
dns_ntatable_t *ntatable = NULL;
|
dns_ntatable_t *ntatable = NULL;
|
||||||
|
|
||||||
static const char *keystr1 = "BQEAAAABok+vaUC9neRv8yeT/FEGgN7svR8s7VBUVSBd8NsAiV8AlaAg O5FHar3JQd95i/puZos6Vi6at9/JBbN8qVmO2AuiXxVqfxMKxIcy+LEB 0Vw4NaSJ3N3uaVREso6aTSs98H/25MjcwLOr7SFfXA7bGhZatLtYY/xu kp6Km5hMfkE=";
|
static const char *keystr1 = "BQEAAAABok+vaUC9neRv8yeT/FEGgN7svR8s7VBUVSBd8NsAiV8AlaAg O5FHar3JQd95i/puZos6Vi6at9/JBbN8qVmO2AuiXxVqfxMKxIcy+LEB 0Vw4NaSJ3N3uaVREso6aTSs98H/25MjcwLOr7SFfXA7bGhZatLtYY/xu kp6Km5hMfkE=";
|
||||||
static const dns_keytag_t keytag1 = 30591;
|
|
||||||
|
|
||||||
static const char *keystr2 = "BQEAAAABwuHz9Cem0BJ0JQTO7C/a3McR6hMaufljs1dfG/inaJpYv7vH XTrAOm/MeKp+/x6eT4QLru0KoZkvZJnqTI8JyaFTw2OM/ItBfh/hL2lm Cft2O7n3MfeqYtvjPnY7dWghYW4sVfH7VVEGm958o9nfi79532Qeklxh x8pXWdeAaRU=";
|
static const char *keystr2 = "BQEAAAABwuHz9Cem0BJ0JQTO7C/a3McR6hMaufljs1dfG/inaJpYv7vH XTrAOm/MeKp+/x6eT4QLru0KoZkvZJnqTI8JyaFTw2OM/ItBfh/hL2lm Cft2O7n3MfeqYtvjPnY7dWghYW4sVfH7VVEGm958o9nfi79532Qeklxh x8pXWdeAaRU=";
|
||||||
|
|
||||||
@ -434,16 +433,23 @@ deletekey_test(void **state) {
|
|||||||
dns_rdata_freestruct(&dnskey);
|
dns_rdata_freestruct(&dnskey);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* exact match. after deleting the node the internal rbt node will be
|
* exact match: should return SUCCESS on the first try, then
|
||||||
* empty, and any delete or deletekeynode attempt should result in
|
* PARTIALMATCH on the second (because the name existed but
|
||||||
* NOTFOUND.
|
* not a matching key).
|
||||||
*/
|
*/
|
||||||
create_keystruct(257, 3, 5, keystr1, &dnskey);
|
create_keystruct(257, 3, 5, keystr1, &dnskey);
|
||||||
assert_int_equal(dns_keytable_deletekey(keytable, keyname, &dnskey),
|
assert_int_equal(dns_keytable_deletekey(keytable, keyname, &dnskey),
|
||||||
ISC_R_SUCCESS);
|
ISC_R_SUCCESS);
|
||||||
assert_int_equal(dns_keytable_deletekey(keytable, keyname, &dnskey),
|
assert_int_equal(dns_keytable_deletekey(keytable, keyname, &dnskey),
|
||||||
ISC_R_NOTFOUND);
|
DNS_R_PARTIALMATCH);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* after deleting the node, any deletekey or delete attempt should
|
||||||
|
* result in NOTFOUND.
|
||||||
|
*/
|
||||||
assert_int_equal(dns_keytable_delete(keytable, keyname),
|
assert_int_equal(dns_keytable_delete(keytable, keyname),
|
||||||
|
ISC_R_SUCCESS);
|
||||||
|
assert_int_equal(dns_keytable_deletekey(keytable, keyname, &dnskey),
|
||||||
ISC_R_NOTFOUND);
|
ISC_R_NOTFOUND);
|
||||||
dns_rdata_freestruct(&dnskey);
|
dns_rdata_freestruct(&dnskey);
|
||||||
|
|
||||||
@ -691,23 +697,16 @@ nta_test(void **state) {
|
|||||||
int
|
int
|
||||||
main(void) {
|
main(void) {
|
||||||
const struct CMUnitTest tests[] = {
|
const struct CMUnitTest tests[] = {
|
||||||
cmocka_unit_test_setup_teardown(add_test,
|
cmocka_unit_test(add_test),
|
||||||
_setup, _teardown),
|
cmocka_unit_test(delete_test),
|
||||||
cmocka_unit_test_setup_teardown(delete_test,
|
cmocka_unit_test(deletekey_test),
|
||||||
_setup, _teardown),
|
cmocka_unit_test(find_test),
|
||||||
cmocka_unit_test_setup_teardown(deletekey_test,
|
cmocka_unit_test(issecuredomain_test),
|
||||||
_setup, _teardown),
|
cmocka_unit_test(dump_test),
|
||||||
cmocka_unit_test_setup_teardown(find_test,
|
cmocka_unit_test(nta_test),
|
||||||
_setup, _teardown),
|
|
||||||
cmocka_unit_test_setup_teardown(issecuredomain_test,
|
|
||||||
_setup, _teardown),
|
|
||||||
cmocka_unit_test_setup_teardown(dump_test,
|
|
||||||
_setup, _teardown),
|
|
||||||
cmocka_unit_test_setup_teardown(nta_test,
|
|
||||||
_setup, _teardown),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return (cmocka_run_group_tests(tests, NULL, NULL));
|
return (cmocka_run_group_tests(tests, _setup, _teardown));
|
||||||
}
|
}
|
||||||
|
|
||||||
#else /* HAVE_CMOCKA */
|
#else /* HAVE_CMOCKA */
|
||||||
|
@ -458,9 +458,6 @@ dns_keydata_fromdnskey
|
|||||||
dns_keydata_todnskey
|
dns_keydata_todnskey
|
||||||
dns_keyflags_fromtext
|
dns_keyflags_fromtext
|
||||||
dns_keymgr_run
|
dns_keymgr_run
|
||||||
dns_keynode_attach
|
|
||||||
dns_keynode_detach
|
|
||||||
dns_keynode_detachall
|
|
||||||
dns_keynode_dsset
|
dns_keynode_dsset
|
||||||
dns_keynode_initial
|
dns_keynode_initial
|
||||||
dns_keynode_managed
|
dns_keynode_managed
|
||||||
@ -468,7 +465,6 @@ dns_keynode_trust
|
|||||||
dns_keyring_restore
|
dns_keyring_restore
|
||||||
dns_keytable_add
|
dns_keytable_add
|
||||||
dns_keytable_attach
|
dns_keytable_attach
|
||||||
dns_keytable_attachkeynode
|
|
||||||
dns_keytable_create
|
dns_keytable_create
|
||||||
dns_keytable_delete
|
dns_keytable_delete
|
||||||
dns_keytable_deletekey
|
dns_keytable_deletekey
|
||||||
|
Loading…
x
Reference in New Issue
Block a user