Release 0.0t
[heimdal.git] / lib / gssapi / krb5 / init_sec_context.c
blob3b7c8f5762c244083eb8a1dfb1571e0718abfb67
1 /*
2 * Copyright (c) 1997, 1998 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. All advertising materials mentioning features or use of this software
18 * must display the following acknowledgement:
19 * This product includes software developed by Kungliga Tekniska
20 * Högskolan and its contributors.
22 * 4. Neither the name of the Institute nor the names of its contributors
23 * may be used to endorse or promote products derived from this software
24 * without specific prior written permission.
26 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 * SUCH DAMAGE.
39 #include "gssapi_locl.h"
41 RCSID("$Id$");
43 static OM_uint32
44 init_auth
45 (OM_uint32 * minor_status,
46 const gss_cred_id_t initiator_cred_handle,
47 gss_ctx_id_t * context_handle,
48 const gss_name_t target_name,
49 const gss_OID mech_type,
50 OM_uint32 req_flags,
51 OM_uint32 time_req,
52 const gss_channel_bindings_t input_chan_bindings,
53 const gss_buffer_t input_token,
54 gss_OID * actual_mech_type,
55 gss_buffer_t output_token,
56 OM_uint32 * ret_flags,
57 OM_uint32 * time_rec
60 OM_uint32 ret;
61 krb5_error_code kret;
62 krb5_flags ap_options;
63 krb5_creds this_cred, *cred;
64 krb5_data outbuf;
65 krb5_ccache ccache;
66 u_int32_t flags;
67 Authenticator *auth;
68 krb5_data authenticator;
69 Checksum cksum;
70 krb5_enctype enctype;
72 gssapi_krb5_init ();
74 outbuf.length = 0;
75 outbuf.data = NULL;
80 *context_handle = malloc(sizeof(**context_handle));
81 if (*context_handle == NULL)
82 return GSS_S_FAILURE;
84 (*context_handle)->auth_context = NULL;
85 (*context_handle)->source = NULL;
86 (*context_handle)->target = NULL;
87 (*context_handle)->flags = 0;
88 (*context_handle)->more_flags = 0;
90 kret = krb5_auth_con_init (gssapi_krb5_context,
91 &(*context_handle)->auth_context);
92 if (kret) {
93 ret = GSS_S_FAILURE;
94 goto failure;
98 int32_t tmp;
100 krb5_auth_con_getflags(gssapi_krb5_context,
101 (*context_handle)->auth_context,
102 &tmp);
103 tmp |= KRB5_AUTH_CONTEXT_DO_SEQUENCE;
104 krb5_auth_con_setflags(gssapi_krb5_context,
105 (*context_handle)->auth_context,
106 tmp);
109 if (actual_mech_type)
110 *actual_mech_type = GSS_KRB5_MECHANISM;
112 flags = 0;
113 ap_options = 0;
114 if (req_flags & GSS_C_DELEG_FLAG)
115 ; /* XXX */
116 if (req_flags & GSS_C_MUTUAL_FLAG) {
117 flags |= GSS_C_MUTUAL_FLAG;
118 ap_options |= AP_OPTS_MUTUAL_REQUIRED;
120 if (req_flags & GSS_C_REPLAY_FLAG)
121 ; /* XXX */
122 if (req_flags & GSS_C_SEQUENCE_FLAG)
123 ; /* XXX */
124 if (req_flags & GSS_C_ANON_FLAG)
125 ; /* XXX */
126 flags |= GSS_C_CONF_FLAG;
127 flags |= GSS_C_INTEG_FLAG;
128 flags |= GSS_C_SEQUENCE_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 ret = GSS_S_FAILURE;
138 goto failure;
141 kret = krb5_cc_get_principal (gssapi_krb5_context,
142 ccache,
143 &(*context_handle)->source);
144 if (kret) {
145 ret = GSS_S_FAILURE;
146 goto failure;
149 kret = krb5_copy_principal (gssapi_krb5_context,
150 target_name,
151 &(*context_handle)->target);
152 if (kret) {
153 ret = GSS_S_FAILURE;
154 goto failure;
157 memset(&this_cred, 0, sizeof(this_cred));
158 this_cred.client = (*context_handle)->source;
159 this_cred.server = (*context_handle)->target;
160 this_cred.times.endtime = 0;
162 kret = krb5_get_credentials (gssapi_krb5_context,
164 ccache,
165 &this_cred,
166 &cred);
168 if (kret) {
169 ret = GSS_S_FAILURE;
170 goto failure;
173 krb5_auth_con_setkey(gssapi_krb5_context,
174 (*context_handle)->auth_context,
175 &cred->session);
177 kret = gssapi_krb5_create_8003_checksum (input_chan_bindings,
178 flags,
179 &cksum);
180 if (kret) {
181 ret = GSS_S_FAILURE;
182 goto failure;
185 if ((*context_handle)->auth_context->enctype)
186 enctype = (*context_handle)->auth_context->enctype;
187 else {
188 kret = krb5_keytype_to_etype(gssapi_krb5_context,
189 (*context_handle)->auth_context->keyblock->keytype,
190 &enctype);
191 if (kret)
192 return kret;
197 kret = krb5_build_authenticator (gssapi_krb5_context,
198 (*context_handle)->auth_context,
199 enctype,
200 cred,
201 &cksum,
202 &auth,
203 &authenticator);
205 if (kret) {
206 ret = GSS_S_FAILURE;
207 goto failure;
210 kret = krb5_build_ap_req (gssapi_krb5_context,
211 enctype,
212 cred,
213 ap_options,
214 authenticator,
215 &outbuf);
217 if (kret) {
218 ret = GSS_S_FAILURE;
219 goto failure;
222 ret = gssapi_krb5_encapsulate (&outbuf,
223 output_token,
224 "\x01\x00");
225 if (ret)
226 goto failure;
228 if (flags & GSS_C_MUTUAL_FLAG) {
229 return GSS_S_CONTINUE_NEEDED;
230 } else {
231 (*context_handle)->more_flags |= OPEN;
232 return GSS_S_COMPLETE;
235 failure:
236 krb5_auth_con_free (gssapi_krb5_context,
237 (*context_handle)->auth_context);
238 if((*context_handle)->source)
239 krb5_free_principal (gssapi_krb5_context,
240 (*context_handle)->source);
241 if((*context_handle)->target)
242 krb5_free_principal (gssapi_krb5_context,
243 (*context_handle)->target);
244 free (*context_handle);
245 krb5_data_free (&outbuf);
246 *context_handle = GSS_C_NO_CONTEXT;
247 return GSS_S_FAILURE;
250 static OM_uint32
251 repl_mutual
252 (OM_uint32 * minor_status,
253 const gss_cred_id_t initiator_cred_handle,
254 gss_ctx_id_t * context_handle,
255 const gss_name_t target_name,
256 const gss_OID mech_type,
257 OM_uint32 req_flags,
258 OM_uint32 time_req,
259 const gss_channel_bindings_t input_chan_bindings,
260 const gss_buffer_t input_token,
261 gss_OID * actual_mech_type,
262 gss_buffer_t output_token,
263 OM_uint32 * ret_flags,
264 OM_uint32 * time_rec
267 OM_uint32 ret;
268 krb5_error_code kret;
269 krb5_data indata;
270 krb5_ap_rep_enc_part *repl;
272 ret = gssapi_krb5_decapsulate (input_token,
273 &indata,
274 "\x02\x00");
275 if (ret) {
276 /* XXX - Handle AP_ERROR */
277 return GSS_S_FAILURE;
280 kret = krb5_rd_rep (gssapi_krb5_context,
281 (*context_handle)->auth_context,
282 &indata,
283 &repl);
284 if (kret)
285 return GSS_S_FAILURE;
286 krb5_free_ap_rep_enc_part (gssapi_krb5_context,
287 repl);
289 output_token->length = 0;
291 (*context_handle)->more_flags |= OPEN;
293 return GSS_S_COMPLETE;
297 * gss_init_sec_context
300 OM_uint32 gss_init_sec_context
301 (OM_uint32 * minor_status,
302 const gss_cred_id_t initiator_cred_handle,
303 gss_ctx_id_t * context_handle,
304 const gss_name_t target_name,
305 const gss_OID mech_type,
306 OM_uint32 req_flags,
307 OM_uint32 time_req,
308 const gss_channel_bindings_t input_chan_bindings,
309 const gss_buffer_t input_token,
310 gss_OID * actual_mech_type,
311 gss_buffer_t output_token,
312 OM_uint32 * ret_flags,
313 OM_uint32 * time_rec
316 gssapi_krb5_init ();
318 if (input_token == GSS_C_NO_BUFFER || input_token->length == 0)
319 return init_auth (minor_status,
320 initiator_cred_handle,
321 context_handle,
322 target_name,
323 mech_type,
324 req_flags,
325 time_req,
326 input_chan_bindings,
327 input_token,
328 actual_mech_type,
329 output_token,
330 ret_flags,
331 time_rec);
332 else
333 return repl_mutual(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);