1178825Sdfr/* 2178825Sdfr * Copyright (c) 2004, PADL Software Pty Ltd. 3178825Sdfr * All rights reserved. 4178825Sdfr * 5178825Sdfr * Redistribution and use in source and binary forms, with or without 6178825Sdfr * modification, are permitted provided that the following conditions 7178825Sdfr * are met: 8178825Sdfr * 9178825Sdfr * 1. Redistributions of source code must retain the above copyright 10178825Sdfr * notice, this list of conditions and the following disclaimer. 11178825Sdfr * 12178825Sdfr * 2. Redistributions in binary form must reproduce the above copyright 13178825Sdfr * notice, this list of conditions and the following disclaimer in the 14178825Sdfr * documentation and/or other materials provided with the distribution. 15178825Sdfr * 16178825Sdfr * 3. Neither the name of PADL Software nor the names of its contributors 17178825Sdfr * may be used to endorse or promote products derived from this software 18178825Sdfr * without specific prior written permission. 19178825Sdfr * 20178825Sdfr * THIS SOFTWARE IS PROVIDED BY PADL SOFTWARE AND CONTRIBUTORS ``AS IS'' AND 21178825Sdfr * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22178825Sdfr * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23178825Sdfr * ARE DISCLAIMED. IN NO EVENT SHALL PADL SOFTWARE OR CONTRIBUTORS BE LIABLE 24178825Sdfr * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25178825Sdfr * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26178825Sdfr * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27178825Sdfr * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28178825Sdfr * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29178825Sdfr * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30178825Sdfr * SUCH DAMAGE. 31178825Sdfr */ 32178825Sdfr 33233294Sstas#include "spnego_locl.h" 34178825Sdfr 35178825Sdfrstatic OM_uint32 36178825Sdfrspnego_supported_mechs(OM_uint32 *minor_status, gss_OID_set *mechs) 37178825Sdfr{ 38178825Sdfr OM_uint32 ret, junk; 39178825Sdfr gss_OID_set m; 40233294Sstas size_t i; 41178825Sdfr 42178825Sdfr ret = gss_indicate_mechs(minor_status, &m); 43178825Sdfr if (ret != GSS_S_COMPLETE) 44178825Sdfr return ret; 45178825Sdfr 46178825Sdfr ret = gss_create_empty_oid_set(minor_status, mechs); 47178825Sdfr if (ret != GSS_S_COMPLETE) { 48178825Sdfr gss_release_oid_set(&junk, &m); 49178825Sdfr return ret; 50178825Sdfr } 51178825Sdfr 52178825Sdfr for (i = 0; i < m->count; i++) { 53178825Sdfr if (gss_oid_equal(&m->elements[i], GSS_SPNEGO_MECHANISM)) 54178825Sdfr continue; 55178825Sdfr 56178825Sdfr ret = gss_add_oid_set_member(minor_status, &m->elements[i], mechs); 57178825Sdfr if (ret) { 58178825Sdfr gss_release_oid_set(&junk, &m); 59178825Sdfr gss_release_oid_set(&junk, mechs); 60178825Sdfr return ret; 61178825Sdfr } 62178825Sdfr } 63233294Sstas gss_release_oid_set(&junk, &m); 64178825Sdfr return ret; 65178825Sdfr} 66178825Sdfr 67178825Sdfr 68178825Sdfr 69233294SstasOM_uint32 GSSAPI_CALLCONV _gss_spnego_process_context_token 70178825Sdfr (OM_uint32 *minor_status, 71178825Sdfr const gss_ctx_id_t context_handle, 72178825Sdfr const gss_buffer_t token_buffer 73178825Sdfr ) 74178825Sdfr{ 75178825Sdfr gss_ctx_id_t context ; 76178825Sdfr gssspnego_ctx ctx; 77178825Sdfr OM_uint32 ret; 78178825Sdfr 79178825Sdfr if (context_handle == GSS_C_NO_CONTEXT) 80178825Sdfr return GSS_S_NO_CONTEXT; 81178825Sdfr 82178825Sdfr context = context_handle; 83178825Sdfr ctx = (gssspnego_ctx)context_handle; 84178825Sdfr 85178825Sdfr HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex); 86178825Sdfr 87178825Sdfr ret = gss_process_context_token(minor_status, 88178825Sdfr ctx->negotiated_ctx_id, 89178825Sdfr token_buffer); 90178825Sdfr if (ret != GSS_S_COMPLETE) { 91178825Sdfr HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); 92178825Sdfr return ret; 93178825Sdfr } 94178825Sdfr 95178825Sdfr ctx->negotiated_ctx_id = GSS_C_NO_CONTEXT; 96178825Sdfr 97178825Sdfr return _gss_spnego_internal_delete_sec_context(minor_status, 98178825Sdfr &context, 99178825Sdfr GSS_C_NO_BUFFER); 100178825Sdfr} 101178825Sdfr 102233294SstasOM_uint32 GSSAPI_CALLCONV _gss_spnego_delete_sec_context 103178825Sdfr (OM_uint32 *minor_status, 104178825Sdfr gss_ctx_id_t *context_handle, 105178825Sdfr gss_buffer_t output_token 106178825Sdfr ) 107178825Sdfr{ 108178825Sdfr gssspnego_ctx ctx; 109178825Sdfr 110178825Sdfr if (context_handle == NULL || *context_handle == GSS_C_NO_CONTEXT) 111178825Sdfr return GSS_S_NO_CONTEXT; 112178825Sdfr 113178825Sdfr ctx = (gssspnego_ctx)*context_handle; 114178825Sdfr 115178825Sdfr HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex); 116178825Sdfr 117178825Sdfr return _gss_spnego_internal_delete_sec_context(minor_status, 118178825Sdfr context_handle, 119178825Sdfr output_token); 120178825Sdfr} 121178825Sdfr 122233294SstasOM_uint32 GSSAPI_CALLCONV _gss_spnego_context_time 123178825Sdfr (OM_uint32 *minor_status, 124178825Sdfr const gss_ctx_id_t context_handle, 125178825Sdfr OM_uint32 *time_rec 126178825Sdfr ) 127178825Sdfr{ 128178825Sdfr gssspnego_ctx ctx; 129178825Sdfr *minor_status = 0; 130178825Sdfr 131178825Sdfr if (context_handle == GSS_C_NO_CONTEXT) { 132178825Sdfr return GSS_S_NO_CONTEXT; 133178825Sdfr } 134178825Sdfr 135178825Sdfr ctx = (gssspnego_ctx)context_handle; 136178825Sdfr 137178825Sdfr if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) { 138178825Sdfr return GSS_S_NO_CONTEXT; 139178825Sdfr } 140178825Sdfr 141178825Sdfr return gss_context_time(minor_status, 142178825Sdfr ctx->negotiated_ctx_id, 143178825Sdfr time_rec); 144178825Sdfr} 145178825Sdfr 146233294SstasOM_uint32 GSSAPI_CALLCONV _gss_spnego_get_mic 147178825Sdfr (OM_uint32 *minor_status, 148178825Sdfr const gss_ctx_id_t context_handle, 149178825Sdfr gss_qop_t qop_req, 150178825Sdfr const gss_buffer_t message_buffer, 151178825Sdfr gss_buffer_t message_token 152178825Sdfr ) 153178825Sdfr{ 154178825Sdfr gssspnego_ctx ctx; 155178825Sdfr 156178825Sdfr *minor_status = 0; 157178825Sdfr 158178825Sdfr if (context_handle == GSS_C_NO_CONTEXT) { 159178825Sdfr return GSS_S_NO_CONTEXT; 160178825Sdfr } 161178825Sdfr 162178825Sdfr ctx = (gssspnego_ctx)context_handle; 163178825Sdfr 164178825Sdfr if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) { 165178825Sdfr return GSS_S_NO_CONTEXT; 166178825Sdfr } 167178825Sdfr 168178825Sdfr return gss_get_mic(minor_status, ctx->negotiated_ctx_id, 169178825Sdfr qop_req, message_buffer, message_token); 170178825Sdfr} 171178825Sdfr 172233294SstasOM_uint32 GSSAPI_CALLCONV _gss_spnego_verify_mic 173178825Sdfr (OM_uint32 * minor_status, 174178825Sdfr const gss_ctx_id_t context_handle, 175178825Sdfr const gss_buffer_t message_buffer, 176178825Sdfr const gss_buffer_t token_buffer, 177178825Sdfr gss_qop_t * qop_state 178178825Sdfr ) 179178825Sdfr{ 180178825Sdfr gssspnego_ctx ctx; 181178825Sdfr 182178825Sdfr *minor_status = 0; 183178825Sdfr 184178825Sdfr if (context_handle == GSS_C_NO_CONTEXT) { 185178825Sdfr return GSS_S_NO_CONTEXT; 186178825Sdfr } 187178825Sdfr 188178825Sdfr ctx = (gssspnego_ctx)context_handle; 189178825Sdfr 190178825Sdfr if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) { 191178825Sdfr return GSS_S_NO_CONTEXT; 192178825Sdfr } 193178825Sdfr 194178825Sdfr return gss_verify_mic(minor_status, 195178825Sdfr ctx->negotiated_ctx_id, 196178825Sdfr message_buffer, 197178825Sdfr token_buffer, 198178825Sdfr qop_state); 199178825Sdfr} 200178825Sdfr 201233294SstasOM_uint32 GSSAPI_CALLCONV _gss_spnego_wrap 202178825Sdfr (OM_uint32 * minor_status, 203178825Sdfr const gss_ctx_id_t context_handle, 204178825Sdfr int conf_req_flag, 205178825Sdfr gss_qop_t qop_req, 206178825Sdfr const gss_buffer_t input_message_buffer, 207178825Sdfr int * conf_state, 208178825Sdfr gss_buffer_t output_message_buffer 209178825Sdfr ) 210178825Sdfr{ 211178825Sdfr gssspnego_ctx ctx; 212178825Sdfr 213178825Sdfr *minor_status = 0; 214178825Sdfr 215178825Sdfr if (context_handle == GSS_C_NO_CONTEXT) { 216178825Sdfr return GSS_S_NO_CONTEXT; 217178825Sdfr } 218178825Sdfr 219178825Sdfr ctx = (gssspnego_ctx)context_handle; 220178825Sdfr 221178825Sdfr if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) { 222178825Sdfr return GSS_S_NO_CONTEXT; 223178825Sdfr } 224178825Sdfr 225178825Sdfr return gss_wrap(minor_status, 226178825Sdfr ctx->negotiated_ctx_id, 227178825Sdfr conf_req_flag, 228178825Sdfr qop_req, 229178825Sdfr input_message_buffer, 230178825Sdfr conf_state, 231178825Sdfr output_message_buffer); 232178825Sdfr} 233178825Sdfr 234233294SstasOM_uint32 GSSAPI_CALLCONV _gss_spnego_unwrap 235178825Sdfr (OM_uint32 * minor_status, 236178825Sdfr const gss_ctx_id_t context_handle, 237178825Sdfr const gss_buffer_t input_message_buffer, 238178825Sdfr gss_buffer_t output_message_buffer, 239178825Sdfr int * conf_state, 240178825Sdfr gss_qop_t * qop_state 241178825Sdfr ) 242178825Sdfr{ 243178825Sdfr gssspnego_ctx ctx; 244178825Sdfr 245178825Sdfr *minor_status = 0; 246178825Sdfr 247178825Sdfr if (context_handle == GSS_C_NO_CONTEXT) { 248178825Sdfr return GSS_S_NO_CONTEXT; 249178825Sdfr } 250178825Sdfr 251178825Sdfr ctx = (gssspnego_ctx)context_handle; 252178825Sdfr 253178825Sdfr if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) { 254178825Sdfr return GSS_S_NO_CONTEXT; 255178825Sdfr } 256178825Sdfr 257178825Sdfr return gss_unwrap(minor_status, 258178825Sdfr ctx->negotiated_ctx_id, 259178825Sdfr input_message_buffer, 260178825Sdfr output_message_buffer, 261178825Sdfr conf_state, 262178825Sdfr qop_state); 263178825Sdfr} 264178825Sdfr 265233294SstasOM_uint32 GSSAPI_CALLCONV _gss_spnego_compare_name 266178825Sdfr (OM_uint32 *minor_status, 267178825Sdfr const gss_name_t name1, 268178825Sdfr const gss_name_t name2, 269178825Sdfr int * name_equal 270178825Sdfr ) 271178825Sdfr{ 272178825Sdfr spnego_name n1 = (spnego_name)name1; 273178825Sdfr spnego_name n2 = (spnego_name)name2; 274178825Sdfr 275178825Sdfr *name_equal = 0; 276178825Sdfr 277178825Sdfr if (!gss_oid_equal(&n1->type, &n2->type)) 278178825Sdfr return GSS_S_COMPLETE; 279178825Sdfr if (n1->value.length != n2->value.length) 280178825Sdfr return GSS_S_COMPLETE; 281178825Sdfr if (memcmp(n1->value.value, n2->value.value, n2->value.length) != 0) 282178825Sdfr return GSS_S_COMPLETE; 283178825Sdfr 284178825Sdfr *name_equal = 1; 285178825Sdfr 286178825Sdfr return GSS_S_COMPLETE; 287178825Sdfr} 288178825Sdfr 289233294SstasOM_uint32 GSSAPI_CALLCONV _gss_spnego_display_name 290178825Sdfr (OM_uint32 * minor_status, 291178825Sdfr const gss_name_t input_name, 292178825Sdfr gss_buffer_t output_name_buffer, 293178825Sdfr gss_OID * output_name_type 294178825Sdfr ) 295178825Sdfr{ 296178825Sdfr spnego_name name = (spnego_name)input_name; 297178825Sdfr 298178825Sdfr *minor_status = 0; 299178825Sdfr 300178825Sdfr if (name == NULL || name->mech == GSS_C_NO_NAME) 301178825Sdfr return GSS_S_FAILURE; 302178825Sdfr 303178825Sdfr return gss_display_name(minor_status, name->mech, 304178825Sdfr output_name_buffer, output_name_type); 305178825Sdfr} 306178825Sdfr 307233294SstasOM_uint32 GSSAPI_CALLCONV _gss_spnego_import_name 308178825Sdfr (OM_uint32 * minor_status, 309178825Sdfr const gss_buffer_t name_buffer, 310178825Sdfr const gss_OID name_type, 311178825Sdfr gss_name_t * output_name 312178825Sdfr ) 313178825Sdfr{ 314178825Sdfr spnego_name name; 315178825Sdfr OM_uint32 maj_stat; 316178825Sdfr 317178825Sdfr *minor_status = 0; 318178825Sdfr 319178825Sdfr name = calloc(1, sizeof(*name)); 320178825Sdfr if (name == NULL) { 321178825Sdfr *minor_status = ENOMEM; 322178825Sdfr return GSS_S_FAILURE; 323178825Sdfr } 324233294Sstas 325178825Sdfr maj_stat = _gss_copy_oid(minor_status, name_type, &name->type); 326178825Sdfr if (maj_stat) { 327178825Sdfr free(name); 328178825Sdfr return GSS_S_FAILURE; 329178825Sdfr } 330233294Sstas 331178825Sdfr maj_stat = _gss_copy_buffer(minor_status, name_buffer, &name->value); 332178825Sdfr if (maj_stat) { 333178825Sdfr gss_name_t rname = (gss_name_t)name; 334178825Sdfr _gss_spnego_release_name(minor_status, &rname); 335178825Sdfr return GSS_S_FAILURE; 336178825Sdfr } 337178825Sdfr name->mech = GSS_C_NO_NAME; 338178825Sdfr *output_name = (gss_name_t)name; 339178825Sdfr 340178825Sdfr return GSS_S_COMPLETE; 341178825Sdfr} 342178825Sdfr 343233294SstasOM_uint32 GSSAPI_CALLCONV _gss_spnego_export_name 344178825Sdfr (OM_uint32 * minor_status, 345178825Sdfr const gss_name_t input_name, 346178825Sdfr gss_buffer_t exported_name 347178825Sdfr ) 348178825Sdfr{ 349178825Sdfr spnego_name name; 350178825Sdfr *minor_status = 0; 351178825Sdfr 352178825Sdfr if (input_name == GSS_C_NO_NAME) 353178825Sdfr return GSS_S_BAD_NAME; 354178825Sdfr 355178825Sdfr name = (spnego_name)input_name; 356178825Sdfr if (name->mech == GSS_C_NO_NAME) 357178825Sdfr return GSS_S_BAD_NAME; 358178825Sdfr 359178825Sdfr return gss_export_name(minor_status, name->mech, exported_name); 360178825Sdfr} 361178825Sdfr 362233294SstasOM_uint32 GSSAPI_CALLCONV _gss_spnego_release_name 363178825Sdfr (OM_uint32 * minor_status, 364178825Sdfr gss_name_t * input_name 365178825Sdfr ) 366178825Sdfr{ 367178825Sdfr *minor_status = 0; 368178825Sdfr 369178825Sdfr if (*input_name != GSS_C_NO_NAME) { 370178825Sdfr OM_uint32 junk; 371178825Sdfr spnego_name name = (spnego_name)*input_name; 372178825Sdfr _gss_free_oid(&junk, &name->type); 373178825Sdfr gss_release_buffer(&junk, &name->value); 374178825Sdfr if (name->mech != GSS_C_NO_NAME) 375178825Sdfr gss_release_name(&junk, &name->mech); 376178825Sdfr free(name); 377178825Sdfr 378178825Sdfr *input_name = GSS_C_NO_NAME; 379178825Sdfr } 380178825Sdfr return GSS_S_COMPLETE; 381178825Sdfr} 382178825Sdfr 383233294SstasOM_uint32 GSSAPI_CALLCONV _gss_spnego_inquire_context ( 384178825Sdfr OM_uint32 * minor_status, 385178825Sdfr const gss_ctx_id_t context_handle, 386178825Sdfr gss_name_t * src_name, 387178825Sdfr gss_name_t * targ_name, 388178825Sdfr OM_uint32 * lifetime_rec, 389178825Sdfr gss_OID * mech_type, 390178825Sdfr OM_uint32 * ctx_flags, 391178825Sdfr int * locally_initiated, 392178825Sdfr int * open_context 393178825Sdfr ) 394178825Sdfr{ 395178825Sdfr gssspnego_ctx ctx; 396233294Sstas OM_uint32 maj_stat, junk; 397233294Sstas gss_name_t src_mn, targ_mn; 398178825Sdfr 399178825Sdfr *minor_status = 0; 400178825Sdfr 401233294Sstas if (context_handle == GSS_C_NO_CONTEXT) 402178825Sdfr return GSS_S_NO_CONTEXT; 403178825Sdfr 404178825Sdfr ctx = (gssspnego_ctx)context_handle; 405178825Sdfr 406233294Sstas if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) 407178825Sdfr return GSS_S_NO_CONTEXT; 408178825Sdfr 409233294Sstas maj_stat = gss_inquire_context(minor_status, 410233294Sstas ctx->negotiated_ctx_id, 411233294Sstas &src_mn, 412233294Sstas &targ_mn, 413233294Sstas lifetime_rec, 414233294Sstas mech_type, 415233294Sstas ctx_flags, 416233294Sstas locally_initiated, 417233294Sstas open_context); 418233294Sstas if (maj_stat != GSS_S_COMPLETE) 419233294Sstas return maj_stat; 420233294Sstas 421233294Sstas if (src_name) { 422233294Sstas spnego_name name = calloc(1, sizeof(*name)); 423233294Sstas if (name == NULL) 424233294Sstas goto enomem; 425233294Sstas name->mech = src_mn; 426233294Sstas *src_name = (gss_name_t)name; 427233294Sstas } else 428233294Sstas gss_release_name(&junk, &src_mn); 429233294Sstas 430233294Sstas if (targ_name) { 431233294Sstas spnego_name name = calloc(1, sizeof(*name)); 432233294Sstas if (name == NULL) { 433233294Sstas gss_release_name(minor_status, src_name); 434233294Sstas goto enomem; 435233294Sstas } 436233294Sstas name->mech = targ_mn; 437233294Sstas *targ_name = (gss_name_t)name; 438233294Sstas } else 439233294Sstas gss_release_name(&junk, &targ_mn); 440233294Sstas 441233294Sstas return GSS_S_COMPLETE; 442233294Sstas 443233294Sstasenomem: 444233294Sstas gss_release_name(&junk, &targ_mn); 445233294Sstas gss_release_name(&junk, &src_mn); 446233294Sstas *minor_status = ENOMEM; 447233294Sstas return GSS_S_FAILURE; 448178825Sdfr} 449178825Sdfr 450233294SstasOM_uint32 GSSAPI_CALLCONV _gss_spnego_wrap_size_limit ( 451178825Sdfr OM_uint32 * minor_status, 452178825Sdfr const gss_ctx_id_t context_handle, 453178825Sdfr int conf_req_flag, 454178825Sdfr gss_qop_t qop_req, 455178825Sdfr OM_uint32 req_output_size, 456178825Sdfr OM_uint32 * max_input_size 457178825Sdfr ) 458178825Sdfr{ 459178825Sdfr gssspnego_ctx ctx; 460178825Sdfr 461178825Sdfr *minor_status = 0; 462178825Sdfr 463178825Sdfr if (context_handle == GSS_C_NO_CONTEXT) { 464178825Sdfr return GSS_S_NO_CONTEXT; 465178825Sdfr } 466178825Sdfr 467178825Sdfr ctx = (gssspnego_ctx)context_handle; 468178825Sdfr 469178825Sdfr if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) { 470178825Sdfr return GSS_S_NO_CONTEXT; 471178825Sdfr } 472178825Sdfr 473178825Sdfr return gss_wrap_size_limit(minor_status, 474178825Sdfr ctx->negotiated_ctx_id, 475178825Sdfr conf_req_flag, 476178825Sdfr qop_req, 477178825Sdfr req_output_size, 478178825Sdfr max_input_size); 479178825Sdfr} 480178825Sdfr 481233294SstasOM_uint32 GSSAPI_CALLCONV _gss_spnego_export_sec_context ( 482178825Sdfr OM_uint32 * minor_status, 483178825Sdfr gss_ctx_id_t * context_handle, 484178825Sdfr gss_buffer_t interprocess_token 485178825Sdfr ) 486178825Sdfr{ 487178825Sdfr gssspnego_ctx ctx; 488178825Sdfr OM_uint32 ret; 489178825Sdfr 490178825Sdfr *minor_status = 0; 491178825Sdfr 492178825Sdfr if (context_handle == NULL) { 493178825Sdfr return GSS_S_NO_CONTEXT; 494178825Sdfr } 495178825Sdfr 496178825Sdfr ctx = (gssspnego_ctx)*context_handle; 497178825Sdfr 498178825Sdfr if (ctx == NULL) 499178825Sdfr return GSS_S_NO_CONTEXT; 500178825Sdfr 501178825Sdfr HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex); 502178825Sdfr 503178825Sdfr if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) { 504178825Sdfr HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); 505178825Sdfr return GSS_S_NO_CONTEXT; 506178825Sdfr } 507178825Sdfr 508178825Sdfr ret = gss_export_sec_context(minor_status, 509178825Sdfr &ctx->negotiated_ctx_id, 510178825Sdfr interprocess_token); 511178825Sdfr if (ret == GSS_S_COMPLETE) { 512178825Sdfr ret = _gss_spnego_internal_delete_sec_context(minor_status, 513178825Sdfr context_handle, 514178825Sdfr GSS_C_NO_BUFFER); 515178825Sdfr if (ret == GSS_S_COMPLETE) 516178825Sdfr return GSS_S_COMPLETE; 517178825Sdfr } 518178825Sdfr 519178825Sdfr HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); 520178825Sdfr 521178825Sdfr return ret; 522178825Sdfr} 523178825Sdfr 524233294SstasOM_uint32 GSSAPI_CALLCONV _gss_spnego_import_sec_context ( 525178825Sdfr OM_uint32 * minor_status, 526178825Sdfr const gss_buffer_t interprocess_token, 527178825Sdfr gss_ctx_id_t *context_handle 528178825Sdfr ) 529178825Sdfr{ 530178825Sdfr OM_uint32 ret, minor; 531178825Sdfr gss_ctx_id_t context; 532178825Sdfr gssspnego_ctx ctx; 533178825Sdfr 534178825Sdfr ret = _gss_spnego_alloc_sec_context(minor_status, &context); 535178825Sdfr if (ret != GSS_S_COMPLETE) { 536178825Sdfr return ret; 537178825Sdfr } 538178825Sdfr ctx = (gssspnego_ctx)context; 539178825Sdfr 540178825Sdfr HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex); 541178825Sdfr 542178825Sdfr ret = gss_import_sec_context(minor_status, 543178825Sdfr interprocess_token, 544178825Sdfr &ctx->negotiated_ctx_id); 545178825Sdfr if (ret != GSS_S_COMPLETE) { 546178825Sdfr _gss_spnego_internal_delete_sec_context(&minor, context_handle, GSS_C_NO_BUFFER); 547178825Sdfr return ret; 548178825Sdfr } 549178825Sdfr 550178825Sdfr ctx->open = 1; 551178825Sdfr /* don't bother filling in the rest of the fields */ 552178825Sdfr 553178825Sdfr HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); 554178825Sdfr 555178825Sdfr *context_handle = (gss_ctx_id_t)ctx; 556178825Sdfr 557178825Sdfr return GSS_S_COMPLETE; 558178825Sdfr} 559178825Sdfr 560233294SstasOM_uint32 GSSAPI_CALLCONV _gss_spnego_inquire_names_for_mech ( 561178825Sdfr OM_uint32 * minor_status, 562178825Sdfr const gss_OID mechanism, 563178825Sdfr gss_OID_set * name_types 564178825Sdfr ) 565178825Sdfr{ 566178825Sdfr gss_OID_set mechs, names, n; 567178825Sdfr OM_uint32 ret, junk; 568233294Sstas size_t i, j; 569178825Sdfr 570178825Sdfr *name_types = NULL; 571178825Sdfr 572178825Sdfr ret = spnego_supported_mechs(minor_status, &mechs); 573178825Sdfr if (ret != GSS_S_COMPLETE) 574178825Sdfr return ret; 575178825Sdfr 576178825Sdfr ret = gss_create_empty_oid_set(minor_status, &names); 577178825Sdfr if (ret != GSS_S_COMPLETE) 578178825Sdfr goto out; 579178825Sdfr 580178825Sdfr for (i = 0; i < mechs->count; i++) { 581178825Sdfr ret = gss_inquire_names_for_mech(minor_status, 582178825Sdfr &mechs->elements[i], 583178825Sdfr &n); 584178825Sdfr if (ret) 585178825Sdfr continue; 586178825Sdfr 587178825Sdfr for (j = 0; j < n->count; j++) 588178825Sdfr gss_add_oid_set_member(minor_status, 589178825Sdfr &n->elements[j], 590178825Sdfr &names); 591178825Sdfr gss_release_oid_set(&junk, &n); 592178825Sdfr } 593178825Sdfr 594178825Sdfr ret = GSS_S_COMPLETE; 595178825Sdfr *name_types = names; 596178825Sdfrout: 597178825Sdfr 598178825Sdfr gss_release_oid_set(&junk, &mechs); 599178825Sdfr 600233294Sstas return ret; 601178825Sdfr} 602178825Sdfr 603233294SstasOM_uint32 GSSAPI_CALLCONV _gss_spnego_inquire_mechs_for_name ( 604178825Sdfr OM_uint32 * minor_status, 605178825Sdfr const gss_name_t input_name, 606178825Sdfr gss_OID_set * mech_types 607178825Sdfr ) 608178825Sdfr{ 609178825Sdfr OM_uint32 ret, junk; 610178825Sdfr 611178825Sdfr ret = gss_create_empty_oid_set(minor_status, mech_types); 612178825Sdfr if (ret) 613178825Sdfr return ret; 614178825Sdfr 615178825Sdfr ret = gss_add_oid_set_member(minor_status, 616178825Sdfr GSS_SPNEGO_MECHANISM, 617178825Sdfr mech_types); 618178825Sdfr if (ret) 619178825Sdfr gss_release_oid_set(&junk, mech_types); 620178825Sdfr 621178825Sdfr return ret; 622178825Sdfr} 623178825Sdfr 624233294SstasOM_uint32 GSSAPI_CALLCONV _gss_spnego_canonicalize_name ( 625178825Sdfr OM_uint32 * minor_status, 626178825Sdfr const gss_name_t input_name, 627178825Sdfr const gss_OID mech_type, 628178825Sdfr gss_name_t * output_name 629178825Sdfr ) 630178825Sdfr{ 631178825Sdfr /* XXX */ 632178825Sdfr return gss_duplicate_name(minor_status, input_name, output_name); 633178825Sdfr} 634178825Sdfr 635233294SstasOM_uint32 GSSAPI_CALLCONV _gss_spnego_duplicate_name ( 636178825Sdfr OM_uint32 * minor_status, 637178825Sdfr const gss_name_t src_name, 638178825Sdfr gss_name_t * dest_name 639178825Sdfr ) 640178825Sdfr{ 641178825Sdfr return gss_duplicate_name(minor_status, src_name, dest_name); 642178825Sdfr} 643178825Sdfr 644233294Sstas#if 0 645233294SstasOM_uint32 GSSAPI_CALLCONV 646233294Sstas_gss_spnego_wrap_iov(OM_uint32 * minor_status, 647233294Sstas gss_ctx_id_t context_handle, 648233294Sstas int conf_req_flag, 649233294Sstas gss_qop_t qop_req, 650233294Sstas int * conf_state, 651233294Sstas gss_iov_buffer_desc *iov, 652233294Sstas int iov_count) 653178825Sdfr{ 654233294Sstas gssspnego_ctx ctx = (gssspnego_ctx)context_handle; 655178825Sdfr 656178825Sdfr *minor_status = 0; 657178825Sdfr 658233294Sstas if (ctx == NULL || ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) 659178825Sdfr return GSS_S_NO_CONTEXT; 660178825Sdfr 661233294Sstas return gss_wrap_iov(minor_status, ctx->negotiated_ctx_id, 662233294Sstas conf_req_flag, qop_req, conf_state, 663233294Sstas iov, iov_count); 664178825Sdfr} 665178825Sdfr 666233294SstasOM_uint32 GSSAPI_CALLCONV 667233294Sstas_gss_spnego_unwrap_iov(OM_uint32 *minor_status, 668233294Sstas gss_ctx_id_t context_handle, 669233294Sstas int *conf_state, 670233294Sstas gss_qop_t *qop_state, 671233294Sstas gss_iov_buffer_desc *iov, 672233294Sstas int iov_count) 673178825Sdfr{ 674233294Sstas gssspnego_ctx ctx = (gssspnego_ctx)context_handle; 675178825Sdfr 676178825Sdfr *minor_status = 0; 677178825Sdfr 678233294Sstas if (ctx == NULL || ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) 679178825Sdfr return GSS_S_NO_CONTEXT; 680178825Sdfr 681233294Sstas return gss_unwrap_iov(minor_status, 682233294Sstas ctx->negotiated_ctx_id, 683233294Sstas conf_state, qop_state, 684233294Sstas iov, iov_count); 685178825Sdfr} 686178825Sdfr 687233294SstasOM_uint32 GSSAPI_CALLCONV 688233294Sstas_gss_spnego_wrap_iov_length(OM_uint32 * minor_status, 689233294Sstas gss_ctx_id_t context_handle, 690233294Sstas int conf_req_flag, 691233294Sstas gss_qop_t qop_req, 692233294Sstas int *conf_state, 693233294Sstas gss_iov_buffer_desc *iov, 694233294Sstas int iov_count) 695178825Sdfr{ 696233294Sstas gssspnego_ctx ctx = (gssspnego_ctx)context_handle; 697178825Sdfr 698178825Sdfr *minor_status = 0; 699178825Sdfr 700233294Sstas if (ctx == NULL || ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) 701178825Sdfr return GSS_S_NO_CONTEXT; 702178825Sdfr 703233294Sstas return gss_wrap_iov_length(minor_status, ctx->negotiated_ctx_id, 704233294Sstas conf_req_flag, qop_req, conf_state, 705233294Sstas iov, iov_count); 706178825Sdfr} 707178825Sdfr 708233294Sstas#endif 709178825Sdfr 710178825Sdfr#if 0 711233294SstasOM_uint32 GSSAPI_CALLCONV _gss_spnego_complete_auth_token 712178825Sdfr (OM_uint32 * minor_status, 713178825Sdfr const gss_ctx_id_t context_handle, 714178825Sdfr gss_buffer_t input_message_buffer) 715178825Sdfr{ 716178825Sdfr gssspnego_ctx ctx; 717178825Sdfr 718178825Sdfr *minor_status = 0; 719178825Sdfr 720178825Sdfr if (context_handle == GSS_C_NO_CONTEXT) { 721178825Sdfr return GSS_S_NO_CONTEXT; 722178825Sdfr } 723178825Sdfr 724178825Sdfr ctx = (gssspnego_ctx)context_handle; 725178825Sdfr 726178825Sdfr if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) { 727178825Sdfr return GSS_S_NO_CONTEXT; 728178825Sdfr } 729178825Sdfr 730178825Sdfr return gss_complete_auth_token(minor_status, 731178825Sdfr ctx->negotiated_ctx_id, 732178825Sdfr input_message_buffer); 733178825Sdfr} 734178825Sdfr#endif 735178825Sdfr 736233294SstasOM_uint32 GSSAPI_CALLCONV _gss_spnego_inquire_sec_context_by_oid 737178825Sdfr (OM_uint32 * minor_status, 738178825Sdfr const gss_ctx_id_t context_handle, 739178825Sdfr const gss_OID desired_object, 740178825Sdfr gss_buffer_set_t *data_set) 741178825Sdfr{ 742178825Sdfr gssspnego_ctx ctx; 743178825Sdfr 744178825Sdfr *minor_status = 0; 745178825Sdfr 746178825Sdfr if (context_handle == GSS_C_NO_CONTEXT) { 747178825Sdfr return GSS_S_NO_CONTEXT; 748178825Sdfr } 749178825Sdfr 750178825Sdfr ctx = (gssspnego_ctx)context_handle; 751178825Sdfr 752178825Sdfr if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) { 753178825Sdfr return GSS_S_NO_CONTEXT; 754178825Sdfr } 755178825Sdfr 756178825Sdfr return gss_inquire_sec_context_by_oid(minor_status, 757178825Sdfr ctx->negotiated_ctx_id, 758178825Sdfr desired_object, 759178825Sdfr data_set); 760178825Sdfr} 761178825Sdfr 762233294SstasOM_uint32 GSSAPI_CALLCONV _gss_spnego_set_sec_context_option 763178825Sdfr (OM_uint32 * minor_status, 764178825Sdfr gss_ctx_id_t * context_handle, 765178825Sdfr const gss_OID desired_object, 766178825Sdfr const gss_buffer_t value) 767178825Sdfr{ 768178825Sdfr gssspnego_ctx ctx; 769178825Sdfr 770178825Sdfr *minor_status = 0; 771178825Sdfr 772178825Sdfr if (context_handle == NULL || *context_handle == GSS_C_NO_CONTEXT) { 773178825Sdfr return GSS_S_NO_CONTEXT; 774178825Sdfr } 775178825Sdfr 776233294Sstas ctx = (gssspnego_ctx)*context_handle; 777178825Sdfr 778178825Sdfr if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) { 779178825Sdfr return GSS_S_NO_CONTEXT; 780178825Sdfr } 781178825Sdfr 782178825Sdfr return gss_set_sec_context_option(minor_status, 783178825Sdfr &ctx->negotiated_ctx_id, 784178825Sdfr desired_object, 785178825Sdfr value); 786178825Sdfr} 787178825Sdfr 788233294Sstas 789233294SstasOM_uint32 GSSAPI_CALLCONV 790233294Sstas_gss_spnego_pseudo_random(OM_uint32 *minor_status, 791233294Sstas gss_ctx_id_t context_handle, 792233294Sstas int prf_key, 793233294Sstas const gss_buffer_t prf_in, 794233294Sstas ssize_t desired_output_len, 795233294Sstas gss_buffer_t prf_out) 796233294Sstas{ 797233294Sstas gssspnego_ctx ctx; 798233294Sstas 799233294Sstas *minor_status = 0; 800233294Sstas 801233294Sstas if (context_handle == GSS_C_NO_CONTEXT) 802233294Sstas return GSS_S_NO_CONTEXT; 803233294Sstas 804233294Sstas ctx = (gssspnego_ctx)context_handle; 805233294Sstas 806233294Sstas if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) 807233294Sstas return GSS_S_NO_CONTEXT; 808233294Sstas 809233294Sstas return gss_pseudo_random(minor_status, 810233294Sstas ctx->negotiated_ctx_id, 811233294Sstas prf_key, 812233294Sstas prf_in, 813233294Sstas desired_output_len, 814233294Sstas prf_out); 815233294Sstas} 816