1*83ee113eSDavid van Moolenbroek /* $NetBSD: auth.c,v 1.1.1.2 2014/07/12 11:57:58 spz Exp $ */
2*83ee113eSDavid van Moolenbroek /* auth.c
3*83ee113eSDavid van Moolenbroek
4*83ee113eSDavid van Moolenbroek Subroutines having to do with authentication. */
5*83ee113eSDavid van Moolenbroek
6*83ee113eSDavid van Moolenbroek /*
7*83ee113eSDavid van Moolenbroek * Copyright (c) 2004,2007,2009,2014 by Internet Systems Consortium, Inc. ("ISC")
8*83ee113eSDavid van Moolenbroek * Copyright (c) 1998-2003 by Internet Software Consortium
9*83ee113eSDavid van Moolenbroek *
10*83ee113eSDavid van Moolenbroek * Permission to use, copy, modify, and distribute this software for any
11*83ee113eSDavid van Moolenbroek * purpose with or without fee is hereby granted, provided that the above
12*83ee113eSDavid van Moolenbroek * copyright notice and this permission notice appear in all copies.
13*83ee113eSDavid van Moolenbroek *
14*83ee113eSDavid van Moolenbroek * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
15*83ee113eSDavid van Moolenbroek * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
16*83ee113eSDavid van Moolenbroek * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
17*83ee113eSDavid van Moolenbroek * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
18*83ee113eSDavid van Moolenbroek * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
19*83ee113eSDavid van Moolenbroek * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
20*83ee113eSDavid van Moolenbroek * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21*83ee113eSDavid van Moolenbroek *
22*83ee113eSDavid van Moolenbroek * Internet Systems Consortium, Inc.
23*83ee113eSDavid van Moolenbroek * 950 Charter Street
24*83ee113eSDavid van Moolenbroek * Redwood City, CA 94063
25*83ee113eSDavid van Moolenbroek * <info@isc.org>
26*83ee113eSDavid van Moolenbroek * https://www.isc.org/
27*83ee113eSDavid van Moolenbroek *
28*83ee113eSDavid van Moolenbroek */
29*83ee113eSDavid van Moolenbroek
30*83ee113eSDavid van Moolenbroek #include <sys/cdefs.h>
31*83ee113eSDavid van Moolenbroek __RCSID("$NetBSD: auth.c,v 1.1.1.2 2014/07/12 11:57:58 spz Exp $");
32*83ee113eSDavid van Moolenbroek
33*83ee113eSDavid van Moolenbroek #include "dhcpd.h"
34*83ee113eSDavid van Moolenbroek
35*83ee113eSDavid van Moolenbroek #include <omapip/omapip_p.h>
36*83ee113eSDavid van Moolenbroek
37*83ee113eSDavid van Moolenbroek OMAPI_OBJECT_ALLOC (omapi_auth_key, omapi_auth_key_t, omapi_type_auth_key)
38*83ee113eSDavid van Moolenbroek typedef struct hash omapi_auth_hash_t;
39*83ee113eSDavid van Moolenbroek HASH_FUNCTIONS_DECL (omapi_auth_key, const char *,
40*83ee113eSDavid van Moolenbroek omapi_auth_key_t, omapi_auth_hash_t)
41*83ee113eSDavid van Moolenbroek omapi_auth_hash_t *auth_key_hash;
HASH_FUNCTIONS(omapi_auth_key,const char *,omapi_auth_key_t,omapi_auth_hash_t,omapi_auth_key_reference,omapi_auth_key_dereference,do_case_hash)42*83ee113eSDavid van Moolenbroek HASH_FUNCTIONS (omapi_auth_key, const char *, omapi_auth_key_t,
43*83ee113eSDavid van Moolenbroek omapi_auth_hash_t,
44*83ee113eSDavid van Moolenbroek omapi_auth_key_reference, omapi_auth_key_dereference,
45*83ee113eSDavid van Moolenbroek do_case_hash)
46*83ee113eSDavid van Moolenbroek
47*83ee113eSDavid van Moolenbroek isc_result_t omapi_auth_key_new (omapi_auth_key_t **o, const char *file,
48*83ee113eSDavid van Moolenbroek int line)
49*83ee113eSDavid van Moolenbroek {
50*83ee113eSDavid van Moolenbroek return omapi_auth_key_allocate (o, file, line);
51*83ee113eSDavid van Moolenbroek }
52*83ee113eSDavid van Moolenbroek
omapi_auth_key_destroy(omapi_object_t * h,const char * file,int line)53*83ee113eSDavid van Moolenbroek isc_result_t omapi_auth_key_destroy (omapi_object_t *h,
54*83ee113eSDavid van Moolenbroek const char *file, int line)
55*83ee113eSDavid van Moolenbroek {
56*83ee113eSDavid van Moolenbroek omapi_auth_key_t *a;
57*83ee113eSDavid van Moolenbroek
58*83ee113eSDavid van Moolenbroek if (h->type != omapi_type_auth_key)
59*83ee113eSDavid van Moolenbroek return DHCP_R_INVALIDARG;
60*83ee113eSDavid van Moolenbroek a = (omapi_auth_key_t *)h;
61*83ee113eSDavid van Moolenbroek
62*83ee113eSDavid van Moolenbroek if (auth_key_hash != NULL)
63*83ee113eSDavid van Moolenbroek omapi_auth_key_hash_delete(auth_key_hash, a->name, 0, MDL);
64*83ee113eSDavid van Moolenbroek
65*83ee113eSDavid van Moolenbroek if (a->name != NULL)
66*83ee113eSDavid van Moolenbroek dfree(a->name, MDL);
67*83ee113eSDavid van Moolenbroek if (a->algorithm != NULL)
68*83ee113eSDavid van Moolenbroek dfree(a->algorithm, MDL);
69*83ee113eSDavid van Moolenbroek if (a->key != NULL)
70*83ee113eSDavid van Moolenbroek omapi_data_string_dereference(&a->key, MDL);
71*83ee113eSDavid van Moolenbroek if (a->tsec_key != NULL)
72*83ee113eSDavid van Moolenbroek dns_tsec_destroy(&a->tsec_key);
73*83ee113eSDavid van Moolenbroek
74*83ee113eSDavid van Moolenbroek return ISC_R_SUCCESS;
75*83ee113eSDavid van Moolenbroek }
76*83ee113eSDavid van Moolenbroek
omapi_auth_key_enter(omapi_auth_key_t * a)77*83ee113eSDavid van Moolenbroek isc_result_t omapi_auth_key_enter (omapi_auth_key_t *a)
78*83ee113eSDavid van Moolenbroek {
79*83ee113eSDavid van Moolenbroek omapi_auth_key_t *tk;
80*83ee113eSDavid van Moolenbroek isc_result_t status;
81*83ee113eSDavid van Moolenbroek dst_key_t *dstkey;
82*83ee113eSDavid van Moolenbroek
83*83ee113eSDavid van Moolenbroek if (a -> type != omapi_type_auth_key)
84*83ee113eSDavid van Moolenbroek return DHCP_R_INVALIDARG;
85*83ee113eSDavid van Moolenbroek
86*83ee113eSDavid van Moolenbroek tk = (omapi_auth_key_t *)0;
87*83ee113eSDavid van Moolenbroek if (auth_key_hash) {
88*83ee113eSDavid van Moolenbroek omapi_auth_key_hash_lookup (&tk, auth_key_hash,
89*83ee113eSDavid van Moolenbroek a -> name, 0, MDL);
90*83ee113eSDavid van Moolenbroek if (tk == a) {
91*83ee113eSDavid van Moolenbroek omapi_auth_key_dereference (&tk, MDL);
92*83ee113eSDavid van Moolenbroek return ISC_R_SUCCESS;
93*83ee113eSDavid van Moolenbroek }
94*83ee113eSDavid van Moolenbroek if (tk) {
95*83ee113eSDavid van Moolenbroek omapi_auth_key_hash_delete (auth_key_hash,
96*83ee113eSDavid van Moolenbroek tk -> name, 0, MDL);
97*83ee113eSDavid van Moolenbroek omapi_auth_key_dereference (&tk, MDL);
98*83ee113eSDavid van Moolenbroek }
99*83ee113eSDavid van Moolenbroek } else {
100*83ee113eSDavid van Moolenbroek if (!omapi_auth_key_new_hash(&auth_key_hash,
101*83ee113eSDavid van Moolenbroek KEY_HASH_SIZE, MDL))
102*83ee113eSDavid van Moolenbroek return ISC_R_NOMEMORY;
103*83ee113eSDavid van Moolenbroek }
104*83ee113eSDavid van Moolenbroek
105*83ee113eSDavid van Moolenbroek /*
106*83ee113eSDavid van Moolenbroek * If possible create a tsec structure for this key,
107*83ee113eSDavid van Moolenbroek * if we can't create the structure we put out a warning
108*83ee113eSDavid van Moolenbroek * and continue.
109*83ee113eSDavid van Moolenbroek */
110*83ee113eSDavid van Moolenbroek status = isclib_make_dst_key(a->name, a->algorithm,
111*83ee113eSDavid van Moolenbroek a->key->value, a->key->len,
112*83ee113eSDavid van Moolenbroek &dstkey);
113*83ee113eSDavid van Moolenbroek if (status == ISC_R_SUCCESS) {
114*83ee113eSDavid van Moolenbroek status = dns_tsec_create(dhcp_gbl_ctx.mctx, dns_tsectype_tsig,
115*83ee113eSDavid van Moolenbroek dstkey, &a->tsec_key);
116*83ee113eSDavid van Moolenbroek dst_key_free(&dstkey);
117*83ee113eSDavid van Moolenbroek }
118*83ee113eSDavid van Moolenbroek if (status != ISC_R_SUCCESS)
119*83ee113eSDavid van Moolenbroek log_error("Unable to create tsec structure for %s", a->name);
120*83ee113eSDavid van Moolenbroek
121*83ee113eSDavid van Moolenbroek omapi_auth_key_hash_add (auth_key_hash, a -> name, 0, a, MDL);
122*83ee113eSDavid van Moolenbroek return ISC_R_SUCCESS;
123*83ee113eSDavid van Moolenbroek }
124*83ee113eSDavid van Moolenbroek
omapi_auth_key_lookup_name(omapi_auth_key_t ** a,const char * name)125*83ee113eSDavid van Moolenbroek isc_result_t omapi_auth_key_lookup_name (omapi_auth_key_t **a,
126*83ee113eSDavid van Moolenbroek const char *name)
127*83ee113eSDavid van Moolenbroek {
128*83ee113eSDavid van Moolenbroek if (!auth_key_hash)
129*83ee113eSDavid van Moolenbroek return ISC_R_NOTFOUND;
130*83ee113eSDavid van Moolenbroek if (!omapi_auth_key_hash_lookup (a, auth_key_hash, name, 0, MDL))
131*83ee113eSDavid van Moolenbroek return ISC_R_NOTFOUND;
132*83ee113eSDavid van Moolenbroek return ISC_R_SUCCESS;
133*83ee113eSDavid van Moolenbroek }
134*83ee113eSDavid van Moolenbroek
omapi_auth_key_lookup(omapi_object_t ** h,omapi_object_t * id,omapi_object_t * ref)135*83ee113eSDavid van Moolenbroek isc_result_t omapi_auth_key_lookup (omapi_object_t **h,
136*83ee113eSDavid van Moolenbroek omapi_object_t *id,
137*83ee113eSDavid van Moolenbroek omapi_object_t *ref)
138*83ee113eSDavid van Moolenbroek {
139*83ee113eSDavid van Moolenbroek isc_result_t status;
140*83ee113eSDavid van Moolenbroek omapi_value_t *name = (omapi_value_t *)0;
141*83ee113eSDavid van Moolenbroek omapi_value_t *algorithm = (omapi_value_t *)0;
142*83ee113eSDavid van Moolenbroek
143*83ee113eSDavid van Moolenbroek if (!auth_key_hash)
144*83ee113eSDavid van Moolenbroek return ISC_R_NOTFOUND;
145*83ee113eSDavid van Moolenbroek
146*83ee113eSDavid van Moolenbroek if (!ref)
147*83ee113eSDavid van Moolenbroek return DHCP_R_NOKEYS;
148*83ee113eSDavid van Moolenbroek
149*83ee113eSDavid van Moolenbroek status = omapi_get_value_str (ref, id, "name", &name);
150*83ee113eSDavid van Moolenbroek if (status != ISC_R_SUCCESS)
151*83ee113eSDavid van Moolenbroek return status;
152*83ee113eSDavid van Moolenbroek
153*83ee113eSDavid van Moolenbroek if ((name -> value -> type != omapi_datatype_string) &&
154*83ee113eSDavid van Moolenbroek (name -> value -> type != omapi_datatype_data)) {
155*83ee113eSDavid van Moolenbroek omapi_value_dereference (&name, MDL);
156*83ee113eSDavid van Moolenbroek return ISC_R_NOTFOUND;
157*83ee113eSDavid van Moolenbroek }
158*83ee113eSDavid van Moolenbroek
159*83ee113eSDavid van Moolenbroek status = omapi_get_value_str (ref, id, "algorithm", &algorithm);
160*83ee113eSDavid van Moolenbroek if (status != ISC_R_SUCCESS) {
161*83ee113eSDavid van Moolenbroek omapi_value_dereference (&name, MDL);
162*83ee113eSDavid van Moolenbroek return status;
163*83ee113eSDavid van Moolenbroek }
164*83ee113eSDavid van Moolenbroek
165*83ee113eSDavid van Moolenbroek if ((algorithm -> value -> type != omapi_datatype_string) &&
166*83ee113eSDavid van Moolenbroek (algorithm -> value -> type != omapi_datatype_data)) {
167*83ee113eSDavid van Moolenbroek omapi_value_dereference (&name, MDL);
168*83ee113eSDavid van Moolenbroek omapi_value_dereference (&algorithm, MDL);
169*83ee113eSDavid van Moolenbroek return ISC_R_NOTFOUND;
170*83ee113eSDavid van Moolenbroek }
171*83ee113eSDavid van Moolenbroek
172*83ee113eSDavid van Moolenbroek
173*83ee113eSDavid van Moolenbroek if (!omapi_auth_key_hash_lookup ((omapi_auth_key_t **)h, auth_key_hash,
174*83ee113eSDavid van Moolenbroek (const char *)
175*83ee113eSDavid van Moolenbroek name -> value -> u.buffer.value,
176*83ee113eSDavid van Moolenbroek name -> value -> u.buffer.len, MDL)) {
177*83ee113eSDavid van Moolenbroek omapi_value_dereference (&name, MDL);
178*83ee113eSDavid van Moolenbroek omapi_value_dereference (&algorithm, MDL);
179*83ee113eSDavid van Moolenbroek return ISC_R_NOTFOUND;
180*83ee113eSDavid van Moolenbroek }
181*83ee113eSDavid van Moolenbroek
182*83ee113eSDavid van Moolenbroek if (omapi_td_strcasecmp (algorithm -> value,
183*83ee113eSDavid van Moolenbroek ((omapi_auth_key_t *)*h) -> algorithm) != 0) {
184*83ee113eSDavid van Moolenbroek omapi_value_dereference (&name, MDL);
185*83ee113eSDavid van Moolenbroek omapi_value_dereference (&algorithm, MDL);
186*83ee113eSDavid van Moolenbroek omapi_object_dereference (h, MDL);
187*83ee113eSDavid van Moolenbroek return ISC_R_NOTFOUND;
188*83ee113eSDavid van Moolenbroek }
189*83ee113eSDavid van Moolenbroek
190*83ee113eSDavid van Moolenbroek omapi_value_dereference (&name, MDL);
191*83ee113eSDavid van Moolenbroek omapi_value_dereference (&algorithm, MDL);
192*83ee113eSDavid van Moolenbroek
193*83ee113eSDavid van Moolenbroek return ISC_R_SUCCESS;
194*83ee113eSDavid van Moolenbroek }
195*83ee113eSDavid van Moolenbroek
omapi_auth_key_stuff_values(omapi_object_t * c,omapi_object_t * id,omapi_object_t * h)196*83ee113eSDavid van Moolenbroek isc_result_t omapi_auth_key_stuff_values (omapi_object_t *c,
197*83ee113eSDavid van Moolenbroek omapi_object_t *id,
198*83ee113eSDavid van Moolenbroek omapi_object_t *h)
199*83ee113eSDavid van Moolenbroek {
200*83ee113eSDavid van Moolenbroek omapi_auth_key_t *a;
201*83ee113eSDavid van Moolenbroek isc_result_t status;
202*83ee113eSDavid van Moolenbroek
203*83ee113eSDavid van Moolenbroek if (h -> type != omapi_type_auth_key)
204*83ee113eSDavid van Moolenbroek return DHCP_R_INVALIDARG;
205*83ee113eSDavid van Moolenbroek a = (omapi_auth_key_t *)h;
206*83ee113eSDavid van Moolenbroek
207*83ee113eSDavid van Moolenbroek /* Write only the name and algorithm -- not the secret! */
208*83ee113eSDavid van Moolenbroek if (a -> name) {
209*83ee113eSDavid van Moolenbroek status = omapi_connection_put_name (c, "name");
210*83ee113eSDavid van Moolenbroek if (status != ISC_R_SUCCESS)
211*83ee113eSDavid van Moolenbroek return status;
212*83ee113eSDavid van Moolenbroek status = omapi_connection_put_string (c, a -> name);
213*83ee113eSDavid van Moolenbroek if (status != ISC_R_SUCCESS)
214*83ee113eSDavid van Moolenbroek return status;
215*83ee113eSDavid van Moolenbroek }
216*83ee113eSDavid van Moolenbroek if (a -> algorithm) {
217*83ee113eSDavid van Moolenbroek status = omapi_connection_put_name (c, "algorithm");
218*83ee113eSDavid van Moolenbroek if (status != ISC_R_SUCCESS)
219*83ee113eSDavid van Moolenbroek return status;
220*83ee113eSDavid van Moolenbroek status = omapi_connection_put_string (c, a -> algorithm);
221*83ee113eSDavid van Moolenbroek if (status != ISC_R_SUCCESS)
222*83ee113eSDavid van Moolenbroek return status;
223*83ee113eSDavid van Moolenbroek }
224*83ee113eSDavid van Moolenbroek
225*83ee113eSDavid van Moolenbroek return ISC_R_SUCCESS;
226*83ee113eSDavid van Moolenbroek }
227*83ee113eSDavid van Moolenbroek
omapi_auth_key_get_value(omapi_object_t * h,omapi_object_t * id,omapi_data_string_t * name,omapi_value_t ** value)228*83ee113eSDavid van Moolenbroek isc_result_t omapi_auth_key_get_value (omapi_object_t *h,
229*83ee113eSDavid van Moolenbroek omapi_object_t *id,
230*83ee113eSDavid van Moolenbroek omapi_data_string_t *name,
231*83ee113eSDavid van Moolenbroek omapi_value_t **value)
232*83ee113eSDavid van Moolenbroek {
233*83ee113eSDavid van Moolenbroek omapi_auth_key_t *a;
234*83ee113eSDavid van Moolenbroek isc_result_t status;
235*83ee113eSDavid van Moolenbroek
236*83ee113eSDavid van Moolenbroek if (h -> type != omapi_type_auth_key)
237*83ee113eSDavid van Moolenbroek return ISC_R_UNEXPECTED;
238*83ee113eSDavid van Moolenbroek a = (omapi_auth_key_t *)h;
239*83ee113eSDavid van Moolenbroek
240*83ee113eSDavid van Moolenbroek if (omapi_ds_strcmp (name, "name") == 0) {
241*83ee113eSDavid van Moolenbroek if (a -> name)
242*83ee113eSDavid van Moolenbroek return omapi_make_string_value
243*83ee113eSDavid van Moolenbroek (value, name, a -> name, MDL);
244*83ee113eSDavid van Moolenbroek else
245*83ee113eSDavid van Moolenbroek return ISC_R_NOTFOUND;
246*83ee113eSDavid van Moolenbroek } else if (omapi_ds_strcmp (name, "key") == 0) {
247*83ee113eSDavid van Moolenbroek if (a -> key) {
248*83ee113eSDavid van Moolenbroek status = omapi_value_new (value, MDL);
249*83ee113eSDavid van Moolenbroek if (status != ISC_R_SUCCESS)
250*83ee113eSDavid van Moolenbroek return status;
251*83ee113eSDavid van Moolenbroek
252*83ee113eSDavid van Moolenbroek status = omapi_data_string_reference
253*83ee113eSDavid van Moolenbroek (&(*value) -> name, name, MDL);
254*83ee113eSDavid van Moolenbroek if (status != ISC_R_SUCCESS) {
255*83ee113eSDavid van Moolenbroek omapi_value_dereference (value, MDL);
256*83ee113eSDavid van Moolenbroek return status;
257*83ee113eSDavid van Moolenbroek }
258*83ee113eSDavid van Moolenbroek
259*83ee113eSDavid van Moolenbroek status = omapi_typed_data_new (MDL, &(*value) -> value,
260*83ee113eSDavid van Moolenbroek omapi_datatype_data,
261*83ee113eSDavid van Moolenbroek a -> key -> len);
262*83ee113eSDavid van Moolenbroek if (status != ISC_R_SUCCESS) {
263*83ee113eSDavid van Moolenbroek omapi_value_dereference (value, MDL);
264*83ee113eSDavid van Moolenbroek return status;
265*83ee113eSDavid van Moolenbroek }
266*83ee113eSDavid van Moolenbroek
267*83ee113eSDavid van Moolenbroek memcpy ((*value) -> value -> u.buffer.value,
268*83ee113eSDavid van Moolenbroek a -> key -> value, a -> key -> len);
269*83ee113eSDavid van Moolenbroek return ISC_R_SUCCESS;
270*83ee113eSDavid van Moolenbroek } else
271*83ee113eSDavid van Moolenbroek return ISC_R_NOTFOUND;
272*83ee113eSDavid van Moolenbroek } else if (omapi_ds_strcmp (name, "algorithm") == 0) {
273*83ee113eSDavid van Moolenbroek if (a -> algorithm)
274*83ee113eSDavid van Moolenbroek return omapi_make_string_value
275*83ee113eSDavid van Moolenbroek (value, name, a -> algorithm, MDL);
276*83ee113eSDavid van Moolenbroek else
277*83ee113eSDavid van Moolenbroek return ISC_R_NOTFOUND;
278*83ee113eSDavid van Moolenbroek }
279*83ee113eSDavid van Moolenbroek
280*83ee113eSDavid van Moolenbroek return ISC_R_SUCCESS;
281*83ee113eSDavid van Moolenbroek }
282