diff options
Diffstat (limited to 'freebsd/contrib/wpa/wpa_supplicant/wpa_supplicant.c')
-rw-r--r-- | freebsd/contrib/wpa/wpa_supplicant/wpa_supplicant.c | 126 |
1 files changed, 101 insertions, 25 deletions
diff --git a/freebsd/contrib/wpa/wpa_supplicant/wpa_supplicant.c b/freebsd/contrib/wpa/wpa_supplicant/wpa_supplicant.c index 1bc62ce6..2d4c6740 100644 --- a/freebsd/contrib/wpa/wpa_supplicant/wpa_supplicant.c +++ b/freebsd/contrib/wpa/wpa_supplicant/wpa_supplicant.c @@ -38,6 +38,7 @@ #include "rsn_supp/preauth.h" #include "rsn_supp/pmksa_cache.h" #include "common/wpa_ctrl.h" +#include "common/ieee802_11_common.h" #include "common/ieee802_11_defs.h" #include "common/hw_features_common.h" #include "common/gas_server.h" @@ -1418,9 +1419,10 @@ int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s, wpa_s->key_mgmt = WPA_KEY_MGMT_FT_IEEE8021X_SHA384; wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT FT/802.1X-SHA384"); - if (pmksa_cache_get_current(wpa_s->wpa)) { - /* PMKSA caching with FT is not fully functional, so - * disable the case for now. */ + if (!ssid->ft_eap_pmksa_caching && + pmksa_cache_get_current(wpa_s->wpa)) { + /* PMKSA caching with FT may have interoperability + * issues, so disable that case by default for now. */ wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Disable PMKSA caching for FT/802.1X connection"); pmksa_cache_clear_current(wpa_s->wpa); @@ -1459,9 +1461,10 @@ int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s, } else if (sel & WPA_KEY_MGMT_FT_IEEE8021X) { wpa_s->key_mgmt = WPA_KEY_MGMT_FT_IEEE8021X; wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT FT/802.1X"); - if (pmksa_cache_get_current(wpa_s->wpa)) { - /* PMKSA caching with FT is not fully functional, so - * disable the case for now. */ + if (!ssid->ft_eap_pmksa_caching && + pmksa_cache_get_current(wpa_s->wpa)) { + /* PMKSA caching with FT may have interoperability + * issues, so disable that case by default for now. */ wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Disable PMKSA caching for FT/802.1X connection"); pmksa_cache_clear_current(wpa_s->wpa); @@ -1710,7 +1713,8 @@ static void wpas_ext_capab_byte(struct wpa_supplicant *wpa_s, u8 *pos, int idx) case 2: /* Bits 16-23 */ #ifdef CONFIG_WNM *pos |= 0x02; /* Bit 17 - WNM-Sleep Mode */ - *pos |= 0x08; /* Bit 19 - BSS Transition */ + if (!wpa_s->conf->disable_btm) + *pos |= 0x08; /* Bit 19 - BSS Transition */ #endif /* CONFIG_WNM */ break; case 3: /* Bits 24-31 */ @@ -2064,7 +2068,7 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s, #endif /* CONFIG_TDLS */ if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) && - ssid->mode == IEEE80211_MODE_INFRA) { + ssid->mode == WPAS_MODE_INFRA) { sme_authenticate(wpa_s, bss, ssid); return; } @@ -2138,6 +2142,7 @@ void ibss_mesh_setup_freq(struct wpa_supplicant *wpa_s, const struct wpa_ssid *ssid, struct hostapd_freq_params *freq) { + int ieee80211_mode = wpas_mode_to_ieee80211_mode(ssid->mode); enum hostapd_hw_mode hw_mode; struct hostapd_hw_modes *mode = NULL; int ht40plus[] = { 36, 44, 52, 60, 100, 108, 116, 124, 132, 149, 157, @@ -2201,6 +2206,9 @@ void ibss_mesh_setup_freq(struct wpa_supplicant *wpa_s, if (!mode) return; + /* HE can work without HT + VHT */ + freq->he_enabled = mode->he_capab[ieee80211_mode].he_supported; + #ifdef CONFIG_HT_OVERRIDES if (ssid->disable_ht) { freq->ht_enabled = 0; @@ -2354,11 +2362,11 @@ skip_ht40: return; } - chwidth = VHT_CHANWIDTH_80MHZ; + chwidth = CHANWIDTH_80MHZ; seg0 = vht80[j] + 6; seg1 = 0; - if (ssid->max_oper_chwidth == VHT_CHANWIDTH_80P80MHZ) { + if (ssid->max_oper_chwidth == CHANWIDTH_80P80MHZ) { /* setup center_freq2, bandwidth */ for (k = 0; k < ARRAY_SIZE(vht80); k++) { /* Only accept 80 MHz segments separated by a gap */ @@ -2377,27 +2385,27 @@ skip_ht40: continue; /* Found a suitable second segment for 80+80 */ - chwidth = VHT_CHANWIDTH_80P80MHZ; + chwidth = CHANWIDTH_80P80MHZ; vht_caps |= VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ; seg1 = vht80[k] + 6; } - if (chwidth == VHT_CHANWIDTH_80P80MHZ) + if (chwidth == CHANWIDTH_80P80MHZ) break; } - } else if (ssid->max_oper_chwidth == VHT_CHANWIDTH_160MHZ) { + } else if (ssid->max_oper_chwidth == CHANWIDTH_160MHZ) { if (freq->freq == 5180) { - chwidth = VHT_CHANWIDTH_160MHZ; + chwidth = CHANWIDTH_160MHZ; vht_caps |= VHT_CAP_SUPP_CHAN_WIDTH_160MHZ; seg0 = 50; } else if (freq->freq == 5520) { - chwidth = VHT_CHANWIDTH_160MHZ; + chwidth = CHANWIDTH_160MHZ; vht_caps |= VHT_CAP_SUPP_CHAN_WIDTH_160MHZ; seg0 = 114; } - } else if (ssid->max_oper_chwidth == VHT_CHANWIDTH_USE_HT) { - chwidth = VHT_CHANWIDTH_USE_HT; + } else if (ssid->max_oper_chwidth == CHANWIDTH_USE_HT) { + chwidth = CHANWIDTH_USE_HT; seg0 = vht80[j] + 2; #ifdef CONFIG_HT_OVERRIDES if (ssid->disable_ht40) @@ -2407,9 +2415,10 @@ skip_ht40: if (hostapd_set_freq_params(&vht_freq, mode->mode, freq->freq, freq->channel, freq->ht_enabled, - vht_freq.vht_enabled, + vht_freq.vht_enabled, freq->he_enabled, freq->sec_channel_offset, - chwidth, seg0, seg1, vht_caps) != 0) + chwidth, seg0, seg1, vht_caps, + &mode->he_capab[ieee80211_mode]) != 0) return; *freq = vht_freq; @@ -3222,7 +3231,7 @@ static void wpas_start_assoc_cb(struct wpa_radio_work *work, int deinit) params.key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X_SHA256 || params.key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X_SUITE_B || params.key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X_SUITE_B_192)) - params.req_key_mgmt_offload = 1; + params.req_handshake_offload = 1; if (wpa_s->conf->key_mgmt_offload) { if (params.key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X || @@ -3423,16 +3432,17 @@ static void wpa_supplicant_clear_connection(struct wpa_supplicant *wpa_s, * current AP. */ void wpa_supplicant_deauthenticate(struct wpa_supplicant *wpa_s, - int reason_code) + u16 reason_code) { u8 *addr = NULL; union wpa_event_data event; int zero_addr = 0; wpa_dbg(wpa_s, MSG_DEBUG, "Request to deauthenticate - bssid=" MACSTR - " pending_bssid=" MACSTR " reason=%d state=%s", + " pending_bssid=" MACSTR " reason=%d (%s) state=%s", MAC2STR(wpa_s->bssid), MAC2STR(wpa_s->pending_bssid), - reason_code, wpa_supplicant_state_txt(wpa_s->wpa_state)); + reason_code, reason2str(reason_code), + wpa_supplicant_state_txt(wpa_s->wpa_state)); if (!is_zero_ether_addr(wpa_s->pending_bssid) && (wpa_s->wpa_state == WPA_AUTHENTICATING || @@ -3474,7 +3484,7 @@ void wpa_supplicant_deauthenticate(struct wpa_supplicant *wpa_s, if (addr) { wpa_drv_deauthenticate(wpa_s, addr, reason_code); os_memset(&event, 0, sizeof(event)); - event.deauth_info.reason_code = (u16) reason_code; + event.deauth_info.reason_code = reason_code; event.deauth_info.locally_generated = 1; wpa_supplicant_event(wpa_s, EVENT_DEAUTH, &event); if (zero_addr) @@ -4229,7 +4239,7 @@ void wpa_supplicant_rx_eapol(void *ctx, const u8 *src_addr, !wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt) || wpa_s->wpa_state != WPA_COMPLETED) && (wpa_s->current_ssid == NULL || - wpa_s->current_ssid->mode != IEEE80211_MODE_IBSS)) { + wpa_s->current_ssid->mode != WPAS_MODE_IBSS)) { /* Timeout for completing IEEE 802.1X and WPA authentication */ int timeout = 10; @@ -6621,6 +6631,9 @@ void wpa_supplicant_update_config(struct wpa_supplicant *wpa_s) wpa_s->conf->wowlan_triggers); } + if (wpa_s->conf->changed_parameters & CFG_CHANGED_DISABLE_BTM) + wpa_supplicant_set_default_scan_ies(wpa_s); + #ifdef CONFIG_WPS wpas_wps_update_config(wpa_s); #endif /* CONFIG_WPS */ @@ -7468,3 +7481,66 @@ int wpa_is_bss_tmp_disallowed(struct wpa_supplicant *wpa_s, return 1; } + + +int wpas_enable_mac_addr_randomization(struct wpa_supplicant *wpa_s, + unsigned int type, const u8 *addr, + const u8 *mask) +{ + if ((addr && !mask) || (!addr && mask)) { + wpa_printf(MSG_INFO, + "MAC_ADDR_RAND_SCAN invalid addr/mask combination"); + return -1; + } + + if (addr && mask && (!(mask[0] & 0x01) || (addr[0] & 0x01))) { + wpa_printf(MSG_INFO, + "MAC_ADDR_RAND_SCAN cannot allow multicast address"); + return -1; + } + + if (type & MAC_ADDR_RAND_SCAN) { + if (wpas_mac_addr_rand_scan_set(wpa_s, MAC_ADDR_RAND_SCAN, + addr, mask)) + return -1; + } + + if (type & MAC_ADDR_RAND_SCHED_SCAN) { + if (wpas_mac_addr_rand_scan_set(wpa_s, MAC_ADDR_RAND_SCHED_SCAN, + addr, mask)) + return -1; + + if (wpa_s->sched_scanning && !wpa_s->pno) + wpas_scan_restart_sched_scan(wpa_s); + } + + if (type & MAC_ADDR_RAND_PNO) { + if (wpas_mac_addr_rand_scan_set(wpa_s, MAC_ADDR_RAND_PNO, + addr, mask)) + return -1; + + if (wpa_s->pno) { + wpas_stop_pno(wpa_s); + wpas_start_pno(wpa_s); + } + } + + return 0; +} + + +int wpas_disable_mac_addr_randomization(struct wpa_supplicant *wpa_s, + unsigned int type) +{ + wpas_mac_addr_rand_scan_clear(wpa_s, type); + if (wpa_s->pno) { + if (type & MAC_ADDR_RAND_PNO) { + wpas_stop_pno(wpa_s); + wpas_start_pno(wpa_s); + } + } else if (wpa_s->sched_scanning && (type & MAC_ADDR_RAND_SCHED_SCAN)) { + wpas_scan_restart_sched_scan(wpa_s); + } + + return 0; +} |