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
, const char *dbg
)
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) (dbg=%s)",
308 MAC2STR(dst
), auth_alg
, auth_transaction
,
309 resp
, (unsigned long) ies_len
, dbg
);
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
,
334 sta
= ap_get_sta(hapd
, dst
);
338 if (sta
->added_unassoc
&& (reply_res
!= WLAN_STATUS_SUCCESS
||
339 status
!= WLAN_STATUS_SUCCESS
)) {
340 hostapd_drv_sta_remove(hapd
, sta
->addr
);
341 sta
->added_unassoc
= 0;
345 if (status
!= WLAN_STATUS_SUCCESS
)
348 hostapd_logger(hapd
, dst
, HOSTAPD_MODULE_IEEE80211
,
349 HOSTAPD_LEVEL_DEBUG
, "authentication OK (FT)");
350 sta
->flags
|= WLAN_STA_AUTH
;
351 mlme_authenticate_indication(hapd
, sta
);
353 #endif /* CONFIG_IEEE80211R_AP */
358 static void sae_set_state(struct sta_info
*sta
, enum sae_state state
,
361 wpa_printf(MSG_DEBUG
, "SAE: State %s -> %s for peer " MACSTR
" (%s)",
362 sae_state_txt(sta
->sae
->state
), sae_state_txt(state
),
363 MAC2STR(sta
->addr
), reason
);
364 sta
->sae
->state
= state
;
368 static struct wpabuf
* auth_build_sae_commit(struct hostapd_data
*hapd
,
369 struct sta_info
*sta
, int update
)
372 const char *password
= NULL
;
373 struct sae_password_entry
*pw
;
374 const char *rx_id
= NULL
;
377 rx_id
= sta
->sae
->tmp
->pw_id
;
379 for (pw
= hapd
->conf
->sae_passwords
; pw
; pw
= pw
->next
) {
380 if (!is_broadcast_ether_addr(pw
->peer_addr
) &&
381 os_memcmp(pw
->peer_addr
, sta
->addr
, ETH_ALEN
) != 0)
383 if ((rx_id
&& !pw
->identifier
) || (!rx_id
&& pw
->identifier
))
385 if (rx_id
&& pw
->identifier
&&
386 os_strcmp(rx_id
, pw
->identifier
) != 0)
388 password
= pw
->password
;
392 password
= hapd
->conf
->ssid
.wpa_passphrase
;
394 wpa_printf(MSG_DEBUG
, "SAE: No password available");
399 sae_prepare_commit(hapd
->own_addr
, sta
->addr
,
400 (u8
*) password
, os_strlen(password
), rx_id
,
402 wpa_printf(MSG_DEBUG
, "SAE: Could not pick PWE");
406 buf
= wpabuf_alloc(SAE_COMMIT_MAX_LEN
+
407 (rx_id
? 3 + os_strlen(rx_id
) : 0));
410 sae_write_commit(sta
->sae
, buf
, sta
->sae
->tmp
?
411 sta
->sae
->tmp
->anti_clogging_token
: NULL
, rx_id
);
417 static struct wpabuf
* auth_build_sae_confirm(struct hostapd_data
*hapd
,
418 struct sta_info
*sta
)
422 buf
= wpabuf_alloc(SAE_CONFIRM_MAX_LEN
);
426 sae_write_confirm(sta
->sae
, buf
);
432 static int auth_sae_send_commit(struct hostapd_data
*hapd
,
433 struct sta_info
*sta
,
434 const u8
*bssid
, int update
)
439 data
= auth_build_sae_commit(hapd
, sta
, update
);
440 if (!data
&& sta
->sae
->tmp
&& sta
->sae
->tmp
->pw_id
)
441 return WLAN_STATUS_UNKNOWN_PASSWORD_IDENTIFIER
;
443 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
445 reply_res
= send_auth_reply(hapd
, sta
->addr
, bssid
, WLAN_AUTH_SAE
, 1,
446 WLAN_STATUS_SUCCESS
, wpabuf_head(data
),
447 wpabuf_len(data
), "sae-send-commit");
455 static int auth_sae_send_confirm(struct hostapd_data
*hapd
,
456 struct sta_info
*sta
,
462 data
= auth_build_sae_confirm(hapd
, sta
);
464 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
466 reply_res
= send_auth_reply(hapd
, sta
->addr
, bssid
, WLAN_AUTH_SAE
, 2,
467 WLAN_STATUS_SUCCESS
, wpabuf_head(data
),
468 wpabuf_len(data
), "sae-send-confirm");
476 static int use_sae_anti_clogging(struct hostapd_data
*hapd
)
478 struct sta_info
*sta
;
479 unsigned int open
= 0;
481 if (hapd
->conf
->sae_anti_clogging_threshold
== 0)
484 for (sta
= hapd
->sta_list
; sta
; sta
= sta
->next
) {
487 if (sta
->sae
->state
!= SAE_COMMITTED
&&
488 sta
->sae
->state
!= SAE_CONFIRMED
)
491 if (open
>= hapd
->conf
->sae_anti_clogging_threshold
)
499 static int check_sae_token(struct hostapd_data
*hapd
, const u8
*addr
,
500 const u8
*token
, size_t token_len
)
502 u8 mac
[SHA256_MAC_LEN
];
504 if (token_len
!= SHA256_MAC_LEN
)
506 if (hmac_sha256(hapd
->sae_token_key
, sizeof(hapd
->sae_token_key
),
507 addr
, ETH_ALEN
, mac
) < 0 ||
508 os_memcmp_const(token
, mac
, SHA256_MAC_LEN
) != 0)
515 static struct wpabuf
* auth_build_token_req(struct hostapd_data
*hapd
,
516 int group
, const u8
*addr
)
520 struct os_reltime now
;
522 os_get_reltime(&now
);
523 if (!os_reltime_initialized(&hapd
->last_sae_token_key_update
) ||
524 os_reltime_expired(&now
, &hapd
->last_sae_token_key_update
, 60)) {
525 if (random_get_bytes(hapd
->sae_token_key
,
526 sizeof(hapd
->sae_token_key
)) < 0)
528 wpa_hexdump(MSG_DEBUG
, "SAE: Updated token key",
529 hapd
->sae_token_key
, sizeof(hapd
->sae_token_key
));
530 hapd
->last_sae_token_key_update
= now
;
533 buf
= wpabuf_alloc(sizeof(le16
) + SHA256_MAC_LEN
);
537 wpabuf_put_le16(buf
, group
); /* Finite Cyclic Group */
539 token
= wpabuf_put(buf
, SHA256_MAC_LEN
);
540 hmac_sha256(hapd
->sae_token_key
, sizeof(hapd
->sae_token_key
),
541 addr
, ETH_ALEN
, token
);
547 static int sae_check_big_sync(struct hostapd_data
*hapd
, struct sta_info
*sta
)
549 if (sta
->sae
->sync
> hapd
->conf
->sae_sync
) {
550 sae_set_state(sta
, SAE_NOTHING
, "Sync > dot11RSNASAESync");
558 static void auth_sae_retransmit_timer(void *eloop_ctx
, void *eloop_data
)
560 struct hostapd_data
*hapd
= eloop_ctx
;
561 struct sta_info
*sta
= eloop_data
;
564 if (sae_check_big_sync(hapd
, sta
))
567 wpa_printf(MSG_DEBUG
, "SAE: Auth SAE retransmit timer for " MACSTR
568 " (sync=%d state=%s)",
569 MAC2STR(sta
->addr
), sta
->sae
->sync
,
570 sae_state_txt(sta
->sae
->state
));
572 switch (sta
->sae
->state
) {
574 ret
= auth_sae_send_commit(hapd
, sta
, hapd
->own_addr
, 0);
575 eloop_register_timeout(0,
576 hapd
->dot11RSNASAERetransPeriod
* 1000,
577 auth_sae_retransmit_timer
, hapd
, sta
);
580 ret
= auth_sae_send_confirm(hapd
, sta
, hapd
->own_addr
);
581 eloop_register_timeout(0,
582 hapd
->dot11RSNASAERetransPeriod
* 1000,
583 auth_sae_retransmit_timer
, hapd
, sta
);
590 if (ret
!= WLAN_STATUS_SUCCESS
)
591 wpa_printf(MSG_INFO
, "SAE: Failed to retransmit: ret=%d", ret
);
595 void sae_clear_retransmit_timer(struct hostapd_data
*hapd
, struct sta_info
*sta
)
597 eloop_cancel_timeout(auth_sae_retransmit_timer
, hapd
, sta
);
601 static void sae_set_retransmit_timer(struct hostapd_data
*hapd
,
602 struct sta_info
*sta
)
604 if (!(hapd
->conf
->mesh
& MESH_ENABLED
))
607 eloop_cancel_timeout(auth_sae_retransmit_timer
, hapd
, sta
);
608 eloop_register_timeout(0, hapd
->dot11RSNASAERetransPeriod
* 1000,
609 auth_sae_retransmit_timer
, hapd
, sta
);
613 void sae_accept_sta(struct hostapd_data
*hapd
, struct sta_info
*sta
)
615 sta
->flags
|= WLAN_STA_AUTH
;
616 sta
->auth_alg
= WLAN_AUTH_SAE
;
617 mlme_authenticate_indication(hapd
, sta
);
618 wpa_auth_sm_event(sta
->wpa_sm
, WPA_AUTH
);
619 sae_set_state(sta
, SAE_ACCEPTED
, "Accept Confirm");
620 wpa_auth_pmksa_add_sae(hapd
->wpa_auth
, sta
->addr
,
621 sta
->sae
->pmk
, sta
->sae
->pmkid
);
625 static int sae_sm_step(struct hostapd_data
*hapd
, struct sta_info
*sta
,
626 const u8
*bssid
, u8 auth_transaction
)
630 if (auth_transaction
!= 1 && auth_transaction
!= 2)
631 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
633 wpa_printf(MSG_DEBUG
, "SAE: Peer " MACSTR
" state=%s auth_trans=%u",
634 MAC2STR(sta
->addr
), sae_state_txt(sta
->sae
->state
),
636 switch (sta
->sae
->state
) {
638 if (auth_transaction
== 1) {
639 ret
= auth_sae_send_commit(hapd
, sta
, bssid
, 1);
642 sae_set_state(sta
, SAE_COMMITTED
, "Sent Commit");
644 if (sae_process_commit(sta
->sae
) < 0)
645 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
648 * In mesh case, both Commit and Confirm can be sent
649 * immediately. In infrastructure BSS, only a single
650 * Authentication frame (Commit) is expected from the AP
651 * here and the second one (Confirm) will be sent once
652 * the STA has sent its second Authentication frame
655 if (hapd
->conf
->mesh
& MESH_ENABLED
) {
657 * Send both Commit and Confirm immediately
658 * based on SAE finite state machine
659 * Nothing -> Confirm transition.
661 ret
= auth_sae_send_confirm(hapd
, sta
, bssid
);
664 sae_set_state(sta
, SAE_CONFIRMED
,
665 "Sent Confirm (mesh)");
668 * For infrastructure BSS, send only the Commit
669 * message now to get alternating sequence of
670 * Authentication frames between the AP and STA.
671 * Confirm will be sent in
672 * Committed -> Confirmed/Accepted transition
673 * when receiving Confirm from STA.
677 sae_set_retransmit_timer(hapd
, sta
);
679 hostapd_logger(hapd
, sta
->addr
,
680 HOSTAPD_MODULE_IEEE80211
,
682 "SAE confirm before commit");
686 sae_clear_retransmit_timer(hapd
, sta
);
687 if (auth_transaction
== 1) {
688 if (sae_process_commit(sta
->sae
) < 0)
689 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
691 ret
= auth_sae_send_confirm(hapd
, sta
, bssid
);
694 sae_set_state(sta
, SAE_CONFIRMED
, "Sent Confirm");
696 sae_set_retransmit_timer(hapd
, sta
);
697 } else if (hapd
->conf
->mesh
& MESH_ENABLED
) {
699 * In mesh case, follow SAE finite state machine and
700 * send Commit now, if sync count allows.
702 if (sae_check_big_sync(hapd
, sta
))
703 return WLAN_STATUS_SUCCESS
;
706 ret
= auth_sae_send_commit(hapd
, sta
, bssid
, 0);
710 sae_set_retransmit_timer(hapd
, sta
);
713 * For instructure BSS, send the postponed Confirm from
714 * Nothing -> Confirmed transition that was reduced to
715 * Nothing -> Committed above.
717 ret
= auth_sae_send_confirm(hapd
, sta
, bssid
);
721 sae_set_state(sta
, SAE_CONFIRMED
, "Sent Confirm");
724 * Since this was triggered on Confirm RX, run another
725 * step to get to Accepted without waiting for
728 return sae_sm_step(hapd
, sta
, bssid
, auth_transaction
);
732 sae_clear_retransmit_timer(hapd
, sta
);
733 if (auth_transaction
== 1) {
734 if (sae_check_big_sync(hapd
, sta
))
735 return WLAN_STATUS_SUCCESS
;
738 ret
= auth_sae_send_commit(hapd
, sta
, bssid
, 1);
742 if (sae_process_commit(sta
->sae
) < 0)
743 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
745 ret
= auth_sae_send_confirm(hapd
, sta
, bssid
);
749 sae_set_retransmit_timer(hapd
, sta
);
751 sta
->sae
->send_confirm
= 0xffff;
752 sae_accept_sta(hapd
, sta
);
756 if (auth_transaction
== 1 &&
757 (hapd
->conf
->mesh
& MESH_ENABLED
)) {
758 wpa_printf(MSG_DEBUG
, "SAE: remove the STA (" MACSTR
759 ") doing reauthentication",
761 ap_free_sta(hapd
, sta
);
762 wpa_auth_pmksa_remove(hapd
->wpa_auth
, sta
->addr
);
763 } else if (auth_transaction
== 1) {
764 wpa_printf(MSG_DEBUG
, "SAE: Start reauthentication");
765 ret
= auth_sae_send_commit(hapd
, sta
, bssid
, 1);
768 sae_set_state(sta
, SAE_COMMITTED
, "Sent Commit");
770 if (sae_process_commit(sta
->sae
) < 0)
771 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
773 sae_set_retransmit_timer(hapd
, sta
);
775 if (sae_check_big_sync(hapd
, sta
))
776 return WLAN_STATUS_SUCCESS
;
779 ret
= auth_sae_send_confirm(hapd
, sta
, bssid
);
780 sae_clear_temp_data(sta
->sae
);
786 wpa_printf(MSG_ERROR
, "SAE: invalid state %d",
788 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
790 return WLAN_STATUS_SUCCESS
;
794 static void sae_pick_next_group(struct hostapd_data
*hapd
, struct sta_info
*sta
)
796 struct sae_data
*sae
= sta
->sae
;
797 int i
, *groups
= hapd
->conf
->sae_groups
;
799 if (sae
->state
!= SAE_COMMITTED
)
802 wpa_printf(MSG_DEBUG
, "SAE: Previously selected group: %d", sae
->group
);
804 for (i
= 0; groups
&& groups
[i
] > 0; i
++) {
805 if (sae
->group
== groups
[i
])
809 if (!groups
|| groups
[i
] <= 0) {
810 wpa_printf(MSG_DEBUG
,
811 "SAE: Previously selected group not found from the current configuration");
817 if (groups
[i
] <= 0) {
818 wpa_printf(MSG_DEBUG
,
819 "SAE: No alternative group enabled");
823 if (sae_set_group(sae
, groups
[i
]) < 0)
828 wpa_printf(MSG_DEBUG
, "SAE: Selected new group: %d", groups
[i
]);
832 static void handle_auth_sae(struct hostapd_data
*hapd
, struct sta_info
*sta
,
833 const struct ieee80211_mgmt
*mgmt
, size_t len
,
834 u16 auth_transaction
, u16 status_code
)
836 int resp
= WLAN_STATUS_SUCCESS
;
837 struct wpabuf
*data
= NULL
;
839 #ifdef CONFIG_TESTING_OPTIONS
840 if (hapd
->conf
->sae_reflection_attack
&& auth_transaction
== 1) {
843 wpa_printf(MSG_DEBUG
, "SAE: TESTING - reflection attack");
844 pos
= mgmt
->u
.auth
.variable
;
845 end
= ((const u8
*) mgmt
) + len
;
846 send_auth_reply(hapd
, mgmt
->sa
, mgmt
->bssid
, WLAN_AUTH_SAE
,
847 auth_transaction
, resp
, pos
, end
- pos
,
848 "auth-sae-reflection-attack");
852 if (hapd
->conf
->sae_commit_override
&& auth_transaction
== 1) {
853 wpa_printf(MSG_DEBUG
, "SAE: TESTING - commit override");
854 send_auth_reply(hapd
, mgmt
->sa
, mgmt
->bssid
, WLAN_AUTH_SAE
,
855 auth_transaction
, resp
,
856 wpabuf_head(hapd
->conf
->sae_commit_override
),
857 wpabuf_len(hapd
->conf
->sae_commit_override
),
858 "sae-commit-override");
861 #endif /* CONFIG_TESTING_OPTIONS */
863 if (auth_transaction
!= 1 ||
864 status_code
!= WLAN_STATUS_SUCCESS
) {
868 sta
->sae
= os_zalloc(sizeof(*sta
->sae
));
873 sae_set_state(sta
, SAE_NOTHING
, "Init");
877 if (sta
->mesh_sae_pmksa_caching
) {
878 wpa_printf(MSG_DEBUG
,
879 "SAE: Cancel use of mesh PMKSA caching because peer starts SAE authentication");
880 wpa_auth_pmksa_remove(hapd
->wpa_auth
, sta
->addr
);
881 sta
->mesh_sae_pmksa_caching
= 0;
884 if (auth_transaction
== 1) {
885 const u8
*token
= NULL
, *pos
, *end
;
886 size_t token_len
= 0;
887 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
889 "start SAE authentication (RX commit, status=%u)",
892 if ((hapd
->conf
->mesh
& MESH_ENABLED
) &&
893 status_code
== WLAN_STATUS_ANTI_CLOGGING_TOKEN_REQ
&&
895 pos
= mgmt
->u
.auth
.variable
;
896 end
= ((const u8
*) mgmt
) + len
;
897 if (pos
+ sizeof(le16
) > end
) {
898 wpa_printf(MSG_ERROR
,
899 "SAE: Too short anti-clogging token request");
900 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
903 resp
= sae_group_allowed(sta
->sae
,
904 hapd
->conf
->sae_groups
,
906 if (resp
!= WLAN_STATUS_SUCCESS
) {
907 wpa_printf(MSG_ERROR
,
908 "SAE: Invalid group in anti-clogging token request");
913 wpabuf_free(sta
->sae
->tmp
->anti_clogging_token
);
914 sta
->sae
->tmp
->anti_clogging_token
=
915 wpabuf_alloc_copy(pos
, end
- pos
);
916 if (sta
->sae
->tmp
->anti_clogging_token
== NULL
) {
917 wpa_printf(MSG_ERROR
,
918 "SAE: Failed to alloc for anti-clogging token");
919 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
924 * IEEE Std 802.11-2012, 11.3.8.6.4: If the Status code
925 * is 76, a new Commit Message shall be constructed
926 * with the Anti-Clogging Token from the received
927 * Authentication frame, and the commit-scalar and
928 * COMMIT-ELEMENT previously sent.
930 resp
= auth_sae_send_commit(hapd
, sta
, mgmt
->bssid
, 0);
931 if (resp
!= WLAN_STATUS_SUCCESS
) {
932 wpa_printf(MSG_ERROR
,
933 "SAE: Failed to send commit message");
936 sae_set_state(sta
, SAE_COMMITTED
,
937 "Sent Commit (anti-clogging token case in mesh)");
939 sae_set_retransmit_timer(hapd
, sta
);
943 if ((hapd
->conf
->mesh
& MESH_ENABLED
) &&
945 WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED
&&
947 wpa_printf(MSG_DEBUG
,
948 "SAE: Peer did not accept our SAE group");
949 sae_pick_next_group(hapd
, sta
);
953 if (status_code
!= WLAN_STATUS_SUCCESS
)
956 if (!(hapd
->conf
->mesh
& MESH_ENABLED
) &&
957 sta
->sae
->state
== SAE_COMMITTED
) {
958 /* This is needed in the infrastructure BSS case to
959 * address a sequence where a STA entry may remain in
960 * hostapd across two attempts to do SAE authentication
961 * by the same STA. The second attempt may end up trying
962 * to use a different group and that would not be
963 * allowed if we remain in Committed state with the
964 * previously set parameters. */
965 sae_set_state(sta
, SAE_NOTHING
,
966 "Clear existing state to allow restart");
967 sae_clear_data(sta
->sae
);
970 resp
= sae_parse_commit(sta
->sae
, mgmt
->u
.auth
.variable
,
971 ((const u8
*) mgmt
) + len
-
972 mgmt
->u
.auth
.variable
, &token
,
973 &token_len
, hapd
->conf
->sae_groups
);
974 if (resp
== SAE_SILENTLY_DISCARD
) {
975 wpa_printf(MSG_DEBUG
,
976 "SAE: Drop commit message from " MACSTR
" due to reflection attack",
981 if (resp
== WLAN_STATUS_UNKNOWN_PASSWORD_IDENTIFIER
) {
982 wpa_msg(hapd
->msg_ctx
, MSG_INFO
,
983 WPA_EVENT_SAE_UNKNOWN_PASSWORD_IDENTIFIER
984 MACSTR
, MAC2STR(sta
->addr
));
985 sae_clear_retransmit_timer(hapd
, sta
);
986 sae_set_state(sta
, SAE_NOTHING
,
987 "Unknown Password Identifier");
991 if (token
&& check_sae_token(hapd
, sta
->addr
, token
, token_len
)
993 wpa_printf(MSG_DEBUG
, "SAE: Drop commit message with "
994 "incorrect token from " MACSTR
,
996 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1000 if (resp
!= WLAN_STATUS_SUCCESS
)
1003 if (!token
&& use_sae_anti_clogging(hapd
)) {
1004 wpa_printf(MSG_DEBUG
,
1005 "SAE: Request anti-clogging token from "
1006 MACSTR
, MAC2STR(sta
->addr
));
1007 data
= auth_build_token_req(hapd
, sta
->sae
->group
,
1009 resp
= WLAN_STATUS_ANTI_CLOGGING_TOKEN_REQ
;
1010 if (hapd
->conf
->mesh
& MESH_ENABLED
)
1011 sae_set_state(sta
, SAE_NOTHING
,
1012 "Request anti-clogging token case in mesh");
1016 resp
= sae_sm_step(hapd
, sta
, mgmt
->bssid
, auth_transaction
);
1017 } else if (auth_transaction
== 2) {
1018 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1019 HOSTAPD_LEVEL_DEBUG
,
1020 "SAE authentication (RX confirm, status=%u)",
1022 if (status_code
!= WLAN_STATUS_SUCCESS
)
1024 if (sta
->sae
->state
>= SAE_CONFIRMED
||
1025 !(hapd
->conf
->mesh
& MESH_ENABLED
)) {
1028 u16 peer_send_confirm
;
1030 var
= mgmt
->u
.auth
.variable
;
1031 var_len
= ((u8
*) mgmt
) + len
- mgmt
->u
.auth
.variable
;
1033 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1037 peer_send_confirm
= WPA_GET_LE16(var
);
1039 if (sta
->sae
->state
== SAE_ACCEPTED
&&
1040 (peer_send_confirm
<= sta
->sae
->rc
||
1041 peer_send_confirm
== 0xffff)) {
1042 wpa_printf(MSG_DEBUG
,
1043 "SAE: Silently ignore unexpected Confirm from peer "
1045 " (peer-send-confirm=%u Rc=%u)",
1047 peer_send_confirm
, sta
->sae
->rc
);
1051 if (sae_check_confirm(sta
->sae
, var
, var_len
) < 0) {
1052 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1055 sta
->sae
->rc
= peer_send_confirm
;
1057 resp
= sae_sm_step(hapd
, sta
, mgmt
->bssid
, auth_transaction
);
1059 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1060 HOSTAPD_LEVEL_DEBUG
,
1061 "unexpected SAE authentication transaction %u (status=%u)",
1062 auth_transaction
, status_code
);
1063 if (status_code
!= WLAN_STATUS_SUCCESS
)
1065 resp
= WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION
;
1069 if (resp
!= WLAN_STATUS_SUCCESS
) {
1070 send_auth_reply(hapd
, mgmt
->sa
, mgmt
->bssid
, WLAN_AUTH_SAE
,
1071 auth_transaction
, resp
,
1072 data
? wpabuf_head(data
) : (u8
*) "",
1073 data
? wpabuf_len(data
) : 0, "auth-sae");
1077 if (sta
->added_unassoc
&& (resp
!= WLAN_STATUS_SUCCESS
||
1078 status_code
!= WLAN_STATUS_SUCCESS
)) {
1079 hostapd_drv_sta_remove(hapd
, sta
->addr
);
1080 sta
->added_unassoc
= 0;
1087 * auth_sae_init_committed - Send COMMIT and start SAE in committed state
1088 * @hapd: BSS data for the device initiating the authentication
1089 * @sta: the peer to which commit authentication frame is sent
1091 * This function implements Init event handling (IEEE Std 802.11-2012,
1092 * 11.3.8.6.3) in which initial COMMIT message is sent. Prior to calling, the
1093 * sta->sae structure should be initialized appropriately via a call to
1094 * sae_prepare_commit().
1096 int auth_sae_init_committed(struct hostapd_data
*hapd
, struct sta_info
*sta
)
1100 if (!sta
->sae
|| !sta
->sae
->tmp
)
1103 if (sta
->sae
->state
!= SAE_NOTHING
)
1106 ret
= auth_sae_send_commit(hapd
, sta
, hapd
->own_addr
, 0);
1110 sae_set_state(sta
, SAE_COMMITTED
, "Init and sent commit");
1112 sae_set_retransmit_timer(hapd
, sta
);
1117 #endif /* CONFIG_SAE */
1120 static u16
wpa_res_to_status_code(int res
)
1122 if (res
== WPA_INVALID_GROUP
)
1123 return WLAN_STATUS_GROUP_CIPHER_NOT_VALID
;
1124 if (res
== WPA_INVALID_PAIRWISE
)
1125 return WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID
;
1126 if (res
== WPA_INVALID_AKMP
)
1127 return WLAN_STATUS_AKMP_NOT_VALID
;
1128 if (res
== WPA_ALLOC_FAIL
)
1129 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
1130 #ifdef CONFIG_IEEE80211W
1131 if (res
== WPA_MGMT_FRAME_PROTECTION_VIOLATION
)
1132 return WLAN_STATUS_ROBUST_MGMT_FRAME_POLICY_VIOLATION
;
1133 if (res
== WPA_INVALID_MGMT_GROUP_CIPHER
)
1134 return WLAN_STATUS_CIPHER_REJECTED_PER_POLICY
;
1135 #endif /* CONFIG_IEEE80211W */
1136 if (res
== WPA_INVALID_MDIE
)
1137 return WLAN_STATUS_INVALID_MDIE
;
1138 if (res
== WPA_INVALID_PMKID
)
1139 return WLAN_STATUS_INVALID_PMKID
;
1140 if (res
!= WPA_IE_OK
)
1141 return WLAN_STATUS_INVALID_IE
;
1142 return WLAN_STATUS_SUCCESS
;
1148 static void handle_auth_fils_finish(struct hostapd_data
*hapd
,
1149 struct sta_info
*sta
, u16 resp
,
1150 struct wpabuf
*data
, int pub
);
1152 void handle_auth_fils(struct hostapd_data
*hapd
, struct sta_info
*sta
,
1153 const u8
*pos
, size_t len
, u16 auth_alg
,
1154 u16 auth_transaction
, u16 status_code
,
1155 void (*cb
)(struct hostapd_data
*hapd
,
1156 struct sta_info
*sta
, u16 resp
,
1157 struct wpabuf
*data
, int pub
))
1159 u16 resp
= WLAN_STATUS_SUCCESS
;
1161 struct ieee802_11_elems elems
;
1163 struct wpa_ie_data rsn
;
1164 struct rsn_pmksa_cache_entry
*pmksa
= NULL
;
1166 if (auth_transaction
!= 1 || status_code
!= WLAN_STATUS_SUCCESS
)
1171 wpa_hexdump(MSG_DEBUG
, "FILS: Authentication frame fields",
1175 #ifdef CONFIG_FILS_SK_PFS
1176 if (auth_alg
== WLAN_AUTH_FILS_SK_PFS
) {
1181 /* Using FILS PFS */
1183 /* Finite Cyclic Group */
1184 if (end
- pos
< 2) {
1185 wpa_printf(MSG_DEBUG
,
1186 "FILS: No room for Finite Cyclic Group");
1187 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1190 group
= WPA_GET_LE16(pos
);
1192 if (group
!= hapd
->conf
->fils_dh_group
) {
1193 wpa_printf(MSG_DEBUG
,
1194 "FILS: Unsupported Finite Cyclic Group: %u (expected %u)",
1195 group
, hapd
->conf
->fils_dh_group
);
1196 resp
= WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED
;
1200 crypto_ecdh_deinit(sta
->fils_ecdh
);
1201 sta
->fils_ecdh
= crypto_ecdh_init(group
);
1202 if (!sta
->fils_ecdh
) {
1203 wpa_printf(MSG_INFO
,
1204 "FILS: Could not initialize ECDH with group %d",
1206 resp
= WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED
;
1210 pub
= crypto_ecdh_get_pubkey(sta
->fils_ecdh
, 1);
1212 wpa_printf(MSG_DEBUG
,
1213 "FILS: Failed to derive ECDH public key");
1214 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1217 elem_len
= wpabuf_len(pub
);
1221 if ((size_t) (end
- pos
) < elem_len
) {
1222 wpa_printf(MSG_DEBUG
, "FILS: No room for Element");
1223 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1227 wpabuf_free(sta
->fils_g_sta
);
1228 sta
->fils_g_sta
= wpabuf_alloc_copy(pos
, elem_len
);
1229 wpabuf_clear_free(sta
->fils_dh_ss
);
1230 sta
->fils_dh_ss
= crypto_ecdh_set_peerkey(sta
->fils_ecdh
, 1,
1232 if (!sta
->fils_dh_ss
) {
1233 wpa_printf(MSG_DEBUG
, "FILS: ECDH operation failed");
1234 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1237 wpa_hexdump_buf_key(MSG_DEBUG
, "FILS: DH_SS", sta
->fils_dh_ss
);
1240 crypto_ecdh_deinit(sta
->fils_ecdh
);
1241 sta
->fils_ecdh
= NULL
;
1242 wpabuf_clear_free(sta
->fils_dh_ss
);
1243 sta
->fils_dh_ss
= NULL
;
1245 #endif /* CONFIG_FILS_SK_PFS */
1247 wpa_hexdump(MSG_DEBUG
, "FILS: Remaining IEs", pos
, end
- pos
);
1248 if (ieee802_11_parse_elems(pos
, end
- pos
, &elems
, 1) == ParseFailed
) {
1249 wpa_printf(MSG_DEBUG
, "FILS: Could not parse elements");
1250 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1255 wpa_hexdump(MSG_DEBUG
, "FILS: RSN element",
1256 elems
.rsn_ie
, elems
.rsn_ie_len
);
1257 if (!elems
.rsn_ie
||
1258 wpa_parse_wpa_ie_rsn(elems
.rsn_ie
- 2, elems
.rsn_ie_len
+ 2,
1260 wpa_printf(MSG_DEBUG
, "FILS: No valid RSN element");
1261 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1266 sta
->wpa_sm
= wpa_auth_sta_init(hapd
->wpa_auth
, sta
->addr
,
1269 wpa_printf(MSG_DEBUG
,
1270 "FILS: Failed to initialize RSN state machine");
1271 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1275 res
= wpa_validate_wpa_ie(hapd
->wpa_auth
, sta
->wpa_sm
,
1276 elems
.rsn_ie
- 2, elems
.rsn_ie_len
+ 2,
1277 elems
.mdie
, elems
.mdie_len
, NULL
, 0);
1278 resp
= wpa_res_to_status_code(res
);
1279 if (resp
!= WLAN_STATUS_SUCCESS
)
1282 if (!elems
.fils_nonce
) {
1283 wpa_printf(MSG_DEBUG
, "FILS: No FILS Nonce field");
1284 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1287 wpa_hexdump(MSG_DEBUG
, "FILS: SNonce", elems
.fils_nonce
,
1289 os_memcpy(sta
->fils_snonce
, elems
.fils_nonce
, FILS_NONCE_LEN
);
1292 if (rsn
.pmkid
&& rsn
.num_pmkid
> 0) {
1296 wpa_hexdump(MSG_DEBUG
, "FILS: PMKID List",
1297 rsn
.pmkid
, rsn
.num_pmkid
* PMKID_LEN
);
1300 num
= rsn
.num_pmkid
;
1302 wpa_hexdump(MSG_DEBUG
, "FILS: PMKID", pmkid
, PMKID_LEN
);
1303 pmksa
= wpa_auth_pmksa_get(hapd
->wpa_auth
, sta
->addr
,
1307 pmksa
= wpa_auth_pmksa_get_fils_cache_id(hapd
->wpa_auth
,
1316 if (pmksa
&& wpa_auth_sta_key_mgmt(sta
->wpa_sm
) != pmksa
->akmp
) {
1317 wpa_printf(MSG_DEBUG
,
1318 "FILS: Matching PMKSA cache entry has different AKMP (0x%x != 0x%x) - ignore",
1319 wpa_auth_sta_key_mgmt(sta
->wpa_sm
), pmksa
->akmp
);
1323 wpa_printf(MSG_DEBUG
, "FILS: Found matching PMKSA cache entry");
1326 if (!elems
.fils_session
) {
1327 wpa_printf(MSG_DEBUG
, "FILS: No FILS Session element");
1328 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1331 wpa_hexdump(MSG_DEBUG
, "FILS: FILS Session", elems
.fils_session
,
1333 os_memcpy(sta
->fils_session
, elems
.fils_session
, FILS_SESSION_LEN
);
1335 /* FILS Wrapped Data */
1336 if (elems
.fils_wrapped_data
) {
1337 wpa_hexdump(MSG_DEBUG
, "FILS: Wrapped Data",
1338 elems
.fils_wrapped_data
,
1339 elems
.fils_wrapped_data_len
);
1341 #ifndef CONFIG_NO_RADIUS
1342 if (!sta
->eapol_sm
) {
1344 ieee802_1x_alloc_eapol_sm(hapd
, sta
);
1346 wpa_printf(MSG_DEBUG
,
1347 "FILS: Forward EAP-Initiate/Re-auth to authentication server");
1348 ieee802_1x_encapsulate_radius(
1349 hapd
, sta
, elems
.fils_wrapped_data
,
1350 elems
.fils_wrapped_data_len
);
1351 sta
->fils_pending_cb
= cb
;
1352 wpa_printf(MSG_DEBUG
,
1353 "FILS: Will send Authentication frame once the response from authentication server is available");
1354 sta
->flags
|= WLAN_STA_PENDING_FILS_ERP
;
1355 /* Calculate pending PMKID here so that we do not need
1356 * to maintain a copy of the EAP-Initiate/Reauth
1358 if (fils_pmkid_erp(wpa_auth_sta_key_mgmt(sta
->wpa_sm
),
1359 elems
.fils_wrapped_data
,
1360 elems
.fils_wrapped_data_len
,
1361 sta
->fils_erp_pmkid
) == 0)
1362 sta
->fils_erp_pmkid_set
= 1;
1364 #else /* CONFIG_NO_RADIUS */
1365 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1367 #endif /* CONFIG_NO_RADIUS */
1373 struct wpabuf
*data
;
1376 data
= prepare_auth_resp_fils(hapd
, sta
, &resp
, pmksa
, NULL
,
1379 wpa_printf(MSG_DEBUG
,
1380 "%s: prepare_auth_resp_fils() returned failure",
1384 cb(hapd
, sta
, resp
, data
, pub
);
1389 static struct wpabuf
*
1390 prepare_auth_resp_fils(struct hostapd_data
*hapd
,
1391 struct sta_info
*sta
, u16
*resp
,
1392 struct rsn_pmksa_cache_entry
*pmksa
,
1393 struct wpabuf
*erp_resp
,
1394 const u8
*msk
, size_t msk_len
,
1397 u8 fils_nonce
[FILS_NONCE_LEN
];
1399 struct wpabuf
*data
= NULL
;
1402 const u8
*pmk
= NULL
;
1404 u8 pmk_buf
[PMK_LEN_MAX
];
1405 struct wpabuf
*pub
= NULL
;
1407 if (*resp
!= WLAN_STATUS_SUCCESS
)
1410 ie
= wpa_auth_get_wpa_ie(hapd
->wpa_auth
, &ielen
);
1412 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1417 /* Add PMKID of the selected PMKSA into RSNE */
1418 ie_buf
= os_malloc(ielen
+ 2 + 2 + PMKID_LEN
);
1420 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1424 os_memcpy(ie_buf
, ie
, ielen
);
1425 if (wpa_insert_pmkid(ie_buf
, &ielen
, pmksa
->pmkid
) < 0) {
1426 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1432 if (random_get_bytes(fils_nonce
, FILS_NONCE_LEN
) < 0) {
1433 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1436 wpa_hexdump(MSG_DEBUG
, "RSN: Generated FILS Nonce",
1437 fils_nonce
, FILS_NONCE_LEN
);
1439 #ifdef CONFIG_FILS_SK_PFS
1440 if (sta
->fils_dh_ss
&& sta
->fils_ecdh
) {
1441 pub
= crypto_ecdh_get_pubkey(sta
->fils_ecdh
, 1);
1443 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1447 #endif /* CONFIG_FILS_SK_PFS */
1449 data
= wpabuf_alloc(1000 + ielen
+ (pub
? wpabuf_len(pub
) : 0));
1451 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1456 #ifdef CONFIG_FILS_SK_PFS
1458 /* Finite Cyclic Group */
1459 wpabuf_put_le16(data
, hapd
->conf
->fils_dh_group
);
1462 wpabuf_put_buf(data
, pub
);
1464 #endif /* CONFIG_FILS_SK_PFS */
1467 wpabuf_put_data(data
, ie
, ielen
);
1469 /* MDE when using FILS+FT (already included in ie,ielen with RSNE) */
1471 #ifdef CONFIG_IEEE80211R_AP
1472 if (wpa_key_mgmt_ft(wpa_auth_sta_key_mgmt(sta
->wpa_sm
))) {
1473 /* FTE[R1KH-ID,R0KH-ID] when using FILS+FT */
1475 int use_sha384
= wpa_key_mgmt_sha384(
1476 wpa_auth_sta_key_mgmt(sta
->wpa_sm
));
1478 res
= wpa_auth_write_fte(hapd
->wpa_auth
, use_sha384
,
1479 wpabuf_put(data
, 0),
1480 wpabuf_tailroom(data
));
1482 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1485 wpabuf_put(data
, res
);
1487 #endif /* CONFIG_IEEE80211R_AP */
1490 wpabuf_put_u8(data
, WLAN_EID_EXTENSION
); /* Element ID */
1491 wpabuf_put_u8(data
, 1 + FILS_NONCE_LEN
); /* Length */
1492 /* Element ID Extension */
1493 wpabuf_put_u8(data
, WLAN_EID_EXT_FILS_NONCE
);
1494 wpabuf_put_data(data
, fils_nonce
, FILS_NONCE_LEN
);
1497 wpabuf_put_u8(data
, WLAN_EID_EXTENSION
); /* Element ID */
1498 wpabuf_put_u8(data
, 1 + FILS_SESSION_LEN
); /* Length */
1499 /* Element ID Extension */
1500 wpabuf_put_u8(data
, WLAN_EID_EXT_FILS_SESSION
);
1501 wpabuf_put_data(data
, sta
->fils_session
, FILS_SESSION_LEN
);
1503 /* FILS Wrapped Data */
1504 if (!pmksa
&& erp_resp
) {
1505 wpabuf_put_u8(data
, WLAN_EID_EXTENSION
); /* Element ID */
1506 wpabuf_put_u8(data
, 1 + wpabuf_len(erp_resp
)); /* Length */
1507 /* Element ID Extension */
1508 wpabuf_put_u8(data
, WLAN_EID_EXT_FILS_WRAPPED_DATA
);
1509 wpabuf_put_buf(data
, erp_resp
);
1511 if (fils_rmsk_to_pmk(wpa_auth_sta_key_mgmt(sta
->wpa_sm
),
1512 msk
, msk_len
, sta
->fils_snonce
, fils_nonce
,
1514 wpabuf_head(sta
->fils_dh_ss
) : NULL
,
1516 wpabuf_len(sta
->fils_dh_ss
) : 0,
1517 pmk_buf
, &pmk_len
)) {
1518 wpa_printf(MSG_DEBUG
, "FILS: Failed to derive PMK");
1519 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1526 /* Don't use DHss in PTK derivation if PMKSA caching is not
1528 wpabuf_clear_free(sta
->fils_dh_ss
);
1529 sta
->fils_dh_ss
= NULL
;
1531 if (sta
->fils_erp_pmkid_set
) {
1532 /* TODO: get PMKLifetime from WPA parameters */
1533 unsigned int dot11RSNAConfigPMKLifetime
= 43200;
1534 int session_timeout
;
1536 session_timeout
= dot11RSNAConfigPMKLifetime
;
1537 if (sta
->session_timeout_set
) {
1538 struct os_reltime now
, diff
;
1540 os_get_reltime(&now
);
1541 os_reltime_sub(&sta
->session_timeout
, &now
,
1543 session_timeout
= diff
.sec
;
1546 sta
->fils_erp_pmkid_set
= 0;
1547 if (wpa_auth_pmksa_add2(
1548 hapd
->wpa_auth
, sta
->addr
,
1550 sta
->fils_erp_pmkid
,
1552 wpa_auth_sta_key_mgmt(sta
->wpa_sm
)) < 0) {
1553 wpa_printf(MSG_ERROR
,
1554 "FILS: Failed to add PMKSA cache entry based on ERP");
1559 pmk_len
= pmksa
->pmk_len
;
1563 wpa_printf(MSG_DEBUG
, "FILS: No PMK available");
1564 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1570 if (fils_auth_pmk_to_ptk(sta
->wpa_sm
, pmk
, pmk_len
,
1571 sta
->fils_snonce
, fils_nonce
,
1573 wpabuf_head(sta
->fils_dh_ss
) : NULL
,
1575 wpabuf_len(sta
->fils_dh_ss
) : 0,
1576 sta
->fils_g_sta
, pub
) < 0) {
1577 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1585 *is_pub
= pub
!= NULL
;
1588 wpabuf_clear_free(sta
->fils_dh_ss
);
1589 sta
->fils_dh_ss
= NULL
;
1590 #ifdef CONFIG_FILS_SK_PFS
1591 crypto_ecdh_deinit(sta
->fils_ecdh
);
1592 sta
->fils_ecdh
= NULL
;
1593 #endif /* CONFIG_FILS_SK_PFS */
1598 static void handle_auth_fils_finish(struct hostapd_data
*hapd
,
1599 struct sta_info
*sta
, u16 resp
,
1600 struct wpabuf
*data
, int pub
)
1605 resp
== WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED
) ?
1606 WLAN_AUTH_FILS_SK_PFS
: WLAN_AUTH_FILS_SK
;
1607 send_auth_reply(hapd
, sta
->addr
, hapd
->own_addr
, auth_alg
, 2, resp
,
1608 data
? wpabuf_head(data
) : (u8
*) "",
1609 data
? wpabuf_len(data
) : 0, "auth-fils-finish");
1612 if (resp
== WLAN_STATUS_SUCCESS
) {
1613 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1614 HOSTAPD_LEVEL_DEBUG
,
1615 "authentication OK (FILS)");
1616 sta
->flags
|= WLAN_STA_AUTH
;
1617 wpa_auth_sm_event(sta
->wpa_sm
, WPA_AUTH
);
1618 sta
->auth_alg
= pub
? WLAN_AUTH_FILS_SK_PFS
: WLAN_AUTH_FILS_SK
;
1619 mlme_authenticate_indication(hapd
, sta
);
1624 void ieee802_11_finish_fils_auth(struct hostapd_data
*hapd
,
1625 struct sta_info
*sta
, int success
,
1626 struct wpabuf
*erp_resp
,
1627 const u8
*msk
, size_t msk_len
)
1629 struct wpabuf
*data
;
1633 sta
->flags
&= ~WLAN_STA_PENDING_FILS_ERP
;
1635 if (!sta
->fils_pending_cb
)
1637 resp
= success
? WLAN_STATUS_SUCCESS
: WLAN_STATUS_UNSPECIFIED_FAILURE
;
1638 data
= prepare_auth_resp_fils(hapd
, sta
, &resp
, NULL
, erp_resp
,
1639 msk
, msk_len
, &pub
);
1641 wpa_printf(MSG_DEBUG
,
1642 "%s: prepare_auth_resp_fils() returned failure",
1645 sta
->fils_pending_cb(hapd
, sta
, resp
, data
, pub
);
1648 #endif /* CONFIG_FILS */
1652 ieee802_11_allowed_address(struct hostapd_data
*hapd
, const u8
*addr
,
1653 const u8
*msg
, size_t len
, u32
*session_timeout
,
1654 u32
*acct_interim_interval
,
1655 struct vlan_description
*vlan_id
,
1656 struct hostapd_sta_wpa_psk_short
**psk
,
1657 char **identity
, char **radius_cui
, int is_probe_req
)
1661 os_memset(vlan_id
, 0, sizeof(*vlan_id
));
1662 res
= hostapd_allowed_address(hapd
, addr
, msg
, len
,
1663 session_timeout
, acct_interim_interval
,
1664 vlan_id
, psk
, identity
, radius_cui
,
1667 if (res
== HOSTAPD_ACL_REJECT
) {
1669 wpa_printf(MSG_DEBUG
,
1671 " not allowed to authenticate",
1673 return HOSTAPD_ACL_REJECT
;
1676 if (res
== HOSTAPD_ACL_PENDING
) {
1677 wpa_printf(MSG_DEBUG
, "Authentication frame from " MACSTR
1678 " waiting for an external authentication",
1680 /* Authentication code will re-send the authentication frame
1681 * after it has received (and cached) information from the
1682 * external source. */
1683 return HOSTAPD_ACL_PENDING
;
1691 ieee802_11_set_radius_info(struct hostapd_data
*hapd
, struct sta_info
*sta
,
1692 int res
, u32 session_timeout
,
1693 u32 acct_interim_interval
,
1694 struct vlan_description
*vlan_id
,
1695 struct hostapd_sta_wpa_psk_short
**psk
,
1696 char **identity
, char **radius_cui
)
1698 if (vlan_id
->notempty
&&
1699 !hostapd_vlan_valid(hapd
->conf
->vlan
, vlan_id
)) {
1700 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_RADIUS
,
1702 "Invalid VLAN %d%s received from RADIUS server",
1704 vlan_id
->tagged
[0] ? "+" : "");
1707 if (ap_sta_set_vlan(hapd
, sta
, vlan_id
) < 0)
1710 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_RADIUS
,
1711 HOSTAPD_LEVEL_INFO
, "VLAN ID %d", sta
->vlan_id
);
1713 hostapd_free_psk_list(sta
->psk
);
1714 if (hapd
->conf
->wpa_psk_radius
!= PSK_RADIUS_IGNORED
) {
1721 os_free(sta
->identity
);
1722 sta
->identity
= *identity
;
1725 os_free(sta
->radius_cui
);
1726 sta
->radius_cui
= *radius_cui
;
1729 if (hapd
->conf
->acct_interim_interval
== 0 && acct_interim_interval
)
1730 sta
->acct_interim_interval
= acct_interim_interval
;
1731 if (res
== HOSTAPD_ACL_ACCEPT_TIMEOUT
) {
1732 sta
->session_timeout_set
= 1;
1733 os_get_reltime(&sta
->session_timeout
);
1734 sta
->session_timeout
.sec
+= session_timeout
;
1735 ap_sta_session_timeout(hapd
, sta
, session_timeout
);
1737 sta
->session_timeout_set
= 0;
1738 ap_sta_no_session_timeout(hapd
, sta
);
1745 static void handle_auth(struct hostapd_data
*hapd
,
1746 const struct ieee80211_mgmt
*mgmt
, size_t len
)
1748 u16 auth_alg
, auth_transaction
, status_code
;
1749 u16 resp
= WLAN_STATUS_SUCCESS
;
1750 struct sta_info
*sta
= NULL
;
1753 const u8
*challenge
= NULL
;
1754 u32 session_timeout
, acct_interim_interval
;
1755 struct vlan_description vlan_id
;
1756 struct hostapd_sta_wpa_psk_short
*psk
= NULL
;
1757 u8 resp_ies
[2 + WLAN_AUTH_CHALLENGE_LEN
];
1758 size_t resp_ies_len
= 0;
1759 char *identity
= NULL
;
1760 char *radius_cui
= NULL
;
1763 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.auth
)) {
1764 wpa_printf(MSG_INFO
, "handle_auth - too short payload (len=%lu)",
1765 (unsigned long) len
);
1769 #ifdef CONFIG_TESTING_OPTIONS
1770 if (hapd
->iconf
->ignore_auth_probability
> 0.0 &&
1771 drand48() < hapd
->iconf
->ignore_auth_probability
) {
1772 wpa_printf(MSG_INFO
,
1773 "TESTING: ignoring auth frame from " MACSTR
,
1777 #endif /* CONFIG_TESTING_OPTIONS */
1779 auth_alg
= le_to_host16(mgmt
->u
.auth
.auth_alg
);
1780 auth_transaction
= le_to_host16(mgmt
->u
.auth
.auth_transaction
);
1781 status_code
= le_to_host16(mgmt
->u
.auth
.status_code
);
1782 fc
= le_to_host16(mgmt
->frame_control
);
1783 seq_ctrl
= le_to_host16(mgmt
->seq_ctrl
);
1785 if (len
>= IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.auth
) +
1786 2 + WLAN_AUTH_CHALLENGE_LEN
&&
1787 mgmt
->u
.auth
.variable
[0] == WLAN_EID_CHALLENGE
&&
1788 mgmt
->u
.auth
.variable
[1] == WLAN_AUTH_CHALLENGE_LEN
)
1789 challenge
= &mgmt
->u
.auth
.variable
[2];
1791 wpa_printf(MSG_DEBUG
, "authentication: STA=" MACSTR
" auth_alg=%d "
1792 "auth_transaction=%d status_code=%d wep=%d%s "
1794 MAC2STR(mgmt
->sa
), auth_alg
, auth_transaction
,
1795 status_code
, !!(fc
& WLAN_FC_ISWEP
),
1796 challenge
? " challenge" : "",
1797 seq_ctrl
, (fc
& WLAN_FC_RETRY
) ? " retry" : "");
1799 #ifdef CONFIG_NO_RC4
1800 if (auth_alg
== WLAN_AUTH_SHARED_KEY
) {
1801 wpa_printf(MSG_INFO
,
1802 "Unsupported authentication algorithm (%d)",
1804 resp
= WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG
;
1807 #endif /* CONFIG_NO_RC4 */
1809 if (hapd
->tkip_countermeasures
) {
1810 wpa_printf(MSG_DEBUG
,
1811 "Ongoing TKIP countermeasures (Michael MIC failure) - reject authentication");
1812 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1816 if (!(((hapd
->conf
->auth_algs
& WPA_AUTH_ALG_OPEN
) &&
1817 auth_alg
== WLAN_AUTH_OPEN
) ||
1818 #ifdef CONFIG_IEEE80211R_AP
1819 (hapd
->conf
->wpa
&& wpa_key_mgmt_ft(hapd
->conf
->wpa_key_mgmt
) &&
1820 auth_alg
== WLAN_AUTH_FT
) ||
1821 #endif /* CONFIG_IEEE80211R_AP */
1823 (hapd
->conf
->wpa
&& wpa_key_mgmt_sae(hapd
->conf
->wpa_key_mgmt
) &&
1824 auth_alg
== WLAN_AUTH_SAE
) ||
1825 #endif /* CONFIG_SAE */
1827 (hapd
->conf
->wpa
&& wpa_key_mgmt_fils(hapd
->conf
->wpa_key_mgmt
) &&
1828 auth_alg
== WLAN_AUTH_FILS_SK
) ||
1829 (hapd
->conf
->wpa
&& wpa_key_mgmt_fils(hapd
->conf
->wpa_key_mgmt
) &&
1830 hapd
->conf
->fils_dh_group
&&
1831 auth_alg
== WLAN_AUTH_FILS_SK_PFS
) ||
1832 #endif /* CONFIG_FILS */
1833 ((hapd
->conf
->auth_algs
& WPA_AUTH_ALG_SHARED
) &&
1834 auth_alg
== WLAN_AUTH_SHARED_KEY
))) {
1835 wpa_printf(MSG_INFO
, "Unsupported authentication algorithm (%d)",
1837 resp
= WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG
;
1841 if (!(auth_transaction
== 1 || auth_alg
== WLAN_AUTH_SAE
||
1842 (auth_alg
== WLAN_AUTH_SHARED_KEY
&& auth_transaction
== 3))) {
1843 wpa_printf(MSG_INFO
, "Unknown authentication transaction number (%d)",
1845 resp
= WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION
;
1849 if (os_memcmp(mgmt
->sa
, hapd
->own_addr
, ETH_ALEN
) == 0) {
1850 wpa_printf(MSG_INFO
, "Station " MACSTR
" not allowed to authenticate",
1852 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1856 if (hapd
->conf
->no_auth_if_seen_on
) {
1857 struct hostapd_data
*other
;
1859 other
= sta_track_seen_on(hapd
->iface
, mgmt
->sa
,
1860 hapd
->conf
->no_auth_if_seen_on
);
1864 u8 op_class
, channel
, phytype
;
1866 wpa_printf(MSG_DEBUG
, "%s: Reject authentication from "
1867 MACSTR
" since STA has been seen on %s",
1868 hapd
->conf
->iface
, MAC2STR(mgmt
->sa
),
1869 hapd
->conf
->no_auth_if_seen_on
);
1871 resp
= WLAN_STATUS_REJECTED_WITH_SUGGESTED_BSS_TRANSITION
;
1873 *pos
++ = WLAN_EID_NEIGHBOR_REPORT
;
1875 os_memcpy(pos
, other
->own_addr
, ETH_ALEN
);
1877 info
= 0; /* TODO: BSSID Information */
1878 WPA_PUT_LE32(pos
, info
);
1880 if (other
->iconf
->hw_mode
== HOSTAPD_MODE_IEEE80211AD
)
1881 phytype
= 8; /* dmg */
1882 else if (other
->iconf
->ieee80211ac
)
1883 phytype
= 9; /* vht */
1884 else if (other
->iconf
->ieee80211n
)
1885 phytype
= 7; /* ht */
1886 else if (other
->iconf
->hw_mode
==
1887 HOSTAPD_MODE_IEEE80211A
)
1888 phytype
= 4; /* ofdm */
1889 else if (other
->iconf
->hw_mode
==
1890 HOSTAPD_MODE_IEEE80211G
)
1891 phytype
= 6; /* erp */
1893 phytype
= 5; /* hrdsss */
1894 if (ieee80211_freq_to_channel_ext(
1895 hostapd_hw_get_freq(other
,
1896 other
->iconf
->channel
),
1897 other
->iconf
->secondary_channel
,
1898 other
->iconf
->ieee80211ac
,
1899 &op_class
, &channel
) == NUM_HOSTAPD_MODES
) {
1901 channel
= other
->iconf
->channel
;
1906 resp_ies_len
= pos
- &resp_ies
[0];
1911 res
= ieee802_11_allowed_address(
1912 hapd
, mgmt
->sa
, (const u8
*) mgmt
, len
, &session_timeout
,
1913 &acct_interim_interval
, &vlan_id
, &psk
, &identity
, &radius_cui
,
1915 if (res
== HOSTAPD_ACL_REJECT
) {
1916 wpa_msg(hapd
->msg_ctx
, MSG_DEBUG
,
1917 "Ignore Authentication frame from " MACSTR
1918 " due to ACL reject", MAC2STR(mgmt
->sa
));
1919 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1922 if (res
== HOSTAPD_ACL_PENDING
)
1925 sta
= ap_get_sta(hapd
, mgmt
->sa
);
1927 sta
->flags
&= ~WLAN_STA_PENDING_FILS_ERP
;
1928 if ((fc
& WLAN_FC_RETRY
) &&
1929 sta
->last_seq_ctrl
!= WLAN_INVALID_MGMT_SEQ
&&
1930 sta
->last_seq_ctrl
== seq_ctrl
&&
1931 sta
->last_subtype
== WLAN_FC_STYPE_AUTH
) {
1932 hostapd_logger(hapd
, sta
->addr
,
1933 HOSTAPD_MODULE_IEEE80211
,
1934 HOSTAPD_LEVEL_DEBUG
,
1935 "Drop repeated authentication frame seq_ctrl=0x%x",
1940 if ((hapd
->conf
->mesh
& MESH_ENABLED
) &&
1941 sta
->plink_state
== PLINK_BLOCKED
) {
1942 wpa_printf(MSG_DEBUG
, "Mesh peer " MACSTR
1943 " is blocked - drop Authentication frame",
1947 #endif /* CONFIG_MESH */
1950 if (hapd
->conf
->mesh
& MESH_ENABLED
) {
1951 /* if the mesh peer is not available, we don't do auth.
1953 wpa_printf(MSG_DEBUG
, "Mesh peer " MACSTR
1954 " not yet known - drop Authentication frame",
1957 * Save a copy of the frame so that it can be processed
1958 * if a new peer entry is added shortly after this.
1960 wpabuf_free(hapd
->mesh_pending_auth
);
1961 hapd
->mesh_pending_auth
= wpabuf_alloc_copy(mgmt
, len
);
1962 os_get_reltime(&hapd
->mesh_pending_auth_time
);
1965 #endif /* CONFIG_MESH */
1967 sta
= ap_sta_add(hapd
, mgmt
->sa
);
1969 wpa_printf(MSG_DEBUG
, "ap_sta_add() failed");
1970 resp
= WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
;
1974 sta
->last_seq_ctrl
= seq_ctrl
;
1975 sta
->last_subtype
= WLAN_FC_STYPE_AUTH
;
1977 res
= ieee802_11_set_radius_info(
1978 hapd
, sta
, res
, session_timeout
, acct_interim_interval
,
1979 &vlan_id
, &psk
, &identity
, &radius_cui
);
1981 wpa_printf(MSG_DEBUG
, "ieee802_11_set_radius_info() failed");
1982 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1986 sta
->flags
&= ~WLAN_STA_PREAUTH
;
1987 ieee802_1x_notify_pre_auth(sta
->eapol_sm
, 0);
1990 * If the driver supports full AP client state, add a station to the
1991 * driver before sending authentication reply to make sure the driver
1992 * has resources, and not to go through the entire authentication and
1993 * association handshake, and fail it at the end.
1995 * If this is not the first transaction, in a multi-step authentication
1996 * algorithm, the station already exists in the driver
1997 * (sta->added_unassoc = 1) so skip it.
1999 * In mesh mode, the station was already added to the driver when the
2000 * NEW_PEER_CANDIDATE event is received.
2002 * If PMF was negotiated for the existing association, skip this to
2003 * avoid dropping the STA entry and the associated keys. This is needed
2004 * to allow the original connection work until the attempt can complete
2005 * (re)association, so that unprotected Authentication frame cannot be
2006 * used to bypass PMF protection.
2008 if (FULL_AP_CLIENT_STATE_SUPP(hapd
->iface
->drv_flags
) &&
2009 (!(sta
->flags
& WLAN_STA_MFP
) || !ap_sta_is_authorized(sta
)) &&
2010 !(hapd
->conf
->mesh
& MESH_ENABLED
) &&
2011 !(sta
->added_unassoc
)) {
2013 * If a station that is already associated to the AP, is trying
2014 * to authenticate again, remove the STA entry, in order to make
2015 * sure the STA PS state gets cleared and configuration gets
2016 * updated. To handle this, station's added_unassoc flag is
2017 * cleared once the station has completed association.
2019 ap_sta_set_authorized(hapd
, sta
, 0);
2020 hostapd_drv_sta_remove(hapd
, sta
->addr
);
2021 sta
->flags
&= ~(WLAN_STA_ASSOC
| WLAN_STA_AUTH
|
2022 WLAN_STA_AUTHORIZED
);
2024 if (hostapd_sta_add(hapd
, sta
->addr
, 0, 0, NULL
, 0, 0,
2025 NULL
, NULL
, sta
->flags
, 0, 0, 0, 0)) {
2026 hostapd_logger(hapd
, sta
->addr
,
2027 HOSTAPD_MODULE_IEEE80211
,
2028 HOSTAPD_LEVEL_NOTICE
,
2029 "Could not add STA to kernel driver");
2030 resp
= WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
;
2034 sta
->added_unassoc
= 1;
2038 case WLAN_AUTH_OPEN
:
2039 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
2040 HOSTAPD_LEVEL_DEBUG
,
2041 "authentication OK (open system)");
2042 sta
->flags
|= WLAN_STA_AUTH
;
2043 wpa_auth_sm_event(sta
->wpa_sm
, WPA_AUTH
);
2044 sta
->auth_alg
= WLAN_AUTH_OPEN
;
2045 mlme_authenticate_indication(hapd
, sta
);
2047 #ifndef CONFIG_NO_RC4
2048 case WLAN_AUTH_SHARED_KEY
:
2049 resp
= auth_shared_key(hapd
, sta
, auth_transaction
, challenge
,
2050 fc
& WLAN_FC_ISWEP
);
2052 wpa_printf(MSG_DEBUG
,
2053 "auth_shared_key() failed: status=%d", resp
);
2054 sta
->auth_alg
= WLAN_AUTH_SHARED_KEY
;
2055 mlme_authenticate_indication(hapd
, sta
);
2056 if (sta
->challenge
&& auth_transaction
== 1) {
2057 resp_ies
[0] = WLAN_EID_CHALLENGE
;
2058 resp_ies
[1] = WLAN_AUTH_CHALLENGE_LEN
;
2059 os_memcpy(resp_ies
+ 2, sta
->challenge
,
2060 WLAN_AUTH_CHALLENGE_LEN
);
2061 resp_ies_len
= 2 + WLAN_AUTH_CHALLENGE_LEN
;
2064 #endif /* CONFIG_NO_RC4 */
2065 #ifdef CONFIG_IEEE80211R_AP
2067 sta
->auth_alg
= WLAN_AUTH_FT
;
2068 if (sta
->wpa_sm
== NULL
)
2069 sta
->wpa_sm
= wpa_auth_sta_init(hapd
->wpa_auth
,
2071 if (sta
->wpa_sm
== NULL
) {
2072 wpa_printf(MSG_DEBUG
, "FT: Failed to initialize WPA "
2074 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
2077 wpa_ft_process_auth(sta
->wpa_sm
, mgmt
->bssid
,
2078 auth_transaction
, mgmt
->u
.auth
.variable
,
2079 len
- IEEE80211_HDRLEN
-
2080 sizeof(mgmt
->u
.auth
),
2081 handle_auth_ft_finish
, hapd
);
2082 /* handle_auth_ft_finish() callback will complete auth. */
2084 #endif /* CONFIG_IEEE80211R_AP */
2088 if (status_code
== WLAN_STATUS_SUCCESS
&&
2089 hapd
->conf
->mesh
& MESH_ENABLED
) {
2090 if (sta
->wpa_sm
== NULL
)
2092 wpa_auth_sta_init(hapd
->wpa_auth
,
2094 if (sta
->wpa_sm
== NULL
) {
2095 wpa_printf(MSG_DEBUG
,
2096 "SAE: Failed to initialize WPA state machine");
2097 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
2101 #endif /* CONFIG_MESH */
2102 handle_auth_sae(hapd
, sta
, mgmt
, len
, auth_transaction
,
2105 #endif /* CONFIG_SAE */
2107 case WLAN_AUTH_FILS_SK
:
2108 case WLAN_AUTH_FILS_SK_PFS
:
2109 handle_auth_fils(hapd
, sta
, mgmt
->u
.auth
.variable
,
2110 len
- IEEE80211_HDRLEN
- sizeof(mgmt
->u
.auth
),
2111 auth_alg
, auth_transaction
, status_code
,
2112 handle_auth_fils_finish
);
2114 #endif /* CONFIG_FILS */
2119 os_free(radius_cui
);
2120 hostapd_free_psk_list(psk
);
2122 reply_res
= send_auth_reply(hapd
, mgmt
->sa
, mgmt
->bssid
, auth_alg
,
2123 auth_transaction
+ 1, resp
, resp_ies
,
2124 resp_ies_len
, "handle-auth");
2126 if (sta
&& sta
->added_unassoc
&& (resp
!= WLAN_STATUS_SUCCESS
||
2127 reply_res
!= WLAN_STATUS_SUCCESS
)) {
2128 hostapd_drv_sta_remove(hapd
, sta
->addr
);
2129 sta
->added_unassoc
= 0;
2134 int hostapd_get_aid(struct hostapd_data
*hapd
, struct sta_info
*sta
)
2138 /* get a unique AID */
2140 wpa_printf(MSG_DEBUG
, " old AID %d", sta
->aid
);
2147 for (i
= 0; i
< AID_WORDS
; i
++) {
2148 if (hapd
->sta_aid
[i
] == (u32
) -1)
2150 for (j
= 0; j
< 32; j
++) {
2151 if (!(hapd
->sta_aid
[i
] & BIT(j
)))
2159 aid
= i
* 32 + j
+ 1;
2164 hapd
->sta_aid
[i
] |= BIT(j
);
2165 wpa_printf(MSG_DEBUG
, " new AID %d", sta
->aid
);
2170 static u16
check_ssid(struct hostapd_data
*hapd
, struct sta_info
*sta
,
2171 const u8
*ssid_ie
, size_t ssid_ie_len
)
2173 if (ssid_ie
== NULL
)
2174 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2176 if (ssid_ie_len
!= hapd
->conf
->ssid
.ssid_len
||
2177 os_memcmp(ssid_ie
, hapd
->conf
->ssid
.ssid
, ssid_ie_len
) != 0) {
2178 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
2180 "Station tried to associate with unknown SSID "
2181 "'%s'", wpa_ssid_txt(ssid_ie
, ssid_ie_len
));
2182 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2185 return WLAN_STATUS_SUCCESS
;
2189 static u16
check_wmm(struct hostapd_data
*hapd
, struct sta_info
*sta
,
2190 const u8
*wmm_ie
, size_t wmm_ie_len
)
2192 sta
->flags
&= ~WLAN_STA_WMM
;
2194 if (wmm_ie
&& hapd
->conf
->wmm_enabled
) {
2195 struct wmm_information_element
*wmm
;
2197 if (!hostapd_eid_wmm_valid(hapd
, wmm_ie
, wmm_ie_len
)) {
2198 hostapd_logger(hapd
, sta
->addr
,
2200 HOSTAPD_LEVEL_DEBUG
,
2201 "invalid WMM element in association "
2203 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2206 sta
->flags
|= WLAN_STA_WMM
;
2207 wmm
= (struct wmm_information_element
*) wmm_ie
;
2208 sta
->qosinfo
= wmm
->qos_info
;
2210 return WLAN_STATUS_SUCCESS
;
2214 static u16
copy_supp_rates(struct hostapd_data
*hapd
, struct sta_info
*sta
,
2215 struct ieee802_11_elems
*elems
)
2217 /* Supported rates not used in IEEE 802.11ad/DMG */
2218 if (hapd
->iface
->current_mode
&&
2219 hapd
->iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211AD
)
2220 return WLAN_STATUS_SUCCESS
;
2222 if (!elems
->supp_rates
) {
2223 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
2224 HOSTAPD_LEVEL_DEBUG
,
2225 "No supported rates element in AssocReq");
2226 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2229 if (elems
->supp_rates_len
+ elems
->ext_supp_rates_len
>
2230 sizeof(sta
->supported_rates
)) {
2231 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
2232 HOSTAPD_LEVEL_DEBUG
,
2233 "Invalid supported rates element length %d+%d",
2234 elems
->supp_rates_len
,
2235 elems
->ext_supp_rates_len
);
2236 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2239 sta
->supported_rates_len
= merge_byte_arrays(
2240 sta
->supported_rates
, sizeof(sta
->supported_rates
),
2241 elems
->supp_rates
, elems
->supp_rates_len
,
2242 elems
->ext_supp_rates
, elems
->ext_supp_rates_len
);
2244 return WLAN_STATUS_SUCCESS
;
2248 static u16
check_ext_capab(struct hostapd_data
*hapd
, struct sta_info
*sta
,
2249 const u8
*ext_capab_ie
, size_t ext_capab_ie_len
)
2251 #ifdef CONFIG_INTERWORKING
2252 /* check for QoS Map support */
2253 if (ext_capab_ie_len
>= 5) {
2254 if (ext_capab_ie
[4] & 0x01)
2255 sta
->qos_map_enabled
= 1;
2257 #endif /* CONFIG_INTERWORKING */
2259 if (ext_capab_ie_len
> 0) {
2260 sta
->ecsa_supported
= !!(ext_capab_ie
[0] & BIT(2));
2261 os_free(sta
->ext_capability
);
2262 sta
->ext_capability
= os_malloc(1 + ext_capab_ie_len
);
2263 if (sta
->ext_capability
) {
2264 sta
->ext_capability
[0] = ext_capab_ie_len
;
2265 os_memcpy(sta
->ext_capability
+ 1, ext_capab_ie
,
2270 return WLAN_STATUS_SUCCESS
;
2276 static int owe_group_supported(struct hostapd_data
*hapd
, u16 group
)
2279 int *groups
= hapd
->conf
->owe_groups
;
2281 if (group
!= 19 && group
!= 20 && group
!= 21)
2287 for (i
= 0; groups
[i
] > 0; i
++) {
2288 if (groups
[i
] == group
)
2296 static u16
owe_process_assoc_req(struct hostapd_data
*hapd
,
2297 struct sta_info
*sta
, const u8
*owe_dh
,
2300 struct wpabuf
*secret
, *pub
, *hkey
;
2302 u8 prk
[SHA512_MAC_LEN
], pmkid
[SHA512_MAC_LEN
];
2303 const char *info
= "OWE Key Generation";
2307 size_t hash_len
, prime_len
;
2309 if (wpa_auth_sta_get_pmksa(sta
->wpa_sm
)) {
2310 wpa_printf(MSG_DEBUG
, "OWE: Using PMKSA caching");
2311 return WLAN_STATUS_SUCCESS
;
2314 group
= WPA_GET_LE16(owe_dh
);
2315 if (!owe_group_supported(hapd
, group
)) {
2316 wpa_printf(MSG_DEBUG
, "OWE: Unsupported DH group %u", group
);
2317 return WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED
;
2321 else if (group
== 20)
2323 else if (group
== 21)
2326 return WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED
;
2328 crypto_ecdh_deinit(sta
->owe_ecdh
);
2329 sta
->owe_ecdh
= crypto_ecdh_init(group
);
2331 return WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED
;
2332 sta
->owe_group
= group
;
2334 secret
= crypto_ecdh_set_peerkey(sta
->owe_ecdh
, 0, owe_dh
+ 2,
2336 secret
= wpabuf_zeropad(secret
, prime_len
);
2338 wpa_printf(MSG_DEBUG
, "OWE: Invalid peer DH public key");
2339 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2341 wpa_hexdump_buf_key(MSG_DEBUG
, "OWE: DH shared secret", secret
);
2343 /* prk = HKDF-extract(C | A | group, z) */
2345 pub
= crypto_ecdh_get_pubkey(sta
->owe_ecdh
, 0);
2347 wpabuf_clear_free(secret
);
2348 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2351 /* PMKID = Truncate-128(Hash(C | A)) */
2352 addr
[0] = owe_dh
+ 2;
2353 len
[0] = owe_dh_len
- 2;
2354 addr
[1] = wpabuf_head(pub
);
2355 len
[1] = wpabuf_len(pub
);
2357 res
= sha256_vector(2, addr
, len
, pmkid
);
2358 hash_len
= SHA256_MAC_LEN
;
2359 } else if (group
== 20) {
2360 res
= sha384_vector(2, addr
, len
, pmkid
);
2361 hash_len
= SHA384_MAC_LEN
;
2362 } else if (group
== 21) {
2363 res
= sha512_vector(2, addr
, len
, pmkid
);
2364 hash_len
= SHA512_MAC_LEN
;
2367 wpabuf_clear_free(secret
);
2368 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2370 pub
= wpabuf_zeropad(pub
, prime_len
);
2371 if (res
< 0 || !pub
) {
2373 wpabuf_clear_free(secret
);
2374 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2377 hkey
= wpabuf_alloc(owe_dh_len
- 2 + wpabuf_len(pub
) + 2);
2380 wpabuf_clear_free(secret
);
2381 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2384 wpabuf_put_data(hkey
, owe_dh
+ 2, owe_dh_len
- 2); /* C */
2385 wpabuf_put_buf(hkey
, pub
); /* A */
2387 wpabuf_put_le16(hkey
, group
); /* group */
2389 res
= hmac_sha256(wpabuf_head(hkey
), wpabuf_len(hkey
),
2390 wpabuf_head(secret
), wpabuf_len(secret
), prk
);
2391 else if (group
== 20)
2392 res
= hmac_sha384(wpabuf_head(hkey
), wpabuf_len(hkey
),
2393 wpabuf_head(secret
), wpabuf_len(secret
), prk
);
2394 else if (group
== 21)
2395 res
= hmac_sha512(wpabuf_head(hkey
), wpabuf_len(hkey
),
2396 wpabuf_head(secret
), wpabuf_len(secret
), prk
);
2397 wpabuf_clear_free(hkey
);
2398 wpabuf_clear_free(secret
);
2400 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2402 wpa_hexdump_key(MSG_DEBUG
, "OWE: prk", prk
, hash_len
);
2404 /* PMK = HKDF-expand(prk, "OWE Key Generation", n) */
2406 os_free(sta
->owe_pmk
);
2407 sta
->owe_pmk
= os_malloc(hash_len
);
2408 if (!sta
->owe_pmk
) {
2409 os_memset(prk
, 0, SHA512_MAC_LEN
);
2410 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2414 res
= hmac_sha256_kdf(prk
, hash_len
, NULL
, (const u8
*) info
,
2415 os_strlen(info
), sta
->owe_pmk
, hash_len
);
2416 else if (group
== 20)
2417 res
= hmac_sha384_kdf(prk
, hash_len
, NULL
, (const u8
*) info
,
2418 os_strlen(info
), sta
->owe_pmk
, hash_len
);
2419 else if (group
== 21)
2420 res
= hmac_sha512_kdf(prk
, hash_len
, NULL
, (const u8
*) info
,
2421 os_strlen(info
), sta
->owe_pmk
, hash_len
);
2422 os_memset(prk
, 0, SHA512_MAC_LEN
);
2424 os_free(sta
->owe_pmk
);
2425 sta
->owe_pmk
= NULL
;
2426 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2428 sta
->owe_pmk_len
= hash_len
;
2430 wpa_hexdump_key(MSG_DEBUG
, "OWE: PMK", sta
->owe_pmk
, sta
->owe_pmk_len
);
2431 wpa_hexdump(MSG_DEBUG
, "OWE: PMKID", pmkid
, PMKID_LEN
);
2432 wpa_auth_pmksa_add2(hapd
->wpa_auth
, sta
->addr
, sta
->owe_pmk
,
2433 sta
->owe_pmk_len
, pmkid
, 0, WPA_KEY_MGMT_OWE
);
2435 return WLAN_STATUS_SUCCESS
;
2438 #endif /* CONFIG_OWE */
2441 static u16
check_assoc_ies(struct hostapd_data
*hapd
, struct sta_info
*sta
,
2442 const u8
*ies
, size_t ies_len
, int reassoc
)
2444 struct ieee802_11_elems elems
;
2448 const u8
*p2p_dev_addr
= NULL
;
2450 if (ieee802_11_parse_elems(ies
, ies_len
, &elems
, 1) == ParseFailed
) {
2451 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
2452 HOSTAPD_LEVEL_INFO
, "Station sent an invalid "
2453 "association request");
2454 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2457 resp
= check_ssid(hapd
, sta
, elems
.ssid
, elems
.ssid_len
);
2458 if (resp
!= WLAN_STATUS_SUCCESS
)
2460 resp
= check_wmm(hapd
, sta
, elems
.wmm
, elems
.wmm_len
);
2461 if (resp
!= WLAN_STATUS_SUCCESS
)
2463 resp
= check_ext_capab(hapd
, sta
, elems
.ext_capab
, elems
.ext_capab_len
);
2464 if (resp
!= WLAN_STATUS_SUCCESS
)
2466 resp
= copy_supp_rates(hapd
, sta
, &elems
);
2467 if (resp
!= WLAN_STATUS_SUCCESS
)
2469 #ifdef CONFIG_IEEE80211N
2470 resp
= copy_sta_ht_capab(hapd
, sta
, elems
.ht_capabilities
);
2471 if (resp
!= WLAN_STATUS_SUCCESS
)
2473 if (hapd
->iconf
->ieee80211n
&& hapd
->iconf
->require_ht
&&
2474 !(sta
->flags
& WLAN_STA_HT
)) {
2475 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
2476 HOSTAPD_LEVEL_INFO
, "Station does not support "
2477 "mandatory HT PHY - reject association");
2478 return WLAN_STATUS_ASSOC_DENIED_NO_HT
;
2480 #endif /* CONFIG_IEEE80211N */
2482 #ifdef CONFIG_IEEE80211AC
2483 if (hapd
->iconf
->ieee80211ac
) {
2484 resp
= copy_sta_vht_capab(hapd
, sta
, elems
.vht_capabilities
);
2485 if (resp
!= WLAN_STATUS_SUCCESS
)
2488 resp
= set_sta_vht_opmode(hapd
, sta
, elems
.vht_opmode_notif
);
2489 if (resp
!= WLAN_STATUS_SUCCESS
)
2493 if (hapd
->iconf
->ieee80211ac
&& hapd
->iconf
->require_vht
&&
2494 !(sta
->flags
& WLAN_STA_VHT
)) {
2495 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
2496 HOSTAPD_LEVEL_INFO
, "Station does not support "
2497 "mandatory VHT PHY - reject association");
2498 return WLAN_STATUS_ASSOC_DENIED_NO_VHT
;
2501 if (hapd
->conf
->vendor_vht
&& !elems
.vht_capabilities
) {
2502 resp
= copy_sta_vendor_vht(hapd
, sta
, elems
.vendor_vht
,
2503 elems
.vendor_vht_len
);
2504 if (resp
!= WLAN_STATUS_SUCCESS
)
2507 #endif /* CONFIG_IEEE80211AC */
2511 wpabuf_free(sta
->p2p_ie
);
2512 sta
->p2p_ie
= ieee802_11_vendor_ie_concat(ies
, ies_len
,
2513 P2P_IE_VENDOR_TYPE
);
2515 p2p_dev_addr
= p2p_get_go_dev_addr(sta
->p2p_ie
);
2517 wpabuf_free(sta
->p2p_ie
);
2520 #endif /* CONFIG_P2P */
2522 if ((hapd
->conf
->wpa
& WPA_PROTO_RSN
) && elems
.rsn_ie
) {
2523 wpa_ie
= elems
.rsn_ie
;
2524 wpa_ie_len
= elems
.rsn_ie_len
;
2525 } else if ((hapd
->conf
->wpa
& WPA_PROTO_WPA
) &&
2527 wpa_ie
= elems
.wpa_ie
;
2528 wpa_ie_len
= elems
.wpa_ie_len
;
2535 sta
->flags
&= ~(WLAN_STA_WPS
| WLAN_STA_MAYBE_WPS
| WLAN_STA_WPS2
);
2536 if (hapd
->conf
->wps_state
&& elems
.wps_ie
) {
2537 wpa_printf(MSG_DEBUG
, "STA included WPS IE in (Re)Association "
2538 "Request - assume WPS is used");
2539 sta
->flags
|= WLAN_STA_WPS
;
2540 wpabuf_free(sta
->wps_ie
);
2541 sta
->wps_ie
= ieee802_11_vendor_ie_concat(ies
, ies_len
,
2542 WPS_IE_VENDOR_TYPE
);
2543 if (sta
->wps_ie
&& wps_is_20(sta
->wps_ie
)) {
2544 wpa_printf(MSG_DEBUG
, "WPS: STA supports WPS 2.0");
2545 sta
->flags
|= WLAN_STA_WPS2
;
2549 if (sta
->wps_ie
&& wps_validate_assoc_req(sta
->wps_ie
) < 0) {
2550 wpa_printf(MSG_DEBUG
, "WPS: Invalid WPS IE in "
2551 "(Re)Association Request - reject");
2552 return WLAN_STATUS_INVALID_IE
;
2554 } else if (hapd
->conf
->wps_state
&& wpa_ie
== NULL
) {
2555 wpa_printf(MSG_DEBUG
, "STA did not include WPA/RSN IE in "
2556 "(Re)Association Request - possible WPS use");
2557 sta
->flags
|= WLAN_STA_MAYBE_WPS
;
2559 #endif /* CONFIG_WPS */
2560 if (hapd
->conf
->wpa
&& wpa_ie
== NULL
) {
2561 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
2563 "No WPA/RSN IE in association request");
2564 return WLAN_STATUS_INVALID_IE
;
2567 if (hapd
->conf
->wpa
&& wpa_ie
) {
2571 if (sta
->wpa_sm
== NULL
)
2572 sta
->wpa_sm
= wpa_auth_sta_init(hapd
->wpa_auth
,
2575 if (sta
->wpa_sm
== NULL
) {
2576 wpa_printf(MSG_WARNING
, "Failed to initialize WPA "
2578 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2580 res
= wpa_validate_wpa_ie(hapd
->wpa_auth
, sta
->wpa_sm
,
2582 elems
.mdie
, elems
.mdie_len
,
2583 elems
.owe_dh
, elems
.owe_dh_len
);
2584 resp
= wpa_res_to_status_code(res
);
2585 if (resp
!= WLAN_STATUS_SUCCESS
)
2587 #ifdef CONFIG_IEEE80211W
2588 if ((sta
->flags
& (WLAN_STA_ASSOC
| WLAN_STA_MFP
)) ==
2589 (WLAN_STA_ASSOC
| WLAN_STA_MFP
) &&
2590 !sta
->sa_query_timed_out
&&
2591 sta
->sa_query_count
> 0)
2592 ap_check_sa_query_timeout(hapd
, sta
);
2593 if ((sta
->flags
& (WLAN_STA_ASSOC
| WLAN_STA_MFP
)) ==
2594 (WLAN_STA_ASSOC
| WLAN_STA_MFP
) &&
2595 !sta
->sa_query_timed_out
&&
2596 (!reassoc
|| sta
->auth_alg
!= WLAN_AUTH_FT
)) {
2598 * STA has already been associated with MFP and SA
2599 * Query timeout has not been reached. Reject the
2600 * association attempt temporarily and start SA Query,
2601 * if one is not pending.
2604 if (sta
->sa_query_count
== 0)
2605 ap_sta_start_sa_query(hapd
, sta
);
2607 return WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY
;
2610 if (wpa_auth_uses_mfp(sta
->wpa_sm
))
2611 sta
->flags
|= WLAN_STA_MFP
;
2613 sta
->flags
&= ~WLAN_STA_MFP
;
2614 #endif /* CONFIG_IEEE80211W */
2616 #ifdef CONFIG_IEEE80211R_AP
2617 if (sta
->auth_alg
== WLAN_AUTH_FT
) {
2619 wpa_printf(MSG_DEBUG
, "FT: " MACSTR
" tried "
2620 "to use association (not "
2621 "re-association) with FT auth_alg",
2622 MAC2STR(sta
->addr
));
2623 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2626 resp
= wpa_ft_validate_reassoc(sta
->wpa_sm
, ies
,
2628 if (resp
!= WLAN_STATUS_SUCCESS
)
2631 #endif /* CONFIG_IEEE80211R_AP */
2634 if (wpa_auth_uses_sae(sta
->wpa_sm
) && sta
->sae
&&
2635 sta
->sae
->state
== SAE_ACCEPTED
)
2636 wpa_auth_add_sae_pmkid(sta
->wpa_sm
, sta
->sae
->pmkid
);
2638 if (wpa_auth_uses_sae(sta
->wpa_sm
) &&
2639 sta
->auth_alg
== WLAN_AUTH_OPEN
) {
2640 struct rsn_pmksa_cache_entry
*sa
;
2641 sa
= wpa_auth_sta_get_pmksa(sta
->wpa_sm
);
2642 if (!sa
|| sa
->akmp
!= WPA_KEY_MGMT_SAE
) {
2643 wpa_printf(MSG_DEBUG
,
2644 "SAE: No PMKSA cache entry found for "
2645 MACSTR
, MAC2STR(sta
->addr
));
2646 return WLAN_STATUS_INVALID_PMKID
;
2648 wpa_printf(MSG_DEBUG
, "SAE: " MACSTR
2649 " using PMKSA caching", MAC2STR(sta
->addr
));
2650 } else if (wpa_auth_uses_sae(sta
->wpa_sm
) &&
2651 sta
->auth_alg
!= WLAN_AUTH_SAE
&&
2652 !(sta
->auth_alg
== WLAN_AUTH_FT
&&
2653 wpa_auth_uses_ft_sae(sta
->wpa_sm
))) {
2654 wpa_printf(MSG_DEBUG
, "SAE: " MACSTR
" tried to use "
2655 "SAE AKM after non-SAE auth_alg %u",
2656 MAC2STR(sta
->addr
), sta
->auth_alg
);
2657 return WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG
;
2659 #endif /* CONFIG_SAE */
2662 if ((hapd
->conf
->wpa_key_mgmt
& WPA_KEY_MGMT_OWE
) &&
2663 wpa_auth_sta_key_mgmt(sta
->wpa_sm
) == WPA_KEY_MGMT_OWE
&&
2665 resp
= owe_process_assoc_req(hapd
, sta
, elems
.owe_dh
,
2667 if (resp
!= WLAN_STATUS_SUCCESS
)
2670 #endif /* CONFIG_OWE */
2672 #ifdef CONFIG_IEEE80211N
2673 if ((sta
->flags
& (WLAN_STA_HT
| WLAN_STA_VHT
)) &&
2674 wpa_auth_get_pairwise(sta
->wpa_sm
) == WPA_CIPHER_TKIP
) {
2675 hostapd_logger(hapd
, sta
->addr
,
2676 HOSTAPD_MODULE_IEEE80211
,
2678 "Station tried to use TKIP with HT "
2680 return WLAN_STATUS_CIPHER_REJECTED_PER_POLICY
;
2682 #endif /* CONFIG_IEEE80211N */
2684 } else if (hapd
->conf
->osen
) {
2685 if (elems
.osen
== NULL
) {
2687 hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
2689 "No HS 2.0 OSEN element in association request");
2690 return WLAN_STATUS_INVALID_IE
;
2693 wpa_printf(MSG_DEBUG
, "HS 2.0: OSEN association");
2694 if (sta
->wpa_sm
== NULL
)
2695 sta
->wpa_sm
= wpa_auth_sta_init(hapd
->wpa_auth
,
2697 if (sta
->wpa_sm
== NULL
) {
2698 wpa_printf(MSG_WARNING
, "Failed to initialize WPA "
2700 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2702 if (wpa_validate_osen(hapd
->wpa_auth
, sta
->wpa_sm
,
2703 elems
.osen
- 2, elems
.osen_len
+ 2) < 0)
2704 return WLAN_STATUS_INVALID_IE
;
2705 #endif /* CONFIG_HS20 */
2707 wpa_auth_sta_no_wpa(sta
->wpa_sm
);
2710 p2p_group_notif_assoc(hapd
->p2p_group
, sta
->addr
, ies
, ies_len
);
2711 #endif /* CONFIG_P2P */
2714 wpabuf_free(sta
->hs20_ie
);
2715 if (elems
.hs20
&& elems
.hs20_len
> 4) {
2716 sta
->hs20_ie
= wpabuf_alloc_copy(elems
.hs20
+ 4,
2717 elems
.hs20_len
- 4);
2719 sta
->hs20_ie
= NULL
;
2721 wpabuf_free(sta
->roaming_consortium
);
2722 if (elems
.roaming_cons_sel
)
2723 sta
->roaming_consortium
= wpabuf_alloc_copy(
2724 elems
.roaming_cons_sel
+ 4,
2725 elems
.roaming_cons_sel_len
- 4);
2727 sta
->roaming_consortium
= NULL
;
2728 #endif /* CONFIG_HS20 */
2731 wpabuf_free(sta
->mb_ies
);
2732 if (hapd
->iface
->fst
)
2733 sta
->mb_ies
= mb_ies_by_info(&elems
.mb_ies
);
2736 #endif /* CONFIG_FST */
2739 mbo_ap_check_sta_assoc(hapd
, sta
, &elems
);
2741 if (hapd
->conf
->mbo_enabled
&& (hapd
->conf
->wpa
& 2) &&
2742 elems
.mbo
&& sta
->cell_capa
&& !(sta
->flags
& WLAN_STA_MFP
) &&
2743 hapd
->conf
->ieee80211w
!= NO_MGMT_FRAME_PROTECTION
) {
2744 wpa_printf(MSG_INFO
,
2745 "MBO: Reject WPA2 association without PMF");
2746 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2748 #endif /* CONFIG_MBO */
2750 ap_copy_sta_supp_op_classes(sta
, elems
.supp_op_classes
,
2751 elems
.supp_op_classes_len
);
2753 if ((sta
->capability
& WLAN_CAPABILITY_RADIO_MEASUREMENT
) &&
2754 elems
.rrm_enabled
&&
2755 elems
.rrm_enabled_len
>= sizeof(sta
->rrm_enabled_capa
))
2756 os_memcpy(sta
->rrm_enabled_capa
, elems
.rrm_enabled
,
2757 sizeof(sta
->rrm_enabled_capa
));
2759 if (elems
.power_capab
) {
2760 sta
->min_tx_power
= elems
.power_capab
[0];
2761 sta
->max_tx_power
= elems
.power_capab
[1];
2762 sta
->power_capab
= 1;
2764 sta
->power_capab
= 0;
2767 return WLAN_STATUS_SUCCESS
;
2771 static void send_deauth(struct hostapd_data
*hapd
, const u8
*addr
,
2775 struct ieee80211_mgmt reply
;
2777 os_memset(&reply
, 0, sizeof(reply
));
2778 reply
.frame_control
=
2779 IEEE80211_FC(WLAN_FC_TYPE_MGMT
, WLAN_FC_STYPE_DEAUTH
);
2780 os_memcpy(reply
.da
, addr
, ETH_ALEN
);
2781 os_memcpy(reply
.sa
, hapd
->own_addr
, ETH_ALEN
);
2782 os_memcpy(reply
.bssid
, hapd
->own_addr
, ETH_ALEN
);
2784 send_len
= IEEE80211_HDRLEN
+ sizeof(reply
.u
.deauth
);
2785 reply
.u
.deauth
.reason_code
= host_to_le16(reason_code
);
2787 if (hostapd_drv_send_mlme(hapd
, &reply
, send_len
, 0) < 0)
2788 wpa_printf(MSG_INFO
, "Failed to send deauth: %s",
2793 static int add_associated_sta(struct hostapd_data
*hapd
,
2794 struct sta_info
*sta
)
2796 struct ieee80211_ht_capabilities ht_cap
;
2797 struct ieee80211_vht_capabilities vht_cap
;
2801 * Remove the STA entry to ensure the STA PS state gets cleared and
2802 * configuration gets updated. This is relevant for cases, such as
2803 * FT-over-the-DS, where a station re-associates back to the same AP but
2804 * skips the authentication flow, or if working with a driver that
2805 * does not support full AP client state.
2807 * Skip this if the STA has already completed FT reassociation and the
2808 * TK has been configured since the TX/RX PN must not be reset to 0 for
2811 if (!sta
->added_unassoc
&&
2812 (!(sta
->flags
& WLAN_STA_AUTHORIZED
) ||
2813 (!wpa_auth_sta_ft_tk_already_set(sta
->wpa_sm
) &&
2814 !wpa_auth_sta_fils_tk_already_set(sta
->wpa_sm
)))) {
2815 hostapd_drv_sta_remove(hapd
, sta
->addr
);
2816 wpa_auth_sm_event(sta
->wpa_sm
, WPA_DRV_STA_REMOVED
);
2820 #ifdef CONFIG_IEEE80211N
2821 if (sta
->flags
& WLAN_STA_HT
)
2822 hostapd_get_ht_capab(hapd
, sta
->ht_capabilities
, &ht_cap
);
2823 #endif /* CONFIG_IEEE80211N */
2824 #ifdef CONFIG_IEEE80211AC
2825 if (sta
->flags
& WLAN_STA_VHT
)
2826 hostapd_get_vht_capab(hapd
, sta
->vht_capabilities
, &vht_cap
);
2827 #endif /* CONFIG_IEEE80211AC */
2830 * Add the station with forced WLAN_STA_ASSOC flag. The sta->flags
2831 * will be set when the ACK frame for the (Re)Association Response frame
2832 * is processed (TX status driver event).
2834 if (hostapd_sta_add(hapd
, sta
->addr
, sta
->aid
, sta
->capability
,
2835 sta
->supported_rates
, sta
->supported_rates_len
,
2836 sta
->listen_interval
,
2837 sta
->flags
& WLAN_STA_HT
? &ht_cap
: NULL
,
2838 sta
->flags
& WLAN_STA_VHT
? &vht_cap
: NULL
,
2839 sta
->flags
| WLAN_STA_ASSOC
, sta
->qosinfo
,
2840 sta
->vht_opmode
, sta
->p2p_ie
? 1 : 0,
2842 hostapd_logger(hapd
, sta
->addr
,
2843 HOSTAPD_MODULE_IEEE80211
, HOSTAPD_LEVEL_NOTICE
,
2844 "Could not %s STA to kernel driver",
2845 set
? "set" : "add");
2847 if (sta
->added_unassoc
) {
2848 hostapd_drv_sta_remove(hapd
, sta
->addr
);
2849 sta
->added_unassoc
= 0;
2855 sta
->added_unassoc
= 0;
2861 static u16
send_assoc_resp(struct hostapd_data
*hapd
, struct sta_info
*sta
,
2862 const u8
*addr
, u16 status_code
, int reassoc
,
2863 const u8
*ies
, size_t ies_len
)
2868 struct ieee80211_mgmt
*reply
;
2870 u16 res
= WLAN_STATUS_SUCCESS
;
2872 buflen
= sizeof(struct ieee80211_mgmt
) + 1024;
2874 if (sta
&& sta
->fils_hlp_resp
)
2875 buflen
+= wpabuf_len(sta
->fils_hlp_resp
);
2876 #endif /* CONFIG_FILS */
2878 if (sta
&& (hapd
->conf
->wpa_key_mgmt
& WPA_KEY_MGMT_OWE
))
2880 #endif /* CONFIG_OWE */
2881 buf
= os_zalloc(buflen
);
2883 res
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
2886 reply
= (struct ieee80211_mgmt
*) buf
;
2887 reply
->frame_control
=
2888 IEEE80211_FC(WLAN_FC_TYPE_MGMT
,
2889 (reassoc
? WLAN_FC_STYPE_REASSOC_RESP
:
2890 WLAN_FC_STYPE_ASSOC_RESP
));
2891 os_memcpy(reply
->da
, addr
, ETH_ALEN
);
2892 os_memcpy(reply
->sa
, hapd
->own_addr
, ETH_ALEN
);
2893 os_memcpy(reply
->bssid
, hapd
->own_addr
, ETH_ALEN
);
2895 send_len
= IEEE80211_HDRLEN
;
2896 send_len
+= sizeof(reply
->u
.assoc_resp
);
2897 reply
->u
.assoc_resp
.capab_info
=
2898 host_to_le16(hostapd_own_capab_info(hapd
));
2899 reply
->u
.assoc_resp
.status_code
= host_to_le16(status_code
);
2901 reply
->u
.assoc_resp
.aid
= host_to_le16((sta
? sta
->aid
: 0) |
2903 /* Supported rates */
2904 p
= hostapd_eid_supp_rates(hapd
, reply
->u
.assoc_resp
.variable
);
2905 /* Extended supported rates */
2906 p
= hostapd_eid_ext_supp_rates(hapd
, p
);
2908 #ifdef CONFIG_IEEE80211R_AP
2909 if (sta
&& status_code
== WLAN_STATUS_SUCCESS
) {
2910 /* IEEE 802.11r: Mobility Domain Information, Fast BSS
2911 * Transition Information, RSN, [RIC Response] */
2912 p
= wpa_sm_write_assoc_resp_ies(sta
->wpa_sm
, p
,
2914 sta
->auth_alg
, ies
, ies_len
);
2916 wpa_printf(MSG_DEBUG
,
2917 "FT: Failed to write AssocResp IEs");
2918 res
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
2922 #endif /* CONFIG_IEEE80211R_AP */
2925 if (sta
&& status_code
== WLAN_STATUS_SUCCESS
&&
2926 (hapd
->conf
->wpa_key_mgmt
& WPA_KEY_MGMT_OWE
))
2927 p
= wpa_auth_write_assoc_resp_owe(sta
->wpa_sm
, p
,
2930 #endif /* CONFIG_OWE */
2932 #ifdef CONFIG_IEEE80211W
2933 if (sta
&& status_code
== WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY
)
2934 p
= hostapd_eid_assoc_comeback_time(hapd
, sta
, p
);
2935 #endif /* CONFIG_IEEE80211W */
2937 #ifdef CONFIG_IEEE80211N
2938 p
= hostapd_eid_ht_capabilities(hapd
, p
);
2939 p
= hostapd_eid_ht_operation(hapd
, p
);
2940 #endif /* CONFIG_IEEE80211N */
2942 #ifdef CONFIG_IEEE80211AC
2943 if (hapd
->iconf
->ieee80211ac
&& !hapd
->conf
->disable_11ac
) {
2944 u32 nsts
= 0, sta_nsts
;
2946 if (sta
&& hapd
->conf
->use_sta_nsts
&& sta
->vht_capabilities
) {
2947 struct ieee80211_vht_capabilities
*capa
;
2949 nsts
= (hapd
->iface
->conf
->vht_capab
>>
2950 VHT_CAP_BEAMFORMEE_STS_OFFSET
) & 7;
2951 capa
= sta
->vht_capabilities
;
2952 sta_nsts
= (le_to_host32(capa
->vht_capabilities_info
) >>
2953 VHT_CAP_BEAMFORMEE_STS_OFFSET
) & 7;
2955 if (nsts
< sta_nsts
)
2960 p
= hostapd_eid_vht_capabilities(hapd
, p
, nsts
);
2961 p
= hostapd_eid_vht_operation(hapd
, p
);
2963 #endif /* CONFIG_IEEE80211AC */
2965 p
= hostapd_eid_ext_capab(hapd
, p
);
2966 p
= hostapd_eid_bss_max_idle_period(hapd
, p
);
2967 if (sta
&& sta
->qos_map_enabled
)
2968 p
= hostapd_eid_qos_map_set(hapd
, p
);
2971 if (hapd
->iface
->fst_ies
) {
2972 os_memcpy(p
, wpabuf_head(hapd
->iface
->fst_ies
),
2973 wpabuf_len(hapd
->iface
->fst_ies
));
2974 p
+= wpabuf_len(hapd
->iface
->fst_ies
);
2976 #endif /* CONFIG_FST */
2978 #ifdef CONFIG_IEEE80211AC
2979 if (sta
&& hapd
->conf
->vendor_vht
&& (sta
->flags
& WLAN_STA_VENDOR_VHT
))
2980 p
= hostapd_eid_vendor_vht(hapd
, p
);
2981 #endif /* CONFIG_IEEE80211AC */
2983 if (sta
&& (sta
->flags
& WLAN_STA_WMM
))
2984 p
= hostapd_eid_wmm(hapd
, p
);
2988 ((sta
->flags
& WLAN_STA_WPS
) ||
2989 ((sta
->flags
& WLAN_STA_MAYBE_WPS
) && hapd
->conf
->wpa
))) {
2990 struct wpabuf
*wps
= wps_build_assoc_resp_ie();
2992 os_memcpy(p
, wpabuf_head(wps
), wpabuf_len(wps
));
2993 p
+= wpabuf_len(wps
);
2997 #endif /* CONFIG_WPS */
3000 if (sta
&& sta
->p2p_ie
&& hapd
->p2p_group
) {
3001 struct wpabuf
*p2p_resp_ie
;
3002 enum p2p_status_code status
;
3003 switch (status_code
) {
3004 case WLAN_STATUS_SUCCESS
:
3005 status
= P2P_SC_SUCCESS
;
3007 case WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
:
3008 status
= P2P_SC_FAIL_LIMIT_REACHED
;
3011 status
= P2P_SC_FAIL_INVALID_PARAMS
;
3014 p2p_resp_ie
= p2p_group_assoc_resp_ie(hapd
->p2p_group
, status
);
3016 os_memcpy(p
, wpabuf_head(p2p_resp_ie
),
3017 wpabuf_len(p2p_resp_ie
));
3018 p
+= wpabuf_len(p2p_resp_ie
);
3019 wpabuf_free(p2p_resp_ie
);
3022 #endif /* CONFIG_P2P */
3024 #ifdef CONFIG_P2P_MANAGER
3025 if (hapd
->conf
->p2p
& P2P_MANAGE
)
3026 p
= hostapd_eid_p2p_manage(hapd
, p
);
3027 #endif /* CONFIG_P2P_MANAGER */
3029 p
= hostapd_eid_mbo(hapd
, p
, buf
+ buflen
- p
);
3031 if (hapd
->conf
->assocresp_elements
&&
3032 (size_t) (buf
+ buflen
- p
) >=
3033 wpabuf_len(hapd
->conf
->assocresp_elements
)) {
3034 os_memcpy(p
, wpabuf_head(hapd
->conf
->assocresp_elements
),
3035 wpabuf_len(hapd
->conf
->assocresp_elements
));
3036 p
+= wpabuf_len(hapd
->conf
->assocresp_elements
);
3039 send_len
+= p
- reply
->u
.assoc_resp
.variable
;
3043 (sta
->auth_alg
== WLAN_AUTH_FILS_SK
||
3044 sta
->auth_alg
== WLAN_AUTH_FILS_SK_PFS
||
3045 sta
->auth_alg
== WLAN_AUTH_FILS_PK
) &&
3046 status_code
== WLAN_STATUS_SUCCESS
) {
3047 struct ieee802_11_elems elems
;
3049 if (ieee802_11_parse_elems(ies
, ies_len
, &elems
, 0) ==
3050 ParseFailed
|| !elems
.fils_session
) {
3051 res
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
3056 *p
++ = WLAN_EID_EXTENSION
; /* Element ID */
3057 *p
++ = 1 + FILS_SESSION_LEN
; /* Length */
3058 *p
++ = WLAN_EID_EXT_FILS_SESSION
; /* Element ID Extension */
3059 os_memcpy(p
, elems
.fils_session
, FILS_SESSION_LEN
);
3060 send_len
+= 2 + 1 + FILS_SESSION_LEN
;
3062 send_len
= fils_encrypt_assoc(sta
->wpa_sm
, buf
, send_len
,
3063 buflen
, sta
->fils_hlp_resp
);
3065 res
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
3069 #endif /* CONFIG_FILS */
3072 if ((hapd
->conf
->wpa_key_mgmt
& WPA_KEY_MGMT_OWE
) &&
3073 sta
&& sta
->owe_ecdh
&& status_code
== WLAN_STATUS_SUCCESS
&&
3074 wpa_auth_sta_key_mgmt(sta
->wpa_sm
) == WPA_KEY_MGMT_OWE
) {
3077 pub
= crypto_ecdh_get_pubkey(sta
->owe_ecdh
, 0);
3079 res
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
3082 /* OWE Diffie-Hellman Parameter element */
3083 *p
++ = WLAN_EID_EXTENSION
; /* Element ID */
3084 *p
++ = 1 + 2 + wpabuf_len(pub
); /* Length */
3085 *p
++ = WLAN_EID_EXT_OWE_DH_PARAM
; /* Element ID Extension */
3086 WPA_PUT_LE16(p
, sta
->owe_group
);
3088 os_memcpy(p
, wpabuf_head(pub
), wpabuf_len(pub
));
3089 p
+= wpabuf_len(pub
);
3090 send_len
+= 3 + 2 + wpabuf_len(pub
);
3093 #endif /* CONFIG_OWE */
3095 if (hostapd_drv_send_mlme(hapd
, reply
, send_len
, 0) < 0) {
3096 wpa_printf(MSG_INFO
, "Failed to send assoc resp: %s",
3098 res
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
3108 u8
* owe_assoc_req_process(struct hostapd_data
*hapd
, struct sta_info
*sta
,
3109 const u8
*owe_dh
, u8 owe_dh_len
,
3110 u8
*owe_buf
, size_t owe_buf_len
, u16
*reason
)
3112 #ifdef CONFIG_TESTING_OPTIONS
3113 if (hapd
->conf
->own_ie_override
) {
3114 wpa_printf(MSG_DEBUG
, "OWE: Using IE override");
3115 *reason
= WLAN_STATUS_SUCCESS
;
3116 return wpa_auth_write_assoc_resp_owe(sta
->wpa_sm
, owe_buf
,
3117 owe_buf_len
, NULL
, 0);
3119 #endif /* CONFIG_TESTING_OPTIONS */
3121 if (wpa_auth_sta_get_pmksa(sta
->wpa_sm
)) {
3122 wpa_printf(MSG_DEBUG
, "OWE: Using PMKSA caching");
3123 owe_buf
= wpa_auth_write_assoc_resp_owe(sta
->wpa_sm
, owe_buf
,
3124 owe_buf_len
, NULL
, 0);
3125 *reason
= WLAN_STATUS_SUCCESS
;
3129 *reason
= owe_process_assoc_req(hapd
, sta
, owe_dh
, owe_dh_len
);
3130 if (*reason
!= WLAN_STATUS_SUCCESS
)
3133 owe_buf
= wpa_auth_write_assoc_resp_owe(sta
->wpa_sm
, owe_buf
,
3134 owe_buf_len
, NULL
, 0);
3136 if (sta
->owe_ecdh
&& owe_buf
) {
3139 pub
= crypto_ecdh_get_pubkey(sta
->owe_ecdh
, 0);
3141 *reason
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
3145 /* OWE Diffie-Hellman Parameter element */
3146 *owe_buf
++ = WLAN_EID_EXTENSION
; /* Element ID */
3147 *owe_buf
++ = 1 + 2 + wpabuf_len(pub
); /* Length */
3148 *owe_buf
++ = WLAN_EID_EXT_OWE_DH_PARAM
; /* Element ID Extension
3150 WPA_PUT_LE16(owe_buf
, sta
->owe_group
);
3152 os_memcpy(owe_buf
, wpabuf_head(pub
), wpabuf_len(pub
));
3153 owe_buf
+= wpabuf_len(pub
);
3159 #endif /* CONFIG_OWE */
3164 void fils_hlp_finish_assoc(struct hostapd_data
*hapd
, struct sta_info
*sta
)
3168 wpa_printf(MSG_DEBUG
, "FILS: Finish association with " MACSTR
,
3169 MAC2STR(sta
->addr
));
3170 eloop_cancel_timeout(fils_hlp_timeout
, hapd
, sta
);
3171 if (!sta
->fils_pending_assoc_req
)
3173 reply_res
= send_assoc_resp(hapd
, sta
, sta
->addr
, WLAN_STATUS_SUCCESS
,
3174 sta
->fils_pending_assoc_is_reassoc
,
3175 sta
->fils_pending_assoc_req
,
3176 sta
->fils_pending_assoc_req_len
);
3177 os_free(sta
->fils_pending_assoc_req
);
3178 sta
->fils_pending_assoc_req
= NULL
;
3179 sta
->fils_pending_assoc_req_len
= 0;
3180 wpabuf_free(sta
->fils_hlp_resp
);
3181 sta
->fils_hlp_resp
= NULL
;
3182 wpabuf_free(sta
->hlp_dhcp_discover
);
3183 sta
->hlp_dhcp_discover
= NULL
;
3186 * Remove the station in case transmission of a success response fails.
3187 * At this point the station was already added associated to the driver.
3189 if (reply_res
!= WLAN_STATUS_SUCCESS
)
3190 hostapd_drv_sta_remove(hapd
, sta
->addr
);
3194 void fils_hlp_timeout(void *eloop_ctx
, void *eloop_data
)
3196 struct hostapd_data
*hapd
= eloop_ctx
;
3197 struct sta_info
*sta
= eloop_data
;
3199 wpa_printf(MSG_DEBUG
,
3200 "FILS: HLP response timeout - continue with association response for "
3201 MACSTR
, MAC2STR(sta
->addr
));
3202 if (sta
->fils_drv_assoc_finish
)
3203 hostapd_notify_assoc_fils_finish(hapd
, sta
);
3205 fils_hlp_finish_assoc(hapd
, sta
);
3208 #endif /* CONFIG_FILS */
3211 static void handle_assoc(struct hostapd_data
*hapd
,
3212 const struct ieee80211_mgmt
*mgmt
, size_t len
,
3215 u16 capab_info
, listen_interval
, seq_ctrl
, fc
;
3216 u16 resp
= WLAN_STATUS_SUCCESS
, reply_res
;
3219 struct sta_info
*sta
;
3221 struct hostapd_sta_wpa_psk_short
*psk
= NULL
;
3222 char *identity
= NULL
;
3223 char *radius_cui
= NULL
;
3225 int delay_assoc
= 0;
3226 #endif /* CONFIG_FILS */
3228 if (len
< IEEE80211_HDRLEN
+ (reassoc
? sizeof(mgmt
->u
.reassoc_req
) :
3229 sizeof(mgmt
->u
.assoc_req
))) {
3230 wpa_printf(MSG_INFO
, "handle_assoc(reassoc=%d) - too short payload (len=%lu)",
3231 reassoc
, (unsigned long) len
);
3235 #ifdef CONFIG_TESTING_OPTIONS
3237 if (hapd
->iconf
->ignore_reassoc_probability
> 0.0 &&
3238 drand48() < hapd
->iconf
->ignore_reassoc_probability
) {
3239 wpa_printf(MSG_INFO
,
3240 "TESTING: ignoring reassoc request from "
3241 MACSTR
, MAC2STR(mgmt
->sa
));
3245 if (hapd
->iconf
->ignore_assoc_probability
> 0.0 &&
3246 drand48() < hapd
->iconf
->ignore_assoc_probability
) {
3247 wpa_printf(MSG_INFO
,
3248 "TESTING: ignoring assoc request from "
3249 MACSTR
, MAC2STR(mgmt
->sa
));
3253 #endif /* CONFIG_TESTING_OPTIONS */
3255 fc
= le_to_host16(mgmt
->frame_control
);
3256 seq_ctrl
= le_to_host16(mgmt
->seq_ctrl
);
3259 capab_info
= le_to_host16(mgmt
->u
.reassoc_req
.capab_info
);
3260 listen_interval
= le_to_host16(
3261 mgmt
->u
.reassoc_req
.listen_interval
);
3262 wpa_printf(MSG_DEBUG
, "reassociation request: STA=" MACSTR
3263 " capab_info=0x%02x listen_interval=%d current_ap="
3264 MACSTR
" seq_ctrl=0x%x%s",
3265 MAC2STR(mgmt
->sa
), capab_info
, listen_interval
,
3266 MAC2STR(mgmt
->u
.reassoc_req
.current_ap
),
3267 seq_ctrl
, (fc
& WLAN_FC_RETRY
) ? " retry" : "");
3268 left
= len
- (IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.reassoc_req
));
3269 pos
= mgmt
->u
.reassoc_req
.variable
;
3271 capab_info
= le_to_host16(mgmt
->u
.assoc_req
.capab_info
);
3272 listen_interval
= le_to_host16(
3273 mgmt
->u
.assoc_req
.listen_interval
);
3274 wpa_printf(MSG_DEBUG
, "association request: STA=" MACSTR
3275 " capab_info=0x%02x listen_interval=%d "
3277 MAC2STR(mgmt
->sa
), capab_info
, listen_interval
,
3278 seq_ctrl
, (fc
& WLAN_FC_RETRY
) ? " retry" : "");
3279 left
= len
- (IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.assoc_req
));
3280 pos
= mgmt
->u
.assoc_req
.variable
;
3283 sta
= ap_get_sta(hapd
, mgmt
->sa
);
3284 #ifdef CONFIG_IEEE80211R_AP
3285 if (sta
&& sta
->auth_alg
== WLAN_AUTH_FT
&&
3286 (sta
->flags
& WLAN_STA_AUTH
) == 0) {
3287 wpa_printf(MSG_DEBUG
, "FT: Allow STA " MACSTR
" to associate "
3288 "prior to authentication since it is using "
3289 "over-the-DS FT", MAC2STR(mgmt
->sa
));
3292 * Mark station as authenticated, to avoid adding station
3293 * entry in the driver as associated and not authenticated
3295 sta
->flags
|= WLAN_STA_AUTH
;
3297 #endif /* CONFIG_IEEE80211R_AP */
3298 if (sta
== NULL
|| (sta
->flags
& WLAN_STA_AUTH
) == 0) {
3299 if (hapd
->iface
->current_mode
&&
3300 hapd
->iface
->current_mode
->mode
==
3301 HOSTAPD_MODE_IEEE80211AD
) {
3303 u32 session_timeout
, acct_interim_interval
;
3304 struct vlan_description vlan_id
;
3306 acl_res
= ieee802_11_allowed_address(
3307 hapd
, mgmt
->sa
, (const u8
*) mgmt
, len
,
3308 &session_timeout
, &acct_interim_interval
,
3309 &vlan_id
, &psk
, &identity
, &radius_cui
, 0);
3310 if (acl_res
== HOSTAPD_ACL_REJECT
) {
3311 wpa_msg(hapd
->msg_ctx
, MSG_DEBUG
,
3312 "Ignore Association Request frame from "
3313 MACSTR
" due to ACL reject",
3315 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
3318 if (acl_res
== HOSTAPD_ACL_PENDING
)
3321 /* DMG/IEEE 802.11ad does not use authentication.
3322 * Allocate sta entry upon association. */
3323 sta
= ap_sta_add(hapd
, mgmt
->sa
);
3325 hostapd_logger(hapd
, mgmt
->sa
,
3326 HOSTAPD_MODULE_IEEE80211
,
3328 "Failed to add STA");
3329 resp
= WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
;
3333 acl_res
= ieee802_11_set_radius_info(
3334 hapd
, sta
, acl_res
, session_timeout
,
3335 acct_interim_interval
, &vlan_id
, &psk
,
3336 &identity
, &radius_cui
);
3338 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
3342 hostapd_logger(hapd
, sta
->addr
,
3343 HOSTAPD_MODULE_IEEE80211
,
3344 HOSTAPD_LEVEL_DEBUG
,
3345 "Skip authentication for DMG/IEEE 802.11ad");
3346 sta
->flags
|= WLAN_STA_AUTH
;
3347 wpa_auth_sm_event(sta
->wpa_sm
, WPA_AUTH
);
3348 sta
->auth_alg
= WLAN_AUTH_OPEN
;
3350 hostapd_logger(hapd
, mgmt
->sa
,
3351 HOSTAPD_MODULE_IEEE80211
,
3353 "Station tried to associate before authentication (aid=%d flags=0x%x)",
3354 sta
? sta
->aid
: -1,
3355 sta
? sta
->flags
: 0);
3356 send_deauth(hapd
, mgmt
->sa
,
3357 WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA
);
3362 if ((fc
& WLAN_FC_RETRY
) &&
3363 sta
->last_seq_ctrl
!= WLAN_INVALID_MGMT_SEQ
&&
3364 sta
->last_seq_ctrl
== seq_ctrl
&&
3365 sta
->last_subtype
== (reassoc
? WLAN_FC_STYPE_REASSOC_REQ
:
3366 WLAN_FC_STYPE_ASSOC_REQ
)) {
3367 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
3368 HOSTAPD_LEVEL_DEBUG
,
3369 "Drop repeated association frame seq_ctrl=0x%x",
3373 sta
->last_seq_ctrl
= seq_ctrl
;
3374 sta
->last_subtype
= reassoc
? WLAN_FC_STYPE_REASSOC_REQ
:
3375 WLAN_FC_STYPE_ASSOC_REQ
;
3377 if (hapd
->tkip_countermeasures
) {
3378 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
3382 if (listen_interval
> hapd
->conf
->max_listen_interval
) {
3383 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
3384 HOSTAPD_LEVEL_DEBUG
,
3385 "Too large Listen Interval (%d)",
3387 resp
= WLAN_STATUS_ASSOC_DENIED_LISTEN_INT_TOO_LARGE
;
3392 if (hapd
->conf
->mbo_enabled
&& hapd
->mbo_assoc_disallow
) {
3393 resp
= WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
;
3396 #endif /* CONFIG_MBO */
3399 * sta->capability is used in check_assoc_ies() for RRM enabled
3400 * capability element.
3402 sta
->capability
= capab_info
;
3405 if (sta
->auth_alg
== WLAN_AUTH_FILS_SK
||
3406 sta
->auth_alg
== WLAN_AUTH_FILS_SK_PFS
||
3407 sta
->auth_alg
== WLAN_AUTH_FILS_PK
) {
3410 /* The end of the payload is encrypted. Need to decrypt it
3411 * before parsing. */
3413 tmp
= os_memdup(pos
, left
);
3415 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
3419 res
= fils_decrypt_assoc(sta
->wpa_sm
, sta
->fils_session
, mgmt
,
3422 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
3428 #endif /* CONFIG_FILS */
3430 /* followed by SSID and Supported rates; and HT capabilities if 802.11n
3432 resp
= check_assoc_ies(hapd
, sta
, pos
, left
, reassoc
);
3433 if (resp
!= WLAN_STATUS_SUCCESS
)
3436 if (hostapd_get_aid(hapd
, sta
) < 0) {
3437 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
3438 HOSTAPD_LEVEL_INFO
, "No room for more AIDs");
3439 resp
= WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
;
3443 sta
->listen_interval
= listen_interval
;
3445 if (hapd
->iface
->current_mode
&&
3446 hapd
->iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211G
)
3447 sta
->flags
|= WLAN_STA_NONERP
;
3448 for (i
= 0; i
< sta
->supported_rates_len
; i
++) {
3449 if ((sta
->supported_rates
[i
] & 0x7f) > 22) {
3450 sta
->flags
&= ~WLAN_STA_NONERP
;
3454 if (sta
->flags
& WLAN_STA_NONERP
&& !sta
->nonerp_set
) {
3455 sta
->nonerp_set
= 1;
3456 hapd
->iface
->num_sta_non_erp
++;
3457 if (hapd
->iface
->num_sta_non_erp
== 1)
3458 ieee802_11_set_beacons(hapd
->iface
);
3461 if (!(sta
->capability
& WLAN_CAPABILITY_SHORT_SLOT_TIME
) &&
3462 !sta
->no_short_slot_time_set
) {
3463 sta
->no_short_slot_time_set
= 1;
3464 hapd
->iface
->num_sta_no_short_slot_time
++;
3465 if (hapd
->iface
->current_mode
&&
3466 hapd
->iface
->current_mode
->mode
==
3467 HOSTAPD_MODE_IEEE80211G
&&
3468 hapd
->iface
->num_sta_no_short_slot_time
== 1)
3469 ieee802_11_set_beacons(hapd
->iface
);
3472 if (sta
->capability
& WLAN_CAPABILITY_SHORT_PREAMBLE
)
3473 sta
->flags
|= WLAN_STA_SHORT_PREAMBLE
;
3475 sta
->flags
&= ~WLAN_STA_SHORT_PREAMBLE
;
3477 if (!(sta
->capability
& WLAN_CAPABILITY_SHORT_PREAMBLE
) &&
3478 !sta
->no_short_preamble_set
) {
3479 sta
->no_short_preamble_set
= 1;
3480 hapd
->iface
->num_sta_no_short_preamble
++;
3481 if (hapd
->iface
->current_mode
&&
3482 hapd
->iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211G
3483 && hapd
->iface
->num_sta_no_short_preamble
== 1)
3484 ieee802_11_set_beacons(hapd
->iface
);
3487 #ifdef CONFIG_IEEE80211N
3488 update_ht_state(hapd
, sta
);
3489 #endif /* CONFIG_IEEE80211N */
3491 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
3492 HOSTAPD_LEVEL_DEBUG
,
3493 "association OK (aid %d)", sta
->aid
);
3494 /* Station will be marked associated, after it acknowledges AssocResp
3496 sta
->flags
|= WLAN_STA_ASSOC_REQ_OK
;
3498 #ifdef CONFIG_IEEE80211W
3499 if ((sta
->flags
& WLAN_STA_MFP
) && sta
->sa_query_timed_out
) {
3500 wpa_printf(MSG_DEBUG
, "Allowing %sassociation after timed out "
3501 "SA Query procedure", reassoc
? "re" : "");
3502 /* TODO: Send a protected Disassociate frame to the STA using
3503 * the old key and Reason Code "Previous Authentication no
3504 * longer valid". Make sure this is only sent protected since
3505 * unprotected frame would be received by the STA that is now
3506 * trying to associate.
3509 #endif /* CONFIG_IEEE80211W */
3511 /* Make sure that the previously registered inactivity timer will not
3512 * remove the STA immediately. */
3513 sta
->timeout_next
= STA_NULLFUNC
;
3515 #ifdef CONFIG_TAXONOMY
3516 taxonomy_sta_info_assoc_req(hapd
, sta
, pos
, left
);
3517 #endif /* CONFIG_TAXONOMY */
3519 sta
->pending_wds_enable
= 0;
3522 if (sta
->auth_alg
== WLAN_AUTH_FILS_SK
||
3523 sta
->auth_alg
== WLAN_AUTH_FILS_SK_PFS
||
3524 sta
->auth_alg
== WLAN_AUTH_FILS_PK
) {
3525 if (fils_process_hlp(hapd
, sta
, pos
, left
) > 0)
3528 #endif /* CONFIG_FILS */
3532 os_free(radius_cui
);
3533 hostapd_free_psk_list(psk
);
3536 * In case of a successful response, add the station to the driver.
3537 * Otherwise, the kernel may ignore Data frames before we process the
3538 * ACK frame (TX status). In case of a failure, this station will be
3541 * Note that this is not compliant with the IEEE 802.11 standard that
3542 * states that a non-AP station should transition into the
3543 * authenticated/associated state only after the station acknowledges
3544 * the (Re)Association Response frame. However, still do this as:
3546 * 1. In case the station does not acknowledge the (Re)Association
3547 * Response frame, it will be removed.
3548 * 2. Data frames will be dropped in the kernel until the station is
3549 * set into authorized state, and there are no significant known
3550 * issues with processing other non-Data Class 3 frames during this
3553 if (resp
== WLAN_STATUS_SUCCESS
&& sta
&& add_associated_sta(hapd
, sta
))
3554 resp
= WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
;
3557 if (sta
&& delay_assoc
&& resp
== WLAN_STATUS_SUCCESS
&&
3558 eloop_is_timeout_registered(fils_hlp_timeout
, hapd
, sta
) &&
3559 sta
->fils_pending_assoc_req
) {
3560 /* Do not reschedule fils_hlp_timeout in case the station
3561 * retransmits (Re)Association Request frame while waiting for
3562 * the previously started FILS HLP wait, so that the timeout can
3563 * be determined from the first pending attempt. */
3564 wpa_printf(MSG_DEBUG
,
3565 "FILS: Continue waiting for HLP processing before sending (Re)Association Response frame to "
3566 MACSTR
, MAC2STR(sta
->addr
));
3571 eloop_cancel_timeout(fils_hlp_timeout
, hapd
, sta
);
3572 os_free(sta
->fils_pending_assoc_req
);
3573 sta
->fils_pending_assoc_req
= NULL
;
3574 sta
->fils_pending_assoc_req_len
= 0;
3575 wpabuf_free(sta
->fils_hlp_resp
);
3576 sta
->fils_hlp_resp
= NULL
;
3578 if (sta
&& delay_assoc
&& resp
== WLAN_STATUS_SUCCESS
) {
3579 sta
->fils_pending_assoc_req
= tmp
;
3580 sta
->fils_pending_assoc_req_len
= left
;
3581 sta
->fils_pending_assoc_is_reassoc
= reassoc
;
3582 sta
->fils_drv_assoc_finish
= 0;
3583 wpa_printf(MSG_DEBUG
,
3584 "FILS: Waiting for HLP processing before sending (Re)Association Response frame to "
3585 MACSTR
, MAC2STR(sta
->addr
));
3586 eloop_cancel_timeout(fils_hlp_timeout
, hapd
, sta
);
3587 eloop_register_timeout(0, hapd
->conf
->fils_hlp_wait_time
* 1024,
3588 fils_hlp_timeout
, hapd
, sta
);
3591 #endif /* CONFIG_FILS */
3593 reply_res
= send_assoc_resp(hapd
, sta
, mgmt
->sa
, resp
, reassoc
, pos
,
3598 * Remove the station in case tranmission of a success response fails
3599 * (the STA was added associated to the driver) or if the station was
3600 * previously added unassociated.
3602 if (sta
&& ((reply_res
!= WLAN_STATUS_SUCCESS
&&
3603 resp
== WLAN_STATUS_SUCCESS
) || sta
->added_unassoc
)) {
3604 hostapd_drv_sta_remove(hapd
, sta
->addr
);
3605 sta
->added_unassoc
= 0;
3610 static void handle_disassoc(struct hostapd_data
*hapd
,
3611 const struct ieee80211_mgmt
*mgmt
, size_t len
)
3613 struct sta_info
*sta
;
3615 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.disassoc
)) {
3616 wpa_printf(MSG_INFO
, "handle_disassoc - too short payload (len=%lu)",
3617 (unsigned long) len
);
3621 wpa_printf(MSG_DEBUG
, "disassocation: STA=" MACSTR
" reason_code=%d",
3623 le_to_host16(mgmt
->u
.disassoc
.reason_code
));
3625 sta
= ap_get_sta(hapd
, mgmt
->sa
);
3627 wpa_printf(MSG_INFO
, "Station " MACSTR
" trying to disassociate, but it is not associated",
3632 ap_sta_set_authorized(hapd
, sta
, 0);
3633 sta
->last_seq_ctrl
= WLAN_INVALID_MGMT_SEQ
;
3634 sta
->flags
&= ~(WLAN_STA_ASSOC
| WLAN_STA_ASSOC_REQ_OK
);
3635 wpa_auth_sm_event(sta
->wpa_sm
, WPA_DISASSOC
);
3636 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
3637 HOSTAPD_LEVEL_INFO
, "disassociated");
3638 sta
->acct_terminate_cause
= RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST
;
3639 ieee802_1x_notify_port_enabled(sta
->eapol_sm
, 0);
3640 /* Stop Accounting and IEEE 802.1X sessions, but leave the STA
3642 accounting_sta_stop(hapd
, sta
);
3643 ieee802_1x_free_station(hapd
, sta
);
3645 hostapd_drv_br_delete_ip_neigh(hapd
, 4, (u8
*) &sta
->ipaddr
);
3646 ap_sta_ip6addr_del(hapd
, sta
);
3647 hostapd_drv_sta_remove(hapd
, sta
->addr
);
3648 sta
->added_unassoc
= 0;
3650 if (sta
->timeout_next
== STA_NULLFUNC
||
3651 sta
->timeout_next
== STA_DISASSOC
) {
3652 sta
->timeout_next
= STA_DEAUTH
;
3653 eloop_cancel_timeout(ap_handle_timer
, hapd
, sta
);
3654 eloop_register_timeout(AP_DEAUTH_DELAY
, 0, ap_handle_timer
,
3658 mlme_disassociate_indication(
3659 hapd
, sta
, le_to_host16(mgmt
->u
.disassoc
.reason_code
));
3661 /* DMG/IEEE 802.11ad does not use deauthication. Deallocate sta upon
3662 * disassociation. */
3663 if (hapd
->iface
->current_mode
&&
3664 hapd
->iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211AD
) {
3665 sta
->flags
&= ~WLAN_STA_AUTH
;
3666 wpa_auth_sm_event(sta
->wpa_sm
, WPA_DEAUTH
);
3667 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
3668 HOSTAPD_LEVEL_DEBUG
, "deauthenticated");
3669 ap_free_sta(hapd
, sta
);
3674 static void handle_deauth(struct hostapd_data
*hapd
,
3675 const struct ieee80211_mgmt
*mgmt
, size_t len
)
3677 struct sta_info
*sta
;
3679 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.deauth
)) {
3680 wpa_msg(hapd
->msg_ctx
, MSG_DEBUG
, "handle_deauth - too short "
3681 "payload (len=%lu)", (unsigned long) len
);
3685 wpa_msg(hapd
->msg_ctx
, MSG_DEBUG
, "deauthentication: STA=" MACSTR
3687 MAC2STR(mgmt
->sa
), le_to_host16(mgmt
->u
.deauth
.reason_code
));
3689 sta
= ap_get_sta(hapd
, mgmt
->sa
);
3691 wpa_msg(hapd
->msg_ctx
, MSG_DEBUG
, "Station " MACSTR
" trying "
3692 "to deauthenticate, but it is not authenticated",
3697 ap_sta_set_authorized(hapd
, sta
, 0);
3698 sta
->last_seq_ctrl
= WLAN_INVALID_MGMT_SEQ
;
3699 sta
->flags
&= ~(WLAN_STA_AUTH
| WLAN_STA_ASSOC
|
3700 WLAN_STA_ASSOC_REQ_OK
);
3701 wpa_auth_sm_event(sta
->wpa_sm
, WPA_DEAUTH
);
3702 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
3703 HOSTAPD_LEVEL_DEBUG
, "deauthenticated");
3704 mlme_deauthenticate_indication(
3705 hapd
, sta
, le_to_host16(mgmt
->u
.deauth
.reason_code
));
3706 sta
->acct_terminate_cause
= RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST
;
3707 ieee802_1x_notify_port_enabled(sta
->eapol_sm
, 0);
3708 ap_free_sta(hapd
, sta
);
3712 static void handle_beacon(struct hostapd_data
*hapd
,
3713 const struct ieee80211_mgmt
*mgmt
, size_t len
,
3714 struct hostapd_frame_info
*fi
)
3716 struct ieee802_11_elems elems
;
3718 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.beacon
)) {
3719 wpa_printf(MSG_INFO
, "handle_beacon - too short payload (len=%lu)",
3720 (unsigned long) len
);
3724 (void) ieee802_11_parse_elems(mgmt
->u
.beacon
.variable
,
3725 len
- (IEEE80211_HDRLEN
+
3726 sizeof(mgmt
->u
.beacon
)), &elems
,
3729 ap_list_process_beacon(hapd
->iface
, mgmt
, &elems
, fi
);
3733 #ifdef CONFIG_IEEE80211W
3735 static int hostapd_sa_query_action(struct hostapd_data
*hapd
,
3736 const struct ieee80211_mgmt
*mgmt
,
3741 end
= mgmt
->u
.action
.u
.sa_query_resp
.trans_id
+
3742 WLAN_SA_QUERY_TR_ID_LEN
;
3743 if (((u8
*) mgmt
) + len
< end
) {
3744 wpa_printf(MSG_DEBUG
, "IEEE 802.11: Too short SA Query Action "
3745 "frame (len=%lu)", (unsigned long) len
);
3749 ieee802_11_sa_query_action(hapd
, mgmt
->sa
,
3750 mgmt
->u
.action
.u
.sa_query_resp
.action
,
3751 mgmt
->u
.action
.u
.sa_query_resp
.trans_id
);
3756 static int robust_action_frame(u8 category
)
3758 return category
!= WLAN_ACTION_PUBLIC
&&
3759 category
!= WLAN_ACTION_HT
;
3761 #endif /* CONFIG_IEEE80211W */
3764 static int handle_action(struct hostapd_data
*hapd
,
3765 const struct ieee80211_mgmt
*mgmt
, size_t len
,
3768 struct sta_info
*sta
;
3769 u8
*action __maybe_unused
;
3771 if (len
< IEEE80211_HDRLEN
+ 2 + 1) {
3772 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
3773 HOSTAPD_LEVEL_DEBUG
,
3774 "handle_action - too short payload (len=%lu)",
3775 (unsigned long) len
);
3779 action
= (u8
*) &mgmt
->u
.action
.u
;
3780 wpa_printf(MSG_DEBUG
, "RX_ACTION category %u action %u sa " MACSTR
3781 " da " MACSTR
" len %d freq %u",
3782 mgmt
->u
.action
.category
, *action
,
3783 MAC2STR(mgmt
->sa
), MAC2STR(mgmt
->da
), (int) len
, freq
);
3785 sta
= ap_get_sta(hapd
, mgmt
->sa
);
3787 if (mgmt
->u
.action
.category
!= WLAN_ACTION_PUBLIC
&&
3788 (sta
== NULL
|| !(sta
->flags
& WLAN_STA_ASSOC
))) {
3789 wpa_printf(MSG_DEBUG
, "IEEE 802.11: Ignored Action "
3790 "frame (category=%u) from unassociated STA " MACSTR
,
3791 mgmt
->u
.action
.category
, MAC2STR(mgmt
->sa
));
3795 #ifdef CONFIG_IEEE80211W
3796 if (sta
&& (sta
->flags
& WLAN_STA_MFP
) &&
3797 !(mgmt
->frame_control
& host_to_le16(WLAN_FC_ISWEP
)) &&
3798 robust_action_frame(mgmt
->u
.action
.category
)) {
3799 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
3800 HOSTAPD_LEVEL_DEBUG
,
3801 "Dropped unprotected Robust Action frame from "
3805 #endif /* CONFIG_IEEE80211W */
3808 u16 fc
= le_to_host16(mgmt
->frame_control
);
3809 u16 seq_ctrl
= le_to_host16(mgmt
->seq_ctrl
);
3811 if ((fc
& WLAN_FC_RETRY
) &&
3812 sta
->last_seq_ctrl
!= WLAN_INVALID_MGMT_SEQ
&&
3813 sta
->last_seq_ctrl
== seq_ctrl
&&
3814 sta
->last_subtype
== WLAN_FC_STYPE_ACTION
) {
3815 hostapd_logger(hapd
, sta
->addr
,
3816 HOSTAPD_MODULE_IEEE80211
,
3817 HOSTAPD_LEVEL_DEBUG
,
3818 "Drop repeated action frame seq_ctrl=0x%x",
3823 sta
->last_seq_ctrl
= seq_ctrl
;
3824 sta
->last_subtype
= WLAN_FC_STYPE_ACTION
;
3827 switch (mgmt
->u
.action
.category
) {
3828 #ifdef CONFIG_IEEE80211R_AP
3829 case WLAN_ACTION_FT
:
3831 wpa_ft_action_rx(sta
->wpa_sm
, (u8
*) &mgmt
->u
.action
,
3832 len
- IEEE80211_HDRLEN
))
3835 #endif /* CONFIG_IEEE80211R_AP */
3836 case WLAN_ACTION_WMM
:
3837 hostapd_wmm_action(hapd
, mgmt
, len
);
3839 #ifdef CONFIG_IEEE80211W
3840 case WLAN_ACTION_SA_QUERY
:
3841 return hostapd_sa_query_action(hapd
, mgmt
, len
);
3842 #endif /* CONFIG_IEEE80211W */
3843 #ifdef CONFIG_WNM_AP
3844 case WLAN_ACTION_WNM
:
3845 ieee802_11_rx_wnm_action_ap(hapd
, mgmt
, len
);
3847 #endif /* CONFIG_WNM_AP */
3849 case WLAN_ACTION_FST
:
3850 if (hapd
->iface
->fst
)
3851 fst_rx_action(hapd
->iface
->fst
, mgmt
, len
);
3853 wpa_printf(MSG_DEBUG
,
3854 "FST: Ignore FST Action frame - no FST attached");
3856 #endif /* CONFIG_FST */
3857 case WLAN_ACTION_PUBLIC
:
3858 case WLAN_ACTION_PROTECTED_DUAL
:
3859 #ifdef CONFIG_IEEE80211N
3860 if (len
>= IEEE80211_HDRLEN
+ 2 &&
3861 mgmt
->u
.action
.u
.public_action
.action
==
3862 WLAN_PA_20_40_BSS_COEX
) {
3863 hostapd_2040_coex_action(hapd
, mgmt
, len
);
3866 #endif /* CONFIG_IEEE80211N */
3868 if (len
>= IEEE80211_HDRLEN
+ 6 &&
3869 mgmt
->u
.action
.u
.vs_public_action
.action
==
3870 WLAN_PA_VENDOR_SPECIFIC
&&
3871 WPA_GET_BE24(mgmt
->u
.action
.u
.vs_public_action
.oui
) ==
3873 mgmt
->u
.action
.u
.vs_public_action
.variable
[0] ==
3875 const u8
*pos
, *end
;
3877 pos
= mgmt
->u
.action
.u
.vs_public_action
.oui
;
3878 end
= ((const u8
*) mgmt
) + len
;
3879 hostapd_dpp_rx_action(hapd
, mgmt
->sa
, pos
, end
- pos
,
3883 if (len
>= IEEE80211_HDRLEN
+ 2 &&
3884 (mgmt
->u
.action
.u
.public_action
.action
==
3885 WLAN_PA_GAS_INITIAL_RESP
||
3886 mgmt
->u
.action
.u
.public_action
.action
==
3887 WLAN_PA_GAS_COMEBACK_RESP
)) {
3888 const u8
*pos
, *end
;
3890 pos
= &mgmt
->u
.action
.u
.public_action
.action
;
3891 end
= ((const u8
*) mgmt
) + len
;
3892 gas_query_ap_rx(hapd
->gas
, mgmt
->sa
,
3893 mgmt
->u
.action
.category
,
3894 pos
, end
- pos
, hapd
->iface
->freq
);
3897 #endif /* CONFIG_DPP */
3898 if (hapd
->public_action_cb
) {
3899 hapd
->public_action_cb(hapd
->public_action_cb_ctx
,
3903 if (hapd
->public_action_cb2
) {
3904 hapd
->public_action_cb2(hapd
->public_action_cb2_ctx
,
3908 if (hapd
->public_action_cb
|| hapd
->public_action_cb2
)
3911 case WLAN_ACTION_VENDOR_SPECIFIC
:
3912 if (hapd
->vendor_action_cb
) {
3913 if (hapd
->vendor_action_cb(hapd
->vendor_action_cb_ctx
,
3915 hapd
->iface
->freq
) == 0)
3919 case WLAN_ACTION_RADIO_MEASUREMENT
:
3920 hostapd_handle_radio_measurement(hapd
, (const u8
*) mgmt
, len
);
3924 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
3925 HOSTAPD_LEVEL_DEBUG
,
3926 "handle_action - unknown action category %d or invalid "
3928 mgmt
->u
.action
.category
);
3929 if (!is_multicast_ether_addr(mgmt
->da
) &&
3930 !(mgmt
->u
.action
.category
& 0x80) &&
3931 !is_multicast_ether_addr(mgmt
->sa
)) {
3932 struct ieee80211_mgmt
*resp
;
3935 * IEEE 802.11-REVma/D9.0 - 7.3.1.11
3936 * Return the Action frame to the source without change
3937 * except that MSB of the Category set to 1.
3939 wpa_printf(MSG_DEBUG
, "IEEE 802.11: Return unknown Action "
3940 "frame back to sender");
3941 resp
= os_memdup(mgmt
, len
);
3944 os_memcpy(resp
->da
, resp
->sa
, ETH_ALEN
);
3945 os_memcpy(resp
->sa
, hapd
->own_addr
, ETH_ALEN
);
3946 os_memcpy(resp
->bssid
, hapd
->own_addr
, ETH_ALEN
);
3947 resp
->u
.action
.category
|= 0x80;
3949 if (hostapd_drv_send_mlme(hapd
, resp
, len
, 0) < 0) {
3950 wpa_printf(MSG_ERROR
, "IEEE 802.11: Failed to send "
3961 * ieee802_11_mgmt - process incoming IEEE 802.11 management frames
3962 * @hapd: hostapd BSS data structure (the BSS to which the management frame was
3964 * @buf: management frame data (starting from IEEE 802.11 header)
3965 * @len: length of frame data in octets
3966 * @fi: meta data about received frame (signal level, etc.)
3968 * Process all incoming IEEE 802.11 management frames. This will be called for
3969 * each frame received from the kernel driver through wlan#ap interface. In
3970 * addition, it can be called to re-inserted pending frames (e.g., when using
3971 * external RADIUS server as an MAC ACL).
3973 int ieee802_11_mgmt(struct hostapd_data
*hapd
, const u8
*buf
, size_t len
,
3974 struct hostapd_frame_info
*fi
)
3976 struct ieee80211_mgmt
*mgmt
;
3980 int ssi_signal
= fi
? fi
->ssi_signal
: 0;
3988 freq
= hapd
->iface
->freq
;
3990 mgmt
= (struct ieee80211_mgmt
*) buf
;
3991 fc
= le_to_host16(mgmt
->frame_control
);
3992 stype
= WLAN_FC_GET_STYPE(fc
);
3994 if (stype
== WLAN_FC_STYPE_BEACON
) {
3995 handle_beacon(hapd
, mgmt
, len
, fi
);
3999 if (!is_broadcast_ether_addr(mgmt
->bssid
) &&
4001 /* Invitation responses can be sent with the peer MAC as BSSID */
4002 !((hapd
->conf
->p2p
& P2P_GROUP_OWNER
) &&
4003 stype
== WLAN_FC_STYPE_ACTION
) &&
4004 #endif /* CONFIG_P2P */
4006 !(hapd
->conf
->mesh
& MESH_ENABLED
) &&
4007 #endif /* CONFIG_MESH */
4008 os_memcmp(mgmt
->bssid
, hapd
->own_addr
, ETH_ALEN
) != 0) {
4009 wpa_printf(MSG_INFO
, "MGMT: BSSID=" MACSTR
" not our address",
4010 MAC2STR(mgmt
->bssid
));
4015 if (stype
== WLAN_FC_STYPE_PROBE_REQ
) {
4016 handle_probe_req(hapd
, mgmt
, len
, ssi_signal
);
4020 if ((!is_broadcast_ether_addr(mgmt
->da
) ||
4021 stype
!= WLAN_FC_STYPE_ACTION
) &&
4022 os_memcmp(mgmt
->da
, hapd
->own_addr
, ETH_ALEN
) != 0) {
4023 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
4024 HOSTAPD_LEVEL_DEBUG
,
4025 "MGMT: DA=" MACSTR
" not our address",
4030 if (hapd
->iconf
->track_sta_max_num
)
4031 sta_track_add(hapd
->iface
, mgmt
->sa
, ssi_signal
);
4034 case WLAN_FC_STYPE_AUTH
:
4035 wpa_printf(MSG_DEBUG
, "mgmt::auth");
4036 handle_auth(hapd
, mgmt
, len
);
4039 case WLAN_FC_STYPE_ASSOC_REQ
:
4040 wpa_printf(MSG_DEBUG
, "mgmt::assoc_req");
4041 handle_assoc(hapd
, mgmt
, len
, 0);
4044 case WLAN_FC_STYPE_REASSOC_REQ
:
4045 wpa_printf(MSG_DEBUG
, "mgmt::reassoc_req");
4046 handle_assoc(hapd
, mgmt
, len
, 1);
4049 case WLAN_FC_STYPE_DISASSOC
:
4050 wpa_printf(MSG_DEBUG
, "mgmt::disassoc");
4051 handle_disassoc(hapd
, mgmt
, len
);
4054 case WLAN_FC_STYPE_DEAUTH
:
4055 wpa_msg(hapd
->msg_ctx
, MSG_DEBUG
, "mgmt::deauth");
4056 handle_deauth(hapd
, mgmt
, len
);
4059 case WLAN_FC_STYPE_ACTION
:
4060 wpa_printf(MSG_DEBUG
, "mgmt::action");
4061 ret
= handle_action(hapd
, mgmt
, len
, freq
);
4064 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
4065 HOSTAPD_LEVEL_DEBUG
,
4066 "unknown mgmt frame subtype %d", stype
);
4074 static void handle_auth_cb(struct hostapd_data
*hapd
,
4075 const struct ieee80211_mgmt
*mgmt
,
4078 u16 auth_alg
, auth_transaction
, status_code
;
4079 struct sta_info
*sta
;
4081 sta
= ap_get_sta(hapd
, mgmt
->da
);
4083 wpa_printf(MSG_DEBUG
, "handle_auth_cb: STA " MACSTR
4089 auth_alg
= le_to_host16(mgmt
->u
.auth
.auth_alg
);
4090 auth_transaction
= le_to_host16(mgmt
->u
.auth
.auth_transaction
);
4091 status_code
= le_to_host16(mgmt
->u
.auth
.status_code
);
4094 hostapd_logger(hapd
, mgmt
->da
, HOSTAPD_MODULE_IEEE80211
,
4095 HOSTAPD_LEVEL_NOTICE
,
4096 "did not acknowledge authentication response");
4100 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.auth
)) {
4101 wpa_printf(MSG_INFO
, "handle_auth_cb - too short payload (len=%lu)",
4102 (unsigned long) len
);
4106 if (status_code
== WLAN_STATUS_SUCCESS
&&
4107 ((auth_alg
== WLAN_AUTH_OPEN
&& auth_transaction
== 2) ||
4108 (auth_alg
== WLAN_AUTH_SHARED_KEY
&& auth_transaction
== 4))) {
4109 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
4110 HOSTAPD_LEVEL_INFO
, "authenticated");
4111 sta
->flags
|= WLAN_STA_AUTH
;
4112 if (sta
->added_unassoc
)
4113 hostapd_set_sta_flags(hapd
, sta
);
4118 if (status_code
!= WLAN_STATUS_SUCCESS
&& sta
->added_unassoc
) {
4119 hostapd_drv_sta_remove(hapd
, sta
->addr
);
4120 sta
->added_unassoc
= 0;
4125 static void hostapd_set_wds_encryption(struct hostapd_data
*hapd
,
4126 struct sta_info
*sta
,
4130 struct hostapd_ssid
*ssid
= &hapd
->conf
->ssid
;
4132 if (hapd
->conf
->ieee802_1x
|| hapd
->conf
->wpa
)
4135 for (i
= 0; i
< 4; i
++) {
4136 if (ssid
->wep
.key
[i
] &&
4137 hostapd_drv_set_key(ifname_wds
, hapd
, WPA_ALG_WEP
, NULL
, i
,
4138 i
== ssid
->wep
.idx
, NULL
, 0,
4139 ssid
->wep
.key
[i
], ssid
->wep
.len
[i
])) {
4140 wpa_printf(MSG_WARNING
,
4141 "Could not set WEP keys for WDS interface; %s",
4149 static void handle_assoc_cb(struct hostapd_data
*hapd
,
4150 const struct ieee80211_mgmt
*mgmt
,
4151 size_t len
, int reassoc
, int ok
)
4154 struct sta_info
*sta
;
4157 sta
= ap_get_sta(hapd
, mgmt
->da
);
4159 wpa_printf(MSG_INFO
, "handle_assoc_cb: STA " MACSTR
" not found",
4164 if (len
< IEEE80211_HDRLEN
+ (reassoc
? sizeof(mgmt
->u
.reassoc_resp
) :
4165 sizeof(mgmt
->u
.assoc_resp
))) {
4166 wpa_printf(MSG_INFO
,
4167 "handle_assoc_cb(reassoc=%d) - too short payload (len=%lu)",
4168 reassoc
, (unsigned long) len
);
4169 hostapd_drv_sta_remove(hapd
, sta
->addr
);
4174 status
= le_to_host16(mgmt
->u
.reassoc_resp
.status_code
);
4176 status
= le_to_host16(mgmt
->u
.assoc_resp
.status_code
);
4179 hostapd_logger(hapd
, mgmt
->da
, HOSTAPD_MODULE_IEEE80211
,
4180 HOSTAPD_LEVEL_DEBUG
,
4181 "did not acknowledge association response");
4182 sta
->flags
&= ~WLAN_STA_ASSOC_REQ_OK
;
4183 /* The STA is added only in case of SUCCESS */
4184 if (status
== WLAN_STATUS_SUCCESS
)
4185 hostapd_drv_sta_remove(hapd
, sta
->addr
);
4190 if (status
!= WLAN_STATUS_SUCCESS
)
4193 /* Stop previous accounting session, if one is started, and allocate
4194 * new session id for the new session. */
4195 accounting_sta_stop(hapd
, sta
);
4197 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
4199 "associated (aid %d)",
4202 if (sta
->flags
& WLAN_STA_ASSOC
)
4204 sta
->flags
|= WLAN_STA_ASSOC
;
4205 sta
->flags
&= ~WLAN_STA_WNM_SLEEP_MODE
;
4206 if ((!hapd
->conf
->ieee802_1x
&& !hapd
->conf
->wpa
&&
4207 !hapd
->conf
->osen
) ||
4208 sta
->auth_alg
== WLAN_AUTH_FILS_SK
||
4209 sta
->auth_alg
== WLAN_AUTH_FILS_SK_PFS
||
4210 sta
->auth_alg
== WLAN_AUTH_FILS_PK
||
4211 sta
->auth_alg
== WLAN_AUTH_FT
) {
4213 * Open, static WEP, FT protocol, or FILS; no separate
4214 * authorization step.
4216 ap_sta_set_authorized(hapd
, sta
, 1);
4220 mlme_reassociate_indication(hapd
, sta
);
4222 mlme_associate_indication(hapd
, sta
);
4224 #ifdef CONFIG_IEEE80211W
4225 sta
->sa_query_timed_out
= 0;
4226 #endif /* CONFIG_IEEE80211W */
4228 if (sta
->eapol_sm
== NULL
) {
4230 * This STA does not use RADIUS server for EAP authentication,
4231 * so bind it to the selected VLAN interface now, since the
4232 * interface selection is not going to change anymore.
4234 if (ap_sta_bind_vlan(hapd
, sta
) < 0)
4236 } else if (sta
->vlan_id
) {
4237 /* VLAN ID already set (e.g., by PMKSA caching), so bind STA */
4238 if (ap_sta_bind_vlan(hapd
, sta
) < 0)
4242 hostapd_set_sta_flags(hapd
, sta
);
4244 if (!(sta
->flags
& WLAN_STA_WDS
) && sta
->pending_wds_enable
) {
4245 wpa_printf(MSG_DEBUG
, "Enable 4-address WDS mode for STA "
4246 MACSTR
" based on pending request",
4247 MAC2STR(sta
->addr
));
4248 sta
->pending_wds_enable
= 0;
4249 sta
->flags
|= WLAN_STA_WDS
;
4252 if (sta
->flags
& WLAN_STA_WDS
) {
4254 char ifname_wds
[IFNAMSIZ
+ 1];
4256 wpa_printf(MSG_DEBUG
, "Reenable 4-address WDS mode for STA "
4258 MAC2STR(sta
->addr
), sta
->aid
);
4259 ret
= hostapd_set_wds_sta(hapd
, ifname_wds
, sta
->addr
,
4262 hostapd_set_wds_encryption(hapd
, sta
, ifname_wds
);
4265 if (sta
->auth_alg
== WLAN_AUTH_FT
)
4266 wpa_auth_sm_event(sta
->wpa_sm
, WPA_ASSOC_FT
);
4268 wpa_auth_sm_event(sta
->wpa_sm
, WPA_ASSOC
);
4269 hapd
->new_assoc_sta_cb(hapd
, sta
, !new_assoc
);
4270 ieee802_1x_notify_port_enabled(sta
->eapol_sm
, 1);
4273 if ((sta
->auth_alg
== WLAN_AUTH_FILS_SK
||
4274 sta
->auth_alg
== WLAN_AUTH_FILS_SK_PFS
||
4275 sta
->auth_alg
== WLAN_AUTH_FILS_PK
) &&
4276 fils_set_tk(sta
->wpa_sm
) < 0) {
4277 wpa_printf(MSG_DEBUG
, "FILS: TK configuration failed");
4278 ap_sta_disconnect(hapd
, sta
, sta
->addr
,
4279 WLAN_REASON_UNSPECIFIED
);
4282 #endif /* CONFIG_FILS */
4284 if (sta
->pending_eapol_rx
) {
4285 struct os_reltime now
, age
;
4287 os_get_reltime(&now
);
4288 os_reltime_sub(&now
, &sta
->pending_eapol_rx
->rx_time
, &age
);
4289 if (age
.sec
== 0 && age
.usec
< 200000) {
4290 wpa_printf(MSG_DEBUG
,
4291 "Process pending EAPOL frame that was received from " MACSTR
" just before association notification",
4292 MAC2STR(sta
->addr
));
4295 wpabuf_head(sta
->pending_eapol_rx
->buf
),
4296 wpabuf_len(sta
->pending_eapol_rx
->buf
));
4298 wpabuf_free(sta
->pending_eapol_rx
->buf
);
4299 os_free(sta
->pending_eapol_rx
);
4300 sta
->pending_eapol_rx
= NULL
;
4305 static void handle_deauth_cb(struct hostapd_data
*hapd
,
4306 const struct ieee80211_mgmt
*mgmt
,
4309 struct sta_info
*sta
;
4310 if (is_multicast_ether_addr(mgmt
->da
))
4312 sta
= ap_get_sta(hapd
, mgmt
->da
);
4314 wpa_printf(MSG_DEBUG
, "handle_deauth_cb: STA " MACSTR
4315 " not found", MAC2STR(mgmt
->da
));
4319 wpa_printf(MSG_DEBUG
, "STA " MACSTR
" acknowledged deauth",
4320 MAC2STR(sta
->addr
));
4322 wpa_printf(MSG_DEBUG
, "STA " MACSTR
" did not acknowledge "
4323 "deauth", MAC2STR(sta
->addr
));
4325 ap_sta_deauth_cb(hapd
, sta
);
4329 static void handle_disassoc_cb(struct hostapd_data
*hapd
,
4330 const struct ieee80211_mgmt
*mgmt
,
4333 struct sta_info
*sta
;
4334 if (is_multicast_ether_addr(mgmt
->da
))
4336 sta
= ap_get_sta(hapd
, mgmt
->da
);
4338 wpa_printf(MSG_DEBUG
, "handle_disassoc_cb: STA " MACSTR
4339 " not found", MAC2STR(mgmt
->da
));
4343 wpa_printf(MSG_DEBUG
, "STA " MACSTR
" acknowledged disassoc",
4344 MAC2STR(sta
->addr
));
4346 wpa_printf(MSG_DEBUG
, "STA " MACSTR
" did not acknowledge "
4347 "disassoc", MAC2STR(sta
->addr
));
4349 ap_sta_disassoc_cb(hapd
, sta
);
4353 static void handle_action_cb(struct hostapd_data
*hapd
,
4354 const struct ieee80211_mgmt
*mgmt
,
4357 struct sta_info
*sta
;
4358 const struct rrm_measurement_report_element
*report
;
4360 if (is_multicast_ether_addr(mgmt
->da
))
4363 if (len
>= IEEE80211_HDRLEN
+ 6 &&
4364 mgmt
->u
.action
.category
== WLAN_ACTION_PUBLIC
&&
4365 mgmt
->u
.action
.u
.vs_public_action
.action
==
4366 WLAN_PA_VENDOR_SPECIFIC
&&
4367 WPA_GET_BE24(mgmt
->u
.action
.u
.vs_public_action
.oui
) ==
4369 mgmt
->u
.action
.u
.vs_public_action
.variable
[0] ==
4371 const u8
*pos
, *end
;
4373 pos
= &mgmt
->u
.action
.u
.vs_public_action
.variable
[1];
4374 end
= ((const u8
*) mgmt
) + len
;
4375 hostapd_dpp_tx_status(hapd
, mgmt
->da
, pos
, end
- pos
, ok
);
4378 if (len
>= IEEE80211_HDRLEN
+ 2 &&
4379 mgmt
->u
.action
.category
== WLAN_ACTION_PUBLIC
&&
4380 (mgmt
->u
.action
.u
.public_action
.action
==
4381 WLAN_PA_GAS_INITIAL_REQ
||
4382 mgmt
->u
.action
.u
.public_action
.action
==
4383 WLAN_PA_GAS_COMEBACK_REQ
)) {
4384 const u8
*pos
, *end
;
4386 pos
= mgmt
->u
.action
.u
.public_action
.variable
;
4387 end
= ((const u8
*) mgmt
) + len
;
4388 gas_query_ap_tx_status(hapd
->gas
, mgmt
->da
, pos
, end
- pos
, ok
);
4391 #endif /* CONFIG_DPP */
4392 sta
= ap_get_sta(hapd
, mgmt
->da
);
4394 wpa_printf(MSG_DEBUG
, "handle_action_cb: STA " MACSTR
4395 " not found", MAC2STR(mgmt
->da
));
4399 if (len
< 24 + 5 + sizeof(*report
))
4401 report
= (const struct rrm_measurement_report_element
*)
4402 &mgmt
->u
.action
.u
.rrm
.variable
[2];
4403 if (mgmt
->u
.action
.category
== WLAN_ACTION_RADIO_MEASUREMENT
&&
4404 mgmt
->u
.action
.u
.rrm
.action
== WLAN_RRM_RADIO_MEASUREMENT_REQUEST
&&
4405 report
->eid
== WLAN_EID_MEASURE_REQUEST
&&
4407 report
->type
== MEASURE_TYPE_BEACON
)
4408 hostapd_rrm_beacon_req_tx_status(hapd
, mgmt
, len
, ok
);
4413 * ieee802_11_mgmt_cb - Process management frame TX status callback
4414 * @hapd: hostapd BSS data structure (the BSS from which the management frame
4416 * @buf: management frame data (starting from IEEE 802.11 header)
4417 * @len: length of frame data in octets
4418 * @stype: management frame subtype from frame control field
4419 * @ok: Whether the frame was ACK'ed
4421 void ieee802_11_mgmt_cb(struct hostapd_data
*hapd
, const u8
*buf
, size_t len
,
4424 const struct ieee80211_mgmt
*mgmt
;
4425 mgmt
= (const struct ieee80211_mgmt
*) buf
;
4427 #ifdef CONFIG_TESTING_OPTIONS
4428 if (hapd
->ext_mgmt_frame_handling
) {
4429 size_t hex_len
= 2 * len
+ 1;
4430 char *hex
= os_malloc(hex_len
);
4433 wpa_snprintf_hex(hex
, hex_len
, buf
, len
);
4434 wpa_msg(hapd
->msg_ctx
, MSG_INFO
,
4435 "MGMT-TX-STATUS stype=%u ok=%d buf=%s",
4441 #endif /* CONFIG_TESTING_OPTIONS */
4444 case WLAN_FC_STYPE_AUTH
:
4445 wpa_printf(MSG_DEBUG
, "mgmt::auth cb");
4446 handle_auth_cb(hapd
, mgmt
, len
, ok
);
4448 case WLAN_FC_STYPE_ASSOC_RESP
:
4449 wpa_printf(MSG_DEBUG
, "mgmt::assoc_resp cb");
4450 handle_assoc_cb(hapd
, mgmt
, len
, 0, ok
);
4452 case WLAN_FC_STYPE_REASSOC_RESP
:
4453 wpa_printf(MSG_DEBUG
, "mgmt::reassoc_resp cb");
4454 handle_assoc_cb(hapd
, mgmt
, len
, 1, ok
);
4456 case WLAN_FC_STYPE_PROBE_RESP
:
4457 wpa_printf(MSG_EXCESSIVE
, "mgmt::proberesp cb ok=%d", ok
);
4459 case WLAN_FC_STYPE_DEAUTH
:
4460 wpa_printf(MSG_DEBUG
, "mgmt::deauth cb");
4461 handle_deauth_cb(hapd
, mgmt
, len
, ok
);
4463 case WLAN_FC_STYPE_DISASSOC
:
4464 wpa_printf(MSG_DEBUG
, "mgmt::disassoc cb");
4465 handle_disassoc_cb(hapd
, mgmt
, len
, ok
);
4467 case WLAN_FC_STYPE_ACTION
:
4468 wpa_printf(MSG_DEBUG
, "mgmt::action cb ok=%d", ok
);
4469 handle_action_cb(hapd
, mgmt
, len
, ok
);
4472 wpa_printf(MSG_INFO
, "unknown mgmt cb frame subtype %d", stype
);
4478 int ieee802_11_get_mib(struct hostapd_data
*hapd
, char *buf
, size_t buflen
)
4485 int ieee802_11_get_mib_sta(struct hostapd_data
*hapd
, struct sta_info
*sta
,
4486 char *buf
, size_t buflen
)
4493 void hostapd_tx_status(struct hostapd_data
*hapd
, const u8
*addr
,
4494 const u8
*buf
, size_t len
, int ack
)
4496 struct sta_info
*sta
;
4497 struct hostapd_iface
*iface
= hapd
->iface
;
4499 sta
= ap_get_sta(hapd
, addr
);
4500 if (sta
== NULL
&& iface
->num_bss
> 1) {
4502 for (j
= 0; j
< iface
->num_bss
; j
++) {
4503 hapd
= iface
->bss
[j
];
4504 sta
= ap_get_sta(hapd
, addr
);
4509 if (sta
== NULL
|| !(sta
->flags
& WLAN_STA_ASSOC
))
4511 if (sta
->flags
& WLAN_STA_PENDING_POLL
) {
4512 wpa_printf(MSG_DEBUG
, "STA " MACSTR
" %s pending "
4513 "activity poll", MAC2STR(sta
->addr
),
4514 ack
? "ACKed" : "did not ACK");
4516 sta
->flags
&= ~WLAN_STA_PENDING_POLL
;
4519 ieee802_1x_tx_status(hapd
, sta
, buf
, len
, ack
);
4523 void hostapd_eapol_tx_status(struct hostapd_data
*hapd
, const u8
*dst
,
4524 const u8
*data
, size_t len
, int ack
)
4526 struct sta_info
*sta
;
4527 struct hostapd_iface
*iface
= hapd
->iface
;
4529 sta
= ap_get_sta(hapd
, dst
);
4530 if (sta
== NULL
&& iface
->num_bss
> 1) {
4532 for (j
= 0; j
< iface
->num_bss
; j
++) {
4533 hapd
= iface
->bss
[j
];
4534 sta
= ap_get_sta(hapd
, dst
);
4539 if (sta
== NULL
|| !(sta
->flags
& WLAN_STA_ASSOC
)) {
4540 wpa_printf(MSG_DEBUG
, "Ignore TX status for Data frame to STA "
4541 MACSTR
" that is not currently associated",
4546 ieee802_1x_eapol_tx_status(hapd
, sta
, data
, len
, ack
);
4550 void hostapd_client_poll_ok(struct hostapd_data
*hapd
, const u8
*addr
)
4552 struct sta_info
*sta
;
4553 struct hostapd_iface
*iface
= hapd
->iface
;
4555 sta
= ap_get_sta(hapd
, addr
);
4556 if (sta
== NULL
&& iface
->num_bss
> 1) {
4558 for (j
= 0; j
< iface
->num_bss
; j
++) {
4559 hapd
= iface
->bss
[j
];
4560 sta
= ap_get_sta(hapd
, addr
);
4567 wpa_msg(hapd
->msg_ctx
, MSG_INFO
, AP_STA_POLL_OK MACSTR
,
4568 MAC2STR(sta
->addr
));
4569 if (!(sta
->flags
& WLAN_STA_PENDING_POLL
))
4572 wpa_printf(MSG_DEBUG
, "STA " MACSTR
" ACKed pending "
4573 "activity poll", MAC2STR(sta
->addr
));
4574 sta
->flags
&= ~WLAN_STA_PENDING_POLL
;
4578 void ieee802_11_rx_from_unknown(struct hostapd_data
*hapd
, const u8
*src
,
4581 struct sta_info
*sta
;
4583 sta
= ap_get_sta(hapd
, src
);
4585 ((sta
->flags
& WLAN_STA_ASSOC
) ||
4586 ((sta
->flags
& WLAN_STA_ASSOC_REQ_OK
) && wds
))) {
4587 if (!hapd
->conf
->wds_sta
)
4590 if ((sta
->flags
& (WLAN_STA_ASSOC
| WLAN_STA_ASSOC_REQ_OK
)) ==
4591 WLAN_STA_ASSOC_REQ_OK
) {
4592 wpa_printf(MSG_DEBUG
,
4593 "Postpone 4-address WDS mode enabling for STA "
4594 MACSTR
" since TX status for AssocResp is not yet known",
4595 MAC2STR(sta
->addr
));
4596 sta
->pending_wds_enable
= 1;
4600 if (wds
&& !(sta
->flags
& WLAN_STA_WDS
)) {
4602 char ifname_wds
[IFNAMSIZ
+ 1];
4604 wpa_printf(MSG_DEBUG
, "Enable 4-address WDS mode for "
4605 "STA " MACSTR
" (aid %u)",
4606 MAC2STR(sta
->addr
), sta
->aid
);
4607 sta
->flags
|= WLAN_STA_WDS
;
4608 ret
= hostapd_set_wds_sta(hapd
, ifname_wds
,
4609 sta
->addr
, sta
->aid
, 1);
4611 hostapd_set_wds_encryption(hapd
, sta
,
4617 wpa_printf(MSG_DEBUG
, "Data/PS-poll frame from not associated STA "
4618 MACSTR
, MAC2STR(src
));
4619 if (is_multicast_ether_addr(src
)) {
4620 /* Broadcast bit set in SA?! Ignore the frame silently. */
4624 if (sta
&& (sta
->flags
& WLAN_STA_ASSOC_REQ_OK
)) {
4625 wpa_printf(MSG_DEBUG
, "Association Response to the STA has "
4626 "already been sent, but no TX status yet known - "
4627 "ignore Class 3 frame issue with " MACSTR
,
4632 if (sta
&& (sta
->flags
& WLAN_STA_AUTH
))
4633 hostapd_drv_sta_disassoc(
4635 WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA
);
4637 hostapd_drv_sta_deauth(
4639 WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA
);
4643 #endif /* CONFIG_NATIVE_WINDOWS */