tsigconf.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2004-2007, 2009, 2011, 2012  Internet Systems Consortium, Inc. ("ISC")
00003  * Copyright (C) 1999-2001  Internet Software Consortium.
00004  *
00005  * Permission to use, copy, modify, and/or distribute this software for any
00006  * purpose with or without fee is hereby granted, provided that the above
00007  * copyright notice and this permission notice appear in all copies.
00008  *
00009  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
00010  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
00011  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
00012  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
00013  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
00014  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
00015  * PERFORMANCE OF THIS SOFTWARE.
00016  */
00017 
00018 /* $Id: tsigconf.c,v 1.35 2011/01/11 23:47:12 tbox Exp $ */
00019 
00020 /*! \file */
00021 
00022 #include <config.h>
00023 
00024 #include <isc/base64.h>
00025 #include <isc/buffer.h>
00026 #include <isc/mem.h>
00027 #include <isc/string.h>
00028 
00029 #include <isccfg/cfg.h>
00030 
00031 #include <dns/tsig.h>
00032 #include <dns/result.h>
00033 
00034 #include <named/log.h>
00035 
00036 #include <named/config.h>
00037 #include <named/tsigconf.h>
00038 
00039 static isc_result_t
00040 add_initial_keys(const cfg_obj_t *list, dns_tsig_keyring_t *ring,
00041                  isc_mem_t *mctx)
00042 {
00043         dns_tsigkey_t *tsigkey = NULL;
00044         const cfg_listelt_t *element;
00045         const cfg_obj_t *key = NULL;
00046         const char *keyid = NULL;
00047         unsigned char *secret = NULL;
00048         int secretalloc = 0;
00049         int secretlen = 0;
00050         isc_result_t ret;
00051         isc_stdtime_t now;
00052         isc_uint16_t bits;
00053 
00054         for (element = cfg_list_first(list);
00055              element != NULL;
00056              element = cfg_list_next(element))
00057         {
00058                 const cfg_obj_t *algobj = NULL;
00059                 const cfg_obj_t *secretobj = NULL;
00060                 dns_name_t keyname;
00061                 dns_name_t *alg;
00062                 const char *algstr;
00063                 char keynamedata[1024];
00064                 isc_buffer_t keynamesrc, keynamebuf;
00065                 const char *secretstr;
00066                 isc_buffer_t secretbuf;
00067 
00068                 key = cfg_listelt_value(element);
00069                 keyid = cfg_obj_asstring(cfg_map_getname(key));
00070 
00071                 algobj = NULL;
00072                 secretobj = NULL;
00073                 (void)cfg_map_get(key, "algorithm", &algobj);
00074                 (void)cfg_map_get(key, "secret", &secretobj);
00075                 INSIST(algobj != NULL && secretobj != NULL);
00076 
00077                 /*
00078                  * Create the key name.
00079                  */
00080                 dns_name_init(&keyname, NULL);
00081                 isc_buffer_constinit(&keynamesrc, keyid, strlen(keyid));
00082                 isc_buffer_add(&keynamesrc, strlen(keyid));
00083                 isc_buffer_init(&keynamebuf, keynamedata, sizeof(keynamedata));
00084                 ret = dns_name_fromtext(&keyname, &keynamesrc, dns_rootname,
00085                                         DNS_NAME_DOWNCASE, &keynamebuf);
00086                 if (ret != ISC_R_SUCCESS)
00087                         goto failure;
00088 
00089                 /*
00090                  * Create the algorithm.
00091                  */
00092                 algstr = cfg_obj_asstring(algobj);
00093                 if (ns_config_getkeyalgorithm(algstr, &alg, &bits)
00094                     != ISC_R_SUCCESS) {
00095                         cfg_obj_log(algobj, ns_g_lctx, ISC_LOG_ERROR,
00096                                     "key '%s': has a unsupported algorithm '%s'",
00097                                     keyid, algstr);
00098                         ret = DNS_R_BADALG;
00099                         goto failure;
00100                 }
00101 
00102                 secretstr = cfg_obj_asstring(secretobj);
00103                 secretalloc = secretlen = strlen(secretstr) * 3 / 4;
00104                 secret = isc_mem_get(mctx, secretlen);
00105                 if (secret == NULL) {
00106                         ret = ISC_R_NOMEMORY;
00107                         goto failure;
00108                 }
00109                 isc_buffer_init(&secretbuf, secret, secretlen);
00110                 ret = isc_base64_decodestring(secretstr, &secretbuf);
00111                 if (ret != ISC_R_SUCCESS)
00112                         goto failure;
00113                 secretlen = isc_buffer_usedlength(&secretbuf);
00114 
00115                 isc_stdtime_get(&now);
00116                 ret = dns_tsigkey_create(&keyname, alg, secret, secretlen,
00117                                          ISC_FALSE, NULL, now, now,
00118                                          mctx, ring, &tsigkey);
00119                 isc_mem_put(mctx, secret, secretalloc);
00120                 secret = NULL;
00121                 if (ret != ISC_R_SUCCESS)
00122                         goto failure;
00123                 /*
00124                  * Set digest bits.
00125                  */
00126                 dst_key_setbits(tsigkey->key, bits);
00127                 dns_tsigkey_detach(&tsigkey);
00128         }
00129 
00130         return (ISC_R_SUCCESS);
00131 
00132  failure:
00133         cfg_obj_log(key, ns_g_lctx, ISC_LOG_ERROR,
00134                     "configuring key '%s': %s", keyid,
00135                     isc_result_totext(ret));
00136 
00137         if (secret != NULL)
00138                 isc_mem_put(mctx, secret, secretalloc);
00139         return (ret);
00140 }
00141 
00142 isc_result_t
00143 ns_tsigkeyring_fromconfig(const cfg_obj_t *config, const cfg_obj_t *vconfig,
00144                           isc_mem_t *mctx, dns_tsig_keyring_t **ringp)
00145 {
00146         const cfg_obj_t *maps[3];
00147         const cfg_obj_t *keylist;
00148         dns_tsig_keyring_t *ring = NULL;
00149         isc_result_t result;
00150         int i;
00151 
00152         REQUIRE(ringp != NULL && *ringp == NULL);
00153 
00154         i = 0;
00155         if (config != NULL)
00156                 maps[i++] = config;
00157         if (vconfig != NULL)
00158                 maps[i++] = cfg_tuple_get(vconfig, "options");
00159         maps[i] = NULL;
00160 
00161         result = dns_tsigkeyring_create(mctx, &ring);
00162         if (result != ISC_R_SUCCESS)
00163                 return (result);
00164 
00165         for (i = 0; ; i++) {
00166                 if (maps[i] == NULL)
00167                         break;
00168                 keylist = NULL;
00169                 result = cfg_map_get(maps[i], "key", &keylist);
00170                 if (result != ISC_R_SUCCESS)
00171                         continue;
00172                 result = add_initial_keys(keylist, ring, mctx);
00173                 if (result != ISC_R_SUCCESS)
00174                         goto failure;
00175         }
00176 
00177         *ringp = ring;
00178         return (ISC_R_SUCCESS);
00179 
00180  failure:
00181         dns_tsigkeyring_detach(&ring);
00182         return (result);
00183 }

Generated on Tue Apr 28 17:40:55 2015 by Doxygen 1.5.4 for BIND9 Internals 9.11.0pre-alpha