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:
parent
6cb8f4f382
commit
8760b9848c
10 changed files with 92 additions and 1 deletions
|
@ -3634,6 +3634,9 @@ static int hostapd_config_fill(struct hostapd_config *conf,
|
||||||
bss->t_c_filename = os_strdup(pos);
|
bss->t_c_filename = os_strdup(pos);
|
||||||
} else if (os_strcmp(buf, "hs20_t_c_timestamp") == 0) {
|
} else if (os_strcmp(buf, "hs20_t_c_timestamp") == 0) {
|
||||||
bss->t_c_timestamp = strtol(pos, NULL, 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 */
|
#endif /* CONFIG_HS20 */
|
||||||
#ifdef CONFIG_MBO
|
#ifdef CONFIG_MBO
|
||||||
} else if (os_strcmp(buf, "mbo") == 0) {
|
} else if (os_strcmp(buf, "mbo") == 0) {
|
||||||
|
|
|
@ -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
|
# of seconds since January 1, 1970 00:00 UTC showing the time when the file was
|
||||||
# last modified.
|
# last modified.
|
||||||
#hs20_t_c_timestamp=1234567
|
#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
|
# OSU and Operator icons
|
||||||
# <Icon Width>:<Icon Height>:<Language code>:<Icon Type>:<Name>:<file path>
|
# <Icon Width>:<Icon Height>:<Language code>:<Icon Type>:<Name>:<file path>
|
||||||
|
|
|
@ -621,6 +621,7 @@ void hostapd_config_free_bss(struct hostapd_bss_config *conf)
|
||||||
}
|
}
|
||||||
os_free(conf->subscr_remediation_url);
|
os_free(conf->subscr_remediation_url);
|
||||||
os_free(conf->t_c_filename);
|
os_free(conf->t_c_filename);
|
||||||
|
os_free(conf->t_c_server_url);
|
||||||
#endif /* CONFIG_HS20 */
|
#endif /* CONFIG_HS20 */
|
||||||
|
|
||||||
wpabuf_free(conf->vendor_elements);
|
wpabuf_free(conf->vendor_elements);
|
||||||
|
|
|
@ -587,6 +587,7 @@ struct hostapd_bss_config {
|
||||||
u8 subscr_remediation_method;
|
u8 subscr_remediation_method;
|
||||||
char *t_c_filename;
|
char *t_c_filename;
|
||||||
u32 t_c_timestamp;
|
u32 t_c_timestamp;
|
||||||
|
char *t_c_server_url;
|
||||||
#endif /* CONFIG_HS20 */
|
#endif /* CONFIG_HS20 */
|
||||||
|
|
||||||
u8 wps_rf_bands; /* RF bands for WPS (WPS_RF_*) */
|
u8 wps_rf_bands; /* RF bands for WPS (WPS_RF_*) */
|
||||||
|
|
|
@ -175,3 +175,46 @@ int hs20_send_wnm_notification_deauth_req(struct hostapd_data *hapd,
|
||||||
|
|
||||||
return ret;
|
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;
|
||||||
|
}
|
||||||
|
|
|
@ -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,
|
int hs20_send_wnm_notification_deauth_req(struct hostapd_data *hapd,
|
||||||
const u8 *addr,
|
const u8 *addr,
|
||||||
const struct wpabuf *payload);
|
const struct wpabuf *payload);
|
||||||
|
int hs20_send_wnm_notification_t_c(struct hostapd_data *hapd,
|
||||||
|
const u8 *addr);
|
||||||
|
|
||||||
#endif /* HS20_H */
|
#endif /* HS20_H */
|
||||||
|
|
|
@ -1622,6 +1622,26 @@ static void ieee802_1x_hs20_session_info(struct hostapd_data *hapd,
|
||||||
ap_sta_session_warning_timeout(hapd, sta, warning_time);
|
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 */
|
#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,
|
ieee802_1x_hs20_session_info(hapd, sta, pos, sublen,
|
||||||
session_timeout);
|
session_timeout);
|
||||||
break;
|
break;
|
||||||
|
case RADIUS_VENDOR_ATTR_WFA_HS20_T_C_FILTERING:
|
||||||
|
ieee802_1x_hs20_t_c_filtering(hapd, sta, pos, sublen);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_HS20 */
|
#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,
|
hs20_send_wnm_notification_deauth_req(hapd, sta->addr,
|
||||||
sta->hs20_deauth_req);
|
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 */
|
#endif /* CONFIG_HS20 */
|
||||||
|
|
||||||
|
@ -2763,7 +2793,8 @@ static void ieee802_1x_finished(struct hostapd_data *hapd,
|
||||||
sta->remediation_method = 1; /* SOAP-XML SPP */
|
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 "
|
wpa_printf(MSG_DEBUG, "HS 2.0: Schedule WNM-Notification to "
|
||||||
MACSTR " in 100 ms", MAC2STR(sta->addr));
|
MACSTR " in 100 ms", MAC2STR(sta->addr));
|
||||||
eloop_cancel_timeout(ieee802_1x_wnm_notif_send, hapd, sta);
|
eloop_cancel_timeout(ieee802_1x_wnm_notif_send, hapd, sta);
|
||||||
|
|
|
@ -116,6 +116,7 @@ struct sta_info {
|
||||||
unsigned int pending_wds_enable:1;
|
unsigned int pending_wds_enable:1;
|
||||||
unsigned int power_capab:1;
|
unsigned int power_capab:1;
|
||||||
unsigned int agreed_to_steer:1;
|
unsigned int agreed_to_steer:1;
|
||||||
|
unsigned int hs20_t_c_filtering:1;
|
||||||
|
|
||||||
u16 auth_alg;
|
u16 auth_alg;
|
||||||
|
|
||||||
|
|
|
@ -1338,6 +1338,7 @@ enum wmm_ac {
|
||||||
/* WNM-Notification WFA vendors specific subtypes */
|
/* WNM-Notification WFA vendors specific subtypes */
|
||||||
#define HS20_WNM_SUB_REM_NEEDED 0
|
#define HS20_WNM_SUB_REM_NEEDED 0
|
||||||
#define HS20_WNM_DEAUTH_IMMINENT_NOTICE 1
|
#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_BSS 0
|
||||||
#define HS20_DEAUTH_REASON_CODE_ESS 1
|
#define HS20_DEAUTH_REASON_CODE_ESS 1
|
||||||
|
|
|
@ -201,6 +201,7 @@ enum {
|
||||||
RADIUS_VENDOR_ATTR_WFA_HS20_ROAMING_CONSORTIUM = 6,
|
RADIUS_VENDOR_ATTR_WFA_HS20_ROAMING_CONSORTIUM = 6,
|
||||||
RADIUS_VENDOR_ATTR_WFA_HS20_T_C_FILENAME = 7,
|
RADIUS_VENDOR_ATTR_WFA_HS20_T_C_FILENAME = 7,
|
||||||
RADIUS_VENDOR_ATTR_WFA_HS20_TIMESTAMP = 8,
|
RADIUS_VENDOR_ATTR_WFA_HS20_TIMESTAMP = 8,
|
||||||
|
RADIUS_VENDOR_ATTR_WFA_HS20_T_C_FILTERING = 9,
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
|
|
Loading…
Reference in a new issue