aboutsummaryrefslogtreecommitdiffstats
path: root/wpa_supplicant
diff options
context:
space:
mode:
authorJouni Malinen <jouni.malinen@atheros.com>2010-05-27 21:01:48 (GMT)
committerJouni Malinen <j@w1.fi>2010-05-27 21:01:48 (GMT)
commit7d6640a62cbb63a95bce60f4bae493dc40ca21d1 (patch)
tree1387427892f6ab11999d1b0be10a24547b07d623 /wpa_supplicant
parent3085b8052ebe96957187e6103a0c0032391c7666 (diff)
downloadhostap-7d6640a62cbb63a95bce60f4bae493dc40ca21d1.zip
hostap-7d6640a62cbb63a95bce60f4bae493dc40ca21d1.tar.gz
hostap-7d6640a62cbb63a95bce60f4bae493dc40ca21d1.tar.bz2
WPS ER: Add command for configuring an AP
wps_er_config can now be used to configure an AP. It is similar to wps_er_learn, but instead of only learning the current AP settings, it continues to send M8 with the new settings for the AP.
Diffstat (limited to 'wpa_supplicant')
-rw-r--r--wpa_supplicant/README-WPS9
-rw-r--r--wpa_supplicant/ctrl_iface.c47
-rw-r--r--wpa_supplicant/wpa_cli.c67
-rw-r--r--wpa_supplicant/wps_supplicant.c51
-rw-r--r--wpa_supplicant/wps_supplicant.h2
5 files changed, 171 insertions, 5 deletions
diff --git a/wpa_supplicant/README-WPS b/wpa_supplicant/README-WPS
index 30ed2aa..9b6f9c5 100644
--- a/wpa_supplicant/README-WPS
+++ b/wpa_supplicant/README-WPS
@@ -236,6 +236,15 @@ wps_er_stop
wps_er_learn <UUID> <AP PIN>
- learn AP configuration
+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
+ wpa_er_config 87654321-9abc-def0-1234-56789abc0002 12345670 clear OPEN NONE ""
+
+<auth> must be one of the following: OPEN WPAPSK WPA2PSK
+<encr> must be one of the following: NONE WEP TKIP CCMP
+
+
wps_er_pbc <Enrollee UUID>
- accept an Enrollee PBC using External Registrar
diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c
index 7df65c1..5c3a735 100644
--- a/wpa_supplicant/ctrl_iface.c
+++ b/wpa_supplicant/ctrl_iface.c
@@ -330,6 +330,50 @@ static int wpa_supplicant_ctrl_iface_wps_er_learn(struct wpa_supplicant *wpa_s,
*pin++ = '\0';
return wpas_wps_er_learn(wpa_s, uuid, pin);
}
+
+
+static int wpa_supplicant_ctrl_iface_wps_er_config(
+ struct wpa_supplicant *wpa_s, char *cmd)
+{
+ char *pin;
+ char *new_ssid;
+ char *new_auth;
+ char *new_encr;
+ char *new_key;
+ struct wps_new_ap_settings ap;
+
+ pin = os_strchr(cmd, ' ');
+ if (pin == NULL)
+ return -1;
+ *pin++ = '\0';
+
+ new_ssid = os_strchr(pin, ' ');
+ if (new_ssid == NULL)
+ return -1;
+ *new_ssid++ = '\0';
+
+ new_auth = os_strchr(new_ssid, ' ');
+ if (new_auth == NULL)
+ return -1;
+ *new_auth++ = '\0';
+
+ new_encr = os_strchr(new_auth, ' ');
+ if (new_encr == NULL)
+ return -1;
+ *new_encr++ = '\0';
+
+ new_key = os_strchr(new_encr, ' ');
+ if (new_key == NULL)
+ return -1;
+ *new_key++ = '\0';
+
+ os_memset(&ap, 0, sizeof(ap));
+ ap.ssid_hex = new_ssid;
+ ap.auth = new_auth;
+ ap.encr = new_encr;
+ ap.key_hex = new_key;
+ return wpas_wps_er_config(wpa_s, cmd, pin, &ap);
+}
#endif /* CONFIG_WPS_ER */
#endif /* CONFIG_WPS */
@@ -1810,6 +1854,9 @@ 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_CONFIG ", 14) == 0) {
+ if (wpa_supplicant_ctrl_iface_wps_er_config(wpa_s, buf + 14))
+ reply_len = -1;
#endif /* CONFIG_WPS_ER */
#endif /* CONFIG_WPS */
#ifdef CONFIG_IBSS_RSN
diff --git a/wpa_supplicant/wpa_cli.c b/wpa_supplicant/wpa_cli.c
index bd258ab..6e67231 100644
--- a/wpa_supplicant/wpa_cli.c
+++ b/wpa_supplicant/wpa_cli.c
@@ -602,7 +602,7 @@ static int wpa_cli_cmd_wps_reg(struct wpa_ctrl *ctrl, int argc, char *argv[])
if (argc == 2)
res = os_snprintf(cmd, sizeof(cmd), "WPS_REG %s %s",
argv[0], argv[1]);
- else if (argc == 6) {
+ else if (argc == 5 || argc == 6) {
char ssid_hex[2 * 32 + 1];
char key_hex[2 * 64 + 1];
int i;
@@ -615,10 +615,13 @@ static int wpa_cli_cmd_wps_reg(struct wpa_ctrl *ctrl, int argc, char *argv[])
}
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]);
+ if (argc == 6) {
+ 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),
@@ -736,6 +739,57 @@ static int wpa_cli_cmd_wps_er_learn(struct wpa_ctrl *ctrl, int argc,
}
+static int wpa_cli_cmd_wps_er_config(struct wpa_ctrl *ctrl, int argc,
+ char *argv[])
+{
+ char cmd[256];
+ int res;
+
+ if (argc == 5 || 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';
+ if (argc == 6) {
+ 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_ER_CONFIG %s %s %s %s %s %s",
+ argv[0], argv[1], ssid_hex, argv[3], argv[4],
+ key_hex);
+ } else {
+ printf("Invalid WPS_ER_CONFIG command: need six arguments:\n"
+ "- AP UUID\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;
+ }
+
+ if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
+ printf("Too long WPS_ER_CONFIG 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];
@@ -1647,6 +1701,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_config", wpa_cli_cmd_wps_er_config,
+ cli_cmd_flag_sensitive,
+ "<UUID> <PIN> <SSID> <auth> <encr> <key> = configure AP" },
{ "ibss_rsn", wpa_cli_cmd_ibss_rsn,
cli_cmd_flag_none,
"<addr> = request RSN authentication with <addr> in IBSS" },
diff --git a/wpa_supplicant/wps_supplicant.c b/wpa_supplicant/wps_supplicant.c
index a1b8d1f..2b90e57 100644
--- a/wpa_supplicant/wps_supplicant.c
+++ b/wpa_supplicant/wps_supplicant.c
@@ -1194,6 +1194,57 @@ int wpas_wps_er_learn(struct wpa_supplicant *wpa_s, const char *uuid,
}
+int wpas_wps_er_config(struct wpa_supplicant *wpa_s, const char *uuid,
+ const char *pin, struct wps_new_ap_settings *settings)
+{
+ u8 u[UUID_LEN];
+ struct wps_credential cred;
+ size_t len;
+
+ if (uuid_str2bin(uuid, u))
+ return -1;
+ if (settings->ssid_hex == NULL || settings->auth == NULL ||
+ settings->encr == NULL || settings->key_hex == NULL)
+ return -1;
+
+ os_memset(&cred, 0, sizeof(cred));
+ len = os_strlen(settings->ssid_hex);
+ if ((len & 1) || len > 2 * sizeof(cred.ssid) ||
+ hexstr2bin(settings->ssid_hex, cred.ssid, len / 2))
+ return -1;
+ cred.ssid_len = len / 2;
+
+ len = os_strlen(settings->key_hex);
+ if ((len & 1) || len > 2 * sizeof(cred.key) ||
+ hexstr2bin(settings->key_hex, cred.key, len / 2))
+ return -1;
+ cred.key_len = len / 2;
+
+ if (os_strcmp(settings->auth, "OPEN") == 0)
+ cred.auth_type = WPS_AUTH_OPEN;
+ else if (os_strcmp(settings->auth, "WPAPSK") == 0)
+ cred.auth_type = WPS_AUTH_WPAPSK;
+ else if (os_strcmp(settings->auth, "WPA2PSK") == 0)
+ cred.auth_type = WPS_AUTH_WPA2PSK;
+ else
+ return -1;
+
+ if (os_strcmp(settings->encr, "NONE") == 0)
+ cred.encr_type = WPS_ENCR_NONE;
+ else if (os_strcmp(settings->encr, "WEP") == 0)
+ cred.encr_type = WPS_ENCR_WEP;
+ else if (os_strcmp(settings->encr, "TKIP") == 0)
+ cred.encr_type = WPS_ENCR_TKIP;
+ else if (os_strcmp(settings->encr, "CCMP") == 0)
+ cred.encr_type = WPS_ENCR_AES;
+ else
+ return -1;
+
+ return wps_er_config(wpa_s->wps_er, u, (const u8 *) pin,
+ os_strlen(pin), &cred);
+}
+
+
static void wpas_wps_terminate_cb(void *ctx)
{
wpa_printf(MSG_DEBUG, "WPS ER: Terminated");
diff --git a/wpa_supplicant/wps_supplicant.h b/wpa_supplicant/wps_supplicant.h
index ab45c0f..701bcb5 100644
--- a/wpa_supplicant/wps_supplicant.h
+++ b/wpa_supplicant/wps_supplicant.h
@@ -59,6 +59,8 @@ int wpas_wps_er_add_pin(struct wpa_supplicant *wpa_s, const char *uuid,
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_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);
#else /* CONFIG_WPS */