Cumulative patch from commit 7b42862ac87f333b0efb0f0bae822dcdf606bc69
7b42862 P2P: Validate GO operating channel on channel list changes
fb2ac53 Remove leftover timeouts on cleanup
1c330a2 Add 'dup_network <id_s> <id_d> <name>' command
316f92c dbus: Reorder deauthentication and cleanup calls when removing a network
Change-Id: I7283a61ed5044c884a728fe0b75199dac8552599
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c
index 14664df..9970597 100644
--- a/wpa_supplicant/ctrl_iface.c
+++ b/wpa_supplicant/ctrl_iface.c
@@ -2495,6 +2495,39 @@
}
+static int wpa_supplicant_ctrl_iface_update_network(
+ struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
+ char *name, char *value)
+{
+ if (wpa_config_set(ssid, name, value, 0) < 0) {
+ wpa_printf(MSG_DEBUG, "CTRL_IFACE: Failed to set network "
+ "variable '%s'", name);
+ return -1;
+ }
+
+ if (os_strcmp(name, "bssid") != 0 &&
+ os_strcmp(name, "priority") != 0)
+ wpa_sm_pmksa_cache_flush(wpa_s->wpa, ssid);
+
+ if (wpa_s->current_ssid == ssid || wpa_s->current_ssid == NULL) {
+ /*
+ * Invalidate the EAP session cache if anything in the current
+ * or previously used configuration changes.
+ */
+ eapol_sm_invalidate_cached_session(wpa_s->eapol);
+ }
+
+ if ((os_strcmp(name, "psk") == 0 &&
+ value[0] == '"' && ssid->ssid_len) ||
+ (os_strcmp(name, "ssid") == 0 && ssid->passphrase))
+ wpa_config_update_psk(ssid);
+ else if (os_strcmp(name, "priority") == 0)
+ wpa_config_update_prio_list(wpa_s->conf);
+
+ return 0;
+}
+
+
static int wpa_supplicant_ctrl_iface_set_network(
struct wpa_supplicant *wpa_s, char *cmd)
{
@@ -2526,32 +2559,8 @@
return -1;
}
- if (wpa_config_set(ssid, name, value, 0) < 0) {
- wpa_printf(MSG_DEBUG, "CTRL_IFACE: Failed to set network "
- "variable '%s'", name);
- return -1;
- }
-
- if (os_strcmp(name, "bssid") != 0 &&
- os_strcmp(name, "priority") != 0)
- wpa_sm_pmksa_cache_flush(wpa_s->wpa, ssid);
-
- if (wpa_s->current_ssid == ssid || wpa_s->current_ssid == NULL) {
- /*
- * Invalidate the EAP session cache if anything in the current
- * or previously used configuration changes.
- */
- eapol_sm_invalidate_cached_session(wpa_s->eapol);
- }
-
- if ((os_strcmp(name, "psk") == 0 &&
- value[0] == '"' && ssid->ssid_len) ||
- (os_strcmp(name, "ssid") == 0 && ssid->passphrase))
- wpa_config_update_psk(ssid);
- else if (os_strcmp(name, "priority") == 0)
- wpa_config_update_prio_list(wpa_s->conf);
-
- return 0;
+ return wpa_supplicant_ctrl_iface_update_network(wpa_s, ssid, name,
+ value);
}
@@ -2599,6 +2608,59 @@
}
+static int wpa_supplicant_ctrl_iface_dup_network(
+ struct wpa_supplicant *wpa_s, char *cmd)
+{
+ struct wpa_ssid *ssid_s, *ssid_d;
+ char *name, *id, *value;
+ int id_s, id_d, ret;
+
+ /* cmd: "<src network id> <dst network id> <variable name>" */
+ id = os_strchr(cmd, ' ');
+ if (id == NULL)
+ return -1;
+ *id++ = '\0';
+
+ name = os_strchr(id, ' ');
+ if (name == NULL)
+ return -1;
+ *name++ = '\0';
+
+ id_s = atoi(cmd);
+ id_d = atoi(id);
+ wpa_printf(MSG_DEBUG, "CTRL_IFACE: DUP_NETWORK id=%d -> %d name='%s'",
+ id_s, id_d, name);
+
+ ssid_s = wpa_config_get_network(wpa_s->conf, id_s);
+ if (ssid_s == NULL) {
+ wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find "
+ "network id=%d", id_s);
+ return -1;
+ }
+
+ ssid_d = wpa_config_get_network(wpa_s->conf, id_d);
+ if (ssid_d == NULL) {
+ wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find "
+ "network id=%d", id_s);
+ return -1;
+ }
+
+ value = wpa_config_get(ssid_s, name);
+ if (value == NULL) {
+ wpa_printf(MSG_DEBUG, "CTRL_IFACE: Failed to get network "
+ "variable '%s'", name);
+ return -1;
+ }
+
+ ret = wpa_supplicant_ctrl_iface_update_network(wpa_s, ssid_d, name,
+ value);
+
+ os_free(value);
+
+ return ret;
+}
+
+
static int wpa_supplicant_ctrl_iface_list_creds(struct wpa_supplicant *wpa_s,
char *buf, size_t buflen)
{
@@ -6450,6 +6512,9 @@
} else if (os_strncmp(buf, "GET_NETWORK ", 12) == 0) {
reply_len = wpa_supplicant_ctrl_iface_get_network(
wpa_s, buf + 12, reply, reply_size);
+ } else if (os_strncmp(buf, "DUP_NETWORK ", 12) == 0) {
+ if (wpa_supplicant_ctrl_iface_dup_network(wpa_s, buf + 12))
+ reply_len = -1;
} else if (os_strcmp(buf, "LIST_CREDS") == 0) {
reply_len = wpa_supplicant_ctrl_iface_list_creds(
wpa_s, reply, reply_size);
diff --git a/wpa_supplicant/dbus/dbus_common.c b/wpa_supplicant/dbus/dbus_common.c
index 6caf740..5cc1505 100644
--- a/wpa_supplicant/dbus/dbus_common.c
+++ b/wpa_supplicant/dbus/dbus_common.c
@@ -320,6 +320,8 @@
if (priv->con) {
eloop_cancel_timeout(dispatch_initial_dbus_messages,
priv->con, NULL);
+ eloop_cancel_timeout(process_timeout, priv, ELOOP_ALL_CTX);
+
dbus_connection_set_watch_functions(priv->con, NULL, NULL,
NULL, NULL, NULL);
dbus_connection_set_timeout_functions(priv->con, NULL, NULL,
diff --git a/wpa_supplicant/dbus/dbus_new_handlers.c b/wpa_supplicant/dbus/dbus_new_handlers.c
index 33a1ba9..bd38d65 100644
--- a/wpa_supplicant/dbus/dbus_new_handlers.c
+++ b/wpa_supplicant/dbus/dbus_new_handlers.c
@@ -1583,16 +1583,6 @@
wpas_notify_network_removed(wpa_s, ssid);
- if (wpa_config_remove_network(wpa_s->conf, id) < 0) {
- wpa_printf(MSG_ERROR,
- "wpas_dbus_handler_remove_network[dbus]: "
- "error occurred when removing network %d", id);
- reply = wpas_dbus_error_unknown_error(
- message, "error removing the specified network on "
- "this interface.");
- goto out;
- }
-
if (ssid == wpa_s->current_ssid)
wpa_supplicant_deauthenticate(wpa_s,
WLAN_REASON_DEAUTH_LEAVING);
@@ -1603,6 +1593,15 @@
wpa_supplicant_req_scan(wpa_s, 0, 0);
}
+ if (wpa_config_remove_network(wpa_s->conf, id) < 0) {
+ wpa_printf(MSG_ERROR,
+ "wpas_dbus_handler_remove_network[dbus]: "
+ "error occurred when removing network %d", id);
+ reply = wpas_dbus_error_unknown_error(
+ message, "error removing the specified network on "
+ "this interface.");
+ goto out;
+ }
out:
os_free(iface);
diff --git a/wpa_supplicant/hs20_supplicant.c b/wpa_supplicant/hs20_supplicant.c
index c242c33..ab8b66b 100644
--- a/wpa_supplicant/hs20_supplicant.c
+++ b/wpa_supplicant/hs20_supplicant.c
@@ -920,3 +920,10 @@
now.sec + reauth_delay;
}
}
+
+
+void hs20_deinit(struct wpa_supplicant *wpa_s)
+{
+ eloop_cancel_timeout(hs20_continue_icon_fetch, wpa_s, NULL);
+ hs20_free_osu_prov(wpa_s);
+}
diff --git a/wpa_supplicant/hs20_supplicant.h b/wpa_supplicant/hs20_supplicant.h
index f6c4d44..06739f5 100644
--- a/wpa_supplicant/hs20_supplicant.h
+++ b/wpa_supplicant/hs20_supplicant.h
@@ -35,5 +35,6 @@
void hs20_cancel_fetch_osu(struct wpa_supplicant *wpa_s);
void hs20_icon_fetch_failed(struct wpa_supplicant *wpa_s);
void hs20_start_osu_scan(struct wpa_supplicant *wpa_s);
+void hs20_deinit(struct wpa_supplicant *wpa_s);
#endif /* HS20_SUPPLICANT_H */
diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c
index be160c0..cd1ff12 100644
--- a/wpa_supplicant/p2p_supplicant.c
+++ b/wpa_supplicant/p2p_supplicant.c
@@ -125,6 +125,7 @@
int group_added);
static int wpas_p2p_stop_find_oper(struct wpa_supplicant *wpa_s);
static void wpas_stop_listen(void *ctx);
+static void wpas_p2p_psk_failure_removal(void *eloop_ctx, void *timeout_ctx);
/*
@@ -3932,6 +3933,7 @@
os_free(wpa_s->go_params);
wpa_s->go_params = NULL;
+ eloop_cancel_timeout(wpas_p2p_psk_failure_removal, wpa_s, NULL);
eloop_cancel_timeout(wpas_p2p_group_formation_timeout, wpa_s, NULL);
eloop_cancel_timeout(wpas_p2p_join_scan, wpa_s, NULL);
wpa_s->p2p_long_listen = 0;
@@ -6411,6 +6413,7 @@
void wpas_p2p_update_channel_list(struct wpa_supplicant *wpa_s)
{
struct p2p_channels chan, cli_chan;
+ struct wpa_supplicant *ifs;
if (wpa_s->global == NULL || wpa_s->global->p2p == NULL)
return;
@@ -6424,6 +6427,28 @@
}
p2p_update_channel_list(wpa_s->global->p2p, &chan, &cli_chan);
+
+ for (ifs = wpa_s->global->ifaces; ifs; ifs = ifs->next) {
+ int freq;
+ if (!ifs->current_ssid ||
+ !ifs->current_ssid->p2p_group ||
+ (ifs->current_ssid->mode != WPAS_MODE_P2P_GO &&
+ ifs->current_ssid->mode != WPAS_MODE_P2P_GROUP_FORMATION))
+ continue;
+ freq = ifs->current_ssid->frequency;
+ if (freq_included(&chan, freq)) {
+ wpa_dbg(ifs, MSG_DEBUG,
+ "P2P GO operating frequency %d MHz in valid range",
+ freq);
+ continue;
+ }
+
+ wpa_dbg(ifs, MSG_DEBUG,
+ "P2P GO operating in invalid frequency %d MHz", freq);
+ /* TODO: Consider using CSA or removing the group within
+ * wpa_supplicant */
+ wpa_msg(ifs, MSG_INFO, P2P_EVENT_REMOVE_AND_REFORM_GROUP);
+ }
}
diff --git a/wpa_supplicant/wpa_cli.c b/wpa_supplicant/wpa_cli.c
index 77c5295..b3812ca 100644
--- a/wpa_supplicant/wpa_cli.c
+++ b/wpa_supplicant/wpa_cli.c
@@ -1416,6 +1416,24 @@
}
+static int wpa_cli_cmd_dup_network(struct wpa_ctrl *ctrl, int argc,
+ char *argv[])
+{
+ if (argc == 0) {
+ wpa_cli_show_network_variables();
+ return 0;
+ }
+
+ if (argc < 3) {
+ printf("Invalid DUP_NETWORK command: needs three arguments\n"
+ "(src netid, dest netid, and variable name)\n");
+ return -1;
+ }
+
+ return wpa_cli_cmd(ctrl, "DUP_NETWORK", 3, argc, argv);
+}
+
+
static int wpa_cli_cmd_list_creds(struct wpa_ctrl *ctrl, int argc,
char *argv[])
{
@@ -2570,6 +2588,10 @@
{ "get_network", wpa_cli_cmd_get_network, NULL,
cli_cmd_flag_none,
"<network id> <variable> = get network variables" },
+ { "dup_network", wpa_cli_cmd_dup_network, NULL,
+ cli_cmd_flag_none,
+ "<src network id> <dst network id> <variable> = duplicate network variables"
+ },
{ "list_creds", wpa_cli_cmd_list_creds, NULL,
cli_cmd_flag_none,
"= list configured credentials" },
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index 8ba816b..e38e3e0 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -498,7 +498,7 @@
wpa_s->last_scan_res = NULL;
#ifdef CONFIG_HS20
- hs20_free_osu_prov(wpa_s);
+ hs20_deinit(wpa_s);
#endif /* CONFIG_HS20 */
}
diff --git a/wpa_supplicant/wps_supplicant.c b/wpa_supplicant/wps_supplicant.c
index 2b58749..de015ee 100644
--- a/wpa_supplicant/wps_supplicant.c
+++ b/wpa_supplicant/wps_supplicant.c
@@ -1465,6 +1465,10 @@
eloop_cancel_timeout(wpas_wps_reenable_networks_cb, wpa_s, NULL);
wpas_wps_clear_ap_info(wpa_s);
+#ifdef CONFIG_P2P
+ eloop_cancel_timeout(wpas_p2p_pbc_overlap_cb, wpa_s, NULL);
+#endif /* CONFIG_P2P */
+
if (wpa_s->wps == NULL)
return;