void wpas_wps_notify_scan_results(struct wpa_supplicant *wpa_s) { struct wpa_bss *bss; unsigned int pbc = 0, auth = 0, pin = 0, wps = 0; if (wpa_s->disconnected || wpa_s->wpa_state >= WPA_ASSOCIATED) return; dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) { struct wpabuf *ie; ie = wpa_bss_get_vendor_ie_multi(bss, WPS_IE_VENDOR_TYPE); if (!ie) continue; if (wps_is_selected_pbc_registrar(ie)) pbc++; else if (wps_is_addr_authorized(ie, wpa_s->own_addr, 0)) auth++; else if (wps_is_selected_pin_registrar(ie)) pin++; else wps++; wpabuf_free(ie); } if (pbc) wpa_msg_ctrl(wpa_s, MSG_INFO, WPS_EVENT_AP_AVAILABLE_PBC); else if (auth) wpa_msg_ctrl(wpa_s, MSG_INFO, WPS_EVENT_AP_AVAILABLE_AUTH); else if (pin) wpa_msg_ctrl(wpa_s, MSG_INFO, WPS_EVENT_AP_AVAILABLE_PIN); else if (wps) wpa_msg_ctrl(wpa_s, MSG_INFO, WPS_EVENT_AP_AVAILABLE); }
int wpas_wps_ssid_wildcard_ok(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid, struct wpa_scan_res *bss) { struct wpabuf *wps_ie = NULL; int ret = 0; if (eap_is_wps_pbc_enrollee(&ssid->eap)) { wps_ie = wpa_scan_get_vendor_ie_multi(bss, WPS_IE_VENDOR_TYPE); if (wps_ie && wps_is_selected_pbc_registrar(wps_ie)) { /* allow wildcard SSID for WPS PBC */ ret = 1; } } else if (eap_is_wps_pin_enrollee(&ssid->eap)) { wps_ie = wpa_scan_get_vendor_ie_multi(bss, WPS_IE_VENDOR_TYPE); if (wps_ie && (wps_is_selected_pin_registrar(wps_ie) || wpa_s->scan_runs >= WPS_PIN_SCAN_IGNORE_SEL_REG)) { /* allow wildcard SSID for WPS PIN */ ret = 1; } } if (!ret && ssid->bssid_set && os_memcmp(ssid->bssid, bss->bssid, ETH_ALEN) == 0) { /* allow wildcard SSID due to hardcoded BSSID match */ ret = 1; } wpabuf_free(wps_ie); return ret; }
void wpas_wps_notify_scan_results(struct wpa_supplicant *wpa_s) { struct wpa_bss *bss; if (wpa_s->disconnected || wpa_s->wpa_state >= WPA_ASSOCIATED) return; dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) { struct wpabuf *ie; ie = wpa_bss_get_vendor_ie_multi(bss, WPS_IE_VENDOR_TYPE); if (!ie) continue; if (wps_is_selected_pbc_registrar(ie)) wpa_msg_ctrl(wpa_s, MSG_INFO, WPS_EVENT_AP_AVAILABLE_PBC); else if (wps_is_selected_pin_registrar(ie)) wpa_msg_ctrl(wpa_s, MSG_INFO, WPS_EVENT_AP_AVAILABLE_PIN); else wpa_msg_ctrl(wpa_s, MSG_INFO, WPS_EVENT_AP_AVAILABLE); wpabuf_free(ie); break; } }
static char * wpa_supplicant_wps_ie_txt(char *pos, char *end, const struct wpa_scan_res *res) { #ifdef CONFIG_WPS struct wpabuf *wps_ie; int ret; const char *txt; wps_ie = wpa_scan_get_vendor_ie_multi(res, WPS_IE_VENDOR_TYPE); if (wps_ie == NULL) return pos; if (wps_is_selected_pbc_registrar(wps_ie)) txt = "[WPS-PBC]"; else if (wps_is_selected_pin_registrar(wps_ie)) txt = "[WPS-PIN]"; else txt = "[WPS]"; ret = os_snprintf(pos, end - pos, "%s", txt); if (ret >= 0 && ret < end - pos) pos += ret; wpabuf_free(wps_ie); #endif /* CONFIG_WPS */ return pos; }
int wpas_wps_ssid_wildcard_ok(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid, struct wpa_scan_res *bss) { struct wpabuf *wps_ie = NULL; int ret = 0; if (eap_is_wps_pbc_enrollee(&ssid->eap)) { wps_ie = wpa_scan_get_vendor_ie_multi(bss, WPS_IE_VENDOR_TYPE); if (wps_ie && wps_is_selected_pbc_registrar(wps_ie)) { /* allow wildcard SSID for WPS PBC */ ret = 1; } } else if (eap_is_wps_pin_enrollee(&ssid->eap)) { wps_ie = wpa_scan_get_vendor_ie_multi(bss, WPS_IE_VENDOR_TYPE); if (wps_ie && (wps_is_addr_authorized(wps_ie, wpa_s->own_addr, 1) || wpa_s->scan_runs >= WPS_PIN_SCAN_IGNORE_SEL_REG)) { /* allow wildcard SSID for WPS PIN */ ret = 1; } } if (!ret && ssid->bssid_set && os_memcmp(ssid->bssid, bss->bssid, ETH_ALEN) == 0) { /* allow wildcard SSID due to hardcoded BSSID match */ ret = 1; } #ifdef CONFIG_WPS_STRICT if (wps_ie) { if (wps_validate_beacon_probe_resp(wps_ie, bss->beacon_ie_len > 0, bss->bssid) < 0) ret = 0; if (bss->beacon_ie_len) { struct wpabuf *bcn_wps; bcn_wps = wpa_scan_get_vendor_ie_multi_beacon( bss, WPS_IE_VENDOR_TYPE); if (bcn_wps == NULL) { wpa_printf(MSG_DEBUG, "WPS: Mandatory WPS IE " "missing from AP Beacon"); ret = 0; } else { if (wps_validate_beacon(wps_ie) < 0) ret = 0; wpabuf_free(bcn_wps); } } } #endif /* CONFIG_WPS_STRICT */ wpabuf_free(wps_ie); return ret; }
int wpas_wps_scan_pbc_overlap(struct wpa_supplicant *wpa_s, struct wpa_scan_res *selected, struct wpa_ssid *ssid) { const u8 *sel_uuid, *uuid; size_t i; struct wpabuf *wps_ie; int ret = 0; if (!eap_is_wps_pbc_enrollee(&ssid->eap)) return 0; /* Make sure that only one AP is in active PBC mode */ wps_ie = wpa_scan_get_vendor_ie_multi(selected, WPS_IE_VENDOR_TYPE); if (wps_ie) sel_uuid = wps_get_uuid_e(wps_ie); else sel_uuid = NULL; for (i = 0; i < wpa_s->scan_res->num; i++) { struct wpa_scan_res *bss = wpa_s->scan_res->res[i]; struct wpabuf *ie; if (bss == selected) continue; ie = wpa_scan_get_vendor_ie_multi(bss, WPS_IE_VENDOR_TYPE); if (!ie) continue; if (!wps_is_selected_pbc_registrar(ie)) { wpabuf_free(ie); continue; } uuid = wps_get_uuid_e(ie); if (sel_uuid == NULL || uuid == NULL || os_memcmp(sel_uuid, uuid, 16) != 0) { ret = 1; /* PBC overlap */ wpabuf_free(ie); break; } /* TODO: verify that this is reasonable dual-band situation */ wpabuf_free(ie); } wpabuf_free(wps_ie); return ret; }
void wpas_wps_notify_scan_results(struct wpa_supplicant *wpa_s) { size_t i; if (wpa_s->disconnected || wpa_s->wpa_state >= WPA_ASSOCIATED) return; for (i = 0; i < wpa_s->scan_res->num; i++) { struct wpa_scan_res *bss = wpa_s->scan_res->res[i]; struct wpabuf *ie; ie = wpa_scan_get_vendor_ie_multi(bss, WPS_IE_VENDOR_TYPE); if (!ie) continue; if (wps_is_selected_pbc_registrar(ie)) wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_AP_AVAILABLE_PBC); else if (wps_is_selected_pin_registrar(ie)) wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_AP_AVAILABLE_PIN); else wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_AP_AVAILABLE); wpabuf_free(ie); break; } }
int wpas_wps_ssid_bss_match(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid, struct wpa_scan_res *bss) { struct wpabuf *wps_ie; if (!(ssid->key_mgmt & WPA_KEY_MGMT_WPS)) return -1; wps_ie = wpa_scan_get_vendor_ie_multi(bss, WPS_IE_VENDOR_TYPE); if (eap_is_wps_pbc_enrollee(&ssid->eap)) { if (!wps_ie) { wpa_printf(MSG_DEBUG, " skip - non-WPS AP"); return 0; } if (!wps_is_selected_pbc_registrar(wps_ie)) { wpa_printf(MSG_DEBUG, " skip - WPS AP " "without active PBC Registrar"); wpabuf_free(wps_ie); return 0; } /* TODO: overlap detection */ wpa_printf(MSG_DEBUG, " selected based on WPS IE " "(Active PBC)"); wpabuf_free(wps_ie); return 1; } if (eap_is_wps_pin_enrollee(&ssid->eap)) { if (!wps_ie) { wpa_printf(MSG_DEBUG, " skip - non-WPS AP"); return 0; } /* * Start with WPS APs that advertise active PIN Registrar and * allow any WPS AP after third scan since some APs do not set * Selected Registrar attribute properly when using external * Registrar. */ if (!wps_is_selected_pin_registrar(wps_ie)) { if (wpa_s->scan_runs < WPS_PIN_SCAN_IGNORE_SEL_REG) { wpa_printf(MSG_DEBUG, " skip - WPS AP " "without active PIN Registrar"); wpabuf_free(wps_ie); return 0; } wpa_printf(MSG_DEBUG, " selected based on WPS IE"); } else { wpa_printf(MSG_DEBUG, " selected based on WPS IE " "(Active PIN)"); } wpabuf_free(wps_ie); return 1; } if (wps_ie) { wpa_printf(MSG_DEBUG, " selected based on WPS IE"); wpabuf_free(wps_ie); return 1; } return -1; }
int wpas_wps_scan_pbc_overlap(struct wpa_supplicant *wpa_s, struct wpa_bss *selected, struct wpa_ssid *ssid) { const u8 *sel_uuid, *uuid; struct wpabuf *wps_ie; int ret = 0; struct wpa_bss *bss; if (!eap_is_wps_pbc_enrollee(&ssid->eap)) return 0; wpa_printf(MSG_DEBUG, "WPS: Check whether PBC session overlap is " "present in scan results; selected BSSID " MACSTR, MAC2STR(selected->bssid)); /* Make sure that only one AP is in active PBC mode */ wps_ie = wpa_bss_get_vendor_ie_multi(selected, WPS_IE_VENDOR_TYPE); if (wps_ie) { sel_uuid = wps_get_uuid_e(wps_ie); wpa_hexdump(MSG_DEBUG, "WPS: UUID of the selected BSS", sel_uuid, UUID_LEN); } else { wpa_printf(MSG_DEBUG, "WPS: Selected BSS does not include " "WPS IE?!"); sel_uuid = NULL; } dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) { struct wpabuf *ie; if (bss == selected) continue; ie = wpa_bss_get_vendor_ie_multi(bss, WPS_IE_VENDOR_TYPE); if (!ie) continue; if (!wps_is_selected_pbc_registrar(ie)) { wpabuf_free(ie); continue; } wpa_printf(MSG_DEBUG, "WPS: Another BSS in active PBC mode: " MACSTR, MAC2STR(bss->bssid)); uuid = wps_get_uuid_e(ie); wpa_hexdump(MSG_DEBUG, "WPS: UUID of the other BSS", uuid, UUID_LEN); if (sel_uuid == NULL || uuid == NULL || os_memcmp(sel_uuid, uuid, UUID_LEN) != 0) { ret = 1; /* PBC overlap */ wpa_msg(wpa_s, MSG_INFO, "WPS: PBC overlap detected: " MACSTR " and " MACSTR, MAC2STR(selected->bssid), MAC2STR(bss->bssid)); wpabuf_free(ie); break; } /* TODO: verify that this is reasonable dual-band situation */ wpabuf_free(ie); } wpabuf_free(wps_ie); return ret; }