00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
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
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
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
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 }