Add heimdal-0.6.3
[dragonfly.git] / crypto / heimdal-0.6.3 / lib / krb5 / auth_context.c
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,v 1.59 2002/09/02 17:11:02 joda 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             ret = krb5_sockaddr2address (context, local, &local_k_address);
157             if(ret) goto out;
158             if(flags & KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR) {
159                 krb5_sockaddr2port (context, local, &auth_context->local_port);
160             } else
161                 auth_context->local_port = 0;
162             lptr = &local_k_address;
163         }
164     }
165     if(flags & KRB5_AUTH_CONTEXT_GENERATE_REMOTE_ADDR) {
166         len = sizeof(ss_remote);
167         if(getpeername(fd, remote, &len) < 0) {
168             ret = errno;
169             krb5_set_error_string (context, "getpeername: %s", strerror(ret));
170             goto out;
171         }
172         ret = krb5_sockaddr2address (context, remote, &remote_k_address);
173         if(ret) goto out;
174         if(flags & KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR) {
175             krb5_sockaddr2port (context, remote, &auth_context->remote_port);
176         } else
177             auth_context->remote_port = 0;
178         rptr = &remote_k_address;
179     }
180     ret = krb5_auth_con_setaddrs (context,
181                                   auth_context,
182                                   lptr,
183                                   rptr);
184   out:
185     if (lptr)
186         krb5_free_address (context, lptr);
187     if (rptr)
188         krb5_free_address (context, rptr);
189     return ret;
190
191 }
192
193 krb5_error_code
194 krb5_auth_con_setaddrs_from_fd (krb5_context context,
195                                 krb5_auth_context auth_context,
196                                 void *p_fd)
197 {
198     int fd = *(int*)p_fd;
199     int flags = 0;
200     if(auth_context->local_address == NULL)
201         flags |= KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR;
202     if(auth_context->remote_address == NULL)
203         flags |= KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR;
204     return krb5_auth_con_genaddrs(context, auth_context, fd, flags);
205 }
206
207 krb5_error_code
208 krb5_auth_con_getaddrs(krb5_context context,
209                        krb5_auth_context auth_context,
210                        krb5_address **local_addr,
211                        krb5_address **remote_addr)
212 {
213     if(*local_addr)
214         krb5_free_address (context, *local_addr);
215     *local_addr = malloc (sizeof(**local_addr));
216     if (*local_addr == NULL) {
217         krb5_set_error_string(context, "malloc: out of memory");
218         return ENOMEM;
219     }
220     krb5_copy_address(context,
221                       auth_context->local_address,
222                       *local_addr);
223
224     if(*remote_addr)
225         krb5_free_address (context, *remote_addr);
226     *remote_addr = malloc (sizeof(**remote_addr));
227     if (*remote_addr == NULL) {
228         krb5_set_error_string(context, "malloc: out of memory");
229         krb5_free_address (context, *local_addr);
230         *local_addr = NULL;
231         return ENOMEM;
232     }
233     krb5_copy_address(context,
234                       auth_context->remote_address,
235                       *remote_addr);
236     return 0;
237 }
238
239 static krb5_error_code
240 copy_key(krb5_context context,
241          krb5_keyblock *in,
242          krb5_keyblock **out)
243 {
244     if(in)
245         return krb5_copy_keyblock(context, in, out);
246     *out = NULL; /* is this right? */
247     return 0;
248 }
249
250 krb5_error_code
251 krb5_auth_con_getkey(krb5_context context,
252                      krb5_auth_context auth_context,
253                      krb5_keyblock **keyblock)
254 {
255     return copy_key(context, auth_context->keyblock, keyblock);
256 }
257
258 krb5_error_code
259 krb5_auth_con_getlocalsubkey(krb5_context context,
260                              krb5_auth_context auth_context,
261                              krb5_keyblock **keyblock)
262 {
263     return copy_key(context, auth_context->local_subkey, keyblock);
264 }
265
266 krb5_error_code
267 krb5_auth_con_getremotesubkey(krb5_context context,
268                               krb5_auth_context auth_context,
269                               krb5_keyblock **keyblock)
270 {
271     return copy_key(context, auth_context->remote_subkey, keyblock);
272 }
273
274 krb5_error_code
275 krb5_auth_con_setkey(krb5_context context,
276                      krb5_auth_context auth_context,
277                      krb5_keyblock *keyblock)
278 {
279     if(auth_context->keyblock)
280         krb5_free_keyblock(context, auth_context->keyblock);
281     return copy_key(context, keyblock, &auth_context->keyblock);
282 }
283
284 krb5_error_code
285 krb5_auth_con_setlocalsubkey(krb5_context context,
286                              krb5_auth_context auth_context,
287                              krb5_keyblock *keyblock)
288 {
289     if(auth_context->local_subkey)
290         krb5_free_keyblock(context, auth_context->local_subkey);
291     return copy_key(context, keyblock, &auth_context->local_subkey);
292 }
293
294 krb5_error_code
295 krb5_auth_con_generatelocalsubkey(krb5_context context,
296                                   krb5_auth_context auth_context,
297                                   krb5_keyblock *key)
298 {
299     krb5_error_code ret;
300     krb5_keyblock *subkey;
301
302     ret = krb5_generate_subkey (context, key, &subkey);
303     if(ret)
304         return ret;
305     if(auth_context->local_subkey)
306         krb5_free_keyblock(context, auth_context->local_subkey);
307     auth_context->local_subkey = subkey;
308     return 0;
309 }
310
311
312 krb5_error_code
313 krb5_auth_con_setremotesubkey(krb5_context context,
314                               krb5_auth_context auth_context,
315                               krb5_keyblock *keyblock)
316 {
317     if(auth_context->remote_subkey)
318         krb5_free_keyblock(context, auth_context->remote_subkey);
319     return copy_key(context, keyblock, &auth_context->remote_subkey);
320 }
321
322 krb5_error_code
323 krb5_auth_con_setcksumtype(krb5_context context,
324                            krb5_auth_context auth_context,
325                            krb5_cksumtype cksumtype)
326 {
327     auth_context->cksumtype = cksumtype;
328     return 0;
329 }
330
331 krb5_error_code
332 krb5_auth_con_getcksumtype(krb5_context context,
333                            krb5_auth_context auth_context,
334                            krb5_cksumtype *cksumtype)
335 {
336     *cksumtype = auth_context->cksumtype;
337     return 0;
338 }
339
340 krb5_error_code
341 krb5_auth_con_setkeytype (krb5_context context,
342                           krb5_auth_context auth_context,
343                           krb5_keytype keytype)
344 {
345     auth_context->keytype = keytype;
346     return 0;
347 }
348
349 krb5_error_code
350 krb5_auth_con_getkeytype (krb5_context context,
351                           krb5_auth_context auth_context,
352                           krb5_keytype *keytype)
353 {
354     *keytype = auth_context->keytype;
355     return 0;
356 }
357
358 #if 0
359 krb5_error_code
360 krb5_auth_con_setenctype(krb5_context context,
361                          krb5_auth_context auth_context,
362                          krb5_enctype etype)
363 {
364     if(auth_context->keyblock)
365         krb5_free_keyblock(context, auth_context->keyblock);
366     ALLOC(auth_context->keyblock, 1);
367     if(auth_context->keyblock == NULL)
368         return ENOMEM;
369     auth_context->keyblock->keytype = etype;
370     return 0;
371 }
372
373 krb5_error_code
374 krb5_auth_con_getenctype(krb5_context context,
375                          krb5_auth_context auth_context,
376                          krb5_enctype *etype)
377 {
378     krb5_abortx(context, "unimplemented krb5_auth_getenctype called");
379 }
380 #endif
381
382 krb5_error_code
383 krb5_auth_con_getlocalseqnumber(krb5_context context,
384                             krb5_auth_context auth_context,
385                             int32_t *seqnumber)
386 {
387   *seqnumber = auth_context->local_seqnumber;
388   return 0;
389 }
390
391 krb5_error_code
392 krb5_auth_con_setlocalseqnumber (krb5_context context,
393                              krb5_auth_context auth_context,
394                              int32_t seqnumber)
395 {
396   auth_context->local_seqnumber = seqnumber;
397   return 0;
398 }
399
400 krb5_error_code
401 krb5_auth_getremoteseqnumber(krb5_context context,
402                              krb5_auth_context auth_context,
403                              int32_t *seqnumber)
404 {
405   *seqnumber = auth_context->remote_seqnumber;
406   return 0;
407 }
408
409 krb5_error_code
410 krb5_auth_con_setremoteseqnumber (krb5_context context,
411                               krb5_auth_context auth_context,
412                               int32_t seqnumber)
413 {
414   auth_context->remote_seqnumber = seqnumber;
415   return 0;
416 }
417
418
419 krb5_error_code
420 krb5_auth_con_getauthenticator(krb5_context context,
421                            krb5_auth_context auth_context,
422                            krb5_authenticator *authenticator)
423 {
424     *authenticator = malloc(sizeof(**authenticator));
425     if (*authenticator == NULL) {
426         krb5_set_error_string(context, "malloc: out of memory");
427         return ENOMEM;
428     }
429
430     copy_Authenticator(auth_context->authenticator,
431                        *authenticator);
432     return 0;
433 }
434
435
436 void
437 krb5_free_authenticator(krb5_context context,
438                         krb5_authenticator *authenticator)
439 {
440     free_Authenticator (*authenticator);
441     free (*authenticator);
442     *authenticator = NULL;
443 }
444
445
446 krb5_error_code
447 krb5_auth_con_setuserkey(krb5_context context,
448                          krb5_auth_context auth_context,
449                          krb5_keyblock *keyblock)
450 {
451     if(auth_context->keyblock)
452         krb5_free_keyblock(context, auth_context->keyblock);
453     return krb5_copy_keyblock(context, keyblock, &auth_context->keyblock);
454 }
455
456 krb5_error_code
457 krb5_auth_con_getrcache(krb5_context context,
458                         krb5_auth_context auth_context,
459                         krb5_rcache *rcache)
460 {
461     *rcache = auth_context->rcache;
462     return 0;
463 }
464
465 krb5_error_code
466 krb5_auth_con_setrcache(krb5_context context,
467                         krb5_auth_context auth_context,
468                         krb5_rcache rcache)
469 {
470     auth_context->rcache = rcache;
471     return 0;
472 }
473
474 #if 0 /* not implemented */
475
476 krb5_error_code
477 krb5_auth_con_initivector(krb5_context context,
478                           krb5_auth_context auth_context)
479 {
480     krb5_abortx(context, "unimplemented krb5_auth_con_initivector called");
481 }
482
483
484 krb5_error_code
485 krb5_auth_con_setivector(krb5_context context,
486                          krb5_auth_context auth_context,
487                          krb5_pointer ivector)
488 {
489     krb5_abortx(context, "unimplemented krb5_auth_con_setivector called");
490 }
491
492 #endif /* not implemented */