📄 wpa.c
字号:
static void wpa_group_setkeys(struct wpa_authenticator *wpa_auth, struct wpa_group *group){ int tmp; wpa_printf(MSG_DEBUG, "WPA: group state machine entering state " "SETKEYS (VLAN-ID %d)", group->vlan_id); group->changed = TRUE; group->wpa_group_state = WPA_GROUP_SETKEYS; group->GTKReKey = FALSE; tmp = group->GM; group->GM = group->GN; group->GN = tmp;#ifdef CONFIG_IEEE80211W tmp = group->GM_igtk; group->GM_igtk = group->GN_igtk; group->GN_igtk = tmp;#endif /* CONFIG_IEEE80211W */ /* "GKeyDoneStations = GNoStations" is done in more robust way by * counting the STAs that are marked with GUpdateStationKeys instead of * including all STAs that could be in not-yet-completed state. */ wpa_gtk_update(wpa_auth, group); wpa_auth_for_each_sta(wpa_auth, wpa_group_update_sta, NULL); wpa_printf(MSG_DEBUG, "wpa_group_setkeys: GKeyDoneStations=%d", group->GKeyDoneStations);}static void wpa_group_setkeysdone(struct wpa_authenticator *wpa_auth, struct wpa_group *group){ wpa_printf(MSG_DEBUG, "WPA: group state machine entering state " "SETKEYSDONE (VLAN-ID %d)", group->vlan_id); group->changed = TRUE; group->wpa_group_state = WPA_GROUP_SETKEYSDONE; wpa_auth_set_key(wpa_auth, group->vlan_id, wpa_alg_txt(wpa_auth->conf.wpa_group), NULL, group->GN, group->GTK[group->GN - 1], group->GTK_len);#ifdef CONFIG_IEEE80211W if (wpa_auth->conf.ieee80211w != WPA_NO_IEEE80211W) { wpa_auth_set_key(wpa_auth, group->vlan_id, "IGTK", NULL, group->GN_igtk, group->IGTK[group->GN_igtk - 4], WPA_IGTK_LEN); }#endif /* CONFIG_IEEE80211W */}static void wpa_group_sm_step(struct wpa_authenticator *wpa_auth, struct wpa_group *group){ if (group->GInit) { wpa_group_gtk_init(wpa_auth, group); } else if (group->wpa_group_state == WPA_GROUP_GTK_INIT && group->GTKAuthenticator) { wpa_group_setkeysdone(wpa_auth, group); } else if (group->wpa_group_state == WPA_GROUP_SETKEYSDONE && group->GTKReKey) { wpa_group_setkeys(wpa_auth, group); } else if (group->wpa_group_state == WPA_GROUP_SETKEYS) { if (group->GKeyDoneStations == 0) wpa_group_setkeysdone(wpa_auth, group); else if (group->GTKReKey) wpa_group_setkeys(wpa_auth, group); }}static void wpa_sm_step(struct wpa_state_machine *sm){ if (sm == NULL) return; if (sm->in_step_loop) { /* This should not happen, but if it does, make sure we do not * end up freeing the state machine too early by exiting the * recursive call. */ wpa_printf(MSG_ERROR, "WPA: wpa_sm_step() called recursively"); return; } sm->in_step_loop = 1; do { if (sm->pending_deinit) break; sm->changed = FALSE; sm->wpa_auth->group->changed = FALSE; SM_STEP_RUN(WPA_PTK); if (sm->pending_deinit) break; SM_STEP_RUN(WPA_PTK_GROUP); if (sm->pending_deinit) break; wpa_group_sm_step(sm->wpa_auth, sm->group); } while (sm->changed || sm->wpa_auth->group->changed); sm->in_step_loop = 0; if (sm->pending_deinit) { wpa_printf(MSG_DEBUG, "WPA: Completing pending STA state " "machine deinit for " MACSTR, MAC2STR(sm->addr)); wpa_free_sta_sm(sm); }}static void wpa_sm_call_step(void *eloop_ctx, void *timeout_ctx){ struct wpa_state_machine *sm = eloop_ctx; wpa_sm_step(sm);}void wpa_auth_sm_notify(struct wpa_state_machine *sm){ if (sm == NULL) return; eloop_register_timeout(0, 0, wpa_sm_call_step, sm, NULL);}void wpa_gtk_rekey(struct wpa_authenticator *wpa_auth){ int tmp, i; struct wpa_group *group; if (wpa_auth == NULL) return; group = wpa_auth->group; for (i = 0; i < 2; i++) { tmp = group->GM; group->GM = group->GN; group->GN = tmp;#ifdef CONFIG_IEEE80211W tmp = group->GM_igtk; group->GM_igtk = group->GN_igtk; group->GN_igtk = tmp;#endif /* CONFIG_IEEE80211W */ wpa_gtk_update(wpa_auth, group); }}static const char * wpa_bool_txt(int bool){ return bool ? "TRUE" : "FALSE";}static int wpa_cipher_bits(int cipher){ switch (cipher) { case WPA_CIPHER_CCMP: return 128; case WPA_CIPHER_TKIP: return 256; case WPA_CIPHER_WEP104: return 104; case WPA_CIPHER_WEP40: return 40; default: return 0; }}#define RSN_SUITE "%02x-%02x-%02x-%d"#define RSN_SUITE_ARG(s) \((s) >> 24) & 0xff, ((s) >> 16) & 0xff, ((s) >> 8) & 0xff, (s) & 0xffint wpa_get_mib(struct wpa_authenticator *wpa_auth, char *buf, size_t buflen){ int len = 0, ret; char pmkid_txt[PMKID_LEN * 2 + 1]; if (wpa_auth == NULL) return len; ret = os_snprintf(buf + len, buflen - len, "dot11RSNAOptionImplemented=TRUE\n"#ifdef CONFIG_RSN_PREAUTH "dot11RSNAPreauthenticationImplemented=TRUE\n"#else /* CONFIG_RSN_PREAUTH */ "dot11RSNAPreauthenticationImplemented=FALSE\n"#endif /* CONFIG_RSN_PREAUTH */ "dot11RSNAEnabled=%s\n" "dot11RSNAPreauthenticationEnabled=%s\n", wpa_bool_txt(wpa_auth->conf.wpa & WPA_PROTO_RSN), wpa_bool_txt(wpa_auth->conf.rsn_preauth)); if (ret < 0 || (size_t) ret >= buflen - len) return len; len += ret; wpa_snprintf_hex(pmkid_txt, sizeof(pmkid_txt), wpa_auth->dot11RSNAPMKIDUsed, PMKID_LEN); ret = os_snprintf( buf + len, buflen - len, "dot11RSNAConfigVersion=%u\n" "dot11RSNAConfigPairwiseKeysSupported=9999\n" /* FIX: dot11RSNAConfigGroupCipher */ /* FIX: dot11RSNAConfigGroupRekeyMethod */ /* FIX: dot11RSNAConfigGroupRekeyTime */ /* FIX: dot11RSNAConfigGroupRekeyPackets */ "dot11RSNAConfigGroupRekeyStrict=%u\n" "dot11RSNAConfigGroupUpdateCount=%u\n" "dot11RSNAConfigPairwiseUpdateCount=%u\n" "dot11RSNAConfigGroupCipherSize=%u\n" "dot11RSNAConfigPMKLifetime=%u\n" "dot11RSNAConfigPMKReauthThreshold=%u\n" "dot11RSNAConfigNumberOfPTKSAReplayCounters=0\n" "dot11RSNAConfigSATimeout=%u\n" "dot11RSNAAuthenticationSuiteSelected=" RSN_SUITE "\n" "dot11RSNAPairwiseCipherSelected=" RSN_SUITE "\n" "dot11RSNAGroupCipherSelected=" RSN_SUITE "\n" "dot11RSNAPMKIDUsed=%s\n" "dot11RSNAAuthenticationSuiteRequested=" RSN_SUITE "\n" "dot11RSNAPairwiseCipherRequested=" RSN_SUITE "\n" "dot11RSNAGroupCipherRequested=" RSN_SUITE "\n" "dot11RSNATKIPCounterMeasuresInvoked=%u\n" "dot11RSNA4WayHandshakeFailures=%u\n" "dot11RSNAConfigNumberOfGTKSAReplayCounters=0\n", RSN_VERSION, !!wpa_auth->conf.wpa_strict_rekey, dot11RSNAConfigGroupUpdateCount, dot11RSNAConfigPairwiseUpdateCount, wpa_cipher_bits(wpa_auth->conf.wpa_group), dot11RSNAConfigPMKLifetime, dot11RSNAConfigPMKReauthThreshold, dot11RSNAConfigSATimeout, RSN_SUITE_ARG(wpa_auth->dot11RSNAAuthenticationSuiteSelected), RSN_SUITE_ARG(wpa_auth->dot11RSNAPairwiseCipherSelected), RSN_SUITE_ARG(wpa_auth->dot11RSNAGroupCipherSelected), pmkid_txt, RSN_SUITE_ARG(wpa_auth->dot11RSNAAuthenticationSuiteRequested), RSN_SUITE_ARG(wpa_auth->dot11RSNAPairwiseCipherRequested), RSN_SUITE_ARG(wpa_auth->dot11RSNAGroupCipherRequested), wpa_auth->dot11RSNATKIPCounterMeasuresInvoked, wpa_auth->dot11RSNA4WayHandshakeFailures); if (ret < 0 || (size_t) ret >= buflen - len) return len; len += ret; /* TODO: dot11RSNAConfigPairwiseCiphersTable */ /* TODO: dot11RSNAConfigAuthenticationSuitesTable */ /* Private MIB */ ret = os_snprintf(buf + len, buflen - len, "hostapdWPAGroupState=%d\n", wpa_auth->group->wpa_group_state); if (ret < 0 || (size_t) ret >= buflen - len) return len; len += ret; return len;}int wpa_get_mib_sta(struct wpa_state_machine *sm, char *buf, size_t buflen){ int len = 0, ret; u32 pairwise = 0; if (sm == NULL) return 0; /* TODO: FF-FF-FF-FF-FF-FF entry for broadcast/multicast stats */ /* dot11RSNAStatsEntry */ if (sm->wpa == WPA_VERSION_WPA) { if (sm->pairwise == WPA_CIPHER_CCMP) pairwise = WPA_CIPHER_SUITE_CCMP; else if (sm->pairwise == WPA_CIPHER_TKIP) pairwise = WPA_CIPHER_SUITE_TKIP; else if (sm->pairwise == WPA_CIPHER_WEP104) pairwise = WPA_CIPHER_SUITE_WEP104; else if (sm->pairwise == WPA_CIPHER_WEP40) pairwise = WPA_CIPHER_SUITE_WEP40; else if (sm->pairwise == WPA_CIPHER_NONE) pairwise = WPA_CIPHER_SUITE_NONE; } else if (sm->wpa == WPA_VERSION_WPA2) { if (sm->pairwise == WPA_CIPHER_CCMP) pairwise = RSN_CIPHER_SUITE_CCMP; else if (sm->pairwise == WPA_CIPHER_TKIP) pairwise = RSN_CIPHER_SUITE_TKIP; else if (sm->pairwise == WPA_CIPHER_WEP104) pairwise = RSN_CIPHER_SUITE_WEP104; else if (sm->pairwise == WPA_CIPHER_WEP40) pairwise = RSN_CIPHER_SUITE_WEP40; else if (sm->pairwise == WPA_CIPHER_NONE) pairwise = RSN_CIPHER_SUITE_NONE; } else return 0; ret = os_snprintf( buf + len, buflen - len, /* TODO: dot11RSNAStatsIndex */ "dot11RSNAStatsSTAAddress=" MACSTR "\n" "dot11RSNAStatsVersion=1\n" "dot11RSNAStatsSelectedPairwiseCipher=" RSN_SUITE "\n" /* TODO: dot11RSNAStatsTKIPICVErrors */ "dot11RSNAStatsTKIPLocalMICFailures=%u\n" "dot11RSNAStatsTKIPRemoveMICFailures=%u\n" /* TODO: dot11RSNAStatsCCMPReplays */ /* TODO: dot11RSNAStatsCCMPDecryptErrors */ /* TODO: dot11RSNAStatsTKIPReplays */, MAC2STR(sm->addr), RSN_SUITE_ARG(pairwise), sm->dot11RSNAStatsTKIPLocalMICFailures, sm->dot11RSNAStatsTKIPRemoteMICFailures); if (ret < 0 || (size_t) ret >= buflen - len) return len; len += ret; /* Private MIB */ ret = os_snprintf(buf + len, buflen - len, "hostapdWPAPTKState=%d\n" "hostapdWPAPTKGroupState=%d\n", sm->wpa_ptk_state, sm->wpa_ptk_group_state); if (ret < 0 || (size_t) ret >= buflen - len) return len; len += ret; return len;}void wpa_auth_countermeasures_start(struct wpa_authenticator *wpa_auth){ if (wpa_auth) wpa_auth->dot11RSNATKIPCounterMeasuresInvoked++;}int wpa_auth_pairwise_set(struct wpa_state_machine *sm){ return sm && sm->pairwise_set;}int wpa_auth_get_pairwise(struct wpa_state_machine *sm){ return sm->pairwise;}int wpa_auth_sta_key_mgmt(struct wpa_state_machine *sm){ if (sm == NULL) return -1; return sm->wpa_key_mgmt;}int wpa_auth_sta_wpa_version(struct wpa_state_machine *sm){ if (sm == NULL) return 0; return sm->wpa;}int wpa_auth_sta_clear_pmksa(struct wpa_state_machine *sm, struct rsn_pmksa_cache_entry *entry){ if (sm == NULL || sm->pmksa != entry) return -1; sm->pmksa = NULL; return 0;}struct rsn_pmksa_cache_entry *wpa_auth_sta_get_pmksa(struct wpa_state_machine *sm){ return sm ? sm->pmksa : NULL;}void wpa_auth_sta_local_mic_failure_report(struct wpa_state_machine *sm){ if (sm) sm->dot11RSNAStatsTKIPLocalMICFailures++;}const u8 * wpa_auth_get_wpa_ie(struct wpa_authenticator *wpa_auth, size_t *len){ if (wpa_auth == NULL) return NULL; *len = wpa_auth->wpa_ie_len; return wpa_auth->wpa_ie;}int wpa_auth_pmksa_add(struct wpa_state_machine *sm, const u8 *pmk, int session_timeout, struct eapol_state_machine *eapol){ if (sm == NULL || sm->wpa != WPA_VERSION_WPA2) return -1; if (pmksa_cache_add(sm->wpa_auth->pmksa, pmk, PMK_LEN, sm->wpa_auth->addr, sm->addr, session_timeout, eapol, sm->wpa_key_mgmt)) return 0; return -1;}int wpa_auth_pmksa_add_preauth(struct wpa_authenticator *wpa_auth, const u8 *pmk, size_t len, const u8 *sta_addr, int session_timeout, struct eapol_state_machine *eapol){ if (wpa_auth == NULL) return -1; if (pmksa_cache_add(wpa_auth->pmksa, pmk, len, wpa_auth->addr, sta_addr, session_timeout, eapol, WPA_KEY_MGMT_IEEE8021X)) return 0; return -1;}static struct wpa_group *wpa_auth_add_group(struct wpa_authenticator *wpa_auth, int vlan_id){ struct wpa_group *group; if (wpa_auth == NULL || wpa_auth->group == NULL) return NULL; wpa_printf(MSG_DEBUG, "WPA: Add group state machine for VLAN-ID %d", vlan_id); group = wpa_group_init(wpa_auth, vlan_id); if (group == NULL) return NULL; group->next = wpa_auth->group->next; wpa_auth->group->next = group; return group;}int wpa_auth_sta_set_vlan(struct wpa_state_machine *sm, int vlan_id){ struct wpa_group *group; if (sm == NULL || sm->wpa_auth == NULL) return 0; group = sm->wpa_auth->group; while (group) { if (group->vlan_id == vlan_id) break; group = group->next; } if (group == NULL) { group = wpa_auth_add_group(sm->wpa_auth, vlan_id); if (group == NULL) return -1; } if (sm->group == group) return 0; wpa_printf(MSG_DEBUG, "WPA: Moving STA " MACSTR " to use group state " "machine for VLAN ID %d", MAC2STR(sm->addr), vlan_id); sm->group = group; return 0;}#endif /* CONFIG_NATIVE_WINDOWS */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -