1 /* $NetBSD: tsigconf.c,v 1.5 2014/12/10 04:37:52 christos Exp $ */
4 * Copyright (C) 2004-2007, 2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
5 * Copyright (C) 1999-2001 Internet Software Consortium.
7 * Permission to use, copy, modify, and/or distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
11 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
12 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
14 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
16 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17 * PERFORMANCE OF THIS SOFTWARE.
20 /* Id: tsigconf.c,v 1.35 2011/01/11 23:47:12 tbox Exp */
26 #include <isc/base64.h>
27 #include <isc/buffer.h>
29 #include <isc/string.h>
31 #include <isccfg/cfg.h>
34 #include <dns/result.h>
36 #include <named/log.h>
38 #include <named/config.h>
39 #include <named/tsigconf.h>
42 add_initial_keys(const cfg_obj_t
*list
, dns_tsig_keyring_t
*ring
,
45 dns_tsigkey_t
*tsigkey
= NULL
;
46 const cfg_listelt_t
*element
;
47 const cfg_obj_t
*key
= NULL
;
48 const char *keyid
= NULL
;
49 unsigned char *secret
= NULL
;
56 for (element
= cfg_list_first(list
);
58 element
= cfg_list_next(element
))
60 const cfg_obj_t
*algobj
= NULL
;
61 const cfg_obj_t
*secretobj
= NULL
;
65 char keynamedata
[1024];
66 isc_buffer_t keynamesrc
, keynamebuf
;
67 const char *secretstr
;
68 isc_buffer_t secretbuf
;
70 key
= cfg_listelt_value(element
);
71 keyid
= cfg_obj_asstring(cfg_map_getname(key
));
75 (void)cfg_map_get(key
, "algorithm", &algobj
);
76 (void)cfg_map_get(key
, "secret", &secretobj
);
77 INSIST(algobj
!= NULL
&& secretobj
!= NULL
);
80 * Create the key name.
82 dns_name_init(&keyname
, NULL
);
83 isc_buffer_constinit(&keynamesrc
, keyid
, strlen(keyid
));
84 isc_buffer_add(&keynamesrc
, strlen(keyid
));
85 isc_buffer_init(&keynamebuf
, keynamedata
, sizeof(keynamedata
));
86 ret
= dns_name_fromtext(&keyname
, &keynamesrc
, dns_rootname
,
87 DNS_NAME_DOWNCASE
, &keynamebuf
);
88 if (ret
!= ISC_R_SUCCESS
)
92 * Create the algorithm.
94 algstr
= cfg_obj_asstring(algobj
);
95 if (ns_config_getkeyalgorithm(algstr
, &alg
, &bits
)
97 cfg_obj_log(algobj
, ns_g_lctx
, ISC_LOG_ERROR
,
98 "key '%s': has a unsupported algorithm '%s'",
104 secretstr
= cfg_obj_asstring(secretobj
);
105 secretalloc
= secretlen
= strlen(secretstr
) * 3 / 4;
106 secret
= isc_mem_get(mctx
, secretlen
);
107 if (secret
== NULL
) {
108 ret
= ISC_R_NOMEMORY
;
111 isc_buffer_init(&secretbuf
, secret
, secretlen
);
112 ret
= isc_base64_decodestring(secretstr
, &secretbuf
);
113 if (ret
!= ISC_R_SUCCESS
)
115 secretlen
= isc_buffer_usedlength(&secretbuf
);
117 isc_stdtime_get(&now
);
118 ret
= dns_tsigkey_create(&keyname
, alg
, secret
, secretlen
,
119 ISC_FALSE
, NULL
, now
, now
,
120 mctx
, ring
, &tsigkey
);
121 isc_mem_put(mctx
, secret
, secretalloc
);
123 if (ret
!= ISC_R_SUCCESS
)
128 dst_key_setbits(tsigkey
->key
, bits
);
129 dns_tsigkey_detach(&tsigkey
);
132 return (ISC_R_SUCCESS
);
135 cfg_obj_log(key
, ns_g_lctx
, ISC_LOG_ERROR
,
136 "configuring key '%s': %s", keyid
,
137 isc_result_totext(ret
));
140 isc_mem_put(mctx
, secret
, secretalloc
);
145 ns_tsigkeyring_fromconfig(const cfg_obj_t
*config
, const cfg_obj_t
*vconfig
,
146 isc_mem_t
*mctx
, dns_tsig_keyring_t
**ringp
)
148 const cfg_obj_t
*maps
[3];
149 const cfg_obj_t
*keylist
;
150 dns_tsig_keyring_t
*ring
= NULL
;
154 REQUIRE(ringp
!= NULL
&& *ringp
== NULL
);
160 maps
[i
++] = cfg_tuple_get(vconfig
, "options");
163 result
= dns_tsigkeyring_create(mctx
, &ring
);
164 if (result
!= ISC_R_SUCCESS
)
171 result
= cfg_map_get(maps
[i
], "key", &keylist
);
172 if (result
!= ISC_R_SUCCESS
)
174 result
= add_initial_keys(keylist
, ring
, mctx
);
175 if (result
!= ISC_R_SUCCESS
)
180 return (ISC_R_SUCCESS
);
183 dns_tsigkeyring_detach(&ring
);