diff --git a/src/ap/dpp_hostapd.c b/src/ap/dpp_hostapd.c index 6772a8748..c048d1db5 100644 --- a/src/ap/dpp_hostapd.c +++ b/src/ap/dpp_hostapd.c @@ -23,6 +23,8 @@ static void hostapd_dpp_reply_wait_timeout(void *eloop_ctx, void *timeout_ctx); +static void hostapd_dpp_auth_conf_wait_timeout(void *eloop_ctx, + void *timeout_ctx); static void hostapd_dpp_auth_success(struct hostapd_data *hapd, int initiator); static void hostapd_dpp_init_timeout(void *eloop_ctx, void *timeout_ctx); static int hostapd_dpp_auth_init_next(struct hostapd_data *hapd); @@ -246,6 +248,8 @@ void hostapd_dpp_tx_status(struct hostapd_data *hapd, const u8 *dst, eloop_cancel_timeout(hostapd_dpp_init_timeout, hapd, NULL); eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout, hapd, NULL); + eloop_cancel_timeout(hostapd_dpp_auth_conf_wait_timeout, + hapd, NULL); eloop_cancel_timeout(hostapd_dpp_auth_resp_retry_timeout, hapd, NULL); #ifdef CONFIG_DPP2 @@ -277,6 +281,17 @@ void hostapd_dpp_tx_status(struct hostapd_data *hapd, const u8 *dst, } } + if (auth->waiting_auth_conf && + auth->auth_resp_status == DPP_STATUS_OK) { + /* Make sure we do not get stuck waiting for Auth Confirm + * indefinitely after successfully transmitted Auth Response to + * allow new authentication exchanges to be started. */ + eloop_cancel_timeout(hostapd_dpp_auth_conf_wait_timeout, hapd, + NULL); + eloop_register_timeout(1, 0, hostapd_dpp_auth_conf_wait_timeout, + hapd, NULL); + } + if (!is_broadcast_ether_addr(dst) && auth->waiting_auth_resp && ok) { /* Allow timeout handling to stop iteration if no response is * received from a peer that has ACKed a request. */ @@ -377,6 +392,25 @@ static void hostapd_dpp_reply_wait_timeout(void *eloop_ctx, void *timeout_ctx) } +static void hostapd_dpp_auth_conf_wait_timeout(void *eloop_ctx, + void *timeout_ctx) +{ + struct hostapd_data *hapd = eloop_ctx; + struct dpp_authentication *auth = hapd->dpp_auth; + + if (!auth || !auth->waiting_auth_conf) + return; + + wpa_printf(MSG_DEBUG, + "DPP: Terminate authentication exchange due to Auth Confirm timeout"); + wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL + "No Auth Confirm received"); + hostapd_drv_send_action_cancel_wait(hapd); + dpp_auth_deinit(auth); + hapd->dpp_auth = NULL; +} + + static void hostapd_dpp_set_testing_options(struct hostapd_data *hapd, struct dpp_authentication *auth) { @@ -594,6 +628,8 @@ int hostapd_dpp_auth_init(struct hostapd_data *hapd, const char *cmd) eloop_cancel_timeout(hostapd_dpp_init_timeout, hapd, NULL); eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout, hapd, NULL); + eloop_cancel_timeout(hostapd_dpp_auth_conf_wait_timeout, + hapd, NULL); eloop_cancel_timeout(hostapd_dpp_auth_resp_retry_timeout, hapd, NULL); #ifdef CONFIG_DPP2 @@ -1962,6 +1998,7 @@ void hostapd_dpp_gas_status_handler(struct hostapd_data *hapd, int ok) wpa_printf(MSG_DEBUG, "DPP: Configuration exchange completed (ok=%d)", ok); eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout, hapd, NULL); + eloop_cancel_timeout(hostapd_dpp_auth_conf_wait_timeout, hapd, NULL); eloop_cancel_timeout(hostapd_dpp_auth_resp_retry_timeout, hapd, NULL); #ifdef CONFIG_DPP2 eloop_cancel_timeout(hostapd_dpp_reconfig_reply_wait_timeout, @@ -2207,6 +2244,7 @@ void hostapd_dpp_deinit(struct hostapd_data *hapd) if (!hapd->dpp_init_done) return; eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout, hapd, NULL); + eloop_cancel_timeout(hostapd_dpp_auth_conf_wait_timeout, hapd, NULL); eloop_cancel_timeout(hostapd_dpp_init_timeout, hapd, NULL); eloop_cancel_timeout(hostapd_dpp_auth_resp_retry_timeout, hapd, NULL); #ifdef CONFIG_DPP2 diff --git a/src/common/dpp_auth.c b/src/common/dpp_auth.c index f79cfef4e..0cabd647f 100644 --- a/src/common/dpp_auth.c +++ b/src/common/dpp_auth.c @@ -251,6 +251,7 @@ static struct wpabuf * dpp_auth_build_resp(struct dpp_authentication *auth, u8 *attr_start, *attr_end, *pos; auth->waiting_auth_conf = 1; + auth->auth_resp_status = status; auth->auth_resp_tries = 0; /* Build DPP Authentication Response frame attributes */ diff --git a/wpa_supplicant/dpp_supplicant.c b/wpa_supplicant/dpp_supplicant.c index 09355cf7f..910602e34 100644 --- a/wpa_supplicant/dpp_supplicant.c +++ b/wpa_supplicant/dpp_supplicant.c @@ -32,6 +32,7 @@ static int wpas_dpp_listen_start(struct wpa_supplicant *wpa_s, unsigned int freq); static void wpas_dpp_reply_wait_timeout(void *eloop_ctx, void *timeout_ctx); +static void wpas_dpp_auth_conf_wait_timeout(void *eloop_ctx, void *timeout_ctx); static void wpas_dpp_auth_success(struct wpa_supplicant *wpa_s, int initiator); static void wpas_dpp_tx_status(struct wpa_supplicant *wpa_s, unsigned int freq, const u8 *dst, @@ -473,6 +474,8 @@ static void wpas_dpp_tx_status(struct wpa_supplicant *wpa_s, "DPP: Terminate authentication exchange due to a request to do so on TX status"); eloop_cancel_timeout(wpas_dpp_init_timeout, wpa_s, NULL); eloop_cancel_timeout(wpas_dpp_reply_wait_timeout, wpa_s, NULL); + eloop_cancel_timeout(wpas_dpp_auth_conf_wait_timeout, wpa_s, + NULL); eloop_cancel_timeout(wpas_dpp_auth_resp_retry_timeout, wpa_s, NULL); #ifdef CONFIG_DPP2 @@ -505,6 +508,17 @@ static void wpas_dpp_tx_status(struct wpa_supplicant *wpa_s, } } + if (auth->waiting_auth_conf && + auth->auth_resp_status == DPP_STATUS_OK) { + /* Make sure we do not get stuck waiting for Auth Confirm + * indefinitely after successfully transmitted Auth Response to + * allow new authentication exchanges to be started. */ + eloop_cancel_timeout(wpas_dpp_auth_conf_wait_timeout, wpa_s, + NULL); + eloop_register_timeout(1, 0, wpas_dpp_auth_conf_wait_timeout, + wpa_s, NULL); + } + if (!is_broadcast_ether_addr(dst) && auth->waiting_auth_resp && result == OFFCHANNEL_SEND_ACTION_SUCCESS) { /* Allow timeout handling to stop iteration if no response is @@ -593,6 +607,23 @@ static void wpas_dpp_reply_wait_timeout(void *eloop_ctx, void *timeout_ctx) } +static void wpas_dpp_auth_conf_wait_timeout(void *eloop_ctx, void *timeout_ctx) +{ + struct wpa_supplicant *wpa_s = eloop_ctx; + struct dpp_authentication *auth = wpa_s->dpp_auth; + + if (!auth || !auth->waiting_auth_conf) + return; + + wpa_printf(MSG_DEBUG, + "DPP: Terminate authentication exchange due to Auth Confirm timeout"); + wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_FAIL "No Auth Confirm received"); + offchannel_send_action_done(wpa_s); + dpp_auth_deinit(auth); + wpa_s->dpp_auth = NULL; +} + + static void wpas_dpp_set_testing_options(struct wpa_supplicant *wpa_s, struct dpp_authentication *auth) { @@ -809,6 +840,8 @@ int wpas_dpp_auth_init(struct wpa_supplicant *wpa_s, const char *cmd) if (!tcp && wpa_s->dpp_auth) { eloop_cancel_timeout(wpas_dpp_init_timeout, wpa_s, NULL); eloop_cancel_timeout(wpas_dpp_reply_wait_timeout, wpa_s, NULL); + eloop_cancel_timeout(wpas_dpp_auth_conf_wait_timeout, wpa_s, + NULL); eloop_cancel_timeout(wpas_dpp_auth_resp_retry_timeout, wpa_s, NULL); #ifdef CONFIG_DPP2 @@ -1808,6 +1841,8 @@ static void wpas_dpp_rx_auth_conf(struct wpa_supplicant *wpa_s, const u8 *src, return; } + eloop_cancel_timeout(wpas_dpp_auth_conf_wait_timeout, wpa_s, NULL); + if (dpp_auth_conf_rx(auth, hdr, buf, len) < 0) { wpa_printf(MSG_DEBUG, "DPP: Authentication failed"); return; @@ -2947,6 +2982,7 @@ wpas_dpp_gas_status_handler(void *ctx, struct wpabuf *resp, int ok) wpa_printf(MSG_DEBUG, "DPP: Configuration exchange completed (ok=%d)", ok); eloop_cancel_timeout(wpas_dpp_reply_wait_timeout, wpa_s, NULL); + eloop_cancel_timeout(wpas_dpp_auth_conf_wait_timeout, wpa_s, NULL); eloop_cancel_timeout(wpas_dpp_auth_resp_retry_timeout, wpa_s, NULL); #ifdef CONFIG_DPP2 if (ok && auth->peer_version >= 2 && @@ -3324,6 +3360,7 @@ void wpas_dpp_deinit(struct wpa_supplicant *wpa_s) return; eloop_cancel_timeout(wpas_dpp_pkex_retry_timeout, wpa_s, NULL); eloop_cancel_timeout(wpas_dpp_reply_wait_timeout, wpa_s, NULL); + eloop_cancel_timeout(wpas_dpp_auth_conf_wait_timeout, wpa_s, NULL); eloop_cancel_timeout(wpas_dpp_init_timeout, wpa_s, NULL); eloop_cancel_timeout(wpas_dpp_auth_resp_retry_timeout, wpa_s, NULL); #ifdef CONFIG_DPP2