From c0e4dd9eeb96fa39cc8bd6151fbf5a7a9cc46a97 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Mon, 21 Dec 2009 15:59:25 +0200 Subject: [PATCH] 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. --- hostapd/hostapd.conf | 2 ++ hostapd/wps_hostapd.c | 13 ++-------- src/wps/wps.h | 1 + src/wps/wps_common.c | 39 ++++++++++++++++++++++++++++++ src/wps/wps_enrollee.c | 13 +--------- wpa_supplicant/config.c | 1 + wpa_supplicant/config.h | 10 ++++++++ wpa_supplicant/config_file.c | 3 +++ wpa_supplicant/config_winreg.c | 4 +++ wpa_supplicant/wpa_supplicant.conf | 6 +++++ wpa_supplicant/wps_supplicant.c | 4 +-- 11 files changed, 71 insertions(+), 25 deletions(-) diff --git a/hostapd/hostapd.conf b/hostapd/hostapd.conf index 36a5aae1d..625449663 100644 --- a/hostapd/hostapd.conf +++ b/hostapd/hostapd.conf @@ -891,6 +891,8 @@ own_ip_addr=127.0.0.1 # 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 # Access point PIN for initial configuration and adding Registrars diff --git a/hostapd/wps_hostapd.c b/hostapd/wps_hostapd.c index 28a184348..4cb980d66 100644 --- a/hostapd/wps_hostapd.c +++ b/hostapd/wps_hostapd.c @@ -531,17 +531,8 @@ int hostapd_init_wps(struct hostapd_data *hapd, os_strdup(hapd->conf->model_number) : NULL; wps->dev.serial_number = hapd->conf->serial_number ? os_strdup(hapd->conf->serial_number) : NULL; - if (hapd->conf->config_methods) { - char *m = 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; - } + wps->config_methods = + wps_config_methods_str2bin(hapd->conf->config_methods); if (hapd->conf->device_type && wps_dev_type_str2bin(hapd->conf->device_type, wps->dev.pri_dev_type) < 0) { diff --git a/src/wps/wps.h b/src/wps/wps.h index abe22d40d..24351ae76 100644 --- a/src/wps/wps.h +++ b/src/wps/wps.h @@ -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, size_t buf_len); void uuid_gen_mac_addr(const u8 *mac_addr, u8 *uuid); +u16 wps_config_methods_str2bin(const char *str); #endif /* WPS_H */ diff --git a/src/wps/wps_common.c b/src/wps/wps_common.c index b5e1d0fc1..ba39ef3e0 100644 --- a/src/wps/wps_common.c +++ b/src/wps/wps_common.c @@ -595,3 +595,42 @@ void uuid_gen_mac_addr(const u8 *mac_addr, u8 *uuid) /* Variant specified in RFC 4122 */ 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; +} diff --git a/src/wps/wps_enrollee.c b/src/wps/wps_enrollee.c index 33b442061..fbc41e5d2 100644 --- a/src/wps/wps_enrollee.c +++ b/src/wps/wps_enrollee.c @@ -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) { struct wpabuf *msg; - u16 methods; if (os_get_random(wps->nonce_e, WPS_NONCE_LEN) < 0) return NULL; @@ -131,16 +130,6 @@ static struct wpabuf * wps_build_m1(struct wps_data *wps) if (msg == 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) || wps_build_msg_type(msg, WPS_M1) || 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_encr_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_device_attrs(&wps->wps->dev, msg) || wps_build_rf_bands(&wps->wps->dev, msg) || diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c index b6c5aa89a..692b52f27 100644 --- a/wpa_supplicant/config.c +++ b/wpa_supplicant/config.c @@ -1671,6 +1671,7 @@ void wpa_config_free(struct wpa_config *config) os_free(config->model_number); os_free(config->serial_number); os_free(config->device_type); + os_free(config->config_methods); os_free(config->pssid); os_free(config); } diff --git a/wpa_supplicant/config.h b/wpa_supplicant/config.h index 84eef48a1..bdc3553c8 100644 --- a/wpa_supplicant/config.h +++ b/wpa_supplicant/config.h @@ -297,6 +297,16 @@ struct wpa_config { */ 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) * 4-octet operating system version number diff --git a/wpa_supplicant/config_file.c b/wpa_supplicant/config_file.c index 07a1e8ae1..5b6233e63 100644 --- a/wpa_supplicant/config_file.c +++ b/wpa_supplicant/config_file.c @@ -454,6 +454,7 @@ static const struct global_parse_data global_fields[] = { { STR_RANGE(serial_number, 0, 32) }, { STR(device_type) }, { FUNC(os_version) }, + { STR(config_methods) }, { INT_RANGE(wps_cred_processing, 0, 2) }, #endif /* CONFIG_WPS */ { 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)) fprintf(f, "os_version=%08x\n", WPA_GET_BE32(config->os_version)); + if (config->config_methods) + fprintf(f, "config_methods=%s\n", config->config_methods); if (config->wps_cred_processing) fprintf(f, "wps_cred_processing=%d\n", config->wps_cred_processing); diff --git a/wpa_supplicant/config_winreg.c b/wpa_supplicant/config_winreg.c index 456d41792..6bd003b6b 100644 --- a/wpa_supplicant/config_winreg.c +++ b/wpa_supplicant/config_winreg.c @@ -249,6 +249,8 @@ static int wpa_config_read_global(struct wpa_config *config, HKEY hk) hk, TEXT("serial_number")); config->device_type = wpa_config_read_reg_string( 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)) errors++; 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", config->serial_number); 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)) { char vbuf[10]; os_snprintf(vbuf, sizeof(vbuf), "%08x", diff --git a/wpa_supplicant/wpa_supplicant.conf b/wpa_supplicant/wpa_supplicant.conf index 1ee282a5f..d552014df 100644 --- a/wpa_supplicant/wpa_supplicant.conf +++ b/wpa_supplicant/wpa_supplicant.conf @@ -196,6 +196,12 @@ fast_reauth=1 # 4-octet operating system version number (hex string) #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 # 0 = process received credentials internally (default) # 1 = do not process received credentials; just pass them over ctrl_iface to diff --git a/wpa_supplicant/wps_supplicant.c b/wpa_supplicant/wps_supplicant.c index 1231d44db..e7b2a7aa2 100644 --- a/wpa_supplicant/wps_supplicant.c +++ b/wpa_supplicant/wps_supplicant.c @@ -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_number = wpa_s->conf->model_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 && wps_dev_type_str2bin(wpa_s->conf->device_type, 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); 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); if (wpa_s->wps_er == NULL) return -1;