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