104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt/* 204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * Copyright (c) 2009, Atheros Communications, Inc. 3f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt * Copyright (c) 2011-2013, Qualcomm Atheros, Inc. 404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * 504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * This software may be distributed under the terms of the BSD license. 604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * See README for more details. 704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt */ 804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#include "includes.h" 102f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt#include <sys/stat.h> 1104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 1204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#include "common.h" 1304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#include "eloop.h" 1404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#include "common/ieee802_11_common.h" 1504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#include "common/ieee802_11_defs.h" 1604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#include "common/gas.h" 1704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#include "common/wpa_ctrl.h" 18f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt#include "rsn_supp/wpa.h" 1904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#include "wpa_supplicant_i.h" 2004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#include "driver_i.h" 2104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#include "config.h" 22f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt#include "scan.h" 2304a9d74743634109939ddb9bc40814681a03dc84Roshan Pius#include "notify.h" 2404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#include "bss.h" 25f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt#include "blacklist.h" 2604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#include "gas_query.h" 2704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#include "interworking.h" 2804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#include "hs20_supplicant.h" 297d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt#include "base64.h" 3004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 3104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 32f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt#define OSU_MAX_ITEMS 10 33f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 34f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidtstruct osu_lang_string { 35f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt char lang[4]; 36f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt char text[253]; 37f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt}; 38f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 39f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidtstruct osu_icon { 40f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt u16 width; 41f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt u16 height; 42f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt char lang[4]; 43f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt char icon_type[256]; 44f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt char filename[256]; 45f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt unsigned int id; 46f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt unsigned int failed:1; 47f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt}; 48f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 49f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidtstruct osu_provider { 50f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt u8 bssid[ETH_ALEN]; 519d9e60286e05ae45025b672636490bd12586138dDmitry Shmidt u8 osu_ssid[SSID_MAX_LEN]; 52f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt u8 osu_ssid_len; 53f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt char server_uri[256]; 54f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt u32 osu_methods; /* bit 0 = OMA-DM, bit 1 = SOAP-XML SPP */ 55f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt char osu_nai[256]; 56f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt struct osu_lang_string friendly_name[OSU_MAX_ITEMS]; 57f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt size_t friendly_name_count; 58f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt struct osu_lang_string serv_desc[OSU_MAX_ITEMS]; 59f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt size_t serv_desc_count; 60f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt struct osu_icon icon[OSU_MAX_ITEMS]; 61f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt size_t icon_count; 62f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt}; 63f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 64f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 65849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidtvoid hs20_configure_frame_filters(struct wpa_supplicant *wpa_s) 66849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt{ 67849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt struct wpa_bss *bss = wpa_s->current_bss; 68849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt u8 *bssid = wpa_s->bssid; 69849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt const u8 *ie; 70849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt const u8 *ext_capa; 71849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt u32 filter = 0; 72849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt 73849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt if (!bss || !is_hs20_network(wpa_s, wpa_s->current_ssid, bss)) { 74849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt wpa_printf(MSG_DEBUG, 75849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt "Not configuring frame filtering - BSS " MACSTR 76849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt " is not a Hotspot 2.0 network", MAC2STR(bssid)); 77849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt return; 78849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt } 79849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt 80849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt ie = wpa_bss_get_vendor_ie(bss, HS20_IE_VENDOR_TYPE); 81849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt 82849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt /* Check if DGAF disabled bit is zero (5th byte in the IE) */ 83849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt if (!ie || ie[1] < 5) 84849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt wpa_printf(MSG_DEBUG, 85849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt "Not configuring frame filtering - Can't extract DGAF bit"); 86849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt else if (!(ie[6] & HS20_DGAF_DISABLED)) 87849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt filter |= WPA_DATA_FRAME_FILTER_FLAG_GTK; 88849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt 89849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt ext_capa = wpa_bss_get_ie(bss, WLAN_EID_EXT_CAPAB); 90849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt if (!ext_capa || ext_capa[1] < 2) { 91849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt wpa_printf(MSG_DEBUG, 92849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt "Not configuring frame filtering - Can't extract Proxy ARP bit"); 93849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt return; 94849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt } 95849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt 96849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt /* Check if Proxy ARP is enabled (2nd byte in the IE) */ 97849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt if (ext_capa[3] & BIT(4)) 98849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt filter |= WPA_DATA_FRAME_FILTER_FLAG_ARP | 99849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt WPA_DATA_FRAME_FILTER_FLAG_NA; 100849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt 101849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt wpa_drv_configure_frame_filters(wpa_s, filter); 102849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt} 103849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt 104849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt 105f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidtvoid wpas_hs20_add_indication(struct wpabuf *buf, int pps_mo_id) 10604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 107f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt u8 conf; 108f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 10904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpabuf_put_u8(buf, WLAN_EID_VENDOR_SPECIFIC); 110f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpabuf_put_u8(buf, pps_mo_id >= 0 ? 7 : 5); 11104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpabuf_put_be24(buf, OUI_WFA); 11204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpabuf_put_u8(buf, HS20_INDICATION_OUI_TYPE); 113f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt conf = HS20_VERSION; 114f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (pps_mo_id >= 0) 115f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt conf |= HS20_PPS_MO_ID_PRESENT; 116f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpabuf_put_u8(buf, conf); 117f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (pps_mo_id >= 0) 118f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpabuf_put_le16(buf, pps_mo_id); 11904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 12004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 12104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 12251b6ea882f234c14cd1fe1332a3840cf61fafccaDmitry Shmidtint is_hs20_network(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid, 12351b6ea882f234c14cd1fe1332a3840cf61fafccaDmitry Shmidt struct wpa_bss *bss) 12451b6ea882f234c14cd1fe1332a3840cf61fafccaDmitry Shmidt{ 12551b6ea882f234c14cd1fe1332a3840cf61fafccaDmitry Shmidt if (!wpa_s->conf->hs20 || !ssid) 12651b6ea882f234c14cd1fe1332a3840cf61fafccaDmitry Shmidt return 0; 12751b6ea882f234c14cd1fe1332a3840cf61fafccaDmitry Shmidt 12851b6ea882f234c14cd1fe1332a3840cf61fafccaDmitry Shmidt if (ssid->parent_cred) 12951b6ea882f234c14cd1fe1332a3840cf61fafccaDmitry Shmidt return 1; 13051b6ea882f234c14cd1fe1332a3840cf61fafccaDmitry Shmidt 13151b6ea882f234c14cd1fe1332a3840cf61fafccaDmitry Shmidt if (bss && !wpa_bss_get_vendor_ie(bss, HS20_IE_VENDOR_TYPE)) 13251b6ea882f234c14cd1fe1332a3840cf61fafccaDmitry Shmidt return 0; 13351b6ea882f234c14cd1fe1332a3840cf61fafccaDmitry Shmidt 13451b6ea882f234c14cd1fe1332a3840cf61fafccaDmitry Shmidt /* 13551b6ea882f234c14cd1fe1332a3840cf61fafccaDmitry Shmidt * This may catch some non-Hotspot 2.0 cases, but it is safer to do that 13651b6ea882f234c14cd1fe1332a3840cf61fafccaDmitry Shmidt * than cause Hotspot 2.0 connections without indication element getting 13751b6ea882f234c14cd1fe1332a3840cf61fafccaDmitry Shmidt * added. Non-Hotspot 2.0 APs should ignore the unknown vendor element. 13851b6ea882f234c14cd1fe1332a3840cf61fafccaDmitry Shmidt */ 13951b6ea882f234c14cd1fe1332a3840cf61fafccaDmitry Shmidt 14051b6ea882f234c14cd1fe1332a3840cf61fafccaDmitry Shmidt if (!(ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X)) 14151b6ea882f234c14cd1fe1332a3840cf61fafccaDmitry Shmidt return 0; 14251b6ea882f234c14cd1fe1332a3840cf61fafccaDmitry Shmidt if (!(ssid->pairwise_cipher & WPA_CIPHER_CCMP)) 14351b6ea882f234c14cd1fe1332a3840cf61fafccaDmitry Shmidt return 0; 14451b6ea882f234c14cd1fe1332a3840cf61fafccaDmitry Shmidt if (ssid->proto != WPA_PROTO_RSN) 14551b6ea882f234c14cd1fe1332a3840cf61fafccaDmitry Shmidt return 0; 14651b6ea882f234c14cd1fe1332a3840cf61fafccaDmitry Shmidt 14751b6ea882f234c14cd1fe1332a3840cf61fafccaDmitry Shmidt return 1; 14851b6ea882f234c14cd1fe1332a3840cf61fafccaDmitry Shmidt} 14951b6ea882f234c14cd1fe1332a3840cf61fafccaDmitry Shmidt 15051b6ea882f234c14cd1fe1332a3840cf61fafccaDmitry Shmidt 151f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidtint hs20_get_pps_mo_id(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid) 152f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt{ 153f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt struct wpa_cred *cred; 154f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 155c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt if (ssid == NULL) 156c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt return 0; 157c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt 158c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt if (ssid->update_identifier) 159c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt return ssid->update_identifier; 160c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt 161c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt if (ssid->parent_cred == NULL) 162f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt return 0; 163f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 164f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt for (cred = wpa_s->conf->cred; cred; cred = cred->next) { 165f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (ssid->parent_cred == cred) 166f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt return cred->update_identifier; 167f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } 168f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 169f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt return 0; 170f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt} 171f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 172f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 17315907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidtvoid hs20_put_anqp_req(u32 stypes, const u8 *payload, size_t payload_len, 17415907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt struct wpabuf *buf) 17504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 17604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt u8 *len_pos; 17704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 17804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (buf == NULL) 17915907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt return; 18004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 18104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt len_pos = gas_anqp_add_element(buf, ANQP_VENDOR_SPECIFIC); 18204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpabuf_put_be24(buf, OUI_WFA); 18304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpabuf_put_u8(buf, HS20_ANQP_OUI_TYPE); 18404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (stypes == BIT(HS20_STYPE_NAI_HOME_REALM_QUERY)) { 18504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpabuf_put_u8(buf, HS20_STYPE_NAI_HOME_REALM_QUERY); 18604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpabuf_put_u8(buf, 0); /* Reserved */ 18704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (payload) 18804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpabuf_put_data(buf, payload, payload_len); 189f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } else if (stypes == BIT(HS20_STYPE_ICON_REQUEST)) { 190f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpabuf_put_u8(buf, HS20_STYPE_ICON_REQUEST); 191f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpabuf_put_u8(buf, 0); /* Reserved */ 192f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (payload) 193f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpabuf_put_data(buf, payload, payload_len); 19404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } else { 19504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt u8 i; 19604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpabuf_put_u8(buf, HS20_STYPE_QUERY_LIST); 19704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpabuf_put_u8(buf, 0); /* Reserved */ 19804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt for (i = 0; i < 32; i++) { 19904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (stypes & BIT(i)) 20004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpabuf_put_u8(buf, i); 20104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 20204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 20304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt gas_anqp_set_element_len(buf, len_pos); 20404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 20504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt gas_anqp_set_len(buf); 20615907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt} 20715907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt 20815907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt 20958d12adcdf693a076f719cef9b9f2ccf81892045Dmitry Shmidtstatic struct wpabuf * hs20_build_anqp_req(u32 stypes, const u8 *payload, 21058d12adcdf693a076f719cef9b9f2ccf81892045Dmitry Shmidt size_t payload_len) 21115907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt{ 21215907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt struct wpabuf *buf; 21315907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt 21415907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt buf = gas_anqp_build_initial_req(0, 100 + payload_len); 21515907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt if (buf == NULL) 21615907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt return NULL; 21715907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt 21815907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt hs20_put_anqp_req(stypes, payload, payload_len, buf); 21904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 22004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return buf; 22104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 22204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 22304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 22404949598a23f501be6eec21697465fd46a28840aDmitry Shmidtint hs20_anqp_send_req(struct wpa_supplicant *wpa_s, const u8 *dst, u32 stypes, 2257d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt const u8 *payload, size_t payload_len, int inmem) 22604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 22704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct wpabuf *buf; 22804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt int ret = 0; 22904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt int freq; 23004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct wpa_bss *bss; 23104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt int res; 2327d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt struct icon_entry *icon_entry; 23304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 23404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt bss = wpa_bss_get_bssid(wpa_s, dst); 235cc00d5dc8483e32158b2ba61ea44b0c38d790ed7Dmitry Shmidt if (!bss) { 236cc00d5dc8483e32158b2ba61ea44b0c38d790ed7Dmitry Shmidt wpa_printf(MSG_WARNING, 237cc00d5dc8483e32158b2ba61ea44b0c38d790ed7Dmitry Shmidt "ANQP: Cannot send query to unknown BSS " 238cc00d5dc8483e32158b2ba61ea44b0c38d790ed7Dmitry Shmidt MACSTR, MAC2STR(dst)); 23904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return -1; 240cc00d5dc8483e32158b2ba61ea44b0c38d790ed7Dmitry Shmidt } 241cc00d5dc8483e32158b2ba61ea44b0c38d790ed7Dmitry Shmidt 242cc00d5dc8483e32158b2ba61ea44b0c38d790ed7Dmitry Shmidt wpa_bss_anqp_unshare_alloc(bss); 243cc00d5dc8483e32158b2ba61ea44b0c38d790ed7Dmitry Shmidt freq = bss->freq; 24404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 24504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_DEBUG, "HS20: ANQP Query Request to " MACSTR " for " 24604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt "subtypes 0x%x", MAC2STR(dst), stypes); 24704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 24804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt buf = hs20_build_anqp_req(stypes, payload, payload_len); 24904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (buf == NULL) 25004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return -1; 25104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 25204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt res = gas_query_req(wpa_s->gas, dst, freq, buf, anqp_resp_cb, wpa_s); 25304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (res < 0) { 25404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_DEBUG, "ANQP: Failed to send Query Request"); 255051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt wpabuf_free(buf); 2567d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt return -1; 25704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } else 25804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_DEBUG, "ANQP: Query started with dialog token " 25904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt "%u", res); 26004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 2617d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt if (inmem) { 2627d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt icon_entry = os_zalloc(sizeof(struct icon_entry)); 2637d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt if (!icon_entry) 2647d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt return -1; 2657d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt os_memcpy(icon_entry->bssid, dst, ETH_ALEN); 2667d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt icon_entry->file_name = os_malloc(payload_len + 1); 2677d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt if (!icon_entry->file_name) { 2687d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt os_free(icon_entry); 2697d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt return -1; 2707d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt } 2717d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt os_memcpy(icon_entry->file_name, payload, payload_len); 2727d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt icon_entry->file_name[payload_len] = '\0'; 2737d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt icon_entry->dialog_token = res; 2747d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt 2757d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt dl_list_add(&wpa_s->icon_head, &icon_entry->list); 2767d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt } 2777d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt 27804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return ret; 27904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 28004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 28104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 2827d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidtstatic struct icon_entry * hs20_find_icon(struct wpa_supplicant *wpa_s, 2837d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt const u8 *bssid, 2847d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt const char *file_name) 2857d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt{ 2867d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt struct icon_entry *icon; 2877d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt 2887d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt dl_list_for_each(icon, &wpa_s->icon_head, struct icon_entry, list) { 2897d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt if (os_memcmp(icon->bssid, bssid, ETH_ALEN) == 0 && 2907d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt os_strcmp(icon->file_name, file_name) == 0 && icon->image) 2917d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt return icon; 2927d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt } 2937d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt 2947d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt return NULL; 2957d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt} 2967d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt 2977d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt 2987d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidtint hs20_get_icon(struct wpa_supplicant *wpa_s, const u8 *bssid, 2997d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt const char *file_name, size_t offset, size_t size, 3007d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt char *reply, size_t buf_len) 3017d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt{ 3027d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt struct icon_entry *icon; 3037d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt size_t out_size; 3047d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt unsigned char *b64; 3057d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt size_t b64_size; 3067d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt int reply_size; 3077d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt 3087d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt wpa_printf(MSG_DEBUG, "HS20: Get icon " MACSTR " %s @ %u +%u (%u)", 3097d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt MAC2STR(bssid), file_name, (unsigned int) offset, 3107d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt (unsigned int) size, (unsigned int) buf_len); 3117d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt 3127d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt icon = hs20_find_icon(wpa_s, bssid, file_name); 3137d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt if (!icon || !icon->image || offset >= icon->image_len) 3147d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt return -1; 3157d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt if (size > icon->image_len - offset) 3167d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt size = icon->image_len - offset; 3177d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt out_size = buf_len - 3 /* max base64 padding */; 3187d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt if (size * 4 > out_size * 3) 3197d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt size = out_size * 3 / 4; 3207d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt if (size == 0) 3217d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt return -1; 3227d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt 3237d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt b64 = base64_encode(&icon->image[offset], size, &b64_size); 32458d12adcdf693a076f719cef9b9f2ccf81892045Dmitry Shmidt if (b64 && buf_len >= b64_size) { 3257d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt os_memcpy(reply, b64, b64_size); 3267d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt reply_size = b64_size; 3277d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt } else { 3287d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt reply_size = -1; 3297d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt } 3307d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt os_free(b64); 3317d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt return reply_size; 3327d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt} 3337d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt 3347d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt 3357d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidtstatic void hs20_free_icon_entry(struct icon_entry *icon) 3367d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt{ 3377d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt wpa_printf(MSG_DEBUG, "HS20: Free stored icon from " MACSTR 3387d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt " dialog_token=%u file_name=%s image_len=%u", 3397d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt MAC2STR(icon->bssid), icon->dialog_token, 3407d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt icon->file_name ? icon->file_name : "N/A", 3417d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt (unsigned int) icon->image_len); 3427d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt os_free(icon->file_name); 3437d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt os_free(icon->image); 3447d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt os_free(icon); 3457d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt} 3467d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt 3477d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt 3487d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidtint hs20_del_icon(struct wpa_supplicant *wpa_s, const u8 *bssid, 3497d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt const char *file_name) 3507d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt{ 3517d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt struct icon_entry *icon, *tmp; 3527d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt int count = 0; 3537d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt 3547d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt if (!bssid) 3557d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt wpa_printf(MSG_DEBUG, "HS20: Delete all stored icons"); 3567d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt else if (!file_name) 3577d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt wpa_printf(MSG_DEBUG, "HS20: Delete all stored icons for " 3587d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt MACSTR, MAC2STR(bssid)); 3597d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt else 3607d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt wpa_printf(MSG_DEBUG, "HS20: Delete stored icons for " 3617d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt MACSTR " file name %s", MAC2STR(bssid), file_name); 3627d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt 3637d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt dl_list_for_each_safe(icon, tmp, &wpa_s->icon_head, struct icon_entry, 3647d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt list) { 3657d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt if ((!bssid || os_memcmp(icon->bssid, bssid, ETH_ALEN) == 0) && 3667d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt (!file_name || 3677d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt os_strcmp(icon->file_name, file_name) == 0)) { 3687d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt dl_list_del(&icon->list); 3697d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt hs20_free_icon_entry(icon); 3707d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt count++; 3717d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt } 3727d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt } 3737d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt return count == 0 ? -1 : 0; 3747d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt} 3757d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt 3767d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt 3772f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidtstatic void hs20_set_osu_access_permission(const char *osu_dir, 3782f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt const char *fname) 3792f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt{ 3802f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt struct stat statbuf; 3812f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt 3822f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt /* Get OSU directory information */ 3832f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt if (stat(osu_dir, &statbuf) < 0) { 3842f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt wpa_printf(MSG_WARNING, "Cannot stat the OSU directory %s", 3852f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt osu_dir); 3862f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt return; 3872f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt } 3882f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt 3892f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt if (chmod(fname, statbuf.st_mode) < 0) { 3902f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt wpa_printf(MSG_WARNING, 3912f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt "Cannot change the permissions for %s", fname); 3922f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt return; 3932f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt } 3942f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt 3952f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt if (chown(fname, statbuf.st_uid, statbuf.st_gid) < 0) { 3962f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt wpa_printf(MSG_WARNING, "Cannot change the ownership for %s", 3972f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt fname); 3982f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt } 3992f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt} 4002f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt 4017d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt 4027d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidtstatic void hs20_remove_duplicate_icons(struct wpa_supplicant *wpa_s, 4037d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt struct icon_entry *new_icon) 4047d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt{ 4057d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt struct icon_entry *icon, *tmp; 4067d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt 4077d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt dl_list_for_each_safe(icon, tmp, &wpa_s->icon_head, struct icon_entry, 4087d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt list) { 4097d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt if (icon == new_icon) 4107d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt continue; 4117d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt if (os_memcmp(icon->bssid, new_icon->bssid, ETH_ALEN) == 0 && 4127d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt os_strcmp(icon->file_name, new_icon->file_name) == 0) { 4137d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt dl_list_del(&icon->list); 4147d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt hs20_free_icon_entry(icon); 4157d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt } 4167d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt } 4177d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt} 4187d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt 4197d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt 420f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidtstatic int hs20_process_icon_binary_file(struct wpa_supplicant *wpa_s, 421f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt const u8 *sa, const u8 *pos, 4227d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt size_t slen, u8 dialog_token) 423f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt{ 424f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt char fname[256]; 425f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt int png; 426f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt FILE *f; 427f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt u16 data_len; 4287d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt struct icon_entry *icon; 4297d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt 4307d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt dl_list_for_each(icon, &wpa_s->icon_head, struct icon_entry, list) { 4317d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt if (icon->dialog_token == dialog_token && !icon->image && 4327d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt os_memcmp(icon->bssid, sa, ETH_ALEN) == 0) { 4337d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt icon->image = os_malloc(slen); 4347d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt if (!icon->image) 4357d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt return -1; 4367d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt os_memcpy(icon->image, pos, slen); 4377d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt icon->image_len = slen; 4387d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt hs20_remove_duplicate_icons(wpa_s, icon); 4397d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt wpa_msg(wpa_s, MSG_INFO, 44058d12adcdf693a076f719cef9b9f2ccf81892045Dmitry Shmidt RX_HS20_ICON MACSTR " %s %u", 4417d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt MAC2STR(sa), icon->file_name, 4427d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt (unsigned int) icon->image_len); 44304a9d74743634109939ddb9bc40814681a03dc84Roshan Pius wpas_notify_hs20_icon_query_done(wpa_s, sa, 44404a9d74743634109939ddb9bc40814681a03dc84Roshan Pius icon->file_name, 44504a9d74743634109939ddb9bc40814681a03dc84Roshan Pius icon->image, 44604a9d74743634109939ddb9bc40814681a03dc84Roshan Pius icon->image_len); 4477d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt return 0; 4487d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt } 4497d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt } 450f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 45158d12adcdf693a076f719cef9b9f2ccf81892045Dmitry Shmidt wpa_msg(wpa_s, MSG_INFO, RX_HS20_ANQP MACSTR " Icon Binary File", 452f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt MAC2STR(sa)); 453f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 454f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (slen < 4) { 455f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "HS 2.0: Too short Icon Binary File " 456f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt "value from " MACSTR, MAC2STR(sa)); 457f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt return -1; 458f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } 459f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 460f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_printf(MSG_DEBUG, "HS 2.0: Download Status Code %u", *pos); 461f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (*pos != 0) 462f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt return -1; 463f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt pos++; 464f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt slen--; 465f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 466f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if ((size_t) 1 + pos[0] > slen) { 467f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "HS 2.0: Too short Icon Binary File " 468f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt "value from " MACSTR, MAC2STR(sa)); 469f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt return -1; 470f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } 471f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_hexdump_ascii(MSG_DEBUG, "Icon Type", pos + 1, pos[0]); 472f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt png = os_strncasecmp((char *) pos + 1, "image/png", 9) == 0; 473f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt slen -= 1 + pos[0]; 474f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt pos += 1 + pos[0]; 475f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 476f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (slen < 2) { 477f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "HS 2.0: Too short Icon Binary File " 478f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt "value from " MACSTR, MAC2STR(sa)); 479f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt return -1; 480f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } 481f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt data_len = WPA_GET_LE16(pos); 482f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt pos += 2; 483f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt slen -= 2; 484f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 485f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (data_len > slen) { 486f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "HS 2.0: Too short Icon Binary File " 487f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt "value from " MACSTR, MAC2STR(sa)); 488f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt return -1; 489f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } 490f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 491f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_printf(MSG_DEBUG, "Icon Binary Data: %u bytes", data_len); 492f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (wpa_s->conf->osu_dir == NULL) 493f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt return -1; 494f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 495f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_s->osu_icon_id++; 496f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (wpa_s->osu_icon_id == 0) 497f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_s->osu_icon_id++; 498f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt snprintf(fname, sizeof(fname), "%s/osu-icon-%u.%s", 499f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_s->conf->osu_dir, wpa_s->osu_icon_id, 500f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt png ? "png" : "icon"); 501f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt f = fopen(fname, "wb"); 502f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (f == NULL) 503f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt return -1; 5042f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt 5052f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt hs20_set_osu_access_permission(wpa_s->conf->osu_dir, fname); 5062f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt 507f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (fwrite(pos, slen, 1, f) != 1) { 508f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt fclose(f); 509f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt unlink(fname); 510f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt return -1; 511f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } 512f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt fclose(f); 513f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 51458d12adcdf693a076f719cef9b9f2ccf81892045Dmitry Shmidt wpa_msg(wpa_s, MSG_INFO, RX_HS20_ANQP_ICON "%s", fname); 515f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt return 0; 516f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt} 517f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 518f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 519f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidtstatic void hs20_continue_icon_fetch(void *eloop_ctx, void *sock_ctx) 520f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt{ 521f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt struct wpa_supplicant *wpa_s = eloop_ctx; 522f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (wpa_s->fetch_osu_icon_in_progress) 523f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt hs20_next_osu_icon(wpa_s); 524f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt} 525f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 526f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 527f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidtstatic void hs20_osu_icon_fetch_result(struct wpa_supplicant *wpa_s, int res) 528f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt{ 529f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt size_t i, j; 530f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt struct os_reltime now, tmp; 531f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt int dur; 532f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 533f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt os_get_reltime(&now); 534f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt os_reltime_sub(&now, &wpa_s->osu_icon_fetch_start, &tmp); 535f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt dur = tmp.sec * 1000 + tmp.usec / 1000; 536f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_printf(MSG_DEBUG, "HS 2.0: Icon fetch dur=%d ms res=%d", 537f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt dur, res); 538f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 539f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt for (i = 0; i < wpa_s->osu_prov_count; i++) { 540f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt struct osu_provider *osu = &wpa_s->osu_prov[i]; 541f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt for (j = 0; j < osu->icon_count; j++) { 542f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt struct osu_icon *icon = &osu->icon[j]; 543f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (icon->id || icon->failed) 544f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt continue; 545f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (res < 0) 546f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt icon->failed = 1; 547f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt else 548f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt icon->id = wpa_s->osu_icon_id; 549f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt return; 550f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } 551f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } 552f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt} 553f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 554f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 55504949598a23f501be6eec21697465fd46a28840aDmitry Shmidtvoid hs20_parse_rx_hs20_anqp_resp(struct wpa_supplicant *wpa_s, 5562f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt struct wpa_bss *bss, const u8 *sa, 5577d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt const u8 *data, size_t slen, u8 dialog_token) 55804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 55904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt const u8 *pos = data; 56004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt u8 subtype; 5614530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt struct wpa_bss_anqp *anqp = NULL; 562f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt int ret; 56304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 56404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (slen < 2) 56504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return; 56604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 5674530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (bss) 5684530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt anqp = bss->anqp; 5694530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 57004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt subtype = *pos++; 57104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt slen--; 57204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 57304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt pos++; /* Reserved */ 57404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt slen--; 57504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 57604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt switch (subtype) { 57704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt case HS20_STYPE_CAPABILITY_LIST: 57858d12adcdf693a076f719cef9b9f2ccf81892045Dmitry Shmidt wpa_msg(wpa_s, MSG_INFO, RX_HS20_ANQP MACSTR 57904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt " HS Capability List", MAC2STR(sa)); 58004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_hexdump_ascii(MSG_DEBUG, "HS Capability List", pos, slen); 5817f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt if (anqp) { 5827f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt wpabuf_free(anqp->hs20_capability_list); 5837f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt anqp->hs20_capability_list = 5847f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt wpabuf_alloc_copy(pos, slen); 5857f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt } 58604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt break; 58704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt case HS20_STYPE_OPERATOR_FRIENDLY_NAME: 58858d12adcdf693a076f719cef9b9f2ccf81892045Dmitry Shmidt wpa_msg(wpa_s, MSG_INFO, RX_HS20_ANQP MACSTR 58904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt " Operator Friendly Name", MAC2STR(sa)); 59004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_hexdump_ascii(MSG_DEBUG, "oper friendly name", pos, slen); 5914530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (anqp) { 5924530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt wpabuf_free(anqp->hs20_operator_friendly_name); 5934530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt anqp->hs20_operator_friendly_name = 59404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpabuf_alloc_copy(pos, slen); 59504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 59604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt break; 59704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt case HS20_STYPE_WAN_METRICS: 598d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_hexdump(MSG_DEBUG, "WAN Metrics", pos, slen); 599d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (slen < 13) { 600d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "HS 2.0: Too short WAN " 601d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt "Metrics value from " MACSTR, MAC2STR(sa)); 602d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt break; 603d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } 60458d12adcdf693a076f719cef9b9f2ccf81892045Dmitry Shmidt wpa_msg(wpa_s, MSG_INFO, RX_HS20_ANQP MACSTR 605d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt " WAN Metrics %02x:%u:%u:%u:%u:%u", MAC2STR(sa), 606d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt pos[0], WPA_GET_LE32(pos + 1), WPA_GET_LE32(pos + 5), 607d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt pos[9], pos[10], WPA_GET_LE16(pos + 11)); 6084530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (anqp) { 6094530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt wpabuf_free(anqp->hs20_wan_metrics); 6104530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt anqp->hs20_wan_metrics = wpabuf_alloc_copy(pos, slen); 61104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 61204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt break; 61304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt case HS20_STYPE_CONNECTION_CAPABILITY: 61458d12adcdf693a076f719cef9b9f2ccf81892045Dmitry Shmidt wpa_msg(wpa_s, MSG_INFO, RX_HS20_ANQP MACSTR 61504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt " Connection Capability", MAC2STR(sa)); 61604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_hexdump_ascii(MSG_DEBUG, "conn capability", pos, slen); 6174530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (anqp) { 6184530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt wpabuf_free(anqp->hs20_connection_capability); 6194530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt anqp->hs20_connection_capability = 62004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpabuf_alloc_copy(pos, slen); 62104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 62204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt break; 62304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt case HS20_STYPE_OPERATING_CLASS: 62458d12adcdf693a076f719cef9b9f2ccf81892045Dmitry Shmidt wpa_msg(wpa_s, MSG_INFO, RX_HS20_ANQP MACSTR 62504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt " Operating Class", MAC2STR(sa)); 62604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_hexdump_ascii(MSG_DEBUG, "Operating Class", pos, slen); 6274530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (anqp) { 6284530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt wpabuf_free(anqp->hs20_operating_class); 6294530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt anqp->hs20_operating_class = 63004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpabuf_alloc_copy(pos, slen); 63104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 63204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt break; 633f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt case HS20_STYPE_OSU_PROVIDERS_LIST: 63458d12adcdf693a076f719cef9b9f2ccf81892045Dmitry Shmidt wpa_msg(wpa_s, MSG_INFO, RX_HS20_ANQP MACSTR 635f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt " OSU Providers list", MAC2STR(sa)); 636f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_s->num_prov_found++; 637f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (anqp) { 638f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpabuf_free(anqp->hs20_osu_providers_list); 639f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt anqp->hs20_osu_providers_list = 640f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpabuf_alloc_copy(pos, slen); 641f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } 642f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt break; 643f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt case HS20_STYPE_ICON_BINARY_FILE: 6447d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt ret = hs20_process_icon_binary_file(wpa_s, sa, pos, slen, 6457d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt dialog_token); 646f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (wpa_s->fetch_osu_icon_in_progress) { 647f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt hs20_osu_icon_fetch_result(wpa_s, ret); 648f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt eloop_cancel_timeout(hs20_continue_icon_fetch, 649f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_s, NULL); 650f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt eloop_register_timeout(0, 0, hs20_continue_icon_fetch, 651f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_s, NULL); 652f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } 653f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt break; 65404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt default: 65504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_DEBUG, "HS20: Unsupported subtype %u", subtype); 65604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt break; 65704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 65804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 659f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 660f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 661f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidtvoid hs20_notify_parse_done(struct wpa_supplicant *wpa_s) 662f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt{ 663f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (!wpa_s->fetch_osu_icon_in_progress) 664f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt return; 665f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (eloop_is_timeout_registered(hs20_continue_icon_fetch, wpa_s, NULL)) 666f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt return; 667f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt /* 668f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt * We are going through icon fetch, but no icon response was received. 669f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt * Assume this means the current AP could not provide an answer to avoid 670f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt * getting stuck in fetch iteration. 671f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt */ 672f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt hs20_icon_fetch_failed(wpa_s); 673f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt} 674f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 675f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 676f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidtstatic void hs20_free_osu_prov_entry(struct osu_provider *prov) 677f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt{ 678f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt} 679f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 680f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 681f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidtvoid hs20_free_osu_prov(struct wpa_supplicant *wpa_s) 682f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt{ 683f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt size_t i; 684f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt for (i = 0; i < wpa_s->osu_prov_count; i++) 685f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt hs20_free_osu_prov_entry(&wpa_s->osu_prov[i]); 686f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt os_free(wpa_s->osu_prov); 687f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_s->osu_prov = NULL; 688f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_s->osu_prov_count = 0; 689f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt} 690f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 691f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 692f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidtstatic void hs20_osu_fetch_done(struct wpa_supplicant *wpa_s) 693f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt{ 694f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt char fname[256]; 695f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt FILE *f; 696f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt size_t i, j; 697f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 698f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_s->fetch_osu_info = 0; 699f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_s->fetch_osu_icon_in_progress = 0; 700f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 701f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (wpa_s->conf->osu_dir == NULL) { 702f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt hs20_free_osu_prov(wpa_s); 703f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_s->fetch_anqp_in_progress = 0; 704f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt return; 705f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } 706f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 707f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt snprintf(fname, sizeof(fname), "%s/osu-providers.txt", 708f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_s->conf->osu_dir); 709f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt f = fopen(fname, "w"); 710f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (f == NULL) { 71158d12adcdf693a076f719cef9b9f2ccf81892045Dmitry Shmidt wpa_msg(wpa_s, MSG_INFO, 71258d12adcdf693a076f719cef9b9f2ccf81892045Dmitry Shmidt "Could not write OSU provider information"); 713f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt hs20_free_osu_prov(wpa_s); 7149c17526f86859e2b6aebac0ed4f2561601816103Dmitry Shmidt wpa_s->fetch_anqp_in_progress = 0; 715f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt return; 716f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } 7172f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt 7182f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt hs20_set_osu_access_permission(wpa_s->conf->osu_dir, fname); 7192f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt 720f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt for (i = 0; i < wpa_s->osu_prov_count; i++) { 721f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt struct osu_provider *osu = &wpa_s->osu_prov[i]; 722f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (i > 0) 723f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt fprintf(f, "\n"); 724f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt fprintf(f, "OSU-PROVIDER " MACSTR "\n" 725f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt "uri=%s\n" 726f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt "methods=%08x\n", 727f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt MAC2STR(osu->bssid), osu->server_uri, osu->osu_methods); 728f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (osu->osu_ssid_len) { 729f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt fprintf(f, "osu_ssid=%s\n", 730f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_ssid_txt(osu->osu_ssid, 731f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt osu->osu_ssid_len)); 732f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } 733f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (osu->osu_nai[0]) 734f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt fprintf(f, "osu_nai=%s\n", osu->osu_nai); 735f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt for (j = 0; j < osu->friendly_name_count; j++) { 736f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt fprintf(f, "friendly_name=%s:%s\n", 737f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt osu->friendly_name[j].lang, 738f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt osu->friendly_name[j].text); 739f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } 740f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt for (j = 0; j < osu->serv_desc_count; j++) { 741f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt fprintf(f, "desc=%s:%s\n", 742f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt osu->serv_desc[j].lang, 743f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt osu->serv_desc[j].text); 744f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } 745f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt for (j = 0; j < osu->icon_count; j++) { 746f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt struct osu_icon *icon = &osu->icon[j]; 747f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (icon->failed) 748f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt continue; /* could not fetch icon */ 749f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt fprintf(f, "icon=%u:%u:%u:%s:%s:%s\n", 750f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt icon->id, icon->width, icon->height, icon->lang, 751f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt icon->icon_type, icon->filename); 752f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } 753f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } 754f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt fclose(f); 755f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt hs20_free_osu_prov(wpa_s); 756f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 757f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_msg(wpa_s, MSG_INFO, "OSU provider fetch completed"); 758f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_s->fetch_anqp_in_progress = 0; 759f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt} 760f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 761f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 762f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidtvoid hs20_next_osu_icon(struct wpa_supplicant *wpa_s) 763f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt{ 764f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt size_t i, j; 765f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 766f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_printf(MSG_DEBUG, "HS 2.0: Ready to fetch next icon"); 767f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 768f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt for (i = 0; i < wpa_s->osu_prov_count; i++) { 769f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt struct osu_provider *osu = &wpa_s->osu_prov[i]; 770f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt for (j = 0; j < osu->icon_count; j++) { 771f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt struct osu_icon *icon = &osu->icon[j]; 772f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (icon->id || icon->failed) 773f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt continue; 774f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 775f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_printf(MSG_DEBUG, "HS 2.0: Try to fetch icon '%s' " 776f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt "from " MACSTR, icon->filename, 777f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt MAC2STR(osu->bssid)); 778f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt os_get_reltime(&wpa_s->osu_icon_fetch_start); 779f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (hs20_anqp_send_req(wpa_s, osu->bssid, 780f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt BIT(HS20_STYPE_ICON_REQUEST), 781f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt (u8 *) icon->filename, 7827d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt os_strlen(icon->filename), 7837d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt 0) < 0) { 784f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt icon->failed = 1; 785f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt continue; 786f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } 787f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt return; 788f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } 789f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } 790f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 791f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_printf(MSG_DEBUG, "HS 2.0: No more icons to fetch"); 792f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt hs20_osu_fetch_done(wpa_s); 793f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt} 794f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 795f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 796f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidtstatic void hs20_osu_add_prov(struct wpa_supplicant *wpa_s, struct wpa_bss *bss, 797f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt const u8 *osu_ssid, u8 osu_ssid_len, 798f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt const u8 *pos, size_t len) 799f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt{ 800f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt struct osu_provider *prov; 801f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt const u8 *end = pos + len; 802f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt u16 len2; 803f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt const u8 *pos2; 8046c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt u8 uri_len, osu_method_len, osu_nai_len; 805f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 806f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "HS 2.0: Parsing OSU Provider", pos, len); 807f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt prov = os_realloc_array(wpa_s->osu_prov, 808f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_s->osu_prov_count + 1, 809f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt sizeof(*prov)); 810f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (prov == NULL) 811f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt return; 812f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_s->osu_prov = prov; 813f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt prov = &prov[wpa_s->osu_prov_count]; 814f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt os_memset(prov, 0, sizeof(*prov)); 815f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 816f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt os_memcpy(prov->bssid, bss->bssid, ETH_ALEN); 817f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt os_memcpy(prov->osu_ssid, osu_ssid, osu_ssid_len); 818f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt prov->osu_ssid_len = osu_ssid_len; 819f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 820f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt /* OSU Friendly Name Length */ 821d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (end - pos < 2) { 822f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_printf(MSG_DEBUG, "HS 2.0: Not enough room for OSU " 823f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt "Friendly Name Length"); 824f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt return; 825f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } 826f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt len2 = WPA_GET_LE16(pos); 827f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt pos += 2; 8286c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (len2 > end - pos) { 829f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_printf(MSG_DEBUG, "HS 2.0: Not enough room for OSU " 830f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt "Friendly Name Duples"); 831f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt return; 832f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } 833f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt pos2 = pos; 834f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt pos += len2; 835f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 836f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt /* OSU Friendly Name Duples */ 837d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt while (pos - pos2 >= 4 && prov->friendly_name_count < OSU_MAX_ITEMS) { 838f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt struct osu_lang_string *f; 839d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (1 + pos2[0] > pos - pos2 || pos2[0] < 3) { 840f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_printf(MSG_DEBUG, "Invalid OSU Friendly Name"); 841f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt break; 842f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } 843f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt f = &prov->friendly_name[prov->friendly_name_count++]; 844f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt os_memcpy(f->lang, pos2 + 1, 3); 845f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt os_memcpy(f->text, pos2 + 1 + 3, pos2[0] - 3); 846f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt pos2 += 1 + pos2[0]; 847f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } 848f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 849f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt /* OSU Server URI */ 850d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (end - pos < 1) { 8516c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_printf(MSG_DEBUG, 8526c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt "HS 2.0: Not enough room for OSU Server URI length"); 8536c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return; 8546c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 8556c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt uri_len = *pos++; 8566c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (uri_len > end - pos) { 857f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_printf(MSG_DEBUG, "HS 2.0: Not enough room for OSU Server " 858f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt "URI"); 859f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt return; 860f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } 8616c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt os_memcpy(prov->server_uri, pos, uri_len); 8626c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt pos += uri_len; 863f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 864f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt /* OSU Method list */ 865d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (end - pos < 1) { 8666c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_printf(MSG_DEBUG, "HS 2.0: Not enough room for OSU Method " 8676c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt "list length"); 8686c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return; 8696c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 8706c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt osu_method_len = pos[0]; 8716c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (osu_method_len > end - pos - 1) { 872f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_printf(MSG_DEBUG, "HS 2.0: Not enough room for OSU Method " 873f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt "list"); 874f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt return; 875f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } 876f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt pos2 = pos + 1; 8776c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt pos += 1 + osu_method_len; 878f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt while (pos2 < pos) { 879f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (*pos2 < 32) 880f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt prov->osu_methods |= BIT(*pos2); 881f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt pos2++; 882f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } 883f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 884f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt /* Icons Available Length */ 885d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (end - pos < 2) { 886f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_printf(MSG_DEBUG, "HS 2.0: Not enough room for Icons " 887f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt "Available Length"); 888f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt return; 889f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } 890f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt len2 = WPA_GET_LE16(pos); 891f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt pos += 2; 8926c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (len2 > end - pos) { 893f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_printf(MSG_DEBUG, "HS 2.0: Not enough room for Icons " 894f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt "Available"); 895f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt return; 896f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } 897f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt pos2 = pos; 898f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt pos += len2; 899f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 900f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt /* Icons Available */ 901f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt while (pos2 < pos) { 902f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt struct osu_icon *icon = &prov->icon[prov->icon_count]; 9036c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt u8 flen; 9046c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 905d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (2 + 2 + 3 + 1 + 1 > pos - pos2) { 906f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_printf(MSG_DEBUG, "HS 2.0: Invalid Icon Metadata"); 907f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt break; 908f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } 909f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 910f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt icon->width = WPA_GET_LE16(pos2); 911f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt pos2 += 2; 912f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt icon->height = WPA_GET_LE16(pos2); 913f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt pos2 += 2; 914f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt os_memcpy(icon->lang, pos2, 3); 915f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt pos2 += 3; 916f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 917d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt flen = *pos2++; 918d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (flen > pos - pos2) { 919f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_printf(MSG_DEBUG, "HS 2.0: Not room for Icon Type"); 920f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt break; 921f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } 922d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt os_memcpy(icon->icon_type, pos2, flen); 923d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt pos2 += flen; 924f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 925d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (pos - pos2 < 1) { 9266c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_printf(MSG_DEBUG, "HS 2.0: Not room for Icon " 9276c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt "Filename length"); 9286c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt break; 9296c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 930d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt flen = *pos2++; 931d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (flen > pos - pos2) { 932f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_printf(MSG_DEBUG, "HS 2.0: Not room for Icon " 933f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt "Filename"); 934f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt break; 935f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } 936d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt os_memcpy(icon->filename, pos2, flen); 937d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt pos2 += flen; 938f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 939f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt prov->icon_count++; 940f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } 941f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 942f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt /* OSU_NAI */ 943d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (end - pos < 1) { 944f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_printf(MSG_DEBUG, "HS 2.0: Not enough room for OSU_NAI"); 945f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt return; 946f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } 947d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt osu_nai_len = *pos++; 948d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (osu_nai_len > end - pos) { 9496c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_printf(MSG_DEBUG, "HS 2.0: Not enough room for OSU_NAI"); 9506c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return; 9516c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 952d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt os_memcpy(prov->osu_nai, pos, osu_nai_len); 953d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt pos += osu_nai_len; 954f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 955f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt /* OSU Service Description Length */ 956d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (end - pos < 2) { 957f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_printf(MSG_DEBUG, "HS 2.0: Not enough room for OSU " 958f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt "Service Description Length"); 959f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt return; 960f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } 961f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt len2 = WPA_GET_LE16(pos); 962f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt pos += 2; 9636c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (len2 > end - pos) { 964f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_printf(MSG_DEBUG, "HS 2.0: Not enough room for OSU " 965f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt "Service Description Duples"); 966f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt return; 967f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } 968f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt pos2 = pos; 969f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt pos += len2; 970f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 971f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt /* OSU Service Description Duples */ 972d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt while (pos - pos2 >= 4 && prov->serv_desc_count < OSU_MAX_ITEMS) { 973f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt struct osu_lang_string *f; 9746c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt u8 descr_len; 9756c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 976d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt descr_len = *pos2++; 977d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (descr_len > pos - pos2 || descr_len < 3) { 978f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_printf(MSG_DEBUG, "Invalid OSU Service " 979f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt "Description"); 980f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt break; 981f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } 982f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt f = &prov->serv_desc[prov->serv_desc_count++]; 983d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt os_memcpy(f->lang, pos2, 3); 984d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt os_memcpy(f->text, pos2 + 3, descr_len - 3); 985d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt pos2 += descr_len; 986f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } 987f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 988f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_printf(MSG_DEBUG, "HS 2.0: Added OSU Provider through " MACSTR, 989f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt MAC2STR(bss->bssid)); 990f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_s->osu_prov_count++; 991f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt} 992f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 993f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 994f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidtvoid hs20_osu_icon_fetch(struct wpa_supplicant *wpa_s) 995f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt{ 996f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt struct wpa_bss *bss; 997f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt struct wpabuf *prov_anqp; 998f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt const u8 *pos, *end; 999f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt u16 len; 1000f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt const u8 *osu_ssid; 1001f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt u8 osu_ssid_len; 1002f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt u8 num_providers; 1003f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 1004f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt hs20_free_osu_prov(wpa_s); 1005f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 1006f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) { 1007f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (bss->anqp == NULL) 1008f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt continue; 1009f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt prov_anqp = bss->anqp->hs20_osu_providers_list; 1010f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (prov_anqp == NULL) 1011f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt continue; 1012f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_printf(MSG_DEBUG, "HS 2.0: Parsing OSU Providers list from " 1013f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt MACSTR, MAC2STR(bss->bssid)); 1014f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_hexdump_buf(MSG_DEBUG, "HS 2.0: OSU Providers list", 1015f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt prov_anqp); 1016f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt pos = wpabuf_head(prov_anqp); 1017f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt end = pos + wpabuf_len(prov_anqp); 1018f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 1019f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt /* OSU SSID */ 1020d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (end - pos < 1) 1021f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt continue; 1022d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (1 + pos[0] > end - pos) { 1023f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_printf(MSG_DEBUG, "HS 2.0: Not enough room for " 1024f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt "OSU SSID"); 1025f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt continue; 1026f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } 1027f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt osu_ssid_len = *pos++; 10289d9e60286e05ae45025b672636490bd12586138dDmitry Shmidt if (osu_ssid_len > SSID_MAX_LEN) { 1029f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_printf(MSG_DEBUG, "HS 2.0: Invalid OSU SSID " 1030f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt "Length %u", osu_ssid_len); 1031f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt continue; 1032f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } 1033f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt osu_ssid = pos; 1034f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt pos += osu_ssid_len; 1035f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 1036d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (end - pos < 1) { 1037f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_printf(MSG_DEBUG, "HS 2.0: Not enough room for " 1038f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt "Number of OSU Providers"); 1039f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt continue; 1040f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } 1041f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt num_providers = *pos++; 1042f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_printf(MSG_DEBUG, "HS 2.0: Number of OSU Providers: %u", 1043f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt num_providers); 1044f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 1045f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt /* OSU Providers */ 1046d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt while (end - pos > 2 && num_providers > 0) { 1047f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt num_providers--; 1048f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt len = WPA_GET_LE16(pos); 1049f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt pos += 2; 10506c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (len > (unsigned int) (end - pos)) 1051f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt break; 1052f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt hs20_osu_add_prov(wpa_s, bss, osu_ssid, 1053f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt osu_ssid_len, pos, len); 1054f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt pos += len; 1055f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } 1056f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 1057f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (pos != end) { 1058f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_printf(MSG_DEBUG, "HS 2.0: Ignored %d bytes of " 1059f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt "extra data after OSU Providers", 1060f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt (int) (end - pos)); 1061f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } 1062f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } 1063f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 1064f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_s->fetch_osu_icon_in_progress = 1; 1065f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt hs20_next_osu_icon(wpa_s); 1066f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt} 1067f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 1068f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 1069f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidtstatic void hs20_osu_scan_res_handler(struct wpa_supplicant *wpa_s, 1070f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt struct wpa_scan_results *scan_res) 1071f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt{ 1072f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_printf(MSG_DEBUG, "OSU provisioning fetch scan completed"); 10736c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (!wpa_s->fetch_osu_waiting_scan) { 10746c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_printf(MSG_DEBUG, "OSU fetch have been canceled"); 10756c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return; 10766c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 1077f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_s->network_select = 0; 1078f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_s->fetch_all_anqp = 1; 1079f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_s->fetch_osu_info = 1; 1080f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_s->fetch_osu_icon_in_progress = 0; 1081f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 1082f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt interworking_start_fetch_anqp(wpa_s); 1083f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt} 1084f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 1085f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 108658d12adcdf693a076f719cef9b9f2ccf81892045Dmitry Shmidtint hs20_fetch_osu(struct wpa_supplicant *wpa_s, int skip_scan) 1087f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt{ 1088f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) { 1089f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_printf(MSG_DEBUG, "HS 2.0: Cannot start fetch_osu - " 1090f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt "interface disabled"); 1091f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt return -1; 1092f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } 1093f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 1094f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (wpa_s->scanning) { 1095f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_printf(MSG_DEBUG, "HS 2.0: Cannot start fetch_osu - " 1096f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt "scanning"); 1097f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt return -1; 1098f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } 1099f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 1100f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (wpa_s->conf->osu_dir == NULL) { 1101f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_printf(MSG_DEBUG, "HS 2.0: Cannot start fetch_osu - " 1102f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt "osu_dir not configured"); 1103f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt return -1; 1104f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } 1105f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 1106f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (wpa_s->fetch_anqp_in_progress || wpa_s->network_select) { 1107f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_printf(MSG_DEBUG, "HS 2.0: Cannot start fetch_osu - " 1108f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt "fetch in progress (%d, %d)", 1109f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_s->fetch_anqp_in_progress, 1110f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_s->network_select); 1111f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt return -1; 1112f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } 1113f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 1114f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_msg(wpa_s, MSG_INFO, "Starting OSU provisioning information fetch"); 1115f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_s->num_osu_scans = 0; 1116f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_s->num_prov_found = 0; 111758d12adcdf693a076f719cef9b9f2ccf81892045Dmitry Shmidt if (skip_scan) { 111858d12adcdf693a076f719cef9b9f2ccf81892045Dmitry Shmidt wpa_s->network_select = 0; 111958d12adcdf693a076f719cef9b9f2ccf81892045Dmitry Shmidt wpa_s->fetch_all_anqp = 1; 112058d12adcdf693a076f719cef9b9f2ccf81892045Dmitry Shmidt wpa_s->fetch_osu_info = 1; 112158d12adcdf693a076f719cef9b9f2ccf81892045Dmitry Shmidt wpa_s->fetch_osu_icon_in_progress = 0; 112258d12adcdf693a076f719cef9b9f2ccf81892045Dmitry Shmidt 112358d12adcdf693a076f719cef9b9f2ccf81892045Dmitry Shmidt interworking_start_fetch_anqp(wpa_s); 112458d12adcdf693a076f719cef9b9f2ccf81892045Dmitry Shmidt } else { 112558d12adcdf693a076f719cef9b9f2ccf81892045Dmitry Shmidt hs20_start_osu_scan(wpa_s); 112658d12adcdf693a076f719cef9b9f2ccf81892045Dmitry Shmidt } 1127f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 1128f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt return 0; 1129f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt} 1130f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 1131f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 1132f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidtvoid hs20_start_osu_scan(struct wpa_supplicant *wpa_s) 1133f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt{ 11346c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_s->fetch_osu_waiting_scan = 1; 1135f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_s->num_osu_scans++; 1136f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_s->scan_req = MANUAL_SCAN_REQ; 1137f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_s->scan_res_handler = hs20_osu_scan_res_handler; 1138f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_supplicant_req_scan(wpa_s, 0, 0); 1139f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt} 1140f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 1141f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 1142f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidtvoid hs20_cancel_fetch_osu(struct wpa_supplicant *wpa_s) 1143f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt{ 1144f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_printf(MSG_DEBUG, "Cancel OSU fetch"); 1145f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt interworking_stop_fetch_anqp(wpa_s); 11466c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_s->fetch_osu_waiting_scan = 0; 1147f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_s->network_select = 0; 1148f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_s->fetch_osu_info = 0; 1149f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_s->fetch_osu_icon_in_progress = 0; 1150f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt} 1151f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 1152f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 1153f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidtvoid hs20_icon_fetch_failed(struct wpa_supplicant *wpa_s) 1154f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt{ 1155f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt hs20_osu_icon_fetch_result(wpa_s, -1); 1156f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt eloop_cancel_timeout(hs20_continue_icon_fetch, wpa_s, NULL); 1157f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt eloop_register_timeout(0, 0, hs20_continue_icon_fetch, wpa_s, NULL); 1158f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt} 1159f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 1160f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 1161f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidtvoid hs20_rx_subscription_remediation(struct wpa_supplicant *wpa_s, 1162f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt const char *url, u8 osu_method) 1163f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt{ 1164f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (url) 1165f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_msg(wpa_s, MSG_INFO, HS20_SUBSCRIPTION_REMEDIATION "%u %s", 1166f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt osu_method, url); 1167f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt else 1168f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_msg(wpa_s, MSG_INFO, HS20_SUBSCRIPTION_REMEDIATION); 116904a9d74743634109939ddb9bc40814681a03dc84Roshan Pius wpas_notify_hs20_rx_subscription_remediation(wpa_s, url, osu_method); 1170f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt} 1171f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 1172f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 1173f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidtvoid hs20_rx_deauth_imminent_notice(struct wpa_supplicant *wpa_s, u8 code, 1174f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt u16 reauth_delay, const char *url) 1175f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt{ 1176f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (!wpa_sm_pmf_enabled(wpa_s->wpa)) { 1177f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_printf(MSG_DEBUG, "HS 2.0: Ignore deauthentication imminent notice since PMF was not enabled"); 1178f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt return; 1179f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } 1180f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 1181f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_msg(wpa_s, MSG_INFO, HS20_DEAUTH_IMMINENT_NOTICE "%u %u %s", 1182f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt code, reauth_delay, url); 118304a9d74743634109939ddb9bc40814681a03dc84Roshan Pius wpas_notify_hs20_rx_deauth_imminent_notice(wpa_s, code, reauth_delay, url); 1184f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 1185f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (code == HS20_DEAUTH_REASON_CODE_BSS) { 1186f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_printf(MSG_DEBUG, "HS 2.0: Add BSS to blacklist"); 1187f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_blacklist_add(wpa_s, wpa_s->bssid); 1188f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt /* TODO: For now, disable full ESS since some drivers may not 1189f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt * support disabling per BSS. */ 1190f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (wpa_s->current_ssid) { 11914582d2a5dd8180c52eb95b1100fb183b9a289708Dmitry Shmidt struct os_reltime now; 11924582d2a5dd8180c52eb95b1100fb183b9a289708Dmitry Shmidt os_get_reltime(&now); 1193f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (now.sec + reauth_delay <= 1194f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_s->current_ssid->disabled_until.sec) 1195f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt return; 1196f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_printf(MSG_DEBUG, "HS 2.0: Disable network for %u seconds (BSS)", 1197f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt reauth_delay); 1198f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_s->current_ssid->disabled_until.sec = 1199f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt now.sec + reauth_delay; 1200f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } 1201f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } 1202f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 1203f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (code == HS20_DEAUTH_REASON_CODE_ESS && wpa_s->current_ssid) { 12044582d2a5dd8180c52eb95b1100fb183b9a289708Dmitry Shmidt struct os_reltime now; 12054582d2a5dd8180c52eb95b1100fb183b9a289708Dmitry Shmidt os_get_reltime(&now); 1206f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (now.sec + reauth_delay <= 1207f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_s->current_ssid->disabled_until.sec) 1208f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt return; 1209f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_printf(MSG_DEBUG, "HS 2.0: Disable network for %u seconds", 1210f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt reauth_delay); 1211f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_s->current_ssid->disabled_until.sec = 1212f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt now.sec + reauth_delay; 1213f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } 1214f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt} 1215684785c7f4e58498603a9a5ce26f933cc2557ebdDmitry Shmidt 1216684785c7f4e58498603a9a5ce26f933cc2557ebdDmitry Shmidt 12177d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidtvoid hs20_init(struct wpa_supplicant *wpa_s) 12187d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt{ 12197d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt dl_list_init(&wpa_s->icon_head); 12207d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt} 12217d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt 12227d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt 1223684785c7f4e58498603a9a5ce26f933cc2557ebdDmitry Shmidtvoid hs20_deinit(struct wpa_supplicant *wpa_s) 1224684785c7f4e58498603a9a5ce26f933cc2557ebdDmitry Shmidt{ 1225684785c7f4e58498603a9a5ce26f933cc2557ebdDmitry Shmidt eloop_cancel_timeout(hs20_continue_icon_fetch, wpa_s, NULL); 1226684785c7f4e58498603a9a5ce26f933cc2557ebdDmitry Shmidt hs20_free_osu_prov(wpa_s); 12277d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt if (wpa_s->icon_head.next) 12287d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt hs20_del_icon(wpa_s, NULL, NULL); 1229684785c7f4e58498603a9a5ce26f933cc2557ebdDmitry Shmidt} 1230