PASN: Add support for deauthentication flow in station
The new wpa_supplicant control interface command "PASN_DEAUTH bssid=<BSSID>" can now be used to flush the local PTKSA cache for the specified BSS and to notify the AP to request it to drop its PTKSA as well. Signed-off-by: Ilan Peer <ilan.peer@intel.com>
This commit is contained in:
parent
4f436d5378
commit
eaeec4da2d
4 changed files with 87 additions and 0 deletions
|
@ -10655,6 +10655,22 @@ static int wpas_ctrl_iface_pasn_start(struct wpa_supplicant *wpa_s, char *cmd)
|
||||||
|
|
||||||
return wpas_pasn_auth_start(wpa_s, bssid, akmp, cipher, group, id);
|
return wpas_pasn_auth_start(wpa_s, bssid, akmp, cipher, group, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int wpas_ctrl_iface_pasn_deauthenticate(struct wpa_supplicant *wpa_s,
|
||||||
|
const char *cmd)
|
||||||
|
{
|
||||||
|
u8 bssid[ETH_ALEN];
|
||||||
|
|
||||||
|
if (os_strncmp(cmd, "bssid=", 6) != 0 || hwaddr_aton(cmd + 6, bssid)) {
|
||||||
|
wpa_printf(MSG_DEBUG,
|
||||||
|
"CTRL: PASN_DEAUTH without valid BSSID");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return wpas_pasn_deauthenticate(wpa_s, bssid);
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* CONFIG_PASN */
|
#endif /* CONFIG_PASN */
|
||||||
|
|
||||||
|
|
||||||
|
@ -11576,6 +11592,9 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
|
||||||
wpas_pasn_auth_stop(wpa_s);
|
wpas_pasn_auth_stop(wpa_s);
|
||||||
} else if (os_strcmp(buf, "PTKSA_CACHE_LIST") == 0) {
|
} else if (os_strcmp(buf, "PTKSA_CACHE_LIST") == 0) {
|
||||||
reply_len = ptksa_cache_list(wpa_s->ptksa, reply, reply_size);
|
reply_len = ptksa_cache_list(wpa_s->ptksa, reply, reply_size);
|
||||||
|
} else if (os_strncmp(buf, "PASN_DEAUTH ", 12) == 0) {
|
||||||
|
if (wpas_ctrl_iface_pasn_deauthenticate(wpa_s, buf + 12) < 0)
|
||||||
|
reply_len = -1;
|
||||||
#endif /* CONFIG_PASN */
|
#endif /* CONFIG_PASN */
|
||||||
} else {
|
} else {
|
||||||
os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
|
os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
|
||||||
|
|
|
@ -1526,3 +1526,59 @@ int wpas_pasn_auth_tx_status(struct wpa_supplicant *wpa_s,
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int wpas_pasn_deauthenticate(struct wpa_supplicant *wpa_s, const u8 *bssid)
|
||||||
|
{
|
||||||
|
struct wpa_bss *bss;
|
||||||
|
struct wpabuf *buf;
|
||||||
|
struct ieee80211_mgmt *deauth;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (os_memcmp(wpa_s->bssid, bssid, ETH_ALEN) == 0) {
|
||||||
|
wpa_printf(MSG_DEBUG,
|
||||||
|
"PASN: Cannot deauthenticate from current BSS");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
wpa_printf(MSG_DEBUG, "PASN: deauth: Flushing all PTKSA entries for "
|
||||||
|
MACSTR, MAC2STR(bssid));
|
||||||
|
ptksa_cache_flush(wpa_s->ptksa, bssid, WPA_CIPHER_NONE);
|
||||||
|
|
||||||
|
bss = wpa_bss_get_bssid(wpa_s, bssid);
|
||||||
|
if (!bss) {
|
||||||
|
wpa_printf(MSG_DEBUG, "PASN: deauth: BSS not found");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
buf = wpabuf_alloc(64);
|
||||||
|
if (!buf) {
|
||||||
|
wpa_printf(MSG_DEBUG, "PASN: deauth: Failed wpabuf allocate");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
deauth = wpabuf_put(buf, offsetof(struct ieee80211_mgmt,
|
||||||
|
u.deauth.variable));
|
||||||
|
|
||||||
|
deauth->frame_control = host_to_le16((WLAN_FC_TYPE_MGMT << 2) |
|
||||||
|
(WLAN_FC_STYPE_DEAUTH << 4));
|
||||||
|
|
||||||
|
os_memcpy(deauth->da, bssid, ETH_ALEN);
|
||||||
|
os_memcpy(deauth->sa, wpa_s->own_addr, ETH_ALEN);
|
||||||
|
os_memcpy(deauth->bssid, bssid, ETH_ALEN);
|
||||||
|
deauth->u.deauth.reason_code =
|
||||||
|
host_to_le16(WLAN_REASON_PREV_AUTH_NOT_VALID);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Since we do not expect any response from the AP, implement the
|
||||||
|
* Deauthentication frame transmission using direct call to the driver
|
||||||
|
* without a radio work.
|
||||||
|
*/
|
||||||
|
ret = wpa_drv_send_mlme(wpa_s, wpabuf_head(buf), wpabuf_len(buf), 1,
|
||||||
|
bss->freq, 0);
|
||||||
|
|
||||||
|
wpabuf_free(buf);
|
||||||
|
wpa_printf(MSG_DEBUG, "PASN: deauth: send_mlme ret=%d", ret);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
|
@ -3210,6 +3210,13 @@ static int wpa_cli_cmd_ptksa_cache_list(struct wpa_ctrl *ctrl, int argc,
|
||||||
return wpa_cli_cmd(ctrl, "PTKSA_CACHE_LIST", 0, argc, argv);
|
return wpa_cli_cmd(ctrl, "PTKSA_CACHE_LIST", 0, argc, argv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int wpa_cli_cmd_pasn_deauth(struct wpa_ctrl *ctrl, int argc,
|
||||||
|
char *argv[])
|
||||||
|
{
|
||||||
|
return wpa_cli_cmd(ctrl, "PASN_DEAUTH", 1, argc, argv);
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* CONFIG_PASN */
|
#endif /* CONFIG_PASN */
|
||||||
|
|
||||||
|
|
||||||
|
@ -3913,6 +3920,9 @@ static const struct wpa_cli_cmd wpa_cli_commands[] = {
|
||||||
{ "ptksa_cache_list", wpa_cli_cmd_ptksa_cache_list, NULL,
|
{ "ptksa_cache_list", wpa_cli_cmd_ptksa_cache_list, NULL,
|
||||||
cli_cmd_flag_none,
|
cli_cmd_flag_none,
|
||||||
"= Get the PTKSA Cache" },
|
"= Get the PTKSA Cache" },
|
||||||
|
{ "pasn_deauth", wpa_cli_cmd_pasn_deauth, NULL,
|
||||||
|
cli_cmd_flag_none,
|
||||||
|
"bssid=<BSSID> = Remove PASN PTKSA state" },
|
||||||
#endif /* CONFIG_PASN */
|
#endif /* CONFIG_PASN */
|
||||||
{ NULL, NULL, NULL, cli_cmd_flag_none, NULL }
|
{ NULL, NULL, NULL, cli_cmd_flag_none, NULL }
|
||||||
};
|
};
|
||||||
|
|
|
@ -1737,4 +1737,6 @@ int wpas_pasn_auth_tx_status(struct wpa_supplicant *wpa_s,
|
||||||
int wpas_pasn_auth_rx(struct wpa_supplicant *wpa_s,
|
int wpas_pasn_auth_rx(struct wpa_supplicant *wpa_s,
|
||||||
const struct ieee80211_mgmt *mgmt, size_t len);
|
const struct ieee80211_mgmt *mgmt, size_t len);
|
||||||
|
|
||||||
|
int wpas_pasn_deauthenticate(struct wpa_supplicant *wpa_s, const u8 *bssid);
|
||||||
|
|
||||||
#endif /* WPA_SUPPLICANT_I_H */
|
#endif /* WPA_SUPPLICANT_I_H */
|
||||||
|
|
Loading…
Reference in a new issue