Path: blob/main/crypto/heimdal/lib/gssapi/spnego/context_stubs.c
34907 views
/*1* Copyright (c) 2004, PADL Software Pty Ltd.2* All rights reserved.3*4* Redistribution and use in source and binary forms, with or without5* modification, are permitted provided that the following conditions6* are met:7*8* 1. Redistributions of source code must retain the above copyright9* notice, this list of conditions and the following disclaimer.10*11* 2. Redistributions in binary form must reproduce the above copyright12* notice, this list of conditions and the following disclaimer in the13* documentation and/or other materials provided with the distribution.14*15* 3. Neither the name of PADL Software nor the names of its contributors16* may be used to endorse or promote products derived from this software17* without specific prior written permission.18*19* THIS SOFTWARE IS PROVIDED BY PADL SOFTWARE AND CONTRIBUTORS ``AS IS'' AND20* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE21* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE22* ARE DISCLAIMED. IN NO EVENT SHALL PADL SOFTWARE OR CONTRIBUTORS BE LIABLE23* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL24* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS25* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)26* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT27* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY28* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF29* SUCH DAMAGE.30*/3132#include "spnego_locl.h"3334static OM_uint3235spnego_supported_mechs(OM_uint32 *minor_status, gss_OID_set *mechs)36{37OM_uint32 ret, junk;38gss_OID_set m;39size_t i;4041ret = gss_indicate_mechs(minor_status, &m);42if (ret != GSS_S_COMPLETE)43return ret;4445ret = gss_create_empty_oid_set(minor_status, mechs);46if (ret != GSS_S_COMPLETE) {47gss_release_oid_set(&junk, &m);48return ret;49}5051for (i = 0; i < m->count; i++) {52if (gss_oid_equal(&m->elements[i], GSS_SPNEGO_MECHANISM))53continue;5455ret = gss_add_oid_set_member(minor_status, &m->elements[i], mechs);56if (ret) {57gss_release_oid_set(&junk, &m);58gss_release_oid_set(&junk, mechs);59return ret;60}61}62gss_release_oid_set(&junk, &m);63return ret;64}65666768OM_uint32 GSSAPI_CALLCONV _gss_spnego_process_context_token69(OM_uint32 *minor_status,70const gss_ctx_id_t context_handle,71const gss_buffer_t token_buffer72)73{74gss_ctx_id_t context ;75gssspnego_ctx ctx;76OM_uint32 ret;7778if (context_handle == GSS_C_NO_CONTEXT)79return GSS_S_NO_CONTEXT;8081context = context_handle;82ctx = (gssspnego_ctx)context_handle;8384HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);8586ret = gss_process_context_token(minor_status,87ctx->negotiated_ctx_id,88token_buffer);89if (ret != GSS_S_COMPLETE) {90HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);91return ret;92}9394ctx->negotiated_ctx_id = GSS_C_NO_CONTEXT;9596return _gss_spnego_internal_delete_sec_context(minor_status,97&context,98GSS_C_NO_BUFFER);99}100101OM_uint32 GSSAPI_CALLCONV _gss_spnego_delete_sec_context102(OM_uint32 *minor_status,103gss_ctx_id_t *context_handle,104gss_buffer_t output_token105)106{107gssspnego_ctx ctx;108109if (context_handle == NULL || *context_handle == GSS_C_NO_CONTEXT)110return GSS_S_NO_CONTEXT;111112ctx = (gssspnego_ctx)*context_handle;113114HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);115116return _gss_spnego_internal_delete_sec_context(minor_status,117context_handle,118output_token);119}120121OM_uint32 GSSAPI_CALLCONV _gss_spnego_context_time122(OM_uint32 *minor_status,123const gss_ctx_id_t context_handle,124OM_uint32 *time_rec125)126{127gssspnego_ctx ctx;128*minor_status = 0;129130if (context_handle == GSS_C_NO_CONTEXT) {131return GSS_S_NO_CONTEXT;132}133134ctx = (gssspnego_ctx)context_handle;135136if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) {137return GSS_S_NO_CONTEXT;138}139140return gss_context_time(minor_status,141ctx->negotiated_ctx_id,142time_rec);143}144145OM_uint32 GSSAPI_CALLCONV _gss_spnego_get_mic146(OM_uint32 *minor_status,147const gss_ctx_id_t context_handle,148gss_qop_t qop_req,149const gss_buffer_t message_buffer,150gss_buffer_t message_token151)152{153gssspnego_ctx ctx;154155*minor_status = 0;156157if (context_handle == GSS_C_NO_CONTEXT) {158return GSS_S_NO_CONTEXT;159}160161ctx = (gssspnego_ctx)context_handle;162163if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) {164return GSS_S_NO_CONTEXT;165}166167return gss_get_mic(minor_status, ctx->negotiated_ctx_id,168qop_req, message_buffer, message_token);169}170171OM_uint32 GSSAPI_CALLCONV _gss_spnego_verify_mic172(OM_uint32 * minor_status,173const gss_ctx_id_t context_handle,174const gss_buffer_t message_buffer,175const gss_buffer_t token_buffer,176gss_qop_t * qop_state177)178{179gssspnego_ctx ctx;180181*minor_status = 0;182183if (context_handle == GSS_C_NO_CONTEXT) {184return GSS_S_NO_CONTEXT;185}186187ctx = (gssspnego_ctx)context_handle;188189if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) {190return GSS_S_NO_CONTEXT;191}192193return gss_verify_mic(minor_status,194ctx->negotiated_ctx_id,195message_buffer,196token_buffer,197qop_state);198}199200OM_uint32 GSSAPI_CALLCONV _gss_spnego_wrap201(OM_uint32 * minor_status,202const gss_ctx_id_t context_handle,203int conf_req_flag,204gss_qop_t qop_req,205const gss_buffer_t input_message_buffer,206int * conf_state,207gss_buffer_t output_message_buffer208)209{210gssspnego_ctx ctx;211212*minor_status = 0;213214if (context_handle == GSS_C_NO_CONTEXT) {215return GSS_S_NO_CONTEXT;216}217218ctx = (gssspnego_ctx)context_handle;219220if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) {221return GSS_S_NO_CONTEXT;222}223224return gss_wrap(minor_status,225ctx->negotiated_ctx_id,226conf_req_flag,227qop_req,228input_message_buffer,229conf_state,230output_message_buffer);231}232233OM_uint32 GSSAPI_CALLCONV _gss_spnego_unwrap234(OM_uint32 * minor_status,235const gss_ctx_id_t context_handle,236const gss_buffer_t input_message_buffer,237gss_buffer_t output_message_buffer,238int * conf_state,239gss_qop_t * qop_state240)241{242gssspnego_ctx ctx;243244*minor_status = 0;245246if (context_handle == GSS_C_NO_CONTEXT) {247return GSS_S_NO_CONTEXT;248}249250ctx = (gssspnego_ctx)context_handle;251252if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) {253return GSS_S_NO_CONTEXT;254}255256return gss_unwrap(minor_status,257ctx->negotiated_ctx_id,258input_message_buffer,259output_message_buffer,260conf_state,261qop_state);262}263264OM_uint32 GSSAPI_CALLCONV _gss_spnego_compare_name265(OM_uint32 *minor_status,266const gss_name_t name1,267const gss_name_t name2,268int * name_equal269)270{271spnego_name n1 = (spnego_name)name1;272spnego_name n2 = (spnego_name)name2;273274*name_equal = 0;275276if (!gss_oid_equal(&n1->type, &n2->type))277return GSS_S_COMPLETE;278if (n1->value.length != n2->value.length)279return GSS_S_COMPLETE;280if (memcmp(n1->value.value, n2->value.value, n2->value.length) != 0)281return GSS_S_COMPLETE;282283*name_equal = 1;284285return GSS_S_COMPLETE;286}287288OM_uint32 GSSAPI_CALLCONV _gss_spnego_display_name289(OM_uint32 * minor_status,290const gss_name_t input_name,291gss_buffer_t output_name_buffer,292gss_OID * output_name_type293)294{295spnego_name name = (spnego_name)input_name;296297*minor_status = 0;298299if (name == NULL || name->mech == GSS_C_NO_NAME)300return GSS_S_FAILURE;301302return gss_display_name(minor_status, name->mech,303output_name_buffer, output_name_type);304}305306OM_uint32 GSSAPI_CALLCONV _gss_spnego_import_name307(OM_uint32 * minor_status,308const gss_buffer_t name_buffer,309const gss_OID name_type,310gss_name_t * output_name311)312{313spnego_name name;314OM_uint32 maj_stat;315316*minor_status = 0;317318name = calloc(1, sizeof(*name));319if (name == NULL) {320*minor_status = ENOMEM;321return GSS_S_FAILURE;322}323324maj_stat = _gss_copy_oid(minor_status, name_type, &name->type);325if (maj_stat) {326free(name);327return GSS_S_FAILURE;328}329330maj_stat = _gss_copy_buffer(minor_status, name_buffer, &name->value);331if (maj_stat) {332gss_name_t rname = (gss_name_t)name;333_gss_spnego_release_name(minor_status, &rname);334return GSS_S_FAILURE;335}336name->mech = GSS_C_NO_NAME;337*output_name = (gss_name_t)name;338339return GSS_S_COMPLETE;340}341342OM_uint32 GSSAPI_CALLCONV _gss_spnego_export_name343(OM_uint32 * minor_status,344const gss_name_t input_name,345gss_buffer_t exported_name346)347{348spnego_name name;349*minor_status = 0;350351if (input_name == GSS_C_NO_NAME)352return GSS_S_BAD_NAME;353354name = (spnego_name)input_name;355if (name->mech == GSS_C_NO_NAME)356return GSS_S_BAD_NAME;357358return gss_export_name(minor_status, name->mech, exported_name);359}360361OM_uint32 GSSAPI_CALLCONV _gss_spnego_release_name362(OM_uint32 * minor_status,363gss_name_t * input_name364)365{366*minor_status = 0;367368if (*input_name != GSS_C_NO_NAME) {369OM_uint32 junk;370spnego_name name = (spnego_name)*input_name;371_gss_free_oid(&junk, &name->type);372gss_release_buffer(&junk, &name->value);373if (name->mech != GSS_C_NO_NAME)374gss_release_name(&junk, &name->mech);375free(name);376377*input_name = GSS_C_NO_NAME;378}379return GSS_S_COMPLETE;380}381382OM_uint32 GSSAPI_CALLCONV _gss_spnego_inquire_context (383OM_uint32 * minor_status,384const gss_ctx_id_t context_handle,385gss_name_t * src_name,386gss_name_t * targ_name,387OM_uint32 * lifetime_rec,388gss_OID * mech_type,389OM_uint32 * ctx_flags,390int * locally_initiated,391int * open_context392)393{394gssspnego_ctx ctx;395OM_uint32 maj_stat, junk;396gss_name_t src_mn, targ_mn;397398*minor_status = 0;399400if (context_handle == GSS_C_NO_CONTEXT)401return GSS_S_NO_CONTEXT;402403ctx = (gssspnego_ctx)context_handle;404405if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT)406return GSS_S_NO_CONTEXT;407408maj_stat = gss_inquire_context(minor_status,409ctx->negotiated_ctx_id,410&src_mn,411&targ_mn,412lifetime_rec,413mech_type,414ctx_flags,415locally_initiated,416open_context);417if (maj_stat != GSS_S_COMPLETE)418return maj_stat;419420if (src_name) {421spnego_name name = calloc(1, sizeof(*name));422if (name == NULL)423goto enomem;424name->mech = src_mn;425*src_name = (gss_name_t)name;426} else427gss_release_name(&junk, &src_mn);428429if (targ_name) {430spnego_name name = calloc(1, sizeof(*name));431if (name == NULL) {432gss_release_name(minor_status, src_name);433goto enomem;434}435name->mech = targ_mn;436*targ_name = (gss_name_t)name;437} else438gss_release_name(&junk, &targ_mn);439440return GSS_S_COMPLETE;441442enomem:443gss_release_name(&junk, &targ_mn);444gss_release_name(&junk, &src_mn);445*minor_status = ENOMEM;446return GSS_S_FAILURE;447}448449OM_uint32 GSSAPI_CALLCONV _gss_spnego_wrap_size_limit (450OM_uint32 * minor_status,451const gss_ctx_id_t context_handle,452int conf_req_flag,453gss_qop_t qop_req,454OM_uint32 req_output_size,455OM_uint32 * max_input_size456)457{458gssspnego_ctx ctx;459460*minor_status = 0;461462if (context_handle == GSS_C_NO_CONTEXT) {463return GSS_S_NO_CONTEXT;464}465466ctx = (gssspnego_ctx)context_handle;467468if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) {469return GSS_S_NO_CONTEXT;470}471472return gss_wrap_size_limit(minor_status,473ctx->negotiated_ctx_id,474conf_req_flag,475qop_req,476req_output_size,477max_input_size);478}479480OM_uint32 GSSAPI_CALLCONV _gss_spnego_export_sec_context (481OM_uint32 * minor_status,482gss_ctx_id_t * context_handle,483gss_buffer_t interprocess_token484)485{486gssspnego_ctx ctx;487OM_uint32 ret;488489*minor_status = 0;490491if (context_handle == NULL) {492return GSS_S_NO_CONTEXT;493}494495ctx = (gssspnego_ctx)*context_handle;496497if (ctx == NULL)498return GSS_S_NO_CONTEXT;499500HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);501502if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) {503HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);504return GSS_S_NO_CONTEXT;505}506507ret = gss_export_sec_context(minor_status,508&ctx->negotiated_ctx_id,509interprocess_token);510if (ret == GSS_S_COMPLETE) {511ret = _gss_spnego_internal_delete_sec_context(minor_status,512context_handle,513GSS_C_NO_BUFFER);514if (ret == GSS_S_COMPLETE)515return GSS_S_COMPLETE;516}517518HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);519520return ret;521}522523OM_uint32 GSSAPI_CALLCONV _gss_spnego_import_sec_context (524OM_uint32 * minor_status,525const gss_buffer_t interprocess_token,526gss_ctx_id_t *context_handle527)528{529OM_uint32 ret, minor;530gss_ctx_id_t context;531gssspnego_ctx ctx;532533ret = _gss_spnego_alloc_sec_context(minor_status, &context);534if (ret != GSS_S_COMPLETE) {535return ret;536}537ctx = (gssspnego_ctx)context;538539HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);540541ret = gss_import_sec_context(minor_status,542interprocess_token,543&ctx->negotiated_ctx_id);544if (ret != GSS_S_COMPLETE) {545_gss_spnego_internal_delete_sec_context(&minor, context_handle, GSS_C_NO_BUFFER);546return ret;547}548549ctx->open = 1;550/* don't bother filling in the rest of the fields */551552HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);553554*context_handle = (gss_ctx_id_t)ctx;555556return GSS_S_COMPLETE;557}558559OM_uint32 GSSAPI_CALLCONV _gss_spnego_inquire_names_for_mech (560OM_uint32 * minor_status,561const gss_OID mechanism,562gss_OID_set * name_types563)564{565gss_OID_set mechs, names, n;566OM_uint32 ret, junk;567size_t i, j;568569*name_types = NULL;570571ret = spnego_supported_mechs(minor_status, &mechs);572if (ret != GSS_S_COMPLETE)573return ret;574575ret = gss_create_empty_oid_set(minor_status, &names);576if (ret != GSS_S_COMPLETE)577goto out;578579for (i = 0; i < mechs->count; i++) {580ret = gss_inquire_names_for_mech(minor_status,581&mechs->elements[i],582&n);583if (ret)584continue;585586for (j = 0; j < n->count; j++)587gss_add_oid_set_member(minor_status,588&n->elements[j],589&names);590gss_release_oid_set(&junk, &n);591}592593ret = GSS_S_COMPLETE;594*name_types = names;595out:596597gss_release_oid_set(&junk, &mechs);598599return ret;600}601602OM_uint32 GSSAPI_CALLCONV _gss_spnego_inquire_mechs_for_name (603OM_uint32 * minor_status,604const gss_name_t input_name,605gss_OID_set * mech_types606)607{608OM_uint32 ret, junk;609610ret = gss_create_empty_oid_set(minor_status, mech_types);611if (ret)612return ret;613614ret = gss_add_oid_set_member(minor_status,615GSS_SPNEGO_MECHANISM,616mech_types);617if (ret)618gss_release_oid_set(&junk, mech_types);619620return ret;621}622623OM_uint32 GSSAPI_CALLCONV _gss_spnego_canonicalize_name (624OM_uint32 * minor_status,625const gss_name_t input_name,626const gss_OID mech_type,627gss_name_t * output_name628)629{630/* XXX */631return gss_duplicate_name(minor_status, input_name, output_name);632}633634OM_uint32 GSSAPI_CALLCONV _gss_spnego_duplicate_name (635OM_uint32 * minor_status,636const gss_name_t src_name,637gss_name_t * dest_name638)639{640return gss_duplicate_name(minor_status, src_name, dest_name);641}642643#if 0644OM_uint32 GSSAPI_CALLCONV645_gss_spnego_wrap_iov(OM_uint32 * minor_status,646gss_ctx_id_t context_handle,647int conf_req_flag,648gss_qop_t qop_req,649int * conf_state,650gss_iov_buffer_desc *iov,651int iov_count)652{653gssspnego_ctx ctx = (gssspnego_ctx)context_handle;654655*minor_status = 0;656657if (ctx == NULL || ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT)658return GSS_S_NO_CONTEXT;659660return gss_wrap_iov(minor_status, ctx->negotiated_ctx_id,661conf_req_flag, qop_req, conf_state,662iov, iov_count);663}664665OM_uint32 GSSAPI_CALLCONV666_gss_spnego_unwrap_iov(OM_uint32 *minor_status,667gss_ctx_id_t context_handle,668int *conf_state,669gss_qop_t *qop_state,670gss_iov_buffer_desc *iov,671int iov_count)672{673gssspnego_ctx ctx = (gssspnego_ctx)context_handle;674675*minor_status = 0;676677if (ctx == NULL || ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT)678return GSS_S_NO_CONTEXT;679680return gss_unwrap_iov(minor_status,681ctx->negotiated_ctx_id,682conf_state, qop_state,683iov, iov_count);684}685686OM_uint32 GSSAPI_CALLCONV687_gss_spnego_wrap_iov_length(OM_uint32 * minor_status,688gss_ctx_id_t context_handle,689int conf_req_flag,690gss_qop_t qop_req,691int *conf_state,692gss_iov_buffer_desc *iov,693int iov_count)694{695gssspnego_ctx ctx = (gssspnego_ctx)context_handle;696697*minor_status = 0;698699if (ctx == NULL || ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT)700return GSS_S_NO_CONTEXT;701702return gss_wrap_iov_length(minor_status, ctx->negotiated_ctx_id,703conf_req_flag, qop_req, conf_state,704iov, iov_count);705}706707#endif708709#if 0710OM_uint32 GSSAPI_CALLCONV _gss_spnego_complete_auth_token711(OM_uint32 * minor_status,712const gss_ctx_id_t context_handle,713gss_buffer_t input_message_buffer)714{715gssspnego_ctx ctx;716717*minor_status = 0;718719if (context_handle == GSS_C_NO_CONTEXT) {720return GSS_S_NO_CONTEXT;721}722723ctx = (gssspnego_ctx)context_handle;724725if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) {726return GSS_S_NO_CONTEXT;727}728729return gss_complete_auth_token(minor_status,730ctx->negotiated_ctx_id,731input_message_buffer);732}733#endif734735OM_uint32 GSSAPI_CALLCONV _gss_spnego_inquire_sec_context_by_oid736(OM_uint32 * minor_status,737const gss_ctx_id_t context_handle,738const gss_OID desired_object,739gss_buffer_set_t *data_set)740{741gssspnego_ctx ctx;742743*minor_status = 0;744745if (context_handle == GSS_C_NO_CONTEXT) {746return GSS_S_NO_CONTEXT;747}748749ctx = (gssspnego_ctx)context_handle;750751if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) {752return GSS_S_NO_CONTEXT;753}754755return gss_inquire_sec_context_by_oid(minor_status,756ctx->negotiated_ctx_id,757desired_object,758data_set);759}760761OM_uint32 GSSAPI_CALLCONV _gss_spnego_set_sec_context_option762(OM_uint32 * minor_status,763gss_ctx_id_t * context_handle,764const gss_OID desired_object,765const gss_buffer_t value)766{767gssspnego_ctx ctx;768769*minor_status = 0;770771if (context_handle == NULL || *context_handle == GSS_C_NO_CONTEXT) {772return GSS_S_NO_CONTEXT;773}774775ctx = (gssspnego_ctx)*context_handle;776777if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) {778return GSS_S_NO_CONTEXT;779}780781return gss_set_sec_context_option(minor_status,782&ctx->negotiated_ctx_id,783desired_object,784value);785}786787788OM_uint32 GSSAPI_CALLCONV789_gss_spnego_pseudo_random(OM_uint32 *minor_status,790gss_ctx_id_t context_handle,791int prf_key,792const gss_buffer_t prf_in,793ssize_t desired_output_len,794gss_buffer_t prf_out)795{796gssspnego_ctx ctx;797798*minor_status = 0;799800if (context_handle == GSS_C_NO_CONTEXT)801return GSS_S_NO_CONTEXT;802803ctx = (gssspnego_ctx)context_handle;804805if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT)806return GSS_S_NO_CONTEXT;807808return gss_pseudo_random(minor_status,809ctx->negotiated_ctx_id,810prf_key,811prf_in,812desired_output_len,813prf_out);814}815816817