update README
[mech_eap.orig] / init_sec_context.c
index a9dadda..0b06ffa 100644 (file)
@@ -459,7 +459,7 @@ eapGssSmInitGssReauth(OM_uint32 *minor,
                               &ctx->kerberosCtx,
                               mechTarget,
                               (gss_OID)gss_mech_krb5,
-                              reqFlags,
+                              reqFlags | GSS_C_MUTUAL_FLAG,
                               timeReq,
                               chanBindings,
                               inputToken,
@@ -473,6 +473,8 @@ eapGssSmInitGssReauth(OM_uint32 *minor,
     ctx->gssFlags = gssFlags;
 
     if (major == GSS_S_COMPLETE) {
+        assert(GSSEAP_SM_STATE(ctx) == GSSEAP_STATE_REAUTHENTICATE);
+
         major = gssEapReauthComplete(minor, ctx, cred, actualMech, timeRec);
         if (GSS_ERROR(major))
             goto cleanup;
@@ -572,9 +574,12 @@ eapGssSmInitIdentity(OM_uint32 *minor,
     struct eap_config eapConfig;
 
     if (GSSEAP_SM_STATE(ctx) == GSSEAP_STATE_REAUTHENTICATE) {
+        OM_uint32 tmpMinor;
+
         /* server didn't support reauthentication, sent EAP request */
-        GSSEAP_SM_TRANSITION(ctx, GSSEAP_STATE_INITIAL);
+        gssDeleteSecContext(&tmpMinor, &ctx->kerberosCtx, GSS_C_NO_BUFFER);
         ctx->flags &= ~(CTX_FLAG_KRB_REAUTH);
+        GSSEAP_SM_TRANSITION(ctx, GSSEAP_STATE_INITIAL);
         *smFlags |= SM_FLAG_RESTART;
     } else {
         *smFlags |= SM_FLAG_FORCE_SEND_TOKEN;
@@ -681,6 +686,8 @@ cleanup:
             major = tmpMajor;
             *minor = tmpMinor;
         }
+
+        *smFlags |= SM_FLAG_OUTPUT_TOKEN_CRITICAL;
     }
 
     wpabuf_set(&ctx->initiatorCtx.reqData, NULL, 0);
@@ -716,6 +723,8 @@ eapGssSmInitGssChannelBindings(OM_uint32 *minor,
     assert(outputToken->value != NULL);
 
     *minor = 0;
+    *smFlags |= SM_FLAG_OUTPUT_TOKEN_CRITICAL;
+
     return GSS_S_CONTINUE_NEEDED;
 }
 
@@ -735,9 +744,11 @@ eapGssSmInitReauthCreds(OM_uint32 *minor,
 {
     OM_uint32 major;
 
-    major = gssEapStoreReauthCreds(minor, ctx, cred, inputToken);
-    if (GSS_ERROR(major))
-        return major;
+    if (ctx->gssFlags & GSS_C_MUTUAL_FLAG) {
+        major = gssEapStoreReauthCreds(minor, ctx, cred, inputToken);
+        if (GSS_ERROR(major))
+            return major;
+    }
 
     *minor = 0;
     return GSS_S_CONTINUE_NEEDED;
@@ -790,7 +801,7 @@ static struct gss_eap_sm eapGssInitiatorSm[] = {
         ITOK_TYPE_CONTEXT_ERR,
         ITOK_TYPE_NONE,
         GSSEAP_STATE_ALL & ~(GSSEAP_STATE_INITIAL),
-        SM_ITOK_FLAG_CRITICAL,
+        0,
         eapGssSmInitError
     },
     {
@@ -822,21 +833,21 @@ static struct gss_eap_sm eapGssInitiatorSm[] = {
         ITOK_TYPE_NONE,
         ITOK_TYPE_NONE,
         GSSEAP_STATE_INITIAL | GSSEAP_STATE_REAUTHENTICATE,
-        SM_ITOK_FLAG_CRITICAL | SM_ITOK_FLAG_REQUIRED,
+        SM_ITOK_FLAG_REQUIRED,
         eapGssSmInitIdentity
     },
     {
         ITOK_TYPE_EAP_REQ,
         ITOK_TYPE_EAP_RESP,
         GSSEAP_STATE_AUTHENTICATE,
-        SM_ITOK_FLAG_CRITICAL | SM_ITOK_FLAG_REQUIRED,
+        SM_ITOK_FLAG_REQUIRED,
         eapGssSmInitAuthenticate
     },
     {
         ITOK_TYPE_NONE,
         ITOK_TYPE_GSS_CHANNEL_BINDINGS,
         GSSEAP_STATE_INITIATOR_EXTS,
-        SM_ITOK_FLAG_CRITICAL | SM_ITOK_FLAG_REQUIRED,
+        SM_ITOK_FLAG_REQUIRED,
         eapGssSmInitGssChannelBindings
     },
     {