HS 2.0: Send Terms and Conditions Acceptance notification

This extends hostapd Access-Accept processing to check if the RADIUS
server indicated that Terms and Conditions Acceptance is required. The
new hs20_t_c_server_url parameter is used to specify the server URL
template that the STA is requested to visit.

This commit does not enable any kind of filtering, i.e., only the part
of forwarding a request from Access-Accept to the STA using
WNM-Notification is covered.

Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
This commit is contained in:
Jouni Malinen 2018-04-24 00:05:44 +03:00 committed by Jouni Malinen
parent 6cb8f4f382
commit 8760b9848c
10 changed files with 92 additions and 1 deletions

View file

@ -3634,6 +3634,9 @@ static int hostapd_config_fill(struct hostapd_config *conf,
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);
} else if (os_strcmp(buf, "hs20_t_c_server_url") == 0) {
os_free(bss->t_c_server_url);
bss->t_c_server_url = os_strdup(pos);
#endif /* CONFIG_HS20 */
#ifdef CONFIG_MBO
} else if (os_strcmp(buf, "mbo") == 0) {

View file

@ -2169,6 +2169,13 @@ own_ip_addr=127.0.0.1
# of seconds since January 1, 1970 00:00 UTC showing the time when the file was
# last modified.
#hs20_t_c_timestamp=1234567
#
# hs20_t_c_server_url contains a template for the Terms and Conditions server
# URL. This template is used to generate the URL for a STA that needs to
# acknowledge Terms and Conditions.
# Macros:
# @1@ = MAC address of the STA (colon separated hex octets)
#hs20_t_c_server_url=https://example.com/t_and_c?addr=@1@&ap=123
# OSU and Operator icons
# <Icon Width>:<Icon Height>:<Language code>:<Icon Type>:<Name>:<file path>

View file

@ -621,6 +621,7 @@ void hostapd_config_free_bss(struct hostapd_bss_config *conf)
}
os_free(conf->subscr_remediation_url);
os_free(conf->t_c_filename);
os_free(conf->t_c_server_url);
#endif /* CONFIG_HS20 */
wpabuf_free(conf->vendor_elements);

View file

