Add 'dup_network <id_s> <id_d> <name>' command
This command allows to copy network variable from one network to another, e.g., to clone the psk field without having to extract it from wpa_supplicant. Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
This commit is contained in:
parent
316f92cd33
commit
1c330a2fdc
2 changed files with 113 additions and 26 deletions
|
@ -2495,6 +2495,39 @@ static int wpa_supplicant_ctrl_iface_remove_network(
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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(
|
static int wpa_supplicant_ctrl_iface_set_network(
|
||||||
struct wpa_supplicant *wpa_s, char *cmd)
|
struct wpa_supplicant *wpa_s, char *cmd)
|
||||||
{
|
{
|
||||||
|
@ -2526,32 +2559,8 @@ static int wpa_supplicant_ctrl_iface_set_network(
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wpa_config_set(ssid, name, value, 0) < 0) {
|
return wpa_supplicant_ctrl_iface_update_network(wpa_s, ssid, name,
|
||||||
wpa_printf(MSG_DEBUG, "CTRL_IFACE: Failed to set network "
|
value);
|
||||||
"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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2599,6 +2608,59 @@ static int wpa_supplicant_ctrl_iface_get_network(
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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,
|
static int wpa_supplicant_ctrl_iface_list_creds(struct wpa_supplicant *wpa_s,
|
||||||
char *buf, size_t buflen)
|
char *buf, size_t buflen)
|
||||||
{
|
{
|
||||||
|
@ -6450,6 +6512,9 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
|
||||||
} else if (os_strncmp(buf, "GET_NETWORK ", 12) == 0) {
|
} else if (os_strncmp(buf, "GET_NETWORK ", 12) == 0) {
|
||||||
reply_len = wpa_supplicant_ctrl_iface_get_network(
|
reply_len = wpa_supplicant_ctrl_iface_get_network(
|
||||||
wpa_s, buf + 12, reply, reply_size);
|
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) {
|
} else if (os_strcmp(buf, "LIST_CREDS") == 0) {
|
||||||
reply_len = wpa_supplicant_ctrl_iface_list_creds(
|
reply_len = wpa_supplicant_ctrl_iface_list_creds(
|
||||||
wpa_s, reply, reply_size);
|
wpa_s, reply, reply_size);
|
||||||
|
|
|
@ -1416,6 +1416,24 @@ static int wpa_cli_cmd_get_network(struct wpa_ctrl *ctrl, int argc,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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,
|
static int wpa_cli_cmd_list_creds(struct wpa_ctrl *ctrl, int argc,
|
||||||
char *argv[])
|
char *argv[])
|
||||||
{
|
{
|
||||||
|
@ -2570,6 +2588,10 @@ static struct wpa_cli_cmd wpa_cli_commands[] = {
|
||||||
{ "get_network", wpa_cli_cmd_get_network, NULL,
|
{ "get_network", wpa_cli_cmd_get_network, NULL,
|
||||||
cli_cmd_flag_none,
|
cli_cmd_flag_none,
|
||||||
"<network id> <variable> = get network variables" },
|
"<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,
|
{ "list_creds", wpa_cli_cmd_list_creds, NULL,
|
||||||
cli_cmd_flag_none,
|
cli_cmd_flag_none,
|
||||||
"= list configured credentials" },
|
"= list configured credentials" },
|
||||||
|
|
Loading…
Reference in a new issue