1/* $NetBSD: context_stubs.c,v 1.2 2017/01/28 21:31:47 christos 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 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 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 71OM_uint32 GSSAPI_CALLCONV _gss_spnego_process_context_token 72 (OM_uint32 *minor_status, 73 gss_const_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 = (gss_ctx_id_t)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 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 124OM_uint32 GSSAPI_CALLCONV _gss_spnego_context_time 125 (OM_uint32 *minor_status, 126 gss_const_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 GSSAPI_CALLCONV _gss_spnego_get_mic 149 (OM_uint32 *minor_status, 150 gss_const_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 GSSAPI_CALLCONV _gss_spnego_verify_mic 175 (OM_uint32 * minor_status, 176 gss_const_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 GSSAPI_CALLCONV _gss_spnego_wrap 204 (OM_uint32 * minor_status, 205 gss_const_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 GSSAPI_CALLCONV _gss_spnego_unwrap 237 (OM_uint32 * minor_status, 238 gss_const_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 GSSAPI_CALLCONV _gss_spnego_compare_name 268 (OM_uint32 *minor_status, 269 gss_const_name_t name1, 270 gss_const_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 GSSAPI_CALLCONV _gss_spnego_display_name 292 (OM_uint32 * minor_status, 293 gss_const_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 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 345OM_uint32 GSSAPI_CALLCONV _gss_spnego_export_name 346 (OM_uint32 * minor_status, 347 gss_const_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 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 385OM_uint32 GSSAPI_CALLCONV _gss_spnego_inquire_context ( 386 OM_uint32 * minor_status, 387 gss_const_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 GSSAPI_CALLCONV _gss_spnego_wrap_size_limit ( 453 OM_uint32 * minor_status, 454 gss_const_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 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 526OM_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 *context_handle = GSS_C_NO_CONTEXT; 537 ret = _gss_spnego_alloc_sec_context(minor_status, &context); 538 if (ret != GSS_S_COMPLETE) { 539 return ret; 540 } 541 ctx = (gssspnego_ctx)context; 542 543 HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex); 544 545 ret = gss_import_sec_context(minor_status, 546 interprocess_token, 547 &ctx->negotiated_ctx_id); 548 if (ret != GSS_S_COMPLETE) { 549 _gss_spnego_internal_delete_sec_context(&minor, &context, GSS_C_NO_BUFFER); 550 return ret; 551 } 552 553 ctx->open = 1; 554 /* don't bother filling in the rest of the fields */ 555 556 HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); 557 558 *context_handle = (gss_ctx_id_t)ctx; 559 560 return GSS_S_COMPLETE; 561} 562 563OM_uint32 GSSAPI_CALLCONV _gss_spnego_inquire_names_for_mech ( 564 OM_uint32 * minor_status, 565 const gss_OID mechanism, 566 gss_OID_set * name_types 567 ) 568{ 569 gss_OID_set mechs, names, n; 570 OM_uint32 ret, junk; 571 size_t i, j; 572 573 *name_types = NULL; 574 575 ret = spnego_supported_mechs(minor_status, &mechs); 576 if (ret != GSS_S_COMPLETE) 577 return ret; 578 579 ret = gss_create_empty_oid_set(minor_status, &names); 580 if (ret != GSS_S_COMPLETE) 581 goto out; 582 583 for (i = 0; i < mechs->count; i++) { 584 ret = gss_inquire_names_for_mech(minor_status, 585 &mechs->elements[i], 586 &n); 587 if (ret) 588 continue; 589 590 for (j = 0; j < n->count; j++) 591 gss_add_oid_set_member(minor_status, 592 &n->elements[j], 593 &names); 594 gss_release_oid_set(&junk, &n); 595 } 596 597 ret = GSS_S_COMPLETE; 598 *name_types = names; 599out: 600 601 gss_release_oid_set(&junk, &mechs); 602 603 return ret; 604} 605 606OM_uint32 GSSAPI_CALLCONV _gss_spnego_inquire_mechs_for_name ( 607 OM_uint32 * minor_status, 608 gss_const_name_t input_name, 609 gss_OID_set * mech_types 610 ) 611{ 612 OM_uint32 ret, junk; 613 614 ret = gss_create_empty_oid_set(minor_status, mech_types); 615 if (ret) 616 return ret; 617 618 ret = gss_add_oid_set_member(minor_status, 619 GSS_SPNEGO_MECHANISM, 620 mech_types); 621 if (ret) 622 gss_release_oid_set(&junk, mech_types); 623 624 return ret; 625} 626 627OM_uint32 GSSAPI_CALLCONV _gss_spnego_canonicalize_name ( 628 OM_uint32 * minor_status, 629 gss_const_name_t input_name, 630 const gss_OID mech_type, 631 gss_name_t * output_name 632 ) 633{ 634 /* XXX */ 635 return gss_duplicate_name(minor_status, input_name, output_name); 636} 637 638OM_uint32 GSSAPI_CALLCONV _gss_spnego_duplicate_name ( 639 OM_uint32 * minor_status, 640 gss_const_name_t src_name, 641 gss_name_t * dest_name 642 ) 643{ 644 return gss_duplicate_name(minor_status, src_name, dest_name); 645} 646 647OM_uint32 GSSAPI_CALLCONV 648_gss_spnego_wrap_iov(OM_uint32 * minor_status, 649 gss_ctx_id_t context_handle, 650 int conf_req_flag, 651 gss_qop_t qop_req, 652 int * conf_state, 653 gss_iov_buffer_desc *iov, 654 int iov_count) 655{ 656 gssspnego_ctx ctx = (gssspnego_ctx)context_handle; 657 658 *minor_status = 0; 659 660 if (ctx == NULL || ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) 661 return GSS_S_NO_CONTEXT; 662 663 return gss_wrap_iov(minor_status, ctx->negotiated_ctx_id, 664 conf_req_flag, qop_req, conf_state, 665 iov, iov_count); 666} 667 668OM_uint32 GSSAPI_CALLCONV 669_gss_spnego_unwrap_iov(OM_uint32 *minor_status, 670 gss_ctx_id_t context_handle, 671 int *conf_state, 672 gss_qop_t *qop_state, 673 gss_iov_buffer_desc *iov, 674 int iov_count) 675{ 676 gssspnego_ctx ctx = (gssspnego_ctx)context_handle; 677 678 *minor_status = 0; 679 680 if (ctx == NULL || ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) 681 return GSS_S_NO_CONTEXT; 682 683 return gss_unwrap_iov(minor_status, 684 ctx->negotiated_ctx_id, 685 conf_state, qop_state, 686 iov, iov_count); 687} 688 689OM_uint32 GSSAPI_CALLCONV 690_gss_spnego_wrap_iov_length(OM_uint32 * minor_status, 691 gss_ctx_id_t context_handle, 692 int conf_req_flag, 693 gss_qop_t qop_req, 694 int *conf_state, 695 gss_iov_buffer_desc *iov, 696 int iov_count) 697{ 698 gssspnego_ctx ctx = (gssspnego_ctx)context_handle; 699 700 *minor_status = 0; 701 702 if (ctx == NULL || ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) 703 return GSS_S_NO_CONTEXT; 704 705 return gss_wrap_iov_length(minor_status, ctx->negotiated_ctx_id, 706 conf_req_flag, qop_req, conf_state, 707 iov, iov_count); 708} 709 710#if 0 711OM_uint32 GSSAPI_CALLCONV _gss_spnego_complete_auth_token 712 (OM_uint32 * minor_status, 713 gss_const_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 736OM_uint32 GSSAPI_CALLCONV _gss_spnego_inquire_sec_context_by_oid 737 (OM_uint32 * minor_status, 738 gss_const_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 762OM_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 789OM_uint32 GSSAPI_CALLCONV 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