📄 wpa_supplicant.c
字号:
*/ if (wpa_s->key_mgmt == WPA_KEY_MGMT_PSK) { /* * Clear forced success to clear EAP state for next * authentication. */ eapol_sm_notify_eap_success(wpa_s->eapol, FALSE); } eapol_sm_notify_config(wpa_s->eapol, NULL, NULL); wpa_sm_set_config(wpa_s->wpa, NULL); wpa_sm_set_fast_reauth(wpa_s->wpa, wpa_s->conf->fast_reauth); rsn_preauth_deinit(wpa_s->wpa); wpa_config_free(wpa_s->conf); wpa_s->conf = conf; if (reconf_ctrl) wpa_s->ctrl_iface = wpa_supplicant_ctrl_iface_init(wpa_s); wpa_supplicant_clear_status(wpa_s); wpa_s->reassociate = 1; wpa_supplicant_req_scan(wpa_s, 0, 0); wpa_msg(wpa_s, MSG_DEBUG, "Reconfiguration completed"); return 0;}static void wpa_supplicant_reconfig(int sig, void *eloop_ctx, void *signal_ctx){ struct wpa_global *global = eloop_ctx; struct wpa_supplicant *wpa_s; wpa_printf(MSG_DEBUG, "Signal %d received - reconfiguring", sig); for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) { if (wpa_supplicant_reload_configuration(wpa_s) < 0) { eloop_terminate(); } }}static void wpa_supplicant_gen_assoc_event(struct wpa_supplicant *wpa_s){ struct wpa_ssid *ssid; union wpa_event_data data; ssid = wpa_supplicant_get_ssid(wpa_s); if (ssid == NULL) return; if (wpa_s->current_ssid == NULL) wpa_s->current_ssid = ssid; wpa_supplicant_initiate_eapol(wpa_s); wpa_printf(MSG_DEBUG, "Already associated with a configured network - " "generating associated event"); os_memset(&data, 0, sizeof(data)); wpa_supplicant_event(wpa_s, EVENT_ASSOC, &data);}static void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx){ struct wpa_supplicant *wpa_s = eloop_ctx; struct wpa_ssid *ssid; int enabled, scan_req = 0, ret; if (wpa_s->disconnected && !wpa_s->scan_req) return; enabled = 0; ssid = wpa_s->conf->ssid; while (ssid) { if (!ssid->disabled) { enabled++; break; } ssid = ssid->next; } if (!enabled && !wpa_s->scan_req) { wpa_printf(MSG_DEBUG, "No enabled networks - do not scan"); wpa_supplicant_set_state(wpa_s, WPA_INACTIVE); return; } scan_req = wpa_s->scan_req; wpa_s->scan_req = 0; if (wpa_s->conf->ap_scan != 0 && wpa_s->driver && os_strcmp(wpa_s->driver->name, "wired") == 0) { wpa_printf(MSG_DEBUG, "Using wired driver - overriding " "ap_scan configuration"); wpa_s->conf->ap_scan = 0; } if (wpa_s->conf->ap_scan == 0) { wpa_supplicant_gen_assoc_event(wpa_s); return; } if (wpa_s->wpa_state == WPA_DISCONNECTED || wpa_s->wpa_state == WPA_INACTIVE) wpa_supplicant_set_state(wpa_s, WPA_SCANNING); ssid = wpa_s->conf->ssid; if (wpa_s->prev_scan_ssid != BROADCAST_SSID_SCAN) { while (ssid) { if (ssid == wpa_s->prev_scan_ssid) { ssid = ssid->next; break; } ssid = ssid->next; } } while (ssid) { if (!ssid->disabled && (ssid->scan_ssid || wpa_s->conf->ap_scan == 2)) break; ssid = ssid->next; } if (scan_req != 2 && wpa_s->conf->ap_scan == 2) { /* * ap_scan=2 mode - try to associate with each SSID instead of * scanning for each scan_ssid=1 network. */ if (ssid == NULL) { wpa_printf(MSG_DEBUG, "wpa_supplicant_scan: Reached " "end of scan list - go back to beginning"); wpa_s->prev_scan_ssid = BROADCAST_SSID_SCAN; wpa_supplicant_req_scan(wpa_s, 0, 0); return; } if (ssid->next) { /* Continue from the next SSID on the next attempt. */ wpa_s->prev_scan_ssid = ssid; } else { /* Start from the beginning of the SSID list. */ wpa_s->prev_scan_ssid = BROADCAST_SSID_SCAN; } wpa_supplicant_associate(wpa_s, NULL, ssid); return; } wpa_printf(MSG_DEBUG, "Starting AP scan (%s SSID)", ssid ? "specific": "broadcast"); if (ssid) { wpa_hexdump_ascii(MSG_DEBUG, "Scan SSID", ssid->ssid, ssid->ssid_len); wpa_s->prev_scan_ssid = ssid; } else wpa_s->prev_scan_ssid = BROADCAST_SSID_SCAN; if (wpa_s->scan_res_tried == 0 && wpa_s->conf->ap_scan == 1) { wpa_s->scan_res_tried++; wpa_printf(MSG_DEBUG, "Trying to get current scan results " "first without requesting a new scan to speed up " "initial association"); wpa_supplicant_event(wpa_s, EVENT_SCAN_RESULTS, NULL); return; } if (wpa_s->use_client_mlme) { ret = ieee80211_sta_req_scan(wpa_s, ssid ? ssid->ssid : NULL, ssid ? ssid->ssid_len : 0); } else { ret = wpa_drv_scan(wpa_s, ssid ? ssid->ssid : NULL, ssid ? ssid->ssid_len : 0); } if (ret) { wpa_printf(MSG_WARNING, "Failed to initiate AP scan."); wpa_supplicant_req_scan(wpa_s, 10, 0); }}static wpa_cipher cipher_suite2driver(int cipher){ switch (cipher) { case WPA_CIPHER_NONE: return CIPHER_NONE; case WPA_CIPHER_WEP40: return CIPHER_WEP40; case WPA_CIPHER_WEP104: return CIPHER_WEP104; case WPA_CIPHER_CCMP: return CIPHER_CCMP; case WPA_CIPHER_TKIP: default: return CIPHER_TKIP; }}static wpa_key_mgmt key_mgmt2driver(int key_mgmt){ switch (key_mgmt) { case WPA_KEY_MGMT_NONE: return KEY_MGMT_NONE; case WPA_KEY_MGMT_IEEE8021X_NO_WPA: return KEY_MGMT_802_1X_NO_WPA; case WPA_KEY_MGMT_IEEE8021X: return KEY_MGMT_802_1X; case WPA_KEY_MGMT_WPA_NONE: return KEY_MGMT_WPA_NONE; case WPA_KEY_MGMT_PSK: default: return KEY_MGMT_PSK; }}static int wpa_supplicant_suites_from_ai(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid, struct wpa_ie_data *ie){ int ret = wpa_sm_parse_own_wpa_ie(wpa_s->wpa, ie); if (ret) { if (ret == -2) { wpa_msg(wpa_s, MSG_INFO, "WPA: Failed to parse WPA IE " "from association info"); } return -1; } wpa_printf(MSG_DEBUG, "WPA: Using WPA IE from AssocReq to set cipher " "suites"); if (!(ie->group_cipher & ssid->group_cipher)) { wpa_msg(wpa_s, MSG_INFO, "WPA: Driver used disabled group " "cipher 0x%x (mask 0x%x) - reject", ie->group_cipher, ssid->group_cipher); return -1; } if (!(ie->pairwise_cipher & ssid->pairwise_cipher)) { wpa_msg(wpa_s, MSG_INFO, "WPA: Driver used disabled pairwise " "cipher 0x%x (mask 0x%x) - reject", ie->pairwise_cipher, ssid->pairwise_cipher); return -1; } if (!(ie->key_mgmt & ssid->key_mgmt)) { wpa_msg(wpa_s, MSG_INFO, "WPA: Driver used disabled key " "management 0x%x (mask 0x%x) - reject", ie->key_mgmt, ssid->key_mgmt); return -1; }#ifdef CONFIG_IEEE80211W if (!(ie->capabilities & WPA_CAPABILITY_MGMT_FRAME_PROTECTION) && ssid->ieee80211w == IEEE80211W_REQUIRED) { wpa_msg(wpa_s, MSG_INFO, "WPA: Driver associated with an AP " "that does not support management frame protection - " "reject"); return -1; }#endif /* CONFIG_IEEE80211W */ return 0;}/** * wpa_supplicant_set_suites - Set authentication and encryption parameters * @wpa_s: Pointer to wpa_supplicant data * @bss: Scan results for the selected BSS, or %NULL if not available * @ssid: Configuration data for the selected network * @wpa_ie: Buffer for the WPA/RSN IE * @wpa_ie_len: Maximum wpa_ie buffer size on input. This is changed to be the * used buffer length in case the functions returns success. * Returns: 0 on success or -1 on failure * * This function is used to configure authentication and encryption parameters * based on the network configuration and scan result for the selected BSS (if * available). */int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s, struct wpa_scan_result *bss, struct wpa_ssid *ssid, u8 *wpa_ie, size_t *wpa_ie_len){ struct wpa_ie_data ie; int sel, proto; if (bss && bss->rsn_ie_len && (ssid->proto & WPA_PROTO_RSN) && wpa_parse_wpa_ie(bss->rsn_ie, bss->rsn_ie_len, &ie) == 0 && (ie.group_cipher & ssid->group_cipher) && (ie.pairwise_cipher & ssid->pairwise_cipher) && (ie.key_mgmt & ssid->key_mgmt)) { wpa_msg(wpa_s, MSG_DEBUG, "RSN: using IEEE 802.11i/D9.0"); proto = WPA_PROTO_RSN; } else if (bss && bss->wpa_ie_len && (ssid->proto & WPA_PROTO_WPA) && wpa_parse_wpa_ie(bss->wpa_ie, bss->wpa_ie_len, &ie) == 0 && (ie.group_cipher & ssid->group_cipher) && (ie.pairwise_cipher & ssid->pairwise_cipher) && (ie.key_mgmt & ssid->key_mgmt)) { wpa_msg(wpa_s, MSG_DEBUG, "WPA: using IEEE 802.11i/D3.0"); proto = WPA_PROTO_WPA; } else if (bss) { wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to select WPA/RSN"); return -1; } else { if (ssid->proto & WPA_PROTO_RSN) proto = WPA_PROTO_RSN; else proto = WPA_PROTO_WPA; if (wpa_supplicant_suites_from_ai(wpa_s, ssid, &ie) < 0) { os_memset(&ie, 0, sizeof(ie)); ie.group_cipher = ssid->group_cipher; ie.pairwise_cipher = ssid->pairwise_cipher; ie.key_mgmt = ssid->key_mgmt;#ifdef CONFIG_IEEE80211W ie.mgmt_group_cipher = ssid->ieee80211w != NO_IEEE80211W ? WPA_CIPHER_AES_128_CMAC : 0;#endif /* CONFIG_IEEE80211W */ wpa_printf(MSG_DEBUG, "WPA: Set cipher suites based " "on configuration"); } else proto = ie.proto; } wpa_printf(MSG_DEBUG, "WPA: Selected cipher suites: group %d " "pairwise %d key_mgmt %d proto %d", ie.group_cipher, ie.pairwise_cipher, ie.key_mgmt, proto);#ifdef CONFIG_IEEE80211W if (ssid->ieee80211w) { wpa_printf(MSG_DEBUG, "WPA: Selected mgmt group cipher %d", ie.mgmt_group_cipher); }#endif /* CONFIG_IEEE80211W */ wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_PROTO, proto); if (wpa_sm_set_ap_wpa_ie(wpa_s->wpa, bss ? bss->wpa_ie : NULL, bss ? bss->wpa_ie_len : 0) || wpa_sm_set_ap_rsn_ie(wpa_s->wpa, bss ? bss->rsn_ie : NULL, bss ? bss->rsn_ie_len : 0)) return -1; sel = ie.group_cipher & ssid->group_cipher; if (sel & WPA_CIPHER_CCMP) { wpa_s->group_cipher = WPA_CIPHER_CCMP; wpa_msg(wpa_s, MSG_DEBUG, "WPA: using GTK CCMP"); } else if (sel & WPA_CIPHER_TKIP) { wpa_s->group_cipher = WPA_CIPHER_TKIP; wpa_msg(wpa_s, MSG_DEBUG, "WPA: using GTK TKIP"); } else if (sel & WPA_CIPHER_WEP104) { wpa_s->group_cipher = WPA_CIPHER_WEP104; wpa_msg(wpa_s, MSG_DEBUG, "WPA: using GTK WEP104"); } else if (sel & WPA_CIPHER_WEP40) { wpa_s->group_cipher = WPA_CIPHER_WEP40; wpa_msg(wpa_s, MSG_DEBUG, "WPA: using GTK WEP40"); } else { wpa_printf(MSG_WARNING, "WPA: Failed to select group cipher."); return -1; } sel = ie.pairwise_cipher & ssid->pairwise_cipher; if (sel & WPA_CIPHER_CCMP) { wpa_s->pairwise_cipher = WPA_CIPHER_CCMP; wpa_msg(wpa_s, MSG_DEBUG, "WPA: using PTK CCMP"); } else if (sel & WPA_CIPHER_TKIP) { wpa_s->pairwise_cipher = WPA_CIPHER_TKIP; wpa_msg(wpa_s, MSG_DEBUG, "WPA: using PTK TKIP"); } else if (sel & WPA_CIPHER_NONE) { wpa_s->pairwise_cipher = WPA_CIPHER_NONE; wpa_msg(wpa_s, MSG_DEBUG, "WPA: using PTK NONE"); } else { wpa_printf(MSG_WARNING, "WPA: Failed to select pairwise " "cipher."); return -1; } sel = ie.key_mgmt & ssid->key_mgmt; if (sel & WPA_KEY_MGMT_IEEE8021X) { wpa_s->key_mgmt = WPA_KEY_MGMT_IEEE8021X; wpa_msg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT 802.1X"); } else if (sel & WPA_KEY_MGMT_PSK) { wpa_s->key_mgmt = WPA_KEY_MGMT_PSK; wpa_msg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT WPA-PSK"); } else if (sel & WPA_KEY_MGMT_WPA_NONE) { wpa_s->key_mgmt = WPA_KEY_MGMT_WPA_NONE; wpa_msg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT WPA-NONE"); } else { wpa_printf(MSG_WARNING, "WPA: Failed to select authenticated " "key management type."); return -1; } wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_KEY_MGMT, wpa_s->key_mgmt); wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_PAIRWISE, wpa_s->pairwise_cipher); wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_GROUP, wpa_s->group_cipher);#ifdef CONFIG_IEEE80211W sel = ie.mgmt_group_cipher; if (ssid->ieee80211w == NO_IEEE80211W || !(ie.capabilities & WPA_CAPABILITY_MGMT_FRAME_PROTECTION)) sel = 0; if (sel & WPA_CIPHER_AES_128_CMAC) { wpa_s->mgmt_group_cipher = WPA_CIPHER_AES_128_CMAC; wpa_msg(wpa_s, MSG_DEBUG, "WPA: using MGMT group cipher " "AES-128-CMAC"); } else { wpa_s->mgmt_group_cipher = 0; wpa_msg(wpa_s, MSG_DEBUG, "WPA: not using MGMT group cipher"); } wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_MGMT_GROUP, wpa_s->mgmt_group_cipher);#endif /* CONFIG_IEEE80211W */ if (wpa_sm_set_assoc_wpa_ie_default(wpa_s->wpa, wpa_ie, wpa_ie_len)) { wpa_printf(MSG_WARNING, "WPA: Failed to generate WPA IE."); return -1; } if (ssid->key_mgmt & WPA_KEY_MGMT_PSK) wpa_sm_set_pmk(wpa_s->wpa, ssid->psk, PMK_LEN); else wpa_sm_set_pmk_from_pmksa(wpa_s->wpa); return 0;}/** * wpa_supplicant_associate - Request association * @wpa_s: Pointer to wpa_supplicant data * @bss: Scan results for the selected BSS, or %NULL if not available * @ssid: Configuration data for the selected network * * This function is used to request %wpa_supplicant to associate with a BSS. */void wpa_supplicant_associate(struct wpa_supplicant *wpa_s, struct wpa_scan_result *bss, struct wpa_ssid *ssid){ u8 wpa_ie[80]; size_t wpa_ie_len; int use_crypt, ret, i; int algs = AUTH_ALG_OPEN_SYSTEM; wpa_cipher cipher_pairwise, cipher_group; struct wpa_driver_associate_params params; int wep_keys_set = 0; struct wpa_driver_capa capa; int assoc_failed = 0; wpa_s->reassociate = 0; if (bss) { wpa_msg(wpa_s, MSG_INFO, "Trying to associate with " MACSTR " (SSID='%s' freq=%d MHz)", MAC2STR(bss->bssid), wpa_ssid_txt(bss->ssid, bss->ssid_len), bss->freq); os_memset(wpa_s->bssid, 0, ETH_ALEN); os_memcpy(wpa_s->pending_bssid, bss->bssid, ETH_ALEN); } else {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -