From 64fa840a9745e398311a8241a94d03b506d2d230 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Fri, 2 Sep 2011 20:40:23 +0300 Subject: [PATCH] nl80211: Fix WPA_VERSIONS attribute for Connect command 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 | 5 +++++ src/drivers/driver_nl80211.c | 15 +++++++-------- wpa_supplicant/ap.c | 1 + wpa_supplicant/sme.c | 8 +++++--- wpa_supplicant/wpa_supplicant.c | 2 ++ wpa_supplicant/wpa_supplicant_i.h | 2 ++ 6 files changed, 22 insertions(+), 11 deletions(-) diff --git a/src/drivers/driver.h b/src/drivers/driver.h index 67c5631da..af7305794 100644 --- a/src/drivers/driver.h +++ b/src/drivers/driver.h @@ -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 * diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c index 233cdb2c4..f15dc5eee 100644 --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c @@ -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); } diff --git a/wpa_supplicant/ap.c b/wpa_supplicant/ap.c index 9eb2ba6f5..b5ae6ddfd 100644 --- a/wpa_supplicant/ap.c +++ b/wpa_supplicant/ap.c @@ -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 diff --git a/wpa_supplicant/sme.c b/wpa_supplicant/sme.c index b49fd5361..dbf385ee7 100644 --- a/wpa_supplicant/sme.c +++ b/wpa_supplicant/sme.c @@ -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; diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c index 3f3e43594..006cfb07a 100644 --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c @@ -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++) { diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h index c1a88089b..89b0982d9 100644 --- a/wpa_supplicant/wpa_supplicant_i.h +++ b/wpa_supplicant/wpa_supplicant_i.h @@ -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 */