WPS ER: Add PIN configuration and SetSelectedRegistrar call
[libeap.git] / wpa_supplicant / wpa_cli.c
index ea9aac6..84dc8c0 100644 (file)
@@ -446,19 +446,85 @@ static int wpa_cli_cmd_wps_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
 }
 
 
+#ifdef CONFIG_WPS_OOB
+static int wpa_cli_cmd_wps_oob(struct wpa_ctrl *ctrl, int argc, char *argv[])
+{
+       char cmd[256];
+       int res;
+
+       if (argc != 3 && argc != 4) {
+               printf("Invalid WPS_OOB command: need three or four "
+                      "arguments:\n"
+                      "- DEV_TYPE: use 'ufd' or 'nfc'\n"
+                      "- PATH: path of OOB device like '/mnt'\n"
+                      "- METHOD: OOB method 'pin-e' or 'pin-r', "
+                      "'cred'\n"
+                      "- DEV_NAME: (only for NFC) device name like "
+                      "'pn531'\n");
+               return -1;
+       }
+
+       if (argc == 3)
+               res = os_snprintf(cmd, sizeof(cmd), "WPS_OOB %s %s %s",
+                                 argv[0], argv[1], argv[2]);
+       else
+               res = os_snprintf(cmd, sizeof(cmd), "WPS_OOB %s %s %s %s",
+                                 argv[0], argv[1], argv[2], argv[3]);
+       if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
+               printf("Too long WPS_OOB command.\n");
+               return -1;
+       }
+       return wpa_ctrl_command(ctrl, cmd);
+}
+#endif /* CONFIG_WPS_OOB */
+
+
 static int wpa_cli_cmd_wps_reg(struct wpa_ctrl *ctrl, int argc, char *argv[])
 {
        char cmd[256];
        int res;
 
-       if (argc != 2) {
+       if (argc == 2)
+               res = os_snprintf(cmd, sizeof(cmd), "WPS_REG %s %s",
+                                 argv[0], argv[1]);
+       else if (argc == 6) {
+               char ssid_hex[2 * 32 + 1];
+               char key_hex[2 * 64 + 1];
+               int i;
+
+               ssid_hex[0] = '\0';
+               for (i = 0; i < 32; i++) {
+                       if (argv[2][i] == '\0')
+                               break;
+                       os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[2][i]);
+               }
+
+               key_hex[0] = '\0';
+               for (i = 0; i < 64; i++) {
+                       if (argv[5][i] == '\0')
+                               break;
+                       os_snprintf(&key_hex[i * 2], 3, "%02x", argv[5][i]);
+               }
+
+               res = os_snprintf(cmd, sizeof(cmd),
+                                 "WPS_REG %s %s %s %s %s %s",
+                                 argv[0], argv[1], ssid_hex, argv[3], argv[4],
+                                 key_hex);
+       } else {
                printf("Invalid WPS_REG command: need two arguments:\n"
                       "- BSSID: use 'any' to select any\n"
                       "- AP PIN\n");
+               printf("Alternatively, six arguments can be used to "
+                      "reconfigure the AP:\n"
+                      "- BSSID: use 'any' to select any\n"
+                      "- AP PIN\n"
+                      "- new SSID\n"
+                      "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
+                      "- new encr (NONE, WEP, TKIP, CCMP)\n"
+                      "- new key\n");
                return -1;
        }
 
-       res = os_snprintf(cmd, sizeof(cmd), "WPS_REG %s %s", argv[0], argv[1]);
        if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
                printf("Too long WPS_REG command.\n");
                return -1;
@@ -467,6 +533,45 @@ static int wpa_cli_cmd_wps_reg(struct wpa_ctrl *ctrl, int argc, char *argv[])
 }
 
 
