The branch stable/12 has been updated by cy:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=7c38194341bf39e8878e3a88838aac7880825c02

commit 7c38194341bf39e8878e3a88838aac7880825c02
Author:     J.R. Oldroyd <[email protected]>
AuthorDate: 2022-07-02 18:15:31 +0000
Commit:     Cy Schubert <[email protected]>
CommitDate: 2022-07-06 00:32:53 +0000

    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 <[email protected]>
                    "J.R. Oldroyd" <[email protected]>
    Submitted by:   "J.R. Oldroyd" <[email protected]>
    
    (cherry picked from commit 775611ea11db0973fd8b7aef0f5eb527308efd05)
---
 contrib/wpa/src/drivers/driver_bsd.c | 65 ++++++++++++++++++++++++++----------
 1 file 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>
@@ -1200,14 +1201,42 @@ handle_read(void *ctx, const u8 *src_addr, const u8 
*buf, size_t len)
        drv_event_eapol_rx(drv->ctx, src_addr, buf, 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

Reply via email to