Added configuration of WPS device parameters for wpa_supplicant
authorJouni Malinen <j@w1.fi>
Sat, 13 Dec 2008 15:20:46 +0000 (17:20 +0200)
committerJouni Malinen <j@w1.fi>
Sat, 13 Dec 2008 15:20:46 +0000 (17:20 +0200)
wpa_supplicant/config.c
wpa_supplicant/config.h
wpa_supplicant/config_file.c
wpa_supplicant/config_winreg.c
wpa_supplicant/win_example.reg
wpa_supplicant/wpa_supplicant.conf
wpa_supplicant/wps_supplicant.c

index 260011d..9a79374 100644 (file)
@@ -1582,6 +1582,12 @@ void wpa_config_free(struct wpa_config *config)
        os_free(config->pkcs11_module_path);
 #endif /* EAP_TLS_OPENSSL */
        os_free(config->driver_param);
+       os_free(config->device_name);
+       os_free(config->manufacturer);
+       os_free(config->model_name);
+       os_free(config->model_number);
+       os_free(config->serial_number);
+       os_free(config->device_type);
        os_free(config->pssid);
        os_free(config);
 }
index 0cea72f..9cb0066 100644 (file)
@@ -254,6 +254,58 @@ struct wpa_config {
        u8 uuid[16];
 
        /**
+        * device_name - Device Name (WPS)
+        * User-friendly description of device; up to 32 octets encoded in
+        * UTF-8
+        */
+       char *device_name;
+
+       /**
+        * manufacturer - Manufacturer (WPS)
+        * The manufacturer of the device (up to 64 ASCII characters)
+        */
+       char *manufacturer;
+
+       /**
+        * model_name - Model Name (WPS)
+        * Model of the device (up to 32 ASCII characters)
+        */
+       char *model_name;
+
+       /**
+        * model_number - Model Number (WPS)
+        * Additional device description (up to 32 ASCII characters)
+        */
+       char *model_number;
+
+       /**
+        * serial_number - Serial Number (WPS)
+        * Serial number of the device (up to 32 characters)
+        */
+       char *serial_number;
+
+       /**
+        * device_type - Primary Device Type (WPS)
+        * Used format: <categ>-<OUI>-<subcateg>
+        * categ = Category as an integer value
+        * OUI = OUI and type octet as a 4-octet hex-encoded value;
+        *      0050F204 for default WPS OUI
+        * subcateg = OUI-specific Sub Category as an integer value
+        * Examples:
+        *   1-0050F204-1 (Computer / PC)
+        *   1-0050F204-2 (Computer / Server)
+        *   5-0050F204-1 (Storage / NAS)
+        *   6-0050F204-1 (Network Infrastructure / AP)
+        */
+       char *device_type;
+
+       /**
+        * os_version - OS Version (WPS)
+        * 4-octet operating system version number
+        */
+       u8 os_version[4];
+
+       /**
         * country - Country code
         *
         * This is the ISO/IEC alpha2 country code for which we are operating
index c19cad4..11f2e3a 100644 (file)
@@ -443,6 +443,7 @@ static int wpa_config_process_load_dynamic_eap(int line, char *so)
 
 
 #ifdef CONFIG_WPS
+
 static int wpa_config_process_uuid(struct wpa_config *config, int line,
                                   char *pos)
 {
@@ -455,6 +456,87 @@ static int wpa_config_process_uuid(struct wpa_config *config, int line,
        wpa_printf(MSG_DEBUG, "uuid=%s", buf);
        return 0;
 }
+
+
+static int wpa_config_process_device_name(struct wpa_config *config, char *pos)
+{
+       if (os_strlen(pos) > 32)
+               return -1;
+       os_free(config->device_name);
+       config->device_name = os_strdup(pos);
+       wpa_printf(MSG_DEBUG, "device_name='%s'", config->device_name);
+       return 0;
+}
+
+
+static int wpa_config_process_manufacturer(struct wpa_config *config,
+                                          char *pos)
+{
+       if (os_strlen(pos) > 64)
+               return -1;
+       os_free(config->manufacturer);
+       config->manufacturer = os_strdup(pos);
+       wpa_printf(MSG_DEBUG, "manufacturer='%s'", config->manufacturer);
+       return 0;
+}
+
+
+static int wpa_config_process_model_name(struct wpa_config *config, char *pos)
+{
+       if (os_strlen(pos) > 32)
+               return -1;
+       os_free(config->model_name);
+       config->model_name = os_strdup(pos);
+       wpa_printf(MSG_DEBUG, "model_name='%s'", config->model_name);
+       return 0;
+}
+
+
+static int wpa_config_process_model_number(struct wpa_config *config,
+                                          char *pos)
+{
+       if (os_strlen(pos) > 32)
+               return -1;
+       os_free(config->model_number);
+       config->model_number = os_strdup(pos);
+       wpa_printf(MSG_DEBUG, "model_number='%s'", config->model_number);
+       return 0;
+}
+
+
+static int wpa_config_process_serial_number(struct wpa_config *config,
+                                           char *pos)
+{
+       if (os_strlen(pos) > 32)
+               return -1;
+       os_free(config->serial_number);
+       config->serial_number = os_strdup(pos);
+       wpa_printf(MSG_DEBUG, "serial_number='%s'", config->serial_number);
+       return 0;
+}
+
+
+static int wpa_config_process_device_type(struct wpa_config *config, char *pos)
+{
+       os_free(config->device_type);
+       config->device_type = os_strdup(pos);
+       wpa_printf(MSG_DEBUG, "device_type='%s'", config->device_type);
+       return 0;
+}
+
+
+static int wpa_config_process_os_version(struct wpa_config *config, int line,
+                                        char *pos)
+{
+       if (hexstr2bin(pos, config->os_version, 4)) {
+               wpa_printf(MSG_ERROR, "Line %d: invalid os_version", line);
+               return -1;
+       }
+       wpa_printf(MSG_DEBUG, "os_version=%08x",
+                  WPA_GET_BE32(config->os_version));
+       return 0;
+}
+
 #endif /* CONFIG_WPS */
 
 
@@ -515,6 +597,20 @@ static int wpa_config_process_global(struct wpa_config *config, char *pos,
 #ifdef CONFIG_WPS
        if (os_strncmp(pos, "uuid=", 5) == 0)
                return wpa_config_process_uuid(config, line, pos + 5);
+       if (os_strncmp(pos, "device_name=", 12) == 0)
+               return wpa_config_process_device_name(config, pos + 12);
+       if (os_strncmp(pos, "manufacturer=", 13) == 0)
+               return wpa_config_process_manufacturer(config, pos + 13);
+       if (os_strncmp(pos, "model_name=", 11) == 0)
+               return wpa_config_process_model_name(config, pos + 11);
+       if (os_strncmp(pos, "model_number=", 13) == 0)
+               return wpa_config_process_model_number(config, pos + 13);
+       if (os_strncmp(pos, "serial_number=", 14) == 0)
+               return wpa_config_process_serial_number(config, pos + 14);
+       if (os_strncmp(pos, "device_type=", 12) == 0)
+               return wpa_config_process_device_type(config, pos + 12);
+       if (os_strncmp(pos, "os_version=", 11) == 0)
+               return wpa_config_process_os_version(config, line, pos + 11);
 #endif /* CONFIG_WPS */
 
        if (os_strncmp(pos, "country=", 8) == 0)
@@ -890,6 +986,21 @@ static void wpa_config_write_global(FILE *f, struct wpa_config *config)
                uuid_bin2str(config->uuid, buf, sizeof(buf));
                fprintf(f, "uuid=%s\n", buf);
        }
+       if (config->device_name)
+               fprintf(f, "device_name=%s\n", config->device_name);
+       if (config->manufacturer)
+               fprintf(f, "manufacturer=%s\n", config->manufacturer);
+       if (config->model_name)
+               fprintf(f, "model_name=%s\n", config->model_name);
+       if (config->model_number)
+               fprintf(f, "model_number=%s\n", config->model_number);
+       if (config->serial_number)
+               fprintf(f, "serial_number=%s\n", config->serial_number);
+       if (config->device_type)
+               fprintf(f, "device_type=%s\n", config->device_type);
+       if (config->os_version)
+               fprintf(f, "os_version=%08x\n",
+                       WPA_GET_BE32(config->os_version));
 #endif /* CONFIG_WPS */
        if (config->country[0] && config->country[1]) {
                fprintf(f, "country=%c%c\n",
index 466908b..48ce603 100644 (file)
@@ -179,6 +179,25 @@ static int wpa_config_read_global_uuid(struct wpa_config *config, HKEY hk)
 
        return ret;
 }
+
+
+static int wpa_config_read_global_os_version(struct wpa_config *config,
+                                            HKEY hk)
+{
+       char *str;
+       int ret = 0;
+
+       str = wpa_config_read_reg_string(hk, TEXT("os_version"));
+       if (str == NULL)
+               return 0;
+
+       if (hexstr2bin(str, config->os_version, 4))
+               ret = -1;
+
+       os_free(str);
+
+       return ret;
+}
 #endif /* CONFIG_WPS */
 
 
@@ -190,12 +209,13 @@ static int wpa_config_read_global(struct wpa_config *config, HKEY hk)
        wpa_config_read_reg_dword(hk, TEXT("fast_reauth"),
                                  &config->fast_reauth);
        wpa_config_read_reg_dword(hk, TEXT("dot11RSNAConfigPMKLifetime"),
-                                 &config->dot11RSNAConfigPMKLifetime);
+                                 (int *) &config->dot11RSNAConfigPMKLifetime);
        wpa_config_read_reg_dword(hk,
                                  TEXT("dot11RSNAConfigPMKReauthThreshold"),
+                                 (int *)
                                  &config->dot11RSNAConfigPMKReauthThreshold);
        wpa_config_read_reg_dword(hk, TEXT("dot11RSNAConfigSATimeout"),
-                                 &config->dot11RSNAConfigSATimeout);
+                                 (int *) &config->dot11RSNAConfigSATimeout);
        wpa_config_read_reg_dword(hk, TEXT("update_config"),
                                  &config->update_config);
 
