WPS ER: Add wps_er_set_config to use local configuration
authorJouni Malinen <jouni.malinen@atheros.com>
Wed, 20 Oct 2010 10:37:01 +0000 (13:37 +0300)
committerJouni Malinen <j@w1.fi>
Wed, 20 Oct 2010 10:37:01 +0000 (13:37 +0300)
This command can be used to enroll a network based on a local
network configuration block instead of having to (re-)learn the
current AP settings with wps_er_learn.

src/wps/wps.h
src/wps/wps_er.c
wpa_supplicant/README-WPS
wpa_supplicant/ctrl_iface.c
wpa_supplicant/wpa_cli.c
wpa_supplicant/wps_supplicant.c
wpa_supplicant/wps_supplicant.h

index a4b7323..beb21b6 100644 (file)
@@ -758,6 +758,8 @@ void wps_er_set_sel_reg(struct wps_er *er, int sel_reg, u16 dev_passwd_id,
 int wps_er_pbc(struct wps_er *er, const u8 *uuid);
 int wps_er_learn(struct wps_er *er, const u8 *uuid, const u8 *pin,
                 size_t pin_len);
+int wps_er_set_config(struct wps_er *er, const u8 *uuid,
+                     const struct wps_credential *cred);
 int wps_er_config(struct wps_er *er, const u8 *uuid, const u8 *pin,
                  size_t pin_len, const struct wps_credential *cred);
 
index f573d62..473cfc3 100644 (file)
@@ -1738,6 +1738,34 @@ int wps_er_learn(struct wps_er *er, const u8 *uuid, const u8 *pin,
 }
 
 
+int wps_er_set_config(struct wps_er *er, const u8 *uuid,
+                     const struct wps_credential *cred)
+{
+       struct wps_er_ap *ap;
+
+       if (er == NULL)
+               return -1;
+
+       ap = wps_er_ap_get(er, NULL, uuid);
+       if (ap == NULL) {
+               wpa_printf(MSG_DEBUG, "WPS ER: AP not found for set config "
+                          "request");
+               return -1;
+       }
+
+       os_free(ap->ap_settings);
+       ap->ap_settings = os_malloc(sizeof(*cred));
+       if (ap->ap_settings == NULL)
+               return -1;
+       os_memcpy(ap->ap_settings, cred, sizeof(*cred));
+       ap->ap_settings->cred_attr = NULL;
+       wpa_printf(MSG_DEBUG, "WPS ER: Updated local AP settings based set "
+                  "config request");
+
+       return 0;
+}
+
+
 static void wps_er_ap_config_m1(struct wps_er_ap *ap, struct wpabuf *m1)
 {
        struct wps_config cfg;
index e866eb0..6aa3a7b 100644 (file)
@@ -244,6 +244,12 @@ wps_er_stop
 wps_er_learn <UUID> <AP PIN>
 - learn AP configuration
 
+wps_er_set_config <UUID> <network id>
+- use AP configuration from a locally configured network (e.g., from
+  wps_reg command); this does not change the AP's configuration, but
+  only prepares a configuration to be used when enrolling a new device
+  to the AP
+
 wps_er_config <UUID> <AP PIN> <new SSID> <auth> <encr> <new key>
 - examples:
   wps_er_config 87654321-9abc-def0-1234-56789abc0002 12345670 testing WPA2PSK CCMP 12345678
index 75c78ee..339eb9b 100644 (file)
@@ -416,6 +416,18 @@ static int wpa_supplicant_ctrl_iface_wps_er_learn(struct wpa_supplicant *wpa_s,
 }
 
 
+static int wpa_supplicant_ctrl_iface_wps_er_set_config(
+       struct wpa_supplicant *wpa_s, char *cmd)
+{
+       char *uuid = cmd, *id;
+       id = os_strchr(uuid, ' ');
+       if (id == NULL)
+               return -1;
+       *id++ = '\0';
+       return wpas_wps_er_set_config(wpa_s, uuid, atoi(id));
+}
+
+
 static int wpa_supplicant_ctrl_iface_wps_er_config(
        struct wpa_supplicant *wpa_s, char *cmd)
 {
@@ -2804,6 +2816,10 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
        } else if (os_strncmp(buf, "WPS_ER_LEARN ", 13) == 0) {
                if (wpa_supplicant_ctrl_iface_wps_er_learn(wpa_s, buf + 13))
                        reply_len = -1;
+       } else if (os_strncmp(buf, "WPS_ER_SET_CONFIG ", 18) == 0) {
+               if (wpa_supplicant_ctrl_iface_wps_er_set_config(wpa_s,
+                                                               buf + 18))
+                       reply_len = -1;
        } else if (os_strncmp(buf, "WPS_ER_CONFIG ", 14) == 0) {
                if (wpa_supplicant_ctrl_iface_wps_er_config(wpa_s, buf + 14))
                        reply_len = -1;
index 587b8af..5e355a5 100644 (file)
@@ -832,6 +832,30 @@ static int wpa_cli_cmd_wps_er_learn(struct wpa_ctrl *ctrl, int argc,
 }
 
 
+static int wpa_cli_cmd_wps_er_set_config(struct wpa_ctrl *ctrl, int argc,
+                                        char *argv[])
+{
+       char cmd[256];
+       int res;
+
+       if (argc != 2) {
+               printf("Invalid WPS_ER_SET_CONFIG command: need two "
+                      "arguments:\n"
+                      "- UUID: specify which AP to use\n"
+                      "- Network configuration id\n");
+               return -1;
+       }
+
+       res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_SET_CONFIG %s %s",
+                         argv[0], argv[1]);
+       if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
+               printf("Too long WPS_ER_SET_CONFIG command.\n");
+               return -1;
+       }
+       return wpa_ctrl_command(ctrl, cmd);
+}
+
+
 static int wpa_cli_cmd_wps_er_config(struct wpa_ctrl *ctrl, int argc,
                                     char *argv[])
 {
@@ -2332,6 +2356,9 @@ static struct wpa_cli_cmd wpa_cli_commands[] = {
        { "wps_er_learn", wpa_cli_cmd_wps_er_learn,
          cli_cmd_flag_sensitive,
          "<UUID> <PIN> = learn AP configuration" },
+       { "wps_er_set_config", wpa_cli_cmd_wps_er_set_config,
+         cli_cmd_flag_none,
+         "<UUID> <network id> = set AP configuration for enrolling" },
        { "wps_er_config", wpa_cli_cmd_wps_er_config,
          cli_cmd_flag_sensitive,
          "<UUID> <PIN> <SSID> <auth> <encr> <key> = configure AP" },
index af8c4c4..bc8dc42 100644 (file)
@@ -1362,6 +1362,49 @@ int wpas_wps_er_learn(struct wpa_supplicant *wpa_s, const char *uuid,
 }
 
 
+int wpas_wps_er_set_config(struct wpa_supplicant *wpa_s, const char *uuid,
+                          int id)
+{
+       u8 u[UUID_LEN];
+       struct wpa_ssid *ssid;
+       struct wps_credential cred;
+
+       if (uuid_str2bin(uuid, u))
+               return -1;
+       ssid = wpa_config_get_network(wpa_s->conf, id);
+       if (ssid == NULL || ssid->ssid == NULL)
+               return -1;
+
+       os_memset(&cred, 0, sizeof(cred));
+       if (ssid->ssid_len > 32)
+               return -1;
+       os_memcpy(cred.ssid, ssid->ssid, ssid->ssid_len);
+       cred.ssid_len = ssid->ssid_len;
+       if (ssid->key_mgmt & WPA_KEY_MGMT_PSK) {
+               cred.auth_type = (ssid->proto & WPA_PROTO_RSN) ?
+                       WPS_AUTH_WPA2PSK : WPS_AUTH_WPAPSK;
+               if (ssid->pairwise_cipher & WPA_CIPHER_CCMP)
+                       cred.encr_type = WPS_ENCR_AES;
+               else
+                       cred.encr_type = WPS_ENCR_TKIP;
+               if (ssid->passphrase) {
+                       cred.key_len = os_strlen(ssid->passphrase);
+                       if (cred.key_len >= 64)
+                               return -1;
+                       os_memcpy(cred.key, ssid->passphrase, cred.key_len);
+               } else if (ssid->psk_set) {
+                       cred.key_len = 32;
+                       os_memcpy(cred.key, ssid->psk, 32);
+               } else
+                       return -1;
+       } else {
+               cred.auth_type = WPS_AUTH_OPEN;
+               cred.encr_type = WPS_ENCR_NONE;
+       }
+       return wps_er_set_config(wpa_s->wps_er, u, &cred);
+}
+
+
 int wpas_wps_er_config(struct wpa_supplicant *wpa_s, const char *uuid,
                       const char *pin, struct wps_new_ap_settings *settings)
 {
index ce1776f..b38c091 100644 (file)
@@ -61,6 +61,8 @@ int wpas_wps_er_add_pin(struct wpa_supplicant *wpa_s, const u8 *addr,
 int wpas_wps_er_pbc(struct wpa_supplicant *wpa_s, const char *uuid);
 int wpas_wps_er_learn(struct wpa_supplicant *wpa_s, const char *uuid,
                      const char *pin);
+int wpas_wps_er_set_config(struct wpa_supplicant *wpa_s, const char *uuid,
+                          int id);
 int wpas_wps_er_config(struct wpa_supplicant *wpa_s, const char *uuid,
                       const char *pin, struct wps_new_ap_settings *settings);
 int wpas_wps_terminate_pending(struct wpa_supplicant *wpa_s);