xref: /freebsd-src/crypto/heimdal/lib/gssapi/spnego/context_stubs.c (revision 6a068746777241722b2b32c5d0bc443a2a64d80b)
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