diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c index 260011d5b..9a7937417 100644 --- a/wpa_supplicant/config.c +++ b/wpa_supplicant/config.c @@ -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); } diff --git a/wpa_supplicant/config.h b/wpa_supplicant/config.h index 0cea72f99..9cb006644 100644 --- a/wpa_supplicant/config.h +++ b/wpa_supplicant/config.h @@ -253,6 +253,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 = 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 * diff --git a/wpa_supplicant/config_file.c b/wpa_supplicant/config_file.c index c19cad4cf..11f2e3acf 100644 --- a/wpa_supplicant/config_file.c +++ b/wpa_supplicant/config_file.c @@ -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", diff --git a/wpa_supplicant/config_winreg.c b/wpa_supplicant/config_winreg.c index 466908b50..48ce6035d 100644 --- a/wpa_supplicant/config_winreg.c +++ b/wpa_supplicant/config_winreg.c @@ -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; diff --git a/wpa_supplicant/win_example.reg b/wpa_supplicant/win_example.reg index 0d1f25c39..876c53c99 100755 --- a/wpa_supplicant/win_example.reg +++ b/wpa_supplicant/win_example.reg @@ -11,6 +11,13 @@ REGEDIT4 [HKEY_LOCAL_MACHINE\SOFTWARE\wpa_supplicant\configs\test] "ap_scan"=dword:00000002 "update_config"=dword:00000001 +"uuid"="12345678-9abc-def0-1234-56789abcdef0" +"device_name"="Wireless Client" +"manufacturer"="Company" +"model_name"="cmodel" +"serial_number"="12345" +"device_type"="1-0050F204-1" +"os_version"="01020300" [HKEY_LOCAL_MACHINE\SOFTWARE\wpa_supplicant\configs\test\blobs] "testblob"=hex:01,02,03,04,05 diff --git a/wpa_supplicant/wpa_supplicant.conf b/wpa_supplicant/wpa_supplicant.conf index a5a3c0df6..d4f05120a 100644 --- a/wpa_supplicant/wpa_supplicant.conf +++ b/wpa_supplicant/wpa_supplicant.conf @@ -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 = 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 # diff --git a/wpa_supplicant/wps_supplicant.c b/wpa_supplicant/wps_supplicant.c index 2b1e6b8e7..147b9c24c 100644 --- a/wpa_supplicant/wps_supplicant.c +++ b/wpa_supplicant/wps_supplicant.c @@ -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]; + /* -- */ + 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);