Commit 267335d6 authored by Antonio Quartulli's avatar Antonio Quartulli Committed by John W. Linville

cfg80211/mac80211: userspace peer authorization in IBSS

If the IBSS network is RSN-protected, let userspace authorize the stations
instead of adding them as AUTHORIZED by default.
Signed-off-by: default avatarAntonio Quartulli <ordex@autistici.org>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 3eda95de
...@@ -1147,6 +1147,10 @@ struct cfg80211_disassoc_request { ...@@ -1147,6 +1147,10 @@ struct cfg80211_disassoc_request {
* @beacon_interval: beacon interval to use * @beacon_interval: beacon interval to use
* @privacy: this is a protected network, keys will be configured * @privacy: this is a protected network, keys will be configured
* after joining * after joining
* @control_port: whether user space controls IEEE 802.1X port, i.e.,
* sets/clears %NL80211_STA_FLAG_AUTHORIZED. If true, the driver is
* required to assume that the port is unauthorized until authorized by
* user space. Otherwise, port is marked authorized by default.
* @basic_rates: bitmap of basic rates to use when creating the IBSS * @basic_rates: bitmap of basic rates to use when creating the IBSS
* @mcast_rate: per-band multicast rate index + 1 (0: disabled) * @mcast_rate: per-band multicast rate index + 1 (0: disabled)
*/ */
...@@ -1161,6 +1165,7 @@ struct cfg80211_ibss_params { ...@@ -1161,6 +1165,7 @@ struct cfg80211_ibss_params {
u32 basic_rates; u32 basic_rates;
bool channel_fixed; bool channel_fixed;
bool privacy; bool privacy;
bool control_port;
int mcast_rate[IEEE80211_NUM_BANDS]; int mcast_rate[IEEE80211_NUM_BANDS];
}; };
......
...@@ -268,7 +268,10 @@ static struct sta_info *ieee80211_ibss_finish_sta(struct sta_info *sta, ...@@ -268,7 +268,10 @@ static struct sta_info *ieee80211_ibss_finish_sta(struct sta_info *sta,
sta_info_pre_move_state(sta, IEEE80211_STA_AUTH); sta_info_pre_move_state(sta, IEEE80211_STA_AUTH);
sta_info_pre_move_state(sta, IEEE80211_STA_ASSOC); sta_info_pre_move_state(sta, IEEE80211_STA_ASSOC);
sta_info_pre_move_state(sta, IEEE80211_STA_AUTHORIZED); /* authorize the station only if the network is not RSN protected. If
* not wait for the userspace to authorize it */
if (!sta->sdata->u.ibss.control_port)
sta_info_pre_move_state(sta, IEEE80211_STA_AUTHORIZED);
rate_control_rate_init(sta); rate_control_rate_init(sta);
...@@ -1075,6 +1078,7 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata, ...@@ -1075,6 +1078,7 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
sdata->u.ibss.fixed_bssid = false; sdata->u.ibss.fixed_bssid = false;
sdata->u.ibss.privacy = params->privacy; sdata->u.ibss.privacy = params->privacy;
sdata->u.ibss.control_port = params->control_port;
sdata->u.ibss.basic_rates = params->basic_rates; sdata->u.ibss.basic_rates = params->basic_rates;
memcpy(sdata->vif.bss_conf.mcast_rate, params->mcast_rate, memcpy(sdata->vif.bss_conf.mcast_rate, params->mcast_rate,
sizeof(params->mcast_rate)); sizeof(params->mcast_rate));
......
...@@ -478,6 +478,8 @@ struct ieee80211_if_ibss { ...@@ -478,6 +478,8 @@ struct ieee80211_if_ibss {
bool fixed_channel; bool fixed_channel;
bool privacy; bool privacy;
bool control_port;
u8 bssid[ETH_ALEN]; u8 bssid[ETH_ALEN];
u8 ssid[IEEE80211_MAX_SSID_LEN]; u8 ssid[IEEE80211_MAX_SSID_LEN];
u8 ssid_len, ie_len; u8 ssid_len, ie_len;
......
...@@ -2654,13 +2654,6 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info) ...@@ -2654,13 +2654,6 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
break; break;
case NL80211_IFTYPE_P2P_CLIENT: case NL80211_IFTYPE_P2P_CLIENT:
case NL80211_IFTYPE_STATION: case NL80211_IFTYPE_STATION:
/* disallow things sta doesn't support */
if (params.plink_action)
return -EINVAL;
if (params.ht_capa)
return -EINVAL;
if (params.listen_interval >= 0)
return -EINVAL;
/* /*
* Don't allow userspace to change the TDLS_PEER flag, * Don't allow userspace to change the TDLS_PEER flag,
* but silently ignore attempts to change it since we * but silently ignore attempts to change it since we
...@@ -2668,7 +2661,15 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info) ...@@ -2668,7 +2661,15 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
* to change the flag. * to change the flag.
*/ */
params.sta_flags_mask &= ~BIT(NL80211_STA_FLAG_TDLS_PEER); params.sta_flags_mask &= ~BIT(NL80211_STA_FLAG_TDLS_PEER);
/* fall through */
case NL80211_IFTYPE_ADHOC:
/* disallow things sta doesn't support */
if (params.plink_action)
return -EINVAL;
if (params.ht_capa)
return -EINVAL;
if (params.listen_interval >= 0)
return -EINVAL;
/* reject any changes other than AUTHORIZED */ /* reject any changes other than AUTHORIZED */
if (params.sta_flags_mask & ~BIT(NL80211_STA_FLAG_AUTHORIZED)) if (params.sta_flags_mask & ~BIT(NL80211_STA_FLAG_AUTHORIZED))
return -EINVAL; return -EINVAL;
...@@ -4802,6 +4803,9 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info) ...@@ -4802,6 +4803,9 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
return PTR_ERR(connkeys); return PTR_ERR(connkeys);
} }
ibss.control_port =
nla_get_flag(info->attrs[NL80211_ATTR_CONTROL_PORT]);
err = cfg80211_join_ibss(rdev, dev, &ibss, connkeys); err = cfg80211_join_ibss(rdev, dev, &ibss, connkeys);
if (err) if (err)
kfree(connkeys); kfree(connkeys);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment