diff --git a/hostapd/config_file.c b/hostapd/config_file.c index b1ab13e43..fbaa04216 100644 --- a/hostapd/config_file.c +++ b/hostapd/config_file.c @@ -2049,6 +2049,24 @@ static int hs20_parse_osu_nai(struct hostapd_bss_config *bss, } +static int hs20_parse_osu_nai2(struct hostapd_bss_config *bss, + char *pos, int line) +{ + if (bss->last_osu == NULL) { + wpa_printf(MSG_ERROR, "Line %d: Unexpected OSU field", line); + return -1; + } + + os_free(bss->last_osu->osu_nai2); + bss->last_osu->osu_nai2 = os_strdup(pos); + if (bss->last_osu->osu_nai2 == NULL) + return -1; + bss->hs20_osu_providers_nai_count++; + + return 0; +} + + static int hs20_parse_osu_method_list(struct hostapd_bss_config *bss, char *pos, int line) { @@ -3761,6 +3779,9 @@ static int hostapd_config_fill(struct hostapd_config *conf, } else if (os_strcmp(buf, "osu_nai") == 0) { if (hs20_parse_osu_nai(bss, pos, line) < 0) return 1; + } else if (os_strcmp(buf, "osu_nai2") == 0) { + if (hs20_parse_osu_nai2(bss, pos, line) < 0) + return 1; } else if (os_strcmp(buf, "osu_method_list") == 0) { if (hs20_parse_osu_method_list(bss, pos, line) < 0) return 1; diff --git a/hostapd/hostapd.conf b/hostapd/hostapd.conf index 70f9713d3..a00521711 100644 --- a/hostapd/hostapd.conf +++ b/hostapd/hostapd.conf @@ -2227,12 +2227,15 @@ own_ip_addr=127.0.0.1 # OSU Providers # One or more sets of following parameter. Each OSU provider is started by the # mandatory osu_server_uri item. The other parameters add information for the -# last added OSU provider. +# last added OSU provider. osu_nai specifies the OSU_NAI value for OSEN +# authentication when using a standalone OSU BSS. osu_nai2 specifies the OSU_NAI +# value for OSEN authentication when using a shared BSS (Single SSID) for OSU. # #osu_server_uri=https://example.com/osu/ #osu_friendly_name=eng:Example operator #osu_friendly_name=fin:Esimerkkipalveluntarjoaja #osu_nai=anonymous@example.com +#osu_nai2=anonymous@example.com #osu_method_list=1 0 #osu_icon=icon32 #osu_icon=icon64 diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c index 820cba956..f9b6f2959 100644 --- a/src/ap/ap_config.c +++ b/src/ap/ap_config.c @@ -631,6 +631,7 @@ void hostapd_config_free_bss(struct hostapd_bss_config *conf) os_free(p->icons[j]); os_free(p->icons); os_free(p->osu_nai); + os_free(p->osu_nai2); os_free(p->service_desc); } os_free(conf->hs20_osu_providers); diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h index 5b7112609..73d2fd832 100644 --- a/src/ap/ap_config.h +++ b/src/ap/ap_config.h @@ -585,10 +585,12 @@ struct hostapd_bss_config { char **icons; size_t icons_count; char *osu_nai; + char *osu_nai2; unsigned int service_desc_count; struct hostapd_lang_string *service_desc; } *hs20_osu_providers, *last_osu; size_t hs20_osu_providers_count; + size_t hs20_osu_providers_nai_count; char **hs20_operator_icon; size_t hs20_operator_icon_count; unsigned int hs20_deauth_req_timeout; diff --git a/src/ap/gas_serv.c b/src/ap/gas_serv.c index 04fb3e146..a7df81032 100644 --- a/src/ap/gas_serv.c +++ b/src/ap/gas_serv.c @@ -181,6 +181,8 @@ static void anqp_add_hs_capab_list(struct hostapd_data *hapd, wpabuf_put_u8(buf, HS20_STYPE_OPERATING_CLASS); if (hapd->conf->hs20_osu_providers_count) wpabuf_put_u8(buf, HS20_STYPE_OSU_PROVIDERS_LIST); + if (hapd->conf->hs20_osu_providers_nai_count) + wpabuf_put_u8(buf, HS20_STYPE_OSU_PROVIDERS_NAI_LIST); if (hapd->conf->hs20_icons_count) wpabuf_put_u8(buf, HS20_STYPE_ICON_REQUEST); if (hapd->conf->hs20_operator_icon_count) @@ -817,6 +819,40 @@ static void anqp_add_osu_providers_list(struct hostapd_data *hapd, } +static void anqp_add_osu_provider_nai(struct wpabuf *buf, + struct hs20_osu_provider *p) +{ + /* OSU_NAI for shared BSS (Single SSID) */ + if (p->osu_nai2) { + wpabuf_put_u8(buf, os_strlen(p->osu_nai2)); + wpabuf_put_str(buf, p->osu_nai2); + } else { + wpabuf_put_u8(buf, 0); + } +} + + +static void anqp_add_osu_providers_nai_list(struct hostapd_data *hapd, + struct wpabuf *buf) +{ + if (hapd->conf->hs20_osu_providers_nai_count) { + size_t i; + u8 *len = gas_anqp_add_element(buf, ANQP_VENDOR_SPECIFIC); + wpabuf_put_be24(buf, OUI_WFA); + wpabuf_put_u8(buf, HS20_ANQP_OUI_TYPE); + wpabuf_put_u8(buf, HS20_STYPE_OSU_PROVIDERS_NAI_LIST); + wpabuf_put_u8(buf, 0); /* Reserved */ + + for (i = 0; i < hapd->conf->hs20_osu_providers_count; i++) { + anqp_add_osu_provider_nai( + buf, &hapd->conf->hs20_osu_providers[i]); + } + + gas_anqp_set_element_len(buf, len); + } +} + + static void anqp_add_icon_binary_file(struct hostapd_data *hapd, struct wpabuf *buf, const u8 *name, size_t name_len) @@ -1024,6 +1060,8 @@ gas_serv_build_gas_resp_payload(struct hostapd_data *hapd, anqp_add_icon_binary_file(hapd, buf, icon_name, icon_name_len); if (request & ANQP_REQ_OPERATOR_ICON_METADATA) anqp_add_operator_icon_metadata(hapd, buf); + if (request & ANQP_REQ_OSU_PROVIDERS_NAI_LIST) + anqp_add_osu_providers_nai_list(hapd, buf); #endif /* CONFIG_HS20 */ #ifdef CONFIG_MBO @@ -1216,6 +1254,11 @@ static void rx_anqp_hs_query_list(struct hostapd_data *hapd, u8 subtype, "Operator Icon Metadata", hapd->conf->hs20_operator_icon_count, qi); break; + case HS20_STYPE_OSU_PROVIDERS_NAI_LIST: + set_anqp_req(ANQP_REQ_OSU_PROVIDERS_NAI_LIST, + "OSU Providers NAI List", + hapd->conf->hs20_osu_providers_nai_count, qi); + break; default: wpa_printf(MSG_DEBUG, "ANQP: Unsupported HS 2.0 subtype %u", subtype); diff --git a/src/ap/gas_serv.h b/src/ap/gas_serv.h index 0afdcb141..2cf181729 100644 --- a/src/ap/gas_serv.h +++ b/src/ap/gas_serv.h @@ -62,6 +62,8 @@ (0x10000 << HS20_STYPE_ICON_REQUEST) #define ANQP_REQ_OPERATOR_ICON_METADATA \ (0x10000 << HS20_STYPE_OPERATOR_ICON_METADATA) +#define ANQP_REQ_OSU_PROVIDERS_NAI_LIST \ + (0x10000 << HS20_STYPE_OSU_PROVIDERS_NAI_LIST) /* The first MBO ANQP-element can be included in the optimized bitmap. */ #define ANQP_REQ_MBO_CELL_DATA_CONN_PREF \ (BIT(29) << MBO_ANQP_SUBTYPE_CELL_CONN_PREF) diff --git a/src/common/ieee802_11_defs.h b/src/common/ieee802_11_defs.h index e03a09530..80ea605d8 100644 --- a/src/common/ieee802_11_defs.h +++ b/src/common/ieee802_11_defs.h @@ -1331,6 +1331,7 @@ enum wmm_ac { #define HS20_STYPE_ICON_REQUEST 10 #define HS20_STYPE_ICON_BINARY_FILE 11 #define HS20_STYPE_OPERATOR_ICON_METADATA 12 +#define HS20_STYPE_OSU_PROVIDERS_NAI_LIST 13 #define HS20_DGAF_DISABLED 0x01 #define HS20_PPS_MO_ID_PRESENT 0x02