📄 wpa_supplicant.c
字号:
wpa_msg(wpa_s, MSG_DEBUG, "Reconfiguration completed"); return 0;}#ifndef CONFIG_NATIVE_WINDOWSstatic 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(); } }}#endif /* CONFIG_NATIVE_WINDOWS */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"); 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; if (wpa_s->disconnected) 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_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) 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_drv_scan(wpa_s, ssid ? ssid->ssid : NULL, ssid ? ssid->ssid_len : 0)) { 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; } 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) { memset(&ie, 0, sizeof(ie)); ie.group_cipher = ssid->group_cipher; ie.pairwise_cipher = ssid->pairwise_cipher; ie.key_mgmt = ssid->key_mgmt; wpa_printf(MSG_DEBUG, "WPA: Set cipher suites based " "on configuration"); } } wpa_printf(MSG_DEBUG, "WPA: Selected cipher suites: group %d " "pairwise %d key_mgmt %d", ie.group_cipher, ie.pairwise_cipher, ie.key_mgmt); 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); 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; int algs = AUTH_ALG_OPEN_SYSTEM; int 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); memset(wpa_s->bssid, 0, ETH_ALEN); } else { wpa_msg(wpa_s, MSG_INFO, "Trying to associate with SSID '%s'", wpa_ssid_txt(ssid->ssid, ssid->ssid_len)); } wpa_supplicant_cancel_scan(wpa_s); /* Starting new association, so clear the possibly used WPA IE from the * previous association. */ wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, NULL, 0); if (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA) { if (ssid->leap) { if (ssid->non_leap == 0) algs = AUTH_ALG_LEAP; else algs |= AUTH_ALG_LEAP; } } wpa_printf(MSG_DEBUG, "Automatic auth_alg selection: 0x%x", algs); if (ssid->auth_alg) { algs = 0; if (ssid->auth_alg & WPA_AUTH_ALG_OPEN) algs |= AUTH_ALG_OPEN_SYSTEM; if (ssid->auth_alg & WPA_AUTH_ALG_SHARED) algs |= AUTH_ALG_SHARED_KEY; if (ssid->auth_alg & WPA_AUTH_ALG_LEAP) algs |= AUTH_ALG_LEAP; wpa_printf(MSG_DEBUG, "Overriding auth_alg selection: 0x%x", algs); } wpa_drv_set_auth_alg(wpa_s, algs); if (bss && (bss->wpa_ie_len || bss->rsn_ie_len) && (ssid->key_mgmt & (WPA_KEY_MGMT_IEEE8021X | WPA_KEY_MGMT_PSK))) { int try_opportunistic; try_opportunistic = ssid->proactive_key_caching && (ssid->proto & WPA_PROTO_RSN); if (pmksa_cache_set_current(wpa_s->wpa, NULL, bss->bssid, wpa_s->current_ssid, try_opportunistic) == 0) eapol_sm_notify_pmkid_attempt(wpa_s->eapol, 1); wpa_ie_len = sizeof(wpa_ie); if (wpa_supplicant_set_suites(wpa_s, bss, ssid, wpa_ie, &wpa_ie_len)) { wpa_printf(MSG_WARNING, "WPA: Failed to set WPA key " "management and encryption suites"); return; } } else if (ssid->key_mgmt & (WPA_KEY_MGMT_PSK | WPA_KEY_MGMT_IEEE8021X | WPA_KEY_MGMT_WPA_NONE)) { wpa_ie_len = sizeof(wpa_ie); if (wpa_supplicant_set_suites(wpa_s, NULL, ssid, wpa_ie, &wpa_ie_len)) { wpa_printf(MSG_WARNING, "WPA: Failed to set WPA key " "management and encryption suites (no scan " "results)"); return; } } else { wpa_supplicant_set_non_wpa_policy(wpa_s, ssid); wpa_ie_len = 0; } wpa_clear_keys(wpa_s, bss ? bss->bssid : NULL); use_crypt = 1; cipher_pairwise = cipher_suite2driver(wpa_s->pairwise_cipher); cipher_group = cipher_suite2driver(wpa_s->group_cipher); if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE || wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) { int i; if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE) use_crypt = 0; for (i = 0; i < NUM_WEP_KEYS; i++) { if (ssid->wep_key_len[i]) { use_crypt = 1; wep_keys_set = 1; wpa_set_wep_key(wpa_s, i == ssid->wep_tx_keyidx, i, ssid->wep_key[i], ssid->wep_key_len[i]); } } } if (wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) { if ((ssid->eapol_flags & (EAPOL_FLAG_REQUIRE_KEY_UNICAST | EAPOL_FLAG_REQUIRE_KEY_BROADCAST)) == 0 && !wep_keys_set) { use_crypt = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -