]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
nl80211: Fix WPA_VERSIONS attribute for Connect command
authorJouni Malinen <jouni@qca.qualcomm.com>
Fri, 2 Sep 2011 17:40:23 +0000 (20:40 +0300)
committerJouni Malinen <j@w1.fi>
Fri, 2 Sep 2011 17:40:23 +0000 (20:40 +0300)
The previous code was trying to figure out which WPA version is
used based on the extra IEs requested for Association Request. That
did not work properly in cases where non-WPA networks are used with
some extra IEs. Fix this by using more robust mechanism for passing
the WPA versions from core wpa_supplicant to the driver_ops
associate().

src/drivers/driver.h
src/drivers/driver_nl80211.c
wpa_supplicant/ap.c
wpa_supplicant/sme.c
wpa_supplicant/wpa_supplicant.c
wpa_supplicant/wpa_supplicant_i.h

index 67c5631da156f1c051e378bf1785bf5b9d88bc0d..af730579426215809c559b5fcc1b5216f79ac9b2 100644 (file)
@@ -350,6 +350,11 @@ struct wpa_driver_associate_params {
         */
        size_t wpa_ie_len;
 
+       /**
+        * wpa_proto - Bitfield of WPA_PROTO_* values to indicate WPA/WPA2
+        */
+       unsigned int wpa_proto;
+
        /**
         * pairwise_suite - Selected pairwise cipher suite
         *
index 233cdb2c4cc495f0f7dd89ad42d4f516b5b12dc6..f15dc5eeea21501d4e1199aed03426845dabf2a1 100644 (file)
@@ -4957,16 +4957,15 @@ static int wpa_driver_nl80211_connect(
        NLA_PUT_U32(msg, NL80211_ATTR_AUTH_TYPE, type);
 
 skip_auth_type:
-       if (params->wpa_ie && params->wpa_ie_len &&
-           params->key_mgmt_suite != KEY_MGMT_WPS) {
-               enum nl80211_wpa_versions ver;
+       if (params->wpa_proto) {
+               enum nl80211_wpa_versions ver = 0;
 
-               if (params->wpa_ie[0] == WLAN_EID_RSN)
-                       ver = NL80211_WPA_VERSION_2;
-               else
-                       ver = NL80211_WPA_VERSION_1;
+               if (params->wpa_proto & WPA_PROTO_WPA)
+                       ver |= NL80211_WPA_VERSION_1;
+               if (params->wpa_proto & WPA_PROTO_RSN)
+                       ver |= NL80211_WPA_VERSION_2;
 
-               wpa_printf(MSG_DEBUG, "  * WPA Version %d", ver);
+               wpa_printf(MSG_DEBUG, "  * WPA Versions 0x%x", ver);
                NLA_PUT_U32(msg, NL80211_ATTR_WPA_VERSIONS, ver);
        }
 
index 9eb2ba6f57272339ce798f3ebbf39f68f4d12965..b5ae6ddfded0b89be5372d4168e9cd6297f0e961 100644 (file)
@@ -373,6 +373,7 @@ int wpa_supplicant_create_ap(struct wpa_supplicant *wpa_s,
        }
        params.freq = ssid->frequency;
 
+       params.wpa_proto = ssid->proto;
        if (ssid->key_mgmt & WPA_KEY_MGMT_PSK)
                wpa_s->key_mgmt = WPA_KEY_MGMT_PSK;
        else
index b49fd53616ed84813236ad02b23d2e6afa3f23c2..dbf385ee7409353b9608d1365d9fe01da4ac9cfd 100644 (file)
@@ -392,13 +392,15 @@ void sme_associate(struct wpa_supplicant *wpa_s, enum wpas_mode mode,
                wpa_dbg(wpa_s, MSG_DEBUG, "SME: Could not parse own IEs?!");
                os_memset(&elems, 0, sizeof(elems));
        }
-       if (elems.rsn_ie)
+       if (elems.rsn_ie) {
+               params.wpa_proto = WPA_PROTO_RSN;
                wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, elems.rsn_ie - 2,
                                        elems.rsn_ie_len + 2);
-       else if (elems.wpa_ie)
+       } else if (elems.wpa_ie) {
+               params.wpa_proto = WPA_PROTO_WPA;
                wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, elems.wpa_ie - 2,
                                        elems.wpa_ie_len + 2);
-       else
+       else
                wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, NULL, 0);
        if (wpa_s->current_ssid && wpa_s->current_ssid->p2p_group)
                params.p2p = 1;
index 3f3e43594a6c3244fc3f9876af3dc010875b48a8..006cfb07a023f71466398c827dae5c41bf05db3b 100644 (file)
@@ -934,6 +934,7 @@ int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s,
        }
 #endif /* CONFIG_IEEE80211W */
 
+       wpa_s->wpa_proto = proto;
        wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_PROTO, proto);
        wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_RSN_ENABLED,
                         !!(ssid->proto & WPA_PROTO_RSN));
@@ -1313,6 +1314,7 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s,
        params.pairwise_suite = cipher_pairwise;
        params.group_suite = cipher_group;
        params.key_mgmt_suite = key_mgmt2driver(wpa_s->key_mgmt);
+       params.wpa_proto = wpa_s->wpa_proto;
        params.auth_alg = algs;
        params.mode = ssid->mode;
        for (i = 0; i < NUM_WEP_KEYS; i++) {
index c1a88089b3d7bf269f69a237e4a74e94b8b3cbc3..89b0982d9a41166564e23eb31d10e099fed5c7d4 100644 (file)
@@ -366,6 +366,7 @@ struct wpa_supplicant {
        int pairwise_cipher;
        int group_cipher;
        int key_mgmt;
+       int wpa_proto;
        int mgmt_group_cipher;
 
        void *drv_priv; /* private data used by driver_ops */
@@ -458,6 +459,7 @@ struct wpa_supplicant {
                u8 prev_bssid[ETH_ALEN];
                int prev_bssid_set;
                int auth_alg;
+               int proto;
 
                int sa_query_count; /* number of pending SA Query requests;
                                     * 0 = no SA Query in progress */