diff mbox series

[v5] Add application extension data to WPS IE

Message ID 1578041906-10980-1-git-send-email-bilalhp@gmail.com
State Accepted
Headers show
Series [v5] Add application extension data to WPS IE | expand

Commit Message

Bilal Hatipoğlu Jan. 3, 2020, 8:58 a.m. UTC
From: Bilal Hatipoglu <bilal.hatipoglu@airties.com>

Application Extension attribute is defined in WPS Spec v2.07 page 104.
This patch makes hostapd add this application extension data to WPS IE
if configured. The implementation is very similar to vendor extension.

A new optional entry called "wps_application_ext" is added to hostapd config
file to configure this.

Signed-off-by: Veli Demirel <veli.demirel@airties.com>
Signed-off-by: Bilal Hatipoglu <bilal.hatipoglu@airties.com>
---
 hostapd/config_file.c   |  3 +++
 src/ap/ap_config.c      |  1 +
 src/ap/ap_config.h      |  1 +
 src/ap/wps_hostapd.c    | 14 ++++++++++++++
 src/wps/wps.h           |  1 +
 src/wps/wps_dev_attr.c  | 13 +++++++++++++
 src/wps/wps_dev_attr.h  |  1 +
 src/wps/wps_registrar.c |  6 ++++--
 8 files changed, 38 insertions(+), 2 deletions(-)

Comments

Jouni Malinen Jan. 4, 2020, 10:11 p.m. UTC | #1
On Fri, Jan 03, 2020 at 11:58:26AM +0300, bilalhp@gmail.com wrote:
> Application Extension attribute is defined in WPS Spec v2.07 page 104.
> This patch makes hostapd add this application extension data to WPS IE
> if configured. The implementation is very similar to vendor extension.
> 
> A new optional entry called "wps_application_ext" is added to hostapd config
> file to configure this.

Thanks, applied with fixes to not crash hostapd if wps_application_ext
is not set and to not leak memory if it is set, and with the requested
documentation in hostapd.conf.
diff mbox series

Patch

diff --git a/hostapd/config_file.c b/hostapd/config_file.c
index 21c9ab2..6a08116 100644
--- a/hostapd/config_file.c
+++ b/hostapd/config_file.c
@@ -3616,6 +3616,9 @@  static int hostapd_config_fill(struct hostapd_config *conf,
 		}
 		os_free(bss->device_name);
 		bss->device_name = os_strdup(pos);
