wlantest: Parse WPA/RSN IE and store info for BSS/STA
In addition, verify that the parameters that the STA is requesting match with what is enabled in the BSS.
This commit is contained in:
parent
f3b87561d7
commit
327f71604c
3 changed files with 176 additions and 0 deletions
|
@ -15,6 +15,7 @@
|
||||||
#include "utils/includes.h"
|
#include "utils/includes.h"
|
||||||
|
|
||||||
#include "utils/common.h"
|
#include "utils/common.h"
|
||||||
|
#include "common/defs.h"
|
||||||
#include "common/ieee802_11_common.h"
|
#include "common/ieee802_11_common.h"
|
||||||
#include "crypto/sha1.h"
|
#include "crypto/sha1.h"
|
||||||
#include "wlantest.h"
|
#include "wlantest.h"
|
||||||
|
@ -103,6 +104,9 @@ static void bss_add_pmk(struct wlantest *wt, struct wlantest_bss *bss)
|
||||||
void bss_update(struct wlantest *wt, struct wlantest_bss *bss,
|
void bss_update(struct wlantest *wt, struct wlantest_bss *bss,
|
||||||
struct ieee802_11_elems *elems)
|
struct ieee802_11_elems *elems)
|
||||||
{
|
{
|
||||||
|
struct wpa_ie_data data;
|
||||||
|
int update = 0;
|
||||||
|
|
||||||
if (elems->ssid == NULL || elems->ssid_len > 32) {
|
if (elems->ssid == NULL || elems->ssid_len > 32) {
|
||||||
wpa_printf(MSG_INFO, "Invalid or missing SSID in a Beacon "
|
wpa_printf(MSG_INFO, "Invalid or missing SSID in a Beacon "
|
||||||
"frame for " MACSTR, MAC2STR(bss->bssid));
|
"frame for " MACSTR, MAC2STR(bss->bssid));
|
||||||
|
@ -126,6 +130,7 @@ void bss_update(struct wlantest *wt, struct wlantest_bss *bss,
|
||||||
wpa_printf(MSG_INFO, "BSS " MACSTR " - RSN IE removed",
|
wpa_printf(MSG_INFO, "BSS " MACSTR " - RSN IE removed",
|
||||||
MAC2STR(bss->bssid));
|
MAC2STR(bss->bssid));
|
||||||
bss->rsnie[0] = 0;
|
bss->rsnie[0] = 0;
|
||||||
|
update = 1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (bss->rsnie[0] == 0 ||
|
if (bss->rsnie[0] == 0 ||
|
||||||
|
@ -135,6 +140,7 @@ void bss_update(struct wlantest *wt, struct wlantest_bss *bss,
|
||||||
"stored", MAC2STR(bss->bssid));
|
"stored", MAC2STR(bss->bssid));
|
||||||
wpa_hexdump(MSG_DEBUG, "RSN IE", elems->rsn_ie - 2,
|
wpa_hexdump(MSG_DEBUG, "RSN IE", elems->rsn_ie - 2,
|
||||||
elems->rsn_ie_len + 2);
|
elems->rsn_ie_len + 2);
|
||||||
|
update = 1;
|
||||||
}
|
}
|
||||||
os_memcpy(bss->rsnie, elems->rsn_ie - 2,
|
os_memcpy(bss->rsnie, elems->rsn_ie - 2,
|
||||||
elems->rsn_ie_len + 2);
|
elems->rsn_ie_len + 2);
|
||||||
|
@ -145,6 +151,7 @@ void bss_update(struct wlantest *wt, struct wlantest_bss *bss,
|
||||||
wpa_printf(MSG_INFO, "BSS " MACSTR " - WPA IE removed",
|
wpa_printf(MSG_INFO, "BSS " MACSTR " - WPA IE removed",
|
||||||
MAC2STR(bss->bssid));
|
MAC2STR(bss->bssid));
|
||||||
bss->wpaie[0] = 0;
|
bss->wpaie[0] = 0;
|
||||||
|
update = 1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (bss->wpaie[0] == 0 ||
|
if (bss->wpaie[0] == 0 ||
|
||||||
|
@ -154,8 +161,94 @@ void bss_update(struct wlantest *wt, struct wlantest_bss *bss,
|
||||||
"stored", MAC2STR(bss->bssid));
|
"stored", MAC2STR(bss->bssid));
|
||||||
wpa_hexdump(MSG_DEBUG, "WPA IE", elems->wpa_ie - 2,
|
wpa_hexdump(MSG_DEBUG, "WPA IE", elems->wpa_ie - 2,
|
||||||
elems->wpa_ie_len + 2);
|
elems->wpa_ie_len + 2);
|
||||||
|
update = 1;
|
||||||
}
|
}
|
||||||
os_memcpy(bss->wpaie, elems->wpa_ie - 2,
|
os_memcpy(bss->wpaie, elems->wpa_ie - 2,
|
||||||
elems->wpa_ie_len + 2);
|
elems->wpa_ie_len + 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!update)
|
||||||
|
return;
|
||||||
|
|
||||||
|
bss->proto = 0;
|
||||||
|
bss->pairwise_cipher = 0;
|
||||||
|
bss->group_cipher = 0;
|
||||||
|
bss->key_mgmt = 0;
|
||||||
|
bss->rsn_capab = 0;
|
||||||
|
bss->mgmt_group_cipher = 0;
|
||||||
|
|
||||||
|
if (bss->wpaie[0]) {
|
||||||
|
if (wpa_parse_wpa_ie_wpa(bss->wpaie, 2 + bss->wpaie[1], &data)
|
||||||
|
< 0) {
|
||||||
|
wpa_printf(MSG_INFO, "Failed to parse WPA IE from "
|
||||||
|
MACSTR, MAC2STR(bss->bssid));
|
||||||
|
} else {
|
||||||
|
bss->proto |= data.proto;
|
||||||
|
bss->pairwise_cipher |= data.pairwise_cipher;
|
||||||
|
bss->group_cipher |= data.group_cipher;
|
||||||
|
bss->key_mgmt |= data.key_mgmt;
|
||||||
|
bss->rsn_capab = data.capabilities;
|
||||||
|
bss->mgmt_group_cipher |= data.mgmt_group_cipher;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bss->rsnie[0]) {
|
||||||
|
if (wpa_parse_wpa_ie_rsn(bss->rsnie, 2 + bss->rsnie[1], &data)
|
||||||
|
< 0) {
|
||||||
|
wpa_printf(MSG_INFO, "Failed to parse RSN IE from "
|
||||||
|
MACSTR, MAC2STR(bss->bssid));
|
||||||
|
} else {
|
||||||
|
bss->proto |= data.proto;
|
||||||
|
bss->pairwise_cipher |= data.pairwise_cipher;
|
||||||
|
bss->group_cipher |= data.group_cipher;
|
||||||
|
bss->key_mgmt |= data.key_mgmt;
|
||||||
|
bss->rsn_capab = data.capabilities;
|
||||||
|
bss->mgmt_group_cipher |= data.mgmt_group_cipher;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(bss->proto & WPA_PROTO_RSN) ||
|
||||||
|
!(bss->rsn_capab & WPA_CAPABILITY_MFPC))
|
||||||
|
bss->mgmt_group_cipher = 0;
|
||||||
|
|
||||||
|
wpa_printf(MSG_INFO, "BSS " MACSTR
|
||||||
|
" proto=%s%s%s"
|
||||||
|
"pairwise=%s%s%s%s"
|
||||||
|
"group=%s%s%s%s%s%s"
|
||||||
|
"mgmt_group_cipher=%s"
|
||||||
|
"key_mgmt=%s%s%s%s%s%s%s%s"
|
||||||
|
"rsn_capab=%s%s%s%s%s",
|
||||||
|
MAC2STR(bss->bssid),
|
||||||
|
bss->proto == 0 ? "OPEN " : "",
|
||||||
|
bss->proto & WPA_PROTO_WPA ? "WPA " : "",
|
||||||
|
bss->proto & WPA_PROTO_RSN ? "WPA2 " : "",
|
||||||
|
bss->pairwise_cipher == 0 ? "N/A " : "",
|
||||||
|
bss->pairwise_cipher & WPA_CIPHER_NONE ? "NONE " : "",
|
||||||
|
bss->pairwise_cipher & WPA_CIPHER_TKIP ? "TKIP " : "",
|
||||||
|
bss->pairwise_cipher & WPA_CIPHER_CCMP ? "CCMP " : "",
|
||||||
|
bss->group_cipher == 0 ? "N/A " : "",
|
||||||
|
bss->group_cipher & WPA_CIPHER_NONE ? "NONE " : "",
|
||||||
|
bss->group_cipher & WPA_CIPHER_WEP40 ? "WEP40 " : "",
|
||||||
|
bss->group_cipher & WPA_CIPHER_WEP104 ? "WEP104 " : "",
|
||||||
|
bss->group_cipher & WPA_CIPHER_TKIP ? "TKIP " : "",
|
||||||
|
bss->group_cipher & WPA_CIPHER_CCMP ? "CCMP " : "",
|
||||||
|
bss->mgmt_group_cipher & WPA_CIPHER_AES_128_CMAC ? "BIP " :
|
||||||
|
"N/A ",
|
||||||
|
bss->key_mgmt == 0 ? "N/A " : "",
|
||||||
|
bss->key_mgmt & WPA_KEY_MGMT_IEEE8021X ? "EAP " : "",
|
||||||
|
bss->key_mgmt & WPA_KEY_MGMT_PSK ? "PSK " : "",
|
||||||
|
bss->key_mgmt & WPA_KEY_MGMT_WPA_NONE ? "WPA-NONE " : "",
|
||||||
|
bss->key_mgmt & WPA_KEY_MGMT_FT_IEEE8021X ? "FT-EAP " : "",
|
||||||
|
bss->key_mgmt & WPA_KEY_MGMT_FT_PSK ? "FT-PSK " : "",
|
||||||
|
bss->key_mgmt & WPA_KEY_MGMT_IEEE8021X_SHA256 ?
|
||||||
|
"EAP-SHA256 " : "",
|
||||||
|
bss->key_mgmt & WPA_KEY_MGMT_PSK_SHA256 ?
|
||||||
|
"PSK-SHA256 " : "",
|
||||||
|
bss->rsn_capab & WPA_CAPABILITY_PREAUTH ? "PREAUTH " : "",
|
||||||
|
bss->rsn_capab & WPA_CAPABILITY_NO_PAIRWISE ?
|
||||||
|
"NO_PAIRWISE " : "",
|
||||||
|
bss->rsn_capab & WPA_CAPABILITY_MFPR ? "MFPR " : "",
|
||||||
|
bss->rsn_capab & WPA_CAPABILITY_MFPC ? "MFPC " : "",
|
||||||
|
bss->rsn_capab & WPA_CAPABILITY_PEERKEY_ENABLED ?
|
||||||
|
"PEERKEY " : "");
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#include "utils/includes.h"
|
#include "utils/includes.h"
|
||||||
|
|
||||||
#include "utils/common.h"
|
#include "utils/common.h"
|
||||||
|
#include "common/defs.h"
|
||||||
#include "common/ieee802_11_common.h"
|
#include "common/ieee802_11_common.h"
|
||||||
#include "wlantest.h"
|
#include "wlantest.h"
|
||||||
|
|
||||||
|
@ -34,6 +35,7 @@ struct wlantest_sta * sta_get(struct wlantest_bss *bss, const u8 *addr)
|
||||||
sta = os_zalloc(sizeof(*sta));
|
sta = os_zalloc(sizeof(*sta));
|
||||||
if (sta == NULL)
|
if (sta == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
sta->bss = bss;
|
||||||
os_memcpy(sta->addr, addr, ETH_ALEN);
|
os_memcpy(sta->addr, addr, ETH_ALEN);
|
||||||
dl_list_add(&bss->sta, &sta->list);
|
dl_list_add(&bss->sta, &sta->list);
|
||||||
wpa_printf(MSG_DEBUG, "Discovered new STA " MACSTR " in BSS " MACSTR,
|
wpa_printf(MSG_DEBUG, "Discovered new STA " MACSTR " in BSS " MACSTR,
|
||||||
|
@ -51,6 +53,9 @@ void sta_deinit(struct wlantest_sta *sta)
|
||||||
|
|
||||||
void sta_update_assoc(struct wlantest_sta *sta, struct ieee802_11_elems *elems)
|
void sta_update_assoc(struct wlantest_sta *sta, struct ieee802_11_elems *elems)
|
||||||
{
|
{
|
||||||
|
struct wpa_ie_data data;
|
||||||
|
struct wlantest_bss *bss = sta->bss;
|
||||||
|
|
||||||
if (elems->wpa_ie && elems->rsn_ie) {
|
if (elems->wpa_ie && elems->rsn_ie) {
|
||||||
wpa_printf(MSG_INFO, "Both WPA IE and RSN IE included in "
|
wpa_printf(MSG_INFO, "Both WPA IE and RSN IE included in "
|
||||||
"Association Request frame from " MACSTR,
|
"Association Request frame from " MACSTR,
|
||||||
|
@ -62,11 +67,76 @@ void sta_update_assoc(struct wlantest_sta *sta, struct ieee802_11_elems *elems)
|
||||||
elems->rsn_ie_len + 2);
|
elems->rsn_ie_len + 2);
|
||||||
os_memcpy(sta->rsnie, elems->rsn_ie - 2,
|
os_memcpy(sta->rsnie, elems->rsn_ie - 2,
|
||||||
elems->rsn_ie_len + 2);
|
elems->rsn_ie_len + 2);
|
||||||
|
if (wpa_parse_wpa_ie_rsn(sta->rsnie, 2 + sta->rsnie[1], &data)
|
||||||
|
< 0) {
|
||||||
|
wpa_printf(MSG_INFO, "Failed to parse RSN IE from "
|
||||||
|
MACSTR, MAC2STR(sta->addr));
|
||||||
|
}
|
||||||
} else if (elems->wpa_ie) {
|
} else if (elems->wpa_ie) {
|
||||||
wpa_hexdump(MSG_DEBUG, "WPA IE", elems->wpa_ie - 2,
|
wpa_hexdump(MSG_DEBUG, "WPA IE", elems->wpa_ie - 2,
|
||||||
elems->wpa_ie_len + 2);
|
elems->wpa_ie_len + 2);
|
||||||
os_memcpy(sta->rsnie, elems->wpa_ie - 2,
|
os_memcpy(sta->rsnie, elems->wpa_ie - 2,
|
||||||
elems->wpa_ie_len + 2);
|
elems->wpa_ie_len + 2);
|
||||||
|
if (wpa_parse_wpa_ie_wpa(sta->rsnie, 2 + sta->rsnie[1], &data)
|
||||||
|
< 0) {
|
||||||
|
wpa_printf(MSG_INFO, "Failed to parse WPA IE from "
|
||||||
|
MACSTR, MAC2STR(sta->addr));
|
||||||
|
}
|
||||||
} else
|
} else
|
||||||
sta->rsnie[0] = 0;
|
sta->rsnie[0] = 0;
|
||||||
|
|
||||||
|
sta->proto = data.proto;
|
||||||
|
sta->pairwise_cipher = data.pairwise_cipher;
|
||||||
|
sta->key_mgmt = data.key_mgmt;
|
||||||
|
sta->rsn_capab = data.capabilities;
|
||||||
|
if (bss->proto && (sta->proto & bss->proto) == 0) {
|
||||||
|
wpa_printf(MSG_INFO, "Mismatch in WPA/WPA2 proto: STA "
|
||||||
|
MACSTR " 0x%x BSS " MACSTR " 0x%x",
|
||||||
|
MAC2STR(sta->addr), sta->proto,
|
||||||
|
MAC2STR(bss->bssid), bss->proto);
|
||||||
|
}
|
||||||
|
if (bss->pairwise_cipher &&
|
||||||
|
(sta->pairwise_cipher & bss->pairwise_cipher) == 0) {
|
||||||
|
wpa_printf(MSG_INFO, "Mismatch in pairwise cipher: STA "
|
||||||
|
MACSTR " 0x%x BSS " MACSTR " 0x%x",
|
||||||
|
MAC2STR(sta->addr), sta->pairwise_cipher,
|
||||||
|
MAC2STR(bss->bssid), bss->pairwise_cipher);
|
||||||
|
}
|
||||||
|
if (sta->proto && data.group_cipher != bss->group_cipher) {
|
||||||
|
wpa_printf(MSG_INFO, "Mismatch in group cipher: STA "
|
||||||
|
MACSTR " 0x%x != BSS " MACSTR " 0x%x",
|
||||||
|
MAC2STR(sta->addr), data.group_cipher,
|
||||||
|
MAC2STR(bss->bssid), bss->group_cipher);
|
||||||
|
}
|
||||||
|
|
||||||
|
wpa_printf(MSG_INFO, "STA " MACSTR
|
||||||
|
" proto=%s%s%s"
|
||||||
|
"pairwise=%s%s%s%s"
|
||||||
|
"key_mgmt=%s%s%s%s%s%s%s%s"
|
||||||
|
"rsn_capab=%s%s%s%s%s",
|
||||||
|
MAC2STR(sta->addr),
|
||||||
|
sta->proto == 0 ? "OPEN " : "",
|
||||||
|
sta->proto & WPA_PROTO_WPA ? "WPA " : "",
|
||||||
|
sta->proto & WPA_PROTO_RSN ? "WPA2 " : "",
|
||||||
|
sta->pairwise_cipher == 0 ? "N/A " : "",
|
||||||
|
sta->pairwise_cipher & WPA_CIPHER_NONE ? "NONE " : "",
|
||||||
|
sta->pairwise_cipher & WPA_CIPHER_TKIP ? "TKIP " : "",
|
||||||
|
sta->pairwise_cipher & WPA_CIPHER_CCMP ? "CCMP " : "",
|
||||||
|
sta->key_mgmt == 0 ? "N/A " : "",
|
||||||
|
sta->key_mgmt & WPA_KEY_MGMT_IEEE8021X ? "EAP " : "",
|
||||||
|
sta->key_mgmt & WPA_KEY_MGMT_PSK ? "PSK " : "",
|
||||||
|
sta->key_mgmt & WPA_KEY_MGMT_WPA_NONE ? "WPA-NONE " : "",
|
||||||
|
sta->key_mgmt & WPA_KEY_MGMT_FT_IEEE8021X ? "FT-EAP " : "",
|
||||||
|
sta->key_mgmt & WPA_KEY_MGMT_FT_PSK ? "FT-PSK " : "",
|
||||||
|
sta->key_mgmt & WPA_KEY_MGMT_IEEE8021X_SHA256 ?
|
||||||
|
"EAP-SHA256 " : "",
|
||||||
|
sta->key_mgmt & WPA_KEY_MGMT_PSK_SHA256 ?
|
||||||
|
"PSK-SHA256 " : "",
|
||||||
|
sta->rsn_capab & WPA_CAPABILITY_PREAUTH ? "PREAUTH " : "",
|
||||||
|
sta->rsn_capab & WPA_CAPABILITY_NO_PAIRWISE ?
|
||||||
|
"NO_PAIRWISE " : "",
|
||||||
|
sta->rsn_capab & WPA_CAPABILITY_MFPR ? "MFPR " : "",
|
||||||
|
sta->rsn_capab & WPA_CAPABILITY_MFPC ? "MFPC " : "",
|
||||||
|
sta->rsn_capab & WPA_CAPABILITY_PEERKEY_ENABLED ?
|
||||||
|
"PEERKEY " : "");
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
struct ieee802_11_elems;
|
struct ieee802_11_elems;
|
||||||
struct radius_msg;
|
struct radius_msg;
|
||||||
struct ieee80211_hdr;
|
struct ieee80211_hdr;
|
||||||
|
struct wlantest_bss;
|
||||||
|
|
||||||
#define MAX_RADIUS_SECRET_LEN 128
|
#define MAX_RADIUS_SECRET_LEN 128
|
||||||
|
|
||||||
|
@ -44,6 +45,7 @@ struct wlantest_pmk {
|
||||||
|
|
||||||
struct wlantest_sta {
|
struct wlantest_sta {
|
||||||
struct dl_list list;
|
struct dl_list list;
|
||||||
|
struct wlantest_bss *bss;
|
||||||
u8 addr[ETH_ALEN];
|
u8 addr[ETH_ALEN];
|
||||||
enum {
|
enum {
|
||||||
STATE1 /* not authenticated */,
|
STATE1 /* not authenticated */,
|
||||||
|
@ -52,6 +54,11 @@ struct wlantest_sta {
|
||||||
} state;
|
} state;
|
||||||
u16 aid;
|
u16 aid;
|
||||||
u8 rsnie[257]; /* WPA/RSN IE */
|
u8 rsnie[257]; /* WPA/RSN IE */
|
||||||
|
int proto;
|
||||||
|
int pairwise_cipher;
|
||||||
|
int group_cipher;
|
||||||
|
int key_mgmt;
|
||||||
|
int rsn_capab;
|
||||||
u8 anonce[32]; /* ANonce from the previous EAPOL-Key msg 1/4 or 3/4 */
|
u8 anonce[32]; /* ANonce from the previous EAPOL-Key msg 1/4 or 3/4 */
|
||||||
u8 snonce[32]; /* SNonce from the previous EAPOL-Key msg 2/4 */
|
u8 snonce[32]; /* SNonce from the previous EAPOL-Key msg 2/4 */
|
||||||
struct wpa_ptk ptk; /* Derived PTK */
|
struct wpa_ptk ptk; /* Derived PTK */
|
||||||
|
@ -72,6 +79,12 @@ struct wlantest_bss {
|
||||||
int parse_error_reported;
|
int parse_error_reported;
|
||||||
u8 wpaie[257];
|
u8 wpaie[257];
|
||||||
u8 rsnie[257];
|
u8 rsnie[257];
|
||||||
|
int proto;
|
||||||
|
int pairwise_cipher;
|
||||||
|
int group_cipher;
|
||||||
|
int mgmt_group_cipher;
|
||||||
|
int key_mgmt;
|
||||||
|
int rsn_capab;
|
||||||
struct dl_list sta; /* struct wlantest_sta */
|
struct dl_list sta; /* struct wlantest_sta */
|
||||||
struct dl_list pmk; /* struct wlantest_pmk */
|
struct dl_list pmk; /* struct wlantest_pmk */
|
||||||
u8 gtk[4][32];
|
u8 gtk[4][32];
|
||||||
|
|
Loading…
Reference in a new issue