WPS ER: Add wps_er_set_config to use local configuration

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.
This commit is contained in:
Jouni Malinen 2010-10-20 13:37:01 +03:00 committed by Jouni Malinen
parent cbbf4a1cc3
commit ef10f4733f
7 changed files with 124 additions and 0 deletions

View 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);

View 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;

View 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

View 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;

View 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" },

View 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)
{

View 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);