X-Git-Url: http://www.project-moonshot.org/gitweb/?a=blobdiff_plain;f=display_status.c;h=8729a96be81e81d19bb3d638664f9344be994fae;hb=refs%2Fheads%2Fjson-name;hp=ebe66bd95b4f9954e21fa6b47f3bd2ce5bcb3fea;hpb=9af21373654beae5e003dcc05806abc577a50b68;p=mech_eap.orig diff --git a/display_status.c b/display_status.c index ebe66bd..8729a96 100644 --- a/display_status.c +++ b/display_status.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, JANET(UK) + * Copyright (c) 2011, JANET(UK) * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -30,6 +30,10 @@ * SUCH DAMAGE. */ +/* + * Function for converting mechanism error codes to strings. + */ + #include "gssapiP_eap.h" static GSSEAP_THREAD_ONCE gssEapStatusInfoKeyOnce = GSSEAP_ONCE_INITIALIZER; @@ -59,33 +63,46 @@ createStatusInfoKey(void) GSSEAP_KEY_CREATE(&gssEapStatusInfoKey, destroyStatusInfo); } +/* + * Associate a message with a mechanism (minor) status code. This function + * takes ownership of the message regardless of success. The message must + * be explicitly cleared, if required, so it is suggested that a specific + * minor code is either always or never associated with a message, to avoid + * dangling (and potentially confusing) error messages. + */ static void saveStatusInfoNoCopy(OM_uint32 minor, char *message) { - struct gss_eap_status_info *info, *p; + struct gss_eap_status_info **next = NULL, *p; GSSEAP_ONCE(&gssEapStatusInfoKeyOnce, createStatusInfoKey); - info = GSSEAP_CALLOC(1, sizeof(*info)); - if (info == NULL) { - GSSEAP_FREE(message); - return; + p = GSSEAP_GETSPECIFIC(gssEapStatusInfoKey); + for (; p != NULL; p = p->next) { + if (p->code == minor) { + /* Set message in-place */ + if (p->message != NULL) + GSSEAP_FREE(p->message); + p->message = message; + return; + } + next = &p->next; } - info->code = minor; - info->message = message; - - p = GSSEAP_GETSPECIFIC(gssEapStatusInfoKey); + p = GSSEAP_CALLOC(1, sizeof(*p)); if (p == NULL) { - GSSEAP_SETSPECIFIC(gssEapStatusInfoKey, info); - } else { - struct gss_eap_status_info **next = &p; + if (message != NULL) + GSSEAP_FREE(message); + return; + } - for (; p != NULL; p = p->next) - next = &p->next; + p->code = minor; + p->message = message; - *next = info; - } + if (next != NULL) + *next = p; + else + GSSEAP_SETSPECIFIC(gssEapStatusInfoKey, p); } static const char * @@ -128,7 +145,7 @@ gss_display_status(OM_uint32 *minor, OM_uint32 *message_context, gss_buffer_t status_string) { - OM_uint32 major = GSS_S_COMPLETE; + OM_uint32 major; krb5_context krbContext = NULL; const char *errMsg; @@ -136,11 +153,14 @@ gss_display_status(OM_uint32 *minor, status_string->value = NULL; if (!gssEapIsMechanismOid(mech_type)) { + *minor = GSSEAP_WRONG_MECH; return GSS_S_BAD_MECH; } - if (status_type != GSS_C_MECH_CODE) { + if (status_type != GSS_C_MECH_CODE || + *message_context != 0) { /* we rely on the mechglue for GSS_C_GSS_CODE */ + *minor = 0; return GSS_S_BAD_STATUS; } @@ -148,11 +168,16 @@ gss_display_status(OM_uint32 *minor, if (errMsg == NULL) { GSSEAP_KRB_INIT(&krbContext); + /* Try the com_err message */ errMsg = krb5_get_error_message(krbContext, status_value); } - if (errMsg != NULL) + if (errMsg != NULL) { major = makeStringBuffer(minor, errMsg, status_string); + } else { + major = GSS_S_COMPLETE; + *minor = 0; + } if (krbContext != NULL) krb5_free_error_message(krbContext, errMsg);