1c19800e8SDoug Rabson /*
2c19800e8SDoug Rabson * Copyright (c) 2004, PADL Software Pty Ltd.
3c19800e8SDoug Rabson * All rights reserved.
4c19800e8SDoug Rabson *
5c19800e8SDoug Rabson * Redistribution and use in source and binary forms, with or without
6c19800e8SDoug Rabson * modification, are permitted provided that the following conditions
7c19800e8SDoug Rabson * are met:
8c19800e8SDoug Rabson *
9c19800e8SDoug Rabson * 1. Redistributions of source code must retain the above copyright
10c19800e8SDoug Rabson * notice, this list of conditions and the following disclaimer.
11c19800e8SDoug Rabson *
12c19800e8SDoug Rabson * 2. Redistributions in binary form must reproduce the above copyright
13c19800e8SDoug Rabson * notice, this list of conditions and the following disclaimer in the
14c19800e8SDoug Rabson * documentation and/or other materials provided with the distribution.
15c19800e8SDoug Rabson *
16c19800e8SDoug Rabson * 3. Neither the name of PADL Software nor the names of its contributors
17c19800e8SDoug Rabson * may be used to endorse or promote products derived from this software
18c19800e8SDoug Rabson * without specific prior written permission.
19c19800e8SDoug Rabson *
20c19800e8SDoug Rabson * THIS SOFTWARE IS PROVIDED BY PADL SOFTWARE AND CONTRIBUTORS ``AS IS'' AND
21c19800e8SDoug Rabson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22c19800e8SDoug Rabson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23c19800e8SDoug Rabson * ARE DISCLAIMED. IN NO EVENT SHALL PADL SOFTWARE OR CONTRIBUTORS BE LIABLE
24c19800e8SDoug Rabson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25c19800e8SDoug Rabson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26c19800e8SDoug Rabson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27c19800e8SDoug Rabson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28c19800e8SDoug Rabson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29c19800e8SDoug Rabson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30c19800e8SDoug Rabson * SUCH DAMAGE.
31c19800e8SDoug Rabson */
32c19800e8SDoug Rabson
33*ae771770SStanislav Sedov #include "spnego_locl.h"
34c19800e8SDoug Rabson
35c19800e8SDoug Rabson static OM_uint32
spnego_supported_mechs(OM_uint32 * minor_status,gss_OID_set * mechs)36c19800e8SDoug Rabson spnego_supported_mechs(OM_uint32 *minor_status, gss_OID_set *mechs)
37c19800e8SDoug Rabson {
38c19800e8SDoug Rabson OM_uint32 ret, junk;
39c19800e8SDoug Rabson gss_OID_set m;
40*ae771770SStanislav Sedov size_t i;
41c19800e8SDoug Rabson
42c19800e8SDoug Rabson ret = gss_indicate_mechs(minor_status, &m);
43c19800e8SDoug Rabson if (ret != GSS_S_COMPLETE)
44c19800e8SDoug Rabson return ret;
45c19800e8SDoug Rabson
46c19800e8SDoug Rabson ret = gss_create_empty_oid_set(minor_status, mechs);
47c19800e8SDoug Rabson if (ret != GSS_S_COMPLETE) {
48c19800e8SDoug Rabson gss_release_oid_set(&junk, &m);
49c19800e8SDoug Rabson return ret;
50c19800e8SDoug Rabson }
51c19800e8SDoug Rabson
52c19800e8SDoug Rabson for (i = 0; i < m->count; i++) {
53c19800e8SDoug Rabson if (gss_oid_equal(&m->elements[i], GSS_SPNEGO_MECHANISM))
54c19800e8SDoug Rabson continue;
55c19800e8SDoug Rabson
56c19800e8SDoug Rabson ret = gss_add_oid_set_member(minor_status, &m->elements[i], mechs);
57c19800e8SDoug Rabson if (ret) {
58c19800e8SDoug Rabson gss_release_oid_set(&junk, &m);
59c19800e8SDoug Rabson gss_release_oid_set(&junk, mechs);
60c19800e8SDoug Rabson return ret;
61c19800e8SDoug Rabson }
62c19800e8SDoug Rabson }
63*ae771770SStanislav Sedov gss_release_oid_set(&junk, &m);
64c19800e8SDoug Rabson return ret;
65c19800e8SDoug Rabson }
66c19800e8SDoug Rabson
67c19800e8SDoug Rabson
68c19800e8SDoug Rabson
_gss_spnego_process_context_token(OM_uint32 * minor_status,const gss_ctx_id_t context_handle,const gss_buffer_t token_buffer)69*ae771770SStanislav Sedov OM_uint32 GSSAPI_CALLCONV _gss_spnego_process_context_token
70c19800e8SDoug Rabson (OM_uint32 *minor_status,
71c19800e8SDoug Rabson const gss_ctx_id_t context_handle,
72c19800e8SDoug Rabson const gss_buffer_t token_buffer
73c19800e8SDoug Rabson )
74c19800e8SDoug Rabson {
75c19800e8SDoug Rabson gss_ctx_id_t context ;
76c19800e8SDoug Rabson gssspnego_ctx ctx;
77c19800e8SDoug Rabson OM_uint32 ret;
78c19800e8SDoug Rabson
79c19800e8SDoug Rabson if (context_handle == GSS_C_NO_CONTEXT)
80c19800e8SDoug Rabson return GSS_S_NO_CONTEXT;
81c19800e8SDoug Rabson
82c19800e8SDoug Rabson context = context_handle;
83c19800e8SDoug Rabson ctx = (gssspnego_ctx)context_handle;
84c19800e8SDoug Rabson
85c19800e8SDoug Rabson HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
86c19800e8SDoug Rabson
87c19800e8SDoug Rabson ret = gss_process_context_token(minor_status,
88c19800e8SDoug Rabson ctx->negotiated_ctx_id,
89c19800e8SDoug Rabson token_buffer);
90c19800e8SDoug Rabson if (ret != GSS_S_COMPLETE) {
91c19800e8SDoug Rabson HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
92c19800e8SDoug Rabson return ret;
93c19800e8SDoug Rabson }
94c19800e8SDoug Rabson
95c19800e8SDoug Rabson ctx->negotiated_ctx_id = GSS_C_NO_CONTEXT;
96c19800e8SDoug Rabson
97c19800e8SDoug Rabson return _gss_spnego_internal_delete_sec_context(minor_status,
98c19800e8SDoug Rabson &context,
99c19800e8SDoug Rabson GSS_C_NO_BUFFER);
100c19800e8SDoug Rabson }
101c19800e8SDoug Rabson
_gss_spnego_delete_sec_context(OM_uint32 * minor_status,gss_ctx_id_t * context_handle,gss_buffer_t output_token)102*ae771770SStanislav Sedov OM_uint32 GSSAPI_CALLCONV _gss_spnego_delete_sec_context
103c19800e8SDoug Rabson (OM_uint32 *minor_status,
104c19800e8SDoug Rabson gss_ctx_id_t *context_handle,
105c19800e8SDoug Rabson gss_buffer_t output_token
106c19800e8SDoug Rabson )
107c19800e8SDoug Rabson {
108c19800e8SDoug Rabson gssspnego_ctx ctx;
109c19800e8SDoug Rabson
110c19800e8SDoug Rabson if (context_handle == NULL || *context_handle == GSS_C_NO_CONTEXT)
111c19800e8SDoug Rabson return GSS_S_NO_CONTEXT;
112c19800e8SDoug Rabson
113c19800e8SDoug Rabson ctx = (gssspnego_ctx)*context_handle;
114c19800e8SDoug Rabson
115c19800e8SDoug Rabson HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
116c19800e8SDoug Rabson
117c19800e8SDoug Rabson return _gss_spnego_internal_delete_sec_context(minor_status,
118c19800e8SDoug Rabson context_handle,
119c19800e8SDoug Rabson output_token);
120c19800e8SDoug Rabson }
121c19800e8SDoug Rabson
_gss_spnego_context_time(OM_uint32 * minor_status,const gss_ctx_id_t context_handle,OM_uint32 * time_rec)122*ae771770SStanislav Sedov OM_uint32 GSSAPI_CALLCONV _gss_spnego_context_time
123c19800e8SDoug Rabson (OM_uint32 *minor_status,
124c19800e8SDoug Rabson const gss_ctx_id_t context_handle,
125c19800e8SDoug Rabson OM_uint32 *time_rec
126c19800e8SDoug Rabson )
127c19800e8SDoug Rabson {
128c19800e8SDoug Rabson gssspnego_ctx ctx;
129c19800e8SDoug Rabson *minor_status = 0;
130c19800e8SDoug Rabson
131c19800e8SDoug Rabson if (context_handle == GSS_C_NO_CONTEXT) {
132c19800e8SDoug Rabson return GSS_S_NO_CONTEXT;
133c19800e8SDoug Rabson }
134c19800e8SDoug Rabson
135c19800e8SDoug Rabson ctx = (gssspnego_ctx)context_handle;
136c19800e8SDoug Rabson
137c19800e8SDoug Rabson if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) {
138c19800e8SDoug Rabson return GSS_S_NO_CONTEXT;
139c19800e8SDoug Rabson }
140c19800e8SDoug Rabson
141c19800e8SDoug Rabson return gss_context_time(minor_status,
142c19800e8SDoug Rabson ctx->negotiated_ctx_id,
143c19800e8SDoug Rabson time_rec);
144c19800e8SDoug Rabson }
145c19800e8SDoug Rabson
_gss_spnego_get_mic(OM_uint32 * minor_status,const gss_ctx_id_t context_handle,gss_qop_t qop_req,const gss_buffer_t message_buffer,gss_buffer_t message_token)146*ae771770SStanislav Sedov OM_uint32 GSSAPI_CALLCONV _gss_spnego_get_mic
147c19800e8SDoug Rabson (OM_uint32 *minor_status,
148c19800e8SDoug Rabson const gss_ctx_id_t context_handle,
149c19800e8SDoug Rabson gss_qop_t qop_req,
150c19800e8SDoug Rabson const gss_buffer_t message_buffer,
151c19800e8SDoug Rabson gss_buffer_t message_token
152c19800e8SDoug Rabson )
153c19800e8SDoug Rabson {
154c19800e8SDoug Rabson gssspnego_ctx ctx;
155c19800e8SDoug Rabson
156c19800e8SDoug Rabson *minor_status = 0;
157c19800e8SDoug Rabson
158c19800e8SDoug Rabson if (context_handle == GSS_C_NO_CONTEXT) {
159c19800e8SDoug Rabson return GSS_S_NO_CONTEXT;
160c19800e8SDoug Rabson }
161c19800e8SDoug Rabson
162c19800e8SDoug Rabson ctx = (gssspnego_ctx)context_handle;
163c19800e8SDoug Rabson
164c19800e8SDoug Rabson if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) {
165c19800e8SDoug Rabson return GSS_S_NO_CONTEXT;
166c19800e8SDoug Rabson }
167c19800e8SDoug Rabson
168c19800e8SDoug Rabson return gss_get_mic(minor_status, ctx->negotiated_ctx_id,
169c19800e8SDoug Rabson qop_req, message_buffer, message_token);
170c19800e8SDoug Rabson }
171c19800e8SDoug Rabson
_gss_spnego_verify_mic(OM_uint32 * minor_status,const gss_ctx_id_t context_handle,const gss_buffer_t message_buffer,const gss_buffer_t token_buffer,gss_qop_t * qop_state)172*ae771770SStanislav Sedov OM_uint32 GSSAPI_CALLCONV _gss_spnego_verify_mic
173c19800e8SDoug Rabson (OM_uint32 * minor_status,
174c19800e8SDoug Rabson const gss_ctx_id_t context_handle,
175c19800e8SDoug Rabson const gss_buffer_t message_buffer,
176c19800e8SDoug Rabson const gss_buffer_t token_buffer,
177c19800e8SDoug Rabson gss_qop_t * qop_state
178c19800e8SDoug Rabson )
179c19800e8SDoug Rabson {
180c19800e8SDoug Rabson gssspnego_ctx ctx;
181c19800e8SDoug Rabson
182c19800e8SDoug Rabson *minor_status = 0;
183c19800e8SDoug Rabson
184c19800e8SDoug Rabson if (context_handle == GSS_C_NO_CONTEXT) {
185c19800e8SDoug Rabson return GSS_S_NO_CONTEXT;
186c19800e8SDoug Rabson }
187c19800e8SDoug Rabson
188c19800e8SDoug Rabson ctx = (gssspnego_ctx)context_handle;
189c19800e8SDoug Rabson
190c19800e8SDoug Rabson if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) {
191c19800e8SDoug Rabson return GSS_S_NO_CONTEXT;
192c19800e8SDoug Rabson }
193c19800e8SDoug Rabson
194c19800e8SDoug Rabson return gss_verify_mic(minor_status,
195c19800e8SDoug Rabson ctx->negotiated_ctx_id,
196c19800e8SDoug Rabson message_buffer,
197c19800e8SDoug Rabson token_buffer,
198c19800e8SDoug Rabson qop_state);
199c19800e8SDoug Rabson }
200c19800e8SDoug Rabson
_gss_spnego_wrap(OM_uint32 * minor_status,const gss_ctx_id_t context_handle,int conf_req_flag,gss_qop_t qop_req,const gss_buffer_t input_message_buffer,int * conf_state,gss_buffer_t output_message_buffer)201*ae771770SStanislav Sedov OM_uint32 GSSAPI_CALLCONV _gss_spnego_wrap
202c19800e8SDoug Rabson (OM_uint32 * minor_status,
203c19800e8SDoug Rabson const gss_ctx_id_t context_handle,
204c19800e8SDoug Rabson int conf_req_flag,
205c19800e8SDoug Rabson gss_qop_t qop_req,
206c19800e8SDoug Rabson const gss_buffer_t input_message_buffer,
207c19800e8SDoug Rabson int * conf_state,
208c19800e8SDoug Rabson gss_buffer_t output_message_buffer
209c19800e8SDoug Rabson )
210c19800e8SDoug Rabson {
211c19800e8SDoug Rabson gssspnego_ctx ctx;
212c19800e8SDoug Rabson
213c19800e8SDoug Rabson *minor_status = 0;
214c19800e8SDoug Rabson
215c19800e8SDoug Rabson if (context_handle == GSS_C_NO_CONTEXT) {
216c19800e8SDoug Rabson return GSS_S_NO_CONTEXT;
217c19800e8SDoug Rabson }
218c19800e8SDoug Rabson
219c19800e8SDoug Rabson ctx = (gssspnego_ctx)context_handle;
220c19800e8SDoug Rabson
221c19800e8SDoug Rabson if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) {
222c19800e8SDoug Rabson return GSS_S_NO_CONTEXT;
223c19800e8SDoug Rabson }
224c19800e8SDoug Rabson
225c19800e8SDoug Rabson return gss_wrap(minor_status,
226c19800e8SDoug Rabson ctx->negotiated_ctx_id,
227c19800e8SDoug Rabson conf_req_flag,
228c19800e8SDoug Rabson qop_req,
229c19800e8SDoug Rabson input_message_buffer,
230c19800e8SDoug Rabson conf_state,
231c19800e8SDoug Rabson output_message_buffer);
232c19800e8SDoug Rabson }
233c19800e8SDoug Rabson
_gss_spnego_unwrap(OM_uint32 * minor_status,const gss_ctx_id_t context_handle,const gss_buffer_t input_message_buffer,gss_buffer_t output_message_buffer,int * conf_state,gss_qop_t * qop_state)234*ae771770SStanislav Sedov OM_uint32 GSSAPI_CALLCONV _gss_spnego_unwrap
235c19800e8SDoug Rabson (OM_uint32 * minor_status,
236c19800e8SDoug Rabson const gss_ctx_id_t context_handle,
237c19800e8SDoug Rabson const gss_buffer_t input_message_buffer,
238c19800e8SDoug Rabson gss_buffer_t output_message_buffer,
239c19800e8SDoug Rabson int * conf_state,
240c19800e8SDoug Rabson gss_qop_t * qop_state
241c19800e8SDoug Rabson )
242c19800e8SDoug Rabson {
243c19800e8SDoug Rabson gssspnego_ctx ctx;
244c19800e8SDoug Rabson
245c19800e8SDoug Rabson *minor_status = 0;
246c19800e8SDoug Rabson
247c19800e8SDoug Rabson if (context_handle == GSS_C_NO_CONTEXT) {
248c19800e8SDoug Rabson return GSS_S_NO_CONTEXT;
249c19800e8SDoug Rabson }
250c19800e8SDoug Rabson
251c19800e8SDoug Rabson ctx = (gssspnego_ctx)context_handle;
252c19800e8SDoug Rabson
253c19800e8SDoug Rabson if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) {
254c19800e8SDoug Rabson return GSS_S_NO_CONTEXT;
255c19800e8SDoug Rabson }
256c19800e8SDoug Rabson
257c19800e8SDoug Rabson return gss_unwrap(minor_status,
258c19800e8SDoug Rabson ctx->negotiated_ctx_id,
259c19800e8SDoug Rabson input_message_buffer,
260c19800e8SDoug Rabson output_message_buffer,
261c19800e8SDoug Rabson conf_state,
262c19800e8SDoug Rabson qop_state);
263c19800e8SDoug Rabson }
264c19800e8SDoug Rabson
_gss_spnego_compare_name(OM_uint32 * minor_status,const gss_name_t name1,const gss_name_t name2,int * name_equal)265*ae771770SStanislav Sedov OM_uint32 GSSAPI_CALLCONV _gss_spnego_compare_name
266c19800e8SDoug Rabson (OM_uint32 *minor_status,
267c19800e8SDoug Rabson const gss_name_t name1,
268c19800e8SDoug Rabson const gss_name_t name2,
269c19800e8SDoug Rabson int * name_equal
270c19800e8SDoug Rabson )
271c19800e8SDoug Rabson {
272c19800e8SDoug Rabson spnego_name n1 = (spnego_name)name1;
273c19800e8SDoug Rabson spnego_name n2 = (spnego_name)name2;
274c19800e8SDoug Rabson
275c19800e8SDoug Rabson *name_equal = 0;
276c19800e8SDoug Rabson
277c19800e8SDoug Rabson if (!gss_oid_equal(&n1->type, &n2->type))
278c19800e8SDoug Rabson return GSS_S_COMPLETE;
279c19800e8SDoug Rabson if (n1->value.length != n2->value.length)
280c19800e8SDoug Rabson return GSS_S_COMPLETE;
281c19800e8SDoug Rabson if (memcmp(n1->value.value, n2->value.value, n2->value.length) != 0)
282c19800e8SDoug Rabson return GSS_S_COMPLETE;
283c19800e8SDoug Rabson
284c19800e8SDoug Rabson *name_equal = 1;
285c19800e8SDoug Rabson
286c19800e8SDoug Rabson return GSS_S_COMPLETE;
287c19800e8SDoug Rabson }
288c19800e8SDoug Rabson
_gss_spnego_display_name(OM_uint32 * minor_status,const gss_name_t input_name,gss_buffer_t output_name_buffer,gss_OID * output_name_type)289*ae771770SStanislav Sedov OM_uint32 GSSAPI_CALLCONV _gss_spnego_display_name
290c19800e8SDoug Rabson (OM_uint32 * minor_status,
291c19800e8SDoug Rabson const gss_name_t input_name,
292c19800e8SDoug Rabson gss_buffer_t output_name_buffer,
293c19800e8SDoug Rabson gss_OID * output_name_type
294c19800e8SDoug Rabson )
295c19800e8SDoug Rabson {
296c19800e8SDoug Rabson spnego_name name = (spnego_name)input_name;
297c19800e8SDoug Rabson
298c19800e8SDoug Rabson *minor_status = 0;
299c19800e8SDoug Rabson
300c19800e8SDoug Rabson if (name == NULL || name->mech == GSS_C_NO_NAME)
301c19800e8SDoug Rabson return GSS_S_FAILURE;
302c19800e8SDoug Rabson
303c19800e8SDoug Rabson return gss_display_name(minor_status, name->mech,
304c19800e8SDoug Rabson output_name_buffer, output_name_type);
305c19800e8SDoug Rabson }
306c19800e8SDoug Rabson
_gss_spnego_import_name(OM_uint32 * minor_status,const gss_buffer_t name_buffer,const gss_OID name_type,gss_name_t * output_name)307*ae771770SStanislav Sedov OM_uint32 GSSAPI_CALLCONV _gss_spnego_import_name
308c19800e8SDoug Rabson (OM_uint32 * minor_status,
309c19800e8SDoug Rabson const gss_buffer_t name_buffer,
310c19800e8SDoug Rabson const gss_OID name_type,
311c19800e8SDoug Rabson gss_name_t * output_name
312c19800e8SDoug Rabson )
313c19800e8SDoug Rabson {
314c19800e8SDoug Rabson spnego_name name;
315c19800e8SDoug Rabson OM_uint32 maj_stat;
316c19800e8SDoug Rabson
317c19800e8SDoug Rabson *minor_status = 0;
318c19800e8SDoug Rabson
319c19800e8SDoug Rabson name = calloc(1, sizeof(*name));
320c19800e8SDoug Rabson if (name == NULL) {
321c19800e8SDoug Rabson *minor_status = ENOMEM;
322c19800e8SDoug Rabson return GSS_S_FAILURE;
323c19800e8SDoug Rabson }
324c19800e8SDoug Rabson
325c19800e8SDoug Rabson maj_stat = _gss_copy_oid(minor_status, name_type, &name->type);
326c19800e8SDoug Rabson if (maj_stat) {
327c19800e8SDoug Rabson free(name);
328c19800e8SDoug Rabson return GSS_S_FAILURE;
329c19800e8SDoug Rabson }
330c19800e8SDoug Rabson
331c19800e8SDoug Rabson maj_stat = _gss_copy_buffer(minor_status, name_buffer, &name->value);
332c19800e8SDoug Rabson if (maj_stat) {
333c19800e8SDoug Rabson gss_name_t rname = (gss_name_t)name;
334c19800e8SDoug Rabson _gss_spnego_release_name(minor_status, &rname);
335c19800e8SDoug Rabson return GSS_S_FAILURE;
336c19800e8SDoug Rabson }
337c19800e8SDoug Rabson name->mech = GSS_C_NO_NAME;
338c19800e8SDoug Rabson *output_name = (gss_name_t)name;
339c19800e8SDoug Rabson
340c19800e8SDoug Rabson return GSS_S_COMPLETE;
341c19800e8SDoug Rabson }
342c19800e8SDoug Rabson
_gss_spnego_export_name(OM_uint32 * minor_status,const gss_name_t input_name,gss_buffer_t exported_name)343*ae771770SStanislav Sedov OM_uint32 GSSAPI_CALLCONV _gss_spnego_export_name
344c19800e8SDoug Rabson (OM_uint32 * minor_status,
345c19800e8SDoug Rabson const gss_name_t input_name,
346c19800e8SDoug Rabson gss_buffer_t exported_name
347c19800e8SDoug Rabson )
348c19800e8SDoug Rabson {
349c19800e8SDoug Rabson spnego_name name;
350c19800e8SDoug Rabson *minor_status = 0;
351c19800e8SDoug Rabson
352c19800e8SDoug Rabson if (input_name == GSS_C_NO_NAME)
353c19800e8SDoug Rabson return GSS_S_BAD_NAME;
354c19800e8SDoug Rabson
355c19800e8SDoug Rabson name = (spnego_name)input_name;
356c19800e8SDoug Rabson if (name->mech == GSS_C_NO_NAME)
357c19800e8SDoug Rabson return GSS_S_BAD_NAME;
358c19800e8SDoug Rabson
359c19800e8SDoug Rabson return gss_export_name(minor_status, name->mech, exported_name);
360c19800e8SDoug Rabson }
361c19800e8SDoug Rabson
_gss_spnego_release_name(OM_uint32 * minor_status,gss_name_t * input_name)362*ae771770SStanislav Sedov OM_uint32 GSSAPI_CALLCONV _gss_spnego_release_name
363c19800e8SDoug Rabson (OM_uint32 * minor_status,
364c19800e8SDoug Rabson gss_name_t * input_name
365c19800e8SDoug Rabson )
366c19800e8SDoug Rabson {
367c19800e8SDoug Rabson *minor_status = 0;
368c19800e8SDoug Rabson
369c19800e8SDoug Rabson if (*input_name != GSS_C_NO_NAME) {
370c19800e8SDoug Rabson OM_uint32 junk;
371c19800e8SDoug Rabson spnego_name name = (spnego_name)*input_name;
372c19800e8SDoug Rabson _gss_free_oid(&junk, &name->type);
373c19800e8SDoug Rabson gss_release_buffer(&junk, &name->value);
374c19800e8SDoug Rabson if (name->mech != GSS_C_NO_NAME)
375c19800e8SDoug Rabson gss_release_name(&junk, &name->mech);
376c19800e8SDoug Rabson free(name);
377c19800e8SDoug Rabson
378c19800e8SDoug Rabson *input_name = GSS_C_NO_NAME;
379c19800e8SDoug Rabson }
380c19800e8SDoug Rabson return GSS_S_COMPLETE;
381c19800e8SDoug Rabson }
382c19800e8SDoug Rabson
_gss_spnego_inquire_context(OM_uint32 * minor_status,const gss_ctx_id_t context_handle,gss_name_t * src_name,gss_name_t * targ_name,OM_uint32 * lifetime_rec,gss_OID * mech_type,OM_uint32 * ctx_flags,int * locally_initiated,int * open_context)383*ae771770SStanislav Sedov OM_uint32 GSSAPI_CALLCONV _gss_spnego_inquire_context (
384c19800e8SDoug Rabson OM_uint32 * minor_status,
385c19800e8SDoug Rabson const gss_ctx_id_t context_handle,
386c19800e8SDoug Rabson gss_name_t * src_name,
387c19800e8SDoug Rabson gss_name_t * targ_name,
388c19800e8SDoug Rabson OM_uint32 * lifetime_rec,
389c19800e8SDoug Rabson gss_OID * mech_type,
390c19800e8SDoug Rabson OM_uint32 * ctx_flags,
391c19800e8SDoug Rabson int * locally_initiated,
392c19800e8SDoug Rabson int * open_context
393c19800e8SDoug Rabson )
394c19800e8SDoug Rabson {
395c19800e8SDoug Rabson gssspnego_ctx ctx;
396*ae771770SStanislav Sedov OM_uint32 maj_stat, junk;
397*ae771770SStanislav Sedov gss_name_t src_mn, targ_mn;
398c19800e8SDoug Rabson
399c19800e8SDoug Rabson *minor_status = 0;
400c19800e8SDoug Rabson
401*ae771770SStanislav Sedov if (context_handle == GSS_C_NO_CONTEXT)
402c19800e8SDoug Rabson return GSS_S_NO_CONTEXT;
403c19800e8SDoug Rabson
404c19800e8SDoug Rabson ctx = (gssspnego_ctx)context_handle;
405c19800e8SDoug Rabson
406*ae771770SStanislav Sedov if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT)
407c19800e8SDoug Rabson return GSS_S_NO_CONTEXT;
408c19800e8SDoug Rabson
409*ae771770SStanislav Sedov maj_stat = gss_inquire_context(minor_status,
410c19800e8SDoug Rabson ctx->negotiated_ctx_id,
411*ae771770SStanislav Sedov &src_mn,
412*ae771770SStanislav Sedov &targ_mn,
413c19800e8SDoug Rabson lifetime_rec,
414c19800e8SDoug Rabson mech_type,
415c19800e8SDoug Rabson ctx_flags,
416c19800e8SDoug Rabson locally_initiated,
417c19800e8SDoug Rabson open_context);
418*ae771770SStanislav Sedov if (maj_stat != GSS_S_COMPLETE)
419*ae771770SStanislav Sedov return maj_stat;
420*ae771770SStanislav Sedov
421*ae771770SStanislav Sedov if (src_name) {
422*ae771770SStanislav Sedov spnego_name name = calloc(1, sizeof(*name));
423*ae771770SStanislav Sedov if (name == NULL)
424*ae771770SStanislav Sedov goto enomem;
425*ae771770SStanislav Sedov name->mech = src_mn;
426*ae771770SStanislav Sedov *src_name = (gss_name_t)name;
427*ae771770SStanislav Sedov } else
428*ae771770SStanislav Sedov gss_release_name(&junk, &src_mn);
429*ae771770SStanislav Sedov
430*ae771770SStanislav Sedov if (targ_name) {
431*ae771770SStanislav Sedov spnego_name name = calloc(1, sizeof(*name));
432*ae771770SStanislav Sedov if (name == NULL) {
433*ae771770SStanislav Sedov gss_release_name(minor_status, src_name);
434*ae771770SStanislav Sedov goto enomem;
435*ae771770SStanislav Sedov }
436*ae771770SStanislav Sedov name->mech = targ_mn;
437*ae771770SStanislav Sedov *targ_name = (gss_name_t)name;
438*ae771770SStanislav Sedov } else
439*ae771770SStanislav Sedov gss_release_name(&junk, &targ_mn);
440*ae771770SStanislav Sedov
441*ae771770SStanislav Sedov return GSS_S_COMPLETE;
442*ae771770SStanislav Sedov
443*ae771770SStanislav Sedov enomem:
444*ae771770SStanislav Sedov gss_release_name(&junk, &targ_mn);
445*ae771770SStanislav Sedov gss_release_name(&junk, &src_mn);
446*ae771770SStanislav Sedov *minor_status = ENOMEM;
447*ae771770SStanislav Sedov return GSS_S_FAILURE;
448c19800e8SDoug Rabson }
449c19800e8SDoug Rabson
_gss_spnego_wrap_size_limit(OM_uint32 * minor_status,const gss_ctx_id_t context_handle,int conf_req_flag,gss_qop_t qop_req,OM_uint32 req_output_size,OM_uint32 * max_input_size)450*ae771770SStanislav Sedov OM_uint32 GSSAPI_CALLCONV _gss_spnego_wrap_size_limit (
451c19800e8SDoug Rabson OM_uint32 * minor_status,
452c19800e8SDoug Rabson const gss_ctx_id_t context_handle,
453c19800e8SDoug Rabson int conf_req_flag,
454c19800e8SDoug Rabson gss_qop_t qop_req,
455c19800e8SDoug Rabson OM_uint32 req_output_size,
456c19800e8SDoug Rabson OM_uint32 * max_input_size
457c19800e8SDoug Rabson )
458c19800e8SDoug Rabson {
459c19800e8SDoug Rabson gssspnego_ctx ctx;
460c19800e8SDoug Rabson
461c19800e8SDoug Rabson *minor_status = 0;
462c19800e8SDoug Rabson
463c19800e8SDoug Rabson if (context_handle == GSS_C_NO_CONTEXT) {
464c19800e8SDoug Rabson return GSS_S_NO_CONTEXT;
465c19800e8SDoug Rabson }
466c19800e8SDoug Rabson
467c19800e8SDoug Rabson ctx = (gssspnego_ctx)context_handle;
468c19800e8SDoug Rabson
469c19800e8SDoug Rabson if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) {
470c19800e8SDoug Rabson return GSS_S_NO_CONTEXT;
471c19800e8SDoug Rabson }
472c19800e8SDoug Rabson
473c19800e8SDoug Rabson return gss_wrap_size_limit(minor_status,
474c19800e8SDoug Rabson ctx->negotiated_ctx_id,
475c19800e8SDoug Rabson conf_req_flag,
476c19800e8SDoug Rabson qop_req,
477c19800e8SDoug Rabson req_output_size,
478c19800e8SDoug Rabson max_input_size);
479c19800e8SDoug Rabson }
480c19800e8SDoug Rabson
_gss_spnego_export_sec_context(OM_uint32 * minor_status,gss_ctx_id_t * context_handle,gss_buffer_t interprocess_token)481*ae771770SStanislav Sedov OM_uint32 GSSAPI_CALLCONV _gss_spnego_export_sec_context (
482c19800e8SDoug Rabson OM_uint32 * minor_status,
483c19800e8SDoug Rabson gss_ctx_id_t * context_handle,
484c19800e8SDoug Rabson gss_buffer_t interprocess_token
485c19800e8SDoug Rabson )
486c19800e8SDoug Rabson {
487c19800e8SDoug Rabson gssspnego_ctx ctx;
488c19800e8SDoug Rabson OM_uint32 ret;
489c19800e8SDoug Rabson
490c19800e8SDoug Rabson *minor_status = 0;
491c19800e8SDoug Rabson
492c19800e8SDoug Rabson if (context_handle == NULL) {
493c19800e8SDoug Rabson return GSS_S_NO_CONTEXT;
494c19800e8SDoug Rabson }
495c19800e8SDoug Rabson
496c19800e8SDoug Rabson ctx = (gssspnego_ctx)*context_handle;
497c19800e8SDoug Rabson
498c19800e8SDoug Rabson if (ctx == NULL)
499c19800e8SDoug Rabson return GSS_S_NO_CONTEXT;
500c19800e8SDoug Rabson
501c19800e8SDoug Rabson HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
502c19800e8SDoug Rabson
503c19800e8SDoug Rabson if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) {
504c19800e8SDoug Rabson HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
505c19800e8SDoug Rabson return GSS_S_NO_CONTEXT;
506c19800e8SDoug Rabson }
507c19800e8SDoug Rabson
508c19800e8SDoug Rabson ret = gss_export_sec_context(minor_status,
509c19800e8SDoug Rabson &ctx->negotiated_ctx_id,
510c19800e8SDoug Rabson interprocess_token);
511c19800e8SDoug Rabson if (ret == GSS_S_COMPLETE) {
512c19800e8SDoug Rabson ret = _gss_spnego_internal_delete_sec_context(minor_status,
513c19800e8SDoug Rabson context_handle,
514c19800e8SDoug Rabson GSS_C_NO_BUFFER);
515c19800e8SDoug Rabson if (ret == GSS_S_COMPLETE)
516c19800e8SDoug Rabson return GSS_S_COMPLETE;
517c19800e8SDoug Rabson }
518c19800e8SDoug Rabson
519c19800e8SDoug Rabson HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
520c19800e8SDoug Rabson
521c19800e8SDoug Rabson return ret;
522c19800e8SDoug Rabson }
523c19800e8SDoug Rabson
_gss_spnego_import_sec_context(OM_uint32 * minor_status,const gss_buffer_t interprocess_token,gss_ctx_id_t * context_handle)524*ae771770SStanislav Sedov OM_uint32 GSSAPI_CALLCONV _gss_spnego_import_sec_context (
525c19800e8SDoug Rabson OM_uint32 * minor_status,
526c19800e8SDoug Rabson const gss_buffer_t interprocess_token,
527c19800e8SDoug Rabson gss_ctx_id_t *context_handle
528c19800e8SDoug Rabson )
529c19800e8SDoug Rabson {
530c19800e8SDoug Rabson OM_uint32 ret, minor;
531c19800e8SDoug Rabson gss_ctx_id_t context;
532c19800e8SDoug Rabson gssspnego_ctx ctx;
533c19800e8SDoug Rabson
534c19800e8SDoug Rabson ret = _gss_spnego_alloc_sec_context(minor_status, &context);
535c19800e8SDoug Rabson if (ret != GSS_S_COMPLETE) {
536c19800e8SDoug Rabson return ret;
537c19800e8SDoug Rabson }
538c19800e8SDoug Rabson ctx = (gssspnego_ctx)context;
539c19800e8SDoug Rabson
540c19800e8SDoug Rabson HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
541c19800e8SDoug Rabson
542c19800e8SDoug Rabson ret = gss_import_sec_context(minor_status,
543c19800e8SDoug Rabson interprocess_token,
544c19800e8SDoug Rabson &ctx->negotiated_ctx_id);
545c19800e8SDoug Rabson if (ret != GSS_S_COMPLETE) {
546c19800e8SDoug Rabson _gss_spnego_internal_delete_sec_context(&minor, context_handle, GSS_C_NO_BUFFER);
547c19800e8SDoug Rabson return ret;
548c19800e8SDoug Rabson }
549c19800e8SDoug Rabson
550c19800e8SDoug Rabson ctx->open = 1;
551c19800e8SDoug Rabson /* don't bother filling in the rest of the fields */
552c19800e8SDoug Rabson
553c19800e8SDoug Rabson HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
554c19800e8SDoug Rabson
555c19800e8SDoug Rabson *context_handle = (gss_ctx_id_t)ctx;
556c19800e8SDoug Rabson
557c19800e8SDoug Rabson return GSS_S_COMPLETE;
558c19800e8SDoug Rabson }
559c19800e8SDoug Rabson
_gss_spnego_inquire_names_for_mech(OM_uint32 * minor_status,const gss_OID mechanism,gss_OID_set * name_types)560*ae771770SStanislav Sedov OM_uint32 GSSAPI_CALLCONV _gss_spnego_inquire_names_for_mech (
561c19800e8SDoug Rabson OM_uint32 * minor_status,
562c19800e8SDoug Rabson const gss_OID mechanism,
563c19800e8SDoug Rabson gss_OID_set * name_types
564c19800e8SDoug Rabson )
565c19800e8SDoug Rabson {
566c19800e8SDoug Rabson gss_OID_set mechs, names, n;
567c19800e8SDoug Rabson OM_uint32 ret, junk;
568*ae771770SStanislav Sedov size_t i, j;
569c19800e8SDoug Rabson
570c19800e8SDoug Rabson *name_types = NULL;
571c19800e8SDoug Rabson
572c19800e8SDoug Rabson ret = spnego_supported_mechs(minor_status, &mechs);
573c19800e8SDoug Rabson if (ret != GSS_S_COMPLETE)
574c19800e8SDoug Rabson return ret;
575c19800e8SDoug Rabson
576c19800e8SDoug Rabson ret = gss_create_empty_oid_set(minor_status, &names);
577c19800e8SDoug Rabson if (ret != GSS_S_COMPLETE)
578c19800e8SDoug Rabson goto out;
579c19800e8SDoug Rabson
580c19800e8SDoug Rabson for (i = 0; i < mechs->count; i++) {
581c19800e8SDoug Rabson ret = gss_inquire_names_for_mech(minor_status,
582c19800e8SDoug Rabson &mechs->elements[i],
583c19800e8SDoug Rabson &n);
584c19800e8SDoug Rabson if (ret)
585c19800e8SDoug Rabson continue;
586c19800e8SDoug Rabson
587c19800e8SDoug Rabson for (j = 0; j < n->count; j++)
588c19800e8SDoug Rabson gss_add_oid_set_member(minor_status,
589c19800e8SDoug Rabson &n->elements[j],
590c19800e8SDoug Rabson &names);
591c19800e8SDoug Rabson gss_release_oid_set(&junk, &n);
592c19800e8SDoug Rabson }
593c19800e8SDoug Rabson
594c19800e8SDoug Rabson ret = GSS_S_COMPLETE;
595c19800e8SDoug Rabson *name_types = names;
596c19800e8SDoug Rabson out:
597c19800e8SDoug Rabson
598c19800e8SDoug Rabson gss_release_oid_set(&junk, &mechs);
599c19800e8SDoug Rabson
600*ae771770SStanislav Sedov return ret;
601c19800e8SDoug Rabson }
602c19800e8SDoug Rabson
_gss_spnego_inquire_mechs_for_name(OM_uint32 * minor_status,const gss_name_t input_name,gss_OID_set * mech_types)603*ae771770SStanislav Sedov OM_uint32 GSSAPI_CALLCONV _gss_spnego_inquire_mechs_for_name (
604c19800e8SDoug Rabson OM_uint32 * minor_status,
605c19800e8SDoug Rabson const gss_name_t input_name,
606c19800e8SDoug Rabson gss_OID_set * mech_types
607c19800e8SDoug Rabson )
608c19800e8SDoug Rabson {
609c19800e8SDoug Rabson OM_uint32 ret, junk;
610c19800e8SDoug Rabson
611c19800e8SDoug Rabson ret = gss_create_empty_oid_set(minor_status, mech_types);
612c19800e8SDoug Rabson if (ret)
613c19800e8SDoug Rabson return ret;
614c19800e8SDoug Rabson
615c19800e8SDoug Rabson ret = gss_add_oid_set_member(minor_status,
616c19800e8SDoug Rabson GSS_SPNEGO_MECHANISM,
617c19800e8SDoug Rabson mech_types);
618c19800e8SDoug Rabson if (ret)
619c19800e8SDoug Rabson gss_release_oid_set(&junk, mech_types);
620c19800e8SDoug Rabson
621c19800e8SDoug Rabson return ret;
622c19800e8SDoug Rabson }
623c19800e8SDoug Rabson
_gss_spnego_canonicalize_name(OM_uint32 * minor_status,const gss_name_t input_name,const gss_OID mech_type,gss_name_t * output_name)624*ae771770SStanislav Sedov OM_uint32 GSSAPI_CALLCONV _gss_spnego_canonicalize_name (
625c19800e8SDoug Rabson OM_uint32 * minor_status,
626c19800e8SDoug Rabson const gss_name_t input_name,
627c19800e8SDoug Rabson const gss_OID mech_type,
628c19800e8SDoug Rabson gss_name_t * output_name
629c19800e8SDoug Rabson )
630c19800e8SDoug Rabson {
631c19800e8SDoug Rabson /* XXX */
632c19800e8SDoug Rabson return gss_duplicate_name(minor_status, input_name, output_name);
633c19800e8SDoug Rabson }
634c19800e8SDoug Rabson
_gss_spnego_duplicate_name(OM_uint32 * minor_status,const gss_name_t src_name,gss_name_t * dest_name)635*ae771770SStanislav Sedov OM_uint32 GSSAPI_CALLCONV _gss_spnego_duplicate_name (
636c19800e8SDoug Rabson OM_uint32 * minor_status,
637c19800e8SDoug Rabson const gss_name_t src_name,
638c19800e8SDoug Rabson gss_name_t * dest_name
639c19800e8SDoug Rabson )
640c19800e8SDoug Rabson {
641c19800e8SDoug Rabson return gss_duplicate_name(minor_status, src_name, dest_name);
642c19800e8SDoug Rabson }
643c19800e8SDoug Rabson
644c19800e8SDoug Rabson #if 0
645*ae771770SStanislav Sedov OM_uint32 GSSAPI_CALLCONV
646*ae771770SStanislav Sedov _gss_spnego_wrap_iov(OM_uint32 * minor_status,
647*ae771770SStanislav Sedov gss_ctx_id_t context_handle,
648c19800e8SDoug Rabson int conf_req_flag,
649c19800e8SDoug Rabson gss_qop_t qop_req,
650c19800e8SDoug Rabson int * conf_state,
651*ae771770SStanislav Sedov gss_iov_buffer_desc *iov,
652*ae771770SStanislav Sedov int iov_count)
653c19800e8SDoug Rabson {
654*ae771770SStanislav Sedov gssspnego_ctx ctx = (gssspnego_ctx)context_handle;
655c19800e8SDoug Rabson
656c19800e8SDoug Rabson *minor_status = 0;
657c19800e8SDoug Rabson
658*ae771770SStanislav Sedov if (ctx == NULL || ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT)
659c19800e8SDoug Rabson return GSS_S_NO_CONTEXT;
660*ae771770SStanislav Sedov
661*ae771770SStanislav Sedov return gss_wrap_iov(minor_status, ctx->negotiated_ctx_id,
662*ae771770SStanislav Sedov conf_req_flag, qop_req, conf_state,
663*ae771770SStanislav Sedov iov, iov_count);
664c19800e8SDoug Rabson }
665c19800e8SDoug Rabson
666*ae771770SStanislav Sedov OM_uint32 GSSAPI_CALLCONV
667*ae771770SStanislav Sedov _gss_spnego_unwrap_iov(OM_uint32 *minor_status,
668*ae771770SStanislav Sedov gss_ctx_id_t context_handle,
669*ae771770SStanislav Sedov int *conf_state,
670*ae771770SStanislav Sedov gss_qop_t *qop_state,
671*ae771770SStanislav Sedov gss_iov_buffer_desc *iov,
672*ae771770SStanislav Sedov int iov_count)
673*ae771770SStanislav Sedov {
674*ae771770SStanislav Sedov gssspnego_ctx ctx = (gssspnego_ctx)context_handle;
675c19800e8SDoug Rabson
676*ae771770SStanislav Sedov *minor_status = 0;
677*ae771770SStanislav Sedov
678*ae771770SStanislav Sedov if (ctx == NULL || ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT)
679c19800e8SDoug Rabson return GSS_S_NO_CONTEXT;
680c19800e8SDoug Rabson
681*ae771770SStanislav Sedov return gss_unwrap_iov(minor_status,
682c19800e8SDoug Rabson ctx->negotiated_ctx_id,
683*ae771770SStanislav Sedov conf_state, qop_state,
684*ae771770SStanislav Sedov iov, iov_count);
685c19800e8SDoug Rabson }
686c19800e8SDoug Rabson
687*ae771770SStanislav Sedov OM_uint32 GSSAPI_CALLCONV
688*ae771770SStanislav Sedov _gss_spnego_wrap_iov_length(OM_uint32 * minor_status,
689*ae771770SStanislav Sedov gss_ctx_id_t context_handle,
690*ae771770SStanislav Sedov int conf_req_flag,
691*ae771770SStanislav Sedov gss_qop_t qop_req,
692*ae771770SStanislav Sedov int *conf_state,
693*ae771770SStanislav Sedov gss_iov_buffer_desc *iov,
694*ae771770SStanislav Sedov int iov_count)
695*ae771770SStanislav Sedov {
696*ae771770SStanislav Sedov gssspnego_ctx ctx = (gssspnego_ctx)context_handle;
697*ae771770SStanislav Sedov
698*ae771770SStanislav Sedov *minor_status = 0;
699*ae771770SStanislav Sedov
700*ae771770SStanislav Sedov if (ctx == NULL || ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT)
701*ae771770SStanislav Sedov return GSS_S_NO_CONTEXT;
702*ae771770SStanislav Sedov
703*ae771770SStanislav Sedov return gss_wrap_iov_length(minor_status, ctx->negotiated_ctx_id,
704*ae771770SStanislav Sedov conf_req_flag, qop_req, conf_state,
705*ae771770SStanislav Sedov iov, iov_count);
706*ae771770SStanislav Sedov }
707*ae771770SStanislav Sedov
708*ae771770SStanislav Sedov #endif
709*ae771770SStanislav Sedov
710*ae771770SStanislav Sedov #if 0
711*ae771770SStanislav Sedov OM_uint32 GSSAPI_CALLCONV _gss_spnego_complete_auth_token
712c19800e8SDoug Rabson (OM_uint32 * minor_status,
713c19800e8SDoug Rabson const gss_ctx_id_t context_handle,
714c19800e8SDoug Rabson gss_buffer_t input_message_buffer)
715c19800e8SDoug Rabson {
716c19800e8SDoug Rabson gssspnego_ctx ctx;
717c19800e8SDoug Rabson
718c19800e8SDoug Rabson *minor_status = 0;
719c19800e8SDoug Rabson
720c19800e8SDoug Rabson if (context_handle == GSS_C_NO_CONTEXT) {
721c19800e8SDoug Rabson return GSS_S_NO_CONTEXT;
722c19800e8SDoug Rabson }
723c19800e8SDoug Rabson
724c19800e8SDoug Rabson ctx = (gssspnego_ctx)context_handle;
725c19800e8SDoug Rabson
726c19800e8SDoug Rabson if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) {
727c19800e8SDoug Rabson return GSS_S_NO_CONTEXT;
728c19800e8SDoug Rabson }
729c19800e8SDoug Rabson
730c19800e8SDoug Rabson return gss_complete_auth_token(minor_status,
731c19800e8SDoug Rabson ctx->negotiated_ctx_id,
732c19800e8SDoug Rabson input_message_buffer);
733c19800e8SDoug Rabson }
734c19800e8SDoug Rabson #endif
735c19800e8SDoug Rabson
_gss_spnego_inquire_sec_context_by_oid(OM_uint32 * minor_status,const gss_ctx_id_t context_handle,const gss_OID desired_object,gss_buffer_set_t * data_set)736*ae771770SStanislav Sedov OM_uint32 GSSAPI_CALLCONV _gss_spnego_inquire_sec_context_by_oid
737c19800e8SDoug Rabson (OM_uint32 * minor_status,
738c19800e8SDoug Rabson const gss_ctx_id_t context_handle,
739c19800e8SDoug Rabson const gss_OID desired_object,
740c19800e8SDoug Rabson gss_buffer_set_t *data_set)
741c19800e8SDoug Rabson {
742c19800e8SDoug Rabson gssspnego_ctx ctx;
743c19800e8SDoug Rabson
744c19800e8SDoug Rabson *minor_status = 0;
745c19800e8SDoug Rabson
746c19800e8SDoug Rabson if (context_handle == GSS_C_NO_CONTEXT) {
747c19800e8SDoug Rabson return GSS_S_NO_CONTEXT;
748c19800e8SDoug Rabson }
749c19800e8SDoug Rabson
750c19800e8SDoug Rabson ctx = (gssspnego_ctx)context_handle;
751c19800e8SDoug Rabson
752c19800e8SDoug Rabson if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) {
753c19800e8SDoug Rabson return GSS_S_NO_CONTEXT;
754c19800e8SDoug Rabson }
755c19800e8SDoug Rabson
756c19800e8SDoug Rabson return gss_inquire_sec_context_by_oid(minor_status,
757c19800e8SDoug Rabson ctx->negotiated_ctx_id,
758c19800e8SDoug Rabson desired_object,
759c19800e8SDoug Rabson data_set);
760c19800e8SDoug Rabson }
761c19800e8SDoug Rabson
_gss_spnego_set_sec_context_option(OM_uint32 * minor_status,gss_ctx_id_t * context_handle,const gss_OID desired_object,const gss_buffer_t value)762*ae771770SStanislav Sedov OM_uint32 GSSAPI_CALLCONV _gss_spnego_set_sec_context_option
763c19800e8SDoug Rabson (OM_uint32 * minor_status,
764c19800e8SDoug Rabson gss_ctx_id_t * context_handle,
765c19800e8SDoug Rabson const gss_OID desired_object,
766c19800e8SDoug Rabson const gss_buffer_t value)
767c19800e8SDoug Rabson {
768c19800e8SDoug Rabson gssspnego_ctx ctx;
769c19800e8SDoug Rabson
770c19800e8SDoug Rabson *minor_status = 0;
771c19800e8SDoug Rabson
772c19800e8SDoug Rabson if (context_handle == NULL || *context_handle == GSS_C_NO_CONTEXT) {
773c19800e8SDoug Rabson return GSS_S_NO_CONTEXT;
774c19800e8SDoug Rabson }
775c19800e8SDoug Rabson
776*ae771770SStanislav Sedov ctx = (gssspnego_ctx)*context_handle;
777c19800e8SDoug Rabson
778c19800e8SDoug Rabson if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) {
779c19800e8SDoug Rabson return GSS_S_NO_CONTEXT;
780c19800e8SDoug Rabson }
781c19800e8SDoug Rabson
782c19800e8SDoug Rabson return gss_set_sec_context_option(minor_status,
783c19800e8SDoug Rabson &ctx->negotiated_ctx_id,
784c19800e8SDoug Rabson desired_object,
785c19800e8SDoug Rabson value);
786c19800e8SDoug Rabson }
787c19800e8SDoug Rabson
788*ae771770SStanislav Sedov
789*ae771770SStanislav Sedov OM_uint32 GSSAPI_CALLCONV
_gss_spnego_pseudo_random(OM_uint32 * minor_status,gss_ctx_id_t context_handle,int prf_key,const gss_buffer_t prf_in,ssize_t desired_output_len,gss_buffer_t prf_out)790*ae771770SStanislav Sedov _gss_spnego_pseudo_random(OM_uint32 *minor_status,
791*ae771770SStanislav Sedov gss_ctx_id_t context_handle,
792*ae771770SStanislav Sedov int prf_key,
793*ae771770SStanislav Sedov const gss_buffer_t prf_in,
794*ae771770SStanislav Sedov ssize_t desired_output_len,
795*ae771770SStanislav Sedov gss_buffer_t prf_out)
796*ae771770SStanislav Sedov {
797*ae771770SStanislav Sedov gssspnego_ctx ctx;
798*ae771770SStanislav Sedov
799*ae771770SStanislav Sedov *minor_status = 0;
800*ae771770SStanislav Sedov
801*ae771770SStanislav Sedov if (context_handle == GSS_C_NO_CONTEXT)
802*ae771770SStanislav Sedov return GSS_S_NO_CONTEXT;
803*ae771770SStanislav Sedov
804*ae771770SStanislav Sedov ctx = (gssspnego_ctx)context_handle;
805*ae771770SStanislav Sedov
806*ae771770SStanislav Sedov if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT)
807*ae771770SStanislav Sedov return GSS_S_NO_CONTEXT;
808*ae771770SStanislav Sedov
809*ae771770SStanislav Sedov return gss_pseudo_random(minor_status,
810*ae771770SStanislav Sedov ctx->negotiated_ctx_id,
811*ae771770SStanislav Sedov prf_key,
812*ae771770SStanislav Sedov prf_in,
813*ae771770SStanislav Sedov desired_output_len,
814*ae771770SStanislav Sedov prf_out);
815*ae771770SStanislav Sedov }
816