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