[PATCH] wpa_supplicant: Resolve secondary VAP association issue
Jouni Malinen
j at w1.fi
Sun Nov 27 09:41:59 PST 2022
On Sun, Jul 03, 2022 at 05:37:54PM -0700, Cy Schubert wrote:
> 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.
>
> FreeBSD PR: 264238
> diff --git a/src/drivers/driver_bsd.c b/src/drivers/driver_bsd.c
> +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;
So this part was just moving the call to a separate function..
> + privacy = !(params->pairwise_suite == WPA_CIPHER_NONE &&
> + params->group_suite == WPA_CIPHER_NONE &&
> + params->key_mgmt_suite == WPA_KEY_MGMT_NONE);
While there is a change here: condition of params->wpa_ie_len == 0 was
removed. And well, this function would not actually be called without an
IE, so that would have been just forcing privacy = 1.
> + wpa_printf(MSG_DEBUG, "%s: set PRIVACY %u", __func__,
> + privacy);
> +
> + if (set80211param(drv, IEEE80211_IOC_PRIVACY, privacy) < 0)
> + return -1;
I'm not completely sure how exactly the IEEE80211_IOC_PRIVACY parameter
is supposed to behave, but it would feel very strange to me not to
expect there to be privacy protection with WPA IE/RSNE included. That
said, it looks like privacy would really be hardcoded to 1 here anyway
for all the cases that end up calling this function, so I cannot really
follow what this is trying to do.
> + if (ie_len &&
> + set80211param(drv, IEEE80211_IOC_WPA,
> + ie[0] == WLAN_EID_RSN ? 2 : 1) < 0)
> + return -1;
This is just from moving to a separate function.
> static int
> wpa_driver_bsd_associate(void *priv, struct wpa_driver_associate_params
> *params)
> 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;
This call was practically made condition on there being either a WPA IE
or an RSNE in the IE buffer.
> - 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;
This is the call that would not be issued anymore unless either a WPA IE
or an RSNE is included. Is that on purpose? What about WEP?
> + 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;
> + }
Is this filtering out any other potential information element from the
buffer other than RSNE? If so, why?
> + 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;
> + }
And same here for filtering anything other than WPA IE (not that I would
expect this part to make much of a difference)?
--
Jouni Malinen PGP id EFC895FA
More information about the Hostap
mailing list