+	} else if (os_strcmp(buf, "wps_application_ext") == 0) {
+		wpabuf_free(bss->wps_application_ext);
+		bss->wps_application_ext = wpabuf_parse_bin(pos);
 	} else if (os_strcmp(buf, "manufacturer") == 0) {
 		if (os_strlen(pos) > 64) {
 			wpa_printf(MSG_ERROR, "Line %d: Too long manufacturer",
diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c
index 68af3c1..035c4bc 100644
--- a/src/ap/ap_config.c
+++ b/src/ap/ap_config.c
@@ -813,6 +813,7 @@  void hostapd_config_free_bss(struct hostapd_bss_config *conf)
 	os_free(conf->upc);
 	for (i = 0; i < MAX_WPS_VENDOR_EXTENSIONS; i++)
 		wpabuf_free(conf->wps_vendor_ext[i]);
+	wpabuf_free(conf->wps_application_ext);
 	wpabuf_free(conf->wps_nfc_dh_pubkey);
 	wpabuf_free(conf->wps_nfc_dh_privkey);
 	wpabuf_free(conf->wps_nfc_dev_pw);
diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
index 7e4b926..e97e616 100644
--- a/src/ap/ap_config.h
+++ b/src/ap/ap_config.h
@@ -498,6 +498,7 @@  struct hostapd_bss_config {
 	char *model_url;
 	char *upc;
 	struct wpabuf *wps_vendor_ext[MAX_WPS_VENDOR_EXTENSIONS];
+	struct wpabuf *wps_application_ext;
 	int wps_nfc_pw_from_config;
 	int wps_nfc_dev_pw_id;
 	struct wpabuf *wps_nfc_dh_pubkey;
diff --git a/src/ap/wps_hostapd.c b/src/ap/wps_hostapd.c
index 175b9fc..e587e10 100644
--- a/src/ap/wps_hostapd.c
+++ b/src/ap/wps_hostapd.c
@@ -985,6 +985,16 @@  static int hostapd_wps_set_vendor_ext(struct hostapd_data *hapd,
 }
 
 
+static int hostapd_wps_set_application_ext(struct hostapd_data *hapd,
+				      struct wps_context *wps)
+{
+	wpabuf_free(wps->dev.application_ext);
+	wps->dev.application_ext = wpabuf_dup(hapd->conf->wps_application_ext);
+
+	return 0;
+}
+
+
 static void hostapd_free_wps(struct wps_context *wps)
 {
 	int i;
@@ -1077,6 +1087,9 @@  int hostapd_init_wps(struct hostapd_data *hapd,
 	if (hostapd_wps_set_vendor_ext(hapd, wps) < 0)
 		goto fail;
 
+	if (hostapd_wps_set_application_ext(hapd, wps) < 0)
+		goto fail;
+
 	wps->dev.os_version = WPA_GET_BE32(hapd->conf->os_version);
 
 	if (conf->wps_rf_bands) {
@@ -1311,6 +1324,7 @@  void hostapd_update_wps(struct hostapd_data *hapd)
 #endif /* CONFIG_WPS_UPNP */
 
 	hostapd_wps_set_vendor_ext(hapd, hapd->wps);
+	hostapd_wps_set_application_ext(hapd, hapd->wps);
 
 	if (hapd->conf->wps_state)
 		wps_registrar_update_ie(hapd->wps->registrar);
diff --git a/src/wps/wps.h b/src/wps/wps.h
index 9963c46..f42045e 100644
--- a/src/wps/wps.h
+++ b/src/wps/wps.h
@@ -98,6 +98,7 @@  struct wps_device_data {
 	u16 config_methods;
 	struct wpabuf *vendor_ext_m1;
 	struct wpabuf *vendor_ext[MAX_WPS_VENDOR_EXTENSIONS];
+	struct wpabuf *application_ext;
 
 	int p2p;
 	u8 multi_ap_ext;
diff --git a/src/wps/wps_dev_attr.c b/src/wps/wps_dev_attr.c
index b209fea..279307a 100644
--- a/src/wps/wps_dev_attr.c
+++ b/src/wps/wps_dev_attr.c
@@ -242,6 +242,19 @@  int wps_build_vendor_ext(struct wps_device_data *dev, struct wpabuf *msg)
 }
 
 
+int wps_build_application_ext(struct wps_device_data *dev, struct wpabuf *msg)
+{
+	wpa_hexdump(MSG_DEBUG, "WPS:  * Application Extension",
+			wpabuf_head_u8(dev->application_ext),
+			wpabuf_len(dev->application_ext));
+	wpabuf_put_be16(msg, ATTR_APPLICATION_EXT);
+	wpabuf_put_be16(msg, wpabuf_len(dev->application_ext));
+	wpabuf_put_buf(msg, dev->application_ext);
+
+	return 0;
+}
+
+
 static int wps_process_manufacturer(struct wps_device_data *dev, const u8 *str,
 				    size_t str_len)
 {
diff --git a/src/wps/wps_dev_attr.h b/src/wps/wps_dev_attr.h
index a4b4173..81fdd5f 100644
--- a/src/wps/wps_dev_attr.h
+++ b/src/wps/wps_dev_attr.h
@@ -33,6 +33,7 @@  void wps_process_vendor_ext_m1(struct wps_device_data *dev, const u8 ext);
 int wps_process_rf_bands(struct wps_device_data *dev, const u8 *bands);
 void wps_device_data_free(struct wps_device_data *dev);
 int wps_build_vendor_ext(struct wps_device_data *dev, struct wpabuf *msg);
+int wps_build_application_ext(struct wps_device_data *dev, struct wpabuf *msg);
 int wps_build_req_dev_type(struct wps_device_data *dev, struct wpabuf *msg,
 			   unsigned int num_req_dev_types,
 			   const u8 *req_dev_types);
diff --git a/src/wps/wps_registrar.c b/src/wps/wps_registrar.c
index 671f5fe..da81d1a 100644
--- a/src/wps/wps_registrar.c
+++ b/src/wps/wps_registrar.c
@@ -1331,7 +1331,8 @@  static int wps_set_ie(struct wps_registrar *reg)
 	    wps_build_sel_pbc_reg_uuid_e(reg, beacon) ||
 	    (reg->dualband && wps_build_rf_bands(&reg->wps->dev, beacon, 0)) ||
 	    wps_build_wfa_ext(beacon, 0, auth_macs, count, 0) ||
-	    wps_build_vendor_ext(&reg->wps->dev, beacon)) {
+	    wps_build_vendor_ext(&reg->wps->dev, beacon) ||
+	    wps_build_application_ext(&reg->wps->dev, beacon)) {
 		wpabuf_free(beacon);
 		wpabuf_free(probe);
 		return -1;
@@ -1361,7 +1362,8 @@  static int wps_set_ie(struct wps_registrar *reg)
 	    wps_build_probe_config_methods(reg, probe) ||
 	    (reg->dualband && wps_build_rf_bands(&reg->wps->dev, probe, 0)) ||
 	    wps_build_wfa_ext(probe, 0, auth_macs, count, 0) ||
-	    wps_build_vendor_ext(&reg->wps->dev, probe)) {
+	    wps_build_vendor_ext(&reg->wps->dev, probe) ||
+	    wps_build_application_ext(&reg->wps->dev, probe)) {
 		wpabuf_free(beacon);
 		wpabuf_free(probe);
 		return -1;