diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c index 888518ea1..3c405be4b 100644 --- a/wpa_supplicant/config.c +++ b/wpa_supplicant/config.c @@ -2487,6 +2487,21 @@ int wpa_config_set_cred(struct wpa_cred *cred, const char *var, return 0; } + if (os_strcmp(var, "required_roaming_consortium") == 0) { + if (len < 3 || len > sizeof(cred->required_roaming_consortium)) + { + wpa_printf(MSG_ERROR, "Line %d: invalid " + "required_roaming_consortium length %d " + "(3..15 expected)", line, (int) len); + os_free(val); + return -1; + } + os_memcpy(cred->required_roaming_consortium, val, len); + cred->required_roaming_consortium_len = len; + os_free(val); + return 0; + } + if (os_strcmp(var, "excluded_ssid") == 0) { struct excluded_ssid *e; diff --git a/wpa_supplicant/config.h b/wpa_supplicant/config.h index 64396df0d..e53c6367b 100644 --- a/wpa_supplicant/config.h +++ b/wpa_supplicant/config.h @@ -200,6 +200,9 @@ struct wpa_cred { */ size_t roaming_consortium_len; + u8 required_roaming_consortium[15]; + size_t required_roaming_consortium_len; + /** * eap_method - EAP method to use * diff --git a/wpa_supplicant/interworking.c b/wpa_supplicant/interworking.c index c296386eb..666e786a2 100644 --- a/wpa_supplicant/interworking.c +++ b/wpa_supplicant/interworking.c @@ -112,6 +112,8 @@ static int cred_with_roaming_consortium(struct wpa_supplicant *wpa_s) for (cred = wpa_s->conf->cred; cred; cred = cred->next) { if (cred->roaming_consortium_len) return 1; + if (cred->required_roaming_consortium_len) + return 1; } return 0; } @@ -944,6 +946,27 @@ static int roaming_consortium_match(const u8 *ie, const struct wpabuf *anqp, } +static int cred_no_required_oi_match(struct wpa_cred *cred, struct wpa_bss *bss) +{ + const u8 *ie; + + if (cred->required_roaming_consortium_len == 0) + return 0; + + ie = wpa_bss_get_ie(bss, WLAN_EID_ROAMING_CONSORTIUM); + + if (ie == NULL && + (bss->anqp == NULL || bss->anqp->roaming_consortium == NULL)) + return 1; + + return !roaming_consortium_match(ie, + bss->anqp ? + bss->anqp->roaming_consortium : NULL, + cred->required_roaming_consortium, + cred->required_roaming_consortium_len); +} + + static int cred_excluded_ssid(struct wpa_cred *cred, struct wpa_bss *bss) { size_t i; @@ -991,6 +1014,8 @@ static struct wpa_cred * interworking_credentials_available_roaming_consortium( if (cred_excluded_ssid(cred, bss)) continue; + if (cred_no_required_oi_match(cred, bss)) + continue; if (selected == NULL || selected->priority < cred->priority) @@ -1409,6 +1434,8 @@ static struct wpa_cred * interworking_credentials_available_3gpp( if (ret) { if (cred_excluded_ssid(cred, bss)) continue; + if (cred_no_required_oi_match(cred, bss)) + continue; if (selected == NULL || selected->priority < cred->priority) selected = cred; @@ -1451,6 +1478,8 @@ static struct wpa_cred * interworking_credentials_available_realm( if (nai_realm_find_eap(cred, &realm[i])) { if (cred_excluded_ssid(cred, bss)) continue; + if (cred_no_required_oi_match(cred, bss)) + continue; if (selected == NULL || selected->priority < cred->priority) selected = cred;