diff options
30 files changed, 470 insertions, 95 deletions
diff --git a/hostapd/Android.mk b/hostapd/Android.mk index 980a5513..bc0273e0 100644 --- a/hostapd/Android.mk +++ b/hostapd/Android.mk @@ -105,7 +105,6 @@ NEED_RC4=y NEED_AES=y NEED_MD5=y NEED_SHA1=y -NEED_SHA256=y OBJS += src/drivers/drivers.c L_CFLAGS += -DHOSTAPD @@ -528,10 +527,6 @@ ifeq ($(CONFIG_TLS), gnutls) ifdef TLS_FUNCS OBJS += src/crypto/tls_gnutls.c LIBS += -lgnutls -lgpg-error -ifdef CONFIG_GNUTLS_EXTRA -L_CFLAGS += -DCONFIG_GNUTLS_EXTRA -LIBS += -lgnutls-extra -endif endif OBJS += src/crypto/crypto_gnutls.c HOBJS += src/crypto/crypto_gnutls.c @@ -858,10 +853,20 @@ endif OBJS += src/drivers/driver_common.c +ifdef CONFIG_ACS +L_CFLAGS += -DCONFIG_ACS +OBJS += src/ap/acs.c +LIBS += -lm +endif + ifdef CONFIG_NO_STDOUT_DEBUG L_CFLAGS += -DCONFIG_NO_STDOUT_DEBUG endif +ifdef CONFIG_DEBUG_LINUX_TRACING +L_CFLAGS += -DCONFIG_DEBUG_LINUX_TRACING +endif + ifdef CONFIG_DEBUG_FILE L_CFLAGS += -DCONFIG_DEBUG_FILE endif @@ -882,12 +887,6 @@ else OBJS_c += src/utils/edit_simple.c endif -ifdef CONFIG_ACS -L_CFLAGS += -DCONFIG_ACS -OBJS += src/ap/acs.c -LIBS += -lm -endif - ######################## include $(CLEAR_VARS) diff --git a/hostapd/config_file.c b/hostapd/config_file.c index ef0d647e..ae059176 100644 --- a/hostapd/config_file.c +++ b/hostapd/config_file.c @@ -2422,6 +2422,8 @@ static int hostapd_config_fill(struct hostapd_config *conf, } } else if (os_strcmp(buf, "require_ht") == 0) { conf->require_ht = atoi(pos); + } else if (os_strcmp(buf, "obss_interval") == 0) { + conf->obss_interval = atoi(pos); #endif /* CONFIG_IEEE80211N */ #ifdef CONFIG_IEEE80211AC } else if (os_strcmp(buf, "ieee80211ac") == 0) { diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c index cea96eb6..3f181fa8 100644 --- a/hostapd/ctrl_iface.c +++ b/hostapd/ctrl_iface.c @@ -82,15 +82,15 @@ static int hostapd_ctrl_iface_detach(struct hostapd_data *hapd, os_memcmp(from->sun_path, dst->addr.sun_path, fromlen - offsetof(struct sockaddr_un, sun_path)) == 0) { + wpa_hexdump(MSG_DEBUG, "CTRL_IFACE monitor detached", + (u8 *) from->sun_path, + fromlen - + offsetof(struct sockaddr_un, sun_path)); if (prev == NULL) hapd->ctrl_dst = dst->next; else prev->next = dst->next; os_free(dst); - wpa_hexdump(MSG_DEBUG, "CTRL_IFACE monitor detached", - (u8 *) from->sun_path, - fromlen - - offsetof(struct sockaddr_un, sun_path)); return 0; } prev = dst; diff --git a/hostapd/hostapd.conf b/hostapd/hostapd.conf index eeb00551..9b70d0fb 100644 --- a/hostapd/hostapd.conf +++ b/hostapd/hostapd.conf @@ -468,6 +468,13 @@ wmm_ac_vo_acm=0 # Require stations to support HT PHY (reject association if they do not) #require_ht=1 +# If set non-zero, require stations to perform scans of overlapping +# channels to test for stations which would be affected by 40 MHz traffic. +# This parameter sets the interval in seconds between these scans. This +# is useful only for testing that stations properly set the OBSS interval, +# since the other parameters in the OBSS scan parameters IE are set to 0. +#obss_interval=0 + ##### IEEE 802.11ac related configuration ##################################### # ieee80211ac: Whether IEEE 802.11ac (VHT) is enabled diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h index 8b737248..09b2778e 100644 --- a/src/ap/ap_config.h +++ b/src/ap/ap_config.h @@ -530,6 +530,7 @@ struct hostapd_config { int ieee80211n; int secondary_channel; int require_ht; + int obss_interval; u32 vht_capab; int ieee80211ac; int require_vht; diff --git a/src/ap/gas_serv.c b/src/ap/gas_serv.c index b3574ba6..8349c4dd 100644 --- a/src/ap/gas_serv.c +++ b/src/ap/gas_serv.c @@ -46,6 +46,8 @@ gas_dialog_create(struct hostapd_data *hapd, const u8 *addr, u8 dialog_token) * it to be that long. */ ap_sta_session_timeout(hapd, sta, 5); + } else { + ap_sta_replenish_timeout(hapd, sta, 5); } if (sta->gas_dialog == NULL) { diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c index 52be3110..60224ccb 100644 --- a/src/ap/hostapd.c +++ b/src/ap/hostapd.c @@ -243,6 +243,7 @@ static int hostapd_broadcast_wep_set(struct hostapd_data *hapd) static void hostapd_free_hapd_data(struct hostapd_data *hapd) { + wpa_printf(MSG_DEBUG, "%s(%s)", __func__, hapd->conf->iface); iapp_deinit(hapd->iapp); hapd->iapp = NULL; accounting_deinit(hapd); @@ -260,7 +261,8 @@ static void hostapd_free_hapd_data(struct hostapd_data *hapd) authsrv_deinit(hapd); - if (hostapd_if_remove(hapd, WPA_IF_AP_BSS, hapd->conf->iface)) { + if (hapd->interface_added && + hostapd_if_remove(hapd, WPA_IF_AP_BSS, hapd->conf->iface)) { wpa_printf(MSG_WARNING, "Failed to remove BSS interface %s", hapd->conf->iface); } @@ -293,34 +295,24 @@ static void hostapd_free_hapd_data(struct hostapd_data *hapd) * @hapd: Pointer to BSS data * * This function is used to free all per-BSS data structures and resources. - * This gets called in a loop for each BSS between calls to - * hostapd_cleanup_iface_pre() and hostapd_cleanup_iface() when an interface - * is deinitialized. Most of the modules that are initialized in - * hostapd_setup_bss() are deinitialized here. + * Most of the modules that are initialized in hostapd_setup_bss() are + * deinitialized here. */ static void hostapd_cleanup(struct hostapd_data *hapd) { + wpa_printf(MSG_DEBUG, "%s(hapd=%p (%s))", __func__, hapd, + hapd->conf->iface); if (hapd->iface->interfaces && hapd->iface->interfaces->ctrl_iface_deinit) hapd->iface->interfaces->ctrl_iface_deinit(hapd); hostapd_free_hapd_data(hapd); -} - - -/** - * hostapd_cleanup_iface_pre - Preliminary per-interface cleanup - * @iface: Pointer to interface data - * - * This function is called before per-BSS data structures are deinitialized - * with hostapd_cleanup(). - */ -static void hostapd_cleanup_iface_pre(struct hostapd_iface *iface) -{ + hapd->started = 0; } static void hostapd_cleanup_iface_partial(struct hostapd_iface *iface) { + wpa_printf(MSG_DEBUG, "%s(%p)", __func__, iface); hostapd_free_hw_features(iface->hw_features, iface->num_hw_features); iface->hw_features = NULL; os_free(iface->current_rates); @@ -340,6 +332,7 @@ static void hostapd_cleanup_iface_partial(struct hostapd_iface *iface) */ static void hostapd_cleanup_iface(struct hostapd_iface *iface) { + wpa_printf(MSG_DEBUG, "%s(%p)", __func__, iface); eloop_cancel_timeout(channel_list_update_timeout, iface, NULL); hostapd_cleanup_iface_partial(iface); @@ -348,6 +341,7 @@ static void hostapd_cleanup_iface(struct hostapd_iface *iface) os_free(iface->config_fname); os_free(iface->bss); + wpa_printf(MSG_DEBUG, "%s: free iface=%p", __func__, iface); os_free(iface); } @@ -629,6 +623,16 @@ static int hostapd_setup_bss(struct hostapd_data *hapd, int first) char force_ifname[IFNAMSIZ]; u8 if_addr[ETH_ALEN]; + wpa_printf(MSG_DEBUG, "%s(hapd=%p (%s), first=%d)", + __func__, hapd, hapd->conf->iface, first); + + if (hapd->started) { + wpa_printf(MSG_ERROR, "%s: Interface %s was already started", + __func__, hapd->conf->iface); + return -1; + } + hapd->started = 1; + if (!first || first == -1) { if (hostapd_mac_comp_empty(hapd->conf->bssid) == 0) { /* Allocate the next available BSSID. */ @@ -649,6 +653,7 @@ static int hostapd_setup_bss(struct hostapd_data *hapd, int first) } } + hapd->interface_added = 1; if (hostapd_if_add(hapd->iface->bss[0], WPA_IF_AP_BSS, hapd->conf->iface, hapd->own_addr, hapd, &hapd->drv_priv, force_ifname, if_addr, @@ -1259,32 +1264,42 @@ hostapd_alloc_bss_data(struct hostapd_iface *hapd_iface, } +static void hostapd_bss_deinit(struct hostapd_data *hapd) +{ + wpa_printf(MSG_DEBUG, "%s: deinit bss %s", __func__, + hapd->conf->iface); + hostapd_free_stas(hapd); + hostapd_flush_old_stations(hapd, WLAN_REASON_DEAUTH_LEAVING); + hostapd_clear_wep(hapd); + hostapd_cleanup(hapd); +} + + void hostapd_interface_deinit(struct hostapd_iface *iface) { int j; + wpa_printf(MSG_DEBUG, "%s(%p)", __func__, iface); if (iface == NULL) return; eloop_cancel_timeout(channel_list_update_timeout, iface, NULL); iface->wait_channel_update = 0; - hostapd_cleanup_iface_pre(iface); - for (j = iface->num_bss - 1; j >= 0; j--) { - struct hostapd_data *hapd = iface->bss[j]; - hostapd_free_stas(hapd); - hostapd_flush_old_stations(hapd, WLAN_REASON_DEAUTH_LEAVING); - hostapd_clear_wep(hapd); - hostapd_cleanup(hapd); - } + for (j = iface->num_bss - 1; j >= 0; j--) + hostapd_bss_deinit(iface->bss[j]); } void hostapd_interface_free(struct hostapd_iface *iface) { size_t j; - for (j = 0; j < iface->num_bss; j++) + wpa_printf(MSG_DEBUG, "%s(%p)", __func__, iface); + for (j = 0; j < iface->num_bss; j++) { + wpa_printf(MSG_DEBUG, "%s: free hapd %p", + __func__, iface->bss[j]); os_free(iface->bss[j]); + } hostapd_cleanup_iface(iface); } @@ -1344,6 +1359,8 @@ fail: if (hapd_iface) { os_free(hapd_iface->config_fname); os_free(hapd_iface->bss); + wpa_printf(MSG_DEBUG, "%s: free iface %p", + __func__, hapd_iface); os_free(hapd_iface); } return NULL; @@ -1488,11 +1505,18 @@ void hostapd_interface_deinit_free(struct hostapd_iface *iface) { const struct wpa_driver_ops *driver; void *drv_priv; + + wpa_printf(MSG_DEBUG, "%s(%p)", __func__, iface); if (iface == NULL) return; + wpa_printf(MSG_DEBUG, "%s: num_bss=%u conf->num_bss=%u", + __func__, (unsigned int) iface->num_bss, + (unsigned int) iface->conf->num_bss); driver = iface->bss[0]->driver; drv_priv = iface->bss[0]->drv_priv; hostapd_interface_deinit(iface); + wpa_printf(MSG_DEBUG, "%s: driver=%p drv_priv=%p -> hapd_deinit", + __func__, driver, drv_priv); if (driver && driver->hapd_deinit && drv_priv) driver->hapd_deinit(drv_priv); hostapd_interface_free(iface); @@ -1521,6 +1545,8 @@ int hostapd_enable_iface(struct hostapd_iface *hapd_iface) driver = hapd_iface->bss[0]->driver; drv_priv = hapd_iface->bss[0]->drv_priv; + wpa_printf(MSG_DEBUG, "%s: driver=%p drv_priv=%p -> hapd_deinit", + __func__, driver, drv_priv); if (driver && driver->hapd_deinit && drv_priv) { driver->hapd_deinit(drv_priv); hapd_iface->bss[0]->drv_priv = NULL; @@ -1573,6 +1599,8 @@ int hostapd_disable_iface(struct hostapd_iface *hapd_iface) hostapd_free_hapd_data(hapd); } + wpa_printf(MSG_DEBUG, "%s: driver=%p drv_priv=%p -> hapd_deinit", + __func__, driver, drv_priv); if (driver && driver->hapd_deinit && drv_priv) { driver->hapd_deinit(drv_priv); hapd_iface->bss[0]->drv_priv = NULL; @@ -1740,9 +1768,12 @@ int hostapd_add_iface(struct hapd_interfaces *interfaces, char *buf) ETH_ALEN); if (start_ctrl_iface_bss(hapd) < 0 || - hostapd_setup_bss(hapd, -1)) { + (hapd_iface->state == HAPD_IFACE_ENABLED && + hostapd_setup_bss(hapd, -1))) { hapd_iface->conf->num_bss--; hapd_iface->num_bss--; + wpa_printf(MSG_DEBUG, "%s: free hapd %p %s", + __func__, hapd, hapd->conf->iface); os_free(hapd); return -1; } @@ -1806,10 +1837,21 @@ fail: hostapd_config_free(conf); if (hapd_iface) { if (hapd_iface->bss) { - for (i = 0; i < hapd_iface->num_bss; i++) + for (i = 0; i < hapd_iface->num_bss; i++) { + hapd = hapd_iface->bss[i]; + if (hapd && hapd_iface->interfaces && + hapd_iface->interfaces->ctrl_iface_deinit) + hapd_iface->interfaces-> + ctrl_iface_deinit(hapd); + wpa_printf(MSG_DEBUG, "%s: free hapd %p (%s)", + __func__, hapd_iface->bss[i], + hapd_iface->bss[i]->conf->iface); os_free(hapd_iface->bss[i]); + } os_free(hapd_iface->bss); } + wpa_printf(MSG_DEBUG, "%s: free iface %p", + __func__, hapd_iface); os_free(hapd_iface); } return -1; @@ -1818,27 +1860,31 @@ fail: static int hostapd_remove_bss(struct hostapd_iface *iface, unsigned int idx) { - struct hostapd_data *hapd; size_t i; - if (idx > iface->num_bss || idx > iface->conf->num_bss) - return -1; - hapd = iface->bss[idx]; - wpa_printf(MSG_INFO, "Remove BSS '%s'", hapd->conf->iface); + wpa_printf(MSG_INFO, "Remove BSS '%s'", iface->conf->bss[idx]->iface); - hostapd_free_stas(hapd); - hostapd_flush_old_stations(hapd, WLAN_REASON_DEAUTH_LEAVING); - hostapd_clear_wep(hapd); - hostapd_cleanup(hapd); - hostapd_config_free_bss(hapd->conf); - os_free(hapd); + /* Remove hostapd_data only if it has already been initialized */ + if (idx < iface->num_bss) { + struct hostapd_data *hapd = iface->bss[idx]; - iface->num_bss--; - for (i = idx; i < iface->num_bss; i++) - iface->bss[i] = iface->bss[i + 1]; + hostapd_bss_deinit(hapd); + wpa_printf(MSG_DEBUG, "%s: free hapd %p (%s)", + __func__, hapd, hapd->conf->iface); + hostapd_config_free_bss(hapd->conf); + os_free(hapd); + + iface->num_bss--; + + for (i = idx; i < iface->num_bss; i++) + iface->bss[i] = iface->bss[i + 1]; + } else { + hostapd_config_free_bss(iface->conf->bss[idx]); + iface->conf->bss[idx] = NULL; + } iface->conf->num_bss--; - for (i = idx; i < iface->num_bss; i++) + for (i = idx; i < iface->conf->num_bss; i++) iface->conf->bss[i] = iface->conf->bss[i + 1]; return 0; @@ -1854,8 +1900,7 @@ int hostapd_remove_iface(struct hapd_interfaces *interfaces, char *buf) hapd_iface = interfaces->iface[i]; if (hapd_iface == NULL) return -1; - if (hapd_iface->conf->num_bss == 1 && - !os_strcmp(hapd_iface->conf->bss[0]->iface, buf)) { + if (!os_strcmp(hapd_iface->conf->bss[0]->iface, buf)) { wpa_printf(MSG_INFO, "Remove interface '%s'", buf); hostapd_interface_deinit_free(hapd_iface); k = i; diff --git a/src/ap/hostapd.h b/src/ap/hostapd.h index adb3728d..1887531f 100644 --- a/src/ap/hostapd.h +++ b/src/ap/hostapd.h @@ -101,6 +101,8 @@ struct hostapd_data { struct hostapd_iface *iface; struct hostapd_config *iconf; struct hostapd_bss_config *conf; + int interface_added; /* virtual interface added for this BSS */ + unsigned int started:1; u8 own_addr[ETH_ALEN]; diff --git a/src/ap/ieee802_11_ht.c b/src/ap/ieee802_11_ht.c index 6483e1c3..2d53648c 100644 --- a/src/ap/ieee802_11_ht.c +++ b/src/ap/ieee802_11_ht.c @@ -50,6 +50,22 @@ u8 * hostapd_eid_ht_capabilities(struct hostapd_data *hapd, u8 *eid) pos += sizeof(*cap); + if (hapd->iconf->obss_interval) { + struct ieee80211_obss_scan_parameters *scan_params; + + *pos++ = WLAN_EID_OVERLAPPING_BSS_SCAN_PARAMS; + *pos++ = sizeof(*scan_params); + + scan_params = (struct ieee80211_obss_scan_parameters *) pos; + os_memset(scan_params, 0, sizeof(*scan_params)); + scan_params->width_trigger_scan_interval = + host_to_le16(hapd->iconf->obss_interval); + + /* TODO: Fill in more parameters (supplicant ignores them) */ + + pos += sizeof(*scan_params); + } + return pos; } diff --git a/src/ap/sta_info.c b/src/ap/sta_info.c index 016b9b6a..a6775f3f 100644 --- a/src/ap/sta_info.c +++ b/src/ap/sta_info.c @@ -490,6 +490,18 @@ static void ap_handle_session_timer(void *eloop_ctx, void *timeout_ctx) } +void ap_sta_replenish_timeout(struct hostapd_data *hapd, struct sta_info *sta, + u32 session_timeout) +{ + if (eloop_replenish_timeout(session_timeout, 0, + ap_handle_session_timer, hapd, sta)) { + hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, + HOSTAPD_LEVEL_DEBUG, "setting session timeout " + "to %d seconds", session_timeout); + } +} + + void ap_sta_session_timeout(struct hostapd_data *hapd, struct sta_info *sta, u32 session_timeout) { diff --git a/src/ap/sta_info.h b/src/ap/sta_info.h index 197e46bc..dc742195 100644 --- a/src/ap/sta_info.h +++ b/src/ap/sta_info.h @@ -162,6 +162,8 @@ void ap_sta_hash_add(struct hostapd_data *hapd, struct sta_info *sta); void ap_free_sta(struct hostapd_data *hapd, struct sta_info *sta); void hostapd_free_stas(struct hostapd_data *hapd); void ap_handle_timer(void *eloop_ctx, void *timeout_ctx); +void ap_sta_replenish_timeout(struct hostapd_data *hapd, struct sta_info *sta, + u32 session_timeout); void ap_sta_session_timeout(struct hostapd_data *hapd, struct sta_info *sta, u32 session_timeout); void ap_sta_no_session_timeout(struct hostapd_data *hapd, diff --git a/src/ap/wps_hostapd.c b/src/ap/wps_hostapd.c index eb300f19..294a39d6 100644 --- a/src/ap/wps_hostapd.c +++ b/src/ap/wps_hostapd.c @@ -1211,6 +1211,7 @@ int hostapd_init_wps_complete(struct hostapd_data *hapd) static void hostapd_wps_nfc_clear(struct wps_context *wps) { #ifdef CONFIG_WPS_NFC + wpa_printf(MSG_DEBUG, "WPS: Clear NFC Tag context %p", wps); wps->ap_nfc_dev_pw_id = 0; wpabuf_free(wps->ap_nfc_dh_pubkey); wps->ap_nfc_dh_pubkey = NULL; @@ -1823,6 +1824,9 @@ int hostapd_wps_nfc_token_enable(struct hostapd_data *hapd) return -1; hostapd_wps_nfc_clear(wps); + wpa_printf(MSG_DEBUG, + "WPS: Enable NFC Tag (Dev Pw Id %u) for AP interface %s (context %p)", + hapd->conf->wps_nfc_dev_pw_id, hapd->conf->iface, wps); wps->ap_nfc_dev_pw_id = hapd->conf->wps_nfc_dev_pw_id; wps->ap_nfc_dh_pubkey = wpabuf_dup(hapd->conf->wps_nfc_dh_pubkey); wps->ap_nfc_dh_privkey = wpabuf_dup(hapd->conf->wps_nfc_dh_privkey); @@ -1849,6 +1853,8 @@ int hostapd_wps_nfc_token_enable(struct hostapd_data *hapd) void hostapd_wps_nfc_token_disable(struct hostapd_data *hapd) { + wpa_printf(MSG_DEBUG, "WPS: Disable NFC token for AP interface %s", + hapd->conf->iface); hostapd_wps_nfc_clear(hapd->wps); } diff --git a/src/common/ieee802_11_defs.h b/src/common/ieee802_11_defs.h index 8ce1bfb2..ca122d93 100644 --- a/src/common/ieee802_11_defs.h +++ b/src/common/ieee802_11_defs.h @@ -587,6 +587,17 @@ struct ieee80211_ht_operation { } STRUCT_PACKED; +struct ieee80211_obss_scan_parameters { + le16 scan_passive_dwell; + le16 scan_active_dwell; + le16 width_trigger_scan_interval; + le16 scan_passive_total_per_channel; + le16 scan_active_total_per_channel; + le16 channel_transition_delay_factor; + le16 scan_activity_threshold; +} STRUCT_PACKED; + + struct ieee80211_vht_capabilities { le32 vht_capabilities_info; struct { diff --git a/src/common/wpa_ctrl.h b/src/common/wpa_ctrl.h index 862f881b..2a4f3016 100644 --- a/src/common/wpa_ctrl.h +++ b/src/common/wpa_ctrl.h @@ -149,6 +149,7 @@ extern "C" { #define INTERWORKING_AP "INTERWORKING-AP " #define INTERWORKING_NO_MATCH "INTERWORKING-NO-MATCH " +#define INTERWORKING_ALREADY_CONNECTED "INTERWORKING-ALREADY-CONNECTED " #define GAS_RESPONSE_INFO "GAS-RESPONSE-INFO " diff --git a/src/drivers/driver_atheros.c b/src/drivers/driver_atheros.c index 2547a43d..7d301f79 100644 --- a/src/drivers/driver_atheros.c +++ b/src/drivers/driver_atheros.c @@ -354,19 +354,16 @@ atheros_set_ieee8021x(void *priv, struct wpa_bss_params *params) return atheros_set_privacy(drv, 0); } if (!params->wpa && !params->ieee802_1x) { - hostapd_logger(drv->hapd, NULL, HOSTAPD_MODULE_DRIVER, - HOSTAPD_LEVEL_WARNING, "No 802.1X or WPA enabled!"); + wpa_printf(MSG_WARNING, "No 802.1X or WPA enabled!"); return -1; } if (params->wpa && atheros_configure_wpa(drv, params) != 0) { - hostapd_logger(drv->hapd, NULL, HOSTAPD_MODULE_DRIVER, - HOSTAPD_LEVEL_WARNING, "Error configuring WPA state!"); + wpa_printf(MSG_WARNING, "Error configuring WPA state!"); return -1; } if (set80211param(priv, IEEE80211_PARAM_AUTHMODE, (params->wpa ? IEEE80211_AUTH_WPA : IEEE80211_AUTH_8021X))) { - hostapd_logger(drv->hapd, NULL, HOSTAPD_MODULE_DRIVER, - HOSTAPD_LEVEL_WARNING, "Error enabling WPA/802.1X!"); + wpa_printf(MSG_WARNING, "Error enabling WPA/802.1X!"); return -1; } diff --git a/src/drivers/driver_madwifi.c b/src/drivers/driver_madwifi.c index d3379270..09308347 100644 --- a/src/drivers/driver_madwifi.c +++ b/src/drivers/driver_madwifi.c @@ -322,19 +322,16 @@ madwifi_set_ieee8021x(void *priv, struct wpa_bss_params *params) IEEE80211_AUTH_AUTO); } if (!params->wpa && !params->ieee802_1x) { - hostapd_logger(drv->hapd, NULL, HOSTAPD_MODULE_DRIVER, - HOSTAPD_LEVEL_WARNING, "No 802.1X or WPA enabled!"); + wpa_printf(MSG_WARNING, "No 802.1X or WPA enabled!"); return -1; } if (params->wpa && madwifi_configure_wpa(drv, params) != 0) { - hostapd_logger(drv->hapd, NULL, HOSTAPD_MODULE_DRIVER, - HOSTAPD_LEVEL_WARNING, "Error configuring WPA state!"); + wpa_printf(MSG_WARNING, "Error configuring WPA state!"); return -1; } if (set80211param(priv, IEEE80211_PARAM_AUTHMODE, (params->wpa ? IEEE80211_AUTH_WPA : IEEE80211_AUTH_8021X))) { - hostapd_logger(drv->hapd, NULL, HOSTAPD_MODULE_DRIVER, - HOSTAPD_LEVEL_WARNING, "Error enabling WPA/802.1X!"); + wpa_printf(MSG_WARNING, "Error enabling WPA/802.1X!"); return -1; } diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c index c4273246..a1d81714 100644 --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c @@ -109,6 +109,17 @@ static void nl80211_handle_destroy(struct nl_handle *handle) #endif /* CONFIG_LIBNL20 */ +#ifdef ANDROID +/* system/core/libnl_2 does not include nl_socket_set_nonblocking() */ +static int android_nl_socket_set_nonblocking(struct nl_handle *handle) +{ + return fcntl(nl_socket_get_fd(handle), F_SETFL, O_NONBLOCK); +} +#undef nl_socket_set_nonblocking +#define nl_socket_set_nonblocking(h) android_nl_socket_set_nonblocking(h) +#endif /* ANDROID */ + + static struct nl_handle * nl_create_handle(struct nl_cb *cb, const char *dbg) { struct nl_handle *handle; diff --git a/src/p2p/p2p_build.c b/src/p2p/p2p_build.c index 3c819ff4..42c02326 100644 --- a/src/p2p/p2p_build.c +++ b/src/p2p/p2p_build.c @@ -258,6 +258,7 @@ void p2p_buf_add_group_id(struct wpabuf *buf, const u8 *dev_addr, wpabuf_put_data(buf, ssid, ssid_len); wpa_printf(MSG_DEBUG, "P2P: * P2P Group ID " MACSTR, MAC2STR(dev_addr)); + wpa_hexdump_ascii(MSG_DEBUG, "P2P: P2P Group ID SSID", ssid, ssid_len); } diff --git a/src/radius/radius_das.c b/src/radius/radius_das.c index 8e5988dd..418b1605 100644 --- a/src/radius/radius_das.c +++ b/src/radius/radius_das.c @@ -200,7 +200,8 @@ static void radius_das_receive(int sock, void *eloop_ctx, void *sock_ctx) (u8 *) &val, 4); if (res == 4) { u32 timestamp = ntohl(val); - if (abs(now.sec - timestamp) > das->time_window) { + if ((unsigned int) abs(now.sec - timestamp) > + das->time_window) { wpa_printf(MSG_DEBUG, "DAS: Unacceptable " "Event-Timestamp (%u; local time %u) in " "packet from %s:%d - drop", diff --git a/src/utils/eloop.c b/src/utils/eloop.c index 12aa1251..ddddcf17 100644 --- a/src/utils/eloop.c +++ b/src/utils/eloop.c @@ -599,6 +599,37 @@ int eloop_is_timeout_registered(eloop_timeout_handler handler, } +int eloop_replenish_timeout(unsigned int req_secs, unsigned int req_usecs, + eloop_timeout_handler handler, void *eloop_data, + void *user_data) +{ + struct os_time now, requested, remaining; + struct eloop_timeout *tmp; + + dl_list_for_each(tmp, &eloop.timeout, struct eloop_timeout, list) { + if (tmp->handler == handler && + tmp->eloop_data == eloop_data && + tmp->user_data == user_data) { + requested.sec = req_secs; + requested.usec = req_usecs; + os_get_time(&now); + os_time_sub(&tmp->time, &now, &remaining); + if (os_time_before(&remaining, &requested)) { + eloop_cancel_timeout(handler, eloop_data, + user_data); + eloop_register_timeout(requested.sec, + requested.usec, + handler, eloop_data, + user_data); + return 1; + } + } + } + + return 0; +} + + #ifndef CONFIG_NATIVE_WINDOWS static void eloop_handle_alarm(int sig) { diff --git a/src/utils/eloop.h b/src/utils/eloop.h index 0037c635..befb0703 100644 --- a/src/utils/eloop.h +++ b/src/utils/eloop.h @@ -223,6 +223,22 @@ int eloop_is_timeout_registered(eloop_timeout_handler handler, void *eloop_data, void *user_data); /** + * eloop_replenish_timeout - Replenish a timeout that is already registered + * @req_secs: Requested number of seconds to the timeout + * @req_usecs: Requested number of microseconds to the timeout + * @handler: Matching callback function + * @eloop_data: Matching eloop_data + * @user_data: Matching user_data + * Returns: 1 if the timeout is replenished, 0 if no change is made + * + * Find a registered matching <handler,eloop_data,user_data> timeout. If found, + * replenish the timeout if remaining time is less than the requested time. + */ +int eloop_replenish_timeout(unsigned int req_secs, unsigned int req_usecs, + eloop_timeout_handler handler, void *eloop_data, + void *user_data); + +/** * eloop_register_signal - Register handler for signals * @sig: Signal number (e.g., SIGHUP) * @handler: Callback function to be called when the signal is received diff --git a/src/utils/eloop_win.c b/src/utils/eloop_win.c index eda412f1..1f40530c 100644 --- a/src/utils/eloop_win.c +++ b/src/utils/eloop_win.c @@ -354,6 +354,37 @@ int eloop_is_timeout_registered(eloop_timeout_handler handler, } +int eloop_replenish_timeout(unsigned int req_secs, unsigned int req_usecs, + eloop_timeout_handler handler, void *eloop_data, + void *user_data) +{ + struct os_time now, requested, remaining; + struct eloop_timeout *tmp; + + dl_list_for_each(tmp, &eloop.timeout, struct eloop_timeout, list) { + if (tmp->handler == handler && + tmp->eloop_data == eloop_data && + tmp->user_data == user_data) { + requested.sec = req_secs; + requested.usec = req_usecs; + os_get_time(&now); + os_time_sub(&tmp->time, &now, &remaining); + if (os_time_before(&remaining, &requested)) { + eloop_cancel_timeout(handler, eloop_data, + user_data); + eloop_register_timeout(requested.sec, + requested.usec, + handler, eloop_data, + user_data); + return 1; + } + } + } + + return 0; +} + + /* TODO: replace with suitable signal handler */ #if 0 static void eloop_handle_signal(int sig) diff --git a/src/wps/wps_attr_build.c b/src/wps/wps_attr_build.c index 3be89453..b2327544 100644 --- a/src/wps/wps_attr_build.c +++ b/src/wps/wps_attr_build.c @@ -382,14 +382,20 @@ int wps_build_oob_dev_pw(struct wpabuf *msg, u16 dev_pw_id, const u8 *addr[1]; u8 pubkey_hash[WPS_HASH_LEN]; + wpa_printf(MSG_DEBUG, "WPS: * OOB Device Password (dev_pw_id=%u)", + dev_pw_id); addr[0] = wpabuf_head(pubkey); hash_len = wpabuf_len(pubkey); sha256_vector(1, addr, &hash_len, pubkey_hash); wpabuf_put_be16(msg, ATTR_OOB_DEVICE_PASSWORD); wpabuf_put_be16(msg, WPS_OOB_PUBKEY_HASH_LEN + 2 + dev_pw_len); + wpa_hexdump(MSG_DEBUG, "WPS: Public Key Hash", + pubkey_hash, WPS_OOB_PUBKEY_HASH_LEN); wpabuf_put_data(msg, pubkey_hash, WPS_OOB_PUBKEY_HASH_LEN); wpabuf_put_be16(msg, dev_pw_id); + wpa_hexdump_key(MSG_DEBUG, "WPS: OOB Device Password", + dev_pw, dev_pw_len); wpabuf_put_data(msg, dev_pw, dev_pw_len); return 0; diff --git a/src/wps/wps_registrar.c b/src/wps/wps_registrar.c index b7fcd9ce..7cb583cf 100644 --- a/src/wps/wps_registrar.c +++ b/src/wps/wps_registrar.c @@ -1379,7 +1379,8 @@ static int wps_get_dev_password(struct wps_data *wps) } if (pin == NULL) { wpa_printf(MSG_DEBUG, "WPS: No Device Password available for " - "the Enrollee"); + "the Enrollee (context %p registrar %p)", + wps->wps, wps->wps->registrar); wps_cb_pin_needed(wps->wps->registrar, wps->uuid_e, &wps->peer_dev); return -1; @@ -2541,6 +2542,8 @@ static enum wps_process_res wps_process_m1(struct wps_data *wps, const u8 *addr[1]; u8 hash[WPS_HASH_LEN]; + wpa_printf(MSG_DEBUG, "WPS: Searching for NFC token match for id=%d (ctx %p registrar %p)", + wps->dev_pw_id, wps->wps, wps->wps->registrar); token = wps_get_nfc_pw_token( &wps->wps->registrar->nfc_pw_tokens, wps->dev_pw_id); if (token) { diff --git a/wpa_supplicant/Android.mk b/wpa_supplicant/Android.mk index f480277e..373a344b 100644 --- a/wpa_supplicant/Android.mk +++ b/wpa_supplicant/Android.mk @@ -1175,7 +1175,10 @@ SHA1OBJS += src/crypto/sha1-tlsprf.c endif endif -MD5OBJS = src/crypto/md5.c +MD5OBJS = +ifndef CONFIG_FIPS +MD5OBJS += src/crypto/md5.c +endif ifdef NEED_MD5 ifdef CONFIG_INTERNAL_MD5 MD5OBJS += src/crypto/md5-internal.c diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c index 19bceceb..18082736 100644 --- a/wpa_supplicant/config.c +++ b/wpa_supplicant/config.c @@ -1321,6 +1321,52 @@ static char * wpa_config_write_wep_key3(const struct parse_data *data, #ifdef CONFIG_P2P +static int wpa_config_parse_go_p2p_dev_addr(const struct parse_data *data, + struct wpa_ssid *ssid, int line, + const char *value) +{ + if (value[0] == '\0' || os_strcmp(value, "\"\"") == 0 || + os_strcmp(value, "any") == 0) { + os_memset(ssid->go_p2p_dev_addr, 0, ETH_ALEN); + wpa_printf(MSG_MSGDUMP, "GO P2P Device Address any"); + return 0; + } + if (hwaddr_aton(value, ssid->go_p2p_dev_addr)) { + wpa_printf(MSG_ERROR, "Line %d: Invalid GO P2P Device Address '%s'.", + line, value); + return -1; + } + ssid->bssid_set = 1; + wpa_printf(MSG_MSGDUMP, "GO P2P Device Address " MACSTR, + MAC2STR(ssid->go_p2p_dev_addr)); + return 0; +} + + +#ifndef NO_CONFIG_WRITE +static char * wpa_config_write_go_p2p_dev_addr(const struct parse_data *data, + struct wpa_ssid *ssid) +{ + char *value; + int res; + + if (is_zero_ether_addr(ssid->go_p2p_dev_addr)) + return NULL; + + value = os_malloc(20); + if (value == NULL) + return NULL; + res = os_snprintf(value, 20, MACSTR, MAC2STR(ssid->go_p2p_dev_addr)); + if (res < 0 || res >= 20) { + os_free(value); + return NULL; + } + value[20 - 1] = '\0'; + return value; +} +#endif /* NO_CONFIG_WRITE */ + + static int wpa_config_parse_p2p_client_list(const struct parse_data *data, struct wpa_ssid *ssid, int line, const char *value) @@ -1632,6 +1678,7 @@ static const struct parse_data ssid_fields[] = { { STR(bgscan) }, { INT_RANGE(ignore_broadcast_ssid, 0, 2) }, #ifdef CONFIG_P2P + { FUNC(go_p2p_dev_addr) }, { FUNC(p2p_client_list) }, { FUNC(psk_list) }, #endif /* CONFIG_P2P */ diff --git a/wpa_supplicant/config_file.c b/wpa_supplicant/config_file.c index cb2dde8e..ed5cdfff 100644 --- a/wpa_supplicant/config_file.c +++ b/wpa_supplicant/config_file.c @@ -606,6 +606,15 @@ static void write_wep_key(FILE *f, int idx, struct wpa_ssid *ssid) #ifdef CONFIG_P2P +static void write_go_p2p_dev_addr(FILE *f, struct wpa_ssid *ssid) +{ + char *value = wpa_config_get(ssid, "go_p2p_dev_addr"); + if (value == NULL) + return; + fprintf(f, "\tgo_p2p_dev_addr=%s\n", value); + os_free(value); +} + static void write_p2p_client_list(FILE *f, struct wpa_ssid *ssid) { char *value = wpa_config_get(ssid, "p2p_client_list"); @@ -714,6 +723,7 @@ static void wpa_config_write_network(FILE *f, struct wpa_ssid *ssid) #endif /* CONFIG_IEEE80211W */ STR(id_str); #ifdef CONFIG_P2P + write_go_p2p_dev_addr(f, ssid); write_p2p_client_list(f, ssid); write_psk_list(f, ssid); #endif /* CONFIG_P2P */ diff --git a/wpa_supplicant/config_ssid.h b/wpa_supplicant/config_ssid.h index 3d008ca5..9c2cf66e 100644 --- a/wpa_supplicant/config_ssid.h +++ b/wpa_supplicant/config_ssid.h @@ -131,6 +131,11 @@ struct wpa_ssid { int bssid_set; /** + * go_p2p_dev_addr - GO's P2P Device Address or all zeros if not set + */ + u8 go_p2p_dev_addr[ETH_ALEN]; + + /** * psk - WPA pre-shared key (256 bits) */ u8 psk[32]; diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c index bffcd1a1..daabecba 100644 --- a/wpa_supplicant/events.c +++ b/wpa_supplicant/events.c @@ -869,6 +869,32 @@ static struct wpa_ssid * wpa_scan_res_match(struct wpa_supplicant *wpa_s, continue; } + if (!is_zero_ether_addr(ssid->go_p2p_dev_addr)) { + struct wpabuf *p2p_ie; + u8 dev_addr[ETH_ALEN]; + + ie = wpa_bss_get_vendor_ie(bss, P2P_IE_VENDOR_TYPE); + if (ie == NULL) { + wpa_dbg(wpa_s, MSG_DEBUG, " skip - no P2P element"); + continue; + } + p2p_ie = wpa_bss_get_vendor_ie_multi( + bss, P2P_IE_VENDOR_TYPE); + if (p2p_ie == NULL) { + wpa_dbg(wpa_s, MSG_DEBUG, " skip - could not fetch P2P element"); + continue; + } + + if (p2p_parse_dev_addr_in_p2p_ie(p2p_ie, dev_addr) < 0 + || os_memcmp(dev_addr, ssid->go_p2p_dev_addr, + ETH_ALEN) != 0) { + wpa_dbg(wpa_s, MSG_DEBUG, " skip - no matching GO P2P Device Address in P2P element"); + wpabuf_free(p2p_ie); + continue; + } + wpabuf_free(p2p_ie); + } + /* * TODO: skip the AP if its P2P IE has Group Formation * bit set in the P2P Group Capability Bitmap and we diff --git a/wpa_supplicant/interworking.c b/wpa_supplicant/interworking.c index 86672219..93652d8f 100644 --- a/wpa_supplicant/interworking.c +++ b/wpa_supplicant/interworking.c @@ -1,6 +1,6 @@ /* * Interworking (IEEE 802.11u) - * Copyright (c) 2011-2012, Qualcomm Atheros, Inc. + * Copyright (c) 2011-2013, Qualcomm Atheros, Inc. * * This software may be distributed under the terms of the BSD license. * See README for more details. @@ -19,6 +19,7 @@ #include "eap_peer/eap.h" #include "eap_peer/eap_methods.h" #include "eapol_supp/eapol_supp_sm.h" +#include "rsn_supp/wpa.h" #include "wpa_supplicant_i.h" #include "config.h" #include "config_ssid.h" @@ -750,6 +751,59 @@ static int set_root_nai(struct wpa_ssid *ssid, const char *imsi, char prefix) #endif /* INTERWORKING_3GPP */ +static int already_connected(struct wpa_supplicant *wpa_s, + struct wpa_cred *cred, struct wpa_bss *bss) +{ + struct wpa_ssid *ssid; + + if (wpa_s->wpa_state < WPA_ASSOCIATED || wpa_s->current_ssid == NULL) + return 0; + + ssid = wpa_s->current_ssid; + if (ssid->parent_cred != cred) + return 0; + + if (ssid->ssid_len != bss->ssid_len || + os_memcmp(ssid->ssid, bss->ssid, bss->ssid_len) != 0) + return 0; + + return 1; +} + + +static void remove_duplicate_network(struct wpa_supplicant *wpa_s, + struct wpa_cred *cred, + struct wpa_bss *bss) +{ + struct wpa_ssid *ssid; + + for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) { + if (ssid->parent_cred != cred) + continue; + if (ssid->ssid_len != bss->ssid_len || + os_memcmp(ssid->ssid, bss->ssid, bss->ssid_len) != 0) + continue; + + break; + } + + if (ssid == NULL) + return; + + wpa_printf(MSG_DEBUG, "Interworking: Remove duplicate network entry for the same credential"); + + if (ssid == wpa_s->current_ssid) { + wpa_sm_set_config(wpa_s->wpa, NULL); + eapol_sm_notify_config(wpa_s->eapol, NULL, NULL); + wpa_supplicant_deauthenticate(wpa_s, + WLAN_REASON_DEAUTH_LEAVING); + } + + wpas_notify_network_removed(wpa_s, ssid); + wpa_config_remove_network(wpa_s->conf, ssid->id); +} + + static int interworking_set_hs20_params(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid) { @@ -771,7 +825,6 @@ static int interworking_connect_3gpp(struct wpa_supplicant *wpa_s, { #ifdef INTERWORKING_3GPP struct wpa_ssid *ssid; - const u8 *ie; int eap_type; int res; char prefix; @@ -779,12 +832,17 @@ static int interworking_connect_3gpp(struct wpa_supplicant *wpa_s, if (bss->anqp == NULL || bss->anqp->anqp_3gpp == NULL) return -1; - ie = wpa_bss_get_ie(bss, WLAN_EID_SSID); - if (ie == NULL) - return -1; wpa_printf(MSG_DEBUG, "Interworking: Connect with " MACSTR " (3GPP)", MAC2STR(bss->bssid)); + if (already_connected(wpa_s, cred, bss)) { + wpa_msg(wpa_s, MSG_INFO, INTERWORKING_ALREADY_CONNECTED MACSTR, + MAC2STR(bss->bssid)); + return 0; + } + + remove_duplicate_network(wpa_s, cred, bss); + ssid = wpa_config_add_network(wpa_s->conf); if (ssid == NULL) return -1; @@ -794,11 +852,11 @@ static int interworking_connect_3gpp(struct wpa_supplicant *wpa_s, wpa_config_set_network_defaults(ssid); ssid->priority = cred->priority; ssid->temporary = 1; - ssid->ssid = os_zalloc(ie[1] + 1); + ssid->ssid = os_zalloc(bss->ssid_len + 1); if (ssid->ssid == NULL) goto fail; - os_memcpy(ssid->ssid, ie + 2, ie[1]); - ssid->ssid_len = ie[1]; + os_memcpy(ssid->ssid, bss->ssid, bss->ssid_len); + ssid->ssid_len = bss->ssid_len; if (interworking_set_hs20_params(wpa_s, ssid) < 0) goto fail; @@ -1137,13 +1195,21 @@ static int interworking_set_eap_params(struct wpa_ssid *ssid, static int interworking_connect_roaming_consortium( struct wpa_supplicant *wpa_s, struct wpa_cred *cred, - struct wpa_bss *bss, const u8 *ssid_ie) + struct wpa_bss *bss) { struct wpa_ssid *ssid; wpa_printf(MSG_DEBUG, "Interworking: Connect with " MACSTR " based on " "roaming consortium match", MAC2STR(bss->bssid)); + if (already_connected(wpa_s, cred, bss)) { + wpa_msg(wpa_s, MSG_INFO, INTERWORKING_ALREADY_CONNECTED MACSTR, + MAC2STR(bss->bssid)); + return 0; + } + + remove_duplicate_network(wpa_s, cred, bss); + ssid = wpa_config_add_network(wpa_s->conf); if (ssid == NULL) return -1; @@ -1152,11 +1218,11 @@ static int interworking_connect_roaming_consortium( wpa_config_set_network_defaults(ssid); ssid->priority = cred->priority; ssid->temporary = 1; - ssid->ssid = os_zalloc(ssid_ie[1] + 1); + ssid->ssid = os_zalloc(bss->ssid_len + 1); if (ssid->ssid == NULL) goto fail; - os_memcpy(ssid->ssid, ssid_ie + 2, ssid_ie[1]); - ssid->ssid_len = ssid_ie[1]; + os_memcpy(ssid->ssid, bss->ssid, bss->ssid_len); + ssid->ssid_len = bss->ssid_len; if (interworking_set_hs20_params(wpa_s, ssid) < 0) goto fail; @@ -1193,13 +1259,12 @@ int interworking_connect(struct wpa_supplicant *wpa_s, struct wpa_bss *bss) struct nai_realm_eap *eap = NULL; u16 count, i; char buf[100]; - const u8 *ie; if (wpa_s->conf->cred == NULL || bss == NULL) return -1; - ie = wpa_bss_get_ie(bss, WLAN_EID_SSID); - if (ie == NULL || ie[1] == 0) { - wpa_printf(MSG_DEBUG, "Interworking: No SSID known for " + if (disallowed_bssid(wpa_s, bss->bssid) || + disallowed_ssid(wpa_s, bss->ssid, bss->ssid_len)) { + wpa_printf(MSG_DEBUG, "Interworking: Reject connection to disallowed BSS " MACSTR, MAC2STR(bss->bssid)); return -1; } @@ -1239,7 +1304,7 @@ int interworking_connect(struct wpa_supplicant *wpa_s, struct wpa_bss *bss) (cred == NULL || cred_rc->priority >= cred->priority) && (cred_3gpp == NULL || cred_rc->priority >= cred_3gpp->priority)) return interworking_connect_roaming_consortium(wpa_s, cred_rc, - bss, ie); + bss); if (cred_3gpp && (cred == NULL || cred_3gpp->priority >= cred->priority)) { @@ -1279,6 +1344,15 @@ int interworking_connect(struct wpa_supplicant *wpa_s, struct wpa_bss *bss) wpa_printf(MSG_DEBUG, "Interworking: Connect with " MACSTR, MAC2STR(bss->bssid)); + if (already_connected(wpa_s, cred, bss)) { + wpa_msg(wpa_s, MSG_INFO, INTERWORKING_ALREADY_CONNECTED MACSTR, + MAC2STR(bss->bssid)); + nai_realm_free(realm, count); + return 0; + } + + remove_duplicate_network(wpa_s, cred, bss); + ssid = wpa_config_add_network(wpa_s->conf); if (ssid == NULL) { nai_realm_free(realm, count); @@ -1289,11 +1363,11 @@ int interworking_connect(struct wpa_supplicant *wpa_s, struct wpa_bss *bss) wpa_config_set_network_defaults(ssid); ssid->priority = cred->priority; ssid->temporary = 1; - ssid->ssid = os_zalloc(ie[1] + 1); + ssid->ssid = os_zalloc(bss->ssid_len + 1); if (ssid->ssid == NULL) goto fail; - os_memcpy(ssid->ssid, ie + 2, ie[1]); - ssid->ssid_len = ie[1]; + os_memcpy(ssid->ssid, bss->ssid, bss->ssid_len); + ssid->ssid_len = bss->ssid_len; if (interworking_set_hs20_params(wpa_s, ssid) < 0) goto fail; @@ -1518,6 +1592,13 @@ static struct wpa_cred * interworking_credentials_available( { struct wpa_cred *cred, *cred2; + if (disallowed_bssid(wpa_s, bss->bssid) || + disallowed_ssid(wpa_s, bss->ssid, bss->ssid_len)) { + wpa_printf(MSG_DEBUG, "Interworking: Ignore disallowed BSS " + MACSTR, MAC2STR(bss->bssid)); + return NULL; + } + cred = interworking_credentials_available_realm(wpa_s, bss); cred2 = interworking_credentials_available_3gpp(wpa_s, bss); if (cred && cred2 && cred2->priority >= cred->priority) @@ -1804,6 +1885,9 @@ static void interworking_next_anqp_fetch(struct wpa_supplicant *wpa_s) ie = wpa_bss_get_ie(bss, WLAN_EID_EXT_CAPAB); if (ie == NULL || ie[1] < 4 || !(ie[5] & 0x80)) continue; /* AP does not support Interworking */ + if (disallowed_bssid(wpa_s, bss->bssid) || + disallowed_ssid(wpa_s, bss->ssid, bss->ssid_len)) + continue; /* Disallowed BSS */ if (!(bss->flags & WPA_BSS_ANQP_FETCH_TRIED)) { if (bss->anqp == NULL) { |