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().
This commit is contained in:
Jouni Malinen 2011-09-02 20:40:23 +03:00 committed by Jouni Malinen
parent bf9d5518d5
commit 64fa840a97
6 changed files with 22 additions and 11 deletions

View file

@ -350,6 +350,11 @@ struct wpa_driver_associate_params {
*/ */
size_t wpa_ie_len; 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 * pairwise_suite - Selected pairwise cipher suite
* *

View file

@ -4957,16 +4957,15 @@ static int wpa_driver_nl80211_connect(
NLA_PUT_U32(msg, NL80211_ATTR_AUTH_TYPE, type); NLA_PUT_U32(msg, NL80211_ATTR_AUTH_TYPE, type);
skip_auth_type: skip_auth_type:
if (params->wpa_ie && params->wpa_ie_len && if (params->wpa_proto) {
params->key_mgmt_suite != KEY_MGMT_WPS) { enum nl80211_wpa_versions ver = 0;
enum nl80211_wpa_versions ver;
if (params->wpa_ie[0] == WLAN_EID_RSN) if (params->wpa_proto & WPA_PROTO_WPA)
ver = NL80211_WPA_VERSION_2; ver |= NL80211_WPA_VERSION_1;
else if (params->wpa_proto & WPA_PROTO_RSN)
ver = NL80211_WPA_VERSION_1; 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); NLA_PUT_U32(msg, NL80211_ATTR_WPA_VERSIONS, ver);
} }

View file

@ -373,6 +373,7 @@ int wpa_supplicant_create_ap(struct wpa_supplicant *wpa_s,
} }
params.freq = ssid->frequency; params.freq = ssid->frequency;
params.wpa_proto = ssid->proto;
if (ssid->key_mgmt & WPA_KEY_MGMT_PSK) if (ssid->key_mgmt & WPA_KEY_MGMT_PSK)
wpa_s->key_mgmt = WPA_KEY_MGMT_PSK; wpa_s->key_mgmt = WPA_KEY_MGMT_PSK;
else else

View 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?!"); wpa_dbg(wpa_s, MSG_DEBUG, "SME: Could not parse own IEs?!");
os_memset(&elems, 0, sizeof(elems)); 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, wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, elems.rsn_ie - 2,
elems.rsn_ie_len + 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, wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, elems.wpa_ie - 2,
elems.wpa_ie_len + 2); elems.wpa_ie_len + 2);
else } else
wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, NULL, 0); wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, NULL, 0);
if (wpa_s->current_ssid && wpa_s->current_ssid->p2p_group) if (wpa_s->current_ssid && wpa_s->current_ssid->p2p_group)
params.p2p = 1; params.p2p = 1;

View file

@ -934,6 +934,7 @@ int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s,
} }
#endif /* CONFIG_IEEE80211W */ #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_PROTO, proto);
wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_RSN_ENABLED, wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_RSN_ENABLED,
!!(ssid->proto & WPA_PROTO_RSN)); !!(ssid->proto & WPA_PROTO_RSN));
@ -1313,6 +1314,7 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s,
params.pairwise_suite = cipher_pairwise; params.pairwise_suite = cipher_pairwise;
params.group_suite = cipher_group; params.group_suite = cipher_group;
params.key_mgmt_suite = key_mgmt2driver(wpa_s->key_mgmt); params.key_mgmt_suite = key_mgmt2driver(wpa_s->key_mgmt);
params.wpa_proto = wpa_s->wpa_proto;
params.auth_alg = algs; params.auth_alg = algs;
params.mode = ssid->mode; params.mode = ssid->mode;
for (i = 0; i < NUM_WEP_KEYS; i++) { for (i = 0; i < NUM_WEP_KEYS; i++) {

View file

@ -366,6 +366,7 @@ struct wpa_supplicant {
int pairwise_cipher; int pairwise_cipher;
int group_cipher; int group_cipher;
int key_mgmt; int key_mgmt;
int wpa_proto;
int mgmt_group_cipher; int mgmt_group_cipher;
void *drv_priv; /* private data used by driver_ops */ void *drv_priv; /* private data used by driver_ops */
@ -458,6 +459,7 @@ struct wpa_supplicant {
u8 prev_bssid[ETH_ALEN]; u8 prev_bssid[ETH_ALEN];
int prev_bssid_set; int prev_bssid_set;
int auth_alg; int auth_alg;
int proto;
int sa_query_count; /* number of pending SA Query requests; int sa_query_count; /* number of pending SA Query requests;
* 0 = no SA Query in progress */ * 0 = no SA Query in progress */