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: context_stubs.c 21035 2007-06-09 15:32:47Z lha $"); 36 37 static OM_uint32 38 spnego_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 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_display_status 267 (OM_uint32 * minor_status, 268 OM_uint32 status_value, 269 int status_type, 270 const gss_OID mech_type, 271 OM_uint32 * message_context, 272 gss_buffer_t status_string 273 ) 274 { 275 return GSS_S_FAILURE; 276 } 277 278 OM_uint32 _gss_spnego_compare_name 279 (OM_uint32 *minor_status, 280 const gss_name_t name1, 281 const gss_name_t name2, 282 int * name_equal 283 ) 284 { 285 spnego_name n1 = (spnego_name)name1; 286 spnego_name n2 = (spnego_name)name2; 287 288 *name_equal = 0; 289 290 if (!gss_oid_equal(&n1->type, &n2->type)) 291 return GSS_S_COMPLETE; 292 if (n1->value.length != n2->value.length) 293 return GSS_S_COMPLETE; 294 if (memcmp(n1->value.value, n2->value.value, n2->value.length) != 0) 295 return GSS_S_COMPLETE; 296 297 *name_equal = 1; 298 299 return GSS_S_COMPLETE; 300 } 301 302 OM_uint32 _gss_spnego_display_name 303 (OM_uint32 * minor_status, 304 const gss_name_t input_name, 305 gss_buffer_t output_name_buffer, 306 gss_OID * output_name_type 307 ) 308 { 309 spnego_name name = (spnego_name)input_name; 310 311 *minor_status = 0; 312 313 if (name == NULL || name->mech == GSS_C_NO_NAME) 314 return GSS_S_FAILURE; 315 316 return gss_display_name(minor_status, name->mech, 317 output_name_buffer, output_name_type); 318 } 319 320 OM_uint32 _gss_spnego_import_name 321 (OM_uint32 * minor_status, 322 const gss_buffer_t name_buffer, 323 const gss_OID name_type, 324 gss_name_t * output_name 325 ) 326 { 327 spnego_name name; 328 OM_uint32 maj_stat; 329 330 *minor_status = 0; 331 332 name = calloc(1, sizeof(*name)); 333 if (name == NULL) { 334 *minor_status = ENOMEM; 335 return GSS_S_FAILURE; 336 } 337 338 maj_stat = _gss_copy_oid(minor_status, name_type, &name->type); 339 if (maj_stat) { 340 free(name); 341 return GSS_S_FAILURE; 342 } 343 344 maj_stat = _gss_copy_buffer(minor_status, name_buffer, &name->value); 345 if (maj_stat) { 346 gss_name_t rname = (gss_name_t)name; 347 _gss_spnego_release_name(minor_status, &rname); 348 return GSS_S_FAILURE; 349 } 350 name->mech = GSS_C_NO_NAME; 351 *output_name = (gss_name_t)name; 352 353 return GSS_S_COMPLETE; 354 } 355 356 OM_uint32 _gss_spnego_export_name 357 (OM_uint32 * minor_status, 358 const gss_name_t input_name, 359 gss_buffer_t exported_name 360 ) 361 { 362 spnego_name name; 363 *minor_status = 0; 364 365 if (input_name == GSS_C_NO_NAME) 366 return GSS_S_BAD_NAME; 367 368 name = (spnego_name)input_name; 369 if (name->mech == GSS_C_NO_NAME) 370 return GSS_S_BAD_NAME; 371 372 return gss_export_name(minor_status, name->mech, exported_name); 373 } 374 375 OM_uint32 _gss_spnego_release_name 376 (OM_uint32 * minor_status, 377 gss_name_t * input_name 378 ) 379 { 380 *minor_status = 0; 381 382 if (*input_name != GSS_C_NO_NAME) { 383 OM_uint32 junk; 384 spnego_name name = (spnego_name)*input_name; 385 _gss_free_oid(&junk, &name->type); 386 gss_release_buffer(&junk, &name->value); 387 if (name->mech != GSS_C_NO_NAME) 388 gss_release_name(&junk, &name->mech); 389 free(name); 390 391 *input_name = GSS_C_NO_NAME; 392 } 393 return GSS_S_COMPLETE; 394 } 395 396 OM_uint32 _gss_spnego_inquire_context ( 397 OM_uint32 * minor_status, 398 const gss_ctx_id_t context_handle, 399 gss_name_t * src_name, 400 gss_name_t * targ_name, 401 OM_uint32 * lifetime_rec, 402 gss_OID * mech_type, 403 OM_uint32 * ctx_flags, 404 int * locally_initiated, 405 int * open_context 406 ) 407 { 408 gssspnego_ctx ctx; 409 410 *minor_status = 0; 411 412 if (context_handle == GSS_C_NO_CONTEXT) { 413 return GSS_S_NO_CONTEXT; 414 } 415 416 ctx = (gssspnego_ctx)context_handle; 417 418 if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) { 419 return GSS_S_NO_CONTEXT; 420 } 421 422 return gss_inquire_context(minor_status, 423 ctx->negotiated_ctx_id, 424 src_name, 425 targ_name, 426 lifetime_rec, 427 mech_type, 428 ctx_flags, 429 locally_initiated, 430 open_context); 431 } 432 433 OM_uint32 _gss_spnego_wrap_size_limit ( 434 OM_uint32 * minor_status, 435 const gss_ctx_id_t context_handle, 436 int conf_req_flag, 437 gss_qop_t qop_req, 438 OM_uint32 req_output_size, 439 OM_uint32 * max_input_size 440 ) 441 { 442 gssspnego_ctx ctx; 443 444 *minor_status = 0; 445 446 if (context_handle == GSS_C_NO_CONTEXT) { 447 return GSS_S_NO_CONTEXT; 448 } 449 450 ctx = (gssspnego_ctx)context_handle; 451 452 if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) { 453 return GSS_S_NO_CONTEXT; 454 } 455 456 return gss_wrap_size_limit(minor_status, 457 ctx->negotiated_ctx_id, 458 conf_req_flag, 459 qop_req, 460 req_output_size, 461 max_input_size); 462 } 463 464 OM_uint32 _gss_spnego_export_sec_context ( 465 OM_uint32 * minor_status, 466 gss_ctx_id_t * context_handle, 467 gss_buffer_t interprocess_token 468 ) 469 { 470 gssspnego_ctx ctx; 471 OM_uint32 ret; 472 473 *minor_status = 0; 474 475 if (context_handle == NULL) { 476 return GSS_S_NO_CONTEXT; 477 } 478 479 ctx = (gssspnego_ctx)*context_handle; 480 481 if (ctx == NULL) 482 return GSS_S_NO_CONTEXT; 483 484 HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex); 485 486 if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) { 487 HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); 488 return GSS_S_NO_CONTEXT; 489 } 490 491 ret = gss_export_sec_context(minor_status, 492 &ctx->negotiated_ctx_id, 493 interprocess_token); 494 if (ret == GSS_S_COMPLETE) { 495 ret = _gss_spnego_internal_delete_sec_context(minor_status, 496 context_handle, 497 GSS_C_NO_BUFFER); 498 if (ret == GSS_S_COMPLETE) 499 return GSS_S_COMPLETE; 500 } 501 502 HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); 503 504 return ret; 505 } 506 507 OM_uint32 _gss_spnego_import_sec_context ( 508 OM_uint32 * minor_status, 509 const gss_buffer_t interprocess_token, 510 gss_ctx_id_t *context_handle 511 ) 512 { 513 OM_uint32 ret, minor; 514 gss_ctx_id_t context; 515 gssspnego_ctx ctx; 516 517 ret = _gss_spnego_alloc_sec_context(minor_status, &context); 518 if (ret != GSS_S_COMPLETE) { 519 return ret; 520 } 521 ctx = (gssspnego_ctx)context; 522 523 HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex); 524 525 ret = gss_import_sec_context(minor_status, 526 interprocess_token, 527 &ctx->negotiated_ctx_id); 528 if (ret != GSS_S_COMPLETE) { 529 _gss_spnego_internal_delete_sec_context(&minor, context_handle, GSS_C_NO_BUFFER); 530 return ret; 531 } 532 533 ctx->open = 1; 534 /* don't bother filling in the rest of the fields */ 535 536 HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); 537 538 *context_handle = (gss_ctx_id_t)ctx; 539 540 return GSS_S_COMPLETE; 541 } 542 543 OM_uint32 _gss_spnego_inquire_names_for_mech ( 544 OM_uint32 * minor_status, 545 const gss_OID mechanism, 546 gss_OID_set * name_types 547 ) 548 { 549 gss_OID_set mechs, names, n; 550 OM_uint32 ret, junk; 551 int i, j; 552 553 *name_types = NULL; 554 555 ret = spnego_supported_mechs(minor_status, &mechs); 556 if (ret != GSS_S_COMPLETE) 557 return ret; 558 559 ret = gss_create_empty_oid_set(minor_status, &names); 560 if (ret != GSS_S_COMPLETE) 561 goto out; 562 563 for (i = 0; i < mechs->count; i++) { 564 ret = gss_inquire_names_for_mech(minor_status, 565 &mechs->elements[i], 566 &n); 567 if (ret) 568 continue; 569 570 for (j = 0; j < n->count; j++) 571 gss_add_oid_set_member(minor_status, 572 &n->elements[j], 573 &names); 574 gss_release_oid_set(&junk, &n); 575 } 576 577 ret = GSS_S_COMPLETE; 578 *name_types = names; 579 out: 580 581 gss_release_oid_set(&junk, &mechs); 582 583 return GSS_S_COMPLETE; 584 } 585 586 OM_uint32 _gss_spnego_inquire_mechs_for_name ( 587 OM_uint32 * minor_status, 588 const gss_name_t input_name, 589 gss_OID_set * mech_types 590 ) 591 { 592 OM_uint32 ret, junk; 593 594 ret = gss_create_empty_oid_set(minor_status, mech_types); 595 if (ret) 596 return ret; 597 598 ret = gss_add_oid_set_member(minor_status, 599 GSS_SPNEGO_MECHANISM, 600 mech_types); 601 if (ret) 602 gss_release_oid_set(&junk, mech_types); 603 604 return ret; 605 } 606 607 OM_uint32 _gss_spnego_canonicalize_name ( 608 OM_uint32 * minor_status, 609 const gss_name_t input_name, 610 const gss_OID mech_type, 611 gss_name_t * output_name 612 ) 613 { 614 /* XXX */ 615 return gss_duplicate_name(minor_status, input_name, output_name); 616 } 617 618 OM_uint32 _gss_spnego_duplicate_name ( 619 OM_uint32 * minor_status, 620 const gss_name_t src_name, 621 gss_name_t * dest_name 622 ) 623 { 624 return gss_duplicate_name(minor_status, src_name, dest_name); 625 } 626 627 OM_uint32 _gss_spnego_sign 628 (OM_uint32 * minor_status, 629 gss_ctx_id_t context_handle, 630 int qop_req, 631 gss_buffer_t message_buffer, 632 gss_buffer_t message_token 633 ) 634 { 635 gssspnego_ctx ctx; 636 637 *minor_status = 0; 638 639 if (context_handle == GSS_C_NO_CONTEXT) { 640 return GSS_S_NO_CONTEXT; 641 } 642 643 ctx = (gssspnego_ctx)context_handle; 644 645 if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) { 646 return GSS_S_NO_CONTEXT; 647 } 648 649 return gss_sign(minor_status, 650 ctx->negotiated_ctx_id, 651 qop_req, 652 message_buffer, 653 message_token); 654 } 655 656 OM_uint32 _gss_spnego_verify 657 (OM_uint32 * minor_status, 658 gss_ctx_id_t context_handle, 659 gss_buffer_t message_buffer, 660 gss_buffer_t token_buffer, 661 int * qop_state 662 ) 663 { 664 gssspnego_ctx ctx; 665 666 *minor_status = 0; 667 668 if (context_handle == GSS_C_NO_CONTEXT) { 669 return GSS_S_NO_CONTEXT; 670 } 671 672 ctx = (gssspnego_ctx)context_handle; 673 674 if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) { 675 return GSS_S_NO_CONTEXT; 676 } 677 678 return gss_verify(minor_status, 679 ctx->negotiated_ctx_id, 680 message_buffer, 681 token_buffer, 682 qop_state); 683 } 684 685 OM_uint32 _gss_spnego_seal 686 (OM_uint32 * minor_status, 687 gss_ctx_id_t context_handle, 688 int conf_req_flag, 689 int qop_req, 690 gss_buffer_t input_message_buffer, 691 int * conf_state, 692 gss_buffer_t output_message_buffer 693 ) 694 { 695 gssspnego_ctx ctx; 696 697 *minor_status = 0; 698 699 if (context_handle == GSS_C_NO_CONTEXT) { 700 return GSS_S_NO_CONTEXT; 701 } 702 703 ctx = (gssspnego_ctx)context_handle; 704 705 if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) { 706 return GSS_S_NO_CONTEXT; 707 } 708 709 return gss_seal(minor_status, 710 ctx->negotiated_ctx_id, 711 conf_req_flag, 712 qop_req, 713 input_message_buffer, 714 conf_state, 715 output_message_buffer); 716 } 717 718 OM_uint32 _gss_spnego_unseal 719 (OM_uint32 * minor_status, 720 gss_ctx_id_t context_handle, 721 gss_buffer_t input_message_buffer, 722 gss_buffer_t output_message_buffer, 723 int * conf_state, 724 int * qop_state 725 ) 726 { 727 gssspnego_ctx ctx; 728 729 *minor_status = 0; 730 731 if (context_handle == GSS_C_NO_CONTEXT) { 732 return GSS_S_NO_CONTEXT; 733 } 734 735 ctx = (gssspnego_ctx)context_handle; 736 737 if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) { 738 return GSS_S_NO_CONTEXT; 739 } 740 741 return gss_unseal(minor_status, 742 ctx->negotiated_ctx_id, 743 input_message_buffer, 744 output_message_buffer, 745 conf_state, 746 qop_state); 747 } 748 749 #if 0 750 OM_uint32 _gss_spnego_unwrap_ex 751 (OM_uint32 * minor_status, 752 const gss_ctx_id_t context_handle, 753 const gss_buffer_t token_header_buffer, 754 const gss_buffer_t associated_data_buffer, 755 const gss_buffer_t input_message_buffer, 756 gss_buffer_t output_message_buffer, 757 int * conf_state, 758 gss_qop_t * qop_state) 759 { 760 gssspnego_ctx ctx; 761 762 *minor_status = 0; 763 764 if (context_handle == GSS_C_NO_CONTEXT) { 765 return GSS_S_NO_CONTEXT; 766 } 767 768 ctx = (gssspnego_ctx)context_handle; 769 770 if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) { 771 return GSS_S_NO_CONTEXT; 772 } 773 774 return gss_unwrap_ex(minor_status, 775 ctx->negotiated_ctx_id, 776 token_header_buffer, 777 associated_data_buffer, 778 input_message_buffer, 779 output_message_buffer, 780 conf_state, 781 qop_state); 782 } 783 784 OM_uint32 _gss_spnego_wrap_ex 785 (OM_uint32 * minor_status, 786 const gss_ctx_id_t context_handle, 787 int conf_req_flag, 788 gss_qop_t qop_req, 789 const gss_buffer_t associated_data_buffer, 790 const gss_buffer_t input_message_buffer, 791 int * conf_state, 792 gss_buffer_t output_token_buffer, 793 gss_buffer_t output_message_buffer 794 ) 795 { 796 gssspnego_ctx ctx; 797 798 *minor_status = 0; 799 800 if (context_handle == GSS_C_NO_CONTEXT) { 801 return GSS_S_NO_CONTEXT; 802 } 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 810 if ((ctx->mech_flags & GSS_C_DCE_STYLE) == 0 && 811 associated_data_buffer->length != input_message_buffer->length) { 812 *minor_status = EINVAL; 813 return GSS_S_BAD_QOP; 814 } 815 816 return gss_wrap_ex(minor_status, 817 ctx->negotiated_ctx_id, 818 conf_req_flag, 819 qop_req, 820 associated_data_buffer, 821 input_message_buffer, 822 conf_state, 823 output_token_buffer, 824 output_message_buffer); 825 } 826 827 OM_uint32 _gss_spnego_complete_auth_token 828 (OM_uint32 * minor_status, 829 const gss_ctx_id_t context_handle, 830 gss_buffer_t input_message_buffer) 831 { 832 gssspnego_ctx ctx; 833 834 *minor_status = 0; 835 836 if (context_handle == GSS_C_NO_CONTEXT) { 837 return GSS_S_NO_CONTEXT; 838 } 839 840 ctx = (gssspnego_ctx)context_handle; 841 842 if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) { 843 return GSS_S_NO_CONTEXT; 844 } 845 846 return gss_complete_auth_token(minor_status, 847 ctx->negotiated_ctx_id, 848 input_message_buffer); 849 } 850 #endif 851 852 OM_uint32 _gss_spnego_inquire_sec_context_by_oid 853 (OM_uint32 * minor_status, 854 const gss_ctx_id_t context_handle, 855 const gss_OID desired_object, 856 gss_buffer_set_t *data_set) 857 { 858 gssspnego_ctx ctx; 859 860 *minor_status = 0; 861 862 if (context_handle == GSS_C_NO_CONTEXT) { 863 return GSS_S_NO_CONTEXT; 864 } 865 866 ctx = (gssspnego_ctx)context_handle; 867 868 if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) { 869 return GSS_S_NO_CONTEXT; 870 } 871 872 return gss_inquire_sec_context_by_oid(minor_status, 873 ctx->negotiated_ctx_id, 874 desired_object, 875 data_set); 876 } 877 878 OM_uint32 _gss_spnego_set_sec_context_option 879 (OM_uint32 * minor_status, 880 gss_ctx_id_t * context_handle, 881 const gss_OID desired_object, 882 const gss_buffer_t value) 883 { 884 gssspnego_ctx ctx; 885 886 *minor_status = 0; 887 888 if (context_handle == NULL || *context_handle == GSS_C_NO_CONTEXT) { 889 return GSS_S_NO_CONTEXT; 890 } 891 892 ctx = (gssspnego_ctx)context_handle; 893 894 if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) { 895 return GSS_S_NO_CONTEXT; 896 } 897 898 return gss_set_sec_context_option(minor_status, 899 &ctx->negotiated_ctx_id, 900 desired_object, 901 value); 902 } 903 904