aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJouni Malinen <j@w1.fi>2019-01-04 20:58:56 (GMT)
committerJouni Malinen <j@w1.fi>2019-01-04 21:22:46 (GMT)
commit4cf5efece394067542673a252d6ea67b898b8eb9 (patch)
tree5d95273835d2cafe929aa51ebb7bb947ef4a2fa9
parentf808bd59e8c707f35ba34af14925894f83061d0f (diff)
downloadhostap-4cf5efece394067542673a252d6ea67b898b8eb9.zip
hostap-4cf5efece394067542673a252d6ea67b898b8eb9.tar.gz
hostap-4cf5efece394067542673a252d6ea67b898b8eb9.tar.bz2
FT: Allow STA entry to be removed/re-added with FT-over-the-DS
FT-over-the-DS has a special case where the STA entry (and as such, the TK) has not yet been configured to the driver depending on which driver interface is used. For that case, allow add-STA operation to be used (instead of set-STA). This is needed to allow mac80211-based drivers to accept the STA parameter configuration. Since this is after a new FT-over-DS exchange, a new TK has been derived after the last STA entry was added to the driver, so key reinstallation is not a concern for this case. Fixes: 0e3bd7ac684a ("hostapd: Avoid key reinstallation in FT handshake") Signed-off-by: Jouni Malinen <j@w1.fi>
-rw-r--r--src/ap/ieee802_11.c28
-rw-r--r--src/ap/sta_info.h1
-rw-r--r--src/ap/wpa_auth_glue.c6
3 files changed, 33 insertions, 2 deletions
diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
index a3b5e99..c6138e1 100644
--- a/src/ap/ieee802_11.c
+++ b/src/ap/ieee802_11.c
@@ -1943,6 +1943,7 @@ static void handle_auth(struct hostapd_data *hapd,
sta = ap_get_sta(hapd, mgmt->sa);
if (sta) {
sta->flags &= ~WLAN_STA_PENDING_FILS_ERP;
+ sta->ft_over_ds = 0;
if ((fc & WLAN_FC_RETRY) &&
sta->last_seq_ctrl != WLAN_INVALID_MGMT_SEQ &&
sta->last_seq_ctrl == seq_ctrl &&
@@ -2911,7 +2912,7 @@ static void send_deauth(struct hostapd_data *hapd, const u8 *addr,
static int add_associated_sta(struct hostapd_data *hapd,
- struct sta_info *sta)
+ struct sta_info *sta, int reassoc)
{
struct ieee80211_ht_capabilities ht_cap;
struct ieee80211_vht_capabilities vht_cap;
@@ -2927,14 +2928,36 @@ static int add_associated_sta(struct hostapd_data *hapd,
* Skip this if the STA has already completed FT reassociation and the
* TK has been configured since the TX/RX PN must not be reset to 0 for
* the same key.
+ *
+ * FT-over-the-DS has a special case where the STA entry (and as such,
+ * the TK) has not yet been configured to the driver depending on which
+ * driver interface is used. For that case, allow add-STA operation to
+ * be used (instead of set-STA). This is needed to allow mac80211-based
+ * drivers to accept the STA parameter configuration. Since this is
+ * after a new FT-over-DS exchange, a new TK has been derived, so key
+ * reinstallation is not a concern for this case.
*/
+ wpa_printf(MSG_DEBUG, "Add associated STA " MACSTR
+ " (added_unassoc=%d auth_alg=%u ft_over_ds=%u reassoc=%d authorized=%d ft_tk=%d fils_tk=%d)",
+ MAC2STR(sta->addr), sta->added_unassoc, sta->auth_alg,
+ sta->ft_over_ds, reassoc,
+ !!(sta->flags & WLAN_STA_AUTHORIZED),
+ wpa_auth_sta_ft_tk_already_set(sta->wpa_sm),
+ wpa_auth_sta_fils_tk_already_set(sta->wpa_sm));
+
if (!sta->added_unassoc &&
(!(sta->flags & WLAN_STA_AUTHORIZED) ||
+ (reassoc && sta->ft_over_ds && sta->auth_alg == WLAN_AUTH_FT) ||
(!wpa_auth_sta_ft_tk_already_set(sta->wpa_sm) &&
!wpa_auth_sta_fils_tk_already_set(sta->wpa_sm)))) {
hostapd_drv_sta_remove(hapd, sta->addr);
wpa_auth_sm_event(sta->wpa_sm, WPA_DRV_STA_REMOVED);
set = 0;
+
+ /* Do not allow the FT-over-DS exception to be used more than
+ * once per authentication exchange to guarantee a new TK is
+ * used here */
+ sta->ft_over_ds = 0;
}
#ifdef CONFIG_IEEE80211N
@@ -3691,7 +3714,8 @@ static void handle_assoc(struct hostapd_data *hapd,
* issues with processing other non-Data Class 3 frames during this
* window.
*/
- if (resp == WLAN_STATUS_SUCCESS && sta && add_associated_sta(hapd, sta))
+ if (resp == WLAN_STATUS_SUCCESS && sta &&
+ add_associated_sta(hapd, sta, reassoc))
resp = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
#ifdef CONFIG_FILS
diff --git a/src/ap/sta_info.h b/src/ap/sta_info.h
index 5c9bf57..fe68369 100644
--- a/src/ap/sta_info.h
+++ b/src/ap/sta_info.h
@@ -118,6 +118,7 @@ struct sta_info {
unsigned int power_capab:1;
unsigned int agreed_to_steer:1;
unsigned int hs20_t_c_filtering:1;
+ unsigned int ft_over_ds:1;
u16 auth_alg;
diff --git a/src/ap/wpa_auth_glue.c b/src/ap/wpa_auth_glue.c
index 5ba88d1..9091f43 100644
--- a/src/ap/wpa_auth_glue.c
+++ b/src/ap/wpa_auth_glue.c
@@ -847,12 +847,18 @@ hostapd_wpa_auth_add_sta(void *ctx, const u8 *sta_addr)
struct hostapd_data *hapd = ctx;
struct sta_info *sta;
+ wpa_printf(MSG_DEBUG, "Add station entry for " MACSTR
+ " based on WPA authenticator callback",
+ MAC2STR(sta_addr));
if (hostapd_add_sta_node(hapd, sta_addr, WLAN_AUTH_FT) < 0)
return NULL;
sta = ap_sta_add(hapd, sta_addr);
if (sta == NULL)
return NULL;
+ if (hapd->driver && hapd->driver->add_sta_node)
+ sta->added_unassoc = 1;
+ sta->ft_over_ds = 1;
if (sta->wpa_sm) {
sta->auth_alg = WLAN_AUTH_FT;
return sta->wpa_sm;