From 0f8385e6fabf74ac5c91c3f9a58108e6e89c10a8 Mon Sep 17 00:00:00 2001 From: Ben Greear Date: Tue, 17 Mar 2015 13:52:29 -0700 Subject: [PATCH] Show OSEN key management properly in scan results Old code defaulted to WEP for an AP advertising OSEN. Show as OSEN instead. Re-use most of the RSN parsing logic since all but the header is the same. Example output: [root@ath9k-f lanforge]# ./local/bin/wpa_cli -i sta0 scan_results bssid / frequency / signal level / flags / ssid 00:0e:8e:6f:40:49 2462 -23 [OSEN-OSEN-CCMP][ESS] ben-138 Signed-off-by: Ben Greear --- src/common/wpa_common.c | 34 +++++++++++++++++++++++----------- src/rsn_supp/wpa_ie.c | 3 +++ wpa_supplicant/ctrl_iface.c | 25 +++++++++++++++++++++---- 3 files changed, 47 insertions(+), 15 deletions(-) diff --git a/src/common/wpa_common.c b/src/common/wpa_common.c index 5534eab4c..036890483 100644 --- a/src/common/wpa_common.c +++ b/src/common/wpa_common.c @@ -486,6 +486,8 @@ static int rsn_key_mgmt_to_bitfield(const u8 *s) return WPA_KEY_MGMT_IEEE8021X_SUITE_B; if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_802_1X_SUITE_B_192) return WPA_KEY_MGMT_IEEE8021X_SUITE_B_192; + if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_OSEN) + return WPA_KEY_MGMT_OSEN; return 0; } @@ -520,7 +522,6 @@ int wpa_cipher_valid_mgmt_group(int cipher) int wpa_parse_wpa_ie_rsn(const u8 *rsn_ie, size_t rsn_ie_len, struct wpa_ie_data *data) { - const struct rsn_ie_hdr *hdr; const u8 *pos; int left; int i, count; @@ -550,19 +551,30 @@ int wpa_parse_wpa_ie_rsn(const u8 *rsn_ie, size_t rsn_ie_len, return -1; } - hdr = (const struct rsn_ie_hdr *) rsn_ie; + if (rsn_ie_len >= 6 && rsn_ie[1] >= 4 && + rsn_ie[1] == rsn_ie_len - 2 && + WPA_GET_BE32(&rsn_ie[2]) == OSEN_IE_VENDOR_TYPE) { + pos = rsn_ie + 6; + left = rsn_ie_len - 6; - if (hdr->elem_id != WLAN_EID_RSN || - hdr->len != rsn_ie_len - 2 || - WPA_GET_LE16(hdr->version) != RSN_VERSION) { - wpa_printf(MSG_DEBUG, "%s: malformed ie or unknown version", - __func__); - return -2; + data->proto = WPA_PROTO_OSEN; + } else { + const struct rsn_ie_hdr *hdr; + + hdr = (const struct rsn_ie_hdr *) rsn_ie; + + if (hdr->elem_id != WLAN_EID_RSN || + hdr->len != rsn_ie_len - 2 || + WPA_GET_LE16(hdr->version) != RSN_VERSION) { + wpa_printf(MSG_DEBUG, "%s: malformed ie or unknown version", + __func__); + return -2; + } + + pos = (const u8 *) (hdr + 1); + left = rsn_ie_len - sizeof(*hdr); } - pos = (const u8 *) (hdr + 1); - left = rsn_ie_len - sizeof(*hdr); - if (left >= RSN_SELECTOR_LEN) { data->group_cipher = rsn_selector_to_bitfield(pos); if (!wpa_cipher_valid_group(data->group_cipher)) { diff --git a/src/rsn_supp/wpa_ie.c b/src/rsn_supp/wpa_ie.c index cb334df67..0d96216d2 100644 --- a/src/rsn_supp/wpa_ie.c +++ b/src/rsn_supp/wpa_ie.c @@ -30,6 +30,9 @@ int wpa_parse_wpa_ie(const u8 *wpa_ie, size_t wpa_ie_len, { if (wpa_ie_len >= 1 && wpa_ie[0] == WLAN_EID_RSN) return wpa_parse_wpa_ie_rsn(wpa_ie, wpa_ie_len, data); + if (wpa_ie_len >= 6 && wpa_ie[0] == WLAN_EID_VENDOR_SPECIFIC && + wpa_ie[1] >= 4 && WPA_GET_BE32(&wpa_ie[2]) == OSEN_IE_VENDOR_TYPE) + return wpa_parse_wpa_ie_rsn(wpa_ie, wpa_ie_len, data); else return wpa_parse_wpa_ie_wpa(wpa_ie, wpa_ie_len, data); } diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c index 53d2d0155..0fb4d99b1 100644 --- a/wpa_supplicant/ctrl_iface.c +++ b/wpa_supplicant/ctrl_iface.c @@ -2366,6 +2366,14 @@ static char * wpa_supplicant_ie_txt(char *pos, char *end, const char *proto, } #endif /* CONFIG_SUITEB192 */ + if (data.key_mgmt & WPA_KEY_MGMT_OSEN) { + ret = os_snprintf(pos, end - pos, "%sOSEN", + pos == start ? "" : "+"); + if (os_snprintf_error(end - pos, ret)) + return pos; + pos += ret; + } + pos = wpa_supplicant_cipher_txt(pos, end, data.pairwise_cipher); if (data.capabilities & WPA_CAPABILITY_PREAUTH) { @@ -2433,7 +2441,7 @@ static int wpa_supplicant_ctrl_iface_scan_result( { char *pos, *end; int ret; - const u8 *ie, *ie2, *p2p, *mesh; + const u8 *ie, *ie2, *osen_ie, *p2p, *mesh; mesh = wpa_bss_get_ie(bss, WLAN_EID_MESH_ID); p2p = wpa_bss_get_vendor_ie(bss, P2P_IE_VENDOR_TYPE); @@ -2460,8 +2468,12 @@ static int wpa_supplicant_ctrl_iface_scan_result( pos = wpa_supplicant_ie_txt(pos, end, mesh ? "RSN" : "WPA2", ie2, 2 + ie2[1]); } + osen_ie = wpa_bss_get_vendor_ie(bss, OSEN_IE_VENDOR_TYPE); + if (osen_ie) + pos = wpa_supplicant_ie_txt(pos, end, "OSEN", + osen_ie, 2 + osen_ie[1]); pos = wpa_supplicant_wps_ie_txt(wpa_s, pos, end, bss); - if (!ie && !ie2 && bss->caps & IEEE80211_CAP_PRIVACY) { + if (!ie && !ie2 && !osen_ie && (bss->caps & IEEE80211_CAP_PRIVACY)) { ret = os_snprintf(pos, end - pos, "[WEP]"); if (os_snprintf_error(end - pos, ret)) return -1; @@ -3937,7 +3949,7 @@ static int print_bss_info(struct wpa_supplicant *wpa_s, struct wpa_bss *bss, size_t i; int ret; char *pos, *end; - const u8 *ie, *ie2; + const u8 *ie, *ie2, *osen_ie; pos = buf; end = buf + buflen; @@ -4054,8 +4066,13 @@ static int print_bss_info(struct wpa_supplicant *wpa_s, struct wpa_bss *bss, if (ie2) pos = wpa_supplicant_ie_txt(pos, end, "WPA2", ie2, 2 + ie2[1]); + osen_ie = wpa_bss_get_vendor_ie(bss, OSEN_IE_VENDOR_TYPE); + if (osen_ie) + pos = wpa_supplicant_ie_txt(pos, end, "OSEN", + osen_ie, 2 + osen_ie[1]); pos = wpa_supplicant_wps_ie_txt(wpa_s, pos, end, bss); - if (!ie && !ie2 && bss->caps & IEEE80211_CAP_PRIVACY) { + if (!ie && !ie2 && !osen_ie && + (bss->caps & IEEE80211_CAP_PRIVACY)) { ret = os_snprintf(pos, end - pos, "[WEP]"); if (os_snprintf_error(end - pos, ret)) return 0;