NDIS: Fix association for WPS provisioning with protected AP
Some NDIS drivers require a workaround to allow them to associate with a WPS AP that is already using protection (Privacy field = 1). Let driver_ndis.c know if the AP is already using Privacy and if so, configure a dummy WEP key to force the driver to associate.
This commit is contained in:
parent
687179edb5
commit
0c80427d77
3 changed files with 51 additions and 2 deletions
|
@ -281,6 +281,13 @@ struct wpa_driver_auth_params {
|
||||||
int local_state_change;
|
int local_state_change;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum wps_mode {
|
||||||
|
WPS_MODE_NONE /* no WPS provisioning being used */,
|
||||||
|
WPS_MODE_OPEN /* WPS provisioning with AP that is in open mode */,
|
||||||
|
WPS_MODE_PRIVACY /* WPS provisioning with AP that is using protection
|
||||||
|
*/
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct wpa_driver_associate_params - Association parameters
|
* struct wpa_driver_associate_params - Association parameters
|
||||||
* Data for struct wpa_driver_ops::associate().
|
* Data for struct wpa_driver_ops::associate().
|
||||||
|
@ -460,6 +467,15 @@ struct wpa_driver_associate_params {
|
||||||
* association.
|
* association.
|
||||||
*/
|
*/
|
||||||
const u8 *prev_bssid;
|
const u8 *prev_bssid;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* wps - WPS mode
|
||||||
|
*
|
||||||
|
* If the driver needs to do special configuration for WPS association,
|
||||||
|
* this variable provides more information on what type of association
|
||||||
|
* is being requested. Most drivers should not need ot use this.
|
||||||
|
*/
|
||||||
|
enum wps_mode wps;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1066,6 +1066,7 @@ wpa_driver_ndis_associate(void *priv,
|
||||||
{
|
{
|
||||||
struct wpa_driver_ndis_data *drv = priv;
|
struct wpa_driver_ndis_data *drv = priv;
|
||||||
u32 auth_mode, encr, priv_mode, mode;
|
u32 auth_mode, encr, priv_mode, mode;
|
||||||
|
u8 bcast[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
|
||||||
|
|
||||||
drv->mode = params->mode;
|
drv->mode = params->mode;
|
||||||
|
|
||||||
|
@ -1091,7 +1092,6 @@ wpa_driver_ndis_associate(void *priv,
|
||||||
if (params->key_mgmt_suite == KEY_MGMT_NONE ||
|
if (params->key_mgmt_suite == KEY_MGMT_NONE ||
|
||||||
params->key_mgmt_suite == KEY_MGMT_802_1X_NO_WPA) {
|
params->key_mgmt_suite == KEY_MGMT_802_1X_NO_WPA) {
|
||||||
/* Re-set WEP keys if static WEP configuration is used. */
|
/* Re-set WEP keys if static WEP configuration is used. */
|
||||||
u8 bcast[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
|
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < 4; i++) {
|
for (i = 0; i < 4; i++) {
|
||||||
if (!params->wep_key[i])
|
if (!params->wep_key[i])
|
||||||
|
@ -1125,6 +1125,22 @@ wpa_driver_ndis_associate(void *priv,
|
||||||
} else if (params->key_mgmt_suite == KEY_MGMT_WPS) {
|
} else if (params->key_mgmt_suite == KEY_MGMT_WPS) {
|
||||||
auth_mode = Ndis802_11AuthModeOpen;
|
auth_mode = Ndis802_11AuthModeOpen;
|
||||||
priv_mode = Ndis802_11PrivFilterAcceptAll;
|
priv_mode = Ndis802_11PrivFilterAcceptAll;
|
||||||
|
if (params->wps == WPS_MODE_PRIVACY) {
|
||||||
|
u8 dummy_key[5] = { 0x11, 0x22, 0x33, 0x44, 0x55 };
|
||||||
|
/*
|
||||||
|
* Some NDIS drivers refuse to associate in open mode
|
||||||
|
* configuration due to Privacy field mismatch, so use
|
||||||
|
* a workaround to make the configuration look like
|
||||||
|
* matching one for WPS provisioning.
|
||||||
|
*/
|
||||||
|
wpa_printf(MSG_DEBUG, "NDIS: Set dummy WEP key as a "
|
||||||
|
"workaround to allow driver to associate "
|
||||||
|
"for WPS");
|
||||||
|
wpa_driver_ndis_set_key(drv->ifname, drv, WPA_ALG_WEP,
|
||||||
|
bcast, 0, 1,
|
||||||
|
NULL, 0, dummy_key,
|
||||||
|
sizeof(dummy_key));
|
||||||
|
}
|
||||||
#endif /* CONFIG_WPS */
|
#endif /* CONFIG_WPS */
|
||||||
} else {
|
} else {
|
||||||
priv_mode = Ndis802_11PrivFilter8021xWEP;
|
priv_mode = Ndis802_11PrivFilter8021xWEP;
|
||||||
|
@ -1148,6 +1164,12 @@ wpa_driver_ndis_associate(void *priv,
|
||||||
encr = Ndis802_11Encryption1Enabled;
|
encr = Ndis802_11Encryption1Enabled;
|
||||||
break;
|
break;
|
||||||
case CIPHER_NONE:
|
case CIPHER_NONE:
|
||||||
|
#ifdef CONFIG_WPS
|
||||||
|
if (params->wps == WPS_MODE_PRIVACY) {
|
||||||
|
encr = Ndis802_11Encryption1Enabled;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_WPS */
|
||||||
if (params->group_suite == CIPHER_CCMP)
|
if (params->group_suite == CIPHER_CCMP)
|
||||||
encr = Ndis802_11Encryption3Enabled;
|
encr = Ndis802_11Encryption3Enabled;
|
||||||
else if (params->group_suite == CIPHER_TKIP)
|
else if (params->group_suite == CIPHER_TKIP)
|
||||||
|
@ -1156,7 +1178,14 @@ wpa_driver_ndis_associate(void *priv,
|
||||||
encr = Ndis802_11EncryptionDisabled;
|
encr = Ndis802_11EncryptionDisabled;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
#ifdef CONFIG_WPS
|
||||||
|
if (params->wps == WPS_MODE_PRIVACY) {
|
||||||
|
encr = Ndis802_11Encryption1Enabled;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_WPS */
|
||||||
encr = Ndis802_11EncryptionDisabled;
|
encr = Ndis802_11EncryptionDisabled;
|
||||||
|
break;
|
||||||
};
|
};
|
||||||
|
|
||||||
if (ndis_set_oid(drv, OID_802_11_PRIVACY_FILTER,
|
if (ndis_set_oid(drv, OID_802_11_PRIVACY_FILTER,
|
||||||
|
|
|
@ -1024,6 +1024,7 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
os_memset(¶ms, 0, sizeof(params));
|
||||||
wpa_s->reassociate = 0;
|
wpa_s->reassociate = 0;
|
||||||
if (bss) {
|
if (bss) {
|
||||||
#ifdef CONFIG_IEEE80211R
|
#ifdef CONFIG_IEEE80211R
|
||||||
|
@ -1131,6 +1132,10 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s,
|
||||||
wpa_ie_len = 0;
|
wpa_ie_len = 0;
|
||||||
wpabuf_free(wps_ie);
|
wpabuf_free(wps_ie);
|
||||||
wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
|
wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
|
||||||
|
if (!bss || (bss->caps & IEEE80211_CAP_PRIVACY))
|
||||||
|
params.wps = WPS_MODE_PRIVACY;
|
||||||
|
else
|
||||||
|
params.wps = WPS_MODE_OPEN;
|
||||||
#endif /* CONFIG_WPS */
|
#endif /* CONFIG_WPS */
|
||||||
} else {
|
} else {
|
||||||
wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
|
wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
|
||||||
|
@ -1175,7 +1180,6 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s,
|
||||||
}
|
}
|
||||||
|
|
||||||
wpa_supplicant_set_state(wpa_s, WPA_ASSOCIATING);
|
wpa_supplicant_set_state(wpa_s, WPA_ASSOCIATING);
|
||||||
os_memset(¶ms, 0, sizeof(params));
|
|
||||||
if (bss) {
|
if (bss) {
|
||||||
params.bssid = bss->bssid;
|
params.bssid = bss->bssid;
|
||||||
params.ssid = bss->ssid;
|
params.ssid = bss->ssid;
|
||||||
|
|
Loading…
Reference in a new issue