+static int wpa_cli_cmd_wps_er_start(struct wpa_ctrl *ctrl, int argc,
+                                   char *argv[])
+{
+       return wpa_ctrl_command(ctrl, "WPS_ER_START");
+
+}
+
+
+static int wpa_cli_cmd_wps_er_stop(struct wpa_ctrl *ctrl, int argc,
+                                  char *argv[])
+{
+       return wpa_ctrl_command(ctrl, "WPS_ER_STOP");
+
+}
+
+
+static int wpa_cli_cmd_wps_er_pin(struct wpa_ctrl *ctrl, int argc,
+                                 char *argv[])
+{
+       char cmd[256];
+       int res;
+
+       if (argc != 2) {
+               printf("Invalid WPS_ER_PIN command: need two arguments:\n"
+                      "- UUID: use 'any' to select any\n"
+                      "- PIN: Enrollee PIN\n");
+               return -1;
+       }
+
+       res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_PIN %s %s",
+                         argv[0], argv[1]);
+       if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
+               printf("Too long WPS_ER_PIN command.\n");
+               return -1;
+       }
+       return wpa_ctrl_command(ctrl, cmd);
+}
+
+
 static int wpa_cli_cmd_ibss_rsn(struct wpa_ctrl *ctrl, int argc, char *argv[])
 {
        char cmd[256];
@@ -1098,6 +1203,71 @@ static int wpa_cli_cmd_interface_list(struct wpa_ctrl *ctrl, int argc,
 }
 
 
+#ifdef CONFIG_AP
+static int wpa_cli_cmd_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
+{
+       char buf[64];
+       if (argc != 1) {
+               printf("Invalid 'sta' command - exactly one argument, STA "
+                      "address, is required.\n");
+               return -1;
+       }
+       snprintf(buf, sizeof(buf), "STA %s", argv[0]);
+       return wpa_ctrl_command(ctrl, buf);
+}
+
+
+static int wpa_ctrl_command_sta(struct wpa_ctrl *ctrl, char *cmd,
+                               char *addr, size_t addr_len)
+{
+       char buf[4096], *pos;
+       size_t len;
+       int ret;
+
+       if (ctrl_conn == NULL) {
+               printf("Not connected to hostapd - command dropped.\n");
+               return -1;
+       }
+       len = sizeof(buf) - 1;
+       ret = wpa_ctrl_request(ctrl, cmd, strlen(cmd), buf, &len,
+                              wpa_cli_msg_cb);
+       if (ret == -2) {
+               printf("'%s' command timed out.\n", cmd);
+               return -2;
+       } else if (ret < 0) {
+               printf("'%s' command failed.\n", cmd);
+               return -1;
+       }
+
+       buf[len] = '\0';
+       if (memcmp(buf, "FAIL", 4) == 0)
+               return -1;
+       printf("%s", buf);
+
+       pos = buf;
+       while (*pos != '\0' && *pos != '\n')
+               pos++;
+       *pos = '\0';
+       os_strlcpy(addr, buf, addr_len);
+       return 0;
+}
+
+
+static int wpa_cli_cmd_all_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
+{
+       char addr[32], cmd[64];
+
+       if (wpa_ctrl_command_sta(ctrl, "STA-FIRST", addr, sizeof(addr)))
+               return 0;
+       do {
+               snprintf(cmd, sizeof(cmd), "STA-NEXT %s", addr);
+       } while (wpa_ctrl_command_sta(ctrl, cmd, addr, sizeof(addr)) == 0);
+
+       return -1;
+}
+#endif /* CONFIG_AP */
+
+
 enum wpa_cli_cmd_flags {
        cli_cmd_flag_none               = 0x00,
        cli_cmd_flag_sensitive          = 0x01
@@ -1258,12 +1428,34 @@ static struct wpa_cli_cmd wpa_cli_commands[] = {
          cli_cmd_flag_sensitive,
          "<BSSID> [PIN] = start WPS PIN method (returns PIN, if not "
          "hardcoded)" },
+#ifdef CONFIG_WPS_OOB
+       { "wps_oob", wpa_cli_cmd_wps_oob,
+         cli_cmd_flag_sensitive,
+         "<DEV_TYPE> <PATH> <METHOD> [DEV_NAME] = start WPS OOB" },
+#endif /* CONFIG_WPS_OOB */
        { "wps_reg", wpa_cli_cmd_wps_reg,
          cli_cmd_flag_sensitive,
          "<BSSID> <AP PIN> = start WPS Registrar to configure an AP" },
+       { "wps_er_start", wpa_cli_cmd_wps_er_start,
+         cli_cmd_flag_none,
+         "= start Wi-Fi Protected Setup External Registrar" },
+       { "wps_er_stop", wpa_cli_cmd_wps_er_stop,
+         cli_cmd_flag_none,
+         "= stop Wi-Fi Protected Setup External Registrar" },
+       { "wps_er_pin", wpa_cli_cmd_wps_er_pin,
+         cli_cmd_flag_sensitive,
+         "<UUID> <PIN> = add an Enrollee PIN to External Registrar" },
        { "ibss_rsn", wpa_cli_cmd_ibss_rsn,
          cli_cmd_flag_none,
          "<addr> = request RSN authentication with <addr> in IBSS" },
+#ifdef CONFIG_AP
+       { "sta", wpa_cli_cmd_sta,
+         cli_cmd_flag_none,
+         "<addr> = get information about an associated station (AP)" },
+       { "all_sta", wpa_cli_cmd_all_sta,
+         cli_cmd_flag_none,
+         "= get information about all associated stations (AP)" },
+#endif /* CONFIG_AP */
        { NULL, NULL, cli_cmd_flag_none, NULL }
 };