wlantest: Update BSS IEs based on EAPOL-Key msg 3/4

If no Beacon or Probe Response frame has been seen in the capture, use
the IEs from EAPOL-Key msg 3/4 to set up BSS information.

Signed-off-by: Jouni Malinen <j@w1.fi>
This commit is contained in:
Jouni Malinen 2020-02-28 00:51:07 +02:00
parent a8a277c169
commit 0e3e3a9ab5
5 changed files with 49 additions and 24 deletions

View file

@ -129,7 +129,7 @@ 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, int beacon)
{ {
struct wpa_ie_data data; struct wpa_ie_data data;
int update = 0; int update = 0;
@ -137,15 +137,18 @@ void bss_update(struct wlantest *wt, struct wlantest_bss *bss,
if (bss->capab_info != bss->prev_capab_info) if (bss->capab_info != bss->prev_capab_info)
update = 1; update = 1;
if (elems->ssid == NULL || elems->ssid_len > 32) { if (beacon && (!elems->ssid || elems->ssid_len > 32)) {
wpa_printf(MSG_INFO, "Invalid or missing SSID in a Beacon " wpa_printf(MSG_INFO,
"frame for " MACSTR, MAC2STR(bss->bssid)); "Invalid or missing SSID in a %s frame for " MACSTR,
beacon == 1 ? "Beacon" : "Probe Response",
MAC2STR(bss->bssid));
bss->parse_error_reported = 1; bss->parse_error_reported = 1;
return; return;
} }
if (bss->ssid_len != elems->ssid_len || if (beacon &&
os_memcmp(bss->ssid, elems->ssid, bss->ssid_len) != 0) { (bss->ssid_len != elems->ssid_len ||
os_memcmp(bss->ssid, elems->ssid, bss->ssid_len) != 0)) {
wpa_printf(MSG_DEBUG, "Store SSID '%s' for BSSID " MACSTR, wpa_printf(MSG_DEBUG, "Store SSID '%s' for BSSID " MACSTR,
wpa_ssid_txt(elems->ssid, elems->ssid_len), wpa_ssid_txt(elems->ssid, elems->ssid_len),
MAC2STR(bss->bssid)); MAC2STR(bss->bssid));
@ -223,7 +226,11 @@ void bss_update(struct wlantest *wt, struct wlantest_bss *bss,
if (!update) if (!update)
return; return;
if (beacon == 1)
bss->beacon_seen = 1; bss->beacon_seen = 1;
else if (beacon == 2)
bss->proberesp_seen = 1;
bss->ies_set = 1;
bss->prev_capab_info = bss->capab_info; bss->prev_capab_info = bss->capab_info;
bss->proto = 0; bss->proto = 0;
bss->pairwise_cipher = 0; bss->pairwise_cipher = 0;

View file

@ -222,6 +222,25 @@ static void derive_ptk(struct wlantest *wt, struct wlantest_bss *bss,
} }
static void elems_from_eapol_ie(struct ieee802_11_elems *elems,
struct wpa_eapol_ie_parse *ie)
{
os_memset(elems, 0, sizeof(*elems));
if (ie->wpa_ie) {
elems->wpa_ie = ie->wpa_ie + 2;
elems->wpa_ie_len = ie->wpa_ie_len - 2;
}
if (ie->rsn_ie) {
elems->rsn_ie = ie->rsn_ie + 2;
elems->rsn_ie_len = ie->rsn_ie_len - 2;
}
if (ie->osen) {
elems->osen = ie->osen + 2;
elems->osen_len = ie->osen_len - 2;
}
}
static void rx_data_eapol_key_2_of_4(struct wlantest *wt, const u8 *dst, static void rx_data_eapol_key_2_of_4(struct wlantest *wt, const u8 *dst,
const u8 *src, const u8 *data, size_t len) const u8 *src, const u8 *data, size_t len)
{ {
@ -268,19 +287,7 @@ static void rx_data_eapol_key_2_of_4(struct wlantest *wt, const u8 *dst,
if (!sta->assocreq_seen) { if (!sta->assocreq_seen) {
struct ieee802_11_elems elems; struct ieee802_11_elems elems;
os_memset(&elems, 0, sizeof(elems)); elems_from_eapol_ie(&elems, &ie);
if (ie.wpa_ie) {
elems.wpa_ie = ie.wpa_ie + 2;
elems.wpa_ie_len = ie.wpa_ie_len - 2;
}
if (ie.rsn_ie) {
elems.rsn_ie = ie.rsn_ie + 2;
elems.rsn_ie_len = ie.rsn_ie_len - 2;
}
if (ie.osen) {
elems.osen = ie.osen + 2;
elems.osen_len = ie.osen_len - 2;
}
wpa_printf(MSG_DEBUG, wpa_printf(MSG_DEBUG,
"Update STA data based on IEs in EAPOL-Key 2/4"); "Update STA data based on IEs in EAPOL-Key 2/4");
sta_update_assoc(sta, &elems); sta_update_assoc(sta, &elems);
@ -750,6 +757,15 @@ static void rx_data_eapol_key_3_of_4(struct wlantest *wt, const u8 *dst,
return; return;
} }
if (!bss->ies_set) {
struct ieee802_11_elems elems;
elems_from_eapol_ie(&elems, &ie);
wpa_printf(MSG_DEBUG,
"Update BSS data based on IEs in EAPOL-Key 3/4");
bss_update(wt, bss, &elems, 0);
}
if ((ie.wpa_ie && if ((ie.wpa_ie &&
os_memcmp(ie.wpa_ie, bss->wpaie, ie.wpa_ie_len) != 0) || os_memcmp(ie.wpa_ie, bss->wpaie, ie.wpa_ie_len) != 0) ||
(ie.wpa_ie == NULL && bss->wpaie[0])) { (ie.wpa_ie == NULL && bss->wpaie[0])) {

View file

@ -86,7 +86,7 @@ static void rx_mgmt_beacon(struct wlantest *wt, const u8 *data, size_t len)
return; return;
} }
bss_update(wt, bss, &elems); bss_update(wt, bss, &elems, 1);
mme = get_ie(mgmt->u.beacon.variable, len - offset, WLAN_EID_MMIE); mme = get_ie(mgmt->u.beacon.variable, len - offset, WLAN_EID_MMIE);
if (!mme) { if (!mme) {
@ -173,7 +173,7 @@ static void rx_mgmt_probe_resp(struct wlantest *wt, const u8 *data, size_t len)
return; return;
} }
bss_update(wt, bss, &elems); bss_update(wt, bss, &elems, 2);
} }

View file

@ -156,7 +156,8 @@ void sta_update_assoc(struct wlantest_sta *sta, struct ieee802_11_elems *elems)
MAC2STR(sta->addr), sta->pairwise_cipher, MAC2STR(sta->addr), sta->pairwise_cipher,
MAC2STR(bss->bssid), bss->pairwise_cipher); MAC2STR(bss->bssid), bss->pairwise_cipher);
} }
if (sta->proto && data.group_cipher != bss->group_cipher) { if (sta->proto && data.group_cipher != bss->group_cipher &&
bss->ies_set) {
wpa_printf(MSG_INFO, "Mismatch in group cipher: STA " wpa_printf(MSG_INFO, "Mismatch in group cipher: STA "
MACSTR " 0x%x != BSS " MACSTR " 0x%x", MACSTR " 0x%x != BSS " MACSTR " 0x%x",
MAC2STR(sta->addr), data.group_cipher, MAC2STR(sta->addr), data.group_cipher,

View file

@ -135,6 +135,7 @@ struct wlantest_bss {
size_t ssid_len; size_t ssid_len;
int beacon_seen; int beacon_seen;
int proberesp_seen; int proberesp_seen;
int ies_set;
int parse_error_reported; int parse_error_reported;
u8 wpaie[257]; u8 wpaie[257];
u8 rsnie[257]; u8 rsnie[257];
@ -265,7 +266,7 @@ struct wlantest_bss * bss_find(struct wlantest *wt, const u8 *bssid);
struct wlantest_bss * bss_get(struct wlantest *wt, const u8 *bssid); struct wlantest_bss * bss_get(struct wlantest *wt, const u8 *bssid);
void bss_deinit(struct wlantest_bss *bss); void bss_deinit(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, int beacon);
void bss_flush(struct wlantest *wt); void bss_flush(struct wlantest *wt);
int bss_add_pmk_from_passphrase(struct wlantest_bss *bss, int bss_add_pmk_from_passphrase(struct wlantest_bss *bss,
const char *passphrase); const char *passphrase);