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>
This commit is contained in:
parent
62657365f8
commit
959af4f576
3 changed files with 76 additions and 0 deletions
|
@ -23,6 +23,8 @@
|
||||||
|
|
||||||
|
|
||||||
static void hostapd_dpp_reply_wait_timeout(void *eloop_ctx, void *timeout_ctx);
|
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_auth_success(struct hostapd_data *hapd, int initiator);
|
||||||
static void hostapd_dpp_init_timeout(void *eloop_ctx, void *timeout_ctx);
|
static void hostapd_dpp_init_timeout(void *eloop_ctx, void *timeout_ctx);
|
||||||
static int hostapd_dpp_auth_init_next(struct hostapd_data *hapd);
|
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_init_timeout, hapd, NULL);
|
||||||
eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout,
|
eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout,
|
||||||
hapd, NULL);
|
hapd, NULL);
|
||||||
|
eloop_cancel_timeout(hostapd_dpp_auth_conf_wait_timeout,
|
||||||
|
hapd, NULL);
|
||||||
eloop_cancel_timeout(hostapd_dpp_auth_resp_retry_timeout, hapd,
|
eloop_cancel_timeout(hostapd_dpp_auth_resp_retry_timeout, hapd,
|
||||||
NULL);
|
NULL);
|
||||||
#ifdef CONFIG_DPP2
|
#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) {
|
if (!is_broadcast_ether_addr(dst) && auth->waiting_auth_resp && ok) {
|
||||||
/* Allow timeout handling to stop iteration if no response is
|
/* Allow timeout handling to stop iteration if no response is
|
||||||
* received from a peer that has ACKed a request. */
|
* 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,
|
static void hostapd_dpp_set_testing_options(struct hostapd_data *hapd,
|
||||||
struct dpp_authentication *auth)
|
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_init_timeout, hapd, NULL);
|
||||||
eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout,
|
eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout,
|
||||||
hapd, NULL);
|
hapd, NULL);
|
||||||
|
eloop_cancel_timeout(hostapd_dpp_auth_conf_wait_timeout,
|
||||||
|
hapd, NULL);
|
||||||
eloop_cancel_timeout(hostapd_dpp_auth_resp_retry_timeout, hapd,
|
eloop_cancel_timeout(hostapd_dpp_auth_resp_retry_timeout, hapd,
|
||||||
NULL);
|
NULL);
|
||||||
#ifdef CONFIG_DPP2
|
#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)",
|
wpa_printf(MSG_DEBUG, "DPP: Configuration exchange completed (ok=%d)",
|
||||||
ok);
|
ok);
|
||||||
eloop_cancel_timeout(hostapd_dpp_reply_wait_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);
|
eloop_cancel_timeout(hostapd_dpp_auth_resp_retry_timeout, hapd, NULL);
|
||||||
#ifdef CONFIG_DPP2
|
#ifdef CONFIG_DPP2
|
||||||
eloop_cancel_timeout(hostapd_dpp_reconfig_reply_wait_timeout,
|
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)
|
if (!hapd->dpp_init_done)
|
||||||
return;
|
return;
|
||||||
eloop_cancel_timeout(hostapd_dpp_reply_wait_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_init_timeout, hapd, NULL);
|
eloop_cancel_timeout(hostapd_dpp_init_timeout, hapd, NULL);
|
||||||
eloop_cancel_timeout(hostapd_dpp_auth_resp_retry_timeout, hapd, NULL);
|
eloop_cancel_timeout(hostapd_dpp_auth_resp_retry_timeout, hapd, NULL);
|
||||||
#ifdef CONFIG_DPP2
|
#ifdef CONFIG_DPP2
|
||||||
|
|
|
@ -251,6 +251,7 @@ static struct wpabuf * dpp_auth_build_resp(struct dpp_authentication *auth,
|
||||||
u8 *attr_start, *attr_end, *pos;
|
u8 *attr_start, *attr_end, *pos;
|
||||||
|
|
||||||
auth->waiting_auth_conf = 1;
|
auth->waiting_auth_conf = 1;
|
||||||
|
auth->auth_resp_status = status;
|
||||||
auth->auth_resp_tries = 0;
|
auth->auth_resp_tries = 0;
|
||||||
|
|
||||||
/* Build DPP Authentication Response frame attributes */
|
/* Build DPP Authentication Response frame attributes */
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
static int wpas_dpp_listen_start(struct wpa_supplicant *wpa_s,
|
static int wpas_dpp_listen_start(struct wpa_supplicant *wpa_s,
|
||||||
unsigned int freq);
|
unsigned int freq);
|
||||||
static void wpas_dpp_reply_wait_timeout(void *eloop_ctx, void *timeout_ctx);
|
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_auth_success(struct wpa_supplicant *wpa_s, int initiator);
|
||||||
static void wpas_dpp_tx_status(struct wpa_supplicant *wpa_s,
|
static void wpas_dpp_tx_status(struct wpa_supplicant *wpa_s,
|
||||||
unsigned int freq, const u8 *dst,
|
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");
|
"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_init_timeout, wpa_s, NULL);
|
||||||
eloop_cancel_timeout(wpas_dpp_reply_wait_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,
|
eloop_cancel_timeout(wpas_dpp_auth_resp_retry_timeout, wpa_s,
|
||||||
NULL);
|
NULL);
|
||||||
#ifdef CONFIG_DPP2
|
#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 &&
|
if (!is_broadcast_ether_addr(dst) && auth->waiting_auth_resp &&
|
||||||
result == OFFCHANNEL_SEND_ACTION_SUCCESS) {
|
result == OFFCHANNEL_SEND_ACTION_SUCCESS) {
|
||||||
/* Allow timeout handling to stop iteration if no response is
|
/* 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,
|
static void wpas_dpp_set_testing_options(struct wpa_supplicant *wpa_s,
|
||||||
struct dpp_authentication *auth)
|
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) {
|
if (!tcp && wpa_s->dpp_auth) {
|
||||||
eloop_cancel_timeout(wpas_dpp_init_timeout, wpa_s, NULL);
|
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_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,
|
eloop_cancel_timeout(wpas_dpp_auth_resp_retry_timeout, wpa_s,
|
||||||
NULL);
|
NULL);
|
||||||
#ifdef CONFIG_DPP2
|
#ifdef CONFIG_DPP2
|
||||||
|
@ -1808,6 +1841,8 @@ static void wpas_dpp_rx_auth_conf(struct wpa_supplicant *wpa_s, const u8 *src,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
eloop_cancel_timeout(wpas_dpp_auth_conf_wait_timeout, wpa_s, NULL);
|
||||||
|
|
||||||
if (dpp_auth_conf_rx(auth, hdr, buf, len) < 0) {
|
if (dpp_auth_conf_rx(auth, hdr, buf, len) < 0) {
|
||||||
wpa_printf(MSG_DEBUG, "DPP: Authentication failed");
|
wpa_printf(MSG_DEBUG, "DPP: Authentication failed");
|
||||||
return;
|
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)",
|
wpa_printf(MSG_DEBUG, "DPP: Configuration exchange completed (ok=%d)",
|
||||||
ok);
|
ok);
|
||||||
eloop_cancel_timeout(wpas_dpp_reply_wait_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);
|
eloop_cancel_timeout(wpas_dpp_auth_resp_retry_timeout, wpa_s, NULL);
|
||||||
#ifdef CONFIG_DPP2
|
#ifdef CONFIG_DPP2
|
||||||
if (ok && auth->peer_version >= 2 &&
|
if (ok && auth->peer_version >= 2 &&
|
||||||
|
@ -3324,6 +3360,7 @@ void wpas_dpp_deinit(struct wpa_supplicant *wpa_s)
|
||||||
return;
|
return;
|
||||||
eloop_cancel_timeout(wpas_dpp_pkex_retry_timeout, wpa_s, NULL);
|
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_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_init_timeout, wpa_s, NULL);
|
||||||
eloop_cancel_timeout(wpas_dpp_auth_resp_retry_timeout, wpa_s, NULL);
|
eloop_cancel_timeout(wpas_dpp_auth_resp_retry_timeout, wpa_s, NULL);
|
||||||
#ifdef CONFIG_DPP2
|
#ifdef CONFIG_DPP2
|
||||||
|
|
Loading…
Reference in a new issue