From 2f646b6e83f47b99202f7b18d5d45ef633c6cfa5 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 17 Mar 2011 18:50:22 +0200 Subject: [PATCH] WPS: Store (secondary) device type as binary Instead of converting back and forth from the string representation, always use the binary representation internally. Signed-off-by: Johannes Berg --- hostapd/config_file.c | 4 +- src/ap/ap_config.c | 1 - src/ap/ap_config.h | 3 +- src/ap/wps_hostapd.c | 10 ++-- wpa_supplicant/ap.c | 4 +- wpa_supplicant/config.c | 26 +++++---- wpa_supplicant/config.h | 19 ++----- wpa_supplicant/config_file.c | 8 ++- wpa_supplicant/config_winreg.c | 16 ++++-- wpa_supplicant/p2p_supplicant.c | 96 ++++++++------------------------- wpa_supplicant/wps_supplicant.c | 58 ++++---------------- 11 files changed, 82 insertions(+), 163 deletions(-) diff --git a/hostapd/config_file.c b/hostapd/config_file.c index e89205972..4b8b16a75 100644 --- a/hostapd/config_file.c +++ b/hostapd/config_file.c @@ -1966,8 +1966,8 @@ struct hostapd_config * hostapd_config_read(const char *fname) os_free(bss->serial_number); bss->serial_number = os_strdup(pos); } else if (os_strcmp(buf, "device_type") == 0) { - os_free(bss->device_type); - bss->device_type = os_strdup(pos); + if (wps_dev_type_str2bin(pos, bss->device_type)) + errors++; } else if (os_strcmp(buf, "config_methods") == 0) { os_free(bss->config_methods); bss->config_methods = os_strdup(pos); diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c index 3fd82763f..e77716bd3 100644 --- a/src/ap/ap_config.c +++ b/src/ap/ap_config.c @@ -456,7 +456,6 @@ static void hostapd_config_free_bss(struct hostapd_bss_config *conf) os_free(conf->model_name); os_free(conf->model_number); os_free(conf->serial_number); - os_free(conf->device_type); os_free(conf->config_methods); os_free(conf->ap_pin); os_free(conf->extra_cred); diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h index 0016a7c9b..fbe8734ff 100644 --- a/src/ap/ap_config.h +++ b/src/ap/ap_config.h @@ -18,6 +18,7 @@ #include "common/defs.h" #include "ip_addr.h" #include "common/wpa_common.h" +#include "wps/wps.h" #define MAX_STA_COUNT 2007 #define MAX_VLAN_ID 4094 @@ -299,7 +300,7 @@ struct hostapd_bss_config { char *model_name; char *model_number; char *serial_number; - char *device_type; + u8 device_type[WPS_DEV_TYPE_LEN]; char *config_methods; u8 os_version[4]; char *ap_pin; diff --git a/src/ap/wps_hostapd.c b/src/ap/wps_hostapd.c index d5042c046..92a6dd4a6 100644 --- a/src/ap/wps_hostapd.c +++ b/src/ap/wps_hostapd.c @@ -728,13 +728,9 @@ int hostapd_init_wps(struct hostapd_data *hapd, wps->config_methods |= WPS_CONFIG_VIRT_PUSHBUTTON; } #endif /* CONFIG_WPS2 */ - if (hapd->conf->device_type && - wps_dev_type_str2bin(hapd->conf->device_type, - wps->dev.pri_dev_type) < 0) { - wpa_printf(MSG_ERROR, "WPS: Invalid device_type"); - os_free(wps); - return -1; - } + os_memcpy(wps->dev.pri_dev_type, hapd->conf->device_type, + WPS_DEV_TYPE_LEN); + wps->dev.os_version = WPA_GET_BE32(hapd->conf->os_version); wps->dev.rf_bands = hapd->iconf->hw_mode == HOSTAPD_MODE_IEEE80211A ? WPS_RF_50GHZ : WPS_RF_24GHZ; /* FIX: dualband AP */ diff --git a/wpa_supplicant/ap.c b/wpa_supplicant/ap.c index 77e5b78a3..fb7a10fdd 100644 --- a/wpa_supplicant/ap.c +++ b/wpa_supplicant/ap.c @@ -169,8 +169,8 @@ static int wpa_supplicant_conf_ap(struct wpa_supplicant *wpa_s, bss->ap_setup_locked = 2; if (wpa_s->conf->config_methods) bss->config_methods = os_strdup(wpa_s->conf->config_methods); - if (wpa_s->conf->device_type) - bss->device_type = os_strdup(wpa_s->conf->device_type); + os_memcpy(bss->device_type, wpa_s->conf->device_type, + WPS_DEV_TYPE_LEN); if (wpa_s->conf->device_name) { bss->device_name = os_strdup(wpa_s->conf->device_name); bss->friendly_name = os_strdup(wpa_s->conf->device_name); diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c index d732f5456..de68ec845 100644 --- a/wpa_supplicant/config.c +++ b/wpa_supplicant/config.c @@ -1694,7 +1694,6 @@ void wpa_config_free(struct wpa_config *config) struct wpa_config_blob *blob, *prevblob; #endif /* CONFIG_NO_CONFIG_BLOBS */ struct wpa_ssid *ssid, *prev = NULL; - int i; ssid = config->ssid; while (ssid) { @@ -1724,9 +1723,6 @@ void wpa_config_free(struct wpa_config *config) os_free(config->model_name); os_free(config->model_number); os_free(config->serial_number); - os_free(config->device_type); - for (i = 0; i < MAX_SEC_DEVICE_TYPES; i++) - os_free(config->sec_device_type[i]); os_free(config->config_methods); os_free(config->p2p_ssid_postfix); os_free(config->pssid); @@ -2311,6 +2307,14 @@ static int wpa_config_process_uuid(const struct global_parse_data *data, } +static int wpa_config_process_device_type( + const struct global_parse_data *data, + struct wpa_config *config, int line, const char *pos) +{ + return wps_dev_type_str2bin(pos, config->device_type); +} + + static int wpa_config_process_os_version(const struct global_parse_data *data, struct wpa_config *config, int line, const char *pos) @@ -2333,18 +2337,18 @@ static int wpa_config_process_sec_device_type( { int idx; - for (idx = 0; idx < MAX_SEC_DEVICE_TYPES; idx++) - if (config->sec_device_type[idx] == NULL) - break; - if (idx == MAX_SEC_DEVICE_TYPES) { + if (config->num_sec_device_types >= MAX_SEC_DEVICE_TYPES) { wpa_printf(MSG_ERROR, "Line %d: too many sec_device_type " "items", line); return -1; } - config->sec_device_type[idx] = os_strdup(pos); - if (config->sec_device_type[idx] == NULL) + idx = config->num_sec_device_types; + + if (wps_dev_type_str2bin(pos, config->sec_device_type[idx])) return -1; + + config->num_sec_device_types++; return 0; } #endif /* CONFIG_P2P */ @@ -2391,7 +2395,7 @@ static const struct global_parse_data global_fields[] = { { STR_RANGE(model_name, 0, 32), CFG_CHANGED_WPS_STRING }, { STR_RANGE(model_number, 0, 32), CFG_CHANGED_WPS_STRING }, { STR_RANGE(serial_number, 0, 32), CFG_CHANGED_WPS_STRING }, - { STR(device_type), CFG_CHANGED_DEVICE_TYPE }, + { FUNC(device_type), CFG_CHANGED_DEVICE_TYPE }, { FUNC(os_version), CFG_CHANGED_OS_VERSION }, { STR(config_methods), CFG_CHANGED_CONFIG_METHODS }, { INT_RANGE(wps_cred_processing, 0, 2), 0 }, diff --git a/wpa_supplicant/config.h b/wpa_supplicant/config.h index c0ac41fa1..cf22ec409 100644 --- a/wpa_supplicant/config.h +++ b/wpa_supplicant/config.h @@ -28,6 +28,7 @@ #define DEFAULT_MAX_NUM_STA 128 #include "config_ssid.h" +#include "wps/wps.h" #define CFG_CHANGED_DEVICE_NAME BIT(0) @@ -299,18 +300,8 @@ struct wpa_config { /** * 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; + u8 device_type[WPS_DEV_TYPE_LEN]; /** * config_methods - Config Methods @@ -352,10 +343,10 @@ struct wpa_config { #define MAX_SEC_DEVICE_TYPES 5 /** - * sec_device_type - Secondary Device Types (P2P) - * See device_type for the format used with these. + * sec_device_types - Secondary Device Types (P2P) */ - char *sec_device_type[MAX_SEC_DEVICE_TYPES]; + u8 sec_device_type[MAX_SEC_DEVICE_TYPES][WPS_DEV_TYPE_LEN]; + int num_sec_device_types; int p2p_listen_reg_class; int p2p_listen_channel; diff --git a/wpa_supplicant/config_file.c b/wpa_supplicant/config_file.c index 09c99e372..464233539 100644 --- a/wpa_supplicant/config_file.c +++ b/wpa_supplicant/config_file.c @@ -645,8 +645,12 @@ static void wpa_config_write_global(FILE *f, struct wpa_config *config) 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); + { + char _buf[WPS_DEV_TYPE_BUFSIZE], *buf; + buf = wps_dev_type_bin2str(config->device_type, + _buf, sizeof(_buf)); + fprintf(f, "device_type=%s\n", buf); + } if (WPA_GET_BE32(config->os_version)) fprintf(f, "os_version=%08x\n", WPA_GET_BE32(config->os_version)); diff --git a/wpa_supplicant/config_winreg.c b/wpa_supplicant/config_winreg.c index 6b2096f50..ea3a2acd6 100644 --- a/wpa_supplicant/config_winreg.c +++ b/wpa_supplicant/config_winreg.c @@ -247,8 +247,13 @@ static int wpa_config_read_global(struct wpa_config *config, HKEY hk) 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")); + { + char *t = wpa_config_read_reg_string( + hk, TEXT("device_type")); + if (t && wps_dev_type_str2bin(t, config->device_type)) + errors++; + os_free(t); + } config->config_methods = wpa_config_read_reg_string( hk, TEXT("config_methods")); if (wpa_config_read_global_os_version(config, hk)) @@ -585,7 +590,12 @@ static int wpa_config_write_global(struct wpa_config *config, HKEY hk) 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); + { + char _buf[WPS_DEV_TYPE_BUFSIZE], *buf; + buf = wps_dev_type_bin2str(config->device_type, + _buf, sizeof(_buf)); + wpa_config_write_reg_string(hk, "device_type", buf); + } wpa_config_write_reg_string(hk, "config_methods", config->config_methods); if (WPA_GET_BE32(config->os_version)) { diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c index b3114932a..f1153f416 100644 --- a/wpa_supplicant/p2p_supplicant.c +++ b/wpa_supplicant/p2p_supplicant.c @@ -931,10 +931,14 @@ static void wpas_p2p_clone_config(struct wpa_supplicant *dst, C(model_name); C(model_number); C(serial_number); - C(device_type); C(config_methods); #undef C + os_memcpy(d->device_type, s->device_type, WPS_DEV_TYPE_LEN); + os_memcpy(d->sec_device_type, s->sec_device_type, + sizeof(d->sec_device_type)); + d->num_sec_device_types = s->num_sec_device_types; + d->p2p_group_idle = s->p2p_group_idle; d->p2p_intra_bss = s->p2p_intra_bss; } @@ -2291,7 +2295,6 @@ int wpas_p2p_init(struct wpa_global *global, struct wpa_supplicant *wpa_s) { struct p2p_config p2p; unsigned int r; - int i; if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_CAPABLE)) return 0; @@ -2317,27 +2320,13 @@ int wpas_p2p_init(struct wpa_global *global, struct wpa_supplicant *wpa_s) wpa_printf(MSG_DEBUG, "P2P: Use driver-based P2P management"); os_memset(¶ms, 0, sizeof(params)); params.dev_name = wpa_s->conf->device_name; - if (wpa_s->conf->device_type && - wps_dev_type_str2bin(wpa_s->conf->device_type, - params.pri_dev_type) < 0) { - wpa_printf(MSG_ERROR, "P2P: Invalid device_type"); - return -1; - } - for (i = 0; i < MAX_SEC_DEVICE_TYPES; i++) { - if (wpa_s->conf->sec_device_type[i] == NULL) - continue; - if (wps_dev_type_str2bin( - wpa_s->conf->sec_device_type[i], - params.sec_dev_type[ - params.num_sec_dev_types]) < 0) { - wpa_printf(MSG_ERROR, "P2P: Invalid " - "sec_device_type"); - return -1; - } - params.num_sec_dev_types++; - if (params.num_sec_dev_types == DRV_MAX_SEC_DEV_TYPES) - break; - } + os_memcpy(params.pri_dev_type, wpa_s->conf->device_type, + WPS_DEV_TYPE_LEN); + params.num_sec_dev_types = wpa_s->conf->num_sec_device_types; + os_memcpy(params.sec_dev_type, + wpa_s->conf->sec_device_type, + params.num_sec_dev_types * WPS_DEV_TYPE_LEN); + if (wpa_drv_p2p_set_params(wpa_s, ¶ms) < 0) return -1; @@ -2417,26 +2406,12 @@ int wpas_p2p_init(struct wpa_global *global, struct wpa_supplicant *wpa_s) return -1; } - if (wpa_s->conf->device_type && - wps_dev_type_str2bin(wpa_s->conf->device_type, p2p.pri_dev_type) < - 0) { - wpa_printf(MSG_ERROR, "P2P: Invalid device_type"); - return -1; - } + os_memcpy(p2p.pri_dev_type, wpa_s->conf->device_type, + WPS_DEV_TYPE_LEN); - for (i = 0; i < MAX_SEC_DEVICE_TYPES; i++) { - if (wpa_s->conf->sec_device_type[i] == NULL) - continue; - if (wps_dev_type_str2bin( - wpa_s->conf->sec_device_type[i], - p2p.sec_dev_type[p2p.num_sec_dev_types]) < 0) { - wpa_printf(MSG_ERROR, "P2P: Invalid sec_device_type"); - return -1; - } - p2p.num_sec_dev_types++; - if (p2p.num_sec_dev_types == P2P_SEC_DEVICE_TYPES) - break; - } + p2p.num_sec_dev_types = wpa_s->conf->num_sec_device_types; + os_memcpy(p2p.sec_dev_type, wpa_s->conf->sec_device_type, + p2p.num_sec_dev_types * WPS_DEV_TYPE_LEN); p2p.concurrent_operations = !!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_CONCURRENT); @@ -3900,38 +3875,13 @@ void wpas_p2p_update_config(struct wpa_supplicant *wpa_s) if (wpa_s->conf->changed_parameters & CFG_CHANGED_DEVICE_NAME) p2p_set_dev_name(p2p, wpa_s->conf->device_name); - if (wpa_s->conf->changed_parameters & CFG_CHANGED_DEVICE_TYPE) { - u8 pri_dev_type[8]; - if (wpa_s->conf->device_type) { - if (wps_dev_type_str2bin(wpa_s->conf->device_type, - pri_dev_type) < 0) { - wpa_printf(MSG_ERROR, "P2P: Invalid " - "device_type"); - } else - p2p_set_pri_dev_type(p2p, pri_dev_type); - } - } + if (wpa_s->conf->changed_parameters & CFG_CHANGED_DEVICE_TYPE) + p2p_set_pri_dev_type(p2p, wpa_s->conf->device_type); - if (wpa_s->conf->changed_parameters & CFG_CHANGED_SEC_DEVICE_TYPE) { - u8 sec_dev_type[P2P_SEC_DEVICE_TYPES][8]; - size_t num = 0; - int i; - for (i = 0; i < MAX_SEC_DEVICE_TYPES; i++) { - if (wpa_s->conf->sec_device_type[i] == NULL) - continue; - if (wps_dev_type_str2bin( - wpa_s->conf->sec_device_type[i], - sec_dev_type[num]) < 0) { - wpa_printf(MSG_ERROR, "P2P: Invalid " - "sec_device_type"); - continue; - } - num++; - if (num == P2P_SEC_DEVICE_TYPES) - break; - } - p2p_set_sec_dev_types(p2p, (void *) sec_dev_type, num); - } + if (wpa_s->conf->changed_parameters & CFG_CHANGED_SEC_DEVICE_TYPE) + p2p_set_sec_dev_types(p2p, + (void *) wpa_s->conf->sec_device_type, + wpa_s->conf->num_sec_device_types); if ((wpa_s->conf->changed_parameters & CFG_CHANGED_COUNTRY) && wpa_s->conf->country[0] && wpa_s->conf->country[1]) { diff --git a/wpa_supplicant/wps_supplicant.c b/wpa_supplicant/wps_supplicant.c index 1bdfea89e..778ccaf37 100644 --- a/wpa_supplicant/wps_supplicant.c +++ b/wpa_supplicant/wps_supplicant.c @@ -1094,7 +1094,6 @@ int wpas_wps_init(struct wpa_supplicant *wpa_s) { struct wps_context *wps; struct wps_registrar_config rcfg; - int i; wps = os_zalloc(sizeof(*wps)); if (wps == NULL) @@ -1119,28 +1118,12 @@ int wpas_wps_init(struct wpa_supplicant *wpa_s) return -1; } wps->config_methods = wps_fix_config_methods(wps->config_methods); - if (wpa_s->conf->device_type && - wps_dev_type_str2bin(wpa_s->conf->device_type, - wps->dev.pri_dev_type) < 0) { - wpa_printf(MSG_ERROR, "WPS: Invalid device_type"); - os_free(wps); - return -1; - } + os_memcpy(wps->dev.pri_dev_type, wpa_s->conf->device_type, + WPS_DEV_TYPE_LEN); - for (i = 0; i < MAX_SEC_DEVICE_TYPES; i++) { - if (wpa_s->conf->sec_device_type[i] == NULL) - continue; - if (wps_dev_type_str2bin( - wpa_s->conf->sec_device_type[i], - wps->dev.sec_dev_type[wps->dev.num_sec_dev_types]) - < 0) { - wpa_printf(MSG_ERROR, "WPS: Invalid sec_device_type"); - return -1; - } - wps->dev.num_sec_dev_types++; - if (wps->dev.num_sec_dev_types == WPS_SEC_DEVICE_TYPES) - break; - } + wps->dev.num_sec_dev_types = wpa_s->conf->num_sec_device_types; + os_memcpy(wps->dev.sec_dev_type, wpa_s->conf->sec_device_type, + WPS_DEV_TYPE_LEN * wps->dev.num_sec_dev_types); wps->dev.os_version = WPA_GET_BE32(wpa_s->conf->os_version); wps->dev.rf_bands = WPS_RF_24GHZ | WPS_RF_50GHZ; /* TODO: config */ @@ -1665,33 +1648,14 @@ void wpas_wps_update_config(struct wpa_supplicant *wpa_s) } wps->config_methods = wps_fix_config_methods(wps->config_methods); - if (wpa_s->conf->changed_parameters & CFG_CHANGED_DEVICE_TYPE) { - if (wpa_s->conf->device_type && - wps_dev_type_str2bin(wpa_s->conf->device_type, - wps->dev.pri_dev_type) < 0) - wpa_printf(MSG_ERROR, "WPS: Invalid device_type"); - } + if (wpa_s->conf->changed_parameters & CFG_CHANGED_DEVICE_TYPE) + os_memcpy(wps->dev.pri_dev_type, wpa_s->conf->device_type, + WPS_DEV_TYPE_LEN); if (wpa_s->conf->changed_parameters & CFG_CHANGED_SEC_DEVICE_TYPE) { - int i; - - wps->dev.num_sec_dev_types = 0; - - for (i = 0; i < MAX_SEC_DEVICE_TYPES; i++) { - if (wpa_s->conf->sec_device_type[i] == NULL) - continue; - if (wps_dev_type_str2bin( - wpa_s->conf->sec_device_type[i], - wps->dev.sec_dev_type[ - wps->dev.num_sec_dev_types]) < 0) { - wpa_printf(MSG_ERROR, - "WPS: Invalid sec_device_type"); - continue; - } - wps->dev.num_sec_dev_types++; - if (wps->dev.num_sec_dev_types == WPS_SEC_DEVICE_TYPES) - break; - } + wps->dev.num_sec_dev_types = wpa_s->conf->num_sec_device_types; + os_memcpy(wps->dev.sec_dev_type, wpa_s->conf->sec_device_type, + wps->dev.num_sec_dev_types * WPS_DEV_TYPE_LEN); } if (wpa_s->conf->changed_parameters & CFG_CHANGED_OS_VERSION)