📄 ieee802_11.c
字号:
" auth_alg=%d auth_transaction=%d resp=%d (IE len=%lu)", MAC2STR(dst), auth_alg, auth_transaction, resp, (unsigned long) ies_len); if (hostapd_send_mgmt_frame(hapd, reply, rlen, 0) < 0) perror("send_auth_reply: send"); os_free(buf);}#ifdef CONFIG_IEEE80211Rstatic void handle_auth_ft_finish(void *ctx, const u8 *dst, const u8 *bssid, u16 auth_transaction, u16 status, const u8 *ies, size_t ies_len){ struct hostapd_data *hapd = ctx; struct sta_info *sta; send_auth_reply(hapd, dst, bssid, WLAN_AUTH_FT, auth_transaction, status, ies, ies_len); if (status != WLAN_STATUS_SUCCESS) return; sta = ap_get_sta(hapd, dst); if (sta == NULL) return; hostapd_logger(hapd, dst, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_DEBUG, "authentication OK (FT)"); sta->flags |= WLAN_STA_AUTH; mlme_authenticate_indication(hapd, sta);}#endif /* CONFIG_IEEE80211R */static void handle_auth(struct hostapd_data *hapd, struct ieee80211_mgmt *mgmt, size_t len){ u16 auth_alg, auth_transaction, status_code; u16 resp = WLAN_STATUS_SUCCESS; struct sta_info *sta = NULL; int res; u16 fc; u8 *challenge = NULL; u32 session_timeout, acct_interim_interval; int vlan_id = 0; u8 resp_ies[2 + WLAN_AUTH_CHALLENGE_LEN]; size_t resp_ies_len = 0; if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.auth)) { printf("handle_auth - too short payload (len=%lu)\n", (unsigned long) len); return; } auth_alg = le_to_host16(mgmt->u.auth.auth_alg); auth_transaction = le_to_host16(mgmt->u.auth.auth_transaction); status_code = le_to_host16(mgmt->u.auth.status_code); fc = le_to_host16(mgmt->frame_control); if (len >= IEEE80211_HDRLEN + sizeof(mgmt->u.auth) + 2 + WLAN_AUTH_CHALLENGE_LEN && mgmt->u.auth.variable[0] == WLAN_EID_CHALLENGE && mgmt->u.auth.variable[1] == WLAN_AUTH_CHALLENGE_LEN) challenge = &mgmt->u.auth.variable[2]; wpa_printf(MSG_DEBUG, "authentication: STA=" MACSTR " auth_alg=%d " "auth_transaction=%d status_code=%d wep=%d%s", MAC2STR(mgmt->sa), auth_alg, auth_transaction, status_code, !!(fc & WLAN_FC_ISWEP), challenge ? " challenge" : ""); if (hapd->tkip_countermeasures) { resp = WLAN_REASON_MICHAEL_MIC_FAILURE; goto fail; } if (!(((hapd->conf->auth_algs & WPA_AUTH_ALG_OPEN) && auth_alg == WLAN_AUTH_OPEN) ||#ifdef CONFIG_IEEE80211R (hapd->conf->wpa && (hapd->conf->wpa_key_mgmt & (WPA_KEY_MGMT_FT_IEEE8021X | WPA_KEY_MGMT_FT_PSK)) && auth_alg == WLAN_AUTH_FT) ||#endif /* CONFIG_IEEE80211R */ ((hapd->conf->auth_algs & WPA_AUTH_ALG_SHARED) && auth_alg == WLAN_AUTH_SHARED_KEY))) { printf("Unsupported authentication algorithm (%d)\n", auth_alg); resp = WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG; goto fail; } if (!(auth_transaction == 1 || (auth_alg == WLAN_AUTH_SHARED_KEY && auth_transaction == 3))) { printf("Unknown authentication transaction number (%d)\n", auth_transaction); resp = WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION; goto fail; } if (os_memcmp(mgmt->sa, hapd->own_addr, ETH_ALEN) == 0) { printf("Station " MACSTR " not allowed to authenticate.\n", MAC2STR(mgmt->sa)); resp = WLAN_STATUS_UNSPECIFIED_FAILURE; goto fail; } res = hostapd_allowed_address(hapd, mgmt->sa, (u8 *) mgmt, len, &session_timeout, &acct_interim_interval, &vlan_id); if (res == HOSTAPD_ACL_REJECT) { printf("Station " MACSTR " not allowed to authenticate.\n", MAC2STR(mgmt->sa)); resp = WLAN_STATUS_UNSPECIFIED_FAILURE; goto fail; } if (res == HOSTAPD_ACL_PENDING) { wpa_printf(MSG_DEBUG, "Authentication frame from " MACSTR " waiting for an external authentication", MAC2STR(mgmt->sa)); /* Authentication code will re-send the authentication frame * after it has received (and cached) information from the * external source. */ return; } sta = ap_sta_add(hapd, mgmt->sa); if (!sta) { resp = WLAN_STATUS_UNSPECIFIED_FAILURE; goto fail; } if (vlan_id > 0) { if (hostapd_get_vlan_id_ifname(hapd->conf->vlan, sta->vlan_id) == NULL) { hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_RADIUS, HOSTAPD_LEVEL_INFO, "Invalid VLAN ID " "%d received from RADIUS server", vlan_id); resp = WLAN_STATUS_UNSPECIFIED_FAILURE; goto fail; } sta->vlan_id = vlan_id; hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_RADIUS, HOSTAPD_LEVEL_INFO, "VLAN ID %d", sta->vlan_id); } sta->flags &= ~WLAN_STA_PREAUTH; ieee802_1x_notify_pre_auth(sta->eapol_sm, 0); if (hapd->conf->radius->acct_interim_interval == 0 && acct_interim_interval) sta->acct_interim_interval = acct_interim_interval; if (res == HOSTAPD_ACL_ACCEPT_TIMEOUT) ap_sta_session_timeout(hapd, sta, session_timeout); else ap_sta_no_session_timeout(hapd, sta); switch (auth_alg) { case WLAN_AUTH_OPEN: hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_DEBUG, "authentication OK (open system)");#ifdef IEEE80211_REQUIRE_AUTH_ACK /* Station will be marked authenticated if it ACKs the * authentication reply. */#else sta->flags |= WLAN_STA_AUTH; wpa_auth_sm_event(sta->wpa_sm, WPA_AUTH); sta->auth_alg = WLAN_AUTH_OPEN; mlme_authenticate_indication(hapd, sta);#endif break; case WLAN_AUTH_SHARED_KEY: resp = auth_shared_key(hapd, sta, auth_transaction, challenge, fc & WLAN_FC_ISWEP); sta->auth_alg = WLAN_AUTH_SHARED_KEY; mlme_authenticate_indication(hapd, sta); if (sta->challenge && auth_transaction == 1) { resp_ies[0] = WLAN_EID_CHALLENGE; resp_ies[1] = WLAN_AUTH_CHALLENGE_LEN; os_memcpy(resp_ies + 2, sta->challenge, WLAN_AUTH_CHALLENGE_LEN); resp_ies_len = 2 + WLAN_AUTH_CHALLENGE_LEN; } break;#ifdef CONFIG_IEEE80211R case WLAN_AUTH_FT: sta->auth_alg = WLAN_AUTH_FT; if (sta->wpa_sm == NULL) sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth, sta->addr); if (sta->wpa_sm == NULL) { wpa_printf(MSG_DEBUG, "FT: Failed to initialize WPA " "state machine"); resp = WLAN_STATUS_UNSPECIFIED_FAILURE; goto fail; } wpa_ft_process_auth(sta->wpa_sm, mgmt->bssid, auth_transaction, mgmt->u.auth.variable, len - IEEE80211_HDRLEN - sizeof(mgmt->u.auth), handle_auth_ft_finish, hapd); /* handle_auth_ft_finish() callback will complete auth. */ return;#endif /* CONFIG_IEEE80211R */ } fail: send_auth_reply(hapd, mgmt->sa, mgmt->bssid, auth_alg, auth_transaction + 1, resp, resp_ies, resp_ies_len);}static void handle_assoc(struct hostapd_data *hapd, struct ieee80211_mgmt *mgmt, size_t len, int reassoc){ u16 capab_info, listen_interval; u16 resp = WLAN_STATUS_SUCCESS; u8 *pos, *wpa_ie; size_t wpa_ie_len; int send_deauth = 0, send_len, left, i; struct sta_info *sta; struct ieee802_11_elems elems; u8 buf[sizeof(struct ieee80211_mgmt) + 512]; struct ieee80211_mgmt *reply; if (len < IEEE80211_HDRLEN + (reassoc ? sizeof(mgmt->u.reassoc_req) : sizeof(mgmt->u.assoc_req))) { printf("handle_assoc(reassoc=%d) - too short payload (len=%lu)" "\n", reassoc, (unsigned long) len); return; } if (reassoc) { capab_info = le_to_host16(mgmt->u.reassoc_req.capab_info); listen_interval = le_to_host16( mgmt->u.reassoc_req.listen_interval); wpa_printf(MSG_DEBUG, "reassociation request: STA=" MACSTR " capab_info=0x%02x listen_interval=%d current_ap=" MACSTR, MAC2STR(mgmt->sa), capab_info, listen_interval, MAC2STR(mgmt->u.reassoc_req.current_ap)); left = len - (IEEE80211_HDRLEN + sizeof(mgmt->u.reassoc_req)); pos = mgmt->u.reassoc_req.variable; } else { capab_info = le_to_host16(mgmt->u.assoc_req.capab_info); listen_interval = le_to_host16( mgmt->u.assoc_req.listen_interval); wpa_printf(MSG_DEBUG, "association request: STA=" MACSTR " capab_info=0x%02x listen_interval=%d", MAC2STR(mgmt->sa), capab_info, listen_interval); left = len - (IEEE80211_HDRLEN + sizeof(mgmt->u.assoc_req)); pos = mgmt->u.assoc_req.variable; } sta = ap_get_sta(hapd, mgmt->sa);#ifdef CONFIG_IEEE80211R if (sta && sta->auth_alg == WLAN_AUTH_FT && (sta->flags & WLAN_STA_AUTH) == 0) { wpa_printf(MSG_DEBUG, "FT: Allow STA " MACSTR " to associate " "prior to authentication since it is using " "over-the-DS FT", MAC2STR(mgmt->sa)); } else#endif /* CONFIG_IEEE80211R */ if (sta == NULL || (sta->flags & WLAN_STA_AUTH) == 0) { printf("STA " MACSTR " trying to associate before " "authentication\n", MAC2STR(mgmt->sa)); if (sta) { printf(" sta: addr=" MACSTR " aid=%d flags=0x%04x\n", MAC2STR(sta->addr), sta->aid, sta->flags); } send_deauth = 1; resp = WLAN_STATUS_UNSPECIFIED_FAILURE; goto fail; } if (hapd->tkip_countermeasures) { resp = WLAN_REASON_MICHAEL_MIC_FAILURE; goto fail; } if (listen_interval > hapd->conf->max_listen_interval) { hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_DEBUG, "Too large Listen Interval (%d)", listen_interval); resp = WLAN_STATUS_ASSOC_DENIED_LISTEN_INT_TOO_LARGE; goto fail; } sta->capability = capab_info; sta->listen_interval = listen_interval; /* followed by SSID and Supported rates; and HT capabilities if 802.11n * is used */ if (ieee802_11_parse_elems(pos, left, &elems, 1) == ParseFailed || !elems.ssid) { printf("STA " MACSTR " sent invalid association request\n", MAC2STR(sta->addr)); resp = WLAN_STATUS_UNSPECIFIED_FAILURE; goto fail; } if (elems.ssid_len != hapd->conf->ssid.ssid_len || os_memcmp(elems.ssid, hapd->conf->ssid.ssid, elems.ssid_len) != 0) { char ssid_txt[33]; ieee802_11_print_ssid(ssid_txt, elems.ssid, elems.ssid_len); printf("Station " MACSTR " tried to associate with " "unknown SSID '%s'\n", MAC2STR(sta->addr), ssid_txt); resp = WLAN_STATUS_UNSPECIFIED_FAILURE; goto fail; } sta->flags &= ~WLAN_STA_WME; if (elems.wme && hapd->conf->wme_enabled) { if (hostapd_eid_wme_valid(hapd, elems.wme, elems.wme_len)) hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_WPA, HOSTAPD_LEVEL_DEBUG, "invalid WME element in association " "request"); else sta->flags |= WLAN_STA_WME; } if (!elems.supp_rates) { hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_DEBUG, "No supported rates element in AssocReq"); resp = WLAN_STATUS_UNSPECIFIED_FAILURE; goto fail; } if (elems.supp_rates_len > sizeof(sta->supported_rates)) { hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_DEBUG, "Invalid supported rates element length %d", elems.supp_rates_len); resp = WLAN_STATUS_UNSPECIFIED_FAILURE; goto fail; } os_memset(sta->supported_rates, 0, sizeof(sta->supported_rates)); os_memcpy(sta->supported_rates, elems.supp_rates, elems.supp_rates_len); sta->supported_rates_len = elems.supp_rates_len; if (elems.ext_supp_rates) { if (elems.supp_rates_len + elems.ext_supp_rates_len > sizeof(sta->supported_rates)) { hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_DEBUG, "Invalid supported rates element length" " %d+%d", elems.supp_rates_len, elems.ext_supp_rates_len); resp = WLAN_STATUS_UNSPECIFIED_FAILURE; goto fail; } os_memcpy(sta->supported_rates + elems.supp_rates_len, elems.ext_supp_rates, elems.ext_supp_rates_len); sta->supported_rates_len += elems.ext_supp_rates_len; }#ifdef CONFIG_IEEE80211N /* save HT capabilities in the sta object */ os_memset(&sta->ht_capabilities, 0, sizeof(sta->ht_capabilities)); if (elems.ht_capabilities && elems.ht_capabilities_len >= sizeof(struct ieee80211_ht_capability)) { sta->flags |= WLAN_STA_HT; sta->ht_capabilities.id = WLAN_EID_HT_CAP; sta->ht_capabilities.length = sizeof(struct ieee80211_ht_capability); os_memcpy(&sta->ht_capabilities.data, elems.ht_capabilities, sizeof(struct ieee80211_ht_capability)); } else sta->flags &= ~WLAN_STA_HT;#endif /* CONFIG_IEEE80211N */ if ((hapd->conf->wpa & WPA_PROTO_RSN) && elems.rsn_ie) { wpa_ie = elems.rsn_ie; wpa_ie_len = elems.rsn_ie_len; } else if ((hapd->conf->wpa & WPA_PROTO_WPA) && elems.wpa_ie) { wpa_ie = elems.wpa_ie; wpa_ie_len = elems.wpa_ie_len; } else { wpa_ie = NULL; wpa_ie_len = 0; }#ifdef CONFIG_WPS sta->flags &= ~(WLAN_STA_WPS | WLAN_STA_MAYBE_WPS); if (hapd->conf->wps_state && wpa_ie == NULL) { if (elems.wps_ie) { wpa_printf(MSG_DEBUG, "STA included WPS IE in " "(Re)Association Request - assume WPS is " "used"); sta->flags |= WLAN_STA_WPS; wpabuf_free(sta->wps_ie); sta->wps_ie = wpabuf_alloc_copy(elems.wps_ie + 4, elems.wps_ie_len - 4); } else { wpa_printf(MSG_DEBUG, "STA did not include WPA/RSN IE " "in (Re)Association Request - possible WPS " "use"); sta->flags |= WLAN_STA_MAYBE_WPS; } } else#endif /* CONFIG_WPS */ if (hapd->conf->wpa && wpa_ie == NULL) { printf("STA " MACSTR ": No WPA/RSN IE in association " "request\n", MAC2STR(sta->addr)); resp = WLAN_STATUS_INVALID_IE; goto fail; } if (hapd->conf->wpa && wpa_ie) { int res; wpa_ie -= 2; wpa_ie_len += 2; if (sta->wpa_sm == NULL) sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth, sta->addr); if (sta->wpa_sm == NULL) { printf("Failed to initialize WPA state machine\n"); resp = WLAN_STATUS_UNSPECIFIED_FAILURE; goto fail; } res = wpa_validate_wpa_ie(hapd->wpa_auth, sta->wpa_sm, wpa_ie, wpa_ie_len, elems.mdie, elems.mdie_len); if (res == WPA_INVALID_GROUP) resp = WLAN_STATUS_GROUP_CIPHER_NOT_VALID; else if (res == WPA_INVALID_PAIRWISE) resp = WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID; else if (res == WPA_INVALID_AKMP) resp = WLAN_STATUS_AKMP_NOT_VALID; else if (res == WPA_ALLOC_FAIL) resp = WLAN_STATUS_UNSPECIFIED_FAILURE;#ifdef CONFIG_IEEE80211W else if (res == WPA_MGMT_FRAME_PROTECTION_VIOLATION) resp = WLAN_STATUS_ROBUST_MGMT_FRAME_POLICY_VIOLATION; else if (res == WPA_INVALID_MGMT_GROUP_CIPHER) resp = WLAN_STATUS_ROBUST_MGMT_FRAME_POLICY_VIOLATION;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -