]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
Add 'dup_network <id_s> <id_d> <name>' command
authorDmitry Shmidt <dimitrysh@google.com>
Tue, 29 Apr 2014 20:41:47 +0000 (13:41 -0700)
committerJouni Malinen <j@w1.fi>
Mon, 12 May 2014 16:43:56 +0000 (19:43 +0300)
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>
wpa_supplicant/ctrl_iface.c
wpa_supplicant/wpa_cli.c

index 14664df0ba1db7db41307a5ad2d8ecfab17089f7..9970597f7c4b7e393e20ab93b611d26517a2ac7c 100644 (file)
@@ -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(
        struct wpa_supplicant *wpa_s, char *cmd)
 {
@@ -2526,32 +2559,8 @@ static int wpa_supplicant_ctrl_iface_set_network(
                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_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,
                                                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) {
                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);
index 77c52954f60dd7717145e159ea16a286b607a55b..b3812cace7eef1b79c59eb0c86f80aaa4a96a6a5 100644 (file)
@@ -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,
                                  char *argv[])
 {
@@ -2570,6 +2588,10 @@ static struct wpa_cli_cmd wpa_cli_commands[] = {
        { "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" },