hostapd: Add wps_config ctrl_interface command for configuring AP
This command can be used to configure the AP using the internal WPS registrar. It works in the same way as new AP settings received from an ER.
This commit is contained in:
parent
7374b68ee9
commit
450eddcfae
7 changed files with 177 additions and 0 deletions
|
@ -239,6 +239,14 @@ hostapd_cli wps_ap_pin set <PIN> [timeout]
|
|||
hostapd_cli get_config
|
||||
- display the current configuration
|
||||
|
||||
hostapd_cli wps_config <new SSID> <auth> <encr> <new key>
|
||||
examples:
|
||||
hostapd_cli wps_config testing WPA2PSK CCMP 12345678
|
||||
hostapd_cli wps_config "no security" OPEN NONE ""
|
||||
|
||||
<auth> must be one of the following: OPEN WPAPSK WPA2PSK
|
||||
<encr> must be one of the following: NONE WEP TKIP CCMP
|
||||
|
||||
|
||||
Credential generation and configuration changes
|
||||
-----------------------------------------------
|
||||
|
|
|
@ -490,6 +490,33 @@ static int hostapd_ctrl_iface_wps_ap_pin(struct hostapd_data *hapd, char *txt,
|
|||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
static int hostapd_ctrl_iface_wps_config(struct hostapd_data *hapd, char *txt)
|
||||
{
|
||||
char *pos;
|
||||
char *ssid, *auth, *encr = NULL, *key = NULL;
|
||||
|
||||
ssid = txt;
|
||||
pos = os_strchr(txt, ' ');
|
||||
if (!pos)
|
||||
return -1;
|
||||
*pos++ = '\0';
|
||||
|
||||
auth = pos;
|
||||
pos = os_strchr(pos, ' ');
|
||||
if (pos) {
|
||||
*pos++ = '\0';
|
||||
encr = pos;
|
||||
pos = os_strchr(pos, ' ');
|
||||
if (pos) {
|
||||
*pos++ = '\0';
|
||||
key = pos;
|
||||
}
|
||||
}
|
||||
|
||||
return hostapd_wps_config_ap(hapd, ssid, auth, encr, key);
|
||||
}
|
||||
#endif /* CONFIG_WPS */
|
||||
|
||||
|
||||
|
@ -821,6 +848,9 @@ static void hostapd_ctrl_iface_receive(int sock, void *eloop_ctx,
|
|||
} else if (os_strncmp(buf, "WPS_AP_PIN ", 11) == 0) {
|
||||
reply_len = hostapd_ctrl_iface_wps_ap_pin(hapd, buf + 11,
|
||||
reply, reply_size);
|
||||
} else if (os_strncmp(buf, "WPS_CONFIG ", 11) == 0) {
|
||||
if (hostapd_ctrl_iface_wps_config(hapd, buf + 11) < 0)
|
||||
reply_len = -1;
|
||||
#endif /* CONFIG_WPS */
|
||||
} else if (os_strcmp(buf, "GET_CONFIG") == 0) {
|
||||
reply_len = hostapd_ctrl_iface_get_config(hapd, reply,
|
||||
|
|
|
@ -96,6 +96,7 @@ static const char *commands_help =
|
|||
" wps_oob <type> <path> <method> use WPS with out-of-band (UFD)\n"
|
||||
#endif /* CONFIG_WPS_OOB */
|
||||
" wps_ap_pin <cmd> [params..] enable/disable AP PIN\n"
|
||||
" wps_config <SSID> <auth> <encr> <key> configure AP\n"
|
||||
#endif /* CONFIG_WPS */
|
||||
" get_config show current configuration\n"
|
||||
" help show this usage help\n"
|
||||
|
@ -458,6 +459,50 @@ static int hostapd_cli_cmd_wps_ap_pin(struct wpa_ctrl *ctrl, int argc,
|
|||
snprintf(buf, sizeof(buf), "WPS_AP_PIN %s", argv[0]);
|
||||
return wpa_ctrl_command(ctrl, buf);
|
||||
}
|
||||
|
||||
|
||||
static int hostapd_cli_cmd_wps_config(struct wpa_ctrl *ctrl, int argc,
|
||||
char *argv[])
|
||||
{
|
||||
char buf[256];
|
||||
char ssid_hex[2 * 32 + 1];
|
||||
char key_hex[2 * 64 + 1];
|
||||
int i;
|
||||
|
||||
if (argc < 1) {
|
||||
printf("Invalid 'wps_config' command - at least two arguments "
|
||||
"are required.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
ssid_hex[0] = '\0';
|
||||
for (i = 0; i < 32; i++) {
|
||||
if (argv[0][i] == '\0')
|
||||
break;
|
||||
os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[0][i]);
|
||||
}
|
||||
|
||||
key_hex[0] = '\0';
|
||||
if (argc > 3) {
|
||||
for (i = 0; i < 64; i++) {
|
||||
if (argv[3][i] == '\0')
|
||||
break;
|
||||
os_snprintf(&key_hex[i * 2], 3, "%02x",
|
||||
argv[3][i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (argc > 3)
|
||||
snprintf(buf, sizeof(buf), "WPS_CONFIG %s %s %s %s",
|
||||
ssid_hex, argv[1], argv[2], key_hex);
|
||||
else if (argc > 2)
|
||||
snprintf(buf, sizeof(buf), "WPS_CONFIG %s %s %s",
|
||||
ssid_hex, argv[1], argv[2]);
|
||||
else
|
||||
snprintf(buf, sizeof(buf), "WPS_CONFIG %s %s",
|
||||
ssid_hex, argv[1]);
|
||||
return wpa_ctrl_command(ctrl, buf);
|
||||
}
|
||||
#endif /* CONFIG_WPS */
|
||||
|
||||
|
||||
|
@ -649,6 +694,7 @@ static struct hostapd_cli_cmd hostapd_cli_commands[] = {
|
|||
{ "wps_oob", hostapd_cli_cmd_wps_oob },
|
||||
#endif /* CONFIG_WPS_OOB */
|
||||
{ "wps_ap_pin", hostapd_cli_cmd_wps_ap_pin },
|
||||
{ "wps_config", hostapd_cli_cmd_wps_config },
|
||||
#endif /* CONFIG_WPS */
|
||||
{ "get_config", hostapd_cli_cmd_get_config },
|
||||
{ "help", hostapd_cli_cmd_help },
|
||||
|
|
|
@ -1286,3 +1286,52 @@ void hostapd_wps_update_ie(struct hostapd_data *hapd)
|
|||
{
|
||||
hostapd_wps_for_each(hapd, wps_update_ie, NULL);
|
||||
}
|
||||
|
||||
|
||||
int hostapd_wps_config_ap(struct hostapd_data *hapd, const char *ssid,
|
||||
const char *auth, const char *encr, const char *key)
|
||||
{
|
||||
struct wps_credential cred;
|
||||
size_t len;
|
||||
|
||||
os_memset(&cred, 0, sizeof(cred));
|
||||
|
||||
len = os_strlen(ssid);
|
||||
if ((len & 1) || len > 2 * sizeof(cred.ssid) ||
|
||||
hexstr2bin(ssid, cred.ssid, len / 2))
|
||||
return -1;
|
||||
cred.ssid_len = len / 2;
|
||||
|
||||
if (os_strncmp(auth, "OPEN", 4) == 0)
|
||||
cred.auth_type = WPS_AUTH_OPEN;
|
||||
else if (os_strncmp(auth, "WPAPSK", 6) == 0)
|
||||
cred.auth_type = WPS_AUTH_WPAPSK;
|
||||
else if (os_strncmp(auth, "WPA2PSK", 7) == 0)
|
||||
cred.auth_type = WPS_AUTH_WPA2PSK;
|
||||
else
|
||||
return -1;
|
||||
|
||||
if (encr) {
|
||||
if (os_strncmp(encr, "NONE", 4) == 0)
|
||||
cred.encr_type = WPS_ENCR_NONE;
|
||||
else if (os_strncmp(encr, "WEP", 3) == 0)
|
||||
cred.encr_type = WPS_ENCR_WEP;
|
||||
else if (os_strncmp(encr, "TKIP", 4) == 0)
|
||||
cred.encr_type = WPS_ENCR_TKIP;
|
||||
else if (os_strncmp(encr, "CCMP", 4) == 0)
|
||||
cred.encr_type = WPS_ENCR_AES;
|
||||
else
|
||||
return -1;
|
||||
} else
|
||||
cred.encr_type = WPS_ENCR_NONE;
|
||||
|
||||
if (key) {
|
||||
len = os_strlen(key);
|
||||
if ((len & 1) || len > 2 * sizeof(cred.key) ||
|
||||
hexstr2bin(key, cred.key, len / 2))
|
||||
return -1;
|
||||
cred.key_len = len / 2;
|
||||
}
|
||||
|
||||
return wps_registrar_config_ap(hapd->wps->registrar, &cred);
|
||||
}
|
||||
|
|
|
@ -34,6 +34,8 @@ const char * hostapd_wps_ap_pin_get(struct hostapd_data *hapd);
|
|||
int hostapd_wps_ap_pin_set(struct hostapd_data *hapd, const char *pin,
|
||||
int timeout);
|
||||
void hostapd_wps_update_ie(struct hostapd_data *hapd);
|
||||
int hostapd_wps_config_ap(struct hostapd_data *hapd, const char *ssid,
|
||||
const char *auth, const char *encr, const char *key);
|
||||
|
||||
#else /* CONFIG_WPS */
|
||||
|
||||
|
|
|
@ -736,6 +736,8 @@ void wps_registrar_probe_req_rx(struct wps_registrar *reg, const u8 *addr,
|
|||
int wps_registrar_update_ie(struct wps_registrar *reg);
|
||||
int wps_registrar_get_info(struct wps_registrar *reg, const u8 *addr,
|
||||
char *buf, size_t buflen);
|
||||
int wps_registrar_config_ap(struct wps_registrar *reg,
|
||||
struct wps_credential *cred);
|
||||
|
||||
unsigned int wps_pin_checksum(unsigned int pin);
|
||||
unsigned int wps_pin_valid(unsigned int pin);
|
||||
|
|
|
@ -3161,3 +3161,43 @@ int wps_registrar_get_info(struct wps_registrar *reg, const u8 *addr,
|
|||
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
int wps_registrar_config_ap(struct wps_registrar *reg,
|
||||
struct wps_credential *cred)
|
||||
{
|
||||
#ifdef CONFIG_WPS2
|
||||
printf("encr_type=0x%x\n", cred->encr_type);
|
||||
if (!(cred->encr_type & (WPS_ENCR_NONE | WPS_ENCR_TKIP |
|
||||
WPS_ENCR_AES))) {
|
||||
if (cred->encr_type & WPS_ENCR_WEP) {
|
||||
wpa_printf(MSG_INFO, "WPS: Reject new AP settings "
|
||||
"due to WEP configuration");
|
||||
return -1;
|
||||
}
|
||||
|
||||
wpa_printf(MSG_INFO, "WPS: Reject new AP settings due to "
|
||||
"invalid encr_type 0x%x", cred->encr_type);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((cred->encr_type & (WPS_ENCR_TKIP | WPS_ENCR_AES)) ==
|
||||
WPS_ENCR_TKIP) {
|
||||
wpa_printf(MSG_DEBUG, "WPS: Upgrade encr_type TKIP -> "
|
||||
"TKIP+AES");
|
||||
cred->encr_type |= WPS_ENCR_AES;
|
||||
}
|
||||
|
||||
if ((cred->auth_type & (WPS_AUTH_WPAPSK | WPS_AUTH_WPA2PSK)) ==
|
||||
WPS_AUTH_WPAPSK) {
|
||||
wpa_printf(MSG_DEBUG, "WPS: Upgrade auth_type WPAPSK -> "
|
||||
"WPAPSK+WPA2PSK");
|
||||
cred->auth_type |= WPS_AUTH_WPA2PSK;
|
||||
}
|
||||
#endif /* CONFIG_WPS2 */
|
||||
|
||||
if (reg->wps->cred_cb)
|
||||
return reg->wps->cred_cb(reg->wps->cb_ctx, cred);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue