2 * Copyright (c) 1997 - 2002 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
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
34 #include "krb5_locl.h"
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
)
54 return krb5_enomem(context
);
55 memset(p
, 0, sizeof(*p
));
56 ALLOC(p
->authenticator
, 1);
57 if (!p
->authenticator
) {
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
;
68 p
->keytype
= KRB5_ENCTYPE_NULL
;
69 p
->cksumtype
= CKSUMTYPE_NONE
;
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
);
110 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
111 krb5_auth_con_setflags(krb5_context context
,
112 krb5_auth_context auth_context
,
115 auth_context
->flags
= flags
;
120 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
121 krb5_auth_con_getflags(krb5_context context
,
122 krb5_auth_context auth_context
,
125 *flags
= auth_context
->flags
;
129 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
130 krb5_auth_con_addflags(krb5_context context
,
131 krb5_auth_context auth_context
,
136 *flags
= auth_context
->flags
;
137 auth_context
->flags
|= addflags
;
141 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
142 krb5_auth_con_removeflags(krb5_context context
,
143 krb5_auth_context auth_context
,
148 *flags
= auth_context
->flags
;
149 auth_context
->flags
&= ~removeflags
;
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
)
160 if (auth_context
->local_address
)
161 krb5_free_address (context
, auth_context
->local_address
);
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
);
168 if (auth_context
->remote_address
)
169 krb5_free_address (context
, auth_context
->remote_address
);
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
);
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
)
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
;
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
))) {
203 rk_strerror_r(ret
, buf
, sizeof(buf
));
204 krb5_set_error_message(context
, ret
, "getsockname: %s", buf
);
207 ret
= krb5_sockaddr2address (context
, local
, &local_k_address
);
209 if(flags
& KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR
) {
210 krb5_sockaddr2port (context
, local
, &auth_context
->local_port
);
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
))) {
221 rk_strerror_r(ret
, buf
, sizeof(buf
));
222 krb5_set_error_message(context
, ret
, "getpeername: %s", buf
);
225 ret
= krb5_sockaddr2address (context
, remote
, &remote_k_address
);
227 if(flags
& KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR
) {
228 krb5_sockaddr2port (context
, remote
, &auth_context
->remote_port
);
230 auth_context
->remote_port
= 0;
231 rptr
= &remote_k_address
;
233 ret
= krb5_auth_con_setaddrs (context
,
239 krb5_free_address (context
, lptr
);
241 krb5_free_address (context
, rptr
);
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
,
251 krb5_socket_t fd
= *(krb5_socket_t
*)p_fd
;
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
)
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
,
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
);
281 return krb5_enomem(context
);
283 krb5_copy_address(context
,
284 auth_context
->remote_address
,
289 /* coverity[+alloc : arg-*2] */
290 static krb5_error_code
291 copy_key(krb5_context context
,
296 return krb5_copy_keyblock(context
, in
, out
);
297 *out
= NULL
; /* is this right? */
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
,
352 krb5_keyblock
*subkey
;
354 ret
= krb5_generate_subkey_extended (context
, key
,
355 auth_context
->keytype
,
359 if(auth_context
->local_subkey
)
360 krb5_free_keyblock(context
, auth_context
->local_subkey
);
361 auth_context
->local_subkey
= subkey
;
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
;
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
;
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
;
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
;
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
,
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
);
426 el
.ad_data
.data
= data
->data
;
427 el
.ad_data
.length
= data
->length
;
429 return add_AuthorizationData(auth_context
->auth_data
, &el
);
435 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
436 krb5_auth_con_setenctype(krb5_context context
,
437 krb5_auth_context auth_context
,
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
;
449 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
450 krb5_auth_con_getenctype(krb5_context context
,
451 krb5_auth_context auth_context
,
454 krb5_abortx(context
, "unimplemented krb5_auth_getenctype called");
458 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
459 krb5_auth_con_getlocalseqnumber(krb5_context context
,
460 krb5_auth_context auth_context
,
463 *seqnumber
= auth_context
->local_seqnumber
;
467 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
468 krb5_auth_con_setlocalseqnumber (krb5_context context
,
469 krb5_auth_context auth_context
,
472 auth_context
->local_seqnumber
= seqnumber
;
476 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
477 krb5_auth_con_getremoteseqnumber(krb5_context context
,
478 krb5_auth_context auth_context
,
481 *seqnumber
= auth_context
->remote_seqnumber
;
485 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
486 krb5_auth_con_setremoteseqnumber (krb5_context context
,
487 krb5_auth_context auth_context
,
490 auth_context
->remote_seqnumber
= seqnumber
;
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
,
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
,
535 *rcache
= auth_context
->rcache
;
539 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
540 krb5_auth_con_setrcache(krb5_context context
,
541 krb5_auth_context auth_context
,
544 auth_context
->rcache
= rcache
;
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 */