TDLS: Do not allow setup to be started if AP prohibits TDLS
This commit is contained in:
parent
fb12d186b6
commit
52c9e6f3f5
7 changed files with 68 additions and 1 deletions
|
@ -1168,6 +1168,7 @@ static int wpa_tdls_process_tpk_m1(struct wpa_sm *sm, const u8 *src_addr,
|
|||
u8 dtoken;
|
||||
u16 ielen;
|
||||
u16 status = WLAN_STATUS_UNSPECIFIED_FAILURE;
|
||||
int tdls_prohibited = sm->tdls_prohibited;
|
||||
|
||||
if (len < 3 + 3)
|
||||
return -1;
|
||||
|
@ -1226,6 +1227,12 @@ static int wpa_tdls_process_tpk_m1(struct wpa_sm *sm, const u8 *src_addr,
|
|||
}
|
||||
#endif /* CONFIG_TDLS_TESTING */
|
||||
|
||||
if (tdls_prohibited) {
|
||||
wpa_printf(MSG_INFO, "TDLS: TDLS prohibited in this BSS");
|
||||
status = WLAN_STATUS_REQUEST_DECLINED;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (!wpa_tdls_get_privacy(sm)) {
|
||||
if (kde.rsn_ie) {
|
||||
wpa_printf(MSG_INFO, "TDLS: RSN IE in TPK M1 while "
|
||||
|
@ -1808,6 +1815,13 @@ static u8 * wpa_add_tdls_timeoutie(u8 *pos, u8 *ie, size_t ie_len, u32 tsecs)
|
|||
int wpa_tdls_start(struct wpa_sm *sm, const u8 *addr)
|
||||
{
|
||||
struct wpa_tdls_peer *peer;
|
||||
int tdls_prohibited = sm->tdls_prohibited;
|
||||
|
||||
if (tdls_prohibited) {
|
||||
wpa_printf(MSG_DEBUG, "TDLS: TDLS is prohibited in this BSS - "
|
||||
"reject request to start setup");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Find existing entry and if found, use that instead of adding
|
||||
* a new one */
|
||||
|
@ -1984,3 +1998,39 @@ void wpa_tdls_disassoc(struct wpa_sm *sm)
|
|||
wpa_printf(MSG_DEBUG, "TDLS: Remove peers on disassociation");
|
||||
wpa_tdls_remove_peers(sm);
|
||||
}
|
||||
|
||||
|
||||
static int wpa_tdls_prohibited(const u8 *ies, size_t len)
|
||||
{
|
||||
struct wpa_eapol_ie_parse elems;
|
||||
|
||||
if (ies == NULL)
|
||||
return 0;
|
||||
|
||||
if (wpa_supplicant_parse_ies(ies, len, &elems) < 0)
|
||||
return 0;
|
||||
|
||||
if (elems.ext_capab == NULL || elems.ext_capab_len < 2 + 5)
|
||||
return 0;
|
||||
|
||||
/* bit 38 - TDLS Prohibited */
|
||||
return !!(elems.ext_capab[2 + 4] & 0x40);
|
||||
}
|
||||
|
||||
|
||||
void wpa_tdls_ap_ies(struct wpa_sm *sm, const u8 *ies, size_t len)
|
||||
{
|
||||
sm->tdls_prohibited = wpa_tdls_prohibited(ies, len);
|
||||
wpa_printf(MSG_DEBUG, "TDLS: TDLS is %s in the target BSS",
|
||||
sm->tdls_prohibited ? "prohibited" : "allowed");
|
||||
}
|
||||
|
||||
|
||||
void wpa_tdls_assoc_resp_ies(struct wpa_sm *sm, const u8 *ies, size_t len)
|
||||
{
|
||||
if (!sm->tdls_prohibited && wpa_tdls_prohibited(ies, len)) {
|
||||
wpa_printf(MSG_DEBUG, "TDLS: TDLS prohibited based on "
|
||||
"(Re)Association Response IEs");
|
||||
sm->tdls_prohibited = 1;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -338,6 +338,8 @@ wpa_ft_validate_reassoc_resp(struct wpa_sm *sm, const u8 *ies, size_t ies_len,
|
|||
|
||||
|
||||
/* tdls.c */
|
||||
void wpa_tdls_ap_ies(struct wpa_sm *sm, const u8 *ies, size_t len);
|
||||
void wpa_tdls_assoc_resp_ies(struct wpa_sm *sm, const u8 *ies, size_t len);
|
||||
int wpa_tdls_start(struct wpa_sm *sm, const u8 *addr);
|
||||
int wpa_tdls_reneg(struct wpa_sm *sm, const u8 *addr);
|
||||
int wpa_tdls_recv_teardown_notify(struct wpa_sm *sm, const u8 *addr,
|
||||
|
|
|
@ -96,6 +96,7 @@ struct wpa_sm {
|
|||
#endif /* CONFIG_PEERKEY */
|
||||
#ifdef CONFIG_TDLS
|
||||
struct wpa_tdls_peer *tdls;
|
||||
int tdls_prohibited;
|
||||
#endif /* CONFIG_TDLS */
|
||||
|
||||
#ifdef CONFIG_IEEE80211R
|
||||
|
|
|
@ -426,6 +426,9 @@ int wpa_supplicant_parse_ies(const u8 *buf, size_t len,
|
|||
} else if (*pos == WLAN_EID_LINK_ID) {
|
||||
ie->lnkid = pos;
|
||||
ie->lnkid_len = pos[1] + 2;
|
||||
} else if (*pos == WLAN_EID_EXT_CAPAB) {
|
||||
ie->ext_capab = pos;
|
||||
ie->ext_capab_len = pos[1] + 2;
|
||||
} else if (*pos == WLAN_EID_VENDOR_SPECIFIC) {
|
||||
ret = wpa_parse_generic(pos, end, ie);
|
||||
if (ret < 0)
|
||||
|
|
|
@ -49,6 +49,8 @@ struct wpa_eapol_ie_parse {
|
|||
const u8 *key_lifetime;
|
||||
const u8 *lnkid;
|
||||
size_t lnkid_len;
|
||||
const u8 *ext_capab;
|
||||
size_t ext_capab_len;
|
||||
};
|
||||
|
||||
int wpa_supplicant_parse_ies(const u8 *buf, size_t len,
|
||||
|
|
|
@ -1024,9 +1024,14 @@ static int wpa_supplicant_event_associnfo(struct wpa_supplicant *wpa_s,
|
|||
if (data->assoc_info.req_ies)
|
||||
wpa_hexdump(MSG_DEBUG, "req_ies", data->assoc_info.req_ies,
|
||||
data->assoc_info.req_ies_len);
|
||||
if (data->assoc_info.resp_ies)
|
||||
if (data->assoc_info.resp_ies) {
|
||||
wpa_hexdump(MSG_DEBUG, "resp_ies", data->assoc_info.resp_ies,
|
||||
data->assoc_info.resp_ies_len);
|
||||
#ifdef CONFIG_TDLS
|
||||
wpa_tdls_assoc_resp_ies(wpa_s->wpa, data->assoc_info.resp_ies,
|
||||
data->assoc_info.resp_ies_len);
|
||||
#endif /* CONFIG_TDLS */
|
||||
}
|
||||
if (data->assoc_info.beacon_ies)
|
||||
wpa_hexdump(MSG_DEBUG, "beacon_ies",
|
||||
data->assoc_info.beacon_ies,
|
||||
|
|
|
@ -1046,6 +1046,10 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s,
|
|||
return;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_TDLS
|
||||
wpa_tdls_ap_ies(wpa_s->wpa, (const u8 *) (bss + 1), bss->ie_len);
|
||||
#endif /* CONFIG_TDLS */
|
||||
|
||||
if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) &&
|
||||
ssid->mode == IEEE80211_MODE_INFRA) {
|
||||
sme_authenticate(wpa_s, bss, ssid);
|
||||
|
|
Loading…
Reference in a new issue