2 * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
9 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
10 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
11 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
12 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
13 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
14 * PERFORMANCE OF THIS SOFTWARE.
17 /* $Id: dnsconf.c,v 1.3 2009/09/02 23:48:02 tbox Exp $ */
25 #include <isc/base64.h>
26 #include <isc/buffer.h>
31 #include <isccfg/dnsconf.h>
33 #include <dns/fixedname.h>
35 #include <dns/rdata.h>
36 #include <dns/rdatastruct.h>
38 #include <irs/dnsconf.h>
40 #define IRS_DNSCONF_MAGIC ISC_MAGIC('D', 'c', 'f', 'g')
41 #define IRS_DNSCONF_VALID(c) ISC_MAGIC_VALID(c, IRS_DNSCONF_MAGIC)
44 * configuration data structure
50 irs_dnsconf_dnskeylist_t trusted_keylist;
54 configure_dnsseckeys(irs_dnsconf_t *conf, cfg_obj_t *cfgobj,
55 dns_rdataclass_t rdclass)
57 isc_mem_t *mctx = conf->mctx;
58 const cfg_obj_t *keys = NULL;
59 const cfg_obj_t *key, *keylist;
60 dns_fixedname_t fkeyname;
61 dns_name_t *keyname_base, *keyname;
62 const cfg_listelt_t *element, *element2;
64 isc_uint32_t flags, proto, alg;
65 const char *keystr, *keynamestr;
66 unsigned char keydata[4096];
67 isc_buffer_t keydatabuf_base, *keydatabuf;
68 dns_rdata_dnskey_t keystruct;
69 unsigned char rrdata[4096];
70 isc_buffer_t rrdatabuf;
73 irs_dnsconf_dnskey_t *keyent;
75 cfg_map_get(cfgobj, "trusted-keys", &keys);
77 return (ISC_R_SUCCESS);
79 for (element = cfg_list_first(keys);
81 element = cfg_list_next(element)) {
82 keylist = cfg_listelt_value(element);
83 for (element2 = cfg_list_first(keylist);
85 element2 = cfg_list_next(element2))
90 key = cfg_listelt_value(element2);
92 flags = cfg_obj_asuint32(cfg_tuple_get(key, "flags"));
93 proto = cfg_obj_asuint32(cfg_tuple_get(key,
95 alg = cfg_obj_asuint32(cfg_tuple_get(key,
97 keynamestr = cfg_obj_asstring(cfg_tuple_get(key,
100 keystruct.common.rdclass = rdclass;
101 keystruct.common.rdtype = dns_rdatatype_dnskey;
102 keystruct.mctx = NULL;
103 ISC_LINK_INIT(&keystruct.common, link);
106 return (ISC_R_RANGE);
108 return (ISC_R_RANGE);
110 return (ISC_R_RANGE);
111 keystruct.flags = (isc_uint16_t)flags;
112 keystruct.protocol = (isc_uint8_t)proto;
113 keystruct.algorithm = (isc_uint8_t)alg;
115 isc_buffer_init(&keydatabuf_base, keydata,
117 isc_buffer_init(&rrdatabuf, rrdata, sizeof(rrdata));
119 /* Configure key value */
120 keystr = cfg_obj_asstring(cfg_tuple_get(key, "key"));
121 result = isc_base64_decodestring(keystr,
123 if (result != ISC_R_SUCCESS)
125 isc_buffer_usedregion(&keydatabuf_base, &r);
126 keystruct.datalen = r.length;
127 keystruct.data = r.base;
129 result = dns_rdata_fromstruct(NULL,
130 keystruct.common.rdclass,
131 keystruct.common.rdtype,
132 &keystruct, &rrdatabuf);
133 if (result != ISC_R_SUCCESS)
135 isc_buffer_usedregion(&rrdatabuf, &r);
136 result = isc_buffer_allocate(mctx, &keydatabuf,
138 if (result != ISC_R_SUCCESS)
140 result = isc_buffer_copyregion(keydatabuf, &r);
141 if (result != ISC_R_SUCCESS)
144 /* Configure key name */
145 dns_fixedname_init(&fkeyname);
146 keyname_base = dns_fixedname_name(&fkeyname);
147 isc_buffer_init(&namebuf, keynamestr,
149 isc_buffer_add(&namebuf, strlen(keynamestr));
150 result = dns_name_fromtext(keyname_base, &namebuf,
151 dns_rootname, 0, NULL);
152 if (result != ISC_R_SUCCESS)
154 keyname = isc_mem_get(mctx, sizeof(*keyname));
155 if (keyname == NULL) {
156 result = ISC_R_NOMEMORY;
159 dns_name_init(keyname, NULL);
160 result = dns_name_dup(keyname_base, mctx, keyname);
161 if (result != ISC_R_SUCCESS)
164 /* Add the key data to the list */
165 keyent = isc_mem_get(mctx, sizeof(*keyent));
166 if (keyent == NULL) {
167 dns_name_free(keyname, mctx);
168 result = ISC_R_NOMEMORY;
171 keyent->keyname = keyname;
172 keyent->keydatabuf = keydatabuf;
174 ISC_LIST_APPEND(conf->trusted_keylist, keyent, link);
178 return (ISC_R_SUCCESS);
181 if (keydatabuf != NULL)
182 isc_buffer_free(&keydatabuf);
184 isc_mem_put(mctx, keyname, sizeof(*keyname));
190 irs_dnsconf_load(isc_mem_t *mctx, const char *filename, irs_dnsconf_t **confp)
193 cfg_parser_t *parser = NULL;
194 cfg_obj_t *cfgobj = NULL;
195 isc_result_t result = ISC_R_SUCCESS;
197 REQUIRE(confp != NULL && *confp == NULL);
199 conf = isc_mem_get(mctx, sizeof(*conf));
201 return (ISC_R_NOMEMORY);
204 ISC_LIST_INIT(conf->trusted_keylist);
207 * If the specified file does not exist, we'll simply with an empty
210 if (!isc_file_exists(filename))
213 result = cfg_parser_create(mctx, NULL, &parser);
214 if (result != ISC_R_SUCCESS)
217 result = cfg_parse_file(parser, filename, &cfg_type_dnsconf,
219 if (result != ISC_R_SUCCESS)
222 result = configure_dnsseckeys(conf, cfgobj, dns_rdataclass_in);
225 if (parser != NULL) {
227 cfg_obj_destroy(parser, &cfgobj);
228 cfg_parser_destroy(&parser);
231 conf->magic = IRS_DNSCONF_MAGIC;
233 if (result == ISC_R_SUCCESS)
236 irs_dnsconf_destroy(&conf);
242 irs_dnsconf_destroy(irs_dnsconf_t **confp) {
244 irs_dnsconf_dnskey_t *keyent;
246 REQUIRE(confp != NULL);
248 REQUIRE(IRS_DNSCONF_VALID(conf));
250 while ((keyent = ISC_LIST_HEAD(conf->trusted_keylist)) != NULL) {
251 ISC_LIST_UNLINK(conf->trusted_keylist, keyent, link);
253 isc_buffer_free(&keyent->keydatabuf);
254 dns_name_free(keyent->keyname, conf->mctx);
255 isc_mem_put(conf->mctx, keyent->keyname, sizeof(dns_name_t));
256 isc_mem_put(conf->mctx, keyent, sizeof(*keyent));
259 isc_mem_put(conf->mctx, conf, sizeof(*conf));
264 irs_dnsconf_dnskeylist_t *
265 irs_dnsconf_gettrustedkeys(irs_dnsconf_t *conf) {
266 REQUIRE(IRS_DNSCONF_VALID(conf));
268 return (&conf->trusted_keylist);