From cf651f093e72306929b29a67af1242dfad47ca58 Mon Sep 17 00:00:00 2001 From: Luke Howard Date: Tue, 28 Sep 2010 01:18:22 +0200 Subject: [PATCH] be careful to lock cred before using it --- accept_sec_context.c | 23 +++++++++++++---------- gssapiP_eap.h | 1 + init_sec_context.c | 43 +++++++++++++++++++------------------------ inquire_cred.c | 7 +++++++ set_cred_option.c | 11 ++++++++--- 5 files changed, 48 insertions(+), 37 deletions(-) diff --git a/accept_sec_context.c b/accept_sec_context.c index 6b0bb6a..5dd68f2 100644 --- a/accept_sec_context.c +++ b/accept_sec_context.c @@ -504,11 +504,6 @@ gss_accept_sec_context(OM_uint32 *minor, output_token->length = 0; output_token->value = NULL; - if (cred != GSS_C_NO_CREDENTIAL && - (cred->flags & CRED_FLAG_ACCEPT) == 0) { - return GSS_S_NO_CRED; - } - if (input_token == GSS_C_NO_BUFFER || input_token->length == 0) { return GSS_S_DEFECTIVE_TOKEN; } @@ -547,11 +542,17 @@ gss_accept_sec_context(OM_uint32 *minor, goto cleanup; } - /* If credentials were provided, check they're usable with this mech */ - if (cred != GSS_C_NO_CREDENTIAL && - !gssEapCredAvailable(cred, ctx->mechanismUsed)) { - major = GSS_S_BAD_MECH; - goto cleanup; + /* Validate and lock credentials */ + if (cred != GSS_C_NO_CREDENTIAL) { + if ((cred->flags & CRED_FLAG_ACCEPT) == 0) { + major = GSS_S_NO_CRED; + goto cleanup; + } else if (!gssEapCredAvailable(cred, ctx->mechanismUsed)) { + major = GSS_S_BAD_MECH; + goto cleanup; + } + + GSSEAP_MUTEX_LOCK(&cred->mutex); } do { @@ -598,6 +599,8 @@ gss_accept_sec_context(OM_uint32 *minor, assert(ctx->state == EAP_STATE_ESTABLISHED || major == GSS_S_CONTINUE_NEEDED); cleanup: + if (cred != GSS_C_NO_CREDENTIAL) + GSSEAP_MUTEX_UNLOCK(&cred->mutex); GSSEAP_MUTEX_UNLOCK(&ctx->mutex); if (GSS_ERROR(major)) diff --git a/gssapiP_eap.h b/gssapiP_eap.h index c6c634e..8dcb311 100644 --- a/gssapiP_eap.h +++ b/gssapiP_eap.h @@ -83,6 +83,7 @@ struct gss_name_struct { #define CRED_FLAG_ACCEPT 0x00020000 #define CRED_FLAG_DEFAULT_IDENTITY 0x00040000 #define CRED_FLAG_PASSWORD 0x00080000 +#define CRED_FLAG_DEFAULT_CCACHE 0x00100000 #define CRED_FLAG_PUBLIC_MASK 0x0000FFFF struct gss_cred_id_struct { diff --git a/init_sec_context.c b/init_sec_context.c index 375b3ef..e27efe8 100644 --- a/init_sec_context.c +++ b/init_sec_context.c @@ -33,9 +33,6 @@ #include "gssapiP_eap.h" #ifdef GSSEAP_ENABLE_REAUTH -static int -canReauthP(gss_cred_id_t cred); - static OM_uint32 eapGssSmInitGssReauth(OM_uint32 *minor, gss_cred_id_t cred, @@ -633,6 +630,7 @@ gss_init_sec_context(OM_uint32 *minor, gss_buffer_desc innerOutputToken = GSS_C_EMPTY_BUFFER; enum gss_eap_token_type tokType; gss_cred_id_t defaultCred = GSS_C_NO_CREDENTIAL; + int initialContextToken = 0; *minor = 0; @@ -646,24 +644,17 @@ gss_init_sec_context(OM_uint32 *minor, major = gssEapAllocContext(minor, &ctx); if (GSS_ERROR(major)) - goto cleanup; + return major; ctx->flags |= CTX_FLAG_INITIATOR; -#ifdef GSSEAP_ENABLE_REAUTH - if (canReauthP(cred)) - ctx->state = EAP_STATE_KRB_REAUTH_GSS; -#endif - + initialContextToken = 1; *context_handle = ctx; } - if (cred != GSS_C_NO_CREDENTIAL) { - if ((cred->flags & CRED_FLAG_INITIATE) == 0) { - major = GSS_S_NO_CRED; - goto cleanup; - } - } else { + GSSEAP_MUTEX_LOCK(&ctx->mutex); + + if (cred == GSS_C_NO_CREDENTIAL) { if (ctx->initiatorCtx.defaultCred == GSS_C_NO_CREDENTIAL) { major = gssEapAcquireCred(minor, GSS_C_NO_NAME, @@ -681,7 +672,17 @@ gss_init_sec_context(OM_uint32 *minor, cred = ctx->initiatorCtx.defaultCred; } - GSSEAP_MUTEX_LOCK(&ctx->mutex); + GSSEAP_MUTEX_LOCK(&cred->mutex); + +#ifdef GSSEAP_ENABLE_REAUTH + if (initialContextToken && gssEapCanReauthP(cred, target_name, time_req)) + ctx->state = EAP_STATE_KRB_REAUTH_GSS; +#endif + + if ((cred->flags & CRED_FLAG_INITIATE) == 0) { + major = GSS_S_NO_CRED; + goto cleanup; + } sm = &eapGssInitiatorSm[ctx->state]; @@ -742,6 +743,8 @@ gss_init_sec_context(OM_uint32 *minor, assert(ctx->state == EAP_STATE_ESTABLISHED || major == GSS_S_CONTINUE_NEEDED); cleanup: + if (cred != GSS_C_NO_CREDENTIAL) + GSSEAP_MUTEX_UNLOCK(&cred->mutex); GSSEAP_MUTEX_UNLOCK(&ctx->mutex); if (GSS_ERROR(major)) @@ -753,14 +756,6 @@ cleanup: } #ifdef GSSEAP_ENABLE_REAUTH -static int -canReauthP(gss_cred_id_t cred) -{ - return (cred != GSS_C_NO_CREDENTIAL && - cred->krbCred != GSS_C_NO_CREDENTIAL && - cred->expiryTime > time(NULL)); -} - static OM_uint32 eapGssSmInitGssReauth(OM_uint32 *minor, gss_cred_id_t cred, diff --git a/inquire_cred.c b/inquire_cred.c index c74e617..05ae554 100644 --- a/inquire_cred.c +++ b/inquire_cred.c @@ -42,6 +42,11 @@ gss_inquire_cred(OM_uint32 *minor, { OM_uint32 major = GSS_S_COMPLETE; + if (cred == NULL) + return GSS_S_NO_CRED; + + GSSEAP_MUTEX_LOCK(&cred->mutex); + if (name != NULL) { major = gssEapDuplicateName(minor, cred->name, name); if (GSS_ERROR(major)) @@ -89,5 +94,7 @@ gss_inquire_cred(OM_uint32 *minor, } cleanup: + GSSEAP_MUTEX_UNLOCK(&cred->mutex); + return major; } diff --git a/set_cred_option.c b/set_cred_option.c index 44ebebc..6c32d4c 100644 --- a/set_cred_option.c +++ b/set_cred_option.c @@ -105,24 +105,29 @@ gss_OID GSS_EAP_CRED_SET_CRED_FLAG = &setCredOps[1].oid; OM_uint32 gssspi_set_cred_option(OM_uint32 *minor, - gss_cred_id_t *cred, + gss_cred_id_t *pCred, const gss_OID desired_object, const gss_buffer_t value) { OM_uint32 major = GSS_S_UNAVAILABLE; + gss_cred_id_t cred = *pCred; int i; - if (*cred == GSS_C_NO_CREDENTIAL) + if (cred == GSS_C_NO_CREDENTIAL) return GSS_S_UNAVAILABLE; + GSSEAP_MUTEX_LOCK(&cred->mutex); + for (i = 0; i < sizeof(setCredOps) / sizeof(setCredOps[0]); i++) { if (oidEqual(&setCredOps[i].oid, desired_object)) { - major = (*setCredOps[i].setOption)(minor, *cred, + major = (*setCredOps[i].setOption)(minor, cred, desired_object, value); break; } } + GSSEAP_MUTEX_UNLOCK(&cred->mutex); + return major; } -- 2.1.4