Use anon realm for anonymous PKINIT
[heimdal.git] / lib / krb5 / auth_context.c
blob7a20eb51e69583d7dbc5f3d4bfb987c5e3b3df6e
1 /*
2 * Copyright (c) 1997 - 2002 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
4 * All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
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.
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.
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.
34 #include "krb5_locl.h"
36 /**
37 * Allocate and initialize an autentication context.
39 * @param context A kerberos context.
40 * @param auth_context The authentication context to be initialized.
42 * Use krb5_auth_con_free() to release the memory when done using the context.
44 * @return An krb5 error code, see krb5_get_error_message().
46 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
47 krb5_auth_con_init(krb5_context context,
48 krb5_auth_context *auth_context)
50 krb5_auth_context p;
52 ALLOC(p, 1);
53 if (!p)
54 return krb5_enomem(context);
55 memset(p, 0, sizeof(*p));
56 ALLOC(p->authenticator, 1);
57 if (!p->authenticator) {
58 free(p);
59 return krb5_enomem(context);
61 memset (p->authenticator, 0, sizeof(*p->authenticator));
62 p->flags = KRB5_AUTH_CONTEXT_DO_TIME;
64 p->local_address = NULL;
65 p->remote_address = NULL;
66 p->local_port = 0;
67 p->remote_port = 0;
68 p->keytype = KRB5_ENCTYPE_NULL;
69 p->cksumtype = CKSUMTYPE_NONE;
70 p->auth_data = NULL;
71 *auth_context = p;
72 return 0;
75 /**
76 * Deallocate an authentication context previously initialized with
77 * krb5_auth_con_init().
79 * @param context A kerberos context.
80 * @param auth_context The authentication context to be deallocated.
82 * @return An krb5 error code, see krb5_get_error_message().
84 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
85 krb5_auth_con_free(krb5_context context,
86 krb5_auth_context auth_context)
88 if (auth_context != NULL) {
89 krb5_free_authenticator(context, &auth_context->authenticator);
90 if(auth_context->local_address){
91 free_HostAddress(auth_context->local_address);
92 free(auth_context->local_address);
94 if(auth_context->remote_address){
95 free_HostAddress(auth_context->remote_address);
96 free(auth_context->remote_address);
98 krb5_free_keyblock(context, auth_context->keyblock);
99 krb5_free_keyblock(context, auth_context->remote_subkey);
100 krb5_free_keyblock(context, auth_context->local_subkey);
101 if (auth_context->auth_data) {
102 free_AuthorizationData(auth_context->auth_data);
103 free(auth_context->auth_data);
105 free (auth_context);
107 return 0;
110 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
111 krb5_auth_con_setflags(krb5_context context,
112 krb5_auth_context auth_context,
113 int32_t flags)
115 auth_context->flags = flags;
116 return 0;
120 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
121 krb5_auth_con_getflags(krb5_context context,
122 krb5_auth_context auth_context,
123 int32_t *flags)
125 *flags = auth_context->flags;
126 return 0;
129 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
130 krb5_auth_con_addflags(krb5_context context,
131 krb5_auth_context auth_context,
132 int32_t addflags,
133 int32_t *flags)
135 if (flags)
136 *flags = auth_context->flags;
137 auth_context->flags |= addflags;
138 return 0;
141 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
142 krb5_auth_con_removeflags(krb5_context context,
143 krb5_auth_context auth_context,
144 int32_t removeflags,
145 int32_t *flags)
147 if (flags)
148 *flags = auth_context->flags;
149 auth_context->flags &= ~removeflags;
150 return 0;
153 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
154 krb5_auth_con_setaddrs(krb5_context context,
155 krb5_auth_context auth_context,
156 krb5_address *local_addr,
157 krb5_address *remote_addr)
159 if (local_addr) {
160 if (auth_context->local_address)
161 krb5_free_address (context, auth_context->local_address);
162 else
163 if ((auth_context->local_address = malloc(sizeof(krb5_address))) == NULL)
164 return krb5_enomem(context);
165 krb5_copy_address(context, local_addr, auth_context->local_address);
167 if (remote_addr) {
168 if (auth_context->remote_address)
169 krb5_free_address (context, auth_context->remote_address);
170 else
171 if ((auth_context->remote_address = malloc(sizeof(krb5_address))) == NULL)
172 return krb5_enomem(context);
173 krb5_copy_address(context, remote_addr, auth_context->remote_address);
175 return 0;
179 * Update the authentication context \a auth_context with the local
180 * and remote addresses from socket \a fd, according to \a flags.
182 * @return An krb5 error code, see krb5_get_error_message().
184 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
185 krb5_auth_con_genaddrs(krb5_context context,
186 krb5_auth_context auth_context,
187 krb5_socket_t fd, int flags)
189 krb5_error_code ret;
190 krb5_address local_k_address, remote_k_address;
191 krb5_address *lptr = NULL, *rptr = NULL;
192 struct sockaddr_storage ss_local, ss_remote;
193 struct sockaddr *local = (struct sockaddr *)&ss_local;
194 struct sockaddr *remote = (struct sockaddr *)&ss_remote;
195 socklen_t len;
197 if(flags & KRB5_AUTH_CONTEXT_GENERATE_LOCAL_ADDR) {
198 if (auth_context->local_address == NULL) {
199 len = sizeof(ss_local);
200 if(rk_IS_SOCKET_ERROR(getsockname(fd, local, &len))) {
201 char buf[128];
202 ret = rk_SOCK_ERRNO;
203 rk_strerror_r(ret, buf, sizeof(buf));
204 krb5_set_error_message(context, ret, "getsockname: %s", buf);
205 goto out;
207 ret = krb5_sockaddr2address (context, local, &local_k_address);
208 if(ret) goto out;
209 if(flags & KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR) {
210 krb5_sockaddr2port (context, local, &auth_context->local_port);
211 } else
212 auth_context->local_port = 0;
213 lptr = &local_k_address;
216 if(flags & KRB5_AUTH_CONTEXT_GENERATE_REMOTE_ADDR) {
217 len = sizeof(ss_remote);
218 if(rk_IS_SOCKET_ERROR(getpeername(fd, remote, &len))) {
219 char buf[128];
220 ret = rk_SOCK_ERRNO;
221 rk_strerror_r(ret, buf, sizeof(buf));
222 krb5_set_error_message(context, ret, "getpeername: %s", buf);
223 goto out;
225 ret = krb5_sockaddr2address (context, remote, &remote_k_address);
226 if(ret) goto out;
227 if(flags & KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR) {
228 krb5_sockaddr2port (context, remote, &auth_context->remote_port);
229 } else
230 auth_context->remote_port = 0;
231 rptr = &remote_k_address;
233 ret = krb5_auth_con_setaddrs (context,
234 auth_context,
235 lptr,
236 rptr);
237 out:
238 if (lptr)
239 krb5_free_address (context, lptr);
240 if (rptr)
241 krb5_free_address (context, rptr);
242 return ret;
246 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
247 krb5_auth_con_setaddrs_from_fd (krb5_context context,
248 krb5_auth_context auth_context,
249 void *p_fd)
251 krb5_socket_t fd = *(krb5_socket_t *)p_fd;
252 int flags = 0;
253 if(auth_context->local_address == NULL)
254 flags |= KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR;
255 if(auth_context->remote_address == NULL)
256 flags |= KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR;
257 return krb5_auth_con_genaddrs(context, auth_context, fd, flags);
260 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
261 krb5_auth_con_getaddrs(krb5_context context,
262 krb5_auth_context auth_context,
263 krb5_address **local_addr,
264 krb5_address **remote_addr)
266 if(*local_addr)
267 krb5_free_address (context, *local_addr);
268 *local_addr = malloc (sizeof(**local_addr));
269 if (*local_addr == NULL)
270 return krb5_enomem(context);
271 krb5_copy_address(context,
272 auth_context->local_address,
273 *local_addr);
275 if(*remote_addr)
276 krb5_free_address (context, *remote_addr);
277 *remote_addr = malloc (sizeof(**remote_addr));
278 if (*remote_addr == NULL) {
279 krb5_free_address (context, *local_addr);
280 *local_addr = NULL;
281 return krb5_enomem(context);
283 krb5_copy_address(context,
284 auth_context->remote_address,
285 *remote_addr);
286 return 0;
289 /* coverity[+alloc : arg-*2] */
290 static krb5_error_code
291 copy_key(krb5_context context,
292 krb5_keyblock *in,
293 krb5_keyblock **out)
295 if(in)
296 return krb5_copy_keyblock(context, in, out);
297 *out = NULL; /* is this right? */
298 return 0;
301 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
302 krb5_auth_con_getkey(krb5_context context,
303 krb5_auth_context auth_context,
304 krb5_keyblock **keyblock)
306 return copy_key(context, auth_context->keyblock, keyblock);
309 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
310 krb5_auth_con_getlocalsubkey(krb5_context context,
311 krb5_auth_context auth_context,
312 krb5_keyblock **keyblock)
314 return copy_key(context, auth_context->local_subkey, keyblock);
317 /* coverity[+alloc : arg-*2] */
318 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
319 krb5_auth_con_getremotesubkey(krb5_context context,
320 krb5_auth_context auth_context,
321 krb5_keyblock **keyblock)
323 return copy_key(context, auth_context->remote_subkey, keyblock);
326 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
327 krb5_auth_con_setkey(krb5_context context,
328 krb5_auth_context auth_context,
329 krb5_keyblock *keyblock)
331 if(auth_context->keyblock)
332 krb5_free_keyblock(context, auth_context->keyblock);
333 return copy_key(context, keyblock, &auth_context->keyblock);
336 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
337 krb5_auth_con_setlocalsubkey(krb5_context context,
338 krb5_auth_context auth_context,
339 krb5_keyblock *keyblock)
341 if(auth_context->local_subkey)
342 krb5_free_keyblock(context, auth_context->local_subkey);
343 return copy_key(context, keyblock, &auth_context->local_subkey);
346 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
347 krb5_auth_con_generatelocalsubkey(krb5_context context,
348 krb5_auth_context auth_context,
349 krb5_keyblock *key)
351 krb5_error_code ret;
352 krb5_keyblock *subkey;
354 ret = krb5_generate_subkey_extended (context, key,
355 auth_context->keytype,
356 &subkey);
357 if(ret)
358 return ret;
359 if(auth_context->local_subkey)
360 krb5_free_keyblock(context, auth_context->local_subkey);
361 auth_context->local_subkey = subkey;
362 return 0;
366 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
367 krb5_auth_con_setremotesubkey(krb5_context context,
368 krb5_auth_context auth_context,
369 krb5_keyblock *keyblock)
371 if(auth_context->remote_subkey)
372 krb5_free_keyblock(context, auth_context->remote_subkey);
373 return copy_key(context, keyblock, &auth_context->remote_subkey);
376 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
377 krb5_auth_con_setcksumtype(krb5_context context,
378 krb5_auth_context auth_context,
379 krb5_cksumtype cksumtype)
381 auth_context->cksumtype = cksumtype;
382 return 0;
385 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
386 krb5_auth_con_getcksumtype(krb5_context context,
387 krb5_auth_context auth_context,
388 krb5_cksumtype *cksumtype)
390 *cksumtype = auth_context->cksumtype;
391 return 0;
394 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
395 krb5_auth_con_setkeytype (krb5_context context,
396 krb5_auth_context auth_context,
397 krb5_keytype keytype)
399 auth_context->keytype = keytype;
400 return 0;
403 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
404 krb5_auth_con_getkeytype (krb5_context context,
405 krb5_auth_context auth_context,
406 krb5_keytype *keytype)
408 *keytype = auth_context->keytype;
409 return 0;
412 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
413 krb5_auth_con_add_AuthorizationData(krb5_context context,
414 krb5_auth_context auth_context,
415 int type,
416 krb5_data *data)
418 AuthorizationDataElement el;
420 if (auth_context->auth_data == NULL) {
421 auth_context->auth_data = calloc(1, sizeof(*auth_context->auth_data));
422 if (auth_context->auth_data == NULL)
423 return krb5_enomem(context);
425 el.ad_type = type;
426 el.ad_data.data = data->data;
427 el.ad_data.length = data->length;
429 return add_AuthorizationData(auth_context->auth_data, &el);
434 #if 0
435 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
436 krb5_auth_con_setenctype(krb5_context context,
437 krb5_auth_context auth_context,
438 krb5_enctype etype)
440 if(auth_context->keyblock)
441 krb5_free_keyblock(context, auth_context->keyblock);
442 ALLOC(auth_context->keyblock, 1);
443 if(auth_context->keyblock == NULL)
444 return krb5_enomem(context);
445 auth_context->keyblock->keytype = etype;
446 return 0;
449 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
450 krb5_auth_con_getenctype(krb5_context context,
451 krb5_auth_context auth_context,
452 krb5_enctype *etype)
454 krb5_abortx(context, "unimplemented krb5_auth_getenctype called");
456 #endif
458 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
459 krb5_auth_con_getlocalseqnumber(krb5_context context,
460 krb5_auth_context auth_context,
461 int32_t *seqnumber)
463 *seqnumber = auth_context->local_seqnumber;
464 return 0;
467 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
468 krb5_auth_con_setlocalseqnumber (krb5_context context,
469 krb5_auth_context auth_context,
470 int32_t seqnumber)
472 auth_context->local_seqnumber = seqnumber;
473 return 0;
476 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
477 krb5_auth_con_getremoteseqnumber(krb5_context context,
478 krb5_auth_context auth_context,
479 int32_t *seqnumber)
481 *seqnumber = auth_context->remote_seqnumber;
482 return 0;
485 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
486 krb5_auth_con_setremoteseqnumber (krb5_context context,
487 krb5_auth_context auth_context,
488 int32_t seqnumber)
490 auth_context->remote_seqnumber = seqnumber;
491 return 0;
495 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
496 krb5_auth_con_getauthenticator(krb5_context context,
497 krb5_auth_context auth_context,
498 krb5_authenticator *authenticator)
500 *authenticator = malloc(sizeof(**authenticator));
501 if (*authenticator == NULL)
502 return krb5_enomem(context);
504 copy_Authenticator(auth_context->authenticator,
505 *authenticator);
506 return 0;
510 KRB5_LIB_FUNCTION void KRB5_LIB_CALL
511 krb5_free_authenticator(krb5_context context,
512 krb5_authenticator *authenticator)
514 free_Authenticator (*authenticator);
515 free (*authenticator);
516 *authenticator = NULL;
520 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
521 krb5_auth_con_setuserkey(krb5_context context,
522 krb5_auth_context auth_context,
523 krb5_keyblock *keyblock)
525 if(auth_context->keyblock)
526 krb5_free_keyblock(context, auth_context->keyblock);
527 return krb5_copy_keyblock(context, keyblock, &auth_context->keyblock);
530 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
531 krb5_auth_con_getrcache(krb5_context context,
532 krb5_auth_context auth_context,
533 krb5_rcache *rcache)
535 *rcache = auth_context->rcache;
536 return 0;
539 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
540 krb5_auth_con_setrcache(krb5_context context,
541 krb5_auth_context auth_context,
542 krb5_rcache rcache)
544 auth_context->rcache = rcache;
545 return 0;
548 #if 0 /* not implemented */
550 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
551 krb5_auth_con_initivector(krb5_context context,
552 krb5_auth_context auth_context)
554 krb5_abortx(context, "unimplemented krb5_auth_con_initivector called");
558 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
559 krb5_auth_con_setivector(krb5_context context,
560 krb5_auth_context auth_context,
561 krb5_pointer ivector)
563 krb5_abortx(context, "unimplemented krb5_auth_con_setivector called");
566 #endif /* not implemented */