2 * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
3 * Copyright (C) 1999-2001 Internet Software Consortium.
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
9 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15 * PERFORMANCE OF THIS SOFTWARE.
18 /* $Id: tsigconf.c,v 1.30 2007/06/19 23:46:59 tbox Exp $ */
24 #include <isc/base64.h>
25 #include <isc/buffer.h>
27 #include <isc/string.h>
29 #include <isccfg/cfg.h>
32 #include <dns/result.h>
34 #include <named/log.h>
36 #include <named/config.h>
37 #include <named/tsigconf.h>
40 add_initial_keys(const cfg_obj_t
*list
, dns_tsig_keyring_t
*ring
,
43 dns_tsigkey_t
*tsigkey
= NULL
;
44 const cfg_listelt_t
*element
;
45 const cfg_obj_t
*key
= NULL
;
46 const char *keyid
= NULL
;
47 unsigned char *secret
= NULL
;
54 for (element
= cfg_list_first(list
);
56 element
= cfg_list_next(element
))
58 const cfg_obj_t
*algobj
= NULL
;
59 const cfg_obj_t
*secretobj
= NULL
;
63 char keynamedata
[1024];
64 isc_buffer_t keynamesrc
, keynamebuf
;
65 const char *secretstr
;
66 isc_buffer_t secretbuf
;
68 key
= cfg_listelt_value(element
);
69 keyid
= cfg_obj_asstring(cfg_map_getname(key
));
73 (void)cfg_map_get(key
, "algorithm", &algobj
);
74 (void)cfg_map_get(key
, "secret", &secretobj
);
75 INSIST(algobj
!= NULL
&& secretobj
!= NULL
);
78 * Create the key name.
80 dns_name_init(&keyname
, NULL
);
81 isc_buffer_init(&keynamesrc
, keyid
, strlen(keyid
));
82 isc_buffer_add(&keynamesrc
, strlen(keyid
));
83 isc_buffer_init(&keynamebuf
, keynamedata
, sizeof(keynamedata
));
84 ret
= dns_name_fromtext(&keyname
, &keynamesrc
, dns_rootname
,
85 ISC_TRUE
, &keynamebuf
);
86 if (ret
!= ISC_R_SUCCESS
)
90 * Create the algorithm.
92 algstr
= cfg_obj_asstring(algobj
);
93 if (ns_config_getkeyalgorithm(algstr
, &alg
, &bits
)
95 cfg_obj_log(algobj
, ns_g_lctx
, ISC_LOG_ERROR
,
96 "key '%s': has a unsupported algorithm '%s'",
102 secretstr
= cfg_obj_asstring(secretobj
);
103 secretalloc
= secretlen
= strlen(secretstr
) * 3 / 4;
104 secret
= isc_mem_get(mctx
, secretlen
);
105 if (secret
== NULL
) {
106 ret
= ISC_R_NOMEMORY
;
109 isc_buffer_init(&secretbuf
, secret
, secretlen
);
110 ret
= isc_base64_decodestring(secretstr
, &secretbuf
);
111 if (ret
!= ISC_R_SUCCESS
)
113 secretlen
= isc_buffer_usedlength(&secretbuf
);
115 isc_stdtime_get(&now
);
116 ret
= dns_tsigkey_create(&keyname
, alg
, secret
, secretlen
,
117 ISC_FALSE
, NULL
, now
, now
,
118 mctx
, ring
, &tsigkey
);
119 isc_mem_put(mctx
, secret
, secretalloc
);
121 if (ret
!= ISC_R_SUCCESS
)
126 dst_key_setbits(tsigkey
->key
, bits
);
127 dns_tsigkey_detach(&tsigkey
);
130 return (ISC_R_SUCCESS
);
133 cfg_obj_log(key
, ns_g_lctx
, ISC_LOG_ERROR
,
134 "configuring key '%s': %s", keyid
,
135 isc_result_totext(ret
));
138 isc_mem_put(mctx
, secret
, secretalloc
);
143 ns_tsigkeyring_fromconfig(const cfg_obj_t
*config
, const cfg_obj_t
*vconfig
,
144 isc_mem_t
*mctx
, dns_tsig_keyring_t
**ringp
)
146 const cfg_obj_t
*maps
[3];
147 const cfg_obj_t
*keylist
;
148 dns_tsig_keyring_t
*ring
= NULL
;
156 maps
[i
++] = cfg_tuple_get(vconfig
, "options");
159 result
= dns_tsigkeyring_create(mctx
, &ring
);
160 if (result
!= ISC_R_SUCCESS
)
167 result
= cfg_map_get(maps
[i
], "key", &keylist
);
168 if (result
!= ISC_R_SUCCESS
)
170 result
= add_initial_keys(keylist
, ring
, mctx
);
171 if (result
!= ISC_R_SUCCESS
)
176 return (ISC_R_SUCCESS
);
179 dns_tsigkeyring_destroy(&ring
);