xref: /freebsd/crypto/heimdal/lib/krb5/auth_context.c (revision 9a14aa017b21c292740c00ee098195cd46642730)
1 /*
2  * Copyright (c) 1997 - 2002 Kungliga Tekniska H�gskolan
3  * (Royal Institute of Technology, Stockholm, Sweden).
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  *
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * 3. Neither the name of the Institute nor the names of its contributors
18  *    may be used to endorse or promote products derived from this software
19  *    without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  */
33 
34 #include "krb5_locl.h"
35 
36 RCSID("$Id: auth_context.c 21745 2007-07-31 16:11:25Z lha $");
37 
38 krb5_error_code KRB5_LIB_FUNCTION
39 krb5_auth_con_init(krb5_context context,
40 		   krb5_auth_context *auth_context)
41 {
42     krb5_auth_context p;
43 
44     ALLOC(p, 1);
45     if(!p) {
46 	krb5_set_error_string(context, "malloc: out of memory");
47 	return ENOMEM;
48     }
49     memset(p, 0, sizeof(*p));
50     ALLOC(p->authenticator, 1);
51     if (!p->authenticator) {
52 	krb5_set_error_string(context, "malloc: out of memory");
53 	free(p);
54 	return ENOMEM;
55     }
56     memset (p->authenticator, 0, sizeof(*p->authenticator));
57     p->flags = KRB5_AUTH_CONTEXT_DO_TIME;
58 
59     p->local_address  = NULL;
60     p->remote_address = NULL;
61     p->local_port     = 0;
62     p->remote_port    = 0;
63     p->keytype        = KEYTYPE_NULL;
64     p->cksumtype      = CKSUMTYPE_NONE;
65     *auth_context     = p;
66     return 0;
67 }
68 
69 krb5_error_code KRB5_LIB_FUNCTION
70 krb5_auth_con_free(krb5_context context,
71 		   krb5_auth_context auth_context)
72 {
73     if (auth_context != NULL) {
74 	krb5_free_authenticator(context, &auth_context->authenticator);
75 	if(auth_context->local_address){
76 	    free_HostAddress(auth_context->local_address);
77 	    free(auth_context->local_address);
78 	}
79 	if(auth_context->remote_address){
80 	    free_HostAddress(auth_context->remote_address);
81 	    free(auth_context->remote_address);
82 	}
83 	krb5_free_keyblock(context, auth_context->keyblock);
84 	krb5_free_keyblock(context, auth_context->remote_subkey);
85 	krb5_free_keyblock(context, auth_context->local_subkey);
86 	free (auth_context);
87     }
88     return 0;
89 }
90 
91 krb5_error_code KRB5_LIB_FUNCTION
92 krb5_auth_con_setflags(krb5_context context,
93 		       krb5_auth_context auth_context,
94 		       int32_t flags)
95 {
96     auth_context->flags = flags;
97     return 0;
98 }
99 
100 
101 krb5_error_code KRB5_LIB_FUNCTION
102 krb5_auth_con_getflags(krb5_context context,
103 		       krb5_auth_context auth_context,
104 		       int32_t *flags)
105 {
106     *flags = auth_context->flags;
107     return 0;
108 }
109 
110 krb5_error_code KRB5_LIB_FUNCTION
111 krb5_auth_con_addflags(krb5_context context,
112 		       krb5_auth_context auth_context,
113 		       int32_t addflags,
114 		       int32_t *flags)
115 {
116     if (flags)
117 	*flags = auth_context->flags;
118     auth_context->flags |= addflags;
119     return 0;
120 }
121 
122 krb5_error_code KRB5_LIB_FUNCTION
123 krb5_auth_con_removeflags(krb5_context context,
124 			  krb5_auth_context auth_context,
125 			  int32_t removeflags,
126 			  int32_t *flags)
127 {
128     if (flags)
129 	*flags = auth_context->flags;
130     auth_context->flags &= ~removeflags;
131     return 0;
132 }
133 
134 krb5_error_code KRB5_LIB_FUNCTION
135 krb5_auth_con_setaddrs(krb5_context context,
136 		       krb5_auth_context auth_context,
137 		       krb5_address *local_addr,
138 		       krb5_address *remote_addr)
139 {
140     if (local_addr) {
141 	if (auth_context->local_address)
142 	    krb5_free_address (context, auth_context->local_address);
143 	else
144 	    if ((auth_context->local_address = malloc(sizeof(krb5_address))) == NULL)
145 		return ENOMEM;
146 	krb5_copy_address(context, local_addr, auth_context->local_address);
147     }
148     if (remote_addr) {
149 	if (auth_context->remote_address)
150 	    krb5_free_address (context, auth_context->remote_address);
151 	else
152 	    if ((auth_context->remote_address = malloc(sizeof(krb5_address))) == NULL)
153 		return ENOMEM;
154 	krb5_copy_address(context, remote_addr, auth_context->remote_address);
155     }
156     return 0;
157 }
158 
159 krb5_error_code KRB5_LIB_FUNCTION
160 krb5_auth_con_genaddrs(krb5_context context,
161 		       krb5_auth_context auth_context,
162 		       int fd, int flags)
163 {
164     krb5_error_code ret;
165     krb5_address local_k_address, remote_k_address;
166     krb5_address *lptr = NULL, *rptr = NULL;
167     struct sockaddr_storage ss_local, ss_remote;
168     struct sockaddr *local  = (struct sockaddr *)&ss_local;
169     struct sockaddr *remote = (struct sockaddr *)&ss_remote;
170     socklen_t len;
171 
172     if(flags & KRB5_AUTH_CONTEXT_GENERATE_LOCAL_ADDR) {
173 	if (auth_context->local_address == NULL) {
174 	    len = sizeof(ss_local);
175 	    if(getsockname(fd, local, &len) < 0) {
176 		ret = errno;
177 		krb5_set_error_string (context, "getsockname: %s",
178 				       strerror(ret));
179 		goto out;
180 	    }
181 	    ret = krb5_sockaddr2address (context, local, &local_k_address);
182 	    if(ret) goto out;
183 	    if(flags & KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR) {
184 		krb5_sockaddr2port (context, local, &auth_context->local_port);
185 	    } else
186 		auth_context->local_port = 0;
187 	    lptr = &local_k_address;
188 	}
189     }
190     if(flags & KRB5_AUTH_CONTEXT_GENERATE_REMOTE_ADDR) {
191 	len = sizeof(ss_remote);
192 	if(getpeername(fd, remote, &len) < 0) {
193 	    ret = errno;
194 	    krb5_set_error_string (context, "getpeername: %s", strerror(ret));
195 	    goto out;
196 	}
197 	ret = krb5_sockaddr2address (context, remote, &remote_k_address);
198 	if(ret) goto out;
199 	if(flags & KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR) {
200 	    krb5_sockaddr2port (context, remote, &auth_context->remote_port);
201 	} else
202 	    auth_context->remote_port = 0;
203 	rptr = &remote_k_address;
204     }
205     ret = krb5_auth_con_setaddrs (context,
206 				  auth_context,
207 				  lptr,
208 				  rptr);
209   out:
210     if (lptr)
211 	krb5_free_address (context, lptr);
212     if (rptr)
213 	krb5_free_address (context, rptr);
214     return ret;
215 
216 }
217 
218 krb5_error_code KRB5_LIB_FUNCTION
219 krb5_auth_con_setaddrs_from_fd (krb5_context context,
220 				krb5_auth_context auth_context,
221 				void *p_fd)
222 {
223     int fd = *(int*)p_fd;
224     int flags = 0;
225     if(auth_context->local_address == NULL)
226 	flags |= KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR;
227     if(auth_context->remote_address == NULL)
228 	flags |= KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR;
229     return krb5_auth_con_genaddrs(context, auth_context, fd, flags);
230 }
231 
232 krb5_error_code KRB5_LIB_FUNCTION
233 krb5_auth_con_getaddrs(krb5_context context,
234 		       krb5_auth_context auth_context,
235 		       krb5_address **local_addr,
236 		       krb5_address **remote_addr)
237 {
238     if(*local_addr)
239 	krb5_free_address (context, *local_addr);
240     *local_addr = malloc (sizeof(**local_addr));
241     if (*local_addr == NULL) {
242 	krb5_set_error_string(context, "malloc: out of memory");
243 	return ENOMEM;
244     }
245     krb5_copy_address(context,
246 		      auth_context->local_address,
247 		      *local_addr);
248 
249     if(*remote_addr)
250 	krb5_free_address (context, *remote_addr);
251     *remote_addr = malloc (sizeof(**remote_addr));
252     if (*remote_addr == NULL) {
253 	krb5_set_error_string(context, "malloc: out of memory");
254 	krb5_free_address (context, *local_addr);
255 	*local_addr = NULL;
256 	return ENOMEM;
257     }
258     krb5_copy_address(context,
259 		      auth_context->remote_address,
260 		      *remote_addr);
261     return 0;
262 }
263 
264 static krb5_error_code
265 copy_key(krb5_context context,
266 	 krb5_keyblock *in,
267 	 krb5_keyblock **out)
268 {
269     if(in)
270 	return krb5_copy_keyblock(context, in, out);
271     *out = NULL; /* is this right? */
272     return 0;
273 }
274 
275 krb5_error_code KRB5_LIB_FUNCTION
276 krb5_auth_con_getkey(krb5_context context,
277 		     krb5_auth_context auth_context,
278 		     krb5_keyblock **keyblock)
279 {
280     return copy_key(context, auth_context->keyblock, keyblock);
281 }
282 
283 krb5_error_code KRB5_LIB_FUNCTION
284 krb5_auth_con_getlocalsubkey(krb5_context context,
285 			     krb5_auth_context auth_context,
286 			     krb5_keyblock **keyblock)
287 {
288     return copy_key(context, auth_context->local_subkey, keyblock);
289 }
290 
291 krb5_error_code KRB5_LIB_FUNCTION
292 krb5_auth_con_getremotesubkey(krb5_context context,
293 			      krb5_auth_context auth_context,
294 			      krb5_keyblock **keyblock)
295 {
296     return copy_key(context, auth_context->remote_subkey, keyblock);
297 }
298 
299 krb5_error_code KRB5_LIB_FUNCTION
300 krb5_auth_con_setkey(krb5_context context,
301 		     krb5_auth_context auth_context,
302 		     krb5_keyblock *keyblock)
303 {
304     if(auth_context->keyblock)
305 	krb5_free_keyblock(context, auth_context->keyblock);
306     return copy_key(context, keyblock, &auth_context->keyblock);
307 }
308 
309 krb5_error_code KRB5_LIB_FUNCTION
310 krb5_auth_con_setlocalsubkey(krb5_context context,
311 			     krb5_auth_context auth_context,
312 			     krb5_keyblock *keyblock)
313 {
314     if(auth_context->local_subkey)
315 	krb5_free_keyblock(context, auth_context->local_subkey);
316     return copy_key(context, keyblock, &auth_context->local_subkey);
317 }
318 
319 krb5_error_code KRB5_LIB_FUNCTION
320 krb5_auth_con_generatelocalsubkey(krb5_context context,
321 				  krb5_auth_context auth_context,
322 				  krb5_keyblock *key)
323 {
324     krb5_error_code ret;
325     krb5_keyblock *subkey;
326 
327     ret = krb5_generate_subkey_extended (context, key,
328 					 auth_context->keytype,
329 					 &subkey);
330     if(ret)
331 	return ret;
332     if(auth_context->local_subkey)
333 	krb5_free_keyblock(context, auth_context->local_subkey);
334     auth_context->local_subkey = subkey;
335     return 0;
336 }
337 
338 
339 krb5_error_code KRB5_LIB_FUNCTION
340 krb5_auth_con_setremotesubkey(krb5_context context,
341 			      krb5_auth_context auth_context,
342 			      krb5_keyblock *keyblock)
343 {
344     if(auth_context->remote_subkey)
345 	krb5_free_keyblock(context, auth_context->remote_subkey);
346     return copy_key(context, keyblock, &auth_context->remote_subkey);
347 }
348 
349 krb5_error_code KRB5_LIB_FUNCTION
350 krb5_auth_con_setcksumtype(krb5_context context,
351 			   krb5_auth_context auth_context,
352 			   krb5_cksumtype cksumtype)
353 {
354     auth_context->cksumtype = cksumtype;
355     return 0;
356 }
357 
358 krb5_error_code KRB5_LIB_FUNCTION
359 krb5_auth_con_getcksumtype(krb5_context context,
360 			   krb5_auth_context auth_context,
361 			   krb5_cksumtype *cksumtype)
362 {
363     *cksumtype = auth_context->cksumtype;
364     return 0;
365 }
366 
367 krb5_error_code KRB5_LIB_FUNCTION
368 krb5_auth_con_setkeytype (krb5_context context,
369 			  krb5_auth_context auth_context,
370 			  krb5_keytype keytype)
371 {
372     auth_context->keytype = keytype;
373     return 0;
374 }
375 
376 krb5_error_code KRB5_LIB_FUNCTION
377 krb5_auth_con_getkeytype (krb5_context context,
378 			  krb5_auth_context auth_context,
379 			  krb5_keytype *keytype)
380 {
381     *keytype = auth_context->keytype;
382     return 0;
383 }
384 
385 #if 0
386 krb5_error_code KRB5_LIB_FUNCTION
387 krb5_auth_con_setenctype(krb5_context context,
388 			 krb5_auth_context auth_context,
389 			 krb5_enctype etype)
390 {
391     if(auth_context->keyblock)
392 	krb5_free_keyblock(context, auth_context->keyblock);
393     ALLOC(auth_context->keyblock, 1);
394     if(auth_context->keyblock == NULL)
395 	return ENOMEM;
396     auth_context->keyblock->keytype = etype;
397     return 0;
398 }
399 
400 krb5_error_code KRB5_LIB_FUNCTION
401 krb5_auth_con_getenctype(krb5_context context,
402 			 krb5_auth_context auth_context,
403 			 krb5_enctype *etype)
404 {
405     krb5_abortx(context, "unimplemented krb5_auth_getenctype called");
406 }
407 #endif
408 
409 krb5_error_code KRB5_LIB_FUNCTION
410 krb5_auth_con_getlocalseqnumber(krb5_context context,
411 			    krb5_auth_context auth_context,
412 			    int32_t *seqnumber)
413 {
414   *seqnumber = auth_context->local_seqnumber;
415   return 0;
416 }
417 
418 krb5_error_code KRB5_LIB_FUNCTION
419 krb5_auth_con_setlocalseqnumber (krb5_context context,
420 			     krb5_auth_context auth_context,
421 			     int32_t seqnumber)
422 {
423   auth_context->local_seqnumber = seqnumber;
424   return 0;
425 }
426 
427 krb5_error_code KRB5_LIB_FUNCTION
428 krb5_auth_getremoteseqnumber(krb5_context context,
429 			     krb5_auth_context auth_context,
430 			     int32_t *seqnumber)
431 {
432   *seqnumber = auth_context->remote_seqnumber;
433   return 0;
434 }
435 
436 krb5_error_code KRB5_LIB_FUNCTION
437 krb5_auth_con_setremoteseqnumber (krb5_context context,
438 			      krb5_auth_context auth_context,
439 			      int32_t seqnumber)
440 {
441   auth_context->remote_seqnumber = seqnumber;
442   return 0;
443 }
444 
445 
446 krb5_error_code KRB5_LIB_FUNCTION
447 krb5_auth_con_getauthenticator(krb5_context context,
448 			   krb5_auth_context auth_context,
449 			   krb5_authenticator *authenticator)
450 {
451     *authenticator = malloc(sizeof(**authenticator));
452     if (*authenticator == NULL) {
453 	krb5_set_error_string(context, "malloc: out of memory");
454 	return ENOMEM;
455     }
456 
457     copy_Authenticator(auth_context->authenticator,
458 		       *authenticator);
459     return 0;
460 }
461 
462 
463 void KRB5_LIB_FUNCTION
464 krb5_free_authenticator(krb5_context context,
465 			krb5_authenticator *authenticator)
466 {
467     free_Authenticator (*authenticator);
468     free (*authenticator);
469     *authenticator = NULL;
470 }
471 
472 
473 krb5_error_code KRB5_LIB_FUNCTION
474 krb5_auth_con_setuserkey(krb5_context context,
475 			 krb5_auth_context auth_context,
476 			 krb5_keyblock *keyblock)
477 {
478     if(auth_context->keyblock)
479 	krb5_free_keyblock(context, auth_context->keyblock);
480     return krb5_copy_keyblock(context, keyblock, &auth_context->keyblock);
481 }
482 
483 krb5_error_code KRB5_LIB_FUNCTION
484 krb5_auth_con_getrcache(krb5_context context,
485 			krb5_auth_context auth_context,
486 			krb5_rcache *rcache)
487 {
488     *rcache = auth_context->rcache;
489     return 0;
490 }
491 
492 krb5_error_code KRB5_LIB_FUNCTION
493 krb5_auth_con_setrcache(krb5_context context,
494 			krb5_auth_context auth_context,
495 			krb5_rcache rcache)
496 {
497     auth_context->rcache = rcache;
498     return 0;
499 }
500 
501 #if 0 /* not implemented */
502 
503 krb5_error_code KRB5_LIB_FUNCTION
504 krb5_auth_con_initivector(krb5_context context,
505 			  krb5_auth_context auth_context)
506 {
507     krb5_abortx(context, "unimplemented krb5_auth_con_initivector called");
508 }
509 
510 
511 krb5_error_code KRB5_LIB_FUNCTION
512 krb5_auth_con_setivector(krb5_context context,
513 			 krb5_auth_context auth_context,
514 			 krb5_pointer ivector)
515 {
516     krb5_abortx(context, "unimplemented krb5_auth_con_setivector called");
517 }
518 
519 #endif /* not implemented */
520