📄 wpa.c
字号:
}/** * wpa_sm_notify_assoc - Notify WPA state machine about association * @sm: Pointer to WPA state machine data from wpa_sm_init() * @bssid: The BSSID of the new association * * This function is called to let WPA state machine know that the connection * was established. */void wpa_sm_notify_assoc(struct wpa_sm *sm, const u8 *bssid){ int clear_ptk = 1; if (sm == NULL) return; wpa_printf(MSG_DEBUG, "WPA: Association event - clear replay counter"); os_memcpy(sm->bssid, bssid, ETH_ALEN); os_memset(sm->rx_replay_counter, 0, WPA_REPLAY_COUNTER_LEN); sm->rx_replay_counter_set = 0; sm->renew_snonce = 1; if (os_memcmp(sm->preauth_bssid, bssid, ETH_ALEN) == 0) rsn_preauth_deinit(sm);#ifdef CONFIG_IEEE80211R if (wpa_ft_is_completed(sm)) { wpa_supplicant_key_neg_complete(sm, sm->bssid, 1); /* Prepare for the next transition */ wpa_ft_prepare_auth_request(sm); clear_ptk = 0; }#endif /* CONFIG_IEEE80211R */ if (clear_ptk) { /* * IEEE 802.11, 8.4.10: Delete PTK SA on (re)association if * this is not part of a Fast BSS Transition. */ wpa_printf(MSG_DEBUG, "WPA: Clear old PTK"); sm->ptk_set = 0; sm->tptk_set = 0; }}/** * wpa_sm_notify_disassoc - Notify WPA state machine about disassociation * @sm: Pointer to WPA state machine data from wpa_sm_init() * * This function is called to let WPA state machine know that the connection * was lost. This will abort any existing pre-authentication session. */void wpa_sm_notify_disassoc(struct wpa_sm *sm){ rsn_preauth_deinit(sm); if (wpa_sm_get_state(sm) == WPA_4WAY_HANDSHAKE) sm->dot11RSNA4WayHandshakeFailures++;}/** * wpa_sm_set_pmk - Set PMK * @sm: Pointer to WPA state machine data from wpa_sm_init() * @pmk: The new PMK * @pmk_len: The length of the new PMK in bytes * * Configure the PMK for WPA state machine. */void wpa_sm_set_pmk(struct wpa_sm *sm, const u8 *pmk, size_t pmk_len){ if (sm == NULL) return; sm->pmk_len = pmk_len; os_memcpy(sm->pmk, pmk, pmk_len);#ifdef CONFIG_IEEE80211R /* Set XXKey to be PSK for FT key derivation */ sm->xxkey_len = pmk_len; os_memcpy(sm->xxkey, pmk, pmk_len);#endif /* CONFIG_IEEE80211R */}/** * wpa_sm_set_pmk_from_pmksa - Set PMK based on the current PMKSA * @sm: Pointer to WPA state machine data from wpa_sm_init() * * Take the PMK from the current PMKSA into use. If no PMKSA is active, the PMK * will be cleared. */void wpa_sm_set_pmk_from_pmksa(struct wpa_sm *sm){ if (sm == NULL) return; if (sm->cur_pmksa) { sm->pmk_len = sm->cur_pmksa->pmk_len; os_memcpy(sm->pmk, sm->cur_pmksa->pmk, sm->pmk_len); } else { sm->pmk_len = PMK_LEN; os_memset(sm->pmk, 0, PMK_LEN); }}/** * wpa_sm_set_fast_reauth - Set fast reauthentication (EAP) enabled/disabled * @sm: Pointer to WPA state machine data from wpa_sm_init() * @fast_reauth: Whether fast reauthentication (EAP) is allowed */void wpa_sm_set_fast_reauth(struct wpa_sm *sm, int fast_reauth){ if (sm) sm->fast_reauth = fast_reauth;}/** * wpa_sm_set_scard_ctx - Set context pointer for smartcard callbacks * @sm: Pointer to WPA state machine data from wpa_sm_init() * @scard_ctx: Context pointer for smartcard related callback functions */void wpa_sm_set_scard_ctx(struct wpa_sm *sm, void *scard_ctx){ if (sm == NULL) return; sm->scard_ctx = scard_ctx; if (sm->preauth_eapol) eapol_sm_register_scard_ctx(sm->preauth_eapol, scard_ctx);}/** * wpa_sm_set_config - Notification of current configration change * @sm: Pointer to WPA state machine data from wpa_sm_init() * @config: Pointer to current network configuration * * Notify WPA state machine that configuration has changed. config will be * stored as a backpointer to network configuration. This can be %NULL to clear * the stored pointed. */void wpa_sm_set_config(struct wpa_sm *sm, struct rsn_supp_config *config){ if (!sm) return; if (config) { sm->network_ctx = config->network_ctx; sm->peerkey_enabled = config->peerkey_enabled; sm->allowed_pairwise_cipher = config->allowed_pairwise_cipher; sm->proactive_key_caching = config->proactive_key_caching; sm->eap_workaround = config->eap_workaround; sm->eap_conf_ctx = config->eap_conf_ctx; if (config->ssid) { os_memcpy(sm->ssid, config->ssid, config->ssid_len); sm->ssid_len = config->ssid_len; } else sm->ssid_len = 0; sm->wpa_ptk_rekey = config->wpa_ptk_rekey; } else { sm->network_ctx = NULL; sm->peerkey_enabled = 0; sm->allowed_pairwise_cipher = 0; sm->proactive_key_caching = 0; sm->eap_workaround = 0; sm->eap_conf_ctx = NULL; sm->ssid_len = 0; sm->wpa_ptk_rekey = 0; } if (config == NULL || config->network_ctx != sm->network_ctx) pmksa_cache_notify_reconfig(sm->pmksa);}/** * wpa_sm_set_own_addr - Set own MAC address * @sm: Pointer to WPA state machine data from wpa_sm_init() * @addr: Own MAC address */void wpa_sm_set_own_addr(struct wpa_sm *sm, const u8 *addr){ if (sm) os_memcpy(sm->own_addr, addr, ETH_ALEN);}/** * wpa_sm_set_ifname - Set network interface name * @sm: Pointer to WPA state machine data from wpa_sm_init() * @ifname: Interface name * @bridge_ifname: Optional bridge interface name (for pre-auth) */void wpa_sm_set_ifname(struct wpa_sm *sm, const char *ifname, const char *bridge_ifname){ if (sm) { sm->ifname = ifname; sm->bridge_ifname = bridge_ifname; }}/** * wpa_sm_set_eapol - Set EAPOL state machine pointer * @sm: Pointer to WPA state machine data from wpa_sm_init() * @eapol: Pointer to EAPOL state machine allocated with eapol_sm_init() */void wpa_sm_set_eapol(struct wpa_sm *sm, struct eapol_sm *eapol){ if (sm) sm->eapol = eapol;}/** * wpa_sm_set_param - Set WPA state machine parameters * @sm: Pointer to WPA state machine data from wpa_sm_init() * @param: Parameter field * @value: Parameter value * Returns: 0 on success, -1 on failure */int wpa_sm_set_param(struct wpa_sm *sm, enum wpa_sm_conf_params param, unsigned int value){ int ret = 0; if (sm == NULL) return -1; switch (param) { case RSNA_PMK_LIFETIME: if (value > 0) sm->dot11RSNAConfigPMKLifetime = value; else ret = -1; break; case RSNA_PMK_REAUTH_THRESHOLD: if (value > 0 && value <= 100) sm->dot11RSNAConfigPMKReauthThreshold = value; else ret = -1; break; case RSNA_SA_TIMEOUT: if (value > 0) sm->dot11RSNAConfigSATimeout = value; else ret = -1; break; case WPA_PARAM_PROTO: sm->proto = value; break; case WPA_PARAM_PAIRWISE: sm->pairwise_cipher = value; break; case WPA_PARAM_GROUP: sm->group_cipher = value; break; case WPA_PARAM_KEY_MGMT: sm->key_mgmt = value; break;#ifdef CONFIG_IEEE80211W case WPA_PARAM_MGMT_GROUP: sm->mgmt_group_cipher = value; break;#endif /* CONFIG_IEEE80211W */ case WPA_PARAM_RSN_ENABLED: sm->rsn_enabled = value; break; default: break; } return ret;}/** * wpa_sm_get_param - Get WPA state machine parameters * @sm: Pointer to WPA state machine data from wpa_sm_init() * @param: Parameter field * Returns: Parameter value */unsigned int wpa_sm_get_param(struct wpa_sm *sm, enum wpa_sm_conf_params param){ if (sm == NULL) return 0; switch (param) { case RSNA_PMK_LIFETIME: return sm->dot11RSNAConfigPMKLifetime; case RSNA_PMK_REAUTH_THRESHOLD: return sm->dot11RSNAConfigPMKReauthThreshold; case RSNA_SA_TIMEOUT: return sm->dot11RSNAConfigSATimeout; case WPA_PARAM_PROTO: return sm->proto; case WPA_PARAM_PAIRWISE: return sm->pairwise_cipher; case WPA_PARAM_GROUP: return sm->group_cipher; case WPA_PARAM_KEY_MGMT: return sm->key_mgmt;#ifdef CONFIG_IEEE80211W case WPA_PARAM_MGMT_GROUP: return sm->mgmt_group_cipher;#endif /* CONFIG_IEEE80211W */ case WPA_PARAM_RSN_ENABLED: return sm->rsn_enabled; default: return 0; }}/** * wpa_sm_get_status - Get WPA state machine * @sm: Pointer to WPA state machine data from wpa_sm_init() * @buf: Buffer for status information * @buflen: Maximum buffer length * @verbose: Whether to include verbose status information * Returns: Number of bytes written to buf. * * Query WPA state machine for status information. This function fills in * a text area with current status information. If the buffer (buf) is not * large enough, status information will be truncated to fit the buffer. */int wpa_sm_get_status(struct wpa_sm *sm, char *buf, size_t buflen, int verbose){ char *pos = buf, *end = buf + buflen; int ret; ret = os_snprintf(pos, end - pos, "pairwise_cipher=%s\n" "group_cipher=%s\n" "key_mgmt=%s\n", wpa_cipher_txt(sm->pairwise_cipher), wpa_cipher_txt(sm->group_cipher), wpa_key_mgmt_txt(sm->key_mgmt, sm->proto)); if (ret < 0 || ret >= end - pos) return pos - buf; pos += ret; return pos - buf;}/** * wpa_sm_set_assoc_wpa_ie_default - Generate own WPA/RSN IE from configuration * @sm: Pointer to WPA state machine data from wpa_sm_init() * @wpa_ie: Pointer to buffer for WPA/RSN IE * @wpa_ie_len: Pointer to the length of the wpa_ie buffer * Returns: 0 on success, -1 on failure */int wpa_sm_set_assoc_wpa_ie_default(struct wpa_sm *sm, u8 *wpa_ie, size_t *wpa_ie_len){ int res; if (sm == NULL) return -1; res = wpa_gen_wpa_ie(sm, wpa_ie, *wpa_ie_len); if (res < 0) return -1; *wpa_ie_len = res; wpa_hexdump(MSG_DEBUG, "WPA: Set own WPA IE default", wpa_ie, *wpa_ie_len); if (sm->assoc_wpa_ie == NULL) { /* * Make a copy of the WPA/RSN IE so that 4-Way Handshake gets * the correct version of the IE even if PMKSA caching is * aborted (which would remove PMKID from IE generation). */ sm->assoc_wpa_ie = os_malloc(*wpa_ie_len); if (sm->assoc_wpa_ie == NULL) return -1; os_memcpy(sm->assoc_wpa_ie, wpa_ie, *wpa_ie_len); sm->assoc_wpa_ie_len = *wpa_ie_len; } return 0;}/** * wpa_sm_set_assoc_wpa_ie - Set own WPA/RSN IE from (Re)AssocReq * @sm: Pointer to WPA state machine data from wpa_sm_init() * @ie: Pointer to IE data (starting from id) * @len: IE length * Returns: 0 on success, -1 on failure * * Inform WPA state machine about the WPA/RSN IE used in (Re)Association * Request frame. The IE will be used to override the default value generated * with wpa_sm_set_assoc_wpa_ie_default(). */int wpa_sm_set_assoc_wpa_ie(struct wpa_sm *sm, const u8 *ie, size_t len){ if (sm == NULL) return -1; os_free(sm->assoc_wpa_ie); if (ie == NULL || len == 0) { wpa_printf(MSG_DEBUG, "WPA: clearing own WPA/RSN IE"); sm->assoc_wpa_ie = NULL; sm->assoc_wpa_ie_len = 0; } else { wpa_hexdump(MSG_DEBUG, "WPA: set own WPA/RSN IE", ie, len); sm->assoc_wpa_ie = os_malloc(len); if (sm->assoc_wpa_ie == NULL) return -1; os_memcpy(sm->assoc_wpa_ie, ie, len); sm->assoc_wpa_ie_len = len; } return 0;}/** * wpa_sm_set_ap_wpa_ie - Set AP WPA IE from Beacon/ProbeResp * @sm: Pointer to WPA state machine data from wpa_sm_init() * @ie: Pointer to IE data (starting from id) * @len: IE length * Returns: 0 on success, -1 on failure * * Inform WPA state machine about the WPA IE used in Beacon / Probe Response * frame. */int wpa_sm_set_ap_wpa_ie(struct wpa_sm *sm, const u8 *ie, size_t len){ if (sm == NULL) return -1; os_free(sm->ap_wpa_ie); if (ie == NULL || len == 0) { wpa_printf(MSG_DEBUG, "WPA: clearing AP WPA IE"); sm->ap_wpa_ie = NULL; sm->ap_wpa_ie_len = 0; } else { wpa_hexdump(MSG_DEBUG, "WPA: set AP WPA IE", ie, len); sm->ap_wpa_ie = os_malloc(len); if (sm->ap_wpa_ie == NULL) return -1; os_memcpy(sm->ap_wpa_ie, ie, len); sm->ap_wpa_ie_len = len; } return 0;}/** * wpa_sm_set_ap_rsn_ie - Set AP RSN IE from Beacon/ProbeResp * @sm: Pointer to WPA state machine data from wpa_sm_init() * @ie: Pointer to IE data (starti
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -