xref: /freebsd/crypto/heimdal/lib/krb5/auth_context.c (revision 6990ffd8a95caaba6858ad44ff1b3157d1efba8f)
1 /*
2  * Copyright (c) 1997 - 2001 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,v 1.56 2001/05/14 06:14:44 assar Exp $");
37 
38 krb5_error_code
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
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
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
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 
111 krb5_error_code
112 krb5_auth_con_setaddrs(krb5_context context,
113 		       krb5_auth_context auth_context,
114 		       krb5_address *local_addr,
115 		       krb5_address *remote_addr)
116 {
117     if (local_addr) {
118 	if (auth_context->local_address)
119 	    krb5_free_address (context, auth_context->local_address);
120 	else
121 	    auth_context->local_address = malloc(sizeof(krb5_address));
122 	krb5_copy_address(context, local_addr, auth_context->local_address);
123     }
124     if (remote_addr) {
125 	if (auth_context->remote_address)
126 	    krb5_free_address (context, auth_context->remote_address);
127 	else
128 	    auth_context->remote_address = malloc(sizeof(krb5_address));
129 	krb5_copy_address(context, remote_addr, auth_context->remote_address);
130     }
131     return 0;
132 }
133 
134 krb5_error_code
135 krb5_auth_con_genaddrs(krb5_context context,
136 		       krb5_auth_context auth_context,
137 		       int fd, int flags)
138 {
139     krb5_error_code ret;
140     krb5_address local_k_address, remote_k_address;
141     krb5_address *lptr = NULL, *rptr = NULL;
142     struct sockaddr_storage ss_local, ss_remote;
143     struct sockaddr *local  = (struct sockaddr *)&ss_local;
144     struct sockaddr *remote = (struct sockaddr *)&ss_remote;
145     socklen_t len;
146 
147     if(flags & KRB5_AUTH_CONTEXT_GENERATE_LOCAL_ADDR) {
148 	if (auth_context->local_address == NULL) {
149 	    len = sizeof(ss_local);
150 	    if(getsockname(fd, local, &len) < 0) {
151 		ret = errno;
152 		krb5_set_error_string (context, "getsockname: %s",
153 				       strerror(ret));
154 		goto out;
155 	    }
156 	    krb5_sockaddr2address (context, local, &local_k_address);
157 	    if(flags & KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR) {
158 		krb5_sockaddr2port (context, local, &auth_context->local_port);
159 	    } else
160 		auth_context->local_port = 0;
161 	    lptr = &local_k_address;
162 	}
163     }
164     if(flags & KRB5_AUTH_CONTEXT_GENERATE_REMOTE_ADDR) {
165 	len = sizeof(ss_remote);
166 	if(getpeername(fd, remote, &len) < 0) {
167 	    ret = errno;
168 	    krb5_set_error_string (context, "getpeername: %s", strerror(ret));
169 	    goto out;
170 	}
171 	krb5_sockaddr2address (context, remote, &remote_k_address);
172 	if(flags & KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR) {
173 	    krb5_sockaddr2port (context, remote, &auth_context->remote_port);
174 	} else
175 	    auth_context->remote_port = 0;
176 	rptr = &remote_k_address;
177     }
178     ret = krb5_auth_con_setaddrs (context,
179 				  auth_context,
180 				  lptr,
181 				  rptr);
182   out:
183     if (lptr)
184 	krb5_free_address (context, lptr);
185     if (rptr)
186 	krb5_free_address (context, rptr);
187     return ret;
188 
189 }
190 
191 krb5_error_code
192 krb5_auth_con_setaddrs_from_fd (krb5_context context,
193 				krb5_auth_context auth_context,
194 				void *p_fd)
195 {
196     int fd = *(int*)p_fd;
197     int flags = 0;
198     if(auth_context->local_address == NULL)
199 	flags |= KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR;
200     if(auth_context->remote_address == NULL)
201 	flags |= KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR;
202     return krb5_auth_con_genaddrs(context, auth_context, fd, flags);
203 }
204 
205 krb5_error_code
206 krb5_auth_con_getaddrs(krb5_context context,
207 		       krb5_auth_context auth_context,
208 		       krb5_address **local_addr,
209 		       krb5_address **remote_addr)
210 {
211     if(*local_addr)
212 	krb5_free_address (context, *local_addr);
213     *local_addr = malloc (sizeof(**local_addr));
214     if (*local_addr == NULL) {
215 	krb5_set_error_string(context, "malloc: out of memory");
216 	return ENOMEM;
217     }
218     krb5_copy_address(context,
219 		      auth_context->local_address,
220 		      *local_addr);
221 
222     if(*remote_addr)
223 	krb5_free_address (context, *remote_addr);
224     *remote_addr = malloc (sizeof(**remote_addr));
225     if (*remote_addr == NULL) {
226 	krb5_set_error_string(context, "malloc: out of memory");
227 	krb5_free_address (context, *local_addr);
228 	*local_addr = NULL;
229 	return ENOMEM;
230     }
231     krb5_copy_address(context,
232 		      auth_context->remote_address,
233 		      *remote_addr);
234     return 0;
235 }
236 
237 static krb5_error_code
238 copy_key(krb5_context context,
239 	 krb5_keyblock *in,
240 	 krb5_keyblock **out)
241 {
242     if(in)
243 	return krb5_copy_keyblock(context, in, out);
244     *out = NULL; /* is this right? */
245     return 0;
246 }
247 
248 krb5_error_code
249 krb5_auth_con_getkey(krb5_context context,
250 		     krb5_auth_context auth_context,
251 		     krb5_keyblock **keyblock)
252 {
253     return copy_key(context, auth_context->keyblock, keyblock);
254 }
255 
256 krb5_error_code
257 krb5_auth_con_getlocalsubkey(krb5_context context,
258 			     krb5_auth_context auth_context,
259 			     krb5_keyblock **keyblock)
260 {
261     return copy_key(context, auth_context->local_subkey, keyblock);
262 }
263 
264 krb5_error_code
265 krb5_auth_con_getremotesubkey(krb5_context context,
266 			      krb5_auth_context auth_context,
267 			      krb5_keyblock **keyblock)
268 {
269     return copy_key(context, auth_context->remote_subkey, keyblock);
270 }
271 
272 krb5_error_code
273 krb5_auth_con_setkey(krb5_context context,
274 		     krb5_auth_context auth_context,
275 		     krb5_keyblock *keyblock)
276 {
277     if(auth_context->keyblock)
278 	krb5_free_keyblock(context, auth_context->keyblock);
279     return copy_key(context, keyblock, &auth_context->keyblock);
280 }
281 
282 krb5_error_code
283 krb5_auth_con_setlocalsubkey(krb5_context context,
284 			     krb5_auth_context auth_context,
285 			     krb5_keyblock *keyblock)
286 {
287     if(auth_context->local_subkey)
288 	krb5_free_keyblock(context, auth_context->local_subkey);
289     return copy_key(context, keyblock, &auth_context->local_subkey);
290 }
291 
292 krb5_error_code
293 krb5_auth_con_setremotesubkey(krb5_context context,
294 			      krb5_auth_context auth_context,
295 			      krb5_keyblock *keyblock)
296 {
297     if(auth_context->remote_subkey)
298 	krb5_free_keyblock(context, auth_context->remote_subkey);
299     return copy_key(context, keyblock, &auth_context->remote_subkey);
300 }
301 
302 krb5_error_code
303 krb5_auth_setcksumtype(krb5_context context,
304 		       krb5_auth_context auth_context,
305 		       krb5_cksumtype cksumtype)
306 {
307     auth_context->cksumtype = cksumtype;
308     return 0;
309 }
310 
311 krb5_error_code
312 krb5_auth_getcksumtype(krb5_context context,
313 		       krb5_auth_context auth_context,
314 		       krb5_cksumtype *cksumtype)
315 {
316     *cksumtype = auth_context->cksumtype;
317     return 0;
318 }
319 
320 krb5_error_code
321 krb5_auth_setkeytype (krb5_context context,
322 		      krb5_auth_context auth_context,
323 		      krb5_keytype keytype)
324 {
325     auth_context->keytype = keytype;
326     return 0;
327 }
328 
329 krb5_error_code
330 krb5_auth_getkeytype (krb5_context context,
331 		      krb5_auth_context auth_context,
332 		      krb5_keytype *keytype)
333 {
334     *keytype = auth_context->keytype;
335     return 0;
336 }
337 
338 #if 0
339 krb5_error_code
340 krb5_auth_setenctype(krb5_context context,
341 		     krb5_auth_context auth_context,
342 		     krb5_enctype etype)
343 {
344     if(auth_context->keyblock)
345 	krb5_free_keyblock(context, auth_context->keyblock);
346     ALLOC(auth_context->keyblock, 1);
347     if(auth_context->keyblock == NULL)
348 	return ENOMEM;
349     auth_context->keyblock->keytype = etype;
350     return 0;
351 }
352 
353 krb5_error_code
354 krb5_auth_getenctype(krb5_context context,
355 		     krb5_auth_context auth_context,
356 		     krb5_enctype *etype)
357 {
358     krb5_abortx(context, "unimplemented krb5_auth_getenctype called");
359 }
360 #endif
361 
362 krb5_error_code
363 krb5_auth_getlocalseqnumber(krb5_context context,
364 			    krb5_auth_context auth_context,
365 			    int32_t *seqnumber)
366 {
367   *seqnumber = auth_context->local_seqnumber;
368   return 0;
369 }
370 
371 krb5_error_code
372 krb5_auth_setlocalseqnumber (krb5_context context,
373 			     krb5_auth_context auth_context,
374 			     int32_t seqnumber)
375 {
376   auth_context->local_seqnumber = seqnumber;
377   return 0;
378 }
379 
380 krb5_error_code
381 krb5_auth_getremoteseqnumber(krb5_context context,
382 			     krb5_auth_context auth_context,
383 			     int32_t *seqnumber)
384 {
385   *seqnumber = auth_context->remote_seqnumber;
386   return 0;
387 }
388 
389 krb5_error_code
390 krb5_auth_setremoteseqnumber (krb5_context context,
391 			      krb5_auth_context auth_context,
392 			      int32_t seqnumber)
393 {
394   auth_context->remote_seqnumber = seqnumber;
395   return 0;
396 }
397 
398 
399 krb5_error_code
400 krb5_auth_getauthenticator(krb5_context context,
401 			   krb5_auth_context auth_context,
402 			   krb5_authenticator *authenticator)
403 {
404     *authenticator = malloc(sizeof(**authenticator));
405     if (*authenticator == NULL) {
406 	krb5_set_error_string(context, "malloc: out of memory");
407 	return ENOMEM;
408     }
409 
410     copy_Authenticator(auth_context->authenticator,
411 		       *authenticator);
412     return 0;
413 }
414 
415 
416 void
417 krb5_free_authenticator(krb5_context context,
418 			krb5_authenticator *authenticator)
419 {
420     free_Authenticator (*authenticator);
421     free (*authenticator);
422     *authenticator = NULL;
423 }
424 
425 
426 krb5_error_code
427 krb5_auth_con_setuserkey(krb5_context context,
428 			 krb5_auth_context auth_context,
429 			 krb5_keyblock *keyblock)
430 {
431     if(auth_context->keyblock)
432 	krb5_free_keyblock(context, auth_context->keyblock);
433     return krb5_copy_keyblock(context, keyblock, &auth_context->keyblock);
434 }
435 
436 krb5_error_code
437 krb5_auth_con_getrcache(krb5_context context,
438 			krb5_auth_context auth_context,
439 			krb5_rcache *rcache)
440 {
441     *rcache = auth_context->rcache;
442     return 0;
443 }
444 
445 krb5_error_code
446 krb5_auth_con_setrcache(krb5_context context,
447 			krb5_auth_context auth_context,
448 			krb5_rcache rcache)
449 {
450     auth_context->rcache = rcache;
451     return 0;
452 }
453 
454 #if 0 /* not implemented */
455 
456 krb5_error_code
457 krb5_auth_con_initivector(krb5_context context,
458 			  krb5_auth_context auth_context)
459 {
460     krb5_abortx(context, "unimplemented krb5_auth_con_initivector called");
461 }
462 
463 
464 krb5_error_code
465 krb5_auth_con_setivector(krb5_context context,
466 			 krb5_auth_context auth_context,
467 			 krb5_pointer ivector)
468 {
469     krb5_abortx(context, "unimplemented krb5_auth_con_setivector called");
470 }
471 
472 #endif /* not implemented */
473