HS 2.0: OSU Provider NAI List advertisement

Extend hostapd to allow the new OSU Provider NAI List ANQP-element to be
advertised in addition to the previously used OSU Providers list
ANQP-element. The new osu_nai2 configurator parameter option is used to
specify the OSU_NAI value for the shared BSS (Single SSID) case while
osu_nai remains to be used for the separate OSU BSS.

Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
This commit is contained in:
Jouni Malinen 2018-10-05 20:49:42 +03:00 committed by Jouni Malinen
parent 1dd66fc103
commit cad810a98f
7 changed files with 74 additions and 1 deletions

View file

@ -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, static int hs20_parse_osu_method_list(struct hostapd_bss_config *bss, char *pos,
int line) int line)
{ {
@ -3761,6 +3779,9 @@ static int hostapd_config_fill(struct hostapd_config *conf,
} else if (os_strcmp(buf, "osu_nai") == 0) { } else if (os_strcmp(buf, "osu_nai") == 0) {
if (hs20_parse_osu_nai(bss, pos, line) < 0) if (hs20_parse_osu_nai(bss, pos, line) < 0)
return 1; 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) { } else if (os_strcmp(buf, "osu_method_list") == 0) {
if (hs20_parse_osu_method_list(bss, pos, line) < 0) if (hs20_parse_osu_method_list(bss, pos, line) < 0)
return 1; return 1;

View file

@ -2227,12 +2227,15 @@ own_ip_addr=127.0.0.1
# OSU Providers # OSU Providers
# One or more sets of following parameter. Each OSU provider is started by the # 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 # 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_server_uri=https://example.com/osu/
#osu_friendly_name=eng:Example operator #osu_friendly_name=eng:Example operator
#osu_friendly_name=fin:Esimerkkipalveluntarjoaja #osu_friendly_name=fin:Esimerkkipalveluntarjoaja
#osu_nai=anonymous@example.com #osu_nai=anonymous@example.com
#osu_nai2=anonymous@example.com
#osu_method_list=1 0 #osu_method_list=1 0
#osu_icon=icon32 #osu_icon=icon32
#osu_icon=icon64 #osu_icon=icon64

View file

@ -631,6 +631,7 @@ void hostapd_config_free_bss(struct hostapd_bss_config *conf)
os_free(p->icons[j]); os_free(p->icons[j]);
os_free(p->icons); os_free(p->icons);
os_free(p->osu_nai); os_free(p->osu_nai);
os_free(p->osu_nai2);
os_free(p->service_desc); os_free(p->service_desc);
} }
os_free(conf->hs20_osu_providers); os_free(conf->hs20_osu_providers);

View file

@ -585,10 +585,12 @@ struct hostapd_bss_config {
char **icons; char **icons;
size_t icons_count; size_t icons_count;
char *osu_nai; char *osu_nai;
char *osu_nai2;
unsigned int service_desc_count; unsigned int service_desc_count;
struct hostapd_lang_string *service_desc; struct hostapd_lang_string *service_desc;
} *hs20_osu_providers, *last_osu; } *hs20_osu_providers, *last_osu;
size_t hs20_osu_providers_count; size_t hs20_osu_providers_count;
size_t hs20_osu_providers_nai_count;
char **hs20_operator_icon; char **hs20_operator_icon;
size_t hs20_operator_icon_count; size_t hs20_operator_icon_count;
unsigned int hs20_deauth_req_timeout; unsigned int hs20_deauth_req_timeout;

View file

@ -181,6 +181,8 @@ static void anqp_add_hs_capab_list(struct hostapd_data *hapd,
wpabuf_put_u8(buf, HS20_STYPE_OPERATING_CLASS); wpabuf_put_u8(buf, HS20_STYPE_OPERATING_CLASS);
if (hapd->conf->hs20_osu_providers_count) if (hapd->conf->hs20_osu_providers_count)
wpabuf_put_u8(buf, HS20_STYPE_OSU_PROVIDERS_LIST); 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) if (hapd->conf->hs20_icons_count)
wpabuf_put_u8(buf, HS20_STYPE_ICON_REQUEST); wpabuf_put_u8(buf, HS20_STYPE_ICON_REQUEST);
if (hapd->conf->hs20_operator_icon_count) 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, static void anqp_add_icon_binary_file(struct hostapd_data *hapd,
struct wpabuf *buf, struct wpabuf *buf,
const u8 *name, size_t name_len) 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); anqp_add_icon_binary_file(hapd, buf, icon_name, icon_name_len);
if (request & ANQP_REQ_OPERATOR_ICON_METADATA) if (request & ANQP_REQ_OPERATOR_ICON_METADATA)
anqp_add_operator_icon_metadata(hapd, buf); 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 */ #endif /* CONFIG_HS20 */
#ifdef CONFIG_MBO #ifdef CONFIG_MBO
@ -1216,6 +1254,11 @@ static void rx_anqp_hs_query_list(struct hostapd_data *hapd, u8 subtype,
"Operator Icon Metadata", "Operator Icon Metadata",
hapd->conf->hs20_operator_icon_count, qi); hapd->conf->hs20_operator_icon_count, qi);
break; 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: default:
wpa_printf(MSG_DEBUG, "ANQP: Unsupported HS 2.0 subtype %u", wpa_printf(MSG_DEBUG, "ANQP: Unsupported HS 2.0 subtype %u",
subtype); subtype);

View file

@ -62,6 +62,8 @@
(0x10000 << HS20_STYPE_ICON_REQUEST) (0x10000 << HS20_STYPE_ICON_REQUEST)
#define ANQP_REQ_OPERATOR_ICON_METADATA \ #define ANQP_REQ_OPERATOR_ICON_METADATA \
(0x10000 << HS20_STYPE_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. */ /* The first MBO ANQP-element can be included in the optimized bitmap. */
#define ANQP_REQ_MBO_CELL_DATA_CONN_PREF \ #define ANQP_REQ_MBO_CELL_DATA_CONN_PREF \
(BIT(29) << MBO_ANQP_SUBTYPE_CELL_CONN_PREF) (BIT(29) << MBO_ANQP_SUBTYPE_CELL_CONN_PREF)

View file

@ -1331,6 +1331,7 @@ enum wmm_ac {
#define HS20_STYPE_ICON_REQUEST 10 #define HS20_STYPE_ICON_REQUEST 10
#define HS20_STYPE_ICON_BINARY_FILE 11 #define HS20_STYPE_ICON_BINARY_FILE 11
#define HS20_STYPE_OPERATOR_ICON_METADATA 12 #define HS20_STYPE_OPERATOR_ICON_METADATA 12
#define HS20_STYPE_OSU_PROVIDERS_NAI_LIST 13
#define HS20_DGAF_DISABLED 0x01 #define HS20_DGAF_DISABLED 0x01
#define HS20_PPS_MO_ID_PRESENT 0x02 #define HS20_PPS_MO_ID_PRESENT 0x02