aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJ.R. Oldroyd <fbsd@opal.com>2022-07-02 18:15:31 +0000
committerCy Schubert <cy@FreeBSD.org>2022-07-03 21:19:38 +0000
commit775611ea11db0973fd8b7aef0f5eb527308efd05 (patch)
treed01fc9ab010366ce10e0f7890a06d993ef47a826
parent7999a7f2a8679f73574b6704377436025601ee85 (diff)
downloadsrc-775611ea11db0973fd8b7aef0f5eb527308efd05.tar.gz
src-775611ea11db0973fd8b7aef0f5eb527308efd05.zip
wpa_supplicant: Resolve secondary VAP association issue
Association will fail on a secondary open unprotected VAP when the primary VAP is configured for WPA. Examples of secondary VAPs are, hotels, universities, and commodity routers' guest networks. A broadly similar bug was discussed on Red Hat's bugzilla affecting association to a D-Link DIR-842. This suggests that as IEs were added to the 802.11 protocol the old code was increasingly inadaquate to handle the additional IEs, not only a secondary VAP. PR: 264238 Reported by: Jaskie <jiangjun12321@gmail.com> "J.R. Oldroyd" <fbsd@opal.com> Submitted by: "J.R. Oldroyd" <fbsd@opal.com> MFC after: 3 days
-rw-r--r--contrib/wpa/src/drivers/driver_bsd.c65
1 files changed, 48 insertions, 17 deletions
diff --git a/contrib/wpa/src/drivers/driver_bsd.c b/contrib/wpa/src/drivers/driver_bsd.c
index c455bc931036..345bbb892ecf 100644
--- a/contrib/wpa/src/drivers/driver_bsd.c
+++ b/contrib/wpa/src/drivers/driver_bsd.c
@@ -14,6 +14,7 @@
#include "driver.h"
#include "eloop.h"
#include "common/ieee802_11_defs.h"
+#include "common/ieee802_11_common.h"
#include "common/wpa_common.h"
#include <ifaddrs.h>
@@ -1201,13 +1202,41 @@ handle_read(void *ctx, const u8 *src_addr, const u8 *buf, size_t len)
}
static int
+wpa_driver_bsd_set_rsn_wpa_ie(struct bsd_driver_data * drv,
+ struct wpa_driver_associate_params *params, const u8 *ie)
+{
+ int privacy;
+ size_t ie_len = ie[1] ? ie[1] + 2 : 0;
+
+ /* XXX error handling is wrong but unclear what to do... */
+ if (wpa_driver_bsd_set_wpa_ie(drv, ie, ie_len) < 0)
+ return -1;
+
+ privacy = !(params->pairwise_suite == WPA_CIPHER_NONE &&
+ params->group_suite == WPA_CIPHER_NONE &&
+ params->key_mgmt_suite == WPA_KEY_MGMT_NONE);
+ wpa_printf(MSG_DEBUG, "%s: set PRIVACY %u", __func__,
+ privacy);
+
+ if (set80211param(drv, IEEE80211_IOC_PRIVACY, privacy) < 0)
+ return -1;
+
+ if (ie_len &&
+ set80211param(drv, IEEE80211_IOC_WPA,
+ ie[0] == WLAN_EID_RSN ? 2 : 1) < 0)
+ return -1;
+
+ return 0;
+}
+
+static int
wpa_driver_bsd_associate(void *priv, struct wpa_driver_associate_params *params)
{
struct bsd_driver_data *drv = priv;
struct ieee80211req_mlme mlme;
u32 mode;
- int privacy;
int ret = 0;
+ const u8 *wpa_ie, *rsn_ie;
wpa_printf(MSG_DEBUG,
"%s: ssid '%.*s' wpa ie len %u pairwise %u group %u key mgmt %u"
@@ -1256,23 +1285,25 @@ wpa_driver_bsd_associate(void *priv, struct wpa_driver_associate_params *params)
ret = -1;
if (wpa_driver_bsd_set_auth_alg(drv, params->auth_alg) < 0)
ret = -1;
- /* XXX error handling is wrong but unclear what to do... */
- if (wpa_driver_bsd_set_wpa_ie(drv, params->wpa_ie, params->wpa_ie_len) < 0)
- return -1;
- privacy = !(params->pairwise_suite == WPA_CIPHER_NONE &&
- params->group_suite == WPA_CIPHER_NONE &&
- params->key_mgmt_suite == WPA_KEY_MGMT_NONE &&
- params->wpa_ie_len == 0);
- wpa_printf(MSG_DEBUG, "%s: set PRIVACY %u", __func__, privacy);
-
- if (set80211param(drv, IEEE80211_IOC_PRIVACY, privacy) < 0)
- return -1;
-
- if (params->wpa_ie_len &&
- set80211param(drv, IEEE80211_IOC_WPA,
- params->wpa_ie[0] == WLAN_EID_RSN ? 2 : 1) < 0)
- return -1;
+ if (params->wpa_ie_len) {
+ rsn_ie = get_ie(params->wpa_ie, params->wpa_ie_len,
+ WLAN_EID_RSN);
+ if (rsn_ie) {
+ if (wpa_driver_bsd_set_rsn_wpa_ie(drv, params,
+ rsn_ie) < 0)
+ return -1;
+ }
+ else {
+ wpa_ie = get_vendor_ie(params->wpa_ie,
+ params->wpa_ie_len, WPA_IE_VENDOR_TYPE);
+ if (wpa_ie) {
+ if (wpa_driver_bsd_set_rsn_wpa_ie(drv, params,
+ wpa_ie) < 0)
+ return -1;
+ }
+ }
+ }
/*
* NB: interface must be marked UP for association