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