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_locl.h"
34
35 static OM_uint32
spnego_supported_mechs(OM_uint32 * minor_status,gss_OID_set * mechs)36 spnego_supported_mechs(OM_uint32 *minor_status, gss_OID_set *mechs)
37 {
38 OM_uint32 ret, junk;
39 gss_OID_set m;
40 size_t i;
41
42 ret = gss_indicate_mechs(minor_status, &m);
43 if (ret != GSS_S_COMPLETE)
44 return ret;
45
46 ret = gss_create_empty_oid_set(minor_status, mechs);
47 if (ret != GSS_S_COMPLETE) {
48 gss_release_oid_set(&junk, &m);
49 return ret;
50 }
51
52 for (i = 0; i < m->count; i++) {
53 if (gss_oid_equal(&m->elements[i], GSS_SPNEGO_MECHANISM))
54 continue;
55
56 ret = gss_add_oid_set_member(minor_status, &m->elements[i], mechs);
57 if (ret) {
58 gss_release_oid_set(&junk, &m);
59 gss_release_oid_set(&junk, mechs);
60 return ret;
61 }
62 }
63 gss_release_oid_set(&junk, &m);
64 return ret;
65 }
66
67
68
_gss_spnego_process_context_token(OM_uint32 * minor_status,const gss_ctx_id_t context_handle,const gss_buffer_t token_buffer)69 OM_uint32 GSSAPI_CALLCONV _gss_spnego_process_context_token
70 (OM_uint32 *minor_status,
71 const gss_ctx_id_t context_handle,
72 const gss_buffer_t token_buffer
73 )
74 {
75 gss_ctx_id_t context ;
76 gssspnego_ctx ctx;
77 OM_uint32 ret;
78
79 if (context_handle == GSS_C_NO_CONTEXT)
80 return GSS_S_NO_CONTEXT;
81
82 context = context_handle;
83 ctx = (gssspnego_ctx)context_handle;
84
85 HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
86
87 ret = gss_process_context_token(minor_status,
88 ctx->negotiated_ctx_id,
89 token_buffer);
90 if (ret != GSS_S_COMPLETE) {
91 HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
92 return ret;
93 }
94
95 ctx->negotiated_ctx_id = GSS_C_NO_CONTEXT;
96
97 return _gss_spnego_internal_delete_sec_context(minor_status,
98 &context,
99 GSS_C_NO_BUFFER);
100 }
101
_gss_spnego_delete_sec_context(OM_uint32 * minor_status,gss_ctx_id_t * context_handle,gss_buffer_t output_token)102 OM_uint32 GSSAPI_CALLCONV _gss_spnego_delete_sec_context
103 (OM_uint32 *minor_status,
104 gss_ctx_id_t *context_handle,
105 gss_buffer_t output_token
106 )
107 {
108 gssspnego_ctx ctx;
109
110 if (context_handle == NULL || *context_handle == GSS_C_NO_CONTEXT)
111 return GSS_S_NO_CONTEXT;
112
113 ctx = (gssspnego_ctx)*context_handle;
114
115 HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
116
117 return _gss_spnego_internal_delete_sec_context(minor_status,
118 context_handle,
119 output_token);
120 }
121
_gss_spnego_context_time(OM_uint32 * minor_status,const gss_ctx_id_t context_handle,OM_uint32 * time_rec)122 OM_uint32 GSSAPI_CALLCONV _gss_spnego_context_time
123 (OM_uint32 *minor_status,
124 const gss_ctx_id_t context_handle,
125 OM_uint32 *time_rec
126 )
127 {
128 gssspnego_ctx ctx;
129 *minor_status = 0;
130
131 if (context_handle == GSS_C_NO_CONTEXT) {
132 return GSS_S_NO_CONTEXT;
133 }
134
135 ctx = (gssspnego_ctx)context_handle;
136
137 if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) {
138 return GSS_S_NO_CONTEXT;
139 }
140
141 return gss_context_time(minor_status,
142 ctx->negotiated_ctx_id,
143 time_rec);
144 }
145
_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 OM_uint32 GSSAPI_CALLCONV _gss_spnego_get_mic
147 (OM_uint32 *minor_status,
148 const gss_ctx_id_t context_handle,
149 gss_qop_t qop_req,
150 const gss_buffer_t message_buffer,
151 gss_buffer_t message_token
152 )
153 {
154 gssspnego_ctx ctx;
155
156 *minor_status = 0;
157
158 if (context_handle == GSS_C_NO_CONTEXT) {
159 return GSS_S_NO_CONTEXT;
160 }
161
162 ctx = (gssspnego_ctx)context_handle;
163
164 if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) {
165 return GSS_S_NO_CONTEXT;
166 }
167
168 return gss_get_mic(minor_status, ctx->negotiated_ctx_id,
169 qop_req, message_buffer, message_token);
170 }
171
_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 OM_uint32 GSSAPI_CALLCONV _gss_spnego_verify_mic
173 (OM_uint32 * minor_status,
174 const gss_ctx_id_t context_handle,
175 const gss_buffer_t message_buffer,
176 const gss_buffer_t token_buffer,
177 gss_qop_t * qop_state
178 )
179 {
180 gssspnego_ctx ctx;
181
182 *minor_status = 0;
183
184 if (context_handle == GSS_C_NO_CONTEXT) {
185 return GSS_S_NO_CONTEXT;
186 }
187
188 ctx = (gssspnego_ctx)context_handle;
189
190 if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) {
191 return GSS_S_NO_CONTEXT;
192 }
193
194 return gss_verify_mic(minor_status,
195 ctx->negotiated_ctx_id,
196 message_buffer,
197 token_buffer,
198 qop_state);
199 }
200
_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 OM_uint32 GSSAPI_CALLCONV _gss_spnego_wrap
202 (OM_uint32 * minor_status,
203 const gss_ctx_id_t context_handle,
204 int conf_req_flag,
205 gss_qop_t qop_req,
206 const gss_buffer_t input_message_buffer,
207 int * conf_state,
208 gss_buffer_t output_message_buffer
209 )
210 {
211 gssspnego_ctx ctx;
212
213 *minor_status = 0;
214
215 if (context_handle == GSS_C_NO_CONTEXT) {
216 return GSS_S_NO_CONTEXT;
217 }
218
219 ctx = (gssspnego_ctx)context_handle;
220
221 if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) {
222 return GSS_S_NO_CONTEXT;
223 }
224
225 return gss_wrap(minor_status,
226 ctx->negotiated_ctx_id,
227 conf_req_flag,
228 qop_req,
229 input_message_buffer,
230 conf_state,
231 output_message_buffer);
232 }
233
_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 OM_uint32 GSSAPI_CALLCONV _gss_spnego_unwrap
235 (OM_uint32 * minor_status,
236 const gss_ctx_id_t context_handle,
237 const gss_buffer_t input_message_buffer,
238 gss_buffer_t output_message_buffer,
239 int * conf_state,
240 gss_qop_t * qop_state
241 )
242 {
243 gssspnego_ctx ctx;
244
245 *minor_status = 0;
246
247 if (context_handle == GSS_C_NO_CONTEXT) {
248 return GSS_S_NO_CONTEXT;
249 }
250
251 ctx = (gssspnego_ctx)context_handle;
252
253 if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) {
254 return GSS_S_NO_CONTEXT;
255 }
256
257 return gss_unwrap(minor_status,
258 ctx->negotiated_ctx_id,
259 input_message_buffer,
260 output_message_buffer,
261 conf_state,
262 qop_state);
263 }
264
_gss_spnego_compare_name(OM_uint32 * minor_status,const gss_name_t name1,const gss_name_t name2,int * name_equal)265 OM_uint32 GSSAPI_CALLCONV _gss_spnego_compare_name
266 (OM_uint32 *minor_status,
267 const gss_name_t name1,
268 const gss_name_t name2,
269 int * name_equal
270 )
271 {
272 spnego_name n1 = (spnego_name)name1;
273 spnego_name n2 = (spnego_name)name2;
274
275 *name_equal = 0;
276
277 if (!gss_oid_equal(&n1->type, &n2->type))
278 return GSS_S_COMPLETE;
279 if (n1->value.length != n2->value.length)
280 return GSS_S_COMPLETE;
281 if (memcmp(n1->value.value, n2->value.value, n2->value.length) != 0)
282 return GSS_S_COMPLETE;
283
284 *name_equal = 1;
285
286 return GSS_S_COMPLETE;
287 }
288
_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 OM_uint32 GSSAPI_CALLCONV _gss_spnego_display_name
290 (OM_uint32 * minor_status,
291 const gss_name_t input_name,
292 gss_buffer_t output_name_buffer,
293 gss_OID * output_name_type
294 )
295 {
296 spnego_name name = (spnego_name)input_name;
297
298 *minor_status = 0;
299
300 if (name == NULL || name->mech == GSS_C_NO_NAME)
301 return GSS_S_FAILURE;
302
303 return gss_display_name(minor_status, name->mech,
304 output_name_buffer, output_name_type);
305 }
306
_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 OM_uint32 GSSAPI_CALLCONV _gss_spnego_import_name
308 (OM_uint32 * minor_status,
309 const gss_buffer_t name_buffer,
310 const gss_OID name_type,
311 gss_name_t * output_name
312 )
313 {
314 spnego_name name;
315 OM_uint32 maj_stat;
316
317 *minor_status = 0;
318
319 name = calloc(1, sizeof(*name));
320 if (name == NULL) {
321 *minor_status = ENOMEM;
322 return GSS_S_FAILURE;
323 }
324
325 maj_stat = _gss_copy_oid(minor_status, name_type, &name->type);
326 if (maj_stat) {
327 free(name);
328 return GSS_S_FAILURE;
329 }
330
331 maj_stat = _gss_copy_buffer(minor_status, name_buffer, &name->value);
332 if (maj_stat) {
333 gss_name_t rname = (gss_name_t)name;
334 _gss_spnego_release_name(minor_status, &rname);
335 return GSS_S_FAILURE;
336 }
337 name->mech = GSS_C_NO_NAME;
338 *output_name = (gss_name_t)name;
339
340 return GSS_S_COMPLETE;
341 }
342
_gss_spnego_export_name(OM_uint32 * minor_status,const gss_name_t input_name,gss_buffer_t exported_name)343 OM_uint32 GSSAPI_CALLCONV _gss_spnego_export_name
344 (OM_uint32 * minor_status,
345 const gss_name_t input_name,
346 gss_buffer_t exported_name
347 )
348 {
349 spnego_name name;
350 *minor_status = 0;
351
352 if (input_name == GSS_C_NO_NAME)
353 return GSS_S_BAD_NAME;
354
355 name = (spnego_name)input_name;
356 if (name->mech == GSS_C_NO_NAME)
357 return GSS_S_BAD_NAME;
358
359 return gss_export_name(minor_status, name->mech, exported_name);
360 }
361
_gss_spnego_release_name(OM_uint32 * minor_status,gss_name_t * input_name)362 OM_uint32 GSSAPI_CALLCONV _gss_spnego_release_name
363 (OM_uint32 * minor_status,
364 gss_name_t * input_name
365 )
366 {
367 *minor_status = 0;
368
369 if (*input_name != GSS_C_NO_NAME) {
370 OM_uint32 junk;
371 spnego_name name = (spnego_name)*input_name;
372 _gss_free_oid(&junk, &name->type);
373 gss_release_buffer(&junk, &name->value);
374 if (name->mech != GSS_C_NO_NAME)
375 gss_release_name(&junk, &name->mech);
376 free(name);
377
378 *input_name = GSS_C_NO_NAME;
379 }
380 return GSS_S_COMPLETE;
381 }
382
_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 OM_uint32 GSSAPI_CALLCONV _gss_spnego_inquire_context (
384 OM_uint32 * minor_status,
385 const gss_ctx_id_t context_handle,
386 gss_name_t * src_name,
387 gss_name_t * targ_name,
388 OM_uint32 * lifetime_rec,
389 gss_OID * mech_type,
390 OM_uint32 * ctx_flags,
391 int * locally_initiated,
392 int * open_context
393 )
394 {
395 gssspnego_ctx ctx;
396 OM_uint32 maj_stat, junk;
397 gss_name_t src_mn, targ_mn;
398
399 *minor_status = 0;
400
401 if (context_handle == GSS_C_NO_CONTEXT)
402 return GSS_S_NO_CONTEXT;
403
404 ctx = (gssspnego_ctx)context_handle;
405
406 if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT)
407 return GSS_S_NO_CONTEXT;
408
409 maj_stat = gss_inquire_context(minor_status,
410 ctx->negotiated_ctx_id,
411 &src_mn,
412 &targ_mn,
413 lifetime_rec,
414 mech_type,
415 ctx_flags,
416 locally_initiated,
417 open_context);
418 if (maj_stat != GSS_S_COMPLETE)
419 return maj_stat;
420
421 if (src_name) {
422 spnego_name name = calloc(1, sizeof(*name));
423 if (name == NULL)
424 goto enomem;
425 name->mech = src_mn;
426 *src_name = (gss_name_t)name;
427 } else
428 gss_release_name(&junk, &src_mn);
429
430 if (targ_name) {
431 spnego_name name = calloc(1, sizeof(*name));
432 if (name == NULL) {
433 gss_release_name(minor_status, src_name);
434 goto enomem;
435 }
436 name->mech = targ_mn;
437 *targ_name = (gss_name_t)name;
438 } else
439 gss_release_name(&junk, &targ_mn);
440
441 return GSS_S_COMPLETE;
442
443 enomem:
444 gss_release_name(&junk, &targ_mn);
445 gss_release_name(&junk, &src_mn);
446 *minor_status = ENOMEM;
447 return GSS_S_FAILURE;
448 }
449
_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 OM_uint32 GSSAPI_CALLCONV _gss_spnego_wrap_size_limit (
451 OM_uint32 * minor_status,
452 const gss_ctx_id_t context_handle,
453 int conf_req_flag,
454 gss_qop_t qop_req,
455 OM_uint32 req_output_size,
456 OM_uint32 * max_input_size
457 )
458 {
459 gssspnego_ctx ctx;
460
461 *minor_status = 0;
462
463 if (context_handle == GSS_C_NO_CONTEXT) {
464 return GSS_S_NO_CONTEXT;
465 }
466
467 ctx = (gssspnego_ctx)context_handle;
468
469 if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) {
470 return GSS_S_NO_CONTEXT;
471 }
472
473 return gss_wrap_size_limit(minor_status,
474 ctx->negotiated_ctx_id,
475 conf_req_flag,
476 qop_req,
477 req_output_size,
478 max_input_size);
479 }
480
_gss_spnego_export_sec_context(OM_uint32 * minor_status,gss_ctx_id_t * context_handle,gss_buffer_t interprocess_token)481 OM_uint32 GSSAPI_CALLCONV _gss_spnego_export_sec_context (
482 OM_uint32 * minor_status,
483 gss_ctx_id_t * context_handle,
484 gss_buffer_t interprocess_token
485 )
486 {
487 gssspnego_ctx ctx;
488 OM_uint32 ret;
489
490 *minor_status = 0;
491
492 if (context_handle == NULL) {
493 return GSS_S_NO_CONTEXT;
494 }
495
496 ctx = (gssspnego_ctx)*context_handle;
497
498 if (ctx == NULL)
499 return GSS_S_NO_CONTEXT;
500
501 HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
502
503 if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) {
504 HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
505 return GSS_S_NO_CONTEXT;
506 }
507
508 ret = gss_export_sec_context(minor_status,
509 &ctx->negotiated_ctx_id,
510 interprocess_token);
511 if (ret == GSS_S_COMPLETE) {
512 ret = _gss_spnego_internal_delete_sec_context(minor_status,
513 context_handle,
514 GSS_C_NO_BUFFER);
515 if (ret == GSS_S_COMPLETE)
516 return GSS_S_COMPLETE;
517 }
518
519 HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
520
521 return ret;
522 }
523
_gss_spnego_import_sec_context(OM_uint32 * minor_status,const gss_buffer_t interprocess_token,gss_ctx_id_t * context_handle)524 OM_uint32 GSSAPI_CALLCONV _gss_spnego_import_sec_context (
525 OM_uint32 * minor_status,
526 const gss_buffer_t interprocess_token,
527 gss_ctx_id_t *context_handle
528 )
529 {
530 OM_uint32 ret, minor;
531 gss_ctx_id_t context;
532 gssspnego_ctx ctx;
533
534 ret = _gss_spnego_alloc_sec_context(minor_status, &context);
535 if (ret != GSS_S_COMPLETE) {
536 return ret;
537 }
538 ctx = (gssspnego_ctx)context;
539
540 HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
541
542 ret = gss_import_sec_context(minor_status,
543 interprocess_token,
544 &ctx->negotiated_ctx_id);
545 if (ret != GSS_S_COMPLETE) {
546 _gss_spnego_internal_delete_sec_context(&minor, context_handle, GSS_C_NO_BUFFER);
547 return ret;
548 }
549
550 ctx->open = 1;
551 /* don't bother filling in the rest of the fields */
552
553 HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
554
555 *context_handle = (gss_ctx_id_t)ctx;
556
557 return GSS_S_COMPLETE;
558 }
559
_gss_spnego_inquire_names_for_mech(OM_uint32 * minor_status,const gss_OID mechanism,gss_OID_set * name_types)560 OM_uint32 GSSAPI_CALLCONV _gss_spnego_inquire_names_for_mech (
561 OM_uint32 * minor_status,
562 const gss_OID mechanism,
563 gss_OID_set * name_types
564 )
565 {
566 gss_OID_set mechs, names, n;
567 OM_uint32 ret, junk;
568 size_t i, j;
569
570 *name_types = NULL;
571
572 ret = spnego_supported_mechs(minor_status, &mechs);
573 if (ret != GSS_S_COMPLETE)
574 return ret;
575
576 ret = gss_create_empty_oid_set(minor_status, &names);
577 if (ret != GSS_S_COMPLETE)
578 goto out;
579
580 for (i = 0; i < mechs->count; i++) {
581 ret = gss_inquire_names_for_mech(minor_status,
582 &mechs->elements[i],
583 &n);
584 if (ret)
585 continue;
586
587 for (j = 0; j < n->count; j++)
588 gss_add_oid_set_member(minor_status,
589 &n->elements[j],
590 &names);
591 gss_release_oid_set(&junk, &n);
592 }
593
594 ret = GSS_S_COMPLETE;
595 *name_types = names;
596 out:
597
598 gss_release_oid_set(&junk, &mechs);
599
600 return ret;
601 }
602
_gss_spnego_inquire_mechs_for_name(OM_uint32 * minor_status,const gss_name_t input_name,gss_OID_set * mech_types)603 OM_uint32 GSSAPI_CALLCONV _gss_spnego_inquire_mechs_for_name (
604 OM_uint32 * minor_status,
605 const gss_name_t input_name,
606 gss_OID_set * mech_types
607 )
608 {
609 OM_uint32 ret, junk;
610
611 ret = gss_create_empty_oid_set(minor_status, mech_types);
612 if (ret)
613 return ret;
614
615 ret = gss_add_oid_set_member(minor_status,
616 GSS_SPNEGO_MECHANISM,
617 mech_types);
618 if (ret)
619 gss_release_oid_set(&junk, mech_types);
620
621 return ret;
622 }
623
_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 OM_uint32 GSSAPI_CALLCONV _gss_spnego_canonicalize_name (
625 OM_uint32 * minor_status,
626 const gss_name_t input_name,
627 const gss_OID mech_type,
628 gss_name_t * output_name
629 )
630 {
631 /* XXX */
632 return gss_duplicate_name(minor_status, input_name, output_name);
633 }
634
_gss_spnego_duplicate_name(OM_uint32 * minor_status,const gss_name_t src_name,gss_name_t * dest_name)635 OM_uint32 GSSAPI_CALLCONV _gss_spnego_duplicate_name (
636 OM_uint32 * minor_status,
637 const gss_name_t src_name,
638 gss_name_t * dest_name
639 )
640 {
641 return gss_duplicate_name(minor_status, src_name, dest_name);
642 }
643
644 #if 0
645 OM_uint32 GSSAPI_CALLCONV
646 _gss_spnego_wrap_iov(OM_uint32 * minor_status,
647 gss_ctx_id_t context_handle,
648 int conf_req_flag,
649 gss_qop_t qop_req,
650 int * conf_state,
651 gss_iov_buffer_desc *iov,
652 int iov_count)
653 {
654 gssspnego_ctx ctx = (gssspnego_ctx)context_handle;
655
656 *minor_status = 0;
657
658 if (ctx == NULL || ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT)
659 return GSS_S_NO_CONTEXT;
660
661 return gss_wrap_iov(minor_status, ctx->negotiated_ctx_id,
662 conf_req_flag, qop_req, conf_state,
663 iov, iov_count);
664 }
665
666 OM_uint32 GSSAPI_CALLCONV
667 _gss_spnego_unwrap_iov(OM_uint32 *minor_status,
668 gss_ctx_id_t context_handle,
669 int *conf_state,
670 gss_qop_t *qop_state,
671 gss_iov_buffer_desc *iov,
672 int iov_count)
673 {
674 gssspnego_ctx ctx = (gssspnego_ctx)context_handle;
675
676 *minor_status = 0;
677
678 if (ctx == NULL || ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT)
679 return GSS_S_NO_CONTEXT;
680
681 return gss_unwrap_iov(minor_status,
682 ctx->negotiated_ctx_id,
683 conf_state, qop_state,
684 iov, iov_count);
685 }
686
687 OM_uint32 GSSAPI_CALLCONV
688 _gss_spnego_wrap_iov_length(OM_uint32 * minor_status,
689 gss_ctx_id_t context_handle,
690 int conf_req_flag,
691 gss_qop_t qop_req,
692 int *conf_state,
693 gss_iov_buffer_desc *iov,
694 int iov_count)
695 {
696 gssspnego_ctx ctx = (gssspnego_ctx)context_handle;
697
698 *minor_status = 0;
699
700 if (ctx == NULL || ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT)
701 return GSS_S_NO_CONTEXT;
702
703 return gss_wrap_iov_length(minor_status, ctx->negotiated_ctx_id,
704 conf_req_flag, qop_req, conf_state,
705 iov, iov_count);
706 }
707
708 #endif
709
710 #if 0
711 OM_uint32 GSSAPI_CALLCONV _gss_spnego_complete_auth_token
712 (OM_uint32 * minor_status,
713 const gss_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,const gss_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 const gss_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