@@ -215,6 +235,18 @@ static int wpa_config_read_global(struct wpa_config *config, HKEY hk)
 #ifdef CONFIG_WPS
        if (wpa_config_read_global_uuid(config, hk))
                errors++;
+       config->device_name = wpa_config_read_reg_string(
+               hk, TEXT("device_name"));
+       config->manufacturer = wpa_config_read_reg_string(
+               hk, TEXT("manufacturer"));
+       config->model_name = wpa_config_read_reg_string(
+               hk, TEXT("model_name"));
+       config->serial_number = wpa_config_read_reg_string(
+               hk, TEXT("serial_number"));
+       config->device_type = wpa_config_read_reg_string(
+               hk, TEXT("device_type"));
+       if (wpa_config_read_global_os_version(config, hk))
+               errors++;
 #endif /* CONFIG_WPS */
 
        return errors ? -1 : 0;
@@ -524,6 +556,19 @@ static int wpa_config_write_global(struct wpa_config *config, HKEY hk)
                uuid_bin2str(config->uuid, buf, sizeof(buf));
                wpa_config_write_reg_string(hk, "uuid", buf);
        }
+       wpa_config_write_reg_string(hk, "device_name", config->device_name);
+       wpa_config_write_reg_string(hk, "manufacturer", config->manufacturer);
+       wpa_config_write_reg_string(hk, "model_name", config->model_name);
+       wpa_config_write_reg_string(hk, "model_number", config->model_number);
+       wpa_config_write_reg_string(hk, "serial_number",
+                                   config->serial_number);
+       wpa_config_write_reg_string(hk, "device_type", config->device_type);
+       if (WPA_GET_BE32(config->os_version)) {
+               char vbuf[10];
+               os_snprintf(vbuf, sizeof(vbuf), "%08x",
+                           WPA_GET_BE32(config->os_version));
+               wpa_config_write_reg_string(hk, "os_version", vbuf);
+       }
 #endif /* CONFIG_WPS */
 
        return 0;
