From 6cb8f4f382d8f08461d6bbd457acb059672aaacf Mon Sep 17 00:00:00 2001
From: Jouni Malinen <jouni@codeaurora.org>
Date: Mon, 23 Apr 2018 21:10:52 +0300
Subject: [PATCH] HS 2.0: Terms and Conditions attributes in Access-Request
 messages

This extends hostapd with two new configuration parameters
(hs20_t_c_filename and hs20_t_c_timestamp) that can be used to specify
that the Terms and Conditions attributes are to be added into all
Access-Request messages for Hotspot 2.0 STAs.

Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
---
 hostapd/config_file.c |  5 +++++
 hostapd/hostapd.conf  | 12 ++++++++++++
 src/ap/ap_config.c    |  1 +
 src/ap/ap_config.h    |  2 ++
 src/ap/ieee802_1x.c   | 25 +++++++++++++++++++++++++
 src/radius/radius.h   |  2 ++
 6 files changed, 47 insertions(+)

diff --git a/hostapd/config_file.c b/hostapd/config_file.c
index f327cff45..c611551f4 100644
--- a/hostapd/config_file.c
+++ b/hostapd/config_file.c
@@ -3629,6 +3629,11 @@ static int hostapd_config_fill(struct hostapd_config *conf,
 		bss->subscr_remediation_url = os_strdup(pos);
 	} else if (os_strcmp(buf, "subscr_remediation_method") == 0) {
 		bss->subscr_remediation_method = atoi(pos);
+	} else if (os_strcmp(buf, "hs20_t_c_filename") == 0) {
+		os_free(bss->t_c_filename);
+		bss->t_c_filename = os_strdup(pos);
+	} else if (os_strcmp(buf, "hs20_t_c_timestamp") == 0) {
+		bss->t_c_timestamp = strtol(pos, NULL, 0);
 #endif /* CONFIG_HS20 */
 #ifdef CONFIG_MBO
 	} else if (os_strcmp(buf, "mbo") == 0) {
diff --git a/hostapd/hostapd.conf b/hostapd/hostapd.conf
index 220625651..f65c00435 100644
--- a/hostapd/hostapd.conf
+++ b/hostapd/hostapd.conf
@@ -2158,6 +2158,18 @@ own_ip_addr=127.0.0.1
 # channels 36-48):
 #hs20_operating_class=5173
 
+# Terms and Conditions information
+#
+# hs20_t_c_filename contains the Terms and Conditions filename that the AP
+# indicates in RADIUS Access-Request messages.
+#hs20_t_c_filename=terms-and-conditions
+#
+# hs20_t_c_timestamp contains the Terms and Conditions timestamp that the AP
+# indicates in RADIUS Access-Request messages. Usually, this contains the number
+# of seconds since January 1, 1970 00:00 UTC showing the time when the file was
+# last modified.
+#hs20_t_c_timestamp=1234567
+
 # OSU and Operator icons
 # <Icon Width>:<Icon Height>:<Language code>:<Icon Type>:<Name>:<file path>
 #hs20_icon=32:32:eng:image/png:icon32:/tmp/icon32.png
diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c
index 6c0d57eed..6de5d40e9 100644
--- a/src/ap/ap_config.c
+++ b/src/ap/ap_config.c
@@ -620,6 +620,7 @@ void hostapd_config_free_bss(struct hostapd_bss_config *conf)
 		os_free(conf->hs20_operator_icon);
 	}
 	os_free(conf->subscr_remediation_url);
+	os_free(conf->t_c_filename);
 #endif /* CONFIG_HS20 */
 
 	wpabuf_free(conf->vendor_elements);
diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
index 87d485c2c..95eb3d4b5 100644
--- a/src/ap/ap_config.h
+++ b/src/ap/ap_config.h
@@ -585,6 +585,8 @@ struct hostapd_bss_config {
 	unsigned int hs20_deauth_req_timeout;
 	char *subscr_remediation_url;
 	u8 subscr_remediation_method;
+	char *t_c_filename;
+	u32 t_c_timestamp;
 #endif /* CONFIG_HS20 */
 
 	u8 wps_rf_bands; /* RF bands for WPS (WPS_RF_*) */
diff --git a/src/ap/ieee802_1x.c b/src/ap/ieee802_1x.c
index 4fcccce72..9663bd757 100644
--- a/src/ap/ieee802_1x.c
+++ b/src/ap/ieee802_1x.c
@@ -722,6 +722,31 @@ void ieee802_1x_encapsulate_radius(struct hostapd_data *hapd,
 				   "Could not add HS 2.0 Roaming Consortium");
 			goto fail;
 		}
+
+		if (hapd->conf->t_c_filename) {
+			be32 timestamp;
+
+			if (!radius_msg_add_wfa(
+				    msg,
+				    RADIUS_VENDOR_ATTR_WFA_HS20_T_C_FILENAME,
+				    (const u8 *) hapd->conf->t_c_filename,
+				    os_strlen(hapd->conf->t_c_filename))) {
+				wpa_printf(MSG_ERROR,
+					   "Could not add HS 2.0 T&C Filename");
+				goto fail;
+			}
+
+			timestamp = host_to_be32(hapd->conf->t_c_timestamp);
+			if (!radius_msg_add_wfa(
+				    msg,
+				    RADIUS_VENDOR_ATTR_WFA_HS20_TIMESTAMP,
+				    (const u8 *) &timestamp,
+				    sizeof(timestamp))) {
+				wpa_printf(MSG_ERROR,
+					   "Could not add HS 2.0 Timestamp");
+				goto fail;
+			}
+		}
 	}
 #endif /* CONFIG_HS20 */
 
diff --git a/src/radius/radius.h b/src/radius/radius.h
index bed7f230e..3d26cf735 100644
--- a/src/radius/radius.h
+++ b/src/radius/radius.h
@@ -199,6 +199,8 @@ enum {
 	RADIUS_VENDOR_ATTR_WFA_HS20_DEAUTH_REQ = 4,
 	RADIUS_VENDOR_ATTR_WFA_HS20_SESSION_INFO_URL = 5,
 	RADIUS_VENDOR_ATTR_WFA_HS20_ROAMING_CONSORTIUM = 6,
+	RADIUS_VENDOR_ATTR_WFA_HS20_T_C_FILENAME = 7,
+	RADIUS_VENDOR_ATTR_WFA_HS20_TIMESTAMP = 8,
 };
 
 #ifdef _MSC_VER