aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless/ibss.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2009-07-08 08:22:54 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-07-24 15:05:09 -0400
commitfffd0934b9390f34bec45762192b7edd3b12b4b5 (patch)
treed9779803763261f5795fe39a402d79c4220a3a22 /net/wireless/ibss.c
parentb9454e83cac42fcdc90bfbfba479132bd6629455 (diff)
cfg80211: rework key operation
This reworks the key operation in cfg80211, and now only allows, from userspace, configuring keys (via nl80211) after the connection has been established (in managed mode), the IBSS been joined (in IBSS mode), at any time (in AP[_VLAN] modes) or never for all the other modes. In order to do shared key authentication correctly, it is now possible to give a WEP key to the AUTH command. To configure static WEP keys, these are given to the CONNECT or IBSS_JOIN command directly, for a userspace SME it is assumed it will configure it properly after the connection has been established. Since mac80211 used to check the default key in IBSS mode to see whether or not the network is protected, it needs an update in that area, as well as an update to make use of the WEP key passed to auth() for shared key authentication. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/wireless/ibss.c')
-rw-r--r--net/wireless/ibss.c79
1 files changed, 66 insertions, 13 deletions
diff --git a/net/wireless/ibss.c b/net/wireless/ibss.c
index 99ef9364b7e8..9394e78cd11f 100644
--- a/net/wireless/ibss.c
+++ b/net/wireless/ibss.c
@@ -39,6 +39,8 @@ void __cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid)
39 cfg80211_hold_bss(bss_from_pub(bss)); 39 cfg80211_hold_bss(bss_from_pub(bss));
40 wdev->current_bss = bss_from_pub(bss); 40 wdev->current_bss = bss_from_pub(bss);
41 41
42 cfg80211_upload_connect_keys(wdev);
43
42 nl80211_send_ibss_bssid(wiphy_to_dev(wdev->wiphy), dev, bssid, 44 nl80211_send_ibss_bssid(wiphy_to_dev(wdev->wiphy), dev, bssid,
43 GFP_KERNEL); 45 GFP_KERNEL);
44#ifdef CONFIG_WIRELESS_EXT 46#ifdef CONFIG_WIRELESS_EXT
@@ -71,7 +73,8 @@ EXPORT_SYMBOL(cfg80211_ibss_joined);
71 73
72int __cfg80211_join_ibss(struct cfg80211_registered_device *rdev, 74int __cfg80211_join_ibss(struct cfg80211_registered_device *rdev,
73 struct net_device *dev, 75 struct net_device *dev,
74 struct cfg80211_ibss_params *params) 76 struct cfg80211_ibss_params *params,
77 struct cfg80211_cached_keys *connkeys)
75{ 78{
76 struct wireless_dev *wdev = dev->ieee80211_ptr; 79 struct wireless_dev *wdev = dev->ieee80211_ptr;
77 int err; 80 int err;
@@ -81,13 +84,18 @@ int __cfg80211_join_ibss(struct cfg80211_registered_device *rdev,
81 if (wdev->ssid_len) 84 if (wdev->ssid_len)
82 return -EALREADY; 85 return -EALREADY;
83 86
87 if (WARN_ON(wdev->connect_keys))
88 kfree(wdev->connect_keys);
89 wdev->connect_keys = connkeys;
90
84#ifdef CONFIG_WIRELESS_EXT 91#ifdef CONFIG_WIRELESS_EXT
85 wdev->wext.ibss.channel = params->channel; 92 wdev->wext.ibss.channel = params->channel;
86#endif 93#endif
87 err = rdev->ops->join_ibss(&rdev->wiphy, dev, params); 94 err = rdev->ops->join_ibss(&rdev->wiphy, dev, params);
88 95 if (err) {
89 if (err) 96 wdev->connect_keys = NULL;
90 return err; 97 return err;
98 }
91 99
92 memcpy(wdev->ssid, params->ssid, params->ssid_len); 100 memcpy(wdev->ssid, params->ssid, params->ssid_len);
93 wdev->ssid_len = params->ssid_len; 101 wdev->ssid_len = params->ssid_len;
@@ -97,13 +105,14 @@ int __cfg80211_join_ibss(struct cfg80211_registered_device *rdev,
97 105
98int cfg80211_join_ibss(struct cfg80211_registered_device *rdev, 106int cfg80211_join_ibss(struct cfg80211_registered_device *rdev,
99 struct net_device *dev, 107 struct net_device *dev,
100 struct cfg80211_ibss_params *params) 108 struct cfg80211_ibss_params *params,
109 struct cfg80211_cached_keys *connkeys)
101{ 110{
102 struct wireless_dev *wdev = dev->ieee80211_ptr; 111 struct wireless_dev *wdev = dev->ieee80211_ptr;
103 int err; 112 int err;
104 113
105 wdev_lock(wdev); 114 wdev_lock(wdev);
106 err = __cfg80211_join_ibss(rdev, dev, params); 115 err = __cfg80211_join_ibss(rdev, dev, params, connkeys);
107 wdev_unlock(wdev); 116 wdev_unlock(wdev);
108 117
109 return err; 118 return err;
@@ -112,9 +121,22 @@ int cfg80211_join_ibss(struct cfg80211_registered_device *rdev,
112static void __cfg80211_clear_ibss(struct net_device *dev, bool nowext) 121static void __cfg80211_clear_ibss(struct net_device *dev, bool nowext)
113{ 122{
114 struct wireless_dev *wdev = dev->ieee80211_ptr; 123 struct wireless_dev *wdev = dev->ieee80211_ptr;
124 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
125 int i;
115 126
116 ASSERT_WDEV_LOCK(wdev); 127 ASSERT_WDEV_LOCK(wdev);
117 128
129 kfree(wdev->connect_keys);
130 wdev->connect_keys = NULL;
131
132 /*
133 * Delete all the keys ... pairwise keys can't really
134 * exist any more anyway, but default keys might.
135 */
136 if (rdev->ops->del_key)
137 for (i = 0; i < 6; i++)
138 rdev->ops->del_key(wdev->wiphy, dev, i, NULL);
139
118 if (wdev->current_bss) { 140 if (wdev->current_bss) {
119 cfg80211_unhold_bss(wdev->current_bss); 141 cfg80211_unhold_bss(wdev->current_bss);
120 cfg80211_put_bss(&wdev->current_bss->pub); 142 cfg80211_put_bss(&wdev->current_bss->pub);
@@ -172,11 +194,14 @@ int cfg80211_leave_ibss(struct cfg80211_registered_device *rdev,
172} 194}
173 195
174#ifdef CONFIG_WIRELESS_EXT 196#ifdef CONFIG_WIRELESS_EXT
175static int cfg80211_ibss_wext_join(struct cfg80211_registered_device *rdev, 197int cfg80211_ibss_wext_join(struct cfg80211_registered_device *rdev,
176 struct wireless_dev *wdev) 198 struct wireless_dev *wdev)
177{ 199{
200 struct cfg80211_cached_keys *ck = NULL;
178 enum ieee80211_band band; 201 enum ieee80211_band band;
179 int i; 202 int i, err;
203
204 ASSERT_WDEV_LOCK(wdev);
180 205
181 if (!wdev->wext.ibss.beacon_interval) 206 if (!wdev->wext.ibss.beacon_interval)
182 wdev->wext.ibss.beacon_interval = 100; 207 wdev->wext.ibss.beacon_interval = 100;
@@ -216,8 +241,24 @@ static int cfg80211_ibss_wext_join(struct cfg80211_registered_device *rdev,
216 if (!netif_running(wdev->netdev)) 241 if (!netif_running(wdev->netdev))
217 return 0; 242 return 0;
218 243
219 return cfg80211_join_ibss(wiphy_to_dev(wdev->wiphy), 244 if (wdev->wext.keys)
220 wdev->netdev, &wdev->wext.ibss); 245 wdev->wext.keys->def = wdev->wext.default_key;
246
247 wdev->wext.ibss.privacy = wdev->wext.default_key != -1;
248
249 if (wdev->wext.keys) {
250 ck = kmemdup(wdev->wext.keys, sizeof(*ck), GFP_KERNEL);
251 if (!ck)
252 return -ENOMEM;
253 for (i = 0; i < 6; i++)
254 ck->params[i].key = ck->data[i];
255 }
256 err = __cfg80211_join_ibss(rdev, wdev->netdev,
257 &wdev->wext.ibss, ck);
258 if (err)
259 kfree(ck);
260
261 return err;
221} 262}
222 263
223int cfg80211_ibss_wext_siwfreq(struct net_device *dev, 264int cfg80211_ibss_wext_siwfreq(struct net_device *dev,
@@ -265,7 +306,11 @@ int cfg80211_ibss_wext_siwfreq(struct net_device *dev,
265 wdev->wext.ibss.channel_fixed = false; 306 wdev->wext.ibss.channel_fixed = false;
266 } 307 }
267 308
268 return cfg80211_ibss_wext_join(wiphy_to_dev(wdev->wiphy), wdev); 309 wdev_lock(wdev);
310 err = cfg80211_ibss_wext_join(wiphy_to_dev(wdev->wiphy), wdev);
311 wdev_unlock(wdev);
312
313 return err;
269} 314}
270/* temporary symbol - mark GPL - in the future the handler won't be */ 315/* temporary symbol - mark GPL - in the future the handler won't be */
271EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_siwfreq); 316EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_siwfreq);
@@ -333,7 +378,11 @@ int cfg80211_ibss_wext_siwessid(struct net_device *dev,
333 memcpy(wdev->wext.ibss.ssid, ssid, len); 378 memcpy(wdev->wext.ibss.ssid, ssid, len);
334 wdev->wext.ibss.ssid_len = len; 379 wdev->wext.ibss.ssid_len = len;
335 380
336 return cfg80211_ibss_wext_join(wiphy_to_dev(wdev->wiphy), wdev); 381 wdev_lock(wdev);
382 err = cfg80211_ibss_wext_join(wiphy_to_dev(wdev->wiphy), wdev);
383 wdev_unlock(wdev);
384
385 return err;
337} 386}
338/* temporary symbol - mark GPL - in the future the handler won't be */ 387/* temporary symbol - mark GPL - in the future the handler won't be */
339EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_siwessid); 388EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_siwessid);
@@ -414,7 +463,11 @@ int cfg80211_ibss_wext_siwap(struct net_device *dev,
414 } else 463 } else
415 wdev->wext.ibss.bssid = NULL; 464 wdev->wext.ibss.bssid = NULL;
416 465
417 return cfg80211_ibss_wext_join(wiphy_to_dev(wdev->wiphy), wdev); 466 wdev_lock(wdev);
467 err = cfg80211_ibss_wext_join(wiphy_to_dev(wdev->wiphy), wdev);
468 wdev_unlock(wdev);
469
470 return err;
418} 471}
419/* temporary symbol - mark GPL - in the future the handler won't be */ 472/* temporary symbol - mark GPL - in the future the handler won't be */
420EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_siwap); 473EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_siwap);