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 "gsskrb5_locl.h" 34178825Sdfr 35178825Sdfrstatic int 36178825Sdfroid_prefix_equal(gss_OID oid_enc, gss_OID prefix_enc, unsigned *suffix) 37178825Sdfr{ 38178825Sdfr int ret; 39178825Sdfr heim_oid oid; 40178825Sdfr heim_oid prefix; 41233294Sstas 42178825Sdfr *suffix = 0; 43178825Sdfr 44178825Sdfr ret = der_get_oid(oid_enc->elements, oid_enc->length, 45178825Sdfr &oid, NULL); 46178825Sdfr if (ret) { 47178825Sdfr return 0; 48178825Sdfr } 49178825Sdfr 50178825Sdfr ret = der_get_oid(prefix_enc->elements, prefix_enc->length, 51178825Sdfr &prefix, NULL); 52178825Sdfr if (ret) { 53178825Sdfr der_free_oid(&oid); 54178825Sdfr return 0; 55178825Sdfr } 56178825Sdfr 57178825Sdfr ret = 0; 58178825Sdfr 59178825Sdfr if (oid.length - 1 == prefix.length) { 60178825Sdfr *suffix = oid.components[oid.length - 1]; 61178825Sdfr oid.length--; 62178825Sdfr ret = (der_heim_oid_cmp(&oid, &prefix) == 0); 63178825Sdfr oid.length++; 64178825Sdfr } 65178825Sdfr 66178825Sdfr der_free_oid(&oid); 67178825Sdfr der_free_oid(&prefix); 68178825Sdfr 69178825Sdfr return ret; 70178825Sdfr} 71178825Sdfr 72178825Sdfrstatic OM_uint32 inquire_sec_context_tkt_flags 73178825Sdfr (OM_uint32 *minor_status, 74178825Sdfr const gsskrb5_ctx context_handle, 75178825Sdfr gss_buffer_set_t *data_set) 76178825Sdfr{ 77178825Sdfr OM_uint32 tkt_flags; 78178825Sdfr unsigned char buf[4]; 79178825Sdfr gss_buffer_desc value; 80178825Sdfr 81178825Sdfr HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex); 82178825Sdfr 83178825Sdfr if (context_handle->ticket == NULL) { 84178825Sdfr HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); 85233294Sstas _gsskrb5_set_status(EINVAL, "No ticket from which to obtain flags"); 86178825Sdfr *minor_status = EINVAL; 87178825Sdfr return GSS_S_BAD_MECH; 88178825Sdfr } 89178825Sdfr 90178825Sdfr tkt_flags = TicketFlags2int(context_handle->ticket->ticket.flags); 91178825Sdfr HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); 92178825Sdfr 93178825Sdfr _gsskrb5_encode_om_uint32(tkt_flags, buf); 94178825Sdfr value.length = sizeof(buf); 95178825Sdfr value.value = buf; 96178825Sdfr 97178825Sdfr return gss_add_buffer_set_member(minor_status, 98178825Sdfr &value, 99178825Sdfr data_set); 100178825Sdfr} 101178825Sdfr 102178825Sdfrenum keytype { ACCEPTOR_KEY, INITIATOR_KEY, TOKEN_KEY }; 103178825Sdfr 104178825Sdfrstatic OM_uint32 inquire_sec_context_get_subkey 105178825Sdfr (OM_uint32 *minor_status, 106178825Sdfr const gsskrb5_ctx context_handle, 107178825Sdfr krb5_context context, 108178825Sdfr enum keytype keytype, 109178825Sdfr gss_buffer_set_t *data_set) 110178825Sdfr{ 111178825Sdfr krb5_keyblock *key = NULL; 112178825Sdfr krb5_storage *sp = NULL; 113178825Sdfr krb5_data data; 114178825Sdfr OM_uint32 maj_stat = GSS_S_COMPLETE; 115178825Sdfr krb5_error_code ret; 116178825Sdfr 117178825Sdfr krb5_data_zero(&data); 118178825Sdfr 119178825Sdfr sp = krb5_storage_emem(); 120178825Sdfr if (sp == NULL) { 121178825Sdfr _gsskrb5_clear_status(); 122178825Sdfr ret = ENOMEM; 123178825Sdfr goto out; 124178825Sdfr } 125178825Sdfr 126178825Sdfr HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex); 127178825Sdfr switch(keytype) { 128178825Sdfr case ACCEPTOR_KEY: 129178825Sdfr ret = _gsskrb5i_get_acceptor_subkey(context_handle, context, &key); 130178825Sdfr break; 131178825Sdfr case INITIATOR_KEY: 132178825Sdfr ret = _gsskrb5i_get_initiator_subkey(context_handle, context, &key); 133178825Sdfr break; 134178825Sdfr case TOKEN_KEY: 135178825Sdfr ret = _gsskrb5i_get_token_key(context_handle, context, &key); 136178825Sdfr break; 137178825Sdfr default: 138233294Sstas _gsskrb5_set_status(EINVAL, "%d is not a valid subkey type", keytype); 139178825Sdfr ret = EINVAL; 140178825Sdfr break; 141178825Sdfr } 142178825Sdfr HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); 143233294Sstas if (ret) 144178825Sdfr goto out; 145178825Sdfr if (key == NULL) { 146233294Sstas _gsskrb5_set_status(EINVAL, "have no subkey of type %d", keytype); 147178825Sdfr ret = EINVAL; 148178825Sdfr goto out; 149178825Sdfr } 150178825Sdfr 151178825Sdfr ret = krb5_store_keyblock(sp, *key); 152178825Sdfr krb5_free_keyblock (context, key); 153178825Sdfr if (ret) 154178825Sdfr goto out; 155178825Sdfr 156178825Sdfr ret = krb5_storage_to_data(sp, &data); 157178825Sdfr if (ret) 158178825Sdfr goto out; 159178825Sdfr 160178825Sdfr { 161178825Sdfr gss_buffer_desc value; 162233294Sstas 163178825Sdfr value.length = data.length; 164178825Sdfr value.value = data.data; 165233294Sstas 166178825Sdfr maj_stat = gss_add_buffer_set_member(minor_status, 167178825Sdfr &value, 168178825Sdfr data_set); 169178825Sdfr } 170178825Sdfr 171178825Sdfrout: 172178825Sdfr krb5_data_free(&data); 173178825Sdfr if (sp) 174178825Sdfr krb5_storage_free(sp); 175178825Sdfr if (ret) { 176178825Sdfr *minor_status = ret; 177178825Sdfr maj_stat = GSS_S_FAILURE; 178178825Sdfr } 179178825Sdfr return maj_stat; 180178825Sdfr} 181178825Sdfr 182233294Sstasstatic OM_uint32 inquire_sec_context_get_sspi_session_key 183233294Sstas (OM_uint32 *minor_status, 184233294Sstas const gsskrb5_ctx context_handle, 185233294Sstas krb5_context context, 186233294Sstas gss_buffer_set_t *data_set) 187233294Sstas{ 188233294Sstas krb5_keyblock *key; 189233294Sstas OM_uint32 maj_stat = GSS_S_COMPLETE; 190233294Sstas krb5_error_code ret; 191233294Sstas gss_buffer_desc value; 192233294Sstas 193233294Sstas HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex); 194233294Sstas ret = _gsskrb5i_get_token_key(context_handle, context, &key); 195233294Sstas HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); 196233294Sstas 197233294Sstas if (ret) 198233294Sstas goto out; 199233294Sstas if (key == NULL) { 200233294Sstas ret = EINVAL; 201233294Sstas goto out; 202233294Sstas } 203233294Sstas 204233294Sstas value.length = key->keyvalue.length; 205233294Sstas value.value = key->keyvalue.data; 206233294Sstas 207233294Sstas maj_stat = gss_add_buffer_set_member(minor_status, 208233294Sstas &value, 209233294Sstas data_set); 210233294Sstas krb5_free_keyblock(context, key); 211233294Sstas 212233294Sstas /* MIT also returns the enctype encoded as an OID in data_set[1] */ 213233294Sstas 214233294Sstasout: 215233294Sstas if (ret) { 216233294Sstas *minor_status = ret; 217233294Sstas maj_stat = GSS_S_FAILURE; 218233294Sstas } 219233294Sstas return maj_stat; 220233294Sstas} 221233294Sstas 222178825Sdfrstatic OM_uint32 inquire_sec_context_authz_data 223178825Sdfr (OM_uint32 *minor_status, 224178825Sdfr const gsskrb5_ctx context_handle, 225178825Sdfr krb5_context context, 226178825Sdfr unsigned ad_type, 227178825Sdfr gss_buffer_set_t *data_set) 228178825Sdfr{ 229178825Sdfr krb5_data data; 230178825Sdfr gss_buffer_desc ad_data; 231178825Sdfr OM_uint32 ret; 232178825Sdfr 233178825Sdfr *minor_status = 0; 234178825Sdfr *data_set = GSS_C_NO_BUFFER_SET; 235178825Sdfr 236178825Sdfr HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex); 237178825Sdfr if (context_handle->ticket == NULL) { 238178825Sdfr HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); 239178825Sdfr *minor_status = EINVAL; 240233294Sstas _gsskrb5_set_status(EINVAL, "No ticket to obtain authz data from"); 241178825Sdfr return GSS_S_NO_CONTEXT; 242178825Sdfr } 243178825Sdfr 244178825Sdfr ret = krb5_ticket_get_authorization_data_type(context, 245178825Sdfr context_handle->ticket, 246178825Sdfr ad_type, 247178825Sdfr &data); 248178825Sdfr HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); 249178825Sdfr if (ret) { 250178825Sdfr *minor_status = ret; 251178825Sdfr return GSS_S_FAILURE; 252178825Sdfr } 253178825Sdfr 254178825Sdfr ad_data.value = data.data; 255178825Sdfr ad_data.length = data.length; 256178825Sdfr 257178825Sdfr ret = gss_add_buffer_set_member(minor_status, 258178825Sdfr &ad_data, 259178825Sdfr data_set); 260178825Sdfr 261178825Sdfr krb5_data_free(&data); 262178825Sdfr 263178825Sdfr return ret; 264178825Sdfr} 265178825Sdfr 266178825Sdfrstatic OM_uint32 inquire_sec_context_has_updated_spnego 267178825Sdfr (OM_uint32 *minor_status, 268178825Sdfr const gsskrb5_ctx context_handle, 269178825Sdfr gss_buffer_set_t *data_set) 270178825Sdfr{ 271178825Sdfr int is_updated = 0; 272178825Sdfr 273178825Sdfr *minor_status = 0; 274178825Sdfr *data_set = GSS_C_NO_BUFFER_SET; 275178825Sdfr 276178825Sdfr /* 277178825Sdfr * For Windows SPNEGO implementations, both the initiator and the 278178825Sdfr * acceptor are assumed to have been updated if a "newer" [CLAR] or 279178825Sdfr * different enctype is negotiated for use by the Kerberos GSS-API 280178825Sdfr * mechanism. 281178825Sdfr */ 282178825Sdfr HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex); 283233294Sstas is_updated = (context_handle->more_flags & IS_CFX); 284178825Sdfr if (is_updated == 0) { 285178825Sdfr krb5_keyblock *acceptor_subkey; 286178825Sdfr 287178825Sdfr if (context_handle->more_flags & LOCAL) 288178825Sdfr acceptor_subkey = context_handle->auth_context->remote_subkey; 289178825Sdfr else 290178825Sdfr acceptor_subkey = context_handle->auth_context->local_subkey; 291178825Sdfr 292178825Sdfr if (acceptor_subkey != NULL) 293178825Sdfr is_updated = (acceptor_subkey->keytype != 294178825Sdfr context_handle->auth_context->keyblock->keytype); 295178825Sdfr } 296178825Sdfr HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); 297178825Sdfr 298178825Sdfr return is_updated ? GSS_S_COMPLETE : GSS_S_FAILURE; 299178825Sdfr} 300178825Sdfr 301178825Sdfr/* 302178825Sdfr * 303178825Sdfr */ 304178825Sdfr 305178825Sdfrstatic OM_uint32 306178825Sdfrexport_lucid_sec_context_v1(OM_uint32 *minor_status, 307178825Sdfr gsskrb5_ctx context_handle, 308178825Sdfr krb5_context context, 309178825Sdfr gss_buffer_set_t *data_set) 310178825Sdfr{ 311178825Sdfr krb5_storage *sp = NULL; 312178825Sdfr OM_uint32 major_status = GSS_S_COMPLETE; 313178825Sdfr krb5_error_code ret; 314178825Sdfr krb5_keyblock *key = NULL; 315178825Sdfr int32_t number; 316178825Sdfr int is_cfx; 317178825Sdfr krb5_data data; 318233294Sstas 319178825Sdfr *minor_status = 0; 320178825Sdfr 321178825Sdfr HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex); 322178825Sdfr 323233294Sstas is_cfx = (context_handle->more_flags & IS_CFX); 324178825Sdfr 325178825Sdfr sp = krb5_storage_emem(); 326178825Sdfr if (sp == NULL) { 327178825Sdfr _gsskrb5_clear_status(); 328178825Sdfr ret = ENOMEM; 329178825Sdfr goto out; 330178825Sdfr } 331178825Sdfr 332178825Sdfr ret = krb5_store_int32(sp, 1); 333178825Sdfr if (ret) goto out; 334178825Sdfr ret = krb5_store_int32(sp, (context_handle->more_flags & LOCAL) ? 1 : 0); 335178825Sdfr if (ret) goto out; 336178825Sdfr ret = krb5_store_int32(sp, context_handle->lifetime); 337178825Sdfr if (ret) goto out; 338178825Sdfr krb5_auth_con_getlocalseqnumber (context, 339178825Sdfr context_handle->auth_context, 340178825Sdfr &number); 341178825Sdfr ret = krb5_store_uint32(sp, (uint32_t)0); /* store top half as zero */ 342233294Sstas if (ret) goto out; 343178825Sdfr ret = krb5_store_uint32(sp, (uint32_t)number); 344233294Sstas if (ret) goto out; 345233294Sstas krb5_auth_con_getremoteseqnumber (context, 346233294Sstas context_handle->auth_context, 347233294Sstas &number); 348178825Sdfr ret = krb5_store_uint32(sp, (uint32_t)0); /* store top half as zero */ 349233294Sstas if (ret) goto out; 350178825Sdfr ret = krb5_store_uint32(sp, (uint32_t)number); 351233294Sstas if (ret) goto out; 352178825Sdfr ret = krb5_store_int32(sp, (is_cfx) ? 1 : 0); 353178825Sdfr if (ret) goto out; 354178825Sdfr 355178825Sdfr ret = _gsskrb5i_get_token_key(context_handle, context, &key); 356178825Sdfr if (ret) goto out; 357178825Sdfr 358178825Sdfr if (is_cfx == 0) { 359178825Sdfr int sign_alg, seal_alg; 360178825Sdfr 361178825Sdfr switch (key->keytype) { 362178825Sdfr case ETYPE_DES_CBC_CRC: 363178825Sdfr case ETYPE_DES_CBC_MD4: 364178825Sdfr case ETYPE_DES_CBC_MD5: 365178825Sdfr sign_alg = 0; 366178825Sdfr seal_alg = 0; 367178825Sdfr break; 368178825Sdfr case ETYPE_DES3_CBC_MD5: 369178825Sdfr case ETYPE_DES3_CBC_SHA1: 370178825Sdfr sign_alg = 4; 371178825Sdfr seal_alg = 2; 372178825Sdfr break; 373178825Sdfr case ETYPE_ARCFOUR_HMAC_MD5: 374178825Sdfr case ETYPE_ARCFOUR_HMAC_MD5_56: 375178825Sdfr sign_alg = 17; 376178825Sdfr seal_alg = 16; 377178825Sdfr break; 378178825Sdfr default: 379178825Sdfr sign_alg = -1; 380178825Sdfr seal_alg = -1; 381178825Sdfr break; 382178825Sdfr } 383178825Sdfr ret = krb5_store_int32(sp, sign_alg); 384178825Sdfr if (ret) goto out; 385178825Sdfr ret = krb5_store_int32(sp, seal_alg); 386178825Sdfr if (ret) goto out; 387178825Sdfr /* ctx_key */ 388178825Sdfr ret = krb5_store_keyblock(sp, *key); 389178825Sdfr if (ret) goto out; 390178825Sdfr } else { 391178825Sdfr int subkey_p = (context_handle->more_flags & ACCEPTOR_SUBKEY) ? 1 : 0; 392178825Sdfr 393178825Sdfr /* have_acceptor_subkey */ 394178825Sdfr ret = krb5_store_int32(sp, subkey_p); 395178825Sdfr if (ret) goto out; 396178825Sdfr /* ctx_key */ 397178825Sdfr ret = krb5_store_keyblock(sp, *key); 398178825Sdfr if (ret) goto out; 399178825Sdfr /* acceptor_subkey */ 400178825Sdfr if (subkey_p) { 401178825Sdfr ret = krb5_store_keyblock(sp, *key); 402178825Sdfr if (ret) goto out; 403178825Sdfr } 404178825Sdfr } 405178825Sdfr ret = krb5_storage_to_data(sp, &data); 406178825Sdfr if (ret) goto out; 407178825Sdfr 408178825Sdfr { 409178825Sdfr gss_buffer_desc ad_data; 410178825Sdfr 411178825Sdfr ad_data.value = data.data; 412178825Sdfr ad_data.length = data.length; 413178825Sdfr 414178825Sdfr ret = gss_add_buffer_set_member(minor_status, &ad_data, data_set); 415178825Sdfr krb5_data_free(&data); 416178825Sdfr if (ret) 417178825Sdfr goto out; 418178825Sdfr } 419178825Sdfr 420178825Sdfrout: 421178825Sdfr if (key) 422178825Sdfr krb5_free_keyblock (context, key); 423178825Sdfr if (sp) 424178825Sdfr krb5_storage_free(sp); 425178825Sdfr if (ret) { 426178825Sdfr *minor_status = ret; 427178825Sdfr major_status = GSS_S_FAILURE; 428178825Sdfr } 429178825Sdfr HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); 430178825Sdfr return major_status; 431178825Sdfr} 432178825Sdfr 433178825Sdfrstatic OM_uint32 434178825Sdfrget_authtime(OM_uint32 *minor_status, 435233294Sstas gsskrb5_ctx ctx, 436178825Sdfr gss_buffer_set_t *data_set) 437178825Sdfr 438178825Sdfr{ 439178825Sdfr gss_buffer_desc value; 440178825Sdfr unsigned char buf[4]; 441178825Sdfr OM_uint32 authtime; 442178825Sdfr 443178825Sdfr HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex); 444178825Sdfr if (ctx->ticket == NULL) { 445178825Sdfr HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); 446233294Sstas _gsskrb5_set_status(EINVAL, "No ticket to obtain auth time from"); 447178825Sdfr *minor_status = EINVAL; 448178825Sdfr return GSS_S_FAILURE; 449178825Sdfr } 450233294Sstas 451178825Sdfr authtime = ctx->ticket->ticket.authtime; 452233294Sstas 453178825Sdfr HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); 454178825Sdfr 455178825Sdfr _gsskrb5_encode_om_uint32(authtime, buf); 456178825Sdfr value.length = sizeof(buf); 457178825Sdfr value.value = buf; 458178825Sdfr 459178825Sdfr return gss_add_buffer_set_member(minor_status, 460178825Sdfr &value, 461178825Sdfr data_set); 462178825Sdfr} 463178825Sdfr 464178825Sdfr 465233294Sstasstatic OM_uint32 466178825Sdfrget_service_keyblock 467178825Sdfr (OM_uint32 *minor_status, 468233294Sstas gsskrb5_ctx ctx, 469178825Sdfr gss_buffer_set_t *data_set) 470178825Sdfr{ 471178825Sdfr krb5_storage *sp = NULL; 472178825Sdfr krb5_data data; 473178825Sdfr OM_uint32 maj_stat = GSS_S_COMPLETE; 474178825Sdfr krb5_error_code ret = EINVAL; 475233294Sstas 476178825Sdfr sp = krb5_storage_emem(); 477178825Sdfr if (sp == NULL) { 478178825Sdfr _gsskrb5_clear_status(); 479178825Sdfr *minor_status = ENOMEM; 480178825Sdfr return GSS_S_FAILURE; 481178825Sdfr } 482178825Sdfr 483178825Sdfr HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex); 484178825Sdfr if (ctx->service_keyblock == NULL) { 485178825Sdfr HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); 486233294Sstas krb5_storage_free(sp); 487233294Sstas _gsskrb5_set_status(EINVAL, "No service keyblock on gssapi context"); 488178825Sdfr *minor_status = EINVAL; 489233294Sstas return GSS_S_FAILURE; 490178825Sdfr } 491178825Sdfr 492178825Sdfr krb5_data_zero(&data); 493178825Sdfr 494178825Sdfr ret = krb5_store_keyblock(sp, *ctx->service_keyblock); 495178825Sdfr 496178825Sdfr HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); 497178825Sdfr 498178825Sdfr if (ret) 499178825Sdfr goto out; 500178825Sdfr 501178825Sdfr ret = krb5_storage_to_data(sp, &data); 502178825Sdfr if (ret) 503178825Sdfr goto out; 504178825Sdfr 505178825Sdfr { 506178825Sdfr gss_buffer_desc value; 507233294Sstas 508178825Sdfr value.length = data.length; 509178825Sdfr value.value = data.data; 510233294Sstas 511178825Sdfr maj_stat = gss_add_buffer_set_member(minor_status, 512178825Sdfr &value, 513178825Sdfr data_set); 514178825Sdfr } 515178825Sdfr 516178825Sdfrout: 517178825Sdfr krb5_data_free(&data); 518178825Sdfr if (sp) 519178825Sdfr krb5_storage_free(sp); 520178825Sdfr if (ret) { 521178825Sdfr *minor_status = ret; 522178825Sdfr maj_stat = GSS_S_FAILURE; 523178825Sdfr } 524178825Sdfr return maj_stat; 525178825Sdfr} 526178825Sdfr/* 527178825Sdfr * 528178825Sdfr */ 529178825Sdfr 530233294SstasOM_uint32 GSSAPI_CALLCONV _gsskrb5_inquire_sec_context_by_oid 531178825Sdfr (OM_uint32 *minor_status, 532178825Sdfr const gss_ctx_id_t context_handle, 533178825Sdfr const gss_OID desired_object, 534178825Sdfr gss_buffer_set_t *data_set) 535178825Sdfr{ 536178825Sdfr krb5_context context; 537178825Sdfr const gsskrb5_ctx ctx = (const gsskrb5_ctx) context_handle; 538178825Sdfr unsigned suffix; 539178825Sdfr 540178825Sdfr if (ctx == NULL) { 541178825Sdfr *minor_status = EINVAL; 542178825Sdfr return GSS_S_NO_CONTEXT; 543178825Sdfr } 544178825Sdfr 545178825Sdfr GSSAPI_KRB5_INIT (&context); 546178825Sdfr 547178825Sdfr if (gss_oid_equal(desired_object, GSS_KRB5_GET_TKT_FLAGS_X)) { 548178825Sdfr return inquire_sec_context_tkt_flags(minor_status, 549178825Sdfr ctx, 550178825Sdfr data_set); 551178825Sdfr } else if (gss_oid_equal(desired_object, GSS_C_PEER_HAS_UPDATED_SPNEGO)) { 552178825Sdfr return inquire_sec_context_has_updated_spnego(minor_status, 553178825Sdfr ctx, 554178825Sdfr data_set); 555178825Sdfr } else if (gss_oid_equal(desired_object, GSS_KRB5_GET_SUBKEY_X)) { 556178825Sdfr return inquire_sec_context_get_subkey(minor_status, 557178825Sdfr ctx, 558178825Sdfr context, 559178825Sdfr TOKEN_KEY, 560178825Sdfr data_set); 561178825Sdfr } else if (gss_oid_equal(desired_object, GSS_KRB5_GET_INITIATOR_SUBKEY_X)) { 562178825Sdfr return inquire_sec_context_get_subkey(minor_status, 563178825Sdfr ctx, 564178825Sdfr context, 565178825Sdfr INITIATOR_KEY, 566178825Sdfr data_set); 567178825Sdfr } else if (gss_oid_equal(desired_object, GSS_KRB5_GET_ACCEPTOR_SUBKEY_X)) { 568178825Sdfr return inquire_sec_context_get_subkey(minor_status, 569178825Sdfr ctx, 570178825Sdfr context, 571178825Sdfr ACCEPTOR_KEY, 572178825Sdfr data_set); 573233294Sstas } else if (gss_oid_equal(desired_object, GSS_C_INQ_SSPI_SESSION_KEY)) { 574233294Sstas return inquire_sec_context_get_sspi_session_key(minor_status, 575233294Sstas ctx, 576233294Sstas context, 577233294Sstas data_set); 578178825Sdfr } else if (gss_oid_equal(desired_object, GSS_KRB5_GET_AUTHTIME_X)) { 579178825Sdfr return get_authtime(minor_status, ctx, data_set); 580178825Sdfr } else if (oid_prefix_equal(desired_object, 581178825Sdfr GSS_KRB5_EXTRACT_AUTHZ_DATA_FROM_SEC_CONTEXT_X, 582178825Sdfr &suffix)) { 583178825Sdfr return inquire_sec_context_authz_data(minor_status, 584178825Sdfr ctx, 585178825Sdfr context, 586178825Sdfr suffix, 587178825Sdfr data_set); 588178825Sdfr } else if (oid_prefix_equal(desired_object, 589178825Sdfr GSS_KRB5_EXPORT_LUCID_CONTEXT_X, 590178825Sdfr &suffix)) { 591178825Sdfr if (suffix == 1) 592178825Sdfr return export_lucid_sec_context_v1(minor_status, 593178825Sdfr ctx, 594178825Sdfr context, 595178825Sdfr data_set); 596178825Sdfr *minor_status = 0; 597178825Sdfr return GSS_S_FAILURE; 598178825Sdfr } else if (gss_oid_equal(desired_object, GSS_KRB5_GET_SERVICE_KEYBLOCK_X)) { 599178825Sdfr return get_service_keyblock(minor_status, ctx, data_set); 600178825Sdfr } else { 601178825Sdfr *minor_status = 0; 602178825Sdfr return GSS_S_FAILURE; 603178825Sdfr } 604178825Sdfr} 605178825Sdfr 606