diff options
Diffstat (limited to 'contrib/wpa/wpa_supplicant/interworking.c')
-rw-r--r-- | contrib/wpa/wpa_supplicant/interworking.c | 66 |
1 files changed, 44 insertions, 22 deletions
diff --git a/contrib/wpa/wpa_supplicant/interworking.c b/contrib/wpa/wpa_supplicant/interworking.c index dd35571d914b..1c82d2117ab0 100644 --- a/contrib/wpa/wpa_supplicant/interworking.c +++ b/contrib/wpa/wpa_supplicant/interworking.c @@ -176,7 +176,7 @@ static int cred_with_nai_realm(struct wpa_supplicant *wpa_s) continue; if (!cred->eap_method) return 1; - if (cred->realm && cred->roaming_consortium_len == 0) + if (cred->realm) return 1; } return 0; @@ -316,7 +316,7 @@ static int interworking_anqp_send_req(struct wpa_supplicant *wpa_s, if (buf == NULL) return -1; - res = gas_query_req(wpa_s->gas, bss->bssid, bss->freq, 0, buf, + res = gas_query_req(wpa_s->gas, bss->bssid, bss->freq, 0, 0, buf, interworking_anqp_resp_cb, wpa_s); if (res < 0) { wpa_msg(wpa_s, MSG_DEBUG, "ANQP: Failed to send Query Request"); @@ -946,7 +946,8 @@ static int interworking_set_hs20_params(struct wpa_supplicant *wpa_s, struct wpa_driver_capa capa; res = wpa_drv_get_capa(wpa_s, &capa); - if (res == 0 && capa.key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_FT) { + if (res == 0 && capa.key_mgmt_iftype[WPA_IF_STATION] & + WPA_DRIVER_CAPA_KEY_MGMT_FT) { key_mgmt = wpa_s->conf->pmf != NO_MGMT_FRAME_PROTECTION ? "WPA-EAP WPA-EAP-SHA256 FT-EAP" : "WPA-EAP FT-EAP"; @@ -958,7 +959,9 @@ static int interworking_set_hs20_params(struct wpa_supplicant *wpa_s, "WPA-EAP WPA-EAP-SHA256" : "WPA-EAP"; if (wpa_config_set(ssid, "key_mgmt", key_mgmt, 0) < 0 || wpa_config_set(ssid, "proto", "RSN", 0) < 0 || - wpa_config_set(ssid, "ieee80211w", "1", 0) < 0 || + wpa_config_set(ssid, "ieee80211w", + wpa_s->conf->pmf == MGMT_FRAME_PROTECTION_REQUIRED ? + "2" : "1", 0) < 0 || wpa_config_set(ssid, "pairwise", "CCMP", 0) < 0) return -1; return 0; @@ -1395,7 +1398,11 @@ static struct wpa_cred * interworking_credentials_available_roaming_consortium( !roaming_consortium_match(ie, anqp, cred->roaming_consortium, cred->roaming_consortium_len)) && - !cred_roaming_consortiums_match(ie, anqp, cred)) + !cred_roaming_consortiums_match(ie, anqp, cred) && + (cred->required_roaming_consortium_len == 0 || + !roaming_consortium_match( + ie, anqp, cred->required_roaming_consortium, + cred->required_roaming_consortium_len))) continue; if (cred_no_required_oi_match(cred, bss)) @@ -1550,7 +1557,7 @@ static int interworking_set_eap_params(struct wpa_ssid *ssid, cred->domain_suffix_match) < 0) return -1; - ssid->eap.ocsp = cred->ocsp; + ssid->eap.cert.ocsp = cred->ocsp; return 0; } @@ -2258,7 +2265,7 @@ int interworking_home_sp_cred(struct wpa_supplicant *wpa_s, realm++; wpa_msg(wpa_s, MSG_DEBUG, "Interworking: Search for match with SIM/USIM domain %s", - realm); + realm ? realm : "[NULL]"); if (realm && domain_name_list_contains(domain_names, realm, 1)) return 1; @@ -2475,7 +2482,7 @@ static void interworking_select_network(struct wpa_supplicant *wpa_s) bss_load = cred_over_max_bss_load(wpa_s, cred, bss); conn_capab = cred_conn_capab_missing(wpa_s, cred, bss); wpa_msg(wpa_s, MSG_INFO, "%s" MACSTR " type=%s%s%s%s id=%d priority=%d sp_priority=%d", - excluded ? INTERWORKING_BLACKLISTED : INTERWORKING_AP, + excluded ? INTERWORKING_EXCLUDED : INTERWORKING_AP, MAC2STR(bss->bssid), type, bh ? " below_min_backhaul=1" : "", bss_load ? " over_max_bss_load=1" : "", @@ -2525,7 +2532,7 @@ static void interworking_select_network(struct wpa_supplicant *wpa_s) (selected_cred == NULL || cred_prio_cmp(selected_home_cred, selected_cred) >= 0)) { /* Prefer network operated by the Home SP */ - wpa_printf(MSG_DEBUG, "Interworking: Overrided selected with selected_home"); + wpa_printf(MSG_DEBUG, "Interworking: Overrode selected with selected_home"); selected = selected_home; selected_cred = selected_home_cred; } @@ -2743,27 +2750,27 @@ void interworking_stop_fetch_anqp(struct wpa_supplicant *wpa_s) } -int anqp_send_req(struct wpa_supplicant *wpa_s, const u8 *dst, +int anqp_send_req(struct wpa_supplicant *wpa_s, const u8 *dst, int freq, u16 info_ids[], size_t num_ids, u32 subtypes, u32 mbo_subtypes) { struct wpabuf *buf; struct wpabuf *extra_buf = NULL; int ret = 0; - int freq; struct wpa_bss *bss; int res; bss = wpa_bss_get_bssid(wpa_s, dst); - if (!bss) { + if (!bss && !freq) { wpa_printf(MSG_WARNING, - "ANQP: Cannot send query to unknown BSS " - MACSTR, MAC2STR(dst)); + "ANQP: Cannot send query without BSS freq info"); return -1; } - wpa_bss_anqp_unshare_alloc(bss); - freq = bss->freq; + if (bss) + wpa_bss_anqp_unshare_alloc(bss); + if (bss && !freq) + freq = bss->freq; wpa_msg(wpa_s, MSG_DEBUG, "ANQP: Query Request to " MACSTR " for %u id(s)", @@ -2782,6 +2789,14 @@ int anqp_send_req(struct wpa_supplicant *wpa_s, const u8 *dst, if (mbo_subtypes) { struct wpabuf *mbo; + if (!bss) { + wpa_printf(MSG_WARNING, + "ANQP: Cannot send MBO query to unknown BSS " + MACSTR, MAC2STR(dst)); + wpabuf_free(extra_buf); + return -1; + } + mbo = mbo_build_anqp_buf(wpa_s, bss, mbo_subtypes); if (mbo) { if (wpabuf_resize(&extra_buf, wpabuf_len(mbo))) { @@ -2800,7 +2815,8 @@ int anqp_send_req(struct wpa_supplicant *wpa_s, const u8 *dst, if (buf == NULL) return -1; - res = gas_query_req(wpa_s->gas, dst, freq, 0, buf, anqp_resp_cb, wpa_s); + res = gas_query_req(wpa_s->gas, dst, freq, 0, 0, buf, anqp_resp_cb, + wpa_s); if (res < 0) { wpa_msg(wpa_s, MSG_DEBUG, "ANQP: Failed to send Query Request"); wpabuf_free(buf); @@ -2816,7 +2832,7 @@ int anqp_send_req(struct wpa_supplicant *wpa_s, const u8 *dst, static void anqp_add_extra(struct wpa_supplicant *wpa_s, struct wpa_bss_anqp *anqp, u16 info_id, - const u8 *data, size_t slen) + const u8 *data, size_t slen, bool protected_response) { struct wpa_bss_anqp_elem *tmp, *elem = NULL; @@ -2841,6 +2857,7 @@ static void anqp_add_extra(struct wpa_supplicant *wpa_s, wpabuf_free(elem->payload); } + elem->protected_response = protected_response; elem->payload = wpabuf_alloc_copy(data, slen); if (!elem->payload) { dl_list_del(&elem->list); @@ -2883,6 +2900,7 @@ static void interworking_parse_rx_anqp_resp(struct wpa_supplicant *wpa_s, const u8 *pos = data; struct wpa_bss_anqp *anqp = NULL; u8 type; + bool protected_response; if (bss) anqp = bss->anqp; @@ -2983,9 +3001,11 @@ static void interworking_parse_rx_anqp_resp(struct wpa_supplicant *wpa_s, case ANQP_VENUE_URL: wpa_msg(wpa_s, MSG_INFO, RX_ANQP MACSTR " Venue URL", MAC2STR(sa)); - anqp_add_extra(wpa_s, anqp, info_id, pos, slen); + protected_response = pmf_in_use(wpa_s, sa); + anqp_add_extra(wpa_s, anqp, info_id, pos, slen, + protected_response); - if (!pmf_in_use(wpa_s, sa)) { + if (!protected_response) { wpa_printf(MSG_DEBUG, "ANQP: Ignore Venue URL since PMF was not enabled"); break; @@ -3037,7 +3057,8 @@ static void interworking_parse_rx_anqp_resp(struct wpa_supplicant *wpa_s, default: wpa_msg(wpa_s, MSG_DEBUG, "Interworking: Unsupported ANQP Info ID %u", info_id); - anqp_add_extra(wpa_s, anqp, info_id, data, slen); + anqp_add_extra(wpa_s, anqp, info_id, data, slen, + pmf_in_use(wpa_s, sa)); break; } } @@ -3239,7 +3260,8 @@ int gas_send_request(struct wpa_supplicant *wpa_s, const u8 *dst, } else wpabuf_put_le16(buf, 0); - res = gas_query_req(wpa_s->gas, dst, freq, 0, buf, gas_resp_cb, wpa_s); + res = gas_query_req(wpa_s->gas, dst, freq, 0, 0, buf, gas_resp_cb, + wpa_s); if (res < 0) { wpa_msg(wpa_s, MSG_DEBUG, "GAS: Failed to send Query Request"); wpabuf_free(buf); |