EAP: Increase the maximum number of message exchanges

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>
This commit is contained in:
Jouni Malinen 2019-08-18 17:18:17 +03:00
parent 0bcd9839bf
commit 7eb157f1e9
4 changed files with 38 additions and 2 deletions

View 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);

View 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;

View 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;

View 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) {