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 35RCSID("$Id: context_stubs.c,v 1.1.1.1 2011/06/10 09:34:41 andrew Exp $"); 36 37static OM_uint32 38spnego_supported_mechs(OM_uint32 *minor_status, gss_OID_set *mechs) 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 gss_release_oid_set(&junk, &m); 66 return ret; 67} 68 69 70 71OM_uint32 _gss_spnego_process_context_token 72 (OM_uint32 *minor_status, 73 const gss_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 = 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 104OM_uint32 _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 124OM_uint32 _gss_spnego_context_time 125 (OM_uint32 *minor_status, 126 const gss_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 148OM_uint32 _gss_spnego_get_mic 149 (OM_uint32 *minor_status, 150 const gss_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 174OM_uint32 _gss_spnego_verify_mic 175 (OM_uint32 * minor_status, 176 const gss_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 203OM_uint32 _gss_spnego_wrap 204 (OM_uint32 * minor_status, 205 const gss_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 236OM_uint32 _gss_spnego_unwrap 237 (OM_uint32 * minor_status, 238 const gss_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 267OM_uint32 _gss_spnego_compare_name 268 (OM_uint32 *minor_status, 269 const gss_name_t name1, 270 const gss_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 291OM_uint32 _gss_spnego_display_name 292 (OM_uint32 * minor_status, 293 const gss_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 309OM_uint32 _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 345OM_uint32 _gss_spnego_export_name 346 (OM_uint32 * minor_status, 347 const gss_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 364OM_uint32 _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 385OM_uint32 _gss_spnego_inquire_context ( 386 OM_uint32 * minor_status, 387 const gss_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 445enomem: 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 452OM_uint32 _gss_spnego_wrap_size_limit ( 453 OM_uint32 * minor_status, 454 const gss_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 483OM_uint32 _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 526OM_uint32 _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 ret = _gss_spnego_alloc_sec_context(minor_status, &context); 537 if (ret != GSS_S_COMPLETE) { 538 return ret; 539 } 540 ctx = (gssspnego_ctx)context; 541 542 HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex); 543 544 ret = gss_import_sec_context(minor_status, 545 interprocess_token, 546 &ctx->negotiated_ctx_id); 547 if (ret != GSS_S_COMPLETE) { 548 _gss_spnego_internal_delete_sec_context(&minor, context_handle, GSS_C_NO_BUFFER); 549 return ret; 550 } 551 552 ctx->open = 1; 553 /* don't bother filling in the rest of the fields */ 554 555 HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); 556 557 *context_handle = (gss_ctx_id_t)ctx; 558 559 return GSS_S_COMPLETE; 560} 561 562OM_uint32 _gss_spnego_inquire_names_for_mech ( 563 OM_uint32 * minor_status, 564 const gss_OID mechanism, 565 gss_OID_set * name_types 566 ) 567{ 568 gss_OID_set mechs, names, n; 569 OM_uint32 ret, junk; 570 int i, j; 571 572 *name_types = NULL; 573 574 ret = spnego_supported_mechs(minor_status, &mechs); 575 if (ret != GSS_S_COMPLETE) 576 return ret; 577 578 ret = gss_create_empty_oid_set(minor_status, &names); 579 if (ret != GSS_S_COMPLETE) 580 goto out; 581 582 for (i = 0; i < mechs->count; i++) { 583 ret = gss_inquire_names_for_mech(minor_status, 584 &mechs->elements[i], 585 &n); 586 if (ret) 587 continue; 588 589 for (j = 0; j < n->count; j++) 590 gss_add_oid_set_member(minor_status, 591 &n->elements[j], 592 &names); 593 gss_release_oid_set(&junk, &n); 594 } 595 596 ret = GSS_S_COMPLETE; 597 *name_types = names; 598out: 599 600 gss_release_oid_set(&junk, &mechs); 601 602 return ret; 603} 604 605OM_uint32 _gss_spnego_inquire_mechs_for_name ( 606 OM_uint32 * minor_status, 607 const gss_name_t input_name, 608 gss_OID_set * mech_types 609 ) 610{ 611 OM_uint32 ret, junk; 612 613 ret = gss_create_empty_oid_set(minor_status, mech_types); 614 if (ret) 615 return ret; 616 617 ret = gss_add_oid_set_member(minor_status, 618 GSS_SPNEGO_MECHANISM, 619 mech_types); 620 if (ret) 621 gss_release_oid_set(&junk, mech_types); 622 623 return ret; 624} 625 626OM_uint32 _gss_spnego_canonicalize_name ( 627 OM_uint32 * minor_status, 628 const gss_name_t input_name, 629 const gss_OID mech_type, 630 gss_name_t * output_name 631 ) 632{ 633 /* XXX */ 634 return gss_duplicate_name(minor_status, input_name, output_name); 635} 636 637OM_uint32 _gss_spnego_duplicate_name ( 638 OM_uint32 * minor_status, 639 const gss_name_t src_name, 640 gss_name_t * dest_name 641 ) 642{ 643 return gss_duplicate_name(minor_status, src_name, dest_name); 644} 645 646#if 0 647OM_uint32 _gss_spnego_unwrap_ex 648 (OM_uint32 * minor_status, 649 const gss_ctx_id_t context_handle, 650 const gss_buffer_t token_header_buffer, 651 const gss_buffer_t associated_data_buffer, 652 const gss_buffer_t input_message_buffer, 653 gss_buffer_t output_message_buffer, 654 int * conf_state, 655 gss_qop_t * qop_state) 656{ 657 gssspnego_ctx ctx; 658 659 *minor_status = 0; 660 661 if (context_handle == GSS_C_NO_CONTEXT) { 662 return GSS_S_NO_CONTEXT; 663 } 664 665 ctx = (gssspnego_ctx)context_handle; 666 667 if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) { 668 return GSS_S_NO_CONTEXT; 669 } 670 671 return gss_unwrap_ex(minor_status, 672 ctx->negotiated_ctx_id, 673 token_header_buffer, 674 associated_data_buffer, 675 input_message_buffer, 676 output_message_buffer, 677 conf_state, 678 qop_state); 679} 680 681OM_uint32 _gss_spnego_wrap_ex 682 (OM_uint32 * minor_status, 683 const gss_ctx_id_t context_handle, 684 int conf_req_flag, 685 gss_qop_t qop_req, 686 const gss_buffer_t associated_data_buffer, 687 const gss_buffer_t input_message_buffer, 688 int * conf_state, 689 gss_buffer_t output_token_buffer, 690 gss_buffer_t output_message_buffer 691 ) 692{ 693 gssspnego_ctx ctx; 694 695 *minor_status = 0; 696 697 if (context_handle == GSS_C_NO_CONTEXT) { 698 return GSS_S_NO_CONTEXT; 699 } 700 701 ctx = (gssspnego_ctx)context_handle; 702 703 if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) { 704 return GSS_S_NO_CONTEXT; 705 } 706 707 if ((ctx->mech_flags & GSS_C_DCE_STYLE) == 0 && 708 associated_data_buffer->length != input_message_buffer->length) { 709 *minor_status = EINVAL; 710 return GSS_S_BAD_QOP; 711 } 712 713 return gss_wrap_ex(minor_status, 714 ctx->negotiated_ctx_id, 715 conf_req_flag, 716 qop_req, 717 associated_data_buffer, 718 input_message_buffer, 719 conf_state, 720 output_token_buffer, 721 output_message_buffer); 722} 723 724OM_uint32 _gss_spnego_complete_auth_token 725 (OM_uint32 * minor_status, 726 const gss_ctx_id_t context_handle, 727 gss_buffer_t input_message_buffer) 728{ 729 gssspnego_ctx ctx; 730 731 *minor_status = 0; 732 733 if (context_handle == GSS_C_NO_CONTEXT) { 734 return GSS_S_NO_CONTEXT; 735 } 736 737 ctx = (gssspnego_ctx)context_handle; 738 739 if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) { 740 return GSS_S_NO_CONTEXT; 741 } 742 743 return gss_complete_auth_token(minor_status, 744 ctx->negotiated_ctx_id, 745 input_message_buffer); 746} 747#endif 748 749OM_uint32 _gss_spnego_inquire_sec_context_by_oid 750 (OM_uint32 * minor_status, 751 const gss_ctx_id_t context_handle, 752 const gss_OID desired_object, 753 gss_buffer_set_t *data_set) 754{ 755 gssspnego_ctx ctx; 756 757 *minor_status = 0; 758 759 if (context_handle == GSS_C_NO_CONTEXT) { 760 return GSS_S_NO_CONTEXT; 761 } 762 763 ctx = (gssspnego_ctx)context_handle; 764 765 if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) { 766 return GSS_S_NO_CONTEXT; 767 } 768 769 return gss_inquire_sec_context_by_oid(minor_status, 770 ctx->negotiated_ctx_id, 771 desired_object, 772 data_set); 773} 774 775OM_uint32 _gss_spnego_set_sec_context_option 776 (OM_uint32 * minor_status, 777 gss_ctx_id_t * context_handle, 778 const gss_OID desired_object, 779 const gss_buffer_t value) 780{ 781 gssspnego_ctx ctx; 782 783 *minor_status = 0; 784 785 if (context_handle == NULL || *context_handle == GSS_C_NO_CONTEXT) { 786 return GSS_S_NO_CONTEXT; 787 } 788 789 ctx = (gssspnego_ctx)*context_handle; 790 791 if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) { 792 return GSS_S_NO_CONTEXT; 793 } 794 795 return gss_set_sec_context_option(minor_status, 796 &ctx->negotiated_ctx_id, 797 desired_object, 798 value); 799} 800 801 802OM_uint32 803_gss_spnego_pseudo_random(OM_uint32 *minor_status, 804 gss_ctx_id_t context_handle, 805 int prf_key, 806 const gss_buffer_t prf_in, 807 ssize_t desired_output_len, 808 gss_buffer_t prf_out) 809{ 810 gssspnego_ctx ctx; 811 812 *minor_status = 0; 813 814 if (context_handle == GSS_C_NO_CONTEXT) 815 return GSS_S_NO_CONTEXT; 816 817 ctx = (gssspnego_ctx)context_handle; 818 819 if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) 820 return GSS_S_NO_CONTEXT; 821 822 return gss_pseudo_random(minor_status, 823 ctx->negotiated_ctx_id, 824 prf_key, 825 prf_in, 826 desired_output_len, 827 prf_out); 828} 829