WPS: Make Config Methods configurable for wpa_supplicant
authorJouni Malinen <jouni.malinen@atheros.com>
Mon, 21 Dec 2009 13:59:25 +0000 (15:59 +0200)
committerJouni Malinen <j@w1.fi>
Mon, 21 Dec 2009 13:59:25 +0000 (15:59 +0200)
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
hostapd/wps_hostapd.c
src/wps/wps.h
src/wps/wps_common.c
src/wps/wps_enrollee.c
wpa_supplicant/config.c
wpa_supplicant/config.h
wpa_supplicant/config_file.c
wpa_supplicant/config_winreg.c
wpa_supplicant/wpa_supplicant.conf
wpa_supplicant/wps_supplicant.c

index 36a5aae..6254496 100644 (file)
@@ -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
index 28a1843..4cb980d 100644 (file)
@@ -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) {
index abe22d4..24351ae 100644 (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,
                            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 */
index b5e1d0f..ba39ef3 100644 (file)
@@ -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;
+}
index 33b4420..fbc41e5 100644 (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)
 {
        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) ||
index b6c5aa8..692b52f 100644 (file)
@@ -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);
 }
index 84eef48..bdc3553 100644 (file)
@@ -298,6 +298,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
         */
index 07a1e8a..5b6233e 100644 (file)
@@ -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);
index 456d417..6bd003b 100644 (file)
@@ -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",
index 1ee282a..d552014 100644 (file)
@@ -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
index 1231d44..e7b2a7a 100644 (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_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;