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/sha384.h"
18 #include "crypto/sha512.h"
19 #include "crypto/random.h"
20 #include "common/ieee802_11_defs.h"
21 #include "common/ieee802_11_common.h"
22 #include "common/wpa_ctrl.h"
23 #include "common/sae.h"
24 #include "radius/radius.h"
25 #include "radius/radius_client.h"
31 #include "ieee802_11_auth.h"
33 #include "ieee802_1x.h"
35 #include "pmksa_cache_auth.h"
38 #include "accounting.h"
39 #include "ap_config.h"
41 #include "p2p_hostapd.h"
42 #include "ap_drv_ops.h"
44 #include "hw_features.h"
45 #include "ieee802_11.h"
51 #include "dpp_hostapd.h"
52 #include "gas_query_ap.h"
56 static struct wpabuf
*
57 prepare_auth_resp_fils(struct hostapd_data
*hapd
,
58 struct sta_info
*sta
, u16
*resp
,
59 struct rsn_pmksa_cache_entry
*pmksa
,
60 struct wpabuf
*erp_resp
,
61 const u8
*msk
, size_t msk_len
,
63 #endif /* CONFIG_FILS */
65 u8
* hostapd_eid_supp_rates(struct hostapd_data
*hapd
, u8
*eid
)
70 if (hapd
->iface
->current_rates
== NULL
)
73 *pos
++ = WLAN_EID_SUPP_RATES
;
74 num
= hapd
->iface
->num_rates
;
75 if (hapd
->iconf
->ieee80211n
&& hapd
->iconf
->require_ht
)
77 if (hapd
->iconf
->ieee80211ac
&& hapd
->iconf
->require_vht
)
80 /* rest of the rates are encoded in Extended supported
86 for (i
= 0, count
= 0; i
< hapd
->iface
->num_rates
&& count
< num
;
89 *pos
= hapd
->iface
->current_rates
[i
].rate
/ 5;
90 if (hapd
->iface
->current_rates
[i
].flags
& HOSTAPD_RATE_BASIC
)
95 if (hapd
->iconf
->ieee80211n
&& hapd
->iconf
->require_ht
&& count
< 8) {
97 *pos
++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_HT_PHY
;
100 if (hapd
->iconf
->ieee80211ac
&& hapd
->iconf
->require_vht
&& count
< 8) {
102 *pos
++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_VHT_PHY
;
109 u8
* hostapd_eid_ext_supp_rates(struct hostapd_data
*hapd
, u8
*eid
)
114 if (hapd
->iface
->current_rates
== NULL
)
117 num
= hapd
->iface
->num_rates
;
118 if (hapd
->iconf
->ieee80211n
&& hapd
->iconf
->require_ht
)
120 if (hapd
->iconf
->ieee80211ac
&& hapd
->iconf
->require_vht
)
126 *pos
++ = WLAN_EID_EXT_SUPP_RATES
;
128 for (i
= 0, count
= 0; i
< hapd
->iface
->num_rates
&& count
< num
+ 8;
132 continue; /* already in SuppRates IE */
133 *pos
= hapd
->iface
->current_rates
[i
].rate
/ 5;
134 if (hapd
->iface
->current_rates
[i
].flags
& HOSTAPD_RATE_BASIC
)
139 if (hapd
->iconf
->ieee80211n
&& hapd
->iconf
->require_ht
) {
142 *pos
++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_HT_PHY
;
145 if (hapd
->iconf
->ieee80211ac
&& hapd
->iconf
->require_vht
) {
148 *pos
++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_VHT_PHY
;
155 u16
hostapd_own_capab_info(struct hostapd_data
*hapd
)
157 int capab
= WLAN_CAPABILITY_ESS
;
162 /* Check if any of configured channels require DFS */
163 dfs
= hostapd_is_dfs_required(hapd
->iface
);
165 wpa_printf(MSG_WARNING
, "Failed to check if DFS is required; ret=%d",
170 if (hapd
->iface
->num_sta_no_short_preamble
== 0 &&
171 hapd
->iconf
->preamble
== SHORT_PREAMBLE
)
172 capab
|= WLAN_CAPABILITY_SHORT_PREAMBLE
;
174 privacy
= hapd
->conf
->ssid
.wep
.keys_set
;
176 if (hapd
->conf
->ieee802_1x
&&
177 (hapd
->conf
->default_wep_key_len
||
178 hapd
->conf
->individual_wep_key_len
))
185 if (hapd
->conf
->osen
)
187 #endif /* CONFIG_HS20 */
190 capab
|= WLAN_CAPABILITY_PRIVACY
;
192 if (hapd
->iface
->current_mode
&&
193 hapd
->iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211G
&&
194 hapd
->iface
->num_sta_no_short_slot_time
== 0)
195 capab
|= WLAN_CAPABILITY_SHORT_SLOT_TIME
;
198 * Currently, Spectrum Management capability bit is set when directly
199 * requested in configuration by spectrum_mgmt_required or when AP is
200 * running on DFS channel.
201 * TODO: Also consider driver support for TPC to set Spectrum Mgmt bit
203 if (hapd
->iface
->current_mode
&&
204 hapd
->iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211A
&&
205 (hapd
->iconf
->spectrum_mgmt_required
|| dfs
))
206 capab
|= WLAN_CAPABILITY_SPECTRUM_MGMT
;
208 for (i
= 0; i
< RRM_CAPABILITIES_IE_LEN
; i
++) {
209 if (hapd
->conf
->radio_measurements
[i
]) {
210 capab
|= IEEE80211_CAP_RRM
;
219 #ifndef CONFIG_NO_RC4
220 static u16
auth_shared_key(struct hostapd_data
*hapd
, struct sta_info
*sta
,
221 u16 auth_transaction
, const u8
*challenge
,
224 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
226 "authentication (shared key, transaction %d)",
229 if (auth_transaction
== 1) {
230 if (!sta
->challenge
) {
231 /* Generate a pseudo-random challenge */
234 sta
->challenge
= os_zalloc(WLAN_AUTH_CHALLENGE_LEN
);
235 if (sta
->challenge
== NULL
)
236 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
238 if (os_get_random(key
, sizeof(key
)) < 0) {
239 os_free(sta
->challenge
);
240 sta
->challenge
= NULL
;
241 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
244 rc4_skip(key
, sizeof(key
), 0,
245 sta
->challenge
, WLAN_AUTH_CHALLENGE_LEN
);
250 if (auth_transaction
!= 3)
251 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
254 if (!iswep
|| !sta
->challenge
|| !challenge
||
255 os_memcmp_const(sta
->challenge
, challenge
,
256 WLAN_AUTH_CHALLENGE_LEN
)) {
257 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
259 "shared key authentication - invalid "
260 "challenge-response");
261 return WLAN_STATUS_CHALLENGE_FAIL
;
264 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
266 "authentication OK (shared key)");
267 sta
->flags
|= WLAN_STA_AUTH
;
268 wpa_auth_sm_event(sta
->wpa_sm
, WPA_AUTH
);
269 os_free(sta
->challenge
);
270 sta
->challenge
= NULL
;
274 #endif /* CONFIG_NO_RC4 */
277 static int send_auth_reply(struct hostapd_data
*hapd
,
278 const u8
*dst
, const u8
*bssid
,
279 u16 auth_alg
, u16 auth_transaction
, u16 resp
,
280 const u8
*ies
, size_t ies_len
)
282 struct ieee80211_mgmt
*reply
;
285 int reply_res
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
287 rlen
= IEEE80211_HDRLEN
+ sizeof(reply
->u
.auth
) + ies_len
;
288 buf
= os_zalloc(rlen
);
292 reply
= (struct ieee80211_mgmt
*) buf
;
293 reply
->frame_control
= IEEE80211_FC(WLAN_FC_TYPE_MGMT
,
295 os_memcpy(reply
->da
, dst
, ETH_ALEN
);
296 os_memcpy(reply
->sa
, hapd
->own_addr
, ETH_ALEN
);
297 os_memcpy(reply
->bssid
, bssid
, ETH_ALEN
);
299 reply
->u
.auth
.auth_alg
= host_to_le16(auth_alg
);
300 reply
->u
.auth
.auth_transaction
= host_to_le16(auth_transaction
);
301 reply
->u
.auth
.status_code
= host_to_le16(resp
);
304 os_memcpy(reply
->u
.auth
.variable
, ies
, ies_len
);
306 wpa_printf(MSG_DEBUG
, "authentication reply: STA=" MACSTR
307 " auth_alg=%d auth_transaction=%d resp=%d (IE len=%lu)",
308 MAC2STR(dst
), auth_alg
, auth_transaction
,
309 resp
, (unsigned long) ies_len
);
310 if (hostapd_drv_send_mlme(hapd
, reply
, rlen
, 0) < 0)
311 wpa_printf(MSG_INFO
, "send_auth_reply: send failed");
313 reply_res
= WLAN_STATUS_SUCCESS
;
321 #ifdef CONFIG_IEEE80211R_AP
322 static void handle_auth_ft_finish(void *ctx
, const u8
*dst
, const u8
*bssid
,
323 u16 auth_transaction
, u16 status
,
324 const u8
*ies
, size_t ies_len
)
326 struct hostapd_data
*hapd
= ctx
;
327 struct sta_info
*sta
;
330 reply_res
= send_auth_reply(hapd
, dst
, bssid
, WLAN_AUTH_FT
,
331 auth_transaction
, status
, ies
, ies_len
);
333 sta
= ap_get_sta(hapd
, dst
);
337 if (sta
->added_unassoc
&& (reply_res
!= WLAN_STATUS_SUCCESS
||
338 status
!= WLAN_STATUS_SUCCESS
)) {
339 hostapd_drv_sta_remove(hapd
, sta
->addr
);
340 sta
->added_unassoc
= 0;
344 if (status
!= WLAN_STATUS_SUCCESS
)
347 hostapd_logger(hapd
, dst
, HOSTAPD_MODULE_IEEE80211
,
348 HOSTAPD_LEVEL_DEBUG
, "authentication OK (FT)");
349 sta
->flags
|= WLAN_STA_AUTH
;
350 mlme_authenticate_indication(hapd
, sta
);
352 #endif /* CONFIG_IEEE80211R_AP */
357 static struct wpabuf
* auth_build_sae_commit(struct hostapd_data
*hapd
,
358 struct sta_info
*sta
, int update
)
361 const char *password
;
363 password
= hapd
->conf
->sae_password
;
365 password
= hapd
->conf
->ssid
.wpa_passphrase
;
367 wpa_printf(MSG_DEBUG
, "SAE: No password available");
372 sae_prepare_commit(hapd
->own_addr
, sta
->addr
,
373 (u8
*) password
, os_strlen(password
),
375 wpa_printf(MSG_DEBUG
, "SAE: Could not pick PWE");
379 buf
= wpabuf_alloc(SAE_COMMIT_MAX_LEN
);
382 sae_write_commit(sta
->sae
, buf
, sta
->sae
->tmp
?
383 sta
->sae
->tmp
->anti_clogging_token
: NULL
);
389 static struct wpabuf
* auth_build_sae_confirm(struct hostapd_data
*hapd
,
390 struct sta_info
*sta
)
394 buf
= wpabuf_alloc(SAE_CONFIRM_MAX_LEN
);
398 sae_write_confirm(sta
->sae
, buf
);
404 static int auth_sae_send_commit(struct hostapd_data
*hapd
,
405 struct sta_info
*sta
,
406 const u8
*bssid
, int update
)
411 data
= auth_build_sae_commit(hapd
, sta
, update
);
413 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
415 reply_res
= send_auth_reply(hapd
, sta
->addr
, bssid
, WLAN_AUTH_SAE
, 1,
416 WLAN_STATUS_SUCCESS
, wpabuf_head(data
),
425 static int auth_sae_send_confirm(struct hostapd_data
*hapd
,
426 struct sta_info
*sta
,
432 data
= auth_build_sae_confirm(hapd
, sta
);
434 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
436 reply_res
= send_auth_reply(hapd
, sta
->addr
, bssid
, WLAN_AUTH_SAE
, 2,
437 WLAN_STATUS_SUCCESS
, wpabuf_head(data
),
446 static int use_sae_anti_clogging(struct hostapd_data
*hapd
)
448 struct sta_info
*sta
;
449 unsigned int open
= 0;
451 if (hapd
->conf
->sae_anti_clogging_threshold
== 0)
454 for (sta
= hapd
->sta_list
; sta
; sta
= sta
->next
) {
457 if (sta
->sae
->state
!= SAE_COMMITTED
&&
458 sta
->sae
->state
!= SAE_CONFIRMED
)
461 if (open
>= hapd
->conf
->sae_anti_clogging_threshold
)
469 static int check_sae_token(struct hostapd_data
*hapd
, const u8
*addr
,
470 const u8
*token
, size_t token_len
)
472 u8 mac
[SHA256_MAC_LEN
];
474 if (token_len
!= SHA256_MAC_LEN
)
476 if (hmac_sha256(hapd
->sae_token_key
, sizeof(hapd
->sae_token_key
),
477 addr
, ETH_ALEN
, mac
) < 0 ||
478 os_memcmp_const(token
, mac
, SHA256_MAC_LEN
) != 0)
485 static struct wpabuf
* auth_build_token_req(struct hostapd_data
*hapd
,
486 int group
, const u8
*addr
)
490 struct os_reltime now
;
492 os_get_reltime(&now
);
493 if (!os_reltime_initialized(&hapd
->last_sae_token_key_update
) ||
494 os_reltime_expired(&now
, &hapd
->last_sae_token_key_update
, 60)) {
495 if (random_get_bytes(hapd
->sae_token_key
,
496 sizeof(hapd
->sae_token_key
)) < 0)
498 wpa_hexdump(MSG_DEBUG
, "SAE: Updated token key",
499 hapd
->sae_token_key
, sizeof(hapd
->sae_token_key
));
500 hapd
->last_sae_token_key_update
= now
;
503 buf
= wpabuf_alloc(sizeof(le16
) + SHA256_MAC_LEN
);
507 wpabuf_put_le16(buf
, group
); /* Finite Cyclic Group */
509 token
= wpabuf_put(buf
, SHA256_MAC_LEN
);
510 hmac_sha256(hapd
->sae_token_key
, sizeof(hapd
->sae_token_key
),
511 addr
, ETH_ALEN
, token
);
517 static int sae_check_big_sync(struct hostapd_data
*hapd
, struct sta_info
*sta
)
519 if (sta
->sae
->sync
> hapd
->conf
->sae_sync
) {
520 sta
->sae
->state
= SAE_NOTHING
;
528 static void auth_sae_retransmit_timer(void *eloop_ctx
, void *eloop_data
)
530 struct hostapd_data
*hapd
= eloop_ctx
;
531 struct sta_info
*sta
= eloop_data
;
534 if (sae_check_big_sync(hapd
, sta
))
537 wpa_printf(MSG_DEBUG
, "SAE: Auth SAE retransmit timer for " MACSTR
538 " (sync=%d state=%d)",
539 MAC2STR(sta
->addr
), sta
->sae
->sync
, sta
->sae
->state
);
541 switch (sta
->sae
->state
) {
543 ret
= auth_sae_send_commit(hapd
, sta
, hapd
->own_addr
, 0);
544 eloop_register_timeout(0,
545 hapd
->dot11RSNASAERetransPeriod
* 1000,
546 auth_sae_retransmit_timer
, hapd
, sta
);
549 ret
= auth_sae_send_confirm(hapd
, sta
, hapd
->own_addr
);
550 eloop_register_timeout(0,
551 hapd
->dot11RSNASAERetransPeriod
* 1000,
552 auth_sae_retransmit_timer
, hapd
, sta
);
559 if (ret
!= WLAN_STATUS_SUCCESS
)
560 wpa_printf(MSG_INFO
, "SAE: Failed to retransmit: ret=%d", ret
);
564 void sae_clear_retransmit_timer(struct hostapd_data
*hapd
, struct sta_info
*sta
)
566 eloop_cancel_timeout(auth_sae_retransmit_timer
, hapd
, sta
);
570 static void sae_set_retransmit_timer(struct hostapd_data
*hapd
,
571 struct sta_info
*sta
)
573 if (!(hapd
->conf
->mesh
& MESH_ENABLED
))
576 eloop_cancel_timeout(auth_sae_retransmit_timer
, hapd
, sta
);
577 eloop_register_timeout(0, hapd
->dot11RSNASAERetransPeriod
* 1000,
578 auth_sae_retransmit_timer
, hapd
, sta
);
582 void sae_accept_sta(struct hostapd_data
*hapd
, struct sta_info
*sta
)
584 sta
->flags
|= WLAN_STA_AUTH
;
585 sta
->auth_alg
= WLAN_AUTH_SAE
;
586 mlme_authenticate_indication(hapd
, sta
);
587 wpa_auth_sm_event(sta
->wpa_sm
, WPA_AUTH
);
588 sta
->sae
->state
= SAE_ACCEPTED
;
589 wpa_auth_pmksa_add_sae(hapd
->wpa_auth
, sta
->addr
,
590 sta
->sae
->pmk
, sta
->sae
->pmkid
);
594 static int sae_sm_step(struct hostapd_data
*hapd
, struct sta_info
*sta
,
595 const u8
*bssid
, u8 auth_transaction
)
599 if (auth_transaction
!= 1 && auth_transaction
!= 2)
600 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
602 switch (sta
->sae
->state
) {
604 if (auth_transaction
== 1) {
605 ret
= auth_sae_send_commit(hapd
, sta
, bssid
, 1);
608 sta
->sae
->state
= SAE_COMMITTED
;
610 if (sae_process_commit(sta
->sae
) < 0)
611 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
614 * In mesh case, both Commit and Confirm can be sent
615 * immediately. In infrastructure BSS, only a single
616 * Authentication frame (Commit) is expected from the AP
617 * here and the second one (Confirm) will be sent once
618 * the STA has sent its second Authentication frame
621 if (hapd
->conf
->mesh
& MESH_ENABLED
) {
623 * Send both Commit and Confirm immediately
624 * based on SAE finite state machine
625 * Nothing -> Confirm transition.
627 ret
= auth_sae_send_confirm(hapd
, sta
, bssid
);
630 sta
->sae
->state
= SAE_CONFIRMED
;
633 * For infrastructure BSS, send only the Commit
634 * message now to get alternating sequence of
635 * Authentication frames between the AP and STA.
636 * Confirm will be sent in
637 * Committed -> Confirmed/Accepted transition
638 * when receiving Confirm from STA.
642 sae_set_retransmit_timer(hapd
, sta
);
644 hostapd_logger(hapd
, sta
->addr
,
645 HOSTAPD_MODULE_IEEE80211
,
647 "SAE confirm before commit");
651 sae_clear_retransmit_timer(hapd
, sta
);
652 if (auth_transaction
== 1) {
653 if (sae_process_commit(sta
->sae
) < 0)
654 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
656 ret
= auth_sae_send_confirm(hapd
, sta
, bssid
);
659 sta
->sae
->state
= SAE_CONFIRMED
;
661 sae_set_retransmit_timer(hapd
, sta
);
662 } else if (hapd
->conf
->mesh
& MESH_ENABLED
) {
664 * In mesh case, follow SAE finite state machine and
665 * send Commit now, if sync count allows.
667 if (sae_check_big_sync(hapd
, sta
))
668 return WLAN_STATUS_SUCCESS
;
671 ret
= auth_sae_send_commit(hapd
, sta
, bssid
, 0);
675 sae_set_retransmit_timer(hapd
, sta
);
678 * For instructure BSS, send the postponed Confirm from
679 * Nothing -> Confirmed transition that was reduced to
680 * Nothing -> Committed above.
682 ret
= auth_sae_send_confirm(hapd
, sta
, bssid
);
686 sta
->sae
->state
= SAE_CONFIRMED
;
689 * Since this was triggered on Confirm RX, run another
690 * step to get to Accepted without waiting for
693 return sae_sm_step(hapd
, sta
, bssid
, auth_transaction
);
697 sae_clear_retransmit_timer(hapd
, sta
);
698 if (auth_transaction
== 1) {
699 if (sae_check_big_sync(hapd
, sta
))
700 return WLAN_STATUS_SUCCESS
;
703 ret
= auth_sae_send_commit(hapd
, sta
, bssid
, 1);
707 if (sae_process_commit(sta
->sae
) < 0)
708 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
710 ret
= auth_sae_send_confirm(hapd
, sta
, bssid
);
714 sae_set_retransmit_timer(hapd
, sta
);
716 sae_accept_sta(hapd
, sta
);
720 if (auth_transaction
== 1) {
721 wpa_printf(MSG_DEBUG
, "SAE: remove the STA (" MACSTR
722 ") doing reauthentication",
724 ap_free_sta(hapd
, sta
);
725 wpa_auth_pmksa_remove(hapd
->wpa_auth
, sta
->addr
);
727 if (sae_check_big_sync(hapd
, sta
))
728 return WLAN_STATUS_SUCCESS
;
731 ret
= auth_sae_send_confirm(hapd
, sta
, bssid
);
732 sae_clear_temp_data(sta
->sae
);
738 wpa_printf(MSG_ERROR
, "SAE: invalid state %d",
740 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
742 return WLAN_STATUS_SUCCESS
;
746 static void sae_pick_next_group(struct hostapd_data
*hapd
, struct sta_info
*sta
)
748 struct sae_data
*sae
= sta
->sae
;
749 int i
, *groups
= hapd
->conf
->sae_groups
;
751 if (sae
->state
!= SAE_COMMITTED
)
754 wpa_printf(MSG_DEBUG
, "SAE: Previously selected group: %d", sae
->group
);
756 for (i
= 0; groups
&& groups
[i
] > 0; i
++) {
757 if (sae
->group
== groups
[i
])
761 if (!groups
|| groups
[i
] <= 0) {
762 wpa_printf(MSG_DEBUG
,
763 "SAE: Previously selected group not found from the current configuration");
769 if (groups
[i
] <= 0) {
770 wpa_printf(MSG_DEBUG
,
771 "SAE: No alternative group enabled");
775 if (sae_set_group(sae
, groups
[i
]) < 0)
780 wpa_printf(MSG_DEBUG
, "SAE: Selected new group: %d", groups
[i
]);
784 static void handle_auth_sae(struct hostapd_data
*hapd
, struct sta_info
*sta
,
785 const struct ieee80211_mgmt
*mgmt
, size_t len
,
786 u16 auth_transaction
, u16 status_code
)
788 int resp
= WLAN_STATUS_SUCCESS
;
789 struct wpabuf
*data
= NULL
;
791 #ifdef CONFIG_TESTING_OPTIONS
792 if (hapd
->conf
->sae_reflection_attack
&& auth_transaction
== 1) {
795 wpa_printf(MSG_DEBUG
, "SAE: TESTING - reflection attack");
796 pos
= mgmt
->u
.auth
.variable
;
797 end
= ((const u8
*) mgmt
) + len
;
798 send_auth_reply(hapd
, mgmt
->sa
, mgmt
->bssid
, WLAN_AUTH_SAE
,
799 auth_transaction
, resp
, pos
, end
- pos
);
803 if (hapd
->conf
->sae_commit_override
&& auth_transaction
== 1) {
804 wpa_printf(MSG_DEBUG
, "SAE: TESTING - commit override");
805 send_auth_reply(hapd
, mgmt
->sa
, mgmt
->bssid
, WLAN_AUTH_SAE
,
806 auth_transaction
, resp
,
807 wpabuf_head(hapd
->conf
->sae_commit_override
),
808 wpabuf_len(hapd
->conf
->sae_commit_override
));
811 #endif /* CONFIG_TESTING_OPTIONS */
813 if (auth_transaction
!= 1 ||
814 status_code
!= WLAN_STATUS_SUCCESS
) {
818 sta
->sae
= os_zalloc(sizeof(*sta
->sae
));
823 sta
->sae
->state
= SAE_NOTHING
;
827 if (sta
->mesh_sae_pmksa_caching
) {
828 wpa_printf(MSG_DEBUG
,
829 "SAE: Cancel use of mesh PMKSA caching because peer starts SAE authentication");
830 wpa_auth_pmksa_remove(hapd
->wpa_auth
, sta
->addr
);
831 sta
->mesh_sae_pmksa_caching
= 0;
834 if (auth_transaction
== 1) {
835 const u8
*token
= NULL
, *pos
, *end
;
836 size_t token_len
= 0;
837 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
839 "start SAE authentication (RX commit, status=%u)",
842 if ((hapd
->conf
->mesh
& MESH_ENABLED
) &&
843 status_code
== WLAN_STATUS_ANTI_CLOGGING_TOKEN_REQ
&&
845 pos
= mgmt
->u
.auth
.variable
;
846 end
= ((const u8
*) mgmt
) + len
;
847 if (pos
+ sizeof(le16
) > end
) {
848 wpa_printf(MSG_ERROR
,
849 "SAE: Too short anti-clogging token request");
850 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
853 resp
= sae_group_allowed(sta
->sae
,
854 hapd
->conf
->sae_groups
,
856 if (resp
!= WLAN_STATUS_SUCCESS
) {
857 wpa_printf(MSG_ERROR
,
858 "SAE: Invalid group in anti-clogging token request");
863 wpabuf_free(sta
->sae
->tmp
->anti_clogging_token
);
864 sta
->sae
->tmp
->anti_clogging_token
=
865 wpabuf_alloc_copy(pos
, end
- pos
);
866 if (sta
->sae
->tmp
->anti_clogging_token
== NULL
) {
867 wpa_printf(MSG_ERROR
,
868 "SAE: Failed to alloc for anti-clogging token");
869 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
874 * IEEE Std 802.11-2012, 11.3.8.6.4: If the Status code
875 * is 76, a new Commit Message shall be constructed
876 * with the Anti-Clogging Token from the received
877 * Authentication frame, and the commit-scalar and
878 * COMMIT-ELEMENT previously sent.
880 resp
= auth_sae_send_commit(hapd
, sta
, mgmt
->bssid
, 0);
881 if (resp
!= WLAN_STATUS_SUCCESS
) {
882 wpa_printf(MSG_ERROR
,
883 "SAE: Failed to send commit message");
886 sta
->sae
->state
= SAE_COMMITTED
;
888 sae_set_retransmit_timer(hapd
, sta
);
892 if ((hapd
->conf
->mesh
& MESH_ENABLED
) &&
894 WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED
&&
896 wpa_printf(MSG_DEBUG
,
897 "SAE: Peer did not accept our SAE group");
898 sae_pick_next_group(hapd
, sta
);
902 if (status_code
!= WLAN_STATUS_SUCCESS
)
905 resp
= sae_parse_commit(sta
->sae
, mgmt
->u
.auth
.variable
,
906 ((const u8
*) mgmt
) + len
-
907 mgmt
->u
.auth
.variable
, &token
,
908 &token_len
, hapd
->conf
->sae_groups
);
909 if (resp
== SAE_SILENTLY_DISCARD
) {
910 wpa_printf(MSG_DEBUG
,
911 "SAE: Drop commit message from " MACSTR
" due to reflection attack",
915 if (token
&& check_sae_token(hapd
, sta
->addr
, token
, token_len
)
917 wpa_printf(MSG_DEBUG
, "SAE: Drop commit message with "
918 "incorrect token from " MACSTR
,
920 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
924 if (resp
!= WLAN_STATUS_SUCCESS
)
927 if (!token
&& use_sae_anti_clogging(hapd
)) {
928 wpa_printf(MSG_DEBUG
,
929 "SAE: Request anti-clogging token from "
930 MACSTR
, MAC2STR(sta
->addr
));
931 data
= auth_build_token_req(hapd
, sta
->sae
->group
,
933 resp
= WLAN_STATUS_ANTI_CLOGGING_TOKEN_REQ
;
934 if (hapd
->conf
->mesh
& MESH_ENABLED
)
935 sta
->sae
->state
= SAE_NOTHING
;
939 resp
= sae_sm_step(hapd
, sta
, mgmt
->bssid
, auth_transaction
);
940 } else if (auth_transaction
== 2) {
941 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
943 "SAE authentication (RX confirm, status=%u)",
945 if (status_code
!= WLAN_STATUS_SUCCESS
)
947 if (sta
->sae
->state
>= SAE_CONFIRMED
||
948 !(hapd
->conf
->mesh
& MESH_ENABLED
)) {
949 if (sae_check_confirm(sta
->sae
, mgmt
->u
.auth
.variable
,
950 ((u8
*) mgmt
) + len
-
951 mgmt
->u
.auth
.variable
) < 0) {
952 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
956 resp
= sae_sm_step(hapd
, sta
, mgmt
->bssid
, auth_transaction
);
958 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
960 "unexpected SAE authentication transaction %u (status=%u)",
961 auth_transaction
, status_code
);
962 if (status_code
!= WLAN_STATUS_SUCCESS
)
964 resp
= WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION
;
968 if (resp
!= WLAN_STATUS_SUCCESS
) {
969 send_auth_reply(hapd
, mgmt
->sa
, mgmt
->bssid
, WLAN_AUTH_SAE
,
970 auth_transaction
, resp
,
971 data
? wpabuf_head(data
) : (u8
*) "",
972 data
? wpabuf_len(data
) : 0);
976 if (sta
->added_unassoc
&& (resp
!= WLAN_STATUS_SUCCESS
||
977 status_code
!= WLAN_STATUS_SUCCESS
)) {
978 hostapd_drv_sta_remove(hapd
, sta
->addr
);
979 sta
->added_unassoc
= 0;
986 * auth_sae_init_committed - Send COMMIT and start SAE in committed state
987 * @hapd: BSS data for the device initiating the authentication
988 * @sta: the peer to which commit authentication frame is sent
990 * This function implements Init event handling (IEEE Std 802.11-2012,
991 * 11.3.8.6.3) in which initial COMMIT message is sent. Prior to calling, the
992 * sta->sae structure should be initialized appropriately via a call to
993 * sae_prepare_commit().
995 int auth_sae_init_committed(struct hostapd_data
*hapd
, struct sta_info
*sta
)
999 if (!sta
->sae
|| !sta
->sae
->tmp
)
1002 if (sta
->sae
->state
!= SAE_NOTHING
)
1005 ret
= auth_sae_send_commit(hapd
, sta
, hapd
->own_addr
, 0);
1009 sta
->sae
->state
= SAE_COMMITTED
;
1011 sae_set_retransmit_timer(hapd
, sta
);
1016 #endif /* CONFIG_SAE */
1019 static u16
wpa_res_to_status_code(int res
)
1021 if (res
== WPA_INVALID_GROUP
)
1022 return WLAN_STATUS_GROUP_CIPHER_NOT_VALID
;
1023 if (res
== WPA_INVALID_PAIRWISE
)
1024 return WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID
;
1025 if (res
== WPA_INVALID_AKMP
)
1026 return WLAN_STATUS_AKMP_NOT_VALID
;
1027 if (res
== WPA_ALLOC_FAIL
)
1028 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
1029 #ifdef CONFIG_IEEE80211W
1030 if (res
== WPA_MGMT_FRAME_PROTECTION_VIOLATION
)
1031 return WLAN_STATUS_ROBUST_MGMT_FRAME_POLICY_VIOLATION
;
1032 if (res
== WPA_INVALID_MGMT_GROUP_CIPHER
)
1033 return WLAN_STATUS_ROBUST_MGMT_FRAME_POLICY_VIOLATION
;
1034 #endif /* CONFIG_IEEE80211W */
1035 if (res
== WPA_INVALID_MDIE
)
1036 return WLAN_STATUS_INVALID_MDIE
;
1037 if (res
== WPA_INVALID_PMKID
)
1038 return WLAN_STATUS_INVALID_PMKID
;
1039 if (res
!= WPA_IE_OK
)
1040 return WLAN_STATUS_INVALID_IE
;
1041 return WLAN_STATUS_SUCCESS
;
1047 static void handle_auth_fils_finish(struct hostapd_data
*hapd
,
1048 struct sta_info
*sta
, u16 resp
,
1049 struct wpabuf
*data
, int pub
);
1051 void handle_auth_fils(struct hostapd_data
*hapd
, struct sta_info
*sta
,
1052 const u8
*pos
, size_t len
, u16 auth_alg
,
1053 u16 auth_transaction
, u16 status_code
,
1054 void (*cb
)(struct hostapd_data
*hapd
,
1055 struct sta_info
*sta
, u16 resp
,
1056 struct wpabuf
*data
, int pub
))
1058 u16 resp
= WLAN_STATUS_SUCCESS
;
1060 struct ieee802_11_elems elems
;
1062 struct wpa_ie_data rsn
;
1063 struct rsn_pmksa_cache_entry
*pmksa
= NULL
;
1065 if (auth_transaction
!= 1 || status_code
!= WLAN_STATUS_SUCCESS
)
1070 wpa_hexdump(MSG_DEBUG
, "FILS: Authentication frame fields",
1074 #ifdef CONFIG_FILS_SK_PFS
1075 if (auth_alg
== WLAN_AUTH_FILS_SK_PFS
) {
1080 /* Using FILS PFS */
1082 /* Finite Cyclic Group */
1083 if (end
- pos
< 2) {
1084 wpa_printf(MSG_DEBUG
,
1085 "FILS: No room for Finite Cyclic Group");
1086 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1089 group
= WPA_GET_LE16(pos
);
1091 if (group
!= hapd
->conf
->fils_dh_group
) {
1092 wpa_printf(MSG_DEBUG
,
1093 "FILS: Unsupported Finite Cyclic Group: %u (expected %u)",
1094 group
, hapd
->conf
->fils_dh_group
);
1095 resp
= WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED
;
1099 crypto_ecdh_deinit(sta
->fils_ecdh
);
1100 sta
->fils_ecdh
= crypto_ecdh_init(group
);
1101 if (!sta
->fils_ecdh
) {
1102 wpa_printf(MSG_INFO
,
1103 "FILS: Could not initialize ECDH with group %d",
1105 resp
= WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED
;
1109 pub
= crypto_ecdh_get_pubkey(sta
->fils_ecdh
, 1);
1111 wpa_printf(MSG_DEBUG
,
1112 "FILS: Failed to derive ECDH public key");
1113 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1116 elem_len
= wpabuf_len(pub
);
1120 if ((size_t) (end
- pos
) < elem_len
) {
1121 wpa_printf(MSG_DEBUG
, "FILS: No room for Element");
1122 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1126 wpabuf_free(sta
->fils_g_sta
);
1127 sta
->fils_g_sta
= wpabuf_alloc_copy(pos
, elem_len
);
1128 wpabuf_clear_free(sta
->fils_dh_ss
);
1129 sta
->fils_dh_ss
= crypto_ecdh_set_peerkey(sta
->fils_ecdh
, 1,
1131 if (!sta
->fils_dh_ss
) {
1132 wpa_printf(MSG_DEBUG
, "FILS: ECDH operation failed");
1133 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1136 wpa_hexdump_buf_key(MSG_DEBUG
, "FILS: DH_SS", sta
->fils_dh_ss
);
1139 crypto_ecdh_deinit(sta
->fils_ecdh
);
1140 sta
->fils_ecdh
= NULL
;
1141 wpabuf_clear_free(sta
->fils_dh_ss
);
1142 sta
->fils_dh_ss
= NULL
;
1144 #endif /* CONFIG_FILS_SK_PFS */
1146 wpa_hexdump(MSG_DEBUG
, "FILS: Remaining IEs", pos
, end
- pos
);
1147 if (ieee802_11_parse_elems(pos
, end
- pos
, &elems
, 1) == ParseFailed
) {
1148 wpa_printf(MSG_DEBUG
, "FILS: Could not parse elements");
1149 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1154 wpa_hexdump(MSG_DEBUG
, "FILS: RSN element",
1155 elems
.rsn_ie
, elems
.rsn_ie_len
);
1156 if (!elems
.rsn_ie
||
1157 wpa_parse_wpa_ie_rsn(elems
.rsn_ie
- 2, elems
.rsn_ie_len
+ 2,
1159 wpa_printf(MSG_DEBUG
, "FILS: No valid RSN element");
1160 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1165 sta
->wpa_sm
= wpa_auth_sta_init(hapd
->wpa_auth
, sta
->addr
,
1168 wpa_printf(MSG_DEBUG
,
1169 "FILS: Failed to initialize RSN state machine");
1170 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1174 res
= wpa_validate_wpa_ie(hapd
->wpa_auth
, sta
->wpa_sm
,
1175 elems
.rsn_ie
- 2, elems
.rsn_ie_len
+ 2,
1176 elems
.mdie
, elems
.mdie_len
, NULL
, 0);
1177 resp
= wpa_res_to_status_code(res
);
1178 if (resp
!= WLAN_STATUS_SUCCESS
)
1181 if (!elems
.fils_nonce
) {
1182 wpa_printf(MSG_DEBUG
, "FILS: No FILS Nonce field");
1183 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1186 wpa_hexdump(MSG_DEBUG
, "FILS: SNonce", elems
.fils_nonce
,
1188 os_memcpy(sta
->fils_snonce
, elems
.fils_nonce
, FILS_NONCE_LEN
);
1191 if (rsn
.pmkid
&& rsn
.num_pmkid
> 0) {
1195 wpa_hexdump(MSG_DEBUG
, "FILS: PMKID List",
1196 rsn
.pmkid
, rsn
.num_pmkid
* PMKID_LEN
);
1199 num
= rsn
.num_pmkid
;
1201 wpa_hexdump(MSG_DEBUG
, "FILS: PMKID", pmkid
, PMKID_LEN
);
1202 pmksa
= wpa_auth_pmksa_get(hapd
->wpa_auth
, sta
->addr
,
1206 pmksa
= wpa_auth_pmksa_get_fils_cache_id(hapd
->wpa_auth
,
1215 if (pmksa
&& wpa_auth_sta_key_mgmt(sta
->wpa_sm
) != pmksa
->akmp
) {
1216 wpa_printf(MSG_DEBUG
,
1217 "FILS: Matching PMKSA cache entry has different AKMP (0x%x != 0x%x) - ignore",
1218 wpa_auth_sta_key_mgmt(sta
->wpa_sm
), pmksa
->akmp
);
1222 wpa_printf(MSG_DEBUG
, "FILS: Found matching PMKSA cache entry");
1225 if (!elems
.fils_session
) {
1226 wpa_printf(MSG_DEBUG
, "FILS: No FILS Session element");
1227 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1230 wpa_hexdump(MSG_DEBUG
, "FILS: FILS Session", elems
.fils_session
,
1232 os_memcpy(sta
->fils_session
, elems
.fils_session
, FILS_SESSION_LEN
);
1234 /* FILS Wrapped Data */
1235 if (elems
.fils_wrapped_data
) {
1236 wpa_hexdump(MSG_DEBUG
, "FILS: Wrapped Data",
1237 elems
.fils_wrapped_data
,
1238 elems
.fils_wrapped_data_len
);
1240 #ifndef CONFIG_NO_RADIUS
1241 if (!sta
->eapol_sm
) {
1243 ieee802_1x_alloc_eapol_sm(hapd
, sta
);
1245 wpa_printf(MSG_DEBUG
,
1246 "FILS: Forward EAP-Initiate/Re-auth to authentication server");
1247 ieee802_1x_encapsulate_radius(
1248 hapd
, sta
, elems
.fils_wrapped_data
,
1249 elems
.fils_wrapped_data_len
);
1250 sta
->fils_pending_cb
= cb
;
1251 wpa_printf(MSG_DEBUG
,
1252 "FILS: Will send Authentication frame once the response from authentication server is available");
1253 sta
->flags
|= WLAN_STA_PENDING_FILS_ERP
;
1254 /* Calculate pending PMKID here so that we do not need
1255 * to maintain a copy of the EAP-Initiate/Reauth
1257 if (fils_pmkid_erp(wpa_auth_sta_key_mgmt(sta
->wpa_sm
),
1258 elems
.fils_wrapped_data
,
1259 elems
.fils_wrapped_data_len
,
1260 sta
->fils_erp_pmkid
) == 0)
1261 sta
->fils_erp_pmkid_set
= 1;
1263 #else /* CONFIG_NO_RADIUS */
1264 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1266 #endif /* CONFIG_NO_RADIUS */
1272 struct wpabuf
*data
;
1275 data
= prepare_auth_resp_fils(hapd
, sta
, &resp
, pmksa
, NULL
,
1278 wpa_printf(MSG_DEBUG
,
1279 "%s: prepare_auth_resp_fils() returned failure",
1283 cb(hapd
, sta
, resp
, data
, pub
);
1288 static struct wpabuf
*
1289 prepare_auth_resp_fils(struct hostapd_data
*hapd
,
1290 struct sta_info
*sta
, u16
*resp
,
1291 struct rsn_pmksa_cache_entry
*pmksa
,
1292 struct wpabuf
*erp_resp
,
1293 const u8
*msk
, size_t msk_len
,
1296 u8 fils_nonce
[FILS_NONCE_LEN
];
1298 struct wpabuf
*data
= NULL
;
1301 const u8
*pmk
= NULL
;
1303 u8 pmk_buf
[PMK_LEN_MAX
];
1304 struct wpabuf
*pub
= NULL
;
1306 if (*resp
!= WLAN_STATUS_SUCCESS
)
1309 ie
= wpa_auth_get_wpa_ie(hapd
->wpa_auth
, &ielen
);
1311 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1316 /* Add PMKID of the selected PMKSA into RSNE */
1317 ie_buf
= os_malloc(ielen
+ 2 + 2 + PMKID_LEN
);
1319 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1323 os_memcpy(ie_buf
, ie
, ielen
);
1324 if (wpa_insert_pmkid(ie_buf
, &ielen
, pmksa
->pmkid
) < 0) {
1325 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1331 if (random_get_bytes(fils_nonce
, FILS_NONCE_LEN
) < 0) {
1332 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1335 wpa_hexdump(MSG_DEBUG
, "RSN: Generated FILS Nonce",
1336 fils_nonce
, FILS_NONCE_LEN
);
1338 #ifdef CONFIG_FILS_SK_PFS
1339 if (sta
->fils_dh_ss
&& sta
->fils_ecdh
) {
1340 pub
= crypto_ecdh_get_pubkey(sta
->fils_ecdh
, 1);
1342 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1346 #endif /* CONFIG_FILS_SK_PFS */
1348 data
= wpabuf_alloc(1000 + ielen
+ (pub
? wpabuf_len(pub
) : 0));
1350 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1355 #ifdef CONFIG_FILS_SK_PFS
1357 /* Finite Cyclic Group */
1358 wpabuf_put_le16(data
, hapd
->conf
->fils_dh_group
);
1361 wpabuf_put_buf(data
, pub
);
1363 #endif /* CONFIG_FILS_SK_PFS */
1366 wpabuf_put_data(data
, ie
, ielen
);
1368 /* MDE when using FILS+FT (already included in ie,ielen with RSNE) */
1370 #ifdef CONFIG_IEEE80211R_AP
1371 if (wpa_key_mgmt_ft(wpa_auth_sta_key_mgmt(sta
->wpa_sm
))) {
1372 /* FTE[R1KH-ID,R0KH-ID] when using FILS+FT */
1375 res
= wpa_auth_write_fte(hapd
->wpa_auth
, wpabuf_put(data
, 0),
1376 wpabuf_tailroom(data
));
1378 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1381 wpabuf_put(data
, res
);
1383 #endif /* CONFIG_IEEE80211R_AP */
1386 wpabuf_put_u8(data
, WLAN_EID_EXTENSION
); /* Element ID */
1387 wpabuf_put_u8(data
, 1 + FILS_NONCE_LEN
); /* Length */
1388 /* Element ID Extension */
1389 wpabuf_put_u8(data
, WLAN_EID_EXT_FILS_NONCE
);
1390 wpabuf_put_data(data
, fils_nonce
, FILS_NONCE_LEN
);
1393 wpabuf_put_u8(data
, WLAN_EID_EXTENSION
); /* Element ID */
1394 wpabuf_put_u8(data
, 1 + FILS_SESSION_LEN
); /* Length */
1395 /* Element ID Extension */
1396 wpabuf_put_u8(data
, WLAN_EID_EXT_FILS_SESSION
);
1397 wpabuf_put_data(data
, sta
->fils_session
, FILS_SESSION_LEN
);
1399 /* FILS Wrapped Data */
1400 if (!pmksa
&& erp_resp
) {
1401 wpabuf_put_u8(data
, WLAN_EID_EXTENSION
); /* Element ID */
1402 wpabuf_put_u8(data
, 1 + wpabuf_len(erp_resp
)); /* Length */
1403 /* Element ID Extension */
1404 wpabuf_put_u8(data
, WLAN_EID_EXT_FILS_WRAPPED_DATA
);
1405 wpabuf_put_buf(data
, erp_resp
);
1407 if (fils_rmsk_to_pmk(wpa_auth_sta_key_mgmt(sta
->wpa_sm
),
1408 msk
, msk_len
, sta
->fils_snonce
, fils_nonce
,
1410 wpabuf_head(sta
->fils_dh_ss
) : NULL
,
1412 wpabuf_len(sta
->fils_dh_ss
) : 0,
1413 pmk_buf
, &pmk_len
)) {
1414 wpa_printf(MSG_DEBUG
, "FILS: Failed to derive PMK");
1415 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1422 /* Don't use DHss in PTK derivation if PMKSA caching is not
1424 wpabuf_clear_free(sta
->fils_dh_ss
);
1425 sta
->fils_dh_ss
= NULL
;
1427 if (sta
->fils_erp_pmkid_set
) {
1428 /* TODO: get PMKLifetime from WPA parameters */
1429 unsigned int dot11RSNAConfigPMKLifetime
= 43200;
1431 sta
->fils_erp_pmkid_set
= 0;
1432 if (wpa_auth_pmksa_add2(
1433 hapd
->wpa_auth
, sta
->addr
,
1435 sta
->fils_erp_pmkid
,
1436 sta
->session_timeout_set
?
1437 sta
->session_timeout
:
1438 dot11RSNAConfigPMKLifetime
,
1439 wpa_auth_sta_key_mgmt(sta
->wpa_sm
)) < 0) {
1440 wpa_printf(MSG_ERROR
,
1441 "FILS: Failed to add PMKSA cache entry based on ERP");
1446 pmk_len
= pmksa
->pmk_len
;
1450 wpa_printf(MSG_DEBUG
, "FILS: No PMK available");
1451 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1457 if (fils_auth_pmk_to_ptk(sta
->wpa_sm
, pmk
, pmk_len
,
1458 sta
->fils_snonce
, fils_nonce
,
1460 wpabuf_head(sta
->fils_dh_ss
) : NULL
,
1462 wpabuf_len(sta
->fils_dh_ss
) : 0,
1463 sta
->fils_g_sta
, pub
) < 0) {
1464 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1472 *is_pub
= pub
!= NULL
;
1475 wpabuf_clear_free(sta
->fils_dh_ss
);
1476 sta
->fils_dh_ss
= NULL
;
1477 #ifdef CONFIG_FILS_SK_PFS
1478 crypto_ecdh_deinit(sta
->fils_ecdh
);
1479 sta
->fils_ecdh
= NULL
;
1480 #endif /* CONFIG_FILS_SK_PFS */
1485 static void handle_auth_fils_finish(struct hostapd_data
*hapd
,
1486 struct sta_info
*sta
, u16 resp
,
1487 struct wpabuf
*data
, int pub
)
1492 resp
== WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED
) ?
1493 WLAN_AUTH_FILS_SK_PFS
: WLAN_AUTH_FILS_SK
;
1494 send_auth_reply(hapd
, sta
->addr
, hapd
->own_addr
, auth_alg
, 2, resp
,
1495 data
? wpabuf_head(data
) : (u8
*) "",
1496 data
? wpabuf_len(data
) : 0);
1499 if (resp
== WLAN_STATUS_SUCCESS
) {
1500 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1501 HOSTAPD_LEVEL_DEBUG
,
1502 "authentication OK (FILS)");
1503 sta
->flags
|= WLAN_STA_AUTH
;
1504 wpa_auth_sm_event(sta
->wpa_sm
, WPA_AUTH
);
1505 sta
->auth_alg
= pub
? WLAN_AUTH_FILS_SK_PFS
: WLAN_AUTH_FILS_SK
;
1506 mlme_authenticate_indication(hapd
, sta
);
1511 void ieee802_11_finish_fils_auth(struct hostapd_data
*hapd
,
1512 struct sta_info
*sta
, int success
,
1513 struct wpabuf
*erp_resp
,
1514 const u8
*msk
, size_t msk_len
)
1516 struct wpabuf
*data
;
1520 sta
->flags
&= ~WLAN_STA_PENDING_FILS_ERP
;
1522 if (!sta
->fils_pending_cb
)
1524 resp
= success
? WLAN_STATUS_SUCCESS
: WLAN_STATUS_UNSPECIFIED_FAILURE
;
1525 data
= prepare_auth_resp_fils(hapd
, sta
, &resp
, NULL
, erp_resp
,
1526 msk
, msk_len
, &pub
);
1528 wpa_printf(MSG_DEBUG
,
1529 "%s: prepare_auth_resp_fils() returned failure",
1532 sta
->fils_pending_cb(hapd
, sta
, resp
, data
, pub
);
1535 #endif /* CONFIG_FILS */
1539 ieee802_11_allowed_address(struct hostapd_data
*hapd
, const u8
*addr
,
1540 const u8
*msg
, size_t len
, u32
*session_timeout
,
1541 u32
*acct_interim_interval
,
1542 struct vlan_description
*vlan_id
,
1543 struct hostapd_sta_wpa_psk_short
**psk
,
1544 char **identity
, char **radius_cui
)
1548 os_memset(vlan_id
, 0, sizeof(*vlan_id
));
1549 res
= hostapd_allowed_address(hapd
, addr
, msg
, len
,
1550 session_timeout
, acct_interim_interval
,
1551 vlan_id
, psk
, identity
, radius_cui
);
1553 if (res
== HOSTAPD_ACL_REJECT
) {
1554 wpa_printf(MSG_INFO
,
1555 "Station " MACSTR
" not allowed to authenticate",
1557 return HOSTAPD_ACL_REJECT
;
1560 if (res
== HOSTAPD_ACL_PENDING
) {
1561 wpa_printf(MSG_DEBUG
, "Authentication frame from " MACSTR
1562 " waiting for an external authentication",
1564 /* Authentication code will re-send the authentication frame
1565 * after it has received (and cached) information from the
1566 * external source. */
1567 return HOSTAPD_ACL_PENDING
;
1575 ieee802_11_set_radius_info(struct hostapd_data
*hapd
, struct sta_info
*sta
,
1576 int res
, u32 session_timeout
,
1577 u32 acct_interim_interval
,
1578 struct vlan_description
*vlan_id
,
1579 struct hostapd_sta_wpa_psk_short
**psk
,
1580 char **identity
, char **radius_cui
)
1582 if (vlan_id
->notempty
&&
1583 !hostapd_vlan_valid(hapd
->conf
->vlan
, vlan_id
)) {
1584 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_RADIUS
,
1586 "Invalid VLAN %d%s received from RADIUS server",
1588 vlan_id
->tagged
[0] ? "+" : "");
1591 if (ap_sta_set_vlan(hapd
, sta
, vlan_id
) < 0)
1594 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_RADIUS
,
1595 HOSTAPD_LEVEL_INFO
, "VLAN ID %d", sta
->vlan_id
);
1597 hostapd_free_psk_list(sta
->psk
);
1598 if (hapd
->conf
->wpa_psk_radius
!= PSK_RADIUS_IGNORED
) {
1605 sta
->identity
= *identity
;
1607 sta
->radius_cui
= *radius_cui
;
1610 if (hapd
->conf
->acct_interim_interval
== 0 && acct_interim_interval
)
1611 sta
->acct_interim_interval
= acct_interim_interval
;
1612 if (res
== HOSTAPD_ACL_ACCEPT_TIMEOUT
)
1613 ap_sta_session_timeout(hapd
, sta
, session_timeout
);
1615 ap_sta_no_session_timeout(hapd
, sta
);
1621 static void handle_auth(struct hostapd_data
*hapd
,
1622 const struct ieee80211_mgmt
*mgmt
, size_t len
)
1624 u16 auth_alg
, auth_transaction
, status_code
;
1625 u16 resp
= WLAN_STATUS_SUCCESS
;
1626 struct sta_info
*sta
= NULL
;
1629 const u8
*challenge
= NULL
;
1630 u32 session_timeout
, acct_interim_interval
;
1631 struct vlan_description vlan_id
;
1632 struct hostapd_sta_wpa_psk_short
*psk
= NULL
;
1633 u8 resp_ies
[2 + WLAN_AUTH_CHALLENGE_LEN
];
1634 size_t resp_ies_len
= 0;
1635 char *identity
= NULL
;
1636 char *radius_cui
= NULL
;
1639 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.auth
)) {
1640 wpa_printf(MSG_INFO
, "handle_auth - too short payload (len=%lu)",
1641 (unsigned long) len
);
1645 #ifdef CONFIG_TESTING_OPTIONS
1646 if (hapd
->iconf
->ignore_auth_probability
> 0.0 &&
1647 drand48() < hapd
->iconf
->ignore_auth_probability
) {
1648 wpa_printf(MSG_INFO
,
1649 "TESTING: ignoring auth frame from " MACSTR
,
1653 #endif /* CONFIG_TESTING_OPTIONS */
1655 auth_alg
= le_to_host16(mgmt
->u
.auth
.auth_alg
);
1656 auth_transaction
= le_to_host16(mgmt
->u
.auth
.auth_transaction
);
1657 status_code
= le_to_host16(mgmt
->u
.auth
.status_code
);
1658 fc
= le_to_host16(mgmt
->frame_control
);
1659 seq_ctrl
= le_to_host16(mgmt
->seq_ctrl
);
1661 if (len
>= IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.auth
) +
1662 2 + WLAN_AUTH_CHALLENGE_LEN
&&
1663 mgmt
->u
.auth
.variable
[0] == WLAN_EID_CHALLENGE
&&
1664 mgmt
->u
.auth
.variable
[1] == WLAN_AUTH_CHALLENGE_LEN
)
1665 challenge
= &mgmt
->u
.auth
.variable
[2];
1667 wpa_printf(MSG_DEBUG
, "authentication: STA=" MACSTR
" auth_alg=%d "
1668 "auth_transaction=%d status_code=%d wep=%d%s "
1670 MAC2STR(mgmt
->sa
), auth_alg
, auth_transaction
,
1671 status_code
, !!(fc
& WLAN_FC_ISWEP
),
1672 challenge
? " challenge" : "",
1673 seq_ctrl
, (fc
& WLAN_FC_RETRY
) ? " retry" : "");
1675 #ifdef CONFIG_NO_RC4
1676 if (auth_alg
== WLAN_AUTH_SHARED_KEY
) {
1677 wpa_printf(MSG_INFO
,
1678 "Unsupported authentication algorithm (%d)",
1680 resp
= WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG
;
1683 #endif /* CONFIG_NO_RC4 */
1685 if (hapd
->tkip_countermeasures
) {
1686 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1690 if (!(((hapd
->conf
->auth_algs
& WPA_AUTH_ALG_OPEN
) &&
1691 auth_alg
== WLAN_AUTH_OPEN
) ||
1692 #ifdef CONFIG_IEEE80211R_AP
1693 (hapd
->conf
->wpa
&& wpa_key_mgmt_ft(hapd
->conf
->wpa_key_mgmt
) &&
1694 auth_alg
== WLAN_AUTH_FT
) ||
1695 #endif /* CONFIG_IEEE80211R_AP */
1697 (hapd
->conf
->wpa
&& wpa_key_mgmt_sae(hapd
->conf
->wpa_key_mgmt
) &&
1698 auth_alg
== WLAN_AUTH_SAE
) ||
1699 #endif /* CONFIG_SAE */
1701 (hapd
->conf
->wpa
&& wpa_key_mgmt_fils(hapd
->conf
->wpa_key_mgmt
) &&
1702 auth_alg
== WLAN_AUTH_FILS_SK
) ||
1703 (hapd
->conf
->wpa
&& wpa_key_mgmt_fils(hapd
->conf
->wpa_key_mgmt
) &&
1704 hapd
->conf
->fils_dh_group
&&
1705 auth_alg
== WLAN_AUTH_FILS_SK_PFS
) ||
1706 #endif /* CONFIG_FILS */
1707 ((hapd
->conf
->auth_algs
& WPA_AUTH_ALG_SHARED
) &&
1708 auth_alg
== WLAN_AUTH_SHARED_KEY
))) {
1709 wpa_printf(MSG_INFO
, "Unsupported authentication algorithm (%d)",
1711 resp
= WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG
;
1715 if (!(auth_transaction
== 1 || auth_alg
== WLAN_AUTH_SAE
||
1716 (auth_alg
== WLAN_AUTH_SHARED_KEY
&& auth_transaction
== 3))) {
1717 wpa_printf(MSG_INFO
, "Unknown authentication transaction number (%d)",
1719 resp
= WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION
;
1723 if (os_memcmp(mgmt
->sa
, hapd
->own_addr
, ETH_ALEN
) == 0) {
1724 wpa_printf(MSG_INFO
, "Station " MACSTR
" not allowed to authenticate",
1726 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1730 if (hapd
->conf
->no_auth_if_seen_on
) {
1731 struct hostapd_data
*other
;
1733 other
= sta_track_seen_on(hapd
->iface
, mgmt
->sa
,
1734 hapd
->conf
->no_auth_if_seen_on
);
1738 u8 op_class
, channel
, phytype
;
1740 wpa_printf(MSG_DEBUG
, "%s: Reject authentication from "
1741 MACSTR
" since STA has been seen on %s",
1742 hapd
->conf
->iface
, MAC2STR(mgmt
->sa
),
1743 hapd
->conf
->no_auth_if_seen_on
);
1745 resp
= WLAN_STATUS_REJECTED_WITH_SUGGESTED_BSS_TRANSITION
;
1747 *pos
++ = WLAN_EID_NEIGHBOR_REPORT
;
1749 os_memcpy(pos
, other
->own_addr
, ETH_ALEN
);
1751 info
= 0; /* TODO: BSSID Information */
1752 WPA_PUT_LE32(pos
, info
);
1754 if (other
->iconf
->hw_mode
== HOSTAPD_MODE_IEEE80211AD
)
1755 phytype
= 8; /* dmg */
1756 else if (other
->iconf
->ieee80211ac
)
1757 phytype
= 9; /* vht */
1758 else if (other
->iconf
->ieee80211n
)
1759 phytype
= 7; /* ht */
1760 else if (other
->iconf
->hw_mode
==
1761 HOSTAPD_MODE_IEEE80211A
)
1762 phytype
= 4; /* ofdm */
1763 else if (other
->iconf
->hw_mode
==
1764 HOSTAPD_MODE_IEEE80211G
)
1765 phytype
= 6; /* erp */
1767 phytype
= 5; /* hrdsss */
1768 if (ieee80211_freq_to_channel_ext(
1769 hostapd_hw_get_freq(other
,
1770 other
->iconf
->channel
),
1771 other
->iconf
->secondary_channel
,
1772 other
->iconf
->ieee80211ac
,
1773 &op_class
, &channel
) == NUM_HOSTAPD_MODES
) {
1775 channel
= other
->iconf
->channel
;
1780 resp_ies_len
= pos
- &resp_ies
[0];
1785 res
= ieee802_11_allowed_address(
1786 hapd
, mgmt
->sa
, (const u8
*) mgmt
, len
, &session_timeout
,
1787 &acct_interim_interval
, &vlan_id
, &psk
, &identity
, &radius_cui
);
1788 if (res
== HOSTAPD_ACL_REJECT
) {
1789 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1792 if (res
== HOSTAPD_ACL_PENDING
)
1795 sta
= ap_get_sta(hapd
, mgmt
->sa
);
1797 sta
->flags
&= ~WLAN_STA_PENDING_FILS_ERP
;
1798 if ((fc
& WLAN_FC_RETRY
) &&
1799 sta
->last_seq_ctrl
!= WLAN_INVALID_MGMT_SEQ
&&
1800 sta
->last_seq_ctrl
== seq_ctrl
&&
1801 sta
->last_subtype
== WLAN_FC_STYPE_AUTH
) {
1802 hostapd_logger(hapd
, sta
->addr
,
1803 HOSTAPD_MODULE_IEEE80211
,
1804 HOSTAPD_LEVEL_DEBUG
,
1805 "Drop repeated authentication frame seq_ctrl=0x%x",
1810 if ((hapd
->conf
->mesh
& MESH_ENABLED
) &&
1811 sta
->plink_state
== PLINK_BLOCKED
) {
1812 wpa_printf(MSG_DEBUG
, "Mesh peer " MACSTR
1813 " is blocked - drop Authentication frame",
1817 #endif /* CONFIG_MESH */
1820 if (hapd
->conf
->mesh
& MESH_ENABLED
) {
1821 /* if the mesh peer is not available, we don't do auth.
1823 wpa_printf(MSG_DEBUG
, "Mesh peer " MACSTR
1824 " not yet known - drop Authentication frame",
1827 * Save a copy of the frame so that it can be processed
1828 * if a new peer entry is added shortly after this.
1830 wpabuf_free(hapd
->mesh_pending_auth
);
1831 hapd
->mesh_pending_auth
= wpabuf_alloc_copy(mgmt
, len
);
1832 os_get_reltime(&hapd
->mesh_pending_auth_time
);
1835 #endif /* CONFIG_MESH */
1837 sta
= ap_sta_add(hapd
, mgmt
->sa
);
1839 resp
= WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
;
1843 sta
->last_seq_ctrl
= seq_ctrl
;
1844 sta
->last_subtype
= WLAN_FC_STYPE_AUTH
;
1846 res
= ieee802_11_set_radius_info(
1847 hapd
, sta
, res
, session_timeout
, acct_interim_interval
,
1848 &vlan_id
, &psk
, &identity
, &radius_cui
);
1850 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1854 sta
->flags
&= ~WLAN_STA_PREAUTH
;
1855 ieee802_1x_notify_pre_auth(sta
->eapol_sm
, 0);
1858 * If the driver supports full AP client state, add a station to the
1859 * driver before sending authentication reply to make sure the driver
1860 * has resources, and not to go through the entire authentication and
1861 * association handshake, and fail it at the end.
1863 * If this is not the first transaction, in a multi-step authentication
1864 * algorithm, the station already exists in the driver
1865 * (sta->added_unassoc = 1) so skip it.
1867 * In mesh mode, the station was already added to the driver when the
1868 * NEW_PEER_CANDIDATE event is received.
1870 * If PMF was negotiated for the existing association, skip this to
1871 * avoid dropping the STA entry and the associated keys. This is needed
1872 * to allow the original connection work until the attempt can complete
1873 * (re)association, so that unprotected Authentication frame cannot be
1874 * used to bypass PMF protection.
1876 if (FULL_AP_CLIENT_STATE_SUPP(hapd
->iface
->drv_flags
) &&
1877 (!(sta
->flags
& WLAN_STA_MFP
) || !ap_sta_is_authorized(sta
)) &&
1878 !(hapd
->conf
->mesh
& MESH_ENABLED
) &&
1879 !(sta
->added_unassoc
)) {
1881 * If a station that is already associated to the AP, is trying
1882 * to authenticate again, remove the STA entry, in order to make
1883 * sure the STA PS state gets cleared and configuration gets
1884 * updated. To handle this, station's added_unassoc flag is
1885 * cleared once the station has completed association.
1887 hostapd_drv_sta_remove(hapd
, sta
->addr
);
1888 sta
->flags
&= ~(WLAN_STA_ASSOC
| WLAN_STA_AUTH
|
1889 WLAN_STA_AUTHORIZED
);
1891 if (hostapd_sta_add(hapd
, sta
->addr
, 0, 0, NULL
, 0, 0,
1892 NULL
, NULL
, sta
->flags
, 0, 0, 0, 0)) {
1893 hostapd_logger(hapd
, sta
->addr
,
1894 HOSTAPD_MODULE_IEEE80211
,
1895 HOSTAPD_LEVEL_NOTICE
,
1896 "Could not add STA to kernel driver");
1897 resp
= WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
;
1901 sta
->added_unassoc
= 1;
1905 case WLAN_AUTH_OPEN
:
1906 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1907 HOSTAPD_LEVEL_DEBUG
,
1908 "authentication OK (open system)");
1909 sta
->flags
|= WLAN_STA_AUTH
;
1910 wpa_auth_sm_event(sta
->wpa_sm
, WPA_AUTH
);
1911 sta
->auth_alg
= WLAN_AUTH_OPEN
;
1912 mlme_authenticate_indication(hapd
, sta
);
1914 #ifndef CONFIG_NO_RC4
1915 case WLAN_AUTH_SHARED_KEY
:
1916 resp
= auth_shared_key(hapd
, sta
, auth_transaction
, challenge
,
1917 fc
& WLAN_FC_ISWEP
);
1918 sta
->auth_alg
= WLAN_AUTH_SHARED_KEY
;
1919 mlme_authenticate_indication(hapd
, sta
);
1920 if (sta
->challenge
&& auth_transaction
== 1) {
1921 resp_ies
[0] = WLAN_EID_CHALLENGE
;
1922 resp_ies
[1] = WLAN_AUTH_CHALLENGE_LEN
;
1923 os_memcpy(resp_ies
+ 2, sta
->challenge
,
1924 WLAN_AUTH_CHALLENGE_LEN
);
1925 resp_ies_len
= 2 + WLAN_AUTH_CHALLENGE_LEN
;
1928 #endif /* CONFIG_NO_RC4 */
1929 #ifdef CONFIG_IEEE80211R_AP
1931 sta
->auth_alg
= WLAN_AUTH_FT
;
1932 if (sta
->wpa_sm
== NULL
)
1933 sta
->wpa_sm
= wpa_auth_sta_init(hapd
->wpa_auth
,
1935 if (sta
->wpa_sm
== NULL
) {
1936 wpa_printf(MSG_DEBUG
, "FT: Failed to initialize WPA "
1938 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1941 wpa_ft_process_auth(sta
->wpa_sm
, mgmt
->bssid
,
1942 auth_transaction
, mgmt
->u
.auth
.variable
,
1943 len
- IEEE80211_HDRLEN
-
1944 sizeof(mgmt
->u
.auth
),
1945 handle_auth_ft_finish
, hapd
);
1946 /* handle_auth_ft_finish() callback will complete auth. */
1948 #endif /* CONFIG_IEEE80211R_AP */
1952 if (status_code
== WLAN_STATUS_SUCCESS
&&
1953 hapd
->conf
->mesh
& MESH_ENABLED
) {
1954 if (sta
->wpa_sm
== NULL
)
1956 wpa_auth_sta_init(hapd
->wpa_auth
,
1958 if (sta
->wpa_sm
== NULL
) {
1959 wpa_printf(MSG_DEBUG
,
1960 "SAE: Failed to initialize WPA state machine");
1961 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1965 #endif /* CONFIG_MESH */
1966 handle_auth_sae(hapd
, sta
, mgmt
, len
, auth_transaction
,
1969 #endif /* CONFIG_SAE */
1971 case WLAN_AUTH_FILS_SK
:
1972 case WLAN_AUTH_FILS_SK_PFS
:
1973 handle_auth_fils(hapd
, sta
, mgmt
->u
.auth
.variable
,
1974 len
- IEEE80211_HDRLEN
- sizeof(mgmt
->u
.auth
),
1975 auth_alg
, auth_transaction
, status_code
,
1976 handle_auth_fils_finish
);
1978 #endif /* CONFIG_FILS */
1983 os_free(radius_cui
);
1984 hostapd_free_psk_list(psk
);
1986 reply_res
= send_auth_reply(hapd
, mgmt
->sa
, mgmt
->bssid
, auth_alg
,
1987 auth_transaction
+ 1, resp
, resp_ies
,
1990 if (sta
&& sta
->added_unassoc
&& (resp
!= WLAN_STATUS_SUCCESS
||
1991 reply_res
!= WLAN_STATUS_SUCCESS
)) {
1992 hostapd_drv_sta_remove(hapd
, sta
->addr
);
1993 sta
->added_unassoc
= 0;
1998 int hostapd_get_aid(struct hostapd_data
*hapd
, struct sta_info
*sta
)
2002 /* get a unique AID */
2004 wpa_printf(MSG_DEBUG
, " old AID %d", sta
->aid
);
2011 for (i
= 0; i
< AID_WORDS
; i
++) {
2012 if (hapd
->sta_aid
[i
] == (u32
) -1)
2014 for (j
= 0; j
< 32; j
++) {
2015 if (!(hapd
->sta_aid
[i
] & BIT(j
)))
2023 aid
= i
* 32 + j
+ 1;
2028 hapd
->sta_aid
[i
] |= BIT(j
);
2029 wpa_printf(MSG_DEBUG
, " new AID %d", sta
->aid
);
2034 static u16
check_ssid(struct hostapd_data
*hapd
, struct sta_info
*sta
,
2035 const u8
*ssid_ie
, size_t ssid_ie_len
)
2037 if (ssid_ie
== NULL
)
2038 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2040 if (ssid_ie_len
!= hapd
->conf
->ssid
.ssid_len
||
2041 os_memcmp(ssid_ie
, hapd
->conf
->ssid
.ssid
, ssid_ie_len
) != 0) {
2042 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
2044 "Station tried to associate with unknown SSID "
2045 "'%s'", wpa_ssid_txt(ssid_ie
, ssid_ie_len
));
2046 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2049 return WLAN_STATUS_SUCCESS
;
2053 static u16
check_wmm(struct hostapd_data
*hapd
, struct sta_info
*sta
,
2054 const u8
*wmm_ie
, size_t wmm_ie_len
)
2056 sta
->flags
&= ~WLAN_STA_WMM
;
2058 if (wmm_ie
&& hapd
->conf
->wmm_enabled
) {
2059 struct wmm_information_element
*wmm
;
2061 if (!hostapd_eid_wmm_valid(hapd
, wmm_ie
, wmm_ie_len
)) {
2062 hostapd_logger(hapd
, sta
->addr
,
2064 HOSTAPD_LEVEL_DEBUG
,
2065 "invalid WMM element in association "
2067 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2070 sta
->flags
|= WLAN_STA_WMM
;
2071 wmm
= (struct wmm_information_element
*) wmm_ie
;
2072 sta
->qosinfo
= wmm
->qos_info
;
2074 return WLAN_STATUS_SUCCESS
;
2078 static u16
copy_supp_rates(struct hostapd_data
*hapd
, struct sta_info
*sta
,
2079 struct ieee802_11_elems
*elems
)
2081 /* Supported rates not used in IEEE 802.11ad/DMG */
2082 if (hapd
->iface
->current_mode
&&
2083 hapd
->iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211AD
)
2084 return WLAN_STATUS_SUCCESS
;
2086 if (!elems
->supp_rates
) {
2087 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
2088 HOSTAPD_LEVEL_DEBUG
,
2089 "No supported rates element in AssocReq");
2090 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2093 if (elems
->supp_rates_len
+ elems
->ext_supp_rates_len
>
2094 sizeof(sta
->supported_rates
)) {
2095 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
2096 HOSTAPD_LEVEL_DEBUG
,
2097 "Invalid supported rates element length %d+%d",
2098 elems
->supp_rates_len
,
2099 elems
->ext_supp_rates_len
);
2100 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2103 sta
->supported_rates_len
= merge_byte_arrays(
2104 sta
->supported_rates
, sizeof(sta
->supported_rates
),
2105 elems
->supp_rates
, elems
->supp_rates_len
,
2106 elems
->ext_supp_rates
, elems
->ext_supp_rates_len
);
2108 return WLAN_STATUS_SUCCESS
;
2112 static u16
check_ext_capab(struct hostapd_data
*hapd
, struct sta_info
*sta
,
2113 const u8
*ext_capab_ie
, size_t ext_capab_ie_len
)
2115 #ifdef CONFIG_INTERWORKING
2116 /* check for QoS Map support */
2117 if (ext_capab_ie_len
>= 5) {
2118 if (ext_capab_ie
[4] & 0x01)
2119 sta
->qos_map_enabled
= 1;
2121 #endif /* CONFIG_INTERWORKING */
2123 if (ext_capab_ie_len
> 0) {
2124 sta
->ecsa_supported
= !!(ext_capab_ie
[0] & BIT(2));
2125 os_free(sta
->ext_capability
);
2126 sta
->ext_capability
= os_malloc(1 + ext_capab_ie_len
);
2127 if (sta
->ext_capability
) {
2128 sta
->ext_capability
[0] = ext_capab_ie_len
;
2129 os_memcpy(sta
->ext_capability
+ 1, ext_capab_ie
,
2134 return WLAN_STATUS_SUCCESS
;
2140 static int owe_group_supported(struct hostapd_data
*hapd
, u16 group
)
2143 int *groups
= hapd
->conf
->owe_groups
;
2145 if (group
!= 19 && group
!= 20 && group
!= 21)
2151 for (i
= 0; groups
[i
] > 0; i
++) {
2152 if (groups
[i
] == group
)
2160 static u16
owe_process_assoc_req(struct hostapd_data
*hapd
,
2161 struct sta_info
*sta
, const u8
*owe_dh
,
2164 struct wpabuf
*secret
, *pub
, *hkey
;
2166 u8 prk
[SHA512_MAC_LEN
], pmkid
[SHA512_MAC_LEN
];
2167 const char *info
= "OWE Key Generation";
2171 size_t hash_len
, prime_len
;
2173 if (wpa_auth_sta_get_pmksa(sta
->wpa_sm
)) {
2174 wpa_printf(MSG_DEBUG
, "OWE: Using PMKSA caching");
2175 return WLAN_STATUS_SUCCESS
;
2178 group
= WPA_GET_LE16(owe_dh
);
2179 if (!owe_group_supported(hapd
, group
)) {
2180 wpa_printf(MSG_DEBUG
, "OWE: Unsupported DH group %u", group
);
2181 return WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED
;
2185 else if (group
== 20)
2187 else if (group
== 21)
2190 return WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED
;
2192 crypto_ecdh_deinit(sta
->owe_ecdh
);
2193 sta
->owe_ecdh
= crypto_ecdh_init(group
);
2195 return WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED
;
2196 sta
->owe_group
= group
;
2198 secret
= crypto_ecdh_set_peerkey(sta
->owe_ecdh
, 0, owe_dh
+ 2,
2200 secret
= wpabuf_zeropad(secret
, prime_len
);
2202 wpa_printf(MSG_DEBUG
, "OWE: Invalid peer DH public key");
2203 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2205 wpa_hexdump_buf_key(MSG_DEBUG
, "OWE: DH shared secret", secret
);
2207 /* prk = HKDF-extract(C | A | group, z) */
2209 pub
= crypto_ecdh_get_pubkey(sta
->owe_ecdh
, 0);
2211 wpabuf_clear_free(secret
);
2212 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2215 /* PMKID = Truncate-128(Hash(C | A)) */
2216 addr
[0] = owe_dh
+ 2;
2217 len
[0] = owe_dh_len
- 2;
2218 addr
[1] = wpabuf_head(pub
);
2219 len
[1] = wpabuf_len(pub
);
2221 res
= sha256_vector(2, addr
, len
, pmkid
);
2222 hash_len
= SHA256_MAC_LEN
;
2223 } else if (group
== 20) {
2224 res
= sha384_vector(2, addr
, len
, pmkid
);
2225 hash_len
= SHA384_MAC_LEN
;
2226 } else if (group
== 21) {
2227 res
= sha512_vector(2, addr
, len
, pmkid
);
2228 hash_len
= SHA512_MAC_LEN
;
2231 wpabuf_clear_free(secret
);
2232 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2234 pub
= wpabuf_zeropad(pub
, prime_len
);
2235 if (res
< 0 || !pub
) {
2237 wpabuf_clear_free(secret
);
2238 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2241 hkey
= wpabuf_alloc(owe_dh_len
- 2 + wpabuf_len(pub
) + 2);
2244 wpabuf_clear_free(secret
);
2245 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2248 wpabuf_put_data(hkey
, owe_dh
+ 2, owe_dh_len
- 2); /* C */
2249 wpabuf_put_buf(hkey
, pub
); /* A */
2251 wpabuf_put_le16(hkey
, group
); /* group */
2253 res
= hmac_sha256(wpabuf_head(hkey
), wpabuf_len(hkey
),
2254 wpabuf_head(secret
), wpabuf_len(secret
), prk
);
2255 else if (group
== 20)
2256 res
= hmac_sha384(wpabuf_head(hkey
), wpabuf_len(hkey
),
2257 wpabuf_head(secret
), wpabuf_len(secret
), prk
);
2258 else if (group
== 21)
2259 res
= hmac_sha512(wpabuf_head(hkey
), wpabuf_len(hkey
),
2260 wpabuf_head(secret
), wpabuf_len(secret
), prk
);
2261 wpabuf_clear_free(hkey
);
2262 wpabuf_clear_free(secret
);
2264 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2266 wpa_hexdump_key(MSG_DEBUG
, "OWE: prk", prk
, hash_len
);
2268 /* PMK = HKDF-expand(prk, "OWE Key Generation", n) */
2270 os_free(sta
->owe_pmk
);
2271 sta
->owe_pmk
= os_malloc(hash_len
);
2272 if (!sta
->owe_pmk
) {
2273 os_memset(prk
, 0, SHA512_MAC_LEN
);
2274 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2278 res
= hmac_sha256_kdf(prk
, hash_len
, NULL
, (const u8
*) info
,
2279 os_strlen(info
), sta
->owe_pmk
, hash_len
);
2280 else if (group
== 20)
2281 res
= hmac_sha384_kdf(prk
, hash_len
, NULL
, (const u8
*) info
,
2282 os_strlen(info
), sta
->owe_pmk
, hash_len
);
2283 else if (group
== 21)
2284 res
= hmac_sha512_kdf(prk
, hash_len
, NULL
, (const u8
*) info
,
2285 os_strlen(info
), sta
->owe_pmk
, hash_len
);
2286 os_memset(prk
, 0, SHA512_MAC_LEN
);
2288 os_free(sta
->owe_pmk
);
2289 sta
->owe_pmk
= NULL
;
2290 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2292 sta
->owe_pmk_len
= hash_len
;
2294 wpa_hexdump_key(MSG_DEBUG
, "OWE: PMK", sta
->owe_pmk
, sta
->owe_pmk_len
);
2295 wpa_hexdump(MSG_DEBUG
, "OWE: PMKID", pmkid
, PMKID_LEN
);
2296 wpa_auth_pmksa_add2(hapd
->wpa_auth
, sta
->addr
, sta
->owe_pmk
,
2297 sta
->owe_pmk_len
, pmkid
, 0, WPA_KEY_MGMT_OWE
);
2299 return WLAN_STATUS_SUCCESS
;
2302 #endif /* CONFIG_OWE */
2305 static u16
check_assoc_ies(struct hostapd_data
*hapd
, struct sta_info
*sta
,
2306 const u8
*ies
, size_t ies_len
, int reassoc
)
2308 struct ieee802_11_elems elems
;
2312 const u8
*p2p_dev_addr
= NULL
;
2314 if (ieee802_11_parse_elems(ies
, ies_len
, &elems
, 1) == ParseFailed
) {
2315 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
2316 HOSTAPD_LEVEL_INFO
, "Station sent an invalid "
2317 "association request");
2318 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2321 resp
= check_ssid(hapd
, sta
, elems
.ssid
, elems
.ssid_len
);
2322 if (resp
!= WLAN_STATUS_SUCCESS
)
2324 resp
= check_wmm(hapd
, sta
, elems
.wmm
, elems
.wmm_len
);
2325 if (resp
!= WLAN_STATUS_SUCCESS
)
2327 resp
= check_ext_capab(hapd
, sta
, elems
.ext_capab
, elems
.ext_capab_len
);
2328 if (resp
!= WLAN_STATUS_SUCCESS
)
2330 resp
= copy_supp_rates(hapd
, sta
, &elems
);
2331 if (resp
!= WLAN_STATUS_SUCCESS
)
2333 #ifdef CONFIG_IEEE80211N
2334 resp
= copy_sta_ht_capab(hapd
, sta
, elems
.ht_capabilities
);
2335 if (resp
!= WLAN_STATUS_SUCCESS
)
2337 if (hapd
->iconf
->ieee80211n
&& hapd
->iconf
->require_ht
&&
2338 !(sta
->flags
& WLAN_STA_HT
)) {
2339 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
2340 HOSTAPD_LEVEL_INFO
, "Station does not support "
2341 "mandatory HT PHY - reject association");
2342 return WLAN_STATUS_ASSOC_DENIED_NO_HT
;
2344 #endif /* CONFIG_IEEE80211N */
2346 #ifdef CONFIG_IEEE80211AC
2347 if (hapd
->iconf
->ieee80211ac
) {
2348 resp
= copy_sta_vht_capab(hapd
, sta
, elems
.vht_capabilities
);
2349 if (resp
!= WLAN_STATUS_SUCCESS
)
2352 resp
= set_sta_vht_opmode(hapd
, sta
, elems
.vht_opmode_notif
);
2353 if (resp
!= WLAN_STATUS_SUCCESS
)
2357 if (hapd
->iconf
->ieee80211ac
&& hapd
->iconf
->require_vht
&&
2358 !(sta
->flags
& WLAN_STA_VHT
)) {
2359 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
2360 HOSTAPD_LEVEL_INFO
, "Station does not support "
2361 "mandatory VHT PHY - reject association");
2362 return WLAN_STATUS_ASSOC_DENIED_NO_VHT
;
2365 if (hapd
->conf
->vendor_vht
&& !elems
.vht_capabilities
) {
2366 resp
= copy_sta_vendor_vht(hapd
, sta
, elems
.vendor_vht
,
2367 elems
.vendor_vht_len
);
2368 if (resp
!= WLAN_STATUS_SUCCESS
)
2371 #endif /* CONFIG_IEEE80211AC */
2375 wpabuf_free(sta
->p2p_ie
);
2376 sta
->p2p_ie
= ieee802_11_vendor_ie_concat(ies
, ies_len
,
2377 P2P_IE_VENDOR_TYPE
);
2379 p2p_dev_addr
= p2p_get_go_dev_addr(sta
->p2p_ie
);
2381 wpabuf_free(sta
->p2p_ie
);
2384 #endif /* CONFIG_P2P */
2386 if ((hapd
->conf
->wpa
& WPA_PROTO_RSN
) && elems
.rsn_ie
) {
2387 wpa_ie
= elems
.rsn_ie
;
2388 wpa_ie_len
= elems
.rsn_ie_len
;
2389 } else if ((hapd
->conf
->wpa
& WPA_PROTO_WPA
) &&
2391 wpa_ie
= elems
.wpa_ie
;
2392 wpa_ie_len
= elems
.wpa_ie_len
;
2399 sta
->flags
&= ~(WLAN_STA_WPS
| WLAN_STA_MAYBE_WPS
| WLAN_STA_WPS2
);
2400 if (hapd
->conf
->wps_state
&& elems
.wps_ie
) {
2401 wpa_printf(MSG_DEBUG
, "STA included WPS IE in (Re)Association "
2402 "Request - assume WPS is used");
2403 sta
->flags
|= WLAN_STA_WPS
;
2404 wpabuf_free(sta
->wps_ie
);
2405 sta
->wps_ie
= ieee802_11_vendor_ie_concat(ies
, ies_len
,
2406 WPS_IE_VENDOR_TYPE
);
2407 if (sta
->wps_ie
&& wps_is_20(sta
->wps_ie
)) {
2408 wpa_printf(MSG_DEBUG
, "WPS: STA supports WPS 2.0");
2409 sta
->flags
|= WLAN_STA_WPS2
;
2413 if (sta
->wps_ie
&& wps_validate_assoc_req(sta
->wps_ie
) < 0) {
2414 wpa_printf(MSG_DEBUG
, "WPS: Invalid WPS IE in "
2415 "(Re)Association Request - reject");
2416 return WLAN_STATUS_INVALID_IE
;
2418 } else if (hapd
->conf
->wps_state
&& wpa_ie
== NULL
) {
2419 wpa_printf(MSG_DEBUG
, "STA did not include WPA/RSN IE in "
2420 "(Re)Association Request - possible WPS use");
2421 sta
->flags
|= WLAN_STA_MAYBE_WPS
;
2423 #endif /* CONFIG_WPS */
2424 if (hapd
->conf
->wpa
&& wpa_ie
== NULL
) {
2425 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
2427 "No WPA/RSN IE in association request");
2428 return WLAN_STATUS_INVALID_IE
;
2431 if (hapd
->conf
->wpa
&& wpa_ie
) {
2435 if (sta
->wpa_sm
== NULL
)
2436 sta
->wpa_sm
= wpa_auth_sta_init(hapd
->wpa_auth
,
2439 if (sta
->wpa_sm
== NULL
) {
2440 wpa_printf(MSG_WARNING
, "Failed to initialize WPA "
2442 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2444 res
= wpa_validate_wpa_ie(hapd
->wpa_auth
, sta
->wpa_sm
,
2446 elems
.mdie
, elems
.mdie_len
,
2447 elems
.owe_dh
, elems
.owe_dh_len
);
2448 resp
= wpa_res_to_status_code(res
);
2449 if (resp
!= WLAN_STATUS_SUCCESS
)
2451 #ifdef CONFIG_IEEE80211W
2452 if ((sta
->flags
& WLAN_STA_MFP
) && !sta
->sa_query_timed_out
&&
2453 sta
->sa_query_count
> 0)
2454 ap_check_sa_query_timeout(hapd
, sta
);
2455 if ((sta
->flags
& WLAN_STA_MFP
) && !sta
->sa_query_timed_out
&&
2456 (!reassoc
|| sta
->auth_alg
!= WLAN_AUTH_FT
)) {
2458 * STA has already been associated with MFP and SA
2459 * Query timeout has not been reached. Reject the
2460 * association attempt temporarily and start SA Query,
2461 * if one is not pending.
2464 if (sta
->sa_query_count
== 0)
2465 ap_sta_start_sa_query(hapd
, sta
);
2467 return WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY
;
2470 if (wpa_auth_uses_mfp(sta
->wpa_sm
))
2471 sta
->flags
|= WLAN_STA_MFP
;
2473 sta
->flags
&= ~WLAN_STA_MFP
;
2474 #endif /* CONFIG_IEEE80211W */
2476 #ifdef CONFIG_IEEE80211R_AP
2477 if (sta
->auth_alg
== WLAN_AUTH_FT
) {
2479 wpa_printf(MSG_DEBUG
, "FT: " MACSTR
" tried "
2480 "to use association (not "
2481 "re-association) with FT auth_alg",
2482 MAC2STR(sta
->addr
));
2483 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2486 resp
= wpa_ft_validate_reassoc(sta
->wpa_sm
, ies
,
2488 if (resp
!= WLAN_STATUS_SUCCESS
)
2491 #endif /* CONFIG_IEEE80211R_AP */
2494 if (wpa_auth_uses_sae(sta
->wpa_sm
) &&
2495 sta
->auth_alg
== WLAN_AUTH_OPEN
) {
2496 struct rsn_pmksa_cache_entry
*sa
;
2497 sa
= wpa_auth_sta_get_pmksa(sta
->wpa_sm
);
2498 if (!sa
|| sa
->akmp
!= WPA_KEY_MGMT_SAE
) {
2499 wpa_printf(MSG_DEBUG
,
2500 "SAE: No PMKSA cache entry found for "
2501 MACSTR
, MAC2STR(sta
->addr
));
2502 return WLAN_STATUS_INVALID_PMKID
;
2504 wpa_printf(MSG_DEBUG
, "SAE: " MACSTR
2505 " using PMKSA caching", MAC2STR(sta
->addr
));
2506 } else if (wpa_auth_uses_sae(sta
->wpa_sm
) &&
2507 sta
->auth_alg
!= WLAN_AUTH_SAE
&&
2508 !(sta
->auth_alg
== WLAN_AUTH_FT
&&
2509 wpa_auth_uses_ft_sae(sta
->wpa_sm
))) {
2510 wpa_printf(MSG_DEBUG
, "SAE: " MACSTR
" tried to use "
2511 "SAE AKM after non-SAE auth_alg %u",
2512 MAC2STR(sta
->addr
), sta
->auth_alg
);
2513 return WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG
;
2515 #endif /* CONFIG_SAE */
2518 if ((hapd
->conf
->wpa_key_mgmt
& WPA_KEY_MGMT_OWE
) &&
2519 wpa_auth_sta_key_mgmt(sta
->wpa_sm
) == WPA_KEY_MGMT_OWE
&&
2521 resp
= owe_process_assoc_req(hapd
, sta
, elems
.owe_dh
,
2523 if (resp
!= WLAN_STATUS_SUCCESS
)
2526 #endif /* CONFIG_OWE */
2528 #ifdef CONFIG_IEEE80211N
2529 if ((sta
->flags
& (WLAN_STA_HT
| WLAN_STA_VHT
)) &&
2530 wpa_auth_get_pairwise(sta
->wpa_sm
) == WPA_CIPHER_TKIP
) {
2531 hostapd_logger(hapd
, sta
->addr
,
2532 HOSTAPD_MODULE_IEEE80211
,
2534 "Station tried to use TKIP with HT "
2536 return WLAN_STATUS_CIPHER_REJECTED_PER_POLICY
;
2538 #endif /* CONFIG_IEEE80211N */
2540 } else if (hapd
->conf
->osen
) {
2541 if (elems
.osen
== NULL
) {
2543 hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
2545 "No HS 2.0 OSEN element in association request");
2546 return WLAN_STATUS_INVALID_IE
;
2549 wpa_printf(MSG_DEBUG
, "HS 2.0: OSEN association");
2550 if (sta
->wpa_sm
== NULL
)
2551 sta
->wpa_sm
= wpa_auth_sta_init(hapd
->wpa_auth
,
2553 if (sta
->wpa_sm
== NULL
) {
2554 wpa_printf(MSG_WARNING
, "Failed to initialize WPA "
2556 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2558 if (wpa_validate_osen(hapd
->wpa_auth
, sta
->wpa_sm
,
2559 elems
.osen
- 2, elems
.osen_len
+ 2) < 0)
2560 return WLAN_STATUS_INVALID_IE
;
2561 #endif /* CONFIG_HS20 */
2563 wpa_auth_sta_no_wpa(sta
->wpa_sm
);
2566 p2p_group_notif_assoc(hapd
->p2p_group
, sta
->addr
, ies
, ies_len
);
2567 #endif /* CONFIG_P2P */
2570 wpabuf_free(sta
->hs20_ie
);
2571 if (elems
.hs20
&& elems
.hs20_len
> 4) {
2572 sta
->hs20_ie
= wpabuf_alloc_copy(elems
.hs20
+ 4,
2573 elems
.hs20_len
- 4);
2575 sta
->hs20_ie
= NULL
;
2576 #endif /* CONFIG_HS20 */
2579 wpabuf_free(sta
->mb_ies
);
2580 if (hapd
->iface
->fst
)
2581 sta
->mb_ies
= mb_ies_by_info(&elems
.mb_ies
);
2584 #endif /* CONFIG_FST */
2587 mbo_ap_check_sta_assoc(hapd
, sta
, &elems
);
2589 if (hapd
->conf
->mbo_enabled
&& (hapd
->conf
->wpa
& 2) &&
2590 elems
.mbo
&& sta
->cell_capa
&& !(sta
->flags
& WLAN_STA_MFP
) &&
2591 hapd
->conf
->ieee80211w
!= NO_MGMT_FRAME_PROTECTION
) {
2592 wpa_printf(MSG_INFO
,
2593 "MBO: Reject WPA2 association without PMF");
2594 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2596 #endif /* CONFIG_MBO */
2598 ap_copy_sta_supp_op_classes(sta
, elems
.supp_op_classes
,
2599 elems
.supp_op_classes_len
);
2601 if ((sta
->capability
& WLAN_CAPABILITY_RADIO_MEASUREMENT
) &&
2602 elems
.rrm_enabled
&&
2603 elems
.rrm_enabled_len
>= sizeof(sta
->rrm_enabled_capa
))
2604 os_memcpy(sta
->rrm_enabled_capa
, elems
.rrm_enabled
,
2605 sizeof(sta
->rrm_enabled_capa
));
2607 if (elems
.power_capab
) {
2608 sta
->min_tx_power
= elems
.power_capab
[0];
2609 sta
->max_tx_power
= elems
.power_capab
[1];
2610 sta
->power_capab
= 1;
2612 sta
->power_capab
= 0;
2615 return WLAN_STATUS_SUCCESS
;
2619 static void send_deauth(struct hostapd_data
*hapd
, const u8
*addr
,
2623 struct ieee80211_mgmt reply
;
2625 os_memset(&reply
, 0, sizeof(reply
));
2626 reply
.frame_control
=
2627 IEEE80211_FC(WLAN_FC_TYPE_MGMT
, WLAN_FC_STYPE_DEAUTH
);
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
+ sizeof(reply
.u
.deauth
);
2633 reply
.u
.deauth
.reason_code
= host_to_le16(reason_code
);
2635 if (hostapd_drv_send_mlme(hapd
, &reply
, send_len
, 0) < 0)
2636 wpa_printf(MSG_INFO
, "Failed to send deauth: %s",
2641 static int add_associated_sta(struct hostapd_data
*hapd
,
2642 struct sta_info
*sta
)
2644 struct ieee80211_ht_capabilities ht_cap
;
2645 struct ieee80211_vht_capabilities vht_cap
;
2649 * Remove the STA entry to ensure the STA PS state gets cleared and
2650 * configuration gets updated. This is relevant for cases, such as
2651 * FT-over-the-DS, where a station re-associates back to the same AP but
2652 * skips the authentication flow, or if working with a driver that
2653 * does not support full AP client state.
2655 * Skip this if the STA has already completed FT reassociation and the
2656 * TK has been configured since the TX/RX PN must not be reset to 0 for
2659 if (!sta
->added_unassoc
&&
2660 (!(sta
->flags
& WLAN_STA_AUTHORIZED
) ||
2661 (!wpa_auth_sta_ft_tk_already_set(sta
->wpa_sm
) &&
2662 !wpa_auth_sta_fils_tk_already_set(sta
->wpa_sm
)))) {
2663 hostapd_drv_sta_remove(hapd
, sta
->addr
);
2664 wpa_auth_sm_event(sta
->wpa_sm
, WPA_DRV_STA_REMOVED
);
2668 #ifdef CONFIG_IEEE80211N
2669 if (sta
->flags
& WLAN_STA_HT
)
2670 hostapd_get_ht_capab(hapd
, sta
->ht_capabilities
, &ht_cap
);
2671 #endif /* CONFIG_IEEE80211N */
2672 #ifdef CONFIG_IEEE80211AC
2673 if (sta
->flags
& WLAN_STA_VHT
)
2674 hostapd_get_vht_capab(hapd
, sta
->vht_capabilities
, &vht_cap
);
2675 #endif /* CONFIG_IEEE80211AC */
2678 * Add the station with forced WLAN_STA_ASSOC flag. The sta->flags
2679 * will be set when the ACK frame for the (Re)Association Response frame
2680 * is processed (TX status driver event).
2682 if (hostapd_sta_add(hapd
, sta
->addr
, sta
->aid
, sta
->capability
,
2683 sta
->supported_rates
, sta
->supported_rates_len
,
2684 sta
->listen_interval
,
2685 sta
->flags
& WLAN_STA_HT
? &ht_cap
: NULL
,
2686 sta
->flags
& WLAN_STA_VHT
? &vht_cap
: NULL
,
2687 sta
->flags
| WLAN_STA_ASSOC
, sta
->qosinfo
,
2688 sta
->vht_opmode
, sta
->p2p_ie
? 1 : 0,
2690 hostapd_logger(hapd
, sta
->addr
,
2691 HOSTAPD_MODULE_IEEE80211
, HOSTAPD_LEVEL_NOTICE
,
2692 "Could not %s STA to kernel driver",
2693 set
? "set" : "add");
2695 if (sta
->added_unassoc
) {
2696 hostapd_drv_sta_remove(hapd
, sta
->addr
);
2697 sta
->added_unassoc
= 0;
2703 sta
->added_unassoc
= 0;
2709 static u16
send_assoc_resp(struct hostapd_data
*hapd
, struct sta_info
*sta
,
2710 const u8
*addr
, u16 status_code
, int reassoc
,
2711 const u8
*ies
, size_t ies_len
)
2716 struct ieee80211_mgmt
*reply
;
2718 u16 res
= WLAN_STATUS_SUCCESS
;
2720 buflen
= sizeof(struct ieee80211_mgmt
) + 1024;
2722 if (sta
&& sta
->fils_hlp_resp
)
2723 buflen
+= wpabuf_len(sta
->fils_hlp_resp
);
2724 #endif /* CONFIG_FILS */
2726 if (sta
&& (hapd
->conf
->wpa_key_mgmt
& WPA_KEY_MGMT_OWE
))
2728 #endif /* CONFIG_OWE */
2729 buf
= os_zalloc(buflen
);
2731 res
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
2734 reply
= (struct ieee80211_mgmt
*) buf
;
2735 reply
->frame_control
=
2736 IEEE80211_FC(WLAN_FC_TYPE_MGMT
,
2737 (reassoc
? WLAN_FC_STYPE_REASSOC_RESP
:
2738 WLAN_FC_STYPE_ASSOC_RESP
));
2739 os_memcpy(reply
->da
, addr
, ETH_ALEN
);
2740 os_memcpy(reply
->sa
, hapd
->own_addr
, ETH_ALEN
);
2741 os_memcpy(reply
->bssid
, hapd
->own_addr
, ETH_ALEN
);
2743 send_len
= IEEE80211_HDRLEN
;
2744 send_len
+= sizeof(reply
->u
.assoc_resp
);
2745 reply
->u
.assoc_resp
.capab_info
=
2746 host_to_le16(hostapd_own_capab_info(hapd
));
2747 reply
->u
.assoc_resp
.status_code
= host_to_le16(status_code
);
2749 reply
->u
.assoc_resp
.aid
= host_to_le16((sta
? sta
->aid
: 0) |
2751 /* Supported rates */
2752 p
= hostapd_eid_supp_rates(hapd
, reply
->u
.assoc_resp
.variable
);
2753 /* Extended supported rates */
2754 p
= hostapd_eid_ext_supp_rates(hapd
, p
);
2756 #ifdef CONFIG_IEEE80211R_AP
2757 if (sta
&& status_code
== WLAN_STATUS_SUCCESS
) {
2758 /* IEEE 802.11r: Mobility Domain Information, Fast BSS
2759 * Transition Information, RSN, [RIC Response] */
2760 p
= wpa_sm_write_assoc_resp_ies(sta
->wpa_sm
, p
,
2762 sta
->auth_alg
, ies
, ies_len
);
2764 #endif /* CONFIG_IEEE80211R_AP */
2767 if (sta
&& (hapd
->conf
->wpa_key_mgmt
& WPA_KEY_MGMT_OWE
))
2768 p
= wpa_auth_write_assoc_resp_owe(sta
->wpa_sm
, p
,
2771 #endif /* CONFIG_OWE */
2773 #ifdef CONFIG_IEEE80211W
2774 if (sta
&& status_code
== WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY
)
2775 p
= hostapd_eid_assoc_comeback_time(hapd
, sta
, p
);
2776 #endif /* CONFIG_IEEE80211W */
2778 #ifdef CONFIG_IEEE80211N
2779 p
= hostapd_eid_ht_capabilities(hapd
, p
);
2780 p
= hostapd_eid_ht_operation(hapd
, p
);
2781 #endif /* CONFIG_IEEE80211N */
2783 #ifdef CONFIG_IEEE80211AC
2784 if (hapd
->iconf
->ieee80211ac
&& !hapd
->conf
->disable_11ac
) {
2785 u32 nsts
= 0, sta_nsts
;
2787 if (sta
&& hapd
->conf
->use_sta_nsts
&& sta
->vht_capabilities
) {
2788 struct ieee80211_vht_capabilities
*capa
;
2790 nsts
= (hapd
->iface
->conf
->vht_capab
>>
2791 VHT_CAP_BEAMFORMEE_STS_OFFSET
) & 7;
2792 capa
= sta
->vht_capabilities
;
2793 sta_nsts
= (le_to_host32(capa
->vht_capabilities_info
) >>
2794 VHT_CAP_BEAMFORMEE_STS_OFFSET
) & 7;
2796 if (nsts
< sta_nsts
)
2801 p
= hostapd_eid_vht_capabilities(hapd
, p
, nsts
);
2802 p
= hostapd_eid_vht_operation(hapd
, p
);
2804 #endif /* CONFIG_IEEE80211AC */
2806 p
= hostapd_eid_ext_capab(hapd
, p
);
2807 p
= hostapd_eid_bss_max_idle_period(hapd
, p
);
2808 if (sta
&& sta
->qos_map_enabled
)
2809 p
= hostapd_eid_qos_map_set(hapd
, p
);
2812 if (hapd
->iface
->fst_ies
) {
2813 os_memcpy(p
, wpabuf_head(hapd
->iface
->fst_ies
),
2814 wpabuf_len(hapd
->iface
->fst_ies
));
2815 p
+= wpabuf_len(hapd
->iface
->fst_ies
);
2817 #endif /* CONFIG_FST */
2819 #ifdef CONFIG_IEEE80211AC
2820 if (sta
&& hapd
->conf
->vendor_vht
&& (sta
->flags
& WLAN_STA_VENDOR_VHT
))
2821 p
= hostapd_eid_vendor_vht(hapd
, p
);
2822 #endif /* CONFIG_IEEE80211AC */
2824 if (sta
&& (sta
->flags
& WLAN_STA_WMM
))
2825 p
= hostapd_eid_wmm(hapd
, p
);
2829 ((sta
->flags
& WLAN_STA_WPS
) ||
2830 ((sta
->flags
& WLAN_STA_MAYBE_WPS
) && hapd
->conf
->wpa
))) {
2831 struct wpabuf
*wps
= wps_build_assoc_resp_ie();
2833 os_memcpy(p
, wpabuf_head(wps
), wpabuf_len(wps
));
2834 p
+= wpabuf_len(wps
);
2838 #endif /* CONFIG_WPS */
2841 if (sta
&& sta
->p2p_ie
&& hapd
->p2p_group
) {
2842 struct wpabuf
*p2p_resp_ie
;
2843 enum p2p_status_code status
;
2844 switch (status_code
) {
2845 case WLAN_STATUS_SUCCESS
:
2846 status
= P2P_SC_SUCCESS
;
2848 case WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
:
2849 status
= P2P_SC_FAIL_LIMIT_REACHED
;
2852 status
= P2P_SC_FAIL_INVALID_PARAMS
;
2855 p2p_resp_ie
= p2p_group_assoc_resp_ie(hapd
->p2p_group
, status
);
2857 os_memcpy(p
, wpabuf_head(p2p_resp_ie
),
2858 wpabuf_len(p2p_resp_ie
));
2859 p
+= wpabuf_len(p2p_resp_ie
);
2860 wpabuf_free(p2p_resp_ie
);
2863 #endif /* CONFIG_P2P */
2865 #ifdef CONFIG_P2P_MANAGER
2866 if (hapd
->conf
->p2p
& P2P_MANAGE
)
2867 p
= hostapd_eid_p2p_manage(hapd
, p
);
2868 #endif /* CONFIG_P2P_MANAGER */
2870 p
= hostapd_eid_mbo(hapd
, p
, buf
+ buflen
- p
);
2872 if (hapd
->conf
->assocresp_elements
&&
2873 (size_t) (buf
+ buflen
- p
) >=
2874 wpabuf_len(hapd
->conf
->assocresp_elements
)) {
2875 os_memcpy(p
, wpabuf_head(hapd
->conf
->assocresp_elements
),
2876 wpabuf_len(hapd
->conf
->assocresp_elements
));
2877 p
+= wpabuf_len(hapd
->conf
->assocresp_elements
);
2880 send_len
+= p
- reply
->u
.assoc_resp
.variable
;
2884 (sta
->auth_alg
== WLAN_AUTH_FILS_SK
||
2885 sta
->auth_alg
== WLAN_AUTH_FILS_SK_PFS
||
2886 sta
->auth_alg
== WLAN_AUTH_FILS_PK
) &&
2887 status_code
== WLAN_STATUS_SUCCESS
) {
2888 struct ieee802_11_elems elems
;
2890 if (ieee802_11_parse_elems(ies
, ies_len
, &elems
, 0) ==
2891 ParseFailed
|| !elems
.fils_session
) {
2892 res
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
2897 *p
++ = WLAN_EID_EXTENSION
; /* Element ID */
2898 *p
++ = 1 + FILS_SESSION_LEN
; /* Length */
2899 *p
++ = WLAN_EID_EXT_FILS_SESSION
; /* Element ID Extension */
2900 os_memcpy(p
, elems
.fils_session
, FILS_SESSION_LEN
);
2901 send_len
+= 2 + 1 + FILS_SESSION_LEN
;
2903 send_len
= fils_encrypt_assoc(sta
->wpa_sm
, buf
, send_len
,
2904 buflen
, sta
->fils_hlp_resp
);
2906 res
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
2910 #endif /* CONFIG_FILS */
2913 if ((hapd
->conf
->wpa_key_mgmt
& WPA_KEY_MGMT_OWE
) &&
2914 sta
&& sta
->owe_ecdh
&&
2915 wpa_auth_sta_key_mgmt(sta
->wpa_sm
) == WPA_KEY_MGMT_OWE
) {
2918 pub
= crypto_ecdh_get_pubkey(sta
->owe_ecdh
, 0);
2920 res
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
2923 /* OWE Diffie-Hellman Parameter element */
2924 *p
++ = WLAN_EID_EXTENSION
; /* Element ID */
2925 *p
++ = 1 + 2 + wpabuf_len(pub
); /* Length */
2926 *p
++ = WLAN_EID_EXT_OWE_DH_PARAM
; /* Element ID Extension */
2927 WPA_PUT_LE16(p
, sta
->owe_group
);
2929 os_memcpy(p
, wpabuf_head(pub
), wpabuf_len(pub
));
2930 p
+= wpabuf_len(pub
);
2931 send_len
+= 3 + 2 + wpabuf_len(pub
);
2934 #endif /* CONFIG_OWE */
2936 if (hostapd_drv_send_mlme(hapd
, reply
, send_len
, 0) < 0) {
2937 wpa_printf(MSG_INFO
, "Failed to send assoc resp: %s",
2939 res
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
2949 u8
* owe_auth_req_process(struct hostapd_data
*hapd
, struct sta_info
*sta
,
2950 const u8
*owe_dh
, u8 owe_dh_len
,
2951 u8
*owe_buf
, u16
*reason
)
2955 *reason
= owe_process_assoc_req(hapd
, sta
, owe_dh
, owe_dh_len
);
2956 if (*reason
!= WLAN_STATUS_SUCCESS
)
2958 pub
= crypto_ecdh_get_pubkey(sta
->owe_ecdh
, 0);
2960 *reason
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
2964 /* OWE Diffie-Hellman Parameter element */
2965 *owe_buf
++ = WLAN_EID_EXTENSION
; /* Element ID */
2966 *owe_buf
++ = 1 + 2 + wpabuf_len(pub
); /* Length */
2967 *owe_buf
++ = WLAN_EID_EXT_OWE_DH_PARAM
; /* Element ID Extension */
2968 WPA_PUT_LE16(owe_buf
, OWE_DH_GROUP
);
2970 os_memcpy(owe_buf
, wpabuf_head(pub
), wpabuf_len(pub
));
2971 owe_buf
+= wpabuf_len(pub
);
2973 *reason
= WLAN_STATUS_SUCCESS
;
2976 #endif /* CONFIG_OWE */
2981 void fils_hlp_finish_assoc(struct hostapd_data
*hapd
, struct sta_info
*sta
)
2985 wpa_printf(MSG_DEBUG
, "FILS: Finish association with " MACSTR
,
2986 MAC2STR(sta
->addr
));
2987 eloop_cancel_timeout(fils_hlp_timeout
, hapd
, sta
);
2988 if (!sta
->fils_pending_assoc_req
)
2990 reply_res
= send_assoc_resp(hapd
, sta
, sta
->addr
, WLAN_STATUS_SUCCESS
,
2991 sta
->fils_pending_assoc_is_reassoc
,
2992 sta
->fils_pending_assoc_req
,
2993 sta
->fils_pending_assoc_req_len
);
2994 os_free(sta
->fils_pending_assoc_req
);
2995 sta
->fils_pending_assoc_req
= NULL
;
2996 sta
->fils_pending_assoc_req_len
= 0;
2997 wpabuf_free(sta
->fils_hlp_resp
);
2998 sta
->fils_hlp_resp
= NULL
;
2999 wpabuf_free(sta
->hlp_dhcp_discover
);
3000 sta
->hlp_dhcp_discover
= NULL
;
3003 * Remove the station in case transmission of a success response fails.
3004 * At this point the station was already added associated to the driver.
3006 if (reply_res
!= WLAN_STATUS_SUCCESS
)
3007 hostapd_drv_sta_remove(hapd
, sta
->addr
);
3011 void fils_hlp_timeout(void *eloop_ctx
, void *eloop_data
)
3013 struct hostapd_data
*hapd
= eloop_ctx
;
3014 struct sta_info
*sta
= eloop_data
;
3016 wpa_printf(MSG_DEBUG
,
3017 "FILS: HLP response timeout - continue with association response for "
3018 MACSTR
, MAC2STR(sta
->addr
));
3019 if (sta
->fils_drv_assoc_finish
)
3020 hostapd_notify_assoc_fils_finish(hapd
, sta
);
3022 fils_hlp_finish_assoc(hapd
, sta
);
3025 #endif /* CONFIG_FILS */
3028 static void handle_assoc(struct hostapd_data
*hapd
,
3029 const struct ieee80211_mgmt
*mgmt
, size_t len
,
3032 u16 capab_info
, listen_interval
, seq_ctrl
, fc
;
3033 u16 resp
= WLAN_STATUS_SUCCESS
, reply_res
;
3036 struct sta_info
*sta
;
3038 struct hostapd_sta_wpa_psk_short
*psk
= NULL
;
3039 char *identity
= NULL
;
3040 char *radius_cui
= NULL
;
3042 int delay_assoc
= 0;
3043 #endif /* CONFIG_FILS */
3045 if (len
< IEEE80211_HDRLEN
+ (reassoc
? sizeof(mgmt
->u
.reassoc_req
) :
3046 sizeof(mgmt
->u
.assoc_req
))) {
3047 wpa_printf(MSG_INFO
, "handle_assoc(reassoc=%d) - too short payload (len=%lu)",
3048 reassoc
, (unsigned long) len
);
3052 #ifdef CONFIG_TESTING_OPTIONS
3054 if (hapd
->iconf
->ignore_reassoc_probability
> 0.0 &&
3055 drand48() < hapd
->iconf
->ignore_reassoc_probability
) {
3056 wpa_printf(MSG_INFO
,
3057 "TESTING: ignoring reassoc request from "
3058 MACSTR
, MAC2STR(mgmt
->sa
));
3062 if (hapd
->iconf
->ignore_assoc_probability
> 0.0 &&
3063 drand48() < hapd
->iconf
->ignore_assoc_probability
) {
3064 wpa_printf(MSG_INFO
,
3065 "TESTING: ignoring assoc request from "
3066 MACSTR
, MAC2STR(mgmt
->sa
));
3070 #endif /* CONFIG_TESTING_OPTIONS */
3072 fc
= le_to_host16(mgmt
->frame_control
);
3073 seq_ctrl
= le_to_host16(mgmt
->seq_ctrl
);
3076 capab_info
= le_to_host16(mgmt
->u
.reassoc_req
.capab_info
);
3077 listen_interval
= le_to_host16(
3078 mgmt
->u
.reassoc_req
.listen_interval
);
3079 wpa_printf(MSG_DEBUG
, "reassociation request: STA=" MACSTR
3080 " capab_info=0x%02x listen_interval=%d current_ap="
3081 MACSTR
" seq_ctrl=0x%x%s",
3082 MAC2STR(mgmt
->sa
), capab_info
, listen_interval
,
3083 MAC2STR(mgmt
->u
.reassoc_req
.current_ap
),
3084 seq_ctrl
, (fc
& WLAN_FC_RETRY
) ? " retry" : "");
3085 left
= len
- (IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.reassoc_req
));
3086 pos
= mgmt
->u
.reassoc_req
.variable
;
3088 capab_info
= le_to_host16(mgmt
->u
.assoc_req
.capab_info
);
3089 listen_interval
= le_to_host16(
3090 mgmt
->u
.assoc_req
.listen_interval
);
3091 wpa_printf(MSG_DEBUG
, "association request: STA=" MACSTR
3092 " capab_info=0x%02x listen_interval=%d "
3094 MAC2STR(mgmt
->sa
), capab_info
, listen_interval
,
3095 seq_ctrl
, (fc
& WLAN_FC_RETRY
) ? " retry" : "");
3096 left
= len
- (IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.assoc_req
));
3097 pos
= mgmt
->u
.assoc_req
.variable
;
3100 sta
= ap_get_sta(hapd
, mgmt
->sa
);
3101 #ifdef CONFIG_IEEE80211R_AP
3102 if (sta
&& sta
->auth_alg
== WLAN_AUTH_FT
&&
3103 (sta
->flags
& WLAN_STA_AUTH
) == 0) {
3104 wpa_printf(MSG_DEBUG
, "FT: Allow STA " MACSTR
" to associate "
3105 "prior to authentication since it is using "
3106 "over-the-DS FT", MAC2STR(mgmt
->sa
));
3109 * Mark station as authenticated, to avoid adding station
3110 * entry in the driver as associated and not authenticated
3112 sta
->flags
|= WLAN_STA_AUTH
;
3114 #endif /* CONFIG_IEEE80211R_AP */
3115 if (sta
== NULL
|| (sta
->flags
& WLAN_STA_AUTH
) == 0) {
3116 if (hapd
->iface
->current_mode
&&
3117 hapd
->iface
->current_mode
->mode
==
3118 HOSTAPD_MODE_IEEE80211AD
) {
3120 u32 session_timeout
, acct_interim_interval
;
3121 struct vlan_description vlan_id
;
3123 acl_res
= ieee802_11_allowed_address(
3124 hapd
, mgmt
->sa
, (const u8
*) mgmt
, len
,
3125 &session_timeout
, &acct_interim_interval
,
3126 &vlan_id
, &psk
, &identity
, &radius_cui
);
3127 if (acl_res
== HOSTAPD_ACL_REJECT
) {
3128 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
3131 if (acl_res
== HOSTAPD_ACL_PENDING
)
3134 /* DMG/IEEE 802.11ad does not use authentication.
3135 * Allocate sta entry upon association. */
3136 sta
= ap_sta_add(hapd
, mgmt
->sa
);
3138 hostapd_logger(hapd
, mgmt
->sa
,
3139 HOSTAPD_MODULE_IEEE80211
,
3141 "Failed to add STA");
3142 resp
= WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
;
3146 acl_res
= ieee802_11_set_radius_info(
3147 hapd
, sta
, acl_res
, session_timeout
,
3148 acct_interim_interval
, &vlan_id
, &psk
,
3149 &identity
, &radius_cui
);
3151 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
3155 hostapd_logger(hapd
, sta
->addr
,
3156 HOSTAPD_MODULE_IEEE80211
,
3157 HOSTAPD_LEVEL_DEBUG
,
3158 "Skip authentication for DMG/IEEE 802.11ad");
3159 sta
->flags
|= WLAN_STA_AUTH
;
3160 wpa_auth_sm_event(sta
->wpa_sm
, WPA_AUTH
);
3161 sta
->auth_alg
= WLAN_AUTH_OPEN
;
3163 hostapd_logger(hapd
, mgmt
->sa
,
3164 HOSTAPD_MODULE_IEEE80211
,
3166 "Station tried to associate before authentication (aid=%d flags=0x%x)",
3167 sta
? sta
->aid
: -1,
3168 sta
? sta
->flags
: 0);
3169 send_deauth(hapd
, mgmt
->sa
,
3170 WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA
);
3175 if ((fc
& WLAN_FC_RETRY
) &&
3176 sta
->last_seq_ctrl
!= WLAN_INVALID_MGMT_SEQ
&&
3177 sta
->last_seq_ctrl
== seq_ctrl
&&
3178 sta
->last_subtype
== (reassoc
? WLAN_FC_STYPE_REASSOC_REQ
:
3179 WLAN_FC_STYPE_ASSOC_REQ
)) {
3180 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
3181 HOSTAPD_LEVEL_DEBUG
,
3182 "Drop repeated association frame seq_ctrl=0x%x",
3186 sta
->last_seq_ctrl
= seq_ctrl
;
3187 sta
->last_subtype
= reassoc
? WLAN_FC_STYPE_REASSOC_REQ
:
3188 WLAN_FC_STYPE_ASSOC_REQ
;
3190 if (hapd
->tkip_countermeasures
) {
3191 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
3195 if (listen_interval
> hapd
->conf
->max_listen_interval
) {
3196 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
3197 HOSTAPD_LEVEL_DEBUG
,
3198 "Too large Listen Interval (%d)",
3200 resp
= WLAN_STATUS_ASSOC_DENIED_LISTEN_INT_TOO_LARGE
;
3205 if (hapd
->conf
->mbo_enabled
&& hapd
->mbo_assoc_disallow
) {
3206 resp
= WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
;
3209 #endif /* CONFIG_MBO */
3212 * sta->capability is used in check_assoc_ies() for RRM enabled
3213 * capability element.
3215 sta
->capability
= capab_info
;
3218 if (sta
->auth_alg
== WLAN_AUTH_FILS_SK
||
3219 sta
->auth_alg
== WLAN_AUTH_FILS_SK_PFS
||
3220 sta
->auth_alg
== WLAN_AUTH_FILS_PK
) {
3223 /* The end of the payload is encrypted. Need to decrypt it
3224 * before parsing. */
3226 tmp
= os_memdup(pos
, left
);
3228 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
3232 res
= fils_decrypt_assoc(sta
->wpa_sm
, sta
->fils_session
, mgmt
,
3235 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
3241 #endif /* CONFIG_FILS */
3243 /* followed by SSID and Supported rates; and HT capabilities if 802.11n
3245 resp
= check_assoc_ies(hapd
, sta
, pos
, left
, reassoc
);
3246 if (resp
!= WLAN_STATUS_SUCCESS
)
3249 if (hostapd_get_aid(hapd
, sta
) < 0) {
3250 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
3251 HOSTAPD_LEVEL_INFO
, "No room for more AIDs");
3252 resp
= WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
;
3256 sta
->listen_interval
= listen_interval
;
3258 if (hapd
->iface
->current_mode
&&
3259 hapd
->iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211G
)
3260 sta
->flags
|= WLAN_STA_NONERP
;
3261 for (i
= 0; i
< sta
->supported_rates_len
; i
++) {
3262 if ((sta
->supported_rates
[i
] & 0x7f) > 22) {
3263 sta
->flags
&= ~WLAN_STA_NONERP
;
3267 if (sta
->flags
& WLAN_STA_NONERP
&& !sta
->nonerp_set
) {
3268 sta
->nonerp_set
= 1;
3269 hapd
->iface
->num_sta_non_erp
++;
3270 if (hapd
->iface
->num_sta_non_erp
== 1)
3271 ieee802_11_set_beacons(hapd
->iface
);
3274 if (!(sta
->capability
& WLAN_CAPABILITY_SHORT_SLOT_TIME
) &&
3275 !sta
->no_short_slot_time_set
) {
3276 sta
->no_short_slot_time_set
= 1;
3277 hapd
->iface
->num_sta_no_short_slot_time
++;
3278 if (hapd
->iface
->current_mode
&&
3279 hapd
->iface
->current_mode
->mode
==
3280 HOSTAPD_MODE_IEEE80211G
&&
3281 hapd
->iface
->num_sta_no_short_slot_time
== 1)
3282 ieee802_11_set_beacons(hapd
->iface
);
3285 if (sta
->capability
& WLAN_CAPABILITY_SHORT_PREAMBLE
)
3286 sta
->flags
|= WLAN_STA_SHORT_PREAMBLE
;
3288 sta
->flags
&= ~WLAN_STA_SHORT_PREAMBLE
;
3290 if (!(sta
->capability
& WLAN_CAPABILITY_SHORT_PREAMBLE
) &&
3291 !sta
->no_short_preamble_set
) {
3292 sta
->no_short_preamble_set
= 1;
3293 hapd
->iface
->num_sta_no_short_preamble
++;
3294 if (hapd
->iface
->current_mode
&&
3295 hapd
->iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211G
3296 && hapd
->iface
->num_sta_no_short_preamble
== 1)
3297 ieee802_11_set_beacons(hapd
->iface
);
3300 #ifdef CONFIG_IEEE80211N
3301 update_ht_state(hapd
, sta
);
3302 #endif /* CONFIG_IEEE80211N */
3304 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
3305 HOSTAPD_LEVEL_DEBUG
,
3306 "association OK (aid %d)", sta
->aid
);
3307 /* Station will be marked associated, after it acknowledges AssocResp
3309 sta
->flags
|= WLAN_STA_ASSOC_REQ_OK
;
3311 #ifdef CONFIG_IEEE80211W
3312 if ((sta
->flags
& WLAN_STA_MFP
) && sta
->sa_query_timed_out
) {
3313 wpa_printf(MSG_DEBUG
, "Allowing %sassociation after timed out "
3314 "SA Query procedure", reassoc
? "re" : "");
3315 /* TODO: Send a protected Disassociate frame to the STA using
3316 * the old key and Reason Code "Previous Authentication no
3317 * longer valid". Make sure this is only sent protected since
3318 * unprotected frame would be received by the STA that is now
3319 * trying to associate.
3322 #endif /* CONFIG_IEEE80211W */
3324 /* Make sure that the previously registered inactivity timer will not
3325 * remove the STA immediately. */
3326 sta
->timeout_next
= STA_NULLFUNC
;
3328 #ifdef CONFIG_TAXONOMY
3329 taxonomy_sta_info_assoc_req(hapd
, sta
, pos
, left
);
3330 #endif /* CONFIG_TAXONOMY */
3332 sta
->pending_wds_enable
= 0;
3335 if (sta
->auth_alg
== WLAN_AUTH_FILS_SK
||
3336 sta
->auth_alg
== WLAN_AUTH_FILS_SK_PFS
||
3337 sta
->auth_alg
== WLAN_AUTH_FILS_PK
) {
3338 if (fils_process_hlp(hapd
, sta
, pos
, left
) > 0)
3341 #endif /* CONFIG_FILS */
3345 os_free(radius_cui
);
3346 hostapd_free_psk_list(psk
);
3349 * In case of a successful response, add the station to the driver.
3350 * Otherwise, the kernel may ignore Data frames before we process the
3351 * ACK frame (TX status). In case of a failure, this station will be
3354 * Note that this is not compliant with the IEEE 802.11 standard that
3355 * states that a non-AP station should transition into the
3356 * authenticated/associated state only after the station acknowledges
3357 * the (Re)Association Response frame. However, still do this as:
3359 * 1. In case the station does not acknowledge the (Re)Association
3360 * Response frame, it will be removed.
3361 * 2. Data frames will be dropped in the kernel until the station is
3362 * set into authorized state, and there are no significant known
3363 * issues with processing other non-Data Class 3 frames during this
3366 if (resp
== WLAN_STATUS_SUCCESS
&& sta
&& add_associated_sta(hapd
, sta
))
3367 resp
= WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
;
3371 eloop_cancel_timeout(fils_hlp_timeout
, hapd
, sta
);
3372 os_free(sta
->fils_pending_assoc_req
);
3373 sta
->fils_pending_assoc_req
= NULL
;
3374 sta
->fils_pending_assoc_req_len
= 0;
3375 wpabuf_free(sta
->fils_hlp_resp
);
3376 sta
->fils_hlp_resp
= NULL
;
3378 if (sta
&& delay_assoc
&& resp
== WLAN_STATUS_SUCCESS
) {
3379 sta
->fils_pending_assoc_req
= tmp
;
3380 sta
->fils_pending_assoc_req_len
= left
;
3381 sta
->fils_pending_assoc_is_reassoc
= reassoc
;
3382 sta
->fils_drv_assoc_finish
= 0;
3383 wpa_printf(MSG_DEBUG
,
3384 "FILS: Waiting for HLP processing before sending (Re)Association Response frame to "
3385 MACSTR
, MAC2STR(sta
->addr
));
3386 eloop_cancel_timeout(fils_hlp_timeout
, hapd
, sta
);
3387 eloop_register_timeout(0, hapd
->conf
->fils_hlp_wait_time
* 1024,
3388 fils_hlp_timeout
, hapd
, sta
);
3391 #endif /* CONFIG_FILS */
3393 reply_res
= send_assoc_resp(hapd
, sta
, mgmt
->sa
, resp
, reassoc
, pos
,
3398 * Remove the station in case tranmission of a success response fails
3399 * (the STA was added associated to the driver) or if the station was
3400 * previously added unassociated.
3402 if (sta
&& ((reply_res
!= WLAN_STATUS_SUCCESS
&&
3403 resp
== WLAN_STATUS_SUCCESS
) || sta
->added_unassoc
)) {
3404 hostapd_drv_sta_remove(hapd
, sta
->addr
);
3405 sta
->added_unassoc
= 0;
3410 static void handle_disassoc(struct hostapd_data
*hapd
,
3411 const struct ieee80211_mgmt
*mgmt
, size_t len
)
3413 struct sta_info
*sta
;
3415 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.disassoc
)) {
3416 wpa_printf(MSG_INFO
, "handle_disassoc - too short payload (len=%lu)",
3417 (unsigned long) len
);
3421 wpa_printf(MSG_DEBUG
, "disassocation: STA=" MACSTR
" reason_code=%d",
3423 le_to_host16(mgmt
->u
.disassoc
.reason_code
));
3425 sta
= ap_get_sta(hapd
, mgmt
->sa
);
3427 wpa_printf(MSG_INFO
, "Station " MACSTR
" trying to disassociate, but it is not associated",
3432 ap_sta_set_authorized(hapd
, sta
, 0);
3433 sta
->last_seq_ctrl
= WLAN_INVALID_MGMT_SEQ
;
3434 sta
->flags
&= ~(WLAN_STA_ASSOC
| WLAN_STA_ASSOC_REQ_OK
);
3435 wpa_auth_sm_event(sta
->wpa_sm
, WPA_DISASSOC
);
3436 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
3437 HOSTAPD_LEVEL_INFO
, "disassociated");
3438 sta
->acct_terminate_cause
= RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST
;
3439 ieee802_1x_notify_port_enabled(sta
->eapol_sm
, 0);
3440 /* Stop Accounting and IEEE 802.1X sessions, but leave the STA
3442 accounting_sta_stop(hapd
, sta
);
3443 ieee802_1x_free_station(hapd
, sta
);
3445 hostapd_drv_br_delete_ip_neigh(hapd
, 4, (u8
*) &sta
->ipaddr
);
3446 ap_sta_ip6addr_del(hapd
, sta
);
3447 hostapd_drv_sta_remove(hapd
, sta
->addr
);
3448 sta
->added_unassoc
= 0;
3450 if (sta
->timeout_next
== STA_NULLFUNC
||
3451 sta
->timeout_next
== STA_DISASSOC
) {
3452 sta
->timeout_next
= STA_DEAUTH
;
3453 eloop_cancel_timeout(ap_handle_timer
, hapd
, sta
);
3454 eloop_register_timeout(AP_DEAUTH_DELAY
, 0, ap_handle_timer
,
3458 mlme_disassociate_indication(
3459 hapd
, sta
, le_to_host16(mgmt
->u
.disassoc
.reason_code
));
3461 /* DMG/IEEE 802.11ad does not use deauthication. Deallocate sta upon
3462 * disassociation. */
3463 if (hapd
->iface
->current_mode
&&
3464 hapd
->iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211AD
) {
3465 sta
->flags
&= ~WLAN_STA_AUTH
;
3466 wpa_auth_sm_event(sta
->wpa_sm
, WPA_DEAUTH
);
3467 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
3468 HOSTAPD_LEVEL_DEBUG
, "deauthenticated");
3469 ap_free_sta(hapd
, sta
);
3474 static void handle_deauth(struct hostapd_data
*hapd
,
3475 const struct ieee80211_mgmt
*mgmt
, size_t len
)
3477 struct sta_info
*sta
;
3479 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.deauth
)) {
3480 wpa_msg(hapd
->msg_ctx
, MSG_DEBUG
, "handle_deauth - too short "
3481 "payload (len=%lu)", (unsigned long) len
);
3485 wpa_msg(hapd
->msg_ctx
, MSG_DEBUG
, "deauthentication: STA=" MACSTR
3487 MAC2STR(mgmt
->sa
), le_to_host16(mgmt
->u
.deauth
.reason_code
));
3489 sta
= ap_get_sta(hapd
, mgmt
->sa
);
3491 wpa_msg(hapd
->msg_ctx
, MSG_DEBUG
, "Station " MACSTR
" trying "
3492 "to deauthenticate, but it is not authenticated",
3497 ap_sta_set_authorized(hapd
, sta
, 0);
3498 sta
->last_seq_ctrl
= WLAN_INVALID_MGMT_SEQ
;
3499 sta
->flags
&= ~(WLAN_STA_AUTH
| WLAN_STA_ASSOC
|
3500 WLAN_STA_ASSOC_REQ_OK
);
3501 wpa_auth_sm_event(sta
->wpa_sm
, WPA_DEAUTH
);
3502 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
3503 HOSTAPD_LEVEL_DEBUG
, "deauthenticated");
3504 mlme_deauthenticate_indication(
3505 hapd
, sta
, le_to_host16(mgmt
->u
.deauth
.reason_code
));
3506 sta
->acct_terminate_cause
= RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST
;
3507 ieee802_1x_notify_port_enabled(sta
->eapol_sm
, 0);
3508 ap_free_sta(hapd
, sta
);
3512 static void handle_beacon(struct hostapd_data
*hapd
,
3513 const struct ieee80211_mgmt
*mgmt
, size_t len
,
3514 struct hostapd_frame_info
*fi
)
3516 struct ieee802_11_elems elems
;
3518 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.beacon
)) {
3519 wpa_printf(MSG_INFO
, "handle_beacon - too short payload (len=%lu)",
3520 (unsigned long) len
);
3524 (void) ieee802_11_parse_elems(mgmt
->u
.beacon
.variable
,
3525 len
- (IEEE80211_HDRLEN
+
3526 sizeof(mgmt
->u
.beacon
)), &elems
,
3529 ap_list_process_beacon(hapd
->iface
, mgmt
, &elems
, fi
);
3533 #ifdef CONFIG_IEEE80211W
3535 static int hostapd_sa_query_action(struct hostapd_data
*hapd
,
3536 const struct ieee80211_mgmt
*mgmt
,
3541 end
= mgmt
->u
.action
.u
.sa_query_resp
.trans_id
+
3542 WLAN_SA_QUERY_TR_ID_LEN
;
3543 if (((u8
*) mgmt
) + len
< end
) {
3544 wpa_printf(MSG_DEBUG
, "IEEE 802.11: Too short SA Query Action "
3545 "frame (len=%lu)", (unsigned long) len
);
3549 ieee802_11_sa_query_action(hapd
, mgmt
->sa
,
3550 mgmt
->u
.action
.u
.sa_query_resp
.action
,
3551 mgmt
->u
.action
.u
.sa_query_resp
.trans_id
);
3556 static int robust_action_frame(u8 category
)
3558 return category
!= WLAN_ACTION_PUBLIC
&&
3559 category
!= WLAN_ACTION_HT
;
3561 #endif /* CONFIG_IEEE80211W */
3564 static int handle_action(struct hostapd_data
*hapd
,
3565 const struct ieee80211_mgmt
*mgmt
, size_t len
)
3567 struct sta_info
*sta
;
3568 sta
= ap_get_sta(hapd
, mgmt
->sa
);
3570 if (len
< IEEE80211_HDRLEN
+ 1) {
3571 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
3572 HOSTAPD_LEVEL_DEBUG
,
3573 "handle_action - too short payload (len=%lu)",
3574 (unsigned long) len
);
3578 if (mgmt
->u
.action
.category
!= WLAN_ACTION_PUBLIC
&&
3579 (sta
== NULL
|| !(sta
->flags
& WLAN_STA_ASSOC
))) {
3580 wpa_printf(MSG_DEBUG
, "IEEE 802.11: Ignored Action "
3581 "frame (category=%u) from unassociated STA " MACSTR
,
3582 mgmt
->u
.action
.category
, MAC2STR(mgmt
->sa
));
3586 #ifdef CONFIG_IEEE80211W
3587 if (sta
&& (sta
->flags
& WLAN_STA_MFP
) &&
3588 !(mgmt
->frame_control
& host_to_le16(WLAN_FC_ISWEP
)) &&
3589 robust_action_frame(mgmt
->u
.action
.category
)) {
3590 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
3591 HOSTAPD_LEVEL_DEBUG
,
3592 "Dropped unprotected Robust Action frame from "
3596 #endif /* CONFIG_IEEE80211W */
3599 u16 fc
= le_to_host16(mgmt
->frame_control
);
3600 u16 seq_ctrl
= le_to_host16(mgmt
->seq_ctrl
);
3602 if ((fc
& WLAN_FC_RETRY
) &&
3603 sta
->last_seq_ctrl
!= WLAN_INVALID_MGMT_SEQ
&&
3604 sta
->last_seq_ctrl
== seq_ctrl
&&
3605 sta
->last_subtype
== WLAN_FC_STYPE_ACTION
) {
3606 hostapd_logger(hapd
, sta
->addr
,
3607 HOSTAPD_MODULE_IEEE80211
,
3608 HOSTAPD_LEVEL_DEBUG
,
3609 "Drop repeated action frame seq_ctrl=0x%x",
3614 sta
->last_seq_ctrl
= seq_ctrl
;
3615 sta
->last_subtype
= WLAN_FC_STYPE_ACTION
;
3618 switch (mgmt
->u
.action
.category
) {
3619 #ifdef CONFIG_IEEE80211R_AP
3620 case WLAN_ACTION_FT
:
3622 wpa_ft_action_rx(sta
->wpa_sm
, (u8
*) &mgmt
->u
.action
,
3623 len
- IEEE80211_HDRLEN
))
3626 #endif /* CONFIG_IEEE80211R_AP */
3627 case WLAN_ACTION_WMM
:
3628 hostapd_wmm_action(hapd
, mgmt
, len
);
3630 #ifdef CONFIG_IEEE80211W
3631 case WLAN_ACTION_SA_QUERY
:
3632 return hostapd_sa_query_action(hapd
, mgmt
, len
);
3633 #endif /* CONFIG_IEEE80211W */
3634 #ifdef CONFIG_WNM_AP
3635 case WLAN_ACTION_WNM
:
3636 ieee802_11_rx_wnm_action_ap(hapd
, mgmt
, len
);
3638 #endif /* CONFIG_WNM_AP */
3640 case WLAN_ACTION_FST
:
3641 if (hapd
->iface
->fst
)
3642 fst_rx_action(hapd
->iface
->fst
, mgmt
, len
);
3644 wpa_printf(MSG_DEBUG
,
3645 "FST: Ignore FST Action frame - no FST attached");
3647 #endif /* CONFIG_FST */
3648 case WLAN_ACTION_PUBLIC
:
3649 case WLAN_ACTION_PROTECTED_DUAL
:
3650 #ifdef CONFIG_IEEE80211N
3651 if (len
>= IEEE80211_HDRLEN
+ 2 &&
3652 mgmt
->u
.action
.u
.public_action
.action
==
3653 WLAN_PA_20_40_BSS_COEX
) {
3654 wpa_printf(MSG_DEBUG
,
3655 "HT20/40 coex mgmt frame received from STA "
3656 MACSTR
, MAC2STR(mgmt
->sa
));
3657 hostapd_2040_coex_action(hapd
, mgmt
, len
);
3660 #endif /* CONFIG_IEEE80211N */
3662 if (len
>= IEEE80211_HDRLEN
+ 6 &&
3663 mgmt
->u
.action
.u
.vs_public_action
.action
==
3664 WLAN_PA_VENDOR_SPECIFIC
&&
3665 WPA_GET_BE24(mgmt
->u
.action
.u
.vs_public_action
.oui
) ==
3667 mgmt
->u
.action
.u
.vs_public_action
.variable
[0] ==
3669 const u8
*pos
, *end
;
3671 pos
= mgmt
->u
.action
.u
.vs_public_action
.oui
;
3672 end
= ((const u8
*) mgmt
) + len
;
3673 hostapd_dpp_rx_action(hapd
, mgmt
->sa
, pos
, end
- pos
,
3677 if (len
>= IEEE80211_HDRLEN
+ 2 &&
3678 (mgmt
->u
.action
.u
.public_action
.action
==
3679 WLAN_PA_GAS_INITIAL_RESP
||
3680 mgmt
->u
.action
.u
.public_action
.action
==
3681 WLAN_PA_GAS_COMEBACK_RESP
)) {
3682 const u8
*pos
, *end
;
3684 pos
= &mgmt
->u
.action
.u
.public_action
.action
;
3685 end
= ((const u8
*) mgmt
) + len
;
3686 gas_query_ap_rx(hapd
->gas
, mgmt
->sa
,
3687 mgmt
->u
.action
.category
,
3688 pos
, end
- pos
, hapd
->iface
->freq
);
3691 #endif /* CONFIG_DPP */
3692 if (hapd
->public_action_cb
) {
3693 hapd
->public_action_cb(hapd
->public_action_cb_ctx
,
3697 if (hapd
->public_action_cb2
) {
3698 hapd
->public_action_cb2(hapd
->public_action_cb2_ctx
,
3702 if (hapd
->public_action_cb
|| hapd
->public_action_cb2
)
3705 case WLAN_ACTION_VENDOR_SPECIFIC
:
3706 if (hapd
->vendor_action_cb
) {
3707 if (hapd
->vendor_action_cb(hapd
->vendor_action_cb_ctx
,
3709 hapd
->iface
->freq
) == 0)
3713 case WLAN_ACTION_RADIO_MEASUREMENT
:
3714 hostapd_handle_radio_measurement(hapd
, (const u8
*) mgmt
, len
);
3718 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
3719 HOSTAPD_LEVEL_DEBUG
,
3720 "handle_action - unknown action category %d or invalid "
3722 mgmt
->u
.action
.category
);
3723 if (!is_multicast_ether_addr(mgmt
->da
) &&
3724 !(mgmt
->u
.action
.category
& 0x80) &&
3725 !is_multicast_ether_addr(mgmt
->sa
)) {
3726 struct ieee80211_mgmt
*resp
;
3729 * IEEE 802.11-REVma/D9.0 - 7.3.1.11
3730 * Return the Action frame to the source without change
3731 * except that MSB of the Category set to 1.
3733 wpa_printf(MSG_DEBUG
, "IEEE 802.11: Return unknown Action "
3734 "frame back to sender");
3735 resp
= os_memdup(mgmt
, len
);
3738 os_memcpy(resp
->da
, resp
->sa
, ETH_ALEN
);
3739 os_memcpy(resp
->sa
, hapd
->own_addr
, ETH_ALEN
);
3740 os_memcpy(resp
->bssid
, hapd
->own_addr
, ETH_ALEN
);
3741 resp
->u
.action
.category
|= 0x80;
3743 if (hostapd_drv_send_mlme(hapd
, resp
, len
, 0) < 0) {
3744 wpa_printf(MSG_ERROR
, "IEEE 802.11: Failed to send "
3755 * ieee802_11_mgmt - process incoming IEEE 802.11 management frames
3756 * @hapd: hostapd BSS data structure (the BSS to which the management frame was
3758 * @buf: management frame data (starting from IEEE 802.11 header)
3759 * @len: length of frame data in octets
3760 * @fi: meta data about received frame (signal level, etc.)
3762 * Process all incoming IEEE 802.11 management frames. This will be called for
3763 * each frame received from the kernel driver through wlan#ap interface. In
3764 * addition, it can be called to re-inserted pending frames (e.g., when using
3765 * external RADIUS server as an MAC ACL).
3767 int ieee802_11_mgmt(struct hostapd_data
*hapd
, const u8
*buf
, size_t len
,
3768 struct hostapd_frame_info
*fi
)
3770 struct ieee80211_mgmt
*mgmt
;
3777 mgmt
= (struct ieee80211_mgmt
*) buf
;
3778 fc
= le_to_host16(mgmt
->frame_control
);
3779 stype
= WLAN_FC_GET_STYPE(fc
);
3781 if (stype
== WLAN_FC_STYPE_BEACON
) {
3782 handle_beacon(hapd
, mgmt
, len
, fi
);
3786 if (!is_broadcast_ether_addr(mgmt
->bssid
) &&
3788 /* Invitation responses can be sent with the peer MAC as BSSID */
3789 !((hapd
->conf
->p2p
& P2P_GROUP_OWNER
) &&
3790 stype
== WLAN_FC_STYPE_ACTION
) &&
3791 #endif /* CONFIG_P2P */
3793 !(hapd
->conf
->mesh
& MESH_ENABLED
) &&
3794 #endif /* CONFIG_MESH */
3795 os_memcmp(mgmt
->bssid
, hapd
->own_addr
, ETH_ALEN
) != 0) {
3796 wpa_printf(MSG_INFO
, "MGMT: BSSID=" MACSTR
" not our address",
3797 MAC2STR(mgmt
->bssid
));
3802 if (stype
== WLAN_FC_STYPE_PROBE_REQ
) {
3803 handle_probe_req(hapd
, mgmt
, len
, fi
->ssi_signal
);
3807 if ((!is_broadcast_ether_addr(mgmt
->da
) ||
3808 stype
!= WLAN_FC_STYPE_ACTION
) &&
3809 os_memcmp(mgmt
->da
, hapd
->own_addr
, ETH_ALEN
) != 0) {
3810 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
3811 HOSTAPD_LEVEL_DEBUG
,
3812 "MGMT: DA=" MACSTR
" not our address",
3817 if (hapd
->iconf
->track_sta_max_num
)
3818 sta_track_add(hapd
->iface
, mgmt
->sa
, fi
->ssi_signal
);
3821 case WLAN_FC_STYPE_AUTH
:
3822 wpa_printf(MSG_DEBUG
, "mgmt::auth");
3823 handle_auth(hapd
, mgmt
, len
);
3826 case WLAN_FC_STYPE_ASSOC_REQ
:
3827 wpa_printf(MSG_DEBUG
, "mgmt::assoc_req");
3828 handle_assoc(hapd
, mgmt
, len
, 0);
3831 case WLAN_FC_STYPE_REASSOC_REQ
:
3832 wpa_printf(MSG_DEBUG
, "mgmt::reassoc_req");
3833 handle_assoc(hapd
, mgmt
, len
, 1);
3836 case WLAN_FC_STYPE_DISASSOC
:
3837 wpa_printf(MSG_DEBUG
, "mgmt::disassoc");
3838 handle_disassoc(hapd
, mgmt
, len
);
3841 case WLAN_FC_STYPE_DEAUTH
:
3842 wpa_msg(hapd
->msg_ctx
, MSG_DEBUG
, "mgmt::deauth");
3843 handle_deauth(hapd
, mgmt
, len
);
3846 case WLAN_FC_STYPE_ACTION
:
3847 wpa_printf(MSG_DEBUG
, "mgmt::action");
3848 ret
= handle_action(hapd
, mgmt
, len
);
3851 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
3852 HOSTAPD_LEVEL_DEBUG
,
3853 "unknown mgmt frame subtype %d", stype
);
3861 static void handle_auth_cb(struct hostapd_data
*hapd
,
3862 const struct ieee80211_mgmt
*mgmt
,
3865 u16 auth_alg
, auth_transaction
, status_code
;
3866 struct sta_info
*sta
;
3868 sta
= ap_get_sta(hapd
, mgmt
->da
);
3870 wpa_printf(MSG_INFO
, "handle_auth_cb: STA " MACSTR
" not found",
3875 auth_alg
= le_to_host16(mgmt
->u
.auth
.auth_alg
);
3876 auth_transaction
= le_to_host16(mgmt
->u
.auth
.auth_transaction
);
3877 status_code
= le_to_host16(mgmt
->u
.auth
.status_code
);
3880 hostapd_logger(hapd
, mgmt
->da
, HOSTAPD_MODULE_IEEE80211
,
3881 HOSTAPD_LEVEL_NOTICE
,
3882 "did not acknowledge authentication response");
3886 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.auth
)) {
3887 wpa_printf(MSG_INFO
, "handle_auth_cb - too short payload (len=%lu)",
3888 (unsigned long) len
);
3892 if (status_code
== WLAN_STATUS_SUCCESS
&&
3893 ((auth_alg
== WLAN_AUTH_OPEN
&& auth_transaction
== 2) ||
3894 (auth_alg
== WLAN_AUTH_SHARED_KEY
&& auth_transaction
== 4))) {
3895 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
3896 HOSTAPD_LEVEL_INFO
, "authenticated");
3897 sta
->flags
|= WLAN_STA_AUTH
;
3898 if (sta
->added_unassoc
)
3899 hostapd_set_sta_flags(hapd
, sta
);
3904 if (status_code
!= WLAN_STATUS_SUCCESS
&& sta
->added_unassoc
) {
3905 hostapd_drv_sta_remove(hapd
, sta
->addr
);
3906 sta
->added_unassoc
= 0;
3911 static void hostapd_set_wds_encryption(struct hostapd_data
*hapd
,
3912 struct sta_info
*sta
,
3916 struct hostapd_ssid
*ssid
= &hapd
->conf
->ssid
;
3918 if (hapd
->conf
->ieee802_1x
|| hapd
->conf
->wpa
)
3921 for (i
= 0; i
< 4; i
++) {
3922 if (ssid
->wep
.key
[i
] &&
3923 hostapd_drv_set_key(ifname_wds
, hapd
, WPA_ALG_WEP
, NULL
, i
,
3924 i
== ssid
->wep
.idx
, NULL
, 0,
3925 ssid
->wep
.key
[i
], ssid
->wep
.len
[i
])) {
3926 wpa_printf(MSG_WARNING
,
3927 "Could not set WEP keys for WDS interface; %s",
3935 static void handle_assoc_cb(struct hostapd_data
*hapd
,
3936 const struct ieee80211_mgmt
*mgmt
,
3937 size_t len
, int reassoc
, int ok
)
3940 struct sta_info
*sta
;
3943 sta
= ap_get_sta(hapd
, mgmt
->da
);
3945 wpa_printf(MSG_INFO
, "handle_assoc_cb: STA " MACSTR
" not found",
3950 if (len
< IEEE80211_HDRLEN
+ (reassoc
? sizeof(mgmt
->u
.reassoc_resp
) :
3951 sizeof(mgmt
->u
.assoc_resp
))) {
3952 wpa_printf(MSG_INFO
,
3953 "handle_assoc_cb(reassoc=%d) - too short payload (len=%lu)",
3954 reassoc
, (unsigned long) len
);
3955 hostapd_drv_sta_remove(hapd
, sta
->addr
);
3960 status
= le_to_host16(mgmt
->u
.reassoc_resp
.status_code
);
3962 status
= le_to_host16(mgmt
->u
.assoc_resp
.status_code
);
3965 hostapd_logger(hapd
, mgmt
->da
, HOSTAPD_MODULE_IEEE80211
,
3966 HOSTAPD_LEVEL_DEBUG
,
3967 "did not acknowledge association response");
3968 sta
->flags
&= ~WLAN_STA_ASSOC_REQ_OK
;
3969 /* The STA is added only in case of SUCCESS */
3970 if (status
== WLAN_STATUS_SUCCESS
)
3971 hostapd_drv_sta_remove(hapd
, sta
->addr
);
3976 if (status
!= WLAN_STATUS_SUCCESS
)
3979 /* Stop previous accounting session, if one is started, and allocate
3980 * new session id for the new session. */
3981 accounting_sta_stop(hapd
, sta
);
3983 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
3985 "associated (aid %d)",
3988 if (sta
->flags
& WLAN_STA_ASSOC
)
3990 sta
->flags
|= WLAN_STA_ASSOC
;
3991 sta
->flags
&= ~WLAN_STA_WNM_SLEEP_MODE
;
3992 if ((!hapd
->conf
->ieee802_1x
&& !hapd
->conf
->wpa
&&
3993 !hapd
->conf
->osen
) ||
3994 sta
->auth_alg
== WLAN_AUTH_FILS_SK
||
3995 sta
->auth_alg
== WLAN_AUTH_FILS_SK_PFS
||
3996 sta
->auth_alg
== WLAN_AUTH_FILS_PK
||
3997 sta
->auth_alg
== WLAN_AUTH_FT
) {
3999 * Open, static WEP, FT protocol, or FILS; no separate
4000 * authorization step.
4002 ap_sta_set_authorized(hapd
, sta
, 1);
4006 mlme_reassociate_indication(hapd
, sta
);
4008 mlme_associate_indication(hapd
, sta
);
4010 #ifdef CONFIG_IEEE80211W
4011 sta
->sa_query_timed_out
= 0;
4012 #endif /* CONFIG_IEEE80211W */
4014 if (sta
->eapol_sm
== NULL
) {
4016 * This STA does not use RADIUS server for EAP authentication,
4017 * so bind it to the selected VLAN interface now, since the
4018 * interface selection is not going to change anymore.
4020 if (ap_sta_bind_vlan(hapd
, sta
) < 0)
4022 } else if (sta
->vlan_id
) {
4023 /* VLAN ID already set (e.g., by PMKSA caching), so bind STA */
4024 if (ap_sta_bind_vlan(hapd
, sta
) < 0)
4028 hostapd_set_sta_flags(hapd
, sta
);
4030 if (!(sta
->flags
& WLAN_STA_WDS
) && sta
->pending_wds_enable
) {
4031 wpa_printf(MSG_DEBUG
, "Enable 4-address WDS mode for STA "
4032 MACSTR
" based on pending request",
4033 MAC2STR(sta
->addr
));
4034 sta
->pending_wds_enable
= 0;
4035 sta
->flags
|= WLAN_STA_WDS
;
4038 if (sta
->flags
& WLAN_STA_WDS
) {
4040 char ifname_wds
[IFNAMSIZ
+ 1];
4042 wpa_printf(MSG_DEBUG
, "Reenable 4-address WDS mode for STA "
4044 MAC2STR(sta
->addr
), sta
->aid
);
4045 ret
= hostapd_set_wds_sta(hapd
, ifname_wds
, sta
->addr
,
4048 hostapd_set_wds_encryption(hapd
, sta
, ifname_wds
);
4051 if (sta
->auth_alg
== WLAN_AUTH_FT
)
4052 wpa_auth_sm_event(sta
->wpa_sm
, WPA_ASSOC_FT
);
4054 wpa_auth_sm_event(sta
->wpa_sm
, WPA_ASSOC
);
4055 hapd
->new_assoc_sta_cb(hapd
, sta
, !new_assoc
);
4056 ieee802_1x_notify_port_enabled(sta
->eapol_sm
, 1);
4059 if ((sta
->auth_alg
== WLAN_AUTH_FILS_SK
||
4060 sta
->auth_alg
== WLAN_AUTH_FILS_SK_PFS
||
4061 sta
->auth_alg
== WLAN_AUTH_FILS_PK
) &&
4062 fils_set_tk(sta
->wpa_sm
) < 0) {
4063 wpa_printf(MSG_DEBUG
, "FILS: TK configuration failed");
4064 ap_sta_disconnect(hapd
, sta
, sta
->addr
,
4065 WLAN_REASON_UNSPECIFIED
);
4068 #endif /* CONFIG_FILS */
4070 if (sta
->pending_eapol_rx
) {
4071 struct os_reltime now
, age
;
4073 os_get_reltime(&now
);
4074 os_reltime_sub(&now
, &sta
->pending_eapol_rx
->rx_time
, &age
);
4075 if (age
.sec
== 0 && age
.usec
< 200000) {
4076 wpa_printf(MSG_DEBUG
,
4077 "Process pending EAPOL frame that was received from " MACSTR
" just before association notification",
4078 MAC2STR(sta
->addr
));
4081 wpabuf_head(sta
->pending_eapol_rx
->buf
),
4082 wpabuf_len(sta
->pending_eapol_rx
->buf
));
4084 wpabuf_free(sta
->pending_eapol_rx
->buf
);
4085 os_free(sta
->pending_eapol_rx
);
4086 sta
->pending_eapol_rx
= NULL
;
4091 static void handle_deauth_cb(struct hostapd_data
*hapd
,
4092 const struct ieee80211_mgmt
*mgmt
,
4095 struct sta_info
*sta
;
4096 if (is_multicast_ether_addr(mgmt
->da
))
4098 sta
= ap_get_sta(hapd
, mgmt
->da
);
4100 wpa_printf(MSG_DEBUG
, "handle_deauth_cb: STA " MACSTR
4101 " not found", MAC2STR(mgmt
->da
));
4105 wpa_printf(MSG_DEBUG
, "STA " MACSTR
" acknowledged deauth",
4106 MAC2STR(sta
->addr
));
4108 wpa_printf(MSG_DEBUG
, "STA " MACSTR
" did not acknowledge "
4109 "deauth", MAC2STR(sta
->addr
));
4111 ap_sta_deauth_cb(hapd
, sta
);
4115 static void handle_disassoc_cb(struct hostapd_data
*hapd
,
4116 const struct ieee80211_mgmt
*mgmt
,
4119 struct sta_info
*sta
;
4120 if (is_multicast_ether_addr(mgmt
->da
))
4122 sta
= ap_get_sta(hapd
, mgmt
->da
);
4124 wpa_printf(MSG_DEBUG
, "handle_disassoc_cb: STA " MACSTR
4125 " not found", MAC2STR(mgmt
->da
));
4129 wpa_printf(MSG_DEBUG
, "STA " MACSTR
" acknowledged disassoc",
4130 MAC2STR(sta
->addr
));
4132 wpa_printf(MSG_DEBUG
, "STA " MACSTR
" did not acknowledge "
4133 "disassoc", MAC2STR(sta
->addr
));
4135 ap_sta_disassoc_cb(hapd
, sta
);
4139 static void handle_action_cb(struct hostapd_data
*hapd
,
4140 const struct ieee80211_mgmt
*mgmt
,
4143 struct sta_info
*sta
;
4144 const struct rrm_measurement_report_element
*report
;
4146 if (is_multicast_ether_addr(mgmt
->da
))
4149 if (len
>= IEEE80211_HDRLEN
+ 6 &&
4150 mgmt
->u
.action
.category
== WLAN_ACTION_PUBLIC
&&
4151 mgmt
->u
.action
.u
.vs_public_action
.action
==
4152 WLAN_PA_VENDOR_SPECIFIC
&&
4153 WPA_GET_BE24(mgmt
->u
.action
.u
.vs_public_action
.oui
) ==
4155 mgmt
->u
.action
.u
.vs_public_action
.variable
[0] ==
4157 const u8
*pos
, *end
;
4159 pos
= &mgmt
->u
.action
.u
.vs_public_action
.variable
[1];
4160 end
= ((const u8
*) mgmt
) + len
;
4161 hostapd_dpp_tx_status(hapd
, mgmt
->da
, pos
, end
- pos
, ok
);
4164 if (len
>= IEEE80211_HDRLEN
+ 2 &&
4165 mgmt
->u
.action
.category
== WLAN_ACTION_PUBLIC
&&
4166 (mgmt
->u
.action
.u
.public_action
.action
==
4167 WLAN_PA_GAS_INITIAL_REQ
||
4168 mgmt
->u
.action
.u
.public_action
.action
==
4169 WLAN_PA_GAS_COMEBACK_REQ
)) {
4170 const u8
*pos
, *end
;
4172 pos
= mgmt
->u
.action
.u
.public_action
.variable
;
4173 end
= ((const u8
*) mgmt
) + len
;
4174 gas_query_ap_tx_status(hapd
->gas
, mgmt
->da
, pos
, end
- pos
, ok
);
4177 #endif /* CONFIG_DPP */
4178 sta
= ap_get_sta(hapd
, mgmt
->da
);
4180 wpa_printf(MSG_DEBUG
, "handle_action_cb: STA " MACSTR
4181 " not found", MAC2STR(mgmt
->da
));
4185 if (len
< 24 + 5 + sizeof(*report
))
4187 report
= (const struct rrm_measurement_report_element
*)
4188 &mgmt
->u
.action
.u
.rrm
.variable
[2];
4189 if (mgmt
->u
.action
.category
== WLAN_ACTION_RADIO_MEASUREMENT
&&
4190 mgmt
->u
.action
.u
.rrm
.action
== WLAN_RRM_RADIO_MEASUREMENT_REQUEST
&&
4191 report
->eid
== WLAN_EID_MEASURE_REQUEST
&&
4193 report
->type
== MEASURE_TYPE_BEACON
)
4194 hostapd_rrm_beacon_req_tx_status(hapd
, mgmt
, len
, ok
);
4199 * ieee802_11_mgmt_cb - Process management frame TX status callback
4200 * @hapd: hostapd BSS data structure (the BSS from which the management frame
4202 * @buf: management frame data (starting from IEEE 802.11 header)
4203 * @len: length of frame data in octets
4204 * @stype: management frame subtype from frame control field
4205 * @ok: Whether the frame was ACK'ed
4207 void ieee802_11_mgmt_cb(struct hostapd_data
*hapd
, const u8
*buf
, size_t len
,
4210 const struct ieee80211_mgmt
*mgmt
;
4211 mgmt
= (const struct ieee80211_mgmt
*) buf
;
4213 #ifdef CONFIG_TESTING_OPTIONS
4214 if (hapd
->ext_mgmt_frame_handling
) {
4215 size_t hex_len
= 2 * len
+ 1;
4216 char *hex
= os_malloc(hex_len
);
4219 wpa_snprintf_hex(hex
, hex_len
, buf
, len
);
4220 wpa_msg(hapd
->msg_ctx
, MSG_INFO
,
4221 "MGMT-TX-STATUS stype=%u ok=%d buf=%s",
4227 #endif /* CONFIG_TESTING_OPTIONS */
4230 case WLAN_FC_STYPE_AUTH
:
4231 wpa_printf(MSG_DEBUG
, "mgmt::auth cb");
4232 handle_auth_cb(hapd
, mgmt
, len
, ok
);
4234 case WLAN_FC_STYPE_ASSOC_RESP
:
4235 wpa_printf(MSG_DEBUG
, "mgmt::assoc_resp cb");
4236 handle_assoc_cb(hapd
, mgmt
, len
, 0, ok
);
4238 case WLAN_FC_STYPE_REASSOC_RESP
:
4239 wpa_printf(MSG_DEBUG
, "mgmt::reassoc_resp cb");
4240 handle_assoc_cb(hapd
, mgmt
, len
, 1, ok
);
4242 case WLAN_FC_STYPE_PROBE_RESP
:
4243 wpa_printf(MSG_EXCESSIVE
, "mgmt::proberesp cb ok=%d", ok
);
4245 case WLAN_FC_STYPE_DEAUTH
:
4246 wpa_printf(MSG_DEBUG
, "mgmt::deauth cb");
4247 handle_deauth_cb(hapd
, mgmt
, len
, ok
);
4249 case WLAN_FC_STYPE_DISASSOC
:
4250 wpa_printf(MSG_DEBUG
, "mgmt::disassoc cb");
4251 handle_disassoc_cb(hapd
, mgmt
, len
, ok
);
4253 case WLAN_FC_STYPE_ACTION
:
4254 wpa_printf(MSG_DEBUG
, "mgmt::action cb ok=%d", ok
);
4255 handle_action_cb(hapd
, mgmt
, len
, ok
);
4258 wpa_printf(MSG_INFO
, "unknown mgmt cb frame subtype %d", stype
);
4264 int ieee802_11_get_mib(struct hostapd_data
*hapd
, char *buf
, size_t buflen
)
4271 int ieee802_11_get_mib_sta(struct hostapd_data
*hapd
, struct sta_info
*sta
,
4272 char *buf
, size_t buflen
)
4279 void hostapd_tx_status(struct hostapd_data
*hapd
, const u8
*addr
,
4280 const u8
*buf
, size_t len
, int ack
)
4282 struct sta_info
*sta
;
4283 struct hostapd_iface
*iface
= hapd
->iface
;
4285 sta
= ap_get_sta(hapd
, addr
);
4286 if (sta
== NULL
&& iface
->num_bss
> 1) {
4288 for (j
= 0; j
< iface
->num_bss
; j
++) {
4289 hapd
= iface
->bss
[j
];
4290 sta
= ap_get_sta(hapd
, addr
);
4295 if (sta
== NULL
|| !(sta
->flags
& WLAN_STA_ASSOC
))
4297 if (sta
->flags
& WLAN_STA_PENDING_POLL
) {
4298 wpa_printf(MSG_DEBUG
, "STA " MACSTR
" %s pending "
4299 "activity poll", MAC2STR(sta
->addr
),
4300 ack
? "ACKed" : "did not ACK");
4302 sta
->flags
&= ~WLAN_STA_PENDING_POLL
;
4305 ieee802_1x_tx_status(hapd
, sta
, buf
, len
, ack
);
4309 void hostapd_eapol_tx_status(struct hostapd_data
*hapd
, const u8
*dst
,
4310 const u8
*data
, size_t len
, int ack
)
4312 struct sta_info
*sta
;
4313 struct hostapd_iface
*iface
= hapd
->iface
;
4315 sta
= ap_get_sta(hapd
, dst
);
4316 if (sta
== NULL
&& iface
->num_bss
> 1) {
4318 for (j
= 0; j
< iface
->num_bss
; j
++) {
4319 hapd
= iface
->bss
[j
];
4320 sta
= ap_get_sta(hapd
, dst
);
4325 if (sta
== NULL
|| !(sta
->flags
& WLAN_STA_ASSOC
)) {
4326 wpa_printf(MSG_DEBUG
, "Ignore TX status for Data frame to STA "
4327 MACSTR
" that is not currently associated",
4332 ieee802_1x_eapol_tx_status(hapd
, sta
, data
, len
, ack
);
4336 void hostapd_client_poll_ok(struct hostapd_data
*hapd
, const u8
*addr
)
4338 struct sta_info
*sta
;
4339 struct hostapd_iface
*iface
= hapd
->iface
;
4341 sta
= ap_get_sta(hapd
, addr
);
4342 if (sta
== NULL
&& iface
->num_bss
> 1) {
4344 for (j
= 0; j
< iface
->num_bss
; j
++) {
4345 hapd
= iface
->bss
[j
];
4346 sta
= ap_get_sta(hapd
, addr
);
4353 wpa_msg(hapd
->msg_ctx
, MSG_INFO
, AP_STA_POLL_OK MACSTR
,
4354 MAC2STR(sta
->addr
));
4355 if (!(sta
->flags
& WLAN_STA_PENDING_POLL
))
4358 wpa_printf(MSG_DEBUG
, "STA " MACSTR
" ACKed pending "
4359 "activity poll", MAC2STR(sta
->addr
));
4360 sta
->flags
&= ~WLAN_STA_PENDING_POLL
;
4364 void ieee802_11_rx_from_unknown(struct hostapd_data
*hapd
, const u8
*src
,
4367 struct sta_info
*sta
;
4369 sta
= ap_get_sta(hapd
, src
);
4371 ((sta
->flags
& WLAN_STA_ASSOC
) ||
4372 ((sta
->flags
& WLAN_STA_ASSOC_REQ_OK
) && wds
))) {
4373 if (!hapd
->conf
->wds_sta
)
4376 if ((sta
->flags
& (WLAN_STA_ASSOC
| WLAN_STA_ASSOC_REQ_OK
)) ==
4377 WLAN_STA_ASSOC_REQ_OK
) {
4378 wpa_printf(MSG_DEBUG
,
4379 "Postpone 4-address WDS mode enabling for STA "
4380 MACSTR
" since TX status for AssocResp is not yet known",
4381 MAC2STR(sta
->addr
));
4382 sta
->pending_wds_enable
= 1;
4386 if (wds
&& !(sta
->flags
& WLAN_STA_WDS
)) {
4388 char ifname_wds
[IFNAMSIZ
+ 1];
4390 wpa_printf(MSG_DEBUG
, "Enable 4-address WDS mode for "
4391 "STA " MACSTR
" (aid %u)",
4392 MAC2STR(sta
->addr
), sta
->aid
);
4393 sta
->flags
|= WLAN_STA_WDS
;
4394 ret
= hostapd_set_wds_sta(hapd
, ifname_wds
,
4395 sta
->addr
, sta
->aid
, 1);
4397 hostapd_set_wds_encryption(hapd
, sta
,
4403 wpa_printf(MSG_DEBUG
, "Data/PS-poll frame from not associated STA "
4404 MACSTR
, MAC2STR(src
));
4405 if (is_multicast_ether_addr(src
)) {
4406 /* Broadcast bit set in SA?! Ignore the frame silently. */
4410 if (sta
&& (sta
->flags
& WLAN_STA_ASSOC_REQ_OK
)) {
4411 wpa_printf(MSG_DEBUG
, "Association Response to the STA has "
4412 "already been sent, but no TX status yet known - "
4413 "ignore Class 3 frame issue with " MACSTR
,
4418 if (sta
&& (sta
->flags
& WLAN_STA_AUTH
))
4419 hostapd_drv_sta_disassoc(
4421 WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA
);
4423 hostapd_drv_sta_deauth(
4425 WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA
);
4429 #endif /* CONFIG_NATIVE_WINDOWS */