1 /* $NetBSD: context_stubs.c,v 1.1.1.2 2014/04/24 12:45:29 pettai 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 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 71 OM_uint32 GSSAPI_CALLCONV _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 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 124 OM_uint32 GSSAPI_CALLCONV _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 148 OM_uint32 GSSAPI_CALLCONV _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 174 OM_uint32 GSSAPI_CALLCONV _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 203 OM_uint32 GSSAPI_CALLCONV _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 236 OM_uint32 GSSAPI_CALLCONV _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 267 OM_uint32 GSSAPI_CALLCONV _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 291 OM_uint32 GSSAPI_CALLCONV _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 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 345 OM_uint32 GSSAPI_CALLCONV _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 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 385 OM_uint32 GSSAPI_CALLCONV _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 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 452 OM_uint32 GSSAPI_CALLCONV _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 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 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 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 562 OM_uint32 GSSAPI_CALLCONV _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 size_t 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; 598 out: 599 600 gss_release_oid_set(&junk, &mechs); 601 602 return ret; 603 } 604 605 OM_uint32 GSSAPI_CALLCONV _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 626 OM_uint32 GSSAPI_CALLCONV _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 637 OM_uint32 GSSAPI_CALLCONV _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 OM_uint32 GSSAPI_CALLCONV 647 _gss_spnego_wrap_iov(OM_uint32 * minor_status, 648 gss_ctx_id_t context_handle, 649 int conf_req_flag, 650 gss_qop_t qop_req, 651 int * conf_state, 652 gss_iov_buffer_desc *iov, 653 int iov_count) 654 { 655 gssspnego_ctx ctx = (gssspnego_ctx)context_handle; 656 657 *minor_status = 0; 658 659 if (ctx == NULL || ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) 660 return GSS_S_NO_CONTEXT; 661 662 return gss_wrap_iov(minor_status, ctx->negotiated_ctx_id, 663 conf_req_flag, qop_req, conf_state, 664 iov, iov_count); 665 } 666 667 OM_uint32 GSSAPI_CALLCONV 668 _gss_spnego_unwrap_iov(OM_uint32 *minor_status, 669 gss_ctx_id_t context_handle, 670 int *conf_state, 671 gss_qop_t *qop_state, 672 gss_iov_buffer_desc *iov, 673 int iov_count) 674 { 675 gssspnego_ctx ctx = (gssspnego_ctx)context_handle; 676 677 *minor_status = 0; 678 679 if (ctx == NULL || ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) 680 return GSS_S_NO_CONTEXT; 681 682 return gss_unwrap_iov(minor_status, 683 ctx->negotiated_ctx_id, 684 conf_state, qop_state, 685 iov, iov_count); 686 } 687 688 OM_uint32 GSSAPI_CALLCONV 689 _gss_spnego_wrap_iov_length(OM_uint32 * minor_status, 690 gss_ctx_id_t context_handle, 691 int conf_req_flag, 692 gss_qop_t qop_req, 693 int *conf_state, 694 gss_iov_buffer_desc *iov, 695 int iov_count) 696 { 697 gssspnego_ctx ctx = (gssspnego_ctx)context_handle; 698 699 *minor_status = 0; 700 701 if (ctx == NULL || ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) 702 return GSS_S_NO_CONTEXT; 703 704 return gss_wrap_iov_length(minor_status, ctx->negotiated_ctx_id, 705 conf_req_flag, qop_req, conf_state, 706 iov, iov_count); 707 } 708 709 #if 0 710 OM_uint32 GSSAPI_CALLCONV _gss_spnego_complete_auth_token 711 (OM_uint32 * minor_status, 712 const gss_ctx_id_t context_handle, 713 gss_buffer_t input_message_buffer) 714 { 715 gssspnego_ctx ctx; 716 717 *minor_status = 0; 718 719 if (context_handle == GSS_C_NO_CONTEXT) { 720 return GSS_S_NO_CONTEXT; 721 } 722 723 ctx = (gssspnego_ctx)context_handle; 724 725 if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) { 726 return GSS_S_NO_CONTEXT; 727 } 728 729 return gss_complete_auth_token(minor_status, 730 ctx->negotiated_ctx_id, 731 input_message_buffer); 732 } 733 #endif 734 735 OM_uint32 GSSAPI_CALLCONV _gss_spnego_inquire_sec_context_by_oid 736 (OM_uint32 * minor_status, 737 const gss_ctx_id_t context_handle, 738 const gss_OID desired_object, 739 gss_buffer_set_t *data_set) 740 { 741 gssspnego_ctx ctx; 742 743 *minor_status = 0; 744 745 if (context_handle == GSS_C_NO_CONTEXT) { 746 return GSS_S_NO_CONTEXT; 747 } 748 749 ctx = (gssspnego_ctx)context_handle; 750 751 if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) { 752 return GSS_S_NO_CONTEXT; 753 } 754 755 return gss_inquire_sec_context_by_oid(minor_status, 756 ctx->negotiated_ctx_id, 757 desired_object, 758 data_set); 759 } 760 761 OM_uint32 GSSAPI_CALLCONV _gss_spnego_set_sec_context_option 762 (OM_uint32 * minor_status, 763 gss_ctx_id_t * context_handle, 764 const gss_OID desired_object, 765 const gss_buffer_t value) 766 { 767 gssspnego_ctx ctx; 768 769 *minor_status = 0; 770 771 if (context_handle == NULL || *context_handle == GSS_C_NO_CONTEXT) { 772 return GSS_S_NO_CONTEXT; 773 } 774 775 ctx = (gssspnego_ctx)*context_handle; 776 777 if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) { 778 return GSS_S_NO_CONTEXT; 779 } 780 781 return gss_set_sec_context_option(minor_status, 782 &ctx->negotiated_ctx_id, 783 desired_object, 784 value); 785 } 786 787 788 OM_uint32 GSSAPI_CALLCONV 789 _gss_spnego_pseudo_random(OM_uint32 *minor_status, 790 gss_ctx_id_t context_handle, 791 int prf_key, 792 const gss_buffer_t prf_in, 793 ssize_t desired_output_len, 794 gss_buffer_t prf_out) 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 ctx = (gssspnego_ctx)context_handle; 804 805 if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) 806 return GSS_S_NO_CONTEXT; 807 808 return gss_pseudo_random(minor_status, 809 ctx->negotiated_ctx_id, 810 prf_key, 811 prf_in, 812 desired_output_len, 813 prf_out); 814 } 815