aboutsummaryrefslogtreecommitdiffstats
path: root/wpa_supplicant
diff options
context:
space:
mode:
Diffstat (limited to 'wpa_supplicant')
-rw-r--r--wpa_supplicant/Android.mk17
-rw-r--r--wpa_supplicant/Makefile17
-rw-r--r--wpa_supplicant/ctrl_iface.c17
-rw-r--r--wpa_supplicant/driver_i.h7
-rw-r--r--wpa_supplicant/events.c97
-rw-r--r--wpa_supplicant/p2p_supplicant.h1
-rw-r--r--wpa_supplicant/p2p_supplicant_sd.c45
-rw-r--r--wpa_supplicant/scan.c24
-rw-r--r--wpa_supplicant/wpa_supplicant.c9
-rw-r--r--wpa_supplicant/wpa_supplicant_i.h1
10 files changed, 174 insertions, 61 deletions
diff --git a/wpa_supplicant/Android.mk b/wpa_supplicant/Android.mk
index 6d396131..5ce8da1c 100644
--- a/wpa_supplicant/Android.mk
+++ b/wpa_supplicant/Android.mk
@@ -375,7 +375,7 @@ endif
ifdef CONFIG_EAP_UNAUTH_TLS
# EAP-UNAUTH-TLS
L_CFLAGS += -DEAP_UNAUTH_TLS
-ifndef CONFIG_EAP_UNAUTH_TLS
+ifndef CONFIG_EAP_TLS
OBJS += src/eap_peer/eap_tls.c
OBJS_h += src/eap_server/eap_server_tls.c
TLS_FUNCS=y
@@ -996,21 +996,6 @@ CONFIG_INTERNAL_RC4=y
CONFIG_INTERNAL_DH_GROUP5=y
endif
-ifeq ($(CONFIG_TLS), schannel)
-ifdef TLS_FUNCS
-OBJS += src/crypto/tls_schannel.c
-endif
-OBJS += src/crypto/crypto_cryptoapi.c
-OBJS_p += src/crypto/crypto_cryptoapi.c
-ifdef NEED_FIPS186_2_PRF
-OBJS += src/crypto/fips_prf_internal.c
-OBJS += src/crypto/sha1-internal.c
-endif
-CONFIG_INTERNAL_SHA256=y
-CONFIG_INTERNAL_RC4=y
-CONFIG_INTERNAL_DH_GROUP5=y
-endif
-
ifeq ($(CONFIG_TLS), internal)
ifndef CONFIG_CRYPTO
CONFIG_CRYPTO=internal
diff --git a/wpa_supplicant/Makefile b/wpa_supplicant/Makefile
index 976b984b..d086eeb6 100644
--- a/wpa_supplicant/Makefile
+++ b/wpa_supplicant/Makefile
@@ -379,7 +379,7 @@ endif
ifdef CONFIG_EAP_UNAUTH_TLS
# EAP-UNAUTH-TLS
CFLAGS += -DEAP_UNAUTH_TLS
-ifndef CONFIG_EAP_UNAUTH_TLS
+ifndef CONFIG_EAP_TLS
OBJS += ../src/eap_peer/eap_tls.o
OBJS_h += ../src/eap_server/eap_server_tls.o
TLS_FUNCS=y
@@ -1013,21 +1013,6 @@ CONFIG_INTERNAL_RC4=y
CONFIG_INTERNAL_DH_GROUP5=y
endif
-ifeq ($(CONFIG_TLS), schannel)
-ifdef TLS_FUNCS
-OBJS += ../src/crypto/tls_schannel.o
-endif
-OBJS += ../src/crypto/crypto_cryptoapi.o
-OBJS_p += ../src/crypto/crypto_cryptoapi.o
-ifdef NEED_FIPS186_2_PRF
-OBJS += ../src/crypto/fips_prf_internal.o
-SHA1OBJS += ../src/crypto/sha1-internal.o
-endif
-CONFIG_INTERNAL_SHA256=y
-CONFIG_INTERNAL_RC4=y
-CONFIG_INTERNAL_DH_GROUP5=y
-endif
-
ifeq ($(CONFIG_TLS), internal)
ifndef CONFIG_CRYPTO
CONFIG_CRYPTO=internal
diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c
index 4ebc3a14..53d2d015 100644
--- a/wpa_supplicant/ctrl_iface.c
+++ b/wpa_supplicant/ctrl_iface.c
@@ -5299,6 +5299,11 @@ static int p2p_ctrl_service_del_asp(struct wpa_supplicant *wpa_s, char *cmd)
{
u32 adv_id;
+ if (os_strcmp(cmd, "all") == 0) {
+ wpas_p2p_service_flush_asp(wpa_s);
+ return 0;
+ }
+
if (sscanf(cmd, "%x", &adv_id) != 1)
return -1;
@@ -6697,6 +6702,8 @@ static void wpa_supplicant_ctrl_iface_flush(struct wpa_supplicant *wpa_s)
MAC2STR(wpa_s->bssid),
MAC2STR(wpa_s->pending_bssid));
}
+
+ eloop_cancel_timeout(wpas_network_reenabled, wpa_s, NULL);
}
@@ -6943,6 +6950,15 @@ static void wpas_ctrl_scan(struct wpa_supplicant *wpa_s, char *params,
return;
}
+#ifdef CONFIG_INTERWORKING
+ if (wpa_s->fetch_anqp_in_progress || wpa_s->network_select) {
+ wpa_printf(MSG_DEBUG,
+ "Interworking select in progress - reject new scan");
+ *reply_len = os_snprintf(reply, reply_size, "FAIL-BUSY\n");
+ return;
+ }
+#endif /* CONFIG_INTERWORKING */
+
if (params) {
if (os_strncasecmp(params, "TYPE=ONLY", 9) == 0)
scan_only = 1;
@@ -8248,6 +8264,7 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
wpa_supplicant_cancel_scan(wpa_s);
wpa_supplicant_deauthenticate(wpa_s,
WLAN_REASON_DEAUTH_LEAVING);
+ eloop_cancel_timeout(wpas_network_reenabled, wpa_s, NULL);
} else if (os_strcmp(buf, "SCAN") == 0) {
wpas_ctrl_scan(wpa_s, NULL, reply, reply_size, &reply_len);
} else if (os_strncmp(buf, "SCAN ", 5) == 0) {
diff --git a/wpa_supplicant/driver_i.h b/wpa_supplicant/driver_i.h
index 65b430d4..ffee1f7d 100644
--- a/wpa_supplicant/driver_i.h
+++ b/wpa_supplicant/driver_i.h
@@ -503,13 +503,6 @@ static inline int wpa_drv_set_ap_wps_ie(struct wpa_supplicant *wpa_s,
proberesp, assocresp);
}
-static inline int wpa_drv_shared_freq(struct wpa_supplicant *wpa_s)
-{
- if (!wpa_s->driver->shared_freq)
- return -1;
- return wpa_s->driver->shared_freq(wpa_s->drv_priv);
-}
-
static inline int wpa_drv_get_noa(struct wpa_supplicant *wpa_s,
u8 *buf, size_t buf_len)
{
diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index 1f55e0fd..6ed2549a 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -71,6 +71,59 @@ static int wpas_temp_disabled(struct wpa_supplicant *wpa_s,
}
+/**
+ * wpas_reenabled_network_time - Time until first network is re-enabled
+ * @wpa_s: Pointer to wpa_supplicant data
+ * Returns: If all enabled networks are temporarily disabled, returns the time
+ * (in sec) until the first network is re-enabled. Otherwise returns 0.
+ *
+ * This function is used in case all enabled networks are temporarily disabled,
+ * in which case it returns the time (in sec) that the first network will be
+ * re-enabled. The function assumes that at least one network is enabled.
+ */
+static int wpas_reenabled_network_time(struct wpa_supplicant *wpa_s)
+{
+ struct wpa_ssid *ssid;
+ int disabled_for, res = 0;
+
+#ifdef CONFIG_INTERWORKING
+ if (wpa_s->conf->auto_interworking && wpa_s->conf->interworking &&
+ wpa_s->conf->cred)
+ return 0;
+#endif /* CONFIG_INTERWORKING */
+
+ for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
+ if (ssid->disabled)
+ continue;
+
+ disabled_for = wpas_temp_disabled(wpa_s, ssid);
+ if (!disabled_for)
+ return 0;
+
+ if (!res || disabled_for < res)
+ res = disabled_for;
+ }
+
+ return res;
+}
+
+
+void wpas_network_reenabled(void *eloop_ctx, void *timeout_ctx)
+{
+ struct wpa_supplicant *wpa_s = eloop_ctx;
+
+ if (wpa_s->disconnected || wpa_s->wpa_state != WPA_SCANNING)
+ return;
+
+ wpa_dbg(wpa_s, MSG_DEBUG,
+ "Try to associate due to network getting re-enabled");
+ if (wpa_supplicant_fast_associate(wpa_s) != 1) {
+ wpa_supplicant_cancel_sched_scan(wpa_s);
+ wpa_supplicant_req_scan(wpa_s, 0, 0);
+ }
+}
+
+
static struct wpa_bss * wpa_supplicant_get_new_bss(
struct wpa_supplicant *wpa_s, const u8 *bssid)
{
@@ -105,11 +158,32 @@ static void wpa_supplicant_update_current_bss(struct wpa_supplicant *wpa_s)
static int wpa_supplicant_select_config(struct wpa_supplicant *wpa_s)
{
struct wpa_ssid *ssid, *old_ssid;
+ u8 drv_ssid[MAX_SSID_LEN];
+ size_t drv_ssid_len;
int res;
if (wpa_s->conf->ap_scan == 1 && wpa_s->current_ssid) {
wpa_supplicant_update_current_bss(wpa_s);
- return 0;
+
+ if (wpa_s->current_ssid->ssid_len == 0)
+ return 0; /* current profile still in use */
+ res = wpa_drv_get_ssid(wpa_s, drv_ssid);
+ if (res < 0) {
+ wpa_msg(wpa_s, MSG_INFO,
+ "Failed to read SSID from driver");
+ return 0; /* try to use current profile */
+ }
+ drv_ssid_len = res;
+
+ if (drv_ssid_len == wpa_s->current_ssid->ssid_len &&
+ os_memcmp(drv_ssid, wpa_s->current_ssid->ssid,
+ drv_ssid_len) == 0)
+ return 0; /* current profile still in use */
+
+ wpa_msg(wpa_s, MSG_DEBUG,
+ "Driver-initiated BSS selection changed the SSID to %s",
+ wpa_ssid_txt(drv_ssid, drv_ssid_len));
+ /* continue selecting a new network profile */
}
wpa_dbg(wpa_s, MSG_DEBUG, "Select network based on association "
@@ -1421,6 +1495,17 @@ static int wpas_select_network_from_last_scan(struct wpa_supplicant *wpa_s,
{
struct wpa_bss *selected;
struct wpa_ssid *ssid = NULL;
+ int time_to_reenable = wpas_reenabled_network_time(wpa_s);
+
+ if (time_to_reenable > 0) {
+ wpa_dbg(wpa_s, MSG_DEBUG,
+ "Postpone network selection by %d seconds since all networks are disabled",
+ time_to_reenable);
+ eloop_cancel_timeout(wpas_network_reenabled, wpa_s, NULL);
+ eloop_register_timeout(time_to_reenable, 0,
+ wpas_network_reenabled, wpa_s, NULL);
+ return 0;
+ }
if (wpa_s->p2p_mgmt)
return 0; /* no normal connection on p2p_mgmt interface */
@@ -1946,6 +2031,8 @@ static void wpa_supplicant_event_assoc(struct wpa_supplicant *wpa_s,
}
#endif /* CONFIG_AP */
+ eloop_cancel_timeout(wpas_network_reenabled, wpa_s, NULL);
+
ft_completed = wpa_ft_is_completed(wpa_s->wpa);
if (data && wpa_supplicant_event_associnfo(wpa_s, data) < 0)
return;
@@ -2868,6 +2955,14 @@ static void wpa_supplicant_update_channel_list(
ifs, &ifs->hw.num_modes, &ifs->hw.flags);
}
}
+
+ /* Restart sched_scan with updated channel list */
+ if (wpa_s->sched_scanning) {
+ wpa_dbg(wpa_s, MSG_DEBUG,
+ "Channel list changed restart sched scan.");
+ wpa_supplicant_cancel_sched_scan(wpa_s);
+ wpa_supplicant_req_scan(wpa_s, 0, 0);
+ }
}
diff --git a/wpa_supplicant/p2p_supplicant.h b/wpa_supplicant/p2p_supplicant.h
index 1d3c67b7..0b9ebc0b 100644
--- a/wpa_supplicant/p2p_supplicant.h
+++ b/wpa_supplicant/p2p_supplicant.h
@@ -93,6 +93,7 @@ int wpas_p2p_service_add_asp(struct wpa_supplicant *wpa_s, int auto_accept,
u32 adv_id, const char *adv_str, u8 svc_state,
u16 config_methods, const char *svc_info);
int wpas_p2p_service_del_asp(struct wpa_supplicant *wpa_s, u32 adv_id);
+void wpas_p2p_service_flush_asp(struct wpa_supplicant *wpa_s);
int wpas_p2p_service_p2ps_id_exists(struct wpa_supplicant *wpa_s, u32 adv_id);
void wpas_sd_request(void *ctx, int freq, const u8 *sa, u8 dialog_token,
u16 update_indic, const u8 *tlvs, size_t tlvs_len);
diff --git a/wpa_supplicant/p2p_supplicant_sd.c b/wpa_supplicant/p2p_supplicant_sd.c
index cb68c03b..f4aa3e03 100644
--- a/wpa_supplicant/p2p_supplicant_sd.c
+++ b/wpa_supplicant/p2p_supplicant_sd.c
@@ -671,6 +671,21 @@ static void wpas_sd_req_asp(struct wpa_supplicant *wpa_s,
}
+static void wpas_sd_all_asp(struct wpa_supplicant *wpa_s,
+ struct wpabuf *resp, u8 srv_trans_id)
+{
+ /* Query data to add all P2PS advertisements:
+ * - Service name length: 1
+ * - Service name: '*'
+ * - Service Information Request Length: 0
+ */
+ const u8 q[] = { 1, (const u8) '*', 0 };
+
+ if (p2p_get_p2ps_adv_list(wpa_s->global->p2p))
+ wpas_sd_req_asp(wpa_s, resp, srv_trans_id, q, sizeof(q));
+}
+
+
void wpas_sd_request(void *ctx, int freq, const u8 *sa, u8 dialog_token,
u16 update_indic, const u8 *tlvs, size_t tlvs_len)
{
@@ -735,6 +750,7 @@ void wpas_sd_request(void *ctx, int freq, const u8 *sa, u8 dialog_token,
"response");
wpas_sd_all_bonjour(wpa_s, resp, srv_trans_id);
wpas_sd_all_upnp(wpa_s, resp, srv_trans_id);
+ wpas_sd_all_asp(wpa_s, resp, srv_trans_id);
goto done;
}
@@ -743,7 +759,8 @@ void wpas_sd_request(void *ctx, int freq, const u8 *sa, u8 dialog_token,
wpa_printf(MSG_DEBUG, "P2P: Service Discovery Request "
"for all services");
if (dl_list_empty(&wpa_s->global->p2p_srv_upnp) &&
- dl_list_empty(&wpa_s->global->p2p_srv_bonjour)) {
+ dl_list_empty(&wpa_s->global->p2p_srv_bonjour) &&
+ !p2p_get_p2ps_adv_list(wpa_s->global->p2p)) {
wpa_printf(MSG_DEBUG, "P2P: No service "
"discovery protocols available");
wpas_sd_add_proto_not_avail(
@@ -753,6 +770,7 @@ void wpas_sd_request(void *ctx, int freq, const u8 *sa, u8 dialog_token,
}
wpas_sd_all_bonjour(wpa_s, resp, srv_trans_id);
wpas_sd_all_upnp(wpa_s, resp, srv_trans_id);
+ wpas_sd_all_asp(wpa_s, resp, srv_trans_id);
break;
case P2P_SERV_BONJOUR:
wpas_sd_req_bonjour(wpa_s, resp, srv_trans_id,
@@ -1136,6 +1154,7 @@ void wpas_p2p_service_flush(struct wpa_supplicant *wpa_s)
struct p2p_srv_upnp, list)
wpas_p2p_srv_upnp_free(usrv);
+ wpas_p2p_service_flush_asp(wpa_s);
wpas_p2p_sd_service_update(wpa_s);
}
@@ -1154,7 +1173,12 @@ int wpas_p2p_service_p2ps_id_exists(struct wpa_supplicant *wpa_s, u32 adv_id)
int wpas_p2p_service_del_asp(struct wpa_supplicant *wpa_s, u32 adv_id)
{
- return p2p_service_del_asp(wpa_s->global->p2p, adv_id);
+ int ret;
+
+ ret = p2p_service_del_asp(wpa_s->global->p2p, adv_id);
+ if (ret == 0)
+ wpas_p2p_sd_service_update(wpa_s);
+ return ret;
}
@@ -1163,9 +1187,20 @@ int wpas_p2p_service_add_asp(struct wpa_supplicant *wpa_s,
const char *adv_str, u8 svc_state,
u16 config_methods, const char *svc_info)
{
- return p2p_service_add_asp(wpa_s->global->p2p, auto_accept, adv_id,
- adv_str, svc_state, config_methods,
- svc_info);
+ int ret;
+
+ ret = p2p_service_add_asp(wpa_s->global->p2p, auto_accept, adv_id,
+ adv_str, svc_state, config_methods,
+ svc_info);
+ if (ret == 0)
+ wpas_p2p_sd_service_update(wpa_s);
+ return ret;
+}
+
+
+void wpas_p2p_service_flush_asp(struct wpa_supplicant *wpa_s)
+{
+ p2p_service_flush_asp(wpa_s->global->p2p);
}
diff --git a/wpa_supplicant/scan.c b/wpa_supplicant/scan.c
index 805891a8..3c6b2c7f 100644
--- a/wpa_supplicant/scan.c
+++ b/wpa_supplicant/scan.c
@@ -418,22 +418,6 @@ static void wpa_supplicant_optimize_freqs(
static void wpas_add_interworking_elements(struct wpa_supplicant *wpa_s,
struct wpabuf *buf)
{
- if (wpa_s->conf->interworking == 0)
- return;
-
- wpabuf_put_u8(buf, WLAN_EID_EXT_CAPAB);
- wpabuf_put_u8(buf, 6);
- wpabuf_put_u8(buf, 0x00);
- wpabuf_put_u8(buf, 0x00);
- wpabuf_put_u8(buf, 0x00);
- wpabuf_put_u8(buf, 0x80); /* Bit 31 - Interworking */
- wpabuf_put_u8(buf, 0x00);
-#ifdef CONFIG_HS20
- wpabuf_put_u8(buf, 0x40); /* Bit 46 - WNM-Notification */
-#else /* CONFIG_HS20 */
- wpabuf_put_u8(buf, 0x00);
-#endif /* CONFIG_HS20 */
-
wpabuf_put_u8(buf, WLAN_EID_INTERWORKING);
wpabuf_put_u8(buf, is_zero_ether_addr(wpa_s->conf->hessid) ? 1 :
1 + ETH_ALEN);
@@ -448,11 +432,19 @@ static void wpas_add_interworking_elements(struct wpa_supplicant *wpa_s,
static struct wpabuf * wpa_supplicant_extra_ies(struct wpa_supplicant *wpa_s)
{
struct wpabuf *extra_ie = NULL;
+ u8 ext_capab[18];
+ int ext_capab_len;
#ifdef CONFIG_WPS
int wps = 0;
enum wps_request_type req_type = WPS_REQ_ENROLLEE_INFO;
#endif /* CONFIG_WPS */
+ ext_capab_len = wpas_build_ext_capab(wpa_s, ext_capab,
+ sizeof(ext_capab));
+ if (ext_capab_len > 0 &&
+ wpabuf_resize(&extra_ie, ext_capab_len) == 0)
+ wpabuf_put_data(extra_ie, ext_capab, ext_capab_len);
+
#ifdef CONFIG_INTERWORKING
if (wpa_s->conf->interworking &&
wpabuf_resize(&extra_ie, 100) == 0)
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index 19fb8900..6f5fbada 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -456,6 +456,8 @@ static void wpa_supplicant_cleanup(struct wpa_supplicant *wpa_s)
wpa_s, NULL);
#endif /* CONFIG_DELAYED_MIC_ERROR_REPORT */
+ eloop_cancel_timeout(wpas_network_reenabled, wpa_s, NULL);
+
wpas_wps_deinit(wpa_s);
wpabuf_free(wpa_s->pending_eapol_rx);
@@ -2625,6 +2627,13 @@ void wpa_supplicant_select_network(struct wpa_supplicant *wpa_s,
eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
wpa_s->connect_without_scan =
(ssid->mode == WPAS_MODE_MESH) ? ssid : NULL;
+
+ /*
+ * Don't optimize next scan freqs since a new ESS has been
+ * selected.
+ */
+ os_free(wpa_s->next_scan_freqs);
+ wpa_s->next_scan_freqs = NULL;
} else {
wpa_s->connect_without_scan = NULL;
}
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
index 26ff216b..0ec102f1 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -1140,4 +1140,5 @@ int get_shared_radio_freqs_data(struct wpa_supplicant *wpa_s,
int get_shared_radio_freqs(struct wpa_supplicant *wpa_s,
int *freq_array, unsigned int len);
+void wpas_network_reenabled(void *eloop_ctx, void *timeout_ctx);
#endif /* WPA_SUPPLICANT_I_H */