WPS: Make Config Methods configurable for wpa_supplicant

This adds config_methods configuration option for wpa_supplicant
following the design used in hostapd. In addition, the string is
now parsed in common code from src/wps/wps_common.c and the list
of configurable methods include all the defined methods from
WPS 1.0h spec.
This commit is contained in:
Jouni Malinen 2009-12-21 15:59:25 +02:00 committed by Jouni Malinen
parent b64576fcf5
commit c0e4dd9eeb
11 changed files with 71 additions and 25 deletions

View file

@ -891,6 +891,8 @@ own_ip_addr=127.0.0.1
# Config Methods # Config Methods
# List of the supported configuration methods # List of the supported configuration methods
# Available methods: usba ethernet label display ext_nfc_token int_nfc_token
# nfc_interface push_button keypad
#config_methods=label display push_button keypad #config_methods=label display push_button keypad
# Access point PIN for initial configuration and adding Registrars # Access point PIN for initial configuration and adding Registrars

View file

@ -531,17 +531,8 @@ int hostapd_init_wps(struct hostapd_data *hapd,
os_strdup(hapd->conf->model_number) : NULL; os_strdup(hapd->conf->model_number) : NULL;
wps->dev.serial_number = hapd->conf->serial_number ? wps->dev.serial_number = hapd->conf->serial_number ?
os_strdup(hapd->conf->serial_number) : NULL; os_strdup(hapd->conf->serial_number) : NULL;
if (hapd->conf->config_methods) { wps->config_methods =
char *m = hapd->conf->config_methods; wps_config_methods_str2bin(hapd->conf->config_methods);
if (os_strstr(m, "label"))
wps->config_methods |= WPS_CONFIG_LABEL;
if (os_strstr(m, "display"))
wps->config_methods |= WPS_CONFIG_DISPLAY;
if (os_strstr(m, "push_button"))
wps->config_methods |= WPS_CONFIG_PUSHBUTTON;
if (os_strstr(m, "keypad"))
wps->config_methods |= WPS_CONFIG_KEYPAD;
}
if (hapd->conf->device_type && if (hapd->conf->device_type &&
wps_dev_type_str2bin(hapd->conf->device_type, wps_dev_type_str2bin(hapd->conf->device_type,
wps->dev.pri_dev_type) < 0) { wps->dev.pri_dev_type) < 0) {

View file

@ -715,5 +715,6 @@ int wps_dev_type_str2bin(const char *str, u8 dev_type[WPS_DEV_TYPE_LEN]);
char * wps_dev_type_bin2str(const u8 dev_type[WPS_DEV_TYPE_LEN], char *buf, char * wps_dev_type_bin2str(const u8 dev_type[WPS_DEV_TYPE_LEN], char *buf,
size_t buf_len); size_t buf_len);
void uuid_gen_mac_addr(const u8 *mac_addr, u8 *uuid); void uuid_gen_mac_addr(const u8 *mac_addr, u8 *uuid);
u16 wps_config_methods_str2bin(const char *str);
#endif /* WPS_H */ #endif /* WPS_H */

View file

@ -595,3 +595,42 @@ void uuid_gen_mac_addr(const u8 *mac_addr, u8 *uuid)
/* Variant specified in RFC 4122 */ /* Variant specified in RFC 4122 */
uuid[8] = 0x80 | (uuid[8] & 0x3f); uuid[8] = 0x80 | (uuid[8] & 0x3f);
} }
u16 wps_config_methods_str2bin(const char *str)
{
u16 methods = 0;
if (str == NULL) {
/* Default to enabling methods based on build configuration */
methods |= WPS_CONFIG_LABEL | WPS_CONFIG_DISPLAY |
WPS_CONFIG_KEYPAD;
#ifdef CONFIG_WPS_UFD
methods |= WPS_CONFIG_USBA;
#endif /* CONFIG_WPS_UFD */
#ifdef CONFIG_WPS_NFC
methods |= WPS_CONFIG_NFC_INTERFACE;
#endif /* CONFIG_WPS_NFC */
} else {
if (os_strstr(str, "usba"))
methods |= WPS_CONFIG_USBA;
if (os_strstr(str, "ethernet"))
methods |= WPS_CONFIG_ETHERNET;
if (os_strstr(str, "label"))
methods |= WPS_CONFIG_LABEL;
if (os_strstr(str, "display"))
methods |= WPS_CONFIG_DISPLAY;
if (os_strstr(str, "ext_nfc_token"))
methods |= WPS_CONFIG_EXT_NFC_TOKEN;
if (os_strstr(str, "int_nfc_token"))
methods |= WPS_CONFIG_INT_NFC_TOKEN;
if (os_strstr(str, "nfc_interface"))
methods |= WPS_CONFIG_NFC_INTERFACE;
if (os_strstr(str, "push_button"))
methods |= WPS_CONFIG_PUSHBUTTON;
if (os_strstr(str, "keypad"))
methods |= WPS_CONFIG_KEYPAD;
}
return methods;
}

View file

@ -119,7 +119,6 @@ static int wps_build_e_snonce2(struct wps_data *wps, struct wpabuf *msg)
static struct wpabuf * wps_build_m1(struct wps_data *wps) static struct wpabuf * wps_build_m1(struct wps_data *wps)
{ {
struct wpabuf *msg; struct wpabuf *msg;
u16 methods;
if (os_get_random(wps->nonce_e, WPS_NONCE_LEN) < 0) if (os_get_random(wps->nonce_e, WPS_NONCE_LEN) < 0)
return NULL; return NULL;
@ -131,16 +130,6 @@ static struct wpabuf * wps_build_m1(struct wps_data *wps)
if (msg == NULL) if (msg == NULL)
return NULL; return NULL;
methods = WPS_CONFIG_LABEL | WPS_CONFIG_DISPLAY | WPS_CONFIG_KEYPAD;
#ifdef CONFIG_WPS_UFD
methods |= WPS_CONFIG_USBA;
#endif /* CONFIG_WPS_UFD */
#ifdef CONFIG_WPS_NFC
methods |= WPS_CONFIG_NFC_INTERFACE;
#endif /* CONFIG_WPS_NFC */
if (wps->pbc)
methods |= WPS_CONFIG_PUSHBUTTON;
if (wps_build_version(msg) || if (wps_build_version(msg) ||
wps_build_msg_type(msg, WPS_M1) || wps_build_msg_type(msg, WPS_M1) ||
wps_build_uuid_e(msg, wps->uuid_e) || wps_build_uuid_e(msg, wps->uuid_e) ||
@ -150,7 +139,7 @@ static struct wpabuf * wps_build_m1(struct wps_data *wps)
wps_build_auth_type_flags(wps, msg) || wps_build_auth_type_flags(wps, msg) ||
wps_build_encr_type_flags(wps, msg) || wps_build_encr_type_flags(wps, msg) ||
wps_build_conn_type_flags(wps, msg) || wps_build_conn_type_flags(wps, msg) ||
wps_build_config_methods(msg, methods) || wps_build_config_methods(msg, wps->wps->config_methods) ||
wps_build_wps_state(wps, msg) || wps_build_wps_state(wps, msg) ||
wps_build_device_attrs(&wps->wps->dev, msg) || wps_build_device_attrs(&wps->wps->dev, msg) ||
wps_build_rf_bands(&wps->wps->dev, msg) || wps_build_rf_bands(&wps->wps->dev, msg) ||

View file

@ -1671,6 +1671,7 @@ void wpa_config_free(struct wpa_config *config)
os_free(config->model_number); os_free(config->model_number);
os_free(config->serial_number); os_free(config->serial_number);
os_free(config->device_type); os_free(config->device_type);
os_free(config->config_methods);
os_free(config->pssid); os_free(config->pssid);
os_free(config); os_free(config);
} }

View file

@ -297,6 +297,16 @@ struct wpa_config {
*/ */
char *device_type; char *device_type;
/**
* config_methods - Config Methods
*
* This is a space-separated list of supported WPS configuration
* methods. For example, "label display push_button keypad".
* Available methods: usba ethernet label display ext_nfc_token
* int_nfc_token nfc_interface push_button keypad.
*/
char *config_methods;
/** /**
* os_version - OS Version (WPS) * os_version - OS Version (WPS)
* 4-octet operating system version number * 4-octet operating system version number

View file

@ -454,6 +454,7 @@ static const struct global_parse_data global_fields[] = {
{ STR_RANGE(serial_number, 0, 32) }, { STR_RANGE(serial_number, 0, 32) },
{ STR(device_type) }, { STR(device_type) },
{ FUNC(os_version) }, { FUNC(os_version) },
{ STR(config_methods) },
{ INT_RANGE(wps_cred_processing, 0, 2) }, { INT_RANGE(wps_cred_processing, 0, 2) },
#endif /* CONFIG_WPS */ #endif /* CONFIG_WPS */
{ FUNC(country) } { FUNC(country) }
@ -878,6 +879,8 @@ static void wpa_config_write_global(FILE *f, struct wpa_config *config)
if (WPA_GET_BE32(config->os_version)) if (WPA_GET_BE32(config->os_version))
fprintf(f, "os_version=%08x\n", fprintf(f, "os_version=%08x\n",
WPA_GET_BE32(config->os_version)); WPA_GET_BE32(config->os_version));
if (config->config_methods)
fprintf(f, "config_methods=%s\n", config->config_methods);
if (config->wps_cred_processing) if (config->wps_cred_processing)
fprintf(f, "wps_cred_processing=%d\n", fprintf(f, "wps_cred_processing=%d\n",
config->wps_cred_processing); config->wps_cred_processing);

View file

@ -249,6 +249,8 @@ static int wpa_config_read_global(struct wpa_config *config, HKEY hk)
hk, TEXT("serial_number")); hk, TEXT("serial_number"));
config->device_type = wpa_config_read_reg_string( config->device_type = wpa_config_read_reg_string(
hk, TEXT("device_type")); hk, TEXT("device_type"));
config->config_methods = wpa_config_read_reg_string(
hk, TEXT("config_methods"));
if (wpa_config_read_global_os_version(config, hk)) if (wpa_config_read_global_os_version(config, hk))
errors++; errors++;
wpa_config_read_reg_dword(hk, TEXT("wps_cred_processing"), wpa_config_read_reg_dword(hk, TEXT("wps_cred_processing"),
@ -569,6 +571,8 @@ static int wpa_config_write_global(struct wpa_config *config, HKEY hk)
wpa_config_write_reg_string(hk, "serial_number", wpa_config_write_reg_string(hk, "serial_number",
config->serial_number); config->serial_number);
wpa_config_write_reg_string(hk, "device_type", config->device_type); wpa_config_write_reg_string(hk, "device_type", config->device_type);
wpa_config_write_reg_string(hk, "config_methods",
config->config_methods);
if (WPA_GET_BE32(config->os_version)) { if (WPA_GET_BE32(config->os_version)) {
char vbuf[10]; char vbuf[10];
os_snprintf(vbuf, sizeof(vbuf), "%08x", os_snprintf(vbuf, sizeof(vbuf), "%08x",

View file

@ -196,6 +196,12 @@ fast_reauth=1
# 4-octet operating system version number (hex string) # 4-octet operating system version number (hex string)
#os_version=01020300 #os_version=01020300
# Config Methods
# List of the supported configuration methods
# Available methods: usba ethernet label display ext_nfc_token int_nfc_token
# nfc_interface push_button keypad
#config_methods=label display push_button keypad
# Credential processing # Credential processing
# 0 = process received credentials internally (default) # 0 = process received credentials internally (default)
# 1 = do not process received credentials; just pass them over ctrl_iface to # 1 = do not process received credentials; just pass them over ctrl_iface to

View file

@ -841,6 +841,8 @@ int wpas_wps_init(struct wpa_supplicant *wpa_s)
wps->dev.model_name = wpa_s->conf->model_name; wps->dev.model_name = wpa_s->conf->model_name;
wps->dev.model_number = wpa_s->conf->model_number; wps->dev.model_number = wpa_s->conf->model_number;
wps->dev.serial_number = wpa_s->conf->serial_number; wps->dev.serial_number = wpa_s->conf->serial_number;
wps->config_methods =
wps_config_methods_str2bin(wpa_s->conf->config_methods);
if (wpa_s->conf->device_type && if (wpa_s->conf->device_type &&
wps_dev_type_str2bin(wpa_s->conf->device_type, wps_dev_type_str2bin(wpa_s->conf->device_type,
wps->dev.pri_dev_type) < 0) { wps->dev.pri_dev_type) < 0) {
@ -1116,8 +1118,6 @@ int wpas_wps_er_start(struct wpa_supplicant *wpa_s)
wps_er_refresh(wpa_s->wps_er); wps_er_refresh(wpa_s->wps_er);
return 0; return 0;
} }
wpa_s->wps->config_methods |= WPS_CONFIG_DISPLAY;
wpa_s->wps->config_methods |= WPS_CONFIG_KEYPAD;
wpa_s->wps_er = wps_er_init(wpa_s->wps, wpa_s->ifname); wpa_s->wps_er = wps_er_init(wpa_s->wps, wpa_s->ifname);
if (wpa_s->wps_er == NULL) if (wpa_s->wps_er == NULL)
return -1; return -1;