revert timeval bonus
[heimdal.git] / lib / gssapi / krb5 / init_sec_context.c
blob12a329266ab9e796c014c79f2053dd2e14a4a9c0
1 /*
2 * Copyright (c) 1997, 1998, 1999 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 "gssapi_locl.h"
36 RCSID("$Id$");
38 static OM_uint32
39 init_auth
40 (OM_uint32 * minor_status,
41 const gss_cred_id_t initiator_cred_handle,
42 gss_ctx_id_t * context_handle,
43 const gss_name_t target_name,
44 const gss_OID mech_type,
45 OM_uint32 req_flags,
46 OM_uint32 time_req,
47 const gss_channel_bindings_t input_chan_bindings,
48 const gss_buffer_t input_token,
49 gss_OID * actual_mech_type,
50 gss_buffer_t output_token,
51 OM_uint32 * ret_flags,
52 OM_uint32 * time_rec
55 OM_uint32 ret = GSS_S_FAILURE;
56 krb5_error_code kret;
57 krb5_flags ap_options;
58 krb5_creds this_cred, *cred;
59 krb5_data outbuf;
60 krb5_ccache ccache;
61 u_int32_t flags;
62 Authenticator *auth;
63 krb5_data authenticator;
64 Checksum cksum;
65 krb5_enctype enctype;
67 output_token->length = 0;
68 output_token->value = NULL;
70 outbuf.length = 0;
71 outbuf.data = NULL;
73 *minor_status = 0;
75 *context_handle = malloc(sizeof(**context_handle));
76 if (*context_handle == NULL) {
77 *minor_status = ENOMEM;
78 return GSS_S_FAILURE;
81 (*context_handle)->auth_context = NULL;
82 (*context_handle)->source = NULL;
83 (*context_handle)->target = NULL;
84 (*context_handle)->flags = 0;
85 (*context_handle)->more_flags = 0;
86 (*context_handle)->ticket = NULL;
88 kret = krb5_auth_con_init (gssapi_krb5_context,
89 &(*context_handle)->auth_context);
90 if (kret) {
91 *minor_status = kret;
92 ret = GSS_S_FAILURE;
93 goto failure;
97 int32_t tmp;
99 krb5_auth_con_getflags(gssapi_krb5_context,
100 (*context_handle)->auth_context,
101 &tmp);
102 tmp |= KRB5_AUTH_CONTEXT_DO_SEQUENCE;
103 krb5_auth_con_setflags(gssapi_krb5_context,
104 (*context_handle)->auth_context,
105 tmp);
108 if (actual_mech_type)
109 *actual_mech_type = GSS_KRB5_MECHANISM;
111 flags = 0;
112 ap_options = 0;
113 if (req_flags & GSS_C_DELEG_FLAG)
114 ; /* XXX */
115 if (req_flags & GSS_C_MUTUAL_FLAG) {
116 flags |= GSS_C_MUTUAL_FLAG;
117 ap_options |= AP_OPTS_MUTUAL_REQUIRED;
119 if (req_flags & GSS_C_REPLAY_FLAG)
120 ; /* XXX */
121 if (req_flags & GSS_C_SEQUENCE_FLAG)
122 ; /* XXX */
123 if (req_flags & GSS_C_ANON_FLAG)
124 ; /* XXX */
125 flags |= GSS_C_CONF_FLAG;
126 flags |= GSS_C_INTEG_FLAG;
127 flags |= GSS_C_SEQUENCE_FLAG;
128 flags |= GSS_C_TRANS_FLAG;
130 if (ret_flags)
131 *ret_flags = flags;
132 (*context_handle)->flags = flags;
133 (*context_handle)->more_flags = LOCAL;
135 kret = krb5_cc_default (gssapi_krb5_context, &ccache);
136 if (kret) {
137 *minor_status = kret;
138 ret = GSS_S_FAILURE;
139 goto failure;
142 kret = krb5_cc_get_principal (gssapi_krb5_context,
143 ccache,
144 &(*context_handle)->source);
145 if (kret) {
146 *minor_status = kret;
147 ret = GSS_S_FAILURE;
148 goto failure;
151 kret = krb5_copy_principal (gssapi_krb5_context,
152 target_name,
153 &(*context_handle)->target);
154 if (kret) {
155 *minor_status = kret;
156 ret = GSS_S_FAILURE;
157 goto failure;
160 memset(&this_cred, 0, sizeof(this_cred));
161 this_cred.client = (*context_handle)->source;
162 this_cred.server = (*context_handle)->target;
163 this_cred.times.endtime = 0;
164 this_cred.session.keytype = ETYPE_DES_CBC_CRC;
166 kret = krb5_get_credentials (gssapi_krb5_context,
167 KRB5_TC_MATCH_KEYTYPE,
168 ccache,
169 &this_cred,
170 &cred);
172 if (kret) {
173 *minor_status = kret;
174 ret = GSS_S_FAILURE;
175 goto failure;
178 krb5_auth_con_setkey(gssapi_krb5_context,
179 (*context_handle)->auth_context,
180 &cred->session);
182 kret = gssapi_krb5_create_8003_checksum (input_chan_bindings,
183 flags,
184 &cksum);
185 if (kret) {
186 *minor_status = kret;
187 ret = GSS_S_FAILURE;
188 goto failure;
191 #if 1
192 enctype = (*context_handle)->auth_context->keyblock->keytype;
193 #else
194 if ((*context_handle)->auth_context->enctype)
195 enctype = (*context_handle)->auth_context->enctype;
196 else {
197 kret = krb5_keytype_to_enctype(gssapi_krb5_context,
198 (*context_handle)->auth_context->keyblock->keytype,
199 &enctype);
200 if (kret)
201 return kret;
203 #endif
207 kret = krb5_build_authenticator (gssapi_krb5_context,
208 (*context_handle)->auth_context,
209 enctype,
210 cred,
211 &cksum,
212 &auth,
213 &authenticator);
215 if (kret) {
216 *minor_status = kret;
217 ret = GSS_S_FAILURE;
218 goto failure;
221 kret = krb5_build_ap_req (gssapi_krb5_context,
222 enctype,
223 cred,
224 ap_options,
225 authenticator,
226 &outbuf);
228 if (kret) {
229 *minor_status = kret;
230 ret = GSS_S_FAILURE;
231 goto failure;
234 ret = gssapi_krb5_encapsulate (&outbuf,
235 output_token,
236 "\x01\x00");
237 if (ret) {
238 *minor_status = kret;
239 goto failure;
242 if (flags & GSS_C_MUTUAL_FLAG) {
243 return GSS_S_CONTINUE_NEEDED;
244 } else {
245 (*context_handle)->more_flags |= OPEN;
246 return GSS_S_COMPLETE;
249 failure:
250 krb5_auth_con_free (gssapi_krb5_context,
251 (*context_handle)->auth_context);
252 if((*context_handle)->source)
253 krb5_free_principal (gssapi_krb5_context,
254 (*context_handle)->source);
255 if((*context_handle)->target)
256 krb5_free_principal (gssapi_krb5_context,
257 (*context_handle)->target);
258 free (*context_handle);
259 krb5_data_free (&outbuf);
260 *context_handle = GSS_C_NO_CONTEXT;
261 return ret;
264 static OM_uint32
265 repl_mutual
266 (OM_uint32 * minor_status,
267 const gss_cred_id_t initiator_cred_handle,
268 gss_ctx_id_t * context_handle,
269 const gss_name_t target_name,
270 const gss_OID mech_type,
271 OM_uint32 req_flags,
272 OM_uint32 time_req,
273 const gss_channel_bindings_t input_chan_bindings,
274 const gss_buffer_t input_token,
275 gss_OID * actual_mech_type,
276 gss_buffer_t output_token,
277 OM_uint32 * ret_flags,
278 OM_uint32 * time_rec
281 OM_uint32 ret;
282 krb5_error_code kret;
283 krb5_data indata;
284 krb5_ap_rep_enc_part *repl;
286 ret = gssapi_krb5_decapsulate (input_token,
287 &indata,
288 "\x02\x00");
289 if (ret) {
290 /* XXX - Handle AP_ERROR */
291 return GSS_S_FAILURE;
294 kret = krb5_rd_rep (gssapi_krb5_context,
295 (*context_handle)->auth_context,
296 &indata,
297 &repl);
298 if (kret)
299 return GSS_S_FAILURE;
300 krb5_free_ap_rep_enc_part (gssapi_krb5_context,
301 repl);
303 output_token->length = 0;
305 (*context_handle)->more_flags |= OPEN;
307 return GSS_S_COMPLETE;
311 * gss_init_sec_context
314 OM_uint32 gss_init_sec_context
315 (OM_uint32 * minor_status,
316 const gss_cred_id_t initiator_cred_handle,
317 gss_ctx_id_t * context_handle,
318 const gss_name_t target_name,
319 const gss_OID mech_type,
320 OM_uint32 req_flags,
321 OM_uint32 time_req,
322 const gss_channel_bindings_t input_chan_bindings,
323 const gss_buffer_t input_token,
324 gss_OID * actual_mech_type,
325 gss_buffer_t output_token,
326 OM_uint32 * ret_flags,
327 OM_uint32 * time_rec
330 gssapi_krb5_init ();
332 if (input_token == GSS_C_NO_BUFFER || input_token->length == 0)
333 return init_auth (minor_status,
334 initiator_cred_handle,
335 context_handle,
336 target_name,
337 mech_type,
338 req_flags,
339 time_req,
340 input_chan_bindings,
341 input_token,
342 actual_mech_type,
343 output_token,
344 ret_flags,
345 time_rec);
346 else
347 return repl_mutual(minor_status,
348 initiator_cred_handle,
349 context_handle,
350 target_name,
351 mech_type,
352 req_flags,
353 time_req,
354 input_chan_bindings,
355 input_token,
356 actual_mech_type,
357 output_token,
358 ret_flags,
359 time_rec);