static int wpa_supplicant_ctrl_iface_blacklist( struct wpa_supplicant *wpa_s, char *cmd, char *buf, size_t buflen) { struct wpa_ssid *ssid; u8 bssid[ETH_ALEN]; struct wpa_blacklist *e; char *pos, *end; int ret; /* cmd: "BLACKLIST [<BSSID>]" */ if (*cmd == '\0') { pos = buf; end = buf + buflen; e = wpa_s->blacklist; while (e) { ret = os_snprintf(pos, end-pos, "%02x:%02x:%02x:%02x:%02x:%02x\n", e->bssid[0], e->bssid[1], e->bssid[2], e->bssid[3], e->bssid[4], e->bssid[5]); if (ret < 0 || ret >= end - pos) return pos - buf; pos += ret; e = e->next; } return pos - buf; } wpa_printf(MSG_DEBUG, "CTRL_IFACE: bssid='%s'", cmd); ++cmd; if (os_strncmp(cmd, "clear", 5) == 0) { wpa_blacklist_clear(wpa_s); return 0; } if (hwaddr_aton(cmd, bssid)) { wpa_printf(MSG_DEBUG ,"CTRL_IFACE: invalid BSSID '%s'", cmd); return -1; } /* * Add the BSSID twice, so its count will be 2, causing it to be * skipped when processing scan results. */ ret = wpa_blacklist_add(wpa_s, bssid); if (ret != 0) return ret; return wpa_blacklist_add(wpa_s, bssid); }
static void wpa_supplicant_event_disassoc(struct wpa_supplicant *wpa_s) { const u8 *bssid; if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE) { /* * At least Host AP driver and a Prism3 card seemed to be * generating streams of disconnected events when configuring * IBSS for WPA-None. Ignore them for now. */ wpa_printf(MSG_DEBUG, "Disconnect event - ignore in " "IBSS/WPA-None mode"); return; } if (wpa_s->wpa_state == WPA_4WAY_HANDSHAKE && wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt)) { wpa_msg(wpa_s, MSG_INFO, "WPA: 4-Way Handshake failed - " "pre-shared key may be incorrect"); } if (wpa_s->wpa_state >= WPA_ASSOCIATED) wpa_supplicant_req_scan(wpa_s, 0, 100000); bssid = wpa_s->bssid; if (is_zero_ether_addr(bssid)) bssid = wpa_s->pending_bssid; wpa_blacklist_add(wpa_s, bssid); wpa_sm_notify_disassoc(wpa_s->wpa); wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DISCONNECTED "- Disconnect event - " "remove keys"); if (wpa_supplicant_dynamic_keys(wpa_s)) { wpa_s->keys_cleared = 0; wpa_clear_keys(wpa_s, wpa_s->bssid); } wpa_supplicant_mark_disassoc(wpa_s); }
int wpas_wps_eapol_cb(struct wpa_supplicant *wpa_s) { if (!wpa_s->wps_success && wpa_s->current_ssid && eap_is_wps_pin_enrollee(&wpa_s->current_ssid->eap)) { const u8 *bssid = wpa_s->bssid; if (is_zero_ether_addr(bssid)) bssid = wpa_s->pending_bssid; wpa_printf(MSG_DEBUG, "WPS: PIN registration with " MACSTR " did not succeed - continue trying to find " "suitable AP", MAC2STR(bssid)); wpa_blacklist_add(wpa_s, bssid); wpa_supplicant_deauthenticate(wpa_s, WLAN_REASON_DEAUTH_LEAVING); wpa_s->reassociate = 1; wpa_supplicant_req_scan(wpa_s, wpa_s->blacklist_cleared ? 5 : 0, 0); wpa_s->blacklist_cleared = 0; return 1; } eloop_cancel_timeout(wpas_wps_timeout, wpa_s, NULL); if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPS && !wpa_s->wps_success) wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_FAIL); if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPS && wpa_s->current_ssid && !(wpa_s->current_ssid->key_mgmt & WPA_KEY_MGMT_WPS)) { int disabled = wpa_s->current_ssid->disabled; wpa_printf(MSG_DEBUG, "WPS: Network configuration replaced - " "try to associate with the received credential"); wpa_supplicant_deauthenticate(wpa_s, WLAN_REASON_DEAUTH_LEAVING); if (disabled) { wpa_printf(MSG_DEBUG, "WPS: Current network is " "disabled - wait for user to enable"); return 1; } wpa_s->after_wps = 5; wpa_s->wps_freq = wpa_s->assoc_freq; wpa_s->normal_scans = 0; wpa_s->reassociate = 1; wpa_supplicant_req_scan(wpa_s, 0, 0); return 1; } if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPS && wpa_s->current_ssid) { wpa_printf(MSG_DEBUG, "WPS: Registration completed - waiting " "for external credential processing"); wpas_clear_wps(wpa_s); wpa_supplicant_deauthenticate(wpa_s, WLAN_REASON_DEAUTH_LEAVING); return 1; } return 0; }
static void wpa_supplicant_event_disassoc(struct wpa_supplicant *wpa_s) { const u8 *bssid; #ifdef CONFIG_SME int authenticating; u8 prev_pending_bssid[ETH_ALEN]; authenticating = wpa_s->wpa_state == WPA_AUTHENTICATING; os_memcpy(prev_pending_bssid, wpa_s->pending_bssid, ETH_ALEN); #endif /* CONFIG_SME */ if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE) { /* * At least Host AP driver and a Prism3 card seemed to be * generating streams of disconnected events when configuring * IBSS for WPA-None. Ignore them for now. */ wpa_printf(MSG_DEBUG, "Disconnect event - ignore in " "IBSS/WPA-None mode"); return; } if (wpa_s->wpa_state == WPA_4WAY_HANDSHAKE && wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt)) { wpa_msg(wpa_s, MSG_INFO, "WPA: 4-Way Handshake failed - " "pre-shared key may be incorrect"); } if (wpa_s->wpa_state >= WPA_ASSOCIATED) wpa_supplicant_req_scan(wpa_s, 0, 100000); bssid = wpa_s->bssid; if (is_zero_ether_addr(bssid)) bssid = wpa_s->pending_bssid; wpa_blacklist_add(wpa_s, bssid); wpa_sm_notify_disassoc(wpa_s->wpa); wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DISCONNECTED "- Disconnect event - " "remove keys"); if (wpa_supplicant_dynamic_keys(wpa_s)) { wpa_s->keys_cleared = 0; wpa_clear_keys(wpa_s, wpa_s->bssid); } wpa_supplicant_mark_disassoc(wpa_s); bgscan_deinit(wpa_s); #ifdef CONFIG_SME if (authenticating && (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME)) { /* * mac80211-workaround to force deauth on failed auth cmd, * requires us to remain in authenticating state to allow the * second authentication attempt to be continued properly. */ wpa_printf(MSG_DEBUG, "SME: Allow pending authentication to " "proceed after disconnection event"); wpa_supplicant_set_state(wpa_s, WPA_AUTHENTICATING); os_memcpy(wpa_s->pending_bssid, prev_pending_bssid, ETH_ALEN); } #endif /* CONFIG_SME */ }
static void wpa_supplicant_event_disassoc(struct wpa_supplicant *wpa_s, u16 reason_code) { const u8 *bssid; #ifdef CONFIG_SME int authenticating; u8 prev_pending_bssid[ETH_ALEN]; authenticating = wpa_s->wpa_state == WPA_AUTHENTICATING; os_memcpy(prev_pending_bssid, wpa_s->pending_bssid, ETH_ALEN); #endif /* CONFIG_SME */ if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE) { /* * At least Host AP driver and a Prism3 card seemed to be * generating streams of disconnected events when configuring * IBSS for WPA-None. Ignore them for now. */ wpa_printf(MSG_DEBUG, "Disconnect event - ignore in " "IBSS/WPA-None mode"); return; } if (wpa_s->wpa_state == WPA_4WAY_HANDSHAKE && wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt)) { wpa_msg(wpa_s, MSG_INFO, "WPA: 4-Way Handshake failed - " "pre-shared key may be incorrect"); } if (!wpa_s->auto_reconnect_disabled || wpa_s->key_mgmt == WPA_KEY_MGMT_WPS) { wpa_printf(MSG_DEBUG, "WPA: Auto connect enabled: try to " "reconnect (wps=%d)", wpa_s->key_mgmt == WPA_KEY_MGMT_WPS); if (wpa_s->wpa_state >= WPA_ASSOCIATING) wpa_supplicant_req_scan(wpa_s, 0, 100000); } else { wpa_printf(MSG_DEBUG, "WPA: Auto connect disabled: do not try " "to re-connect"); wpa_s->reassociate = 0; wpa_s->disconnected = 1; } bssid = wpa_s->bssid; if (is_zero_ether_addr(bssid)) bssid = wpa_s->pending_bssid; wpa_blacklist_add(wpa_s, bssid); wpa_sm_notify_disassoc(wpa_s->wpa); wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DISCONNECTED "bssid=" MACSTR " reason=%d", MAC2STR(bssid), reason_code); if (wpa_supplicant_dynamic_keys(wpa_s)) { wpa_printf(MSG_DEBUG, "Disconnect event - remove keys"); wpa_s->keys_cleared = 0; wpa_clear_keys(wpa_s, wpa_s->bssid); } wpa_supplicant_mark_disassoc(wpa_s); }
void sme_event_assoc_reject(struct wpa_supplicant *wpa_s, union wpa_event_data *data) { int bssid_changed; int timeout = 5000; wpa_printf(MSG_DEBUG, "SME: Association with " MACSTR " failed: " "status code %d", MAC2STR(wpa_s->pending_bssid), data->assoc_reject.status_code); bssid_changed = !is_zero_ether_addr(wpa_s->bssid); /* * For now, unconditionally terminate the previous authentication. In * theory, this should not be needed, but mac80211 gets quite confused * if the authentication is left pending.. Some roaming cases might * benefit from using the previous authentication, so this could be * optimized in the future. */ if (wpa_drv_deauthenticate(wpa_s, wpa_s->pending_bssid, WLAN_REASON_DEAUTH_LEAVING) < 0) { wpa_msg(wpa_s, MSG_INFO, "Deauth request to the driver failed"); } wpa_s->sme.prev_bssid_set = 0; if (wpa_blacklist_add(wpa_s, wpa_s->pending_bssid) == 0) { struct wpa_blacklist *b; b = wpa_blacklist_get(wpa_s, wpa_s->pending_bssid); if (b && b->count < 3) { /* * Speed up next attempt if there could be other APs * that could accept association. */ timeout = 100; } } wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED); os_memset(wpa_s->bssid, 0, ETH_ALEN); os_memset(wpa_s->pending_bssid, 0, ETH_ALEN); if (bssid_changed) wpas_notify_bssid_changed(wpa_s); /* * TODO: if more than one possible AP is available in scan results, * could try the other ones before requesting a new scan. */ ros_assoc_failed(wpa_s, wpa_s->pending_bssid, "Association rejected"); //wpa_supplicant_req_scan(wpa_s, timeout / 1000, // 1000 * (timeout % 1000)); }
void hs20_rx_deauth_imminent_notice(struct wpa_supplicant *wpa_s, u8 code, u16 reauth_delay, const char *url) { if (!wpa_sm_pmf_enabled(wpa_s->wpa)) { wpa_printf(MSG_DEBUG, "HS 2.0: Ignore deauthentication imminent notice since PMF was not enabled"); return; } wpa_msg(wpa_s, MSG_INFO, HS20_DEAUTH_IMMINENT_NOTICE "%u %u %s", code, reauth_delay, url); if (code == HS20_DEAUTH_REASON_CODE_BSS) { wpa_printf(MSG_DEBUG, "HS 2.0: Add BSS to blacklist"); wpa_blacklist_add(wpa_s, wpa_s->bssid); /* TODO: For now, disable full ESS since some drivers may not * support disabling per BSS. */ if (wpa_s->current_ssid) { struct os_reltime now; os_get_reltime(&now); if (now.sec + reauth_delay <= wpa_s->current_ssid->disabled_until.sec) return; wpa_printf(MSG_DEBUG, "HS 2.0: Disable network for %u seconds (BSS)", reauth_delay); wpa_s->current_ssid->disabled_until.sec = now.sec + reauth_delay; } } if (code == HS20_DEAUTH_REASON_CODE_ESS && wpa_s->current_ssid) { struct os_reltime now; os_get_reltime(&now); if (now.sec + reauth_delay <= wpa_s->current_ssid->disabled_until.sec) return; wpa_printf(MSG_DEBUG, "HS 2.0: Disable network for %u seconds", reauth_delay); wpa_s->current_ssid->disabled_until.sec = now.sec + reauth_delay; } }
void sme_event_auth_timed_out(struct wpa_supplicant *wpa_s, union wpa_event_data *data) { int timeout = 5000; wpa_printf(MSG_DEBUG, "SME: Authentication timed out"); if (wpa_blacklist_add(wpa_s, wpa_s->pending_bssid) == 0) { struct wpa_blacklist *b; b = wpa_blacklist_get(wpa_s, wpa_s->pending_bssid); if (b && b->count < 3) { /* * Speed up next attempt if there could be other APs * that could accept association. */ timeout = 100; } } ros_assoc_failed(wpa_s, wpa_s->pending_bssid, "Authentication timed out"); //wpa_supplicant_req_scan(wpa_s, timeout / 1000, // 1000 * (timeout % 1000)); }
static void wpa_supplicant_event_disassoc(struct wpa_supplicant *wpa_s) { const u8 *bssid; if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE) { /* * At least Host AP driver and a Prism3 card seemed to be * generating streams of disconnected events when configuring * IBSS for WPA-None. Ignore them for now. */ wpa_printf(MSG_DEBUG, "Disconnect event - ignore in " "IBSS/WPA-None mode"); return; } if (wpa_s->wpa_state == WPA_4WAY_HANDSHAKE && wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt)) { wpa_msg(wpa_s, MSG_INFO, "WPA: 4-Way Handshake failed - " "pre-shared key may be incorrect"); } #ifdef CONFIG_WAPI_SUPPORT if (wpa_s->key_mgmt == WAPI_KEY_MGMT_CERT || wpa_s->key_mgmt == WAPI_KEY_MGMT_PSK) { MAC_ADDRESS bssid_s; MAC_ADDRESS own_s; wpa_printf(MSG_DEBUG,"[Debug-WAPI] Own MAC address "MACSTR" "MACSTR"!!", MAC2STR(wpa_s->bssid), MAC2STR(wpa_s->own_addr)); memcpy(bssid_s.v, wpa_s->bssid, sizeof(bssid_s.v)); memcpy(own_s.v, wpa_s->own_addr, sizeof(own_s.v)); wpa_printf(MSG_DEBUG,"[Debug-WAPI ^_^!!] Ready send Disassociate complete evert to WAPI Modules!!!"); wapi_set_msg(CONN_DISASSOC, &bssid_s, &own_s, wpa_s->bss_wapi_ie , wpa_s->bss_wapi_ie_len); /*state changed, and trigger the next scanning to connect the another remembered AP*/ /*++ patch CR: [ALPS00125697] [WAPI Support] WLAN status always show "connected"*/ if (wpa_s->wpa_state >= WPA_ASSOCIATED) wpa_supplicant_req_scan(wpa_s, 0, 100000); #if 0 bssid = wpa_s->bssid; if (is_zero_ether_addr(bssid)) bssid = wpa_s->pending_bssid; wpa_printf(MSG_DEBUG,"[Debug-WAPI] Add "MACSTR "to blacklist!!", MAC2STR(wpa_s->bssid)); wpa_blacklist_add(wpa_s, bssid); #endif wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DISCONNECTED "- Disconnect event - " "remove keys"); wpa_supplicant_mark_disassoc(wpa_s); /*--*/ return; } #endif if (wpa_s->wpa_state >= WPA_ASSOCIATED) wpa_supplicant_req_scan(wpa_s, 0, 100000); bssid = wpa_s->bssid; if (is_zero_ether_addr(bssid)) bssid = wpa_s->pending_bssid; wpa_blacklist_add(wpa_s, bssid); wpa_sm_notify_disassoc(wpa_s->wpa); wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DISCONNECTED "- Disconnect event - " "remove keys"); if (wpa_supplicant_dynamic_keys(wpa_s)) { wpa_s->keys_cleared = 0; wpa_clear_keys(wpa_s, wpa_s->bssid); } wpa_supplicant_mark_disassoc(wpa_s); }
static int wpas_blacklist_module_tests(void) { struct wpa_supplicant wpa_s; int ret = -1; os_memset(&wpa_s, 0, sizeof(wpa_s)); wpa_blacklist_clear(&wpa_s); if (wpa_blacklist_get(NULL, NULL) != NULL || wpa_blacklist_get(NULL, (u8 *) "123456") != NULL || wpa_blacklist_get(&wpa_s, NULL) != NULL || wpa_blacklist_get(&wpa_s, (u8 *) "123456") != NULL) goto fail; if (wpa_blacklist_add(NULL, NULL) == 0 || wpa_blacklist_add(NULL, (u8 *) "123456") == 0 || wpa_blacklist_add(&wpa_s, NULL) == 0) goto fail; if (wpa_blacklist_del(NULL, NULL) == 0 || wpa_blacklist_del(NULL, (u8 *) "123456") == 0 || wpa_blacklist_del(&wpa_s, NULL) == 0 || wpa_blacklist_del(&wpa_s, (u8 *) "123456") == 0) goto fail; if (wpa_blacklist_add(&wpa_s, (u8 *) "111111") < 0 || wpa_blacklist_add(&wpa_s, (u8 *) "111111") < 0 || wpa_blacklist_add(&wpa_s, (u8 *) "222222") < 0 || wpa_blacklist_add(&wpa_s, (u8 *) "333333") < 0 || wpa_blacklist_add(&wpa_s, (u8 *) "444444") < 0 || wpa_blacklist_del(&wpa_s, (u8 *) "333333") < 0 || wpa_blacklist_del(&wpa_s, (u8 *) "xxxxxx") == 0 || wpa_blacklist_get(&wpa_s, (u8 *) "xxxxxx") != NULL || wpa_blacklist_get(&wpa_s, (u8 *) "111111") == NULL || wpa_blacklist_get(&wpa_s, (u8 *) "222222") == NULL || wpa_blacklist_get(&wpa_s, (u8 *) "444444") == NULL || wpa_blacklist_del(&wpa_s, (u8 *) "111111") < 0 || wpa_blacklist_del(&wpa_s, (u8 *) "222222") < 0 || wpa_blacklist_del(&wpa_s, (u8 *) "444444") < 0 || wpa_blacklist_add(&wpa_s, (u8 *) "111111") < 0 || wpa_blacklist_add(&wpa_s, (u8 *) "222222") < 0 || wpa_blacklist_add(&wpa_s, (u8 *) "333333") < 0) goto fail; ret = 0; fail: wpa_blacklist_clear(&wpa_s); if (ret) wpa_printf(MSG_ERROR, "blacklist module test failure"); return ret; }