@ -587,6 +587,7 @@ struct hostapd_bss_config {
u8 subscr_remediation_method;
char *t_c_filename;
u32 t_c_timestamp;
char *t_c_server_url;
#endif /* CONFIG_HS20 */
u8 wps_rf_bands; /* RF bands for WPS (WPS_RF_*) */

View file

@ -175,3 +175,46 @@ int hs20_send_wnm_notification_deauth_req(struct hostapd_data *hapd,
return ret;
}
int hs20_send_wnm_notification_t_c(struct hostapd_data *hapd,
const u8 *addr)
{
struct wpabuf *buf;
int ret;
const char *url = hapd->conf->t_c_server_url, *pos;
size_t url_len;
if (!url)
return -1;
pos = os_strstr(url, "@1@");
if (!pos)
return -1;
url_len = os_strlen(url) + ETH_ALEN * 3 - 1 - 3;
buf = wpabuf_alloc(4 + 7 + url_len);
if (!buf)
return -1;
wpabuf_put_u8(buf, WLAN_ACTION_WNM);
wpabuf_put_u8(buf, WNM_NOTIFICATION_REQ);
wpabuf_put_u8(buf, 1); /* Dialog token */
wpabuf_put_u8(buf, 1); /* Type - 1 reserved for WFA */
/* Terms and Conditions Acceptance subelement */
wpabuf_put_u8(buf, WLAN_EID_VENDOR_SPECIFIC);
wpabuf_put_u8(buf, 4 + 1 + url_len);
wpabuf_put_be24(buf, OUI_WFA);
wpabuf_put_u8(buf, HS20_WNM_T_C_ACCEPTANCE);
wpabuf_put_u8(buf, url_len);
wpabuf_put_data(buf, url, pos - url);
wpabuf_printf(buf, MACSTR, MAC2STR(addr));
wpabuf_put_str(buf, pos + 3);
ret = hostapd_drv_send_action(hapd, hapd->iface->freq, 0, addr,
wpabuf_head(buf), wpabuf_len(buf));
wpabuf_free(buf);
return ret;
}

View file

@ -18,5 +18,7 @@ int hs20_send_wnm_notification(struct hostapd_data *hapd, const u8 *addr,
int hs20_send_wnm_notification_deauth_req(struct hostapd_data *hapd,
const u8 *addr,
const struct wpabuf *payload);
int hs20_send_wnm_notification_t_c(struct hostapd_data *hapd,
const u8 *addr);
#endif /* HS20_H */

View file

@ -1622,6 +1622,26 @@ static void ieee802_1x_hs20_session_info(struct hostapd_data *hapd,
ap_sta_session_warning_timeout(hapd, sta, warning_time);
}
static void ieee802_1x_hs20_t_c_filtering(struct hostapd_data *hapd,
struct sta_info *sta, u8 *pos,
size_t len)
{
if (len < 4)
return; /* Malformed information */
wpa_printf(MSG_DEBUG,
"HS 2.0: Terms and Conditions filtering %02x %02x %02x %02x",
pos[0], pos[1], pos[2], pos[3]);
if (pos[0] & BIT(0)) {
wpa_printf(MSG_DEBUG,
"HS 2.0: Terms and Conditions filtering required");
sta->hs20_t_c_filtering = 1;
/* TODO: Enable firewall filtering for the STA */
} else {
sta->hs20_t_c_filtering = 0;
}
}
#endif /* CONFIG_HS20 */
@ -1669,6 +1689,9 @@ static void ieee802_1x_check_hs20(struct hostapd_data *hapd,
ieee802_1x_hs20_session_info(hapd, sta, pos, sublen,
session_timeout);
break;
case RADIUS_VENDOR_ATTR_WFA_HS20_T_C_FILTERING:
ieee802_1x_hs20_t_c_filtering(hapd, sta, pos, sublen);
break;
}
}
#endif /* CONFIG_HS20 */
@ -2739,6 +2762,13 @@ static void ieee802_1x_wnm_notif_send(void *eloop_ctx, void *timeout_ctx)
hs20_send_wnm_notification_deauth_req(hapd, sta->addr,
sta->hs20_deauth_req);
}
if (sta->hs20_t_c_filtering) {
wpa_printf(MSG_DEBUG, "HS 2.0: Send WNM-Notification to "
MACSTR " to indicate Terms and Conditions filtering",
MAC2STR(sta->addr));
hs20_send_wnm_notification_t_c(hapd, sta->addr);
}
}
#endif /* CONFIG_HS20 */
@ -2763,7 +2793,8 @@ static void ieee802_1x_finished(struct hostapd_data *hapd,
sta->remediation_method = 1; /* SOAP-XML SPP */
}
if (success && (sta->remediation || sta->hs20_deauth_req)) {
if (success && (sta->remediation || sta->hs20_deauth_req ||
sta->hs20_t_c_filtering)) {
wpa_printf(MSG_DEBUG, "HS 2.0: Schedule WNM-Notification to "
MACSTR " in 100 ms", MAC2STR(sta->addr));
eloop_cancel_timeout(ieee802_1x_wnm_notif_send, hapd, sta);

View file

@ -116,6 +116,7 @@ struct sta_info {
unsigned int pending_wds_enable:1;
unsigned int power_capab:1;
unsigned int agreed_to_steer:1;
unsigned int hs20_t_c_filtering:1;
u16 auth_alg;

View file

@ -1338,6 +1338,7 @@ enum wmm_ac {
/* WNM-Notification WFA vendors specific subtypes */
#define HS20_WNM_SUB_REM_NEEDED 0
#define HS20_WNM_DEAUTH_IMMINENT_NOTICE 1
#define HS20_WNM_T_C_ACCEPTANCE 2
#define HS20_DEAUTH_REASON_CODE_BSS 0
#define HS20_DEAUTH_REASON_CODE_ESS 1

View file

@ -201,6 +201,7 @@ enum {
RADIUS_VENDOR_ATTR_WFA_HS20_ROAMING_CONSORTIUM = 6,
RADIUS_VENDOR_ATTR_WFA_HS20_T_C_FILENAME = 7,
RADIUS_VENDOR_ATTR_WFA_HS20_TIMESTAMP = 8,
RADIUS_VENDOR_ATTR_WFA_HS20_T_C_FILTERING = 9,
};
#ifdef _MSC_VER