Show OSEN key management properly in scan results
authorBen Greear <greearb@candelatech.com>
Tue, 17 Mar 2015 20:52:29 +0000 (13:52 -0700)
committerJouni Malinen <j@w1.fi>
Wed, 25 Mar 2015 14:04:03 +0000 (16:04 +0200)
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 <greearb@candelatech.com>
src/common/wpa_common.c
src/rsn_supp/wpa_ie.c
wpa_supplicant/ctrl_iface.c

index 5534eab..0368904 100644 (file)
@@ -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,18 +551,29 @@ 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;
 
-       pos = (const u8 *) (hdr + 1);
-       left = rsn_ie_len - sizeof(*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);
+       }
 
        if (left >= RSN_SELECTOR_LEN) {
                data->group_cipher = rsn_selector_to_bitfield(pos);
index cb334df..0d96216 100644 (file)
@@ -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);
 }
index 53d2d01..0fb4d99 100644 (file)
@@ -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;