📄 wpa.c
字号:
l2_packet_set_rx_l2_hdr(piface->l2, 1); piface->next = hapd->preauth_iface; hapd->preauth_iface = piface; return 0;fail2: free(piface->ifname);fail1: free(piface); return -1;}static void rsn_preauth_iface_deinit(struct hostapd_data *hapd){ struct rsn_preauth_interface *piface, *prev; piface = hapd->preauth_iface; hapd->preauth_iface = NULL; while (piface) { prev = piface; piface = piface->next; l2_packet_deinit(prev->l2); free(prev->ifname); free(prev); }}static int rsn_preauth_iface_init(struct hostapd_data *hapd){ char *tmp, *start, *end; if (hapd->conf->rsn_preauth_interfaces == NULL) return 0; tmp = strdup(hapd->conf->rsn_preauth_interfaces); if (tmp == NULL) return -1; start = tmp; for (;;) { while (*start == ' ') start++; if (*start == '\0') break; end = strchr(start, ' '); if (end) *end = '\0'; if (rsn_preauth_iface_add(hapd, start)) { rsn_preauth_iface_deinit(hapd); return -1; } if (end) start = end + 1; else break; } free(tmp); return 0;}void rsn_preauth_finished(struct hostapd_data *hapd, struct sta_info *sta, int success){ u8 *key; size_t len; hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_WPA, HOSTAPD_LEVEL_INFO, "pre-authentication %s", success ? "succeeded" : "failed"); key = ieee802_1x_get_key_crypt(sta->eapol_sm, &len); if (success && key) { pmksa_cache_add(hapd, sta, key, dot11RSNAConfigPMKLifetime); } ap_free_sta(hapd, sta);}void rsn_preauth_send(struct hostapd_data *hapd, struct sta_info *sta, u8 *buf, size_t len){ struct rsn_preauth_interface *piface; struct l2_ethhdr *ethhdr; piface = hapd->preauth_iface; while (piface) { if (piface == sta->preauth_iface) break; piface = piface->next; } if (piface == NULL) { HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, "RSN: Could not find " "pre-authentication interface for " MACSTR "\n", MAC2STR(sta->addr)); return; } ethhdr = malloc(sizeof(*ethhdr) + len); if (ethhdr == NULL) return; memcpy(ethhdr->h_dest, sta->addr, ETH_ALEN); memcpy(ethhdr->h_source, hapd->own_addr, ETH_ALEN); ethhdr->h_proto = htons(ETH_P_PREAUTH); memcpy(ethhdr + 1, buf, len); if (l2_packet_send(piface->l2, (u8 *) ethhdr, sizeof(*ethhdr) + len) < 0) { printf("Failed to send preauth packet using l2_packet_send\n"); } free(ethhdr);}#else /* CONFIG_RSN_PREAUTH */static inline int rsn_preauth_iface_init(struct hostapd_data *hapd){ return 0;}static inline void rsn_preauth_iface_deinit(struct hostapd_data *hapd){}void rsn_preauth_finished(struct hostapd_data *hapd, struct sta_info *sta, int success){}void rsn_preauth_send(struct hostapd_data *hapd, struct sta_info *sta, u8 *buf, size_t len){}#endif /* CONFIG_RSN_PREAUTH */int wpa_init(struct hostapd_data *hapd){ u8 rkey[32]; u8 buf[ETH_ALEN + 8]; if (rsn_preauth_iface_init(hapd)) return -1; if (hostapd_set_privacy(hapd, 1)) { printf("Could not set PrivacyInvoked for interface %s\n", hapd->conf->iface); return -1; } if (wpa_gen_wpa_ie(hapd)) { printf("Could not generate WPA IE.\n"); return -1; } if (hostapd_set_generic_elem(hapd, hapd->wpa_ie, hapd->wpa_ie_len)) { printf("Failed to configure WPA IE for the kernel driver.\n"); return -1; } hapd->wpa_auth = malloc(sizeof(struct wpa_authenticator)); if (hapd->wpa_auth == NULL) return -1; memset(hapd->wpa_auth, 0, sizeof(struct wpa_authenticator)); hapd->wpa_auth->GTKAuthenticator = TRUE; switch (hapd->conf->wpa_group) { case WPA_CIPHER_CCMP: hapd->wpa_auth->GTK_len = 16; break; case WPA_CIPHER_TKIP: hapd->wpa_auth->GTK_len = 32; break; case WPA_CIPHER_WEP104: hapd->wpa_auth->GTK_len = 13; break; case WPA_CIPHER_WEP40: hapd->wpa_auth->GTK_len = 5; break; } /* Counter = PRF-256(Random number, "Init Counter", * Local MAC Address || Time) */ memcpy(buf, hapd->own_addr, ETH_ALEN); hostapd_get_ntp_timestamp(buf + ETH_ALEN); if (hostapd_get_rand(rkey, sizeof(rkey)) || hostapd_get_rand(hapd->wpa_auth->GMK, WPA_GMK_LEN)) { printf("Failed to get random data for WPA initialization.\n"); free(hapd->wpa_auth); hapd->wpa_auth = NULL; return -1; } sha1_prf(rkey, sizeof(rkey), "Init Counter", buf, sizeof(buf), hapd->wpa_auth->Counter, WPA_NONCE_LEN); if (hapd->conf->wpa_gmk_rekey) { eloop_register_timeout(hapd->conf->wpa_gmk_rekey, 0, wpa_rekey_gmk, hapd, NULL); } if (hapd->conf->wpa_group_rekey) { eloop_register_timeout(hapd->conf->wpa_group_rekey, 0, wpa_rekey_gtk, hapd, NULL); } hapd->wpa_auth->GInit = TRUE; wpa_group_sm_step(hapd); hapd->wpa_auth->GInit = FALSE; wpa_group_sm_step(hapd); return 0;}void wpa_deinit(struct hostapd_data *hapd){ rsn_preauth_iface_deinit(hapd); eloop_cancel_timeout(wpa_rekey_gmk, hapd, NULL); eloop_cancel_timeout(wpa_rekey_gtk, hapd, NULL); if (hostapd_set_privacy(hapd, 0)) { printf("Could not disable PrivacyInvoked for interface %s\n", hapd->conf->iface); } if (hostapd_set_generic_elem(hapd, (u8 *) "", 0)) { printf("Could not remove generic information element from " "interface %s\n", hapd->conf->iface); } free(hapd->wpa_ie); hapd->wpa_ie = NULL; free(hapd->wpa_auth); hapd->wpa_auth = NULL; pmksa_cache_free(hapd);}static int wpa_selector_to_bitfield(u8 *s){ if (memcmp(s, WPA_CIPHER_SUITE_NONE, WPA_SELECTOR_LEN) == 0) return WPA_CIPHER_NONE; if (memcmp(s, WPA_CIPHER_SUITE_WEP40, WPA_SELECTOR_LEN) == 0) return WPA_CIPHER_WEP40; if (memcmp(s, WPA_CIPHER_SUITE_TKIP, WPA_SELECTOR_LEN) == 0) return WPA_CIPHER_TKIP; if (memcmp(s, WPA_CIPHER_SUITE_CCMP, WPA_SELECTOR_LEN) == 0) return WPA_CIPHER_CCMP; if (memcmp(s, WPA_CIPHER_SUITE_WEP104, WPA_SELECTOR_LEN) == 0) return WPA_CIPHER_WEP104; return 0;}static int wpa_key_mgmt_to_bitfield(u8 *s){ if (memcmp(s, WPA_AUTH_KEY_MGMT_UNSPEC_802_1X, WPA_SELECTOR_LEN) == 0) return WPA_KEY_MGMT_IEEE8021X; if (memcmp(s, WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X, WPA_SELECTOR_LEN) == 0) return WPA_KEY_MGMT_PSK; return 0;}static int rsn_selector_to_bitfield(u8 *s){ if (memcmp(s, RSN_CIPHER_SUITE_NONE, RSN_SELECTOR_LEN) == 0) return WPA_CIPHER_NONE; if (memcmp(s, RSN_CIPHER_SUITE_WEP40, RSN_SELECTOR_LEN) == 0) return WPA_CIPHER_WEP40; if (memcmp(s, RSN_CIPHER_SUITE_TKIP, RSN_SELECTOR_LEN) == 0) return WPA_CIPHER_TKIP; if (memcmp(s, RSN_CIPHER_SUITE_CCMP, RSN_SELECTOR_LEN) == 0) return WPA_CIPHER_CCMP; if (memcmp(s, RSN_CIPHER_SUITE_WEP104, RSN_SELECTOR_LEN) == 0) return WPA_CIPHER_WEP104; return 0;}static int rsn_key_mgmt_to_bitfield(u8 *s){ if (memcmp(s, RSN_AUTH_KEY_MGMT_UNSPEC_802_1X, RSN_SELECTOR_LEN) == 0) return WPA_KEY_MGMT_IEEE8021X; if (memcmp(s, RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X, RSN_SELECTOR_LEN) == 0) return WPA_KEY_MGMT_PSK; return 0;}static void rsn_pmkid(const u8 *pmk, const u8 *aa, const u8 *spa, u8 *pmkid){ char *title = "PMK Name"; const u8 *addr[3]; const size_t len[3] = { 8, ETH_ALEN, ETH_ALEN }; unsigned char hash[SHA1_MAC_LEN]; addr[0] = (u8 *) title; addr[1] = aa; addr[2] = spa; hmac_sha1_vector(pmk, PMK_LEN, 3, addr, len, hash); memcpy(pmkid, hash, PMKID_LEN);}static void pmksa_cache_set_expiration(struct hostapd_data *hapd);static void pmksa_cache_free_entry(struct hostapd_data *hapd, struct rsn_pmksa_cache *entry){ struct sta_info *sta; struct rsn_pmksa_cache *pos, *prev; hapd->pmksa_count--; for (sta = hapd->sta_list; sta != NULL; sta = sta->next) { if (sta->pmksa == entry) sta->pmksa = NULL; } pos = hapd->pmkid[PMKID_HASH(entry->pmkid)]; prev = NULL; while (pos) { if (pos == entry) { if (prev != NULL) { prev->hnext = pos->hnext; } else { hapd->pmkid[PMKID_HASH(entry->pmkid)] = pos->hnext; } break; } prev = pos; pos = pos->hnext; } pos = hapd->pmksa; prev = NULL; while (pos) { if (pos == entry) { if (prev != NULL) prev->next = pos->next; else hapd->pmksa = pos->next; break; } prev = pos; pos = pos->next; } free(entry);}static void pmksa_cache_expire(void *eloop_ctx, void *timeout_ctx){ struct hostapd_data *hapd = eloop_ctx; time_t now; time(&now); while (hapd->pmksa && hapd->pmksa->expiration <= now) { struct rsn_pmksa_cache *entry = hapd->pmksa; hapd->pmksa = entry->next; HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, "RSN: expired PMKSA cache entry for " MACSTR, MAC2STR(entry->spa)); pmksa_cache_free_entry(hapd, entry); } pmksa_cache_set_expiration(hapd);}static void pmksa_cache_set_expiration(struct hostapd_data *hapd){ int sec; eloop_cancel_timeout(pmksa_cache_expire, hapd, NULL); if (hapd->pmksa == NULL) return; sec = hapd->pmksa->expiration - time(NULL); if (sec < 0) sec = 0; eloop_register_timeout(sec + 1, 0, pmksa_cache_expire, hapd, NULL);}void pmksa_cache_add(struct hostapd_data *hapd, struct sta_info *sta, u8 *pmk, int session_timeout){ struct rsn_pmksa_cache *entry, *pos, *prev; if (sta->wpa != WPA_VERSION_WPA2) return; entry = malloc(sizeof(*entry)); if (entry == NULL) return; memset(entry, 0, sizeof(*entry)); memcpy(entry->pmk, pmk, PMK_LEN); rsn_pmkid(pmk, hapd->own_addr, sta->addr, entry->pmkid); time(&entry->expiration); if (session_timeout > 0) entry->expiration += session_timeout; else entry->expiration += dot11RSNAConfigPMKLifetime; entry->akmp = WPA_KEY_MGMT_IEEE8021X; memcpy(entry->spa, sta->addr, ETH_ALEN); /* Replace an old entry for the same STA (if found) with the new entry */ pos = pmksa_cache_get(hapd, sta->addr, NULL); if (pos) pmksa_cache_free_entry(hapd, pos); if (hapd->pmksa_count >= pmksa_cache_max_entries && hapd->pmksa) { /* Remove the oldest entry to make room for the new entry */ HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, "RSN: removed the oldest PMKSA cache entry (for " MACSTR ") to make room for new one", MAC2STR(hapd->pmksa->spa)); pmksa_cache_free_entry(hapd, hapd->pmksa); } /* Add the new entry; order by expiration time */ pos = hapd->pmksa; prev = NULL; while (pos) { if (pos->expiration > entry->expiration) break; prev = pos; pos = pos->next; } if (prev == NULL) { entry->next = hapd->pmksa; hapd->pmksa = entry; } else { entry->next = prev->next; prev->next = entry; } entry->hnext = hapd->pmkid[PMKID_HASH(entry->pmkid)]; hapd->pmkid[PMKID_HASH(entry->pmkid)] = entry; hapd->pmksa_count++; hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_WPA, HOSTAPD_LEVEL_DEBUG, "added PMKSA cache entry"); if (HOSTAPD_DEBUG_COND(HOSTAPD_DEBUG_MINIMAL)) { hostapd_hexdump("RSN: added PMKID", entry->pmkid, PMKID_LEN); }}static void pmksa_cache_free(struct hostapd_data *hapd){ struct rsn_pmksa_cache *entry, *prev; int i; struct sta_info *sta; entry = hapd->pmksa; hapd->pmksa = NULL; while (entry) { prev = entry; entry = entry->next; free(prev); } eloop_cancel_timeout(pmksa_cache_expire, hapd, NULL); for (i = 0; i < PMKID_HASH_SIZE; i++) hapd->pmkid[i] = NULL; for (sta = hapd->sta_list; sta; sta = sta->next) sta->pmksa = NULL;}static struct rsn_pmksa_cache * pmksa_cache_get(struct hostapd_data *hapd, u8 *spa, u8 *pmkid){ struct rsn_pmksa_cache *entry;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -