diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2018-08-22 14:59:50 +0200 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2018-09-21 10:29:41 +0200 |
commit | 3489e3b6396ee9944a6a2e19e675ca54c36993b4 (patch) | |
tree | cd55cfac1c96ff4b888a9606fd6a0d8eb65bb446 /freebsd/contrib/wpa/wpa_supplicant/bss.c | |
parent | ck: Define CK_MD_PPC32_LWSYNC if available (diff) | |
download | rtems-libbsd-3489e3b6396ee9944a6a2e19e675ca54c36993b4.tar.bz2 |
Update to FreeBSD head 2018-09-17
Git mirror commit 6c2192b1ef8c50788c751f878552526800b1e319.
Update #3472.
Diffstat (limited to 'freebsd/contrib/wpa/wpa_supplicant/bss.c')
-rw-r--r-- | freebsd/contrib/wpa/wpa_supplicant/bss.c | 97 |
1 files changed, 71 insertions, 26 deletions
diff --git a/freebsd/contrib/wpa/wpa_supplicant/bss.c b/freebsd/contrib/wpa/wpa_supplicant/bss.c index ff40bef0..4f805b1b 100644 --- a/freebsd/contrib/wpa/wpa_supplicant/bss.c +++ b/freebsd/contrib/wpa/wpa_supplicant/bss.c @@ -14,6 +14,7 @@ #include "utils/eloop.h" #include "common/ieee802_11_defs.h" #include "drivers/driver.h" +#include "eap_peer/eap.h" #include "wpa_supplicant_i.h" #include "config.h" #include "notify.h" @@ -62,6 +63,9 @@ struct wpa_bss_anqp * wpa_bss_anqp_alloc(void) anqp = os_zalloc(sizeof(*anqp)); if (anqp == NULL) return NULL; +#ifdef CONFIG_INTERWORKING + dl_list_init(&anqp->anqp_elems); +#endif /* CONFIG_INTERWORKING */ anqp->users = 1; return anqp; } @@ -82,6 +86,7 @@ static struct wpa_bss_anqp * wpa_bss_anqp_clone(struct wpa_bss_anqp *anqp) #define ANQP_DUP(f) if (anqp->f) n->f = wpabuf_dup(anqp->f) #ifdef CONFIG_INTERWORKING + dl_list_init(&n->anqp_elems); ANQP_DUP(capability_list); ANQP_DUP(venue_name); ANQP_DUP(network_auth_type); @@ -143,6 +148,10 @@ int wpa_bss_anqp_unshare_alloc(struct wpa_bss *bss) */ static void wpa_bss_anqp_free(struct wpa_bss_anqp *anqp) { +#ifdef CONFIG_INTERWORKING + struct wpa_bss_anqp_elem *elem; +#endif /* CONFIG_INTERWORKING */ + if (anqp == NULL) return; @@ -161,6 +170,13 @@ static void wpa_bss_anqp_free(struct wpa_bss_anqp *anqp) wpabuf_free(anqp->nai_realm); wpabuf_free(anqp->anqp_3gpp); wpabuf_free(anqp->domain_name); + + while ((elem = dl_list_first(&anqp->anqp_elems, + struct wpa_bss_anqp_elem, list))) { + dl_list_del(&elem->list); + wpabuf_free(elem->payload); + os_free(elem); + } #endif /* CONFIG_INTERWORKING */ #ifdef CONFIG_HS20 wpabuf_free(anqp->hs20_capability_list); @@ -200,8 +216,8 @@ static void wpa_bss_update_pending_connect(struct wpa_supplicant *wpa_s, } -static void wpa_bss_remove(struct wpa_supplicant *wpa_s, struct wpa_bss *bss, - const char *reason) +void wpa_bss_remove(struct wpa_supplicant *wpa_s, struct wpa_bss *bss, + const char *reason) { if (wpa_s->last_scan_res) { unsigned int i; @@ -290,6 +306,47 @@ static void wpa_bss_copy_res(struct wpa_bss *dst, struct wpa_scan_res *src, } +static int wpa_bss_is_wps_candidate(struct wpa_supplicant *wpa_s, + struct wpa_bss *bss) +{ +#ifdef CONFIG_WPS + struct wpa_ssid *ssid; + struct wpabuf *wps_ie; + int pbc = 0, ret; + + wps_ie = wpa_bss_get_vendor_ie_multi(bss, WPS_IE_VENDOR_TYPE); + if (!wps_ie) + return 0; + + if (wps_is_selected_pbc_registrar(wps_ie)) { + pbc = 1; + } else if (!wps_is_addr_authorized(wps_ie, wpa_s->own_addr, 1)) { + wpabuf_free(wps_ie); + return 0; + } + + for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) { + if (!(ssid->key_mgmt & WPA_KEY_MGMT_WPS)) + continue; + if (ssid->ssid_len && + (ssid->ssid_len != bss->ssid_len || + os_memcmp(ssid->ssid, bss->ssid, ssid->ssid_len) != 0)) + continue; + + if (pbc) + ret = eap_is_wps_pbc_enrollee(&ssid->eap); + else + ret = eap_is_wps_pin_enrollee(&ssid->eap); + wpabuf_free(wps_ie); + return ret; + } + wpabuf_free(wps_ie); +#endif /* CONFIG_WPS */ + + return 0; +} + + static int wpa_bss_known(struct wpa_supplicant *wpa_s, struct wpa_bss *bss) { struct wpa_ssid *ssid; @@ -328,7 +385,8 @@ static int wpa_bss_remove_oldest_unknown(struct wpa_supplicant *wpa_s) struct wpa_bss *bss; dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) { - if (!wpa_bss_known(wpa_s, bss)) { + if (!wpa_bss_known(wpa_s, bss) && + !wpa_bss_is_wps_candidate(wpa_s, bss)) { wpa_bss_remove(wpa_s, bss, __func__); return 0; } @@ -786,7 +844,7 @@ void wpa_bss_update_end(struct wpa_supplicant *wpa_s, struct scan_info *info, struct wpa_bss *bss, *n; os_get_reltime(&wpa_s->last_scan); - if (!new_scan) + if ((info && info->aborted) || !new_scan) return; /* do not expire entries without new scan */ dl_list_for_each_safe(bss, n, &wpa_s->bss, struct wpa_bss, list) { @@ -1006,20 +1064,7 @@ struct wpa_bss * wpa_bss_get_id_range(struct wpa_supplicant *wpa_s, */ const u8 * wpa_bss_get_ie(const struct wpa_bss *bss, u8 ie) { - const u8 *end, *pos; - - pos = (const u8 *) (bss + 1); - end = pos + bss->ie_len; - - while (pos + 1 < end) { - if (pos + 2 + pos[1] > end) - break; - if (pos[0] == ie) - return pos; - pos += 2 + pos[1]; - } - - return NULL; + return get_ie((const u8 *) (bss + 1), bss->ie_len, ie); } @@ -1039,8 +1084,8 @@ const u8 * wpa_bss_get_vendor_ie(const struct wpa_bss *bss, u32 vendor_type) pos = (const u8 *) (bss + 1); end = pos + bss->ie_len; - while (pos + 1 < end) { - if (pos + 2 + pos[1] > end) + while (end - pos > 1) { + if (2 + pos[1] > end - pos) break; if (pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 && vendor_type == WPA_GET_BE32(&pos[2])) @@ -1076,8 +1121,8 @@ const u8 * wpa_bss_get_vendor_ie_beacon(const struct wpa_bss *bss, pos += bss->ie_len; end = pos + bss->beacon_ie_len; - while (pos + 1 < end) { - if (pos + 2 + pos[1] > end) + while (end - pos > 1) { + if (2 + pos[1] > end - pos) break; if (pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 && vendor_type == WPA_GET_BE32(&pos[2])) @@ -1112,8 +1157,8 @@ struct wpabuf * wpa_bss_get_vendor_ie_multi(const struct wpa_bss *bss, pos = (const u8 *) (bss + 1); end = pos + bss->ie_len; - while (pos + 1 < end) { - if (pos + 2 + pos[1] > end) + while (end - pos > 1) { + if (2 + pos[1] > end - pos) break; if (pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 && vendor_type == WPA_GET_BE32(&pos[2])) @@ -1157,8 +1202,8 @@ struct wpabuf * wpa_bss_get_vendor_ie_multi_beacon(const struct wpa_bss *bss, pos += bss->ie_len; end = pos + bss->beacon_ie_len; - while (pos + 1 < end) { - if (pos + 2 + pos[1] > end) + while (end - pos > 1) { + if (2 + pos[1] > end - pos) break; if (pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 && vendor_type == WPA_GET_BE32(&pos[2])) |