index 0d1f25c..876c53c 100755 (executable)
@@ -11,6 +11,13 @@ REGEDIT4
 [HKEY_LOCAL_MACHINE\SOFTWARE\wpa_supplicant\configs\test]\r
 "ap_scan"=dword:00000002\r
 "update_config"=dword:00000001\r
+"uuid"="12345678-9abc-def0-1234-56789abcdef0"\r
+"device_name"="Wireless Client"\r
+"manufacturer"="Company"\r
+"model_name"="cmodel"\r
+"serial_number"="12345"\r
+"device_type"="1-0050F204-1"\r
+"os_version"="01020300"\r
 \r
 [HKEY_LOCAL_MACHINE\SOFTWARE\wpa_supplicant\configs\test\blobs]\r
 "testblob"=hex:01,02,03,04,05\r
index a5a3c0d..d4f0512 100644 (file)
@@ -152,6 +152,43 @@ fast_reauth=1
 # Universally Unique IDentifier (UUID; see RFC 4122) of the device
 #uuid=12345678-9abc-def0-1234-56789abcdef0
 
+# Device Name
+# User-friendly description of device; up to 32 octets encoded in UTF-8
+#device_name=Wireless Client
+
+# Manufacturer
+# The manufacturer of the device (up to 64 ASCII characters)
+#manufacturer=Company
+
+# Model Name
+# Model of the device (up to 32 ASCII characters)
+#model_name=cmodel
+
+# Model Number
+# Additional device description (up to 32 ASCII characters)
+#model_number=123
+
+# Serial Number
+# Serial number of the device (up to 32 characters)
+#serial_number=12345
+
+# Primary Device Type
+# Used format: <categ>-<OUI>-<subcateg>
+# categ = Category as an integer value
+# OUI = OUI and type octet as a 4-octet hex-encoded value; 0050F204 for
+#       default WPS OUI
+# subcateg = OUI-specific Sub Category as an integer value
+# Examples:
+#   1-0050F204-1 (Computer / PC)
+#   1-0050F204-2 (Computer / Server)
+#   5-0050F204-1 (Storage / NAS)
+#   6-0050F204-1 (Network Infrastructure / AP)
+#device_type=6-0050F204-1
+
+# OS Version
+# 4-octet operating system version number (hex string)
+#os_version=01020300
+
 
 # network block
 #
