confkeys.c revision 292031c9fc4d26bfff35d3cbb9b77217c66c39cd
d0be1e954bd4674fc27f2616c72adb37cf3525a2David Lawrence/*
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * Copyright (C) 1999 Internet Software Consortium.
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence *
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * Permission to use, copy, modify, and distribute this software for any
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * purpose with or without fee is hereby granted, provided that the above
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * copyright notice and this permission notice appear in all copies.
d0be1e954bd4674fc27f2616c72adb37cf3525a2David Lawrence *
d0be1e954bd4674fc27f2616c72adb37cf3525a2David Lawrence * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
70e5a7403f0e0a3bd292b8287c5fed5772c15270Automatic Updater * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
821644d49b73b49f2abc5463bc53a3132f612478Mark Andrews * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
821644d49b73b49f2abc5463bc53a3132f612478Mark Andrews * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
9c3531d72aeaad6c5f01efe6a1c82023e1379e4dDavid Lawrence * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
f4f73ec517c5389acb234bc737265f8c98ad17f9Michael Sawyer * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
ee6fe1d1975604af266af6c370fc6193dae80fddMichael Sawyer * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
f333ea9bdd3f85b74ae790e6c8ce2684295b3483Andreas Gustafsson * SOFTWARE.
ccd492e4eebc39acd6e304f50e6e3966562fb3a3Brian Wellington */
10bc8ffed60f064a2950527a82d7fdffe91b6206Michael Sawyer
f4f73ec517c5389acb234bc737265f8c98ad17f9Michael Sawyer#include <config.h>
f4f73ec517c5389acb234bc737265f8c98ad17f9Michael Sawyer
f4f73ec517c5389acb234bc737265f8c98ad17f9Michael Sawyer#include <string.h>
f333ea9bdd3f85b74ae790e6c8ce2684295b3483Andreas Gustafsson
f4f73ec517c5389acb234bc737265f8c98ad17f9Michael Sawyer#include <isc/assertions.h>
f4f73ec517c5389acb234bc737265f8c98ad17f9Michael Sawyer
f4f73ec517c5389acb234bc737265f8c98ad17f9Michael Sawyer#include <dns/result.h>
f4f73ec517c5389acb234bc737265f8c98ad17f9Michael Sawyer
27c1fa93a0b4cef925ddbc69e6cd2bdb78240feaDavid Lawrence#include <dns/confkeys.h>
2c089bf6d24936de631a57b4958ba6b8b5e3b23dMark Andrews#include <dns/confcommon.h>
2c089bf6d24936de631a57b4958ba6b8b5e3b23dMark Andrews
27c1fa93a0b4cef925ddbc69e6cd2bdb78240feaDavid Lawrencestatic isc_result_t keyid_delete(isc_log_t *lctx, dns_c_kid_t **ki);
27c1fa93a0b4cef925ddbc69e6cd2bdb78240feaDavid Lawrence
27c1fa93a0b4cef925ddbc69e6cd2bdb78240feaDavid Lawrence
2c089bf6d24936de631a57b4958ba6b8b5e3b23dMark Andrews
27c1fa93a0b4cef925ddbc69e6cd2bdb78240feaDavid Lawrenceisc_result_t
27c1fa93a0b4cef925ddbc69e6cd2bdb78240feaDavid Lawrencedns_c_kdeflist_new(isc_log_t *lctx,
f4f73ec517c5389acb234bc737265f8c98ad17f9Michael Sawyer isc_mem_t *mem, dns_c_kdeflist_t **list)
f4f73ec517c5389acb234bc737265f8c98ad17f9Michael Sawyer{
1988fd60faefcc65119896996e0f33d91440b1d2Andreas Gustafsson dns_c_kdeflist_t *newlist;
f4f73ec517c5389acb234bc737265f8c98ad17f9Michael Sawyer
f4f73ec517c5389acb234bc737265f8c98ad17f9Michael Sawyer (void)lctx;
f4f73ec517c5389acb234bc737265f8c98ad17f9Michael Sawyer
f4f73ec517c5389acb234bc737265f8c98ad17f9Michael Sawyer REQUIRE(mem != NULL);
f4f73ec517c5389acb234bc737265f8c98ad17f9Michael Sawyer REQUIRE(list != NULL);
2c089bf6d24936de631a57b4958ba6b8b5e3b23dMark Andrews
f4f73ec517c5389acb234bc737265f8c98ad17f9Michael Sawyer newlist = isc_mem_get(mem, sizeof *newlist);
f4f73ec517c5389acb234bc737265f8c98ad17f9Michael Sawyer if (newlist == NULL) {
434bfc3dfa2003ba0dd4b2392286806131fd6724Evan Hunt return (ISC_R_NOMEMORY);
434bfc3dfa2003ba0dd4b2392286806131fd6724Evan Hunt }
434bfc3dfa2003ba0dd4b2392286806131fd6724Evan Hunt
434bfc3dfa2003ba0dd4b2392286806131fd6724Evan Hunt newlist->mem = mem;
434bfc3dfa2003ba0dd4b2392286806131fd6724Evan Hunt ISC_LIST_INIT(newlist->keydefs);
434bfc3dfa2003ba0dd4b2392286806131fd6724Evan Hunt
*list = newlist;
return (ISC_R_SUCCESS);
}
isc_result_t
dns_c_kdeflist_delete(isc_log_t *lctx,
dns_c_kdeflist_t **list)
{
dns_c_kdeflist_t *l;
dns_c_kdef_t *kd;
dns_c_kdef_t *tmpkd;
isc_result_t res;
REQUIRE(list != NULL);
REQUIRE(*list != NULL);
l = *list;
kd = ISC_LIST_HEAD(l->keydefs);
while (kd != NULL) {
tmpkd = ISC_LIST_NEXT(kd, next);
ISC_LIST_UNLINK(l->keydefs, kd, next);
res = dns_c_kdef_delete(lctx, &kd);
if (res != ISC_R_SUCCESS) {
return (res);
}
kd = tmpkd;
}
isc_mem_put(l->mem, l, sizeof *l);
*list = NULL;
return (ISC_R_SUCCESS);
}
isc_result_t
dns_c_kdeflist_copy(isc_log_t *lctx,
isc_mem_t *mem, dns_c_kdeflist_t **dest,
dns_c_kdeflist_t *src)
{
dns_c_kdeflist_t *newlist;
dns_c_kdef_t *key;
isc_result_t res;
REQUIRE(dest != NULL);
REQUIRE(src != NULL);
res = dns_c_kdeflist_new(lctx, mem, &newlist);
if (res != ISC_R_SUCCESS) {
return (res);
}
key = ISC_LIST_HEAD(src->keydefs);
while (key != NULL) {
res = dns_c_kdeflist_append(lctx, newlist, key, ISC_TRUE);
if (res != ISC_R_SUCCESS) {
dns_c_kdeflist_delete(lctx, &newlist);
return (res);
}
key = ISC_LIST_NEXT(key, next);
}
*dest = newlist;
return (ISC_R_SUCCESS);
}
isc_result_t
dns_c_kdeflist_append(isc_log_t *lctx, dns_c_kdeflist_t *list,
dns_c_kdef_t *key, isc_boolean_t copy)
{
dns_c_kdef_t *newe;
isc_result_t res;
REQUIRE(list != NULL);
REQUIRE(key != NULL);
if (copy) {
res = dns_c_kdef_copy(lctx, list->mem, &newe, key);
if (res != ISC_R_SUCCESS) {
return (res);
}
} else {
newe = key;
}
ISC_LIST_APPEND(list->keydefs, newe, next);
return (ISC_R_SUCCESS);
}
isc_result_t
dns_c_kdeflist_undef(isc_log_t *lctx,
dns_c_kdeflist_t *list, const char *keyid)
{
dns_c_kdef_t *kd;
isc_result_t r;
REQUIRE(list != NULL);
REQUIRE(keyid != NULL);
kd = ISC_LIST_HEAD(list->keydefs);
while (kd != NULL) {
if (strcmp(kd->keyid, keyid) == 0) {
break;
}
kd = ISC_LIST_NEXT(kd, next);
}
if (kd != NULL) {
ISC_LIST_UNLINK(list->keydefs, kd, next);
(void)dns_c_kdef_delete(lctx, &kd);
r = ISC_R_SUCCESS;
} else {
r = ISC_R_NOTFOUND;
}
return (r);
}
isc_result_t
dns_c_kdeflist_find(isc_log_t *lctx,
dns_c_kdeflist_t *list, const char *keyid,
dns_c_kdef_t **retval)
{
dns_c_kdef_t *kd;
isc_result_t r;
(void)lctx;
REQUIRE(list != NULL);
REQUIRE(keyid != NULL);
kd = ISC_LIST_HEAD(list->keydefs);
while (kd != NULL) {
if (strcmp(kd->keyid, keyid) == 0) {
break;
}
kd = ISC_LIST_NEXT(kd, next);
}
if (kd != NULL) {
*retval = kd;
r = ISC_R_SUCCESS;
} else {
r = ISC_R_NOTFOUND;
}
return (r);
}
void
dns_c_kdeflist_print(isc_log_t *lctx,
FILE *fp, int indent, dns_c_kdeflist_t *list)
{
dns_c_kdef_t *kd;
REQUIRE(fp != NULL);
REQUIRE(indent >= 0);
if (list == NULL) {
return;
}
kd = ISC_LIST_HEAD(list->keydefs);
while (kd != NULL) {
dns_c_kdef_print(lctx, fp, indent, kd);
fprintf(fp, "\n");
kd = ISC_LIST_NEXT(kd, next);
}
}
isc_result_t
dns_c_kdef_new(isc_log_t *lctx,
dns_c_kdeflist_t *list, const char *name,
dns_c_kdef_t **keyid)
{
dns_c_kdef_t *kd;
(void)lctx;
REQUIRE(list != NULL);
kd = isc_mem_get(list->mem, sizeof *kd);
if (kd == NULL) {
return (ISC_R_NOMEMORY);
}
kd->keyid = isc_mem_strdup(list->mem, name);
if (kd->keyid == NULL) {
isc_mem_put(list->mem, kd, sizeof *kd);
}
kd->mylist = list;
kd->algorithm = NULL;
kd->secret = NULL;
ISC_LIST_APPEND(list->keydefs, kd, next);
*keyid = kd;
return (ISC_R_SUCCESS);
}
isc_result_t
dns_c_kdef_delete(isc_log_t *lctx, dns_c_kdef_t **keydef)
{
dns_c_kdef_t *kd;
isc_mem_t *mem;
(void)lctx;
REQUIRE(keydef != NULL);
REQUIRE(*keydef != NULL);
kd = *keydef;
mem = kd->mylist->mem;
isc_mem_free(mem, kd->keyid);
if (kd->algorithm != NULL) {
isc_mem_free(mem, kd->algorithm);
}
if (kd->secret != NULL) {
isc_mem_free(mem, kd->secret);
}
kd->keyid = NULL;
kd->mylist = NULL;
kd->algorithm = NULL;
kd->secret = NULL;
ISC_LINK_INIT(kd,next);
isc_mem_put(mem, kd, sizeof *kd);
*keydef = NULL;
return (ISC_R_SUCCESS);
}
isc_result_t
dns_c_kdef_copy(isc_log_t *lctx, isc_mem_t *mem,
dns_c_kdef_t **dest, dns_c_kdef_t *src)
{
dns_c_kdef_t *newk;
REQUIRE(dest != NULL);
REQUIRE(src != NULL);
newk = isc_mem_get(mem, sizeof *newk);
if (newk == NULL) {
return (ISC_R_NOMEMORY);
}
newk->secret = newk->algorithm = newk->keyid = NULL;
newk->keyid = isc_mem_strdup(mem, src->keyid);
if (newk->keyid == NULL) {
dns_c_kdef_delete(lctx, &newk);
return (ISC_R_NOMEMORY);
}
newk->algorithm = isc_mem_strdup(mem, src->algorithm);
if (newk->algorithm == NULL) {
dns_c_kdef_delete(lctx, &newk);
return (ISC_R_NOMEMORY);
}
newk->secret = isc_mem_strdup(mem, src->secret);
if (newk->secret == NULL) {
dns_c_kdef_delete(lctx, &newk);
return (ISC_R_NOMEMORY);
}
*dest = newk;
return (ISC_R_SUCCESS);
}
void
dns_c_kdef_print(isc_log_t *lctx,
FILE *fp, int indent, dns_c_kdef_t *keydef)
{
const char *quote = "";
REQUIRE(fp != NULL);
REQUIRE(keydef != NULL);
if (dns_c_need_quote(lctx, keydef->keyid)) {
quote = "\"";
}
dns_c_printtabs(lctx, fp, indent);
fprintf(fp, "key %s%s%s {\n",quote, keydef->keyid, quote);
dns_c_printtabs(lctx, fp, indent + 1);
fprintf(fp, "algorithm \"%s\";\n",keydef->algorithm);
dns_c_printtabs(lctx, fp, indent + 1);
fprintf(fp, "secret \"%s\";\n",keydef->secret);
dns_c_printtabs(lctx, fp, indent);
fprintf(fp, "};\n");
}
isc_result_t
dns_c_kdef_setalgorithm(isc_log_t *lctx,
dns_c_kdef_t *keydef, const char *algorithm)
{
(void)lctx;
REQUIRE(keydef != NULL);
if (keydef->algorithm != NULL) {
isc_mem_free(keydef->mylist->mem, keydef->algorithm);
}
keydef->algorithm = isc_mem_strdup(keydef->mylist->mem,
algorithm);
if (keydef->algorithm == NULL) {
return (ISC_R_NOMEMORY);
}
return (ISC_R_SUCCESS);
}
isc_result_t
dns_c_kdef_setsecret(isc_log_t *lctx,
dns_c_kdef_t *keydef, const char *secret)
{
(void)lctx;
REQUIRE(keydef != NULL);
if (keydef->secret != NULL) {
isc_mem_free(keydef->mylist->mem, keydef->secret);
}
keydef->secret = isc_mem_strdup(keydef->mylist->mem, secret);
if (keydef->secret == NULL) {
return (ISC_R_NOMEMORY);
}
return (ISC_R_SUCCESS);
}
isc_result_t
dns_c_kidlist_new(isc_log_t *lctx,
isc_mem_t *mem, dns_c_kidlist_t **list)
{
dns_c_kidlist_t *l;
(void)lctx;
l = isc_mem_get(mem, sizeof *l);
if (l == NULL) {
return (ISC_R_NOMEMORY);
}
l->mem = mem;
*list = l;
ISC_LIST_INIT(l->keyids);
return (ISC_R_SUCCESS);
}
isc_result_t
dns_c_kidlist_delete(isc_log_t *lctx,
dns_c_kidlist_t **list)
{
dns_c_kidlist_t *l;
dns_c_kid_t *ki, *tmpki;
isc_result_t r;
REQUIRE(list != NULL);
REQUIRE(*list != NULL);
l = *list;
ki = ISC_LIST_HEAD(l->keyids);
while (ki != NULL) {
tmpki = ISC_LIST_NEXT(ki, next);
ISC_LIST_UNLINK(l->keyids, ki, next);
r = keyid_delete(lctx, &ki);
if (r != ISC_R_SUCCESS) {
return (r);
}
ki = tmpki;
}
isc_mem_put(l->mem, l, sizeof *l);
*list = NULL;
return (ISC_R_SUCCESS);
}
static isc_result_t
keyid_delete(isc_log_t *lctx,
dns_c_kid_t **keyid)
{
dns_c_kid_t *ki;
(void)lctx;
REQUIRE(keyid != NULL);
REQUIRE(*keyid != NULL);
ki = *keyid;
isc_mem_free(ki->mylist->mem, ki->keyid);
isc_mem_put(ki->mylist->mem, ki, sizeof *ki);
*keyid = NULL;
return (ISC_R_SUCCESS);
}
isc_result_t
dns_c_kidlist_undef(isc_log_t *lctx,
dns_c_kidlist_t *list, const char *keyid)
{
dns_c_kid_t *ki;
isc_result_t r;
dns_c_kidlist_find(lctx, list, keyid, &ki);
if (ki != NULL) {
ISC_LIST_UNLINK(list->keyids, ki, next);
r = keyid_delete(lctx, &ki);
} else {
r = ISC_R_SUCCESS;
}
return (r);
}
isc_result_t
dns_c_kidlist_find(isc_log_t *lctx,
dns_c_kidlist_t *list, const char *keyid,
dns_c_kid_t **retval)
{
dns_c_kid_t *iter;
(void)lctx;
REQUIRE(retval != NULL);
iter = ISC_LIST_HEAD(list->keyids);
while (iter != NULL) {
if (strcmp(keyid, iter->keyid) == 0) {
break;
}
iter = ISC_LIST_NEXT(iter, next);
}
*retval = iter;
return (iter == NULL ? ISC_R_NOTFOUND : ISC_R_SUCCESS);
}
void
dns_c_kidlist_print(isc_log_t *lctx, FILE *fp, int indent,
dns_c_kidlist_t *list)
{
dns_c_kid_t *iter;
const char *quote;
REQUIRE(fp != NULL);
REQUIRE(list != NULL);
if (ISC_LIST_EMPTY(list->keyids)) {
return;
}
dns_c_printtabs(lctx, fp, indent);
fprintf(fp, "keys {\n");
iter = ISC_LIST_HEAD(list->keyids);
if (iter == NULL) {
dns_c_printtabs(lctx, fp, indent + 1);
fprintf(fp, "/* no keys defined */\n");
} else {
while (iter != NULL) {
if (dns_c_need_quote(lctx, iter->keyid)) {
quote = "\"";
} else {
quote = "";
}
dns_c_printtabs(lctx, fp, indent + 1);
fprintf(fp, "%s%s%s;\n", quote, iter->keyid, quote);
iter = ISC_LIST_NEXT(iter, next);
}
}
dns_c_printtabs(lctx, fp, indent);
fprintf(fp, "};\n");
}
isc_result_t
dns_c_kid_new(isc_log_t *lctx,
dns_c_kidlist_t *list, const char *name, dns_c_kid_t **keyid)
{
dns_c_kid_t *ki;
(void)lctx;
REQUIRE(list != NULL);
ki = isc_mem_get(list->mem, sizeof *ki);
if (ki == NULL) {
return (ISC_R_NOMEMORY);
}
ki->mylist = list;
ki->keyid = isc_mem_strdup(list->mem, name);
ISC_LINK_INIT(ki, next);
ISC_LIST_APPEND(list->keyids, ki, next);
*keyid = ki;
return (ISC_R_SUCCESS);
}
isc_result_t
dns_c_pubkey_new(isc_log_t *lctx,
isc_mem_t *mem, isc_int32_t flags,
isc_int32_t protocol,
isc_int32_t algorithm,
const char *key, dns_c_pubkey_t **pubkey)
{
dns_c_pubkey_t *pkey;
(void)lctx;
pkey = isc_mem_get(mem, sizeof *pkey);
if (pkey == NULL) {
return (ISC_R_NOMEMORY);
}
pkey->mem = mem;
pkey->flags = flags;
pkey->protocol = protocol;
pkey->algorithm = algorithm;
pkey->key = isc_mem_strdup(mem, key);
if (pkey->key == NULL) {
isc_mem_put(mem, pkey, sizeof *pkey);
return (ISC_R_NOMEMORY);
}
*pubkey = pkey;
return (ISC_R_SUCCESS);
}
isc_result_t
dns_c_pubkey_delete(isc_log_t *lctx,
dns_c_pubkey_t **pubkey)
{
dns_c_pubkey_t *pkey;
(void)lctx;
REQUIRE(pubkey != NULL);
REQUIRE(*pubkey != NULL);
pkey = *pubkey;
if (pkey->key != NULL) {
isc_mem_free(pkey->mem, pkey->key);
}
isc_mem_put(pkey->mem, pkey, sizeof *pkey);
return (ISC_R_SUCCESS);
}
isc_result_t
dns_c_pubkey_copy(isc_log_t *lctx,
isc_mem_t *mem, dns_c_pubkey_t **dest, dns_c_pubkey_t *src)
{
dns_c_pubkey_t *k;
isc_result_t res;
res = dns_c_pubkey_new(lctx, mem, src->flags, src->protocol,
src->algorithm, src->key, &k);
if (res != ISC_R_SUCCESS) {
return (res);
}
*dest = k;
return (ISC_R_SUCCESS);
}
isc_boolean_t
dns_c_pubkey_equal(dns_c_pubkey_t *k1, dns_c_pubkey_t *k2) {
if (k1 == NULL && k2 == NULL)
return (ISC_TRUE);
if (k1 == NULL || k2 == NULL)
return (ISC_FALSE);
return (ISC_TF(k1->flags == k2->flags &&
k1->protocol == k2->protocol &&
k1->algorithm == k2->algorithm &&
strcmp(k1->key, k2->key) == 0));
}
void
dns_c_pubkey_print(isc_log_t *lctx,
FILE *fp, int indent, dns_c_pubkey_t *pubkey)
{
REQUIRE(fp != NULL);
REQUIRE(pubkey != NULL);
if (pubkey == NULL) {
return;
}
dns_c_printtabs(lctx, fp, indent);
fprintf(fp, "pubkey %d %d %d \"%s\";\n",
pubkey->flags, pubkey->protocol,
pubkey->algorithm, pubkey->key);
}
isc_result_t
dns_c_tkeylist_new(isc_log_t *lctx,
isc_mem_t *mem, dns_c_tkeylist_t **newlist)
{
dns_c_tkeylist_t *nl;
(void)lctx;
REQUIRE(newlist != NULL);
nl = isc_mem_get(mem, sizeof *nl);
if (nl == NULL) {
return (ISC_R_NOMEMORY);
}
nl->mem = mem;
ISC_LIST_INIT(nl->tkeylist);
*newlist = nl;
return (ISC_R_SUCCESS);
}
isc_result_t
dns_c_tkeylist_delete(isc_log_t *lctx,
dns_c_tkeylist_t **list)
{
dns_c_tkeylist_t *l;
dns_c_tkey_t *tkey, *tmptkey;
isc_result_t res;
REQUIRE(list != NULL);
REQUIRE(*list != NULL);
l = *list;
tkey = ISC_LIST_HEAD(l->tkeylist);
while (tkey != NULL) {
tmptkey = ISC_LIST_NEXT(tkey, next);
ISC_LIST_UNLINK(l->tkeylist, tkey, next);
res = dns_c_tkey_delete(lctx, &tkey);
if (res != ISC_R_SUCCESS) {
return (res);
}
tkey = tmptkey;
}
isc_mem_put(l->mem, l, sizeof *l);
*list = NULL;
return (ISC_R_SUCCESS);
}
isc_result_t
dns_c_tkeylist_copy(isc_log_t *lctx,
isc_mem_t *mem, dns_c_tkeylist_t **dest,
dns_c_tkeylist_t *src)
{
dns_c_tkeylist_t *newlist;
dns_c_tkey_t *tkey, *tmptkey;
isc_result_t res;
REQUIRE(dest != NULL);
REQUIRE(src != NULL);
res = dns_c_tkeylist_new(lctx, mem, &newlist);
if (res != ISC_R_SUCCESS) {
return (res);
}
tkey = ISC_LIST_HEAD(src->tkeylist);
while (tkey != NULL) {
res = dns_c_tkey_copy(lctx, mem, &tmptkey, tkey);
if (res != ISC_R_SUCCESS) {
dns_c_tkeylist_delete(lctx, &newlist);
return (res);
}
res = dns_c_tkeylist_append(lctx, newlist, tmptkey, ISC_FALSE);
if (res != ISC_R_SUCCESS) {
dns_c_tkey_delete(lctx, &tmptkey);
dns_c_tkeylist_delete(lctx, &newlist);
return (res);
}
tkey = ISC_LIST_NEXT(tkey, next);
}
*dest = newlist;
return (ISC_R_SUCCESS);
}
void
dns_c_tkeylist_print(isc_log_t *lctx,
FILE *fp, int indent, dns_c_tkeylist_t *list)
{
dns_c_tkey_t *tkey;
REQUIRE(fp != NULL);
if (list == NULL || ISC_LIST_EMPTY(list->tkeylist)) {
return;
}
dns_c_printtabs(lctx, fp, indent);
fprintf(fp, "trusted-keys {\n");
tkey = ISC_LIST_HEAD(list->tkeylist);
while (tkey != NULL) {
dns_c_tkey_print(lctx, fp, indent + 1, tkey);
tkey = ISC_LIST_NEXT(tkey, next);
}
dns_c_printtabs(lctx, fp, indent);
fprintf(fp,"};\n");
}
isc_result_t
dns_c_tkeylist_append(isc_log_t *lctx,
dns_c_tkeylist_t *list, dns_c_tkey_t *element,
isc_boolean_t copy)
{
dns_c_tkey_t *newe;
isc_result_t res;
REQUIRE(list != NULL);
REQUIRE(element != NULL);
if (copy) {
res = dns_c_tkey_copy(lctx, list->mem, &newe, element);
if (res != ISC_R_SUCCESS) {
return (res);
}
} else {
newe = element;
}
ISC_LIST_APPEND(list->tkeylist, newe, next);
return (ISC_R_SUCCESS);
}
isc_result_t
dns_c_tkey_new(isc_log_t *lctx,
isc_mem_t *mem, const char *domain, isc_int32_t flags,
isc_int32_t protocol, isc_int32_t algorithm,
const char *key, dns_c_tkey_t **newkey)
{
dns_c_tkey_t *newk;
dns_c_pubkey_t *pk;
dns_result_t res;
REQUIRE(domain != NULL);
REQUIRE(strlen(domain) > 0);
REQUIRE(key != NULL);
REQUIRE(strlen(key) > 0);
newk = isc_mem_get(mem, sizeof *newk);
if (newk == NULL) {
return (ISC_R_NOMEMORY);
}
res = dns_c_pubkey_new(lctx, mem, flags, protocol,
algorithm, key, &pk);
if (res != ISC_R_SUCCESS) {
isc_mem_put(mem, newk, sizeof *newk);
return (res);
}
newk->mem = mem;
newk->domain = isc_mem_strdup(mem, domain);
if (newk->domain == NULL) {
dns_c_pubkey_delete(lctx, &pk);
isc_mem_put(mem, newk, sizeof *newk);
return (ISC_R_NOMEMORY);
}
newk->pubkey = pk;
ISC_LINK_INIT(newk, next);
*newkey = newk;
return (ISC_R_SUCCESS);
}
isc_result_t
dns_c_tkey_delete(isc_log_t *lctx,
dns_c_tkey_t **tkey)
{
isc_result_t res;
dns_c_tkey_t *tk;
REQUIRE(tkey != NULL);
REQUIRE(*tkey != NULL);
tk = *tkey;
isc_mem_free(tk->mem, tk->domain);
res = dns_c_pubkey_delete(lctx, &tk->pubkey);
if (res != ISC_R_SUCCESS) {
return (res);
}
isc_mem_put(tk->mem, tk, sizeof *tk);
*tkey = NULL;
return (ISC_R_SUCCESS);
}
isc_result_t
dns_c_tkey_copy(isc_log_t *lctx,
isc_mem_t *mem, dns_c_tkey_t **dest, dns_c_tkey_t *src)
{
dns_c_tkey_t *newk;
dns_c_pubkey_t *newpk;
isc_result_t res;
REQUIRE(dest != NULL);
REQUIRE(src != NULL);
newk = isc_mem_get(mem, sizeof *newk);
if (newk == NULL) {
return (ISC_R_NOMEMORY);
}
newk->domain = isc_mem_strdup(mem, src->domain);
if (newk->domain == NULL) {
isc_mem_put(mem, newk, sizeof *newk);
return (ISC_R_NOMEMORY);
}
res = dns_c_pubkey_copy(lctx, mem, &newpk, src->pubkey);
if (res != ISC_R_SUCCESS) {
isc_mem_free(mem, newk->domain);
isc_mem_put(mem, newk, sizeof *newk);
return (res);
}
newk->pubkey = newpk;
*dest = newk;
return (ISC_R_SUCCESS);
}
isc_result_t
dns_c_tkey_getflags(isc_log_t *lctx,
dns_c_tkey_t *tkey, isc_int32_t *flags)
{
(void)lctx;
REQUIRE(tkey != NULL);
*flags = tkey->pubkey->flags;
return (ISC_R_SUCCESS);
}
isc_result_t
dns_c_tkey_getprotocol(isc_log_t *lctx,
dns_c_tkey_t *tkey, isc_int32_t *protocol)
{
(void)lctx;
REQUIRE(tkey != NULL);
*protocol = tkey->pubkey->protocol;
return (ISC_R_SUCCESS);
}
isc_result_t
dns_c_tkey_getalgorithm(isc_log_t *lctx,
dns_c_tkey_t *tkey, isc_int32_t *algorithm)
{
(void)lctx;
REQUIRE(tkey != NULL);
*algorithm = tkey->pubkey->algorithm;
return (ISC_R_SUCCESS);
}
isc_result_t
dns_c_tkey_getkey(isc_log_t *lctx,
dns_c_tkey_t *tkey, const char **key)
{
(void)lctx;
REQUIRE(key != NULL);
REQUIRE(tkey != NULL);
*key = tkey->pubkey->key;
return (ISC_R_SUCCESS);
}
void
dns_c_tkey_print(isc_log_t *lctx,
FILE *fp, int indent, dns_c_tkey_t *tkey)
{
REQUIRE(fp != NULL);
REQUIRE(tkey != NULL);
dns_c_printtabs(lctx, fp, indent);
fprintf(fp, "\"%s\" %d %d %d \"%s\";\n",
tkey->domain, tkey->pubkey->flags,
tkey->pubkey->protocol, tkey->pubkey->algorithm,
tkey->pubkey->key);
return;
}