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.
This commit is contained in:
@@ -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)
|
||||
result = configure_key(mctx, key, conf, rdclass);
|
||||
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;
|
||||
keys = NULL;
|
||||
cfg_map_get(cfgobj, "managed-keys", &keys);
|
||||
if (keys == NULL) {
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
keyent->keyname = keyname;
|
||||
keyent->keydatabuf = keydatabuf;
|
||||
|
||||
ISC_LIST_APPEND(conf->trusted_keylist, keyent, link);
|
||||
}
|
||||
}
|
||||
|
||||
return (ISC_R_SUCCESS);
|
||||
|
||||
cleanup:
|
||||
if (keydatabuf != NULL)
|
||||
isc_buffer_free(&keydatabuf);
|
||||
if (keyname != NULL)
|
||||
isc_mem_put(mctx, keyname, sizeof(*keyname));
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
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>
|
||||
|
||||
Reference in New Issue
Block a user