]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
HS 2.0: Send Terms and Conditions Acceptance notification
authorJouni Malinen <jouni@codeaurora.org>
Mon, 23 Apr 2018 21:05:44 +0000 (00:05 +0300)
committerJouni Malinen <j@w1.fi>
Mon, 23 Apr 2018 21:35:47 +0000 (00:35 +0300)
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>
hostapd/config_file.c
hostapd/hostapd.conf
src/ap/ap_config.c
src/ap/ap_config.h
src/ap/hs20.c
src/ap/hs20.h
src/ap/ieee802_1x.c
src/ap/sta_info.h
src/common/ieee802_11_defs.h
src/radius/radius.h

index c611551f466f3a126da0c2695d3b963727444baf..bd52f4ae7b3961c366f436bb01312bd3b3fa5d8b 100644 (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) {
index f65c00435b30d35144a6543866bc02fc939be740..b5a271866720601061830cac297e37516bf0d4ce 100644 (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>
index 6de5d40e94e657991662f3b6d4898603cdc34782..d9f50b1f9d61b67fa2d0ecec302a0e125a0f4785 100644 (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);
index 95eb3d4b510c535095c369f8fb1a31bba4a67c5b..7f24e6f68888e0dc725d9c1ac2d1dbeae299e3cb 100644 (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_*) */
index d7909fad4a144d1028c883b138cd7de482ad9abc..79523f91e9603a4c55356c8ba835f1407cd70eec 100644 (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;
+}
index 152439f4dcb45f5689f5a9dd63b613a73ced625c..70ecc94730e683f4694127e8fc2624e6490387bf 100644 (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 */
index 9663bd757742fd266bfb92e5ad101cb3f7d9c8db..630787de4b2c5bb4aac3059574f80f5f0734d9fa 100644 (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);
index 74910d1d23e51de4fa10ee70acf1c3177858390d..0459549ebc6be17a4e9cf2b51360dc92da417175 100644 (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;
 
index 45bbead39f50fc55dad066d18999cd786eef1ffe..ff2912518042dc27365117a8805d75506be5cb84 100644 (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
index 3d26cf735a698b0bb1519445acf6a8a658d82e26..55185dfb32288968cd47f7b8e23f6f7a33d86af2 100644 (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