Path: blob/main/crypto/heimdal/lib/gssapi/mech/context.c
34907 views
#include "mech_locl.h"1#include "heim_threads.h"23struct mg_thread_ctx {4gss_OID mech;5OM_uint32 maj_stat;6OM_uint32 min_stat;7gss_buffer_desc maj_error;8gss_buffer_desc min_error;9};1011static HEIMDAL_MUTEX context_mutex = HEIMDAL_MUTEX_INITIALIZER;12static int created_key;13static HEIMDAL_thread_key context_key;141516static void17destroy_context(void *ptr)18{19struct mg_thread_ctx *mg = ptr;20OM_uint32 junk;2122if (mg == NULL)23return;2425gss_release_buffer(&junk, &mg->maj_error);26gss_release_buffer(&junk, &mg->min_error);27free(mg);28}293031static struct mg_thread_ctx *32_gss_mechglue_thread(void)33{34struct mg_thread_ctx *ctx;35int ret = 0;3637HEIMDAL_MUTEX_lock(&context_mutex);3839if (!created_key) {40HEIMDAL_key_create(&context_key, destroy_context, ret);41if (ret) {42HEIMDAL_MUTEX_unlock(&context_mutex);43return NULL;44}45created_key = 1;46}47HEIMDAL_MUTEX_unlock(&context_mutex);4849ctx = HEIMDAL_getspecific(context_key);50if (ctx == NULL) {5152ctx = calloc(1, sizeof(*ctx));53if (ctx == NULL)54return NULL;55HEIMDAL_setspecific(context_key, ctx, ret);56if (ret) {57free(ctx);58return NULL;59}60}61return ctx;62}6364OM_uint3265_gss_mg_get_error(const gss_OID mech, OM_uint32 type,66OM_uint32 value, gss_buffer_t string)67{68struct mg_thread_ctx *mg;6970mg = _gss_mechglue_thread();71if (mg == NULL)72return GSS_S_BAD_STATUS;7374#if 075/*76* We cant check the mech here since a pseudo-mech might have77* called an lower layer and then the mech info is all broken78*/79if (mech != NULL && gss_oid_equal(mg->mech, mech) == 0)80return GSS_S_BAD_STATUS;81#endif8283switch (type) {84case GSS_C_GSS_CODE: {85if (value != mg->maj_stat || mg->maj_error.length == 0)86break;87string->value = malloc(mg->maj_error.length + 1);88string->length = mg->maj_error.length;89memcpy(string->value, mg->maj_error.value, mg->maj_error.length);90((char *) string->value)[string->length] = '\0';91return GSS_S_COMPLETE;92}93case GSS_C_MECH_CODE: {94if (value != mg->min_stat || mg->min_error.length == 0)95break;96string->value = malloc(mg->min_error.length + 1);97string->length = mg->min_error.length;98memcpy(string->value, mg->min_error.value, mg->min_error.length);99((char *) string->value)[string->length] = '\0';100return GSS_S_COMPLETE;101}102}103string->value = NULL;104string->length = 0;105return GSS_S_BAD_STATUS;106}107108void109_gss_mg_error(gssapi_mech_interface m, OM_uint32 maj, OM_uint32 min)110{111OM_uint32 major_status, minor_status;112OM_uint32 message_content;113struct mg_thread_ctx *mg;114115/*116* Mechs without gss_display_status() does117* gss_mg_collect_error() by themself.118*/119if (m->gm_display_status == NULL)120return ;121122mg = _gss_mechglue_thread();123if (mg == NULL)124return;125126gss_release_buffer(&minor_status, &mg->maj_error);127gss_release_buffer(&minor_status, &mg->min_error);128129mg->mech = &m->gm_mech_oid;130mg->maj_stat = maj;131mg->min_stat = min;132133major_status = m->gm_display_status(&minor_status,134maj,135GSS_C_GSS_CODE,136&m->gm_mech_oid,137&message_content,138&mg->maj_error);139if (GSS_ERROR(major_status)) {140mg->maj_error.value = NULL;141mg->maj_error.length = 0;142}143major_status = m->gm_display_status(&minor_status,144min,145GSS_C_MECH_CODE,146&m->gm_mech_oid,147&message_content,148&mg->min_error);149if (GSS_ERROR(major_status)) {150mg->min_error.value = NULL;151mg->min_error.length = 0;152}153}154155void156gss_mg_collect_error(gss_OID mech, OM_uint32 maj, OM_uint32 min)157{158gssapi_mech_interface m = __gss_get_mechanism(mech);159if (m == NULL)160return;161_gss_mg_error(m, maj, min);162}163164165