be careful to lock cred before using it
authorLuke Howard <lukeh@padl.com>
Mon, 27 Sep 2010 23:18:22 +0000 (01:18 +0200)
committerLuke Howard <lukeh@padl.com>
Mon, 27 Sep 2010 23:18:22 +0000 (01:18 +0200)
accept_sec_context.c
gssapiP_eap.h
init_sec_context.c
inquire_cred.c
set_cred_option.c

index 6b0bb6a..5dd68f2 100644 (file)
@@ -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))
index c6c634e..8dcb311 100644 (file)
@@ -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 {
index 375b3ef..e27efe8 100644 (file)
@@ -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,
index c74e617..05ae554 100644 (file)
@@ -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;
 }
index 44ebebc..6c32d4c 100644 (file)
@@ -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;
 }