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