From 8d76e0ad7bbffbc6b7a5fb898bbd1f42651101f6 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Sun, 1 Sep 2019 15:58:10 +0300 Subject: [PATCH] EAP server: Configurable maximum number of authentication message rounds Allow the previously hardcoded maximum numbers of EAP message rounds to be configured in hostapd EAP server. This can be used, e.g., to increase the default limits if very large X.509 certificates are used for EAP authentication. Signed-off-by: Jouni Malinen --- hostapd/config_file.c | 4 ++++ hostapd/hostapd.conf | 6 ++++++ src/ap/ap_config.c | 3 +++ src/ap/ap_config.h | 2 ++ src/ap/authsrv.c | 2 ++ src/eap_server/eap.h | 3 +++ src/eap_server/eap_i.h | 4 ++-- src/eap_server/eap_server.c | 16 +++++++--------- 8 files changed, 29 insertions(+), 11 deletions(-) diff --git a/hostapd/config_file.c b/hostapd/config_file.c index 4a2f12d94..3ffd1ac2d 100644 --- a/hostapd/config_file.c +++ b/hostapd/config_file.c @@ -2547,6 +2547,10 @@ static int hostapd_config_fill(struct hostapd_config *conf, bss->tls_session_lifetime = atoi(pos); } else if (os_strcmp(buf, "tls_flags") == 0) { bss->tls_flags = parse_tls_flags(pos); + } else if (os_strcmp(buf, "max_auth_rounds") == 0) { + bss->max_auth_rounds = atoi(pos); + } else if (os_strcmp(buf, "max_auth_rounds_short") == 0) { + bss->max_auth_rounds_short = atoi(pos); } else if (os_strcmp(buf, "ocsp_stapling_response") == 0) { os_free(bss->ocsp_stapling_response); bss->ocsp_stapling_response = os_strdup(pos); diff --git a/hostapd/hostapd.conf b/hostapd/hostapd.conf index b6091a1e2..6c96a760a 100644 --- a/hostapd/hostapd.conf +++ b/hostapd/hostapd.conf @@ -1081,6 +1081,12 @@ eap_server=0 # [ENABLE-TLSv1.3] = enable TLSv1.3 (experimental - disabled by default) #tls_flags=[flag1][flag2]... +# Maximum number of EAP message rounds with data (default: 100) +#max_auth_rounds=100 + +# Maximum number of short EAP message rounds (default: 50) +#max_auth_rounds_short=50 + # Cached OCSP stapling response (DER encoded) # If set, this file is sent as a certificate status response by the EAP server # if the EAP peer requests certificate status in the ClientHello message. diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c index 90348e1dd..80a73d6d1 100644 --- a/src/ap/ap_config.c +++ b/src/ap/ap_config.c @@ -135,6 +135,9 @@ void hostapd_config_defaults_bss(struct hostapd_bss_config *bss) * completed and tested with other implementations. */ bss->tls_flags = TLS_CONN_DISABLE_TLSv1_3; + bss->max_auth_rounds = 100; + bss->max_auth_rounds_short = 50; + bss->send_probe_response = 1; #ifdef CONFIG_HS20 diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h index 484e1b679..c49b48fca 100644 --- a/src/ap/ap_config.h +++ b/src/ap/ap_config.h @@ -415,6 +415,8 @@ struct hostapd_bss_config { unsigned int crl_reload_interval; unsigned int tls_session_lifetime; unsigned int tls_flags; + unsigned int max_auth_rounds; + unsigned int max_auth_rounds_short; char *ocsp_stapling_response; char *ocsp_stapling_response_multi; char *dh_file; diff --git a/src/ap/authsrv.c b/src/ap/authsrv.c index 110c0caff..8e12daf40 100644 --- a/src/ap/authsrv.c +++ b/src/ap/authsrv.c @@ -187,6 +187,8 @@ static struct eap_config * authsrv_eap_config(struct hostapd_data *hapd) cfg->eap_sim_db_priv = hapd->eap_sim_db_priv; cfg->tls_session_lifetime = hapd->conf->tls_session_lifetime; cfg->tls_flags = hapd->conf->tls_flags; + cfg->max_auth_rounds = hapd->conf->max_auth_rounds; + cfg->max_auth_rounds_short = hapd->conf->max_auth_rounds_short; if (hapd->conf->pac_opaque_encr_key) cfg->pac_opaque_encr_key = os_memdup(hapd->conf->pac_opaque_encr_key, 16); diff --git a/src/eap_server/eap.h b/src/eap_server/eap.h index 9192c1af6..540b4e70b 100644 --- a/src/eap_server/eap.h +++ b/src/eap_server/eap.h @@ -255,6 +255,9 @@ struct eap_config { int erp; unsigned int tls_session_lifetime; unsigned int tls_flags; + + unsigned int max_auth_rounds; + unsigned int max_auth_rounds_short; }; struct eap_session_data { diff --git a/src/eap_server/eap_i.h b/src/eap_server/eap_i.h index c56011639..44896a695 100644 --- a/src/eap_server/eap_i.h +++ b/src/eap_server/eap_i.h @@ -171,8 +171,8 @@ struct eap_sm { struct eap_config cfg_buf; Boolean update_user; - int num_rounds; - int num_rounds_short; + unsigned int num_rounds; + unsigned int num_rounds_short; enum { METHOD_PENDING_NONE, METHOD_PENDING_WAIT, METHOD_PENDING_CONT } method_pending; diff --git a/src/eap_server/eap_server.c b/src/eap_server/eap_server.c index 677fc4e2e..34ce23946 100644 --- a/src/eap_server/eap_server.c +++ b/src/eap_server/eap_server.c @@ -23,9 +23,6 @@ #define STATE_MACHINE_DATA struct eap_sm #define STATE_MACHINE_DEBUG_PREFIX "EAP" -#define EAP_MAX_AUTH_ROUNDS 100 -#define EAP_MAX_AUTH_ROUNDS_SHORT 50 - /* EAP state machines are described in RFC 4137 */ static int eap_sm_calculateTimeout(struct eap_sm *sm, int retransCount, @@ -1172,19 +1169,20 @@ SM_STEP(EAP) SM_ENTER_GLOBAL(EAP, INITIALIZE); else if (!sm->eap_if.portEnabled) SM_ENTER_GLOBAL(EAP, DISABLED); - else if (sm->num_rounds > EAP_MAX_AUTH_ROUNDS) { - if (sm->num_rounds == EAP_MAX_AUTH_ROUNDS + 1) { + else if (sm->num_rounds > sm->cfg->max_auth_rounds) { + if (sm->num_rounds == sm->cfg->max_auth_rounds + 1) { wpa_printf(MSG_DEBUG, "EAP: more than %d " "authentication rounds - abort", - EAP_MAX_AUTH_ROUNDS); + sm->cfg->max_auth_rounds); 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) { + } else if (sm->num_rounds_short > sm->cfg->max_auth_rounds_short) { + if (sm->num_rounds_short == + sm->cfg->max_auth_rounds_short + 1) { wpa_printf(MSG_DEBUG, "EAP: more than %d authentication rounds (short) - abort", - EAP_MAX_AUTH_ROUNDS_SHORT); + sm->cfg->max_auth_rounds_short); sm->num_rounds_short++; SM_ENTER_GLOBAL(EAP, FAILURE); }