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
;
374 password
= hapd
->conf
->sae_password
;
376 password
= hapd
->conf
->ssid
.wpa_passphrase
;
378 wpa_printf(MSG_DEBUG
, "SAE: No password available");
383 sae_prepare_commit(hapd
->own_addr
, sta
->addr
,
384 (u8
*) password
, os_strlen(password
),
386 wpa_printf(MSG_DEBUG
, "SAE: Could not pick PWE");
390 buf
= wpabuf_alloc(SAE_COMMIT_MAX_LEN
);
393 sae_write_commit(sta
->sae
, buf
, sta
->sae
->tmp
?
394 sta
->sae
->tmp
->anti_clogging_token
: NULL
);
400 static struct wpabuf
* auth_build_sae_confirm(struct hostapd_data
*hapd
,
401 struct sta_info
*sta
)
405 buf
= wpabuf_alloc(SAE_CONFIRM_MAX_LEN
);
409 sae_write_confirm(sta
->sae
, buf
);
415 static int auth_sae_send_commit(struct hostapd_data
*hapd
,
416 struct sta_info
*sta
,
417 const u8
*bssid
, int update
)
422 data
= auth_build_sae_commit(hapd
, sta
, update
);
424 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
426 reply_res
= send_auth_reply(hapd
, sta
->addr
, bssid
, WLAN_AUTH_SAE
, 1,
427 WLAN_STATUS_SUCCESS
, wpabuf_head(data
),
428 wpabuf_len(data
), "sae-send-commit");
436 static int auth_sae_send_confirm(struct hostapd_data
*hapd
,
437 struct sta_info
*sta
,
443 data
= auth_build_sae_confirm(hapd
, sta
);
445 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
447 reply_res
= send_auth_reply(hapd
, sta
->addr
, bssid
, WLAN_AUTH_SAE
, 2,
448 WLAN_STATUS_SUCCESS
, wpabuf_head(data
),
449 wpabuf_len(data
), "sae-send-confirm");
457 static int use_sae_anti_clogging(struct hostapd_data
*hapd
)
459 struct sta_info
*sta
;
460 unsigned int open
= 0;
462 if (hapd
->conf
->sae_anti_clogging_threshold
== 0)
465 for (sta
= hapd
->sta_list
; sta
; sta
= sta
->next
) {
468 if (sta
->sae
->state
!= SAE_COMMITTED
&&
469 sta
->sae
->state
!= SAE_CONFIRMED
)
472 if (open
>= hapd
->conf
->sae_anti_clogging_threshold
)
480 static int check_sae_token(struct hostapd_data
*hapd
, const u8
*addr
,
481 const u8
*token
, size_t token_len
)
483 u8 mac
[SHA256_MAC_LEN
];
485 if (token_len
!= SHA256_MAC_LEN
)
487 if (hmac_sha256(hapd
->sae_token_key
, sizeof(hapd
->sae_token_key
),
488 addr
, ETH_ALEN
, mac
) < 0 ||
489 os_memcmp_const(token
, mac
, SHA256_MAC_LEN
) != 0)
496 static struct wpabuf
* auth_build_token_req(struct hostapd_data
*hapd
,
497 int group
, const u8
*addr
)
501 struct os_reltime now
;
503 os_get_reltime(&now
);
504 if (!os_reltime_initialized(&hapd
->last_sae_token_key_update
) ||
505 os_reltime_expired(&now
, &hapd
->last_sae_token_key_update
, 60)) {
506 if (random_get_bytes(hapd
->sae_token_key
,
507 sizeof(hapd
->sae_token_key
)) < 0)
509 wpa_hexdump(MSG_DEBUG
, "SAE: Updated token key",
510 hapd
->sae_token_key
, sizeof(hapd
->sae_token_key
));
511 hapd
->last_sae_token_key_update
= now
;
514 buf
= wpabuf_alloc(sizeof(le16
) + SHA256_MAC_LEN
);
518 wpabuf_put_le16(buf
, group
); /* Finite Cyclic Group */
520 token
= wpabuf_put(buf
, SHA256_MAC_LEN
);
521 hmac_sha256(hapd
->sae_token_key
, sizeof(hapd
->sae_token_key
),
522 addr
, ETH_ALEN
, token
);
528 static int sae_check_big_sync(struct hostapd_data
*hapd
, struct sta_info
*sta
)
530 if (sta
->sae
->sync
> hapd
->conf
->sae_sync
) {
531 sae_set_state(sta
, SAE_NOTHING
, "Sync > dot11RSNASAESync");
539 static void auth_sae_retransmit_timer(void *eloop_ctx
, void *eloop_data
)
541 struct hostapd_data
*hapd
= eloop_ctx
;
542 struct sta_info
*sta
= eloop_data
;
545 if (sae_check_big_sync(hapd
, sta
))
548 wpa_printf(MSG_DEBUG
, "SAE: Auth SAE retransmit timer for " MACSTR
549 " (sync=%d state=%s)",
550 MAC2STR(sta
->addr
), sta
->sae
->sync
,
551 sae_state_txt(sta
->sae
->state
));
553 switch (sta
->sae
->state
) {
555 ret
= auth_sae_send_commit(hapd
, sta
, hapd
->own_addr
, 0);
556 eloop_register_timeout(0,
557 hapd
->dot11RSNASAERetransPeriod
* 1000,
558 auth_sae_retransmit_timer
, hapd
, sta
);
561 ret
= auth_sae_send_confirm(hapd
, sta
, hapd
->own_addr
);
562 eloop_register_timeout(0,
563 hapd
->dot11RSNASAERetransPeriod
* 1000,
564 auth_sae_retransmit_timer
, hapd
, sta
);
571 if (ret
!= WLAN_STATUS_SUCCESS
)
572 wpa_printf(MSG_INFO
, "SAE: Failed to retransmit: ret=%d", ret
);
576 void sae_clear_retransmit_timer(struct hostapd_data
*hapd
, struct sta_info
*sta
)
578 eloop_cancel_timeout(auth_sae_retransmit_timer
, hapd
, sta
);
582 static void sae_set_retransmit_timer(struct hostapd_data
*hapd
,
583 struct sta_info
*sta
)
585 if (!(hapd
->conf
->mesh
& MESH_ENABLED
))
588 eloop_cancel_timeout(auth_sae_retransmit_timer
, hapd
, sta
);
589 eloop_register_timeout(0, hapd
->dot11RSNASAERetransPeriod
* 1000,
590 auth_sae_retransmit_timer
, hapd
, sta
);
594 void sae_accept_sta(struct hostapd_data
*hapd
, struct sta_info
*sta
)
596 sta
->flags
|= WLAN_STA_AUTH
;
597 sta
->auth_alg
= WLAN_AUTH_SAE
;
598 mlme_authenticate_indication(hapd
, sta
);
599 wpa_auth_sm_event(sta
->wpa_sm
, WPA_AUTH
);
600 sae_set_state(sta
, SAE_ACCEPTED
, "Accept Confirm");
601 wpa_auth_pmksa_add_sae(hapd
->wpa_auth
, sta
->addr
,
602 sta
->sae
->pmk
, sta
->sae
->pmkid
);
606 static int sae_sm_step(struct hostapd_data
*hapd
, struct sta_info
*sta
,
607 const u8
*bssid
, u8 auth_transaction
)
611 if (auth_transaction
!= 1 && auth_transaction
!= 2)
612 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
614 wpa_printf(MSG_DEBUG
, "SAE: Peer " MACSTR
" state=%s auth_trans=%u",
615 MAC2STR(sta
->addr
), sae_state_txt(sta
->sae
->state
),
617 switch (sta
->sae
->state
) {
619 if (auth_transaction
== 1) {
620 ret
= auth_sae_send_commit(hapd
, sta
, bssid
, 1);
623 sae_set_state(sta
, SAE_COMMITTED
, "Sent Commit");
625 if (sae_process_commit(sta
->sae
) < 0)
626 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
629 * In mesh case, both Commit and Confirm can be sent
630 * immediately. In infrastructure BSS, only a single
631 * Authentication frame (Commit) is expected from the AP
632 * here and the second one (Confirm) will be sent once
633 * the STA has sent its second Authentication frame
636 if (hapd
->conf
->mesh
& MESH_ENABLED
) {
638 * Send both Commit and Confirm immediately
639 * based on SAE finite state machine
640 * Nothing -> Confirm transition.
642 ret
= auth_sae_send_confirm(hapd
, sta
, bssid
);
645 sae_set_state(sta
, SAE_CONFIRMED
,
646 "Sent Confirm (mesh)");
649 * For infrastructure BSS, send only the Commit
650 * message now to get alternating sequence of
651 * Authentication frames between the AP and STA.
652 * Confirm will be sent in
653 * Committed -> Confirmed/Accepted transition
654 * when receiving Confirm from STA.
658 sae_set_retransmit_timer(hapd
, sta
);
660 hostapd_logger(hapd
, sta
->addr
,
661 HOSTAPD_MODULE_IEEE80211
,
663 "SAE confirm before commit");
667 sae_clear_retransmit_timer(hapd
, sta
);
668 if (auth_transaction
== 1) {
669 if (sae_process_commit(sta
->sae
) < 0)
670 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
672 ret
= auth_sae_send_confirm(hapd
, sta
, bssid
);
675 sae_set_state(sta
, SAE_CONFIRMED
, "Sent Confirm");
677 sae_set_retransmit_timer(hapd
, sta
);
678 } else if (hapd
->conf
->mesh
& MESH_ENABLED
) {
680 * In mesh case, follow SAE finite state machine and
681 * send Commit now, if sync count allows.
683 if (sae_check_big_sync(hapd
, sta
))
684 return WLAN_STATUS_SUCCESS
;
687 ret
= auth_sae_send_commit(hapd
, sta
, bssid
, 0);
691 sae_set_retransmit_timer(hapd
, sta
);
694 * For instructure BSS, send the postponed Confirm from
695 * Nothing -> Confirmed transition that was reduced to
696 * Nothing -> Committed above.
698 ret
= auth_sae_send_confirm(hapd
, sta
, bssid
);
702 sae_set_state(sta
, SAE_CONFIRMED
, "Sent Confirm");
705 * Since this was triggered on Confirm RX, run another
706 * step to get to Accepted without waiting for
709 return sae_sm_step(hapd
, sta
, bssid
, auth_transaction
);
713 sae_clear_retransmit_timer(hapd
, sta
);
714 if (auth_transaction
== 1) {
715 if (sae_check_big_sync(hapd
, sta
))
716 return WLAN_STATUS_SUCCESS
;
719 ret
= auth_sae_send_commit(hapd
, sta
, bssid
, 1);
723 if (sae_process_commit(sta
->sae
) < 0)
724 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
726 ret
= auth_sae_send_confirm(hapd
, sta
, bssid
);
730 sae_set_retransmit_timer(hapd
, sta
);
732 sta
->sae
->send_confirm
= 0xffff;
733 sae_accept_sta(hapd
, sta
);
737 if (auth_transaction
== 1) {
738 wpa_printf(MSG_DEBUG
, "SAE: remove the STA (" MACSTR
739 ") doing reauthentication",
741 ap_free_sta(hapd
, sta
);
742 wpa_auth_pmksa_remove(hapd
->wpa_auth
, sta
->addr
);
744 if (sae_check_big_sync(hapd
, sta
))
745 return WLAN_STATUS_SUCCESS
;
748 ret
= auth_sae_send_confirm(hapd
, sta
, bssid
);
749 sae_clear_temp_data(sta
->sae
);
755 wpa_printf(MSG_ERROR
, "SAE: invalid state %d",
757 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
759 return WLAN_STATUS_SUCCESS
;
763 static void sae_pick_next_group(struct hostapd_data
*hapd
, struct sta_info
*sta
)
765 struct sae_data
*sae
= sta
->sae
;
766 int i
, *groups
= hapd
->conf
->sae_groups
;
768 if (sae
->state
!= SAE_COMMITTED
)
771 wpa_printf(MSG_DEBUG
, "SAE: Previously selected group: %d", sae
->group
);
773 for (i
= 0; groups
&& groups
[i
] > 0; i
++) {
774 if (sae
->group
== groups
[i
])
778 if (!groups
|| groups
[i
] <= 0) {
779 wpa_printf(MSG_DEBUG
,
780 "SAE: Previously selected group not found from the current configuration");
786 if (groups
[i
] <= 0) {
787 wpa_printf(MSG_DEBUG
,
788 "SAE: No alternative group enabled");
792 if (sae_set_group(sae
, groups
[i
]) < 0)
797 wpa_printf(MSG_DEBUG
, "SAE: Selected new group: %d", groups
[i
]);
801 static void handle_auth_sae(struct hostapd_data
*hapd
, struct sta_info
*sta
,
802 const struct ieee80211_mgmt
*mgmt
, size_t len
,
803 u16 auth_transaction
, u16 status_code
)
805 int resp
= WLAN_STATUS_SUCCESS
;
806 struct wpabuf
*data
= NULL
;
808 #ifdef CONFIG_TESTING_OPTIONS
809 if (hapd
->conf
->sae_reflection_attack
&& auth_transaction
== 1) {
812 wpa_printf(MSG_DEBUG
, "SAE: TESTING - reflection attack");
813 pos
= mgmt
->u
.auth
.variable
;
814 end
= ((const u8
*) mgmt
) + len
;
815 send_auth_reply(hapd
, mgmt
->sa
, mgmt
->bssid
, WLAN_AUTH_SAE
,
816 auth_transaction
, resp
, pos
, end
- pos
,
817 "auth-sae-reflection-attack");
821 if (hapd
->conf
->sae_commit_override
&& auth_transaction
== 1) {
822 wpa_printf(MSG_DEBUG
, "SAE: TESTING - commit override");
823 send_auth_reply(hapd
, mgmt
->sa
, mgmt
->bssid
, WLAN_AUTH_SAE
,
824 auth_transaction
, resp
,
825 wpabuf_head(hapd
->conf
->sae_commit_override
),
826 wpabuf_len(hapd
->conf
->sae_commit_override
),
827 "sae-commit-override");
830 #endif /* CONFIG_TESTING_OPTIONS */
832 if (auth_transaction
!= 1 ||
833 status_code
!= WLAN_STATUS_SUCCESS
) {
837 sta
->sae
= os_zalloc(sizeof(*sta
->sae
));
842 sae_set_state(sta
, SAE_NOTHING
, "Init");
846 if (sta
->mesh_sae_pmksa_caching
) {
847 wpa_printf(MSG_DEBUG
,
848 "SAE: Cancel use of mesh PMKSA caching because peer starts SAE authentication");
849 wpa_auth_pmksa_remove(hapd
->wpa_auth
, sta
->addr
);
850 sta
->mesh_sae_pmksa_caching
= 0;
853 if (auth_transaction
== 1) {
854 const u8
*token
= NULL
, *pos
, *end
;
855 size_t token_len
= 0;
856 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
858 "start SAE authentication (RX commit, status=%u)",
861 if ((hapd
->conf
->mesh
& MESH_ENABLED
) &&
862 status_code
== WLAN_STATUS_ANTI_CLOGGING_TOKEN_REQ
&&
864 pos
= mgmt
->u
.auth
.variable
;
865 end
= ((const u8
*) mgmt
) + len
;
866 if (pos
+ sizeof(le16
) > end
) {
867 wpa_printf(MSG_ERROR
,
868 "SAE: Too short anti-clogging token request");
869 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
872 resp
= sae_group_allowed(sta
->sae
,
873 hapd
->conf
->sae_groups
,
875 if (resp
!= WLAN_STATUS_SUCCESS
) {
876 wpa_printf(MSG_ERROR
,
877 "SAE: Invalid group in anti-clogging token request");
882 wpabuf_free(sta
->sae
->tmp
->anti_clogging_token
);
883 sta
->sae
->tmp
->anti_clogging_token
=
884 wpabuf_alloc_copy(pos
, end
- pos
);
885 if (sta
->sae
->tmp
->anti_clogging_token
== NULL
) {
886 wpa_printf(MSG_ERROR
,
887 "SAE: Failed to alloc for anti-clogging token");
888 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
893 * IEEE Std 802.11-2012, 11.3.8.6.4: If the Status code
894 * is 76, a new Commit Message shall be constructed
895 * with the Anti-Clogging Token from the received
896 * Authentication frame, and the commit-scalar and
897 * COMMIT-ELEMENT previously sent.
899 resp
= auth_sae_send_commit(hapd
, sta
, mgmt
->bssid
, 0);
900 if (resp
!= WLAN_STATUS_SUCCESS
) {
901 wpa_printf(MSG_ERROR
,
902 "SAE: Failed to send commit message");
905 sae_set_state(sta
, SAE_COMMITTED
,
906 "Sent Commit (anti-clogging token case in mesh)");
908 sae_set_retransmit_timer(hapd
, sta
);
912 if ((hapd
->conf
->mesh
& MESH_ENABLED
) &&
914 WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED
&&
916 wpa_printf(MSG_DEBUG
,
917 "SAE: Peer did not accept our SAE group");
918 sae_pick_next_group(hapd
, sta
);
922 if (status_code
!= WLAN_STATUS_SUCCESS
)
925 resp
= sae_parse_commit(sta
->sae
, mgmt
->u
.auth
.variable
,
926 ((const u8
*) mgmt
) + len
-
927 mgmt
->u
.auth
.variable
, &token
,
928 &token_len
, hapd
->conf
->sae_groups
);
929 if (resp
== SAE_SILENTLY_DISCARD
) {
930 wpa_printf(MSG_DEBUG
,
931 "SAE: Drop commit message from " MACSTR
" due to reflection attack",
935 if (token
&& check_sae_token(hapd
, sta
->addr
, token
, token_len
)
937 wpa_printf(MSG_DEBUG
, "SAE: Drop commit message with "
938 "incorrect token from " MACSTR
,
940 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
944 if (resp
!= WLAN_STATUS_SUCCESS
)
947 if (!token
&& use_sae_anti_clogging(hapd
)) {
948 wpa_printf(MSG_DEBUG
,
949 "SAE: Request anti-clogging token from "
950 MACSTR
, MAC2STR(sta
->addr
));
951 data
= auth_build_token_req(hapd
, sta
->sae
->group
,
953 resp
= WLAN_STATUS_ANTI_CLOGGING_TOKEN_REQ
;
954 if (hapd
->conf
->mesh
& MESH_ENABLED
)
955 sae_set_state(sta
, SAE_NOTHING
,
956 "Request anti-clogging token case in mesh");
960 resp
= sae_sm_step(hapd
, sta
, mgmt
->bssid
, auth_transaction
);
961 } else if (auth_transaction
== 2) {
962 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
964 "SAE authentication (RX confirm, status=%u)",
966 if (status_code
!= WLAN_STATUS_SUCCESS
)
968 if (sta
->sae
->state
>= SAE_CONFIRMED
||
969 !(hapd
->conf
->mesh
& MESH_ENABLED
)) {
972 u16 peer_send_confirm
;
974 var
= mgmt
->u
.auth
.variable
;
975 var_len
= ((u8
*) mgmt
) + len
- mgmt
->u
.auth
.variable
;
977 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
981 peer_send_confirm
= WPA_GET_LE16(var
);
983 if (sta
->sae
->state
== SAE_ACCEPTED
&&
984 (peer_send_confirm
<= sta
->sae
->rc
||
985 peer_send_confirm
== 0xffff)) {
986 wpa_printf(MSG_DEBUG
,
987 "SAE: Silently ignore unexpected Confirm from peer "
989 " (peer-send-confirm=%u Rc=%u)",
991 peer_send_confirm
, sta
->sae
->rc
);
995 if (sae_check_confirm(sta
->sae
, var
, var_len
) < 0) {
996 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
999 sta
->sae
->rc
= peer_send_confirm
;
1001 resp
= sae_sm_step(hapd
, sta
, mgmt
->bssid
, auth_transaction
);
1003 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1004 HOSTAPD_LEVEL_DEBUG
,
1005 "unexpected SAE authentication transaction %u (status=%u)",
1006 auth_transaction
, status_code
);
1007 if (status_code
!= WLAN_STATUS_SUCCESS
)
1009 resp
= WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION
;
1013 if (resp
!= WLAN_STATUS_SUCCESS
) {
1014 send_auth_reply(hapd
, mgmt
->sa
, mgmt
->bssid
, WLAN_AUTH_SAE
,
1015 auth_transaction
, resp
,
1016 data
? wpabuf_head(data
) : (u8
*) "",
1017 data
? wpabuf_len(data
) : 0, "auth-sae");
1021 if (sta
->added_unassoc
&& (resp
!= WLAN_STATUS_SUCCESS
||
1022 status_code
!= WLAN_STATUS_SUCCESS
)) {
1023 hostapd_drv_sta_remove(hapd
, sta
->addr
);
1024 sta
->added_unassoc
= 0;
1031 * auth_sae_init_committed - Send COMMIT and start SAE in committed state
1032 * @hapd: BSS data for the device initiating the authentication
1033 * @sta: the peer to which commit authentication frame is sent
1035 * This function implements Init event handling (IEEE Std 802.11-2012,
1036 * 11.3.8.6.3) in which initial COMMIT message is sent. Prior to calling, the
1037 * sta->sae structure should be initialized appropriately via a call to
1038 * sae_prepare_commit().
1040 int auth_sae_init_committed(struct hostapd_data
*hapd
, struct sta_info
*sta
)
1044 if (!sta
->sae
|| !sta
->sae
->tmp
)
1047 if (sta
->sae
->state
!= SAE_NOTHING
)
1050 ret
= auth_sae_send_commit(hapd
, sta
, hapd
->own_addr
, 0);
1054 sae_set_state(sta
, SAE_COMMITTED
, "Init and sent commit");
1056 sae_set_retransmit_timer(hapd
, sta
);
1061 #endif /* CONFIG_SAE */
1064 static u16
wpa_res_to_status_code(int res
)
1066 if (res
== WPA_INVALID_GROUP
)
1067 return WLAN_STATUS_GROUP_CIPHER_NOT_VALID
;
1068 if (res
== WPA_INVALID_PAIRWISE
)
1069 return WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID
;
1070 if (res
== WPA_INVALID_AKMP
)
1071 return WLAN_STATUS_AKMP_NOT_VALID
;
1072 if (res
== WPA_ALLOC_FAIL
)
1073 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
1074 #ifdef CONFIG_IEEE80211W
1075 if (res
== WPA_MGMT_FRAME_PROTECTION_VIOLATION
)
1076 return WLAN_STATUS_ROBUST_MGMT_FRAME_POLICY_VIOLATION
;
1077 if (res
== WPA_INVALID_MGMT_GROUP_CIPHER
)
1078 return WLAN_STATUS_CIPHER_REJECTED_PER_POLICY
;
1079 #endif /* CONFIG_IEEE80211W */
1080 if (res
== WPA_INVALID_MDIE
)
1081 return WLAN_STATUS_INVALID_MDIE
;
1082 if (res
== WPA_INVALID_PMKID
)
1083 return WLAN_STATUS_INVALID_PMKID
;
1084 if (res
!= WPA_IE_OK
)
1085 return WLAN_STATUS_INVALID_IE
;
1086 return WLAN_STATUS_SUCCESS
;
1092 static void handle_auth_fils_finish(struct hostapd_data
*hapd
,
1093 struct sta_info
*sta
, u16 resp
,
1094 struct wpabuf
*data
, int pub
);
1096 void handle_auth_fils(struct hostapd_data
*hapd
, struct sta_info
*sta
,
1097 const u8
*pos
, size_t len
, u16 auth_alg
,
1098 u16 auth_transaction
, u16 status_code
,
1099 void (*cb
)(struct hostapd_data
*hapd
,
1100 struct sta_info
*sta
, u16 resp
,
1101 struct wpabuf
*data
, int pub
))
1103 u16 resp
= WLAN_STATUS_SUCCESS
;
1105 struct ieee802_11_elems elems
;
1107 struct wpa_ie_data rsn
;
1108 struct rsn_pmksa_cache_entry
*pmksa
= NULL
;
1110 if (auth_transaction
!= 1 || status_code
!= WLAN_STATUS_SUCCESS
)
1115 wpa_hexdump(MSG_DEBUG
, "FILS: Authentication frame fields",
1119 #ifdef CONFIG_FILS_SK_PFS
1120 if (auth_alg
== WLAN_AUTH_FILS_SK_PFS
) {
1125 /* Using FILS PFS */
1127 /* Finite Cyclic Group */
1128 if (end
- pos
< 2) {
1129 wpa_printf(MSG_DEBUG
,
1130 "FILS: No room for Finite Cyclic Group");
1131 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1134 group
= WPA_GET_LE16(pos
);
1136 if (group
!= hapd
->conf
->fils_dh_group
) {
1137 wpa_printf(MSG_DEBUG
,
1138 "FILS: Unsupported Finite Cyclic Group: %u (expected %u)",
1139 group
, hapd
->conf
->fils_dh_group
);
1140 resp
= WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED
;
1144 crypto_ecdh_deinit(sta
->fils_ecdh
);
1145 sta
->fils_ecdh
= crypto_ecdh_init(group
);
1146 if (!sta
->fils_ecdh
) {
1147 wpa_printf(MSG_INFO
,
1148 "FILS: Could not initialize ECDH with group %d",
1150 resp
= WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED
;
1154 pub
= crypto_ecdh_get_pubkey(sta
->fils_ecdh
, 1);
1156 wpa_printf(MSG_DEBUG
,
1157 "FILS: Failed to derive ECDH public key");
1158 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1161 elem_len
= wpabuf_len(pub
);
1165 if ((size_t) (end
- pos
) < elem_len
) {
1166 wpa_printf(MSG_DEBUG
, "FILS: No room for Element");
1167 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1171 wpabuf_free(sta
->fils_g_sta
);
1172 sta
->fils_g_sta
= wpabuf_alloc_copy(pos
, elem_len
);
1173 wpabuf_clear_free(sta
->fils_dh_ss
);
1174 sta
->fils_dh_ss
= crypto_ecdh_set_peerkey(sta
->fils_ecdh
, 1,
1176 if (!sta
->fils_dh_ss
) {
1177 wpa_printf(MSG_DEBUG
, "FILS: ECDH operation failed");
1178 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1181 wpa_hexdump_buf_key(MSG_DEBUG
, "FILS: DH_SS", sta
->fils_dh_ss
);
1184 crypto_ecdh_deinit(sta
->fils_ecdh
);
1185 sta
->fils_ecdh
= NULL
;
1186 wpabuf_clear_free(sta
->fils_dh_ss
);
1187 sta
->fils_dh_ss
= NULL
;
1189 #endif /* CONFIG_FILS_SK_PFS */
1191 wpa_hexdump(MSG_DEBUG
, "FILS: Remaining IEs", pos
, end
- pos
);
1192 if (ieee802_11_parse_elems(pos
, end
- pos
, &elems
, 1) == ParseFailed
) {
1193 wpa_printf(MSG_DEBUG
, "FILS: Could not parse elements");
1194 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1199 wpa_hexdump(MSG_DEBUG
, "FILS: RSN element",
1200 elems
.rsn_ie
, elems
.rsn_ie_len
);
1201 if (!elems
.rsn_ie
||
1202 wpa_parse_wpa_ie_rsn(elems
.rsn_ie
- 2, elems
.rsn_ie_len
+ 2,
1204 wpa_printf(MSG_DEBUG
, "FILS: No valid RSN element");
1205 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1210 sta
->wpa_sm
= wpa_auth_sta_init(hapd
->wpa_auth
, sta
->addr
,
1213 wpa_printf(MSG_DEBUG
,
1214 "FILS: Failed to initialize RSN state machine");
1215 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1219 res
= wpa_validate_wpa_ie(hapd
->wpa_auth
, sta
->wpa_sm
,
1220 elems
.rsn_ie
- 2, elems
.rsn_ie_len
+ 2,
1221 elems
.mdie
, elems
.mdie_len
, NULL
, 0);
1222 resp
= wpa_res_to_status_code(res
);
1223 if (resp
!= WLAN_STATUS_SUCCESS
)
1226 if (!elems
.fils_nonce
) {
1227 wpa_printf(MSG_DEBUG
, "FILS: No FILS Nonce field");
1228 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1231 wpa_hexdump(MSG_DEBUG
, "FILS: SNonce", elems
.fils_nonce
,
1233 os_memcpy(sta
->fils_snonce
, elems
.fils_nonce
, FILS_NONCE_LEN
);
1236 if (rsn
.pmkid
&& rsn
.num_pmkid
> 0) {
1240 wpa_hexdump(MSG_DEBUG
, "FILS: PMKID List",
1241 rsn
.pmkid
, rsn
.num_pmkid
* PMKID_LEN
);
1244 num
= rsn
.num_pmkid
;
1246 wpa_hexdump(MSG_DEBUG
, "FILS: PMKID", pmkid
, PMKID_LEN
);
1247 pmksa
= wpa_auth_pmksa_get(hapd
->wpa_auth
, sta
->addr
,
1251 pmksa
= wpa_auth_pmksa_get_fils_cache_id(hapd
->wpa_auth
,
1260 if (pmksa
&& wpa_auth_sta_key_mgmt(sta
->wpa_sm
) != pmksa
->akmp
) {
1261 wpa_printf(MSG_DEBUG
,
1262 "FILS: Matching PMKSA cache entry has different AKMP (0x%x != 0x%x) - ignore",
1263 wpa_auth_sta_key_mgmt(sta
->wpa_sm
), pmksa
->akmp
);
1267 wpa_printf(MSG_DEBUG
, "FILS: Found matching PMKSA cache entry");
1270 if (!elems
.fils_session
) {
1271 wpa_printf(MSG_DEBUG
, "FILS: No FILS Session element");
1272 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1275 wpa_hexdump(MSG_DEBUG
, "FILS: FILS Session", elems
.fils_session
,
1277 os_memcpy(sta
->fils_session
, elems
.fils_session
, FILS_SESSION_LEN
);
1279 /* FILS Wrapped Data */
1280 if (elems
.fils_wrapped_data
) {
1281 wpa_hexdump(MSG_DEBUG
, "FILS: Wrapped Data",
1282 elems
.fils_wrapped_data
,
1283 elems
.fils_wrapped_data_len
);
1285 #ifndef CONFIG_NO_RADIUS
1286 if (!sta
->eapol_sm
) {
1288 ieee802_1x_alloc_eapol_sm(hapd
, sta
);
1290 wpa_printf(MSG_DEBUG
,
1291 "FILS: Forward EAP-Initiate/Re-auth to authentication server");
1292 ieee802_1x_encapsulate_radius(
1293 hapd
, sta
, elems
.fils_wrapped_data
,
1294 elems
.fils_wrapped_data_len
);
1295 sta
->fils_pending_cb
= cb
;
1296 wpa_printf(MSG_DEBUG
,
1297 "FILS: Will send Authentication frame once the response from authentication server is available");
1298 sta
->flags
|= WLAN_STA_PENDING_FILS_ERP
;
1299 /* Calculate pending PMKID here so that we do not need
1300 * to maintain a copy of the EAP-Initiate/Reauth
1302 if (fils_pmkid_erp(wpa_auth_sta_key_mgmt(sta
->wpa_sm
),
1303 elems
.fils_wrapped_data
,
1304 elems
.fils_wrapped_data_len
,
1305 sta
->fils_erp_pmkid
) == 0)
1306 sta
->fils_erp_pmkid_set
= 1;
1308 #else /* CONFIG_NO_RADIUS */
1309 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1311 #endif /* CONFIG_NO_RADIUS */
1317 struct wpabuf
*data
;
1320 data
= prepare_auth_resp_fils(hapd
, sta
, &resp
, pmksa
, NULL
,
1323 wpa_printf(MSG_DEBUG
,
1324 "%s: prepare_auth_resp_fils() returned failure",
1328 cb(hapd
, sta
, resp
, data
, pub
);
1333 static struct wpabuf
*
1334 prepare_auth_resp_fils(struct hostapd_data
*hapd
,
1335 struct sta_info
*sta
, u16
*resp
,
1336 struct rsn_pmksa_cache_entry
*pmksa
,
1337 struct wpabuf
*erp_resp
,
1338 const u8
*msk
, size_t msk_len
,
1341 u8 fils_nonce
[FILS_NONCE_LEN
];
1343 struct wpabuf
*data
= NULL
;
1346 const u8
*pmk
= NULL
;
1348 u8 pmk_buf
[PMK_LEN_MAX
];
1349 struct wpabuf
*pub
= NULL
;
1351 if (*resp
!= WLAN_STATUS_SUCCESS
)
1354 ie
= wpa_auth_get_wpa_ie(hapd
->wpa_auth
, &ielen
);
1356 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1361 /* Add PMKID of the selected PMKSA into RSNE */
1362 ie_buf
= os_malloc(ielen
+ 2 + 2 + PMKID_LEN
);
1364 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1368 os_memcpy(ie_buf
, ie
, ielen
);
1369 if (wpa_insert_pmkid(ie_buf
, &ielen
, pmksa
->pmkid
) < 0) {
1370 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1376 if (random_get_bytes(fils_nonce
, FILS_NONCE_LEN
) < 0) {
1377 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1380 wpa_hexdump(MSG_DEBUG
, "RSN: Generated FILS Nonce",
1381 fils_nonce
, FILS_NONCE_LEN
);
1383 #ifdef CONFIG_FILS_SK_PFS
1384 if (sta
->fils_dh_ss
&& sta
->fils_ecdh
) {
1385 pub
= crypto_ecdh_get_pubkey(sta
->fils_ecdh
, 1);
1387 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1391 #endif /* CONFIG_FILS_SK_PFS */
1393 data
= wpabuf_alloc(1000 + ielen
+ (pub
? wpabuf_len(pub
) : 0));
1395 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1400 #ifdef CONFIG_FILS_SK_PFS
1402 /* Finite Cyclic Group */
1403 wpabuf_put_le16(data
, hapd
->conf
->fils_dh_group
);
1406 wpabuf_put_buf(data
, pub
);
1408 #endif /* CONFIG_FILS_SK_PFS */
1411 wpabuf_put_data(data
, ie
, ielen
);
1413 /* MDE when using FILS+FT (already included in ie,ielen with RSNE) */
1415 #ifdef CONFIG_IEEE80211R_AP
1416 if (wpa_key_mgmt_ft(wpa_auth_sta_key_mgmt(sta
->wpa_sm
))) {
1417 /* FTE[R1KH-ID,R0KH-ID] when using FILS+FT */
1420 res
= wpa_auth_write_fte(hapd
->wpa_auth
, wpabuf_put(data
, 0),
1421 wpabuf_tailroom(data
));
1423 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1426 wpabuf_put(data
, res
);
1428 #endif /* CONFIG_IEEE80211R_AP */
1431 wpabuf_put_u8(data
, WLAN_EID_EXTENSION
); /* Element ID */
1432 wpabuf_put_u8(data
, 1 + FILS_NONCE_LEN
); /* Length */
1433 /* Element ID Extension */
1434 wpabuf_put_u8(data
, WLAN_EID_EXT_FILS_NONCE
);
1435 wpabuf_put_data(data
, fils_nonce
, FILS_NONCE_LEN
);
1438 wpabuf_put_u8(data
, WLAN_EID_EXTENSION
); /* Element ID */
1439 wpabuf_put_u8(data
, 1 + FILS_SESSION_LEN
); /* Length */
1440 /* Element ID Extension */
1441 wpabuf_put_u8(data
, WLAN_EID_EXT_FILS_SESSION
);
1442 wpabuf_put_data(data
, sta
->fils_session
, FILS_SESSION_LEN
);
1444 /* FILS Wrapped Data */
1445 if (!pmksa
&& erp_resp
) {
1446 wpabuf_put_u8(data
, WLAN_EID_EXTENSION
); /* Element ID */
1447 wpabuf_put_u8(data
, 1 + wpabuf_len(erp_resp
)); /* Length */
1448 /* Element ID Extension */
1449 wpabuf_put_u8(data
, WLAN_EID_EXT_FILS_WRAPPED_DATA
);
1450 wpabuf_put_buf(data
, erp_resp
);
1452 if (fils_rmsk_to_pmk(wpa_auth_sta_key_mgmt(sta
->wpa_sm
),
1453 msk
, msk_len
, sta
->fils_snonce
, fils_nonce
,
1455 wpabuf_head(sta
->fils_dh_ss
) : NULL
,
1457 wpabuf_len(sta
->fils_dh_ss
) : 0,
1458 pmk_buf
, &pmk_len
)) {
1459 wpa_printf(MSG_DEBUG
, "FILS: Failed to derive PMK");
1460 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1467 /* Don't use DHss in PTK derivation if PMKSA caching is not
1469 wpabuf_clear_free(sta
->fils_dh_ss
);
1470 sta
->fils_dh_ss
= NULL
;
1472 if (sta
->fils_erp_pmkid_set
) {
1473 /* TODO: get PMKLifetime from WPA parameters */
1474 unsigned int dot11RSNAConfigPMKLifetime
= 43200;
1476 sta
->fils_erp_pmkid_set
= 0;
1477 if (wpa_auth_pmksa_add2(
1478 hapd
->wpa_auth
, sta
->addr
,
1480 sta
->fils_erp_pmkid
,
1481 sta
->session_timeout_set
?
1482 sta
->session_timeout
:
1483 dot11RSNAConfigPMKLifetime
,
1484 wpa_auth_sta_key_mgmt(sta
->wpa_sm
)) < 0) {
1485 wpa_printf(MSG_ERROR
,
1486 "FILS: Failed to add PMKSA cache entry based on ERP");
1491 pmk_len
= pmksa
->pmk_len
;
1495 wpa_printf(MSG_DEBUG
, "FILS: No PMK available");
1496 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1502 if (fils_auth_pmk_to_ptk(sta
->wpa_sm
, pmk
, pmk_len
,
1503 sta
->fils_snonce
, fils_nonce
,
1505 wpabuf_head(sta
->fils_dh_ss
) : NULL
,
1507 wpabuf_len(sta
->fils_dh_ss
) : 0,
1508 sta
->fils_g_sta
, pub
) < 0) {
1509 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1517 *is_pub
= pub
!= NULL
;
1520 wpabuf_clear_free(sta
->fils_dh_ss
);
1521 sta
->fils_dh_ss
= NULL
;
1522 #ifdef CONFIG_FILS_SK_PFS
1523 crypto_ecdh_deinit(sta
->fils_ecdh
);
1524 sta
->fils_ecdh
= NULL
;
1525 #endif /* CONFIG_FILS_SK_PFS */
1530 static void handle_auth_fils_finish(struct hostapd_data
*hapd
,
1531 struct sta_info
*sta
, u16 resp
,
1532 struct wpabuf
*data
, int pub
)
1537 resp
== WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED
) ?
1538 WLAN_AUTH_FILS_SK_PFS
: WLAN_AUTH_FILS_SK
;
1539 send_auth_reply(hapd
, sta
->addr
, hapd
->own_addr
, auth_alg
, 2, resp
,
1540 data
? wpabuf_head(data
) : (u8
*) "",
1541 data
? wpabuf_len(data
) : 0, "auth-fils-finish");
1544 if (resp
== WLAN_STATUS_SUCCESS
) {
1545 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1546 HOSTAPD_LEVEL_DEBUG
,
1547 "authentication OK (FILS)");
1548 sta
->flags
|= WLAN_STA_AUTH
;
1549 wpa_auth_sm_event(sta
->wpa_sm
, WPA_AUTH
);
1550 sta
->auth_alg
= pub
? WLAN_AUTH_FILS_SK_PFS
: WLAN_AUTH_FILS_SK
;
1551 mlme_authenticate_indication(hapd
, sta
);
1556 void ieee802_11_finish_fils_auth(struct hostapd_data
*hapd
,
1557 struct sta_info
*sta
, int success
,
1558 struct wpabuf
*erp_resp
,
1559 const u8
*msk
, size_t msk_len
)
1561 struct wpabuf
*data
;
1565 sta
->flags
&= ~WLAN_STA_PENDING_FILS_ERP
;
1567 if (!sta
->fils_pending_cb
)
1569 resp
= success
? WLAN_STATUS_SUCCESS
: WLAN_STATUS_UNSPECIFIED_FAILURE
;
1570 data
= prepare_auth_resp_fils(hapd
, sta
, &resp
, NULL
, erp_resp
,
1571 msk
, msk_len
, &pub
);
1573 wpa_printf(MSG_DEBUG
,
1574 "%s: prepare_auth_resp_fils() returned failure",
1577 sta
->fils_pending_cb(hapd
, sta
, resp
, data
, pub
);
1580 #endif /* CONFIG_FILS */
1584 ieee802_11_allowed_address(struct hostapd_data
*hapd
, const u8
*addr
,
1585 const u8
*msg
, size_t len
, u32
*session_timeout
,
1586 u32
*acct_interim_interval
,
1587 struct vlan_description
*vlan_id
,
1588 struct hostapd_sta_wpa_psk_short
**psk
,
1589 char **identity
, char **radius_cui
, int is_probe_req
)
1593 os_memset(vlan_id
, 0, sizeof(*vlan_id
));
1594 res
= hostapd_allowed_address(hapd
, addr
, msg
, len
,
1595 session_timeout
, acct_interim_interval
,
1596 vlan_id
, psk
, identity
, radius_cui
,
1599 if (res
== HOSTAPD_ACL_REJECT
) {
1600 wpa_printf(MSG_INFO
,
1601 "Station " MACSTR
" not allowed to authenticate",
1603 return HOSTAPD_ACL_REJECT
;
1606 if (res
== HOSTAPD_ACL_PENDING
) {
1607 wpa_printf(MSG_DEBUG
, "Authentication frame from " MACSTR
1608 " waiting for an external authentication",
1610 /* Authentication code will re-send the authentication frame
1611 * after it has received (and cached) information from the
1612 * external source. */
1613 return HOSTAPD_ACL_PENDING
;
1621 ieee802_11_set_radius_info(struct hostapd_data
*hapd
, struct sta_info
*sta
,
1622 int res
, u32 session_timeout
,
1623 u32 acct_interim_interval
,
1624 struct vlan_description
*vlan_id
,
1625 struct hostapd_sta_wpa_psk_short
**psk
,
1626 char **identity
, char **radius_cui
)
1628 if (vlan_id
->notempty
&&
1629 !hostapd_vlan_valid(hapd
->conf
->vlan
, vlan_id
)) {
1630 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_RADIUS
,
1632 "Invalid VLAN %d%s received from RADIUS server",
1634 vlan_id
->tagged
[0] ? "+" : "");
1637 if (ap_sta_set_vlan(hapd
, sta
, vlan_id
) < 0)
1640 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_RADIUS
,
1641 HOSTAPD_LEVEL_INFO
, "VLAN ID %d", sta
->vlan_id
);
1643 hostapd_free_psk_list(sta
->psk
);
1644 if (hapd
->conf
->wpa_psk_radius
!= PSK_RADIUS_IGNORED
) {
1651 sta
->identity
= *identity
;
1653 sta
->radius_cui
= *radius_cui
;
1656 if (hapd
->conf
->acct_interim_interval
== 0 && acct_interim_interval
)
1657 sta
->acct_interim_interval
= acct_interim_interval
;
1658 if (res
== HOSTAPD_ACL_ACCEPT_TIMEOUT
)
1659 ap_sta_session_timeout(hapd
, sta
, session_timeout
);
1661 ap_sta_no_session_timeout(hapd
, sta
);
1667 static void handle_auth(struct hostapd_data
*hapd
,
1668 const struct ieee80211_mgmt
*mgmt
, size_t len
)
1670 u16 auth_alg
, auth_transaction
, status_code
;
1671 u16 resp
= WLAN_STATUS_SUCCESS
;
1672 struct sta_info
*sta
= NULL
;
1675 const u8
*challenge
= NULL
;
1676 u32 session_timeout
, acct_interim_interval
;
1677 struct vlan_description vlan_id
;
1678 struct hostapd_sta_wpa_psk_short
*psk
= NULL
;
1679 u8 resp_ies
[2 + WLAN_AUTH_CHALLENGE_LEN
];
1680 size_t resp_ies_len
= 0;
1681 char *identity
= NULL
;
1682 char *radius_cui
= NULL
;
1685 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.auth
)) {
1686 wpa_printf(MSG_INFO
, "handle_auth - too short payload (len=%lu)",
1687 (unsigned long) len
);
1691 #ifdef CONFIG_TESTING_OPTIONS
1692 if (hapd
->iconf
->ignore_auth_probability
> 0.0 &&
1693 drand48() < hapd
->iconf
->ignore_auth_probability
) {
1694 wpa_printf(MSG_INFO
,
1695 "TESTING: ignoring auth frame from " MACSTR
,
1699 #endif /* CONFIG_TESTING_OPTIONS */
1701 auth_alg
= le_to_host16(mgmt
->u
.auth
.auth_alg
);
1702 auth_transaction
= le_to_host16(mgmt
->u
.auth
.auth_transaction
);
1703 status_code
= le_to_host16(mgmt
->u
.auth
.status_code
);
1704 fc
= le_to_host16(mgmt
->frame_control
);
1705 seq_ctrl
= le_to_host16(mgmt
->seq_ctrl
);
1707 if (len
>= IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.auth
) +
1708 2 + WLAN_AUTH_CHALLENGE_LEN
&&
1709 mgmt
->u
.auth
.variable
[0] == WLAN_EID_CHALLENGE
&&
1710 mgmt
->u
.auth
.variable
[1] == WLAN_AUTH_CHALLENGE_LEN
)
1711 challenge
= &mgmt
->u
.auth
.variable
[2];
1713 wpa_printf(MSG_DEBUG
, "authentication: STA=" MACSTR
" auth_alg=%d "
1714 "auth_transaction=%d status_code=%d wep=%d%s "
1716 MAC2STR(mgmt
->sa
), auth_alg
, auth_transaction
,
1717 status_code
, !!(fc
& WLAN_FC_ISWEP
),
1718 challenge
? " challenge" : "",
1719 seq_ctrl
, (fc
& WLAN_FC_RETRY
) ? " retry" : "");
1721 #ifdef CONFIG_NO_RC4
1722 if (auth_alg
== WLAN_AUTH_SHARED_KEY
) {
1723 wpa_printf(MSG_INFO
,
1724 "Unsupported authentication algorithm (%d)",
1726 resp
= WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG
;
1729 #endif /* CONFIG_NO_RC4 */
1731 if (hapd
->tkip_countermeasures
) {
1732 wpa_printf(MSG_DEBUG
,
1733 "Ongoing TKIP countermeasures (Michael MIC failure) - reject authentication");
1734 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1738 if (!(((hapd
->conf
->auth_algs
& WPA_AUTH_ALG_OPEN
) &&
1739 auth_alg
== WLAN_AUTH_OPEN
) ||
1740 #ifdef CONFIG_IEEE80211R_AP
1741 (hapd
->conf
->wpa
&& wpa_key_mgmt_ft(hapd
->conf
->wpa_key_mgmt
) &&
1742 auth_alg
== WLAN_AUTH_FT
) ||
1743 #endif /* CONFIG_IEEE80211R_AP */
1745 (hapd
->conf
->wpa
&& wpa_key_mgmt_sae(hapd
->conf
->wpa_key_mgmt
) &&
1746 auth_alg
== WLAN_AUTH_SAE
) ||
1747 #endif /* CONFIG_SAE */
1749 (hapd
->conf
->wpa
&& wpa_key_mgmt_fils(hapd
->conf
->wpa_key_mgmt
) &&
1750 auth_alg
== WLAN_AUTH_FILS_SK
) ||
1751 (hapd
->conf
->wpa
&& wpa_key_mgmt_fils(hapd
->conf
->wpa_key_mgmt
) &&
1752 hapd
->conf
->fils_dh_group
&&
1753 auth_alg
== WLAN_AUTH_FILS_SK_PFS
) ||
1754 #endif /* CONFIG_FILS */
1755 ((hapd
->conf
->auth_algs
& WPA_AUTH_ALG_SHARED
) &&
1756 auth_alg
== WLAN_AUTH_SHARED_KEY
))) {
1757 wpa_printf(MSG_INFO
, "Unsupported authentication algorithm (%d)",
1759 resp
= WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG
;
1763 if (!(auth_transaction
== 1 || auth_alg
== WLAN_AUTH_SAE
||
1764 (auth_alg
== WLAN_AUTH_SHARED_KEY
&& auth_transaction
== 3))) {
1765 wpa_printf(MSG_INFO
, "Unknown authentication transaction number (%d)",
1767 resp
= WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION
;
1771 if (os_memcmp(mgmt
->sa
, hapd
->own_addr
, ETH_ALEN
) == 0) {
1772 wpa_printf(MSG_INFO
, "Station " MACSTR
" not allowed to authenticate",
1774 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1778 if (hapd
->conf
->no_auth_if_seen_on
) {
1779 struct hostapd_data
*other
;
1781 other
= sta_track_seen_on(hapd
->iface
, mgmt
->sa
,
1782 hapd
->conf
->no_auth_if_seen_on
);
1786 u8 op_class
, channel
, phytype
;
1788 wpa_printf(MSG_DEBUG
, "%s: Reject authentication from "
1789 MACSTR
" since STA has been seen on %s",
1790 hapd
->conf
->iface
, MAC2STR(mgmt
->sa
),
1791 hapd
->conf
->no_auth_if_seen_on
);
1793 resp
= WLAN_STATUS_REJECTED_WITH_SUGGESTED_BSS_TRANSITION
;
1795 *pos
++ = WLAN_EID_NEIGHBOR_REPORT
;
1797 os_memcpy(pos
, other
->own_addr
, ETH_ALEN
);
1799 info
= 0; /* TODO: BSSID Information */
1800 WPA_PUT_LE32(pos
, info
);
1802 if (other
->iconf
->hw_mode
== HOSTAPD_MODE_IEEE80211AD
)
1803 phytype
= 8; /* dmg */
1804 else if (other
->iconf
->ieee80211ac
)
1805 phytype
= 9; /* vht */
1806 else if (other
->iconf
->ieee80211n
)
1807 phytype
= 7; /* ht */
1808 else if (other
->iconf
->hw_mode
==
1809 HOSTAPD_MODE_IEEE80211A
)
1810 phytype
= 4; /* ofdm */
1811 else if (other
->iconf
->hw_mode
==
1812 HOSTAPD_MODE_IEEE80211G
)
1813 phytype
= 6; /* erp */
1815 phytype
= 5; /* hrdsss */
1816 if (ieee80211_freq_to_channel_ext(
1817 hostapd_hw_get_freq(other
,
1818 other
->iconf
->channel
),
1819 other
->iconf
->secondary_channel
,
1820 other
->iconf
->ieee80211ac
,
1821 &op_class
, &channel
) == NUM_HOSTAPD_MODES
) {
1823 channel
= other
->iconf
->channel
;
1828 resp_ies_len
= pos
- &resp_ies
[0];
1833 res
= ieee802_11_allowed_address(
1834 hapd
, mgmt
->sa
, (const u8
*) mgmt
, len
, &session_timeout
,
1835 &acct_interim_interval
, &vlan_id
, &psk
, &identity
, &radius_cui
,
1837 if (res
== HOSTAPD_ACL_REJECT
) {
1838 wpa_msg(hapd
->msg_ctx
, MSG_DEBUG
,
1839 "Ignore Authentication frame from " MACSTR
1840 " due to ACL reject", MAC2STR(mgmt
->sa
));
1841 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1844 if (res
== HOSTAPD_ACL_PENDING
)
1847 sta
= ap_get_sta(hapd
, mgmt
->sa
);
1849 sta
->flags
&= ~WLAN_STA_PENDING_FILS_ERP
;
1850 if ((fc
& WLAN_FC_RETRY
) &&
1851 sta
->last_seq_ctrl
!= WLAN_INVALID_MGMT_SEQ
&&
1852 sta
->last_seq_ctrl
== seq_ctrl
&&
1853 sta
->last_subtype
== WLAN_FC_STYPE_AUTH
) {
1854 hostapd_logger(hapd
, sta
->addr
,
1855 HOSTAPD_MODULE_IEEE80211
,
1856 HOSTAPD_LEVEL_DEBUG
,
1857 "Drop repeated authentication frame seq_ctrl=0x%x",
1862 if ((hapd
->conf
->mesh
& MESH_ENABLED
) &&
1863 sta
->plink_state
== PLINK_BLOCKED
) {
1864 wpa_printf(MSG_DEBUG
, "Mesh peer " MACSTR
1865 " is blocked - drop Authentication frame",
1869 #endif /* CONFIG_MESH */
1872 if (hapd
->conf
->mesh
& MESH_ENABLED
) {
1873 /* if the mesh peer is not available, we don't do auth.
1875 wpa_printf(MSG_DEBUG
, "Mesh peer " MACSTR
1876 " not yet known - drop Authentication frame",
1879 * Save a copy of the frame so that it can be processed
1880 * if a new peer entry is added shortly after this.
1882 wpabuf_free(hapd
->mesh_pending_auth
);
1883 hapd
->mesh_pending_auth
= wpabuf_alloc_copy(mgmt
, len
);
1884 os_get_reltime(&hapd
->mesh_pending_auth_time
);
1887 #endif /* CONFIG_MESH */
1889 sta
= ap_sta_add(hapd
, mgmt
->sa
);
1891 wpa_printf(MSG_DEBUG
, "ap_sta_add() failed");
1892 resp
= WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
;
1896 sta
->last_seq_ctrl
= seq_ctrl
;
1897 sta
->last_subtype
= WLAN_FC_STYPE_AUTH
;
1899 res
= ieee802_11_set_radius_info(
1900 hapd
, sta
, res
, session_timeout
, acct_interim_interval
,
1901 &vlan_id
, &psk
, &identity
, &radius_cui
);
1903 wpa_printf(MSG_DEBUG
, "ieee802_11_set_radius_info() failed");
1904 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1908 sta
->flags
&= ~WLAN_STA_PREAUTH
;
1909 ieee802_1x_notify_pre_auth(sta
->eapol_sm
, 0);
1912 * If the driver supports full AP client state, add a station to the
1913 * driver before sending authentication reply to make sure the driver
1914 * has resources, and not to go through the entire authentication and
1915 * association handshake, and fail it at the end.
1917 * If this is not the first transaction, in a multi-step authentication
1918 * algorithm, the station already exists in the driver
1919 * (sta->added_unassoc = 1) so skip it.
1921 * In mesh mode, the station was already added to the driver when the
1922 * NEW_PEER_CANDIDATE event is received.
1924 * If PMF was negotiated for the existing association, skip this to
1925 * avoid dropping the STA entry and the associated keys. This is needed
1926 * to allow the original connection work until the attempt can complete
1927 * (re)association, so that unprotected Authentication frame cannot be
1928 * used to bypass PMF protection.
1930 if (FULL_AP_CLIENT_STATE_SUPP(hapd
->iface
->drv_flags
) &&
1931 (!(sta
->flags
& WLAN_STA_MFP
) || !ap_sta_is_authorized(sta
)) &&
1932 !(hapd
->conf
->mesh
& MESH_ENABLED
) &&
1933 !(sta
->added_unassoc
)) {
1935 * If a station that is already associated to the AP, is trying
1936 * to authenticate again, remove the STA entry, in order to make
1937 * sure the STA PS state gets cleared and configuration gets
1938 * updated. To handle this, station's added_unassoc flag is
1939 * cleared once the station has completed association.
1941 hostapd_drv_sta_remove(hapd
, sta
->addr
);
1942 sta
->flags
&= ~(WLAN_STA_ASSOC
| WLAN_STA_AUTH
|
1943 WLAN_STA_AUTHORIZED
);
1945 if (hostapd_sta_add(hapd
, sta
->addr
, 0, 0, NULL
, 0, 0,
1946 NULL
, NULL
, sta
->flags
, 0, 0, 0, 0)) {
1947 hostapd_logger(hapd
, sta
->addr
,
1948 HOSTAPD_MODULE_IEEE80211
,
1949 HOSTAPD_LEVEL_NOTICE
,
1950 "Could not add STA to kernel driver");
1951 resp
= WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
;
1955 sta
->added_unassoc
= 1;
1959 case WLAN_AUTH_OPEN
:
1960 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1961 HOSTAPD_LEVEL_DEBUG
,
1962 "authentication OK (open system)");
1963 sta
->flags
|= WLAN_STA_AUTH
;
1964 wpa_auth_sm_event(sta
->wpa_sm
, WPA_AUTH
);
1965 sta
->auth_alg
= WLAN_AUTH_OPEN
;
1966 mlme_authenticate_indication(hapd
, sta
);
1968 #ifndef CONFIG_NO_RC4
1969 case WLAN_AUTH_SHARED_KEY
:
1970 resp
= auth_shared_key(hapd
, sta
, auth_transaction
, challenge
,
1971 fc
& WLAN_FC_ISWEP
);
1973 wpa_printf(MSG_DEBUG
,
1974 "auth_shared_key() failed: status=%d", resp
);
1975 sta
->auth_alg
= WLAN_AUTH_SHARED_KEY
;
1976 mlme_authenticate_indication(hapd
, sta
);
1977 if (sta
->challenge
&& auth_transaction
== 1) {
1978 resp_ies
[0] = WLAN_EID_CHALLENGE
;
1979 resp_ies
[1] = WLAN_AUTH_CHALLENGE_LEN
;
1980 os_memcpy(resp_ies
+ 2, sta
->challenge
,
1981 WLAN_AUTH_CHALLENGE_LEN
);
1982 resp_ies_len
= 2 + WLAN_AUTH_CHALLENGE_LEN
;
1985 #endif /* CONFIG_NO_RC4 */
1986 #ifdef CONFIG_IEEE80211R_AP
1988 sta
->auth_alg
= WLAN_AUTH_FT
;
1989 if (sta
->wpa_sm
== NULL
)
1990 sta
->wpa_sm
= wpa_auth_sta_init(hapd
->wpa_auth
,
1992 if (sta
->wpa_sm
== NULL
) {
1993 wpa_printf(MSG_DEBUG
, "FT: Failed to initialize WPA "
1995 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1998 wpa_ft_process_auth(sta
->wpa_sm
, mgmt
->bssid
,
1999 auth_transaction
, mgmt
->u
.auth
.variable
,
2000 len
- IEEE80211_HDRLEN
-
2001 sizeof(mgmt
->u
.auth
),
2002 handle_auth_ft_finish
, hapd
);
2003 /* handle_auth_ft_finish() callback will complete auth. */
2005 #endif /* CONFIG_IEEE80211R_AP */
2009 if (status_code
== WLAN_STATUS_SUCCESS
&&
2010 hapd
->conf
->mesh
& MESH_ENABLED
) {
2011 if (sta
->wpa_sm
== NULL
)
2013 wpa_auth_sta_init(hapd
->wpa_auth
,
2015 if (sta
->wpa_sm
== NULL
) {
2016 wpa_printf(MSG_DEBUG
,
2017 "SAE: Failed to initialize WPA state machine");
2018 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
2022 #endif /* CONFIG_MESH */
2023 handle_auth_sae(hapd
, sta
, mgmt
, len
, auth_transaction
,
2026 #endif /* CONFIG_SAE */
2028 case WLAN_AUTH_FILS_SK
:
2029 case WLAN_AUTH_FILS_SK_PFS
:
2030 handle_auth_fils(hapd
, sta
, mgmt
->u
.auth
.variable
,
2031 len
- IEEE80211_HDRLEN
- sizeof(mgmt
->u
.auth
),
2032 auth_alg
, auth_transaction
, status_code
,
2033 handle_auth_fils_finish
);
2035 #endif /* CONFIG_FILS */
2040 os_free(radius_cui
);
2041 hostapd_free_psk_list(psk
);
2043 reply_res
= send_auth_reply(hapd
, mgmt
->sa
, mgmt
->bssid
, auth_alg
,
2044 auth_transaction
+ 1, resp
, resp_ies
,
2045 resp_ies_len
, "handle-auth");
2047 if (sta
&& sta
->added_unassoc
&& (resp
!= WLAN_STATUS_SUCCESS
||
2048 reply_res
!= WLAN_STATUS_SUCCESS
)) {
2049 hostapd_drv_sta_remove(hapd
, sta
->addr
);
2050 sta
->added_unassoc
= 0;
2055 int hostapd_get_aid(struct hostapd_data
*hapd
, struct sta_info
*sta
)
2059 /* get a unique AID */
2061 wpa_printf(MSG_DEBUG
, " old AID %d", sta
->aid
);
2068 for (i
= 0; i
< AID_WORDS
; i
++) {
2069 if (hapd
->sta_aid
[i
] == (u32
) -1)
2071 for (j
= 0; j
< 32; j
++) {
2072 if (!(hapd
->sta_aid
[i
] & BIT(j
)))
2080 aid
= i
* 32 + j
+ 1;
2085 hapd
->sta_aid
[i
] |= BIT(j
);
2086 wpa_printf(MSG_DEBUG
, " new AID %d", sta
->aid
);
2091 static u16
check_ssid(struct hostapd_data
*hapd
, struct sta_info
*sta
,
2092 const u8
*ssid_ie
, size_t ssid_ie_len
)
2094 if (ssid_ie
== NULL
)
2095 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2097 if (ssid_ie_len
!= hapd
->conf
->ssid
.ssid_len
||
2098 os_memcmp(ssid_ie
, hapd
->conf
->ssid
.ssid
, ssid_ie_len
) != 0) {
2099 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
2101 "Station tried to associate with unknown SSID "
2102 "'%s'", wpa_ssid_txt(ssid_ie
, ssid_ie_len
));
2103 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2106 return WLAN_STATUS_SUCCESS
;
2110 static u16
check_wmm(struct hostapd_data
*hapd
, struct sta_info
*sta
,
2111 const u8
*wmm_ie
, size_t wmm_ie_len
)
2113 sta
->flags
&= ~WLAN_STA_WMM
;
2115 if (wmm_ie
&& hapd
->conf
->wmm_enabled
) {
2116 struct wmm_information_element
*wmm
;
2118 if (!hostapd_eid_wmm_valid(hapd
, wmm_ie
, wmm_ie_len
)) {
2119 hostapd_logger(hapd
, sta
->addr
,
2121 HOSTAPD_LEVEL_DEBUG
,
2122 "invalid WMM element in association "
2124 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2127 sta
->flags
|= WLAN_STA_WMM
;
2128 wmm
= (struct wmm_information_element
*) wmm_ie
;
2129 sta
->qosinfo
= wmm
->qos_info
;
2131 return WLAN_STATUS_SUCCESS
;
2135 static u16
copy_supp_rates(struct hostapd_data
*hapd
, struct sta_info
*sta
,
2136 struct ieee802_11_elems
*elems
)
2138 /* Supported rates not used in IEEE 802.11ad/DMG */
2139 if (hapd
->iface
->current_mode
&&
2140 hapd
->iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211AD
)
2141 return WLAN_STATUS_SUCCESS
;
2143 if (!elems
->supp_rates
) {
2144 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
2145 HOSTAPD_LEVEL_DEBUG
,
2146 "No supported rates element in AssocReq");
2147 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2150 if (elems
->supp_rates_len
+ elems
->ext_supp_rates_len
>
2151 sizeof(sta
->supported_rates
)) {
2152 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
2153 HOSTAPD_LEVEL_DEBUG
,
2154 "Invalid supported rates element length %d+%d",
2155 elems
->supp_rates_len
,
2156 elems
->ext_supp_rates_len
);
2157 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2160 sta
->supported_rates_len
= merge_byte_arrays(
2161 sta
->supported_rates
, sizeof(sta
->supported_rates
),
2162 elems
->supp_rates
, elems
->supp_rates_len
,
2163 elems
->ext_supp_rates
, elems
->ext_supp_rates_len
);
2165 return WLAN_STATUS_SUCCESS
;
2169 static u16
check_ext_capab(struct hostapd_data
*hapd
, struct sta_info
*sta
,
2170 const u8
*ext_capab_ie
, size_t ext_capab_ie_len
)
2172 #ifdef CONFIG_INTERWORKING
2173 /* check for QoS Map support */
2174 if (ext_capab_ie_len
>= 5) {
2175 if (ext_capab_ie
[4] & 0x01)
2176 sta
->qos_map_enabled
= 1;
2178 #endif /* CONFIG_INTERWORKING */
2180 if (ext_capab_ie_len
> 0) {
2181 sta
->ecsa_supported
= !!(ext_capab_ie
[0] & BIT(2));
2182 os_free(sta
->ext_capability
);
2183 sta
->ext_capability
= os_malloc(1 + ext_capab_ie_len
);
2184 if (sta
->ext_capability
) {
2185 sta
->ext_capability
[0] = ext_capab_ie_len
;
2186 os_memcpy(sta
->ext_capability
+ 1, ext_capab_ie
,
2191 return WLAN_STATUS_SUCCESS
;
2197 static int owe_group_supported(struct hostapd_data
*hapd
, u16 group
)
2200 int *groups
= hapd
->conf
->owe_groups
;
2202 if (group
!= 19 && group
!= 20 && group
!= 21)
2208 for (i
= 0; groups
[i
] > 0; i
++) {
2209 if (groups
[i
] == group
)
2217 static u16
owe_process_assoc_req(struct hostapd_data
*hapd
,
2218 struct sta_info
*sta
, const u8
*owe_dh
,
2221 struct wpabuf
*secret
, *pub
, *hkey
;
2223 u8 prk
[SHA512_MAC_LEN
], pmkid
[SHA512_MAC_LEN
];
2224 const char *info
= "OWE Key Generation";
2228 size_t hash_len
, prime_len
;
2230 if (wpa_auth_sta_get_pmksa(sta
->wpa_sm
)) {
2231 wpa_printf(MSG_DEBUG
, "OWE: Using PMKSA caching");
2232 return WLAN_STATUS_SUCCESS
;
2235 group
= WPA_GET_LE16(owe_dh
);
2236 if (!owe_group_supported(hapd
, group
)) {
2237 wpa_printf(MSG_DEBUG
, "OWE: Unsupported DH group %u", group
);
2238 return WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED
;
2242 else if (group
== 20)
2244 else if (group
== 21)
2247 return WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED
;
2249 crypto_ecdh_deinit(sta
->owe_ecdh
);
2250 sta
->owe_ecdh
= crypto_ecdh_init(group
);
2252 return WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED
;
2253 sta
->owe_group
= group
;
2255 secret
= crypto_ecdh_set_peerkey(sta
->owe_ecdh
, 0, owe_dh
+ 2,
2257 secret
= wpabuf_zeropad(secret
, prime_len
);
2259 wpa_printf(MSG_DEBUG
, "OWE: Invalid peer DH public key");
2260 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2262 wpa_hexdump_buf_key(MSG_DEBUG
, "OWE: DH shared secret", secret
);
2264 /* prk = HKDF-extract(C | A | group, z) */
2266 pub
= crypto_ecdh_get_pubkey(sta
->owe_ecdh
, 0);
2268 wpabuf_clear_free(secret
);
2269 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2272 /* PMKID = Truncate-128(Hash(C | A)) */
2273 addr
[0] = owe_dh
+ 2;
2274 len
[0] = owe_dh_len
- 2;
2275 addr
[1] = wpabuf_head(pub
);
2276 len
[1] = wpabuf_len(pub
);
2278 res
= sha256_vector(2, addr
, len
, pmkid
);
2279 hash_len
= SHA256_MAC_LEN
;
2280 } else if (group
== 20) {
2281 res
= sha384_vector(2, addr
, len
, pmkid
);
2282 hash_len
= SHA384_MAC_LEN
;
2283 } else if (group
== 21) {
2284 res
= sha512_vector(2, addr
, len
, pmkid
);
2285 hash_len
= SHA512_MAC_LEN
;
2288 wpabuf_clear_free(secret
);
2289 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2291 pub
= wpabuf_zeropad(pub
, prime_len
);
2292 if (res
< 0 || !pub
) {
2294 wpabuf_clear_free(secret
);
2295 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2298 hkey
= wpabuf_alloc(owe_dh_len
- 2 + wpabuf_len(pub
) + 2);
2301 wpabuf_clear_free(secret
);
2302 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2305 wpabuf_put_data(hkey
, owe_dh
+ 2, owe_dh_len
- 2); /* C */
2306 wpabuf_put_buf(hkey
, pub
); /* A */
2308 wpabuf_put_le16(hkey
, group
); /* group */
2310 res
= hmac_sha256(wpabuf_head(hkey
), wpabuf_len(hkey
),
2311 wpabuf_head(secret
), wpabuf_len(secret
), prk
);
2312 else if (group
== 20)
2313 res
= hmac_sha384(wpabuf_head(hkey
), wpabuf_len(hkey
),
2314 wpabuf_head(secret
), wpabuf_len(secret
), prk
);
2315 else if (group
== 21)
2316 res
= hmac_sha512(wpabuf_head(hkey
), wpabuf_len(hkey
),
2317 wpabuf_head(secret
), wpabuf_len(secret
), prk
);
2318 wpabuf_clear_free(hkey
);
2319 wpabuf_clear_free(secret
);
2321 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2323 wpa_hexdump_key(MSG_DEBUG
, "OWE: prk", prk
, hash_len
);
2325 /* PMK = HKDF-expand(prk, "OWE Key Generation", n) */
2327 os_free(sta
->owe_pmk
);
2328 sta
->owe_pmk
= os_malloc(hash_len
);
2329 if (!sta
->owe_pmk
) {
2330 os_memset(prk
, 0, SHA512_MAC_LEN
);
2331 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2335 res
= hmac_sha256_kdf(prk
, hash_len
, NULL
, (const u8
*) info
,
2336 os_strlen(info
), sta
->owe_pmk
, hash_len
);
2337 else if (group
== 20)
2338 res
= hmac_sha384_kdf(prk
, hash_len
, NULL
, (const u8
*) info
,
2339 os_strlen(info
), sta
->owe_pmk
, hash_len
);
2340 else if (group
== 21)
2341 res
= hmac_sha512_kdf(prk
, hash_len
, NULL
, (const u8
*) info
,
2342 os_strlen(info
), sta
->owe_pmk
, hash_len
);
2343 os_memset(prk
, 0, SHA512_MAC_LEN
);
2345 os_free(sta
->owe_pmk
);
2346 sta
->owe_pmk
= NULL
;
2347 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2349 sta
->owe_pmk_len
= hash_len
;
2351 wpa_hexdump_key(MSG_DEBUG
, "OWE: PMK", sta
->owe_pmk
, sta
->owe_pmk_len
);
2352 wpa_hexdump(MSG_DEBUG
, "OWE: PMKID", pmkid
, PMKID_LEN
);
2353 wpa_auth_pmksa_add2(hapd
->wpa_auth
, sta
->addr
, sta
->owe_pmk
,
2354 sta
->owe_pmk_len
, pmkid
, 0, WPA_KEY_MGMT_OWE
);
2356 return WLAN_STATUS_SUCCESS
;
2359 #endif /* CONFIG_OWE */
2362 static u16
check_assoc_ies(struct hostapd_data
*hapd
, struct sta_info
*sta
,
2363 const u8
*ies
, size_t ies_len
, int reassoc
)
2365 struct ieee802_11_elems elems
;
2369 const u8
*p2p_dev_addr
= NULL
;
2371 if (ieee802_11_parse_elems(ies
, ies_len
, &elems
, 1) == ParseFailed
) {
2372 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
2373 HOSTAPD_LEVEL_INFO
, "Station sent an invalid "
2374 "association request");
2375 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2378 resp
= check_ssid(hapd
, sta
, elems
.ssid
, elems
.ssid_len
);
2379 if (resp
!= WLAN_STATUS_SUCCESS
)
2381 resp
= check_wmm(hapd
, sta
, elems
.wmm
, elems
.wmm_len
);
2382 if (resp
!= WLAN_STATUS_SUCCESS
)
2384 resp
= check_ext_capab(hapd
, sta
, elems
.ext_capab
, elems
.ext_capab_len
);
2385 if (resp
!= WLAN_STATUS_SUCCESS
)
2387 resp
= copy_supp_rates(hapd
, sta
, &elems
);
2388 if (resp
!= WLAN_STATUS_SUCCESS
)
2390 #ifdef CONFIG_IEEE80211N
2391 resp
= copy_sta_ht_capab(hapd
, sta
, elems
.ht_capabilities
);
2392 if (resp
!= WLAN_STATUS_SUCCESS
)
2394 if (hapd
->iconf
->ieee80211n
&& hapd
->iconf
->require_ht
&&
2395 !(sta
->flags
& WLAN_STA_HT
)) {
2396 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
2397 HOSTAPD_LEVEL_INFO
, "Station does not support "
2398 "mandatory HT PHY - reject association");
2399 return WLAN_STATUS_ASSOC_DENIED_NO_HT
;
2401 #endif /* CONFIG_IEEE80211N */
2403 #ifdef CONFIG_IEEE80211AC
2404 if (hapd
->iconf
->ieee80211ac
) {
2405 resp
= copy_sta_vht_capab(hapd
, sta
, elems
.vht_capabilities
);
2406 if (resp
!= WLAN_STATUS_SUCCESS
)
2409 resp
= set_sta_vht_opmode(hapd
, sta
, elems
.vht_opmode_notif
);
2410 if (resp
!= WLAN_STATUS_SUCCESS
)
2414 if (hapd
->iconf
->ieee80211ac
&& hapd
->iconf
->require_vht
&&
2415 !(sta
->flags
& WLAN_STA_VHT
)) {
2416 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
2417 HOSTAPD_LEVEL_INFO
, "Station does not support "
2418 "mandatory VHT PHY - reject association");
2419 return WLAN_STATUS_ASSOC_DENIED_NO_VHT
;
2422 if (hapd
->conf
->vendor_vht
&& !elems
.vht_capabilities
) {
2423 resp
= copy_sta_vendor_vht(hapd
, sta
, elems
.vendor_vht
,
2424 elems
.vendor_vht_len
);
2425 if (resp
!= WLAN_STATUS_SUCCESS
)
2428 #endif /* CONFIG_IEEE80211AC */
2432 wpabuf_free(sta
->p2p_ie
);
2433 sta
->p2p_ie
= ieee802_11_vendor_ie_concat(ies
, ies_len
,
2434 P2P_IE_VENDOR_TYPE
);
2436 p2p_dev_addr
= p2p_get_go_dev_addr(sta
->p2p_ie
);
2438 wpabuf_free(sta
->p2p_ie
);
2441 #endif /* CONFIG_P2P */
2443 if ((hapd
->conf
->wpa
& WPA_PROTO_RSN
) && elems
.rsn_ie
) {
2444 wpa_ie
= elems
.rsn_ie
;
2445 wpa_ie_len
= elems
.rsn_ie_len
;
2446 } else if ((hapd
->conf
->wpa
& WPA_PROTO_WPA
) &&
2448 wpa_ie
= elems
.wpa_ie
;
2449 wpa_ie_len
= elems
.wpa_ie_len
;
2456 sta
->flags
&= ~(WLAN_STA_WPS
| WLAN_STA_MAYBE_WPS
| WLAN_STA_WPS2
);
2457 if (hapd
->conf
->wps_state
&& elems
.wps_ie
) {
2458 wpa_printf(MSG_DEBUG
, "STA included WPS IE in (Re)Association "
2459 "Request - assume WPS is used");
2460 sta
->flags
|= WLAN_STA_WPS
;
2461 wpabuf_free(sta
->wps_ie
);
2462 sta
->wps_ie
= ieee802_11_vendor_ie_concat(ies
, ies_len
,
2463 WPS_IE_VENDOR_TYPE
);
2464 if (sta
->wps_ie
&& wps_is_20(sta
->wps_ie
)) {
2465 wpa_printf(MSG_DEBUG
, "WPS: STA supports WPS 2.0");
2466 sta
->flags
|= WLAN_STA_WPS2
;
2470 if (sta
->wps_ie
&& wps_validate_assoc_req(sta
->wps_ie
) < 0) {
2471 wpa_printf(MSG_DEBUG
, "WPS: Invalid WPS IE in "
2472 "(Re)Association Request - reject");
2473 return WLAN_STATUS_INVALID_IE
;
2475 } else if (hapd
->conf
->wps_state
&& wpa_ie
== NULL
) {
2476 wpa_printf(MSG_DEBUG
, "STA did not include WPA/RSN IE in "
2477 "(Re)Association Request - possible WPS use");
2478 sta
->flags
|= WLAN_STA_MAYBE_WPS
;
2480 #endif /* CONFIG_WPS */
2481 if (hapd
->conf
->wpa
&& wpa_ie
== NULL
) {
2482 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
2484 "No WPA/RSN IE in association request");
2485 return WLAN_STATUS_INVALID_IE
;
2488 if (hapd
->conf
->wpa
&& wpa_ie
) {
2492 if (sta
->wpa_sm
== NULL
)
2493 sta
->wpa_sm
= wpa_auth_sta_init(hapd
->wpa_auth
,
2496 if (sta
->wpa_sm
== NULL
) {
2497 wpa_printf(MSG_WARNING
, "Failed to initialize WPA "
2499 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2501 res
= wpa_validate_wpa_ie(hapd
->wpa_auth
, sta
->wpa_sm
,
2503 elems
.mdie
, elems
.mdie_len
,
2504 elems
.owe_dh
, elems
.owe_dh_len
);
2505 resp
= wpa_res_to_status_code(res
);
2506 if (resp
!= WLAN_STATUS_SUCCESS
)
2508 #ifdef CONFIG_IEEE80211W
2509 if ((sta
->flags
& WLAN_STA_MFP
) && !sta
->sa_query_timed_out
&&
2510 sta
->sa_query_count
> 0)
2511 ap_check_sa_query_timeout(hapd
, sta
);
2512 if ((sta
->flags
& WLAN_STA_MFP
) && !sta
->sa_query_timed_out
&&
2513 (!reassoc
|| sta
->auth_alg
!= WLAN_AUTH_FT
)) {
2515 * STA has already been associated with MFP and SA
2516 * Query timeout has not been reached. Reject the
2517 * association attempt temporarily and start SA Query,
2518 * if one is not pending.
2521 if (sta
->sa_query_count
== 0)
2522 ap_sta_start_sa_query(hapd
, sta
);
2524 return WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY
;
2527 if (wpa_auth_uses_mfp(sta
->wpa_sm
))
2528 sta
->flags
|= WLAN_STA_MFP
;
2530 sta
->flags
&= ~WLAN_STA_MFP
;
2531 #endif /* CONFIG_IEEE80211W */
2533 #ifdef CONFIG_IEEE80211R_AP
2534 if (sta
->auth_alg
== WLAN_AUTH_FT
) {
2536 wpa_printf(MSG_DEBUG
, "FT: " MACSTR
" tried "
2537 "to use association (not "
2538 "re-association) with FT auth_alg",
2539 MAC2STR(sta
->addr
));
2540 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2543 resp
= wpa_ft_validate_reassoc(sta
->wpa_sm
, ies
,
2545 if (resp
!= WLAN_STATUS_SUCCESS
)
2548 #endif /* CONFIG_IEEE80211R_AP */
2551 if (wpa_auth_uses_sae(sta
->wpa_sm
) && sta
->sae
&&
2552 sta
->sae
->state
== SAE_ACCEPTED
)
2553 wpa_auth_add_sae_pmkid(sta
->wpa_sm
, sta
->sae
->pmkid
);
2555 if (wpa_auth_uses_sae(sta
->wpa_sm
) &&
2556 sta
->auth_alg
== WLAN_AUTH_OPEN
) {
2557 struct rsn_pmksa_cache_entry
*sa
;
2558 sa
= wpa_auth_sta_get_pmksa(sta
->wpa_sm
);
2559 if (!sa
|| sa
->akmp
!= WPA_KEY_MGMT_SAE
) {
2560 wpa_printf(MSG_DEBUG
,
2561 "SAE: No PMKSA cache entry found for "
2562 MACSTR
, MAC2STR(sta
->addr
));
2563 return WLAN_STATUS_INVALID_PMKID
;
2565 wpa_printf(MSG_DEBUG
, "SAE: " MACSTR
2566 " using PMKSA caching", MAC2STR(sta
->addr
));
2567 } else if (wpa_auth_uses_sae(sta
->wpa_sm
) &&
2568 sta
->auth_alg
!= WLAN_AUTH_SAE
&&
2569 !(sta
->auth_alg
== WLAN_AUTH_FT
&&
2570 wpa_auth_uses_ft_sae(sta
->wpa_sm
))) {
2571 wpa_printf(MSG_DEBUG
, "SAE: " MACSTR
" tried to use "
2572 "SAE AKM after non-SAE auth_alg %u",
2573 MAC2STR(sta
->addr
), sta
->auth_alg
);
2574 return WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG
;
2576 #endif /* CONFIG_SAE */
2579 if ((hapd
->conf
->wpa_key_mgmt
& WPA_KEY_MGMT_OWE
) &&
2580 wpa_auth_sta_key_mgmt(sta
->wpa_sm
) == WPA_KEY_MGMT_OWE
&&
2582 resp
= owe_process_assoc_req(hapd
, sta
, elems
.owe_dh
,
2584 if (resp
!= WLAN_STATUS_SUCCESS
)
2587 #endif /* CONFIG_OWE */
2589 #ifdef CONFIG_IEEE80211N
2590 if ((sta
->flags
& (WLAN_STA_HT
| WLAN_STA_VHT
)) &&
2591 wpa_auth_get_pairwise(sta
->wpa_sm
) == WPA_CIPHER_TKIP
) {
2592 hostapd_logger(hapd
, sta
->addr
,
2593 HOSTAPD_MODULE_IEEE80211
,
2595 "Station tried to use TKIP with HT "
2597 return WLAN_STATUS_CIPHER_REJECTED_PER_POLICY
;
2599 #endif /* CONFIG_IEEE80211N */
2601 } else if (hapd
->conf
->osen
) {
2602 if (elems
.osen
== NULL
) {
2604 hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
2606 "No HS 2.0 OSEN element in association request");
2607 return WLAN_STATUS_INVALID_IE
;
2610 wpa_printf(MSG_DEBUG
, "HS 2.0: OSEN association");
2611 if (sta
->wpa_sm
== NULL
)
2612 sta
->wpa_sm
= wpa_auth_sta_init(hapd
->wpa_auth
,
2614 if (sta
->wpa_sm
== NULL
) {
2615 wpa_printf(MSG_WARNING
, "Failed to initialize WPA "
2617 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2619 if (wpa_validate_osen(hapd
->wpa_auth
, sta
->wpa_sm
,
2620 elems
.osen
- 2, elems
.osen_len
+ 2) < 0)
2621 return WLAN_STATUS_INVALID_IE
;
2622 #endif /* CONFIG_HS20 */
2624 wpa_auth_sta_no_wpa(sta
->wpa_sm
);
2627 p2p_group_notif_assoc(hapd
->p2p_group
, sta
->addr
, ies
, ies_len
);
2628 #endif /* CONFIG_P2P */
2631 wpabuf_free(sta
->hs20_ie
);
2632 if (elems
.hs20
&& elems
.hs20_len
> 4) {
2633 sta
->hs20_ie
= wpabuf_alloc_copy(elems
.hs20
+ 4,
2634 elems
.hs20_len
- 4);
2636 sta
->hs20_ie
= NULL
;
2637 #endif /* CONFIG_HS20 */
2640 wpabuf_free(sta
->mb_ies
);
2641 if (hapd
->iface
->fst
)
2642 sta
->mb_ies
= mb_ies_by_info(&elems
.mb_ies
);
2645 #endif /* CONFIG_FST */
2648 mbo_ap_check_sta_assoc(hapd
, sta
, &elems
);
2650 if (hapd
->conf
->mbo_enabled
&& (hapd
->conf
->wpa
& 2) &&
2651 elems
.mbo
&& sta
->cell_capa
&& !(sta
->flags
& WLAN_STA_MFP
) &&
2652 hapd
->conf
->ieee80211w
!= NO_MGMT_FRAME_PROTECTION
) {
2653 wpa_printf(MSG_INFO
,
2654 "MBO: Reject WPA2 association without PMF");
2655 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2657 #endif /* CONFIG_MBO */
2659 ap_copy_sta_supp_op_classes(sta
, elems
.supp_op_classes
,
2660 elems
.supp_op_classes_len
);
2662 if ((sta
->capability
& WLAN_CAPABILITY_RADIO_MEASUREMENT
) &&
2663 elems
.rrm_enabled
&&
2664 elems
.rrm_enabled_len
>= sizeof(sta
->rrm_enabled_capa
))
2665 os_memcpy(sta
->rrm_enabled_capa
, elems
.rrm_enabled
,
2666 sizeof(sta
->rrm_enabled_capa
));
2668 if (elems
.power_capab
) {
2669 sta
->min_tx_power
= elems
.power_capab
[0];
2670 sta
->max_tx_power
= elems
.power_capab
[1];
2671 sta
->power_capab
= 1;
2673 sta
->power_capab
= 0;
2676 return WLAN_STATUS_SUCCESS
;
2680 static void send_deauth(struct hostapd_data
*hapd
, const u8
*addr
,
2684 struct ieee80211_mgmt reply
;
2686 os_memset(&reply
, 0, sizeof(reply
));
2687 reply
.frame_control
=
2688 IEEE80211_FC(WLAN_FC_TYPE_MGMT
, WLAN_FC_STYPE_DEAUTH
);
2689 os_memcpy(reply
.da
, addr
, ETH_ALEN
);
2690 os_memcpy(reply
.sa
, hapd
->own_addr
, ETH_ALEN
);
2691 os_memcpy(reply
.bssid
, hapd
->own_addr
, ETH_ALEN
);
2693 send_len
= IEEE80211_HDRLEN
+ sizeof(reply
.u
.deauth
);
2694 reply
.u
.deauth
.reason_code
= host_to_le16(reason_code
);
2696 if (hostapd_drv_send_mlme(hapd
, &reply
, send_len
, 0) < 0)
2697 wpa_printf(MSG_INFO
, "Failed to send deauth: %s",
2702 static int add_associated_sta(struct hostapd_data
*hapd
,
2703 struct sta_info
*sta
)
2705 struct ieee80211_ht_capabilities ht_cap
;
2706 struct ieee80211_vht_capabilities vht_cap
;
2710 * Remove the STA entry to ensure the STA PS state gets cleared and
2711 * configuration gets updated. This is relevant for cases, such as
2712 * FT-over-the-DS, where a station re-associates back to the same AP but
2713 * skips the authentication flow, or if working with a driver that
2714 * does not support full AP client state.
2716 * Skip this if the STA has already completed FT reassociation and the
2717 * TK has been configured since the TX/RX PN must not be reset to 0 for
2720 if (!sta
->added_unassoc
&&
2721 (!(sta
->flags
& WLAN_STA_AUTHORIZED
) ||
2722 (!wpa_auth_sta_ft_tk_already_set(sta
->wpa_sm
) &&
2723 !wpa_auth_sta_fils_tk_already_set(sta
->wpa_sm
)))) {
2724 hostapd_drv_sta_remove(hapd
, sta
->addr
);
2725 wpa_auth_sm_event(sta
->wpa_sm
, WPA_DRV_STA_REMOVED
);
2729 #ifdef CONFIG_IEEE80211N
2730 if (sta
->flags
& WLAN_STA_HT
)
2731 hostapd_get_ht_capab(hapd
, sta
->ht_capabilities
, &ht_cap
);
2732 #endif /* CONFIG_IEEE80211N */
2733 #ifdef CONFIG_IEEE80211AC
2734 if (sta
->flags
& WLAN_STA_VHT
)
2735 hostapd_get_vht_capab(hapd
, sta
->vht_capabilities
, &vht_cap
);
2736 #endif /* CONFIG_IEEE80211AC */
2739 * Add the station with forced WLAN_STA_ASSOC flag. The sta->flags
2740 * will be set when the ACK frame for the (Re)Association Response frame
2741 * is processed (TX status driver event).
2743 if (hostapd_sta_add(hapd
, sta
->addr
, sta
->aid
, sta
->capability
,
2744 sta
->supported_rates
, sta
->supported_rates_len
,
2745 sta
->listen_interval
,
2746 sta
->flags
& WLAN_STA_HT
? &ht_cap
: NULL
,
2747 sta
->flags
& WLAN_STA_VHT
? &vht_cap
: NULL
,
2748 sta
->flags
| WLAN_STA_ASSOC
, sta
->qosinfo
,
2749 sta
->vht_opmode
, sta
->p2p_ie
? 1 : 0,
2751 hostapd_logger(hapd
, sta
->addr
,
2752 HOSTAPD_MODULE_IEEE80211
, HOSTAPD_LEVEL_NOTICE
,
2753 "Could not %s STA to kernel driver",
2754 set
? "set" : "add");
2756 if (sta
->added_unassoc
) {
2757 hostapd_drv_sta_remove(hapd
, sta
->addr
);
2758 sta
->added_unassoc
= 0;
2764 sta
->added_unassoc
= 0;
2770 static u16
send_assoc_resp(struct hostapd_data
*hapd
, struct sta_info
*sta
,
2771 const u8
*addr
, u16 status_code
, int reassoc
,
2772 const u8
*ies
, size_t ies_len
)
2777 struct ieee80211_mgmt
*reply
;
2779 u16 res
= WLAN_STATUS_SUCCESS
;
2781 buflen
= sizeof(struct ieee80211_mgmt
) + 1024;
2783 if (sta
&& sta
->fils_hlp_resp
)
2784 buflen
+= wpabuf_len(sta
->fils_hlp_resp
);
2785 #endif /* CONFIG_FILS */
2787 if (sta
&& (hapd
->conf
->wpa_key_mgmt
& WPA_KEY_MGMT_OWE
))
2789 #endif /* CONFIG_OWE */
2790 buf
= os_zalloc(buflen
);
2792 res
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
2795 reply
= (struct ieee80211_mgmt
*) buf
;
2796 reply
->frame_control
=
2797 IEEE80211_FC(WLAN_FC_TYPE_MGMT
,
2798 (reassoc
? WLAN_FC_STYPE_REASSOC_RESP
:
2799 WLAN_FC_STYPE_ASSOC_RESP
));
2800 os_memcpy(reply
->da
, addr
, ETH_ALEN
);
2801 os_memcpy(reply
->sa
, hapd
->own_addr
, ETH_ALEN
);
2802 os_memcpy(reply
->bssid
, hapd
->own_addr
, ETH_ALEN
);
2804 send_len
= IEEE80211_HDRLEN
;
2805 send_len
+= sizeof(reply
->u
.assoc_resp
);
2806 reply
->u
.assoc_resp
.capab_info
=
2807 host_to_le16(hostapd_own_capab_info(hapd
));
2808 reply
->u
.assoc_resp
.status_code
= host_to_le16(status_code
);
2810 reply
->u
.assoc_resp
.aid
= host_to_le16((sta
? sta
->aid
: 0) |
2812 /* Supported rates */
2813 p
= hostapd_eid_supp_rates(hapd
, reply
->u
.assoc_resp
.variable
);
2814 /* Extended supported rates */
2815 p
= hostapd_eid_ext_supp_rates(hapd
, p
);
2817 #ifdef CONFIG_IEEE80211R_AP
2818 if (sta
&& status_code
== WLAN_STATUS_SUCCESS
) {
2819 /* IEEE 802.11r: Mobility Domain Information, Fast BSS
2820 * Transition Information, RSN, [RIC Response] */
2821 p
= wpa_sm_write_assoc_resp_ies(sta
->wpa_sm
, p
,
2823 sta
->auth_alg
, ies
, ies_len
);
2825 #endif /* CONFIG_IEEE80211R_AP */
2828 if (sta
&& (hapd
->conf
->wpa_key_mgmt
& WPA_KEY_MGMT_OWE
))
2829 p
= wpa_auth_write_assoc_resp_owe(sta
->wpa_sm
, p
,
2832 #endif /* CONFIG_OWE */
2834 #ifdef CONFIG_IEEE80211W
2835 if (sta
&& status_code
== WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY
)
2836 p
= hostapd_eid_assoc_comeback_time(hapd
, sta
, p
);
2837 #endif /* CONFIG_IEEE80211W */
2839 #ifdef CONFIG_IEEE80211N
2840 p
= hostapd_eid_ht_capabilities(hapd
, p
);
2841 p
= hostapd_eid_ht_operation(hapd
, p
);
2842 #endif /* CONFIG_IEEE80211N */
2844 #ifdef CONFIG_IEEE80211AC
2845 if (hapd
->iconf
->ieee80211ac
&& !hapd
->conf
->disable_11ac
) {
2846 u32 nsts
= 0, sta_nsts
;
2848 if (sta
&& hapd
->conf
->use_sta_nsts
&& sta
->vht_capabilities
) {
2849 struct ieee80211_vht_capabilities
*capa
;
2851 nsts
= (hapd
->iface
->conf
->vht_capab
>>
2852 VHT_CAP_BEAMFORMEE_STS_OFFSET
) & 7;
2853 capa
= sta
->vht_capabilities
;
2854 sta_nsts
= (le_to_host32(capa
->vht_capabilities_info
) >>
2855 VHT_CAP_BEAMFORMEE_STS_OFFSET
) & 7;
2857 if (nsts
< sta_nsts
)
2862 p
= hostapd_eid_vht_capabilities(hapd
, p
, nsts
);
2863 p
= hostapd_eid_vht_operation(hapd
, p
);
2865 #endif /* CONFIG_IEEE80211AC */
2867 p
= hostapd_eid_ext_capab(hapd
, p
);
2868 p
= hostapd_eid_bss_max_idle_period(hapd
, p
);
2869 if (sta
&& sta
->qos_map_enabled
)
2870 p
= hostapd_eid_qos_map_set(hapd
, p
);
2873 if (hapd
->iface
->fst_ies
) {
2874 os_memcpy(p
, wpabuf_head(hapd
->iface
->fst_ies
),
2875 wpabuf_len(hapd
->iface
->fst_ies
));
2876 p
+= wpabuf_len(hapd
->iface
->fst_ies
);
2878 #endif /* CONFIG_FST */
2880 #ifdef CONFIG_IEEE80211AC
2881 if (sta
&& hapd
->conf
->vendor_vht
&& (sta
->flags
& WLAN_STA_VENDOR_VHT
))
2882 p
= hostapd_eid_vendor_vht(hapd
, p
);
2883 #endif /* CONFIG_IEEE80211AC */
2885 if (sta
&& (sta
->flags
& WLAN_STA_WMM
))
2886 p
= hostapd_eid_wmm(hapd
, p
);
2890 ((sta
->flags
& WLAN_STA_WPS
) ||
2891 ((sta
->flags
& WLAN_STA_MAYBE_WPS
) && hapd
->conf
->wpa
))) {
2892 struct wpabuf
*wps
= wps_build_assoc_resp_ie();
2894 os_memcpy(p
, wpabuf_head(wps
), wpabuf_len(wps
));
2895 p
+= wpabuf_len(wps
);
2899 #endif /* CONFIG_WPS */
2902 if (sta
&& sta
->p2p_ie
&& hapd
->p2p_group
) {
2903 struct wpabuf
*p2p_resp_ie
;
2904 enum p2p_status_code status
;
2905 switch (status_code
) {
2906 case WLAN_STATUS_SUCCESS
:
2907 status
= P2P_SC_SUCCESS
;
2909 case WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
:
2910 status
= P2P_SC_FAIL_LIMIT_REACHED
;
2913 status
= P2P_SC_FAIL_INVALID_PARAMS
;
2916 p2p_resp_ie
= p2p_group_assoc_resp_ie(hapd
->p2p_group
, status
);
2918 os_memcpy(p
, wpabuf_head(p2p_resp_ie
),
2919 wpabuf_len(p2p_resp_ie
));
2920 p
+= wpabuf_len(p2p_resp_ie
);
2921 wpabuf_free(p2p_resp_ie
);
2924 #endif /* CONFIG_P2P */
2926 #ifdef CONFIG_P2P_MANAGER
2927 if (hapd
->conf
->p2p
& P2P_MANAGE
)
2928 p
= hostapd_eid_p2p_manage(hapd
, p
);
2929 #endif /* CONFIG_P2P_MANAGER */
2931 p
= hostapd_eid_mbo(hapd
, p
, buf
+ buflen
- p
);
2933 if (hapd
->conf
->assocresp_elements
&&
2934 (size_t) (buf
+ buflen
- p
) >=
2935 wpabuf_len(hapd
->conf
->assocresp_elements
)) {
2936 os_memcpy(p
, wpabuf_head(hapd
->conf
->assocresp_elements
),
2937 wpabuf_len(hapd
->conf
->assocresp_elements
));
2938 p
+= wpabuf_len(hapd
->conf
->assocresp_elements
);
2941 send_len
+= p
- reply
->u
.assoc_resp
.variable
;
2945 (sta
->auth_alg
== WLAN_AUTH_FILS_SK
||
2946 sta
->auth_alg
== WLAN_AUTH_FILS_SK_PFS
||
2947 sta
->auth_alg
== WLAN_AUTH_FILS_PK
) &&
2948 status_code
== WLAN_STATUS_SUCCESS
) {
2949 struct ieee802_11_elems elems
;
2951 if (ieee802_11_parse_elems(ies
, ies_len
, &elems
, 0) ==
2952 ParseFailed
|| !elems
.fils_session
) {
2953 res
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
2958 *p
++ = WLAN_EID_EXTENSION
; /* Element ID */
2959 *p
++ = 1 + FILS_SESSION_LEN
; /* Length */
2960 *p
++ = WLAN_EID_EXT_FILS_SESSION
; /* Element ID Extension */
2961 os_memcpy(p
, elems
.fils_session
, FILS_SESSION_LEN
);
2962 send_len
+= 2 + 1 + FILS_SESSION_LEN
;
2964 send_len
= fils_encrypt_assoc(sta
->wpa_sm
, buf
, send_len
,
2965 buflen
, sta
->fils_hlp_resp
);
2967 res
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
2971 #endif /* CONFIG_FILS */
2974 if ((hapd
->conf
->wpa_key_mgmt
& WPA_KEY_MGMT_OWE
) &&
2975 sta
&& sta
->owe_ecdh
&&
2976 wpa_auth_sta_key_mgmt(sta
->wpa_sm
) == WPA_KEY_MGMT_OWE
) {
2979 pub
= crypto_ecdh_get_pubkey(sta
->owe_ecdh
, 0);
2981 res
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
2984 /* OWE Diffie-Hellman Parameter element */
2985 *p
++ = WLAN_EID_EXTENSION
; /* Element ID */
2986 *p
++ = 1 + 2 + wpabuf_len(pub
); /* Length */
2987 *p
++ = WLAN_EID_EXT_OWE_DH_PARAM
; /* Element ID Extension */
2988 WPA_PUT_LE16(p
, sta
->owe_group
);
2990 os_memcpy(p
, wpabuf_head(pub
), wpabuf_len(pub
));
2991 p
+= wpabuf_len(pub
);
2992 send_len
+= 3 + 2 + wpabuf_len(pub
);
2995 #endif /* CONFIG_OWE */
2997 if (hostapd_drv_send_mlme(hapd
, reply
, send_len
, 0) < 0) {
2998 wpa_printf(MSG_INFO
, "Failed to send assoc resp: %s",
3000 res
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
3010 u8
* owe_assoc_req_process(struct hostapd_data
*hapd
, struct sta_info
*sta
,
3011 const u8
*owe_dh
, u8 owe_dh_len
,
3012 u8
*owe_buf
, size_t owe_buf_len
, u16
*reason
)
3014 #ifdef CONFIG_TESTING_OPTIONS
3015 if (hapd
->conf
->own_ie_override
) {
3016 wpa_printf(MSG_DEBUG
, "OWE: Using IE override");
3017 *reason
= WLAN_STATUS_SUCCESS
;
3018 return wpa_auth_write_assoc_resp_owe(sta
->wpa_sm
, owe_buf
,
3019 owe_buf_len
, NULL
, 0);
3021 #endif /* CONFIG_TESTING_OPTIONS */
3023 if (wpa_auth_sta_get_pmksa(sta
->wpa_sm
)) {
3024 wpa_printf(MSG_DEBUG
, "OWE: Using PMKSA caching");
3025 owe_buf
= wpa_auth_write_assoc_resp_owe(sta
->wpa_sm
, owe_buf
,
3026 owe_buf_len
, NULL
, 0);
3027 *reason
= WLAN_STATUS_SUCCESS
;
3031 *reason
= owe_process_assoc_req(hapd
, sta
, owe_dh
, owe_dh_len
);
3032 if (*reason
!= WLAN_STATUS_SUCCESS
)
3035 owe_buf
= wpa_auth_write_assoc_resp_owe(sta
->wpa_sm
, owe_buf
,
3036 owe_buf_len
, NULL
, 0);
3038 if (sta
->owe_ecdh
&& owe_buf
) {
3041 pub
= crypto_ecdh_get_pubkey(sta
->owe_ecdh
, 0);
3043 *reason
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
3047 /* OWE Diffie-Hellman Parameter element */
3048 *owe_buf
++ = WLAN_EID_EXTENSION
; /* Element ID */
3049 *owe_buf
++ = 1 + 2 + wpabuf_len(pub
); /* Length */
3050 *owe_buf
++ = WLAN_EID_EXT_OWE_DH_PARAM
; /* Element ID Extension
3052 WPA_PUT_LE16(owe_buf
, sta
->owe_group
);
3054 os_memcpy(owe_buf
, wpabuf_head(pub
), wpabuf_len(pub
));
3055 owe_buf
+= wpabuf_len(pub
);
3061 #endif /* CONFIG_OWE */
3066 void fils_hlp_finish_assoc(struct hostapd_data
*hapd
, struct sta_info
*sta
)
3070 wpa_printf(MSG_DEBUG
, "FILS: Finish association with " MACSTR
,
3071 MAC2STR(sta
->addr
));
3072 eloop_cancel_timeout(fils_hlp_timeout
, hapd
, sta
);
3073 if (!sta
->fils_pending_assoc_req
)
3075 reply_res
= send_assoc_resp(hapd
, sta
, sta
->addr
, WLAN_STATUS_SUCCESS
,
3076 sta
->fils_pending_assoc_is_reassoc
,
3077 sta
->fils_pending_assoc_req
,
3078 sta
->fils_pending_assoc_req_len
);
3079 os_free(sta
->fils_pending_assoc_req
);
3080 sta
->fils_pending_assoc_req
= NULL
;
3081 sta
->fils_pending_assoc_req_len
= 0;
3082 wpabuf_free(sta
->fils_hlp_resp
);
3083 sta
->fils_hlp_resp
= NULL
;
3084 wpabuf_free(sta
->hlp_dhcp_discover
);
3085 sta
->hlp_dhcp_discover
= NULL
;
3088 * Remove the station in case transmission of a success response fails.
3089 * At this point the station was already added associated to the driver.
3091 if (reply_res
!= WLAN_STATUS_SUCCESS
)
3092 hostapd_drv_sta_remove(hapd
, sta
->addr
);
3096 void fils_hlp_timeout(void *eloop_ctx
, void *eloop_data
)
3098 struct hostapd_data
*hapd
= eloop_ctx
;
3099 struct sta_info
*sta
= eloop_data
;
3101 wpa_printf(MSG_DEBUG
,
3102 "FILS: HLP response timeout - continue with association response for "
3103 MACSTR
, MAC2STR(sta
->addr
));
3104 if (sta
->fils_drv_assoc_finish
)
3105 hostapd_notify_assoc_fils_finish(hapd
, sta
);
3107 fils_hlp_finish_assoc(hapd
, sta
);
3110 #endif /* CONFIG_FILS */
3113 static void handle_assoc(struct hostapd_data
*hapd
,
3114 const struct ieee80211_mgmt
*mgmt
, size_t len
,
3117 u16 capab_info
, listen_interval
, seq_ctrl
, fc
;
3118 u16 resp
= WLAN_STATUS_SUCCESS
, reply_res
;
3121 struct sta_info
*sta
;
3123 struct hostapd_sta_wpa_psk_short
*psk
= NULL
;
3124 char *identity
= NULL
;
3125 char *radius_cui
= NULL
;
3127 int delay_assoc
= 0;
3128 #endif /* CONFIG_FILS */
3130 if (len
< IEEE80211_HDRLEN
+ (reassoc
? sizeof(mgmt
->u
.reassoc_req
) :
3131 sizeof(mgmt
->u
.assoc_req
))) {
3132 wpa_printf(MSG_INFO
, "handle_assoc(reassoc=%d) - too short payload (len=%lu)",
3133 reassoc
, (unsigned long) len
);
3137 #ifdef CONFIG_TESTING_OPTIONS
3139 if (hapd
->iconf
->ignore_reassoc_probability
> 0.0 &&
3140 drand48() < hapd
->iconf
->ignore_reassoc_probability
) {
3141 wpa_printf(MSG_INFO
,
3142 "TESTING: ignoring reassoc request from "
3143 MACSTR
, MAC2STR(mgmt
->sa
));
3147 if (hapd
->iconf
->ignore_assoc_probability
> 0.0 &&
3148 drand48() < hapd
->iconf
->ignore_assoc_probability
) {
3149 wpa_printf(MSG_INFO
,
3150 "TESTING: ignoring assoc request from "
3151 MACSTR
, MAC2STR(mgmt
->sa
));
3155 #endif /* CONFIG_TESTING_OPTIONS */
3157 fc
= le_to_host16(mgmt
->frame_control
);
3158 seq_ctrl
= le_to_host16(mgmt
->seq_ctrl
);
3161 capab_info
= le_to_host16(mgmt
->u
.reassoc_req
.capab_info
);
3162 listen_interval
= le_to_host16(
3163 mgmt
->u
.reassoc_req
.listen_interval
);
3164 wpa_printf(MSG_DEBUG
, "reassociation request: STA=" MACSTR
3165 " capab_info=0x%02x listen_interval=%d current_ap="
3166 MACSTR
" seq_ctrl=0x%x%s",
3167 MAC2STR(mgmt
->sa
), capab_info
, listen_interval
,
3168 MAC2STR(mgmt
->u
.reassoc_req
.current_ap
),
3169 seq_ctrl
, (fc
& WLAN_FC_RETRY
) ? " retry" : "");
3170 left
= len
- (IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.reassoc_req
));
3171 pos
= mgmt
->u
.reassoc_req
.variable
;
3173 capab_info
= le_to_host16(mgmt
->u
.assoc_req
.capab_info
);
3174 listen_interval
= le_to_host16(
3175 mgmt
->u
.assoc_req
.listen_interval
);
3176 wpa_printf(MSG_DEBUG
, "association request: STA=" MACSTR
3177 " capab_info=0x%02x listen_interval=%d "
3179 MAC2STR(mgmt
->sa
), capab_info
, listen_interval
,
3180 seq_ctrl
, (fc
& WLAN_FC_RETRY
) ? " retry" : "");
3181 left
= len
- (IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.assoc_req
));
3182 pos
= mgmt
->u
.assoc_req
.variable
;
3185 sta
= ap_get_sta(hapd
, mgmt
->sa
);
3186 #ifdef CONFIG_IEEE80211R_AP
3187 if (sta
&& sta
->auth_alg
== WLAN_AUTH_FT
&&
3188 (sta
->flags
& WLAN_STA_AUTH
) == 0) {
3189 wpa_printf(MSG_DEBUG
, "FT: Allow STA " MACSTR
" to associate "
3190 "prior to authentication since it is using "
3191 "over-the-DS FT", MAC2STR(mgmt
->sa
));
3194 * Mark station as authenticated, to avoid adding station
3195 * entry in the driver as associated and not authenticated
3197 sta
->flags
|= WLAN_STA_AUTH
;
3199 #endif /* CONFIG_IEEE80211R_AP */
3200 if (sta
== NULL
|| (sta
->flags
& WLAN_STA_AUTH
) == 0) {
3201 if (hapd
->iface
->current_mode
&&
3202 hapd
->iface
->current_mode
->mode
==
3203 HOSTAPD_MODE_IEEE80211AD
) {
3205 u32 session_timeout
, acct_interim_interval
;
3206 struct vlan_description vlan_id
;
3208 acl_res
= ieee802_11_allowed_address(
3209 hapd
, mgmt
->sa
, (const u8
*) mgmt
, len
,
3210 &session_timeout
, &acct_interim_interval
,
3211 &vlan_id
, &psk
, &identity
, &radius_cui
, 0);
3212 if (acl_res
== HOSTAPD_ACL_REJECT
) {
3213 wpa_msg(hapd
->msg_ctx
, MSG_DEBUG
,
3214 "Ignore Association Request frame from "
3215 MACSTR
" due to ACL reject",
3217 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
3220 if (acl_res
== HOSTAPD_ACL_PENDING
)
3223 /* DMG/IEEE 802.11ad does not use authentication.
3224 * Allocate sta entry upon association. */
3225 sta
= ap_sta_add(hapd
, mgmt
->sa
);
3227 hostapd_logger(hapd
, mgmt
->sa
,
3228 HOSTAPD_MODULE_IEEE80211
,
3230 "Failed to add STA");
3231 resp
= WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
;
3235 acl_res
= ieee802_11_set_radius_info(
3236 hapd
, sta
, acl_res
, session_timeout
,
3237 acct_interim_interval
, &vlan_id
, &psk
,
3238 &identity
, &radius_cui
);
3240 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
3244 hostapd_logger(hapd
, sta
->addr
,
3245 HOSTAPD_MODULE_IEEE80211
,
3246 HOSTAPD_LEVEL_DEBUG
,
3247 "Skip authentication for DMG/IEEE 802.11ad");
3248 sta
->flags
|= WLAN_STA_AUTH
;
3249 wpa_auth_sm_event(sta
->wpa_sm
, WPA_AUTH
);
3250 sta
->auth_alg
= WLAN_AUTH_OPEN
;
3252 hostapd_logger(hapd
, mgmt
->sa
,
3253 HOSTAPD_MODULE_IEEE80211
,
3255 "Station tried to associate before authentication (aid=%d flags=0x%x)",
3256 sta
? sta
->aid
: -1,
3257 sta
? sta
->flags
: 0);
3258 send_deauth(hapd
, mgmt
->sa
,
3259 WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA
);
3264 if ((fc
& WLAN_FC_RETRY
) &&
3265 sta
->last_seq_ctrl
!= WLAN_INVALID_MGMT_SEQ
&&
3266 sta
->last_seq_ctrl
== seq_ctrl
&&
3267 sta
->last_subtype
== (reassoc
? WLAN_FC_STYPE_REASSOC_REQ
:
3268 WLAN_FC_STYPE_ASSOC_REQ
)) {
3269 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
3270 HOSTAPD_LEVEL_DEBUG
,
3271 "Drop repeated association frame seq_ctrl=0x%x",
3275 sta
->last_seq_ctrl
= seq_ctrl
;
3276 sta
->last_subtype
= reassoc
? WLAN_FC_STYPE_REASSOC_REQ
:
3277 WLAN_FC_STYPE_ASSOC_REQ
;
3279 if (hapd
->tkip_countermeasures
) {
3280 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
3284 if (listen_interval
> hapd
->conf
->max_listen_interval
) {
3285 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
3286 HOSTAPD_LEVEL_DEBUG
,
3287 "Too large Listen Interval (%d)",
3289 resp
= WLAN_STATUS_ASSOC_DENIED_LISTEN_INT_TOO_LARGE
;
3294 if (hapd
->conf
->mbo_enabled
&& hapd
->mbo_assoc_disallow
) {
3295 resp
= WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
;
3298 #endif /* CONFIG_MBO */
3301 * sta->capability is used in check_assoc_ies() for RRM enabled
3302 * capability element.
3304 sta
->capability
= capab_info
;
3307 if (sta
->auth_alg
== WLAN_AUTH_FILS_SK
||
3308 sta
->auth_alg
== WLAN_AUTH_FILS_SK_PFS
||
3309 sta
->auth_alg
== WLAN_AUTH_FILS_PK
) {
3312 /* The end of the payload is encrypted. Need to decrypt it
3313 * before parsing. */
3315 tmp
= os_memdup(pos
, left
);
3317 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
3321 res
= fils_decrypt_assoc(sta
->wpa_sm
, sta
->fils_session
, mgmt
,
3324 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
3330 #endif /* CONFIG_FILS */
3332 /* followed by SSID and Supported rates; and HT capabilities if 802.11n
3334 resp
= check_assoc_ies(hapd
, sta
, pos
, left
, reassoc
);
3335 if (resp
!= WLAN_STATUS_SUCCESS
)
3338 if (hostapd_get_aid(hapd
, sta
) < 0) {
3339 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
3340 HOSTAPD_LEVEL_INFO
, "No room for more AIDs");
3341 resp
= WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
;
3345 sta
->listen_interval
= listen_interval
;
3347 if (hapd
->iface
->current_mode
&&
3348 hapd
->iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211G
)
3349 sta
->flags
|= WLAN_STA_NONERP
;
3350 for (i
= 0; i
< sta
->supported_rates_len
; i
++) {
3351 if ((sta
->supported_rates
[i
] & 0x7f) > 22) {
3352 sta
->flags
&= ~WLAN_STA_NONERP
;
3356 if (sta
->flags
& WLAN_STA_NONERP
&& !sta
->nonerp_set
) {
3357 sta
->nonerp_set
= 1;
3358 hapd
->iface
->num_sta_non_erp
++;
3359 if (hapd
->iface
->num_sta_non_erp
== 1)
3360 ieee802_11_set_beacons(hapd
->iface
);
3363 if (!(sta
->capability
& WLAN_CAPABILITY_SHORT_SLOT_TIME
) &&
3364 !sta
->no_short_slot_time_set
) {
3365 sta
->no_short_slot_time_set
= 1;
3366 hapd
->iface
->num_sta_no_short_slot_time
++;
3367 if (hapd
->iface
->current_mode
&&
3368 hapd
->iface
->current_mode
->mode
==
3369 HOSTAPD_MODE_IEEE80211G
&&
3370 hapd
->iface
->num_sta_no_short_slot_time
== 1)
3371 ieee802_11_set_beacons(hapd
->iface
);
3374 if (sta
->capability
& WLAN_CAPABILITY_SHORT_PREAMBLE
)
3375 sta
->flags
|= WLAN_STA_SHORT_PREAMBLE
;
3377 sta
->flags
&= ~WLAN_STA_SHORT_PREAMBLE
;
3379 if (!(sta
->capability
& WLAN_CAPABILITY_SHORT_PREAMBLE
) &&
3380 !sta
->no_short_preamble_set
) {
3381 sta
->no_short_preamble_set
= 1;
3382 hapd
->iface
->num_sta_no_short_preamble
++;
3383 if (hapd
->iface
->current_mode
&&
3384 hapd
->iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211G
3385 && hapd
->iface
->num_sta_no_short_preamble
== 1)
3386 ieee802_11_set_beacons(hapd
->iface
);
3389 #ifdef CONFIG_IEEE80211N
3390 update_ht_state(hapd
, sta
);
3391 #endif /* CONFIG_IEEE80211N */
3393 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
3394 HOSTAPD_LEVEL_DEBUG
,
3395 "association OK (aid %d)", sta
->aid
);
3396 /* Station will be marked associated, after it acknowledges AssocResp
3398 sta
->flags
|= WLAN_STA_ASSOC_REQ_OK
;
3400 #ifdef CONFIG_IEEE80211W
3401 if ((sta
->flags
& WLAN_STA_MFP
) && sta
->sa_query_timed_out
) {
3402 wpa_printf(MSG_DEBUG
, "Allowing %sassociation after timed out "
3403 "SA Query procedure", reassoc
? "re" : "");
3404 /* TODO: Send a protected Disassociate frame to the STA using
3405 * the old key and Reason Code "Previous Authentication no
3406 * longer valid". Make sure this is only sent protected since
3407 * unprotected frame would be received by the STA that is now
3408 * trying to associate.
3411 #endif /* CONFIG_IEEE80211W */
3413 /* Make sure that the previously registered inactivity timer will not
3414 * remove the STA immediately. */
3415 sta
->timeout_next
= STA_NULLFUNC
;
3417 #ifdef CONFIG_TAXONOMY
3418 taxonomy_sta_info_assoc_req(hapd
, sta
, pos
, left
);
3419 #endif /* CONFIG_TAXONOMY */
3421 sta
->pending_wds_enable
= 0;
3424 if (sta
->auth_alg
== WLAN_AUTH_FILS_SK
||
3425 sta
->auth_alg
== WLAN_AUTH_FILS_SK_PFS
||
3426 sta
->auth_alg
== WLAN_AUTH_FILS_PK
) {
3427 if (fils_process_hlp(hapd
, sta
, pos
, left
) > 0)
3430 #endif /* CONFIG_FILS */
3434 os_free(radius_cui
);
3435 hostapd_free_psk_list(psk
);
3438 * In case of a successful response, add the station to the driver.
3439 * Otherwise, the kernel may ignore Data frames before we process the
3440 * ACK frame (TX status). In case of a failure, this station will be
3443 * Note that this is not compliant with the IEEE 802.11 standard that
3444 * states that a non-AP station should transition into the
3445 * authenticated/associated state only after the station acknowledges
3446 * the (Re)Association Response frame. However, still do this as:
3448 * 1. In case the station does not acknowledge the (Re)Association
3449 * Response frame, it will be removed.
3450 * 2. Data frames will be dropped in the kernel until the station is
3451 * set into authorized state, and there are no significant known
3452 * issues with processing other non-Data Class 3 frames during this
3455 if (resp
== WLAN_STATUS_SUCCESS
&& sta
&& add_associated_sta(hapd
, sta
))
3456 resp
= WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
;
3460 eloop_cancel_timeout(fils_hlp_timeout
, hapd
, sta
);
3461 os_free(sta
->fils_pending_assoc_req
);
3462 sta
->fils_pending_assoc_req
= NULL
;
3463 sta
->fils_pending_assoc_req_len
= 0;
3464 wpabuf_free(sta
->fils_hlp_resp
);
3465 sta
->fils_hlp_resp
= NULL
;
3467 if (sta
&& delay_assoc
&& resp
== WLAN_STATUS_SUCCESS
) {
3468 sta
->fils_pending_assoc_req
= tmp
;
3469 sta
->fils_pending_assoc_req_len
= left
;
3470 sta
->fils_pending_assoc_is_reassoc
= reassoc
;
3471 sta
->fils_drv_assoc_finish
= 0;
3472 wpa_printf(MSG_DEBUG
,
3473 "FILS: Waiting for HLP processing before sending (Re)Association Response frame to "
3474 MACSTR
, MAC2STR(sta
->addr
));
3475 eloop_cancel_timeout(fils_hlp_timeout
, hapd
, sta
);
3476 eloop_register_timeout(0, hapd
->conf
->fils_hlp_wait_time
* 1024,
3477 fils_hlp_timeout
, hapd
, sta
);
3480 #endif /* CONFIG_FILS */
3482 reply_res
= send_assoc_resp(hapd
, sta
, mgmt
->sa
, resp
, reassoc
, pos
,
3487 * Remove the station in case tranmission of a success response fails
3488 * (the STA was added associated to the driver) or if the station was
3489 * previously added unassociated.
3491 if (sta
&& ((reply_res
!= WLAN_STATUS_SUCCESS
&&
3492 resp
== WLAN_STATUS_SUCCESS
) || sta
->added_unassoc
)) {
3493 hostapd_drv_sta_remove(hapd
, sta
->addr
);
3494 sta
->added_unassoc
= 0;
3499 static void handle_disassoc(struct hostapd_data
*hapd
,
3500 const struct ieee80211_mgmt
*mgmt
, size_t len
)
3502 struct sta_info
*sta
;
3504 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.disassoc
)) {
3505 wpa_printf(MSG_INFO
, "handle_disassoc - too short payload (len=%lu)",
3506 (unsigned long) len
);
3510 wpa_printf(MSG_DEBUG
, "disassocation: STA=" MACSTR
" reason_code=%d",
3512 le_to_host16(mgmt
->u
.disassoc
.reason_code
));
3514 sta
= ap_get_sta(hapd
, mgmt
->sa
);
3516 wpa_printf(MSG_INFO
, "Station " MACSTR
" trying to disassociate, but it is not associated",
3521 ap_sta_set_authorized(hapd
, sta
, 0);
3522 sta
->last_seq_ctrl
= WLAN_INVALID_MGMT_SEQ
;
3523 sta
->flags
&= ~(WLAN_STA_ASSOC
| WLAN_STA_ASSOC_REQ_OK
);
3524 wpa_auth_sm_event(sta
->wpa_sm
, WPA_DISASSOC
);
3525 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
3526 HOSTAPD_LEVEL_INFO
, "disassociated");
3527 sta
->acct_terminate_cause
= RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST
;
3528 ieee802_1x_notify_port_enabled(sta
->eapol_sm
, 0);
3529 /* Stop Accounting and IEEE 802.1X sessions, but leave the STA
3531 accounting_sta_stop(hapd
, sta
);
3532 ieee802_1x_free_station(hapd
, sta
);
3534 hostapd_drv_br_delete_ip_neigh(hapd
, 4, (u8
*) &sta
->ipaddr
);
3535 ap_sta_ip6addr_del(hapd
, sta
);
3536 hostapd_drv_sta_remove(hapd
, sta
->addr
);
3537 sta
->added_unassoc
= 0;
3539 if (sta
->timeout_next
== STA_NULLFUNC
||
3540 sta
->timeout_next
== STA_DISASSOC
) {
3541 sta
->timeout_next
= STA_DEAUTH
;
3542 eloop_cancel_timeout(ap_handle_timer
, hapd
, sta
);
3543 eloop_register_timeout(AP_DEAUTH_DELAY
, 0, ap_handle_timer
,
3547 mlme_disassociate_indication(
3548 hapd
, sta
, le_to_host16(mgmt
->u
.disassoc
.reason_code
));
3550 /* DMG/IEEE 802.11ad does not use deauthication. Deallocate sta upon
3551 * disassociation. */
3552 if (hapd
->iface
->current_mode
&&
3553 hapd
->iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211AD
) {
3554 sta
->flags
&= ~WLAN_STA_AUTH
;
3555 wpa_auth_sm_event(sta
->wpa_sm
, WPA_DEAUTH
);
3556 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
3557 HOSTAPD_LEVEL_DEBUG
, "deauthenticated");
3558 ap_free_sta(hapd
, sta
);
3563 static void handle_deauth(struct hostapd_data
*hapd
,
3564 const struct ieee80211_mgmt
*mgmt
, size_t len
)
3566 struct sta_info
*sta
;
3568 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.deauth
)) {
3569 wpa_msg(hapd
->msg_ctx
, MSG_DEBUG
, "handle_deauth - too short "
3570 "payload (len=%lu)", (unsigned long) len
);
3574 wpa_msg(hapd
->msg_ctx
, MSG_DEBUG
, "deauthentication: STA=" MACSTR
3576 MAC2STR(mgmt
->sa
), le_to_host16(mgmt
->u
.deauth
.reason_code
));
3578 sta
= ap_get_sta(hapd
, mgmt
->sa
);
3580 wpa_msg(hapd
->msg_ctx
, MSG_DEBUG
, "Station " MACSTR
" trying "
3581 "to deauthenticate, but it is not authenticated",
3586 ap_sta_set_authorized(hapd
, sta
, 0);
3587 sta
->last_seq_ctrl
= WLAN_INVALID_MGMT_SEQ
;
3588 sta
->flags
&= ~(WLAN_STA_AUTH
| WLAN_STA_ASSOC
|
3589 WLAN_STA_ASSOC_REQ_OK
);
3590 wpa_auth_sm_event(sta
->wpa_sm
, WPA_DEAUTH
);
3591 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
3592 HOSTAPD_LEVEL_DEBUG
, "deauthenticated");
3593 mlme_deauthenticate_indication(
3594 hapd
, sta
, le_to_host16(mgmt
->u
.deauth
.reason_code
));
3595 sta
->acct_terminate_cause
= RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST
;
3596 ieee802_1x_notify_port_enabled(sta
->eapol_sm
, 0);
3597 ap_free_sta(hapd
, sta
);
3601 static void handle_beacon(struct hostapd_data
*hapd
,
3602 const struct ieee80211_mgmt
*mgmt
, size_t len
,
3603 struct hostapd_frame_info
*fi
)
3605 struct ieee802_11_elems elems
;
3607 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.beacon
)) {
3608 wpa_printf(MSG_INFO
, "handle_beacon - too short payload (len=%lu)",
3609 (unsigned long) len
);
3613 (void) ieee802_11_parse_elems(mgmt
->u
.beacon
.variable
,
3614 len
- (IEEE80211_HDRLEN
+
3615 sizeof(mgmt
->u
.beacon
)), &elems
,
3618 ap_list_process_beacon(hapd
->iface
, mgmt
, &elems
, fi
);
3622 #ifdef CONFIG_IEEE80211W
3624 static int hostapd_sa_query_action(struct hostapd_data
*hapd
,
3625 const struct ieee80211_mgmt
*mgmt
,
3630 end
= mgmt
->u
.action
.u
.sa_query_resp
.trans_id
+
3631 WLAN_SA_QUERY_TR_ID_LEN
;
3632 if (((u8
*) mgmt
) + len
< end
) {
3633 wpa_printf(MSG_DEBUG
, "IEEE 802.11: Too short SA Query Action "
3634 "frame (len=%lu)", (unsigned long) len
);
3638 ieee802_11_sa_query_action(hapd
, mgmt
->sa
,
3639 mgmt
->u
.action
.u
.sa_query_resp
.action
,
3640 mgmt
->u
.action
.u
.sa_query_resp
.trans_id
);
3645 static int robust_action_frame(u8 category
)
3647 return category
!= WLAN_ACTION_PUBLIC
&&
3648 category
!= WLAN_ACTION_HT
;
3650 #endif /* CONFIG_IEEE80211W */
3653 static int handle_action(struct hostapd_data
*hapd
,
3654 const struct ieee80211_mgmt
*mgmt
, size_t len
,
3657 struct sta_info
*sta
;
3658 sta
= ap_get_sta(hapd
, mgmt
->sa
);
3660 if (len
< IEEE80211_HDRLEN
+ 1) {
3661 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
3662 HOSTAPD_LEVEL_DEBUG
,
3663 "handle_action - too short payload (len=%lu)",
3664 (unsigned long) len
);
3668 if (mgmt
->u
.action
.category
!= WLAN_ACTION_PUBLIC
&&
3669 (sta
== NULL
|| !(sta
->flags
& WLAN_STA_ASSOC
))) {
3670 wpa_printf(MSG_DEBUG
, "IEEE 802.11: Ignored Action "
3671 "frame (category=%u) from unassociated STA " MACSTR
,
3672 mgmt
->u
.action
.category
, MAC2STR(mgmt
->sa
));
3676 #ifdef CONFIG_IEEE80211W
3677 if (sta
&& (sta
->flags
& WLAN_STA_MFP
) &&
3678 !(mgmt
->frame_control
& host_to_le16(WLAN_FC_ISWEP
)) &&
3679 robust_action_frame(mgmt
->u
.action
.category
)) {
3680 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
3681 HOSTAPD_LEVEL_DEBUG
,
3682 "Dropped unprotected Robust Action frame from "
3686 #endif /* CONFIG_IEEE80211W */
3689 u16 fc
= le_to_host16(mgmt
->frame_control
);
3690 u16 seq_ctrl
= le_to_host16(mgmt
->seq_ctrl
);
3692 if ((fc
& WLAN_FC_RETRY
) &&
3693 sta
->last_seq_ctrl
!= WLAN_INVALID_MGMT_SEQ
&&
3694 sta
->last_seq_ctrl
== seq_ctrl
&&
3695 sta
->last_subtype
== WLAN_FC_STYPE_ACTION
) {
3696 hostapd_logger(hapd
, sta
->addr
,
3697 HOSTAPD_MODULE_IEEE80211
,
3698 HOSTAPD_LEVEL_DEBUG
,
3699 "Drop repeated action frame seq_ctrl=0x%x",
3704 sta
->last_seq_ctrl
= seq_ctrl
;
3705 sta
->last_subtype
= WLAN_FC_STYPE_ACTION
;
3708 switch (mgmt
->u
.action
.category
) {
3709 #ifdef CONFIG_IEEE80211R_AP
3710 case WLAN_ACTION_FT
:
3712 wpa_ft_action_rx(sta
->wpa_sm
, (u8
*) &mgmt
->u
.action
,
3713 len
- IEEE80211_HDRLEN
))
3716 #endif /* CONFIG_IEEE80211R_AP */
3717 case WLAN_ACTION_WMM
:
3718 hostapd_wmm_action(hapd
, mgmt
, len
);
3720 #ifdef CONFIG_IEEE80211W
3721 case WLAN_ACTION_SA_QUERY
:
3722 return hostapd_sa_query_action(hapd
, mgmt
, len
);
3723 #endif /* CONFIG_IEEE80211W */
3724 #ifdef CONFIG_WNM_AP
3725 case WLAN_ACTION_WNM
:
3726 ieee802_11_rx_wnm_action_ap(hapd
, mgmt
, len
);
3728 #endif /* CONFIG_WNM_AP */
3730 case WLAN_ACTION_FST
:
3731 if (hapd
->iface
->fst
)
3732 fst_rx_action(hapd
->iface
->fst
, mgmt
, len
);
3734 wpa_printf(MSG_DEBUG
,
3735 "FST: Ignore FST Action frame - no FST attached");
3737 #endif /* CONFIG_FST */
3738 case WLAN_ACTION_PUBLIC
:
3739 case WLAN_ACTION_PROTECTED_DUAL
:
3740 #ifdef CONFIG_IEEE80211N
3741 if (len
>= IEEE80211_HDRLEN
+ 2 &&
3742 mgmt
->u
.action
.u
.public_action
.action
==
3743 WLAN_PA_20_40_BSS_COEX
) {
3744 hostapd_2040_coex_action(hapd
, mgmt
, len
);
3747 #endif /* CONFIG_IEEE80211N */
3749 if (len
>= IEEE80211_HDRLEN
+ 6 &&
3750 mgmt
->u
.action
.u
.vs_public_action
.action
==
3751 WLAN_PA_VENDOR_SPECIFIC
&&
3752 WPA_GET_BE24(mgmt
->u
.action
.u
.vs_public_action
.oui
) ==
3754 mgmt
->u
.action
.u
.vs_public_action
.variable
[0] ==
3756 const u8
*pos
, *end
;
3758 pos
= mgmt
->u
.action
.u
.vs_public_action
.oui
;
3759 end
= ((const u8
*) mgmt
) + len
;
3760 hostapd_dpp_rx_action(hapd
, mgmt
->sa
, pos
, end
- pos
,
3764 if (len
>= IEEE80211_HDRLEN
+ 2 &&
3765 (mgmt
->u
.action
.u
.public_action
.action
==
3766 WLAN_PA_GAS_INITIAL_RESP
||
3767 mgmt
->u
.action
.u
.public_action
.action
==
3768 WLAN_PA_GAS_COMEBACK_RESP
)) {
3769 const u8
*pos
, *end
;
3771 pos
= &mgmt
->u
.action
.u
.public_action
.action
;
3772 end
= ((const u8
*) mgmt
) + len
;
3773 gas_query_ap_rx(hapd
->gas
, mgmt
->sa
,
3774 mgmt
->u
.action
.category
,
3775 pos
, end
- pos
, hapd
->iface
->freq
);
3778 #endif /* CONFIG_DPP */
3779 if (hapd
->public_action_cb
) {
3780 hapd
->public_action_cb(hapd
->public_action_cb_ctx
,
3784 if (hapd
->public_action_cb2
) {
3785 hapd
->public_action_cb2(hapd
->public_action_cb2_ctx
,
3789 if (hapd
->public_action_cb
|| hapd
->public_action_cb2
)
3792 case WLAN_ACTION_VENDOR_SPECIFIC
:
3793 if (hapd
->vendor_action_cb
) {
3794 if (hapd
->vendor_action_cb(hapd
->vendor_action_cb_ctx
,
3796 hapd
->iface
->freq
) == 0)
3800 case WLAN_ACTION_RADIO_MEASUREMENT
:
3801 hostapd_handle_radio_measurement(hapd
, (const u8
*) mgmt
, len
);
3805 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
3806 HOSTAPD_LEVEL_DEBUG
,
3807 "handle_action - unknown action category %d or invalid "
3809 mgmt
->u
.action
.category
);
3810 if (!is_multicast_ether_addr(mgmt
->da
) &&
3811 !(mgmt
->u
.action
.category
& 0x80) &&
3812 !is_multicast_ether_addr(mgmt
->sa
)) {
3813 struct ieee80211_mgmt
*resp
;
3816 * IEEE 802.11-REVma/D9.0 - 7.3.1.11
3817 * Return the Action frame to the source without change
3818 * except that MSB of the Category set to 1.
3820 wpa_printf(MSG_DEBUG
, "IEEE 802.11: Return unknown Action "
3821 "frame back to sender");
3822 resp
= os_memdup(mgmt
, len
);
3825 os_memcpy(resp
->da
, resp
->sa
, ETH_ALEN
);
3826 os_memcpy(resp
->sa
, hapd
->own_addr
, ETH_ALEN
);
3827 os_memcpy(resp
->bssid
, hapd
->own_addr
, ETH_ALEN
);
3828 resp
->u
.action
.category
|= 0x80;
3830 if (hostapd_drv_send_mlme(hapd
, resp
, len
, 0) < 0) {
3831 wpa_printf(MSG_ERROR
, "IEEE 802.11: Failed to send "
3842 * ieee802_11_mgmt - process incoming IEEE 802.11 management frames
3843 * @hapd: hostapd BSS data structure (the BSS to which the management frame was
3845 * @buf: management frame data (starting from IEEE 802.11 header)
3846 * @len: length of frame data in octets
3847 * @fi: meta data about received frame (signal level, etc.)
3849 * Process all incoming IEEE 802.11 management frames. This will be called for
3850 * each frame received from the kernel driver through wlan#ap interface. In
3851 * addition, it can be called to re-inserted pending frames (e.g., when using
3852 * external RADIUS server as an MAC ACL).
3854 int ieee802_11_mgmt(struct hostapd_data
*hapd
, const u8
*buf
, size_t len
,
3855 struct hostapd_frame_info
*fi
)
3857 struct ieee80211_mgmt
*mgmt
;
3861 int ssi_signal
= fi
? fi
->ssi_signal
: 0;
3869 freq
= hapd
->iface
->freq
;
3871 mgmt
= (struct ieee80211_mgmt
*) buf
;
3872 fc
= le_to_host16(mgmt
->frame_control
);
3873 stype
= WLAN_FC_GET_STYPE(fc
);
3875 if (stype
== WLAN_FC_STYPE_BEACON
) {
3876 handle_beacon(hapd
, mgmt
, len
, fi
);
3880 if (!is_broadcast_ether_addr(mgmt
->bssid
) &&
3882 /* Invitation responses can be sent with the peer MAC as BSSID */
3883 !((hapd
->conf
->p2p
& P2P_GROUP_OWNER
) &&
3884 stype
== WLAN_FC_STYPE_ACTION
) &&
3885 #endif /* CONFIG_P2P */
3887 !(hapd
->conf
->mesh
& MESH_ENABLED
) &&
3888 #endif /* CONFIG_MESH */
3889 os_memcmp(mgmt
->bssid
, hapd
->own_addr
, ETH_ALEN
) != 0) {
3890 wpa_printf(MSG_INFO
, "MGMT: BSSID=" MACSTR
" not our address",
3891 MAC2STR(mgmt
->bssid
));
3896 if (stype
== WLAN_FC_STYPE_PROBE_REQ
) {
3897 handle_probe_req(hapd
, mgmt
, len
, ssi_signal
);
3901 if ((!is_broadcast_ether_addr(mgmt
->da
) ||
3902 stype
!= WLAN_FC_STYPE_ACTION
) &&
3903 os_memcmp(mgmt
->da
, hapd
->own_addr
, ETH_ALEN
) != 0) {
3904 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
3905 HOSTAPD_LEVEL_DEBUG
,
3906 "MGMT: DA=" MACSTR
" not our address",
3911 if (hapd
->iconf
->track_sta_max_num
)
3912 sta_track_add(hapd
->iface
, mgmt
->sa
, ssi_signal
);
3915 case WLAN_FC_STYPE_AUTH
:
3916 wpa_printf(MSG_DEBUG
, "mgmt::auth");
3917 handle_auth(hapd
, mgmt
, len
);
3920 case WLAN_FC_STYPE_ASSOC_REQ
:
3921 wpa_printf(MSG_DEBUG
, "mgmt::assoc_req");
3922 handle_assoc(hapd
, mgmt
, len
, 0);
3925 case WLAN_FC_STYPE_REASSOC_REQ
:
3926 wpa_printf(MSG_DEBUG
, "mgmt::reassoc_req");
3927 handle_assoc(hapd
, mgmt
, len
, 1);
3930 case WLAN_FC_STYPE_DISASSOC
:
3931 wpa_printf(MSG_DEBUG
, "mgmt::disassoc");
3932 handle_disassoc(hapd
, mgmt
, len
);
3935 case WLAN_FC_STYPE_DEAUTH
:
3936 wpa_msg(hapd
->msg_ctx
, MSG_DEBUG
, "mgmt::deauth");
3937 handle_deauth(hapd
, mgmt
, len
);
3940 case WLAN_FC_STYPE_ACTION
:
3941 wpa_printf(MSG_DEBUG
, "mgmt::action");
3942 ret
= handle_action(hapd
, mgmt
, len
, freq
);
3945 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
3946 HOSTAPD_LEVEL_DEBUG
,
3947 "unknown mgmt frame subtype %d", stype
);
3955 static void handle_auth_cb(struct hostapd_data
*hapd
,
3956 const struct ieee80211_mgmt
*mgmt
,
3959 u16 auth_alg
, auth_transaction
, status_code
;
3960 struct sta_info
*sta
;
3962 sta
= ap_get_sta(hapd
, mgmt
->da
);
3964 wpa_printf(MSG_INFO
, "handle_auth_cb: STA " MACSTR
" not found",
3969 auth_alg
= le_to_host16(mgmt
->u
.auth
.auth_alg
);
3970 auth_transaction
= le_to_host16(mgmt
->u
.auth
.auth_transaction
);
3971 status_code
= le_to_host16(mgmt
->u
.auth
.status_code
);
3974 hostapd_logger(hapd
, mgmt
->da
, HOSTAPD_MODULE_IEEE80211
,
3975 HOSTAPD_LEVEL_NOTICE
,
3976 "did not acknowledge authentication response");
3980 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.auth
)) {
3981 wpa_printf(MSG_INFO
, "handle_auth_cb - too short payload (len=%lu)",
3982 (unsigned long) len
);
3986 if (status_code
== WLAN_STATUS_SUCCESS
&&
3987 ((auth_alg
== WLAN_AUTH_OPEN
&& auth_transaction
== 2) ||
3988 (auth_alg
== WLAN_AUTH_SHARED_KEY
&& auth_transaction
== 4))) {
3989 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
3990 HOSTAPD_LEVEL_INFO
, "authenticated");
3991 sta
->flags
|= WLAN_STA_AUTH
;
3992 if (sta
->added_unassoc
)
3993 hostapd_set_sta_flags(hapd
, sta
);
3998 if (status_code
!= WLAN_STATUS_SUCCESS
&& sta
->added_unassoc
) {
3999 hostapd_drv_sta_remove(hapd
, sta
->addr
);
4000 sta
->added_unassoc
= 0;
4005 static void hostapd_set_wds_encryption(struct hostapd_data
*hapd
,
4006 struct sta_info
*sta
,
4010 struct hostapd_ssid
*ssid
= &hapd
->conf
->ssid
;
4012 if (hapd
->conf
->ieee802_1x
|| hapd
->conf
->wpa
)
4015 for (i
= 0; i
< 4; i
++) {
4016 if (ssid
->wep
.key
[i
] &&
4017 hostapd_drv_set_key(ifname_wds
, hapd
, WPA_ALG_WEP
, NULL
, i
,
4018 i
== ssid
->wep
.idx
, NULL
, 0,
4019 ssid
->wep
.key
[i
], ssid
->wep
.len
[i
])) {
4020 wpa_printf(MSG_WARNING
,
4021 "Could not set WEP keys for WDS interface; %s",
4029 static void handle_assoc_cb(struct hostapd_data
*hapd
,
4030 const struct ieee80211_mgmt
*mgmt
,
4031 size_t len
, int reassoc
, int ok
)
4034 struct sta_info
*sta
;
4037 sta
= ap_get_sta(hapd
, mgmt
->da
);
4039 wpa_printf(MSG_INFO
, "handle_assoc_cb: STA " MACSTR
" not found",
4044 if (len
< IEEE80211_HDRLEN
+ (reassoc
? sizeof(mgmt
->u
.reassoc_resp
) :
4045 sizeof(mgmt
->u
.assoc_resp
))) {
4046 wpa_printf(MSG_INFO
,
4047 "handle_assoc_cb(reassoc=%d) - too short payload (len=%lu)",
4048 reassoc
, (unsigned long) len
);
4049 hostapd_drv_sta_remove(hapd
, sta
->addr
);
4054 status
= le_to_host16(mgmt
->u
.reassoc_resp
.status_code
);
4056 status
= le_to_host16(mgmt
->u
.assoc_resp
.status_code
);
4059 hostapd_logger(hapd
, mgmt
->da
, HOSTAPD_MODULE_IEEE80211
,
4060 HOSTAPD_LEVEL_DEBUG
,
4061 "did not acknowledge association response");
4062 sta
->flags
&= ~WLAN_STA_ASSOC_REQ_OK
;
4063 /* The STA is added only in case of SUCCESS */
4064 if (status
== WLAN_STATUS_SUCCESS
)
4065 hostapd_drv_sta_remove(hapd
, sta
->addr
);
4070 if (status
!= WLAN_STATUS_SUCCESS
)
4073 /* Stop previous accounting session, if one is started, and allocate
4074 * new session id for the new session. */
4075 accounting_sta_stop(hapd
, sta
);
4077 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
4079 "associated (aid %d)",
4082 if (sta
->flags
& WLAN_STA_ASSOC
)
4084 sta
->flags
|= WLAN_STA_ASSOC
;
4085 sta
->flags
&= ~WLAN_STA_WNM_SLEEP_MODE
;
4086 if ((!hapd
->conf
->ieee802_1x
&& !hapd
->conf
->wpa
&&
4087 !hapd
->conf
->osen
) ||
4088 sta
->auth_alg
== WLAN_AUTH_FILS_SK
||
4089 sta
->auth_alg
== WLAN_AUTH_FILS_SK_PFS
||
4090 sta
->auth_alg
== WLAN_AUTH_FILS_PK
||
4091 sta
->auth_alg
== WLAN_AUTH_FT
) {
4093 * Open, static WEP, FT protocol, or FILS; no separate
4094 * authorization step.
4096 ap_sta_set_authorized(hapd
, sta
, 1);
4100 mlme_reassociate_indication(hapd
, sta
);
4102 mlme_associate_indication(hapd
, sta
);
4104 #ifdef CONFIG_IEEE80211W
4105 sta
->sa_query_timed_out
= 0;
4106 #endif /* CONFIG_IEEE80211W */
4108 if (sta
->eapol_sm
== NULL
) {
4110 * This STA does not use RADIUS server for EAP authentication,
4111 * so bind it to the selected VLAN interface now, since the
4112 * interface selection is not going to change anymore.
4114 if (ap_sta_bind_vlan(hapd
, sta
) < 0)
4116 } else if (sta
->vlan_id
) {
4117 /* VLAN ID already set (e.g., by PMKSA caching), so bind STA */
4118 if (ap_sta_bind_vlan(hapd
, sta
) < 0)
4122 hostapd_set_sta_flags(hapd
, sta
);
4124 if (!(sta
->flags
& WLAN_STA_WDS
) && sta
->pending_wds_enable
) {
4125 wpa_printf(MSG_DEBUG
, "Enable 4-address WDS mode for STA "
4126 MACSTR
" based on pending request",
4127 MAC2STR(sta
->addr
));
4128 sta
->pending_wds_enable
= 0;
4129 sta
->flags
|= WLAN_STA_WDS
;
4132 if (sta
->flags
& WLAN_STA_WDS
) {
4134 char ifname_wds
[IFNAMSIZ
+ 1];
4136 wpa_printf(MSG_DEBUG
, "Reenable 4-address WDS mode for STA "
4138 MAC2STR(sta
->addr
), sta
->aid
);
4139 ret
= hostapd_set_wds_sta(hapd
, ifname_wds
, sta
->addr
,
4142 hostapd_set_wds_encryption(hapd
, sta
, ifname_wds
);
4145 if (sta
->auth_alg
== WLAN_AUTH_FT
)
4146 wpa_auth_sm_event(sta
->wpa_sm
, WPA_ASSOC_FT
);
4148 wpa_auth_sm_event(sta
->wpa_sm
, WPA_ASSOC
);
4149 hapd
->new_assoc_sta_cb(hapd
, sta
, !new_assoc
);
4150 ieee802_1x_notify_port_enabled(sta
->eapol_sm
, 1);
4153 if ((sta
->auth_alg
== WLAN_AUTH_FILS_SK
||
4154 sta
->auth_alg
== WLAN_AUTH_FILS_SK_PFS
||
4155 sta
->auth_alg
== WLAN_AUTH_FILS_PK
) &&
4156 fils_set_tk(sta
->wpa_sm
) < 0) {
4157 wpa_printf(MSG_DEBUG
, "FILS: TK configuration failed");
4158 ap_sta_disconnect(hapd
, sta
, sta
->addr
,
4159 WLAN_REASON_UNSPECIFIED
);
4162 #endif /* CONFIG_FILS */
4164 if (sta
->pending_eapol_rx
) {
4165 struct os_reltime now
, age
;
4167 os_get_reltime(&now
);
4168 os_reltime_sub(&now
, &sta
->pending_eapol_rx
->rx_time
, &age
);
4169 if (age
.sec
== 0 && age
.usec
< 200000) {
4170 wpa_printf(MSG_DEBUG
,
4171 "Process pending EAPOL frame that was received from " MACSTR
" just before association notification",
4172 MAC2STR(sta
->addr
));
4175 wpabuf_head(sta
->pending_eapol_rx
->buf
),
4176 wpabuf_len(sta
->pending_eapol_rx
->buf
));
4178 wpabuf_free(sta
->pending_eapol_rx
->buf
);
4179 os_free(sta
->pending_eapol_rx
);
4180 sta
->pending_eapol_rx
= NULL
;
4185 static void handle_deauth_cb(struct hostapd_data
*hapd
,
4186 const struct ieee80211_mgmt
*mgmt
,
4189 struct sta_info
*sta
;
4190 if (is_multicast_ether_addr(mgmt
->da
))
4192 sta
= ap_get_sta(hapd
, mgmt
->da
);
4194 wpa_printf(MSG_DEBUG
, "handle_deauth_cb: STA " MACSTR
4195 " not found", MAC2STR(mgmt
->da
));
4199 wpa_printf(MSG_DEBUG
, "STA " MACSTR
" acknowledged deauth",
4200 MAC2STR(sta
->addr
));
4202 wpa_printf(MSG_DEBUG
, "STA " MACSTR
" did not acknowledge "
4203 "deauth", MAC2STR(sta
->addr
));
4205 ap_sta_deauth_cb(hapd
, sta
);
4209 static void handle_disassoc_cb(struct hostapd_data
*hapd
,
4210 const struct ieee80211_mgmt
*mgmt
,
4213 struct sta_info
*sta
;
4214 if (is_multicast_ether_addr(mgmt
->da
))
4216 sta
= ap_get_sta(hapd
, mgmt
->da
);
4218 wpa_printf(MSG_DEBUG
, "handle_disassoc_cb: STA " MACSTR
4219 " not found", MAC2STR(mgmt
->da
));
4223 wpa_printf(MSG_DEBUG
, "STA " MACSTR
" acknowledged disassoc",
4224 MAC2STR(sta
->addr
));
4226 wpa_printf(MSG_DEBUG
, "STA " MACSTR
" did not acknowledge "
4227 "disassoc", MAC2STR(sta
->addr
));
4229 ap_sta_disassoc_cb(hapd
, sta
);
4233 static void handle_action_cb(struct hostapd_data
*hapd
,
4234 const struct ieee80211_mgmt
*mgmt
,
4237 struct sta_info
*sta
;
4238 const struct rrm_measurement_report_element
*report
;
4240 if (is_multicast_ether_addr(mgmt
->da
))
4243 if (len
>= IEEE80211_HDRLEN
+ 6 &&
4244 mgmt
->u
.action
.category
== WLAN_ACTION_PUBLIC
&&
4245 mgmt
->u
.action
.u
.vs_public_action
.action
==
4246 WLAN_PA_VENDOR_SPECIFIC
&&
4247 WPA_GET_BE24(mgmt
->u
.action
.u
.vs_public_action
.oui
) ==
4249 mgmt
->u
.action
.u
.vs_public_action
.variable
[0] ==
4251 const u8
*pos
, *end
;
4253 pos
= &mgmt
->u
.action
.u
.vs_public_action
.variable
[1];
4254 end
= ((const u8
*) mgmt
) + len
;
4255 hostapd_dpp_tx_status(hapd
, mgmt
->da
, pos
, end
- pos
, ok
);
4258 if (len
>= IEEE80211_HDRLEN
+ 2 &&
4259 mgmt
->u
.action
.category
== WLAN_ACTION_PUBLIC
&&
4260 (mgmt
->u
.action
.u
.public_action
.action
==
4261 WLAN_PA_GAS_INITIAL_REQ
||
4262 mgmt
->u
.action
.u
.public_action
.action
==
4263 WLAN_PA_GAS_COMEBACK_REQ
)) {
4264 const u8
*pos
, *end
;
4266 pos
= mgmt
->u
.action
.u
.public_action
.variable
;
4267 end
= ((const u8
*) mgmt
) + len
;
4268 gas_query_ap_tx_status(hapd
->gas
, mgmt
->da
, pos
, end
- pos
, ok
);
4271 #endif /* CONFIG_DPP */
4272 sta
= ap_get_sta(hapd
, mgmt
->da
);
4274 wpa_printf(MSG_DEBUG
, "handle_action_cb: STA " MACSTR
4275 " not found", MAC2STR(mgmt
->da
));
4279 if (len
< 24 + 5 + sizeof(*report
))
4281 report
= (const struct rrm_measurement_report_element
*)
4282 &mgmt
->u
.action
.u
.rrm
.variable
[2];
4283 if (mgmt
->u
.action
.category
== WLAN_ACTION_RADIO_MEASUREMENT
&&
4284 mgmt
->u
.action
.u
.rrm
.action
== WLAN_RRM_RADIO_MEASUREMENT_REQUEST
&&
4285 report
->eid
== WLAN_EID_MEASURE_REQUEST
&&
4287 report
->type
== MEASURE_TYPE_BEACON
)
4288 hostapd_rrm_beacon_req_tx_status(hapd
, mgmt
, len
, ok
);
4293 * ieee802_11_mgmt_cb - Process management frame TX status callback
4294 * @hapd: hostapd BSS data structure (the BSS from which the management frame
4296 * @buf: management frame data (starting from IEEE 802.11 header)
4297 * @len: length of frame data in octets
4298 * @stype: management frame subtype from frame control field
4299 * @ok: Whether the frame was ACK'ed
4301 void ieee802_11_mgmt_cb(struct hostapd_data
*hapd
, const u8
*buf
, size_t len
,
4304 const struct ieee80211_mgmt
*mgmt
;
4305 mgmt
= (const struct ieee80211_mgmt
*) buf
;
4307 #ifdef CONFIG_TESTING_OPTIONS
4308 if (hapd
->ext_mgmt_frame_handling
) {
4309 size_t hex_len
= 2 * len
+ 1;
4310 char *hex
= os_malloc(hex_len
);
4313 wpa_snprintf_hex(hex
, hex_len
, buf
, len
);
4314 wpa_msg(hapd
->msg_ctx
, MSG_INFO
,
4315 "MGMT-TX-STATUS stype=%u ok=%d buf=%s",
4321 #endif /* CONFIG_TESTING_OPTIONS */
4324 case WLAN_FC_STYPE_AUTH
:
4325 wpa_printf(MSG_DEBUG
, "mgmt::auth cb");
4326 handle_auth_cb(hapd
, mgmt
, len
, ok
);
4328 case WLAN_FC_STYPE_ASSOC_RESP
:
4329 wpa_printf(MSG_DEBUG
, "mgmt::assoc_resp cb");
4330 handle_assoc_cb(hapd
, mgmt
, len
, 0, ok
);
4332 case WLAN_FC_STYPE_REASSOC_RESP
:
4333 wpa_printf(MSG_DEBUG
, "mgmt::reassoc_resp cb");
4334 handle_assoc_cb(hapd
, mgmt
, len
, 1, ok
);
4336 case WLAN_FC_STYPE_PROBE_RESP
:
4337 wpa_printf(MSG_EXCESSIVE
, "mgmt::proberesp cb ok=%d", ok
);
4339 case WLAN_FC_STYPE_DEAUTH
:
4340 wpa_printf(MSG_DEBUG
, "mgmt::deauth cb");
4341 handle_deauth_cb(hapd
, mgmt
, len
, ok
);
4343 case WLAN_FC_STYPE_DISASSOC
:
4344 wpa_printf(MSG_DEBUG
, "mgmt::disassoc cb");
4345 handle_disassoc_cb(hapd
, mgmt
, len
, ok
);
4347 case WLAN_FC_STYPE_ACTION
:
4348 wpa_printf(MSG_DEBUG
, "mgmt::action cb ok=%d", ok
);
4349 handle_action_cb(hapd
, mgmt
, len
, ok
);
4352 wpa_printf(MSG_INFO
, "unknown mgmt cb frame subtype %d", stype
);
4358 int ieee802_11_get_mib(struct hostapd_data
*hapd
, char *buf
, size_t buflen
)
4365 int ieee802_11_get_mib_sta(struct hostapd_data
*hapd
, struct sta_info
*sta
,
4366 char *buf
, size_t buflen
)
4373 void hostapd_tx_status(struct hostapd_data
*hapd
, const u8
*addr
,
4374 const u8
*buf
, size_t len
, int ack
)
4376 struct sta_info
*sta
;
4377 struct hostapd_iface
*iface
= hapd
->iface
;
4379 sta
= ap_get_sta(hapd
, addr
);
4380 if (sta
== NULL
&& iface
->num_bss
> 1) {
4382 for (j
= 0; j
< iface
->num_bss
; j
++) {
4383 hapd
= iface
->bss
[j
];
4384 sta
= ap_get_sta(hapd
, addr
);
4389 if (sta
== NULL
|| !(sta
->flags
& WLAN_STA_ASSOC
))
4391 if (sta
->flags
& WLAN_STA_PENDING_POLL
) {
4392 wpa_printf(MSG_DEBUG
, "STA " MACSTR
" %s pending "
4393 "activity poll", MAC2STR(sta
->addr
),
4394 ack
? "ACKed" : "did not ACK");
4396 sta
->flags
&= ~WLAN_STA_PENDING_POLL
;
4399 ieee802_1x_tx_status(hapd
, sta
, buf
, len
, ack
);
4403 void hostapd_eapol_tx_status(struct hostapd_data
*hapd
, const u8
*dst
,
4404 const u8
*data
, size_t len
, int ack
)
4406 struct sta_info
*sta
;
4407 struct hostapd_iface
*iface
= hapd
->iface
;
4409 sta
= ap_get_sta(hapd
, dst
);
4410 if (sta
== NULL
&& iface
->num_bss
> 1) {
4412 for (j
= 0; j
< iface
->num_bss
; j
++) {
4413 hapd
= iface
->bss
[j
];
4414 sta
= ap_get_sta(hapd
, dst
);
4419 if (sta
== NULL
|| !(sta
->flags
& WLAN_STA_ASSOC
)) {
4420 wpa_printf(MSG_DEBUG
, "Ignore TX status for Data frame to STA "
4421 MACSTR
" that is not currently associated",
4426 ieee802_1x_eapol_tx_status(hapd
, sta
, data
, len
, ack
);
4430 void hostapd_client_poll_ok(struct hostapd_data
*hapd
, const u8
*addr
)
4432 struct sta_info
*sta
;
4433 struct hostapd_iface
*iface
= hapd
->iface
;
4435 sta
= ap_get_sta(hapd
, addr
);
4436 if (sta
== NULL
&& iface
->num_bss
> 1) {
4438 for (j
= 0; j
< iface
->num_bss
; j
++) {
4439 hapd
= iface
->bss
[j
];
4440 sta
= ap_get_sta(hapd
, addr
);
4447 wpa_msg(hapd
->msg_ctx
, MSG_INFO
, AP_STA_POLL_OK MACSTR
,
4448 MAC2STR(sta
->addr
));
4449 if (!(sta
->flags
& WLAN_STA_PENDING_POLL
))
4452 wpa_printf(MSG_DEBUG
, "STA " MACSTR
" ACKed pending "
4453 "activity poll", MAC2STR(sta
->addr
));
4454 sta
->flags
&= ~WLAN_STA_PENDING_POLL
;
4458 void ieee802_11_rx_from_unknown(struct hostapd_data
*hapd
, const u8
*src
,
4461 struct sta_info
*sta
;
4463 sta
= ap_get_sta(hapd
, src
);
4465 ((sta
->flags
& WLAN_STA_ASSOC
) ||
4466 ((sta
->flags
& WLAN_STA_ASSOC_REQ_OK
) && wds
))) {
4467 if (!hapd
->conf
->wds_sta
)
4470 if ((sta
->flags
& (WLAN_STA_ASSOC
| WLAN_STA_ASSOC_REQ_OK
)) ==
4471 WLAN_STA_ASSOC_REQ_OK
) {
4472 wpa_printf(MSG_DEBUG
,
4473 "Postpone 4-address WDS mode enabling for STA "
4474 MACSTR
" since TX status for AssocResp is not yet known",
4475 MAC2STR(sta
->addr
));
4476 sta
->pending_wds_enable
= 1;
4480 if (wds
&& !(sta
->flags
& WLAN_STA_WDS
)) {
4482 char ifname_wds
[IFNAMSIZ
+ 1];
4484 wpa_printf(MSG_DEBUG
, "Enable 4-address WDS mode for "
4485 "STA " MACSTR
" (aid %u)",
4486 MAC2STR(sta
->addr
), sta
->aid
);
4487 sta
->flags
|= WLAN_STA_WDS
;
4488 ret
= hostapd_set_wds_sta(hapd
, ifname_wds
,
4489 sta
->addr
, sta
->aid
, 1);
4491 hostapd_set_wds_encryption(hapd
, sta
,
4497 wpa_printf(MSG_DEBUG
, "Data/PS-poll frame from not associated STA "
4498 MACSTR
, MAC2STR(src
));
4499 if (is_multicast_ether_addr(src
)) {
4500 /* Broadcast bit set in SA?! Ignore the frame silently. */
4504 if (sta
&& (sta
->flags
& WLAN_STA_ASSOC_REQ_OK
)) {
4505 wpa_printf(MSG_DEBUG
, "Association Response to the STA has "
4506 "already been sent, but no TX status yet known - "
4507 "ignore Class 3 frame issue with " MACSTR
,
4512 if (sta
&& (sta
->flags
& WLAN_STA_AUTH
))
4513 hostapd_drv_sta_disassoc(
4515 WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA
);
4517 hostapd_drv_sta_deauth(
4519 WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA
);
4523 #endif /* CONFIG_NATIVE_WINDOWS */