]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
EAP: Increase the maximum number of message exchanges
authorJouni Malinen <j@w1.fi>
Sun, 18 Aug 2019 14:18:17 +0000 (17:18 +0300)
committerJouni Malinen <j@w1.fi>
Sun, 18 Aug 2019 14:40:31 +0000 (17:40 +0300)
Allow 100 rounds of EAP messages if there is data being transmitted.
Keep the old 50 round limit for cases where only short EAP messages are
sent (i.e., the likely case of getting stuck in ACK loop).

This allows larger EAP data (e.g., large certificates) to be exchanged
without breaking the workaround for ACK loop interop issues.

Signed-off-by: Jouni Malinen <j@w1.fi>
src/eap_peer/eap.c
src/eap_peer/eap_i.h
src/eap_server/eap_i.h
src/eap_server/eap_server.c

index d71d00cad61ec701e802f196f7ffbb26f4e7f82c..ada3c6db639ffe3ea8b20659cb028ed7bc8b5459 100644 (file)
@@ -32,7 +32,8 @@
 #define STATE_MACHINE_DATA struct eap_sm
 #define STATE_MACHINE_DEBUG_PREFIX "EAP"
 
-#define EAP_MAX_AUTH_ROUNDS 50
+#define EAP_MAX_AUTH_ROUNDS 100
+#define EAP_MAX_AUTH_ROUNDS_SHORT 50
 #define EAP_CLIENT_TIMEOUT_DEFAULT 60
 
 
@@ -260,6 +261,7 @@ SM_STATE(EAP, INITIALIZE)
         */
        sm->ignore = 0;
        sm->num_rounds = 0;
+       sm->num_rounds_short = 0;
        sm->prev_failure = 0;
        sm->expected_failure = 0;
        sm->reauthInit = FALSE;
@@ -276,6 +278,7 @@ SM_STATE(EAP, DISABLED)
 {
        SM_ENTRY(EAP, DISABLED);
        sm->num_rounds = 0;
+       sm->num_rounds_short = 0;
        /*
         * RFC 4137 does not describe clearing of idleWhile here, but doing so
         * allows the timer tick to be stopped more quickly when EAP is not in
@@ -309,6 +312,10 @@ SM_STATE(EAP, RECEIVED)
        /* parse rxReq, rxSuccess, rxFailure, reqId, reqMethod */
        eap_sm_parseEapReq(sm, eapReqData);
        sm->num_rounds++;
+       if (!eapReqData || wpabuf_len(eapReqData) < 20)
+               sm->num_rounds_short++;
+       else
+               sm->num_rounds_short = 0;
 }
 
 
@@ -950,6 +957,8 @@ SM_STATE(EAP, SEND_RESPONSE)
        SM_ENTRY(EAP, SEND_RESPONSE);
        wpabuf_free(sm->lastRespData);
        if (sm->eapRespData) {
+               if (wpabuf_len(sm->eapRespData) >= 20)
+                       sm->num_rounds_short = 0;
                if (sm->workaround)
                        os_memcpy(sm->last_sha1, sm->req_sha1, 20);
                sm->lastId = sm->reqId;
@@ -1342,6 +1351,14 @@ SM_STEP(EAP)
                        sm->num_rounds++;
                        SM_ENTER_GLOBAL(EAP, FAILURE);
                }
