2 * hostapd / IEEE 802.11 Management
3 * Copyright (c) 2002-2017, Jouni Malinen <j@w1.fi>
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
9 #include "utils/includes.h"
11 #ifndef CONFIG_NATIVE_WINDOWS
13 #include "utils/common.h"
14 #include "utils/eloop.h"
15 #include "crypto/crypto.h"
16 #include "crypto/sha256.h"
17 #include "crypto/random.h"
18 #include "common/ieee802_11_defs.h"
19 #include "common/ieee802_11_common.h"
20 #include "common/wpa_ctrl.h"
21 #include "common/sae.h"
22 #include "radius/radius.h"
23 #include "radius/radius_client.h"
29 #include "ieee802_11_auth.h"
31 #include "ieee802_1x.h"
33 #include "pmksa_cache_auth.h"
36 #include "accounting.h"
37 #include "ap_config.h"
39 #include "p2p_hostapd.h"
40 #include "ap_drv_ops.h"
42 #include "hw_features.h"
43 #include "ieee802_11.h"
49 #include "dpp_hostapd.h"
50 #include "gas_query_ap.h"
54 static struct wpabuf
*
55 prepare_auth_resp_fils(struct hostapd_data
*hapd
,
56 struct sta_info
*sta
, u16
*resp
,
57 struct rsn_pmksa_cache_entry
*pmksa
,
58 struct wpabuf
*erp_resp
,
59 const u8
*msk
, size_t msk_len
,
61 #endif /* CONFIG_FILS */
63 u8
* hostapd_eid_supp_rates(struct hostapd_data
*hapd
, u8
*eid
)
68 if (hapd
->iface
->current_rates
== NULL
)
71 *pos
++ = WLAN_EID_SUPP_RATES
;
72 num
= hapd
->iface
->num_rates
;
73 if (hapd
->iconf
->ieee80211n
&& hapd
->iconf
->require_ht
)
75 if (hapd
->iconf
->ieee80211ac
&& hapd
->iconf
->require_vht
)
78 /* rest of the rates are encoded in Extended supported
84 for (i
= 0, count
= 0; i
< hapd
->iface
->num_rates
&& count
< num
;
87 *pos
= hapd
->iface
->current_rates
[i
].rate
/ 5;
88 if (hapd
->iface
->current_rates
[i
].flags
& HOSTAPD_RATE_BASIC
)
93 if (hapd
->iconf
->ieee80211n
&& hapd
->iconf
->require_ht
&& count
< 8) {
95 *pos
++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_HT_PHY
;
98 if (hapd
->iconf
->ieee80211ac
&& hapd
->iconf
->require_vht
&& count
< 8) {
100 *pos
++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_VHT_PHY
;
107 u8
* hostapd_eid_ext_supp_rates(struct hostapd_data
*hapd
, u8
*eid
)
112 if (hapd
->iface
->current_rates
== NULL
)
115 num
= hapd
->iface
->num_rates
;
116 if (hapd
->iconf
->ieee80211n
&& hapd
->iconf
->require_ht
)
118 if (hapd
->iconf
->ieee80211ac
&& hapd
->iconf
->require_vht
)
124 *pos
++ = WLAN_EID_EXT_SUPP_RATES
;
126 for (i
= 0, count
= 0; i
< hapd
->iface
->num_rates
&& count
< num
+ 8;
130 continue; /* already in SuppRates IE */
131 *pos
= hapd
->iface
->current_rates
[i
].rate
/ 5;
132 if (hapd
->iface
->current_rates
[i
].flags
& HOSTAPD_RATE_BASIC
)
137 if (hapd
->iconf
->ieee80211n
&& hapd
->iconf
->require_ht
) {
140 *pos
++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_HT_PHY
;
143 if (hapd
->iconf
->ieee80211ac
&& hapd
->iconf
->require_vht
) {
146 *pos
++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_VHT_PHY
;
153 u16
hostapd_own_capab_info(struct hostapd_data
*hapd
)
155 int capab
= WLAN_CAPABILITY_ESS
;
160 /* Check if any of configured channels require DFS */
161 dfs
= hostapd_is_dfs_required(hapd
->iface
);
163 wpa_printf(MSG_WARNING
, "Failed to check if DFS is required; ret=%d",
168 if (hapd
->iface
->num_sta_no_short_preamble
== 0 &&
169 hapd
->iconf
->preamble
== SHORT_PREAMBLE
)
170 capab
|= WLAN_CAPABILITY_SHORT_PREAMBLE
;
172 privacy
= hapd
->conf
->ssid
.wep
.keys_set
;
174 if (hapd
->conf
->ieee802_1x
&&
175 (hapd
->conf
->default_wep_key_len
||
176 hapd
->conf
->individual_wep_key_len
))
183 if (hapd
->conf
->osen
)
185 #endif /* CONFIG_HS20 */
188 capab
|= WLAN_CAPABILITY_PRIVACY
;
190 if (hapd
->iface
->current_mode
&&
191 hapd
->iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211G
&&
192 hapd
->iface
->num_sta_no_short_slot_time
== 0)
193 capab
|= WLAN_CAPABILITY_SHORT_SLOT_TIME
;
196 * Currently, Spectrum Management capability bit is set when directly
197 * requested in configuration by spectrum_mgmt_required or when AP is
198 * running on DFS channel.
199 * TODO: Also consider driver support for TPC to set Spectrum Mgmt bit
201 if (hapd
->iface
->current_mode
&&
202 hapd
->iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211A
&&
203 (hapd
->iconf
->spectrum_mgmt_required
|| dfs
))
204 capab
|= WLAN_CAPABILITY_SPECTRUM_MGMT
;
206 for (i
= 0; i
< RRM_CAPABILITIES_IE_LEN
; i
++) {
207 if (hapd
->conf
->radio_measurements
[i
]) {
208 capab
|= IEEE80211_CAP_RRM
;
217 #ifndef CONFIG_NO_RC4
218 static u16
auth_shared_key(struct hostapd_data
*hapd
, struct sta_info
*sta
,
219 u16 auth_transaction
, const u8
*challenge
,
222 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
224 "authentication (shared key, transaction %d)",
227 if (auth_transaction
== 1) {
228 if (!sta
->challenge
) {
229 /* Generate a pseudo-random challenge */
232 sta
->challenge
= os_zalloc(WLAN_AUTH_CHALLENGE_LEN
);
233 if (sta
->challenge
== NULL
)
234 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
236 if (os_get_random(key
, sizeof(key
)) < 0) {
237 os_free(sta
->challenge
);
238 sta
->challenge
= NULL
;
239 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
242 rc4_skip(key
, sizeof(key
), 0,
243 sta
->challenge
, WLAN_AUTH_CHALLENGE_LEN
);
248 if (auth_transaction
!= 3)
249 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
252 if (!iswep
|| !sta
->challenge
|| !challenge
||
253 os_memcmp_const(sta
->challenge
, challenge
,
254 WLAN_AUTH_CHALLENGE_LEN
)) {
255 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
257 "shared key authentication - invalid "
258 "challenge-response");
259 return WLAN_STATUS_CHALLENGE_FAIL
;
262 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
264 "authentication OK (shared key)");
265 sta
->flags
|= WLAN_STA_AUTH
;
266 wpa_auth_sm_event(sta
->wpa_sm
, WPA_AUTH
);
267 os_free(sta
->challenge
);
268 sta
->challenge
= NULL
;
272 #endif /* CONFIG_NO_RC4 */
275 static int send_auth_reply(struct hostapd_data
*hapd
,
276 const u8
*dst
, const u8
*bssid
,
277 u16 auth_alg
, u16 auth_transaction
, u16 resp
,
278 const u8
*ies
, size_t ies_len
)
280 struct ieee80211_mgmt
*reply
;
283 int reply_res
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
285 rlen
= IEEE80211_HDRLEN
+ sizeof(reply
->u
.auth
) + ies_len
;
286 buf
= os_zalloc(rlen
);
290 reply
= (struct ieee80211_mgmt
*) buf
;
291 reply
->frame_control
= IEEE80211_FC(WLAN_FC_TYPE_MGMT
,
293 os_memcpy(reply
->da
, dst
, ETH_ALEN
);
294 os_memcpy(reply
->sa
, hapd
->own_addr
, ETH_ALEN
);
295 os_memcpy(reply
->bssid
, bssid
, ETH_ALEN
);
297 reply
->u
.auth
.auth_alg
= host_to_le16(auth_alg
);
298 reply
->u
.auth
.auth_transaction
= host_to_le16(auth_transaction
);
299 reply
->u
.auth
.status_code
= host_to_le16(resp
);
302 os_memcpy(reply
->u
.auth
.variable
, ies
, ies_len
);
304 wpa_printf(MSG_DEBUG
, "authentication reply: STA=" MACSTR
305 " auth_alg=%d auth_transaction=%d resp=%d (IE len=%lu)",
306 MAC2STR(dst
), auth_alg
, auth_transaction
,
307 resp
, (unsigned long) ies_len
);
308 if (hostapd_drv_send_mlme(hapd
, reply
, rlen
, 0) < 0)
309 wpa_printf(MSG_INFO
, "send_auth_reply: send failed");
311 reply_res
= WLAN_STATUS_SUCCESS
;
319 #ifdef CONFIG_IEEE80211R_AP
320 static void handle_auth_ft_finish(void *ctx
, const u8
*dst
, const u8
*bssid
,
321 u16 auth_transaction
, u16 status
,
322 const u8
*ies
, size_t ies_len
)
324 struct hostapd_data
*hapd
= ctx
;
325 struct sta_info
*sta
;
328 reply_res
= send_auth_reply(hapd
, dst
, bssid
, WLAN_AUTH_FT
,
329 auth_transaction
, status
, ies
, ies_len
);
331 sta
= ap_get_sta(hapd
, dst
);
335 if (sta
->added_unassoc
&& (reply_res
!= WLAN_STATUS_SUCCESS
||
336 status
!= WLAN_STATUS_SUCCESS
)) {
337 hostapd_drv_sta_remove(hapd
, sta
->addr
);
338 sta
->added_unassoc
= 0;
342 if (status
!= WLAN_STATUS_SUCCESS
)
345 hostapd_logger(hapd
, dst
, HOSTAPD_MODULE_IEEE80211
,
346 HOSTAPD_LEVEL_DEBUG
, "authentication OK (FT)");
347 sta
->flags
|= WLAN_STA_AUTH
;
348 mlme_authenticate_indication(hapd
, sta
);
350 #endif /* CONFIG_IEEE80211R_AP */
355 #define dot11RSNASAESync 5 /* attempts */
358 static struct wpabuf
* auth_build_sae_commit(struct hostapd_data
*hapd
,
359 struct sta_info
*sta
, int update
)
363 if (hapd
->conf
->ssid
.wpa_passphrase
== NULL
) {
364 wpa_printf(MSG_DEBUG
, "SAE: No password available");
369 sae_prepare_commit(hapd
->own_addr
, sta
->addr
,
370 (u8
*) hapd
->conf
->ssid
.wpa_passphrase
,
371 os_strlen(hapd
->conf
->ssid
.wpa_passphrase
),
373 wpa_printf(MSG_DEBUG
, "SAE: Could not pick PWE");
377 buf
= wpabuf_alloc(SAE_COMMIT_MAX_LEN
);
380 sae_write_commit(sta
->sae
, buf
, sta
->sae
->tmp
?
381 sta
->sae
->tmp
->anti_clogging_token
: NULL
);
387 static struct wpabuf
* auth_build_sae_confirm(struct hostapd_data
*hapd
,
388 struct sta_info
*sta
)
392 buf
= wpabuf_alloc(SAE_CONFIRM_MAX_LEN
);
396 sae_write_confirm(sta
->sae
, buf
);
402 static int auth_sae_send_commit(struct hostapd_data
*hapd
,
403 struct sta_info
*sta
,
404 const u8
*bssid
, int update
)
409 data
= auth_build_sae_commit(hapd
, sta
, update
);
411 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
413 reply_res
= send_auth_reply(hapd
, sta
->addr
, bssid
, WLAN_AUTH_SAE
, 1,
414 WLAN_STATUS_SUCCESS
, wpabuf_head(data
),
423 static int auth_sae_send_confirm(struct hostapd_data
*hapd
,
424 struct sta_info
*sta
,
430 data
= auth_build_sae_confirm(hapd
, sta
);
432 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
434 reply_res
= send_auth_reply(hapd
, sta
->addr
, bssid
, WLAN_AUTH_SAE
, 2,
435 WLAN_STATUS_SUCCESS
, wpabuf_head(data
),
444 static int use_sae_anti_clogging(struct hostapd_data
*hapd
)
446 struct sta_info
*sta
;
447 unsigned int open
= 0;
449 if (hapd
->conf
->sae_anti_clogging_threshold
== 0)
452 for (sta
= hapd
->sta_list
; sta
; sta
= sta
->next
) {
455 if (sta
->sae
->state
!= SAE_COMMITTED
&&
456 sta
->sae
->state
!= SAE_CONFIRMED
)
459 if (open
>= hapd
->conf
->sae_anti_clogging_threshold
)
467 static int check_sae_token(struct hostapd_data
*hapd
, const u8
*addr
,
468 const u8
*token
, size_t token_len
)
470 u8 mac
[SHA256_MAC_LEN
];
472 if (token_len
!= SHA256_MAC_LEN
)
474 if (hmac_sha256(hapd
->sae_token_key
, sizeof(hapd
->sae_token_key
),
475 addr
, ETH_ALEN
, mac
) < 0 ||
476 os_memcmp_const(token
, mac
, SHA256_MAC_LEN
) != 0)
483 static struct wpabuf
* auth_build_token_req(struct hostapd_data
*hapd
,
484 int group
, const u8
*addr
)
488 struct os_reltime now
;
490 os_get_reltime(&now
);
491 if (!os_reltime_initialized(&hapd
->last_sae_token_key_update
) ||
492 os_reltime_expired(&now
, &hapd
->last_sae_token_key_update
, 60)) {
493 if (random_get_bytes(hapd
->sae_token_key
,
494 sizeof(hapd
->sae_token_key
)) < 0)
496 wpa_hexdump(MSG_DEBUG
, "SAE: Updated token key",
497 hapd
->sae_token_key
, sizeof(hapd
->sae_token_key
));
498 hapd
->last_sae_token_key_update
= now
;
501 buf
= wpabuf_alloc(sizeof(le16
) + SHA256_MAC_LEN
);
505 wpabuf_put_le16(buf
, group
); /* Finite Cyclic Group */
507 token
= wpabuf_put(buf
, SHA256_MAC_LEN
);
508 hmac_sha256(hapd
->sae_token_key
, sizeof(hapd
->sae_token_key
),
509 addr
, ETH_ALEN
, token
);
515 static int sae_check_big_sync(struct sta_info
*sta
)
517 if (sta
->sae
->sync
> dot11RSNASAESync
) {
518 sta
->sae
->state
= SAE_NOTHING
;
526 static void auth_sae_retransmit_timer(void *eloop_ctx
, void *eloop_data
)
528 struct hostapd_data
*hapd
= eloop_ctx
;
529 struct sta_info
*sta
= eloop_data
;
532 if (sae_check_big_sync(sta
))
535 wpa_printf(MSG_DEBUG
, "SAE: Auth SAE retransmit timer for " MACSTR
536 " (sync=%d state=%d)",
537 MAC2STR(sta
->addr
), sta
->sae
->sync
, sta
->sae
->state
);
539 switch (sta
->sae
->state
) {
541 ret
= auth_sae_send_commit(hapd
, sta
, hapd
->own_addr
, 0);
542 eloop_register_timeout(0,
543 hapd
->dot11RSNASAERetransPeriod
* 1000,
544 auth_sae_retransmit_timer
, hapd
, sta
);
547 ret
= auth_sae_send_confirm(hapd
, sta
, hapd
->own_addr
);
548 eloop_register_timeout(0,
549 hapd
->dot11RSNASAERetransPeriod
* 1000,
550 auth_sae_retransmit_timer
, hapd
, sta
);
557 if (ret
!= WLAN_STATUS_SUCCESS
)
558 wpa_printf(MSG_INFO
, "SAE: Failed to retransmit: ret=%d", ret
);
562 void sae_clear_retransmit_timer(struct hostapd_data
*hapd
, struct sta_info
*sta
)
564 eloop_cancel_timeout(auth_sae_retransmit_timer
, hapd
, sta
);
568 static void sae_set_retransmit_timer(struct hostapd_data
*hapd
,
569 struct sta_info
*sta
)
571 if (!(hapd
->conf
->mesh
& MESH_ENABLED
))
574 eloop_cancel_timeout(auth_sae_retransmit_timer
, hapd
, sta
);
575 eloop_register_timeout(0, hapd
->dot11RSNASAERetransPeriod
* 1000,
576 auth_sae_retransmit_timer
, hapd
, sta
);
580 void sae_accept_sta(struct hostapd_data
*hapd
, struct sta_info
*sta
)
582 sta
->flags
|= WLAN_STA_AUTH
;
583 sta
->auth_alg
= WLAN_AUTH_SAE
;
584 mlme_authenticate_indication(hapd
, sta
);
585 wpa_auth_sm_event(sta
->wpa_sm
, WPA_AUTH
);
586 sta
->sae
->state
= SAE_ACCEPTED
;
587 wpa_auth_pmksa_add_sae(hapd
->wpa_auth
, sta
->addr
,
588 sta
->sae
->pmk
, sta
->sae
->pmkid
);
592 static int sae_sm_step(struct hostapd_data
*hapd
, struct sta_info
*sta
,
593 const u8
*bssid
, u8 auth_transaction
)
597 if (auth_transaction
!= 1 && auth_transaction
!= 2)
598 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
600 switch (sta
->sae
->state
) {
602 if (auth_transaction
== 1) {
603 ret
= auth_sae_send_commit(hapd
, sta
, bssid
, 1);
606 sta
->sae
->state
= SAE_COMMITTED
;
608 if (sae_process_commit(sta
->sae
) < 0)
609 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
612 * In mesh case, both Commit and Confirm can be sent
613 * immediately. In infrastructure BSS, only a single
614 * Authentication frame (Commit) is expected from the AP
615 * here and the second one (Confirm) will be sent once
616 * the STA has sent its second Authentication frame
619 if (hapd
->conf
->mesh
& MESH_ENABLED
) {
621 * Send both Commit and Confirm immediately
622 * based on SAE finite state machine
623 * Nothing -> Confirm transition.
625 ret
= auth_sae_send_confirm(hapd
, sta
, bssid
);
628 sta
->sae
->state
= SAE_CONFIRMED
;
631 * For infrastructure BSS, send only the Commit
632 * message now to get alternating sequence of
633 * Authentication frames between the AP and STA.
634 * Confirm will be sent in
635 * Committed -> Confirmed/Accepted transition
636 * when receiving Confirm from STA.
640 sae_set_retransmit_timer(hapd
, sta
);
642 hostapd_logger(hapd
, sta
->addr
,
643 HOSTAPD_MODULE_IEEE80211
,
645 "SAE confirm before commit");
649 sae_clear_retransmit_timer(hapd
, sta
);
650 if (auth_transaction
== 1) {
651 if (sae_process_commit(sta
->sae
) < 0)
652 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
654 ret
= auth_sae_send_confirm(hapd
, sta
, bssid
);
657 sta
->sae
->state
= SAE_CONFIRMED
;
659 sae_set_retransmit_timer(hapd
, sta
);
660 } else if (hapd
->conf
->mesh
& MESH_ENABLED
) {
662 * In mesh case, follow SAE finite state machine and
663 * send Commit now, if sync count allows.
665 if (sae_check_big_sync(sta
))
666 return WLAN_STATUS_SUCCESS
;
669 ret
= auth_sae_send_commit(hapd
, sta
, bssid
, 0);
673 sae_set_retransmit_timer(hapd
, sta
);
676 * For instructure BSS, send the postponed Confirm from
677 * Nothing -> Confirmed transition that was reduced to
678 * Nothing -> Committed above.
680 ret
= auth_sae_send_confirm(hapd
, sta
, bssid
);
684 sta
->sae
->state
= SAE_CONFIRMED
;
687 * Since this was triggered on Confirm RX, run another
688 * step to get to Accepted without waiting for
691 return sae_sm_step(hapd
, sta
, bssid
, auth_transaction
);
695 sae_clear_retransmit_timer(hapd
, sta
);
696 if (auth_transaction
== 1) {
697 if (sae_check_big_sync(sta
))
698 return WLAN_STATUS_SUCCESS
;
701 ret
= auth_sae_send_commit(hapd
, sta
, bssid
, 1);
705 if (sae_process_commit(sta
->sae
) < 0)
706 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
708 ret
= auth_sae_send_confirm(hapd
, sta
, bssid
);
712 sae_set_retransmit_timer(hapd
, sta
);
714 sae_accept_sta(hapd
, sta
);
718 if (auth_transaction
== 1) {
719 wpa_printf(MSG_DEBUG
, "SAE: remove the STA (" MACSTR
720 ") doing reauthentication",
722 ap_free_sta(hapd
, sta
);
723 wpa_auth_pmksa_remove(hapd
->wpa_auth
, sta
->addr
);
725 if (sae_check_big_sync(sta
))
726 return WLAN_STATUS_SUCCESS
;
729 ret
= auth_sae_send_confirm(hapd
, sta
, bssid
);
730 sae_clear_temp_data(sta
->sae
);
736 wpa_printf(MSG_ERROR
, "SAE: invalid state %d",
738 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
740 return WLAN_STATUS_SUCCESS
;
744 static void sae_pick_next_group(struct hostapd_data
*hapd
, struct sta_info
*sta
)
746 struct sae_data
*sae
= sta
->sae
;
747 int i
, *groups
= hapd
->conf
->sae_groups
;
749 if (sae
->state
!= SAE_COMMITTED
)
752 wpa_printf(MSG_DEBUG
, "SAE: Previously selected group: %d", sae
->group
);
754 for (i
= 0; groups
&& groups
[i
] > 0; i
++) {
755 if (sae
->group
== groups
[i
])
759 if (!groups
|| groups
[i
] <= 0) {
760 wpa_printf(MSG_DEBUG
,
761 "SAE: Previously selected group not found from the current configuration");
767 if (groups
[i
] <= 0) {
768 wpa_printf(MSG_DEBUG
,
769 "SAE: No alternative group enabled");
773 if (sae_set_group(sae
, groups
[i
]) < 0)
778 wpa_printf(MSG_DEBUG
, "SAE: Selected new group: %d", groups
[i
]);
782 static void handle_auth_sae(struct hostapd_data
*hapd
, struct sta_info
*sta
,
783 const struct ieee80211_mgmt
*mgmt
, size_t len
,
784 u16 auth_transaction
, u16 status_code
)
786 int resp
= WLAN_STATUS_SUCCESS
;
787 struct wpabuf
*data
= NULL
;
789 #ifdef CONFIG_TESTING_OPTIONS
790 if (hapd
->conf
->sae_reflection_attack
&& auth_transaction
== 1) {
793 wpa_printf(MSG_DEBUG
, "SAE: TESTING - reflection attack");
794 pos
= mgmt
->u
.auth
.variable
;
795 end
= ((const u8
*) mgmt
) + len
;
796 send_auth_reply(hapd
, mgmt
->sa
, mgmt
->bssid
, WLAN_AUTH_SAE
,
797 auth_transaction
, resp
, pos
, end
- pos
);
801 if (hapd
->conf
->sae_commit_override
&& auth_transaction
== 1) {
802 wpa_printf(MSG_DEBUG
, "SAE: TESTING - commit override");
803 send_auth_reply(hapd
, mgmt
->sa
, mgmt
->bssid
, WLAN_AUTH_SAE
,
804 auth_transaction
, resp
,
805 wpabuf_head(hapd
->conf
->sae_commit_override
),
806 wpabuf_len(hapd
->conf
->sae_commit_override
));
809 #endif /* CONFIG_TESTING_OPTIONS */
811 if (auth_transaction
!= 1 ||
812 status_code
!= WLAN_STATUS_SUCCESS
) {
816 sta
->sae
= os_zalloc(sizeof(*sta
->sae
));
821 sta
->sae
->state
= SAE_NOTHING
;
825 if (sta
->mesh_sae_pmksa_caching
) {
826 wpa_printf(MSG_DEBUG
,
827 "SAE: Cancel use of mesh PMKSA caching because peer starts SAE authentication");
828 wpa_auth_pmksa_remove(hapd
->wpa_auth
, sta
->addr
);
829 sta
->mesh_sae_pmksa_caching
= 0;
832 if (auth_transaction
== 1) {
833 const u8
*token
= NULL
, *pos
, *end
;
834 size_t token_len
= 0;
835 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
837 "start SAE authentication (RX commit, status=%u)",
840 if ((hapd
->conf
->mesh
& MESH_ENABLED
) &&
841 status_code
== WLAN_STATUS_ANTI_CLOGGING_TOKEN_REQ
&&
843 pos
= mgmt
->u
.auth
.variable
;
844 end
= ((const u8
*) mgmt
) + len
;
845 if (pos
+ sizeof(le16
) > end
) {
846 wpa_printf(MSG_ERROR
,
847 "SAE: Too short anti-clogging token request");
848 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
851 resp
= sae_group_allowed(sta
->sae
,
852 hapd
->conf
->sae_groups
,
854 if (resp
!= WLAN_STATUS_SUCCESS
) {
855 wpa_printf(MSG_ERROR
,
856 "SAE: Invalid group in anti-clogging token request");
861 wpabuf_free(sta
->sae
->tmp
->anti_clogging_token
);
862 sta
->sae
->tmp
->anti_clogging_token
=
863 wpabuf_alloc_copy(pos
, end
- pos
);
864 if (sta
->sae
->tmp
->anti_clogging_token
== NULL
) {
865 wpa_printf(MSG_ERROR
,
866 "SAE: Failed to alloc for anti-clogging token");
867 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
872 * IEEE Std 802.11-2012, 11.3.8.6.4: If the Status code
873 * is 76, a new Commit Message shall be constructed
874 * with the Anti-Clogging Token from the received
875 * Authentication frame, and the commit-scalar and
876 * COMMIT-ELEMENT previously sent.
878 resp
= auth_sae_send_commit(hapd
, sta
, mgmt
->bssid
, 0);
879 if (resp
!= WLAN_STATUS_SUCCESS
) {
880 wpa_printf(MSG_ERROR
,
881 "SAE: Failed to send commit message");
884 sta
->sae
->state
= SAE_COMMITTED
;
886 sae_set_retransmit_timer(hapd
, sta
);
890 if ((hapd
->conf
->mesh
& MESH_ENABLED
) &&
892 WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED
&&
894 wpa_printf(MSG_DEBUG
,
895 "SAE: Peer did not accept our SAE group");
896 sae_pick_next_group(hapd
, sta
);
900 if (status_code
!= WLAN_STATUS_SUCCESS
)
903 resp
= sae_parse_commit(sta
->sae
, mgmt
->u
.auth
.variable
,
904 ((const u8
*) mgmt
) + len
-
905 mgmt
->u
.auth
.variable
, &token
,
906 &token_len
, hapd
->conf
->sae_groups
);
907 if (resp
== SAE_SILENTLY_DISCARD
) {
908 wpa_printf(MSG_DEBUG
,
909 "SAE: Drop commit message from " MACSTR
" due to reflection attack",
913 if (token
&& check_sae_token(hapd
, sta
->addr
, token
, token_len
)
915 wpa_printf(MSG_DEBUG
, "SAE: Drop commit message with "
916 "incorrect token from " MACSTR
,
918 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
922 if (resp
!= WLAN_STATUS_SUCCESS
)
925 if (!token
&& use_sae_anti_clogging(hapd
)) {
926 wpa_printf(MSG_DEBUG
,
927 "SAE: Request anti-clogging token from "
928 MACSTR
, MAC2STR(sta
->addr
));
929 data
= auth_build_token_req(hapd
, sta
->sae
->group
,
931 resp
= WLAN_STATUS_ANTI_CLOGGING_TOKEN_REQ
;
932 if (hapd
->conf
->mesh
& MESH_ENABLED
)
933 sta
->sae
->state
= SAE_NOTHING
;
937 resp
= sae_sm_step(hapd
, sta
, mgmt
->bssid
, auth_transaction
);
938 } else if (auth_transaction
== 2) {
939 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
941 "SAE authentication (RX confirm, status=%u)",
943 if (status_code
!= WLAN_STATUS_SUCCESS
)
945 if (sta
->sae
->state
>= SAE_CONFIRMED
||
946 !(hapd
->conf
->mesh
& MESH_ENABLED
)) {
947 if (sae_check_confirm(sta
->sae
, mgmt
->u
.auth
.variable
,
948 ((u8
*) mgmt
) + len
-
949 mgmt
->u
.auth
.variable
) < 0) {
950 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
954 resp
= sae_sm_step(hapd
, sta
, mgmt
->bssid
, auth_transaction
);
956 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
958 "unexpected SAE authentication transaction %u (status=%u)",
959 auth_transaction
, status_code
);
960 if (status_code
!= WLAN_STATUS_SUCCESS
)
962 resp
= WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION
;
966 if (resp
!= WLAN_STATUS_SUCCESS
) {
967 send_auth_reply(hapd
, mgmt
->sa
, mgmt
->bssid
, WLAN_AUTH_SAE
,
968 auth_transaction
, resp
,
969 data
? wpabuf_head(data
) : (u8
*) "",
970 data
? wpabuf_len(data
) : 0);
974 if (sta
->added_unassoc
&& (resp
!= WLAN_STATUS_SUCCESS
||
975 status_code
!= WLAN_STATUS_SUCCESS
)) {
976 hostapd_drv_sta_remove(hapd
, sta
->addr
);
977 sta
->added_unassoc
= 0;
984 * auth_sae_init_committed - Send COMMIT and start SAE in committed state
985 * @hapd: BSS data for the device initiating the authentication
986 * @sta: the peer to which commit authentication frame is sent
988 * This function implements Init event handling (IEEE Std 802.11-2012,
989 * 11.3.8.6.3) in which initial COMMIT message is sent. Prior to calling, the
990 * sta->sae structure should be initialized appropriately via a call to
991 * sae_prepare_commit().
993 int auth_sae_init_committed(struct hostapd_data
*hapd
, struct sta_info
*sta
)
997 if (!sta
->sae
|| !sta
->sae
->tmp
)
1000 if (sta
->sae
->state
!= SAE_NOTHING
)
1003 ret
= auth_sae_send_commit(hapd
, sta
, hapd
->own_addr
, 0);
1007 sta
->sae
->state
= SAE_COMMITTED
;
1009 sae_set_retransmit_timer(hapd
, sta
);
1014 #endif /* CONFIG_SAE */
1017 static u16
wpa_res_to_status_code(int res
)
1019 if (res
== WPA_INVALID_GROUP
)
1020 return WLAN_STATUS_GROUP_CIPHER_NOT_VALID
;
1021 if (res
== WPA_INVALID_PAIRWISE
)
1022 return WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID
;
1023 if (res
== WPA_INVALID_AKMP
)
1024 return WLAN_STATUS_AKMP_NOT_VALID
;
1025 if (res
== WPA_ALLOC_FAIL
)
1026 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
1027 #ifdef CONFIG_IEEE80211W
1028 if (res
== WPA_MGMT_FRAME_PROTECTION_VIOLATION
)
1029 return WLAN_STATUS_ROBUST_MGMT_FRAME_POLICY_VIOLATION
;
1030 if (res
== WPA_INVALID_MGMT_GROUP_CIPHER
)
1031 return WLAN_STATUS_ROBUST_MGMT_FRAME_POLICY_VIOLATION
;
1032 #endif /* CONFIG_IEEE80211W */
1033 if (res
== WPA_INVALID_MDIE
)
1034 return WLAN_STATUS_INVALID_MDIE
;
1035 if (res
== WPA_INVALID_PMKID
)
1036 return WLAN_STATUS_INVALID_PMKID
;
1037 if (res
!= WPA_IE_OK
)
1038 return WLAN_STATUS_INVALID_IE
;
1039 return WLAN_STATUS_SUCCESS
;
1045 static void handle_auth_fils_finish(struct hostapd_data
*hapd
,
1046 struct sta_info
*sta
, u16 resp
,
1047 struct wpabuf
*data
, int pub
);
1049 void handle_auth_fils(struct hostapd_data
*hapd
, struct sta_info
*sta
,
1050 const u8
*pos
, size_t len
, u16 auth_alg
,
1051 u16 auth_transaction
, u16 status_code
,
1052 void (*cb
)(struct hostapd_data
*hapd
,
1053 struct sta_info
*sta
, u16 resp
,
1054 struct wpabuf
*data
, int pub
))
1056 u16 resp
= WLAN_STATUS_SUCCESS
;
1058 struct ieee802_11_elems elems
;
1060 struct wpa_ie_data rsn
;
1061 struct rsn_pmksa_cache_entry
*pmksa
= NULL
;
1063 if (auth_transaction
!= 1 || status_code
!= WLAN_STATUS_SUCCESS
)
1068 wpa_hexdump(MSG_DEBUG
, "FILS: Authentication frame fields",
1072 #ifdef CONFIG_FILS_SK_PFS
1073 if (auth_alg
== WLAN_AUTH_FILS_SK_PFS
) {
1078 /* Using FILS PFS */
1080 /* Finite Cyclic Group */
1081 if (end
- pos
< 2) {
1082 wpa_printf(MSG_DEBUG
,
1083 "FILS: No room for Finite Cyclic Group");
1084 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1087 group
= WPA_GET_LE16(pos
);
1089 if (group
!= hapd
->conf
->fils_dh_group
) {
1090 wpa_printf(MSG_DEBUG
,
1091 "FILS: Unsupported Finite Cyclic Group: %u (expected %u)",
1092 group
, hapd
->conf
->fils_dh_group
);
1093 resp
= WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED
;
1097 crypto_ecdh_deinit(sta
->fils_ecdh
);
1098 sta
->fils_ecdh
= crypto_ecdh_init(group
);
1099 if (!sta
->fils_ecdh
) {
1100 wpa_printf(MSG_INFO
,
1101 "FILS: Could not initialize ECDH with group %d",
1103 resp
= WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED
;
1107 pub
= crypto_ecdh_get_pubkey(sta
->fils_ecdh
, 1);
1109 wpa_printf(MSG_DEBUG
,
1110 "FILS: Failed to derive ECDH public key");
1111 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1114 elem_len
= wpabuf_len(pub
);
1118 if ((size_t) (end
- pos
) < elem_len
) {
1119 wpa_printf(MSG_DEBUG
, "FILS: No room for Element");
1120 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1124 wpabuf_free(sta
->fils_g_sta
);
1125 sta
->fils_g_sta
= wpabuf_alloc_copy(pos
, elem_len
);
1126 wpabuf_clear_free(sta
->fils_dh_ss
);
1127 sta
->fils_dh_ss
= crypto_ecdh_set_peerkey(sta
->fils_ecdh
, 1,
1129 if (!sta
->fils_dh_ss
) {
1130 wpa_printf(MSG_DEBUG
, "FILS: ECDH operation failed");
1131 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1134 wpa_hexdump_buf_key(MSG_DEBUG
, "FILS: DH_SS", sta
->fils_dh_ss
);
1137 crypto_ecdh_deinit(sta
->fils_ecdh
);
1138 sta
->fils_ecdh
= NULL
;
1139 wpabuf_clear_free(sta
->fils_dh_ss
);
1140 sta
->fils_dh_ss
= NULL
;
1142 #endif /* CONFIG_FILS_SK_PFS */
1144 wpa_hexdump(MSG_DEBUG
, "FILS: Remaining IEs", pos
, end
- pos
);
1145 if (ieee802_11_parse_elems(pos
, end
- pos
, &elems
, 1) == ParseFailed
) {
1146 wpa_printf(MSG_DEBUG
, "FILS: Could not parse elements");
1147 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1152 wpa_hexdump(MSG_DEBUG
, "FILS: RSN element",
1153 elems
.rsn_ie
, elems
.rsn_ie_len
);
1154 if (!elems
.rsn_ie
||
1155 wpa_parse_wpa_ie_rsn(elems
.rsn_ie
- 2, elems
.rsn_ie_len
+ 2,
1157 wpa_printf(MSG_DEBUG
, "FILS: No valid RSN element");
1158 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1163 sta
->wpa_sm
= wpa_auth_sta_init(hapd
->wpa_auth
, sta
->addr
,
1166 wpa_printf(MSG_DEBUG
,
1167 "FILS: Failed to initialize RSN state machine");
1168 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1172 res
= wpa_validate_wpa_ie(hapd
->wpa_auth
, sta
->wpa_sm
,
1173 elems
.rsn_ie
- 2, elems
.rsn_ie_len
+ 2,
1174 elems
.mdie
, elems
.mdie_len
, NULL
, 0);
1175 resp
= wpa_res_to_status_code(res
);
1176 if (resp
!= WLAN_STATUS_SUCCESS
)
1179 if (!elems
.fils_nonce
) {
1180 wpa_printf(MSG_DEBUG
, "FILS: No FILS Nonce field");
1181 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1184 wpa_hexdump(MSG_DEBUG
, "FILS: SNonce", elems
.fils_nonce
,
1186 os_memcpy(sta
->fils_snonce
, elems
.fils_nonce
, FILS_NONCE_LEN
);
1189 if (rsn
.pmkid
&& rsn
.num_pmkid
> 0) {
1193 wpa_hexdump(MSG_DEBUG
, "FILS: PMKID List",
1194 rsn
.pmkid
, rsn
.num_pmkid
* PMKID_LEN
);
1197 num
= rsn
.num_pmkid
;
1199 wpa_hexdump(MSG_DEBUG
, "FILS: PMKID", pmkid
, PMKID_LEN
);
1200 pmksa
= wpa_auth_pmksa_get(hapd
->wpa_auth
, sta
->addr
,
1204 pmksa
= wpa_auth_pmksa_get_fils_cache_id(hapd
->wpa_auth
,
1213 if (pmksa
&& wpa_auth_sta_key_mgmt(sta
->wpa_sm
) != pmksa
->akmp
) {
1214 wpa_printf(MSG_DEBUG
,
1215 "FILS: Matching PMKSA cache entry has different AKMP (0x%x != 0x%x) - ignore",
1216 wpa_auth_sta_key_mgmt(sta
->wpa_sm
), pmksa
->akmp
);
1220 wpa_printf(MSG_DEBUG
, "FILS: Found matching PMKSA cache entry");
1223 if (!elems
.fils_session
) {
1224 wpa_printf(MSG_DEBUG
, "FILS: No FILS Session element");
1225 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1228 wpa_hexdump(MSG_DEBUG
, "FILS: FILS Session", elems
.fils_session
,
1230 os_memcpy(sta
->fils_session
, elems
.fils_session
, FILS_SESSION_LEN
);
1232 /* FILS Wrapped Data */
1233 if (elems
.fils_wrapped_data
) {
1234 wpa_hexdump(MSG_DEBUG
, "FILS: Wrapped Data",
1235 elems
.fils_wrapped_data
,
1236 elems
.fils_wrapped_data_len
);
1238 #ifndef CONFIG_NO_RADIUS
1239 if (!sta
->eapol_sm
) {
1241 ieee802_1x_alloc_eapol_sm(hapd
, sta
);
1243 wpa_printf(MSG_DEBUG
,
1244 "FILS: Forward EAP-Initiate/Re-auth to authentication server");
1245 ieee802_1x_encapsulate_radius(
1246 hapd
, sta
, elems
.fils_wrapped_data
,
1247 elems
.fils_wrapped_data_len
);
1248 sta
->fils_pending_cb
= cb
;
1249 wpa_printf(MSG_DEBUG
,
1250 "FILS: Will send Authentication frame once the response from authentication server is available");
1251 sta
->flags
|= WLAN_STA_PENDING_FILS_ERP
;
1252 /* Calculate pending PMKID here so that we do not need
1253 * to maintain a copy of the EAP-Initiate/Reauth
1255 if (fils_pmkid_erp(wpa_auth_sta_key_mgmt(sta
->wpa_sm
),
1256 elems
.fils_wrapped_data
,
1257 elems
.fils_wrapped_data_len
,
1258 sta
->fils_erp_pmkid
) == 0)
1259 sta
->fils_erp_pmkid_set
= 1;
1261 #else /* CONFIG_NO_RADIUS */
1262 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1264 #endif /* CONFIG_NO_RADIUS */
1270 struct wpabuf
*data
;
1273 data
= prepare_auth_resp_fils(hapd
, sta
, &resp
, pmksa
, NULL
,
1276 wpa_printf(MSG_DEBUG
,
1277 "%s: prepare_auth_resp_fils() returned failure",
1281 cb(hapd
, sta
, resp
, data
, pub
);
1286 static struct wpabuf
*
1287 prepare_auth_resp_fils(struct hostapd_data
*hapd
,
1288 struct sta_info
*sta
, u16
*resp
,
1289 struct rsn_pmksa_cache_entry
*pmksa
,
1290 struct wpabuf
*erp_resp
,
1291 const u8
*msk
, size_t msk_len
,
1294 u8 fils_nonce
[FILS_NONCE_LEN
];
1296 struct wpabuf
*data
= NULL
;
1299 const u8
*pmk
= NULL
;
1301 u8 pmk_buf
[PMK_LEN_MAX
];
1302 struct wpabuf
*pub
= NULL
;
1304 if (*resp
!= WLAN_STATUS_SUCCESS
)
1307 ie
= wpa_auth_get_wpa_ie(hapd
->wpa_auth
, &ielen
);
1309 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1314 /* Add PMKID of the selected PMKSA into RSNE */
1315 ie_buf
= os_malloc(ielen
+ 2 + 2 + PMKID_LEN
);
1317 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1321 os_memcpy(ie_buf
, ie
, ielen
);
1322 if (wpa_insert_pmkid(ie_buf
, &ielen
, pmksa
->pmkid
) < 0) {
1323 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1329 if (random_get_bytes(fils_nonce
, FILS_NONCE_LEN
) < 0) {
1330 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1333 wpa_hexdump(MSG_DEBUG
, "RSN: Generated FILS Nonce",
1334 fils_nonce
, FILS_NONCE_LEN
);
1336 #ifdef CONFIG_FILS_SK_PFS
1337 if (sta
->fils_dh_ss
&& sta
->fils_ecdh
) {
1338 pub
= crypto_ecdh_get_pubkey(sta
->fils_ecdh
, 1);
1340 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1344 #endif /* CONFIG_FILS_SK_PFS */
1346 data
= wpabuf_alloc(1000 + ielen
+ (pub
? wpabuf_len(pub
) : 0));
1348 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1353 #ifdef CONFIG_FILS_SK_PFS
1355 /* Finite Cyclic Group */
1356 wpabuf_put_le16(data
, hapd
->conf
->fils_dh_group
);
1359 wpabuf_put_buf(data
, pub
);
1361 #endif /* CONFIG_FILS_SK_PFS */
1364 wpabuf_put_data(data
, ie
, ielen
);
1366 /* MDE when using FILS+FT (already included in ie,ielen with RSNE) */
1368 #ifdef CONFIG_IEEE80211R_AP
1369 if (wpa_key_mgmt_ft(wpa_auth_sta_key_mgmt(sta
->wpa_sm
))) {
1370 /* FTE[R1KH-ID,R0KH-ID] when using FILS+FT */
1373 res
= wpa_auth_write_fte(hapd
->wpa_auth
, wpabuf_put(data
, 0),
1374 wpabuf_tailroom(data
));
1376 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1379 wpabuf_put(data
, res
);
1381 #endif /* CONFIG_IEEE80211R_AP */
1384 wpabuf_put_u8(data
, WLAN_EID_EXTENSION
); /* Element ID */
1385 wpabuf_put_u8(data
, 1 + FILS_NONCE_LEN
); /* Length */
1386 /* Element ID Extension */
1387 wpabuf_put_u8(data
, WLAN_EID_EXT_FILS_NONCE
);
1388 wpabuf_put_data(data
, fils_nonce
, FILS_NONCE_LEN
);
1391 wpabuf_put_u8(data
, WLAN_EID_EXTENSION
); /* Element ID */
1392 wpabuf_put_u8(data
, 1 + FILS_SESSION_LEN
); /* Length */
1393 /* Element ID Extension */
1394 wpabuf_put_u8(data
, WLAN_EID_EXT_FILS_SESSION
);
1395 wpabuf_put_data(data
, sta
->fils_session
, FILS_SESSION_LEN
);
1397 /* FILS Wrapped Data */
1398 if (!pmksa
&& erp_resp
) {
1399 wpabuf_put_u8(data
, WLAN_EID_EXTENSION
); /* Element ID */
1400 wpabuf_put_u8(data
, 1 + wpabuf_len(erp_resp
)); /* Length */
1401 /* Element ID Extension */
1402 wpabuf_put_u8(data
, WLAN_EID_EXT_FILS_WRAPPED_DATA
);
1403 wpabuf_put_buf(data
, erp_resp
);
1405 if (fils_rmsk_to_pmk(wpa_auth_sta_key_mgmt(sta
->wpa_sm
),
1406 msk
, msk_len
, sta
->fils_snonce
, fils_nonce
,
1408 wpabuf_head(sta
->fils_dh_ss
) : NULL
,
1410 wpabuf_len(sta
->fils_dh_ss
) : 0,
1411 pmk_buf
, &pmk_len
)) {
1412 wpa_printf(MSG_DEBUG
, "FILS: Failed to derive PMK");
1413 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1420 if (sta
->fils_erp_pmkid_set
) {
1421 /* TODO: get PMKLifetime from WPA parameters */
1422 unsigned int dot11RSNAConfigPMKLifetime
= 43200;
1424 sta
->fils_erp_pmkid_set
= 0;
1425 if (wpa_auth_pmksa_add2(
1426 hapd
->wpa_auth
, sta
->addr
,
1428 sta
->fils_erp_pmkid
,
1429 sta
->session_timeout_set
?
1430 sta
->session_timeout
:
1431 dot11RSNAConfigPMKLifetime
,
1432 wpa_auth_sta_key_mgmt(sta
->wpa_sm
)) < 0) {
1433 wpa_printf(MSG_ERROR
,
1434 "FILS: Failed to add PMKSA cache entry based on ERP");
1439 pmk_len
= pmksa
->pmk_len
;
1443 wpa_printf(MSG_DEBUG
, "FILS: No PMK available");
1444 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1450 if (fils_auth_pmk_to_ptk(sta
->wpa_sm
, pmk
, pmk_len
,
1451 sta
->fils_snonce
, fils_nonce
,
1452 sta
->fils_g_sta
, pub
) < 0) {
1453 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1461 *is_pub
= pub
!= NULL
;
1464 wpabuf_clear_free(sta
->fils_dh_ss
);
1465 sta
->fils_dh_ss
= NULL
;
1466 #ifdef CONFIG_FILS_SK_PFS
1467 crypto_ecdh_deinit(sta
->fils_ecdh
);
1468 sta
->fils_ecdh
= NULL
;
1469 #endif /* CONFIG_FILS_SK_PFS */
1474 static void handle_auth_fils_finish(struct hostapd_data
*hapd
,
1475 struct sta_info
*sta
, u16 resp
,
1476 struct wpabuf
*data
, int pub
)
1481 resp
== WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED
) ?
1482 WLAN_AUTH_FILS_SK_PFS
: WLAN_AUTH_FILS_SK
;
1483 send_auth_reply(hapd
, sta
->addr
, hapd
->own_addr
, auth_alg
, 2, resp
,
1484 data
? wpabuf_head(data
) : (u8
*) "",
1485 data
? wpabuf_len(data
) : 0);
1488 if (resp
== WLAN_STATUS_SUCCESS
) {
1489 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1490 HOSTAPD_LEVEL_DEBUG
,
1491 "authentication OK (FILS)");
1492 sta
->flags
|= WLAN_STA_AUTH
;
1493 wpa_auth_sm_event(sta
->wpa_sm
, WPA_AUTH
);
1494 sta
->auth_alg
= pub
? WLAN_AUTH_FILS_SK_PFS
: WLAN_AUTH_FILS_SK
;
1495 mlme_authenticate_indication(hapd
, sta
);
1500 void ieee802_11_finish_fils_auth(struct hostapd_data
*hapd
,
1501 struct sta_info
*sta
, int success
,
1502 struct wpabuf
*erp_resp
,
1503 const u8
*msk
, size_t msk_len
)
1505 struct wpabuf
*data
;
1509 sta
->flags
&= ~WLAN_STA_PENDING_FILS_ERP
;
1511 if (!sta
->fils_pending_cb
)
1513 resp
= success
? WLAN_STATUS_SUCCESS
: WLAN_STATUS_UNSPECIFIED_FAILURE
;
1514 data
= prepare_auth_resp_fils(hapd
, sta
, &resp
, NULL
, erp_resp
,
1515 msk
, msk_len
, &pub
);
1517 wpa_printf(MSG_DEBUG
,
1518 "%s: prepare_auth_resp_fils() returned failure",
1521 sta
->fils_pending_cb(hapd
, sta
, resp
, data
, pub
);
1524 #endif /* CONFIG_FILS */
1528 ieee802_11_allowed_address(struct hostapd_data
*hapd
, const u8
*addr
,
1529 const u8
*msg
, size_t len
, u32
*session_timeout
,
1530 u32
*acct_interim_interval
,
1531 struct vlan_description
*vlan_id
,
1532 struct hostapd_sta_wpa_psk_short
**psk
,
1533 char **identity
, char **radius_cui
)
1537 os_memset(vlan_id
, 0, sizeof(*vlan_id
));
1538 res
= hostapd_allowed_address(hapd
, addr
, msg
, len
,
1539 session_timeout
, acct_interim_interval
,
1540 vlan_id
, psk
, identity
, radius_cui
);
1542 if (res
== HOSTAPD_ACL_REJECT
) {
1543 wpa_printf(MSG_INFO
,
1544 "Station " MACSTR
" not allowed to authenticate",
1546 return HOSTAPD_ACL_REJECT
;
1549 if (res
== HOSTAPD_ACL_PENDING
) {
1550 wpa_printf(MSG_DEBUG
, "Authentication frame from " MACSTR
1551 " waiting for an external authentication",
1553 /* Authentication code will re-send the authentication frame
1554 * after it has received (and cached) information from the
1555 * external source. */
1556 return HOSTAPD_ACL_PENDING
;
1564 ieee802_11_set_radius_info(struct hostapd_data
*hapd
, struct sta_info
*sta
,
1565 int res
, u32 session_timeout
,
1566 u32 acct_interim_interval
,
1567 struct vlan_description
*vlan_id
,
1568 struct hostapd_sta_wpa_psk_short
**psk
,
1569 char **identity
, char **radius_cui
)
1571 if (vlan_id
->notempty
&&
1572 !hostapd_vlan_valid(hapd
->conf
->vlan
, vlan_id
)) {
1573 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_RADIUS
,
1575 "Invalid VLAN %d%s received from RADIUS server",
1577 vlan_id
->tagged
[0] ? "+" : "");
1580 if (ap_sta_set_vlan(hapd
, sta
, vlan_id
) < 0)
1583 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_RADIUS
,
1584 HOSTAPD_LEVEL_INFO
, "VLAN ID %d", sta
->vlan_id
);
1586 hostapd_free_psk_list(sta
->psk
);
1587 if (hapd
->conf
->wpa_psk_radius
!= PSK_RADIUS_IGNORED
) {
1594 sta
->identity
= *identity
;
1596 sta
->radius_cui
= *radius_cui
;
1599 if (hapd
->conf
->acct_interim_interval
== 0 && acct_interim_interval
)
1600 sta
->acct_interim_interval
= acct_interim_interval
;
1601 if (res
== HOSTAPD_ACL_ACCEPT_TIMEOUT
)
1602 ap_sta_session_timeout(hapd
, sta
, session_timeout
);
1604 ap_sta_no_session_timeout(hapd
, sta
);
1610 static void handle_auth(struct hostapd_data
*hapd
,
1611 const struct ieee80211_mgmt
*mgmt
, size_t len
)
1613 u16 auth_alg
, auth_transaction
, status_code
;
1614 u16 resp
= WLAN_STATUS_SUCCESS
;
1615 struct sta_info
*sta
= NULL
;
1618 const u8
*challenge
= NULL
;
1619 u32 session_timeout
, acct_interim_interval
;
1620 struct vlan_description vlan_id
;
1621 struct hostapd_sta_wpa_psk_short
*psk
= NULL
;
1622 u8 resp_ies
[2 + WLAN_AUTH_CHALLENGE_LEN
];
1623 size_t resp_ies_len
= 0;
1624 char *identity
= NULL
;
1625 char *radius_cui
= NULL
;
1628 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.auth
)) {
1629 wpa_printf(MSG_INFO
, "handle_auth - too short payload (len=%lu)",
1630 (unsigned long) len
);
1634 #ifdef CONFIG_TESTING_OPTIONS
1635 if (hapd
->iconf
->ignore_auth_probability
> 0.0 &&
1636 drand48() < hapd
->iconf
->ignore_auth_probability
) {
1637 wpa_printf(MSG_INFO
,
1638 "TESTING: ignoring auth frame from " MACSTR
,
1642 #endif /* CONFIG_TESTING_OPTIONS */
1644 auth_alg
= le_to_host16(mgmt
->u
.auth
.auth_alg
);
1645 auth_transaction
= le_to_host16(mgmt
->u
.auth
.auth_transaction
);
1646 status_code
= le_to_host16(mgmt
->u
.auth
.status_code
);
1647 fc
= le_to_host16(mgmt
->frame_control
);
1648 seq_ctrl
= le_to_host16(mgmt
->seq_ctrl
);
1650 if (len
>= IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.auth
) +
1651 2 + WLAN_AUTH_CHALLENGE_LEN
&&
1652 mgmt
->u
.auth
.variable
[0] == WLAN_EID_CHALLENGE
&&
1653 mgmt
->u
.auth
.variable
[1] == WLAN_AUTH_CHALLENGE_LEN
)
1654 challenge
= &mgmt
->u
.auth
.variable
[2];
1656 wpa_printf(MSG_DEBUG
, "authentication: STA=" MACSTR
" auth_alg=%d "
1657 "auth_transaction=%d status_code=%d wep=%d%s "
1659 MAC2STR(mgmt
->sa
), auth_alg
, auth_transaction
,
1660 status_code
, !!(fc
& WLAN_FC_ISWEP
),
1661 challenge
? " challenge" : "",
1662 seq_ctrl
, (fc
& WLAN_FC_RETRY
) ? " retry" : "");
1664 #ifdef CONFIG_NO_RC4
1665 if (auth_alg
== WLAN_AUTH_SHARED_KEY
) {
1666 wpa_printf(MSG_INFO
,
1667 "Unsupported authentication algorithm (%d)",
1669 resp
= WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG
;
1672 #endif /* CONFIG_NO_RC4 */
1674 if (hapd
->tkip_countermeasures
) {
1675 resp
= WLAN_REASON_MICHAEL_MIC_FAILURE
;
1679 if (!(((hapd
->conf
->auth_algs
& WPA_AUTH_ALG_OPEN
) &&
1680 auth_alg
== WLAN_AUTH_OPEN
) ||
1681 #ifdef CONFIG_IEEE80211R_AP
1682 (hapd
->conf
->wpa
&& wpa_key_mgmt_ft(hapd
->conf
->wpa_key_mgmt
) &&
1683 auth_alg
== WLAN_AUTH_FT
) ||
1684 #endif /* CONFIG_IEEE80211R_AP */
1686 (hapd
->conf
->wpa
&& wpa_key_mgmt_sae(hapd
->conf
->wpa_key_mgmt
) &&
1687 auth_alg
== WLAN_AUTH_SAE
) ||
1688 #endif /* CONFIG_SAE */
1690 (hapd
->conf
->wpa
&& wpa_key_mgmt_fils(hapd
->conf
->wpa_key_mgmt
) &&
1691 auth_alg
== WLAN_AUTH_FILS_SK
) ||
1692 (hapd
->conf
->wpa
&& wpa_key_mgmt_fils(hapd
->conf
->wpa_key_mgmt
) &&
1693 hapd
->conf
->fils_dh_group
&&
1694 auth_alg
== WLAN_AUTH_FILS_SK_PFS
) ||
1695 #endif /* CONFIG_FILS */
1696 ((hapd
->conf
->auth_algs
& WPA_AUTH_ALG_SHARED
) &&
1697 auth_alg
== WLAN_AUTH_SHARED_KEY
))) {
1698 wpa_printf(MSG_INFO
, "Unsupported authentication algorithm (%d)",
1700 resp
= WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG
;
1704 if (!(auth_transaction
== 1 || auth_alg
== WLAN_AUTH_SAE
||
1705 (auth_alg
== WLAN_AUTH_SHARED_KEY
&& auth_transaction
== 3))) {
1706 wpa_printf(MSG_INFO
, "Unknown authentication transaction number (%d)",
1708 resp
= WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION
;
1712 if (os_memcmp(mgmt
->sa
, hapd
->own_addr
, ETH_ALEN
) == 0) {
1713 wpa_printf(MSG_INFO
, "Station " MACSTR
" not allowed to authenticate",
1715 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1719 if (hapd
->conf
->no_auth_if_seen_on
) {
1720 struct hostapd_data
*other
;
1722 other
= sta_track_seen_on(hapd
->iface
, mgmt
->sa
,
1723 hapd
->conf
->no_auth_if_seen_on
);
1727 u8 op_class
, channel
, phytype
;
1729 wpa_printf(MSG_DEBUG
, "%s: Reject authentication from "
1730 MACSTR
" since STA has been seen on %s",
1731 hapd
->conf
->iface
, MAC2STR(mgmt
->sa
),
1732 hapd
->conf
->no_auth_if_seen_on
);
1734 resp
= WLAN_STATUS_REJECTED_WITH_SUGGESTED_BSS_TRANSITION
;
1736 *pos
++ = WLAN_EID_NEIGHBOR_REPORT
;
1738 os_memcpy(pos
, other
->own_addr
, ETH_ALEN
);
1740 info
= 0; /* TODO: BSSID Information */
1741 WPA_PUT_LE32(pos
, info
);
1743 if (other
->iconf
->hw_mode
== HOSTAPD_MODE_IEEE80211AD
)
1744 phytype
= 8; /* dmg */
1745 else if (other
->iconf
->ieee80211ac
)
1746 phytype
= 9; /* vht */
1747 else if (other
->iconf
->ieee80211n
)
1748 phytype
= 7; /* ht */
1749 else if (other
->iconf
->hw_mode
==
1750 HOSTAPD_MODE_IEEE80211A
)
1751 phytype
= 4; /* ofdm */
1752 else if (other
->iconf
->hw_mode
==
1753 HOSTAPD_MODE_IEEE80211G
)
1754 phytype
= 6; /* erp */
1756 phytype
= 5; /* hrdsss */
1757 if (ieee80211_freq_to_channel_ext(
1758 hostapd_hw_get_freq(other
,
1759 other
->iconf
->channel
),
1760 other
->iconf
->secondary_channel
,
1761 other
->iconf
->ieee80211ac
,
1762 &op_class
, &channel
) == NUM_HOSTAPD_MODES
) {
1764 channel
= other
->iconf
->channel
;
1769 resp_ies_len
= pos
- &resp_ies
[0];
1774 res
= ieee802_11_allowed_address(
1775 hapd
, mgmt
->sa
, (const u8
*) mgmt
, len
, &session_timeout
,
1776 &acct_interim_interval
, &vlan_id
, &psk
, &identity
, &radius_cui
);
1777 if (res
== HOSTAPD_ACL_REJECT
) {
1778 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1781 if (res
== HOSTAPD_ACL_PENDING
)
1784 sta
= ap_get_sta(hapd
, mgmt
->sa
);
1786 sta
->flags
&= ~WLAN_STA_PENDING_FILS_ERP
;
1787 if ((fc
& WLAN_FC_RETRY
) &&
1788 sta
->last_seq_ctrl
!= WLAN_INVALID_MGMT_SEQ
&&
1789 sta
->last_seq_ctrl
== seq_ctrl
&&
1790 sta
->last_subtype
== WLAN_FC_STYPE_AUTH
) {
1791 hostapd_logger(hapd
, sta
->addr
,
1792 HOSTAPD_MODULE_IEEE80211
,
1793 HOSTAPD_LEVEL_DEBUG
,
1794 "Drop repeated authentication frame seq_ctrl=0x%x",
1799 if ((hapd
->conf
->mesh
& MESH_ENABLED
) &&
1800 sta
->plink_state
== PLINK_BLOCKED
) {
1801 wpa_printf(MSG_DEBUG
, "Mesh peer " MACSTR
1802 " is blocked - drop Authentication frame",
1806 #endif /* CONFIG_MESH */
1809 if (hapd
->conf
->mesh
& MESH_ENABLED
) {
1810 /* if the mesh peer is not available, we don't do auth.
1812 wpa_printf(MSG_DEBUG
, "Mesh peer " MACSTR
1813 " not yet known - drop Authentication frame",
1816 * Save a copy of the frame so that it can be processed
1817 * if a new peer entry is added shortly after this.
1819 wpabuf_free(hapd
->mesh_pending_auth
);
1820 hapd
->mesh_pending_auth
= wpabuf_alloc_copy(mgmt
, len
);
1821 os_get_reltime(&hapd
->mesh_pending_auth_time
);
1824 #endif /* CONFIG_MESH */
1826 sta
= ap_sta_add(hapd
, mgmt
->sa
);
1828 resp
= WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
;
1832 sta
->last_seq_ctrl
= seq_ctrl
;
1833 sta
->last_subtype
= WLAN_FC_STYPE_AUTH
;
1835 res
= ieee802_11_set_radius_info(
1836 hapd
, sta
, res
, session_timeout
, acct_interim_interval
,
1837 &vlan_id
, &psk
, &identity
, &radius_cui
);
1839 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1843 sta
->flags
&= ~WLAN_STA_PREAUTH
;
1844 ieee802_1x_notify_pre_auth(sta
->eapol_sm
, 0);
1847 * If the driver supports full AP client state, add a station to the
1848 * driver before sending authentication reply to make sure the driver
1849 * has resources, and not to go through the entire authentication and
1850 * association handshake, and fail it at the end.
1852 * If this is not the first transaction, in a multi-step authentication
1853 * algorithm, the station already exists in the driver
1854 * (sta->added_unassoc = 1) so skip it.
1856 * In mesh mode, the station was already added to the driver when the
1857 * NEW_PEER_CANDIDATE event is received.
1859 * If PMF was negotiated for the existing association, skip this to
1860 * avoid dropping the STA entry and the associated keys. This is needed
1861 * to allow the original connection work until the attempt can complete
1862 * (re)association, so that unprotected Authentication frame cannot be
1863 * used to bypass PMF protection.
1865 if (FULL_AP_CLIENT_STATE_SUPP(hapd
->iface
->drv_flags
) &&
1866 (!(sta
->flags
& WLAN_STA_MFP
) || !ap_sta_is_authorized(sta
)) &&
1867 !(hapd
->conf
->mesh
& MESH_ENABLED
) &&
1868 !(sta
->added_unassoc
)) {
1870 * If a station that is already associated to the AP, is trying
1871 * to authenticate again, remove the STA entry, in order to make
1872 * sure the STA PS state gets cleared and configuration gets
1873 * updated. To handle this, station's added_unassoc flag is
1874 * cleared once the station has completed association.
1876 hostapd_drv_sta_remove(hapd
, sta
->addr
);
1877 sta
->flags
&= ~(WLAN_STA_ASSOC
| WLAN_STA_AUTH
|
1878 WLAN_STA_AUTHORIZED
);
1880 if (hostapd_sta_add(hapd
, sta
->addr
, 0, 0, NULL
, 0, 0,
1881 NULL
, NULL
, sta
->flags
, 0, 0, 0, 0)) {
1882 hostapd_logger(hapd
, sta
->addr
,
1883 HOSTAPD_MODULE_IEEE80211
,
1884 HOSTAPD_LEVEL_NOTICE
,
1885 "Could not add STA to kernel driver");
1886 resp
= WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
;
1890 sta
->added_unassoc
= 1;
1894 case WLAN_AUTH_OPEN
:
1895 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1896 HOSTAPD_LEVEL_DEBUG
,
1897 "authentication OK (open system)");
1898 sta
->flags
|= WLAN_STA_AUTH
;
1899 wpa_auth_sm_event(sta
->wpa_sm
, WPA_AUTH
);
1900 sta
->auth_alg
= WLAN_AUTH_OPEN
;
1901 mlme_authenticate_indication(hapd
, sta
);
1903 #ifndef CONFIG_NO_RC4
1904 case WLAN_AUTH_SHARED_KEY
:
1905 resp
= auth_shared_key(hapd
, sta
, auth_transaction
, challenge
,
1906 fc
& WLAN_FC_ISWEP
);
1907 sta
->auth_alg
= WLAN_AUTH_SHARED_KEY
;
1908 mlme_authenticate_indication(hapd
, sta
);
1909 if (sta
->challenge
&& auth_transaction
== 1) {
1910 resp_ies
[0] = WLAN_EID_CHALLENGE
;
1911 resp_ies
[1] = WLAN_AUTH_CHALLENGE_LEN
;
1912 os_memcpy(resp_ies
+ 2, sta
->challenge
,
1913 WLAN_AUTH_CHALLENGE_LEN
);
1914 resp_ies_len
= 2 + WLAN_AUTH_CHALLENGE_LEN
;
1917 #endif /* CONFIG_NO_RC4 */
1918 #ifdef CONFIG_IEEE80211R_AP
1920 sta
->auth_alg
= WLAN_AUTH_FT
;
1921 if (sta
->wpa_sm
== NULL
)
1922 sta
->wpa_sm
= wpa_auth_sta_init(hapd
->wpa_auth
,
1924 if (sta
->wpa_sm
== NULL
) {
1925 wpa_printf(MSG_DEBUG
, "FT: Failed to initialize WPA "
1927 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1930 wpa_ft_process_auth(sta
->wpa_sm
, mgmt
->bssid
,
1931 auth_transaction
, mgmt
->u
.auth
.variable
,
1932 len
- IEEE80211_HDRLEN
-
1933 sizeof(mgmt
->u
.auth
),
1934 handle_auth_ft_finish
, hapd
);
1935 /* handle_auth_ft_finish() callback will complete auth. */
1937 #endif /* CONFIG_IEEE80211R_AP */
1941 if (status_code
== WLAN_STATUS_SUCCESS
&&
1942 hapd
->conf
->mesh
& MESH_ENABLED
) {
1943 if (sta
->wpa_sm
== NULL
)
1945 wpa_auth_sta_init(hapd
->wpa_auth
,
1947 if (sta
->wpa_sm
== NULL
) {
1948 wpa_printf(MSG_DEBUG
,
1949 "SAE: Failed to initialize WPA state machine");
1950 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1954 #endif /* CONFIG_MESH */
1955 handle_auth_sae(hapd
, sta
, mgmt
, len
, auth_transaction
,
1958 #endif /* CONFIG_SAE */
1960 case WLAN_AUTH_FILS_SK
:
1961 case WLAN_AUTH_FILS_SK_PFS
:
1962 handle_auth_fils(hapd
, sta
, mgmt
->u
.auth
.variable
,
1963 len
- IEEE80211_HDRLEN
- sizeof(mgmt
->u
.auth
),
1964 auth_alg
, auth_transaction
, status_code
,
1965 handle_auth_fils_finish
);
1967 #endif /* CONFIG_FILS */
1972 os_free(radius_cui
);
1973 hostapd_free_psk_list(psk
);
1975 reply_res
= send_auth_reply(hapd
, mgmt
->sa
, mgmt
->bssid
, auth_alg
,
1976 auth_transaction
+ 1, resp
, resp_ies
,
1979 if (sta
&& sta
->added_unassoc
&& (resp
!= WLAN_STATUS_SUCCESS
||
1980 reply_res
!= WLAN_STATUS_SUCCESS
)) {
1981 hostapd_drv_sta_remove(hapd
, sta
->addr
);
1982 sta
->added_unassoc
= 0;
1987 int hostapd_get_aid(struct hostapd_data
*hapd
, struct sta_info
*sta
)
1991 /* get a unique AID */
1993 wpa_printf(MSG_DEBUG
, " old AID %d", sta
->aid
);
2000 for (i
= 0; i
< AID_WORDS
; i
++) {
2001 if (hapd
->sta_aid
[i
] == (u32
) -1)
2003 for (j
= 0; j
< 32; j
++) {
2004 if (!(hapd
->sta_aid
[i
] & BIT(j
)))
2012 aid
= i
* 32 + j
+ 1;
2017 hapd
->sta_aid
[i
] |= BIT(j
);
2018 wpa_printf(MSG_DEBUG
, " new AID %d", sta
->aid
);
2023 static u16
check_ssid(struct hostapd_data
*hapd
, struct sta_info
*sta
,
2024 const u8
*ssid_ie
, size_t ssid_ie_len
)
2026 if (ssid_ie
== NULL
)
2027 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2029 if (ssid_ie_len
!= hapd
->conf
->ssid
.ssid_len
||
2030 os_memcmp(ssid_ie
, hapd
->conf
->ssid
.ssid
, ssid_ie_len
) != 0) {
2031 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
2033 "Station tried to associate with unknown SSID "
2034 "'%s'", wpa_ssid_txt(ssid_ie
, ssid_ie_len
));
2035 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2038 return WLAN_STATUS_SUCCESS
;
2042 static u16
check_wmm(struct hostapd_data
*hapd
, struct sta_info
*sta
,
2043 const u8
*wmm_ie
, size_t wmm_ie_len
)
2045 sta
->flags
&= ~WLAN_STA_WMM
;
2047 if (wmm_ie
&& hapd
->conf
->wmm_enabled
) {
2048 struct wmm_information_element
*wmm
;
2050 if (!hostapd_eid_wmm_valid(hapd
, wmm_ie
, wmm_ie_len
)) {
2051 hostapd_logger(hapd
, sta
->addr
,
2053 HOSTAPD_LEVEL_DEBUG
,
2054 "invalid WMM element in association "
2056 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2059 sta
->flags
|= WLAN_STA_WMM
;
2060 wmm
= (struct wmm_information_element
*) wmm_ie
;
2061 sta
->qosinfo
= wmm
->qos_info
;
2063 return WLAN_STATUS_SUCCESS
;
2067 static u16
copy_supp_rates(struct hostapd_data
*hapd
, struct sta_info
*sta
,
2068 struct ieee802_11_elems
*elems
)
2070 /* Supported rates not used in IEEE 802.11ad/DMG */
2071 if (hapd
->iface
->current_mode
&&
2072 hapd
->iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211AD
)
2073 return WLAN_STATUS_SUCCESS
;
2075 if (!elems
->supp_rates
) {
2076 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
2077 HOSTAPD_LEVEL_DEBUG
,
2078 "No supported rates element in AssocReq");
2079 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2082 if (elems
->supp_rates_len
+ elems
->ext_supp_rates_len
>
2083 sizeof(sta
->supported_rates
)) {
2084 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
2085 HOSTAPD_LEVEL_DEBUG
,
2086 "Invalid supported rates element length %d+%d",
2087 elems
->supp_rates_len
,
2088 elems
->ext_supp_rates_len
);
2089 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2092 sta
->supported_rates_len
= merge_byte_arrays(
2093 sta
->supported_rates
, sizeof(sta
->supported_rates
),
2094 elems
->supp_rates
, elems
->supp_rates_len
,
2095 elems
->ext_supp_rates
, elems
->ext_supp_rates_len
);
2097 return WLAN_STATUS_SUCCESS
;
2101 static u16
check_ext_capab(struct hostapd_data
*hapd
, struct sta_info
*sta
,
2102 const u8
*ext_capab_ie
, size_t ext_capab_ie_len
)
2104 #ifdef CONFIG_INTERWORKING
2105 /* check for QoS Map support */
2106 if (ext_capab_ie_len
>= 5) {
2107 if (ext_capab_ie
[4] & 0x01)
2108 sta
->qos_map_enabled
= 1;
2110 #endif /* CONFIG_INTERWORKING */
2112 if (ext_capab_ie_len
> 0)
2113 sta
->ecsa_supported
= !!(ext_capab_ie
[0] & BIT(2));
2115 return WLAN_STATUS_SUCCESS
;
2120 static u16
owe_process_assoc_req(struct sta_info
*sta
, const u8
*owe_dh
,
2123 struct wpabuf
*secret
, *pub
, *hkey
;
2125 u8 prk
[SHA256_MAC_LEN
], pmkid
[SHA256_MAC_LEN
];
2126 const char *info
= "OWE Key Generation";
2130 if (WPA_GET_LE16(owe_dh
) != OWE_DH_GROUP
)
2131 return WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED
;
2133 crypto_ecdh_deinit(sta
->owe_ecdh
);
2134 sta
->owe_ecdh
= crypto_ecdh_init(OWE_DH_GROUP
);
2136 return WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED
;
2138 secret
= crypto_ecdh_set_peerkey(sta
->owe_ecdh
, 0, owe_dh
+ 2,
2141 wpa_printf(MSG_DEBUG
, "OWE: Invalid peer DH public key");
2142 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2144 wpa_hexdump_buf_key(MSG_DEBUG
, "OWE: DH shared secret", secret
);
2146 /* prk = HKDF-extract(C | A | group, z) */
2148 pub
= crypto_ecdh_get_pubkey(sta
->owe_ecdh
, 0);
2150 wpabuf_clear_free(secret
);
2151 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2154 /* PMKID = Truncate-128(Hash(C | A)) */
2155 addr
[0] = owe_dh
+ 2;
2156 len
[0] = owe_dh_len
- 2;
2157 addr
[1] = wpabuf_head(pub
);
2158 len
[1] = wpabuf_len(pub
);
2159 res
= sha256_vector(2, addr
, len
, pmkid
);
2162 wpabuf_clear_free(secret
);
2163 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2166 hkey
= wpabuf_alloc(owe_dh_len
- 2 + wpabuf_len(pub
) + 2);
2169 wpabuf_clear_free(secret
);
2170 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2173 wpabuf_put_data(hkey
, owe_dh
+ 2, owe_dh_len
- 2); /* C */
2174 wpabuf_put_buf(hkey
, pub
); /* A */
2176 wpabuf_put_le16(hkey
, OWE_DH_GROUP
); /* group */
2177 res
= hmac_sha256(wpabuf_head(hkey
), wpabuf_len(hkey
),
2178 wpabuf_head(secret
), wpabuf_len(secret
), prk
);
2179 wpabuf_clear_free(hkey
);
2180 wpabuf_clear_free(secret
);
2182 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2184 wpa_hexdump_key(MSG_DEBUG
, "OWE: prk", prk
, SHA256_MAC_LEN
);
2186 /* PMK = HKDF-expand(prk, "OWE Key Generation", n) */
2188 os_free(sta
->owe_pmk
);
2189 sta
->owe_pmk
= os_malloc(PMK_LEN
);
2190 if (!sta
->owe_pmk
) {
2191 os_memset(prk
, 0, SHA256_MAC_LEN
);
2192 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2195 res
= hmac_sha256_kdf(prk
, SHA256_MAC_LEN
, NULL
, (const u8
*) info
,
2196 os_strlen(info
), sta
->owe_pmk
, PMK_LEN
);
2197 os_memset(prk
, 0, SHA256_MAC_LEN
);
2199 os_free(sta
->owe_pmk
);
2200 sta
->owe_pmk
= NULL
;
2201 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2204 wpa_hexdump_key(MSG_DEBUG
, "OWE: PMK", sta
->owe_pmk
, PMK_LEN
);
2205 wpa_hexdump(MSG_DEBUG
, "OWE: PMKID", pmkid
, PMKID_LEN
);
2206 /* TODO: Add PMKSA cache entry */
2208 return WLAN_STATUS_SUCCESS
;
2210 #endif /* CONFIG_OWE */
2213 static u16
check_assoc_ies(struct hostapd_data
*hapd
, struct sta_info
*sta
,
2214 const u8
*ies
, size_t ies_len
, int reassoc
)
2216 struct ieee802_11_elems elems
;
2220 const u8
*p2p_dev_addr
= NULL
;
2222 if (ieee802_11_parse_elems(ies
, ies_len
, &elems
, 1) == ParseFailed
) {
2223 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
2224 HOSTAPD_LEVEL_INFO
, "Station sent an invalid "
2225 "association request");
2226 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2229 resp
= check_ssid(hapd
, sta
, elems
.ssid
, elems
.ssid_len
);
2230 if (resp
!= WLAN_STATUS_SUCCESS
)
2232 resp
= check_wmm(hapd
, sta
, elems
.wmm
, elems
.wmm_len
);
2233 if (resp
!= WLAN_STATUS_SUCCESS
)
2235 resp
= check_ext_capab(hapd
, sta
, elems
.ext_capab
, elems
.ext_capab_len
);
2236 if (resp
!= WLAN_STATUS_SUCCESS
)
2238 resp
= copy_supp_rates(hapd
, sta
, &elems
);
2239 if (resp
!= WLAN_STATUS_SUCCESS
)
2241 #ifdef CONFIG_IEEE80211N
2242 resp
= copy_sta_ht_capab(hapd
, sta
, elems
.ht_capabilities
);
2243 if (resp
!= WLAN_STATUS_SUCCESS
)
2245 if (hapd
->iconf
->ieee80211n
&& hapd
->iconf
->require_ht
&&
2246 !(sta
->flags
& WLAN_STA_HT
)) {
2247 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
2248 HOSTAPD_LEVEL_INFO
, "Station does not support "
2249 "mandatory HT PHY - reject association");
2250 return WLAN_STATUS_ASSOC_DENIED_NO_HT
;
2252 #endif /* CONFIG_IEEE80211N */
2254 #ifdef CONFIG_IEEE80211AC
2255 if (hapd
->iconf
->ieee80211ac
) {
2256 resp
= copy_sta_vht_capab(hapd
, sta
, elems
.vht_capabilities
);
2257 if (resp
!= WLAN_STATUS_SUCCESS
)
2260 resp
= set_sta_vht_opmode(hapd
, sta
, elems
.vht_opmode_notif
);
2261 if (resp
!= WLAN_STATUS_SUCCESS
)
2265 if (hapd
->iconf
->ieee80211ac
&& hapd
->iconf
->require_vht
&&
2266 !(sta
->flags
& WLAN_STA_VHT
)) {
2267 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
2268 HOSTAPD_LEVEL_INFO
, "Station does not support "
2269 "mandatory VHT PHY - reject association");
2270 return WLAN_STATUS_ASSOC_DENIED_NO_VHT
;
2273 if (hapd
->conf
->vendor_vht
&& !elems
.vht_capabilities
) {
2274 resp
= copy_sta_vendor_vht(hapd
, sta
, elems
.vendor_vht
,
2275 elems
.vendor_vht_len
);
2276 if (resp
!= WLAN_STATUS_SUCCESS
)
2279 #endif /* CONFIG_IEEE80211AC */
2283 wpabuf_free(sta
->p2p_ie
);
2284 sta
->p2p_ie
= ieee802_11_vendor_ie_concat(ies
, ies_len
,
2285 P2P_IE_VENDOR_TYPE
);
2287 p2p_dev_addr
= p2p_get_go_dev_addr(sta
->p2p_ie
);
2289 wpabuf_free(sta
->p2p_ie
);
2292 #endif /* CONFIG_P2P */
2294 if ((hapd
->conf
->wpa
& WPA_PROTO_RSN
) && elems
.rsn_ie
) {
2295 wpa_ie
= elems
.rsn_ie
;
2296 wpa_ie_len
= elems
.rsn_ie_len
;
2297 } else if ((hapd
->conf
->wpa
& WPA_PROTO_WPA
) &&
2299 wpa_ie
= elems
.wpa_ie
;
2300 wpa_ie_len
= elems
.wpa_ie_len
;
2307 sta
->flags
&= ~(WLAN_STA_WPS
| WLAN_STA_MAYBE_WPS
| WLAN_STA_WPS2
);
2308 if (hapd
->conf
->wps_state
&& elems
.wps_ie
) {
2309 wpa_printf(MSG_DEBUG
, "STA included WPS IE in (Re)Association "
2310 "Request - assume WPS is used");
2311 sta
->flags
|= WLAN_STA_WPS
;
2312 wpabuf_free(sta
->wps_ie
);
2313 sta
->wps_ie
= ieee802_11_vendor_ie_concat(ies
, ies_len
,
2314 WPS_IE_VENDOR_TYPE
);
2315 if (sta
->wps_ie
&& wps_is_20(sta
->wps_ie
)) {
2316 wpa_printf(MSG_DEBUG
, "WPS: STA supports WPS 2.0");
2317 sta
->flags
|= WLAN_STA_WPS2
;
2321 if (sta
->wps_ie
&& wps_validate_assoc_req(sta
->wps_ie
) < 0) {
2322 wpa_printf(MSG_DEBUG
, "WPS: Invalid WPS IE in "
2323 "(Re)Association Request - reject");
2324 return WLAN_STATUS_INVALID_IE
;
2326 } else if (hapd
->conf
->wps_state
&& wpa_ie
== NULL
) {
2327 wpa_printf(MSG_DEBUG
, "STA did not include WPA/RSN IE in "
2328 "(Re)Association Request - possible WPS use");
2329 sta
->flags
|= WLAN_STA_MAYBE_WPS
;
2331 #endif /* CONFIG_WPS */
2332 if (hapd
->conf
->wpa
&& wpa_ie
== NULL
) {
2333 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
2335 "No WPA/RSN IE in association request");
2336 return WLAN_STATUS_INVALID_IE
;
2339 if (hapd
->conf
->wpa
&& wpa_ie
) {
2343 if (sta
->wpa_sm
== NULL
)
2344 sta
->wpa_sm
= wpa_auth_sta_init(hapd
->wpa_auth
,
2347 if (sta
->wpa_sm
== NULL
) {
2348 wpa_printf(MSG_WARNING
, "Failed to initialize WPA "
2350 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2352 res
= wpa_validate_wpa_ie(hapd
->wpa_auth
, sta
->wpa_sm
,
2354 elems
.mdie
, elems
.mdie_len
,
2355 elems
.owe_dh
, elems
.owe_dh_len
);
2356 resp
= wpa_res_to_status_code(res
);
2357 if (resp
!= WLAN_STATUS_SUCCESS
)
2359 #ifdef CONFIG_IEEE80211W
2360 if ((sta
->flags
& WLAN_STA_MFP
) && !sta
->sa_query_timed_out
&&
2361 sta
->sa_query_count
> 0)
2362 ap_check_sa_query_timeout(hapd
, sta
);
2363 if ((sta
->flags
& WLAN_STA_MFP
) && !sta
->sa_query_timed_out
&&
2364 (!reassoc
|| sta
->auth_alg
!= WLAN_AUTH_FT
)) {
2366 * STA has already been associated with MFP and SA
2367 * Query timeout has not been reached. Reject the
2368 * association attempt temporarily and start SA Query,
2369 * if one is not pending.
2372 if (sta
->sa_query_count
== 0)
2373 ap_sta_start_sa_query(hapd
, sta
);
2375 return WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY
;
2378 if (wpa_auth_uses_mfp(sta
->wpa_sm
))
2379 sta
->flags
|= WLAN_STA_MFP
;
2381 sta
->flags
&= ~WLAN_STA_MFP
;
2382 #endif /* CONFIG_IEEE80211W */
2384 #ifdef CONFIG_IEEE80211R_AP
2385 if (sta
->auth_alg
== WLAN_AUTH_FT
) {
2387 wpa_printf(MSG_DEBUG
, "FT: " MACSTR
" tried "
2388 "to use association (not "
2389 "re-association) with FT auth_alg",
2390 MAC2STR(sta
->addr
));
2391 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2394 resp
= wpa_ft_validate_reassoc(sta
->wpa_sm
, ies
,
2396 if (resp
!= WLAN_STATUS_SUCCESS
)
2399 #endif /* CONFIG_IEEE80211R_AP */
2402 if (wpa_auth_uses_sae(sta
->wpa_sm
) &&
2403 sta
->auth_alg
== WLAN_AUTH_OPEN
) {
2404 struct rsn_pmksa_cache_entry
*sa
;
2405 sa
= wpa_auth_sta_get_pmksa(sta
->wpa_sm
);
2406 if (!sa
|| sa
->akmp
!= WPA_KEY_MGMT_SAE
) {
2407 wpa_printf(MSG_DEBUG
,
2408 "SAE: No PMKSA cache entry found for "
2409 MACSTR
, MAC2STR(sta
->addr
));
2410 return WLAN_STATUS_INVALID_PMKID
;
2412 wpa_printf(MSG_DEBUG
, "SAE: " MACSTR
2413 " using PMKSA caching", MAC2STR(sta
->addr
));
2414 } else if (wpa_auth_uses_sae(sta
->wpa_sm
) &&
2415 sta
->auth_alg
!= WLAN_AUTH_SAE
&&
2416 !(sta
->auth_alg
== WLAN_AUTH_FT
&&
2417 wpa_auth_uses_ft_sae(sta
->wpa_sm
))) {
2418 wpa_printf(MSG_DEBUG
, "SAE: " MACSTR
" tried to use "
2419 "SAE AKM after non-SAE auth_alg %u",
2420 MAC2STR(sta
->addr
), sta
->auth_alg
);
2421 return WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG
;
2423 #endif /* CONFIG_SAE */
2426 if ((hapd
->conf
->wpa_key_mgmt
& WPA_KEY_MGMT_OWE
) &&
2427 wpa_auth_sta_key_mgmt(sta
->wpa_sm
) == WPA_KEY_MGMT_OWE
&&
2429 resp
= owe_process_assoc_req(sta
, elems
.owe_dh
,
2431 if (resp
!= WLAN_STATUS_SUCCESS
)
2434 #endif /* CONFIG_OWE */
2436 #ifdef CONFIG_IEEE80211N
2437 if ((sta
->flags
& (WLAN_STA_HT
| WLAN_STA_VHT
)) &&
2438 wpa_auth_get_pairwise(sta
->wpa_sm
) == WPA_CIPHER_TKIP
) {
2439 hostapd_logger(hapd
, sta
->addr
,
2440 HOSTAPD_MODULE_IEEE80211
,
2442 "Station tried to use TKIP with HT "
2444 return WLAN_STATUS_CIPHER_REJECTED_PER_POLICY
;
2446 #endif /* CONFIG_IEEE80211N */
2448 } else if (hapd
->conf
->osen
) {
2449 if (elems
.osen
== NULL
) {
2451 hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
2453 "No HS 2.0 OSEN element in association request");
2454 return WLAN_STATUS_INVALID_IE
;
2457 wpa_printf(MSG_DEBUG
, "HS 2.0: OSEN association");
2458 if (sta
->wpa_sm
== NULL
)
2459 sta
->wpa_sm
= wpa_auth_sta_init(hapd
->wpa_auth
,
2461 if (sta
->wpa_sm
== NULL
) {
2462 wpa_printf(MSG_WARNING
, "Failed to initialize WPA "
2464 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2466 if (wpa_validate_osen(hapd
->wpa_auth
, sta
->wpa_sm
,
2467 elems
.osen
- 2, elems
.osen_len
+ 2) < 0)
2468 return WLAN_STATUS_INVALID_IE
;
2469 #endif /* CONFIG_HS20 */
2471 wpa_auth_sta_no_wpa(sta
->wpa_sm
);
2474 p2p_group_notif_assoc(hapd
->p2p_group
, sta
->addr
, ies
, ies_len
);
2475 #endif /* CONFIG_P2P */
2478 wpabuf_free(sta
->hs20_ie
);
2479 if (elems
.hs20
&& elems
.hs20_len
> 4) {
2480 sta
->hs20_ie
= wpabuf_alloc_copy(elems
.hs20
+ 4,
2481 elems
.hs20_len
- 4);
2483 sta
->hs20_ie
= NULL
;
2484 #endif /* CONFIG_HS20 */
2487 wpabuf_free(sta
->mb_ies
);
2488 if (hapd
->iface
->fst
)
2489 sta
->mb_ies
= mb_ies_by_info(&elems
.mb_ies
);
2492 #endif /* CONFIG_FST */
2495 mbo_ap_check_sta_assoc(hapd
, sta
, &elems
);
2497 if (hapd
->conf
->mbo_enabled
&& (hapd
->conf
->wpa
& 2) &&
2498 elems
.mbo
&& sta
->cell_capa
&& !(sta
->flags
& WLAN_STA_MFP
) &&
2499 hapd
->conf
->ieee80211w
!= NO_MGMT_FRAME_PROTECTION
) {
2500 wpa_printf(MSG_INFO
,
2501 "MBO: Reject WPA2 association without PMF");
2502 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2504 #endif /* CONFIG_MBO */
2506 ap_copy_sta_supp_op_classes(sta
, elems
.supp_op_classes
,
2507 elems
.supp_op_classes_len
);
2509 if ((sta
->capability
& WLAN_CAPABILITY_RADIO_MEASUREMENT
) &&
2510 elems
.rrm_enabled
&&
2511 elems
.rrm_enabled_len
>= sizeof(sta
->rrm_enabled_capa
))
2512 os_memcpy(sta
->rrm_enabled_capa
, elems
.rrm_enabled
,
2513 sizeof(sta
->rrm_enabled_capa
));
2515 return WLAN_STATUS_SUCCESS
;
2519 static void send_deauth(struct hostapd_data
*hapd
, const u8
*addr
,
2523 struct ieee80211_mgmt reply
;
2525 os_memset(&reply
, 0, sizeof(reply
));
2526 reply
.frame_control
=
2527 IEEE80211_FC(WLAN_FC_TYPE_MGMT
, WLAN_FC_STYPE_DEAUTH
);
2528 os_memcpy(reply
.da
, addr
, ETH_ALEN
);
2529 os_memcpy(reply
.sa
, hapd
->own_addr
, ETH_ALEN
);
2530 os_memcpy(reply
.bssid
, hapd
->own_addr
, ETH_ALEN
);
2532 send_len
= IEEE80211_HDRLEN
+ sizeof(reply
.u
.deauth
);
2533 reply
.u
.deauth
.reason_code
= host_to_le16(reason_code
);
2535 if (hostapd_drv_send_mlme(hapd
, &reply
, send_len
, 0) < 0)
2536 wpa_printf(MSG_INFO
, "Failed to send deauth: %s",
2541 static int add_associated_sta(struct hostapd_data
*hapd
,
2542 struct sta_info
*sta
)
2544 struct ieee80211_ht_capabilities ht_cap
;
2545 struct ieee80211_vht_capabilities vht_cap
;
2548 * Remove the STA entry to ensure the STA PS state gets cleared and
2549 * configuration gets updated. This is relevant for cases, such as
2550 * FT-over-the-DS, where a station re-associates back to the same AP but
2551 * skips the authentication flow, or if working with a driver that
2552 * does not support full AP client state.
2554 if (!sta
->added_unassoc
)
2555 hostapd_drv_sta_remove(hapd
, sta
->addr
);
2557 #ifdef CONFIG_IEEE80211N
2558 if (sta
->flags
& WLAN_STA_HT
)
2559 hostapd_get_ht_capab(hapd
, sta
->ht_capabilities
, &ht_cap
);
2560 #endif /* CONFIG_IEEE80211N */
2561 #ifdef CONFIG_IEEE80211AC
2562 if (sta
->flags
& WLAN_STA_VHT
)
2563 hostapd_get_vht_capab(hapd
, sta
->vht_capabilities
, &vht_cap
);
2564 #endif /* CONFIG_IEEE80211AC */
2567 * Add the station with forced WLAN_STA_ASSOC flag. The sta->flags
2568 * will be set when the ACK frame for the (Re)Association Response frame
2569 * is processed (TX status driver event).
2571 if (hostapd_sta_add(hapd
, sta
->addr
, sta
->aid
, sta
->capability
,
2572 sta
->supported_rates
, sta
->supported_rates_len
,
2573 sta
->listen_interval
,
2574 sta
->flags
& WLAN_STA_HT
? &ht_cap
: NULL
,
2575 sta
->flags
& WLAN_STA_VHT
? &vht_cap
: NULL
,
2576 sta
->flags
| WLAN_STA_ASSOC
, sta
->qosinfo
,
2577 sta
->vht_opmode
, sta
->p2p_ie
? 1 : 0,
2578 sta
->added_unassoc
)) {
2579 hostapd_logger(hapd
, sta
->addr
,
2580 HOSTAPD_MODULE_IEEE80211
, HOSTAPD_LEVEL_NOTICE
,
2581 "Could not %s STA to kernel driver",
2582 sta
->added_unassoc
? "set" : "add");
2584 if (sta
->added_unassoc
) {
2585 hostapd_drv_sta_remove(hapd
, sta
->addr
);
2586 sta
->added_unassoc
= 0;
2592 sta
->added_unassoc
= 0;
2598 static u16
send_assoc_resp(struct hostapd_data
*hapd
, struct sta_info
*sta
,
2599 const u8
*addr
, u16 status_code
, int reassoc
,
2600 const u8
*ies
, size_t ies_len
)
2605 struct ieee80211_mgmt
*reply
;
2607 u16 res
= WLAN_STATUS_SUCCESS
;
2609 buflen
= sizeof(struct ieee80211_mgmt
) + 1024;
2611 if (sta
&& sta
->fils_hlp_resp
)
2612 buflen
+= wpabuf_len(sta
->fils_hlp_resp
);
2613 #endif /* CONFIG_FILS */
2615 if (sta
&& (hapd
->conf
->wpa_key_mgmt
& WPA_KEY_MGMT_OWE
))
2617 #endif /* CONFIG_OWE */
2618 buf
= os_zalloc(buflen
);
2620 res
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
2623 reply
= (struct ieee80211_mgmt
*) buf
;
2624 reply
->frame_control
=
2625 IEEE80211_FC(WLAN_FC_TYPE_MGMT
,
2626 (reassoc
? WLAN_FC_STYPE_REASSOC_RESP
:
2627 WLAN_FC_STYPE_ASSOC_RESP
));
2628 os_memcpy(reply
->da
, addr
, ETH_ALEN
);
2629 os_memcpy(reply
->sa
, hapd
->own_addr
, ETH_ALEN
);
2630 os_memcpy(reply
->bssid
, hapd
->own_addr
, ETH_ALEN
);
2632 send_len
= IEEE80211_HDRLEN
;
2633 send_len
+= sizeof(reply
->u
.assoc_resp
);
2634 reply
->u
.assoc_resp
.capab_info
=
2635 host_to_le16(hostapd_own_capab_info(hapd
));
2636 reply
->u
.assoc_resp
.status_code
= host_to_le16(status_code
);
2638 reply
->u
.assoc_resp
.aid
= host_to_le16((sta
? sta
->aid
: 0) |
2640 /* Supported rates */
2641 p
= hostapd_eid_supp_rates(hapd
, reply
->u
.assoc_resp
.variable
);
2642 /* Extended supported rates */
2643 p
= hostapd_eid_ext_supp_rates(hapd
, p
);
2645 #ifdef CONFIG_IEEE80211R_AP
2646 if (sta
&& status_code
== WLAN_STATUS_SUCCESS
) {
2647 /* IEEE 802.11r: Mobility Domain Information, Fast BSS
2648 * Transition Information, RSN, [RIC Response] */
2649 p
= wpa_sm_write_assoc_resp_ies(sta
->wpa_sm
, p
,
2651 sta
->auth_alg
, ies
, ies_len
);
2653 #endif /* CONFIG_IEEE80211R_AP */
2655 #ifdef CONFIG_IEEE80211W
2656 if (sta
&& status_code
== WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY
)
2657 p
= hostapd_eid_assoc_comeback_time(hapd
, sta
, p
);
2658 #endif /* CONFIG_IEEE80211W */
2660 #ifdef CONFIG_IEEE80211N
2661 p
= hostapd_eid_ht_capabilities(hapd
, p
);
2662 p
= hostapd_eid_ht_operation(hapd
, p
);
2663 #endif /* CONFIG_IEEE80211N */
2665 #ifdef CONFIG_IEEE80211AC
2666 if (hapd
->iconf
->ieee80211ac
&& !hapd
->conf
->disable_11ac
) {
2667 u32 nsts
= 0, sta_nsts
;
2669 if (sta
&& hapd
->conf
->use_sta_nsts
&& sta
->vht_capabilities
) {
2670 struct ieee80211_vht_capabilities
*capa
;
2672 nsts
= (hapd
->iface
->conf
->vht_capab
>>
2673 VHT_CAP_BEAMFORMEE_STS_OFFSET
) & 7;
2674 capa
= sta
->vht_capabilities
;
2675 sta_nsts
= (le_to_host32(capa
->vht_capabilities_info
) >>
2676 VHT_CAP_BEAMFORMEE_STS_OFFSET
) & 7;
2678 if (nsts
< sta_nsts
)
2683 p
= hostapd_eid_vht_capabilities(hapd
, p
, nsts
);
2684 p
= hostapd_eid_vht_operation(hapd
, p
);
2686 #endif /* CONFIG_IEEE80211AC */
2688 p
= hostapd_eid_ext_capab(hapd
, p
);
2689 p
= hostapd_eid_bss_max_idle_period(hapd
, p
);
2690 if (sta
&& sta
->qos_map_enabled
)
2691 p
= hostapd_eid_qos_map_set(hapd
, p
);
2694 if (hapd
->iface
->fst_ies
) {
2695 os_memcpy(p
, wpabuf_head(hapd
->iface
->fst_ies
),
2696 wpabuf_len(hapd
->iface
->fst_ies
));
2697 p
+= wpabuf_len(hapd
->iface
->fst_ies
);
2699 #endif /* CONFIG_FST */
2701 #ifdef CONFIG_IEEE80211AC
2702 if (sta
&& hapd
->conf
->vendor_vht
&& (sta
->flags
& WLAN_STA_VENDOR_VHT
))
2703 p
= hostapd_eid_vendor_vht(hapd
, p
);
2704 #endif /* CONFIG_IEEE80211AC */
2706 if (sta
&& (sta
->flags
& WLAN_STA_WMM
))
2707 p
= hostapd_eid_wmm(hapd
, p
);
2711 ((sta
->flags
& WLAN_STA_WPS
) ||
2712 ((sta
->flags
& WLAN_STA_MAYBE_WPS
) && hapd
->conf
->wpa
))) {
2713 struct wpabuf
*wps
= wps_build_assoc_resp_ie();
2715 os_memcpy(p
, wpabuf_head(wps
), wpabuf_len(wps
));
2716 p
+= wpabuf_len(wps
);
2720 #endif /* CONFIG_WPS */
2723 if (sta
&& sta
->p2p_ie
&& hapd
->p2p_group
) {
2724 struct wpabuf
*p2p_resp_ie
;
2725 enum p2p_status_code status
;
2726 switch (status_code
) {
2727 case WLAN_STATUS_SUCCESS
:
2728 status
= P2P_SC_SUCCESS
;
2730 case WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
:
2731 status
= P2P_SC_FAIL_LIMIT_REACHED
;
2734 status
= P2P_SC_FAIL_INVALID_PARAMS
;
2737 p2p_resp_ie
= p2p_group_assoc_resp_ie(hapd
->p2p_group
, status
);
2739 os_memcpy(p
, wpabuf_head(p2p_resp_ie
),
2740 wpabuf_len(p2p_resp_ie
));
2741 p
+= wpabuf_len(p2p_resp_ie
);
2742 wpabuf_free(p2p_resp_ie
);
2745 #endif /* CONFIG_P2P */
2747 #ifdef CONFIG_P2P_MANAGER
2748 if (hapd
->conf
->p2p
& P2P_MANAGE
)
2749 p
= hostapd_eid_p2p_manage(hapd
, p
);
2750 #endif /* CONFIG_P2P_MANAGER */
2752 p
= hostapd_eid_mbo(hapd
, p
, buf
+ buflen
- p
);
2754 if (hapd
->conf
->assocresp_elements
&&
2755 (size_t) (buf
+ buflen
- p
) >=
2756 wpabuf_len(hapd
->conf
->assocresp_elements
)) {
2757 os_memcpy(p
, wpabuf_head(hapd
->conf
->assocresp_elements
),
2758 wpabuf_len(hapd
->conf
->assocresp_elements
));
2759 p
+= wpabuf_len(hapd
->conf
->assocresp_elements
);
2762 send_len
+= p
- reply
->u
.assoc_resp
.variable
;
2766 (sta
->auth_alg
== WLAN_AUTH_FILS_SK
||
2767 sta
->auth_alg
== WLAN_AUTH_FILS_SK_PFS
||
2768 sta
->auth_alg
== WLAN_AUTH_FILS_PK
) &&
2769 status_code
== WLAN_STATUS_SUCCESS
) {
2770 struct ieee802_11_elems elems
;
2772 if (ieee802_11_parse_elems(ies
, ies_len
, &elems
, 0) ==
2773 ParseFailed
|| !elems
.fils_session
) {
2774 res
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
2779 *p
++ = WLAN_EID_EXTENSION
; /* Element ID */
2780 *p
++ = 1 + FILS_SESSION_LEN
; /* Length */
2781 *p
++ = WLAN_EID_EXT_FILS_SESSION
; /* Element ID Extension */
2782 os_memcpy(p
, elems
.fils_session
, FILS_SESSION_LEN
);
2783 send_len
+= 2 + 1 + FILS_SESSION_LEN
;
2785 send_len
= fils_encrypt_assoc(sta
->wpa_sm
, buf
, send_len
,
2786 buflen
, sta
->fils_hlp_resp
);
2788 res
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
2792 #endif /* CONFIG_FILS */
2795 if ((hapd
->conf
->wpa_key_mgmt
& WPA_KEY_MGMT_OWE
) &&
2796 sta
&& sta
->owe_ecdh
&&
2797 wpa_auth_sta_key_mgmt(sta
->wpa_sm
) == WPA_KEY_MGMT_OWE
) {
2800 pub
= crypto_ecdh_get_pubkey(sta
->owe_ecdh
, 0);
2802 res
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
2805 /* OWE Diffie-Hellman Parameter element */
2806 *p
++ = WLAN_EID_EXTENSION
; /* Element ID */
2807 *p
++ = 1 + 2 + wpabuf_len(pub
); /* Length */
2808 *p
++ = WLAN_EID_EXT_OWE_DH_PARAM
; /* Element ID Extension */
2809 WPA_PUT_LE16(p
, OWE_DH_GROUP
);
2811 os_memcpy(p
, wpabuf_head(pub
), wpabuf_len(pub
));
2812 p
+= wpabuf_len(pub
);
2813 send_len
+= 3 + 2 + wpabuf_len(pub
);
2816 #endif /* CONFIG_OWE */
2818 if (hostapd_drv_send_mlme(hapd
, reply
, send_len
, 0) < 0) {
2819 wpa_printf(MSG_INFO
, "Failed to send assoc resp: %s",
2821 res
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
2832 void fils_hlp_finish_assoc(struct hostapd_data
*hapd
, struct sta_info
*sta
)
2836 wpa_printf(MSG_DEBUG
, "FILS: Finish association with " MACSTR
,
2837 MAC2STR(sta
->addr
));
2838 eloop_cancel_timeout(fils_hlp_timeout
, hapd
, sta
);
2839 if (!sta
->fils_pending_assoc_req
)
2841 reply_res
= send_assoc_resp(hapd
, sta
, sta
->addr
, WLAN_STATUS_SUCCESS
,
2842 sta
->fils_pending_assoc_is_reassoc
,
2843 sta
->fils_pending_assoc_req
,
2844 sta
->fils_pending_assoc_req_len
);
2845 os_free(sta
->fils_pending_assoc_req
);
2846 sta
->fils_pending_assoc_req
= NULL
;
2847 sta
->fils_pending_assoc_req_len
= 0;
2848 wpabuf_free(sta
->fils_hlp_resp
);
2849 sta
->fils_hlp_resp
= NULL
;
2850 wpabuf_free(sta
->hlp_dhcp_discover
);
2851 sta
->hlp_dhcp_discover
= NULL
;
2854 * Remove the station in case tranmission of a success response fails
2855 * (the STA was added associated to the driver) or if the station was
2856 * previously added unassociated.
2858 if (reply_res
!= WLAN_STATUS_SUCCESS
|| sta
->added_unassoc
) {
2859 hostapd_drv_sta_remove(hapd
, sta
->addr
);
2860 sta
->added_unassoc
= 0;
2865 void fils_hlp_timeout(void *eloop_ctx
, void *eloop_data
)
2867 struct hostapd_data
*hapd
= eloop_ctx
;
2868 struct sta_info
*sta
= eloop_data
;
2870 wpa_printf(MSG_DEBUG
,
2871 "FILS: HLP response timeout - continue with association response for "
2872 MACSTR
, MAC2STR(sta
->addr
));
2873 if (sta
->fils_drv_assoc_finish
)
2874 hostapd_notify_assoc_fils_finish(hapd
, sta
);
2876 fils_hlp_finish_assoc(hapd
, sta
);
2879 #endif /* CONFIG_FILS */
2882 static void handle_assoc(struct hostapd_data
*hapd
,
2883 const struct ieee80211_mgmt
*mgmt
, size_t len
,
2886 u16 capab_info
, listen_interval
, seq_ctrl
, fc
;
2887 u16 resp
= WLAN_STATUS_SUCCESS
, reply_res
;
2890 struct sta_info
*sta
;
2892 struct hostapd_sta_wpa_psk_short
*psk
= NULL
;
2893 char *identity
= NULL
;
2894 char *radius_cui
= NULL
;
2896 int delay_assoc
= 0;
2897 #endif /* CONFIG_FILS */
2899 if (len
< IEEE80211_HDRLEN
+ (reassoc
? sizeof(mgmt
->u
.reassoc_req
) :
2900 sizeof(mgmt
->u
.assoc_req
))) {
2901 wpa_printf(MSG_INFO
, "handle_assoc(reassoc=%d) - too short payload (len=%lu)",
2902 reassoc
, (unsigned long) len
);
2906 #ifdef CONFIG_TESTING_OPTIONS
2908 if (hapd
->iconf
->ignore_reassoc_probability
> 0.0 &&
2909 drand48() < hapd
->iconf
->ignore_reassoc_probability
) {
2910 wpa_printf(MSG_INFO
,
2911 "TESTING: ignoring reassoc request from "
2912 MACSTR
, MAC2STR(mgmt
->sa
));
2916 if (hapd
->iconf
->ignore_assoc_probability
> 0.0 &&
2917 drand48() < hapd
->iconf
->ignore_assoc_probability
) {
2918 wpa_printf(MSG_INFO
,
2919 "TESTING: ignoring assoc request from "
2920 MACSTR
, MAC2STR(mgmt
->sa
));
2924 #endif /* CONFIG_TESTING_OPTIONS */
2926 fc
= le_to_host16(mgmt
->frame_control
);
2927 seq_ctrl
= le_to_host16(mgmt
->seq_ctrl
);
2930 capab_info
= le_to_host16(mgmt
->u
.reassoc_req
.capab_info
);
2931 listen_interval
= le_to_host16(
2932 mgmt
->u
.reassoc_req
.listen_interval
);
2933 wpa_printf(MSG_DEBUG
, "reassociation request: STA=" MACSTR
2934 " capab_info=0x%02x listen_interval=%d current_ap="
2935 MACSTR
" seq_ctrl=0x%x%s",
2936 MAC2STR(mgmt
->sa
), capab_info
, listen_interval
,
2937 MAC2STR(mgmt
->u
.reassoc_req
.current_ap
),
2938 seq_ctrl
, (fc
& WLAN_FC_RETRY
) ? " retry" : "");
2939 left
= len
- (IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.reassoc_req
));
2940 pos
= mgmt
->u
.reassoc_req
.variable
;
2942 capab_info
= le_to_host16(mgmt
->u
.assoc_req
.capab_info
);
2943 listen_interval
= le_to_host16(
2944 mgmt
->u
.assoc_req
.listen_interval
);
2945 wpa_printf(MSG_DEBUG
, "association request: STA=" MACSTR
2946 " capab_info=0x%02x listen_interval=%d "
2948 MAC2STR(mgmt
->sa
), capab_info
, listen_interval
,
2949 seq_ctrl
, (fc
& WLAN_FC_RETRY
) ? " retry" : "");
2950 left
= len
- (IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.assoc_req
));
2951 pos
= mgmt
->u
.assoc_req
.variable
;
2954 sta
= ap_get_sta(hapd
, mgmt
->sa
);
2955 #ifdef CONFIG_IEEE80211R_AP
2956 if (sta
&& sta
->auth_alg
== WLAN_AUTH_FT
&&
2957 (sta
->flags
& WLAN_STA_AUTH
) == 0) {
2958 wpa_printf(MSG_DEBUG
, "FT: Allow STA " MACSTR
" to associate "
2959 "prior to authentication since it is using "
2960 "over-the-DS FT", MAC2STR(mgmt
->sa
));
2963 * Mark station as authenticated, to avoid adding station
2964 * entry in the driver as associated and not authenticated
2966 sta
->flags
|= WLAN_STA_AUTH
;
2968 #endif /* CONFIG_IEEE80211R_AP */
2969 if (sta
== NULL
|| (sta
->flags
& WLAN_STA_AUTH
) == 0) {
2970 if (hapd
->iface
->current_mode
&&
2971 hapd
->iface
->current_mode
->mode
==
2972 HOSTAPD_MODE_IEEE80211AD
) {
2974 u32 session_timeout
, acct_interim_interval
;
2975 struct vlan_description vlan_id
;
2977 acl_res
= ieee802_11_allowed_address(
2978 hapd
, mgmt
->sa
, (const u8
*) mgmt
, len
,
2979 &session_timeout
, &acct_interim_interval
,
2980 &vlan_id
, &psk
, &identity
, &radius_cui
);
2981 if (acl_res
== HOSTAPD_ACL_REJECT
) {
2982 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
2985 if (acl_res
== HOSTAPD_ACL_PENDING
)
2988 /* DMG/IEEE 802.11ad does not use authentication.
2989 * Allocate sta entry upon association. */
2990 sta
= ap_sta_add(hapd
, mgmt
->sa
);
2992 hostapd_logger(hapd
, mgmt
->sa
,
2993 HOSTAPD_MODULE_IEEE80211
,
2995 "Failed to add STA");
2996 resp
= WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
;
3000 acl_res
= ieee802_11_set_radius_info(
3001 hapd
, sta
, acl_res
, session_timeout
,
3002 acct_interim_interval
, &vlan_id
, &psk
,
3003 &identity
, &radius_cui
);
3005 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
3009 hostapd_logger(hapd
, sta
->addr
,
3010 HOSTAPD_MODULE_IEEE80211
,
3011 HOSTAPD_LEVEL_DEBUG
,
3012 "Skip authentication for DMG/IEEE 802.11ad");
3013 sta
->flags
|= WLAN_STA_AUTH
;
3014 wpa_auth_sm_event(sta
->wpa_sm
, WPA_AUTH
);
3015 sta
->auth_alg
= WLAN_AUTH_OPEN
;
3017 hostapd_logger(hapd
, mgmt
->sa
,
3018 HOSTAPD_MODULE_IEEE80211
,
3020 "Station tried to associate before authentication (aid=%d flags=0x%x)",
3021 sta
? sta
->aid
: -1,
3022 sta
? sta
->flags
: 0);
3023 send_deauth(hapd
, mgmt
->sa
,
3024 WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA
);
3029 if ((fc
& WLAN_FC_RETRY
) &&
3030 sta
->last_seq_ctrl
!= WLAN_INVALID_MGMT_SEQ
&&
3031 sta
->last_seq_ctrl
== seq_ctrl
&&
3032 sta
->last_subtype
== (reassoc
? WLAN_FC_STYPE_REASSOC_REQ
:
3033 WLAN_FC_STYPE_ASSOC_REQ
)) {
3034 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
3035 HOSTAPD_LEVEL_DEBUG
,
3036 "Drop repeated association frame seq_ctrl=0x%x",
3040 sta
->last_seq_ctrl
= seq_ctrl
;
3041 sta
->last_subtype
= reassoc
? WLAN_FC_STYPE_REASSOC_REQ
:
3042 WLAN_FC_STYPE_ASSOC_REQ
;
3044 if (hapd
->tkip_countermeasures
) {
3045 resp
= WLAN_REASON_MICHAEL_MIC_FAILURE
;
3049 if (listen_interval
> hapd
->conf
->max_listen_interval
) {
3050 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
3051 HOSTAPD_LEVEL_DEBUG
,
3052 "Too large Listen Interval (%d)",
3054 resp
= WLAN_STATUS_ASSOC_DENIED_LISTEN_INT_TOO_LARGE
;
3059 if (hapd
->conf
->mbo_enabled
&& hapd
->mbo_assoc_disallow
) {
3060 resp
= WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
;
3063 #endif /* CONFIG_MBO */
3066 * sta->capability is used in check_assoc_ies() for RRM enabled
3067 * capability element.
3069 sta
->capability
= capab_info
;
3072 if (sta
->auth_alg
== WLAN_AUTH_FILS_SK
||
3073 sta
->auth_alg
== WLAN_AUTH_FILS_SK_PFS
||
3074 sta
->auth_alg
== WLAN_AUTH_FILS_PK
) {
3075 /* The end of the payload is encrypted. Need to decrypt it
3076 * before parsing. */
3078 tmp
= os_memdup(pos
, left
);
3080 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
3084 left
= fils_decrypt_assoc(sta
->wpa_sm
, sta
->fils_session
, mgmt
,
3087 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
3092 #endif /* CONFIG_FILS */
3094 /* followed by SSID and Supported rates; and HT capabilities if 802.11n
3096 resp
= check_assoc_ies(hapd
, sta
, pos
, left
, reassoc
);
3097 if (resp
!= WLAN_STATUS_SUCCESS
)
3100 if (hostapd_get_aid(hapd
, sta
) < 0) {
3101 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
3102 HOSTAPD_LEVEL_INFO
, "No room for more AIDs");
3103 resp
= WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
;
3107 sta
->listen_interval
= listen_interval
;
3109 if (hapd
->iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211G
)
3110 sta
->flags
|= WLAN_STA_NONERP
;
3111 for (i
= 0; i
< sta
->supported_rates_len
; i
++) {
3112 if ((sta
->supported_rates
[i
] & 0x7f) > 22) {
3113 sta
->flags
&= ~WLAN_STA_NONERP
;
3117 if (sta
->flags
& WLAN_STA_NONERP
&& !sta
->nonerp_set
) {
3118 sta
->nonerp_set
= 1;
3119 hapd
->iface
->num_sta_non_erp
++;
3120 if (hapd
->iface
->num_sta_non_erp
== 1)
3121 ieee802_11_set_beacons(hapd
->iface
);
3124 if (!(sta
->capability
& WLAN_CAPABILITY_SHORT_SLOT_TIME
) &&
3125 !sta
->no_short_slot_time_set
) {
3126 sta
->no_short_slot_time_set
= 1;
3127 hapd
->iface
->num_sta_no_short_slot_time
++;
3128 if (hapd
->iface
->current_mode
->mode
==
3129 HOSTAPD_MODE_IEEE80211G
&&
3130 hapd
->iface
->num_sta_no_short_slot_time
== 1)
3131 ieee802_11_set_beacons(hapd
->iface
);
3134 if (sta
->capability
& WLAN_CAPABILITY_SHORT_PREAMBLE
)
3135 sta
->flags
|= WLAN_STA_SHORT_PREAMBLE
;
3137 sta
->flags
&= ~WLAN_STA_SHORT_PREAMBLE
;
3139 if (!(sta
->capability
& WLAN_CAPABILITY_SHORT_PREAMBLE
) &&
3140 !sta
->no_short_preamble_set
) {
3141 sta
->no_short_preamble_set
= 1;
3142 hapd
->iface
->num_sta_no_short_preamble
++;
3143 if (hapd
->iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211G
3144 && hapd
->iface
->num_sta_no_short_preamble
== 1)
3145 ieee802_11_set_beacons(hapd
->iface
);
3148 #ifdef CONFIG_IEEE80211N
3149 update_ht_state(hapd
, sta
);
3150 #endif /* CONFIG_IEEE80211N */
3152 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
3153 HOSTAPD_LEVEL_DEBUG
,
3154 "association OK (aid %d)", sta
->aid
);
3155 /* Station will be marked associated, after it acknowledges AssocResp
3157 sta
->flags
|= WLAN_STA_ASSOC_REQ_OK
;
3159 #ifdef CONFIG_IEEE80211W
3160 if ((sta
->flags
& WLAN_STA_MFP
) && sta
->sa_query_timed_out
) {
3161 wpa_printf(MSG_DEBUG
, "Allowing %sassociation after timed out "
3162 "SA Query procedure", reassoc
? "re" : "");
3163 /* TODO: Send a protected Disassociate frame to the STA using
3164 * the old key and Reason Code "Previous Authentication no
3165 * longer valid". Make sure this is only sent protected since
3166 * unprotected frame would be received by the STA that is now
3167 * trying to associate.
3170 #endif /* CONFIG_IEEE80211W */
3172 /* Make sure that the previously registered inactivity timer will not
3173 * remove the STA immediately. */
3174 sta
->timeout_next
= STA_NULLFUNC
;
3176 #ifdef CONFIG_TAXONOMY
3177 taxonomy_sta_info_assoc_req(hapd
, sta
, pos
, left
);
3178 #endif /* CONFIG_TAXONOMY */
3180 sta
->pending_wds_enable
= 0;
3183 if (sta
->auth_alg
== WLAN_AUTH_FILS_SK
||
3184 sta
->auth_alg
== WLAN_AUTH_FILS_SK_PFS
||
3185 sta
->auth_alg
== WLAN_AUTH_FILS_PK
) {
3186 if (fils_process_hlp(hapd
, sta
, pos
, left
) > 0)
3189 #endif /* CONFIG_FILS */
3193 os_free(radius_cui
);
3194 hostapd_free_psk_list(psk
);
3197 * In case of a successful response, add the station to the driver.
3198 * Otherwise, the kernel may ignore Data frames before we process the
3199 * ACK frame (TX status). In case of a failure, this station will be
3202 * Note that this is not compliant with the IEEE 802.11 standard that
3203 * states that a non-AP station should transition into the
3204 * authenticated/associated state only after the station acknowledges
3205 * the (Re)Association Response frame. However, still do this as:
3207 * 1. In case the station does not acknowledge the (Re)Association
3208 * Response frame, it will be removed.
3209 * 2. Data frames will be dropped in the kernel until the station is
3210 * set into authorized state, and there are no significant known
3211 * issues with processing other non-Data Class 3 frames during this
3214 if (resp
== WLAN_STATUS_SUCCESS
&& sta
&& add_associated_sta(hapd
, sta
))
3215 resp
= WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
;
3219 eloop_cancel_timeout(fils_hlp_timeout
, hapd
, sta
);
3220 os_free(sta
->fils_pending_assoc_req
);
3221 sta
->fils_pending_assoc_req
= NULL
;
3222 sta
->fils_pending_assoc_req_len
= 0;
3223 wpabuf_free(sta
->fils_hlp_resp
);
3224 sta
->fils_hlp_resp
= NULL
;
3226 if (sta
&& delay_assoc
&& resp
== WLAN_STATUS_SUCCESS
) {
3227 sta
->fils_pending_assoc_req
= tmp
;
3228 sta
->fils_pending_assoc_req_len
= left
;
3229 sta
->fils_pending_assoc_is_reassoc
= reassoc
;
3230 sta
->fils_drv_assoc_finish
= 0;
3231 wpa_printf(MSG_DEBUG
,
3232 "FILS: Waiting for HLP processing before sending (Re)Association Response frame to "
3233 MACSTR
, MAC2STR(sta
->addr
));
3234 eloop_cancel_timeout(fils_hlp_timeout
, hapd
, sta
);
3235 eloop_register_timeout(0, hapd
->conf
->fils_hlp_wait_time
* 1024,
3236 fils_hlp_timeout
, hapd
, sta
);
3239 #endif /* CONFIG_FILS */
3241 reply_res
= send_assoc_resp(hapd
, sta
, mgmt
->sa
, resp
, reassoc
, pos
,
3246 * Remove the station in case tranmission of a success response fails
3247 * (the STA was added associated to the driver) or if the station was
3248 * previously added unassociated.
3250 if (sta
&& ((reply_res
!= WLAN_STATUS_SUCCESS
&&
3251 resp
== WLAN_STATUS_SUCCESS
) || sta
->added_unassoc
)) {
3252 hostapd_drv_sta_remove(hapd
, sta
->addr
);
3253 sta
->added_unassoc
= 0;
3258 static void handle_disassoc(struct hostapd_data
*hapd
,
3259 const struct ieee80211_mgmt
*mgmt
, size_t len
)
3261 struct sta_info
*sta
;
3263 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.disassoc
)) {
3264 wpa_printf(MSG_INFO
, "handle_disassoc - too short payload (len=%lu)",
3265 (unsigned long) len
);
3269 wpa_printf(MSG_DEBUG
, "disassocation: STA=" MACSTR
" reason_code=%d",
3271 le_to_host16(mgmt
->u
.disassoc
.reason_code
));
3273 sta
= ap_get_sta(hapd
, mgmt
->sa
);
3275 wpa_printf(MSG_INFO
, "Station " MACSTR
" trying to disassociate, but it is not associated",
3280 ap_sta_set_authorized(hapd
, sta
, 0);
3281 sta
->last_seq_ctrl
= WLAN_INVALID_MGMT_SEQ
;
3282 sta
->flags
&= ~(WLAN_STA_ASSOC
| WLAN_STA_ASSOC_REQ_OK
);
3283 wpa_auth_sm_event(sta
->wpa_sm
, WPA_DISASSOC
);
3284 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
3285 HOSTAPD_LEVEL_INFO
, "disassociated");
3286 sta
->acct_terminate_cause
= RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST
;
3287 ieee802_1x_notify_port_enabled(sta
->eapol_sm
, 0);
3288 /* Stop Accounting and IEEE 802.1X sessions, but leave the STA
3290 accounting_sta_stop(hapd
, sta
);
3291 ieee802_1x_free_station(hapd
, sta
);
3293 hostapd_drv_br_delete_ip_neigh(hapd
, 4, (u8
*) &sta
->ipaddr
);
3294 ap_sta_ip6addr_del(hapd
, sta
);
3295 hostapd_drv_sta_remove(hapd
, sta
->addr
);
3296 sta
->added_unassoc
= 0;
3298 if (sta
->timeout_next
== STA_NULLFUNC
||
3299 sta
->timeout_next
== STA_DISASSOC
) {
3300 sta
->timeout_next
= STA_DEAUTH
;
3301 eloop_cancel_timeout(ap_handle_timer
, hapd
, sta
);
3302 eloop_register_timeout(AP_DEAUTH_DELAY
, 0, ap_handle_timer
,
3306 mlme_disassociate_indication(
3307 hapd
, sta
, le_to_host16(mgmt
->u
.disassoc
.reason_code
));
3309 /* DMG/IEEE 802.11ad does not use deauthication. Deallocate sta upon
3310 * disassociation. */
3311 if (hapd
->iface
->current_mode
&&
3312 hapd
->iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211AD
) {
3313 sta
->flags
&= ~WLAN_STA_AUTH
;
3314 wpa_auth_sm_event(sta
->wpa_sm
, WPA_DEAUTH
);
3315 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
3316 HOSTAPD_LEVEL_DEBUG
, "deauthenticated");
3317 ap_free_sta(hapd
, sta
);
3322 static void handle_deauth(struct hostapd_data
*hapd
,
3323 const struct ieee80211_mgmt
*mgmt
, size_t len
)
3325 struct sta_info
*sta
;
3327 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.deauth
)) {
3328 wpa_msg(hapd
->msg_ctx
, MSG_DEBUG
, "handle_deauth - too short "
3329 "payload (len=%lu)", (unsigned long) len
);
3333 wpa_msg(hapd
->msg_ctx
, MSG_DEBUG
, "deauthentication: STA=" MACSTR
3335 MAC2STR(mgmt
->sa
), le_to_host16(mgmt
->u
.deauth
.reason_code
));
3337 sta
= ap_get_sta(hapd
, mgmt
->sa
);
3339 wpa_msg(hapd
->msg_ctx
, MSG_DEBUG
, "Station " MACSTR
" trying "
3340 "to deauthenticate, but it is not authenticated",
3345 ap_sta_set_authorized(hapd
, sta
, 0);
3346 sta
->last_seq_ctrl
= WLAN_INVALID_MGMT_SEQ
;
3347 sta
->flags
&= ~(WLAN_STA_AUTH
| WLAN_STA_ASSOC
|
3348 WLAN_STA_ASSOC_REQ_OK
);
3349 wpa_auth_sm_event(sta
->wpa_sm
, WPA_DEAUTH
);
3350 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
3351 HOSTAPD_LEVEL_DEBUG
, "deauthenticated");
3352 mlme_deauthenticate_indication(
3353 hapd
, sta
, le_to_host16(mgmt
->u
.deauth
.reason_code
));
3354 sta
->acct_terminate_cause
= RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST
;
3355 ieee802_1x_notify_port_enabled(sta
->eapol_sm
, 0);
3356 ap_free_sta(hapd
, sta
);
3360 static void handle_beacon(struct hostapd_data
*hapd
,
3361 const struct ieee80211_mgmt
*mgmt
, size_t len
,
3362 struct hostapd_frame_info
*fi
)
3364 struct ieee802_11_elems elems
;
3366 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.beacon
)) {
3367 wpa_printf(MSG_INFO
, "handle_beacon - too short payload (len=%lu)",
3368 (unsigned long) len
);
3372 (void) ieee802_11_parse_elems(mgmt
->u
.beacon
.variable
,
3373 len
- (IEEE80211_HDRLEN
+
3374 sizeof(mgmt
->u
.beacon
)), &elems
,
3377 ap_list_process_beacon(hapd
->iface
, mgmt
, &elems
, fi
);
3381 #ifdef CONFIG_IEEE80211W
3383 static int hostapd_sa_query_action(struct hostapd_data
*hapd
,
3384 const struct ieee80211_mgmt
*mgmt
,
3389 end
= mgmt
->u
.action
.u
.sa_query_resp
.trans_id
+
3390 WLAN_SA_QUERY_TR_ID_LEN
;
3391 if (((u8
*) mgmt
) + len
< end
) {
3392 wpa_printf(MSG_DEBUG
, "IEEE 802.11: Too short SA Query Action "
3393 "frame (len=%lu)", (unsigned long) len
);
3397 ieee802_11_sa_query_action(hapd
, mgmt
->sa
,
3398 mgmt
->u
.action
.u
.sa_query_resp
.action
,
3399 mgmt
->u
.action
.u
.sa_query_resp
.trans_id
);
3404 static int robust_action_frame(u8 category
)
3406 return category
!= WLAN_ACTION_PUBLIC
&&
3407 category
!= WLAN_ACTION_HT
;
3409 #endif /* CONFIG_IEEE80211W */
3412 static int handle_action(struct hostapd_data
*hapd
,
3413 const struct ieee80211_mgmt
*mgmt
, size_t len
)
3415 struct sta_info
*sta
;
3416 sta
= ap_get_sta(hapd
, mgmt
->sa
);
3418 if (len
< IEEE80211_HDRLEN
+ 1) {
3419 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
3420 HOSTAPD_LEVEL_DEBUG
,
3421 "handle_action - too short payload (len=%lu)",
3422 (unsigned long) len
);
3426 if (mgmt
->u
.action
.category
!= WLAN_ACTION_PUBLIC
&&
3427 (sta
== NULL
|| !(sta
->flags
& WLAN_STA_ASSOC
))) {
3428 wpa_printf(MSG_DEBUG
, "IEEE 802.11: Ignored Action "
3429 "frame (category=%u) from unassociated STA " MACSTR
,
3430 mgmt
->u
.action
.category
, MAC2STR(mgmt
->sa
));
3434 #ifdef CONFIG_IEEE80211W
3435 if (sta
&& (sta
->flags
& WLAN_STA_MFP
) &&
3436 !(mgmt
->frame_control
& host_to_le16(WLAN_FC_ISWEP
)) &&
3437 robust_action_frame(mgmt
->u
.action
.category
)) {
3438 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
3439 HOSTAPD_LEVEL_DEBUG
,
3440 "Dropped unprotected Robust Action frame from "
3444 #endif /* CONFIG_IEEE80211W */
3447 u16 fc
= le_to_host16(mgmt
->frame_control
);
3448 u16 seq_ctrl
= le_to_host16(mgmt
->seq_ctrl
);
3450 if ((fc
& WLAN_FC_RETRY
) &&
3451 sta
->last_seq_ctrl
!= WLAN_INVALID_MGMT_SEQ
&&
3452 sta
->last_seq_ctrl
== seq_ctrl
&&
3453 sta
->last_subtype
== WLAN_FC_STYPE_ACTION
) {
3454 hostapd_logger(hapd
, sta
->addr
,
3455 HOSTAPD_MODULE_IEEE80211
,
3456 HOSTAPD_LEVEL_DEBUG
,
3457 "Drop repeated action frame seq_ctrl=0x%x",
3462 sta
->last_seq_ctrl
= seq_ctrl
;
3463 sta
->last_subtype
= WLAN_FC_STYPE_ACTION
;
3466 switch (mgmt
->u
.action
.category
) {
3467 #ifdef CONFIG_IEEE80211R_AP
3468 case WLAN_ACTION_FT
:
3470 wpa_ft_action_rx(sta
->wpa_sm
, (u8
*) &mgmt
->u
.action
,
3471 len
- IEEE80211_HDRLEN
))
3474 #endif /* CONFIG_IEEE80211R_AP */
3475 case WLAN_ACTION_WMM
:
3476 hostapd_wmm_action(hapd
, mgmt
, len
);
3478 #ifdef CONFIG_IEEE80211W
3479 case WLAN_ACTION_SA_QUERY
:
3480 return hostapd_sa_query_action(hapd
, mgmt
, len
);
3481 #endif /* CONFIG_IEEE80211W */
3482 #ifdef CONFIG_WNM_AP
3483 case WLAN_ACTION_WNM
:
3484 ieee802_11_rx_wnm_action_ap(hapd
, mgmt
, len
);
3486 #endif /* CONFIG_WNM_AP */
3488 case WLAN_ACTION_FST
:
3489 if (hapd
->iface
->fst
)
3490 fst_rx_action(hapd
->iface
->fst
, mgmt
, len
);
3492 wpa_printf(MSG_DEBUG
,
3493 "FST: Ignore FST Action frame - no FST attached");
3495 #endif /* CONFIG_FST */
3496 case WLAN_ACTION_PUBLIC
:
3497 case WLAN_ACTION_PROTECTED_DUAL
:
3498 #ifdef CONFIG_IEEE80211N
3499 if (len
>= IEEE80211_HDRLEN
+ 2 &&
3500 mgmt
->u
.action
.u
.public_action
.action
==
3501 WLAN_PA_20_40_BSS_COEX
) {
3502 wpa_printf(MSG_DEBUG
,
3503 "HT20/40 coex mgmt frame received from STA "
3504 MACSTR
, MAC2STR(mgmt
->sa
));
3505 hostapd_2040_coex_action(hapd
, mgmt
, len
);
3508 #endif /* CONFIG_IEEE80211N */
3510 if (len
>= IEEE80211_HDRLEN
+ 6 &&
3511 mgmt
->u
.action
.u
.vs_public_action
.action
==
3512 WLAN_PA_VENDOR_SPECIFIC
&&
3513 WPA_GET_BE24(mgmt
->u
.action
.u
.vs_public_action
.oui
) ==
3515 mgmt
->u
.action
.u
.vs_public_action
.variable
[0] ==
3517 const u8
*pos
, *end
;
3519 pos
= &mgmt
->u
.action
.u
.vs_public_action
.variable
[1];
3520 end
= ((const u8
*) mgmt
) + len
;
3521 hostapd_dpp_rx_action(hapd
, mgmt
->sa
, pos
, end
- pos
,
3525 if (len
>= IEEE80211_HDRLEN
+ 2 &&
3526 (mgmt
->u
.action
.u
.public_action
.action
==
3527 WLAN_PA_GAS_INITIAL_RESP
||
3528 mgmt
->u
.action
.u
.public_action
.action
==
3529 WLAN_PA_GAS_COMEBACK_RESP
)) {
3530 const u8
*pos
, *end
;
3532 pos
= &mgmt
->u
.action
.u
.public_action
.action
;
3533 end
= ((const u8
*) mgmt
) + len
;
3534 gas_query_ap_rx(hapd
->gas
, mgmt
->sa
,
3535 mgmt
->u
.action
.category
,
3536 pos
, end
- pos
, hapd
->iface
->freq
);
3539 #endif /* CONFIG_DPP */
3540 if (hapd
->public_action_cb
) {
3541 hapd
->public_action_cb(hapd
->public_action_cb_ctx
,
3545 if (hapd
->public_action_cb2
) {
3546 hapd
->public_action_cb2(hapd
->public_action_cb2_ctx
,
3550 if (hapd
->public_action_cb
|| hapd
->public_action_cb2
)
3553 case WLAN_ACTION_VENDOR_SPECIFIC
:
3554 if (hapd
->vendor_action_cb
) {
3555 if (hapd
->vendor_action_cb(hapd
->vendor_action_cb_ctx
,
3557 hapd
->iface
->freq
) == 0)
3561 case WLAN_ACTION_RADIO_MEASUREMENT
:
3562 hostapd_handle_radio_measurement(hapd
, (const u8
*) mgmt
, len
);
3566 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
3567 HOSTAPD_LEVEL_DEBUG
,
3568 "handle_action - unknown action category %d or invalid "
3570 mgmt
->u
.action
.category
);
3571 if (!is_multicast_ether_addr(mgmt
->da
) &&
3572 !(mgmt
->u
.action
.category
& 0x80) &&
3573 !is_multicast_ether_addr(mgmt
->sa
)) {
3574 struct ieee80211_mgmt
*resp
;
3577 * IEEE 802.11-REVma/D9.0 - 7.3.1.11
3578 * Return the Action frame to the source without change
3579 * except that MSB of the Category set to 1.
3581 wpa_printf(MSG_DEBUG
, "IEEE 802.11: Return unknown Action "
3582 "frame back to sender");
3583 resp
= os_memdup(mgmt
, len
);
3586 os_memcpy(resp
->da
, resp
->sa
, ETH_ALEN
);
3587 os_memcpy(resp
->sa
, hapd
->own_addr
, ETH_ALEN
);
3588 os_memcpy(resp
->bssid
, hapd
->own_addr
, ETH_ALEN
);
3589 resp
->u
.action
.category
|= 0x80;
3591 if (hostapd_drv_send_mlme(hapd
, resp
, len
, 0) < 0) {
3592 wpa_printf(MSG_ERROR
, "IEEE 802.11: Failed to send "
3603 * ieee802_11_mgmt - process incoming IEEE 802.11 management frames
3604 * @hapd: hostapd BSS data structure (the BSS to which the management frame was
3606 * @buf: management frame data (starting from IEEE 802.11 header)
3607 * @len: length of frame data in octets
3608 * @fi: meta data about received frame (signal level, etc.)
3610 * Process all incoming IEEE 802.11 management frames. This will be called for
3611 * each frame received from the kernel driver through wlan#ap interface. In
3612 * addition, it can be called to re-inserted pending frames (e.g., when using
3613 * external RADIUS server as an MAC ACL).
3615 int ieee802_11_mgmt(struct hostapd_data
*hapd
, const u8
*buf
, size_t len
,
3616 struct hostapd_frame_info
*fi
)
3618 struct ieee80211_mgmt
*mgmt
;
3625 mgmt
= (struct ieee80211_mgmt
*) buf
;
3626 fc
= le_to_host16(mgmt
->frame_control
);
3627 stype
= WLAN_FC_GET_STYPE(fc
);
3629 if (stype
== WLAN_FC_STYPE_BEACON
) {
3630 handle_beacon(hapd
, mgmt
, len
, fi
);
3634 if (!is_broadcast_ether_addr(mgmt
->bssid
) &&
3636 /* Invitation responses can be sent with the peer MAC as BSSID */
3637 !((hapd
->conf
->p2p
& P2P_GROUP_OWNER
) &&
3638 stype
== WLAN_FC_STYPE_ACTION
) &&
3639 #endif /* CONFIG_P2P */
3641 !(hapd
->conf
->mesh
& MESH_ENABLED
) &&
3642 #endif /* CONFIG_MESH */
3643 os_memcmp(mgmt
->bssid
, hapd
->own_addr
, ETH_ALEN
) != 0) {
3644 wpa_printf(MSG_INFO
, "MGMT: BSSID=" MACSTR
" not our address",
3645 MAC2STR(mgmt
->bssid
));
3650 if (stype
== WLAN_FC_STYPE_PROBE_REQ
) {
3651 handle_probe_req(hapd
, mgmt
, len
, fi
->ssi_signal
);
3655 if ((!is_broadcast_ether_addr(mgmt
->da
) ||
3656 stype
!= WLAN_FC_STYPE_ACTION
) &&
3657 os_memcmp(mgmt
->da
, hapd
->own_addr
, ETH_ALEN
) != 0) {
3658 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
3659 HOSTAPD_LEVEL_DEBUG
,
3660 "MGMT: DA=" MACSTR
" not our address",
3665 if (hapd
->iconf
->track_sta_max_num
)
3666 sta_track_add(hapd
->iface
, mgmt
->sa
, fi
->ssi_signal
);
3669 case WLAN_FC_STYPE_AUTH
:
3670 wpa_printf(MSG_DEBUG
, "mgmt::auth");
3671 handle_auth(hapd
, mgmt
, len
);
3674 case WLAN_FC_STYPE_ASSOC_REQ
:
3675 wpa_printf(MSG_DEBUG
, "mgmt::assoc_req");
3676 handle_assoc(hapd
, mgmt
, len
, 0);
3679 case WLAN_FC_STYPE_REASSOC_REQ
:
3680 wpa_printf(MSG_DEBUG
, "mgmt::reassoc_req");
3681 handle_assoc(hapd
, mgmt
, len
, 1);
3684 case WLAN_FC_STYPE_DISASSOC
:
3685 wpa_printf(MSG_DEBUG
, "mgmt::disassoc");
3686 handle_disassoc(hapd
, mgmt
, len
);
3689 case WLAN_FC_STYPE_DEAUTH
:
3690 wpa_msg(hapd
->msg_ctx
, MSG_DEBUG
, "mgmt::deauth");
3691 handle_deauth(hapd
, mgmt
, len
);
3694 case WLAN_FC_STYPE_ACTION
:
3695 wpa_printf(MSG_DEBUG
, "mgmt::action");
3696 ret
= handle_action(hapd
, mgmt
, len
);
3699 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
3700 HOSTAPD_LEVEL_DEBUG
,
3701 "unknown mgmt frame subtype %d", stype
);
3709 static void handle_auth_cb(struct hostapd_data
*hapd
,
3710 const struct ieee80211_mgmt
*mgmt
,
3713 u16 auth_alg
, auth_transaction
, status_code
;
3714 struct sta_info
*sta
;
3716 sta
= ap_get_sta(hapd
, mgmt
->da
);
3718 wpa_printf(MSG_INFO
, "handle_auth_cb: STA " MACSTR
" not found",
3723 auth_alg
= le_to_host16(mgmt
->u
.auth
.auth_alg
);
3724 auth_transaction
= le_to_host16(mgmt
->u
.auth
.auth_transaction
);
3725 status_code
= le_to_host16(mgmt
->u
.auth
.status_code
);
3728 hostapd_logger(hapd
, mgmt
->da
, HOSTAPD_MODULE_IEEE80211
,
3729 HOSTAPD_LEVEL_NOTICE
,
3730 "did not acknowledge authentication response");
3734 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.auth
)) {
3735 wpa_printf(MSG_INFO
, "handle_auth_cb - too short payload (len=%lu)",
3736 (unsigned long) len
);
3740 if (status_code
== WLAN_STATUS_SUCCESS
&&
3741 ((auth_alg
== WLAN_AUTH_OPEN
&& auth_transaction
== 2) ||
3742 (auth_alg
== WLAN_AUTH_SHARED_KEY
&& auth_transaction
== 4))) {
3743 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
3744 HOSTAPD_LEVEL_INFO
, "authenticated");
3745 sta
->flags
|= WLAN_STA_AUTH
;
3746 if (sta
->added_unassoc
)
3747 hostapd_set_sta_flags(hapd
, sta
);
3752 if (status_code
!= WLAN_STATUS_SUCCESS
&& sta
->added_unassoc
) {
3753 hostapd_drv_sta_remove(hapd
, sta
->addr
);
3754 sta
->added_unassoc
= 0;
3759 static void hostapd_set_wds_encryption(struct hostapd_data
*hapd
,
3760 struct sta_info
*sta
,
3764 struct hostapd_ssid
*ssid
= &hapd
->conf
->ssid
;
3766 if (hapd
->conf
->ieee802_1x
|| hapd
->conf
->wpa
)
3769 for (i
= 0; i
< 4; i
++) {
3770 if (ssid
->wep
.key
[i
] &&
3771 hostapd_drv_set_key(ifname_wds
, hapd
, WPA_ALG_WEP
, NULL
, i
,
3772 i
== ssid
->wep
.idx
, NULL
, 0,
3773 ssid
->wep
.key
[i
], ssid
->wep
.len
[i
])) {
3774 wpa_printf(MSG_WARNING
,
3775 "Could not set WEP keys for WDS interface; %s",
3783 static void handle_assoc_cb(struct hostapd_data
*hapd
,
3784 const struct ieee80211_mgmt
*mgmt
,
3785 size_t len
, int reassoc
, int ok
)
3788 struct sta_info
*sta
;
3791 sta
= ap_get_sta(hapd
, mgmt
->da
);
3793 wpa_printf(MSG_INFO
, "handle_assoc_cb: STA " MACSTR
" not found",
3798 if (len
< IEEE80211_HDRLEN
+ (reassoc
? sizeof(mgmt
->u
.reassoc_resp
) :
3799 sizeof(mgmt
->u
.assoc_resp
))) {
3800 wpa_printf(MSG_INFO
,
3801 "handle_assoc_cb(reassoc=%d) - too short payload (len=%lu)",
3802 reassoc
, (unsigned long) len
);
3803 hostapd_drv_sta_remove(hapd
, sta
->addr
);
3808 status
= le_to_host16(mgmt
->u
.reassoc_resp
.status_code
);
3810 status
= le_to_host16(mgmt
->u
.assoc_resp
.status_code
);
3813 hostapd_logger(hapd
, mgmt
->da
, HOSTAPD_MODULE_IEEE80211
,
3814 HOSTAPD_LEVEL_DEBUG
,
3815 "did not acknowledge association response");
3816 sta
->flags
&= ~WLAN_STA_ASSOC_REQ_OK
;
3817 /* The STA is added only in case of SUCCESS */
3818 if (status
== WLAN_STATUS_SUCCESS
)
3819 hostapd_drv_sta_remove(hapd
, sta
->addr
);
3824 if (status
!= WLAN_STATUS_SUCCESS
)
3827 /* Stop previous accounting session, if one is started, and allocate
3828 * new session id for the new session. */
3829 accounting_sta_stop(hapd
, sta
);
3831 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
3833 "associated (aid %d)",
3836 if (sta
->flags
& WLAN_STA_ASSOC
)
3838 sta
->flags
|= WLAN_STA_ASSOC
;
3839 sta
->flags
&= ~WLAN_STA_WNM_SLEEP_MODE
;
3840 if ((!hapd
->conf
->ieee802_1x
&& !hapd
->conf
->wpa
&&
3841 !hapd
->conf
->osen
) ||
3842 sta
->auth_alg
== WLAN_AUTH_FILS_SK
||
3843 sta
->auth_alg
== WLAN_AUTH_FILS_SK_PFS
||
3844 sta
->auth_alg
== WLAN_AUTH_FILS_PK
||
3845 sta
->auth_alg
== WLAN_AUTH_FT
) {
3847 * Open, static WEP, FT protocol, or FILS; no separate
3848 * authorization step.
3850 ap_sta_set_authorized(hapd
, sta
, 1);
3854 mlme_reassociate_indication(hapd
, sta
);
3856 mlme_associate_indication(hapd
, sta
);
3858 #ifdef CONFIG_IEEE80211W
3859 sta
->sa_query_timed_out
= 0;
3860 #endif /* CONFIG_IEEE80211W */
3862 if (sta
->eapol_sm
== NULL
) {
3864 * This STA does not use RADIUS server for EAP authentication,
3865 * so bind it to the selected VLAN interface now, since the
3866 * interface selection is not going to change anymore.
3868 if (ap_sta_bind_vlan(hapd
, sta
) < 0)
3870 } else if (sta
->vlan_id
) {
3871 /* VLAN ID already set (e.g., by PMKSA caching), so bind STA */
3872 if (ap_sta_bind_vlan(hapd
, sta
) < 0)
3876 hostapd_set_sta_flags(hapd
, sta
);
3878 if (!(sta
->flags
& WLAN_STA_WDS
) && sta
->pending_wds_enable
) {
3879 wpa_printf(MSG_DEBUG
, "Enable 4-address WDS mode for STA "
3880 MACSTR
" based on pending request",
3881 MAC2STR(sta
->addr
));
3882 sta
->pending_wds_enable
= 0;
3883 sta
->flags
|= WLAN_STA_WDS
;
3886 if (sta
->flags
& WLAN_STA_WDS
) {
3888 char ifname_wds
[IFNAMSIZ
+ 1];
3890 wpa_printf(MSG_DEBUG
, "Reenable 4-address WDS mode for STA "
3892 MAC2STR(sta
->addr
), sta
->aid
);
3893 ret
= hostapd_set_wds_sta(hapd
, ifname_wds
, sta
->addr
,
3896 hostapd_set_wds_encryption(hapd
, sta
, ifname_wds
);
3899 if (sta
->auth_alg
== WLAN_AUTH_FT
)
3900 wpa_auth_sm_event(sta
->wpa_sm
, WPA_ASSOC_FT
);
3902 wpa_auth_sm_event(sta
->wpa_sm
, WPA_ASSOC
);
3903 hapd
->new_assoc_sta_cb(hapd
, sta
, !new_assoc
);
3904 ieee802_1x_notify_port_enabled(sta
->eapol_sm
, 1);
3907 if ((sta
->auth_alg
== WLAN_AUTH_FILS_SK
||
3908 sta
->auth_alg
== WLAN_AUTH_FILS_SK_PFS
||
3909 sta
->auth_alg
== WLAN_AUTH_FILS_PK
) &&
3910 fils_set_tk(sta
->wpa_sm
) < 0) {
3911 wpa_printf(MSG_DEBUG
, "FILS: TK configuration failed");
3912 ap_sta_disconnect(hapd
, sta
, sta
->addr
,
3913 WLAN_REASON_UNSPECIFIED
);
3916 #endif /* CONFIG_FILS */
3918 if (sta
->pending_eapol_rx
) {
3919 struct os_reltime now
, age
;
3921 os_get_reltime(&now
);
3922 os_reltime_sub(&now
, &sta
->pending_eapol_rx
->rx_time
, &age
);
3923 if (age
.sec
== 0 && age
.usec
< 200000) {
3924 wpa_printf(MSG_DEBUG
,
3925 "Process pending EAPOL frame that was received from " MACSTR
" just before association notification",
3926 MAC2STR(sta
->addr
));
3929 wpabuf_head(sta
->pending_eapol_rx
->buf
),
3930 wpabuf_len(sta
->pending_eapol_rx
->buf
));
3932 wpabuf_free(sta
->pending_eapol_rx
->buf
);
3933 os_free(sta
->pending_eapol_rx
);
3934 sta
->pending_eapol_rx
= NULL
;
3939 static void handle_deauth_cb(struct hostapd_data
*hapd
,
3940 const struct ieee80211_mgmt
*mgmt
,
3943 struct sta_info
*sta
;
3944 if (is_multicast_ether_addr(mgmt
->da
))
3946 sta
= ap_get_sta(hapd
, mgmt
->da
);
3948 wpa_printf(MSG_DEBUG
, "handle_deauth_cb: STA " MACSTR
3949 " not found", MAC2STR(mgmt
->da
));
3953 wpa_printf(MSG_DEBUG
, "STA " MACSTR
" acknowledged deauth",
3954 MAC2STR(sta
->addr
));
3956 wpa_printf(MSG_DEBUG
, "STA " MACSTR
" did not acknowledge "
3957 "deauth", MAC2STR(sta
->addr
));
3959 ap_sta_deauth_cb(hapd
, sta
);
3963 static void handle_disassoc_cb(struct hostapd_data
*hapd
,
3964 const struct ieee80211_mgmt
*mgmt
,
3967 struct sta_info
*sta
;
3968 if (is_multicast_ether_addr(mgmt
->da
))
3970 sta
= ap_get_sta(hapd
, mgmt
->da
);
3972 wpa_printf(MSG_DEBUG
, "handle_disassoc_cb: STA " MACSTR
3973 " not found", MAC2STR(mgmt
->da
));
3977 wpa_printf(MSG_DEBUG
, "STA " MACSTR
" acknowledged disassoc",
3978 MAC2STR(sta
->addr
));
3980 wpa_printf(MSG_DEBUG
, "STA " MACSTR
" did not acknowledge "
3981 "disassoc", MAC2STR(sta
->addr
));
3983 ap_sta_disassoc_cb(hapd
, sta
);
3987 static void handle_action_cb(struct hostapd_data
*hapd
,
3988 const struct ieee80211_mgmt
*mgmt
,
3991 struct sta_info
*sta
;
3992 const struct rrm_measurement_report_element
*report
;
3994 if (is_multicast_ether_addr(mgmt
->da
))
3997 if (len
>= IEEE80211_HDRLEN
+ 6 &&
3998 mgmt
->u
.action
.category
== WLAN_ACTION_PUBLIC
&&
3999 mgmt
->u
.action
.u
.vs_public_action
.action
==
4000 WLAN_PA_VENDOR_SPECIFIC
&&
4001 WPA_GET_BE24(mgmt
->u
.action
.u
.vs_public_action
.oui
) ==
4003 mgmt
->u
.action
.u
.vs_public_action
.variable
[0] ==
4005 const u8
*pos
, *end
;
4007 pos
= &mgmt
->u
.action
.u
.vs_public_action
.variable
[1];
4008 end
= ((const u8
*) mgmt
) + len
;
4009 hostapd_dpp_tx_status(hapd
, mgmt
->da
, pos
, end
- pos
, ok
);
4012 if (len
>= IEEE80211_HDRLEN
+ 2 &&
4013 mgmt
->u
.action
.category
== WLAN_ACTION_PUBLIC
&&
4014 (mgmt
->u
.action
.u
.public_action
.action
==
4015 WLAN_PA_GAS_INITIAL_REQ
||
4016 mgmt
->u
.action
.u
.public_action
.action
==
4017 WLAN_PA_GAS_COMEBACK_REQ
)) {
4018 const u8
*pos
, *end
;
4020 pos
= mgmt
->u
.action
.u
.public_action
.variable
;
4021 end
= ((const u8
*) mgmt
) + len
;
4022 gas_query_ap_tx_status(hapd
->gas
, mgmt
->da
, pos
, end
- pos
, ok
);
4025 #endif /* CONFIG_DPP */
4026 sta
= ap_get_sta(hapd
, mgmt
->da
);
4028 wpa_printf(MSG_DEBUG
, "handle_action_cb: STA " MACSTR
4029 " not found", MAC2STR(mgmt
->da
));
4033 if (len
< 24 + 5 + sizeof(*report
))
4035 report
= (const struct rrm_measurement_report_element
*)
4036 &mgmt
->u
.action
.u
.rrm
.variable
[2];
4037 if (mgmt
->u
.action
.category
== WLAN_ACTION_RADIO_MEASUREMENT
&&
4038 mgmt
->u
.action
.u
.rrm
.action
== WLAN_RRM_RADIO_MEASUREMENT_REQUEST
&&
4039 report
->eid
== WLAN_EID_MEASURE_REQUEST
&&
4041 report
->type
== MEASURE_TYPE_BEACON
)
4042 hostapd_rrm_beacon_req_tx_status(hapd
, mgmt
, len
, ok
);
4047 * ieee802_11_mgmt_cb - Process management frame TX status callback
4048 * @hapd: hostapd BSS data structure (the BSS from which the management frame
4050 * @buf: management frame data (starting from IEEE 802.11 header)
4051 * @len: length of frame data in octets
4052 * @stype: management frame subtype from frame control field
4053 * @ok: Whether the frame was ACK'ed
4055 void ieee802_11_mgmt_cb(struct hostapd_data
*hapd
, const u8
*buf
, size_t len
,
4058 const struct ieee80211_mgmt
*mgmt
;
4059 mgmt
= (const struct ieee80211_mgmt
*) buf
;
4061 #ifdef CONFIG_TESTING_OPTIONS
4062 if (hapd
->ext_mgmt_frame_handling
) {
4063 wpa_msg(hapd
->msg_ctx
, MSG_INFO
, "MGMT-TX-STATUS stype=%u ok=%d",
4067 #endif /* CONFIG_TESTING_OPTIONS */
4070 case WLAN_FC_STYPE_AUTH
:
4071 wpa_printf(MSG_DEBUG
, "mgmt::auth cb");
4072 handle_auth_cb(hapd
, mgmt
, len
, ok
);
4074 case WLAN_FC_STYPE_ASSOC_RESP
:
4075 wpa_printf(MSG_DEBUG
, "mgmt::assoc_resp cb");
4076 handle_assoc_cb(hapd
, mgmt
, len
, 0, ok
);
4078 case WLAN_FC_STYPE_REASSOC_RESP
:
4079 wpa_printf(MSG_DEBUG
, "mgmt::reassoc_resp cb");
4080 handle_assoc_cb(hapd
, mgmt
, len
, 1, ok
);
4082 case WLAN_FC_STYPE_PROBE_RESP
:
4083 wpa_printf(MSG_EXCESSIVE
, "mgmt::proberesp cb ok=%d", ok
);
4085 case WLAN_FC_STYPE_DEAUTH
:
4086 wpa_printf(MSG_DEBUG
, "mgmt::deauth cb");
4087 handle_deauth_cb(hapd
, mgmt
, len
, ok
);
4089 case WLAN_FC_STYPE_DISASSOC
:
4090 wpa_printf(MSG_DEBUG
, "mgmt::disassoc cb");
4091 handle_disassoc_cb(hapd
, mgmt
, len
, ok
);
4093 case WLAN_FC_STYPE_ACTION
:
4094 wpa_printf(MSG_DEBUG
, "mgmt::action cb ok=%d", ok
);
4095 handle_action_cb(hapd
, mgmt
, len
, ok
);
4098 wpa_printf(MSG_INFO
, "unknown mgmt cb frame subtype %d", stype
);
4104 int ieee802_11_get_mib(struct hostapd_data
*hapd
, char *buf
, size_t buflen
)
4111 int ieee802_11_get_mib_sta(struct hostapd_data
*hapd
, struct sta_info
*sta
,
4112 char *buf
, size_t buflen
)
4119 void hostapd_tx_status(struct hostapd_data
*hapd
, const u8
*addr
,
4120 const u8
*buf
, size_t len
, int ack
)
4122 struct sta_info
*sta
;
4123 struct hostapd_iface
*iface
= hapd
->iface
;
4125 sta
= ap_get_sta(hapd
, addr
);
4126 if (sta
== NULL
&& iface
->num_bss
> 1) {
4128 for (j
= 0; j
< iface
->num_bss
; j
++) {
4129 hapd
= iface
->bss
[j
];
4130 sta
= ap_get_sta(hapd
, addr
);
4135 if (sta
== NULL
|| !(sta
->flags
& WLAN_STA_ASSOC
))
4137 if (sta
->flags
& WLAN_STA_PENDING_POLL
) {
4138 wpa_printf(MSG_DEBUG
, "STA " MACSTR
" %s pending "
4139 "activity poll", MAC2STR(sta
->addr
),
4140 ack
? "ACKed" : "did not ACK");
4142 sta
->flags
&= ~WLAN_STA_PENDING_POLL
;
4145 ieee802_1x_tx_status(hapd
, sta
, buf
, len
, ack
);
4149 void hostapd_eapol_tx_status(struct hostapd_data
*hapd
, const u8
*dst
,
4150 const u8
*data
, size_t len
, int ack
)
4152 struct sta_info
*sta
;
4153 struct hostapd_iface
*iface
= hapd
->iface
;
4155 sta
= ap_get_sta(hapd
, dst
);
4156 if (sta
== NULL
&& iface
->num_bss
> 1) {
4158 for (j
= 0; j
< iface
->num_bss
; j
++) {
4159 hapd
= iface
->bss
[j
];
4160 sta
= ap_get_sta(hapd
, dst
);
4165 if (sta
== NULL
|| !(sta
->flags
& WLAN_STA_ASSOC
)) {
4166 wpa_printf(MSG_DEBUG
, "Ignore TX status for Data frame to STA "
4167 MACSTR
" that is not currently associated",
4172 ieee802_1x_eapol_tx_status(hapd
, sta
, data
, len
, ack
);
4176 void hostapd_client_poll_ok(struct hostapd_data
*hapd
, const u8
*addr
)
4178 struct sta_info
*sta
;
4179 struct hostapd_iface
*iface
= hapd
->iface
;
4181 sta
= ap_get_sta(hapd
, addr
);
4182 if (sta
== NULL
&& iface
->num_bss
> 1) {
4184 for (j
= 0; j
< iface
->num_bss
; j
++) {
4185 hapd
= iface
->bss
[j
];
4186 sta
= ap_get_sta(hapd
, addr
);
4193 wpa_msg(hapd
->msg_ctx
, MSG_INFO
, AP_STA_POLL_OK MACSTR
,
4194 MAC2STR(sta
->addr
));
4195 if (!(sta
->flags
& WLAN_STA_PENDING_POLL
))
4198 wpa_printf(MSG_DEBUG
, "STA " MACSTR
" ACKed pending "
4199 "activity poll", MAC2STR(sta
->addr
));
4200 sta
->flags
&= ~WLAN_STA_PENDING_POLL
;
4204 void ieee802_11_rx_from_unknown(struct hostapd_data
*hapd
, const u8
*src
,
4207 struct sta_info
*sta
;
4209 sta
= ap_get_sta(hapd
, src
);
4211 ((sta
->flags
& WLAN_STA_ASSOC
) ||
4212 ((sta
->flags
& WLAN_STA_ASSOC_REQ_OK
) && wds
))) {
4213 if (!hapd
->conf
->wds_sta
)
4216 if ((sta
->flags
& (WLAN_STA_ASSOC
| WLAN_STA_ASSOC_REQ_OK
)) ==
4217 WLAN_STA_ASSOC_REQ_OK
) {
4218 wpa_printf(MSG_DEBUG
,
4219 "Postpone 4-address WDS mode enabling for STA "
4220 MACSTR
" since TX status for AssocResp is not yet known",
4221 MAC2STR(sta
->addr
));
4222 sta
->pending_wds_enable
= 1;
4226 if (wds
&& !(sta
->flags
& WLAN_STA_WDS
)) {
4228 char ifname_wds
[IFNAMSIZ
+ 1];
4230 wpa_printf(MSG_DEBUG
, "Enable 4-address WDS mode for "
4231 "STA " MACSTR
" (aid %u)",
4232 MAC2STR(sta
->addr
), sta
->aid
);
4233 sta
->flags
|= WLAN_STA_WDS
;
4234 ret
= hostapd_set_wds_sta(hapd
, ifname_wds
,
4235 sta
->addr
, sta
->aid
, 1);
4237 hostapd_set_wds_encryption(hapd
, sta
,
4243 wpa_printf(MSG_DEBUG
, "Data/PS-poll frame from not associated STA "
4244 MACSTR
, MAC2STR(src
));
4245 if (is_multicast_ether_addr(src
)) {
4246 /* Broadcast bit set in SA?! Ignore the frame silently. */
4250 if (sta
&& (sta
->flags
& WLAN_STA_ASSOC_REQ_OK
)) {
4251 wpa_printf(MSG_DEBUG
, "Association Response to the STA has "
4252 "already been sent, but no TX status yet known - "
4253 "ignore Class 3 frame issue with " MACSTR
,
4258 if (sta
&& (sta
->flags
& WLAN_STA_AUTH
))
4259 hostapd_drv_sta_disassoc(
4261 WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA
);
4263 hostapd_drv_sta_deauth(
4265 WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA
);
4269 #endif /* CONFIG_NATIVE_WINDOWS */