Home | History | Annotate | Line # | Download | only in named
tsigconf.c revision 1.1.1.1
      1  1.1  christos /*	$NetBSD: tsigconf.c,v 1.1.1.1 2018/08/12 12:07:41 christos Exp $	*/
      2  1.1  christos 
      3  1.1  christos /*
      4  1.1  christos  * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
      5  1.1  christos  *
      6  1.1  christos  * This Source Code Form is subject to the terms of the Mozilla Public
      7  1.1  christos  * License, v. 2.0. If a copy of the MPL was not distributed with this
      8  1.1  christos  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
      9  1.1  christos  *
     10  1.1  christos  * See the COPYRIGHT file distributed with this work for additional
     11  1.1  christos  * information regarding copyright ownership.
     12  1.1  christos  */
     13  1.1  christos 
     14  1.1  christos 
     15  1.1  christos /*! \file */
     16  1.1  christos 
     17  1.1  christos #include <config.h>
     18  1.1  christos 
     19  1.1  christos #include <isc/base64.h>
     20  1.1  christos #include <isc/buffer.h>
     21  1.1  christos #include <isc/mem.h>
     22  1.1  christos #include <isc/string.h>
     23  1.1  christos #include <isc/util.h>
     24  1.1  christos 
     25  1.1  christos #include <isccfg/cfg.h>
     26  1.1  christos 
     27  1.1  christos #include <dns/tsig.h>
     28  1.1  christos #include <dns/result.h>
     29  1.1  christos 
     30  1.1  christos #include <named/log.h>
     31  1.1  christos 
     32  1.1  christos #include <named/config.h>
     33  1.1  christos #include <named/tsigconf.h>
     34  1.1  christos 
     35  1.1  christos static isc_result_t
     36  1.1  christos add_initial_keys(const cfg_obj_t *list, dns_tsig_keyring_t *ring,
     37  1.1  christos 		 isc_mem_t *mctx)
     38  1.1  christos {
     39  1.1  christos 	dns_tsigkey_t *tsigkey = NULL;
     40  1.1  christos 	const cfg_listelt_t *element;
     41  1.1  christos 	const cfg_obj_t *key = NULL;
     42  1.1  christos 	const char *keyid = NULL;
     43  1.1  christos 	unsigned char *secret = NULL;
     44  1.1  christos 	int secretalloc = 0;
     45  1.1  christos 	int secretlen = 0;
     46  1.1  christos 	isc_result_t ret;
     47  1.1  christos 	isc_stdtime_t now;
     48  1.1  christos 	isc_uint16_t bits;
     49  1.1  christos 
     50  1.1  christos 	for (element = cfg_list_first(list);
     51  1.1  christos 	     element != NULL;
     52  1.1  christos 	     element = cfg_list_next(element))
     53  1.1  christos 	{
     54  1.1  christos 		const cfg_obj_t *algobj = NULL;
     55  1.1  christos 		const cfg_obj_t *secretobj = NULL;
     56  1.1  christos 		dns_name_t keyname;
     57  1.1  christos 		const dns_name_t *alg;
     58  1.1  christos 		const char *algstr;
     59  1.1  christos 		char keynamedata[1024];
     60  1.1  christos 		isc_buffer_t keynamesrc, keynamebuf;
     61  1.1  christos 		const char *secretstr;
     62  1.1  christos 		isc_buffer_t secretbuf;
     63  1.1  christos 
     64  1.1  christos 		key = cfg_listelt_value(element);
     65  1.1  christos 		keyid = cfg_obj_asstring(cfg_map_getname(key));
     66  1.1  christos 
     67  1.1  christos 		algobj = NULL;
     68  1.1  christos 		secretobj = NULL;
     69  1.1  christos 		(void)cfg_map_get(key, "algorithm", &algobj);
     70  1.1  christos 		(void)cfg_map_get(key, "secret", &secretobj);
     71  1.1  christos 		INSIST(algobj != NULL && secretobj != NULL);
     72  1.1  christos 
     73  1.1  christos 		/*
     74  1.1  christos 		 * Create the key name.
     75  1.1  christos 		 */
     76  1.1  christos 		dns_name_init(&keyname, NULL);
     77  1.1  christos 		isc_buffer_constinit(&keynamesrc, keyid, strlen(keyid));
     78  1.1  christos 		isc_buffer_add(&keynamesrc, strlen(keyid));
     79  1.1  christos 		isc_buffer_init(&keynamebuf, keynamedata, sizeof(keynamedata));
     80  1.1  christos 		ret = dns_name_fromtext(&keyname, &keynamesrc, dns_rootname,
     81  1.1  christos 					DNS_NAME_DOWNCASE, &keynamebuf);
     82  1.1  christos 		if (ret != ISC_R_SUCCESS)
     83  1.1  christos 			goto failure;
     84  1.1  christos 
     85  1.1  christos 		/*
     86  1.1  christos 		 * Create the algorithm.
     87  1.1  christos 		 */
     88  1.1  christos 		algstr = cfg_obj_asstring(algobj);
     89  1.1  christos 		if (named_config_getkeyalgorithm(algstr, &alg, &bits)
     90  1.1  christos 		    != ISC_R_SUCCESS) {
     91  1.1  christos 			cfg_obj_log(algobj, named_g_lctx, ISC_LOG_ERROR,
     92  1.1  christos 				    "key '%s': has a "
     93  1.1  christos 				    "unsupported algorithm '%s'",
     94  1.1  christos 				    keyid, algstr);
     95  1.1  christos 			ret = DNS_R_BADALG;
     96  1.1  christos 			goto failure;
     97  1.1  christos 		}
     98  1.1  christos 
     99  1.1  christos 		secretstr = cfg_obj_asstring(secretobj);
    100  1.1  christos 		secretalloc = secretlen = strlen(secretstr) * 3 / 4;
    101  1.1  christos 		secret = isc_mem_get(mctx, secretlen);
    102  1.1  christos 		if (secret == NULL) {
    103  1.1  christos 			ret = ISC_R_NOMEMORY;
    104  1.1  christos 			goto failure;
    105  1.1  christos 		}
    106  1.1  christos 		isc_buffer_init(&secretbuf, secret, secretlen);
    107  1.1  christos 		ret = isc_base64_decodestring(secretstr, &secretbuf);
    108  1.1  christos 		if (ret != ISC_R_SUCCESS)
    109  1.1  christos 			goto failure;
    110  1.1  christos 		secretlen = isc_buffer_usedlength(&secretbuf);
    111  1.1  christos 
    112  1.1  christos 		isc_stdtime_get(&now);
    113  1.1  christos 		ret = dns_tsigkey_create(&keyname, alg, secret, secretlen,
    114  1.1  christos 					 ISC_FALSE, NULL, now, now,
    115  1.1  christos 					 mctx, ring, &tsigkey);
    116  1.1  christos 		isc_mem_put(mctx, secret, secretalloc);
    117  1.1  christos 		secret = NULL;
    118  1.1  christos 		if (ret != ISC_R_SUCCESS)
    119  1.1  christos 			goto failure;
    120  1.1  christos 		/*
    121  1.1  christos 		 * Set digest bits.
    122  1.1  christos 		 */
    123  1.1  christos 		dst_key_setbits(tsigkey->key, bits);
    124  1.1  christos 		dns_tsigkey_detach(&tsigkey);
    125  1.1  christos 	}
    126  1.1  christos 
    127  1.1  christos 	return (ISC_R_SUCCESS);
    128  1.1  christos 
    129  1.1  christos  failure:
    130  1.1  christos 	cfg_obj_log(key, named_g_lctx, ISC_LOG_ERROR,
    131  1.1  christos 		    "configuring key '%s': %s", keyid,
    132  1.1  christos 		    isc_result_totext(ret));
    133  1.1  christos 
    134  1.1  christos 	if (secret != NULL)
    135  1.1  christos 		isc_mem_put(mctx, secret, secretalloc);
    136  1.1  christos 	return (ret);
    137  1.1  christos }
    138  1.1  christos 
    139  1.1  christos isc_result_t
    140  1.1  christos named_tsigkeyring_fromconfig(const cfg_obj_t *config, const cfg_obj_t *vconfig,
    141  1.1  christos 			     isc_mem_t *mctx, dns_tsig_keyring_t **ringp)
    142  1.1  christos {
    143  1.1  christos 	const cfg_obj_t *maps[3];
    144  1.1  christos 	const cfg_obj_t *keylist;
    145  1.1  christos 	dns_tsig_keyring_t *ring = NULL;
    146  1.1  christos 	isc_result_t result;
    147  1.1  christos 	int i;
    148  1.1  christos 
    149  1.1  christos 	REQUIRE(ringp != NULL && *ringp == NULL);
    150  1.1  christos 
    151  1.1  christos 	i = 0;
    152  1.1  christos 	if (config != NULL)
    153  1.1  christos 		maps[i++] = config;
    154  1.1  christos 	if (vconfig != NULL)
    155  1.1  christos 		maps[i++] = cfg_tuple_get(vconfig, "options");
    156  1.1  christos 	maps[i] = NULL;
    157  1.1  christos 
    158  1.1  christos 	result = dns_tsigkeyring_create(mctx, &ring);
    159  1.1  christos 	if (result != ISC_R_SUCCESS)
    160  1.1  christos 		return (result);
    161  1.1  christos 
    162  1.1  christos 	for (i = 0; ; i++) {
    163  1.1  christos 		if (maps[i] == NULL)
    164  1.1  christos 			break;
    165  1.1  christos 		keylist = NULL;
    166  1.1  christos 		result = cfg_map_get(maps[i], "key", &keylist);
    167  1.1  christos 		if (result != ISC_R_SUCCESS)
    168  1.1  christos 			continue;
    169  1.1  christos 		result = add_initial_keys(keylist, ring, mctx);
    170  1.1  christos 		if (result != ISC_R_SUCCESS)
    171  1.1  christos 			goto failure;
    172  1.1  christos 	}
    173  1.1  christos 
    174  1.1  christos 	*ringp = ring;
    175  1.1  christos 	return (ISC_R_SUCCESS);
    176  1.1  christos 
    177  1.1  christos  failure:
    178  1.1  christos 	dns_tsigkeyring_detach(&ring);
    179  1.1  christos 	return (result);
    180  1.1  christos }
    181