2 * Copyright (C) 2004, 2006 Internet Systems Consortium, Inc. ("ISC")
3 * Copyright (C) 1999-2001 Internet Software Consortium.
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
9 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15 * PERFORMANCE OF THIS SOFTWARE.
18 /* $Id: tsigconf.c,v 1.21.208.6 2006/03/02 00:37:20 marka Exp $ */
22 #include <isc/base64.h>
23 #include <isc/buffer.h>
25 #include <isc/string.h>
27 #include <isccfg/cfg.h>
30 #include <dns/result.h>
32 #include <named/log.h>
34 #include <named/config.h>
35 #include <named/tsigconf.h>
38 add_initial_keys(const cfg_obj_t *list, dns_tsig_keyring_t *ring,
41 const cfg_listelt_t *element;
42 const cfg_obj_t *key = NULL;
43 const char *keyid = NULL;
44 unsigned char *secret = NULL;
50 for (element = cfg_list_first(list);
52 element = cfg_list_next(element))
54 const cfg_obj_t *algobj = NULL;
55 const cfg_obj_t *secretobj = NULL;
59 char keynamedata[1024];
60 isc_buffer_t keynamesrc, keynamebuf;
61 const char *secretstr;
62 isc_buffer_t secretbuf;
64 key = cfg_listelt_value(element);
65 keyid = cfg_obj_asstring(cfg_map_getname(key));
69 (void)cfg_map_get(key, "algorithm", &algobj);
70 (void)cfg_map_get(key, "secret", &secretobj);
71 INSIST(algobj != NULL && secretobj != NULL);
74 * Create the key name.
76 dns_name_init(&keyname, NULL);
77 isc_buffer_init(&keynamesrc, keyid, strlen(keyid));
78 isc_buffer_add(&keynamesrc, strlen(keyid));
79 isc_buffer_init(&keynamebuf, keynamedata, sizeof(keynamedata));
80 ret = dns_name_fromtext(&keyname, &keynamesrc, dns_rootname,
81 ISC_TRUE, &keynamebuf);
82 if (ret != ISC_R_SUCCESS)
86 * Create the algorithm.
88 algstr = cfg_obj_asstring(algobj);
89 if (ns_config_getkeyalgorithm(algstr, &alg) != ISC_R_SUCCESS) {
90 cfg_obj_log(algobj, ns_g_lctx, ISC_LOG_ERROR,
91 "key '%s': the only supported algorithm "
92 "is hmac-md5", keyid);
97 secretstr = cfg_obj_asstring(secretobj);
98 secretalloc = secretlen = strlen(secretstr) * 3 / 4;
99 secret = isc_mem_get(mctx, secretlen);
100 if (secret == NULL) {
101 ret = ISC_R_NOMEMORY;
104 isc_buffer_init(&secretbuf, secret, secretlen);
105 ret = isc_base64_decodestring(secretstr, &secretbuf);
106 if (ret != ISC_R_SUCCESS)
108 secretlen = isc_buffer_usedlength(&secretbuf);
110 isc_stdtime_get(&now);
111 ret = dns_tsigkey_create(&keyname, alg, secret, secretlen,
112 ISC_FALSE, NULL, now, now,
114 isc_mem_put(mctx, secret, secretalloc);
116 if (ret != ISC_R_SUCCESS)
120 return (ISC_R_SUCCESS);
123 cfg_obj_log(key, ns_g_lctx, ISC_LOG_ERROR,
124 "configuring key '%s': %s", keyid,
125 isc_result_totext(ret));
128 isc_mem_put(mctx, secret, secretalloc);
134 ns_tsigkeyring_fromconfig(const cfg_obj_t *config, const cfg_obj_t *vconfig,
135 isc_mem_t *mctx, dns_tsig_keyring_t **ringp)
137 const cfg_obj_t *maps[3];
138 const cfg_obj_t *keylist;
139 dns_tsig_keyring_t *ring = NULL;
147 maps[i++] = cfg_tuple_get(vconfig, "options");
150 result = dns_tsigkeyring_create(mctx, &ring);
151 if (result != ISC_R_SUCCESS)
158 result = cfg_map_get(maps[i], "key", &keylist);
159 if (result != ISC_R_SUCCESS)
161 result = add_initial_keys(keylist, ring, mctx);
162 if (result != ISC_R_SUCCESS)
167 return (ISC_R_SUCCESS);
170 dns_tsigkeyring_destroy(&ring);