X-Git-Url: http://www.project-moonshot.org/gitweb/?a=blobdiff_plain;f=wpa_supplicant%2Finterworking.c;h=1fb40c74e5cf9a669e95955a50a83491394ea77a;hb=5ac8f8623d8dc1a47626e22a3b5a1b8e147718d2;hp=12411863177cc8a1507f179554d5a1f97baa415d;hpb=876e74aa5fa919dcfdddd970e97d310c6eb03879;p=mech_eap.git diff --git a/wpa_supplicant/interworking.c b/wpa_supplicant/interworking.c index 1241186..1fb40c7 100644 --- a/wpa_supplicant/interworking.c +++ b/wpa_supplicant/interworking.c @@ -362,13 +362,13 @@ static const u8 * nai_realm_parse_eap(struct nai_realm_eap *e, const u8 *pos, u8 elen, auth_count, a; const u8 *e_end; - if (pos + 3 > end) { + if (end - pos < 3) { wpa_printf(MSG_DEBUG, "No room for EAP Method fixed fields"); return NULL; } elen = *pos++; - if (pos + elen > end || elen < 2) { + if (elen > end - pos || elen < 2) { wpa_printf(MSG_DEBUG, "No room for EAP Method subfield"); return NULL; } @@ -381,14 +381,19 @@ static const u8 * nai_realm_parse_eap(struct nai_realm_eap *e, const u8 *pos, for (a = 0; a < auth_count; a++) { u8 id, len; - if (pos + 2 > end || pos + 2 + pos[1] > end) { - wpa_printf(MSG_DEBUG, "No room for Authentication " - "Parameter subfield"); + if (end - pos < 2) { + wpa_printf(MSG_DEBUG, + "No room for Authentication Parameter subfield header"); return NULL; } id = *pos++; len = *pos++; + if (len > end - pos) { + wpa_printf(MSG_DEBUG, + "No room for Authentication Parameter subfield"); + return NULL; + } switch (id) { case NAI_REALM_EAP_AUTH_NON_EAP_INNER_AUTH: @@ -463,7 +468,7 @@ static const u8 * nai_realm_parse_realm(struct nai_realm *r, const u8 *pos, len = WPA_GET_LE16(pos); /* NAI Realm Data field Length */ pos += 2; - if (pos + len > end || len < 3) { + if (len > end - pos || len < 3) { wpa_printf(MSG_DEBUG, "No room for NAI Realm Data " "(len=%u; left=%u)", len, (unsigned int) (end - pos)); @@ -473,7 +478,7 @@ static const u8 * nai_realm_parse_realm(struct nai_realm *r, const u8 *pos, r->encoding = *pos++; realm_len = *pos++; - if (pos + realm_len > f_end) { + if (realm_len > f_end - pos) { wpa_printf(MSG_DEBUG, "No room for NAI Realm " "(len=%u; left=%u)", realm_len, (unsigned int) (f_end - pos)); @@ -485,13 +490,13 @@ static const u8 * nai_realm_parse_realm(struct nai_realm *r, const u8 *pos, return NULL; pos += realm_len; - if (pos + 1 > f_end) { + if (f_end - pos < 1) { wpa_printf(MSG_DEBUG, "No room for EAP Method Count"); return NULL; } r->eap_count = *pos++; wpa_printf(MSG_DEBUG, "EAP Count: %u", r->eap_count); - if (pos + r->eap_count * 3 > f_end) { + if (r->eap_count * 3 > f_end - pos) { wpa_printf(MSG_DEBUG, "No room for EAP Methods"); return NULL; } @@ -746,7 +751,7 @@ static int plmn_id_match(struct wpabuf *anqp, const char *imsi, int mnc_len) return 0; pos = wpabuf_head_u8(anqp); end = pos + wpabuf_len(anqp); - if (pos + 2 > end) + if (end - pos < 2) return 0; if (*pos != 0) { wpa_printf(MSG_DEBUG, "Unsupported GUD version 0x%x", *pos); @@ -754,7 +759,7 @@ static int plmn_id_match(struct wpabuf *anqp, const char *imsi, int mnc_len) } pos++; udhl = *pos++; - if (pos + udhl > end) { + if (udhl > end - pos) { wpa_printf(MSG_DEBUG, "Invalid UDHL"); return 0; } @@ -764,12 +769,12 @@ static int plmn_id_match(struct wpabuf *anqp, const char *imsi, int mnc_len) plmn[0], plmn[1], plmn[2], plmn2[0], plmn2[1], plmn2[2], imsi, mnc_len); - while (pos + 2 <= end) { + while (end - pos >= 2) { u8 iei, len; const u8 *l_end; iei = *pos++; len = *pos++ & 0x7f; - if (pos + len > end) + if (len > end - pos) break; l_end = pos + len; @@ -780,7 +785,7 @@ static int plmn_id_match(struct wpabuf *anqp, const char *imsi, int mnc_len) pos, len); num = *pos++; for (i = 0; i < num; i++) { - if (pos + 3 > l_end) + if (l_end - pos < 3) break; if (os_memcmp(pos, plmn, 3) == 0 || os_memcmp(pos, plmn2, 3) == 0) @@ -945,11 +950,9 @@ static int interworking_set_hs20_params(struct wpa_supplicant *wpa_s, if (!key_mgmt) key_mgmt = wpa_s->conf->pmf != NO_MGMT_FRAME_PROTECTION ? "WPA-EAP WPA-EAP-SHA256" : "WPA-EAP"; - if (wpa_config_set(ssid, "key_mgmt", key_mgmt, 0) < 0) - return -1; - if (wpa_config_set(ssid, "proto", "RSN", 0) < 0) - return -1; - if (wpa_config_set(ssid, "pairwise", "CCMP", 0) < 0) + if (wpa_config_set(ssid, "key_mgmt", key_mgmt, 0) < 0 || + wpa_config_set(ssid, "proto", "RSN", 0) < 0 || + wpa_config_set(ssid, "pairwise", "CCMP", 0) < 0) return -1; return 0; } @@ -1082,12 +1085,12 @@ static int roaming_consortium_element_match(const u8 *ie, const u8 *rc_id, * OI #1, [OI #2], [OI #3] */ - if (pos + 2 > end) + if (end - pos < 2) return 0; pos++; /* skip Number of ANQP OIs */ lens = *pos++; - if (pos + (lens & 0x0f) + (lens >> 4) > end) + if ((lens & 0x0f) + (lens >> 4) > end - pos) return 0; if ((lens & 0x0f) == rc_len && os_memcmp(pos, rc_id, rc_len) == 0) @@ -1121,7 +1124,7 @@ static int roaming_consortium_anqp_match(const struct wpabuf *anqp, /* Set of duples */ while (pos < end) { len = *pos++; - if (pos + len > end) + if (len > end - pos) break; if (len == rc_len && os_memcmp(pos, rc_id, rc_len) == 0) return 1; @@ -1266,7 +1269,7 @@ static int cred_over_max_bss_load(struct wpa_supplicant *wpa_s, static int has_proto_match(const u8 *pos, const u8 *end, u8 proto) { - while (pos + 4 <= end) { + while (end - pos >= 4) { if (pos[0] == proto && pos[3] == 1 /* Open */) return 1; pos += 4; @@ -1279,7 +1282,7 @@ static int has_proto_match(const u8 *pos, const u8 *end, u8 proto) static int has_proto_port_match(const u8 *pos, const u8 *end, u8 proto, u16 port) { - while (pos + 4 <= end) { + while (end - pos >= 4) { if (pos[0] == proto && WPA_GET_LE16(&pos[1]) == port && pos[3] == 1 /* Open */) return 1; @@ -1446,7 +1449,24 @@ static int interworking_set_eap_params(struct wpa_ssid *ssid, os_free(anon); } - if (cred->username && cred->username[0] && + if (!ttls && cred->username && cred->username[0] && cred->realm && + !os_strchr(cred->username, '@')) { + char *id; + size_t buflen; + int res; + + buflen = os_strlen(cred->username) + 1 + + os_strlen(cred->realm) + 1; + + id = os_malloc(buflen); + if (!id) + return -1; + os_snprintf(id, buflen, "%s@%s", cred->username, cred->realm); + res = wpa_config_set_quoted(ssid, "identity", id); + os_free(id); + if (res < 0) + return -1; + } else if (cred->username && cred->username[0] && wpa_config_set_quoted(ssid, "identity", cred->username) < 0) return -1; @@ -1568,9 +1588,8 @@ fail: } -static int interworking_connect_helper(struct wpa_supplicant *wpa_s, - struct wpa_bss *bss, int allow_excluded, - int only_add) +int interworking_connect(struct wpa_supplicant *wpa_s, struct wpa_bss *bss, + int only_add) { struct wpa_cred *cred, *cred_rc, *cred_3gpp; struct wpa_ssid *ssid; @@ -1578,7 +1597,7 @@ static int interworking_connect_helper(struct wpa_supplicant *wpa_s, struct nai_realm_eap *eap = NULL; u16 count, i; char buf[100]; - int excluded = 0, *excl = allow_excluded ? &excluded : NULL; + int excluded = 0, *excl = &excluded; const char *name; if (wpa_s->conf->cred == NULL || bss == NULL) @@ -1592,8 +1611,8 @@ static int interworking_connect_helper(struct wpa_supplicant *wpa_s, } wpa_printf(MSG_DEBUG, "Interworking: Considering BSS " MACSTR - " for connection (allow_excluded=%d)", - MAC2STR(bss->bssid), allow_excluded); + " for connection", + MAC2STR(bss->bssid)); if (!wpa_bss_get_ie(bss, WLAN_EID_RSN)) { /* @@ -1611,7 +1630,7 @@ static int interworking_connect_helper(struct wpa_supplicant *wpa_s, wpa_msg(wpa_s, MSG_DEBUG, "Interworking: Highest roaming consortium matching credential priority %d sp_priority %d", cred_rc->priority, cred_rc->sp_priority); - if (allow_excluded && excl && !(*excl)) + if (excl && !(*excl)) excl = NULL; } @@ -1620,7 +1639,7 @@ static int interworking_connect_helper(struct wpa_supplicant *wpa_s, wpa_msg(wpa_s, MSG_DEBUG, "Interworking: Highest NAI Realm list matching credential priority %d sp_priority %d", cred->priority, cred->sp_priority); - if (allow_excluded && excl && !(*excl)) + if (excl && !(*excl)) excl = NULL; } @@ -1630,7 +1649,7 @@ static int interworking_connect_helper(struct wpa_supplicant *wpa_s, wpa_msg(wpa_s, MSG_DEBUG, "Interworking: Highest 3GPP matching credential priority %d sp_priority %d", cred_3gpp->priority, cred_3gpp->sp_priority); - if (allow_excluded && excl && !(*excl)) + if (excl && !(*excl)) excl = NULL; } @@ -1643,7 +1662,7 @@ static int interworking_connect_helper(struct wpa_supplicant *wpa_s, wpa_msg(wpa_s, MSG_DEBUG, "Interworking: Highest roaming consortium matching credential priority %d sp_priority %d (ignore BW)", cred_rc->priority, cred_rc->sp_priority); - if (allow_excluded && excl && !(*excl)) + if (excl && !(*excl)) excl = NULL; } @@ -1653,7 +1672,7 @@ static int interworking_connect_helper(struct wpa_supplicant *wpa_s, wpa_msg(wpa_s, MSG_DEBUG, "Interworking: Highest NAI Realm list matching credential priority %d sp_priority %d (ignore BW)", cred->priority, cred->sp_priority); - if (allow_excluded && excl && !(*excl)) + if (excl && !(*excl)) excl = NULL; } @@ -1663,7 +1682,7 @@ static int interworking_connect_helper(struct wpa_supplicant *wpa_s, wpa_msg(wpa_s, MSG_DEBUG, "Interworking: Highest 3GPP matching credential priority %d sp_priority %d (ignore BW)", cred_3gpp->priority, cred_3gpp->sp_priority); - if (allow_excluded && excl && !(*excl)) + if (excl && !(*excl)) excl = NULL; } } @@ -1828,13 +1847,6 @@ fail: } -int interworking_connect(struct wpa_supplicant *wpa_s, struct wpa_bss *bss, - int only_add) -{ - return interworking_connect_helper(wpa_s, bss, 1, only_add); -} - - #ifdef PCSC_FUNCS static int interworking_pcsc_read_imsi(struct wpa_supplicant *wpa_s) { @@ -2133,23 +2145,27 @@ int domain_name_list_contains(struct wpabuf *domain_names, pos = wpabuf_head(domain_names); end = pos + wpabuf_len(domain_names); - while (pos + 1 < end) { - if (pos + 1 + pos[0] > end) + while (end - pos > 1) { + u8 elen; + + elen = *pos++; + if (elen > end - pos) break; wpa_hexdump_ascii(MSG_DEBUG, "Interworking: AP domain name", - pos + 1, pos[0]); - if (pos[0] == len && - os_strncasecmp(domain, (const char *) (pos + 1), len) == 0) + pos, elen); + if (elen == len && + os_strncasecmp(domain, (const char *) pos, len) == 0) return 1; - if (!exact_match && pos[0] > len && pos[pos[0] - len] == '.') { - const char *ap = (const char *) (pos + 1); - int offset = pos[0] - len; + if (!exact_match && elen > len && pos[elen - len - 1] == '.') { + const char *ap = (const char *) pos; + int offset = elen - len; + if (os_strncasecmp(domain, ap + offset, len) == 0) return 1; } - pos += 1 + pos[0]; + pos += elen; } return 0; @@ -2676,10 +2692,11 @@ void interworking_stop_fetch_anqp(struct wpa_supplicant *wpa_s) int anqp_send_req(struct wpa_supplicant *wpa_s, const u8 *dst, - u16 info_ids[], size_t num_ids, u32 subtypes) + u16 info_ids[], size_t num_ids, u32 subtypes, + int get_cell_pref) { struct wpabuf *buf; - struct wpabuf *hs20_buf = NULL; + struct wpabuf *extra_buf = NULL; int ret = 0; int freq; struct wpa_bss *bss; @@ -2702,15 +2719,31 @@ int anqp_send_req(struct wpa_supplicant *wpa_s, const u8 *dst, #ifdef CONFIG_HS20 if (subtypes != 0) { - hs20_buf = wpabuf_alloc(100); - if (hs20_buf == NULL) + extra_buf = wpabuf_alloc(100); + if (extra_buf == NULL) return -1; - hs20_put_anqp_req(subtypes, NULL, 0, hs20_buf); + hs20_put_anqp_req(subtypes, NULL, 0, extra_buf); } #endif /* CONFIG_HS20 */ - buf = anqp_build_req(info_ids, num_ids, hs20_buf); - wpabuf_free(hs20_buf); +#ifdef CONFIG_MBO + if (get_cell_pref) { + struct wpabuf *mbo; + + mbo = mbo_build_anqp_buf(wpa_s, bss); + if (mbo) { + if (wpabuf_resize(&extra_buf, wpabuf_len(mbo))) { + wpabuf_free(extra_buf); + return -1; + } + wpabuf_put_buf(extra_buf, mbo); + wpabuf_free(mbo); + } + } +#endif /* CONFIG_MBO */ + + buf = anqp_build_req(info_ids, num_ids, extra_buf); + wpabuf_free(extra_buf); if (buf == NULL) return -1; @@ -2766,7 +2799,8 @@ static void anqp_add_extra(struct wpa_supplicant *wpa_s, static void interworking_parse_rx_anqp_resp(struct wpa_supplicant *wpa_s, struct wpa_bss *bss, const u8 *sa, u16 info_id, - const u8 *data, size_t slen) + const u8 *data, size_t slen, + u8 dialog_token) { const u8 *pos = data; struct wpa_bss_anqp *anqp = NULL; @@ -2779,7 +2813,7 @@ static void interworking_parse_rx_anqp_resp(struct wpa_supplicant *wpa_s, switch (info_id) { case ANQP_CAPABILITY_LIST: - wpa_msg(wpa_s, MSG_INFO, "RX-ANQP " MACSTR + wpa_msg(wpa_s, MSG_INFO, RX_ANQP MACSTR " ANQP Capability list", MAC2STR(sa)); wpa_hexdump_ascii(MSG_DEBUG, "ANQP: Capability list", pos, slen); @@ -2789,7 +2823,7 @@ static void interworking_parse_rx_anqp_resp(struct wpa_supplicant *wpa_s, } break; case ANQP_VENUE_NAME: - wpa_msg(wpa_s, MSG_INFO, "RX-ANQP " MACSTR + wpa_msg(wpa_s, MSG_INFO, RX_ANQP MACSTR " Venue Name", MAC2STR(sa)); wpa_hexdump_ascii(MSG_DEBUG, "ANQP: Venue Name", pos, slen); if (anqp) { @@ -2798,7 +2832,7 @@ static void interworking_parse_rx_anqp_resp(struct wpa_supplicant *wpa_s, } break; case ANQP_NETWORK_AUTH_TYPE: - wpa_msg(wpa_s, MSG_INFO, "RX-ANQP " MACSTR + wpa_msg(wpa_s, MSG_INFO, RX_ANQP MACSTR " Network Authentication Type information", MAC2STR(sa)); wpa_hexdump_ascii(MSG_DEBUG, "ANQP: Network Authentication " @@ -2809,7 +2843,7 @@ static void interworking_parse_rx_anqp_resp(struct wpa_supplicant *wpa_s, } break; case ANQP_ROAMING_CONSORTIUM: - wpa_msg(wpa_s, MSG_INFO, "RX-ANQP " MACSTR + wpa_msg(wpa_s, MSG_INFO, RX_ANQP MACSTR " Roaming Consortium list", MAC2STR(sa)); wpa_hexdump_ascii(MSG_DEBUG, "ANQP: Roaming Consortium", pos, slen); @@ -2819,7 +2853,7 @@ static void interworking_parse_rx_anqp_resp(struct wpa_supplicant *wpa_s, } break; case ANQP_IP_ADDR_TYPE_AVAILABILITY: - wpa_msg(wpa_s, MSG_INFO, "RX-ANQP " MACSTR + wpa_msg(wpa_s, MSG_INFO, RX_ANQP MACSTR " IP Address Type Availability information", MAC2STR(sa)); wpa_hexdump(MSG_MSGDUMP, "ANQP: IP Address Availability", @@ -2831,7 +2865,7 @@ static void interworking_parse_rx_anqp_resp(struct wpa_supplicant *wpa_s, } break; case ANQP_NAI_REALM: - wpa_msg(wpa_s, MSG_INFO, "RX-ANQP " MACSTR + wpa_msg(wpa_s, MSG_INFO, RX_ANQP MACSTR " NAI Realm list", MAC2STR(sa)); wpa_hexdump_ascii(MSG_DEBUG, "ANQP: NAI Realm", pos, slen); if (anqp) { @@ -2840,7 +2874,7 @@ static void interworking_parse_rx_anqp_resp(struct wpa_supplicant *wpa_s, } break; case ANQP_3GPP_CELLULAR_NETWORK: - wpa_msg(wpa_s, MSG_INFO, "RX-ANQP " MACSTR + wpa_msg(wpa_s, MSG_INFO, RX_ANQP MACSTR " 3GPP Cellular Network information", MAC2STR(sa)); wpa_hexdump_ascii(MSG_DEBUG, "ANQP: 3GPP Cellular Network", pos, slen); @@ -2850,7 +2884,7 @@ static void interworking_parse_rx_anqp_resp(struct wpa_supplicant *wpa_s, } break; case ANQP_DOMAIN_NAME: - wpa_msg(wpa_s, MSG_INFO, "RX-ANQP " MACSTR + wpa_msg(wpa_s, MSG_INFO, RX_ANQP MACSTR " Domain Name list", MAC2STR(sa)); wpa_hexdump_ascii(MSG_MSGDUMP, "ANQP: Domain Name", pos, slen); if (anqp) { @@ -2876,7 +2910,8 @@ static void interworking_parse_rx_anqp_resp(struct wpa_supplicant *wpa_s, switch (type) { case HS20_ANQP_OUI_TYPE: hs20_parse_rx_hs20_anqp_resp(wpa_s, bss, sa, - pos, slen); + pos, slen, + dialog_token); break; default: wpa_msg(wpa_s, MSG_DEBUG, @@ -2979,7 +3014,7 @@ void anqp_resp_cb(void *ctx, const u8 *dst, u8 dialog_token, goto out_parse_done; } interworking_parse_rx_anqp_resp(wpa_s, bss, dst, info_id, pos, - slen); + slen, dialog_token); pos += slen; }