Allow for graceful restart if acceptor ignores reauth token
authorLuke Howard <lukeh@padl.com>
Wed, 9 Mar 2011 04:31:48 +0000 (15:31 +1100)
committerLuke Howard <lukeh@padl.com>
Wed, 9 Mar 2011 04:31:48 +0000 (15:31 +1100)
init_sec_context.c
util_sm.c

index 8104a63..9966090 100644 (file)
@@ -438,7 +438,7 @@ eapGssSmInitGssReauth(OM_uint32 *minor,
 
     assert(cred != GSS_C_NO_CREDENTIAL);
 
-    if (ctx->state == GSSEAP_STATE_INITIAL) {
+    if (GSSEAP_SM_STATE(ctx) == GSSEAP_STATE_INITIAL) {
         if (!gssEapCanReauthP(cred, target, timeReq))
             return GSS_S_CONTINUE_NEEDED;
 
@@ -533,6 +533,15 @@ eapGssSmInitIdentity(OM_uint32 *minor,
     OM_uint32 major;
     struct eap_config eapConfig;
 
+    if (GSSEAP_SM_STATE(ctx) == GSSEAP_STATE_REAUTHENTICATE) {
+        /* server didn't support reauthentication, sent EAP request */
+        GSSEAP_SM_TRANSITION(ctx, GSSEAP_STATE_INITIAL);
+        ctx->flags &= ~(CTX_FLAG_KRB_REAUTH);
+        *smFlags |= SM_FLAG_RESTART;
+    } else {
+        *smFlags |= SM_FLAG_FORCE_SEND_TOKEN;
+    }
+
     assert((ctx->flags & CTX_FLAG_KRB_REAUTH) == 0);
     assert(inputToken == GSS_C_NO_BUFFER);
 
@@ -563,9 +572,7 @@ eapGssSmInitIdentity(OM_uint32 *minor,
 
     GSSEAP_SM_TRANSITION_NEXT(ctx);
 
-    /* force sending of empty token */
     *minor = 0;
-    *smFlags |= SM_FLAG_FORCE_SEND_TOKEN;
 
     return GSS_S_CONTINUE_NEEDED;
 }
@@ -775,7 +782,7 @@ static struct gss_eap_sm eapGssInitiatorSm[] = {
     {
         ITOK_TYPE_NONE,
         ITOK_TYPE_NONE,
-        GSSEAP_STATE_INITIAL,
+        GSSEAP_STATE_INITIAL | GSSEAP_STATE_REAUTHENTICATE,
         SM_ITOK_FLAG_CRITICAL | SM_ITOK_FLAG_REQUIRED,
         eapGssSmInitIdentity,
     },
@@ -910,7 +917,7 @@ gss_init_sec_context(OM_uint32 *minor,
     if (time_rec != NULL)
         gssEapContextTime(&tmpMinor, ctx, time_rec);
 
-    assert(ctx->state == GSSEAP_STATE_ESTABLISHED || major == GSS_S_CONTINUE_NEEDED);
+    assert(CTX_IS_ESTABLISHED(ctx) || major == GSS_S_CONTINUE_NEEDED);
 
 cleanup:
     if (cred != GSS_C_NO_CREDENTIAL)
index 8bbe40e..0788bcf 100644 (file)
--- a/util_sm.c
+++ b/util_sm.c
@@ -81,11 +81,11 @@ gssEapStateToString(enum gss_eap_state state)
 void
 gssEapSmTransition(gss_ctx_id_t ctx, enum gss_eap_state state)
 {
-    assert(state > ctx->state);
     assert(state <= GSSEAP_STATE_ESTABLISHED);
 
     fprintf(stderr, "GSS-EAP: state transition %s->%s\n",
-            gssEapStateToString(ctx->state), gssEapStateToString(state));
+            gssEapStateToString(GSSEAP_SM_STATE(ctx)),
+            gssEapStateToString(state));
 
     ctx->state = state;
 }
@@ -236,7 +236,7 @@ gssEapSmStep(OM_uint32 *minor,
         initialContextToken = 1;
     }
 
-    if (ctx->state == GSSEAP_STATE_ESTABLISHED) {
+    if (CTX_IS_ESTABLISHED(ctx)) {
         major = GSS_S_BAD_STATUS;
         *minor = GSSEAP_CONTEXT_ESTABLISHED;
         goto cleanup;
@@ -310,8 +310,12 @@ gssEapSmStep(OM_uint32 *minor,
 
             if (inputTokenType != NULL)
                 *inputTokenType |= ITOK_FLAG_VERIFIED;
-            if (ctx->state != oldState)
+            if (smFlags & SM_FLAG_RESTART) {
+                assert(ctx->state < oldState);
+                i = 0;
+            } else if (ctx->state != oldState) {
                 smFlags |= SM_FLAG_TRANSITED;
+            }
 
             if (innerOutputToken.value != NULL) {
                 innerOutputTokens->elements[innerOutputTokens->count] = innerOutputToken;