DPP: Abort authentication if no Auth Confirm is received within a second

After sending DPP Auth Response, the Responder might not receive the
Auth Confirm either due to the Initiator not sending it or the reception
of the frame failing for some reason (e.g., Responder having already
left the negotiation channel). If this happens, following initiation
attempts would fail since the consecutive Auth Request would get
discarded since the previous authentication is still in progress.

Terminate DPP authentication on Responder, if no Auth Confirm is
received within one second of successfully sending Auth Response. This
allows the Responder to accept start of a new exchange.

Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
master
Purushottam Kushwaha 3 years ago committed by Jouni Malinen
parent 62657365f8
commit 959af4f576

@ -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

@ -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 */

@ -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

Loading…
Cancel
Save