tsigconf.c revision 165071
1135446Strhodes/* 2165071Sdougb * Copyright (C) 2004, 2006 Internet Systems Consortium, Inc. ("ISC") 3135446Strhodes * Copyright (C) 1999-2001 Internet Software Consortium. 4135446Strhodes * 5135446Strhodes * Permission to use, copy, modify, and distribute this software for any 6135446Strhodes * purpose with or without fee is hereby granted, provided that the above 7135446Strhodes * copyright notice and this permission notice appear in all copies. 8135446Strhodes * 9135446Strhodes * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 10135446Strhodes * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 11135446Strhodes * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 12135446Strhodes * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 13135446Strhodes * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 14135446Strhodes * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 15135446Strhodes * PERFORMANCE OF THIS SOFTWARE. 16135446Strhodes */ 17135446Strhodes 18165071Sdougb/* $Id: tsigconf.c,v 1.21.208.6 2006/03/02 00:37:20 marka Exp $ */ 19135446Strhodes 20135446Strhodes#include <config.h> 21135446Strhodes 22135446Strhodes#include <isc/base64.h> 23135446Strhodes#include <isc/buffer.h> 24135446Strhodes#include <isc/mem.h> 25135446Strhodes#include <isc/string.h> 26135446Strhodes 27135446Strhodes#include <isccfg/cfg.h> 28135446Strhodes 29135446Strhodes#include <dns/tsig.h> 30135446Strhodes#include <dns/result.h> 31135446Strhodes 32135446Strhodes#include <named/log.h> 33135446Strhodes 34135446Strhodes#include <named/config.h> 35135446Strhodes#include <named/tsigconf.h> 36135446Strhodes 37135446Strhodesstatic isc_result_t 38165071Sdougbadd_initial_keys(const cfg_obj_t *list, dns_tsig_keyring_t *ring, 39165071Sdougb isc_mem_t *mctx) 40165071Sdougb{ 41165071Sdougb const cfg_listelt_t *element; 42165071Sdougb const cfg_obj_t *key = NULL; 43165071Sdougb const char *keyid = NULL; 44135446Strhodes unsigned char *secret = NULL; 45135446Strhodes int secretalloc = 0; 46135446Strhodes int secretlen = 0; 47135446Strhodes isc_result_t ret; 48135446Strhodes isc_stdtime_t now; 49135446Strhodes 50135446Strhodes for (element = cfg_list_first(list); 51135446Strhodes element != NULL; 52135446Strhodes element = cfg_list_next(element)) 53135446Strhodes { 54165071Sdougb const cfg_obj_t *algobj = NULL; 55165071Sdougb const cfg_obj_t *secretobj = NULL; 56135446Strhodes dns_name_t keyname; 57135446Strhodes dns_name_t *alg; 58165071Sdougb const char *algstr; 59135446Strhodes char keynamedata[1024]; 60135446Strhodes isc_buffer_t keynamesrc, keynamebuf; 61165071Sdougb const char *secretstr; 62135446Strhodes isc_buffer_t secretbuf; 63135446Strhodes 64135446Strhodes key = cfg_listelt_value(element); 65135446Strhodes keyid = cfg_obj_asstring(cfg_map_getname(key)); 66135446Strhodes 67135446Strhodes algobj = NULL; 68135446Strhodes secretobj = NULL; 69135446Strhodes (void)cfg_map_get(key, "algorithm", &algobj); 70135446Strhodes (void)cfg_map_get(key, "secret", &secretobj); 71135446Strhodes INSIST(algobj != NULL && secretobj != NULL); 72135446Strhodes 73135446Strhodes /* 74135446Strhodes * Create the key name. 75135446Strhodes */ 76135446Strhodes dns_name_init(&keyname, NULL); 77135446Strhodes isc_buffer_init(&keynamesrc, keyid, strlen(keyid)); 78135446Strhodes isc_buffer_add(&keynamesrc, strlen(keyid)); 79135446Strhodes isc_buffer_init(&keynamebuf, keynamedata, sizeof(keynamedata)); 80135446Strhodes ret = dns_name_fromtext(&keyname, &keynamesrc, dns_rootname, 81135446Strhodes ISC_TRUE, &keynamebuf); 82135446Strhodes if (ret != ISC_R_SUCCESS) 83135446Strhodes goto failure; 84135446Strhodes 85135446Strhodes /* 86135446Strhodes * Create the algorithm. 87135446Strhodes */ 88135446Strhodes algstr = cfg_obj_asstring(algobj); 89135446Strhodes if (ns_config_getkeyalgorithm(algstr, &alg) != ISC_R_SUCCESS) { 90135446Strhodes cfg_obj_log(algobj, ns_g_lctx, ISC_LOG_ERROR, 91135446Strhodes "key '%s': the only supported algorithm " 92135446Strhodes "is hmac-md5", keyid); 93135446Strhodes ret = DNS_R_BADALG; 94135446Strhodes goto failure; 95135446Strhodes } 96135446Strhodes 97135446Strhodes secretstr = cfg_obj_asstring(secretobj); 98135446Strhodes secretalloc = secretlen = strlen(secretstr) * 3 / 4; 99135446Strhodes secret = isc_mem_get(mctx, secretlen); 100135446Strhodes if (secret == NULL) { 101135446Strhodes ret = ISC_R_NOMEMORY; 102135446Strhodes goto failure; 103135446Strhodes } 104135446Strhodes isc_buffer_init(&secretbuf, secret, secretlen); 105135446Strhodes ret = isc_base64_decodestring(secretstr, &secretbuf); 106135446Strhodes if (ret != ISC_R_SUCCESS) 107135446Strhodes goto failure; 108135446Strhodes secretlen = isc_buffer_usedlength(&secretbuf); 109135446Strhodes 110135446Strhodes isc_stdtime_get(&now); 111135446Strhodes ret = dns_tsigkey_create(&keyname, alg, secret, secretlen, 112135446Strhodes ISC_FALSE, NULL, now, now, 113135446Strhodes mctx, ring, NULL); 114135446Strhodes isc_mem_put(mctx, secret, secretalloc); 115135446Strhodes secret = NULL; 116135446Strhodes if (ret != ISC_R_SUCCESS) 117135446Strhodes goto failure; 118135446Strhodes } 119135446Strhodes 120135446Strhodes return (ISC_R_SUCCESS); 121135446Strhodes 122135446Strhodes failure: 123135446Strhodes cfg_obj_log(key, ns_g_lctx, ISC_LOG_ERROR, 124135446Strhodes "configuring key '%s': %s", keyid, 125135446Strhodes isc_result_totext(ret)); 126135446Strhodes 127135446Strhodes if (secret != NULL) 128135446Strhodes isc_mem_put(mctx, secret, secretalloc); 129135446Strhodes return (ret); 130135446Strhodes 131135446Strhodes} 132135446Strhodes 133135446Strhodesisc_result_t 134165071Sdougbns_tsigkeyring_fromconfig(const cfg_obj_t *config, const cfg_obj_t *vconfig, 135135446Strhodes isc_mem_t *mctx, dns_tsig_keyring_t **ringp) 136135446Strhodes{ 137165071Sdougb const cfg_obj_t *maps[3]; 138165071Sdougb const cfg_obj_t *keylist; 139135446Strhodes dns_tsig_keyring_t *ring = NULL; 140135446Strhodes isc_result_t result; 141135446Strhodes int i; 142135446Strhodes 143135446Strhodes i = 0; 144135446Strhodes if (config != NULL) 145135446Strhodes maps[i++] = config; 146135446Strhodes if (vconfig != NULL) 147135446Strhodes maps[i++] = cfg_tuple_get(vconfig, "options"); 148135446Strhodes maps[i] = NULL; 149135446Strhodes 150135446Strhodes result = dns_tsigkeyring_create(mctx, &ring); 151135446Strhodes if (result != ISC_R_SUCCESS) 152135446Strhodes return (result); 153135446Strhodes 154135446Strhodes for (i = 0; ; i++) { 155135446Strhodes if (maps[i] == NULL) 156135446Strhodes break; 157135446Strhodes keylist = NULL; 158135446Strhodes result = cfg_map_get(maps[i], "key", &keylist); 159135446Strhodes if (result != ISC_R_SUCCESS) 160135446Strhodes continue; 161135446Strhodes result = add_initial_keys(keylist, ring, mctx); 162135446Strhodes if (result != ISC_R_SUCCESS) 163135446Strhodes goto failure; 164135446Strhodes } 165135446Strhodes 166135446Strhodes *ringp = ring; 167135446Strhodes return (ISC_R_SUCCESS); 168135446Strhodes 169135446Strhodes failure: 170135446Strhodes dns_tsigkeyring_destroy(&ring); 171135446Strhodes return (result); 172135446Strhodes} 173