*** empty log message ***
[heimdal.git] / lib / gssapi / init_sec_context.c
blob59d02c7fd3d4f631ab9a64f5dff959099130d1d8
1 /*
2 * Copyright (c) 1997 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 this_cred.client = (*context_handle)->source;
158 this_cred.server = (*context_handle)->target;
159 this_cred.times.endtime = 0;
161 kret = krb5_get_credentials (gssapi_krb5_context,
163 ccache,
164 &this_cred,
165 &cred);
167 if (kret) {
168 ret = GSS_S_FAILURE;
169 goto failure;
173 /* XXX ugly */
174 krb5_keyblock *c;
175 krb5_auth_con_getkey(gssapi_krb5_context,
176 (*context_handle)->auth_context,
177 &c);
178 cred->session = *c;
179 free(c);
182 kret = gssapi_krb5_create_8003_checksum (input_chan_bindings,
183 flags,
184 &cksum);
185 if (kret) {
186 ret = GSS_S_FAILURE;
187 goto failure;
190 if ((*context_handle)->auth_context->enctype)
191 enctype = (*context_handle)->auth_context->enctype;
192 else {
193 kret = krb5_keytype_to_etype(gssapi_krb5_context,
194 (*context_handle)->auth_context->keyblock->keytype,
195 &enctype);
196 if (kret)
197 return kret;
202 kret = krb5_build_authenticator (gssapi_krb5_context,
203 (*context_handle)->auth_context,
204 enctype,
205 cred,
206 &cksum,
207 &auth,
208 &authenticator);
210 if (kret) {
211 ret = GSS_S_FAILURE;
212 goto failure;
215 kret = krb5_build_ap_req (gssapi_krb5_context,
216 enctype,
217 cred,
218 ap_options,
219 authenticator,
220 &outbuf);
222 if (kret) {
223 ret = GSS_S_FAILURE;
224 goto failure;
227 ret = gssapi_krb5_encapsulate (&outbuf,
228 output_token,
229 "\x01\x00");
230 if (ret)
231 goto failure;
233 if (flags & GSS_C_MUTUAL_FLAG) {
234 return GSS_S_CONTINUE_NEEDED;
235 } else {
236 (*context_handle)->more_flags |= OPEN;
237 return GSS_S_COMPLETE;
240 failure:
241 krb5_auth_con_free (gssapi_krb5_context,
242 (*context_handle)->auth_context);
243 if((*context_handle)->source)
244 krb5_free_principal (gssapi_krb5_context,
245 (*context_handle)->source);
246 if((*context_handle)->target)
247 krb5_free_principal (gssapi_krb5_context,
248 (*context_handle)->target);
249 free (*context_handle);
250 krb5_data_free (&outbuf);
251 *context_handle = GSS_C_NO_CONTEXT;
252 return GSS_S_FAILURE;
255 static OM_uint32
256 repl_mutual
257 (OM_uint32 * minor_status,
258 const gss_cred_id_t initiator_cred_handle,
259 gss_ctx_id_t * context_handle,
260 const gss_name_t target_name,
261 const gss_OID mech_type,
262 OM_uint32 req_flags,
263 OM_uint32 time_req,
264 const gss_channel_bindings_t input_chan_bindings,
265 const gss_buffer_t input_token,
266 gss_OID * actual_mech_type,
267 gss_buffer_t output_token,
268 OM_uint32 * ret_flags,
269 OM_uint32 * time_rec
272 OM_uint32 ret;
273 krb5_error_code kret;
274 krb5_data indata;
275 krb5_ap_rep_enc_part *repl;
277 ret = gssapi_krb5_decapsulate (input_token,
278 &indata,
279 "\x02\x00");
280 if (ret) {
281 /* XXX - Handle AP_ERROR */
282 return GSS_S_FAILURE;
285 kret = krb5_rd_rep (gssapi_krb5_context,
286 (*context_handle)->auth_context,
287 &indata,
288 &repl);
289 if (kret)
290 return GSS_S_FAILURE;
291 krb5_free_ap_rep_enc_part (gssapi_krb5_context,
292 repl);
294 (*context_handle)->more_flags |= OPEN;
296 return GSS_S_COMPLETE;
300 * gss_init_sec_context
303 OM_uint32 gss_init_sec_context
304 (OM_uint32 * minor_status,
305 const gss_cred_id_t initiator_cred_handle,
306 gss_ctx_id_t * context_handle,
307 const gss_name_t target_name,
308 const gss_OID mech_type,
309 OM_uint32 req_flags,
310 OM_uint32 time_req,
311 const gss_channel_bindings_t input_chan_bindings,
312 const gss_buffer_t input_token,
313 gss_OID * actual_mech_type,
314 gss_buffer_t output_token,
315 OM_uint32 * ret_flags,
316 OM_uint32 * time_rec
319 gssapi_krb5_init ();
321 if (input_token == GSS_C_NO_BUFFER || input_token->length == 0)
322 return init_auth (minor_status,
323 initiator_cred_handle,
324 context_handle,
325 target_name,
326 mech_type,
327 req_flags,
328 time_req,
329 input_chan_bindings,
330 input_token,
331 actual_mech_type,
332 output_token,
333 ret_flags,
334 time_rec);
335 else
336 return repl_mutual(minor_status,
337 initiator_cred_handle,
338 context_handle,
339 target_name,
340 mech_type,
341 req_flags,
342 time_req,
343 input_chan_bindings,
344 input_token,
345 actual_mech_type,
346 output_token,
347 ret_flags,
348 time_rec);