tsigconf.c revision 90c099e88e9f16bfee9edee3ac1a51fc98843772
f93d33e24fdf76eb2558168f018b8992bcfc5681Andreas Gustafsson/*
499b34cea04a46823d003d4c0520c8b03e8513cbBrian Wellington * Copyright (C) 1999-2001 Internet Software Consortium.
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence *
f93d33e24fdf76eb2558168f018b8992bcfc5681Andreas Gustafsson * Permission to use, copy, modify, and distribute this software for any
f93d33e24fdf76eb2558168f018b8992bcfc5681Andreas Gustafsson * purpose with or without fee is hereby granted, provided that the above
f93d33e24fdf76eb2558168f018b8992bcfc5681Andreas Gustafsson * copyright notice and this permission notice appear in all copies.
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence *
15a44745412679c30a6d022733925af70a38b715David Lawrence * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
15a44745412679c30a6d022733925af70a38b715David Lawrence * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
15a44745412679c30a6d022733925af70a38b715David Lawrence * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
15a44745412679c30a6d022733925af70a38b715David Lawrence * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
15a44745412679c30a6d022733925af70a38b715David Lawrence * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
15a44745412679c30a6d022733925af70a38b715David Lawrence * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
15a44745412679c30a6d022733925af70a38b715David Lawrence * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
15a44745412679c30a6d022733925af70a38b715David Lawrence * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
f93d33e24fdf76eb2558168f018b8992bcfc5681Andreas Gustafsson */
f93d33e24fdf76eb2558168f018b8992bcfc5681Andreas Gustafsson
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington/* $Id: tsigconf.c,v 1.16 2001/03/04 21:21:28 bwelling Exp $ */
9c3531d72aeaad6c5f01efe6a1c82023e1379e4dDavid Lawrence
f93d33e24fdf76eb2558168f018b8992bcfc5681Andreas Gustafsson#include <config.h>
f93d33e24fdf76eb2558168f018b8992bcfc5681Andreas Gustafsson
f93d33e24fdf76eb2558168f018b8992bcfc5681Andreas Gustafsson#include <isc/base64.h>
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence#include <isc/buffer.h>
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence#include <isc/mem.h>
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence#include <isc/string.h>
f93d33e24fdf76eb2558168f018b8992bcfc5681Andreas Gustafsson
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington#include <isccfg/cfg.h>
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence#include <dns/tsig.h>
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington#include <dns/result.h>
f93d33e24fdf76eb2558168f018b8992bcfc5681Andreas Gustafsson
7dde2780aeae0da4e965d823578a604d8ce1215fAndreas Gustafsson#include <named/log.h>
7dde2780aeae0da4e965d823578a604d8ce1215fAndreas Gustafsson
9259fed3d8ac5d1efa9b5a647969e40c9c934484Andreas Gustafsson#include <named/tsigconf.h>
9259fed3d8ac5d1efa9b5a647969e40c9c934484Andreas Gustafsson
f93d33e24fdf76eb2558168f018b8992bcfc5681Andreas Gustafssonstatic isc_result_t
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellingtonadd_initial_keys(cfg_obj_t *list, dns_tsig_keyring_t *ring, isc_mem_t *mctx) {
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington cfg_listelt_t *element;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington cfg_obj_t *key = NULL;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington char *keyid = NULL;
f93d33e24fdf76eb2558168f018b8992bcfc5681Andreas Gustafsson unsigned char *secret = NULL;
f93d33e24fdf76eb2558168f018b8992bcfc5681Andreas Gustafsson int secretalloc = 0;
f93d33e24fdf76eb2558168f018b8992bcfc5681Andreas Gustafsson int secretlen = 0;
f93d33e24fdf76eb2558168f018b8992bcfc5681Andreas Gustafsson isc_result_t ret;
fb01226bcd598c36b5edc566489c890c39f03ed3Brian Wellington isc_stdtime_t now;
f93d33e24fdf76eb2558168f018b8992bcfc5681Andreas Gustafsson
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington for (element = cfg_list_first(list);
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington element != NULL;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington element = cfg_list_next(element))
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington {
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington cfg_obj_t *algobj = NULL;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington cfg_obj_t *secretobj = NULL;
f93d33e24fdf76eb2558168f018b8992bcfc5681Andreas Gustafsson dns_name_t keyname;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington dns_name_t *alg;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington char keynamedata[1024];
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington isc_buffer_t keynamesrc, keynamebuf;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington char *secretstr;
9df7d74e421cf715c6e3cbbad2aba6d33a5d1c9bBrian Wellington isc_buffer_t secretbuf;
f93d33e24fdf76eb2558168f018b8992bcfc5681Andreas Gustafsson
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington key = cfg_listelt_value(element);
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington keyid = cfg_obj_asstring(cfg_map_getname(key));
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington algobj = NULL;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington secretobj = NULL;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington (void)cfg_map_get(key, "algorithm", &algobj);
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington (void)cfg_map_get(key, "secret", &secretobj);
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington INSIST(algobj != NULL && secretobj != NULL);
f93d33e24fdf76eb2558168f018b8992bcfc5681Andreas Gustafsson
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence /*
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence * Create the key name.
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence */
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington dns_name_init(&keyname, NULL);
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington isc_buffer_init(&keynamesrc, keyid, strlen(keyid));
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington isc_buffer_add(&keynamesrc, strlen(keyid));
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence isc_buffer_init(&keynamebuf, keynamedata, sizeof(keynamedata));
f93d33e24fdf76eb2558168f018b8992bcfc5681Andreas Gustafsson ret = dns_name_fromtext(&keyname, &keynamesrc, dns_rootname,
f93d33e24fdf76eb2558168f018b8992bcfc5681Andreas Gustafsson ISC_TRUE, &keynamebuf);
f93d33e24fdf76eb2558168f018b8992bcfc5681Andreas Gustafsson if (ret != ISC_R_SUCCESS)
f93d33e24fdf76eb2558168f018b8992bcfc5681Andreas Gustafsson goto failure;
f93d33e24fdf76eb2558168f018b8992bcfc5681Andreas Gustafsson
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence /*
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence * Create the algorithm.
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence */
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington if (strcasecmp(cfg_obj_asstring(algobj), "hmac-md5") == 0)
7a184cd4e5a54a4e530f9bff8a4e46be392d0b52Brian Wellington alg = dns_tsig_hmacmd5_name;
f93d33e24fdf76eb2558168f018b8992bcfc5681Andreas Gustafsson else {
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington cfg_obj_log(algobj, ns_g_lctx, ISC_LOG_ERROR,
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington "key '%s': the only supported algorithm "
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington "is hmac-md5", keyid);
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington ret = DNS_R_BADALG;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington goto failure;
f93d33e24fdf76eb2558168f018b8992bcfc5681Andreas Gustafsson }
f93d33e24fdf76eb2558168f018b8992bcfc5681Andreas Gustafsson
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington secretstr = cfg_obj_asstring(secretobj);
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington secretalloc = secretlen = strlen(secretstr) * 3 / 4;
f93d33e24fdf76eb2558168f018b8992bcfc5681Andreas Gustafsson secret = isc_mem_get(mctx, secretlen);
f93d33e24fdf76eb2558168f018b8992bcfc5681Andreas Gustafsson if (secret == NULL) {
f93d33e24fdf76eb2558168f018b8992bcfc5681Andreas Gustafsson ret = ISC_R_NOMEMORY;
f93d33e24fdf76eb2558168f018b8992bcfc5681Andreas Gustafsson goto failure;
f93d33e24fdf76eb2558168f018b8992bcfc5681Andreas Gustafsson }
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence isc_buffer_init(&secretbuf, secret, secretlen);
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington ret = isc_base64_decodestring(mctx, secretstr, &secretbuf);
f93d33e24fdf76eb2558168f018b8992bcfc5681Andreas Gustafsson if (ret != ISC_R_SUCCESS)
f93d33e24fdf76eb2558168f018b8992bcfc5681Andreas Gustafsson goto failure;
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence secretlen = isc_buffer_usedlength(&secretbuf);
f93d33e24fdf76eb2558168f018b8992bcfc5681Andreas Gustafsson
fb01226bcd598c36b5edc566489c890c39f03ed3Brian Wellington isc_stdtime_get(&now);
7a184cd4e5a54a4e530f9bff8a4e46be392d0b52Brian Wellington ret = dns_tsigkey_create(&keyname, alg, secret, secretlen,
fb01226bcd598c36b5edc566489c890c39f03ed3Brian Wellington ISC_FALSE, NULL, now, now,
fb01226bcd598c36b5edc566489c890c39f03ed3Brian Wellington mctx, ring, NULL);
f93d33e24fdf76eb2558168f018b8992bcfc5681Andreas Gustafsson isc_mem_put(mctx, secret, secretalloc);
f93d33e24fdf76eb2558168f018b8992bcfc5681Andreas Gustafsson secret = NULL;
f93d33e24fdf76eb2558168f018b8992bcfc5681Andreas Gustafsson if (ret != ISC_R_SUCCESS)
f93d33e24fdf76eb2558168f018b8992bcfc5681Andreas Gustafsson goto failure;
f93d33e24fdf76eb2558168f018b8992bcfc5681Andreas Gustafsson }
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington
f93d33e24fdf76eb2558168f018b8992bcfc5681Andreas Gustafsson return (ISC_R_SUCCESS);
f93d33e24fdf76eb2558168f018b8992bcfc5681Andreas Gustafsson
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington failure:
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington cfg_obj_log(key, ns_g_lctx, ISC_LOG_ERROR,
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington "configuring TSIG key '%s': %s", keyid,
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington isc_result_totext(ret));
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington
f93d33e24fdf76eb2558168f018b8992bcfc5681Andreas Gustafsson if (secret != NULL)
9df7d74e421cf715c6e3cbbad2aba6d33a5d1c9bBrian Wellington isc_mem_put(mctx, secret, secretalloc);
f93d33e24fdf76eb2558168f018b8992bcfc5681Andreas Gustafsson return (ret);
f93d33e24fdf76eb2558168f018b8992bcfc5681Andreas Gustafsson
f93d33e24fdf76eb2558168f018b8992bcfc5681Andreas Gustafsson}
f93d33e24fdf76eb2558168f018b8992bcfc5681Andreas Gustafsson
f93d33e24fdf76eb2558168f018b8992bcfc5681Andreas Gustafssonisc_result_t
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellingtonns_tsigkeyring_fromconfig(cfg_obj_t *config, cfg_obj_t *vconfig,
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington isc_mem_t *mctx, dns_tsig_keyring_t **ringp)
f93d33e24fdf76eb2558168f018b8992bcfc5681Andreas Gustafsson{
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington cfg_obj_t *maps[3];
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington cfg_obj_t *keylist;
f93d33e24fdf76eb2558168f018b8992bcfc5681Andreas Gustafsson dns_tsig_keyring_t *ring = NULL;
f93d33e24fdf76eb2558168f018b8992bcfc5681Andreas Gustafsson isc_result_t result;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington int i;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington i = 0;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington if (config != NULL)
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington maps[i++] = config;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington if (vconfig != NULL)
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington maps[i++] = cfg_tuple_get(vconfig, "options");
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington maps[i] = NULL;
f93d33e24fdf76eb2558168f018b8992bcfc5681Andreas Gustafsson
f93d33e24fdf76eb2558168f018b8992bcfc5681Andreas Gustafsson result = dns_tsigkeyring_create(mctx, &ring);
f93d33e24fdf76eb2558168f018b8992bcfc5681Andreas Gustafsson if (result != ISC_R_SUCCESS)
f93d33e24fdf76eb2558168f018b8992bcfc5681Andreas Gustafsson return (result);
c885fad9b8bf204ae9e62c9acb0321e2bcca30a4Andreas Gustafsson
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington for (i = 0; ; i++) {
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington if (maps[i] == NULL)
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington break;
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence keylist = NULL;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington result = cfg_map_get(maps[i], "key", &keylist);
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington if (result != ISC_R_SUCCESS)
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington continue;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington result = add_initial_keys(keylist, ring, mctx);
8c7eaac6bbcc9746afe8f57b60bb964745c01eafAndreas Gustafsson if (result != ISC_R_SUCCESS)
8c7eaac6bbcc9746afe8f57b60bb964745c01eafAndreas Gustafsson goto failure;
8c7eaac6bbcc9746afe8f57b60bb964745c01eafAndreas Gustafsson }
c885fad9b8bf204ae9e62c9acb0321e2bcca30a4Andreas Gustafsson
f93d33e24fdf76eb2558168f018b8992bcfc5681Andreas Gustafsson *ringp = ring;
f93d33e24fdf76eb2558168f018b8992bcfc5681Andreas Gustafsson return (ISC_R_SUCCESS);
f93d33e24fdf76eb2558168f018b8992bcfc5681Andreas Gustafsson
f93d33e24fdf76eb2558168f018b8992bcfc5681Andreas Gustafsson failure:
f93d33e24fdf76eb2558168f018b8992bcfc5681Andreas Gustafsson dns_tsigkeyring_destroy(&ring);
f93d33e24fdf76eb2558168f018b8992bcfc5681Andreas Gustafsson return (result);
f93d33e24fdf76eb2558168f018b8992bcfc5681Andreas Gustafsson}