Fix autoconf 2.70 compatibility
[platform/upstream/krb5.git] / src / lib / krb5 / krb / auth_con.c
1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 /* lib/krb5/krb/auth_con.c */
3 /*
4  * Copyright 2010 by the Massachusetts Institute of Technology.
5  * All Rights Reserved.
6  *
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.
11  *
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.
25  */
26
27 #include "k5-int.h"
28 #include "int-proto.h"
29 #include "auth_con.h"
30
31 krb5_error_code KRB5_CALLCONV
32 krb5_auth_con_init(krb5_context context, krb5_auth_context *auth_context)
33 {
34     *auth_context =
35         (krb5_auth_context)calloc(1, sizeof(struct _krb5_auth_context));
36     if (!*auth_context)
37         return ENOMEM;
38
39     /* Default flags, do time not seq */
40     (*auth_context)->auth_context_flags =
41         KRB5_AUTH_CONTEXT_DO_TIME |  KRB5_AUTH_CONN_INITIALIZED;
42
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;
49     return 0;
50 }
51
52 krb5_error_code KRB5_CALLCONV
53 krb5_auth_con_free(krb5_context context, krb5_auth_context auth_context)
54 {
55     if (auth_context == NULL)
56         return 0;
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);
80     free(auth_context);
81     return 0;
82 }
83
84 krb5_error_code
85 krb5_auth_con_setaddrs(krb5_context context, krb5_auth_context auth_context, krb5_address *local_addr, krb5_address *remote_addr)
86 {
87     krb5_error_code     retval;
88
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);
94
95     retval = 0;
96     if (local_addr)
97         retval = krb5_copy_addr(context,
98                                 local_addr,
99                                 &auth_context->local_addr);
100     else
101         auth_context->local_addr = NULL;
102
103     if (!retval && remote_addr)
104         retval = krb5_copy_addr(context,
105                                 remote_addr,
106                                 &auth_context->remote_addr);
107     else
108         auth_context->remote_addr = NULL;
109
110     return retval;
111 }
112
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)
115 {
116     krb5_error_code     retval;
117
118     retval = 0;
119     if (local_addr && auth_context->local_addr) {
120         retval = krb5_copy_addr(context,
121                                 auth_context->local_addr,
122                                 local_addr);
123     }
124     if (!retval && (remote_addr) && auth_context->remote_addr) {
125         retval = krb5_copy_addr(context,
126                                 auth_context->remote_addr,
127                                 remote_addr);
128     }
129     return retval;
130 }
131
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)
134 {
135     krb5_error_code     retval;
136
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);
142
143     retval = 0;
144     if (local_port)
145         retval = krb5_copy_addr(context,
146                                 local_port,
147                                 &auth_context->local_port);
148     else
149         auth_context->local_port = NULL;
150
151     if (!retval && remote_port)
152         retval = krb5_copy_addr(context,
153                                 remote_port,
154                                 &auth_context->remote_port);
155     else
156         auth_context->remote_port = NULL;
157
158     return retval;
159 }
160
161
162 /*
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.
168  */
169 krb5_error_code KRB5_CALLCONV
170 krb5_auth_con_setuseruserkey(krb5_context context, krb5_auth_context auth_context, krb5_keyblock *keyblock)
171 {
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)));
175 }
176
177 krb5_error_code KRB5_CALLCONV
178 krb5_auth_con_getkey(krb5_context context, krb5_auth_context auth_context, krb5_keyblock **keyblock)
179 {
180     if (auth_context->key)
181         return krb5_k_key_keyblock(context, auth_context->key, keyblock);
182     *keyblock = NULL;
183     return 0;
184 }
185
186 krb5_error_code KRB5_CALLCONV
187 krb5_auth_con_getkey_k(krb5_context context, krb5_auth_context auth_context,
188                        krb5_key *key)
189 {
190     krb5_k_reference_key(context, auth_context->key);
191     *key = auth_context->key;
192     return 0;
193 }
194
195 krb5_error_code KRB5_CALLCONV
196 krb5_auth_con_getlocalsubkey(krb5_context context, krb5_auth_context auth_context, krb5_keyblock **keyblock)
197 {
198     return krb5_auth_con_getsendsubkey(context, auth_context, keyblock);
199 }
200
201 krb5_error_code KRB5_CALLCONV
202 krb5_auth_con_getremotesubkey(krb5_context context, krb5_auth_context auth_context, krb5_keyblock **keyblock)
203 {
204     return krb5_auth_con_getrecvsubkey(context, auth_context, keyblock);
205 }
206
207 krb5_error_code KRB5_CALLCONV
208 krb5_auth_con_setsendsubkey(krb5_context ctx, krb5_auth_context ac, krb5_keyblock *keyblock)
209 {
210     if (ac->send_subkey != NULL)
211         krb5_k_free_key(ctx, ac->send_subkey);
212     ac->send_subkey = NULL;
213     if (keyblock !=NULL)
214         return krb5_k_create_key(ctx, keyblock, &ac->send_subkey);
215     else
216         return 0;
217 }
218
219 krb5_error_code KRB5_CALLCONV
220 krb5_auth_con_setsendsubkey_k(krb5_context ctx, krb5_auth_context ac,
221                               krb5_key key)
222 {
223     krb5_k_free_key(ctx, ac->send_subkey);
224     ac->send_subkey = key;
225     krb5_k_reference_key(ctx, key);
226     return 0;
227 }
228
229 krb5_error_code KRB5_CALLCONV
230 krb5_auth_con_setrecvsubkey(krb5_context ctx, krb5_auth_context ac, krb5_keyblock *keyblock)
231 {
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);
237     else
238         return 0;
239 }
240
241 krb5_error_code KRB5_CALLCONV
242 krb5_auth_con_setrecvsubkey_k(krb5_context ctx, krb5_auth_context ac,
243                               krb5_key key)
244 {
245     krb5_k_free_key(ctx, ac->recv_subkey);
246     ac->recv_subkey = key;
247     krb5_k_reference_key(ctx, key);
248     return 0;
249 }
250
251 krb5_error_code KRB5_CALLCONV
252 krb5_auth_con_getsendsubkey(krb5_context ctx, krb5_auth_context ac, krb5_keyblock **keyblock)
253 {
254     if (ac->send_subkey != NULL)
255         return krb5_k_key_keyblock(ctx, ac->send_subkey, keyblock);
256     *keyblock = NULL;
257     return 0;
258 }
259
260 krb5_error_code KRB5_CALLCONV
261 krb5_auth_con_getsendsubkey_k(krb5_context ctx, krb5_auth_context ac,
262                               krb5_key *key)
263 {
264     krb5_k_reference_key(ctx, ac->send_subkey);
265     *key = ac->send_subkey;
266     return 0;
267 }
268
269 krb5_error_code KRB5_CALLCONV
270 krb5_auth_con_getrecvsubkey(krb5_context ctx, krb5_auth_context ac, krb5_keyblock **keyblock)
271 {
272     if (ac->recv_subkey != NULL)
273         return krb5_k_key_keyblock(ctx, ac->recv_subkey, keyblock);
274     *keyblock = NULL;
275     return 0;
276 }
277
278 krb5_error_code KRB5_CALLCONV
279 krb5_auth_con_getrecvsubkey_k(krb5_context ctx, krb5_auth_context ac,
280                               krb5_key *key)
281 {
282     krb5_k_reference_key(ctx, ac->recv_subkey);
283     *key = ac->recv_subkey;
284     return 0;
285 }
286
287 krb5_error_code KRB5_CALLCONV
288 krb5_auth_con_set_req_cksumtype(krb5_context context, krb5_auth_context auth_context, krb5_cksumtype cksumtype)
289 {
290     auth_context->req_cksumtype = cksumtype;
291     return 0;
292 }
293
294 krb5_error_code
295 krb5_auth_con_set_safe_cksumtype(krb5_context context, krb5_auth_context auth_context, krb5_cksumtype cksumtype)
296 {
297     auth_context->safe_cksumtype = cksumtype;
298     return 0;
299 }
300
301 krb5_error_code KRB5_CALLCONV
302 krb5_auth_con_getlocalseqnumber(krb5_context context, krb5_auth_context auth_context, krb5_int32 *seqnumber)
303 {
304     *seqnumber = auth_context->local_seq_number;
305     return 0;
306 }
307
308 krb5_error_code KRB5_CALLCONV
309 krb5_auth_con_getremoteseqnumber(krb5_context context, krb5_auth_context auth_context, krb5_int32 *seqnumber)
310 {
311     *seqnumber = auth_context->remote_seq_number;
312     return 0;
313 }
314
315 krb5_error_code KRB5_CALLCONV
316 krb5_auth_con_initivector(krb5_context context, krb5_auth_context auth_context)
317 {
318     krb5_error_code ret;
319     krb5_enctype enctype;
320
321     if (auth_context->key == NULL)
322         return EINVAL;
323     ret = krb5_c_init_state(context, &auth_context->key->keyblock,
324                             KRB5_KEYUSAGE_KRB_PRIV_ENCPART,
325                             &auth_context->cstate);
326     if (ret)
327         return ret;
328
329     /*
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.
334      */
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);
338
339     return 0;
340 }
341
342 krb5_error_code
343 krb5_auth_con_setivector(krb5_context context, krb5_auth_context auth_context, krb5_pointer ivector)
344 {
345     /*
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.
349      */
350     return EINVAL;
351 }
352
353 krb5_error_code
354 krb5_auth_con_getivector(krb5_context context, krb5_auth_context auth_context, krb5_pointer *ivector)
355 {
356     *ivector = auth_context->cstate.data;
357     return 0;
358 }
359
360 krb5_error_code KRB5_CALLCONV
361 krb5_auth_con_setflags(krb5_context context, krb5_auth_context auth_context, krb5_int32 flags)
362 {
363     auth_context->auth_context_flags = flags;
364     return 0;
365 }
366
367 krb5_error_code KRB5_CALLCONV
368 krb5_auth_con_getflags(krb5_context context, krb5_auth_context auth_context, krb5_int32 *flags)
369 {
370     *flags = auth_context->auth_context_flags;
371     return 0;
372 }
373
374 krb5_error_code KRB5_CALLCONV
375 krb5_auth_con_setrcache(krb5_context context, krb5_auth_context auth_context, krb5_rcache rcache)
376 {
377     auth_context->rcache = rcache;
378     return 0;
379 }
380
381 krb5_error_code
382 krb5_auth_con_getrcache(krb5_context context, krb5_auth_context auth_context, krb5_rcache *rcache)
383 {
384     *rcache = auth_context->rcache;
385     return 0;
386 }
387
388 krb5_error_code
389 krb5_auth_con_setpermetypes(krb5_context context,
390                             krb5_auth_context auth_context,
391                             const krb5_enctype *permetypes)
392 {
393     krb5_enctype *newpe;
394     krb5_error_code ret;
395
396     ret = k5_copy_etypes(permetypes, &newpe);
397     if (ret != 0)
398         return ret;
399
400     free(auth_context->permitted_etypes);
401     auth_context->permitted_etypes = newpe;
402     return 0;
403 }
404
405 krb5_error_code
406 krb5_auth_con_getpermetypes(krb5_context context,
407                             krb5_auth_context auth_context,
408                             krb5_enctype **permetypes)
409 {
410     *permetypes = NULL;
411     if (auth_context->permitted_etypes == NULL)
412         return 0;
413     return k5_copy_etypes(auth_context->permitted_etypes, permetypes);
414 }
415
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,
420                                  void *data)
421 {
422     auth_context->checksum_func = func;
423     auth_context->checksum_func_data = data;
424     return 0;
425 }
426
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,
431                                  void **data)
432 {
433     *func = auth_context->checksum_func;
434     *data = auth_context->checksum_func_data;
435     return 0;
436 }
437
438 krb5_error_code
439 krb5_auth_con_get_subkey_enctype(krb5_context context,
440                                  krb5_auth_context auth_context,
441                                  krb5_enctype *etype)
442 {
443     *etype = auth_context->negotiated_etype;
444     return 0;
445 }
446
447 krb5_error_code
448 krb5_auth_con_get_authdata_context(krb5_context context,
449                                    krb5_auth_context auth_context,
450                                    krb5_authdata_context *ad_context)
451 {
452     *ad_context = auth_context->ad_context;
453     return 0;
454 }
455
456 krb5_error_code
457 krb5_auth_con_set_authdata_context(krb5_context context,
458                                    krb5_auth_context auth_context,
459                                    krb5_authdata_context ad_context)
460 {
461     auth_context->ad_context = ad_context;
462     return 0;
463 }