WPS: Allow vendor specific attribute to be added into M1
wps_vendor_ext_m1 configuration parameter can now be used to add a vendor specific attribute into the WPS M1 message, e.g., for Windows Vertical Pairing. Signed-hostap: Jouni Malinen <jouni@qca.qualcomm.com>
This commit is contained in:
parent
2e9f078c8d
commit
71dd3b78f9
9 changed files with 96 additions and 1 deletions
|
@ -94,6 +94,7 @@ struct wps_device_data {
|
||||||
u32 os_version;
|
u32 os_version;
|
||||||
u8 rf_bands;
|
u8 rf_bands;
|
||||||
u16 config_methods;
|
u16 config_methods;
|
||||||
|
struct wpabuf *vendor_ext_m1;
|
||||||
struct wpabuf *vendor_ext[MAX_WPS_VENDOR_EXTENSIONS];
|
struct wpabuf *vendor_ext[MAX_WPS_VENDOR_EXTENSIONS];
|
||||||
|
|
||||||
int p2p;
|
int p2p;
|
||||||
|
|
|
@ -203,6 +203,20 @@ int wps_build_os_version(struct wps_device_data *dev, struct wpabuf *msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int wps_build_vendor_ext_m1(struct wps_device_data *dev, struct wpabuf *msg)
|
||||||
|
{
|
||||||
|
if (dev->vendor_ext_m1 != NULL) {
|
||||||
|
wpa_hexdump(MSG_DEBUG, "WPS: * Vendor Extension M1",
|
||||||
|
wpabuf_head_u8(dev->vendor_ext_m1),
|
||||||
|
wpabuf_len(dev->vendor_ext_m1));
|
||||||
|
wpabuf_put_be16(msg, ATTR_VENDOR_EXT);
|
||||||
|
wpabuf_put_be16(msg, wpabuf_len(dev->vendor_ext_m1));
|
||||||
|
wpabuf_put_buf(msg, dev->vendor_ext_m1);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int wps_build_rf_bands(struct wps_device_data *dev, struct wpabuf *msg)
|
int wps_build_rf_bands(struct wps_device_data *dev, struct wpabuf *msg)
|
||||||
{
|
{
|
||||||
wpa_printf(MSG_DEBUG, "WPS: * RF Bands (%x)", dev->rf_bands);
|
wpa_printf(MSG_DEBUG, "WPS: * RF Bands (%x)", dev->rf_bands);
|
||||||
|
|
|
@ -17,6 +17,7 @@ int wps_build_model_number(struct wps_device_data *dev, struct wpabuf *msg);
|
||||||
int wps_build_dev_name(struct wps_device_data *dev, struct wpabuf *msg);
|
int wps_build_dev_name(struct wps_device_data *dev, struct wpabuf *msg);
|
||||||
int wps_build_device_attrs(struct wps_device_data *dev, struct wpabuf *msg);
|
int wps_build_device_attrs(struct wps_device_data *dev, struct wpabuf *msg);
|
||||||
int wps_build_os_version(struct wps_device_data *dev, struct wpabuf *msg);
|
int wps_build_os_version(struct wps_device_data *dev, struct wpabuf *msg);
|
||||||
|
int wps_build_vendor_ext_m1(struct wps_device_data *dev, struct wpabuf *msg);
|
||||||
int wps_build_rf_bands(struct wps_device_data *dev, struct wpabuf *msg);
|
int wps_build_rf_bands(struct wps_device_data *dev, struct wpabuf *msg);
|
||||||
int wps_build_primary_dev_type(struct wps_device_data *dev,
|
int wps_build_primary_dev_type(struct wps_device_data *dev,
|
||||||
struct wpabuf *msg);
|
struct wpabuf *msg);
|
||||||
|
|
|
@ -163,7 +163,8 @@ static struct wpabuf * wps_build_m1(struct wps_data *wps)
|
||||||
wps_build_dev_password_id(msg, wps->dev_pw_id) ||
|
wps_build_dev_password_id(msg, wps->dev_pw_id) ||
|
||||||
wps_build_config_error(msg, WPS_CFG_NO_ERROR) ||
|
wps_build_config_error(msg, WPS_CFG_NO_ERROR) ||
|
||||||
wps_build_os_version(&wps->wps->dev, msg) ||
|
wps_build_os_version(&wps->wps->dev, msg) ||
|
||||||
wps_build_wfa_ext(msg, 0, NULL, 0)) {
|
wps_build_wfa_ext(msg, 0, NULL, 0) ||
|
||||||
|
wps_build_vendor_ext_m1(&wps->wps->dev, msg)) {
|
||||||
wpabuf_free(msg);
|
wpabuf_free(msg);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1835,6 +1835,7 @@ void wpa_config_free(struct wpa_config *config)
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_NO_CONFIG_BLOBS */
|
#endif /* CONFIG_NO_CONFIG_BLOBS */
|
||||||
|
|
||||||
|
wpabuf_free(config->wps_vendor_ext_m1);
|
||||||
os_free(config->ctrl_interface);
|
os_free(config->ctrl_interface);
|
||||||
os_free(config->ctrl_interface_group);
|
os_free(config->ctrl_interface_group);
|
||||||
os_free(config->opensc_engine_path);
|
os_free(config->opensc_engine_path);
|
||||||
|
@ -2673,6 +2674,43 @@ static int wpa_config_process_os_version(const struct global_parse_data *data,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int wpa_config_process_wps_vendor_ext_m1(
|
||||||
|
const struct global_parse_data *data,
|
||||||
|
struct wpa_config *config, int line, const char *pos)
|
||||||
|
{
|
||||||
|
struct wpabuf *tmp;
|
||||||
|
int len = os_strlen(pos) / 2;
|
||||||
|
u8 *p;
|
||||||
|
|
||||||
|
if (!len) {
|
||||||
|
wpa_printf(MSG_ERROR, "Line %d: "
|
||||||
|
"invalid wps_vendor_ext_m1", line);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp = wpabuf_alloc(len);
|
||||||
|
if (tmp) {
|
||||||
|
p = wpabuf_put(tmp, len);
|
||||||
|
|
||||||
|
if (hexstr2bin(pos, p, len)) {
|
||||||
|
wpa_printf(MSG_ERROR, "Line %d: "
|
||||||
|
"invalid wps_vendor_ext_m1", line);
|
||||||
|
wpabuf_free(tmp);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
wpabuf_free(config->wps_vendor_ext_m1);
|
||||||
|
config->wps_vendor_ext_m1 = tmp;
|
||||||
|
} else {
|
||||||
|
wpa_printf(MSG_ERROR, "Can not allocate "
|
||||||
|
"memory for wps_vendor_ext_m1");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* CONFIG_WPS */
|
#endif /* CONFIG_WPS */
|
||||||
|
|
||||||
#ifdef CONFIG_P2P
|
#ifdef CONFIG_P2P
|
||||||
|
@ -2809,6 +2847,7 @@ static const struct global_parse_data global_fields[] = {
|
||||||
{ FUNC(os_version), CFG_CHANGED_OS_VERSION },
|
{ FUNC(os_version), CFG_CHANGED_OS_VERSION },
|
||||||
{ STR(config_methods), CFG_CHANGED_CONFIG_METHODS },
|
{ STR(config_methods), CFG_CHANGED_CONFIG_METHODS },
|
||||||
{ INT_RANGE(wps_cred_processing, 0, 2), 0 },
|
{ INT_RANGE(wps_cred_processing, 0, 2), 0 },
|
||||||
|
{ FUNC(wps_vendor_ext_m1), CFG_CHANGED_VENDOR_EXTENSION },
|
||||||
#endif /* CONFIG_WPS */
|
#endif /* CONFIG_WPS */
|
||||||
#ifdef CONFIG_P2P
|
#ifdef CONFIG_P2P
|
||||||
{ FUNC(sec_device_type), CFG_CHANGED_SEC_DEVICE_TYPE },
|
{ FUNC(sec_device_type), CFG_CHANGED_SEC_DEVICE_TYPE },
|
||||||
|
|
|
@ -507,6 +507,8 @@ struct wpa_config {
|
||||||
unsigned int num_p2p_pref_chan;
|
unsigned int num_p2p_pref_chan;
|
||||||
struct p2p_channel *p2p_pref_chan;
|
struct p2p_channel *p2p_pref_chan;
|
||||||
|
|
||||||
|
struct wpabuf *wps_vendor_ext_m1;
|
||||||
|
|
||||||
#define MAX_WPS_VENDOR_EXT 10
|
#define MAX_WPS_VENDOR_EXT 10
|
||||||
/**
|
/**
|
||||||
* wps_vendor_ext - Vendor extension attributes in WPS
|
* wps_vendor_ext - Vendor extension attributes in WPS
|
||||||
|
|
|
@ -768,6 +768,16 @@ static void wpa_config_write_global(FILE *f, struct wpa_config *config)
|
||||||
if (config->wps_cred_processing)
|
if (config->wps_cred_processing)
|
||||||
fprintf(f, "wps_cred_processing=%d\n",
|
fprintf(f, "wps_cred_processing=%d\n",
|
||||||
config->wps_cred_processing);
|
config->wps_cred_processing);
|
||||||
|
if (config->wps_vendor_ext_m1) {
|
||||||
|
int i, len = wpabuf_len(config->wps_vendor_ext_m1);
|
||||||
|
const u8 *p = wpabuf_head_u8(config->wps_vendor_ext_m1);
|
||||||
|
if (len > 0) {
|
||||||
|
fprintf(f, "wps_vendor_ext_m1=");
|
||||||
|
for (i = 0; i < len; i++)
|
||||||
|
fprintf(f, "%02x", *p++);
|
||||||
|
fprintf(f, "\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif /* CONFIG_WPS */
|
#endif /* CONFIG_WPS */
|
||||||
#ifdef CONFIG_P2P
|
#ifdef CONFIG_P2P
|
||||||
if (config->p2p_listen_reg_class)
|
if (config->p2p_listen_reg_class)
|
||||||
|
|
|
@ -214,6 +214,10 @@ fast_reauth=1
|
||||||
# to external program(s)
|
# to external program(s)
|
||||||
#wps_cred_processing=0
|
#wps_cred_processing=0
|
||||||
|
|
||||||
|
# Vendor attribute in WPS M1, e.g., Windows 7 Vertical Pairing
|
||||||
|
# The vendor attribute contents to be added in M1 (hex string)
|
||||||
|
#wps_vendor_ext_m1=000137100100020001
|
||||||
|
|
||||||
# Maximum number of BSS entries to keep in memory
|
# Maximum number of BSS entries to keep in memory
|
||||||
# Default: 200
|
# Default: 200
|
||||||
# This can be used to limit memory use on the BSS entries (cached scan
|
# This can be used to limit memory use on the BSS entries (cached scan
|
||||||
|
|
|
@ -1130,6 +1130,23 @@ static void wpas_wps_set_uuid(struct wpa_supplicant *wpa_s,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void wpas_wps_set_vendor_ext_m1(struct wpa_supplicant *wpa_s,
|
||||||
|
struct wps_context *wps)
|
||||||
|
{
|
||||||
|
wpabuf_free(wps->dev.vendor_ext_m1);
|
||||||
|
wps->dev.vendor_ext_m1 = NULL;
|
||||||
|
|
||||||
|
if (wpa_s->conf->wps_vendor_ext_m1) {
|
||||||
|
wps->dev.vendor_ext_m1 =
|
||||||
|
wpabuf_dup(wpa_s->conf->wps_vendor_ext_m1);
|
||||||
|
if (!wps->dev.vendor_ext_m1) {
|
||||||
|
wpa_printf(MSG_ERROR, "WPS: Cannot "
|
||||||
|
"allocate memory for vendor_ext_m1");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int wpas_wps_init(struct wpa_supplicant *wpa_s)
|
int wpas_wps_init(struct wpa_supplicant *wpa_s)
|
||||||
{
|
{
|
||||||
struct wps_context *wps;
|
struct wps_context *wps;
|
||||||
|
@ -1168,6 +1185,8 @@ int wpas_wps_init(struct wpa_supplicant *wpa_s)
|
||||||
os_memcpy(wps->dev.sec_dev_type, wpa_s->conf->sec_device_type,
|
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_TYPE_LEN * wps->dev.num_sec_dev_types);
|
||||||
|
|
||||||
|
wpas_wps_set_vendor_ext_m1(wpa_s, wps);
|
||||||
|
|
||||||
wps->dev.os_version = WPA_GET_BE32(wpa_s->conf->os_version);
|
wps->dev.os_version = WPA_GET_BE32(wpa_s->conf->os_version);
|
||||||
modes = wpa_s->hw.modes;
|
modes = wpa_s->hw.modes;
|
||||||
if (modes) {
|
if (modes) {
|
||||||
|
@ -1228,6 +1247,7 @@ void wpas_wps_deinit(struct wpa_supplicant *wpa_s)
|
||||||
wpabuf_free(wpa_s->wps->dh_privkey);
|
wpabuf_free(wpa_s->wps->dh_privkey);
|
||||||
wpabuf_free(wpa_s->wps->oob_conf.pubkey_hash);
|
wpabuf_free(wpa_s->wps->oob_conf.pubkey_hash);
|
||||||
wpabuf_free(wpa_s->wps->oob_conf.dev_password);
|
wpabuf_free(wpa_s->wps->oob_conf.dev_password);
|
||||||
|
wpabuf_free(wpa_s->wps->dev.vendor_ext_m1);
|
||||||
os_free(wpa_s->wps->network_key);
|
os_free(wpa_s->wps->network_key);
|
||||||
os_free(wpa_s->wps);
|
os_free(wpa_s->wps);
|
||||||
wpa_s->wps = NULL;
|
wpa_s->wps = NULL;
|
||||||
|
@ -1717,6 +1737,9 @@ void wpas_wps_update_config(struct wpa_supplicant *wpa_s)
|
||||||
wps->dev.num_sec_dev_types * WPS_DEV_TYPE_LEN);
|
wps->dev.num_sec_dev_types * WPS_DEV_TYPE_LEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (wpa_s->conf->changed_parameters & CFG_CHANGED_VENDOR_EXTENSION)
|
||||||
|
wpas_wps_set_vendor_ext_m1(wpa_s, wps);
|
||||||
|
|
||||||
if (wpa_s->conf->changed_parameters & CFG_CHANGED_OS_VERSION)
|
if (wpa_s->conf->changed_parameters & CFG_CHANGED_OS_VERSION)
|
||||||
wps->dev.os_version = WPA_GET_BE32(wpa_s->conf->os_version);
|
wps->dev.os_version = WPA_GET_BE32(wpa_s->conf->os_version);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue