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 "common/dpp.h"
25 #include "common/ocv.h"
26 #include "radius/radius.h"
27 #include "radius/radius_client.h"
33 #include "ieee802_11_auth.h"
35 #include "ieee802_1x.h"
37 #include "pmksa_cache_auth.h"
40 #include "accounting.h"
41 #include "ap_config.h"
43 #include "p2p_hostapd.h"
44 #include "ap_drv_ops.h"
46 #include "hw_features.h"
47 #include "ieee802_11.h"
53 #include "dpp_hostapd.h"
54 #include "gas_query_ap.h"
58 static struct wpabuf
*
59 prepare_auth_resp_fils(struct hostapd_data
*hapd
,
60 struct sta_info
*sta
, u16
*resp
,
61 struct rsn_pmksa_cache_entry
*pmksa
,
62 struct wpabuf
*erp_resp
,
63 const u8
*msk
, size_t msk_len
,
65 #endif /* CONFIG_FILS */
66 static void handle_auth(struct hostapd_data
*hapd
,
67 const struct ieee80211_mgmt
*mgmt
, size_t len
,
68 int rssi
, int from_queue
);
71 u8
* hostapd_eid_multi_ap(struct hostapd_data
*hapd
, u8
*eid
)
75 if (!hapd
->conf
->multi_ap
)
77 if (hapd
->conf
->multi_ap
& BACKHAUL_BSS
)
78 multi_ap_val
|= MULTI_AP_BACKHAUL_BSS
;
79 if (hapd
->conf
->multi_ap
& FRONTHAUL_BSS
)
80 multi_ap_val
|= MULTI_AP_FRONTHAUL_BSS
;
82 return eid
+ add_multi_ap_ie(eid
, 9, multi_ap_val
);
86 u8
* hostapd_eid_supp_rates(struct hostapd_data
*hapd
, u8
*eid
)
91 if (hapd
->iface
->current_rates
== NULL
)
94 *pos
++ = WLAN_EID_SUPP_RATES
;
95 num
= hapd
->iface
->num_rates
;
96 if (hapd
->iconf
->ieee80211n
&& hapd
->iconf
->require_ht
)
98 if (hapd
->iconf
->ieee80211ac
&& hapd
->iconf
->require_vht
)
101 /* rest of the rates are encoded in Extended supported
107 for (i
= 0, count
= 0; i
< hapd
->iface
->num_rates
&& count
< num
;
110 *pos
= hapd
->iface
->current_rates
[i
].rate
/ 5;
111 if (hapd
->iface
->current_rates
[i
].flags
& HOSTAPD_RATE_BASIC
)
116 if (hapd
->iconf
->ieee80211n
&& hapd
->iconf
->require_ht
&& count
< 8) {
118 *pos
++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_HT_PHY
;
121 if (hapd
->iconf
->ieee80211ac
&& hapd
->iconf
->require_vht
&& count
< 8) {
123 *pos
++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_VHT_PHY
;
130 u8
* hostapd_eid_ext_supp_rates(struct hostapd_data
*hapd
, u8
*eid
)
135 if (hapd
->iface
->current_rates
== NULL
)
138 num
= hapd
->iface
->num_rates
;
139 if (hapd
->iconf
->ieee80211n
&& hapd
->iconf
->require_ht
)
141 if (hapd
->iconf
->ieee80211ac
&& hapd
->iconf
->require_vht
)
147 *pos
++ = WLAN_EID_EXT_SUPP_RATES
;
149 for (i
= 0, count
= 0; i
< hapd
->iface
->num_rates
&& count
< num
+ 8;
153 continue; /* already in SuppRates IE */
154 *pos
= hapd
->iface
->current_rates
[i
].rate
/ 5;
155 if (hapd
->iface
->current_rates
[i
].flags
& HOSTAPD_RATE_BASIC
)
160 if (hapd
->iconf
->ieee80211n
&& hapd
->iconf
->require_ht
) {
163 *pos
++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_HT_PHY
;
166 if (hapd
->iconf
->ieee80211ac
&& hapd
->iconf
->require_vht
) {
169 *pos
++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_VHT_PHY
;
176 u16
hostapd_own_capab_info(struct hostapd_data
*hapd
)
178 int capab
= WLAN_CAPABILITY_ESS
;
183 /* Check if any of configured channels require DFS */
184 dfs
= hostapd_is_dfs_required(hapd
->iface
);
186 wpa_printf(MSG_WARNING
, "Failed to check if DFS is required; ret=%d",
191 if (hapd
->iface
->num_sta_no_short_preamble
== 0 &&
192 hapd
->iconf
->preamble
== SHORT_PREAMBLE
)
193 capab
|= WLAN_CAPABILITY_SHORT_PREAMBLE
;
195 privacy
= hapd
->conf
->ssid
.wep
.keys_set
;
197 if (hapd
->conf
->ieee802_1x
&&
198 (hapd
->conf
->default_wep_key_len
||
199 hapd
->conf
->individual_wep_key_len
))
206 if (hapd
->conf
->osen
)
208 #endif /* CONFIG_HS20 */
211 capab
|= WLAN_CAPABILITY_PRIVACY
;
213 if (hapd
->iface
->current_mode
&&
214 hapd
->iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211G
&&
215 hapd
->iface
->num_sta_no_short_slot_time
== 0)
216 capab
|= WLAN_CAPABILITY_SHORT_SLOT_TIME
;
219 * Currently, Spectrum Management capability bit is set when directly
220 * requested in configuration by spectrum_mgmt_required or when AP is
221 * running on DFS channel.
222 * TODO: Also consider driver support for TPC to set Spectrum Mgmt bit
224 if (hapd
->iface
->current_mode
&&
225 hapd
->iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211A
&&
226 (hapd
->iconf
->spectrum_mgmt_required
|| dfs
))
227 capab
|= WLAN_CAPABILITY_SPECTRUM_MGMT
;
229 for (i
= 0; i
< RRM_CAPABILITIES_IE_LEN
; i
++) {
230 if (hapd
->conf
->radio_measurements
[i
]) {
231 capab
|= IEEE80211_CAP_RRM
;
240 #ifndef CONFIG_NO_RC4
241 static u16
auth_shared_key(struct hostapd_data
*hapd
, struct sta_info
*sta
,
242 u16 auth_transaction
, const u8
*challenge
,
245 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
247 "authentication (shared key, transaction %d)",
250 if (auth_transaction
== 1) {
251 if (!sta
->challenge
) {
252 /* Generate a pseudo-random challenge */
255 sta
->challenge
= os_zalloc(WLAN_AUTH_CHALLENGE_LEN
);
256 if (sta
->challenge
== NULL
)
257 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
259 if (os_get_random(key
, sizeof(key
)) < 0) {
260 os_free(sta
->challenge
);
261 sta
->challenge
= NULL
;
262 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
265 rc4_skip(key
, sizeof(key
), 0,
266 sta
->challenge
, WLAN_AUTH_CHALLENGE_LEN
);
271 if (auth_transaction
!= 3)
272 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
275 if (!iswep
|| !sta
->challenge
|| !challenge
||
276 os_memcmp_const(sta
->challenge
, challenge
,
277 WLAN_AUTH_CHALLENGE_LEN
)) {
278 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
280 "shared key authentication - invalid "
281 "challenge-response");
282 return WLAN_STATUS_CHALLENGE_FAIL
;
285 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
287 "authentication OK (shared key)");
288 sta
->flags
|= WLAN_STA_AUTH
;
289 wpa_auth_sm_event(sta
->wpa_sm
, WPA_AUTH
);
290 os_free(sta
->challenge
);
291 sta
->challenge
= NULL
;
295 #endif /* CONFIG_NO_RC4 */
298 static int send_auth_reply(struct hostapd_data
*hapd
,
299 const u8
*dst
, const u8
*bssid
,
300 u16 auth_alg
, u16 auth_transaction
, u16 resp
,
301 const u8
*ies
, size_t ies_len
, const char *dbg
)
303 struct ieee80211_mgmt
*reply
;
306 int reply_res
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
308 rlen
= IEEE80211_HDRLEN
+ sizeof(reply
->u
.auth
) + ies_len
;
309 buf
= os_zalloc(rlen
);
313 reply
= (struct ieee80211_mgmt
*) buf
;
314 reply
->frame_control
= IEEE80211_FC(WLAN_FC_TYPE_MGMT
,
316 os_memcpy(reply
->da
, dst
, ETH_ALEN
);
317 os_memcpy(reply
->sa
, hapd
->own_addr
, ETH_ALEN
);
318 os_memcpy(reply
->bssid
, bssid
, ETH_ALEN
);
320 reply
->u
.auth
.auth_alg
= host_to_le16(auth_alg
);
321 reply
->u
.auth
.auth_transaction
= host_to_le16(auth_transaction
);
322 reply
->u
.auth
.status_code
= host_to_le16(resp
);
325 os_memcpy(reply
->u
.auth
.variable
, ies
, ies_len
);
327 wpa_printf(MSG_DEBUG
, "authentication reply: STA=" MACSTR
328 " auth_alg=%d auth_transaction=%d resp=%d (IE len=%lu) (dbg=%s)",
329 MAC2STR(dst
), auth_alg
, auth_transaction
,
330 resp
, (unsigned long) ies_len
, dbg
);
331 if (hostapd_drv_send_mlme(hapd
, reply
, rlen
, 0) < 0)
332 wpa_printf(MSG_INFO
, "send_auth_reply: send failed");
334 reply_res
= WLAN_STATUS_SUCCESS
;
342 #ifdef CONFIG_IEEE80211R_AP
343 static void handle_auth_ft_finish(void *ctx
, const u8
*dst
, const u8
*bssid
,
344 u16 auth_transaction
, u16 status
,
345 const u8
*ies
, size_t ies_len
)
347 struct hostapd_data
*hapd
= ctx
;
348 struct sta_info
*sta
;
351 reply_res
= send_auth_reply(hapd
, dst
, bssid
, WLAN_AUTH_FT
,
352 auth_transaction
, status
, ies
, ies_len
,
355 sta
= ap_get_sta(hapd
, dst
);
359 if (sta
->added_unassoc
&& (reply_res
!= WLAN_STATUS_SUCCESS
||
360 status
!= WLAN_STATUS_SUCCESS
)) {
361 hostapd_drv_sta_remove(hapd
, sta
->addr
);
362 sta
->added_unassoc
= 0;
366 if (status
!= WLAN_STATUS_SUCCESS
)
369 hostapd_logger(hapd
, dst
, HOSTAPD_MODULE_IEEE80211
,
370 HOSTAPD_LEVEL_DEBUG
, "authentication OK (FT)");
371 sta
->flags
|= WLAN_STA_AUTH
;
372 mlme_authenticate_indication(hapd
, sta
);
374 #endif /* CONFIG_IEEE80211R_AP */
379 static void sae_set_state(struct sta_info
*sta
, enum sae_state state
,
382 wpa_printf(MSG_DEBUG
, "SAE: State %s -> %s for peer " MACSTR
" (%s)",
383 sae_state_txt(sta
->sae
->state
), sae_state_txt(state
),
384 MAC2STR(sta
->addr
), reason
);
385 sta
->sae
->state
= state
;
389 static struct wpabuf
* auth_build_sae_commit(struct hostapd_data
*hapd
,
390 struct sta_info
*sta
, int update
)
393 const char *password
= NULL
;
394 struct sae_password_entry
*pw
;
395 const char *rx_id
= NULL
;
398 rx_id
= sta
->sae
->tmp
->pw_id
;
400 for (pw
= hapd
->conf
->sae_passwords
; pw
; pw
= pw
->next
) {
401 if (!is_broadcast_ether_addr(pw
->peer_addr
) &&
402 os_memcmp(pw
->peer_addr
, sta
->addr
, ETH_ALEN
) != 0)
404 if ((rx_id
&& !pw
->identifier
) || (!rx_id
&& pw
->identifier
))
406 if (rx_id
&& pw
->identifier
&&
407 os_strcmp(rx_id
, pw
->identifier
) != 0)
409 password
= pw
->password
;
413 password
= hapd
->conf
->ssid
.wpa_passphrase
;
415 wpa_printf(MSG_DEBUG
, "SAE: No password available");
420 sae_prepare_commit(hapd
->own_addr
, sta
->addr
,
421 (u8
*) password
, os_strlen(password
), rx_id
,
423 wpa_printf(MSG_DEBUG
, "SAE: Could not pick PWE");
427 if (pw
&& pw
->vlan_id
) {
428 if (!sta
->sae
->tmp
) {
430 "SAE: No temporary data allocated - cannot store VLAN ID");
433 sta
->sae
->tmp
->vlan_id
= pw
->vlan_id
;
436 buf
= wpabuf_alloc(SAE_COMMIT_MAX_LEN
+
437 (rx_id
? 3 + os_strlen(rx_id
) : 0));
440 sae_write_commit(sta
->sae
, buf
, sta
->sae
->tmp
?
441 sta
->sae
->tmp
->anti_clogging_token
: NULL
, rx_id
);
447 static struct wpabuf
* auth_build_sae_confirm(struct hostapd_data
*hapd
,
448 struct sta_info
*sta
)
452 buf
= wpabuf_alloc(SAE_CONFIRM_MAX_LEN
);
456 sae_write_confirm(sta
->sae
, buf
);
462 static int auth_sae_send_commit(struct hostapd_data
*hapd
,
463 struct sta_info
*sta
,
464 const u8
*bssid
, int update
)
469 data
= auth_build_sae_commit(hapd
, sta
, update
);
470 if (!data
&& sta
->sae
->tmp
&& sta
->sae
->tmp
->pw_id
)
471 return WLAN_STATUS_UNKNOWN_PASSWORD_IDENTIFIER
;
473 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
475 reply_res
= send_auth_reply(hapd
, sta
->addr
, bssid
, WLAN_AUTH_SAE
, 1,
476 WLAN_STATUS_SUCCESS
, wpabuf_head(data
),
477 wpabuf_len(data
), "sae-send-commit");
485 static int auth_sae_send_confirm(struct hostapd_data
*hapd
,
486 struct sta_info
*sta
,
492 data
= auth_build_sae_confirm(hapd
, sta
);
494 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
496 reply_res
= send_auth_reply(hapd
, sta
->addr
, bssid
, WLAN_AUTH_SAE
, 2,
497 WLAN_STATUS_SUCCESS
, wpabuf_head(data
),
498 wpabuf_len(data
), "sae-send-confirm");
506 static int use_sae_anti_clogging(struct hostapd_data
*hapd
)
508 struct sta_info
*sta
;
509 unsigned int open
= 0;
511 if (hapd
->conf
->sae_anti_clogging_threshold
== 0)
514 for (sta
= hapd
->sta_list
; sta
; sta
= sta
->next
) {
517 if (sta
->sae
->state
!= SAE_COMMITTED
&&
518 sta
->sae
->state
!= SAE_CONFIRMED
)
521 if (open
>= hapd
->conf
->sae_anti_clogging_threshold
)
525 /* In addition to already existing open SAE sessions, check whether
526 * there are enough pending commit messages in the processing queue to
527 * potentially result in too many open sessions. */
528 if (open
+ dl_list_len(&hapd
->sae_commit_queue
) >=
529 hapd
->conf
->sae_anti_clogging_threshold
)
536 static u8
sae_token_hash(struct hostapd_data
*hapd
, const u8
*addr
)
538 u8 hash
[SHA256_MAC_LEN
];
540 hmac_sha256(hapd
->sae_token_key
, sizeof(hapd
->sae_token_key
),
541 addr
, ETH_ALEN
, hash
);
546 static int check_sae_token(struct hostapd_data
*hapd
, const u8
*addr
,
547 const u8
*token
, size_t token_len
)
549 u8 mac
[SHA256_MAC_LEN
];
555 if (token_len
!= SHA256_MAC_LEN
)
557 idx
= sae_token_hash(hapd
, addr
);
558 token_idx
= hapd
->sae_pending_token_idx
[idx
];
559 if (token_idx
== 0 || token_idx
!= WPA_GET_BE16(token
)) {
560 wpa_printf(MSG_DEBUG
, "SAE: Invalid anti-clogging token from "
561 MACSTR
" - token_idx 0x%04x, expected 0x%04x",
562 MAC2STR(addr
), WPA_GET_BE16(token
), token_idx
);
570 if (hmac_sha256_vector(hapd
->sae_token_key
, sizeof(hapd
->sae_token_key
),
571 2, addrs
, len
, mac
) < 0 ||
572 os_memcmp_const(token
+ 2, &mac
[2], SHA256_MAC_LEN
- 2) != 0)
575 hapd
->sae_pending_token_idx
[idx
] = 0; /* invalidate used token */
581 static struct wpabuf
* auth_build_token_req(struct hostapd_data
*hapd
,
582 int group
, const u8
*addr
)
586 struct os_reltime now
;
593 os_get_reltime(&now
);
594 if (!os_reltime_initialized(&hapd
->last_sae_token_key_update
) ||
595 os_reltime_expired(&now
, &hapd
->last_sae_token_key_update
, 60) ||
596 hapd
->sae_token_idx
== 0xffff) {
597 if (random_get_bytes(hapd
->sae_token_key
,
598 sizeof(hapd
->sae_token_key
)) < 0)
600 wpa_hexdump(MSG_DEBUG
, "SAE: Updated token key",
601 hapd
->sae_token_key
, sizeof(hapd
->sae_token_key
));
602 hapd
->last_sae_token_key_update
= now
;
603 hapd
->sae_token_idx
= 0;
604 os_memset(hapd
->sae_pending_token_idx
, 0,
605 sizeof(hapd
->sae_pending_token_idx
));
608 buf
= wpabuf_alloc(sizeof(le16
) + SHA256_MAC_LEN
);
612 wpabuf_put_le16(buf
, group
); /* Finite Cyclic Group */
614 p_idx
= sae_token_hash(hapd
, addr
);
615 token_idx
= hapd
->sae_pending_token_idx
[p_idx
];
617 hapd
->sae_token_idx
++;
618 token_idx
= hapd
->sae_token_idx
;
619 hapd
->sae_pending_token_idx
[p_idx
] = token_idx
;
621 WPA_PUT_BE16(idx
, token_idx
);
622 token
= wpabuf_put(buf
, SHA256_MAC_LEN
);
626 len
[1] = sizeof(idx
);
627 if (hmac_sha256_vector(hapd
->sae_token_key
, sizeof(hapd
->sae_token_key
),
628 2, addrs
, len
, token
) < 0) {
632 WPA_PUT_BE16(token
, token_idx
);
638 static int sae_check_big_sync(struct hostapd_data
*hapd
, struct sta_info
*sta
)
640 if (sta
->sae
->sync
> hapd
->conf
->sae_sync
) {
641 sae_set_state(sta
, SAE_NOTHING
, "Sync > dot11RSNASAESync");
649 static void auth_sae_retransmit_timer(void *eloop_ctx
, void *eloop_data
)
651 struct hostapd_data
*hapd
= eloop_ctx
;
652 struct sta_info
*sta
= eloop_data
;
655 if (sae_check_big_sync(hapd
, sta
))
658 wpa_printf(MSG_DEBUG
, "SAE: Auth SAE retransmit timer for " MACSTR
659 " (sync=%d state=%s)",
660 MAC2STR(sta
->addr
), sta
->sae
->sync
,
661 sae_state_txt(sta
->sae
->state
));
663 switch (sta
->sae
->state
) {
665 ret
= auth_sae_send_commit(hapd
, sta
, hapd
->own_addr
, 0);
666 eloop_register_timeout(0,
667 hapd
->dot11RSNASAERetransPeriod
* 1000,
668 auth_sae_retransmit_timer
, hapd
, sta
);
671 ret
= auth_sae_send_confirm(hapd
, sta
, hapd
->own_addr
);
672 eloop_register_timeout(0,
673 hapd
->dot11RSNASAERetransPeriod
* 1000,
674 auth_sae_retransmit_timer
, hapd
, sta
);
681 if (ret
!= WLAN_STATUS_SUCCESS
)
682 wpa_printf(MSG_INFO
, "SAE: Failed to retransmit: ret=%d", ret
);
686 void sae_clear_retransmit_timer(struct hostapd_data
*hapd
, struct sta_info
*sta
)
688 eloop_cancel_timeout(auth_sae_retransmit_timer
, hapd
, sta
);
692 static void sae_set_retransmit_timer(struct hostapd_data
*hapd
,
693 struct sta_info
*sta
)
695 if (!(hapd
->conf
->mesh
& MESH_ENABLED
))
698 eloop_cancel_timeout(auth_sae_retransmit_timer
, hapd
, sta
);
699 eloop_register_timeout(0, hapd
->dot11RSNASAERetransPeriod
* 1000,
700 auth_sae_retransmit_timer
, hapd
, sta
);
704 static void sae_sme_send_external_auth_status(struct hostapd_data
*hapd
,
705 struct sta_info
*sta
, u16 status
)
707 struct external_auth params
;
709 os_memset(¶ms
, 0, sizeof(params
));
710 params
.status
= status
;
711 params
.bssid
= sta
->addr
;
712 if (status
== WLAN_STATUS_SUCCESS
&& sta
->sae
&&
713 !hapd
->conf
->disable_pmksa_caching
)
714 params
.pmkid
= sta
->sae
->pmkid
;
716 hostapd_drv_send_external_auth_status(hapd
, ¶ms
);
720 void sae_accept_sta(struct hostapd_data
*hapd
, struct sta_info
*sta
)
722 #ifndef CONFIG_NO_VLAN
723 struct vlan_description vlan_desc
;
725 if (sta
->sae
->tmp
&& sta
->sae
->tmp
->vlan_id
> 0) {
726 wpa_printf(MSG_DEBUG
, "SAE: Assign STA " MACSTR
728 MAC2STR(sta
->addr
), sta
->sae
->tmp
->vlan_id
);
730 os_memset(&vlan_desc
, 0, sizeof(vlan_desc
));
731 vlan_desc
.notempty
= 1;
732 vlan_desc
.untagged
= sta
->sae
->tmp
->vlan_id
;
733 if (!hostapd_vlan_valid(hapd
->conf
->vlan
, &vlan_desc
)) {
735 "Invalid VLAN ID %d in sae_password",
736 sta
->sae
->tmp
->vlan_id
);
740 if (ap_sta_set_vlan(hapd
, sta
, &vlan_desc
) < 0 ||
741 ap_sta_bind_vlan(hapd
, sta
) < 0) {
743 "Failed to assign VLAN ID %d from sae_password to "
744 MACSTR
, sta
->sae
->tmp
->vlan_id
,
749 #endif /* CONFIG_NO_VLAN */
751 sta
->flags
|= WLAN_STA_AUTH
;
752 sta
->auth_alg
= WLAN_AUTH_SAE
;
753 mlme_authenticate_indication(hapd
, sta
);
754 wpa_auth_sm_event(sta
->wpa_sm
, WPA_AUTH
);
755 sae_set_state(sta
, SAE_ACCEPTED
, "Accept Confirm");
756 wpa_auth_pmksa_add_sae(hapd
->wpa_auth
, sta
->addr
,
757 sta
->sae
->pmk
, sta
->sae
->pmkid
);
758 sae_sme_send_external_auth_status(hapd
, sta
, WLAN_STATUS_SUCCESS
);
762 static int sae_sm_step(struct hostapd_data
*hapd
, struct sta_info
*sta
,
763 const u8
*bssid
, u8 auth_transaction
, int allow_reuse
,
770 if (auth_transaction
!= 1 && auth_transaction
!= 2)
771 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
773 wpa_printf(MSG_DEBUG
, "SAE: Peer " MACSTR
" state=%s auth_trans=%u",
774 MAC2STR(sta
->addr
), sae_state_txt(sta
->sae
->state
),
776 switch (sta
->sae
->state
) {
778 if (auth_transaction
== 1) {
779 ret
= auth_sae_send_commit(hapd
, sta
, bssid
,
783 sae_set_state(sta
, SAE_COMMITTED
, "Sent Commit");
785 if (sae_process_commit(sta
->sae
) < 0)
786 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
789 * In mesh case, both Commit and Confirm can be sent
790 * immediately. In infrastructure BSS, only a single
791 * Authentication frame (Commit) is expected from the AP
792 * here and the second one (Confirm) will be sent once
793 * the STA has sent its second Authentication frame
796 if (hapd
->conf
->mesh
& MESH_ENABLED
) {
798 * Send both Commit and Confirm immediately
799 * based on SAE finite state machine
800 * Nothing -> Confirm transition.
802 ret
= auth_sae_send_confirm(hapd
, sta
, bssid
);
805 sae_set_state(sta
, SAE_CONFIRMED
,
806 "Sent Confirm (mesh)");
809 * For infrastructure BSS, send only the Commit
810 * message now to get alternating sequence of
811 * Authentication frames between the AP and STA.
812 * Confirm will be sent in
813 * Committed -> Confirmed/Accepted transition
814 * when receiving Confirm from STA.
818 sae_set_retransmit_timer(hapd
, sta
);
820 hostapd_logger(hapd
, sta
->addr
,
821 HOSTAPD_MODULE_IEEE80211
,
823 "SAE confirm before commit");
827 sae_clear_retransmit_timer(hapd
, sta
);
828 if (auth_transaction
== 1) {
829 if (sae_process_commit(sta
->sae
) < 0)
830 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
832 ret
= auth_sae_send_confirm(hapd
, sta
, bssid
);
835 sae_set_state(sta
, SAE_CONFIRMED
, "Sent Confirm");
837 sae_set_retransmit_timer(hapd
, sta
);
838 } else if (hapd
->conf
->mesh
& MESH_ENABLED
) {
840 * In mesh case, follow SAE finite state machine and
841 * send Commit now, if sync count allows.
843 if (sae_check_big_sync(hapd
, sta
))
844 return WLAN_STATUS_SUCCESS
;
847 ret
= auth_sae_send_commit(hapd
, sta
, bssid
, 0);
851 sae_set_retransmit_timer(hapd
, sta
);
854 * For instructure BSS, send the postponed Confirm from
855 * Nothing -> Confirmed transition that was reduced to
856 * Nothing -> Committed above.
858 ret
= auth_sae_send_confirm(hapd
, sta
, bssid
);
862 sae_set_state(sta
, SAE_CONFIRMED
, "Sent Confirm");
865 * Since this was triggered on Confirm RX, run another
866 * step to get to Accepted without waiting for
869 return sae_sm_step(hapd
, sta
, bssid
, auth_transaction
,
874 sae_clear_retransmit_timer(hapd
, sta
);
875 if (auth_transaction
== 1) {
876 if (sae_check_big_sync(hapd
, sta
))
877 return WLAN_STATUS_SUCCESS
;
880 ret
= auth_sae_send_commit(hapd
, sta
, bssid
, 1);
884 if (sae_process_commit(sta
->sae
) < 0)
885 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
887 ret
= auth_sae_send_confirm(hapd
, sta
, bssid
);
891 sae_set_retransmit_timer(hapd
, sta
);
893 sta
->sae
->send_confirm
= 0xffff;
894 sae_accept_sta(hapd
, sta
);
898 if (auth_transaction
== 1 &&
899 (hapd
->conf
->mesh
& MESH_ENABLED
)) {
900 wpa_printf(MSG_DEBUG
, "SAE: remove the STA (" MACSTR
901 ") doing reauthentication",
903 wpa_auth_pmksa_remove(hapd
->wpa_auth
, sta
->addr
);
904 ap_free_sta(hapd
, sta
);
906 } else if (auth_transaction
== 1) {
907 wpa_printf(MSG_DEBUG
, "SAE: Start reauthentication");
908 ret
= auth_sae_send_commit(hapd
, sta
, bssid
, 1);
911 sae_set_state(sta
, SAE_COMMITTED
, "Sent Commit");
913 if (sae_process_commit(sta
->sae
) < 0)
914 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
916 sae_set_retransmit_timer(hapd
, sta
);
918 if (sae_check_big_sync(hapd
, sta
))
919 return WLAN_STATUS_SUCCESS
;
922 ret
= auth_sae_send_confirm(hapd
, sta
, bssid
);
923 sae_clear_temp_data(sta
->sae
);
929 wpa_printf(MSG_ERROR
, "SAE: invalid state %d",
931 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
933 return WLAN_STATUS_SUCCESS
;
937 static void sae_pick_next_group(struct hostapd_data
*hapd
, struct sta_info
*sta
)
939 struct sae_data
*sae
= sta
->sae
;
940 int i
, *groups
= hapd
->conf
->sae_groups
;
941 int default_groups
[] = { 19, 0 };
943 if (sae
->state
!= SAE_COMMITTED
)
946 wpa_printf(MSG_DEBUG
, "SAE: Previously selected group: %d", sae
->group
);
949 groups
= default_groups
;
950 for (i
= 0; groups
[i
] > 0; i
++) {
951 if (sae
->group
== groups
[i
])
955 if (groups
[i
] <= 0) {
956 wpa_printf(MSG_DEBUG
,
957 "SAE: Previously selected group not found from the current configuration");
963 if (groups
[i
] <= 0) {
964 wpa_printf(MSG_DEBUG
,
965 "SAE: No alternative group enabled");
969 if (sae_set_group(sae
, groups
[i
]) < 0)
974 wpa_printf(MSG_DEBUG
, "SAE: Selected new group: %d", groups
[i
]);
978 static void handle_auth_sae(struct hostapd_data
*hapd
, struct sta_info
*sta
,
979 const struct ieee80211_mgmt
*mgmt
, size_t len
,
980 u16 auth_transaction
, u16 status_code
)
982 int resp
= WLAN_STATUS_SUCCESS
;
983 struct wpabuf
*data
= NULL
;
984 int *groups
= hapd
->conf
->sae_groups
;
985 int default_groups
[] = { 19, 0 };
990 groups
= default_groups
;
992 #ifdef CONFIG_TESTING_OPTIONS
993 if (hapd
->conf
->sae_reflection_attack
&& auth_transaction
== 1) {
994 wpa_printf(MSG_DEBUG
, "SAE: TESTING - reflection attack");
995 pos
= mgmt
->u
.auth
.variable
;
996 end
= ((const u8
*) mgmt
) + len
;
997 send_auth_reply(hapd
, mgmt
->sa
, mgmt
->bssid
, WLAN_AUTH_SAE
,
998 auth_transaction
, resp
, pos
, end
- pos
,
999 "auth-sae-reflection-attack");
1003 if (hapd
->conf
->sae_commit_override
&& auth_transaction
== 1) {
1004 wpa_printf(MSG_DEBUG
, "SAE: TESTING - commit override");
1005 send_auth_reply(hapd
, mgmt
->sa
, mgmt
->bssid
, WLAN_AUTH_SAE
,
1006 auth_transaction
, resp
,
1007 wpabuf_head(hapd
->conf
->sae_commit_override
),
1008 wpabuf_len(hapd
->conf
->sae_commit_override
),
1009 "sae-commit-override");
1012 #endif /* CONFIG_TESTING_OPTIONS */
1014 if (auth_transaction
!= 1 ||
1015 status_code
!= WLAN_STATUS_SUCCESS
) {
1019 sta
->sae
= os_zalloc(sizeof(*sta
->sae
));
1024 sae_set_state(sta
, SAE_NOTHING
, "Init");
1028 if (sta
->mesh_sae_pmksa_caching
) {
1029 wpa_printf(MSG_DEBUG
,
1030 "SAE: Cancel use of mesh PMKSA caching because peer starts SAE authentication");
1031 wpa_auth_pmksa_remove(hapd
->wpa_auth
, sta
->addr
);
1032 sta
->mesh_sae_pmksa_caching
= 0;
1035 if (auth_transaction
== 1) {
1036 const u8
*token
= NULL
;
1037 size_t token_len
= 0;
1038 int allow_reuse
= 0;
1040 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1041 HOSTAPD_LEVEL_DEBUG
,
1042 "start SAE authentication (RX commit, status=%u (%s))",
1043 status_code
, status2str(status_code
));
1045 if ((hapd
->conf
->mesh
& MESH_ENABLED
) &&
1046 status_code
== WLAN_STATUS_ANTI_CLOGGING_TOKEN_REQ
&&
1048 pos
= mgmt
->u
.auth
.variable
;
1049 end
= ((const u8
*) mgmt
) + len
;
1050 if (pos
+ sizeof(le16
) > end
) {
1051 wpa_printf(MSG_ERROR
,
1052 "SAE: Too short anti-clogging token request");
1053 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1056 resp
= sae_group_allowed(sta
->sae
, groups
,
1058 if (resp
!= WLAN_STATUS_SUCCESS
) {
1059 wpa_printf(MSG_ERROR
,
1060 "SAE: Invalid group in anti-clogging token request");
1063 pos
+= sizeof(le16
);
1065 wpabuf_free(sta
->sae
->tmp
->anti_clogging_token
);
1066 sta
->sae
->tmp
->anti_clogging_token
=
1067 wpabuf_alloc_copy(pos
, end
- pos
);
1068 if (sta
->sae
->tmp
->anti_clogging_token
== NULL
) {
1069 wpa_printf(MSG_ERROR
,
1070 "SAE: Failed to alloc for anti-clogging token");
1071 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1076 * IEEE Std 802.11-2012, 11.3.8.6.4: If the Status code
1077 * is 76, a new Commit Message shall be constructed
1078 * with the Anti-Clogging Token from the received
1079 * Authentication frame, and the commit-scalar and
1080 * COMMIT-ELEMENT previously sent.
1082 resp
= auth_sae_send_commit(hapd
, sta
, mgmt
->bssid
, 0);
1083 if (resp
!= WLAN_STATUS_SUCCESS
) {
1084 wpa_printf(MSG_ERROR
,
1085 "SAE: Failed to send commit message");
1088 sae_set_state(sta
, SAE_COMMITTED
,
1089 "Sent Commit (anti-clogging token case in mesh)");
1091 sae_set_retransmit_timer(hapd
, sta
);
1095 if ((hapd
->conf
->mesh
& MESH_ENABLED
) &&
1097 WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED
&&
1099 wpa_printf(MSG_DEBUG
,
1100 "SAE: Peer did not accept our SAE group");
1101 sae_pick_next_group(hapd
, sta
);
1105 if (status_code
!= WLAN_STATUS_SUCCESS
)
1108 if (!(hapd
->conf
->mesh
& MESH_ENABLED
) &&
1109 sta
->sae
->state
== SAE_COMMITTED
) {
1110 /* This is needed in the infrastructure BSS case to
1111 * address a sequence where a STA entry may remain in
1112 * hostapd across two attempts to do SAE authentication
1113 * by the same STA. The second attempt may end up trying
1114 * to use a different group and that would not be
1115 * allowed if we remain in Committed state with the
1116 * previously set parameters. */
1117 pos
= mgmt
->u
.auth
.variable
;
1118 end
= ((const u8
*) mgmt
) + len
;
1119 if (end
- pos
>= (int) sizeof(le16
) &&
1120 sae_group_allowed(sta
->sae
, groups
,
1121 WPA_GET_LE16(pos
)) ==
1122 WLAN_STATUS_SUCCESS
) {
1123 /* Do not waste resources deriving the same PWE
1124 * again since the same group is reused. */
1125 sae_set_state(sta
, SAE_NOTHING
,
1126 "Allow previous PWE to be reused");
1129 sae_set_state(sta
, SAE_NOTHING
,
1130 "Clear existing state to allow restart");
1131 sae_clear_data(sta
->sae
);
1135 resp
= sae_parse_commit(sta
->sae
, mgmt
->u
.auth
.variable
,
1136 ((const u8
*) mgmt
) + len
-
1137 mgmt
->u
.auth
.variable
, &token
,
1138 &token_len
, groups
);
1139 if (resp
== SAE_SILENTLY_DISCARD
) {
1140 wpa_printf(MSG_DEBUG
,
1141 "SAE: Drop commit message from " MACSTR
" due to reflection attack",
1142 MAC2STR(sta
->addr
));
1146 if (resp
== WLAN_STATUS_UNKNOWN_PASSWORD_IDENTIFIER
) {
1147 wpa_msg(hapd
->msg_ctx
, MSG_INFO
,
1148 WPA_EVENT_SAE_UNKNOWN_PASSWORD_IDENTIFIER
1149 MACSTR
, MAC2STR(sta
->addr
));
1150 sae_clear_retransmit_timer(hapd
, sta
);
1151 sae_set_state(sta
, SAE_NOTHING
,
1152 "Unknown Password Identifier");
1156 if (token
&& check_sae_token(hapd
, sta
->addr
, token
, token_len
)
1158 wpa_printf(MSG_DEBUG
, "SAE: Drop commit message with "
1159 "incorrect token from " MACSTR
,
1160 MAC2STR(sta
->addr
));
1161 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1165 if (resp
!= WLAN_STATUS_SUCCESS
)
1168 if (!token
&& use_sae_anti_clogging(hapd
) && !allow_reuse
) {
1169 wpa_printf(MSG_DEBUG
,
1170 "SAE: Request anti-clogging token from "
1171 MACSTR
, MAC2STR(sta
->addr
));
1172 data
= auth_build_token_req(hapd
, sta
->sae
->group
,
1174 resp
= WLAN_STATUS_ANTI_CLOGGING_TOKEN_REQ
;
1175 if (hapd
->conf
->mesh
& MESH_ENABLED
)
1176 sae_set_state(sta
, SAE_NOTHING
,
1177 "Request anti-clogging token case in mesh");
1181 resp
= sae_sm_step(hapd
, sta
, mgmt
->bssid
, auth_transaction
,
1182 allow_reuse
, &sta_removed
);
1183 } else if (auth_transaction
== 2) {
1184 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1185 HOSTAPD_LEVEL_DEBUG
,
1186 "SAE authentication (RX confirm, status=%u (%s))",
1187 status_code
, status2str(status_code
));
1188 if (status_code
!= WLAN_STATUS_SUCCESS
)
1190 if (sta
->sae
->state
>= SAE_CONFIRMED
||
1191 !(hapd
->conf
->mesh
& MESH_ENABLED
)) {
1194 u16 peer_send_confirm
;
1196 var
= mgmt
->u
.auth
.variable
;
1197 var_len
= ((u8
*) mgmt
) + len
- mgmt
->u
.auth
.variable
;
1199 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1203 peer_send_confirm
= WPA_GET_LE16(var
);
1205 if (sta
->sae
->state
== SAE_ACCEPTED
&&
1206 (peer_send_confirm
<= sta
->sae
->rc
||
1207 peer_send_confirm
== 0xffff)) {
1208 wpa_printf(MSG_DEBUG
,
1209 "SAE: Silently ignore unexpected Confirm from peer "
1211 " (peer-send-confirm=%u Rc=%u)",
1213 peer_send_confirm
, sta
->sae
->rc
);
1217 if (sae_check_confirm(sta
->sae
, var
, var_len
) < 0) {
1218 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1221 sta
->sae
->rc
= peer_send_confirm
;
1223 resp
= sae_sm_step(hapd
, sta
, mgmt
->bssid
, auth_transaction
, 0,
1226 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1227 HOSTAPD_LEVEL_DEBUG
,
1228 "unexpected SAE authentication transaction %u (status=%u (%s))",
1229 auth_transaction
, status_code
,
1230 status2str(status_code
));
1231 if (status_code
!= WLAN_STATUS_SUCCESS
)
1233 resp
= WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION
;
1237 if (!sta_removed
&& resp
!= WLAN_STATUS_SUCCESS
) {
1238 pos
= mgmt
->u
.auth
.variable
;
1239 end
= ((const u8
*) mgmt
) + len
;
1241 /* Copy the Finite Cyclic Group field from the request if we
1242 * rejected it as unsupported group. */
1243 if (resp
== WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED
&&
1244 !data
&& end
- pos
>= 2)
1245 data
= wpabuf_alloc_copy(pos
, 2);
1247 sae_sme_send_external_auth_status(hapd
, sta
, resp
);
1248 send_auth_reply(hapd
, mgmt
->sa
, mgmt
->bssid
, WLAN_AUTH_SAE
,
1249 auth_transaction
, resp
,
1250 data
? wpabuf_head(data
) : (u8
*) "",
1251 data
? wpabuf_len(data
) : 0, "auth-sae");
1255 if (!sta_removed
&& sta
->added_unassoc
&&
1256 (resp
!= WLAN_STATUS_SUCCESS
||
1257 status_code
!= WLAN_STATUS_SUCCESS
)) {
1258 hostapd_drv_sta_remove(hapd
, sta
->addr
);
1259 sta
->added_unassoc
= 0;
1266 * auth_sae_init_committed - Send COMMIT and start SAE in committed state
1267 * @hapd: BSS data for the device initiating the authentication
1268 * @sta: the peer to which commit authentication frame is sent
1270 * This function implements Init event handling (IEEE Std 802.11-2012,
1271 * 11.3.8.6.3) in which initial COMMIT message is sent. Prior to calling, the
1272 * sta->sae structure should be initialized appropriately via a call to
1273 * sae_prepare_commit().
1275 int auth_sae_init_committed(struct hostapd_data
*hapd
, struct sta_info
*sta
)
1279 if (!sta
->sae
|| !sta
->sae
->tmp
)
1282 if (sta
->sae
->state
!= SAE_NOTHING
)
1285 ret
= auth_sae_send_commit(hapd
, sta
, hapd
->own_addr
, 0);
1289 sae_set_state(sta
, SAE_COMMITTED
, "Init and sent commit");
1291 sae_set_retransmit_timer(hapd
, sta
);
1297 void auth_sae_process_commit(void *eloop_ctx
, void *user_ctx
)
1299 struct hostapd_data
*hapd
= eloop_ctx
;
1300 struct hostapd_sae_commit_queue
*q
;
1301 unsigned int queue_len
;
1303 q
= dl_list_first(&hapd
->sae_commit_queue
,
1304 struct hostapd_sae_commit_queue
, list
);
1307 wpa_printf(MSG_DEBUG
,
1308 "SAE: Process next available message from queue");
1309 dl_list_del(&q
->list
);
1310 handle_auth(hapd
, (const struct ieee80211_mgmt
*) q
->msg
, q
->len
,
1314 if (eloop_is_timeout_registered(auth_sae_process_commit
, hapd
, NULL
))
1316 queue_len
= dl_list_len(&hapd
->sae_commit_queue
);
1317 eloop_register_timeout(0, queue_len
* 10000, auth_sae_process_commit
,
1322 static void auth_sae_queue(struct hostapd_data
*hapd
,
1323 const struct ieee80211_mgmt
*mgmt
, size_t len
,
1326 struct hostapd_sae_commit_queue
*q
, *q2
;
1327 unsigned int queue_len
;
1328 const struct ieee80211_mgmt
*mgmt2
;
1330 queue_len
= dl_list_len(&hapd
->sae_commit_queue
);
1331 if (queue_len
>= 15) {
1332 wpa_printf(MSG_DEBUG
,
1333 "SAE: No more room in message queue - drop the new frame from "
1334 MACSTR
, MAC2STR(mgmt
->sa
));
1338 wpa_printf(MSG_DEBUG
, "SAE: Queue Authentication message from "
1339 MACSTR
" for processing (queue_len %u)", MAC2STR(mgmt
->sa
),
1341 q
= os_zalloc(sizeof(*q
) + len
);
1346 os_memcpy(q
->msg
, mgmt
, len
);
1348 /* Check whether there is already a queued Authentication frame from the
1349 * same station with the same transaction number and if so, replace that
1350 * queue entry with the new one. This avoids issues with a peer that
1351 * sends multiple times (e.g., due to frequent SAE retries). There is no
1352 * point in us trying to process the old attempts after a new one has
1353 * obsoleted them. */
1354 dl_list_for_each(q2
, &hapd
->sae_commit_queue
,
1355 struct hostapd_sae_commit_queue
, list
) {
1356 mgmt2
= (const struct ieee80211_mgmt
*) q2
->msg
;
1357 if (os_memcmp(mgmt
->sa
, mgmt2
->sa
, ETH_ALEN
) == 0 &&
1358 mgmt
->u
.auth
.auth_transaction
==
1359 mgmt2
->u
.auth
.auth_transaction
) {
1360 wpa_printf(MSG_DEBUG
,
1361 "SAE: Replace queued message from same STA with same transaction number");
1362 dl_list_add(&q2
->list
, &q
->list
);
1363 dl_list_del(&q2
->list
);
1369 /* No pending identical entry, so add to the end of the queue */
1370 dl_list_add_tail(&hapd
->sae_commit_queue
, &q
->list
);
1373 if (eloop_is_timeout_registered(auth_sae_process_commit
, hapd
, NULL
))
1375 eloop_register_timeout(0, queue_len
* 10000, auth_sae_process_commit
,
1380 static int auth_sae_queued_addr(struct hostapd_data
*hapd
, const u8
*addr
)
1382 struct hostapd_sae_commit_queue
*q
;
1383 const struct ieee80211_mgmt
*mgmt
;
1385 dl_list_for_each(q
, &hapd
->sae_commit_queue
,
1386 struct hostapd_sae_commit_queue
, list
) {
1387 mgmt
= (const struct ieee80211_mgmt
*) q
->msg
;
1388 if (os_memcmp(addr
, mgmt
->sa
, ETH_ALEN
) == 0)
1395 #endif /* CONFIG_SAE */
1398 static u16
wpa_res_to_status_code(int res
)
1400 if (res
== WPA_INVALID_GROUP
)
1401 return WLAN_STATUS_GROUP_CIPHER_NOT_VALID
;
1402 if (res
== WPA_INVALID_PAIRWISE
)
1403 return WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID
;
1404 if (res
== WPA_INVALID_AKMP
)
1405 return WLAN_STATUS_AKMP_NOT_VALID
;
1406 if (res
== WPA_ALLOC_FAIL
)
1407 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
1408 #ifdef CONFIG_IEEE80211W
1409 if (res
== WPA_MGMT_FRAME_PROTECTION_VIOLATION
)
1410 return WLAN_STATUS_ROBUST_MGMT_FRAME_POLICY_VIOLATION
;
1411 if (res
== WPA_INVALID_MGMT_GROUP_CIPHER
)
1412 return WLAN_STATUS_CIPHER_REJECTED_PER_POLICY
;
1413 #endif /* CONFIG_IEEE80211W */
1414 if (res
== WPA_INVALID_MDIE
)
1415 return WLAN_STATUS_INVALID_MDIE
;
1416 if (res
== WPA_INVALID_PMKID
)
1417 return WLAN_STATUS_INVALID_PMKID
;
1418 if (res
!= WPA_IE_OK
)
1419 return WLAN_STATUS_INVALID_IE
;
1420 return WLAN_STATUS_SUCCESS
;
1426 static void handle_auth_fils_finish(struct hostapd_data
*hapd
,
1427 struct sta_info
*sta
, u16 resp
,
1428 struct wpabuf
*data
, int pub
);
1430 void handle_auth_fils(struct hostapd_data
*hapd
, struct sta_info
*sta
,
1431 const u8
*pos
, size_t len
, u16 auth_alg
,
1432 u16 auth_transaction
, u16 status_code
,
1433 void (*cb
)(struct hostapd_data
*hapd
,
1434 struct sta_info
*sta
, u16 resp
,
1435 struct wpabuf
*data
, int pub
))
1437 u16 resp
= WLAN_STATUS_SUCCESS
;
1439 struct ieee802_11_elems elems
;
1441 struct wpa_ie_data rsn
;
1442 struct rsn_pmksa_cache_entry
*pmksa
= NULL
;
1444 if (auth_transaction
!= 1 || status_code
!= WLAN_STATUS_SUCCESS
)
1449 wpa_hexdump(MSG_DEBUG
, "FILS: Authentication frame fields",
1453 #ifdef CONFIG_FILS_SK_PFS
1454 if (auth_alg
== WLAN_AUTH_FILS_SK_PFS
) {
1459 /* Using FILS PFS */
1461 /* Finite Cyclic Group */
1462 if (end
- pos
< 2) {
1463 wpa_printf(MSG_DEBUG
,
1464 "FILS: No room for Finite Cyclic Group");
1465 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1468 group
= WPA_GET_LE16(pos
);
1470 if (group
!= hapd
->conf
->fils_dh_group
) {
1471 wpa_printf(MSG_DEBUG
,
1472 "FILS: Unsupported Finite Cyclic Group: %u (expected %u)",
1473 group
, hapd
->conf
->fils_dh_group
);
1474 resp
= WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED
;
1478 crypto_ecdh_deinit(sta
->fils_ecdh
);
1479 sta
->fils_ecdh
= crypto_ecdh_init(group
);
1480 if (!sta
->fils_ecdh
) {
1481 wpa_printf(MSG_INFO
,
1482 "FILS: Could not initialize ECDH with group %d",
1484 resp
= WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED
;
1488 pub
= crypto_ecdh_get_pubkey(sta
->fils_ecdh
, 1);
1490 wpa_printf(MSG_DEBUG
,
1491 "FILS: Failed to derive ECDH public key");
1492 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1495 elem_len
= wpabuf_len(pub
);
1499 if ((size_t) (end
- pos
) < elem_len
) {
1500 wpa_printf(MSG_DEBUG
, "FILS: No room for Element");
1501 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1505 wpabuf_free(sta
->fils_g_sta
);
1506 sta
->fils_g_sta
= wpabuf_alloc_copy(pos
, elem_len
);
1507 wpabuf_clear_free(sta
->fils_dh_ss
);
1508 sta
->fils_dh_ss
= crypto_ecdh_set_peerkey(sta
->fils_ecdh
, 1,
1510 if (!sta
->fils_dh_ss
) {
1511 wpa_printf(MSG_DEBUG
, "FILS: ECDH operation failed");
1512 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1515 wpa_hexdump_buf_key(MSG_DEBUG
, "FILS: DH_SS", sta
->fils_dh_ss
);
1518 crypto_ecdh_deinit(sta
->fils_ecdh
);
1519 sta
->fils_ecdh
= NULL
;
1520 wpabuf_clear_free(sta
->fils_dh_ss
);
1521 sta
->fils_dh_ss
= NULL
;
1523 #endif /* CONFIG_FILS_SK_PFS */
1525 wpa_hexdump(MSG_DEBUG
, "FILS: Remaining IEs", pos
, end
- pos
);
1526 if (ieee802_11_parse_elems(pos
, end
- pos
, &elems
, 1) == ParseFailed
) {
1527 wpa_printf(MSG_DEBUG
, "FILS: Could not parse elements");
1528 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1533 wpa_hexdump(MSG_DEBUG
, "FILS: RSN element",
1534 elems
.rsn_ie
, elems
.rsn_ie_len
);
1535 if (!elems
.rsn_ie
||
1536 wpa_parse_wpa_ie_rsn(elems
.rsn_ie
- 2, elems
.rsn_ie_len
+ 2,
1538 wpa_printf(MSG_DEBUG
, "FILS: No valid RSN element");
1539 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1544 sta
->wpa_sm
= wpa_auth_sta_init(hapd
->wpa_auth
, sta
->addr
,
1547 wpa_printf(MSG_DEBUG
,
1548 "FILS: Failed to initialize RSN state machine");
1549 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1553 res
= wpa_validate_wpa_ie(hapd
->wpa_auth
, sta
->wpa_sm
,
1555 elems
.rsn_ie
- 2, elems
.rsn_ie_len
+ 2,
1556 elems
.mdie
, elems
.mdie_len
, NULL
, 0);
1557 resp
= wpa_res_to_status_code(res
);
1558 if (resp
!= WLAN_STATUS_SUCCESS
)
1561 if (!elems
.fils_nonce
) {
1562 wpa_printf(MSG_DEBUG
, "FILS: No FILS Nonce field");
1563 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1566 wpa_hexdump(MSG_DEBUG
, "FILS: SNonce", elems
.fils_nonce
,
1568 os_memcpy(sta
->fils_snonce
, elems
.fils_nonce
, FILS_NONCE_LEN
);
1571 if (rsn
.pmkid
&& rsn
.num_pmkid
> 0) {
1575 wpa_hexdump(MSG_DEBUG
, "FILS: PMKID List",
1576 rsn
.pmkid
, rsn
.num_pmkid
* PMKID_LEN
);
1579 num
= rsn
.num_pmkid
;
1581 wpa_hexdump(MSG_DEBUG
, "FILS: PMKID", pmkid
, PMKID_LEN
);
1582 pmksa
= wpa_auth_pmksa_get(hapd
->wpa_auth
, sta
->addr
,
1586 pmksa
= wpa_auth_pmksa_get_fils_cache_id(hapd
->wpa_auth
,
1595 if (pmksa
&& wpa_auth_sta_key_mgmt(sta
->wpa_sm
) != pmksa
->akmp
) {
1596 wpa_printf(MSG_DEBUG
,
1597 "FILS: Matching PMKSA cache entry has different AKMP (0x%x != 0x%x) - ignore",
1598 wpa_auth_sta_key_mgmt(sta
->wpa_sm
), pmksa
->akmp
);
1602 wpa_printf(MSG_DEBUG
, "FILS: Found matching PMKSA cache entry");
1605 if (!elems
.fils_session
) {
1606 wpa_printf(MSG_DEBUG
, "FILS: No FILS Session element");
1607 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1610 wpa_hexdump(MSG_DEBUG
, "FILS: FILS Session", elems
.fils_session
,
1612 os_memcpy(sta
->fils_session
, elems
.fils_session
, FILS_SESSION_LEN
);
1614 /* FILS Wrapped Data */
1615 if (elems
.fils_wrapped_data
) {
1616 wpa_hexdump(MSG_DEBUG
, "FILS: Wrapped Data",
1617 elems
.fils_wrapped_data
,
1618 elems
.fils_wrapped_data_len
);
1620 #ifndef CONFIG_NO_RADIUS
1621 if (!sta
->eapol_sm
) {
1623 ieee802_1x_alloc_eapol_sm(hapd
, sta
);
1625 wpa_printf(MSG_DEBUG
,
1626 "FILS: Forward EAP-Initiate/Re-auth to authentication server");
1627 ieee802_1x_encapsulate_radius(
1628 hapd
, sta
, elems
.fils_wrapped_data
,
1629 elems
.fils_wrapped_data_len
);
1630 sta
->fils_pending_cb
= cb
;
1631 wpa_printf(MSG_DEBUG
,
1632 "FILS: Will send Authentication frame once the response from authentication server is available");
1633 sta
->flags
|= WLAN_STA_PENDING_FILS_ERP
;
1634 /* Calculate pending PMKID here so that we do not need
1635 * to maintain a copy of the EAP-Initiate/Reauth
1637 if (fils_pmkid_erp(wpa_auth_sta_key_mgmt(sta
->wpa_sm
),
1638 elems
.fils_wrapped_data
,
1639 elems
.fils_wrapped_data_len
,
1640 sta
->fils_erp_pmkid
) == 0)
1641 sta
->fils_erp_pmkid_set
= 1;
1643 #else /* CONFIG_NO_RADIUS */
1644 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1646 #endif /* CONFIG_NO_RADIUS */
1652 struct wpabuf
*data
;
1655 data
= prepare_auth_resp_fils(hapd
, sta
, &resp
, pmksa
, NULL
,
1658 wpa_printf(MSG_DEBUG
,
1659 "%s: prepare_auth_resp_fils() returned failure",
1663 cb(hapd
, sta
, resp
, data
, pub
);
1668 static struct wpabuf
*
1669 prepare_auth_resp_fils(struct hostapd_data
*hapd
,
1670 struct sta_info
*sta
, u16
*resp
,
1671 struct rsn_pmksa_cache_entry
*pmksa
,
1672 struct wpabuf
*erp_resp
,
1673 const u8
*msk
, size_t msk_len
,
1676 u8 fils_nonce
[FILS_NONCE_LEN
];
1678 struct wpabuf
*data
= NULL
;
1681 const u8
*pmk
= NULL
;
1683 u8 pmk_buf
[PMK_LEN_MAX
];
1684 struct wpabuf
*pub
= NULL
;
1686 if (*resp
!= WLAN_STATUS_SUCCESS
)
1689 ie
= wpa_auth_get_wpa_ie(hapd
->wpa_auth
, &ielen
);
1691 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1696 /* Add PMKID of the selected PMKSA into RSNE */
1697 ie_buf
= os_malloc(ielen
+ 2 + 2 + PMKID_LEN
);
1699 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1703 os_memcpy(ie_buf
, ie
, ielen
);
1704 if (wpa_insert_pmkid(ie_buf
, &ielen
, pmksa
->pmkid
) < 0) {
1705 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1711 if (random_get_bytes(fils_nonce
, FILS_NONCE_LEN
) < 0) {
1712 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1715 wpa_hexdump(MSG_DEBUG
, "RSN: Generated FILS Nonce",
1716 fils_nonce
, FILS_NONCE_LEN
);
1718 #ifdef CONFIG_FILS_SK_PFS
1719 if (sta
->fils_dh_ss
&& sta
->fils_ecdh
) {
1720 pub
= crypto_ecdh_get_pubkey(sta
->fils_ecdh
, 1);
1722 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1726 #endif /* CONFIG_FILS_SK_PFS */
1728 data
= wpabuf_alloc(1000 + ielen
+ (pub
? wpabuf_len(pub
) : 0));
1730 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1735 #ifdef CONFIG_FILS_SK_PFS
1737 /* Finite Cyclic Group */
1738 wpabuf_put_le16(data
, hapd
->conf
->fils_dh_group
);
1741 wpabuf_put_buf(data
, pub
);
1743 #endif /* CONFIG_FILS_SK_PFS */
1746 wpabuf_put_data(data
, ie
, ielen
);
1748 /* MDE when using FILS+FT (already included in ie,ielen with RSNE) */
1750 #ifdef CONFIG_IEEE80211R_AP
1751 if (wpa_key_mgmt_ft(wpa_auth_sta_key_mgmt(sta
->wpa_sm
))) {
1752 /* FTE[R1KH-ID,R0KH-ID] when using FILS+FT */
1754 int use_sha384
= wpa_key_mgmt_sha384(
1755 wpa_auth_sta_key_mgmt(sta
->wpa_sm
));
1757 res
= wpa_auth_write_fte(hapd
->wpa_auth
, use_sha384
,
1758 wpabuf_put(data
, 0),
1759 wpabuf_tailroom(data
));
1761 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1764 wpabuf_put(data
, res
);
1766 #endif /* CONFIG_IEEE80211R_AP */
1769 wpabuf_put_u8(data
, WLAN_EID_EXTENSION
); /* Element ID */
1770 wpabuf_put_u8(data
, 1 + FILS_NONCE_LEN
); /* Length */
1771 /* Element ID Extension */
1772 wpabuf_put_u8(data
, WLAN_EID_EXT_FILS_NONCE
);
1773 wpabuf_put_data(data
, fils_nonce
, FILS_NONCE_LEN
);
1776 wpabuf_put_u8(data
, WLAN_EID_EXTENSION
); /* Element ID */
1777 wpabuf_put_u8(data
, 1 + FILS_SESSION_LEN
); /* Length */
1778 /* Element ID Extension */
1779 wpabuf_put_u8(data
, WLAN_EID_EXT_FILS_SESSION
);
1780 wpabuf_put_data(data
, sta
->fils_session
, FILS_SESSION_LEN
);
1782 /* FILS Wrapped Data */
1783 if (!pmksa
&& erp_resp
) {
1784 wpabuf_put_u8(data
, WLAN_EID_EXTENSION
); /* Element ID */
1785 wpabuf_put_u8(data
, 1 + wpabuf_len(erp_resp
)); /* Length */
1786 /* Element ID Extension */
1787 wpabuf_put_u8(data
, WLAN_EID_EXT_FILS_WRAPPED_DATA
);
1788 wpabuf_put_buf(data
, erp_resp
);
1790 if (fils_rmsk_to_pmk(wpa_auth_sta_key_mgmt(sta
->wpa_sm
),
1791 msk
, msk_len
, sta
->fils_snonce
, fils_nonce
,
1793 wpabuf_head(sta
->fils_dh_ss
) : NULL
,
1795 wpabuf_len(sta
->fils_dh_ss
) : 0,
1796 pmk_buf
, &pmk_len
)) {
1797 wpa_printf(MSG_DEBUG
, "FILS: Failed to derive PMK");
1798 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1805 /* Don't use DHss in PTK derivation if PMKSA caching is not
1807 wpabuf_clear_free(sta
->fils_dh_ss
);
1808 sta
->fils_dh_ss
= NULL
;
1810 if (sta
->fils_erp_pmkid_set
) {
1811 /* TODO: get PMKLifetime from WPA parameters */
1812 unsigned int dot11RSNAConfigPMKLifetime
= 43200;
1813 int session_timeout
;
1815 session_timeout
= dot11RSNAConfigPMKLifetime
;
1816 if (sta
->session_timeout_set
) {
1817 struct os_reltime now
, diff
;
1819 os_get_reltime(&now
);
1820 os_reltime_sub(&sta
->session_timeout
, &now
,
1822 session_timeout
= diff
.sec
;
1825 sta
->fils_erp_pmkid_set
= 0;
1826 wpa_auth_add_fils_pmk_pmkid(sta
->wpa_sm
, pmk
, pmk_len
,
1827 sta
->fils_erp_pmkid
);
1828 if (!hapd
->conf
->disable_pmksa_caching
&&
1829 wpa_auth_pmksa_add2(
1830 hapd
->wpa_auth
, sta
->addr
,
1832 sta
->fils_erp_pmkid
,
1834 wpa_auth_sta_key_mgmt(sta
->wpa_sm
)) < 0) {
1835 wpa_printf(MSG_ERROR
,
1836 "FILS: Failed to add PMKSA cache entry based on ERP");
1841 pmk_len
= pmksa
->pmk_len
;
1845 wpa_printf(MSG_DEBUG
, "FILS: No PMK available");
1846 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1852 if (fils_auth_pmk_to_ptk(sta
->wpa_sm
, pmk
, pmk_len
,
1853 sta
->fils_snonce
, fils_nonce
,
1855 wpabuf_head(sta
->fils_dh_ss
) : NULL
,
1857 wpabuf_len(sta
->fils_dh_ss
) : 0,
1858 sta
->fils_g_sta
, pub
) < 0) {
1859 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1867 *is_pub
= pub
!= NULL
;
1870 wpabuf_clear_free(sta
->fils_dh_ss
);
1871 sta
->fils_dh_ss
= NULL
;
1872 #ifdef CONFIG_FILS_SK_PFS
1873 crypto_ecdh_deinit(sta
->fils_ecdh
);
1874 sta
->fils_ecdh
= NULL
;
1875 #endif /* CONFIG_FILS_SK_PFS */
1880 static void handle_auth_fils_finish(struct hostapd_data
*hapd
,
1881 struct sta_info
*sta
, u16 resp
,
1882 struct wpabuf
*data
, int pub
)
1887 resp
== WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED
) ?
1888 WLAN_AUTH_FILS_SK_PFS
: WLAN_AUTH_FILS_SK
;
1889 send_auth_reply(hapd
, sta
->addr
, hapd
->own_addr
, auth_alg
, 2, resp
,
1890 data
? wpabuf_head(data
) : (u8
*) "",
1891 data
? wpabuf_len(data
) : 0, "auth-fils-finish");
1894 if (resp
== WLAN_STATUS_SUCCESS
) {
1895 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1896 HOSTAPD_LEVEL_DEBUG
,
1897 "authentication OK (FILS)");
1898 sta
->flags
|= WLAN_STA_AUTH
;
1899 wpa_auth_sm_event(sta
->wpa_sm
, WPA_AUTH
);
1900 sta
->auth_alg
= pub
? WLAN_AUTH_FILS_SK_PFS
: WLAN_AUTH_FILS_SK
;
1901 mlme_authenticate_indication(hapd
, sta
);
1906 void ieee802_11_finish_fils_auth(struct hostapd_data
*hapd
,
1907 struct sta_info
*sta
, int success
,
1908 struct wpabuf
*erp_resp
,
1909 const u8
*msk
, size_t msk_len
)
1911 struct wpabuf
*data
;
1915 sta
->flags
&= ~WLAN_STA_PENDING_FILS_ERP
;
1917 if (!sta
->fils_pending_cb
)
1919 resp
= success
? WLAN_STATUS_SUCCESS
: WLAN_STATUS_UNSPECIFIED_FAILURE
;
1920 data
= prepare_auth_resp_fils(hapd
, sta
, &resp
, NULL
, erp_resp
,
1921 msk
, msk_len
, &pub
);
1923 wpa_printf(MSG_DEBUG
,
1924 "%s: prepare_auth_resp_fils() returned failure",
1927 sta
->fils_pending_cb(hapd
, sta
, resp
, data
, pub
);
1930 #endif /* CONFIG_FILS */
1934 ieee802_11_allowed_address(struct hostapd_data
*hapd
, const u8
*addr
,
1935 const u8
*msg
, size_t len
, u32
*session_timeout
,
1936 u32
*acct_interim_interval
,
1937 struct vlan_description
*vlan_id
,
1938 struct hostapd_sta_wpa_psk_short
**psk
,
1939 char **identity
, char **radius_cui
, int is_probe_req
)
1943 os_memset(vlan_id
, 0, sizeof(*vlan_id
));
1944 res
= hostapd_allowed_address(hapd
, addr
, msg
, len
,
1945 session_timeout
, acct_interim_interval
,
1946 vlan_id
, psk
, identity
, radius_cui
,
1949 if (res
== HOSTAPD_ACL_REJECT
) {
1951 wpa_printf(MSG_DEBUG
,
1953 " not allowed to authenticate",
1955 return HOSTAPD_ACL_REJECT
;
1958 if (res
== HOSTAPD_ACL_PENDING
) {
1959 wpa_printf(MSG_DEBUG
, "Authentication frame from " MACSTR
1960 " waiting for an external authentication",
1962 /* Authentication code will re-send the authentication frame
1963 * after it has received (and cached) information from the
1964 * external source. */
1965 return HOSTAPD_ACL_PENDING
;
1973 ieee802_11_set_radius_info(struct hostapd_data
*hapd
, struct sta_info
*sta
,
1974 int res
, u32 session_timeout
,
1975 u32 acct_interim_interval
,
1976 struct vlan_description
*vlan_id
,
1977 struct hostapd_sta_wpa_psk_short
**psk
,
1978 char **identity
, char **radius_cui
)
1980 if (vlan_id
->notempty
&&
1981 !hostapd_vlan_valid(hapd
->conf
->vlan
, vlan_id
)) {
1982 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_RADIUS
,
1984 "Invalid VLAN %d%s received from RADIUS server",
1986 vlan_id
->tagged
[0] ? "+" : "");
1989 if (ap_sta_set_vlan(hapd
, sta
, vlan_id
) < 0)
1992 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_RADIUS
,
1993 HOSTAPD_LEVEL_INFO
, "VLAN ID %d", sta
->vlan_id
);
1995 hostapd_free_psk_list(sta
->psk
);
1996 if (hapd
->conf
->wpa_psk_radius
!= PSK_RADIUS_IGNORED
) {
2003 os_free(sta
->identity
);
2004 sta
->identity
= *identity
;
2007 os_free(sta
->radius_cui
);
2008 sta
->radius_cui
= *radius_cui
;
2011 if (hapd
->conf
->acct_interim_interval
== 0 && acct_interim_interval
)
2012 sta
->acct_interim_interval
= acct_interim_interval
;
2013 if (res
== HOSTAPD_ACL_ACCEPT_TIMEOUT
) {
2014 sta
->session_timeout_set
= 1;
2015 os_get_reltime(&sta
->session_timeout
);
2016 sta
->session_timeout
.sec
+= session_timeout
;
2017 ap_sta_session_timeout(hapd
, sta
, session_timeout
);
2019 sta
->session_timeout_set
= 0;
2020 ap_sta_no_session_timeout(hapd
, sta
);
2027 static void handle_auth(struct hostapd_data
*hapd
,
2028 const struct ieee80211_mgmt
*mgmt
, size_t len
,
2029 int rssi
, int from_queue
)
2031 u16 auth_alg
, auth_transaction
, status_code
;
2032 u16 resp
= WLAN_STATUS_SUCCESS
;
2033 struct sta_info
*sta
= NULL
;
2036 const u8
*challenge
= NULL
;
2037 u32 session_timeout
, acct_interim_interval
;
2038 struct vlan_description vlan_id
;
2039 struct hostapd_sta_wpa_psk_short
*psk
= NULL
;
2040 u8 resp_ies
[2 + WLAN_AUTH_CHALLENGE_LEN
];
2041 size_t resp_ies_len
= 0;
2042 char *identity
= NULL
;
2043 char *radius_cui
= NULL
;
2046 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.auth
)) {
2047 wpa_printf(MSG_INFO
, "handle_auth - too short payload (len=%lu)",
2048 (unsigned long) len
);
2052 #ifdef CONFIG_TESTING_OPTIONS
2053 if (hapd
->iconf
->ignore_auth_probability
> 0.0 &&
2054 drand48() < hapd
->iconf
->ignore_auth_probability
) {
2055 wpa_printf(MSG_INFO
,
2056 "TESTING: ignoring auth frame from " MACSTR
,
2060 #endif /* CONFIG_TESTING_OPTIONS */
2062 auth_alg
= le_to_host16(mgmt
->u
.auth
.auth_alg
);
2063 auth_transaction
= le_to_host16(mgmt
->u
.auth
.auth_transaction
);
2064 status_code
= le_to_host16(mgmt
->u
.auth
.status_code
);
2065 fc
= le_to_host16(mgmt
->frame_control
);
2066 seq_ctrl
= le_to_host16(mgmt
->seq_ctrl
);
2068 if (len
>= IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.auth
) +
2069 2 + WLAN_AUTH_CHALLENGE_LEN
&&
2070 mgmt
->u
.auth
.variable
[0] == WLAN_EID_CHALLENGE
&&
2071 mgmt
->u
.auth
.variable
[1] == WLAN_AUTH_CHALLENGE_LEN
)
2072 challenge
= &mgmt
->u
.auth
.variable
[2];
2074 wpa_printf(MSG_DEBUG
, "authentication: STA=" MACSTR
" auth_alg=%d "
2075 "auth_transaction=%d status_code=%d wep=%d%s "
2076 "seq_ctrl=0x%x%s%s",
2077 MAC2STR(mgmt
->sa
), auth_alg
, auth_transaction
,
2078 status_code
, !!(fc
& WLAN_FC_ISWEP
),
2079 challenge
? " challenge" : "",
2080 seq_ctrl
, (fc
& WLAN_FC_RETRY
) ? " retry" : "",
2081 from_queue
? " (from queue)" : "");
2083 #ifdef CONFIG_NO_RC4
2084 if (auth_alg
== WLAN_AUTH_SHARED_KEY
) {
2085 wpa_printf(MSG_INFO
,
2086 "Unsupported authentication algorithm (%d)",
2088 resp
= WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG
;
2091 #endif /* CONFIG_NO_RC4 */
2093 if (hapd
->tkip_countermeasures
) {
2094 wpa_printf(MSG_DEBUG
,
2095 "Ongoing TKIP countermeasures (Michael MIC failure) - reject authentication");
2096 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
2100 if (!(((hapd
->conf
->auth_algs
& WPA_AUTH_ALG_OPEN
) &&
2101 auth_alg
== WLAN_AUTH_OPEN
) ||
2102 #ifdef CONFIG_IEEE80211R_AP
2103 (hapd
->conf
->wpa
&& wpa_key_mgmt_ft(hapd
->conf
->wpa_key_mgmt
) &&
2104 auth_alg
== WLAN_AUTH_FT
) ||
2105 #endif /* CONFIG_IEEE80211R_AP */
2107 (hapd
->conf
->wpa
&& wpa_key_mgmt_sae(hapd
->conf
->wpa_key_mgmt
) &&
2108 auth_alg
== WLAN_AUTH_SAE
) ||
2109 #endif /* CONFIG_SAE */
2111 (hapd
->conf
->wpa
&& wpa_key_mgmt_fils(hapd
->conf
->wpa_key_mgmt
) &&
2112 auth_alg
== WLAN_AUTH_FILS_SK
) ||
2113 (hapd
->conf
->wpa
&& wpa_key_mgmt_fils(hapd
->conf
->wpa_key_mgmt
) &&
2114 hapd
->conf
->fils_dh_group
&&
2115 auth_alg
== WLAN_AUTH_FILS_SK_PFS
) ||
2116 #endif /* CONFIG_FILS */
2117 ((hapd
->conf
->auth_algs
& WPA_AUTH_ALG_SHARED
) &&
2118 auth_alg
== WLAN_AUTH_SHARED_KEY
))) {
2119 wpa_printf(MSG_INFO
, "Unsupported authentication algorithm (%d)",
2121 resp
= WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG
;
2125 if (!(auth_transaction
== 1 || auth_alg
== WLAN_AUTH_SAE
||
2126 (auth_alg
== WLAN_AUTH_SHARED_KEY
&& auth_transaction
== 3))) {
2127 wpa_printf(MSG_INFO
, "Unknown authentication transaction number (%d)",
2129 resp
= WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION
;
2133 if (os_memcmp(mgmt
->sa
, hapd
->own_addr
, ETH_ALEN
) == 0) {
2134 wpa_printf(MSG_INFO
, "Station " MACSTR
" not allowed to authenticate",
2136 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
2140 if (hapd
->conf
->no_auth_if_seen_on
) {
2141 struct hostapd_data
*other
;
2143 other
= sta_track_seen_on(hapd
->iface
, mgmt
->sa
,
2144 hapd
->conf
->no_auth_if_seen_on
);
2148 u8 op_class
, channel
, phytype
;
2150 wpa_printf(MSG_DEBUG
, "%s: Reject authentication from "
2151 MACSTR
" since STA has been seen on %s",
2152 hapd
->conf
->iface
, MAC2STR(mgmt
->sa
),
2153 hapd
->conf
->no_auth_if_seen_on
);
2155 resp
= WLAN_STATUS_REJECTED_WITH_SUGGESTED_BSS_TRANSITION
;
2157 *pos
++ = WLAN_EID_NEIGHBOR_REPORT
;
2159 os_memcpy(pos
, other
->own_addr
, ETH_ALEN
);
2161 info
= 0; /* TODO: BSSID Information */
2162 WPA_PUT_LE32(pos
, info
);
2164 if (other
->iconf
->hw_mode
== HOSTAPD_MODE_IEEE80211AD
)
2165 phytype
= 8; /* dmg */
2166 else if (other
->iconf
->ieee80211ac
)
2167 phytype
= 9; /* vht */
2168 else if (other
->iconf
->ieee80211n
)
2169 phytype
= 7; /* ht */
2170 else if (other
->iconf
->hw_mode
==
2171 HOSTAPD_MODE_IEEE80211A
)
2172 phytype
= 4; /* ofdm */
2173 else if (other
->iconf
->hw_mode
==
2174 HOSTAPD_MODE_IEEE80211G
)
2175 phytype
= 6; /* erp */
2177 phytype
= 5; /* hrdsss */
2178 if (ieee80211_freq_to_channel_ext(
2179 hostapd_hw_get_freq(other
,
2180 other
->iconf
->channel
),
2181 other
->iconf
->secondary_channel
,
2182 other
->iconf
->ieee80211ac
,
2183 &op_class
, &channel
) == NUM_HOSTAPD_MODES
) {
2185 channel
= other
->iconf
->channel
;
2190 resp_ies_len
= pos
- &resp_ies
[0];
2195 res
= ieee802_11_allowed_address(
2196 hapd
, mgmt
->sa
, (const u8
*) mgmt
, len
, &session_timeout
,
2197 &acct_interim_interval
, &vlan_id
, &psk
, &identity
, &radius_cui
,
2199 if (res
== HOSTAPD_ACL_REJECT
) {
2200 wpa_msg(hapd
->msg_ctx
, MSG_DEBUG
,
2201 "Ignore Authentication frame from " MACSTR
2202 " due to ACL reject", MAC2STR(mgmt
->sa
));
2203 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
2206 if (res
== HOSTAPD_ACL_PENDING
)
2210 if (auth_alg
== WLAN_AUTH_SAE
&& !from_queue
&&
2211 (auth_transaction
== 1 ||
2212 (auth_transaction
== 2 && auth_sae_queued_addr(hapd
, mgmt
->sa
)))) {
2213 /* Handle SAE Authentication commit message through a queue to
2214 * provide more control for postponing the needed heavy
2215 * processing under a possible DoS attack scenario. In addition,
2216 * queue SAE Authentication confirm message if there happens to
2217 * be a queued commit message from the same peer. This is needed
2218 * to avoid reordering Authentication frames within the same
2220 auth_sae_queue(hapd
, mgmt
, len
, rssi
);
2223 #endif /* CONFIG_SAE */
2225 sta
= ap_get_sta(hapd
, mgmt
->sa
);
2227 sta
->flags
&= ~WLAN_STA_PENDING_FILS_ERP
;
2228 sta
->ft_over_ds
= 0;
2229 if ((fc
& WLAN_FC_RETRY
) &&
2230 sta
->last_seq_ctrl
!= WLAN_INVALID_MGMT_SEQ
&&
2231 sta
->last_seq_ctrl
== seq_ctrl
&&
2232 sta
->last_subtype
== WLAN_FC_STYPE_AUTH
) {
2233 hostapd_logger(hapd
, sta
->addr
,
2234 HOSTAPD_MODULE_IEEE80211
,
2235 HOSTAPD_LEVEL_DEBUG
,
2236 "Drop repeated authentication frame seq_ctrl=0x%x",
2241 if ((hapd
->conf
->mesh
& MESH_ENABLED
) &&
2242 sta
->plink_state
== PLINK_BLOCKED
) {
2243 wpa_printf(MSG_DEBUG
, "Mesh peer " MACSTR
2244 " is blocked - drop Authentication frame",
2248 #endif /* CONFIG_MESH */
2251 if (hapd
->conf
->mesh
& MESH_ENABLED
) {
2252 /* if the mesh peer is not available, we don't do auth.
2254 wpa_printf(MSG_DEBUG
, "Mesh peer " MACSTR
2255 " not yet known - drop Authentication frame",
2258 * Save a copy of the frame so that it can be processed
2259 * if a new peer entry is added shortly after this.
2261 wpabuf_free(hapd
->mesh_pending_auth
);
2262 hapd
->mesh_pending_auth
= wpabuf_alloc_copy(mgmt
, len
);
2263 os_get_reltime(&hapd
->mesh_pending_auth_time
);
2266 #endif /* CONFIG_MESH */
2268 sta
= ap_sta_add(hapd
, mgmt
->sa
);
2270 wpa_printf(MSG_DEBUG
, "ap_sta_add() failed");
2271 resp
= WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
;
2275 sta
->last_seq_ctrl
= seq_ctrl
;
2276 sta
->last_subtype
= WLAN_FC_STYPE_AUTH
;
2278 sta
->auth_rssi
= rssi
;
2279 #endif /* CONFIG_MBO */
2281 res
= ieee802_11_set_radius_info(
2282 hapd
, sta
, res
, session_timeout
, acct_interim_interval
,
2283 &vlan_id
, &psk
, &identity
, &radius_cui
);
2285 wpa_printf(MSG_DEBUG
, "ieee802_11_set_radius_info() failed");
2286 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
2290 sta
->flags
&= ~WLAN_STA_PREAUTH
;
2291 ieee802_1x_notify_pre_auth(sta
->eapol_sm
, 0);
2294 * If the driver supports full AP client state, add a station to the
2295 * driver before sending authentication reply to make sure the driver
2296 * has resources, and not to go through the entire authentication and
2297 * association handshake, and fail it at the end.
2299 * If this is not the first transaction, in a multi-step authentication
2300 * algorithm, the station already exists in the driver
2301 * (sta->added_unassoc = 1) so skip it.
2303 * In mesh mode, the station was already added to the driver when the
2304 * NEW_PEER_CANDIDATE event is received.
2306 * If PMF was negotiated for the existing association, skip this to
2307 * avoid dropping the STA entry and the associated keys. This is needed
2308 * to allow the original connection work until the attempt can complete
2309 * (re)association, so that unprotected Authentication frame cannot be
2310 * used to bypass PMF protection.
2312 if (FULL_AP_CLIENT_STATE_SUPP(hapd
->iface
->drv_flags
) &&
2313 (!(sta
->flags
& WLAN_STA_MFP
) || !ap_sta_is_authorized(sta
)) &&
2314 !(hapd
->conf
->mesh
& MESH_ENABLED
) &&
2315 !(sta
->added_unassoc
)) {
2317 * If a station that is already associated to the AP, is trying
2318 * to authenticate again, remove the STA entry, in order to make
2319 * sure the STA PS state gets cleared and configuration gets
2320 * updated. To handle this, station's added_unassoc flag is
2321 * cleared once the station has completed association.
2323 ap_sta_set_authorized(hapd
, sta
, 0);
2324 hostapd_drv_sta_remove(hapd
, sta
->addr
);
2325 sta
->flags
&= ~(WLAN_STA_ASSOC
| WLAN_STA_AUTH
|
2326 WLAN_STA_AUTHORIZED
);
2328 if (hostapd_sta_add(hapd
, sta
->addr
, 0, 0,
2329 sta
->supported_rates
,
2330 sta
->supported_rates_len
,
2331 0, NULL
, NULL
, NULL
, 0,
2332 sta
->flags
, 0, 0, 0, 0)) {
2333 hostapd_logger(hapd
, sta
->addr
,
2334 HOSTAPD_MODULE_IEEE80211
,
2335 HOSTAPD_LEVEL_NOTICE
,
2336 "Could not add STA to kernel driver");
2337 resp
= WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
;
2341 sta
->added_unassoc
= 1;
2345 case WLAN_AUTH_OPEN
:
2346 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
2347 HOSTAPD_LEVEL_DEBUG
,
2348 "authentication OK (open system)");
2349 sta
->flags
|= WLAN_STA_AUTH
;
2350 wpa_auth_sm_event(sta
->wpa_sm
, WPA_AUTH
);
2351 sta
->auth_alg
= WLAN_AUTH_OPEN
;
2352 mlme_authenticate_indication(hapd
, sta
);
2354 #ifndef CONFIG_NO_RC4
2355 case WLAN_AUTH_SHARED_KEY
:
2356 resp
= auth_shared_key(hapd
, sta
, auth_transaction
, challenge
,
2357 fc
& WLAN_FC_ISWEP
);
2359 wpa_printf(MSG_DEBUG
,
2360 "auth_shared_key() failed: status=%d", resp
);
2361 sta
->auth_alg
= WLAN_AUTH_SHARED_KEY
;
2362 mlme_authenticate_indication(hapd
, sta
);
2363 if (sta
->challenge
&& auth_transaction
== 1) {
2364 resp_ies
[0] = WLAN_EID_CHALLENGE
;
2365 resp_ies
[1] = WLAN_AUTH_CHALLENGE_LEN
;
2366 os_memcpy(resp_ies
+ 2, sta
->challenge
,
2367 WLAN_AUTH_CHALLENGE_LEN
);
2368 resp_ies_len
= 2 + WLAN_AUTH_CHALLENGE_LEN
;
2371 #endif /* CONFIG_NO_RC4 */
2372 #ifdef CONFIG_IEEE80211R_AP
2374 sta
->auth_alg
= WLAN_AUTH_FT
;
2375 if (sta
->wpa_sm
== NULL
)
2376 sta
->wpa_sm
= wpa_auth_sta_init(hapd
->wpa_auth
,
2378 if (sta
->wpa_sm
== NULL
) {
2379 wpa_printf(MSG_DEBUG
, "FT: Failed to initialize WPA "
2381 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
2384 wpa_ft_process_auth(sta
->wpa_sm
, mgmt
->bssid
,
2385 auth_transaction
, mgmt
->u
.auth
.variable
,
2386 len
- IEEE80211_HDRLEN
-
2387 sizeof(mgmt
->u
.auth
),
2388 handle_auth_ft_finish
, hapd
);
2389 /* handle_auth_ft_finish() callback will complete auth. */
2391 #endif /* CONFIG_IEEE80211R_AP */
2395 if (status_code
== WLAN_STATUS_SUCCESS
&&
2396 hapd
->conf
->mesh
& MESH_ENABLED
) {
2397 if (sta
->wpa_sm
== NULL
)
2399 wpa_auth_sta_init(hapd
->wpa_auth
,
2401 if (sta
->wpa_sm
== NULL
) {
2402 wpa_printf(MSG_DEBUG
,
2403 "SAE: Failed to initialize WPA state machine");
2404 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
2408 #endif /* CONFIG_MESH */
2409 handle_auth_sae(hapd
, sta
, mgmt
, len
, auth_transaction
,
2412 #endif /* CONFIG_SAE */
2414 case WLAN_AUTH_FILS_SK
:
2415 case WLAN_AUTH_FILS_SK_PFS
:
2416 handle_auth_fils(hapd
, sta
, mgmt
->u
.auth
.variable
,
2417 len
- IEEE80211_HDRLEN
- sizeof(mgmt
->u
.auth
),
2418 auth_alg
, auth_transaction
, status_code
,
2419 handle_auth_fils_finish
);
2421 #endif /* CONFIG_FILS */
2426 os_free(radius_cui
);
2427 hostapd_free_psk_list(psk
);
2429 reply_res
= send_auth_reply(hapd
, mgmt
->sa
, mgmt
->bssid
, auth_alg
,
2430 auth_transaction
+ 1, resp
, resp_ies
,
2431 resp_ies_len
, "handle-auth");
2433 if (sta
&& sta
->added_unassoc
&& (resp
!= WLAN_STATUS_SUCCESS
||
2434 reply_res
!= WLAN_STATUS_SUCCESS
)) {
2435 hostapd_drv_sta_remove(hapd
, sta
->addr
);
2436 sta
->added_unassoc
= 0;
2441 int hostapd_get_aid(struct hostapd_data
*hapd
, struct sta_info
*sta
)
2445 /* get a unique AID */
2447 wpa_printf(MSG_DEBUG
, " old AID %d", sta
->aid
);
2454 for (i
= 0; i
< AID_WORDS
; i
++) {
2455 if (hapd
->sta_aid
[i
] == (u32
) -1)
2457 for (j
= 0; j
< 32; j
++) {
2458 if (!(hapd
->sta_aid
[i
] & BIT(j
)))
2466 aid
= i
* 32 + j
+ 1;
2471 hapd
->sta_aid
[i
] |= BIT(j
);
2472 wpa_printf(MSG_DEBUG
, " new AID %d", sta
->aid
);
2477 static u16
check_ssid(struct hostapd_data
*hapd
, struct sta_info
*sta
,
2478 const u8
*ssid_ie
, size_t ssid_ie_len
)
2480 if (ssid_ie
== NULL
)
2481 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2483 if (ssid_ie_len
!= hapd
->conf
->ssid
.ssid_len
||
2484 os_memcmp(ssid_ie
, hapd
->conf
->ssid
.ssid
, ssid_ie_len
) != 0) {
2485 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
2487 "Station tried to associate with unknown SSID "
2488 "'%s'", wpa_ssid_txt(ssid_ie
, ssid_ie_len
));
2489 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2492 return WLAN_STATUS_SUCCESS
;
2496 static u16
check_wmm(struct hostapd_data
*hapd
, struct sta_info
*sta
,
2497 const u8
*wmm_ie
, size_t wmm_ie_len
)
2499 sta
->flags
&= ~WLAN_STA_WMM
;
2501 if (wmm_ie
&& hapd
->conf
->wmm_enabled
) {
2502 struct wmm_information_element
*wmm
;
2504 if (!hostapd_eid_wmm_valid(hapd
, wmm_ie
, wmm_ie_len
)) {
2505 hostapd_logger(hapd
, sta
->addr
,
2507 HOSTAPD_LEVEL_DEBUG
,
2508 "invalid WMM element in association "
2510 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2513 sta
->flags
|= WLAN_STA_WMM
;
2514 wmm
= (struct wmm_information_element
*) wmm_ie
;
2515 sta
->qosinfo
= wmm
->qos_info
;
2517 return WLAN_STATUS_SUCCESS
;
2520 static u16
check_multi_ap(struct hostapd_data
*hapd
, struct sta_info
*sta
,
2521 const u8
*multi_ap_ie
, size_t multi_ap_len
)
2523 u8 multi_ap_value
= 0;
2525 sta
->flags
&= ~WLAN_STA_MULTI_AP
;
2527 if (!hapd
->conf
->multi_ap
)
2528 return WLAN_STATUS_SUCCESS
;
2531 const u8
*multi_ap_subelem
;
2533 multi_ap_subelem
= get_ie(multi_ap_ie
+ 4,
2535 MULTI_AP_SUB_ELEM_TYPE
);
2536 if (multi_ap_subelem
&& multi_ap_subelem
[1] == 1) {
2537 multi_ap_value
= multi_ap_subelem
[2];
2539 hostapd_logger(hapd
, sta
->addr
,
2540 HOSTAPD_MODULE_IEEE80211
,
2542 "Multi-AP IE has missing or invalid Multi-AP subelement");
2543 return WLAN_STATUS_INVALID_IE
;
2547 if (multi_ap_value
&& multi_ap_value
!= MULTI_AP_BACKHAUL_STA
)
2548 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
2550 "Multi-AP IE with unexpected value 0x%02x",
2553 if (!(multi_ap_value
& MULTI_AP_BACKHAUL_STA
)) {
2554 if (hapd
->conf
->multi_ap
& FRONTHAUL_BSS
)
2555 return WLAN_STATUS_SUCCESS
;
2557 hostapd_logger(hapd
, sta
->addr
,
2558 HOSTAPD_MODULE_IEEE80211
,
2560 "Non-Multi-AP STA tries to associate with backhaul-only BSS");
2561 return WLAN_STATUS_ASSOC_DENIED_UNSPEC
;
2564 if (!(hapd
->conf
->multi_ap
& BACKHAUL_BSS
))
2565 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
2566 HOSTAPD_LEVEL_DEBUG
,
2567 "Backhaul STA tries to associate with fronthaul-only BSS");
2569 sta
->flags
|= WLAN_STA_MULTI_AP
;
2570 return WLAN_STATUS_SUCCESS
;
2574 static u16
copy_supp_rates(struct hostapd_data
*hapd
, struct sta_info
*sta
,
2575 struct ieee802_11_elems
*elems
)
2577 /* Supported rates not used in IEEE 802.11ad/DMG */
2578 if (hapd
->iface
->current_mode
&&
2579 hapd
->iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211AD
)
2580 return WLAN_STATUS_SUCCESS
;
2582 if (!elems
->supp_rates
) {
2583 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
2584 HOSTAPD_LEVEL_DEBUG
,
2585 "No supported rates element in AssocReq");
2586 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2589 if (elems
->supp_rates_len
+ elems
->ext_supp_rates_len
>
2590 sizeof(sta
->supported_rates
)) {
2591 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
2592 HOSTAPD_LEVEL_DEBUG
,
2593 "Invalid supported rates element length %d+%d",
2594 elems
->supp_rates_len
,
2595 elems
->ext_supp_rates_len
);
2596 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2599 sta
->supported_rates_len
= merge_byte_arrays(
2600 sta
->supported_rates
, sizeof(sta
->supported_rates
),
2601 elems
->supp_rates
, elems
->supp_rates_len
,
2602 elems
->ext_supp_rates
, elems
->ext_supp_rates_len
);
2604 return WLAN_STATUS_SUCCESS
;
2608 static u16
check_ext_capab(struct hostapd_data
*hapd
, struct sta_info
*sta
,
2609 const u8
*ext_capab_ie
, size_t ext_capab_ie_len
)
2611 #ifdef CONFIG_INTERWORKING
2612 /* check for QoS Map support */
2613 if (ext_capab_ie_len
>= 5) {
2614 if (ext_capab_ie
[4] & 0x01)
2615 sta
->qos_map_enabled
= 1;
2617 #endif /* CONFIG_INTERWORKING */
2619 if (ext_capab_ie_len
> 0) {
2620 sta
->ecsa_supported
= !!(ext_capab_ie
[0] & BIT(2));
2621 os_free(sta
->ext_capability
);
2622 sta
->ext_capability
= os_malloc(1 + ext_capab_ie_len
);
2623 if (sta
->ext_capability
) {
2624 sta
->ext_capability
[0] = ext_capab_ie_len
;
2625 os_memcpy(sta
->ext_capability
+ 1, ext_capab_ie
,
2630 return WLAN_STATUS_SUCCESS
;
2636 static int owe_group_supported(struct hostapd_data
*hapd
, u16 group
)
2639 int *groups
= hapd
->conf
->owe_groups
;
2641 if (group
!= 19 && group
!= 20 && group
!= 21)
2647 for (i
= 0; groups
[i
] > 0; i
++) {
2648 if (groups
[i
] == group
)
2656 static u16
owe_process_assoc_req(struct hostapd_data
*hapd
,
2657 struct sta_info
*sta
, const u8
*owe_dh
,
2660 struct wpabuf
*secret
, *pub
, *hkey
;
2662 u8 prk
[SHA512_MAC_LEN
], pmkid
[SHA512_MAC_LEN
];
2663 const char *info
= "OWE Key Generation";
2667 size_t hash_len
, prime_len
;
2669 if (wpa_auth_sta_get_pmksa(sta
->wpa_sm
)) {
2670 wpa_printf(MSG_DEBUG
, "OWE: Using PMKSA caching");
2671 return WLAN_STATUS_SUCCESS
;
2674 group
= WPA_GET_LE16(owe_dh
);
2675 if (!owe_group_supported(hapd
, group
)) {
2676 wpa_printf(MSG_DEBUG
, "OWE: Unsupported DH group %u", group
);
2677 return WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED
;
2681 else if (group
== 20)
2683 else if (group
== 21)
2686 return WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED
;
2688 crypto_ecdh_deinit(sta
->owe_ecdh
);
2689 sta
->owe_ecdh
= crypto_ecdh_init(group
);
2691 return WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED
;
2692 sta
->owe_group
= group
;
2694 secret
= crypto_ecdh_set_peerkey(sta
->owe_ecdh
, 0, owe_dh
+ 2,
2696 secret
= wpabuf_zeropad(secret
, prime_len
);
2698 wpa_printf(MSG_DEBUG
, "OWE: Invalid peer DH public key");
2699 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2701 wpa_hexdump_buf_key(MSG_DEBUG
, "OWE: DH shared secret", secret
);
2703 /* prk = HKDF-extract(C | A | group, z) */
2705 pub
= crypto_ecdh_get_pubkey(sta
->owe_ecdh
, 0);
2707 wpabuf_clear_free(secret
);
2708 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2711 /* PMKID = Truncate-128(Hash(C | A)) */
2712 addr
[0] = owe_dh
+ 2;
2713 len
[0] = owe_dh_len
- 2;
2714 addr
[1] = wpabuf_head(pub
);
2715 len
[1] = wpabuf_len(pub
);
2717 res
= sha256_vector(2, addr
, len
, pmkid
);
2718 hash_len
= SHA256_MAC_LEN
;
2719 } else if (group
== 20) {
2720 res
= sha384_vector(2, addr
, len
, pmkid
);
2721 hash_len
= SHA384_MAC_LEN
;
2722 } else if (group
== 21) {
2723 res
= sha512_vector(2, addr
, len
, pmkid
);
2724 hash_len
= SHA512_MAC_LEN
;
2727 wpabuf_clear_free(secret
);
2728 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2730 pub
= wpabuf_zeropad(pub
, prime_len
);
2731 if (res
< 0 || !pub
) {
2733 wpabuf_clear_free(secret
);
2734 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2737 hkey
= wpabuf_alloc(owe_dh_len
- 2 + wpabuf_len(pub
) + 2);
2740 wpabuf_clear_free(secret
);
2741 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2744 wpabuf_put_data(hkey
, owe_dh
+ 2, owe_dh_len
- 2); /* C */
2745 wpabuf_put_buf(hkey
, pub
); /* A */
2747 wpabuf_put_le16(hkey
, group
); /* group */
2749 res
= hmac_sha256(wpabuf_head(hkey
), wpabuf_len(hkey
),
2750 wpabuf_head(secret
), wpabuf_len(secret
), prk
);
2751 else if (group
== 20)
2752 res
= hmac_sha384(wpabuf_head(hkey
), wpabuf_len(hkey
),
2753 wpabuf_head(secret
), wpabuf_len(secret
), prk
);
2754 else if (group
== 21)
2755 res
= hmac_sha512(wpabuf_head(hkey
), wpabuf_len(hkey
),
2756 wpabuf_head(secret
), wpabuf_len(secret
), prk
);
2757 wpabuf_clear_free(hkey
);
2758 wpabuf_clear_free(secret
);
2760 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2762 wpa_hexdump_key(MSG_DEBUG
, "OWE: prk", prk
, hash_len
);
2764 /* PMK = HKDF-expand(prk, "OWE Key Generation", n) */
2766 os_free(sta
->owe_pmk
);
2767 sta
->owe_pmk
= os_malloc(hash_len
);
2768 if (!sta
->owe_pmk
) {
2769 os_memset(prk
, 0, SHA512_MAC_LEN
);
2770 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2774 res
= hmac_sha256_kdf(prk
, hash_len
, NULL
, (const u8
*) info
,
2775 os_strlen(info
), sta
->owe_pmk
, hash_len
);
2776 else if (group
== 20)
2777 res
= hmac_sha384_kdf(prk
, hash_len
, NULL
, (const u8
*) info
,
2778 os_strlen(info
), sta
->owe_pmk
, hash_len
);
2779 else if (group
== 21)
2780 res
= hmac_sha512_kdf(prk
, hash_len
, NULL
, (const u8
*) info
,
2781 os_strlen(info
), sta
->owe_pmk
, hash_len
);
2782 os_memset(prk
, 0, SHA512_MAC_LEN
);
2784 os_free(sta
->owe_pmk
);
2785 sta
->owe_pmk
= NULL
;
2786 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2788 sta
->owe_pmk_len
= hash_len
;
2790 wpa_hexdump_key(MSG_DEBUG
, "OWE: PMK", sta
->owe_pmk
, sta
->owe_pmk_len
);
2791 wpa_hexdump(MSG_DEBUG
, "OWE: PMKID", pmkid
, PMKID_LEN
);
2792 wpa_auth_pmksa_add2(hapd
->wpa_auth
, sta
->addr
, sta
->owe_pmk
,
2793 sta
->owe_pmk_len
, pmkid
, 0, WPA_KEY_MGMT_OWE
);
2795 return WLAN_STATUS_SUCCESS
;
2798 #endif /* CONFIG_OWE */
2801 static u16
check_assoc_ies(struct hostapd_data
*hapd
, struct sta_info
*sta
,
2802 const u8
*ies
, size_t ies_len
, int reassoc
)
2804 struct ieee802_11_elems elems
;
2808 const u8
*p2p_dev_addr
= NULL
;
2810 if (ieee802_11_parse_elems(ies
, ies_len
, &elems
, 1) == ParseFailed
) {
2811 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
2812 HOSTAPD_LEVEL_INFO
, "Station sent an invalid "
2813 "association request");
2814 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2817 resp
= check_ssid(hapd
, sta
, elems
.ssid
, elems
.ssid_len
);
2818 if (resp
!= WLAN_STATUS_SUCCESS
)
2820 resp
= check_wmm(hapd
, sta
, elems
.wmm
, elems
.wmm_len
);
2821 if (resp
!= WLAN_STATUS_SUCCESS
)
2823 resp
= check_ext_capab(hapd
, sta
, elems
.ext_capab
, elems
.ext_capab_len
);
2824 if (resp
!= WLAN_STATUS_SUCCESS
)
2826 resp
= copy_supp_rates(hapd
, sta
, &elems
);
2827 if (resp
!= WLAN_STATUS_SUCCESS
)
2830 resp
= check_multi_ap(hapd
, sta
, elems
.multi_ap
, elems
.multi_ap_len
);
2831 if (resp
!= WLAN_STATUS_SUCCESS
)
2834 #ifdef CONFIG_IEEE80211N
2835 resp
= copy_sta_ht_capab(hapd
, sta
, elems
.ht_capabilities
);
2836 if (resp
!= WLAN_STATUS_SUCCESS
)
2838 if (hapd
->iconf
->ieee80211n
&& hapd
->iconf
->require_ht
&&
2839 !(sta
->flags
& WLAN_STA_HT
)) {
2840 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
2841 HOSTAPD_LEVEL_INFO
, "Station does not support "
2842 "mandatory HT PHY - reject association");
2843 return WLAN_STATUS_ASSOC_DENIED_NO_HT
;
2845 #endif /* CONFIG_IEEE80211N */
2847 #ifdef CONFIG_IEEE80211AC
2848 if (hapd
->iconf
->ieee80211ac
) {
2849 resp
= copy_sta_vht_capab(hapd
, sta
, elems
.vht_capabilities
);
2850 if (resp
!= WLAN_STATUS_SUCCESS
)
2853 resp
= set_sta_vht_opmode(hapd
, sta
, elems
.vht_opmode_notif
);
2854 if (resp
!= WLAN_STATUS_SUCCESS
)
2858 if (hapd
->iconf
->ieee80211ac
&& hapd
->iconf
->require_vht
&&
2859 !(sta
->flags
& WLAN_STA_VHT
)) {
2860 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
2861 HOSTAPD_LEVEL_INFO
, "Station does not support "
2862 "mandatory VHT PHY - reject association");
2863 return WLAN_STATUS_ASSOC_DENIED_NO_VHT
;
2866 if (hapd
->conf
->vendor_vht
&& !elems
.vht_capabilities
) {
2867 resp
= copy_sta_vendor_vht(hapd
, sta
, elems
.vendor_vht
,
2868 elems
.vendor_vht_len
);
2869 if (resp
!= WLAN_STATUS_SUCCESS
)
2872 #endif /* CONFIG_IEEE80211AC */
2873 #ifdef CONFIG_IEEE80211AX
2874 if (hapd
->iconf
->ieee80211ax
) {
2875 resp
= copy_sta_he_capab(hapd
, sta
, elems
.he_capabilities
,
2876 elems
.he_capabilities_len
);
2877 if (resp
!= WLAN_STATUS_SUCCESS
)
2880 #endif /* CONFIG_IEEE80211AX */
2884 wpabuf_free(sta
->p2p_ie
);
2885 sta
->p2p_ie
= ieee802_11_vendor_ie_concat(ies
, ies_len
,
2886 P2P_IE_VENDOR_TYPE
);
2888 p2p_dev_addr
= p2p_get_go_dev_addr(sta
->p2p_ie
);
2890 wpabuf_free(sta
->p2p_ie
);
2893 #endif /* CONFIG_P2P */
2895 if ((hapd
->conf
->wpa
& WPA_PROTO_RSN
) && elems
.rsn_ie
) {
2896 wpa_ie
= elems
.rsn_ie
;
2897 wpa_ie_len
= elems
.rsn_ie_len
;
2898 } else if ((hapd
->conf
->wpa
& WPA_PROTO_WPA
) &&
2900 wpa_ie
= elems
.wpa_ie
;
2901 wpa_ie_len
= elems
.wpa_ie_len
;
2908 sta
->flags
&= ~(WLAN_STA_WPS
| WLAN_STA_MAYBE_WPS
| WLAN_STA_WPS2
);
2909 if (hapd
->conf
->wps_state
&& elems
.wps_ie
) {
2910 wpa_printf(MSG_DEBUG
, "STA included WPS IE in (Re)Association "
2911 "Request - assume WPS is used");
2912 sta
->flags
|= WLAN_STA_WPS
;
2913 wpabuf_free(sta
->wps_ie
);
2914 sta
->wps_ie
= ieee802_11_vendor_ie_concat(ies
, ies_len
,
2915 WPS_IE_VENDOR_TYPE
);
2916 if (sta
->wps_ie
&& wps_is_20(sta
->wps_ie
)) {
2917 wpa_printf(MSG_DEBUG
, "WPS: STA supports WPS 2.0");
2918 sta
->flags
|= WLAN_STA_WPS2
;
2922 if (sta
->wps_ie
&& wps_validate_assoc_req(sta
->wps_ie
) < 0) {
2923 wpa_printf(MSG_DEBUG
, "WPS: Invalid WPS IE in "
2924 "(Re)Association Request - reject");
2925 return WLAN_STATUS_INVALID_IE
;
2927 } else if (hapd
->conf
->wps_state
&& wpa_ie
== NULL
) {
2928 wpa_printf(MSG_DEBUG
, "STA did not include WPA/RSN IE in "
2929 "(Re)Association Request - possible WPS use");
2930 sta
->flags
|= WLAN_STA_MAYBE_WPS
;
2932 #endif /* CONFIG_WPS */
2933 if (hapd
->conf
->wpa
&& wpa_ie
== NULL
) {
2934 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
2936 "No WPA/RSN IE in association request");
2937 return WLAN_STATUS_INVALID_IE
;
2940 if (hapd
->conf
->wpa
&& wpa_ie
) {
2944 if (sta
->wpa_sm
== NULL
)
2945 sta
->wpa_sm
= wpa_auth_sta_init(hapd
->wpa_auth
,
2948 if (sta
->wpa_sm
== NULL
) {
2949 wpa_printf(MSG_WARNING
, "Failed to initialize WPA "
2951 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2953 wpa_auth_set_auth_alg(sta
->wpa_sm
, sta
->auth_alg
);
2954 res
= wpa_validate_wpa_ie(hapd
->wpa_auth
, sta
->wpa_sm
,
2957 elems
.mdie
, elems
.mdie_len
,
2958 elems
.owe_dh
, elems
.owe_dh_len
);
2959 resp
= wpa_res_to_status_code(res
);
2960 if (resp
!= WLAN_STATUS_SUCCESS
)
2962 #ifdef CONFIG_IEEE80211W
2963 if ((sta
->flags
& (WLAN_STA_ASSOC
| WLAN_STA_MFP
)) ==
2964 (WLAN_STA_ASSOC
| WLAN_STA_MFP
) &&
2965 !sta
->sa_query_timed_out
&&
2966 sta
->sa_query_count
> 0)
2967 ap_check_sa_query_timeout(hapd
, sta
);
2968 if ((sta
->flags
& (WLAN_STA_ASSOC
| WLAN_STA_MFP
)) ==
2969 (WLAN_STA_ASSOC
| WLAN_STA_MFP
) &&
2970 !sta
->sa_query_timed_out
&&
2971 (!reassoc
|| sta
->auth_alg
!= WLAN_AUTH_FT
)) {
2973 * STA has already been associated with MFP and SA
2974 * Query timeout has not been reached. Reject the
2975 * association attempt temporarily and start SA Query,
2976 * if one is not pending.
2979 if (sta
->sa_query_count
== 0)
2980 ap_sta_start_sa_query(hapd
, sta
);
2982 return WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY
;
2985 if (wpa_auth_uses_mfp(sta
->wpa_sm
))
2986 sta
->flags
|= WLAN_STA_MFP
;
2988 sta
->flags
&= ~WLAN_STA_MFP
;
2989 #endif /* CONFIG_IEEE80211W */
2991 #ifdef CONFIG_IEEE80211R_AP
2992 if (sta
->auth_alg
== WLAN_AUTH_FT
) {
2994 wpa_printf(MSG_DEBUG
, "FT: " MACSTR
" tried "
2995 "to use association (not "
2996 "re-association) with FT auth_alg",
2997 MAC2STR(sta
->addr
));
2998 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3001 resp
= wpa_ft_validate_reassoc(sta
->wpa_sm
, ies
,
3003 if (resp
!= WLAN_STATUS_SUCCESS
)
3006 #endif /* CONFIG_IEEE80211R_AP */
3009 if (wpa_auth_uses_sae(sta
->wpa_sm
) && sta
->sae
&&
3010 sta
->sae
->state
== SAE_ACCEPTED
)
3011 wpa_auth_add_sae_pmkid(sta
->wpa_sm
, sta
->sae
->pmkid
);
3013 if (wpa_auth_uses_sae(sta
->wpa_sm
) &&
3014 sta
->auth_alg
== WLAN_AUTH_OPEN
) {
3015 struct rsn_pmksa_cache_entry
*sa
;
3016 sa
= wpa_auth_sta_get_pmksa(sta
->wpa_sm
);
3017 if (!sa
|| sa
->akmp
!= WPA_KEY_MGMT_SAE
) {
3018 wpa_printf(MSG_DEBUG
,
3019 "SAE: No PMKSA cache entry found for "
3020 MACSTR
, MAC2STR(sta
->addr
));
3021 return WLAN_STATUS_INVALID_PMKID
;
3023 wpa_printf(MSG_DEBUG
, "SAE: " MACSTR
3024 " using PMKSA caching", MAC2STR(sta
->addr
));
3025 } else if (wpa_auth_uses_sae(sta
->wpa_sm
) &&
3026 sta
->auth_alg
!= WLAN_AUTH_SAE
&&
3027 !(sta
->auth_alg
== WLAN_AUTH_FT
&&
3028 wpa_auth_uses_ft_sae(sta
->wpa_sm
))) {
3029 wpa_printf(MSG_DEBUG
, "SAE: " MACSTR
" tried to use "
3030 "SAE AKM after non-SAE auth_alg %u",
3031 MAC2STR(sta
->addr
), sta
->auth_alg
);
3032 return WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG
;
3034 #endif /* CONFIG_SAE */
3037 if ((hapd
->conf
->wpa_key_mgmt
& WPA_KEY_MGMT_OWE
) &&
3038 wpa_auth_sta_key_mgmt(sta
->wpa_sm
) == WPA_KEY_MGMT_OWE
&&
3040 resp
= owe_process_assoc_req(hapd
, sta
, elems
.owe_dh
,
3042 if (resp
!= WLAN_STATUS_SUCCESS
)
3045 #endif /* CONFIG_OWE */
3048 dpp_pfs_free(sta
->dpp_pfs
);
3049 sta
->dpp_pfs
= NULL
;
3051 if ((hapd
->conf
->wpa_key_mgmt
& WPA_KEY_MGMT_DPP
) &&
3052 hapd
->conf
->dpp_netaccesskey
&& sta
->wpa_sm
&&
3053 wpa_auth_sta_key_mgmt(sta
->wpa_sm
) == WPA_KEY_MGMT_DPP
&&
3055 sta
->dpp_pfs
= dpp_pfs_init(
3056 wpabuf_head(hapd
->conf
->dpp_netaccesskey
),
3057 wpabuf_len(hapd
->conf
->dpp_netaccesskey
));
3058 if (!sta
->dpp_pfs
) {
3059 wpa_printf(MSG_DEBUG
,
3060 "DPP: Could not initialize PFS");
3061 /* Try to continue without PFS */
3065 if (dpp_pfs_process(sta
->dpp_pfs
, elems
.owe_dh
,
3066 elems
.owe_dh_len
) < 0) {
3067 dpp_pfs_free(sta
->dpp_pfs
);
3068 sta
->dpp_pfs
= NULL
;
3069 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3073 wpa_auth_set_dpp_z(sta
->wpa_sm
, sta
->dpp_pfs
?
3074 sta
->dpp_pfs
->secret
: NULL
);
3076 #endif /* CONFIG_DPP2 */
3078 #ifdef CONFIG_IEEE80211N
3079 if ((sta
->flags
& (WLAN_STA_HT
| WLAN_STA_VHT
)) &&
3080 wpa_auth_get_pairwise(sta
->wpa_sm
) == WPA_CIPHER_TKIP
) {
3081 hostapd_logger(hapd
, sta
->addr
,
3082 HOSTAPD_MODULE_IEEE80211
,
3084 "Station tried to use TKIP with HT "
3086 return WLAN_STATUS_CIPHER_REJECTED_PER_POLICY
;
3088 #endif /* CONFIG_IEEE80211N */
3090 } else if (hapd
->conf
->osen
) {
3091 if (elems
.osen
== NULL
) {
3093 hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
3095 "No HS 2.0 OSEN element in association request");
3096 return WLAN_STATUS_INVALID_IE
;
3099 wpa_printf(MSG_DEBUG
, "HS 2.0: OSEN association");
3100 if (sta
->wpa_sm
== NULL
)
3101 sta
->wpa_sm
= wpa_auth_sta_init(hapd
->wpa_auth
,
3103 if (sta
->wpa_sm
== NULL
) {
3104 wpa_printf(MSG_WARNING
, "Failed to initialize WPA "
3106 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3108 if (wpa_validate_osen(hapd
->wpa_auth
, sta
->wpa_sm
,
3109 elems
.osen
- 2, elems
.osen_len
+ 2) < 0)
3110 return WLAN_STATUS_INVALID_IE
;
3111 #endif /* CONFIG_HS20 */
3113 wpa_auth_sta_no_wpa(sta
->wpa_sm
);
3116 p2p_group_notif_assoc(hapd
->p2p_group
, sta
->addr
, ies
, ies_len
);
3117 #endif /* CONFIG_P2P */
3120 wpabuf_free(sta
->hs20_ie
);
3121 if (elems
.hs20
&& elems
.hs20_len
> 4) {
3124 sta
->hs20_ie
= wpabuf_alloc_copy(elems
.hs20
+ 4,
3125 elems
.hs20_len
- 4);
3126 release
= ((elems
.hs20
[4] >> 4) & 0x0f) + 1;
3127 if (release
>= 2 && !wpa_auth_uses_mfp(sta
->wpa_sm
)) {
3128 wpa_printf(MSG_DEBUG
,
3129 "HS 2.0: PMF not negotiated by release %d station "
3130 MACSTR
, release
, MAC2STR(sta
->addr
));
3131 return WLAN_STATUS_ROBUST_MGMT_FRAME_POLICY_VIOLATION
;
3134 sta
->hs20_ie
= NULL
;
3137 wpabuf_free(sta
->roaming_consortium
);
3138 if (elems
.roaming_cons_sel
)
3139 sta
->roaming_consortium
= wpabuf_alloc_copy(
3140 elems
.roaming_cons_sel
+ 4,
3141 elems
.roaming_cons_sel_len
- 4);
3143 sta
->roaming_consortium
= NULL
;
3144 #endif /* CONFIG_HS20 */
3147 wpabuf_free(sta
->mb_ies
);
3148 if (hapd
->iface
->fst
)
3149 sta
->mb_ies
= mb_ies_by_info(&elems
.mb_ies
);
3152 #endif /* CONFIG_FST */
3155 mbo_ap_check_sta_assoc(hapd
, sta
, &elems
);
3157 if (hapd
->conf
->mbo_enabled
&& (hapd
->conf
->wpa
& 2) &&
3158 elems
.mbo
&& sta
->cell_capa
&& !(sta
->flags
& WLAN_STA_MFP
) &&
3159 hapd
->conf
->ieee80211w
!= NO_MGMT_FRAME_PROTECTION
) {
3160 wpa_printf(MSG_INFO
,
3161 "MBO: Reject WPA2 association without PMF");
3162 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3164 #endif /* CONFIG_MBO */
3166 #if defined(CONFIG_FILS) && defined(CONFIG_OCV)
3167 if (wpa_auth_uses_ocv(sta
->wpa_sm
) &&
3168 (sta
->auth_alg
== WLAN_AUTH_FILS_SK
||
3169 sta
->auth_alg
== WLAN_AUTH_FILS_SK_PFS
||
3170 sta
->auth_alg
== WLAN_AUTH_FILS_PK
)) {
3171 struct wpa_channel_info ci
;
3175 if (hostapd_drv_channel_info(hapd
, &ci
) != 0) {
3176 wpa_printf(MSG_WARNING
,
3177 "Failed to get channel info to validate received OCI in FILS (Re)Association Request frame");
3178 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3181 if (get_sta_tx_parameters(sta
->wpa_sm
,
3182 channel_width_to_int(ci
.chanwidth
),
3183 ci
.seg1_idx
, &tx_chanwidth
,
3185 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3187 if (ocv_verify_tx_params(elems
.oci
, elems
.oci_len
, &ci
,
3188 tx_chanwidth
, tx_seg1_idx
) != 0) {
3189 wpa_printf(MSG_WARNING
, "FILS: %s", ocv_errorstr
);
3190 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3193 #endif /* CONFIG_FILS && CONFIG_OCV */
3195 ap_copy_sta_supp_op_classes(sta
, elems
.supp_op_classes
,
3196 elems
.supp_op_classes_len
);
3198 if ((sta
->capability
& WLAN_CAPABILITY_RADIO_MEASUREMENT
) &&
3199 elems
.rrm_enabled
&&
3200 elems
.rrm_enabled_len
>= sizeof(sta
->rrm_enabled_capa
))
3201 os_memcpy(sta
->rrm_enabled_capa
, elems
.rrm_enabled
,
3202 sizeof(sta
->rrm_enabled_capa
));
3204 if (elems
.power_capab
) {
3205 sta
->min_tx_power
= elems
.power_capab
[0];
3206 sta
->max_tx_power
= elems
.power_capab
[1];
3207 sta
->power_capab
= 1;
3209 sta
->power_capab
= 0;
3212 return WLAN_STATUS_SUCCESS
;
3216 static void send_deauth(struct hostapd_data
*hapd
, const u8
*addr
,
3220 struct ieee80211_mgmt reply
;
3222 os_memset(&reply
, 0, sizeof(reply
));
3223 reply
.frame_control
=
3224 IEEE80211_FC(WLAN_FC_TYPE_MGMT
, WLAN_FC_STYPE_DEAUTH
);
3225 os_memcpy(reply
.da
, addr
, ETH_ALEN
);
3226 os_memcpy(reply
.sa
, hapd
->own_addr
, ETH_ALEN
);
3227 os_memcpy(reply
.bssid
, hapd
->own_addr
, ETH_ALEN
);
3229 send_len
= IEEE80211_HDRLEN
+ sizeof(reply
.u
.deauth
);
3230 reply
.u
.deauth
.reason_code
= host_to_le16(reason_code
);
3232 if (hostapd_drv_send_mlme(hapd
, &reply
, send_len
, 0) < 0)
3233 wpa_printf(MSG_INFO
, "Failed to send deauth: %s",
3238 static int add_associated_sta(struct hostapd_data
*hapd
,
3239 struct sta_info
*sta
, int reassoc
)
3241 struct ieee80211_ht_capabilities ht_cap
;
3242 struct ieee80211_vht_capabilities vht_cap
;
3243 struct ieee80211_he_capabilities he_cap
;
3247 * Remove the STA entry to ensure the STA PS state gets cleared and
3248 * configuration gets updated. This is relevant for cases, such as
3249 * FT-over-the-DS, where a station re-associates back to the same AP but
3250 * skips the authentication flow, or if working with a driver that
3251 * does not support full AP client state.
3253 * Skip this if the STA has already completed FT reassociation and the
3254 * TK has been configured since the TX/RX PN must not be reset to 0 for
3257 * FT-over-the-DS has a special case where the STA entry (and as such,
3258 * the TK) has not yet been configured to the driver depending on which
3259 * driver interface is used. For that case, allow add-STA operation to
3260 * be used (instead of set-STA). This is needed to allow mac80211-based
3261 * drivers to accept the STA parameter configuration. Since this is
3262 * after a new FT-over-DS exchange, a new TK has been derived, so key
3263 * reinstallation is not a concern for this case.
3265 wpa_printf(MSG_DEBUG
, "Add associated STA " MACSTR
3266 " (added_unassoc=%d auth_alg=%u ft_over_ds=%u reassoc=%d authorized=%d ft_tk=%d fils_tk=%d)",
3267 MAC2STR(sta
->addr
), sta
->added_unassoc
, sta
->auth_alg
,
3268 sta
->ft_over_ds
, reassoc
,
3269 !!(sta
->flags
& WLAN_STA_AUTHORIZED
),
3270 wpa_auth_sta_ft_tk_already_set(sta
->wpa_sm
),
3271 wpa_auth_sta_fils_tk_already_set(sta
->wpa_sm
));
3273 if (!sta
->added_unassoc
&&
3274 (!(sta
->flags
& WLAN_STA_AUTHORIZED
) ||
3275 (reassoc
&& sta
->ft_over_ds
&& sta
->auth_alg
== WLAN_AUTH_FT
) ||
3276 (!wpa_auth_sta_ft_tk_already_set(sta
->wpa_sm
) &&
3277 !wpa_auth_sta_fils_tk_already_set(sta
->wpa_sm
)))) {
3278 hostapd_drv_sta_remove(hapd
, sta
->addr
);
3279 wpa_auth_sm_event(sta
->wpa_sm
, WPA_DRV_STA_REMOVED
);
3282 /* Do not allow the FT-over-DS exception to be used more than
3283 * once per authentication exchange to guarantee a new TK is
3285 sta
->ft_over_ds
= 0;
3288 #ifdef CONFIG_IEEE80211N
3289 if (sta
->flags
& WLAN_STA_HT
)
3290 hostapd_get_ht_capab(hapd
, sta
->ht_capabilities
, &ht_cap
);
3291 #endif /* CONFIG_IEEE80211N */
3292 #ifdef CONFIG_IEEE80211AC
3293 if (sta
->flags
& WLAN_STA_VHT
)
3294 hostapd_get_vht_capab(hapd
, sta
->vht_capabilities
, &vht_cap
);
3295 #endif /* CONFIG_IEEE80211AC */
3296 #ifdef CONFIG_IEEE80211AX
3297 if (sta
->flags
& WLAN_STA_HE
) {
3298 hostapd_get_he_capab(hapd
, sta
->he_capab
, &he_cap
,
3301 #endif /* CONFIG_IEEE80211AX */
3304 * Add the station with forced WLAN_STA_ASSOC flag. The sta->flags
3305 * will be set when the ACK frame for the (Re)Association Response frame
3306 * is processed (TX status driver event).
3308 if (hostapd_sta_add(hapd
, sta
->addr
, sta
->aid
, sta
->capability
,
3309 sta
->supported_rates
, sta
->supported_rates_len
,
3310 sta
->listen_interval
,
3311 sta
->flags
& WLAN_STA_HT
? &ht_cap
: NULL
,
3312 sta
->flags
& WLAN_STA_VHT
? &vht_cap
: NULL
,
3313 sta
->flags
& WLAN_STA_HE
? &he_cap
: NULL
,
3314 sta
->flags
& WLAN_STA_HE
? sta
->he_capab_len
: 0,
3315 sta
->flags
| WLAN_STA_ASSOC
, sta
->qosinfo
,
3316 sta
->vht_opmode
, sta
->p2p_ie
? 1 : 0,
3318 hostapd_logger(hapd
, sta
->addr
,
3319 HOSTAPD_MODULE_IEEE80211
, HOSTAPD_LEVEL_NOTICE
,
3320 "Could not %s STA to kernel driver",
3321 set
? "set" : "add");
3323 if (sta
->added_unassoc
) {
3324 hostapd_drv_sta_remove(hapd
, sta
->addr
);
3325 sta
->added_unassoc
= 0;
3331 sta
->added_unassoc
= 0;
3337 static u16
send_assoc_resp(struct hostapd_data
*hapd
, struct sta_info
*sta
,
3338 const u8
*addr
, u16 status_code
, int reassoc
,
3339 const u8
*ies
, size_t ies_len
, int rssi
)
3344 struct ieee80211_mgmt
*reply
;
3346 u16 res
= WLAN_STATUS_SUCCESS
;
3348 buflen
= sizeof(struct ieee80211_mgmt
) + 1024;
3350 if (sta
&& sta
->fils_hlp_resp
)
3351 buflen
+= wpabuf_len(sta
->fils_hlp_resp
);
3354 #endif /* CONFIG_FILS */
3356 if (sta
&& (hapd
->conf
->wpa_key_mgmt
& WPA_KEY_MGMT_OWE
))
3358 #endif /* CONFIG_OWE */
3360 if (sta
&& sta
->dpp_pfs
)
3361 buflen
+= 5 + sta
->dpp_pfs
->curve
->prime_len
;
3362 #endif /* CONFIG_DPP2 */
3363 buf
= os_zalloc(buflen
);
3365 res
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
3368 reply
= (struct ieee80211_mgmt
*) buf
;
3369 reply
->frame_control
=
3370 IEEE80211_FC(WLAN_FC_TYPE_MGMT
,
3371 (reassoc
? WLAN_FC_STYPE_REASSOC_RESP
:
3372 WLAN_FC_STYPE_ASSOC_RESP
));
3373 os_memcpy(reply
->da
, addr
, ETH_ALEN
);
3374 os_memcpy(reply
->sa
, hapd
->own_addr
, ETH_ALEN
);
3375 os_memcpy(reply
->bssid
, hapd
->own_addr
, ETH_ALEN
);
3377 send_len
= IEEE80211_HDRLEN
;
3378 send_len
+= sizeof(reply
->u
.assoc_resp
);
3379 reply
->u
.assoc_resp
.capab_info
=
3380 host_to_le16(hostapd_own_capab_info(hapd
));
3381 reply
->u
.assoc_resp
.status_code
= host_to_le16(status_code
);
3383 reply
->u
.assoc_resp
.aid
= host_to_le16((sta
? sta
->aid
: 0) |
3385 /* Supported rates */
3386 p
= hostapd_eid_supp_rates(hapd
, reply
->u
.assoc_resp
.variable
);
3387 /* Extended supported rates */
3388 p
= hostapd_eid_ext_supp_rates(hapd
, p
);
3391 if (status_code
== WLAN_STATUS_DENIED_POOR_CHANNEL_CONDITIONS
&&
3393 int delta
= hapd
->iconf
->rssi_reject_assoc_rssi
- rssi
;
3395 p
= hostapd_eid_mbo_rssi_assoc_rej(hapd
, p
, buf
+ buflen
- p
,
3398 #endif /* CONFIG_MBO */
3400 #ifdef CONFIG_IEEE80211R_AP
3401 if (sta
&& status_code
== WLAN_STATUS_SUCCESS
) {
3402 /* IEEE 802.11r: Mobility Domain Information, Fast BSS
3403 * Transition Information, RSN, [RIC Response] */
3404 p
= wpa_sm_write_assoc_resp_ies(sta
->wpa_sm
, p
,
3406 sta
->auth_alg
, ies
, ies_len
);
3408 wpa_printf(MSG_DEBUG
,
3409 "FT: Failed to write AssocResp IEs");
3410 res
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
3414 #endif /* CONFIG_IEEE80211R_AP */
3416 if (sta
&& status_code
== WLAN_STATUS_SUCCESS
&&
3417 (sta
->auth_alg
== WLAN_AUTH_FILS_SK
||
3418 sta
->auth_alg
== WLAN_AUTH_FILS_SK_PFS
||
3419 sta
->auth_alg
== WLAN_AUTH_FILS_PK
))
3420 p
= wpa_auth_write_assoc_resp_fils(sta
->wpa_sm
, p
,
3423 #endif /* CONFIG_FILS */
3426 if (sta
&& status_code
== WLAN_STATUS_SUCCESS
&&
3427 (hapd
->conf
->wpa_key_mgmt
& WPA_KEY_MGMT_OWE
))
3428 p
= wpa_auth_write_assoc_resp_owe(sta
->wpa_sm
, p
,
3431 #endif /* CONFIG_OWE */
3433 #ifdef CONFIG_IEEE80211W
3434 if (sta
&& status_code
== WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY
)
3435 p
= hostapd_eid_assoc_comeback_time(hapd
, sta
, p
);
3436 #endif /* CONFIG_IEEE80211W */
3438 #ifdef CONFIG_IEEE80211N
3439 p
= hostapd_eid_ht_capabilities(hapd
, p
);
3440 p
= hostapd_eid_ht_operation(hapd
, p
);
3441 #endif /* CONFIG_IEEE80211N */
3443 #ifdef CONFIG_IEEE80211AC
3444 if (hapd
->iconf
->ieee80211ac
&& !hapd
->conf
->disable_11ac
) {
3445 u32 nsts
= 0, sta_nsts
;
3447 if (sta
&& hapd
->conf
->use_sta_nsts
&& sta
->vht_capabilities
) {
3448 struct ieee80211_vht_capabilities
*capa
;
3450 nsts
= (hapd
->iface
->conf
->vht_capab
>>
3451 VHT_CAP_BEAMFORMEE_STS_OFFSET
) & 7;
3452 capa
= sta
->vht_capabilities
;
3453 sta_nsts
= (le_to_host32(capa
->vht_capabilities_info
) >>
3454 VHT_CAP_BEAMFORMEE_STS_OFFSET
) & 7;
3456 if (nsts
< sta_nsts
)
3461 p
= hostapd_eid_vht_capabilities(hapd
, p
, nsts
);
3462 p
= hostapd_eid_vht_operation(hapd
, p
);
3464 #endif /* CONFIG_IEEE80211AC */
3466 #ifdef CONFIG_IEEE80211AX
3467 if (hapd
->iconf
->ieee80211ax
) {
3468 p
= hostapd_eid_he_capab(hapd
, p
);
3469 p
= hostapd_eid_he_operation(hapd
, p
);
3470 p
= hostapd_eid_spatial_reuse(hapd
, p
);
3471 p
= hostapd_eid_he_mu_edca_parameter_set(hapd
, p
);
3473 #endif /* CONFIG_IEEE80211AX */
3475 p
= hostapd_eid_ext_capab(hapd
, p
);
3476 p
= hostapd_eid_bss_max_idle_period(hapd
, p
);
3477 if (sta
&& sta
->qos_map_enabled
)
3478 p
= hostapd_eid_qos_map_set(hapd
, p
);
3481 if (hapd
->iface
->fst_ies
) {
3482 os_memcpy(p
, wpabuf_head(hapd
->iface
->fst_ies
),
3483 wpabuf_len(hapd
->iface
->fst_ies
));
3484 p
+= wpabuf_len(hapd
->iface
->fst_ies
);
3486 #endif /* CONFIG_FST */
3489 if ((hapd
->conf
->wpa_key_mgmt
& WPA_KEY_MGMT_OWE
) &&
3490 sta
&& sta
->owe_ecdh
&& status_code
== WLAN_STATUS_SUCCESS
&&
3491 wpa_auth_sta_key_mgmt(sta
->wpa_sm
) == WPA_KEY_MGMT_OWE
) {
3494 pub
= crypto_ecdh_get_pubkey(sta
->owe_ecdh
, 0);
3496 res
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
3499 /* OWE Diffie-Hellman Parameter element */
3500 *p
++ = WLAN_EID_EXTENSION
; /* Element ID */
3501 *p
++ = 1 + 2 + wpabuf_len(pub
); /* Length */
3502 *p
++ = WLAN_EID_EXT_OWE_DH_PARAM
; /* Element ID Extension */
3503 WPA_PUT_LE16(p
, sta
->owe_group
);
3505 os_memcpy(p
, wpabuf_head(pub
), wpabuf_len(pub
));
3506 p
+= wpabuf_len(pub
);
3509 #endif /* CONFIG_OWE */
3512 if ((hapd
->conf
->wpa_key_mgmt
& WPA_KEY_MGMT_DPP
) &&
3513 sta
&& sta
->dpp_pfs
&& status_code
== WLAN_STATUS_SUCCESS
&&
3514 wpa_auth_sta_key_mgmt(sta
->wpa_sm
) == WPA_KEY_MGMT_DPP
) {
3515 os_memcpy(p
, wpabuf_head(sta
->dpp_pfs
->ie
),
3516 wpabuf_len(sta
->dpp_pfs
->ie
));
3517 p
+= wpabuf_len(sta
->dpp_pfs
->ie
);
3519 #endif /* CONFIG_DPP2 */
3521 #ifdef CONFIG_IEEE80211AC
3522 if (sta
&& hapd
->conf
->vendor_vht
&& (sta
->flags
& WLAN_STA_VENDOR_VHT
))
3523 p
= hostapd_eid_vendor_vht(hapd
, p
);
3524 #endif /* CONFIG_IEEE80211AC */
3526 if (sta
&& (sta
->flags
& WLAN_STA_WMM
))
3527 p
= hostapd_eid_wmm(hapd
, p
);
3531 ((sta
->flags
& WLAN_STA_WPS
) ||
3532 ((sta
->flags
& WLAN_STA_MAYBE_WPS
) && hapd
->conf
->wpa
))) {
3533 struct wpabuf
*wps
= wps_build_assoc_resp_ie();
3535 os_memcpy(p
, wpabuf_head(wps
), wpabuf_len(wps
));
3536 p
+= wpabuf_len(wps
);
3540 #endif /* CONFIG_WPS */
3542 if (sta
&& (sta
->flags
& WLAN_STA_MULTI_AP
))
3543 p
= hostapd_eid_multi_ap(hapd
, p
);
3546 if (sta
&& sta
->p2p_ie
&& hapd
->p2p_group
) {
3547 struct wpabuf
*p2p_resp_ie
;
3548 enum p2p_status_code status
;
3549 switch (status_code
) {
3550 case WLAN_STATUS_SUCCESS
:
3551 status
= P2P_SC_SUCCESS
;
3553 case WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
:
3554 status
= P2P_SC_FAIL_LIMIT_REACHED
;
3557 status
= P2P_SC_FAIL_INVALID_PARAMS
;
3560 p2p_resp_ie
= p2p_group_assoc_resp_ie(hapd
->p2p_group
, status
);
3562 os_memcpy(p
, wpabuf_head(p2p_resp_ie
),
3563 wpabuf_len(p2p_resp_ie
));
3564 p
+= wpabuf_len(p2p_resp_ie
);
3565 wpabuf_free(p2p_resp_ie
);
3568 #endif /* CONFIG_P2P */
3570 #ifdef CONFIG_P2P_MANAGER
3571 if (hapd
->conf
->p2p
& P2P_MANAGE
)
3572 p
= hostapd_eid_p2p_manage(hapd
, p
);
3573 #endif /* CONFIG_P2P_MANAGER */
3575 p
= hostapd_eid_mbo(hapd
, p
, buf
+ buflen
- p
);
3577 if (hapd
->conf
->assocresp_elements
&&
3578 (size_t) (buf
+ buflen
- p
) >=
3579 wpabuf_len(hapd
->conf
->assocresp_elements
)) {
3580 os_memcpy(p
, wpabuf_head(hapd
->conf
->assocresp_elements
),
3581 wpabuf_len(hapd
->conf
->assocresp_elements
));
3582 p
+= wpabuf_len(hapd
->conf
->assocresp_elements
);
3585 send_len
+= p
- reply
->u
.assoc_resp
.variable
;
3589 (sta
->auth_alg
== WLAN_AUTH_FILS_SK
||
3590 sta
->auth_alg
== WLAN_AUTH_FILS_SK_PFS
||
3591 sta
->auth_alg
== WLAN_AUTH_FILS_PK
) &&
3592 status_code
== WLAN_STATUS_SUCCESS
) {
3593 struct ieee802_11_elems elems
;
3595 if (ieee802_11_parse_elems(ies
, ies_len
, &elems
, 0) ==
3596 ParseFailed
|| !elems
.fils_session
) {
3597 res
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
3602 *p
++ = WLAN_EID_EXTENSION
; /* Element ID */
3603 *p
++ = 1 + FILS_SESSION_LEN
; /* Length */
3604 *p
++ = WLAN_EID_EXT_FILS_SESSION
; /* Element ID Extension */
3605 os_memcpy(p
, elems
.fils_session
, FILS_SESSION_LEN
);
3606 send_len
+= 2 + 1 + FILS_SESSION_LEN
;
3608 send_len
= fils_encrypt_assoc(sta
->wpa_sm
, buf
, send_len
,
3609 buflen
, sta
->fils_hlp_resp
);
3611 res
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
3615 #endif /* CONFIG_FILS */
3617 if (hostapd_drv_send_mlme(hapd
, reply
, send_len
, 0) < 0) {
3618 wpa_printf(MSG_INFO
, "Failed to send assoc resp: %s",
3620 res
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
3630 u8
* owe_assoc_req_process(struct hostapd_data
*hapd
, struct sta_info
*sta
,
3631 const u8
*owe_dh
, u8 owe_dh_len
,
3632 u8
*owe_buf
, size_t owe_buf_len
, u16
*reason
)
3634 #ifdef CONFIG_TESTING_OPTIONS
3635 if (hapd
->conf
->own_ie_override
) {
3636 wpa_printf(MSG_DEBUG
, "OWE: Using IE override");
3637 *reason
= WLAN_STATUS_SUCCESS
;
3638 return wpa_auth_write_assoc_resp_owe(sta
->wpa_sm
, owe_buf
,
3639 owe_buf_len
, NULL
, 0);
3641 #endif /* CONFIG_TESTING_OPTIONS */
3643 if (wpa_auth_sta_get_pmksa(sta
->wpa_sm
)) {
3644 wpa_printf(MSG_DEBUG
, "OWE: Using PMKSA caching");
3645 owe_buf
= wpa_auth_write_assoc_resp_owe(sta
->wpa_sm
, owe_buf
,
3646 owe_buf_len
, NULL
, 0);
3647 *reason
= WLAN_STATUS_SUCCESS
;
3651 *reason
= owe_process_assoc_req(hapd
, sta
, owe_dh
, owe_dh_len
);
3652 if (*reason
!= WLAN_STATUS_SUCCESS
)
3655 owe_buf
= wpa_auth_write_assoc_resp_owe(sta
->wpa_sm
, owe_buf
,
3656 owe_buf_len
, NULL
, 0);
3658 if (sta
->owe_ecdh
&& owe_buf
) {
3661 pub
= crypto_ecdh_get_pubkey(sta
->owe_ecdh
, 0);
3663 *reason
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
3667 /* OWE Diffie-Hellman Parameter element */
3668 *owe_buf
++ = WLAN_EID_EXTENSION
; /* Element ID */
3669 *owe_buf
++ = 1 + 2 + wpabuf_len(pub
); /* Length */
3670 *owe_buf
++ = WLAN_EID_EXT_OWE_DH_PARAM
; /* Element ID Extension
3672 WPA_PUT_LE16(owe_buf
, sta
->owe_group
);
3674 os_memcpy(owe_buf
, wpabuf_head(pub
), wpabuf_len(pub
));
3675 owe_buf
+= wpabuf_len(pub
);
3681 #endif /* CONFIG_OWE */
3686 void fils_hlp_finish_assoc(struct hostapd_data
*hapd
, struct sta_info
*sta
)
3690 wpa_printf(MSG_DEBUG
, "FILS: Finish association with " MACSTR
,
3691 MAC2STR(sta
->addr
));
3692 eloop_cancel_timeout(fils_hlp_timeout
, hapd
, sta
);
3693 if (!sta
->fils_pending_assoc_req
)
3695 reply_res
= send_assoc_resp(hapd
, sta
, sta
->addr
, WLAN_STATUS_SUCCESS
,
3696 sta
->fils_pending_assoc_is_reassoc
,
3697 sta
->fils_pending_assoc_req
,
3698 sta
->fils_pending_assoc_req_len
, 0);
3699 os_free(sta
->fils_pending_assoc_req
);
3700 sta
->fils_pending_assoc_req
= NULL
;
3701 sta
->fils_pending_assoc_req_len
= 0;
3702 wpabuf_free(sta
->fils_hlp_resp
);
3703 sta
->fils_hlp_resp
= NULL
;
3704 wpabuf_free(sta
->hlp_dhcp_discover
);
3705 sta
->hlp_dhcp_discover
= NULL
;
3708 * Remove the station in case transmission of a success response fails.
3709 * At this point the station was already added associated to the driver.
3711 if (reply_res
!= WLAN_STATUS_SUCCESS
)
3712 hostapd_drv_sta_remove(hapd
, sta
->addr
);
3716 void fils_hlp_timeout(void *eloop_ctx
, void *eloop_data
)
3718 struct hostapd_data
*hapd
= eloop_ctx
;
3719 struct sta_info
*sta
= eloop_data
;
3721 wpa_printf(MSG_DEBUG
,
3722 "FILS: HLP response timeout - continue with association response for "
3723 MACSTR
, MAC2STR(sta
->addr
));
3724 if (sta
->fils_drv_assoc_finish
)
3725 hostapd_notify_assoc_fils_finish(hapd
, sta
);
3727 fils_hlp_finish_assoc(hapd
, sta
);
3730 #endif /* CONFIG_FILS */
3733 static void handle_assoc(struct hostapd_data
*hapd
,
3734 const struct ieee80211_mgmt
*mgmt
, size_t len
,
3735 int reassoc
, int rssi
)
3737 u16 capab_info
, listen_interval
, seq_ctrl
, fc
;
3738 u16 resp
= WLAN_STATUS_SUCCESS
, reply_res
;
3741 struct sta_info
*sta
;
3743 struct hostapd_sta_wpa_psk_short
*psk
= NULL
;
3744 char *identity
= NULL
;
3745 char *radius_cui
= NULL
;
3747 int delay_assoc
= 0;
3748 #endif /* CONFIG_FILS */
3750 if (len
< IEEE80211_HDRLEN
+ (reassoc
? sizeof(mgmt
->u
.reassoc_req
) :
3751 sizeof(mgmt
->u
.assoc_req
))) {
3752 wpa_printf(MSG_INFO
, "handle_assoc(reassoc=%d) - too short payload (len=%lu)",
3753 reassoc
, (unsigned long) len
);
3757 #ifdef CONFIG_TESTING_OPTIONS
3759 if (hapd
->iconf
->ignore_reassoc_probability
> 0.0 &&
3760 drand48() < hapd
->iconf
->ignore_reassoc_probability
) {
3761 wpa_printf(MSG_INFO
,
3762 "TESTING: ignoring reassoc request from "
3763 MACSTR
, MAC2STR(mgmt
->sa
));
3767 if (hapd
->iconf
->ignore_assoc_probability
> 0.0 &&
3768 drand48() < hapd
->iconf
->ignore_assoc_probability
) {
3769 wpa_printf(MSG_INFO
,
3770 "TESTING: ignoring assoc request from "
3771 MACSTR
, MAC2STR(mgmt
->sa
));
3775 #endif /* CONFIG_TESTING_OPTIONS */
3777 fc
= le_to_host16(mgmt
->frame_control
);
3778 seq_ctrl
= le_to_host16(mgmt
->seq_ctrl
);
3781 capab_info
= le_to_host16(mgmt
->u
.reassoc_req
.capab_info
);
3782 listen_interval
= le_to_host16(
3783 mgmt
->u
.reassoc_req
.listen_interval
);
3784 wpa_printf(MSG_DEBUG
, "reassociation request: STA=" MACSTR
3785 " capab_info=0x%02x listen_interval=%d current_ap="
3786 MACSTR
" seq_ctrl=0x%x%s",
3787 MAC2STR(mgmt
->sa
), capab_info
, listen_interval
,
3788 MAC2STR(mgmt
->u
.reassoc_req
.current_ap
),
3789 seq_ctrl
, (fc
& WLAN_FC_RETRY
) ? " retry" : "");
3790 left
= len
- (IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.reassoc_req
));
3791 pos
= mgmt
->u
.reassoc_req
.variable
;
3793 capab_info
= le_to_host16(mgmt
->u
.assoc_req
.capab_info
);
3794 listen_interval
= le_to_host16(
3795 mgmt
->u
.assoc_req
.listen_interval
);
3796 wpa_printf(MSG_DEBUG
, "association request: STA=" MACSTR
3797 " capab_info=0x%02x listen_interval=%d "
3799 MAC2STR(mgmt
->sa
), capab_info
, listen_interval
,
3800 seq_ctrl
, (fc
& WLAN_FC_RETRY
) ? " retry" : "");
3801 left
= len
- (IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.assoc_req
));
3802 pos
= mgmt
->u
.assoc_req
.variable
;
3805 sta
= ap_get_sta(hapd
, mgmt
->sa
);
3806 #ifdef CONFIG_IEEE80211R_AP
3807 if (sta
&& sta
->auth_alg
== WLAN_AUTH_FT
&&
3808 (sta
->flags
& WLAN_STA_AUTH
) == 0) {
3809 wpa_printf(MSG_DEBUG
, "FT: Allow STA " MACSTR
" to associate "
3810 "prior to authentication since it is using "
3811 "over-the-DS FT", MAC2STR(mgmt
->sa
));
3814 * Mark station as authenticated, to avoid adding station
3815 * entry in the driver as associated and not authenticated
3817 sta
->flags
|= WLAN_STA_AUTH
;
3819 #endif /* CONFIG_IEEE80211R_AP */
3820 if (sta
== NULL
|| (sta
->flags
& WLAN_STA_AUTH
) == 0) {
3821 if (hapd
->iface
->current_mode
&&
3822 hapd
->iface
->current_mode
->mode
==
3823 HOSTAPD_MODE_IEEE80211AD
) {
3825 u32 session_timeout
, acct_interim_interval
;
3826 struct vlan_description vlan_id
;
3828 acl_res
= ieee802_11_allowed_address(
3829 hapd
, mgmt
->sa
, (const u8
*) mgmt
, len
,
3830 &session_timeout
, &acct_interim_interval
,
3831 &vlan_id
, &psk
, &identity
, &radius_cui
, 0);
3832 if (acl_res
== HOSTAPD_ACL_REJECT
) {
3833 wpa_msg(hapd
->msg_ctx
, MSG_DEBUG
,
3834 "Ignore Association Request frame from "
3835 MACSTR
" due to ACL reject",
3837 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
3840 if (acl_res
== HOSTAPD_ACL_PENDING
)
3843 /* DMG/IEEE 802.11ad does not use authentication.
3844 * Allocate sta entry upon association. */
3845 sta
= ap_sta_add(hapd
, mgmt
->sa
);
3847 hostapd_logger(hapd
, mgmt
->sa
,
3848 HOSTAPD_MODULE_IEEE80211
,
3850 "Failed to add STA");
3851 resp
= WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
;
3855 acl_res
= ieee802_11_set_radius_info(
3856 hapd
, sta
, acl_res
, session_timeout
,
3857 acct_interim_interval
, &vlan_id
, &psk
,
3858 &identity
, &radius_cui
);
3860 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
3864 hostapd_logger(hapd
, sta
->addr
,
3865 HOSTAPD_MODULE_IEEE80211
,
3866 HOSTAPD_LEVEL_DEBUG
,
3867 "Skip authentication for DMG/IEEE 802.11ad");
3868 sta
->flags
|= WLAN_STA_AUTH
;
3869 wpa_auth_sm_event(sta
->wpa_sm
, WPA_AUTH
);
3870 sta
->auth_alg
= WLAN_AUTH_OPEN
;
3872 hostapd_logger(hapd
, mgmt
->sa
,
3873 HOSTAPD_MODULE_IEEE80211
,
3875 "Station tried to associate before authentication (aid=%d flags=0x%x)",
3876 sta
? sta
->aid
: -1,
3877 sta
? sta
->flags
: 0);
3878 send_deauth(hapd
, mgmt
->sa
,
3879 WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA
);
3884 if ((fc
& WLAN_FC_RETRY
) &&
3885 sta
->last_seq_ctrl
!= WLAN_INVALID_MGMT_SEQ
&&
3886 sta
->last_seq_ctrl
== seq_ctrl
&&
3887 sta
->last_subtype
== (reassoc
? WLAN_FC_STYPE_REASSOC_REQ
:
3888 WLAN_FC_STYPE_ASSOC_REQ
)) {
3889 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
3890 HOSTAPD_LEVEL_DEBUG
,
3891 "Drop repeated association frame seq_ctrl=0x%x",
3895 sta
->last_seq_ctrl
= seq_ctrl
;
3896 sta
->last_subtype
= reassoc
? WLAN_FC_STYPE_REASSOC_REQ
:
3897 WLAN_FC_STYPE_ASSOC_REQ
;
3899 if (hapd
->tkip_countermeasures
) {
3900 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
3904 if (listen_interval
> hapd
->conf
->max_listen_interval
) {
3905 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
3906 HOSTAPD_LEVEL_DEBUG
,
3907 "Too large Listen Interval (%d)",
3909 resp
= WLAN_STATUS_ASSOC_DENIED_LISTEN_INT_TOO_LARGE
;
3914 if (hapd
->conf
->mbo_enabled
&& hapd
->mbo_assoc_disallow
) {
3915 resp
= WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
;
3919 if (hapd
->iconf
->rssi_reject_assoc_rssi
&& rssi
&&
3920 rssi
< hapd
->iconf
->rssi_reject_assoc_rssi
&&
3921 (sta
->auth_rssi
== 0 ||
3922 sta
->auth_rssi
< hapd
->iconf
->rssi_reject_assoc_rssi
)) {
3923 resp
= WLAN_STATUS_DENIED_POOR_CHANNEL_CONDITIONS
;
3926 #endif /* CONFIG_MBO */
3929 * sta->capability is used in check_assoc_ies() for RRM enabled
3930 * capability element.
3932 sta
->capability
= capab_info
;
3935 if (sta
->auth_alg
== WLAN_AUTH_FILS_SK
||
3936 sta
->auth_alg
== WLAN_AUTH_FILS_SK_PFS
||
3937 sta
->auth_alg
== WLAN_AUTH_FILS_PK
) {
3940 /* The end of the payload is encrypted. Need to decrypt it
3941 * before parsing. */
3943 tmp
= os_memdup(pos
, left
);
3945 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
3949 res
= fils_decrypt_assoc(sta
->wpa_sm
, sta
->fils_session
, mgmt
,
3952 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
3958 #endif /* CONFIG_FILS */
3960 /* followed by SSID and Supported rates; and HT capabilities if 802.11n
3962 resp
= check_assoc_ies(hapd
, sta
, pos
, left
, reassoc
);
3963 if (resp
!= WLAN_STATUS_SUCCESS
)
3966 if (hostapd_get_aid(hapd
, sta
) < 0) {
3967 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
3968 HOSTAPD_LEVEL_INFO
, "No room for more AIDs");
3969 resp
= WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
;
3973 sta
->listen_interval
= listen_interval
;
3975 if (hapd
->iface
->current_mode
&&
3976 hapd
->iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211G
)
3977 sta
->flags
|= WLAN_STA_NONERP
;
3978 for (i
= 0; i
< sta
->supported_rates_len
; i
++) {
3979 if ((sta
->supported_rates
[i
] & 0x7f) > 22) {
3980 sta
->flags
&= ~WLAN_STA_NONERP
;
3984 if (sta
->flags
& WLAN_STA_NONERP
&& !sta
->nonerp_set
) {
3985 sta
->nonerp_set
= 1;
3986 hapd
->iface
->num_sta_non_erp
++;
3987 if (hapd
->iface
->num_sta_non_erp
== 1)
3988 ieee802_11_set_beacons(hapd
->iface
);
3991 if (!(sta
->capability
& WLAN_CAPABILITY_SHORT_SLOT_TIME
) &&
3992 !sta
->no_short_slot_time_set
) {
3993 sta
->no_short_slot_time_set
= 1;
3994 hapd
->iface
->num_sta_no_short_slot_time
++;
3995 if (hapd
->iface
->current_mode
&&
3996 hapd
->iface
->current_mode
->mode
==
3997 HOSTAPD_MODE_IEEE80211G
&&
3998 hapd
->iface
->num_sta_no_short_slot_time
== 1)
3999 ieee802_11_set_beacons(hapd
->iface
);
4002 if (sta
->capability
& WLAN_CAPABILITY_SHORT_PREAMBLE
)
4003 sta
->flags
|= WLAN_STA_SHORT_PREAMBLE
;
4005 sta
->flags
&= ~WLAN_STA_SHORT_PREAMBLE
;
4007 if (!(sta
->capability
& WLAN_CAPABILITY_SHORT_PREAMBLE
) &&
4008 !sta
->no_short_preamble_set
) {
4009 sta
->no_short_preamble_set
= 1;
4010 hapd
->iface
->num_sta_no_short_preamble
++;
4011 if (hapd
->iface
->current_mode
&&
4012 hapd
->iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211G
4013 && hapd
->iface
->num_sta_no_short_preamble
== 1)
4014 ieee802_11_set_beacons(hapd
->iface
);
4017 #ifdef CONFIG_IEEE80211N
4018 update_ht_state(hapd
, sta
);
4019 #endif /* CONFIG_IEEE80211N */
4021 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
4022 HOSTAPD_LEVEL_DEBUG
,
4023 "association OK (aid %d)", sta
->aid
);
4024 /* Station will be marked associated, after it acknowledges AssocResp
4026 sta
->flags
|= WLAN_STA_ASSOC_REQ_OK
;
4028 #ifdef CONFIG_IEEE80211W
4029 if ((sta
->flags
& WLAN_STA_MFP
) && sta
->sa_query_timed_out
) {
4030 wpa_printf(MSG_DEBUG
, "Allowing %sassociation after timed out "
4031 "SA Query procedure", reassoc
? "re" : "");
4032 /* TODO: Send a protected Disassociate frame to the STA using
4033 * the old key and Reason Code "Previous Authentication no
4034 * longer valid". Make sure this is only sent protected since
4035 * unprotected frame would be received by the STA that is now
4036 * trying to associate.
4039 #endif /* CONFIG_IEEE80211W */
4041 /* Make sure that the previously registered inactivity timer will not
4042 * remove the STA immediately. */
4043 sta
->timeout_next
= STA_NULLFUNC
;
4045 #ifdef CONFIG_TAXONOMY
4046 taxonomy_sta_info_assoc_req(hapd
, sta
, pos
, left
);
4047 #endif /* CONFIG_TAXONOMY */
4049 sta
->pending_wds_enable
= 0;
4052 if (sta
->auth_alg
== WLAN_AUTH_FILS_SK
||
4053 sta
->auth_alg
== WLAN_AUTH_FILS_SK_PFS
||
4054 sta
->auth_alg
== WLAN_AUTH_FILS_PK
) {
4055 if (fils_process_hlp(hapd
, sta
, pos
, left
) > 0)
4058 #endif /* CONFIG_FILS */
4062 os_free(radius_cui
);
4063 hostapd_free_psk_list(psk
);
4066 * In case of a successful response, add the station to the driver.
4067 * Otherwise, the kernel may ignore Data frames before we process the
4068 * ACK frame (TX status). In case of a failure, this station will be
4071 * Note that this is not compliant with the IEEE 802.11 standard that
4072 * states that a non-AP station should transition into the
4073 * authenticated/associated state only after the station acknowledges
4074 * the (Re)Association Response frame. However, still do this as:
4076 * 1. In case the station does not acknowledge the (Re)Association
4077 * Response frame, it will be removed.
4078 * 2. Data frames will be dropped in the kernel until the station is
4079 * set into authorized state, and there are no significant known
4080 * issues with processing other non-Data Class 3 frames during this
4083 if (resp
== WLAN_STATUS_SUCCESS
&& sta
&&
4084 add_associated_sta(hapd
, sta
, reassoc
))
4085 resp
= WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
;
4088 if (sta
&& delay_assoc
&& resp
== WLAN_STATUS_SUCCESS
&&
4089 eloop_is_timeout_registered(fils_hlp_timeout
, hapd
, sta
) &&
4090 sta
->fils_pending_assoc_req
) {
4091 /* Do not reschedule fils_hlp_timeout in case the station
4092 * retransmits (Re)Association Request frame while waiting for
4093 * the previously started FILS HLP wait, so that the timeout can
4094 * be determined from the first pending attempt. */
4095 wpa_printf(MSG_DEBUG
,
4096 "FILS: Continue waiting for HLP processing before sending (Re)Association Response frame to "
4097 MACSTR
, MAC2STR(sta
->addr
));
4102 eloop_cancel_timeout(fils_hlp_timeout
, hapd
, sta
);
4103 os_free(sta
->fils_pending_assoc_req
);
4104 sta
->fils_pending_assoc_req
= NULL
;
4105 sta
->fils_pending_assoc_req_len
= 0;
4106 wpabuf_free(sta
->fils_hlp_resp
);
4107 sta
->fils_hlp_resp
= NULL
;
4109 if (sta
&& delay_assoc
&& resp
== WLAN_STATUS_SUCCESS
) {
4110 sta
->fils_pending_assoc_req
= tmp
;
4111 sta
->fils_pending_assoc_req_len
= left
;
4112 sta
->fils_pending_assoc_is_reassoc
= reassoc
;
4113 sta
->fils_drv_assoc_finish
= 0;
4114 wpa_printf(MSG_DEBUG
,
4115 "FILS: Waiting for HLP processing before sending (Re)Association Response frame to "
4116 MACSTR
, MAC2STR(sta
->addr
));
4117 eloop_cancel_timeout(fils_hlp_timeout
, hapd
, sta
);
4118 eloop_register_timeout(0, hapd
->conf
->fils_hlp_wait_time
* 1024,
4119 fils_hlp_timeout
, hapd
, sta
);
4122 #endif /* CONFIG_FILS */
4124 reply_res
= send_assoc_resp(hapd
, sta
, mgmt
->sa
, resp
, reassoc
, pos
,
4129 * Remove the station in case tranmission of a success response fails
4130 * (the STA was added associated to the driver) or if the station was
4131 * previously added unassociated.
4133 if (sta
&& ((reply_res
!= WLAN_STATUS_SUCCESS
&&
4134 resp
== WLAN_STATUS_SUCCESS
) || sta
->added_unassoc
)) {
4135 hostapd_drv_sta_remove(hapd
, sta
->addr
);
4136 sta
->added_unassoc
= 0;
4141 static void handle_disassoc(struct hostapd_data
*hapd
,
4142 const struct ieee80211_mgmt
*mgmt
, size_t len
)
4144 struct sta_info
*sta
;
4146 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.disassoc
)) {
4147 wpa_printf(MSG_INFO
, "handle_disassoc - too short payload (len=%lu)",
4148 (unsigned long) len
);
4152 wpa_printf(MSG_DEBUG
, "disassocation: STA=" MACSTR
" reason_code=%d",
4154 le_to_host16(mgmt
->u
.disassoc
.reason_code
));
4156 sta
= ap_get_sta(hapd
, mgmt
->sa
);
4158 wpa_printf(MSG_INFO
, "Station " MACSTR
" trying to disassociate, but it is not associated",
4163 ap_sta_set_authorized(hapd
, sta
, 0);
4164 sta
->last_seq_ctrl
= WLAN_INVALID_MGMT_SEQ
;
4165 sta
->flags
&= ~(WLAN_STA_ASSOC
| WLAN_STA_ASSOC_REQ_OK
);
4166 wpa_auth_sm_event(sta
->wpa_sm
, WPA_DISASSOC
);
4167 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
4168 HOSTAPD_LEVEL_INFO
, "disassociated");
4169 sta
->acct_terminate_cause
= RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST
;
4170 ieee802_1x_notify_port_enabled(sta
->eapol_sm
, 0);
4171 /* Stop Accounting and IEEE 802.1X sessions, but leave the STA
4173 accounting_sta_stop(hapd
, sta
);
4174 ieee802_1x_free_station(hapd
, sta
);
4176 hostapd_drv_br_delete_ip_neigh(hapd
, 4, (u8
*) &sta
->ipaddr
);
4177 ap_sta_ip6addr_del(hapd
, sta
);
4178 hostapd_drv_sta_remove(hapd
, sta
->addr
);
4179 sta
->added_unassoc
= 0;
4181 if (sta
->timeout_next
== STA_NULLFUNC
||
4182 sta
->timeout_next
== STA_DISASSOC
) {
4183 sta
->timeout_next
= STA_DEAUTH
;
4184 eloop_cancel_timeout(ap_handle_timer
, hapd
, sta
);
4185 eloop_register_timeout(AP_DEAUTH_DELAY
, 0, ap_handle_timer
,
4189 mlme_disassociate_indication(
4190 hapd
, sta
, le_to_host16(mgmt
->u
.disassoc
.reason_code
));
4192 /* DMG/IEEE 802.11ad does not use deauthication. Deallocate sta upon
4193 * disassociation. */
4194 if (hapd
->iface
->current_mode
&&
4195 hapd
->iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211AD
) {
4196 sta
->flags
&= ~WLAN_STA_AUTH
;
4197 wpa_auth_sm_event(sta
->wpa_sm
, WPA_DEAUTH
);
4198 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
4199 HOSTAPD_LEVEL_DEBUG
, "deauthenticated");
4200 ap_free_sta(hapd
, sta
);
4205 static void handle_deauth(struct hostapd_data
*hapd
,
4206 const struct ieee80211_mgmt
*mgmt
, size_t len
)
4208 struct sta_info
*sta
;
4210 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.deauth
)) {
4211 wpa_msg(hapd
->msg_ctx
, MSG_DEBUG
, "handle_deauth - too short "
4212 "payload (len=%lu)", (unsigned long) len
);
4216 wpa_msg(hapd
->msg_ctx
, MSG_DEBUG
, "deauthentication: STA=" MACSTR
4218 MAC2STR(mgmt
->sa
), le_to_host16(mgmt
->u
.deauth
.reason_code
));
4220 sta
= ap_get_sta(hapd
, mgmt
->sa
);
4222 wpa_msg(hapd
->msg_ctx
, MSG_DEBUG
, "Station " MACSTR
" trying "
4223 "to deauthenticate, but it is not authenticated",
4228 ap_sta_set_authorized(hapd
, sta
, 0);
4229 sta
->last_seq_ctrl
= WLAN_INVALID_MGMT_SEQ
;
4230 sta
->flags
&= ~(WLAN_STA_AUTH
| WLAN_STA_ASSOC
|
4231 WLAN_STA_ASSOC_REQ_OK
);
4232 wpa_auth_sm_event(sta
->wpa_sm
, WPA_DEAUTH
);
4233 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
4234 HOSTAPD_LEVEL_DEBUG
, "deauthenticated");
4235 mlme_deauthenticate_indication(
4236 hapd
, sta
, le_to_host16(mgmt
->u
.deauth
.reason_code
));
4237 sta
->acct_terminate_cause
= RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST
;
4238 ieee802_1x_notify_port_enabled(sta
->eapol_sm
, 0);
4239 ap_free_sta(hapd
, sta
);
4243 static void handle_beacon(struct hostapd_data
*hapd
,
4244 const struct ieee80211_mgmt
*mgmt
, size_t len
,
4245 struct hostapd_frame_info
*fi
)
4247 struct ieee802_11_elems elems
;
4249 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.beacon
)) {
4250 wpa_printf(MSG_INFO
, "handle_beacon - too short payload (len=%lu)",
4251 (unsigned long) len
);
4255 (void) ieee802_11_parse_elems(mgmt
->u
.beacon
.variable
,
4256 len
- (IEEE80211_HDRLEN
+
4257 sizeof(mgmt
->u
.beacon
)), &elems
,
4260 ap_list_process_beacon(hapd
->iface
, mgmt
, &elems
, fi
);
4264 #ifdef CONFIG_IEEE80211W
4265 static int robust_action_frame(u8 category
)
4267 return category
!= WLAN_ACTION_PUBLIC
&&
4268 category
!= WLAN_ACTION_HT
;
4270 #endif /* CONFIG_IEEE80211W */
4273 static int handle_action(struct hostapd_data
*hapd
,
4274 const struct ieee80211_mgmt
*mgmt
, size_t len
,
4277 struct sta_info
*sta
;
4278 u8
*action __maybe_unused
;
4280 if (len
< IEEE80211_HDRLEN
+ 2 + 1) {
4281 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
4282 HOSTAPD_LEVEL_DEBUG
,
4283 "handle_action - too short payload (len=%lu)",
4284 (unsigned long) len
);
4288 action
= (u8
*) &mgmt
->u
.action
.u
;
4289 wpa_printf(MSG_DEBUG
, "RX_ACTION category %u action %u sa " MACSTR
4290 " da " MACSTR
" len %d freq %u",
4291 mgmt
->u
.action
.category
, *action
,
4292 MAC2STR(mgmt
->sa
), MAC2STR(mgmt
->da
), (int) len
, freq
);
4294 sta
= ap_get_sta(hapd
, mgmt
->sa
);
4296 if (mgmt
->u
.action
.category
!= WLAN_ACTION_PUBLIC
&&
4297 (sta
== NULL
|| !(sta
->flags
& WLAN_STA_ASSOC
))) {
4298 wpa_printf(MSG_DEBUG
, "IEEE 802.11: Ignored Action "
4299 "frame (category=%u) from unassociated STA " MACSTR
,
4300 mgmt
->u
.action
.category
, MAC2STR(mgmt
->sa
));
4304 #ifdef CONFIG_IEEE80211W
4305 if (sta
&& (sta
->flags
& WLAN_STA_MFP
) &&
4306 !(mgmt
->frame_control
& host_to_le16(WLAN_FC_ISWEP
)) &&
4307 robust_action_frame(mgmt
->u
.action
.category
)) {
4308 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
4309 HOSTAPD_LEVEL_DEBUG
,
4310 "Dropped unprotected Robust Action frame from "
4314 #endif /* CONFIG_IEEE80211W */
4317 u16 fc
= le_to_host16(mgmt
->frame_control
);
4318 u16 seq_ctrl
= le_to_host16(mgmt
->seq_ctrl
);
4320 if ((fc
& WLAN_FC_RETRY
) &&
4321 sta
->last_seq_ctrl
!= WLAN_INVALID_MGMT_SEQ
&&
4322 sta
->last_seq_ctrl
== seq_ctrl
&&
4323 sta
->last_subtype
== WLAN_FC_STYPE_ACTION
) {
4324 hostapd_logger(hapd
, sta
->addr
,
4325 HOSTAPD_MODULE_IEEE80211
,
4326 HOSTAPD_LEVEL_DEBUG
,
4327 "Drop repeated action frame seq_ctrl=0x%x",
4332 sta
->last_seq_ctrl
= seq_ctrl
;
4333 sta
->last_subtype
= WLAN_FC_STYPE_ACTION
;
4336 switch (mgmt
->u
.action
.category
) {
4337 #ifdef CONFIG_IEEE80211R_AP
4338 case WLAN_ACTION_FT
:
4340 wpa_ft_action_rx(sta
->wpa_sm
, (u8
*) &mgmt
->u
.action
,
4341 len
- IEEE80211_HDRLEN
))
4344 #endif /* CONFIG_IEEE80211R_AP */
4345 case WLAN_ACTION_WMM
:
4346 hostapd_wmm_action(hapd
, mgmt
, len
);
4348 #ifdef CONFIG_IEEE80211W
4349 case WLAN_ACTION_SA_QUERY
:
4350 ieee802_11_sa_query_action(hapd
, mgmt
, len
);
4352 #endif /* CONFIG_IEEE80211W */
4353 #ifdef CONFIG_WNM_AP
4354 case WLAN_ACTION_WNM
:
4355 ieee802_11_rx_wnm_action_ap(hapd
, mgmt
, len
);
4357 #endif /* CONFIG_WNM_AP */
4359 case WLAN_ACTION_FST
:
4360 if (hapd
->iface
->fst
)
4361 fst_rx_action(hapd
->iface
->fst
, mgmt
, len
);
4363 wpa_printf(MSG_DEBUG
,
4364 "FST: Ignore FST Action frame - no FST attached");
4366 #endif /* CONFIG_FST */
4367 case WLAN_ACTION_PUBLIC
:
4368 case WLAN_ACTION_PROTECTED_DUAL
:
4369 #ifdef CONFIG_IEEE80211N
4370 if (len
>= IEEE80211_HDRLEN
+ 2 &&
4371 mgmt
->u
.action
.u
.public_action
.action
==
4372 WLAN_PA_20_40_BSS_COEX
) {
4373 hostapd_2040_coex_action(hapd
, mgmt
, len
);
4376 #endif /* CONFIG_IEEE80211N */
4378 if (len
>= IEEE80211_HDRLEN
+ 6 &&
4379 mgmt
->u
.action
.u
.vs_public_action
.action
==
4380 WLAN_PA_VENDOR_SPECIFIC
&&
4381 WPA_GET_BE24(mgmt
->u
.action
.u
.vs_public_action
.oui
) ==
4383 mgmt
->u
.action
.u
.vs_public_action
.variable
[0] ==
4385 const u8
*pos
, *end
;
4387 pos
= mgmt
->u
.action
.u
.vs_public_action
.oui
;
4388 end
= ((const u8
*) mgmt
) + len
;
4389 hostapd_dpp_rx_action(hapd
, mgmt
->sa
, pos
, end
- pos
,
4393 if (len
>= IEEE80211_HDRLEN
+ 2 &&
4394 (mgmt
->u
.action
.u
.public_action
.action
==
4395 WLAN_PA_GAS_INITIAL_RESP
||
4396 mgmt
->u
.action
.u
.public_action
.action
==
4397 WLAN_PA_GAS_COMEBACK_RESP
)) {
4398 const u8
*pos
, *end
;
4400 pos
= &mgmt
->u
.action
.u
.public_action
.action
;
4401 end
= ((const u8
*) mgmt
) + len
;
4402 gas_query_ap_rx(hapd
->gas
, mgmt
->sa
,
4403 mgmt
->u
.action
.category
,
4404 pos
, end
- pos
, hapd
->iface
->freq
);
4407 #endif /* CONFIG_DPP */
4408 if (hapd
->public_action_cb
) {
4409 hapd
->public_action_cb(hapd
->public_action_cb_ctx
,
4413 if (hapd
->public_action_cb2
) {
4414 hapd
->public_action_cb2(hapd
->public_action_cb2_ctx
,
4418 if (hapd
->public_action_cb
|| hapd
->public_action_cb2
)
4421 case WLAN_ACTION_VENDOR_SPECIFIC
:
4422 if (hapd
->vendor_action_cb
) {
4423 if (hapd
->vendor_action_cb(hapd
->vendor_action_cb_ctx
,
4425 hapd
->iface
->freq
) == 0)
4429 case WLAN_ACTION_RADIO_MEASUREMENT
:
4430 hostapd_handle_radio_measurement(hapd
, (const u8
*) mgmt
, len
);
4434 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
4435 HOSTAPD_LEVEL_DEBUG
,
4436 "handle_action - unknown action category %d or invalid "
4438 mgmt
->u
.action
.category
);
4439 if (!is_multicast_ether_addr(mgmt
->da
) &&
4440 !(mgmt
->u
.action
.category
& 0x80) &&
4441 !is_multicast_ether_addr(mgmt
->sa
)) {
4442 struct ieee80211_mgmt
*resp
;
4445 * IEEE 802.11-REVma/D9.0 - 7.3.1.11
4446 * Return the Action frame to the source without change
4447 * except that MSB of the Category set to 1.
4449 wpa_printf(MSG_DEBUG
, "IEEE 802.11: Return unknown Action "
4450 "frame back to sender");
4451 resp
= os_memdup(mgmt
, len
);
4454 os_memcpy(resp
->da
, resp
->sa
, ETH_ALEN
);
4455 os_memcpy(resp
->sa
, hapd
->own_addr
, ETH_ALEN
);
4456 os_memcpy(resp
->bssid
, hapd
->own_addr
, ETH_ALEN
);
4457 resp
->u
.action
.category
|= 0x80;
4459 if (hostapd_drv_send_mlme(hapd
, resp
, len
, 0) < 0) {
4460 wpa_printf(MSG_ERROR
, "IEEE 802.11: Failed to send "
4471 * ieee802_11_mgmt - process incoming IEEE 802.11 management frames
4472 * @hapd: hostapd BSS data structure (the BSS to which the management frame was
4474 * @buf: management frame data (starting from IEEE 802.11 header)
4475 * @len: length of frame data in octets
4476 * @fi: meta data about received frame (signal level, etc.)
4478 * Process all incoming IEEE 802.11 management frames. This will be called for
4479 * each frame received from the kernel driver through wlan#ap interface. In
4480 * addition, it can be called to re-inserted pending frames (e.g., when using
4481 * external RADIUS server as an MAC ACL).
4483 int ieee802_11_mgmt(struct hostapd_data
*hapd
, const u8
*buf
, size_t len
,
4484 struct hostapd_frame_info
*fi
)
4486 struct ieee80211_mgmt
*mgmt
;
4490 int ssi_signal
= fi
? fi
->ssi_signal
: 0;
4498 freq
= hapd
->iface
->freq
;
4500 mgmt
= (struct ieee80211_mgmt
*) buf
;
4501 fc
= le_to_host16(mgmt
->frame_control
);
4502 stype
= WLAN_FC_GET_STYPE(fc
);
4504 if (stype
== WLAN_FC_STYPE_BEACON
) {
4505 handle_beacon(hapd
, mgmt
, len
, fi
);
4509 if (!is_broadcast_ether_addr(mgmt
->bssid
) &&
4511 /* Invitation responses can be sent with the peer MAC as BSSID */
4512 !((hapd
->conf
->p2p
& P2P_GROUP_OWNER
) &&
4513 stype
== WLAN_FC_STYPE_ACTION
) &&
4514 #endif /* CONFIG_P2P */
4516 !(hapd
->conf
->mesh
& MESH_ENABLED
) &&
4517 #endif /* CONFIG_MESH */
4518 os_memcmp(mgmt
->bssid
, hapd
->own_addr
, ETH_ALEN
) != 0) {
4519 wpa_printf(MSG_INFO
, "MGMT: BSSID=" MACSTR
" not our address",
4520 MAC2STR(mgmt
->bssid
));
4525 if (stype
== WLAN_FC_STYPE_PROBE_REQ
) {
4526 handle_probe_req(hapd
, mgmt
, len
, ssi_signal
);
4530 if ((!is_broadcast_ether_addr(mgmt
->da
) ||
4531 stype
!= WLAN_FC_STYPE_ACTION
) &&
4532 os_memcmp(mgmt
->da
, hapd
->own_addr
, ETH_ALEN
) != 0) {
4533 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
4534 HOSTAPD_LEVEL_DEBUG
,
4535 "MGMT: DA=" MACSTR
" not our address",
4540 if (hapd
->iconf
->track_sta_max_num
)
4541 sta_track_add(hapd
->iface
, mgmt
->sa
, ssi_signal
);
4544 case WLAN_FC_STYPE_AUTH
:
4545 wpa_printf(MSG_DEBUG
, "mgmt::auth");
4546 handle_auth(hapd
, mgmt
, len
, ssi_signal
, 0);
4549 case WLAN_FC_STYPE_ASSOC_REQ
:
4550 wpa_printf(MSG_DEBUG
, "mgmt::assoc_req");
4551 handle_assoc(hapd
, mgmt
, len
, 0, ssi_signal
);
4554 case WLAN_FC_STYPE_REASSOC_REQ
:
4555 wpa_printf(MSG_DEBUG
, "mgmt::reassoc_req");
4556 handle_assoc(hapd
, mgmt
, len
, 1, ssi_signal
);
4559 case WLAN_FC_STYPE_DISASSOC
:
4560 wpa_printf(MSG_DEBUG
, "mgmt::disassoc");
4561 handle_disassoc(hapd
, mgmt
, len
);
4564 case WLAN_FC_STYPE_DEAUTH
:
4565 wpa_msg(hapd
->msg_ctx
, MSG_DEBUG
, "mgmt::deauth");
4566 handle_deauth(hapd
, mgmt
, len
);
4569 case WLAN_FC_STYPE_ACTION
:
4570 wpa_printf(MSG_DEBUG
, "mgmt::action");
4571 ret
= handle_action(hapd
, mgmt
, len
, freq
);
4574 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
4575 HOSTAPD_LEVEL_DEBUG
,
4576 "unknown mgmt frame subtype %d", stype
);
4584 static void handle_auth_cb(struct hostapd_data
*hapd
,
4585 const struct ieee80211_mgmt
*mgmt
,
4588 u16 auth_alg
, auth_transaction
, status_code
;
4589 struct sta_info
*sta
;
4591 sta
= ap_get_sta(hapd
, mgmt
->da
);
4593 wpa_printf(MSG_DEBUG
, "handle_auth_cb: STA " MACSTR
4599 auth_alg
= le_to_host16(mgmt
->u
.auth
.auth_alg
);
4600 auth_transaction
= le_to_host16(mgmt
->u
.auth
.auth_transaction
);
4601 status_code
= le_to_host16(mgmt
->u
.auth
.status_code
);
4604 hostapd_logger(hapd
, mgmt
->da
, HOSTAPD_MODULE_IEEE80211
,
4605 HOSTAPD_LEVEL_NOTICE
,
4606 "did not acknowledge authentication response");
4610 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.auth
)) {
4611 wpa_printf(MSG_INFO
, "handle_auth_cb - too short payload (len=%lu)",
4612 (unsigned long) len
);
4616 if (status_code
== WLAN_STATUS_SUCCESS
&&
4617 ((auth_alg
== WLAN_AUTH_OPEN
&& auth_transaction
== 2) ||
4618 (auth_alg
== WLAN_AUTH_SHARED_KEY
&& auth_transaction
== 4))) {
4619 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
4620 HOSTAPD_LEVEL_INFO
, "authenticated");
4621 sta
->flags
|= WLAN_STA_AUTH
;
4622 if (sta
->added_unassoc
)
4623 hostapd_set_sta_flags(hapd
, sta
);
4628 if (status_code
!= WLAN_STATUS_SUCCESS
&& sta
->added_unassoc
) {
4629 hostapd_drv_sta_remove(hapd
, sta
->addr
);
4630 sta
->added_unassoc
= 0;
4635 static void hostapd_set_wds_encryption(struct hostapd_data
*hapd
,
4636 struct sta_info
*sta
,
4640 struct hostapd_ssid
*ssid
= &hapd
->conf
->ssid
;
4642 if (hapd
->conf
->ieee802_1x
|| hapd
->conf
->wpa
)
4645 for (i
= 0; i
< 4; i
++) {
4646 if (ssid
->wep
.key
[i
] &&
4647 hostapd_drv_set_key(ifname_wds
, hapd
, WPA_ALG_WEP
, NULL
, i
,
4648 i
== ssid
->wep
.idx
, NULL
, 0,
4649 ssid
->wep
.key
[i
], ssid
->wep
.len
[i
])) {
4650 wpa_printf(MSG_WARNING
,
4651 "Could not set WEP keys for WDS interface; %s",
4659 static void handle_assoc_cb(struct hostapd_data
*hapd
,
4660 const struct ieee80211_mgmt
*mgmt
,
4661 size_t len
, int reassoc
, int ok
)
4664 struct sta_info
*sta
;
4667 sta
= ap_get_sta(hapd
, mgmt
->da
);
4669 wpa_printf(MSG_INFO
, "handle_assoc_cb: STA " MACSTR
" not found",
4674 if (len
< IEEE80211_HDRLEN
+ (reassoc
? sizeof(mgmt
->u
.reassoc_resp
) :
4675 sizeof(mgmt
->u
.assoc_resp
))) {
4676 wpa_printf(MSG_INFO
,
4677 "handle_assoc_cb(reassoc=%d) - too short payload (len=%lu)",
4678 reassoc
, (unsigned long) len
);
4679 hostapd_drv_sta_remove(hapd
, sta
->addr
);
4684 status
= le_to_host16(mgmt
->u
.reassoc_resp
.status_code
);
4686 status
= le_to_host16(mgmt
->u
.assoc_resp
.status_code
);
4689 hostapd_logger(hapd
, mgmt
->da
, HOSTAPD_MODULE_IEEE80211
,
4690 HOSTAPD_LEVEL_DEBUG
,
4691 "did not acknowledge association response");
4692 sta
->flags
&= ~WLAN_STA_ASSOC_REQ_OK
;
4693 /* The STA is added only in case of SUCCESS */
4694 if (status
== WLAN_STATUS_SUCCESS
)
4695 hostapd_drv_sta_remove(hapd
, sta
->addr
);
4700 if (status
!= WLAN_STATUS_SUCCESS
)
4703 /* Stop previous accounting session, if one is started, and allocate
4704 * new session id for the new session. */
4705 accounting_sta_stop(hapd
, sta
);
4707 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
4709 "associated (aid %d)",
4712 if (sta
->flags
& WLAN_STA_ASSOC
)
4714 sta
->flags
|= WLAN_STA_ASSOC
;
4715 sta
->flags
&= ~WLAN_STA_WNM_SLEEP_MODE
;
4716 if ((!hapd
->conf
->ieee802_1x
&& !hapd
->conf
->wpa
&&
4717 !hapd
->conf
->osen
) ||
4718 sta
->auth_alg
== WLAN_AUTH_FILS_SK
||
4719 sta
->auth_alg
== WLAN_AUTH_FILS_SK_PFS
||
4720 sta
->auth_alg
== WLAN_AUTH_FILS_PK
||
4721 sta
->auth_alg
== WLAN_AUTH_FT
) {
4723 * Open, static WEP, FT protocol, or FILS; no separate
4724 * authorization step.
4726 ap_sta_set_authorized(hapd
, sta
, 1);
4730 mlme_reassociate_indication(hapd
, sta
);
4732 mlme_associate_indication(hapd
, sta
);
4734 #ifdef CONFIG_IEEE80211W
4735 sta
->sa_query_timed_out
= 0;
4736 #endif /* CONFIG_IEEE80211W */
4738 if (sta
->eapol_sm
== NULL
) {
4740 * This STA does not use RADIUS server for EAP authentication,
4741 * so bind it to the selected VLAN interface now, since the
4742 * interface selection is not going to change anymore.
4744 if (ap_sta_bind_vlan(hapd
, sta
) < 0)
4746 } else if (sta
->vlan_id
) {
4747 /* VLAN ID already set (e.g., by PMKSA caching), so bind STA */
4748 if (ap_sta_bind_vlan(hapd
, sta
) < 0)
4752 hostapd_set_sta_flags(hapd
, sta
);
4754 if (!(sta
->flags
& WLAN_STA_WDS
) && sta
->pending_wds_enable
) {
4755 wpa_printf(MSG_DEBUG
, "Enable 4-address WDS mode for STA "
4756 MACSTR
" based on pending request",
4757 MAC2STR(sta
->addr
));
4758 sta
->pending_wds_enable
= 0;
4759 sta
->flags
|= WLAN_STA_WDS
;
4762 if (sta
->flags
& (WLAN_STA_WDS
| WLAN_STA_MULTI_AP
)) {
4764 char ifname_wds
[IFNAMSIZ
+ 1];
4766 wpa_printf(MSG_DEBUG
, "Reenable 4-address WDS mode for STA "
4768 MAC2STR(sta
->addr
), sta
->aid
);
4769 ret
= hostapd_set_wds_sta(hapd
, ifname_wds
, sta
->addr
,
4772 hostapd_set_wds_encryption(hapd
, sta
, ifname_wds
);
4775 if (sta
->auth_alg
== WLAN_AUTH_FT
)
4776 wpa_auth_sm_event(sta
->wpa_sm
, WPA_ASSOC_FT
);
4778 wpa_auth_sm_event(sta
->wpa_sm
, WPA_ASSOC
);
4779 hapd
->new_assoc_sta_cb(hapd
, sta
, !new_assoc
);
4780 ieee802_1x_notify_port_enabled(sta
->eapol_sm
, 1);
4783 if ((sta
->auth_alg
== WLAN_AUTH_FILS_SK
||
4784 sta
->auth_alg
== WLAN_AUTH_FILS_SK_PFS
||
4785 sta
->auth_alg
== WLAN_AUTH_FILS_PK
) &&
4786 fils_set_tk(sta
->wpa_sm
) < 0) {
4787 wpa_printf(MSG_DEBUG
, "FILS: TK configuration failed");
4788 ap_sta_disconnect(hapd
, sta
, sta
->addr
,
4789 WLAN_REASON_UNSPECIFIED
);
4792 #endif /* CONFIG_FILS */
4794 if (sta
->pending_eapol_rx
) {
4795 struct os_reltime now
, age
;
4797 os_get_reltime(&now
);
4798 os_reltime_sub(&now
, &sta
->pending_eapol_rx
->rx_time
, &age
);
4799 if (age
.sec
== 0 && age
.usec
< 200000) {
4800 wpa_printf(MSG_DEBUG
,
4801 "Process pending EAPOL frame that was received from " MACSTR
" just before association notification",
4802 MAC2STR(sta
->addr
));
4805 wpabuf_head(sta
->pending_eapol_rx
->buf
),
4806 wpabuf_len(sta
->pending_eapol_rx
->buf
));
4808 wpabuf_free(sta
->pending_eapol_rx
->buf
);
4809 os_free(sta
->pending_eapol_rx
);
4810 sta
->pending_eapol_rx
= NULL
;
4815 static void handle_deauth_cb(struct hostapd_data
*hapd
,
4816 const struct ieee80211_mgmt
*mgmt
,
4819 struct sta_info
*sta
;
4820 if (is_multicast_ether_addr(mgmt
->da
))
4822 sta
= ap_get_sta(hapd
, mgmt
->da
);
4824 wpa_printf(MSG_DEBUG
, "handle_deauth_cb: STA " MACSTR
4825 " not found", MAC2STR(mgmt
->da
));
4829 wpa_printf(MSG_DEBUG
, "STA " MACSTR
" acknowledged deauth",
4830 MAC2STR(sta
->addr
));
4832 wpa_printf(MSG_DEBUG
, "STA " MACSTR
" did not acknowledge "
4833 "deauth", MAC2STR(sta
->addr
));
4835 ap_sta_deauth_cb(hapd
, sta
);
4839 static void handle_disassoc_cb(struct hostapd_data
*hapd
,
4840 const struct ieee80211_mgmt
*mgmt
,
4843 struct sta_info
*sta
;
4844 if (is_multicast_ether_addr(mgmt
->da
))
4846 sta
= ap_get_sta(hapd
, mgmt
->da
);
4848 wpa_printf(MSG_DEBUG
, "handle_disassoc_cb: STA " MACSTR
4849 " not found", MAC2STR(mgmt
->da
));
4853 wpa_printf(MSG_DEBUG
, "STA " MACSTR
" acknowledged disassoc",
4854 MAC2STR(sta
->addr
));
4856 wpa_printf(MSG_DEBUG
, "STA " MACSTR
" did not acknowledge "
4857 "disassoc", MAC2STR(sta
->addr
));
4859 ap_sta_disassoc_cb(hapd
, sta
);
4863 static void handle_action_cb(struct hostapd_data
*hapd
,
4864 const struct ieee80211_mgmt
*mgmt
,
4867 struct sta_info
*sta
;
4868 const struct rrm_measurement_report_element
*report
;
4870 if (is_multicast_ether_addr(mgmt
->da
))
4873 if (len
>= IEEE80211_HDRLEN
+ 6 &&
4874 mgmt
->u
.action
.category
== WLAN_ACTION_PUBLIC
&&
4875 mgmt
->u
.action
.u
.vs_public_action
.action
==
4876 WLAN_PA_VENDOR_SPECIFIC
&&
4877 WPA_GET_BE24(mgmt
->u
.action
.u
.vs_public_action
.oui
) ==
4879 mgmt
->u
.action
.u
.vs_public_action
.variable
[0] ==
4881 const u8
*pos
, *end
;
4883 pos
= &mgmt
->u
.action
.u
.vs_public_action
.variable
[1];
4884 end
= ((const u8
*) mgmt
) + len
;
4885 hostapd_dpp_tx_status(hapd
, mgmt
->da
, pos
, end
- pos
, ok
);
4888 if (len
>= IEEE80211_HDRLEN
+ 2 &&
4889 mgmt
->u
.action
.category
== WLAN_ACTION_PUBLIC
&&
4890 (mgmt
->u
.action
.u
.public_action
.action
==
4891 WLAN_PA_GAS_INITIAL_REQ
||
4892 mgmt
->u
.action
.u
.public_action
.action
==
4893 WLAN_PA_GAS_COMEBACK_REQ
)) {
4894 const u8
*pos
, *end
;
4896 pos
= mgmt
->u
.action
.u
.public_action
.variable
;
4897 end
= ((const u8
*) mgmt
) + len
;
4898 gas_query_ap_tx_status(hapd
->gas
, mgmt
->da
, pos
, end
- pos
, ok
);
4901 #endif /* CONFIG_DPP */
4902 sta
= ap_get_sta(hapd
, mgmt
->da
);
4904 wpa_printf(MSG_DEBUG
, "handle_action_cb: STA " MACSTR
4905 " not found", MAC2STR(mgmt
->da
));
4909 if (len
< 24 + 5 + sizeof(*report
))
4911 report
= (const struct rrm_measurement_report_element
*)
4912 &mgmt
->u
.action
.u
.rrm
.variable
[2];
4913 if (mgmt
->u
.action
.category
== WLAN_ACTION_RADIO_MEASUREMENT
&&
4914 mgmt
->u
.action
.u
.rrm
.action
== WLAN_RRM_RADIO_MEASUREMENT_REQUEST
&&
4915 report
->eid
== WLAN_EID_MEASURE_REQUEST
&&
4917 report
->type
== MEASURE_TYPE_BEACON
)
4918 hostapd_rrm_beacon_req_tx_status(hapd
, mgmt
, len
, ok
);
4923 * ieee802_11_mgmt_cb - Process management frame TX status callback
4924 * @hapd: hostapd BSS data structure (the BSS from which the management frame
4926 * @buf: management frame data (starting from IEEE 802.11 header)
4927 * @len: length of frame data in octets
4928 * @stype: management frame subtype from frame control field
4929 * @ok: Whether the frame was ACK'ed
4931 void ieee802_11_mgmt_cb(struct hostapd_data
*hapd
, const u8
*buf
, size_t len
,
4934 const struct ieee80211_mgmt
*mgmt
;
4935 mgmt
= (const struct ieee80211_mgmt
*) buf
;
4937 #ifdef CONFIG_TESTING_OPTIONS
4938 if (hapd
->ext_mgmt_frame_handling
) {
4939 size_t hex_len
= 2 * len
+ 1;
4940 char *hex
= os_malloc(hex_len
);
4943 wpa_snprintf_hex(hex
, hex_len
, buf
, len
);
4944 wpa_msg(hapd
->msg_ctx
, MSG_INFO
,
4945 "MGMT-TX-STATUS stype=%u ok=%d buf=%s",
4951 #endif /* CONFIG_TESTING_OPTIONS */
4954 case WLAN_FC_STYPE_AUTH
:
4955 wpa_printf(MSG_DEBUG
, "mgmt::auth cb");
4956 handle_auth_cb(hapd
, mgmt
, len
, ok
);
4958 case WLAN_FC_STYPE_ASSOC_RESP
:
4959 wpa_printf(MSG_DEBUG
, "mgmt::assoc_resp cb");
4960 handle_assoc_cb(hapd
, mgmt
, len
, 0, ok
);
4962 case WLAN_FC_STYPE_REASSOC_RESP
:
4963 wpa_printf(MSG_DEBUG
, "mgmt::reassoc_resp cb");
4964 handle_assoc_cb(hapd
, mgmt
, len
, 1, ok
);
4966 case WLAN_FC_STYPE_PROBE_RESP
:
4967 wpa_printf(MSG_EXCESSIVE
, "mgmt::proberesp cb ok=%d", ok
);
4969 case WLAN_FC_STYPE_DEAUTH
:
4970 wpa_printf(MSG_DEBUG
, "mgmt::deauth cb");
4971 handle_deauth_cb(hapd
, mgmt
, len
, ok
);
4973 case WLAN_FC_STYPE_DISASSOC
:
4974 wpa_printf(MSG_DEBUG
, "mgmt::disassoc cb");
4975 handle_disassoc_cb(hapd
, mgmt
, len
, ok
);
4977 case WLAN_FC_STYPE_ACTION
:
4978 wpa_printf(MSG_DEBUG
, "mgmt::action cb ok=%d", ok
);
4979 handle_action_cb(hapd
, mgmt
, len
, ok
);
4982 wpa_printf(MSG_INFO
, "unknown mgmt cb frame subtype %d", stype
);
4988 int ieee802_11_get_mib(struct hostapd_data
*hapd
, char *buf
, size_t buflen
)
4995 int ieee802_11_get_mib_sta(struct hostapd_data
*hapd
, struct sta_info
*sta
,
4996 char *buf
, size_t buflen
)
5003 void hostapd_tx_status(struct hostapd_data
*hapd
, const u8
*addr
,
5004 const u8
*buf
, size_t len
, int ack
)
5006 struct sta_info
*sta
;
5007 struct hostapd_iface
*iface
= hapd
->iface
;
5009 sta
= ap_get_sta(hapd
, addr
);
5010 if (sta
== NULL
&& iface
->num_bss
> 1) {
5012 for (j
= 0; j
< iface
->num_bss
; j
++) {
5013 hapd
= iface
->bss
[j
];
5014 sta
= ap_get_sta(hapd
, addr
);
5019 if (sta
== NULL
|| !(sta
->flags
& WLAN_STA_ASSOC
))
5021 if (sta
->flags
& WLAN_STA_PENDING_POLL
) {
5022 wpa_printf(MSG_DEBUG
, "STA " MACSTR
" %s pending "
5023 "activity poll", MAC2STR(sta
->addr
),
5024 ack
? "ACKed" : "did not ACK");
5026 sta
->flags
&= ~WLAN_STA_PENDING_POLL
;
5029 ieee802_1x_tx_status(hapd
, sta
, buf
, len
, ack
);
5033 void hostapd_eapol_tx_status(struct hostapd_data
*hapd
, const u8
*dst
,
5034 const u8
*data
, size_t len
, int ack
)
5036 struct sta_info
*sta
;
5037 struct hostapd_iface
*iface
= hapd
->iface
;
5039 sta
= ap_get_sta(hapd
, dst
);
5040 if (sta
== NULL
&& iface
->num_bss
> 1) {
5042 for (j
= 0; j
< iface
->num_bss
; j
++) {
5043 hapd
= iface
->bss
[j
];
5044 sta
= ap_get_sta(hapd
, dst
);
5049 if (sta
== NULL
|| !(sta
->flags
& WLAN_STA_ASSOC
)) {
5050 wpa_printf(MSG_DEBUG
, "Ignore TX status for Data frame to STA "
5051 MACSTR
" that is not currently associated",
5056 ieee802_1x_eapol_tx_status(hapd
, sta
, data
, len
, ack
);
5060 void hostapd_client_poll_ok(struct hostapd_data
*hapd
, const u8
*addr
)
5062 struct sta_info
*sta
;
5063 struct hostapd_iface
*iface
= hapd
->iface
;
5065 sta
= ap_get_sta(hapd
, addr
);
5066 if (sta
== NULL
&& iface
->num_bss
> 1) {
5068 for (j
= 0; j
< iface
->num_bss
; j
++) {
5069 hapd
= iface
->bss
[j
];
5070 sta
= ap_get_sta(hapd
, addr
);
5077 wpa_msg(hapd
->msg_ctx
, MSG_INFO
, AP_STA_POLL_OK MACSTR
,
5078 MAC2STR(sta
->addr
));
5079 if (!(sta
->flags
& WLAN_STA_PENDING_POLL
))
5082 wpa_printf(MSG_DEBUG
, "STA " MACSTR
" ACKed pending "
5083 "activity poll", MAC2STR(sta
->addr
));
5084 sta
->flags
&= ~WLAN_STA_PENDING_POLL
;
5088 void ieee802_11_rx_from_unknown(struct hostapd_data
*hapd
, const u8
*src
,
5091 struct sta_info
*sta
;
5093 sta
= ap_get_sta(hapd
, src
);
5095 ((sta
->flags
& WLAN_STA_ASSOC
) ||
5096 ((sta
->flags
& WLAN_STA_ASSOC_REQ_OK
) && wds
))) {
5097 if (!hapd
->conf
->wds_sta
)
5100 if ((sta
->flags
& (WLAN_STA_ASSOC
| WLAN_STA_ASSOC_REQ_OK
)) ==
5101 WLAN_STA_ASSOC_REQ_OK
) {
5102 wpa_printf(MSG_DEBUG
,
5103 "Postpone 4-address WDS mode enabling for STA "
5104 MACSTR
" since TX status for AssocResp is not yet known",
5105 MAC2STR(sta
->addr
));
5106 sta
->pending_wds_enable
= 1;
5110 if (wds
&& !(sta
->flags
& WLAN_STA_WDS
)) {
5112 char ifname_wds
[IFNAMSIZ
+ 1];
5114 wpa_printf(MSG_DEBUG
, "Enable 4-address WDS mode for "
5115 "STA " MACSTR
" (aid %u)",
5116 MAC2STR(sta
->addr
), sta
->aid
);
5117 sta
->flags
|= WLAN_STA_WDS
;
5118 ret
= hostapd_set_wds_sta(hapd
, ifname_wds
,
5119 sta
->addr
, sta
->aid
, 1);
5121 hostapd_set_wds_encryption(hapd
, sta
,
5127 wpa_printf(MSG_DEBUG
, "Data/PS-poll frame from not associated STA "
5128 MACSTR
, MAC2STR(src
));
5129 if (is_multicast_ether_addr(src
)) {
5130 /* Broadcast bit set in SA?! Ignore the frame silently. */
5134 if (sta
&& (sta
->flags
& WLAN_STA_ASSOC_REQ_OK
)) {
5135 wpa_printf(MSG_DEBUG
, "Association Response to the STA has "
5136 "already been sent, but no TX status yet known - "
5137 "ignore Class 3 frame issue with " MACSTR
,
5142 if (sta
&& (sta
->flags
& WLAN_STA_AUTH
))
5143 hostapd_drv_sta_disassoc(
5145 WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA
);
5147 hostapd_drv_sta_deauth(
5149 WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA
);
5153 #endif /* CONFIG_NATIVE_WINDOWS */