+       } else if (sm->num_rounds_short > EAP_MAX_AUTH_ROUNDS_SHORT) {
+               if (sm->num_rounds_short == EAP_MAX_AUTH_ROUNDS_SHORT + 1) {
+                       wpa_msg(sm->msg_ctx, MSG_INFO,
+                               "EAP: more than %d authentication rounds (short) - abort",
+                               EAP_MAX_AUTH_ROUNDS_SHORT);
+                       sm->num_rounds_short++;
+                       SM_ENTER_GLOBAL(EAP, FAILURE);
+               }
        } else {
                /* Local transitions */
                eap_peer_sm_step_local(sm);
index 629bc336e2a33ffd353fa45439d4ccadb9638e7e..7c633236c6ccc1a0475495965eb8387d525e9d83 100644 (file)
@@ -366,6 +366,7 @@ struct eap_sm {
        u8 *peer_challenge, *auth_challenge;
 
        int num_rounds;
+       int num_rounds_short;
        int force_disabled;
 
        struct wps_context *wps;
index cbdad5f192bb85e0a98eb427329ec9e1d4899c6f..c56011639a3855dec0193419e25fefb0b1dcd23c 100644 (file)
@@ -172,6 +172,7 @@ struct eap_sm {
        Boolean update_user;
 
        int num_rounds;
+       int num_rounds_short;
        enum {
                METHOD_PENDING_NONE, METHOD_PENDING_WAIT, METHOD_PENDING_CONT
        } method_pending;
index 4c6ba6d3443db7be6263356157e87813a642fb89..677fc4e2e2ebfbcc4d781f3d0a7e12d698622710 100644 (file)
@@ -23,7 +23,8 @@
 #define STATE_MACHINE_DATA struct eap_sm
 #define STATE_MACHINE_DEBUG_PREFIX "EAP"
 
-#define EAP_MAX_AUTH_ROUNDS 50
+#define EAP_MAX_AUTH_ROUNDS 100
+#define EAP_MAX_AUTH_ROUNDS_SHORT 50
 
 /* EAP state machines are described in RFC 4137 */
 
@@ -216,6 +217,7 @@ SM_STATE(EAP, DISABLED)
 {
        SM_ENTRY(EAP, DISABLED);
        sm->num_rounds = 0;
+       sm->num_rounds_short = 0;
 }
 
 
@@ -266,6 +268,7 @@ SM_STATE(EAP, INITIALIZE)
                }
        }
        sm->num_rounds = 0;
+       sm->num_rounds_short = 0;
        sm->method_pending = METHOD_PENDING_NONE;
 
        wpa_msg(sm->cfg->msg_ctx, MSG_INFO, WPA_EVENT_EAP_STARTED
@@ -337,6 +340,10 @@ SM_STATE(EAP, RECEIVED)
        /* parse rxResp, respId, respMethod */
        eap_sm_parseEapResp(sm, sm->eap_if.eapRespData);
        sm->num_rounds++;
+       if (!sm->eap_if.eapRespData || wpabuf_len(sm->eap_if.eapRespData) < 20)
+               sm->num_rounds_short++;
+       else
+               sm->num_rounds_short = 0;
 }
 
 
@@ -354,6 +361,8 @@ SM_STATE(EAP, SEND_REQUEST)
 
        sm->retransCount = 0;
        if (sm->eap_if.eapReqData) {
+               if (wpabuf_len(sm->eap_if.eapReqData) >= 20)
+                       sm->num_rounds_short = 0;
                if (eap_copy_buf(&sm->lastReqData, sm->eap_if.eapReqData) == 0)
                {
                        sm->eap_if.eapResp = FALSE;
@@ -1171,6 +1180,14 @@ SM_STEP(EAP)
                        sm->num_rounds++;
                        SM_ENTER_GLOBAL(EAP, FAILURE);
                }
+       } else if (sm->num_rounds_short > EAP_MAX_AUTH_ROUNDS_SHORT) {
+               if (sm->num_rounds_short == EAP_MAX_AUTH_ROUNDS_SHORT + 1) {
+                       wpa_printf(MSG_DEBUG,
+                                  "EAP: more than %d authentication rounds (short) - abort",
+                                  EAP_MAX_AUTH_ROUNDS_SHORT);
+                       sm->num_rounds_short++;
+                       SM_ENTER_GLOBAL(EAP, FAILURE);
+               }
        } else switch (sm->EAP_state) {
        case EAP_INITIALIZE:
                if (sm->cfg->backend_auth) {