1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 /* lib/krb5/krb/auth_con.c */
4 * Copyright 2010 by the Massachusetts Institute of Technology.
7 * Export of this software from the United States of America may
8 * require a specific license from the United States Government.
9 * It is the responsibility of any person or organization contemplating
10 * export to obtain such a license before exporting.
12 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
13 * distribute this software and its documentation for any purpose and
14 * without fee is hereby granted, provided that the above copyright
15 * notice appear in all copies and that both that copyright notice and
16 * this permission notice appear in supporting documentation, and that
17 * the name of M.I.T. not be used in advertising or publicity pertaining
18 * to distribution of the software without specific, written prior
19 * permission. Furthermore if you modify this software you must label
20 * your software as modified software and not distribute it in such a
21 * fashion that it might be confused with the original M.I.T. software.
22 * M.I.T. makes no representations about the suitability of
23 * this software for any purpose. It is provided "as is" without express
24 * or implied warranty.
28 #include "int-proto.h"
31 krb5_error_code KRB5_CALLCONV
32 krb5_auth_con_init(krb5_context context, krb5_auth_context *auth_context)
35 (krb5_auth_context)calloc(1, sizeof(struct _krb5_auth_context));
39 /* Default flags, do time not seq */
40 (*auth_context)->auth_context_flags =
41 KRB5_AUTH_CONTEXT_DO_TIME | KRB5_AUTH_CONN_INITIALIZED;
43 (*auth_context)->req_cksumtype = context->default_ap_req_sumtype;
44 (*auth_context)->safe_cksumtype = context->default_safe_sumtype;
45 (*auth_context)->checksum_func = NULL;
46 (*auth_context)->checksum_func_data = NULL;
47 (*auth_context)->negotiated_etype = ENCTYPE_NULL;
48 (*auth_context)->magic = KV5M_AUTH_CONTEXT;
52 krb5_error_code KRB5_CALLCONV
53 krb5_auth_con_free(krb5_context context, krb5_auth_context auth_context)
55 if (auth_context == NULL)
57 if (auth_context->local_addr)
58 krb5_free_address(context, auth_context->local_addr);
59 if (auth_context->remote_addr)
60 krb5_free_address(context, auth_context->remote_addr);
61 if (auth_context->local_port)
62 krb5_free_address(context, auth_context->local_port);
63 if (auth_context->remote_port)
64 krb5_free_address(context, auth_context->remote_port);
65 if (auth_context->authentp)
66 krb5_free_authenticator(context, auth_context->authentp);
67 if (auth_context->key)
68 krb5_k_free_key(context, auth_context->key);
69 if (auth_context->send_subkey)
70 krb5_k_free_key(context, auth_context->send_subkey);
71 if (auth_context->recv_subkey)
72 krb5_k_free_key(context, auth_context->recv_subkey);
73 zapfree(auth_context->cstate.data, auth_context->cstate.length);
74 if (auth_context->rcache)
75 krb5_rc_close(context, auth_context->rcache);
76 if (auth_context->permitted_etypes)
77 free(auth_context->permitted_etypes);
78 if (auth_context->ad_context)
79 krb5_authdata_context_free(context, auth_context->ad_context);
85 krb5_auth_con_setaddrs(krb5_context context, krb5_auth_context auth_context, krb5_address *local_addr, krb5_address *remote_addr)
87 krb5_error_code retval;
89 /* Free old addresses */
90 if (auth_context->local_addr)
91 (void) krb5_free_address(context, auth_context->local_addr);
92 if (auth_context->remote_addr)
93 (void) krb5_free_address(context, auth_context->remote_addr);
97 retval = krb5_copy_addr(context,
99 &auth_context->local_addr);
101 auth_context->local_addr = NULL;
103 if (!retval && remote_addr)
104 retval = krb5_copy_addr(context,
106 &auth_context->remote_addr);
108 auth_context->remote_addr = NULL;
113 krb5_error_code KRB5_CALLCONV
114 krb5_auth_con_getaddrs(krb5_context context, krb5_auth_context auth_context, krb5_address **local_addr, krb5_address **remote_addr)
116 krb5_error_code retval;
119 if (local_addr && auth_context->local_addr) {
120 retval = krb5_copy_addr(context,
121 auth_context->local_addr,
124 if (!retval && (remote_addr) && auth_context->remote_addr) {
125 retval = krb5_copy_addr(context,
126 auth_context->remote_addr,
132 krb5_error_code KRB5_CALLCONV
133 krb5_auth_con_setports(krb5_context context, krb5_auth_context auth_context, krb5_address *local_port, krb5_address *remote_port)
135 krb5_error_code retval;
137 /* Free old addresses */
138 if (auth_context->local_port)
139 (void) krb5_free_address(context, auth_context->local_port);
140 if (auth_context->remote_port)
141 (void) krb5_free_address(context, auth_context->remote_port);
145 retval = krb5_copy_addr(context,
147 &auth_context->local_port);
149 auth_context->local_port = NULL;
151 if (!retval && remote_port)
152 retval = krb5_copy_addr(context,
154 &auth_context->remote_port);
156 auth_context->remote_port = NULL;
163 * This function overloads the keyblock field. It is only useful prior to
164 * a krb5_rd_req_decode() call for user to user authentication where the
165 * server has the key and needs to use it to decrypt the incoming request.
166 * Once decrypted this key is no longer necessary and is then overwritten
167 * with the session key sent by the client.
169 krb5_error_code KRB5_CALLCONV
170 krb5_auth_con_setuseruserkey(krb5_context context, krb5_auth_context auth_context, krb5_keyblock *keyblock)
172 if (auth_context->key)
173 krb5_k_free_key(context, auth_context->key);
174 return(krb5_k_create_key(context, keyblock, &(auth_context->key)));
177 krb5_error_code KRB5_CALLCONV
178 krb5_auth_con_getkey(krb5_context context, krb5_auth_context auth_context, krb5_keyblock **keyblock)
180 if (auth_context->key)
181 return krb5_k_key_keyblock(context, auth_context->key, keyblock);
186 krb5_error_code KRB5_CALLCONV
187 krb5_auth_con_getkey_k(krb5_context context, krb5_auth_context auth_context,
190 krb5_k_reference_key(context, auth_context->key);
191 *key = auth_context->key;
195 krb5_error_code KRB5_CALLCONV
196 krb5_auth_con_getlocalsubkey(krb5_context context, krb5_auth_context auth_context, krb5_keyblock **keyblock)
198 return krb5_auth_con_getsendsubkey(context, auth_context, keyblock);
201 krb5_error_code KRB5_CALLCONV
202 krb5_auth_con_getremotesubkey(krb5_context context, krb5_auth_context auth_context, krb5_keyblock **keyblock)
204 return krb5_auth_con_getrecvsubkey(context, auth_context, keyblock);
207 krb5_error_code KRB5_CALLCONV
208 krb5_auth_con_setsendsubkey(krb5_context ctx, krb5_auth_context ac, krb5_keyblock *keyblock)
210 if (ac->send_subkey != NULL)
211 krb5_k_free_key(ctx, ac->send_subkey);
212 ac->send_subkey = NULL;
214 return krb5_k_create_key(ctx, keyblock, &ac->send_subkey);
219 krb5_error_code KRB5_CALLCONV
220 krb5_auth_con_setsendsubkey_k(krb5_context ctx, krb5_auth_context ac,
223 krb5_k_free_key(ctx, ac->send_subkey);
224 ac->send_subkey = key;
225 krb5_k_reference_key(ctx, key);
229 krb5_error_code KRB5_CALLCONV
230 krb5_auth_con_setrecvsubkey(krb5_context ctx, krb5_auth_context ac, krb5_keyblock *keyblock)
232 if (ac->recv_subkey != NULL)
233 krb5_k_free_key(ctx, ac->recv_subkey);
234 ac->recv_subkey = NULL;
235 if (keyblock != NULL)
236 return krb5_k_create_key(ctx, keyblock, &ac->recv_subkey);
241 krb5_error_code KRB5_CALLCONV
242 krb5_auth_con_setrecvsubkey_k(krb5_context ctx, krb5_auth_context ac,
245 krb5_k_free_key(ctx, ac->recv_subkey);
246 ac->recv_subkey = key;
247 krb5_k_reference_key(ctx, key);
251 krb5_error_code KRB5_CALLCONV
252 krb5_auth_con_getsendsubkey(krb5_context ctx, krb5_auth_context ac, krb5_keyblock **keyblock)
254 if (ac->send_subkey != NULL)
255 return krb5_k_key_keyblock(ctx, ac->send_subkey, keyblock);
260 krb5_error_code KRB5_CALLCONV
261 krb5_auth_con_getsendsubkey_k(krb5_context ctx, krb5_auth_context ac,
264 krb5_k_reference_key(ctx, ac->send_subkey);
265 *key = ac->send_subkey;
269 krb5_error_code KRB5_CALLCONV
270 krb5_auth_con_getrecvsubkey(krb5_context ctx, krb5_auth_context ac, krb5_keyblock **keyblock)
272 if (ac->recv_subkey != NULL)
273 return krb5_k_key_keyblock(ctx, ac->recv_subkey, keyblock);
278 krb5_error_code KRB5_CALLCONV
279 krb5_auth_con_getrecvsubkey_k(krb5_context ctx, krb5_auth_context ac,
282 krb5_k_reference_key(ctx, ac->recv_subkey);
283 *key = ac->recv_subkey;
287 krb5_error_code KRB5_CALLCONV
288 krb5_auth_con_set_req_cksumtype(krb5_context context, krb5_auth_context auth_context, krb5_cksumtype cksumtype)
290 auth_context->req_cksumtype = cksumtype;
295 krb5_auth_con_set_safe_cksumtype(krb5_context context, krb5_auth_context auth_context, krb5_cksumtype cksumtype)
297 auth_context->safe_cksumtype = cksumtype;
301 krb5_error_code KRB5_CALLCONV
302 krb5_auth_con_getlocalseqnumber(krb5_context context, krb5_auth_context auth_context, krb5_int32 *seqnumber)
304 *seqnumber = auth_context->local_seq_number;
308 krb5_error_code KRB5_CALLCONV
309 krb5_auth_con_getremoteseqnumber(krb5_context context, krb5_auth_context auth_context, krb5_int32 *seqnumber)
311 *seqnumber = auth_context->remote_seq_number;
315 krb5_error_code KRB5_CALLCONV
316 krb5_auth_con_initivector(krb5_context context, krb5_auth_context auth_context)
319 krb5_enctype enctype;
321 if (auth_context->key == NULL)
323 ret = krb5_c_init_state(context, &auth_context->key->keyblock,
324 KRB5_KEYUSAGE_KRB_PRIV_ENCPART,
325 &auth_context->cstate);
330 * Historically we used a zero-filled buffer of the enctype block size.
331 * This matches every existing enctype except RC4 (which has a block size
332 * of 1) and des-cbc-crc (which uses the key instead of a zero-filled
333 * buffer). Special-case des-cbc-crc to remain interoperable.
335 enctype = krb5_k_key_enctype(context, auth_context->key);
336 if (enctype == ENCTYPE_DES_CBC_CRC)
337 zap(auth_context->cstate.data, auth_context->cstate.length);
343 krb5_auth_con_setivector(krb5_context context, krb5_auth_context auth_context, krb5_pointer ivector)
346 * This function was part of the pre-1.2.2 API. Because it aliased the
347 * caller's memory into auth_context, and doesn't provide the size of the
348 * cipher state, it's inconvenient to support now, so return an error.
354 krb5_auth_con_getivector(krb5_context context, krb5_auth_context auth_context, krb5_pointer *ivector)
356 *ivector = auth_context->cstate.data;
360 krb5_error_code KRB5_CALLCONV
361 krb5_auth_con_setflags(krb5_context context, krb5_auth_context auth_context, krb5_int32 flags)
363 auth_context->auth_context_flags = flags;
367 krb5_error_code KRB5_CALLCONV
368 krb5_auth_con_getflags(krb5_context context, krb5_auth_context auth_context, krb5_int32 *flags)
370 *flags = auth_context->auth_context_flags;
374 krb5_error_code KRB5_CALLCONV
375 krb5_auth_con_setrcache(krb5_context context, krb5_auth_context auth_context, krb5_rcache rcache)
377 auth_context->rcache = rcache;
382 krb5_auth_con_getrcache(krb5_context context, krb5_auth_context auth_context, krb5_rcache *rcache)
384 *rcache = auth_context->rcache;
389 krb5_auth_con_setpermetypes(krb5_context context,
390 krb5_auth_context auth_context,
391 const krb5_enctype *permetypes)
396 ret = k5_copy_etypes(permetypes, &newpe);
400 free(auth_context->permitted_etypes);
401 auth_context->permitted_etypes = newpe;
406 krb5_auth_con_getpermetypes(krb5_context context,
407 krb5_auth_context auth_context,
408 krb5_enctype **permetypes)
411 if (auth_context->permitted_etypes == NULL)
413 return k5_copy_etypes(auth_context->permitted_etypes, permetypes);
416 krb5_error_code KRB5_CALLCONV
417 krb5_auth_con_set_checksum_func( krb5_context context,
418 krb5_auth_context auth_context,
419 krb5_mk_req_checksum_func func,
422 auth_context->checksum_func = func;
423 auth_context->checksum_func_data = data;
427 krb5_error_code KRB5_CALLCONV
428 krb5_auth_con_get_checksum_func( krb5_context context,
429 krb5_auth_context auth_context,
430 krb5_mk_req_checksum_func *func,
433 *func = auth_context->checksum_func;
434 *data = auth_context->checksum_func_data;
439 krb5_auth_con_get_subkey_enctype(krb5_context context,
440 krb5_auth_context auth_context,
443 *etype = auth_context->negotiated_etype;
448 krb5_auth_con_get_authdata_context(krb5_context context,
449 krb5_auth_context auth_context,
450 krb5_authdata_context *ad_context)
452 *ad_context = auth_context->ad_context;
457 krb5_auth_con_set_authdata_context(krb5_context context,
458 krb5_auth_context auth_context,
459 krb5_authdata_context ad_context)
461 auth_context->ad_context = ad_context;