index 2b1e6b8..147b9c2 100644 (file)
@@ -360,17 +360,40 @@ int wpas_wps_init(struct wpa_supplicant *wpa_s)
        wps->cred_cb = wpa_supplicant_wps_cred;
        wps->cb_ctx = wpa_s;
 
-       /* TODO: make the device data configurable */
-       wps->dev.device_name = "dev name";
-       wps->dev.manufacturer = "manuf";
-       wps->dev.model_name = "model name";
-       wps->dev.model_number = "model number";
-       wps->dev.serial_number = "12345";
-       wps->dev.categ = WPS_DEV_COMPUTER;
-       wps->dev.oui = WPS_DEV_OUI_WFA;
-       wps->dev.sub_categ = WPS_DEV_COMPUTER_PC;
-       wps->dev.os_version = 0;
-       wps->dev.rf_bands = WPS_RF_24GHZ | WPS_RF_50GHZ;
+       wps->dev.device_name = wpa_s->conf->device_name;
+       wps->dev.manufacturer = wpa_s->conf->manufacturer;
+       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;
+       if (wpa_s->conf->device_type) {
+               char *pos;
+               u8 oui[4];
+               /* <categ>-<OUI>-<subcateg> */
+               wps->dev.categ = atoi(wpa_s->conf->device_type);
+               pos = os_strchr(wpa_s->conf->device_type, '-');
+               if (pos == NULL) {
+                       wpa_printf(MSG_ERROR, "WPS: Invalid device_type");
+                       os_free(wps);
+                       return -1;
+               }
+               pos++;
+               if (hexstr2bin(pos, oui, 4)) {
+                       wpa_printf(MSG_ERROR, "WPS: Invalid device_type OUI");
+                       os_free(wps);
+                       return -1;
+               }
+               wps->dev.oui = WPA_GET_BE32(oui);
+               pos = os_strchr(pos, '-');
+               if (pos == NULL) {
+                       wpa_printf(MSG_ERROR, "WPS: Invalid device_type");
+                       os_free(wps);
+                       return -1;
+               }
+               pos++;
+               wps->dev.sub_categ = atoi(pos);
+       }
+       wps->dev.os_version = WPA_GET_BE32(wpa_s->conf->os_version);
+       wps->dev.rf_bands = WPS_RF_24GHZ | WPS_RF_50GHZ; /* TODO: config */
        os_memcpy(wps->dev.mac_addr, wpa_s->own_addr, ETH_ALEN);
        os_memcpy(wps->uuid, wpa_s->conf->uuid, 16);