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