Commit fec03258 authored by Evan Hunt's avatar Evan Hunt

update irs_dnsconf_load() to read managed-keys statements

- this allows the use of both trusted-keys and managed-keys in files
  loaded by libirs, but managed-keys are always treated as static.
parent 82f5bce1
......@@ -44,138 +44,181 @@ struct irs_dnsconf {
};
static isc_result_t
configure_dnsseckeys(irs_dnsconf_t *conf, cfg_obj_t *cfgobj,
dns_rdataclass_t rdclass)
configure_key(isc_mem_t *mctx, const cfg_obj_t *key, irs_dnsconf_t *conf,
dns_rdataclass_t rdclass)
{
isc_mem_t *mctx = conf->mctx;
const cfg_obj_t *keys = NULL;
const cfg_obj_t *key, *keylist;
dns_fixedname_t fkeyname;
dns_name_t *keyname_base, *keyname;
const cfg_listelt_t *element, *element2;
isc_result_t result;
uint32_t flags, proto, alg;
const char *keystr, *keynamestr;
dns_fixedname_t fkeyname;
dns_name_t *keyname_base = NULL, *keyname = NULL;
const char *keystr = NULL, *keynamestr = NULL;
unsigned char keydata[4096];
isc_buffer_t keydatabuf_base, *keydatabuf;
isc_buffer_t keydatabuf_base, *keydatabuf = NULL;
dns_rdata_dnskey_t keystruct;
unsigned char rrdata[4096];
isc_buffer_t rrdatabuf;
isc_region_t r;
isc_buffer_t namebuf;
irs_dnsconf_dnskey_t *keyent;
irs_dnsconf_dnskey_t *keyent = NULL;
flags = cfg_obj_asuint32(cfg_tuple_get(key, "flags"));
proto = cfg_obj_asuint32(cfg_tuple_get(key,
"protocol"));
alg = cfg_obj_asuint32(cfg_tuple_get(key,
"algorithm"));
keynamestr = cfg_obj_asstring(cfg_tuple_get(key,
"name"));
keystruct.common.rdclass = rdclass;
keystruct.common.rdtype = dns_rdatatype_dnskey;
keystruct.mctx = NULL;
ISC_LINK_INIT(&keystruct.common, link);
if (flags > 0xffff) {
return (ISC_R_RANGE);
}
if (proto > 0xff) {
return (ISC_R_RANGE);
}
if (alg > 0xff) {
return (ISC_R_RANGE);
}
keystruct.flags = (uint16_t)flags;
keystruct.protocol = (uint8_t)proto;
keystruct.algorithm = (uint8_t)alg;
isc_buffer_init(&keydatabuf_base, keydata,
sizeof(keydata));
isc_buffer_init(&rrdatabuf, rrdata, sizeof(rrdata));
/* Configure key value */
keystr = cfg_obj_asstring(cfg_tuple_get(key, "key"));
result = isc_base64_decodestring(keystr,
&keydatabuf_base);
if (result != ISC_R_SUCCESS) {
return (result);
}
isc_buffer_usedregion(&keydatabuf_base, &r);
keystruct.datalen = r.length;
keystruct.data = r.base;
result = dns_rdata_fromstruct(NULL, keystruct.common.rdclass,
keystruct.common.rdtype,
&keystruct, &rrdatabuf);
if (result != ISC_R_SUCCESS) {
return (result);
}
isc_buffer_usedregion(&rrdatabuf, &r);
result = isc_buffer_allocate(mctx, &keydatabuf,
r.length);
if (result != ISC_R_SUCCESS) {
return (result);
}
result = isc_buffer_copyregion(keydatabuf, &r);
if (result != ISC_R_SUCCESS) {
goto cleanup;
}
/* Configure key name */
keyname_base = dns_fixedname_initname(&fkeyname);
isc_buffer_constinit(&namebuf, keynamestr,
strlen(keynamestr));
isc_buffer_add(&namebuf, strlen(keynamestr));
result = dns_name_fromtext(keyname_base, &namebuf,
dns_rootname, 0, NULL);
if (result != ISC_R_SUCCESS) {
return (result);
}
keyname = isc_mem_get(mctx, sizeof(*keyname));
if (keyname == NULL) {
result = ISC_R_NOMEMORY;
goto cleanup;
}
dns_name_init(keyname, NULL);
result = dns_name_dup(keyname_base, mctx, keyname);
if (result != ISC_R_SUCCESS) {
goto cleanup;
}
/* Add the key data to the list */
keyent = isc_mem_get(mctx, sizeof(*keyent));
if (keyent == NULL) {
dns_name_free(keyname, mctx);
result = ISC_R_NOMEMORY;
goto cleanup;
}
keyent->keyname = keyname;
keyent->keydatabuf = keydatabuf;
ISC_LIST_APPEND(conf->trusted_keylist, keyent, link);
cleanup:
if (keydatabuf != NULL) {
isc_buffer_free(&keydatabuf);
}
if (keyname != NULL) {
isc_mem_put(mctx, keyname, sizeof(*keyname));
}
return (result);
}
static isc_result_t
configure_dnsseckeys(irs_dnsconf_t *conf, cfg_obj_t *cfgobj,
dns_rdataclass_t rdclass)
{
isc_result_t result;
isc_mem_t *mctx = conf->mctx;
const cfg_obj_t *keys = NULL;
const cfg_obj_t *key, *keylist;
const cfg_listelt_t *element, *element2;
cfg_map_get(cfgobj, "trusted-keys", &keys);
if (keys == NULL)
if (keys == NULL) {
return (ISC_R_SUCCESS);
}
for (element = cfg_list_first(keys);
element != NULL;
element = cfg_list_next(element)) {
element = cfg_list_next(element))
{
keylist = cfg_listelt_value(element);
for (element2 = cfg_list_first(keylist);
element2 != NULL;
element2 = cfg_list_next(element2))
{
keydatabuf = NULL;
keyname = NULL;
key = cfg_listelt_value(element2);
flags = cfg_obj_asuint32(cfg_tuple_get(key, "flags"));
proto = cfg_obj_asuint32(cfg_tuple_get(key,
"protocol"));
alg = cfg_obj_asuint32(cfg_tuple_get(key,
"algorithm"));
keynamestr = cfg_obj_asstring(cfg_tuple_get(key,
"name"));
keystruct.common.rdclass = rdclass;
keystruct.common.rdtype = dns_rdatatype_dnskey;
keystruct.mctx = NULL;
ISC_LINK_INIT(&keystruct.common, link);
if (flags > 0xffff)
return (ISC_R_RANGE);
if (proto > 0xff)
return (ISC_R_RANGE);
if (alg > 0xff)
return (ISC_R_RANGE);
keystruct.flags = (uint16_t)flags;
keystruct.protocol = (uint8_t)proto;
keystruct.algorithm = (uint8_t)alg;
isc_buffer_init(&keydatabuf_base, keydata,
sizeof(keydata));
isc_buffer_init(&rrdatabuf, rrdata, sizeof(rrdata));
/* Configure key value */
keystr = cfg_obj_asstring(cfg_tuple_get(key, "key"));
result = isc_base64_decodestring(keystr,
&keydatabuf_base);
if (result != ISC_R_SUCCESS)
return (result);
isc_buffer_usedregion(&keydatabuf_base, &r);
keystruct.datalen = r.length;
keystruct.data = r.base;
result = dns_rdata_fromstruct(NULL,
keystruct.common.rdclass,
keystruct.common.rdtype,
&keystruct, &rrdatabuf);
if (result != ISC_R_SUCCESS)
return (result);
isc_buffer_usedregion(&rrdatabuf, &r);
result = isc_buffer_allocate(mctx, &keydatabuf,
r.length);
if (result != ISC_R_SUCCESS)
return (result);
result = isc_buffer_copyregion(keydatabuf, &r);
if (result != ISC_R_SUCCESS)
goto cleanup;
/* Configure key name */
keyname_base = dns_fixedname_initname(&fkeyname);
isc_buffer_constinit(&namebuf, keynamestr,
strlen(keynamestr));
isc_buffer_add(&namebuf, strlen(keynamestr));
result = dns_name_fromtext(keyname_base, &namebuf,
dns_rootname, 0, NULL);
if (result != ISC_R_SUCCESS)
result = configure_key(mctx, key, conf, rdclass);
if (result != ISC_R_SUCCESS) {
return (result);
keyname = isc_mem_get(mctx, sizeof(*keyname));
if (keyname == NULL) {
result = ISC_R_NOMEMORY;
goto cleanup;
}
dns_name_init(keyname, NULL);
result = dns_name_dup(keyname_base, mctx, keyname);
if (result != ISC_R_SUCCESS)
goto cleanup;
/* Add the key data to the list */
keyent = isc_mem_get(mctx, sizeof(*keyent));
if (keyent == NULL) {
dns_name_free(keyname, mctx);
result = ISC_R_NOMEMORY;
goto cleanup;
}
keyent->keyname = keyname;
keyent->keydatabuf = keydatabuf;
ISC_LIST_APPEND(conf->trusted_keylist, keyent, link);
}
}
return (ISC_R_SUCCESS);
keys = NULL;
cfg_map_get(cfgobj, "managed-keys", &keys);
if (keys == NULL) {
return (ISC_R_SUCCESS);
}
cleanup:
if (keydatabuf != NULL)
isc_buffer_free(&keydatabuf);
if (keyname != NULL)
isc_mem_put(mctx, keyname, sizeof(*keyname));
for (element = cfg_list_first(keys);
element != NULL;
element = cfg_list_next(element))
{
keylist = cfg_listelt_value(element);
for (element2 = cfg_list_first(keylist);
element2 != NULL;
element2 = cfg_list_next(element2))
{
key = cfg_listelt_value(element2);
result = configure_key(mctx, key, conf, rdclass);
if (result != ISC_R_SUCCESS) {
return (result);
}
}
}
return (result);
return (ISC_R_SUCCESS);
}
isc_result_t
......
......@@ -22,9 +22,12 @@
*
* Notes:
* This module is very experimental and the configuration syntax or library
* interfaces may change in future versions. Currently, only the
* 'trusted-keys' statement is supported, whose syntax is the same as the
* same name of statement for named.conf.
* interfaces may change in future versions. Currently, only static
* key configuration is supported; "trusted-keys" and "managed-keys"
* statements will be parsed exactly as they are in named.conf, except
* that all "managed-keys" entries will be treated as if they were
* configured with "static-key", even if they were actually configured
* with "initial-key".
*/
#include <irs/types.h>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment