tsigconf.c revision 307d2084502eddc7ce921e5ce439aec3531d90e0
6ceca14e5ea7972a9ba8bc1dca0de1f63f669cfdDanny Mayer/*
4a979d35776321abc952346ba128d1a3cef730ceAutomatic Updater * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
1fa26403d7679235a30fbf6289f68fed5872df30Mark Andrews * Copyright (C) 1999-2001 Internet Software Consortium.
6ceca14e5ea7972a9ba8bc1dca0de1f63f669cfdDanny Mayer *
ec5347e2c775f027573ce5648b910361aa926c01Automatic Updater * Permission to use, copy, modify, and/or distribute this software for any
6ceca14e5ea7972a9ba8bc1dca0de1f63f669cfdDanny Mayer * purpose with or without fee is hereby granted, provided that the above
6ceca14e5ea7972a9ba8bc1dca0de1f63f669cfdDanny Mayer * copyright notice and this permission notice appear in all copies.
6ceca14e5ea7972a9ba8bc1dca0de1f63f669cfdDanny Mayer *
1fa26403d7679235a30fbf6289f68fed5872df30Mark Andrews * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
1fa26403d7679235a30fbf6289f68fed5872df30Mark Andrews * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
1fa26403d7679235a30fbf6289f68fed5872df30Mark Andrews * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
1fa26403d7679235a30fbf6289f68fed5872df30Mark Andrews * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
1fa26403d7679235a30fbf6289f68fed5872df30Mark Andrews * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
1fa26403d7679235a30fbf6289f68fed5872df30Mark Andrews * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
1fa26403d7679235a30fbf6289f68fed5872df30Mark Andrews * PERFORMANCE OF THIS SOFTWARE.
6ceca14e5ea7972a9ba8bc1dca0de1f63f669cfdDanny Mayer */
6ceca14e5ea7972a9ba8bc1dca0de1f63f669cfdDanny Mayer
891b61c3909afdae7e5d7ba14cd12d16186f4a68Mark Andrews/* $Id: tsigconf.c,v 1.33 2009/09/01 00:22:25 jinmei Exp $ */
6ceca14e5ea7972a9ba8bc1dca0de1f63f669cfdDanny Mayer
6ceca14e5ea7972a9ba8bc1dca0de1f63f669cfdDanny Mayer/*! \file */
6ceca14e5ea7972a9ba8bc1dca0de1f63f669cfdDanny Mayer
6ceca14e5ea7972a9ba8bc1dca0de1f63f669cfdDanny Mayer#include <config.h>
6ceca14e5ea7972a9ba8bc1dca0de1f63f669cfdDanny Mayer
6ceca14e5ea7972a9ba8bc1dca0de1f63f669cfdDanny Mayer#include <isc/base64.h>
6ceca14e5ea7972a9ba8bc1dca0de1f63f669cfdDanny Mayer#include <isc/buffer.h>
487e6abc16c1b2958d371b0d4e808953646b520aDavid Lawrence#include <isc/mem.h>
487e6abc16c1b2958d371b0d4e808953646b520aDavid Lawrence#include <isc/string.h>
487e6abc16c1b2958d371b0d4e808953646b520aDavid Lawrence
487e6abc16c1b2958d371b0d4e808953646b520aDavid Lawrence#include <isccfg/cfg.h>
487e6abc16c1b2958d371b0d4e808953646b520aDavid Lawrence
487e6abc16c1b2958d371b0d4e808953646b520aDavid Lawrence#include <dns/tsig.h>
487e6abc16c1b2958d371b0d4e808953646b520aDavid Lawrence#include <dns/result.h>
487e6abc16c1b2958d371b0d4e808953646b520aDavid Lawrence
487e6abc16c1b2958d371b0d4e808953646b520aDavid Lawrence#include <named/log.h>
487e6abc16c1b2958d371b0d4e808953646b520aDavid Lawrence
d3243476c280d3a98cadbfd6343437fa2b29356bDanny Mayer#include <named/config.h>
d3243476c280d3a98cadbfd6343437fa2b29356bDanny Mayer#include <named/tsigconf.h>
d3243476c280d3a98cadbfd6343437fa2b29356bDanny Mayer
d3243476c280d3a98cadbfd6343437fa2b29356bDanny Mayerstatic isc_result_t
d3243476c280d3a98cadbfd6343437fa2b29356bDanny Mayeradd_initial_keys(const cfg_obj_t *list, dns_tsig_keyring_t *ring,
667c498942c0e605c1aab98bca6b90aac4cbbd71Mark Andrews isc_mem_t *mctx)
667c498942c0e605c1aab98bca6b90aac4cbbd71Mark Andrews{
667c498942c0e605c1aab98bca6b90aac4cbbd71Mark Andrews dns_tsigkey_t *tsigkey = NULL;
667c498942c0e605c1aab98bca6b90aac4cbbd71Mark Andrews const cfg_listelt_t *element;
667c498942c0e605c1aab98bca6b90aac4cbbd71Mark Andrews const cfg_obj_t *key = NULL;
667c498942c0e605c1aab98bca6b90aac4cbbd71Mark Andrews const char *keyid = NULL;
667c498942c0e605c1aab98bca6b90aac4cbbd71Mark Andrews unsigned char *secret = NULL;
667c498942c0e605c1aab98bca6b90aac4cbbd71Mark Andrews int secretalloc = 0;
667c498942c0e605c1aab98bca6b90aac4cbbd71Mark Andrews int secretlen = 0;
667c498942c0e605c1aab98bca6b90aac4cbbd71Mark Andrews isc_result_t ret;
d3243476c280d3a98cadbfd6343437fa2b29356bDanny Mayer isc_stdtime_t now;
d3243476c280d3a98cadbfd6343437fa2b29356bDanny Mayer isc_uint16_t bits;
d3243476c280d3a98cadbfd6343437fa2b29356bDanny Mayer
e7c38ca9635e73c9a928bbab9c73c2abbd499f8bEvan Hunt for (element = cfg_list_first(list);
d3243476c280d3a98cadbfd6343437fa2b29356bDanny Mayer element != NULL;
e7c38ca9635e73c9a928bbab9c73c2abbd499f8bEvan Hunt element = cfg_list_next(element))
e7c38ca9635e73c9a928bbab9c73c2abbd499f8bEvan Hunt {
487e6abc16c1b2958d371b0d4e808953646b520aDavid Lawrence const cfg_obj_t *algobj = NULL;
487e6abc16c1b2958d371b0d4e808953646b520aDavid Lawrence const cfg_obj_t *secretobj = NULL;
487e6abc16c1b2958d371b0d4e808953646b520aDavid Lawrence dns_name_t keyname;
487e6abc16c1b2958d371b0d4e808953646b520aDavid Lawrence dns_name_t *alg;
487e6abc16c1b2958d371b0d4e808953646b520aDavid Lawrence const char *algstr;
487e6abc16c1b2958d371b0d4e808953646b520aDavid Lawrence char keynamedata[1024];
487e6abc16c1b2958d371b0d4e808953646b520aDavid Lawrence isc_buffer_t keynamesrc, keynamebuf;
487e6abc16c1b2958d371b0d4e808953646b520aDavid Lawrence const char *secretstr;
487e6abc16c1b2958d371b0d4e808953646b520aDavid Lawrence isc_buffer_t secretbuf;
487e6abc16c1b2958d371b0d4e808953646b520aDavid Lawrence
487e6abc16c1b2958d371b0d4e808953646b520aDavid Lawrence key = cfg_listelt_value(element);
487e6abc16c1b2958d371b0d4e808953646b520aDavid Lawrence keyid = cfg_obj_asstring(cfg_map_getname(key));
487e6abc16c1b2958d371b0d4e808953646b520aDavid Lawrence
487e6abc16c1b2958d371b0d4e808953646b520aDavid Lawrence algobj = NULL;
487e6abc16c1b2958d371b0d4e808953646b520aDavid Lawrence secretobj = NULL;
487e6abc16c1b2958d371b0d4e808953646b520aDavid Lawrence (void)cfg_map_get(key, "algorithm", &algobj);
487e6abc16c1b2958d371b0d4e808953646b520aDavid Lawrence (void)cfg_map_get(key, "secret", &secretobj);
487e6abc16c1b2958d371b0d4e808953646b520aDavid Lawrence INSIST(algobj != NULL && secretobj != NULL);
487e6abc16c1b2958d371b0d4e808953646b520aDavid Lawrence
487e6abc16c1b2958d371b0d4e808953646b520aDavid Lawrence /*
487e6abc16c1b2958d371b0d4e808953646b520aDavid Lawrence * Create the key name.
487e6abc16c1b2958d371b0d4e808953646b520aDavid Lawrence */
487e6abc16c1b2958d371b0d4e808953646b520aDavid Lawrence dns_name_init(&keyname, NULL);
487e6abc16c1b2958d371b0d4e808953646b520aDavid Lawrence isc_buffer_init(&keynamesrc, keyid, strlen(keyid));
487e6abc16c1b2958d371b0d4e808953646b520aDavid Lawrence isc_buffer_add(&keynamesrc, strlen(keyid));
487e6abc16c1b2958d371b0d4e808953646b520aDavid Lawrence isc_buffer_init(&keynamebuf, keynamedata, sizeof(keynamedata));
487e6abc16c1b2958d371b0d4e808953646b520aDavid Lawrence ret = dns_name_fromtext(&keyname, &keynamesrc, dns_rootname,
487e6abc16c1b2958d371b0d4e808953646b520aDavid Lawrence DNS_NAME_DOWNCASE, &keynamebuf);
487e6abc16c1b2958d371b0d4e808953646b520aDavid Lawrence if (ret != ISC_R_SUCCESS)
487e6abc16c1b2958d371b0d4e808953646b520aDavid Lawrence goto failure;
487e6abc16c1b2958d371b0d4e808953646b520aDavid Lawrence
487e6abc16c1b2958d371b0d4e808953646b520aDavid Lawrence /*
487e6abc16c1b2958d371b0d4e808953646b520aDavid Lawrence * Create the algorithm.
487e6abc16c1b2958d371b0d4e808953646b520aDavid Lawrence */
487e6abc16c1b2958d371b0d4e808953646b520aDavid Lawrence algstr = cfg_obj_asstring(algobj);
487e6abc16c1b2958d371b0d4e808953646b520aDavid Lawrence if (ns_config_getkeyalgorithm(algstr, &alg, &bits)
487e6abc16c1b2958d371b0d4e808953646b520aDavid Lawrence != ISC_R_SUCCESS) {
487e6abc16c1b2958d371b0d4e808953646b520aDavid Lawrence cfg_obj_log(algobj, ns_g_lctx, ISC_LOG_ERROR,
487e6abc16c1b2958d371b0d4e808953646b520aDavid Lawrence "key '%s': has a unsupported algorithm '%s'",
487e6abc16c1b2958d371b0d4e808953646b520aDavid Lawrence keyid, algstr);
487e6abc16c1b2958d371b0d4e808953646b520aDavid Lawrence ret = DNS_R_BADALG;
487e6abc16c1b2958d371b0d4e808953646b520aDavid Lawrence goto failure;
487e6abc16c1b2958d371b0d4e808953646b520aDavid Lawrence }
487e6abc16c1b2958d371b0d4e808953646b520aDavid Lawrence
487e6abc16c1b2958d371b0d4e808953646b520aDavid Lawrence secretstr = cfg_obj_asstring(secretobj);
487e6abc16c1b2958d371b0d4e808953646b520aDavid Lawrence secretalloc = secretlen = strlen(secretstr) * 3 / 4;
487e6abc16c1b2958d371b0d4e808953646b520aDavid Lawrence secret = isc_mem_get(mctx, secretlen);
487e6abc16c1b2958d371b0d4e808953646b520aDavid Lawrence if (secret == NULL) {
487e6abc16c1b2958d371b0d4e808953646b520aDavid Lawrence ret = ISC_R_NOMEMORY;
487e6abc16c1b2958d371b0d4e808953646b520aDavid Lawrence goto failure;
487e6abc16c1b2958d371b0d4e808953646b520aDavid Lawrence }
487e6abc16c1b2958d371b0d4e808953646b520aDavid Lawrence isc_buffer_init(&secretbuf, secret, secretlen);
487e6abc16c1b2958d371b0d4e808953646b520aDavid Lawrence ret = isc_base64_decodestring(secretstr, &secretbuf);
487e6abc16c1b2958d371b0d4e808953646b520aDavid Lawrence if (ret != ISC_R_SUCCESS)
487e6abc16c1b2958d371b0d4e808953646b520aDavid Lawrence goto failure;
487e6abc16c1b2958d371b0d4e808953646b520aDavid Lawrence secretlen = isc_buffer_usedlength(&secretbuf);
487e6abc16c1b2958d371b0d4e808953646b520aDavid Lawrence
487e6abc16c1b2958d371b0d4e808953646b520aDavid Lawrence isc_stdtime_get(&now);
487e6abc16c1b2958d371b0d4e808953646b520aDavid Lawrence ret = dns_tsigkey_create(&keyname, alg, secret, secretlen,
6ceca14e5ea7972a9ba8bc1dca0de1f63f669cfdDanny Mayer ISC_FALSE, NULL, now, now,
6ceca14e5ea7972a9ba8bc1dca0de1f63f669cfdDanny Mayer mctx, ring, &tsigkey);
6ceca14e5ea7972a9ba8bc1dca0de1f63f669cfdDanny Mayer isc_mem_put(mctx, secret, secretalloc);
ecffc3aae3e72c5c65b1911ec3f4e1d180dc4bbcMark Andrews secret = NULL;
ecffc3aae3e72c5c65b1911ec3f4e1d180dc4bbcMark Andrews if (ret != ISC_R_SUCCESS)
ecffc3aae3e72c5c65b1911ec3f4e1d180dc4bbcMark Andrews goto failure;
ecffc3aae3e72c5c65b1911ec3f4e1d180dc4bbcMark Andrews /*
ecffc3aae3e72c5c65b1911ec3f4e1d180dc4bbcMark Andrews * Set digest bits.
ecffc3aae3e72c5c65b1911ec3f4e1d180dc4bbcMark Andrews */
ecffc3aae3e72c5c65b1911ec3f4e1d180dc4bbcMark Andrews dst_key_setbits(tsigkey->key, bits);
ecffc3aae3e72c5c65b1911ec3f4e1d180dc4bbcMark Andrews dns_tsigkey_detach(&tsigkey);
ecffc3aae3e72c5c65b1911ec3f4e1d180dc4bbcMark Andrews }
07555e64d9102eae058efd58f872b4a3b9ddff61Mark Andrews
578f588228f5e04ccf648b6ae596f396ad6a22c9Mark Andrews return (ISC_R_SUCCESS);
d3243476c280d3a98cadbfd6343437fa2b29356bDanny Mayer
d3243476c280d3a98cadbfd6343437fa2b29356bDanny Mayer failure:
d3243476c280d3a98cadbfd6343437fa2b29356bDanny Mayer cfg_obj_log(key, ns_g_lctx, ISC_LOG_ERROR,
d3243476c280d3a98cadbfd6343437fa2b29356bDanny Mayer "configuring key '%s': %s", keyid,
d3243476c280d3a98cadbfd6343437fa2b29356bDanny Mayer isc_result_totext(ret));
d3243476c280d3a98cadbfd6343437fa2b29356bDanny Mayer
d3243476c280d3a98cadbfd6343437fa2b29356bDanny Mayer if (secret != NULL)
d3243476c280d3a98cadbfd6343437fa2b29356bDanny Mayer isc_mem_put(mctx, secret, secretalloc);
d3243476c280d3a98cadbfd6343437fa2b29356bDanny Mayer return (ret);
d3243476c280d3a98cadbfd6343437fa2b29356bDanny Mayer}
d3243476c280d3a98cadbfd6343437fa2b29356bDanny Mayer
d3243476c280d3a98cadbfd6343437fa2b29356bDanny Mayerisc_result_t
d3243476c280d3a98cadbfd6343437fa2b29356bDanny Mayerns_tsigkeyring_fromconfig(const cfg_obj_t *config, const cfg_obj_t *vconfig,
d3243476c280d3a98cadbfd6343437fa2b29356bDanny Mayer isc_mem_t *mctx, dns_tsig_keyring_t **ringp)
d3243476c280d3a98cadbfd6343437fa2b29356bDanny Mayer{
d3243476c280d3a98cadbfd6343437fa2b29356bDanny Mayer const cfg_obj_t *maps[3];
d3243476c280d3a98cadbfd6343437fa2b29356bDanny Mayer const cfg_obj_t *keylist;
6ceca14e5ea7972a9ba8bc1dca0de1f63f669cfdDanny Mayer dns_tsig_keyring_t *ring = NULL;
d3243476c280d3a98cadbfd6343437fa2b29356bDanny Mayer isc_result_t result;
a687db7ce86c97d884b7ee1a68f59fcddf4d1c2aAutomatic Updater int i;
d3243476c280d3a98cadbfd6343437fa2b29356bDanny Mayer
d3243476c280d3a98cadbfd6343437fa2b29356bDanny Mayer REQUIRE(ringp != NULL && *ringp == NULL);
d3243476c280d3a98cadbfd6343437fa2b29356bDanny Mayer
d3243476c280d3a98cadbfd6343437fa2b29356bDanny Mayer i = 0;
d3243476c280d3a98cadbfd6343437fa2b29356bDanny Mayer if (config != NULL)
d3243476c280d3a98cadbfd6343437fa2b29356bDanny Mayer maps[i++] = config;
d3243476c280d3a98cadbfd6343437fa2b29356bDanny Mayer if (vconfig != NULL)
d3243476c280d3a98cadbfd6343437fa2b29356bDanny Mayer maps[i++] = cfg_tuple_get(vconfig, "options");
d3243476c280d3a98cadbfd6343437fa2b29356bDanny Mayer maps[i] = NULL;
d3243476c280d3a98cadbfd6343437fa2b29356bDanny Mayer
487e6abc16c1b2958d371b0d4e808953646b520aDavid Lawrence result = dns_tsigkeyring_create(mctx, &ring);
487e6abc16c1b2958d371b0d4e808953646b520aDavid Lawrence if (result != ISC_R_SUCCESS)
487e6abc16c1b2958d371b0d4e808953646b520aDavid Lawrence return (result);
d3243476c280d3a98cadbfd6343437fa2b29356bDanny Mayer
d3243476c280d3a98cadbfd6343437fa2b29356bDanny Mayer for (i = 0; ; i++) {
d3243476c280d3a98cadbfd6343437fa2b29356bDanny Mayer if (maps[i] == NULL)
d3243476c280d3a98cadbfd6343437fa2b29356bDanny Mayer break;
d3243476c280d3a98cadbfd6343437fa2b29356bDanny Mayer keylist = NULL;
d3243476c280d3a98cadbfd6343437fa2b29356bDanny Mayer result = cfg_map_get(maps[i], "key", &keylist);
d3243476c280d3a98cadbfd6343437fa2b29356bDanny Mayer if (result != ISC_R_SUCCESS)
d3243476c280d3a98cadbfd6343437fa2b29356bDanny Mayer continue;
d3243476c280d3a98cadbfd6343437fa2b29356bDanny Mayer result = add_initial_keys(keylist, ring, mctx);
d3243476c280d3a98cadbfd6343437fa2b29356bDanny Mayer if (result != ISC_R_SUCCESS)
d3243476c280d3a98cadbfd6343437fa2b29356bDanny Mayer goto failure;
d3243476c280d3a98cadbfd6343437fa2b29356bDanny Mayer }
d3243476c280d3a98cadbfd6343437fa2b29356bDanny Mayer
d3243476c280d3a98cadbfd6343437fa2b29356bDanny Mayer *ringp = ring;
d3243476c280d3a98cadbfd6343437fa2b29356bDanny Mayer return (ISC_R_SUCCESS);
d3243476c280d3a98cadbfd6343437fa2b29356bDanny Mayer
d3243476c280d3a98cadbfd6343437fa2b29356bDanny Mayer failure:
d3243476c280d3a98cadbfd6343437fa2b29356bDanny Mayer dns_tsigkeyring_destroy(&ring);
6fa7a247a1037be08d7a8e0b4c4fd3785b2f268cAndreas Gustafsson return (result);
d3243476c280d3a98cadbfd6343437fa2b29356bDanny Mayer}
d3243476c280d3a98cadbfd6343437fa2b29356bDanny Mayer