From 67cca34645638c5cbac4a0a3064ac4bea13eb090 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Tue, 17 Apr 2018 13:08:31 +0300 Subject: [PATCH] HS 2.0: Copy Roaming Consortium OI from (Re)AssocReq to Access-Request This extends hostapd processing of (Re)Association Request frames to store a local copy of the Consortium OI within the Roaming Consortium Selection element, if present, and then add that in HS 2.0 Roaming Consortium attribute into RADIUS Access-Request messages. Signed-off-by: Jouni Malinen --- src/ap/drv_callbacks.c | 8 ++++++++ src/ap/ieee802_11.c | 8 ++++++++ src/ap/ieee802_1x.c | 10 ++++++++++ src/ap/sta_info.c | 1 + src/ap/sta_info.h | 2 ++ src/common/ieee802_11_common.c | 5 +++++ src/common/ieee802_11_common.h | 2 ++ src/common/ieee802_11_defs.h | 1 + src/radius/radius.h | 1 + 9 files changed, 38 insertions(+) diff --git a/src/ap/drv_callbacks.c b/src/ap/drv_callbacks.c index b9443ee24..59299ad1b 100644 --- a/src/ap/drv_callbacks.c +++ b/src/ap/drv_callbacks.c @@ -235,6 +235,14 @@ int hostapd_notif_assoc(struct hostapd_data *hapd, const u8 *addr, elems.hs20_len - 4); } else sta->hs20_ie = NULL; + + wpabuf_free(sta->roaming_consortium); + if (elems.roaming_cons_sel) + sta->roaming_consortium = wpabuf_alloc_copy( + elems.roaming_cons_sel + 4, + elems.roaming_cons_sel_len - 4); + else + sta->roaming_consortium = NULL; #endif /* CONFIG_HS20 */ #ifdef CONFIG_FST diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c index bf94571cb..68c0da24d 100644 --- a/src/ap/ieee802_11.c +++ b/src/ap/ieee802_11.c @@ -2651,6 +2651,14 @@ static u16 check_assoc_ies(struct hostapd_data *hapd, struct sta_info *sta, elems.hs20_len - 4); } else sta->hs20_ie = NULL; + + wpabuf_free(sta->roaming_consortium); + if (elems.roaming_cons_sel) + sta->roaming_consortium = wpabuf_alloc_copy( + elems.roaming_cons_sel + 4, + elems.roaming_cons_sel_len - 4); + else + sta->roaming_consortium = NULL; #endif /* CONFIG_HS20 */ #ifdef CONFIG_FST diff --git a/src/ap/ieee802_1x.c b/src/ap/ieee802_1x.c index 98dc2bc5b..4fcccce72 100644 --- a/src/ap/ieee802_1x.c +++ b/src/ap/ieee802_1x.c @@ -712,6 +712,16 @@ void ieee802_1x_encapsulate_radius(struct hostapd_data *hapd, goto fail; } } + + if (sta->roaming_consortium && + !radius_msg_add_wfa( + msg, RADIUS_VENDOR_ATTR_WFA_HS20_ROAMING_CONSORTIUM, + wpabuf_head(sta->roaming_consortium), + wpabuf_len(sta->roaming_consortium))) { + wpa_printf(MSG_ERROR, + "Could not add HS 2.0 Roaming Consortium"); + goto fail; + } } #endif /* CONFIG_HS20 */ diff --git a/src/ap/sta_info.c b/src/ap/sta_info.c index 154879c06..cb9be2832 100644 --- a/src/ap/sta_info.c +++ b/src/ap/sta_info.c @@ -321,6 +321,7 @@ void ap_free_sta(struct hostapd_data *hapd, struct sta_info *sta) wpabuf_free(sta->wps_ie); wpabuf_free(sta->p2p_ie); wpabuf_free(sta->hs20_ie); + wpabuf_free(sta->roaming_consortium); #ifdef CONFIG_FST wpabuf_free(sta->mb_ies); #endif /* CONFIG_FST */ diff --git a/src/ap/sta_info.h b/src/ap/sta_info.h index fc7777bf9..896a2b54c 100644 --- a/src/ap/sta_info.h +++ b/src/ap/sta_info.h @@ -182,6 +182,8 @@ struct sta_info { struct wpabuf *wps_ie; /* WPS IE from (Re)Association Request */ struct wpabuf *p2p_ie; /* P2P IE from (Re)Association Request */ struct wpabuf *hs20_ie; /* HS 2.0 IE from (Re)Association Request */ + /* Hotspot 2.0 Roaming Consortium from (Re)Association Request */ + struct wpabuf *roaming_consortium; u8 remediation_method; char *remediation_url; /* HS 2.0 Subscription Remediation Server URL */ struct wpabuf *hs20_deauth_req; diff --git a/src/common/ieee802_11_common.c b/src/common/ieee802_11_common.c index f04e77fa5..d29c60188 100644 --- a/src/common/ieee802_11_common.c +++ b/src/common/ieee802_11_common.c @@ -120,6 +120,11 @@ static int ieee802_11_parse_vendor_specific(const u8 *pos, size_t elen, elems->mbo = pos; elems->mbo_len = elen; break; + case HS20_ROAMING_CONS_SEL_OUI_TYPE: + /* Hotspot 2.0 Roaming Consortium Selection */ + elems->roaming_cons_sel = pos; + elems->roaming_cons_sel_len = elen; + break; default: wpa_printf(MSG_MSGDUMP, "Unknown WFA " "information element ignored " diff --git a/src/common/ieee802_11_common.h b/src/common/ieee802_11_common.h index 89ca92b70..bbb916b1f 100644 --- a/src/common/ieee802_11_common.h +++ b/src/common/ieee802_11_common.h @@ -80,6 +80,7 @@ struct ieee802_11_elems { const u8 *fils_nonce; const u8 *owe_dh; const u8 *power_capab; + const u8 *roaming_cons_sel; u8 ssid_len; u8 supp_rates_len; @@ -124,6 +125,7 @@ struct ieee802_11_elems { u8 fils_pk_len; u8 owe_dh_len; u8 power_capab_len; + u8 roaming_cons_sel_len; struct mb_ies_info mb_ies; }; diff --git a/src/common/ieee802_11_defs.h b/src/common/ieee802_11_defs.h index 2bd585f21..45bbead39 100644 --- a/src/common/ieee802_11_defs.h +++ b/src/common/ieee802_11_defs.h @@ -1317,6 +1317,7 @@ enum wmm_ac { #define HS20_INDICATION_OUI_TYPE 16 #define HS20_ANQP_OUI_TYPE 17 #define HS20_OSEN_OUI_TYPE 18 +#define HS20_ROAMING_CONS_SEL_OUI_TYPE 29 #define HS20_STYPE_QUERY_LIST 1 #define HS20_STYPE_CAPABILITY_LIST 2 #define HS20_STYPE_OPERATOR_FRIENDLY_NAME 3 diff --git a/src/radius/radius.h b/src/radius/radius.h index a75922d44..bed7f230e 100644 --- a/src/radius/radius.h +++ b/src/radius/radius.h @@ -198,6 +198,7 @@ enum { RADIUS_VENDOR_ATTR_WFA_HS20_STA_VERSION = 3, 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, }; #ifdef _MSC_VER