[PATCH] libertas: Make WPA work through supplicant handshake
Fix WPA so it works up through the supplicant 4-Way handshake process. Doesn't successfully pass traffic yet; may be problems installing the GTK to the firmware. - RSN needs to be enabled before the association command is sent - Use keys from the association request not the adapter structure - cmd_act_mac_strict_protection_enable != IW_AUTH_DROP_UNENCRYPTED - Fix network filtering logic in is_network_compatible() WPA helpers Signed-off-by: Dan Williams <dcbw@redhat.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
Родитель
45f43de829
Коммит
90a42210f2
|
@ -347,7 +347,17 @@ static int assoc_helper_secinfo(wlan_private *priv,
|
|||
sizeof(struct wlan_802_11_security));
|
||||
|
||||
ret = libertas_set_mac_packet_filter(priv);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
/* enable/disable RSN */
|
||||
ret = libertas_prepare_and_send_command(priv,
|
||||
cmd_802_11_enable_rsn,
|
||||
cmd_act_set,
|
||||
cmd_option_waitforrsp,
|
||||
0, assoc_req);
|
||||
|
||||
out:
|
||||
lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
@ -360,22 +370,12 @@ static int assoc_helper_wpa_keys(wlan_private *priv,
|
|||
|
||||
lbs_deb_enter(LBS_DEB_ASSOC);
|
||||
|
||||
/* enable/Disable RSN */
|
||||
ret = libertas_prepare_and_send_command(priv,
|
||||
cmd_802_11_enable_rsn,
|
||||
cmd_act_set,
|
||||
cmd_option_waitforrsp,
|
||||
0, assoc_req);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
ret = libertas_prepare_and_send_command(priv,
|
||||
cmd_802_11_key_material,
|
||||
cmd_act_set,
|
||||
cmd_option_waitforrsp,
|
||||
0, assoc_req);
|
||||
|
||||
out:
|
||||
lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -232,22 +232,25 @@ done:
|
|||
|
||||
static int wlan_cmd_802_11_enable_rsn(wlan_private * priv,
|
||||
struct cmd_ds_command *cmd,
|
||||
u16 cmd_action)
|
||||
u16 cmd_action,
|
||||
void * pdata_buf)
|
||||
{
|
||||
struct cmd_ds_802_11_enable_rsn *penableRSN = &cmd->params.enbrsn;
|
||||
wlan_adapter *adapter = priv->adapter;
|
||||
struct assoc_request * assoc_req = pdata_buf;
|
||||
|
||||
lbs_deb_enter(LBS_DEB_CMD);
|
||||
|
||||
cmd->command = cpu_to_le16(cmd_802_11_enable_rsn);
|
||||
cmd->size =
|
||||
cpu_to_le16(sizeof(struct cmd_ds_802_11_enable_rsn) +
|
||||
S_DS_GEN);
|
||||
cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_enable_rsn) +
|
||||
S_DS_GEN);
|
||||
penableRSN->action = cpu_to_le16(cmd_action);
|
||||
if (adapter->secinfo.WPAenabled || adapter->secinfo.WPA2enabled) {
|
||||
if (assoc_req->secinfo.WPAenabled || assoc_req->secinfo.WPA2enabled) {
|
||||
penableRSN->enable = cpu_to_le16(cmd_enable_rsn);
|
||||
} else {
|
||||
penableRSN->enable = cpu_to_le16(cmd_disable_rsn);
|
||||
}
|
||||
|
||||
lbs_deb_leave(LBS_DEB_CMD);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -258,14 +261,12 @@ static void set_one_wpa_key(struct MrvlIEtype_keyParamSet * pkeyparamset,
|
|||
pkeyparamset->keytypeid = cpu_to_le16(pkey->type);
|
||||
|
||||
if (pkey->flags & KEY_INFO_WPA_ENABLED) {
|
||||
pkeyparamset->keyinfo = cpu_to_le16(KEY_INFO_WPA_ENABLED);
|
||||
} else {
|
||||
pkeyparamset->keyinfo = cpu_to_le16(!KEY_INFO_WPA_ENABLED);
|
||||
pkeyparamset->keyinfo |= cpu_to_le16(KEY_INFO_WPA_ENABLED);
|
||||
}
|
||||
|
||||
if (pkey->flags & KEY_INFO_WPA_UNICAST) {
|
||||
pkeyparamset->keyinfo |= cpu_to_le16(KEY_INFO_WPA_UNICAST);
|
||||
} else if (pkey->flags & KEY_INFO_WPA_MCAST) {
|
||||
}
|
||||
if (pkey->flags & KEY_INFO_WPA_MCAST) {
|
||||
pkeyparamset->keyinfo |= cpu_to_le16(KEY_INFO_WPA_MCAST);
|
||||
}
|
||||
|
||||
|
@ -283,9 +284,9 @@ static int wlan_cmd_802_11_key_material(wlan_private * priv,
|
|||
u16 cmd_action,
|
||||
u32 cmd_oid, void *pdata_buf)
|
||||
{
|
||||
wlan_adapter *adapter = priv->adapter;
|
||||
struct cmd_ds_802_11_key_material *pkeymaterial =
|
||||
&cmd->params.keymaterial;
|
||||
struct assoc_request * assoc_req = pdata_buf;
|
||||
int ret = 0;
|
||||
int index = 0;
|
||||
|
||||
|
@ -295,29 +296,28 @@ static int wlan_cmd_802_11_key_material(wlan_private * priv,
|
|||
pkeymaterial->action = cpu_to_le16(cmd_action);
|
||||
|
||||
if (cmd_action == cmd_act_get) {
|
||||
cmd->size = cpu_to_le16( S_DS_GEN
|
||||
+ sizeof (pkeymaterial->action));
|
||||
cmd->size = cpu_to_le16(S_DS_GEN + sizeof (pkeymaterial->action));
|
||||
ret = 0;
|
||||
goto done;
|
||||
}
|
||||
|
||||
memset(&pkeymaterial->keyParamSet, 0, sizeof(pkeymaterial->keyParamSet));
|
||||
|
||||
if (adapter->wpa_unicast_key.len) {
|
||||
if (test_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags)) {
|
||||
set_one_wpa_key(&pkeymaterial->keyParamSet[index],
|
||||
&adapter->wpa_unicast_key);
|
||||
&assoc_req->wpa_unicast_key);
|
||||
index++;
|
||||
}
|
||||
|
||||
if (adapter->wpa_mcast_key.len) {
|
||||
if (test_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags)) {
|
||||
set_one_wpa_key(&pkeymaterial->keyParamSet[index],
|
||||
&adapter->wpa_mcast_key);
|
||||
&assoc_req->wpa_mcast_key);
|
||||
index++;
|
||||
}
|
||||
|
||||
cmd->size = cpu_to_le16( S_DS_GEN
|
||||
+ sizeof (pkeymaterial->action)
|
||||
+ index * sizeof(struct MrvlIEtype_keyParamSet));
|
||||
+ sizeof (pkeymaterial->action)
|
||||
+ (index * sizeof(struct MrvlIEtype_keyParamSet)));
|
||||
|
||||
ret = 0;
|
||||
|
||||
|
@ -1302,13 +1302,13 @@ int libertas_prepare_and_send_command(wlan_private * priv,
|
|||
break;
|
||||
|
||||
case cmd_802_11_enable_rsn:
|
||||
ret = wlan_cmd_802_11_enable_rsn(priv, cmdptr, cmd_action);
|
||||
ret = wlan_cmd_802_11_enable_rsn(priv, cmdptr, cmd_action,
|
||||
pdata_buf);
|
||||
break;
|
||||
|
||||
case cmd_802_11_key_material:
|
||||
ret = wlan_cmd_802_11_key_material(priv, cmdptr,
|
||||
cmd_action, cmd_oid,
|
||||
pdata_buf);
|
||||
ret = wlan_cmd_802_11_key_material(priv, cmdptr, cmd_action,
|
||||
cmd_oid, pdata_buf);
|
||||
break;
|
||||
|
||||
case cmd_802_11_pairwise_tsc:
|
||||
|
|
|
@ -99,7 +99,6 @@ static inline int match_bss_wpa(struct wlan_802_11_security * secinfo,
|
|||
{
|
||||
if ( !secinfo->wep_enabled
|
||||
&& secinfo->WPAenabled
|
||||
&& !secinfo->WPA2enabled
|
||||
&& (match_bss->wpa_ie[0] == WPA_IE)
|
||||
/* privacy bit may NOT be set in some APs like LinkSys WRT54G
|
||||
&& bss->privacy */
|
||||
|
@ -113,7 +112,6 @@ static inline int match_bss_wpa2(struct wlan_802_11_security * secinfo,
|
|||
struct bss_descriptor * match_bss)
|
||||
{
|
||||
if ( !secinfo->wep_enabled
|
||||
&& !secinfo->WPAenabled
|
||||
&& secinfo->WPA2enabled
|
||||
&& (match_bss->rsn_ie[0] == WPA2_IE)
|
||||
/* privacy bit may NOT be set in some APs like LinkSys WRT54G
|
||||
|
|
|
@ -1498,6 +1498,8 @@ static void disable_wep(struct assoc_request *assoc_req)
|
|||
{
|
||||
int i;
|
||||
|
||||
lbs_deb_enter(LBS_DEB_WEXT);
|
||||
|
||||
/* Set Open System auth mode */
|
||||
assoc_req->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM;
|
||||
|
||||
|
@ -1508,6 +1510,27 @@ static void disable_wep(struct assoc_request *assoc_req)
|
|||
|
||||
set_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags);
|
||||
set_bit(ASSOC_FLAG_WEP_KEYS, &assoc_req->flags);
|
||||
|
||||
lbs_deb_leave(LBS_DEB_WEXT);
|
||||
}
|
||||
|
||||
static void disable_wpa(struct assoc_request *assoc_req)
|
||||
{
|
||||
lbs_deb_enter(LBS_DEB_WEXT);
|
||||
|
||||
memset(&assoc_req->wpa_mcast_key, 0, sizeof (struct WLAN_802_11_KEY));
|
||||
assoc_req->wpa_mcast_key.flags = KEY_INFO_WPA_MCAST;
|
||||
set_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags);
|
||||
|
||||
memset(&assoc_req->wpa_unicast_key, 0, sizeof (struct WLAN_802_11_KEY));
|
||||
assoc_req->wpa_unicast_key.flags = KEY_INFO_WPA_UNICAST;
|
||||
set_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags);
|
||||
|
||||
assoc_req->secinfo.WPAenabled = 0;
|
||||
assoc_req->secinfo.WPA2enabled = 0;
|
||||
set_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags);
|
||||
|
||||
lbs_deb_leave(LBS_DEB_WEXT);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1540,6 +1563,7 @@ static int wlan_set_encode(struct net_device *dev,
|
|||
|
||||
if (dwrq->flags & IW_ENCODE_DISABLED) {
|
||||
disable_wep (assoc_req);
|
||||
disable_wpa (assoc_req);
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
@ -1641,6 +1665,7 @@ static int wlan_get_encodeext(struct net_device *dev,
|
|||
if ( adapter->secinfo.wep_enabled
|
||||
&& !adapter->secinfo.WPAenabled
|
||||
&& !adapter->secinfo.WPA2enabled) {
|
||||
/* WEP */
|
||||
ext->alg = IW_ENCODE_ALG_WEP;
|
||||
ext->key_len = adapter->wep_keys[index].len;
|
||||
key = &adapter->wep_keys[index].key[0];
|
||||
|
@ -1648,8 +1673,27 @@ static int wlan_get_encodeext(struct net_device *dev,
|
|||
&& (adapter->secinfo.WPAenabled ||
|
||||
adapter->secinfo.WPA2enabled)) {
|
||||
/* WPA */
|
||||
ext->alg = IW_ENCODE_ALG_TKIP;
|
||||
ext->key_len = 0;
|
||||
struct WLAN_802_11_KEY * pkey = NULL;
|
||||
|
||||
if ( adapter->wpa_mcast_key.len
|
||||
&& (adapter->wpa_mcast_key.flags & KEY_INFO_WPA_ENABLED))
|
||||
pkey = &adapter->wpa_mcast_key;
|
||||
else if ( adapter->wpa_unicast_key.len
|
||||
&& (adapter->wpa_unicast_key.flags & KEY_INFO_WPA_ENABLED))
|
||||
pkey = &adapter->wpa_unicast_key;
|
||||
|
||||
if (pkey) {
|
||||
if (pkey->type == KEY_TYPE_ID_AES) {
|
||||
ext->alg = IW_ENCODE_ALG_CCMP;
|
||||
} else {
|
||||
ext->alg = IW_ENCODE_ALG_TKIP;
|
||||
}
|
||||
ext->key_len = pkey->len;
|
||||
key = &pkey->key[0];
|
||||
} else {
|
||||
ext->alg = IW_ENCODE_ALG_TKIP;
|
||||
ext->key_len = 0;
|
||||
}
|
||||
} else {
|
||||
goto out;
|
||||
}
|
||||
|
@ -1704,6 +1748,7 @@ static int wlan_set_encodeext(struct net_device *dev,
|
|||
|
||||
if ((alg == IW_ENCODE_ALG_NONE) || (dwrq->flags & IW_ENCODE_DISABLED)) {
|
||||
disable_wep (assoc_req);
|
||||
disable_wpa (assoc_req);
|
||||
} else if (alg == IW_ENCODE_ALG_WEP) {
|
||||
u16 is_default = 0, index, set_tx_key = 0;
|
||||
|
||||
|
@ -1739,7 +1784,6 @@ static int wlan_set_encodeext(struct net_device *dev,
|
|||
set_bit(ASSOC_FLAG_WEP_KEYS, &assoc_req->flags);
|
||||
if (set_tx_key)
|
||||
set_bit(ASSOC_FLAG_WEP_TX_KEYIDX, &assoc_req->flags);
|
||||
|
||||
} else if ((alg == IW_ENCODE_ALG_TKIP) || (alg == IW_ENCODE_ALG_CCMP)) {
|
||||
struct WLAN_802_11_KEY * pkey;
|
||||
|
||||
|
@ -1756,28 +1800,35 @@ static int wlan_set_encodeext(struct net_device *dev,
|
|||
goto out;
|
||||
}
|
||||
|
||||
if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)
|
||||
if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
|
||||
pkey = &assoc_req->wpa_mcast_key;
|
||||
else
|
||||
set_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags);
|
||||
} else {
|
||||
pkey = &assoc_req->wpa_unicast_key;
|
||||
set_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags);
|
||||
}
|
||||
|
||||
memset(pkey, 0, sizeof (struct WLAN_802_11_KEY));
|
||||
memcpy(pkey->key, ext->key, ext->key_len);
|
||||
pkey->len = ext->key_len;
|
||||
pkey->flags = KEY_INFO_WPA_ENABLED;
|
||||
if (pkey->len)
|
||||
pkey->flags |= KEY_INFO_WPA_ENABLED;
|
||||
|
||||
/* Do this after zeroing key structure */
|
||||
if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
|
||||
pkey->flags |= KEY_INFO_WPA_MCAST;
|
||||
set_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags);
|
||||
} else {
|
||||
pkey->flags |= KEY_INFO_WPA_UNICAST;
|
||||
set_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags);
|
||||
}
|
||||
|
||||
if (alg == IW_ENCODE_ALG_TKIP)
|
||||
if (alg == IW_ENCODE_ALG_TKIP) {
|
||||
pkey->type = KEY_TYPE_ID_TKIP;
|
||||
else if (alg == IW_ENCODE_ALG_CCMP)
|
||||
} else if (alg == IW_ENCODE_ALG_CCMP) {
|
||||
pkey->type = KEY_TYPE_ID_AES;
|
||||
} else {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* If WPA isn't enabled yet, do that now */
|
||||
if ( assoc_req->secinfo.WPAenabled == 0
|
||||
|
@ -1904,6 +1955,7 @@ static int wlan_set_auth(struct net_device *dev,
|
|||
case IW_AUTH_CIPHER_PAIRWISE:
|
||||
case IW_AUTH_CIPHER_GROUP:
|
||||
case IW_AUTH_KEY_MGMT:
|
||||
case IW_AUTH_DROP_UNENCRYPTED:
|
||||
/*
|
||||
* libertas does not use these parameters
|
||||
*/
|
||||
|
@ -1913,6 +1965,7 @@ static int wlan_set_auth(struct net_device *dev,
|
|||
if (dwrq->value & IW_AUTH_WPA_VERSION_DISABLED) {
|
||||
assoc_req->secinfo.WPAenabled = 0;
|
||||
assoc_req->secinfo.WPA2enabled = 0;
|
||||
disable_wpa (assoc_req);
|
||||
}
|
||||
if (dwrq->value & IW_AUTH_WPA_VERSION_WPA) {
|
||||
assoc_req->secinfo.WPAenabled = 1;
|
||||
|
@ -1927,17 +1980,6 @@ static int wlan_set_auth(struct net_device *dev,
|
|||
updated = 1;
|
||||
break;
|
||||
|
||||
case IW_AUTH_DROP_UNENCRYPTED:
|
||||
if (dwrq->value) {
|
||||
adapter->currentpacketfilter |=
|
||||
cmd_act_mac_strict_protection_enable;
|
||||
} else {
|
||||
adapter->currentpacketfilter &=
|
||||
~cmd_act_mac_strict_protection_enable;
|
||||
}
|
||||
updated = 1;
|
||||
break;
|
||||
|
||||
case IW_AUTH_80211_AUTH_ALG:
|
||||
if (dwrq->value & IW_AUTH_ALG_SHARED_KEY) {
|
||||
assoc_req->secinfo.auth_mode = IW_AUTH_ALG_SHARED_KEY;
|
||||
|
@ -1963,6 +2005,7 @@ static int wlan_set_auth(struct net_device *dev,
|
|||
} else {
|
||||
assoc_req->secinfo.WPAenabled = 0;
|
||||
assoc_req->secinfo.WPA2enabled = 0;
|
||||
disable_wpa (assoc_req);
|
||||
}
|
||||
updated = 1;
|
||||
break;
|
||||
|
@ -2008,13 +2051,6 @@ static int wlan_get_auth(struct net_device *dev,
|
|||
dwrq->value |= IW_AUTH_WPA_VERSION_DISABLED;
|
||||
break;
|
||||
|
||||
case IW_AUTH_DROP_UNENCRYPTED:
|
||||
dwrq->value = 0;
|
||||
if (adapter->currentpacketfilter &
|
||||
cmd_act_mac_strict_protection_enable)
|
||||
dwrq->value = 1;
|
||||
break;
|
||||
|
||||
case IW_AUTH_80211_AUTH_ALG:
|
||||
dwrq->value = adapter->secinfo.auth_mode;
|
||||
break;
|
||||
|
|
Загрузка…
Ссылка в новой задаче