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 "common/wpa_common.h"
27 #include "radius/radius.h"
28 #include "radius/radius_client.h"
34 #include "ieee802_11_auth.h"
36 #include "ieee802_1x.h"
38 #include "pmksa_cache_auth.h"
41 #include "accounting.h"
42 #include "ap_config.h"
44 #include "p2p_hostapd.h"
45 #include "ap_drv_ops.h"
47 #include "hw_features.h"
48 #include "ieee802_11.h"
54 #include "dpp_hostapd.h"
55 #include "gas_query_ap.h"
59 static struct wpabuf
*
60 prepare_auth_resp_fils(struct hostapd_data
*hapd
,
61 struct sta_info
*sta
, u16
*resp
,
62 struct rsn_pmksa_cache_entry
*pmksa
,
63 struct wpabuf
*erp_resp
,
64 const u8
*msk
, size_t msk_len
,
66 #endif /* CONFIG_FILS */
67 static void handle_auth(struct hostapd_data
*hapd
,
68 const struct ieee80211_mgmt
*mgmt
, size_t len
,
69 int rssi
, int from_queue
);
72 u8
* hostapd_eid_multi_ap(struct hostapd_data
*hapd
, u8
*eid
)
76 if (!hapd
->conf
->multi_ap
)
78 if (hapd
->conf
->multi_ap
& BACKHAUL_BSS
)
79 multi_ap_val
|= MULTI_AP_BACKHAUL_BSS
;
80 if (hapd
->conf
->multi_ap
& FRONTHAUL_BSS
)
81 multi_ap_val
|= MULTI_AP_FRONTHAUL_BSS
;
83 return eid
+ add_multi_ap_ie(eid
, 9, multi_ap_val
);
87 u8
* hostapd_eid_supp_rates(struct hostapd_data
*hapd
, u8
*eid
)
92 if (hapd
->iface
->current_rates
== NULL
)
95 *pos
++ = WLAN_EID_SUPP_RATES
;
96 num
= hapd
->iface
->num_rates
;
97 if (hapd
->iconf
->ieee80211n
&& hapd
->iconf
->require_ht
)
99 if (hapd
->iconf
->ieee80211ac
&& hapd
->iconf
->require_vht
)
101 if (hapd
->conf
->sae_pwe
== 1 &&
102 wpa_key_mgmt_sae(hapd
->conf
->wpa_key_mgmt
))
105 /* rest of the rates are encoded in Extended supported
111 for (i
= 0, count
= 0; i
< hapd
->iface
->num_rates
&& count
< num
;
114 *pos
= hapd
->iface
->current_rates
[i
].rate
/ 5;
115 if (hapd
->iface
->current_rates
[i
].flags
& HOSTAPD_RATE_BASIC
)
120 if (hapd
->iconf
->ieee80211n
&& hapd
->iconf
->require_ht
&& count
< 8) {
122 *pos
++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_HT_PHY
;
125 if (hapd
->iconf
->ieee80211ac
&& hapd
->iconf
->require_vht
&& count
< 8) {
127 *pos
++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_VHT_PHY
;
130 if (hapd
->conf
->sae_pwe
== 1 &&
131 wpa_key_mgmt_sae(hapd
->conf
->wpa_key_mgmt
) &&
134 *pos
++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_SAE_H2E_ONLY
;
141 u8
* hostapd_eid_ext_supp_rates(struct hostapd_data
*hapd
, u8
*eid
)
146 if (hapd
->iface
->current_rates
== NULL
)
149 num
= hapd
->iface
->num_rates
;
150 if (hapd
->iconf
->ieee80211n
&& hapd
->iconf
->require_ht
)
152 if (hapd
->iconf
->ieee80211ac
&& hapd
->iconf
->require_vht
)
154 if (hapd
->conf
->sae_pwe
== 1 &&
155 wpa_key_mgmt_sae(hapd
->conf
->wpa_key_mgmt
))
161 *pos
++ = WLAN_EID_EXT_SUPP_RATES
;
163 for (i
= 0, count
= 0; i
< hapd
->iface
->num_rates
&& count
< num
+ 8;
167 continue; /* already in SuppRates IE */
168 *pos
= hapd
->iface
->current_rates
[i
].rate
/ 5;
169 if (hapd
->iface
->current_rates
[i
].flags
& HOSTAPD_RATE_BASIC
)
174 if (hapd
->iconf
->ieee80211n
&& hapd
->iconf
->require_ht
) {
177 *pos
++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_HT_PHY
;
180 if (hapd
->iconf
->ieee80211ac
&& hapd
->iconf
->require_vht
) {
183 *pos
++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_VHT_PHY
;
186 if (hapd
->conf
->sae_pwe
== 1 &&
187 wpa_key_mgmt_sae(hapd
->conf
->wpa_key_mgmt
)) {
190 *pos
++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_SAE_H2E_ONLY
;
197 u16
hostapd_own_capab_info(struct hostapd_data
*hapd
)
199 int capab
= WLAN_CAPABILITY_ESS
;
204 /* Check if any of configured channels require DFS */
205 dfs
= hostapd_is_dfs_required(hapd
->iface
);
207 wpa_printf(MSG_WARNING
, "Failed to check if DFS is required; ret=%d",
212 if (hapd
->iface
->num_sta_no_short_preamble
== 0 &&
213 hapd
->iconf
->preamble
== SHORT_PREAMBLE
)
214 capab
|= WLAN_CAPABILITY_SHORT_PREAMBLE
;
216 privacy
= hapd
->conf
->ssid
.wep
.keys_set
;
218 if (hapd
->conf
->ieee802_1x
&&
219 (hapd
->conf
->default_wep_key_len
||
220 hapd
->conf
->individual_wep_key_len
))
227 if (hapd
->conf
->osen
)
229 #endif /* CONFIG_HS20 */
232 capab
|= WLAN_CAPABILITY_PRIVACY
;
234 if (hapd
->iface
->current_mode
&&
235 hapd
->iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211G
&&
236 hapd
->iface
->num_sta_no_short_slot_time
== 0)
237 capab
|= WLAN_CAPABILITY_SHORT_SLOT_TIME
;
240 * Currently, Spectrum Management capability bit is set when directly
241 * requested in configuration by spectrum_mgmt_required or when AP is
242 * running on DFS channel.
243 * TODO: Also consider driver support for TPC to set Spectrum Mgmt bit
245 if (hapd
->iface
->current_mode
&&
246 hapd
->iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211A
&&
247 (hapd
->iconf
->spectrum_mgmt_required
|| dfs
))
248 capab
|= WLAN_CAPABILITY_SPECTRUM_MGMT
;
250 for (i
= 0; i
< RRM_CAPABILITIES_IE_LEN
; i
++) {
251 if (hapd
->conf
->radio_measurements
[i
]) {
252 capab
|= IEEE80211_CAP_RRM
;
261 #ifndef CONFIG_NO_RC4
262 static u16
auth_shared_key(struct hostapd_data
*hapd
, struct sta_info
*sta
,
263 u16 auth_transaction
, const u8
*challenge
,
266 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
268 "authentication (shared key, transaction %d)",
271 if (auth_transaction
== 1) {
272 if (!sta
->challenge
) {
273 /* Generate a pseudo-random challenge */
276 sta
->challenge
= os_zalloc(WLAN_AUTH_CHALLENGE_LEN
);
277 if (sta
->challenge
== NULL
)
278 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
280 if (os_get_random(key
, sizeof(key
)) < 0) {
281 os_free(sta
->challenge
);
282 sta
->challenge
= NULL
;
283 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
286 rc4_skip(key
, sizeof(key
), 0,
287 sta
->challenge
, WLAN_AUTH_CHALLENGE_LEN
);
292 if (auth_transaction
!= 3)
293 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
296 if (!iswep
|| !sta
->challenge
|| !challenge
||
297 os_memcmp_const(sta
->challenge
, challenge
,
298 WLAN_AUTH_CHALLENGE_LEN
)) {
299 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
301 "shared key authentication - invalid "
302 "challenge-response");
303 return WLAN_STATUS_CHALLENGE_FAIL
;
306 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
308 "authentication OK (shared key)");
309 sta
->flags
|= WLAN_STA_AUTH
;
310 wpa_auth_sm_event(sta
->wpa_sm
, WPA_AUTH
);
311 os_free(sta
->challenge
);
312 sta
->challenge
= NULL
;
316 #endif /* CONFIG_NO_RC4 */
319 static int send_auth_reply(struct hostapd_data
*hapd
,
320 const u8
*dst
, const u8
*bssid
,
321 u16 auth_alg
, u16 auth_transaction
, u16 resp
,
322 const u8
*ies
, size_t ies_len
, const char *dbg
)
324 struct ieee80211_mgmt
*reply
;
327 int reply_res
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
329 rlen
= IEEE80211_HDRLEN
+ sizeof(reply
->u
.auth
) + ies_len
;
330 buf
= os_zalloc(rlen
);
334 reply
= (struct ieee80211_mgmt
*) buf
;
335 reply
->frame_control
= IEEE80211_FC(WLAN_FC_TYPE_MGMT
,
337 os_memcpy(reply
->da
, dst
, ETH_ALEN
);
338 os_memcpy(reply
->sa
, hapd
->own_addr
, ETH_ALEN
);
339 os_memcpy(reply
->bssid
, bssid
, ETH_ALEN
);
341 reply
->u
.auth
.auth_alg
= host_to_le16(auth_alg
);
342 reply
->u
.auth
.auth_transaction
= host_to_le16(auth_transaction
);
343 reply
->u
.auth
.status_code
= host_to_le16(resp
);
346 os_memcpy(reply
->u
.auth
.variable
, ies
, ies_len
);
348 wpa_printf(MSG_DEBUG
, "authentication reply: STA=" MACSTR
349 " auth_alg=%d auth_transaction=%d resp=%d (IE len=%lu) (dbg=%s)",
350 MAC2STR(dst
), auth_alg
, auth_transaction
,
351 resp
, (unsigned long) ies_len
, dbg
);
352 if (hostapd_drv_send_mlme(hapd
, reply
, rlen
, 0) < 0)
353 wpa_printf(MSG_INFO
, "send_auth_reply: send failed");
355 reply_res
= WLAN_STATUS_SUCCESS
;
363 #ifdef CONFIG_IEEE80211R_AP
364 static void handle_auth_ft_finish(void *ctx
, const u8
*dst
, const u8
*bssid
,
365 u16 auth_transaction
, u16 status
,
366 const u8
*ies
, size_t ies_len
)
368 struct hostapd_data
*hapd
= ctx
;
369 struct sta_info
*sta
;
372 reply_res
= send_auth_reply(hapd
, dst
, bssid
, WLAN_AUTH_FT
,
373 auth_transaction
, status
, ies
, ies_len
,
376 sta
= ap_get_sta(hapd
, dst
);
380 if (sta
->added_unassoc
&& (reply_res
!= WLAN_STATUS_SUCCESS
||
381 status
!= WLAN_STATUS_SUCCESS
)) {
382 hostapd_drv_sta_remove(hapd
, sta
->addr
);
383 sta
->added_unassoc
= 0;
387 if (status
!= WLAN_STATUS_SUCCESS
)
390 hostapd_logger(hapd
, dst
, HOSTAPD_MODULE_IEEE80211
,
391 HOSTAPD_LEVEL_DEBUG
, "authentication OK (FT)");
392 sta
->flags
|= WLAN_STA_AUTH
;
393 mlme_authenticate_indication(hapd
, sta
);
395 #endif /* CONFIG_IEEE80211R_AP */
400 static void sae_set_state(struct sta_info
*sta
, enum sae_state state
,
403 wpa_printf(MSG_DEBUG
, "SAE: State %s -> %s for peer " MACSTR
" (%s)",
404 sae_state_txt(sta
->sae
->state
), sae_state_txt(state
),
405 MAC2STR(sta
->addr
), reason
);
406 sta
->sae
->state
= state
;
410 static struct wpabuf
* auth_build_sae_commit(struct hostapd_data
*hapd
,
411 struct sta_info
*sta
, int update
,
415 const char *password
= NULL
;
416 struct sae_password_entry
*pw
;
417 const char *rx_id
= NULL
;
419 struct sae_pt
*pt
= NULL
;
422 rx_id
= sta
->sae
->tmp
->pw_id
;
423 use_pt
= sta
->sae
->tmp
->h2e
;
426 if (status_code
== WLAN_STATUS_SUCCESS
)
428 else if (status_code
== WLAN_STATUS_SAE_HASH_TO_ELEMENT
)
431 for (pw
= hapd
->conf
->sae_passwords
; pw
; pw
= pw
->next
) {
432 if (!is_broadcast_ether_addr(pw
->peer_addr
) &&
433 os_memcmp(pw
->peer_addr
, sta
->addr
, ETH_ALEN
) != 0)
435 if ((rx_id
&& !pw
->identifier
) || (!rx_id
&& pw
->identifier
))
437 if (rx_id
&& pw
->identifier
&&
438 os_strcmp(rx_id
, pw
->identifier
) != 0)
440 password
= pw
->password
;
445 password
= hapd
->conf
->ssid
.wpa_passphrase
;
446 pt
= hapd
->conf
->ssid
.pt
;
448 if (!password
|| (use_pt
&& !pt
)) {
449 wpa_printf(MSG_DEBUG
, "SAE: No password available");
453 if (update
&& use_pt
&&
454 sae_prepare_commit_pt(sta
->sae
, pt
, hapd
->own_addr
, sta
->addr
,
458 if (update
&& !use_pt
&&
459 sae_prepare_commit(hapd
->own_addr
, sta
->addr
,
460 (u8
*) password
, os_strlen(password
), rx_id
,
462 wpa_printf(MSG_DEBUG
, "SAE: Could not pick PWE");
466 if (pw
&& pw
->vlan_id
) {
467 if (!sta
->sae
->tmp
) {
469 "SAE: No temporary data allocated - cannot store VLAN ID");
472 sta
->sae
->tmp
->vlan_id
= pw
->vlan_id
;
475 buf
= wpabuf_alloc(SAE_COMMIT_MAX_LEN
+
476 (rx_id
? 3 + os_strlen(rx_id
) : 0));
479 sae_write_commit(sta
->sae
, buf
, sta
->sae
->tmp
?
480 sta
->sae
->tmp
->anti_clogging_token
: NULL
, rx_id
);
486 static struct wpabuf
* auth_build_sae_confirm(struct hostapd_data
*hapd
,
487 struct sta_info
*sta
)
491 buf
= wpabuf_alloc(SAE_CONFIRM_MAX_LEN
);
495 sae_write_confirm(sta
->sae
, buf
);
501 static int auth_sae_send_commit(struct hostapd_data
*hapd
,
502 struct sta_info
*sta
,
503 const u8
*bssid
, int update
, int status_code
)
509 data
= auth_build_sae_commit(hapd
, sta
, update
, status_code
);
510 if (!data
&& sta
->sae
->tmp
&& sta
->sae
->tmp
->pw_id
)
511 return WLAN_STATUS_UNKNOWN_PASSWORD_IDENTIFIER
;
513 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
515 status
= (sta
->sae
->tmp
&& sta
->sae
->tmp
->h2e
) ?
516 WLAN_STATUS_SAE_HASH_TO_ELEMENT
: WLAN_STATUS_SUCCESS
;
517 reply_res
= send_auth_reply(hapd
, sta
->addr
, bssid
, WLAN_AUTH_SAE
, 1,
518 status
, wpabuf_head(data
),
519 wpabuf_len(data
), "sae-send-commit");
527 static int auth_sae_send_confirm(struct hostapd_data
*hapd
,
528 struct sta_info
*sta
,
534 data
= auth_build_sae_confirm(hapd
, sta
);
536 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
538 reply_res
= send_auth_reply(hapd
, sta
->addr
, bssid
, WLAN_AUTH_SAE
, 2,
539 WLAN_STATUS_SUCCESS
, wpabuf_head(data
),
540 wpabuf_len(data
), "sae-send-confirm");
548 static int use_sae_anti_clogging(struct hostapd_data
*hapd
)
550 struct sta_info
*sta
;
551 unsigned int open
= 0;
553 if (hapd
->conf
->sae_anti_clogging_threshold
== 0)
556 for (sta
= hapd
->sta_list
; sta
; sta
= sta
->next
) {
559 if (sta
->sae
->state
!= SAE_COMMITTED
&&
560 sta
->sae
->state
!= SAE_CONFIRMED
)
563 if (open
>= hapd
->conf
->sae_anti_clogging_threshold
)
567 /* In addition to already existing open SAE sessions, check whether
568 * there are enough pending commit messages in the processing queue to
569 * potentially result in too many open sessions. */
570 if (open
+ dl_list_len(&hapd
->sae_commit_queue
) >=
571 hapd
->conf
->sae_anti_clogging_threshold
)
578 static u8
sae_token_hash(struct hostapd_data
*hapd
, const u8
*addr
)
580 u8 hash
[SHA256_MAC_LEN
];
582 hmac_sha256(hapd
->sae_token_key
, sizeof(hapd
->sae_token_key
),
583 addr
, ETH_ALEN
, hash
);
588 static int check_sae_token(struct hostapd_data
*hapd
, const u8
*addr
,
589 const u8
*token
, size_t token_len
)
591 u8 mac
[SHA256_MAC_LEN
];
597 if (token_len
!= SHA256_MAC_LEN
)
599 idx
= sae_token_hash(hapd
, addr
);
600 token_idx
= hapd
->sae_pending_token_idx
[idx
];
601 if (token_idx
== 0 || token_idx
!= WPA_GET_BE16(token
)) {
602 wpa_printf(MSG_DEBUG
, "SAE: Invalid anti-clogging token from "
603 MACSTR
" - token_idx 0x%04x, expected 0x%04x",
604 MAC2STR(addr
), WPA_GET_BE16(token
), token_idx
);
612 if (hmac_sha256_vector(hapd
->sae_token_key
, sizeof(hapd
->sae_token_key
),
613 2, addrs
, len
, mac
) < 0 ||
614 os_memcmp_const(token
+ 2, &mac
[2], SHA256_MAC_LEN
- 2) != 0)
617 hapd
->sae_pending_token_idx
[idx
] = 0; /* invalidate used token */
623 static struct wpabuf
* auth_build_token_req(struct hostapd_data
*hapd
,
624 int group
, const u8
*addr
)
628 struct os_reltime now
;
635 os_get_reltime(&now
);
636 if (!os_reltime_initialized(&hapd
->last_sae_token_key_update
) ||
637 os_reltime_expired(&now
, &hapd
->last_sae_token_key_update
, 60) ||
638 hapd
->sae_token_idx
== 0xffff) {
639 if (random_get_bytes(hapd
->sae_token_key
,
640 sizeof(hapd
->sae_token_key
)) < 0)
642 wpa_hexdump(MSG_DEBUG
, "SAE: Updated token key",
643 hapd
->sae_token_key
, sizeof(hapd
->sae_token_key
));
644 hapd
->last_sae_token_key_update
= now
;
645 hapd
->sae_token_idx
= 0;
646 os_memset(hapd
->sae_pending_token_idx
, 0,
647 sizeof(hapd
->sae_pending_token_idx
));
650 buf
= wpabuf_alloc(sizeof(le16
) + SHA256_MAC_LEN
);
654 wpabuf_put_le16(buf
, group
); /* Finite Cyclic Group */
656 p_idx
= sae_token_hash(hapd
, addr
);
657 token_idx
= hapd
->sae_pending_token_idx
[p_idx
];
659 hapd
->sae_token_idx
++;
660 token_idx
= hapd
->sae_token_idx
;
661 hapd
->sae_pending_token_idx
[p_idx
] = token_idx
;
663 WPA_PUT_BE16(idx
, token_idx
);
664 token
= wpabuf_put(buf
, SHA256_MAC_LEN
);
668 len
[1] = sizeof(idx
);
669 if (hmac_sha256_vector(hapd
->sae_token_key
, sizeof(hapd
->sae_token_key
),
670 2, addrs
, len
, token
) < 0) {
674 WPA_PUT_BE16(token
, token_idx
);
680 static int sae_check_big_sync(struct hostapd_data
*hapd
, struct sta_info
*sta
)
682 if (sta
->sae
->sync
> hapd
->conf
->sae_sync
) {
683 sae_set_state(sta
, SAE_NOTHING
, "Sync > dot11RSNASAESync");
691 static void auth_sae_retransmit_timer(void *eloop_ctx
, void *eloop_data
)
693 struct hostapd_data
*hapd
= eloop_ctx
;
694 struct sta_info
*sta
= eloop_data
;
697 if (sae_check_big_sync(hapd
, sta
))
700 wpa_printf(MSG_DEBUG
, "SAE: Auth SAE retransmit timer for " MACSTR
701 " (sync=%d state=%s)",
702 MAC2STR(sta
->addr
), sta
->sae
->sync
,
703 sae_state_txt(sta
->sae
->state
));
705 switch (sta
->sae
->state
) {
707 ret
= auth_sae_send_commit(hapd
, sta
, hapd
->own_addr
, 0, -1);
708 eloop_register_timeout(0,
709 hapd
->dot11RSNASAERetransPeriod
* 1000,
710 auth_sae_retransmit_timer
, hapd
, sta
);
713 ret
= auth_sae_send_confirm(hapd
, sta
, hapd
->own_addr
);
714 eloop_register_timeout(0,
715 hapd
->dot11RSNASAERetransPeriod
* 1000,
716 auth_sae_retransmit_timer
, hapd
, sta
);
723 if (ret
!= WLAN_STATUS_SUCCESS
)
724 wpa_printf(MSG_INFO
, "SAE: Failed to retransmit: ret=%d", ret
);
728 void sae_clear_retransmit_timer(struct hostapd_data
*hapd
, struct sta_info
*sta
)
730 eloop_cancel_timeout(auth_sae_retransmit_timer
, hapd
, sta
);
734 static void sae_set_retransmit_timer(struct hostapd_data
*hapd
,
735 struct sta_info
*sta
)
737 if (!(hapd
->conf
->mesh
& MESH_ENABLED
))
740 eloop_cancel_timeout(auth_sae_retransmit_timer
, hapd
, sta
);
741 eloop_register_timeout(0, hapd
->dot11RSNASAERetransPeriod
* 1000,
742 auth_sae_retransmit_timer
, hapd
, sta
);
746 static void sae_sme_send_external_auth_status(struct hostapd_data
*hapd
,
747 struct sta_info
*sta
, u16 status
)
749 struct external_auth params
;
751 os_memset(¶ms
, 0, sizeof(params
));
752 params
.status
= status
;
753 params
.bssid
= sta
->addr
;
754 if (status
== WLAN_STATUS_SUCCESS
&& sta
->sae
&&
755 !hapd
->conf
->disable_pmksa_caching
)
756 params
.pmkid
= sta
->sae
->pmkid
;
758 hostapd_drv_send_external_auth_status(hapd
, ¶ms
);
762 void sae_accept_sta(struct hostapd_data
*hapd
, struct sta_info
*sta
)
764 #ifndef CONFIG_NO_VLAN
765 struct vlan_description vlan_desc
;
767 if (sta
->sae
->tmp
&& sta
->sae
->tmp
->vlan_id
> 0) {
768 wpa_printf(MSG_DEBUG
, "SAE: Assign STA " MACSTR
770 MAC2STR(sta
->addr
), sta
->sae
->tmp
->vlan_id
);
772 os_memset(&vlan_desc
, 0, sizeof(vlan_desc
));
773 vlan_desc
.notempty
= 1;
774 vlan_desc
.untagged
= sta
->sae
->tmp
->vlan_id
;
775 if (!hostapd_vlan_valid(hapd
->conf
->vlan
, &vlan_desc
)) {
777 "Invalid VLAN ID %d in sae_password",
778 sta
->sae
->tmp
->vlan_id
);
782 if (ap_sta_set_vlan(hapd
, sta
, &vlan_desc
) < 0 ||
783 ap_sta_bind_vlan(hapd
, sta
) < 0) {
785 "Failed to assign VLAN ID %d from sae_password to "
786 MACSTR
, sta
->sae
->tmp
->vlan_id
,
791 #endif /* CONFIG_NO_VLAN */
793 sta
->flags
|= WLAN_STA_AUTH
;
794 sta
->auth_alg
= WLAN_AUTH_SAE
;
795 mlme_authenticate_indication(hapd
, sta
);
796 wpa_auth_sm_event(sta
->wpa_sm
, WPA_AUTH
);
797 sae_set_state(sta
, SAE_ACCEPTED
, "Accept Confirm");
798 wpa_auth_pmksa_add_sae(hapd
->wpa_auth
, sta
->addr
,
799 sta
->sae
->pmk
, sta
->sae
->pmkid
);
800 sae_sme_send_external_auth_status(hapd
, sta
, WLAN_STATUS_SUCCESS
);
804 static int sae_sm_step(struct hostapd_data
*hapd
, struct sta_info
*sta
,
805 const u8
*bssid
, u16 auth_transaction
, u16 status_code
,
806 int allow_reuse
, int *sta_removed
)
812 if (auth_transaction
!= 1 && auth_transaction
!= 2)
813 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
815 wpa_printf(MSG_DEBUG
, "SAE: Peer " MACSTR
" state=%s auth_trans=%u",
816 MAC2STR(sta
->addr
), sae_state_txt(sta
->sae
->state
),
818 switch (sta
->sae
->state
) {
820 if (auth_transaction
== 1) {
822 sta
->sae
->tmp
->h2e
= status_code
==
823 WLAN_STATUS_SAE_HASH_TO_ELEMENT
;
824 ret
= auth_sae_send_commit(hapd
, sta
, bssid
,
825 !allow_reuse
, status_code
);
828 sae_set_state(sta
, SAE_COMMITTED
, "Sent Commit");
830 if (sae_process_commit(sta
->sae
) < 0)
831 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
834 * In mesh case, both Commit and Confirm are sent
835 * immediately. In infrastructure BSS, by default, only
836 * a single Authentication frame (Commit) is expected
837 * from the AP here and the second one (Confirm) will
838 * be sent once the STA has sent its second
839 * Authentication frame (Confirm). This behavior can be
840 * overridden with explicit configuration so that the
841 * infrastructure BSS case sends both frames together.
843 if ((hapd
->conf
->mesh
& MESH_ENABLED
) ||
844 hapd
->conf
->sae_confirm_immediate
) {
846 * Send both Commit and Confirm immediately
847 * based on SAE finite state machine
848 * Nothing -> Confirm transition.
850 ret
= auth_sae_send_confirm(hapd
, sta
, bssid
);
853 sae_set_state(sta
, SAE_CONFIRMED
,
854 "Sent Confirm (mesh)");
857 * For infrastructure BSS, send only the Commit
858 * message now to get alternating sequence of
859 * Authentication frames between the AP and STA.
860 * Confirm will be sent in
861 * Committed -> Confirmed/Accepted transition
862 * when receiving Confirm from STA.
866 sae_set_retransmit_timer(hapd
, sta
);
868 hostapd_logger(hapd
, sta
->addr
,
869 HOSTAPD_MODULE_IEEE80211
,
871 "SAE confirm before commit");
875 sae_clear_retransmit_timer(hapd
, sta
);
876 if (auth_transaction
== 1) {
877 if (sae_process_commit(sta
->sae
) < 0)
878 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
880 ret
= auth_sae_send_confirm(hapd
, sta
, bssid
);
883 sae_set_state(sta
, SAE_CONFIRMED
, "Sent Confirm");
885 sae_set_retransmit_timer(hapd
, sta
);
886 } else if (hapd
->conf
->mesh
& MESH_ENABLED
) {
888 * In mesh case, follow SAE finite state machine and
889 * send Commit now, if sync count allows.
891 if (sae_check_big_sync(hapd
, sta
))
892 return WLAN_STATUS_SUCCESS
;
895 ret
= auth_sae_send_commit(hapd
, sta
, bssid
, 0,
900 sae_set_retransmit_timer(hapd
, sta
);
903 * For instructure BSS, send the postponed Confirm from
904 * Nothing -> Confirmed transition that was reduced to
905 * Nothing -> Committed above.
907 ret
= auth_sae_send_confirm(hapd
, sta
, bssid
);
911 sae_set_state(sta
, SAE_CONFIRMED
, "Sent Confirm");
914 * Since this was triggered on Confirm RX, run another
915 * step to get to Accepted without waiting for
918 return sae_sm_step(hapd
, sta
, bssid
, auth_transaction
,
919 WLAN_STATUS_SUCCESS
, 0, sta_removed
);
923 sae_clear_retransmit_timer(hapd
, sta
);
924 if (auth_transaction
== 1) {
925 if (sae_check_big_sync(hapd
, sta
))
926 return WLAN_STATUS_SUCCESS
;
929 ret
= auth_sae_send_commit(hapd
, sta
, bssid
, 1,
934 if (sae_process_commit(sta
->sae
) < 0)
935 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
937 ret
= auth_sae_send_confirm(hapd
, sta
, bssid
);
941 sae_set_retransmit_timer(hapd
, sta
);
943 sta
->sae
->send_confirm
= 0xffff;
944 sae_accept_sta(hapd
, sta
);
948 if (auth_transaction
== 1 &&
949 (hapd
->conf
->mesh
& MESH_ENABLED
)) {
950 wpa_printf(MSG_DEBUG
, "SAE: remove the STA (" MACSTR
951 ") doing reauthentication",
953 wpa_auth_pmksa_remove(hapd
->wpa_auth
, sta
->addr
);
954 ap_free_sta(hapd
, sta
);
956 } else if (auth_transaction
== 1) {
957 wpa_printf(MSG_DEBUG
, "SAE: Start reauthentication");
958 ret
= auth_sae_send_commit(hapd
, sta
, bssid
, 1,
962 sae_set_state(sta
, SAE_COMMITTED
, "Sent Commit");
964 if (sae_process_commit(sta
->sae
) < 0)
965 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
967 sae_set_retransmit_timer(hapd
, sta
);
969 if (sae_check_big_sync(hapd
, sta
))
970 return WLAN_STATUS_SUCCESS
;
973 ret
= auth_sae_send_confirm(hapd
, sta
, bssid
);
974 sae_clear_temp_data(sta
->sae
);
980 wpa_printf(MSG_ERROR
, "SAE: invalid state %d",
982 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
984 return WLAN_STATUS_SUCCESS
;
988 static void sae_pick_next_group(struct hostapd_data
*hapd
, struct sta_info
*sta
)
990 struct sae_data
*sae
= sta
->sae
;
991 int i
, *groups
= hapd
->conf
->sae_groups
;
992 int default_groups
[] = { 19, 0 };
994 if (sae
->state
!= SAE_COMMITTED
)
997 wpa_printf(MSG_DEBUG
, "SAE: Previously selected group: %d", sae
->group
);
1000 groups
= default_groups
;
1001 for (i
= 0; groups
[i
] > 0; i
++) {
1002 if (sae
->group
== groups
[i
])
1006 if (groups
[i
] <= 0) {
1007 wpa_printf(MSG_DEBUG
,
1008 "SAE: Previously selected group not found from the current configuration");
1014 if (groups
[i
] <= 0) {
1015 wpa_printf(MSG_DEBUG
,
1016 "SAE: No alternative group enabled");
1020 if (sae_set_group(sae
, groups
[i
]) < 0)
1025 wpa_printf(MSG_DEBUG
, "SAE: Selected new group: %d", groups
[i
]);
1029 static int sae_status_success(struct hostapd_data
*hapd
, u16 status_code
)
1031 return (hapd
->conf
->sae_pwe
== 0 &&
1032 status_code
== WLAN_STATUS_SUCCESS
) ||
1033 (hapd
->conf
->sae_pwe
== 1 &&
1034 status_code
== WLAN_STATUS_SAE_HASH_TO_ELEMENT
) ||
1035 (hapd
->conf
->sae_pwe
== 2 &&
1036 (status_code
== WLAN_STATUS_SUCCESS
||
1037 status_code
== WLAN_STATUS_SAE_HASH_TO_ELEMENT
));
1041 static int sae_is_group_enabled(struct hostapd_data
*hapd
, int group
)
1043 int *groups
= hapd
->conf
->sae_groups
;
1044 int default_groups
[] = { 19, 0 };
1048 groups
= default_groups
;
1050 for (i
= 0; groups
[i
] > 0; i
++) {
1051 if (groups
[i
] == group
)
1059 static int check_sae_rejected_groups(struct hostapd_data
*hapd
,
1060 const struct wpabuf
*groups
)
1068 pos
= wpabuf_head(groups
);
1069 count
= wpabuf_len(groups
) / 2;
1070 for (i
= 0; i
< count
; i
++) {
1074 group
= WPA_GET_LE16(pos
);
1076 enabled
= sae_is_group_enabled(hapd
, group
);
1077 wpa_printf(MSG_DEBUG
, "SAE: Rejected group %u is %s",
1078 group
, enabled
? "enabled" : "disabled");
1087 static void handle_auth_sae(struct hostapd_data
*hapd
, struct sta_info
*sta
,
1088 const struct ieee80211_mgmt
*mgmt
, size_t len
,
1089 u16 auth_transaction
, u16 status_code
)
1091 int resp
= WLAN_STATUS_SUCCESS
;
1092 struct wpabuf
*data
= NULL
;
1093 int *groups
= hapd
->conf
->sae_groups
;
1094 int default_groups
[] = { 19, 0 };
1095 const u8
*pos
, *end
;
1096 int sta_removed
= 0;
1099 groups
= default_groups
;
1101 #ifdef CONFIG_TESTING_OPTIONS
1102 if (hapd
->conf
->sae_reflection_attack
&& auth_transaction
== 1) {
1103 wpa_printf(MSG_DEBUG
, "SAE: TESTING - reflection attack");
1104 pos
= mgmt
->u
.auth
.variable
;
1105 end
= ((const u8
*) mgmt
) + len
;
1106 send_auth_reply(hapd
, mgmt
->sa
, mgmt
->bssid
, WLAN_AUTH_SAE
,
1107 auth_transaction
, resp
, pos
, end
- pos
,
1108 "auth-sae-reflection-attack");
1112 if (hapd
->conf
->sae_commit_override
&& auth_transaction
== 1) {
1113 wpa_printf(MSG_DEBUG
, "SAE: TESTING - commit override");
1114 send_auth_reply(hapd
, mgmt
->sa
, mgmt
->bssid
, WLAN_AUTH_SAE
,
1115 auth_transaction
, resp
,
1116 wpabuf_head(hapd
->conf
->sae_commit_override
),
1117 wpabuf_len(hapd
->conf
->sae_commit_override
),
1118 "sae-commit-override");
1121 #endif /* CONFIG_TESTING_OPTIONS */
1123 if (auth_transaction
!= 1 ||
1124 !sae_status_success(hapd
, status_code
)) {
1125 wpa_printf(MSG_DEBUG
, "SAE: Unexpected Status Code %u",
1127 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1130 sta
->sae
= os_zalloc(sizeof(*sta
->sae
));
1135 sae_set_state(sta
, SAE_NOTHING
, "Init");
1139 if (sta
->mesh_sae_pmksa_caching
) {
1140 wpa_printf(MSG_DEBUG
,
1141 "SAE: Cancel use of mesh PMKSA caching because peer starts SAE authentication");
1142 wpa_auth_pmksa_remove(hapd
->wpa_auth
, sta
->addr
);
1143 sta
->mesh_sae_pmksa_caching
= 0;
1146 if (auth_transaction
== 1) {
1147 const u8
*token
= NULL
;
1148 size_t token_len
= 0;
1149 int allow_reuse
= 0;
1151 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1152 HOSTAPD_LEVEL_DEBUG
,
1153 "start SAE authentication (RX commit, status=%u (%s))",
1154 status_code
, status2str(status_code
));
1156 if ((hapd
->conf
->mesh
& MESH_ENABLED
) &&
1157 status_code
== WLAN_STATUS_ANTI_CLOGGING_TOKEN_REQ
&&
1159 pos
= mgmt
->u
.auth
.variable
;
1160 end
= ((const u8
*) mgmt
) + len
;
1161 if (pos
+ sizeof(le16
) > end
) {
1162 wpa_printf(MSG_ERROR
,
1163 "SAE: Too short anti-clogging token request");
1164 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1167 resp
= sae_group_allowed(sta
->sae
, groups
,
1169 if (resp
!= WLAN_STATUS_SUCCESS
) {
1170 wpa_printf(MSG_ERROR
,
1171 "SAE: Invalid group in anti-clogging token request");
1174 pos
+= sizeof(le16
);
1176 wpabuf_free(sta
->sae
->tmp
->anti_clogging_token
);
1177 sta
->sae
->tmp
->anti_clogging_token
=
1178 wpabuf_alloc_copy(pos
, end
- pos
);
1179 if (sta
->sae
->tmp
->anti_clogging_token
== NULL
) {
1180 wpa_printf(MSG_ERROR
,
1181 "SAE: Failed to alloc for anti-clogging token");
1182 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1187 * IEEE Std 802.11-2012, 11.3.8.6.4: If the Status code
1188 * is 76, a new Commit Message shall be constructed
1189 * with the Anti-Clogging Token from the received
1190 * Authentication frame, and the commit-scalar and
1191 * COMMIT-ELEMENT previously sent.
1193 resp
= auth_sae_send_commit(hapd
, sta
, mgmt
->bssid
, 0,
1195 if (resp
!= WLAN_STATUS_SUCCESS
) {
1196 wpa_printf(MSG_ERROR
,
1197 "SAE: Failed to send commit message");
1200 sae_set_state(sta
, SAE_COMMITTED
,
1201 "Sent Commit (anti-clogging token case in mesh)");
1203 sae_set_retransmit_timer(hapd
, sta
);
1207 if ((hapd
->conf
->mesh
& MESH_ENABLED
) &&
1209 WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED
&&
1211 wpa_printf(MSG_DEBUG
,
1212 "SAE: Peer did not accept our SAE group");
1213 sae_pick_next_group(hapd
, sta
);
1217 if (!sae_status_success(hapd
, status_code
))
1220 if (!(hapd
->conf
->mesh
& MESH_ENABLED
) &&
1221 sta
->sae
->state
== SAE_COMMITTED
) {
1222 /* This is needed in the infrastructure BSS case to
1223 * address a sequence where a STA entry may remain in
1224 * hostapd across two attempts to do SAE authentication
1225 * by the same STA. The second attempt may end up trying
1226 * to use a different group and that would not be
1227 * allowed if we remain in Committed state with the
1228 * previously set parameters. */
1229 pos
= mgmt
->u
.auth
.variable
;
1230 end
= ((const u8
*) mgmt
) + len
;
1231 if (end
- pos
>= (int) sizeof(le16
) &&
1232 sae_group_allowed(sta
->sae
, groups
,
1233 WPA_GET_LE16(pos
)) ==
1234 WLAN_STATUS_SUCCESS
) {
1235 /* Do not waste resources deriving the same PWE
1236 * again since the same group is reused. */
1237 sae_set_state(sta
, SAE_NOTHING
,
1238 "Allow previous PWE to be reused");
1241 sae_set_state(sta
, SAE_NOTHING
,
1242 "Clear existing state to allow restart");
1243 sae_clear_data(sta
->sae
);
1247 resp
= sae_parse_commit(sta
->sae
, mgmt
->u
.auth
.variable
,
1248 ((const u8
*) mgmt
) + len
-
1249 mgmt
->u
.auth
.variable
, &token
,
1250 &token_len
, groups
, status_code
==
1251 WLAN_STATUS_SAE_HASH_TO_ELEMENT
);
1252 if (resp
== SAE_SILENTLY_DISCARD
) {
1253 wpa_printf(MSG_DEBUG
,
1254 "SAE: Drop commit message from " MACSTR
" due to reflection attack",
1255 MAC2STR(sta
->addr
));
1259 if (resp
== WLAN_STATUS_UNKNOWN_PASSWORD_IDENTIFIER
) {
1260 wpa_msg(hapd
->msg_ctx
, MSG_INFO
,
1261 WPA_EVENT_SAE_UNKNOWN_PASSWORD_IDENTIFIER
1262 MACSTR
, MAC2STR(sta
->addr
));
1263 sae_clear_retransmit_timer(hapd
, sta
);
1264 sae_set_state(sta
, SAE_NOTHING
,
1265 "Unknown Password Identifier");
1269 if (token
&& check_sae_token(hapd
, sta
->addr
, token
, token_len
)
1271 wpa_printf(MSG_DEBUG
, "SAE: Drop commit message with "
1272 "incorrect token from " MACSTR
,
1273 MAC2STR(sta
->addr
));
1274 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1278 if (resp
!= WLAN_STATUS_SUCCESS
)
1281 if (sta
->sae
->tmp
&&
1282 check_sae_rejected_groups(
1283 hapd
, sta
->sae
->tmp
->peer_rejected_groups
)) {
1284 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1288 if (!token
&& use_sae_anti_clogging(hapd
) && !allow_reuse
) {
1289 wpa_printf(MSG_DEBUG
,
1290 "SAE: Request anti-clogging token from "
1291 MACSTR
, MAC2STR(sta
->addr
));
1292 data
= auth_build_token_req(hapd
, sta
->sae
->group
,
1294 resp
= WLAN_STATUS_ANTI_CLOGGING_TOKEN_REQ
;
1295 if (hapd
->conf
->mesh
& MESH_ENABLED
)
1296 sae_set_state(sta
, SAE_NOTHING
,
1297 "Request anti-clogging token case in mesh");
1301 resp
= sae_sm_step(hapd
, sta
, mgmt
->bssid
, auth_transaction
,
1302 status_code
, allow_reuse
, &sta_removed
);
1303 } else if (auth_transaction
== 2) {
1304 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1305 HOSTAPD_LEVEL_DEBUG
,
1306 "SAE authentication (RX confirm, status=%u (%s))",
1307 status_code
, status2str(status_code
));
1308 if (status_code
!= WLAN_STATUS_SUCCESS
)
1310 if (sta
->sae
->state
>= SAE_CONFIRMED
||
1311 !(hapd
->conf
->mesh
& MESH_ENABLED
)) {
1314 u16 peer_send_confirm
;
1316 var
= mgmt
->u
.auth
.variable
;
1317 var_len
= ((u8
*) mgmt
) + len
- mgmt
->u
.auth
.variable
;
1319 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1323 peer_send_confirm
= WPA_GET_LE16(var
);
1325 if (sta
->sae
->state
== SAE_ACCEPTED
&&
1326 (peer_send_confirm
<= sta
->sae
->rc
||
1327 peer_send_confirm
== 0xffff)) {
1328 wpa_printf(MSG_DEBUG
,
1329 "SAE: Silently ignore unexpected Confirm from peer "
1331 " (peer-send-confirm=%u Rc=%u)",
1333 peer_send_confirm
, sta
->sae
->rc
);
1337 if (sae_check_confirm(sta
->sae
, var
, var_len
) < 0) {
1338 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1341 sta
->sae
->rc
= peer_send_confirm
;
1343 resp
= sae_sm_step(hapd
, sta
, mgmt
->bssid
, auth_transaction
,
1344 status_code
, 0, &sta_removed
);
1346 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1347 HOSTAPD_LEVEL_DEBUG
,
1348 "unexpected SAE authentication transaction %u (status=%u (%s))",
1349 auth_transaction
, status_code
,
1350 status2str(status_code
));
1351 if (status_code
!= WLAN_STATUS_SUCCESS
)
1353 resp
= WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION
;
1357 if (!sta_removed
&& resp
!= WLAN_STATUS_SUCCESS
) {
1358 pos
= mgmt
->u
.auth
.variable
;
1359 end
= ((const u8
*) mgmt
) + len
;
1361 /* Copy the Finite Cyclic Group field from the request if we
1362 * rejected it as unsupported group. */
1363 if (resp
== WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED
&&
1364 !data
&& end
- pos
>= 2)
1365 data
= wpabuf_alloc_copy(pos
, 2);
1367 sae_sme_send_external_auth_status(hapd
, sta
, resp
);
1368 send_auth_reply(hapd
, mgmt
->sa
, mgmt
->bssid
, WLAN_AUTH_SAE
,
1369 auth_transaction
, resp
,
1370 data
? wpabuf_head(data
) : (u8
*) "",
1371 data
? wpabuf_len(data
) : 0, "auth-sae");
1375 if (!sta_removed
&& sta
->added_unassoc
&&
1376 (resp
!= WLAN_STATUS_SUCCESS
||
1377 status_code
!= WLAN_STATUS_SUCCESS
)) {
1378 hostapd_drv_sta_remove(hapd
, sta
->addr
);
1379 sta
->added_unassoc
= 0;
1386 * auth_sae_init_committed - Send COMMIT and start SAE in committed state
1387 * @hapd: BSS data for the device initiating the authentication
1388 * @sta: the peer to which commit authentication frame is sent
1390 * This function implements Init event handling (IEEE Std 802.11-2012,
1391 * 11.3.8.6.3) in which initial COMMIT message is sent. Prior to calling, the
1392 * sta->sae structure should be initialized appropriately via a call to
1393 * sae_prepare_commit().
1395 int auth_sae_init_committed(struct hostapd_data
*hapd
, struct sta_info
*sta
)
1399 if (!sta
->sae
|| !sta
->sae
->tmp
)
1402 if (sta
->sae
->state
!= SAE_NOTHING
)
1405 ret
= auth_sae_send_commit(hapd
, sta
, hapd
->own_addr
, 0, -1);
1409 sae_set_state(sta
, SAE_COMMITTED
, "Init and sent commit");
1411 sae_set_retransmit_timer(hapd
, sta
);
1417 void auth_sae_process_commit(void *eloop_ctx
, void *user_ctx
)
1419 struct hostapd_data
*hapd
= eloop_ctx
;
1420 struct hostapd_sae_commit_queue
*q
;
1421 unsigned int queue_len
;
1423 q
= dl_list_first(&hapd
->sae_commit_queue
,
1424 struct hostapd_sae_commit_queue
, list
);
1427 wpa_printf(MSG_DEBUG
,
1428 "SAE: Process next available message from queue");
1429 dl_list_del(&q
->list
);
1430 handle_auth(hapd
, (const struct ieee80211_mgmt
*) q
->msg
, q
->len
,
1434 if (eloop_is_timeout_registered(auth_sae_process_commit
, hapd
, NULL
))
1436 queue_len
= dl_list_len(&hapd
->sae_commit_queue
);
1437 eloop_register_timeout(0, queue_len
* 10000, auth_sae_process_commit
,
1442 static void auth_sae_queue(struct hostapd_data
*hapd
,
1443 const struct ieee80211_mgmt
*mgmt
, size_t len
,
1446 struct hostapd_sae_commit_queue
*q
, *q2
;
1447 unsigned int queue_len
;
1448 const struct ieee80211_mgmt
*mgmt2
;
1450 queue_len
= dl_list_len(&hapd
->sae_commit_queue
);
1451 if (queue_len
>= 15) {
1452 wpa_printf(MSG_DEBUG
,
1453 "SAE: No more room in message queue - drop the new frame from "
1454 MACSTR
, MAC2STR(mgmt
->sa
));
1458 wpa_printf(MSG_DEBUG
, "SAE: Queue Authentication message from "
1459 MACSTR
" for processing (queue_len %u)", MAC2STR(mgmt
->sa
),
1461 q
= os_zalloc(sizeof(*q
) + len
);
1466 os_memcpy(q
->msg
, mgmt
, len
);
1468 /* Check whether there is already a queued Authentication frame from the
1469 * same station with the same transaction number and if so, replace that
1470 * queue entry with the new one. This avoids issues with a peer that
1471 * sends multiple times (e.g., due to frequent SAE retries). There is no
1472 * point in us trying to process the old attempts after a new one has
1473 * obsoleted them. */
1474 dl_list_for_each(q2
, &hapd
->sae_commit_queue
,
1475 struct hostapd_sae_commit_queue
, list
) {
1476 mgmt2
= (const struct ieee80211_mgmt
*) q2
->msg
;
1477 if (os_memcmp(mgmt
->sa
, mgmt2
->sa
, ETH_ALEN
) == 0 &&
1478 mgmt
->u
.auth
.auth_transaction
==
1479 mgmt2
->u
.auth
.auth_transaction
) {
1480 wpa_printf(MSG_DEBUG
,
1481 "SAE: Replace queued message from same STA with same transaction number");
1482 dl_list_add(&q2
->list
, &q
->list
);
1483 dl_list_del(&q2
->list
);
1489 /* No pending identical entry, so add to the end of the queue */
1490 dl_list_add_tail(&hapd
->sae_commit_queue
, &q
->list
);
1493 if (eloop_is_timeout_registered(auth_sae_process_commit
, hapd
, NULL
))
1495 eloop_register_timeout(0, queue_len
* 10000, auth_sae_process_commit
,
1500 static int auth_sae_queued_addr(struct hostapd_data
*hapd
, const u8
*addr
)
1502 struct hostapd_sae_commit_queue
*q
;
1503 const struct ieee80211_mgmt
*mgmt
;
1505 dl_list_for_each(q
, &hapd
->sae_commit_queue
,
1506 struct hostapd_sae_commit_queue
, list
) {
1507 mgmt
= (const struct ieee80211_mgmt
*) q
->msg
;
1508 if (os_memcmp(addr
, mgmt
->sa
, ETH_ALEN
) == 0)
1515 #endif /* CONFIG_SAE */
1518 static u16
wpa_res_to_status_code(int res
)
1520 if (res
== WPA_INVALID_GROUP
)
1521 return WLAN_STATUS_GROUP_CIPHER_NOT_VALID
;
1522 if (res
== WPA_INVALID_PAIRWISE
)
1523 return WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID
;
1524 if (res
== WPA_INVALID_AKMP
)
1525 return WLAN_STATUS_AKMP_NOT_VALID
;
1526 if (res
== WPA_ALLOC_FAIL
)
1527 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
1528 if (res
== WPA_MGMT_FRAME_PROTECTION_VIOLATION
)
1529 return WLAN_STATUS_ROBUST_MGMT_FRAME_POLICY_VIOLATION
;
1530 if (res
== WPA_INVALID_MGMT_GROUP_CIPHER
)
1531 return WLAN_STATUS_CIPHER_REJECTED_PER_POLICY
;
1532 if (res
== WPA_INVALID_MDIE
)
1533 return WLAN_STATUS_INVALID_MDIE
;
1534 if (res
== WPA_INVALID_PMKID
)
1535 return WLAN_STATUS_INVALID_PMKID
;
1536 if (res
!= WPA_IE_OK
)
1537 return WLAN_STATUS_INVALID_IE
;
1538 return WLAN_STATUS_SUCCESS
;
1544 static void handle_auth_fils_finish(struct hostapd_data
*hapd
,
1545 struct sta_info
*sta
, u16 resp
,
1546 struct wpabuf
*data
, int pub
);
1548 void handle_auth_fils(struct hostapd_data
*hapd
, struct sta_info
*sta
,
1549 const u8
*pos
, size_t len
, u16 auth_alg
,
1550 u16 auth_transaction
, u16 status_code
,
1551 void (*cb
)(struct hostapd_data
*hapd
,
1552 struct sta_info
*sta
, u16 resp
,
1553 struct wpabuf
*data
, int pub
))
1555 u16 resp
= WLAN_STATUS_SUCCESS
;
1557 struct ieee802_11_elems elems
;
1559 struct wpa_ie_data rsn
;
1560 struct rsn_pmksa_cache_entry
*pmksa
= NULL
;
1562 if (auth_transaction
!= 1 || status_code
!= WLAN_STATUS_SUCCESS
)
1567 wpa_hexdump(MSG_DEBUG
, "FILS: Authentication frame fields",
1571 #ifdef CONFIG_FILS_SK_PFS
1572 if (auth_alg
== WLAN_AUTH_FILS_SK_PFS
) {
1577 /* Using FILS PFS */
1579 /* Finite Cyclic Group */
1580 if (end
- pos
< 2) {
1581 wpa_printf(MSG_DEBUG
,
1582 "FILS: No room for Finite Cyclic Group");
1583 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1586 group
= WPA_GET_LE16(pos
);
1588 if (group
!= hapd
->conf
->fils_dh_group
) {
1589 wpa_printf(MSG_DEBUG
,
1590 "FILS: Unsupported Finite Cyclic Group: %u (expected %u)",
1591 group
, hapd
->conf
->fils_dh_group
);
1592 resp
= WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED
;
1596 crypto_ecdh_deinit(sta
->fils_ecdh
);
1597 sta
->fils_ecdh
= crypto_ecdh_init(group
);
1598 if (!sta
->fils_ecdh
) {
1599 wpa_printf(MSG_INFO
,
1600 "FILS: Could not initialize ECDH with group %d",
1602 resp
= WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED
;
1606 pub
= crypto_ecdh_get_pubkey(sta
->fils_ecdh
, 1);
1608 wpa_printf(MSG_DEBUG
,
1609 "FILS: Failed to derive ECDH public key");
1610 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1613 elem_len
= wpabuf_len(pub
);
1617 if ((size_t) (end
- pos
) < elem_len
) {
1618 wpa_printf(MSG_DEBUG
, "FILS: No room for Element");
1619 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1623 wpabuf_free(sta
->fils_g_sta
);
1624 sta
->fils_g_sta
= wpabuf_alloc_copy(pos
, elem_len
);
1625 wpabuf_clear_free(sta
->fils_dh_ss
);
1626 sta
->fils_dh_ss
= crypto_ecdh_set_peerkey(sta
->fils_ecdh
, 1,
1628 if (!sta
->fils_dh_ss
) {
1629 wpa_printf(MSG_DEBUG
, "FILS: ECDH operation failed");
1630 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1633 wpa_hexdump_buf_key(MSG_DEBUG
, "FILS: DH_SS", sta
->fils_dh_ss
);
1636 crypto_ecdh_deinit(sta
->fils_ecdh
);
1637 sta
->fils_ecdh
= NULL
;
1638 wpabuf_clear_free(sta
->fils_dh_ss
);
1639 sta
->fils_dh_ss
= NULL
;
1641 #endif /* CONFIG_FILS_SK_PFS */
1643 wpa_hexdump(MSG_DEBUG
, "FILS: Remaining IEs", pos
, end
- pos
);
1644 if (ieee802_11_parse_elems(pos
, end
- pos
, &elems
, 1) == ParseFailed
) {
1645 wpa_printf(MSG_DEBUG
, "FILS: Could not parse elements");
1646 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1651 wpa_hexdump(MSG_DEBUG
, "FILS: RSN element",
1652 elems
.rsn_ie
, elems
.rsn_ie_len
);
1653 if (!elems
.rsn_ie
||
1654 wpa_parse_wpa_ie_rsn(elems
.rsn_ie
- 2, elems
.rsn_ie_len
+ 2,
1656 wpa_printf(MSG_DEBUG
, "FILS: No valid RSN element");
1657 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1662 sta
->wpa_sm
= wpa_auth_sta_init(hapd
->wpa_auth
, sta
->addr
,
1665 wpa_printf(MSG_DEBUG
,
1666 "FILS: Failed to initialize RSN state machine");
1667 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1671 res
= wpa_validate_wpa_ie(hapd
->wpa_auth
, sta
->wpa_sm
,
1673 elems
.rsn_ie
- 2, elems
.rsn_ie_len
+ 2,
1674 elems
.rsnxe
? elems
.rsnxe
- 2 : NULL
,
1675 elems
.rsnxe
? elems
.rsnxe_len
+ 2 : 0,
1676 elems
.mdie
, elems
.mdie_len
, NULL
, 0);
1677 resp
= wpa_res_to_status_code(res
);
1678 if (resp
!= WLAN_STATUS_SUCCESS
)
1681 if (!elems
.fils_nonce
) {
1682 wpa_printf(MSG_DEBUG
, "FILS: No FILS Nonce field");
1683 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1686 wpa_hexdump(MSG_DEBUG
, "FILS: SNonce", elems
.fils_nonce
,
1688 os_memcpy(sta
->fils_snonce
, elems
.fils_nonce
, FILS_NONCE_LEN
);
1691 if (rsn
.pmkid
&& rsn
.num_pmkid
> 0) {
1695 wpa_hexdump(MSG_DEBUG
, "FILS: PMKID List",
1696 rsn
.pmkid
, rsn
.num_pmkid
* PMKID_LEN
);
1699 num
= rsn
.num_pmkid
;
1701 wpa_hexdump(MSG_DEBUG
, "FILS: PMKID", pmkid
, PMKID_LEN
);
1702 pmksa
= wpa_auth_pmksa_get(hapd
->wpa_auth
, sta
->addr
,
1706 pmksa
= wpa_auth_pmksa_get_fils_cache_id(hapd
->wpa_auth
,
1715 if (pmksa
&& wpa_auth_sta_key_mgmt(sta
->wpa_sm
) != pmksa
->akmp
) {
1716 wpa_printf(MSG_DEBUG
,
1717 "FILS: Matching PMKSA cache entry has different AKMP (0x%x != 0x%x) - ignore",
1718 wpa_auth_sta_key_mgmt(sta
->wpa_sm
), pmksa
->akmp
);
1722 wpa_printf(MSG_DEBUG
, "FILS: Found matching PMKSA cache entry");
1725 if (!elems
.fils_session
) {
1726 wpa_printf(MSG_DEBUG
, "FILS: No FILS Session element");
1727 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1730 wpa_hexdump(MSG_DEBUG
, "FILS: FILS Session", elems
.fils_session
,
1732 os_memcpy(sta
->fils_session
, elems
.fils_session
, FILS_SESSION_LEN
);
1734 /* FILS Wrapped Data */
1735 if (elems
.fils_wrapped_data
) {
1736 wpa_hexdump(MSG_DEBUG
, "FILS: Wrapped Data",
1737 elems
.fils_wrapped_data
,
1738 elems
.fils_wrapped_data_len
);
1740 #ifndef CONFIG_NO_RADIUS
1741 if (!sta
->eapol_sm
) {
1743 ieee802_1x_alloc_eapol_sm(hapd
, sta
);
1745 wpa_printf(MSG_DEBUG
,
1746 "FILS: Forward EAP-Initiate/Re-auth to authentication server");
1747 ieee802_1x_encapsulate_radius(
1748 hapd
, sta
, elems
.fils_wrapped_data
,
1749 elems
.fils_wrapped_data_len
);
1750 sta
->fils_pending_cb
= cb
;
1751 wpa_printf(MSG_DEBUG
,
1752 "FILS: Will send Authentication frame once the response from authentication server is available");
1753 sta
->flags
|= WLAN_STA_PENDING_FILS_ERP
;
1754 /* Calculate pending PMKID here so that we do not need
1755 * to maintain a copy of the EAP-Initiate/Reauth
1757 if (fils_pmkid_erp(wpa_auth_sta_key_mgmt(sta
->wpa_sm
),
1758 elems
.fils_wrapped_data
,
1759 elems
.fils_wrapped_data_len
,
1760 sta
->fils_erp_pmkid
) == 0)
1761 sta
->fils_erp_pmkid_set
= 1;
1763 #else /* CONFIG_NO_RADIUS */
1764 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1766 #endif /* CONFIG_NO_RADIUS */
1772 struct wpabuf
*data
;
1775 data
= prepare_auth_resp_fils(hapd
, sta
, &resp
, pmksa
, NULL
,
1778 wpa_printf(MSG_DEBUG
,
1779 "%s: prepare_auth_resp_fils() returned failure",
1783 cb(hapd
, sta
, resp
, data
, pub
);
1788 static struct wpabuf
*
1789 prepare_auth_resp_fils(struct hostapd_data
*hapd
,
1790 struct sta_info
*sta
, u16
*resp
,
1791 struct rsn_pmksa_cache_entry
*pmksa
,
1792 struct wpabuf
*erp_resp
,
1793 const u8
*msk
, size_t msk_len
,
1796 u8 fils_nonce
[FILS_NONCE_LEN
];
1798 struct wpabuf
*data
= NULL
;
1801 const u8
*pmk
= NULL
;
1803 u8 pmk_buf
[PMK_LEN_MAX
];
1804 struct wpabuf
*pub
= NULL
;
1806 if (*resp
!= WLAN_STATUS_SUCCESS
)
1809 ie
= wpa_auth_get_wpa_ie(hapd
->wpa_auth
, &ielen
);
1811 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1816 /* Add PMKID of the selected PMKSA into RSNE */
1817 ie_buf
= os_malloc(ielen
+ 2 + 2 + PMKID_LEN
);
1819 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1823 os_memcpy(ie_buf
, ie
, ielen
);
1824 if (wpa_insert_pmkid(ie_buf
, &ielen
, pmksa
->pmkid
) < 0) {
1825 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1831 if (random_get_bytes(fils_nonce
, FILS_NONCE_LEN
) < 0) {
1832 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1835 wpa_hexdump(MSG_DEBUG
, "RSN: Generated FILS Nonce",
1836 fils_nonce
, FILS_NONCE_LEN
);
1838 #ifdef CONFIG_FILS_SK_PFS
1839 if (sta
->fils_dh_ss
&& sta
->fils_ecdh
) {
1840 pub
= crypto_ecdh_get_pubkey(sta
->fils_ecdh
, 1);
1842 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1846 #endif /* CONFIG_FILS_SK_PFS */
1848 data
= wpabuf_alloc(1000 + ielen
+ (pub
? wpabuf_len(pub
) : 0));
1850 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1855 #ifdef CONFIG_FILS_SK_PFS
1857 /* Finite Cyclic Group */
1858 wpabuf_put_le16(data
, hapd
->conf
->fils_dh_group
);
1861 wpabuf_put_buf(data
, pub
);
1863 #endif /* CONFIG_FILS_SK_PFS */
1866 wpabuf_put_data(data
, ie
, ielen
);
1868 /* MDE when using FILS+FT (already included in ie,ielen with RSNE) */
1870 #ifdef CONFIG_IEEE80211R_AP
1871 if (wpa_key_mgmt_ft(wpa_auth_sta_key_mgmt(sta
->wpa_sm
))) {
1872 /* FTE[R1KH-ID,R0KH-ID] when using FILS+FT */
1874 int use_sha384
= wpa_key_mgmt_sha384(
1875 wpa_auth_sta_key_mgmt(sta
->wpa_sm
));
1877 res
= wpa_auth_write_fte(hapd
->wpa_auth
, use_sha384
,
1878 wpabuf_put(data
, 0),
1879 wpabuf_tailroom(data
));
1881 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1884 wpabuf_put(data
, res
);
1886 #endif /* CONFIG_IEEE80211R_AP */
1889 wpabuf_put_u8(data
, WLAN_EID_EXTENSION
); /* Element ID */
1890 wpabuf_put_u8(data
, 1 + FILS_NONCE_LEN
); /* Length */
1891 /* Element ID Extension */
1892 wpabuf_put_u8(data
, WLAN_EID_EXT_FILS_NONCE
);
1893 wpabuf_put_data(data
, fils_nonce
, FILS_NONCE_LEN
);
1896 wpabuf_put_u8(data
, WLAN_EID_EXTENSION
); /* Element ID */
1897 wpabuf_put_u8(data
, 1 + FILS_SESSION_LEN
); /* Length */
1898 /* Element ID Extension */
1899 wpabuf_put_u8(data
, WLAN_EID_EXT_FILS_SESSION
);
1900 wpabuf_put_data(data
, sta
->fils_session
, FILS_SESSION_LEN
);
1902 /* FILS Wrapped Data */
1903 if (!pmksa
&& erp_resp
) {
1904 wpabuf_put_u8(data
, WLAN_EID_EXTENSION
); /* Element ID */
1905 wpabuf_put_u8(data
, 1 + wpabuf_len(erp_resp
)); /* Length */
1906 /* Element ID Extension */
1907 wpabuf_put_u8(data
, WLAN_EID_EXT_FILS_WRAPPED_DATA
);
1908 wpabuf_put_buf(data
, erp_resp
);
1910 if (fils_rmsk_to_pmk(wpa_auth_sta_key_mgmt(sta
->wpa_sm
),
1911 msk
, msk_len
, sta
->fils_snonce
, fils_nonce
,
1913 wpabuf_head(sta
->fils_dh_ss
) : NULL
,
1915 wpabuf_len(sta
->fils_dh_ss
) : 0,
1916 pmk_buf
, &pmk_len
)) {
1917 wpa_printf(MSG_DEBUG
, "FILS: Failed to derive PMK");
1918 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1925 /* Don't use DHss in PTK derivation if PMKSA caching is not
1927 wpabuf_clear_free(sta
->fils_dh_ss
);
1928 sta
->fils_dh_ss
= NULL
;
1930 if (sta
->fils_erp_pmkid_set
) {
1931 /* TODO: get PMKLifetime from WPA parameters */
1932 unsigned int dot11RSNAConfigPMKLifetime
= 43200;
1933 int session_timeout
;
1935 session_timeout
= dot11RSNAConfigPMKLifetime
;
1936 if (sta
->session_timeout_set
) {
1937 struct os_reltime now
, diff
;
1939 os_get_reltime(&now
);
1940 os_reltime_sub(&sta
->session_timeout
, &now
,
1942 session_timeout
= diff
.sec
;
1945 sta
->fils_erp_pmkid_set
= 0;
1946 wpa_auth_add_fils_pmk_pmkid(sta
->wpa_sm
, pmk
, pmk_len
,
1947 sta
->fils_erp_pmkid
);
1948 if (!hapd
->conf
->disable_pmksa_caching
&&
1949 wpa_auth_pmksa_add2(
1950 hapd
->wpa_auth
, sta
->addr
,
1952 sta
->fils_erp_pmkid
,
1954 wpa_auth_sta_key_mgmt(sta
->wpa_sm
)) < 0) {
1955 wpa_printf(MSG_ERROR
,
1956 "FILS: Failed to add PMKSA cache entry based on ERP");
1961 pmk_len
= pmksa
->pmk_len
;
1965 wpa_printf(MSG_DEBUG
, "FILS: No PMK available");
1966 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1972 if (fils_auth_pmk_to_ptk(sta
->wpa_sm
, pmk
, pmk_len
,
1973 sta
->fils_snonce
, fils_nonce
,
1975 wpabuf_head(sta
->fils_dh_ss
) : NULL
,
1977 wpabuf_len(sta
->fils_dh_ss
) : 0,
1978 sta
->fils_g_sta
, pub
) < 0) {
1979 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1987 *is_pub
= pub
!= NULL
;
1990 wpabuf_clear_free(sta
->fils_dh_ss
);
1991 sta
->fils_dh_ss
= NULL
;
1992 #ifdef CONFIG_FILS_SK_PFS
1993 crypto_ecdh_deinit(sta
->fils_ecdh
);
1994 sta
->fils_ecdh
= NULL
;
1995 #endif /* CONFIG_FILS_SK_PFS */
2000 static void handle_auth_fils_finish(struct hostapd_data
*hapd
,
2001 struct sta_info
*sta
, u16 resp
,
2002 struct wpabuf
*data
, int pub
)
2007 resp
== WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED
) ?
2008 WLAN_AUTH_FILS_SK_PFS
: WLAN_AUTH_FILS_SK
;
2009 send_auth_reply(hapd
, sta
->addr
, hapd
->own_addr
, auth_alg
, 2, resp
,
2010 data
? wpabuf_head(data
) : (u8
*) "",
2011 data
? wpabuf_len(data
) : 0, "auth-fils-finish");
2014 if (resp
== WLAN_STATUS_SUCCESS
) {
2015 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
2016 HOSTAPD_LEVEL_DEBUG
,
2017 "authentication OK (FILS)");
2018 sta
->flags
|= WLAN_STA_AUTH
;
2019 wpa_auth_sm_event(sta
->wpa_sm
, WPA_AUTH
);
2020 sta
->auth_alg
= pub
? WLAN_AUTH_FILS_SK_PFS
: WLAN_AUTH_FILS_SK
;
2021 mlme_authenticate_indication(hapd
, sta
);
2026 void ieee802_11_finish_fils_auth(struct hostapd_data
*hapd
,
2027 struct sta_info
*sta
, int success
,
2028 struct wpabuf
*erp_resp
,
2029 const u8
*msk
, size_t msk_len
)
2031 struct wpabuf
*data
;
2035 sta
->flags
&= ~WLAN_STA_PENDING_FILS_ERP
;
2037 if (!sta
->fils_pending_cb
)
2039 resp
= success
? WLAN_STATUS_SUCCESS
: WLAN_STATUS_UNSPECIFIED_FAILURE
;
2040 data
= prepare_auth_resp_fils(hapd
, sta
, &resp
, NULL
, erp_resp
,
2041 msk
, msk_len
, &pub
);
2043 wpa_printf(MSG_DEBUG
,
2044 "%s: prepare_auth_resp_fils() returned failure",
2047 sta
->fils_pending_cb(hapd
, sta
, resp
, data
, pub
);
2050 #endif /* CONFIG_FILS */
2053 int ieee802_11_allowed_address(struct hostapd_data
*hapd
, const u8
*addr
,
2054 const u8
*msg
, size_t len
,
2055 struct radius_sta
*info
, int is_probe_req
)
2059 res
= hostapd_allowed_address(hapd
, addr
, msg
, len
, info
, is_probe_req
);
2061 if (res
== HOSTAPD_ACL_REJECT
) {
2063 wpa_printf(MSG_DEBUG
,
2065 " not allowed to authenticate",
2067 return HOSTAPD_ACL_REJECT
;
2070 if (res
== HOSTAPD_ACL_PENDING
) {
2071 wpa_printf(MSG_DEBUG
, "Authentication frame from " MACSTR
2072 " waiting for an external authentication",
2074 /* Authentication code will re-send the authentication frame
2075 * after it has received (and cached) information from the
2076 * external source. */
2077 return HOSTAPD_ACL_PENDING
;
2085 ieee802_11_set_radius_info(struct hostapd_data
*hapd
, struct sta_info
*sta
,
2086 int res
, struct radius_sta
*info
)
2088 u32 session_timeout
= info
->session_timeout
;
2089 u32 acct_interim_interval
= info
->acct_interim_interval
;
2090 struct vlan_description
*vlan_id
= &info
->vlan_id
;
2091 struct hostapd_sta_wpa_psk_short
*psk
= info
->psk
;
2092 char *identity
= info
->identity
;
2093 char *radius_cui
= info
->radius_cui
;
2095 if (vlan_id
->notempty
&&
2096 !hostapd_vlan_valid(hapd
->conf
->vlan
, vlan_id
)) {
2097 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_RADIUS
,
2099 "Invalid VLAN %d%s received from RADIUS server",
2101 vlan_id
->tagged
[0] ? "+" : "");
2104 if (ap_sta_set_vlan(hapd
, sta
, vlan_id
) < 0)
2107 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_RADIUS
,
2108 HOSTAPD_LEVEL_INFO
, "VLAN ID %d", sta
->vlan_id
);
2110 hostapd_free_psk_list(sta
->psk
);
2111 if (hapd
->conf
->wpa_psk_radius
!= PSK_RADIUS_IGNORED
)
2112 hostapd_copy_psk_list(&sta
->psk
, psk
);
2116 os_free(sta
->identity
);
2118 sta
->identity
= os_strdup(identity
);
2120 sta
->identity
= NULL
;
2122 os_free(sta
->radius_cui
);
2124 sta
->radius_cui
= os_strdup(radius_cui
);
2126 sta
->radius_cui
= NULL
;
2128 if (hapd
->conf
->acct_interim_interval
== 0 && acct_interim_interval
)
2129 sta
->acct_interim_interval
= acct_interim_interval
;
2130 if (res
== HOSTAPD_ACL_ACCEPT_TIMEOUT
) {
2131 sta
->session_timeout_set
= 1;
2132 os_get_reltime(&sta
->session_timeout
);
2133 sta
->session_timeout
.sec
+= session_timeout
;
2134 ap_sta_session_timeout(hapd
, sta
, session_timeout
);
2136 sta
->session_timeout_set
= 0;
2137 ap_sta_no_session_timeout(hapd
, sta
);
2144 static void handle_auth(struct hostapd_data
*hapd
,
2145 const struct ieee80211_mgmt
*mgmt
, size_t len
,
2146 int rssi
, int from_queue
)
2148 u16 auth_alg
, auth_transaction
, status_code
;
2149 u16 resp
= WLAN_STATUS_SUCCESS
;
2150 struct sta_info
*sta
= NULL
;
2153 const u8
*challenge
= NULL
;
2154 u8 resp_ies
[2 + WLAN_AUTH_CHALLENGE_LEN
];
2155 size_t resp_ies_len
= 0;
2157 struct radius_sta rad_info
;
2159 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.auth
)) {
2160 wpa_printf(MSG_INFO
, "handle_auth - too short payload (len=%lu)",
2161 (unsigned long) len
);
2165 #ifdef CONFIG_TESTING_OPTIONS
2166 if (hapd
->iconf
->ignore_auth_probability
> 0.0 &&
2167 drand48() < hapd
->iconf
->ignore_auth_probability
) {
2168 wpa_printf(MSG_INFO
,
2169 "TESTING: ignoring auth frame from " MACSTR
,
2173 #endif /* CONFIG_TESTING_OPTIONS */
2175 auth_alg
= le_to_host16(mgmt
->u
.auth
.auth_alg
);
2176 auth_transaction
= le_to_host16(mgmt
->u
.auth
.auth_transaction
);
2177 status_code
= le_to_host16(mgmt
->u
.auth
.status_code
);
2178 fc
= le_to_host16(mgmt
->frame_control
);
2179 seq_ctrl
= le_to_host16(mgmt
->seq_ctrl
);
2181 if (len
>= IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.auth
) +
2182 2 + WLAN_AUTH_CHALLENGE_LEN
&&
2183 mgmt
->u
.auth
.variable
[0] == WLAN_EID_CHALLENGE
&&
2184 mgmt
->u
.auth
.variable
[1] == WLAN_AUTH_CHALLENGE_LEN
)
2185 challenge
= &mgmt
->u
.auth
.variable
[2];
2187 wpa_printf(MSG_DEBUG
, "authentication: STA=" MACSTR
" auth_alg=%d "
2188 "auth_transaction=%d status_code=%d wep=%d%s "
2189 "seq_ctrl=0x%x%s%s",
2190 MAC2STR(mgmt
->sa
), auth_alg
, auth_transaction
,
2191 status_code
, !!(fc
& WLAN_FC_ISWEP
),
2192 challenge
? " challenge" : "",
2193 seq_ctrl
, (fc
& WLAN_FC_RETRY
) ? " retry" : "",
2194 from_queue
? " (from queue)" : "");
2196 #ifdef CONFIG_NO_RC4
2197 if (auth_alg
== WLAN_AUTH_SHARED_KEY
) {
2198 wpa_printf(MSG_INFO
,
2199 "Unsupported authentication algorithm (%d)",
2201 resp
= WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG
;
2204 #endif /* CONFIG_NO_RC4 */
2206 if (hapd
->tkip_countermeasures
) {
2207 wpa_printf(MSG_DEBUG
,
2208 "Ongoing TKIP countermeasures (Michael MIC failure) - reject authentication");
2209 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
2213 if (!(((hapd
->conf
->auth_algs
& WPA_AUTH_ALG_OPEN
) &&
2214 auth_alg
== WLAN_AUTH_OPEN
) ||
2215 #ifdef CONFIG_IEEE80211R_AP
2216 (hapd
->conf
->wpa
&& wpa_key_mgmt_ft(hapd
->conf
->wpa_key_mgmt
) &&
2217 auth_alg
== WLAN_AUTH_FT
) ||
2218 #endif /* CONFIG_IEEE80211R_AP */
2220 (hapd
->conf
->wpa
&& wpa_key_mgmt_sae(hapd
->conf
->wpa_key_mgmt
) &&
2221 auth_alg
== WLAN_AUTH_SAE
) ||
2222 #endif /* CONFIG_SAE */
2224 (hapd
->conf
->wpa
&& wpa_key_mgmt_fils(hapd
->conf
->wpa_key_mgmt
) &&
2225 auth_alg
== WLAN_AUTH_FILS_SK
) ||
2226 (hapd
->conf
->wpa
&& wpa_key_mgmt_fils(hapd
->conf
->wpa_key_mgmt
) &&
2227 hapd
->conf
->fils_dh_group
&&
2228 auth_alg
== WLAN_AUTH_FILS_SK_PFS
) ||
2229 #endif /* CONFIG_FILS */
2230 ((hapd
->conf
->auth_algs
& WPA_AUTH_ALG_SHARED
) &&
2231 auth_alg
== WLAN_AUTH_SHARED_KEY
))) {
2232 wpa_printf(MSG_INFO
, "Unsupported authentication algorithm (%d)",
2234 resp
= WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG
;
2238 if (!(auth_transaction
== 1 || auth_alg
== WLAN_AUTH_SAE
||
2239 (auth_alg
== WLAN_AUTH_SHARED_KEY
&& auth_transaction
== 3))) {
2240 wpa_printf(MSG_INFO
, "Unknown authentication transaction number (%d)",
2242 resp
= WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION
;
2246 if (os_memcmp(mgmt
->sa
, hapd
->own_addr
, ETH_ALEN
) == 0) {
2247 wpa_printf(MSG_INFO
, "Station " MACSTR
" not allowed to authenticate",
2249 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
2253 if (hapd
->conf
->no_auth_if_seen_on
) {
2254 struct hostapd_data
*other
;
2256 other
= sta_track_seen_on(hapd
->iface
, mgmt
->sa
,
2257 hapd
->conf
->no_auth_if_seen_on
);
2261 u8 op_class
, channel
, phytype
;
2263 wpa_printf(MSG_DEBUG
, "%s: Reject authentication from "
2264 MACSTR
" since STA has been seen on %s",
2265 hapd
->conf
->iface
, MAC2STR(mgmt
->sa
),
2266 hapd
->conf
->no_auth_if_seen_on
);
2268 resp
= WLAN_STATUS_REJECTED_WITH_SUGGESTED_BSS_TRANSITION
;
2270 *pos
++ = WLAN_EID_NEIGHBOR_REPORT
;
2272 os_memcpy(pos
, other
->own_addr
, ETH_ALEN
);
2274 info
= 0; /* TODO: BSSID Information */
2275 WPA_PUT_LE32(pos
, info
);
2277 if (other
->iconf
->hw_mode
== HOSTAPD_MODE_IEEE80211AD
)
2278 phytype
= 8; /* dmg */
2279 else if (other
->iconf
->ieee80211ac
)
2280 phytype
= 9; /* vht */
2281 else if (other
->iconf
->ieee80211n
)
2282 phytype
= 7; /* ht */
2283 else if (other
->iconf
->hw_mode
==
2284 HOSTAPD_MODE_IEEE80211A
)
2285 phytype
= 4; /* ofdm */
2286 else if (other
->iconf
->hw_mode
==
2287 HOSTAPD_MODE_IEEE80211G
)
2288 phytype
= 6; /* erp */
2290 phytype
= 5; /* hrdsss */
2291 if (ieee80211_freq_to_channel_ext(
2292 hostapd_hw_get_freq(other
,
2293 other
->iconf
->channel
),
2294 other
->iconf
->secondary_channel
,
2295 other
->iconf
->ieee80211ac
,
2296 &op_class
, &channel
) == NUM_HOSTAPD_MODES
) {
2298 channel
= other
->iconf
->channel
;
2303 resp_ies_len
= pos
- &resp_ies
[0];
2308 res
= ieee802_11_allowed_address(
2309 hapd
, mgmt
->sa
, (const u8
*) mgmt
, len
, &rad_info
, 0);
2310 if (res
== HOSTAPD_ACL_REJECT
) {
2311 wpa_msg(hapd
->msg_ctx
, MSG_DEBUG
,
2312 "Ignore Authentication frame from " MACSTR
2313 " due to ACL reject", MAC2STR(mgmt
->sa
));
2314 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
2317 if (res
== HOSTAPD_ACL_PENDING
)
2321 if (auth_alg
== WLAN_AUTH_SAE
&& !from_queue
&&
2322 (auth_transaction
== 1 ||
2323 (auth_transaction
== 2 && auth_sae_queued_addr(hapd
, mgmt
->sa
)))) {
2324 /* Handle SAE Authentication commit message through a queue to
2325 * provide more control for postponing the needed heavy
2326 * processing under a possible DoS attack scenario. In addition,
2327 * queue SAE Authentication confirm message if there happens to
2328 * be a queued commit message from the same peer. This is needed
2329 * to avoid reordering Authentication frames within the same
2331 auth_sae_queue(hapd
, mgmt
, len
, rssi
);
2334 #endif /* CONFIG_SAE */
2336 sta
= ap_get_sta(hapd
, mgmt
->sa
);
2338 sta
->flags
&= ~WLAN_STA_PENDING_FILS_ERP
;
2339 sta
->ft_over_ds
= 0;
2340 if ((fc
& WLAN_FC_RETRY
) &&
2341 sta
->last_seq_ctrl
!= WLAN_INVALID_MGMT_SEQ
&&
2342 sta
->last_seq_ctrl
== seq_ctrl
&&
2343 sta
->last_subtype
== WLAN_FC_STYPE_AUTH
) {
2344 hostapd_logger(hapd
, sta
->addr
,
2345 HOSTAPD_MODULE_IEEE80211
,
2346 HOSTAPD_LEVEL_DEBUG
,
2347 "Drop repeated authentication frame seq_ctrl=0x%x",
2352 if ((hapd
->conf
->mesh
& MESH_ENABLED
) &&
2353 sta
->plink_state
== PLINK_BLOCKED
) {
2354 wpa_printf(MSG_DEBUG
, "Mesh peer " MACSTR
2355 " is blocked - drop Authentication frame",
2359 #endif /* CONFIG_MESH */
2362 if (hapd
->conf
->mesh
& MESH_ENABLED
) {
2363 /* if the mesh peer is not available, we don't do auth.
2365 wpa_printf(MSG_DEBUG
, "Mesh peer " MACSTR
2366 " not yet known - drop Authentication frame",
2369 * Save a copy of the frame so that it can be processed
2370 * if a new peer entry is added shortly after this.
2372 wpabuf_free(hapd
->mesh_pending_auth
);
2373 hapd
->mesh_pending_auth
= wpabuf_alloc_copy(mgmt
, len
);
2374 os_get_reltime(&hapd
->mesh_pending_auth_time
);
2377 #endif /* CONFIG_MESH */
2379 sta
= ap_sta_add(hapd
, mgmt
->sa
);
2381 wpa_printf(MSG_DEBUG
, "ap_sta_add() failed");
2382 resp
= WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
;
2386 sta
->last_seq_ctrl
= seq_ctrl
;
2387 sta
->last_subtype
= WLAN_FC_STYPE_AUTH
;
2389 sta
->auth_rssi
= rssi
;
2390 #endif /* CONFIG_MBO */
2392 res
= ieee802_11_set_radius_info(hapd
, sta
, res
, &rad_info
);
2394 wpa_printf(MSG_DEBUG
, "ieee802_11_set_radius_info() failed");
2395 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
2399 sta
->flags
&= ~WLAN_STA_PREAUTH
;
2400 ieee802_1x_notify_pre_auth(sta
->eapol_sm
, 0);
2403 * If the driver supports full AP client state, add a station to the
2404 * driver before sending authentication reply to make sure the driver
2405 * has resources, and not to go through the entire authentication and
2406 * association handshake, and fail it at the end.
2408 * If this is not the first transaction, in a multi-step authentication
2409 * algorithm, the station already exists in the driver
2410 * (sta->added_unassoc = 1) so skip it.
2412 * In mesh mode, the station was already added to the driver when the
2413 * NEW_PEER_CANDIDATE event is received.
2415 * If PMF was negotiated for the existing association, skip this to
2416 * avoid dropping the STA entry and the associated keys. This is needed
2417 * to allow the original connection work until the attempt can complete
2418 * (re)association, so that unprotected Authentication frame cannot be
2419 * used to bypass PMF protection.
2421 if (FULL_AP_CLIENT_STATE_SUPP(hapd
->iface
->drv_flags
) &&
2422 (!(sta
->flags
& WLAN_STA_MFP
) || !ap_sta_is_authorized(sta
)) &&
2423 !(hapd
->conf
->mesh
& MESH_ENABLED
) &&
2424 !(sta
->added_unassoc
)) {
2426 * If a station that is already associated to the AP, is trying
2427 * to authenticate again, remove the STA entry, in order to make
2428 * sure the STA PS state gets cleared and configuration gets
2429 * updated. To handle this, station's added_unassoc flag is
2430 * cleared once the station has completed association.
2432 ap_sta_set_authorized(hapd
, sta
, 0);
2433 hostapd_drv_sta_remove(hapd
, sta
->addr
);
2434 sta
->flags
&= ~(WLAN_STA_ASSOC
| WLAN_STA_AUTH
|
2435 WLAN_STA_AUTHORIZED
);
2437 if (hostapd_sta_add(hapd
, sta
->addr
, 0, 0,
2438 sta
->supported_rates
,
2439 sta
->supported_rates_len
,
2440 0, NULL
, NULL
, NULL
, 0,
2441 sta
->flags
, 0, 0, 0, 0)) {
2442 hostapd_logger(hapd
, sta
->addr
,
2443 HOSTAPD_MODULE_IEEE80211
,
2444 HOSTAPD_LEVEL_NOTICE
,
2445 "Could not add STA to kernel driver");
2446 resp
= WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
;
2450 sta
->added_unassoc
= 1;
2454 case WLAN_AUTH_OPEN
:
2455 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
2456 HOSTAPD_LEVEL_DEBUG
,
2457 "authentication OK (open system)");
2458 sta
->flags
|= WLAN_STA_AUTH
;
2459 wpa_auth_sm_event(sta
->wpa_sm
, WPA_AUTH
);
2460 sta
->auth_alg
= WLAN_AUTH_OPEN
;
2461 mlme_authenticate_indication(hapd
, sta
);
2463 #ifndef CONFIG_NO_RC4
2464 case WLAN_AUTH_SHARED_KEY
:
2465 resp
= auth_shared_key(hapd
, sta
, auth_transaction
, challenge
,
2466 fc
& WLAN_FC_ISWEP
);
2468 wpa_printf(MSG_DEBUG
,
2469 "auth_shared_key() failed: status=%d", resp
);
2470 sta
->auth_alg
= WLAN_AUTH_SHARED_KEY
;
2471 mlme_authenticate_indication(hapd
, sta
);
2472 if (sta
->challenge
&& auth_transaction
== 1) {
2473 resp_ies
[0] = WLAN_EID_CHALLENGE
;
2474 resp_ies
[1] = WLAN_AUTH_CHALLENGE_LEN
;
2475 os_memcpy(resp_ies
+ 2, sta
->challenge
,
2476 WLAN_AUTH_CHALLENGE_LEN
);
2477 resp_ies_len
= 2 + WLAN_AUTH_CHALLENGE_LEN
;
2480 #endif /* CONFIG_NO_RC4 */
2481 #ifdef CONFIG_IEEE80211R_AP
2483 sta
->auth_alg
= WLAN_AUTH_FT
;
2484 if (sta
->wpa_sm
== NULL
)
2485 sta
->wpa_sm
= wpa_auth_sta_init(hapd
->wpa_auth
,
2487 if (sta
->wpa_sm
== NULL
) {
2488 wpa_printf(MSG_DEBUG
, "FT: Failed to initialize WPA "
2490 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
2493 wpa_ft_process_auth(sta
->wpa_sm
, mgmt
->bssid
,
2494 auth_transaction
, mgmt
->u
.auth
.variable
,
2495 len
- IEEE80211_HDRLEN
-
2496 sizeof(mgmt
->u
.auth
),
2497 handle_auth_ft_finish
, hapd
);
2498 /* handle_auth_ft_finish() callback will complete auth. */
2500 #endif /* CONFIG_IEEE80211R_AP */
2504 if (status_code
== WLAN_STATUS_SUCCESS
&&
2505 hapd
->conf
->mesh
& MESH_ENABLED
) {
2506 if (sta
->wpa_sm
== NULL
)
2508 wpa_auth_sta_init(hapd
->wpa_auth
,
2510 if (sta
->wpa_sm
== NULL
) {
2511 wpa_printf(MSG_DEBUG
,
2512 "SAE: Failed to initialize WPA state machine");
2513 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
2517 #endif /* CONFIG_MESH */
2518 handle_auth_sae(hapd
, sta
, mgmt
, len
, auth_transaction
,
2521 #endif /* CONFIG_SAE */
2523 case WLAN_AUTH_FILS_SK
:
2524 case WLAN_AUTH_FILS_SK_PFS
:
2525 handle_auth_fils(hapd
, sta
, mgmt
->u
.auth
.variable
,
2526 len
- IEEE80211_HDRLEN
- sizeof(mgmt
->u
.auth
),
2527 auth_alg
, auth_transaction
, status_code
,
2528 handle_auth_fils_finish
);
2530 #endif /* CONFIG_FILS */
2534 reply_res
= send_auth_reply(hapd
, mgmt
->sa
, mgmt
->bssid
, auth_alg
,
2535 auth_transaction
+ 1, resp
, resp_ies
,
2536 resp_ies_len
, "handle-auth");
2538 if (sta
&& sta
->added_unassoc
&& (resp
!= WLAN_STATUS_SUCCESS
||
2539 reply_res
!= WLAN_STATUS_SUCCESS
)) {
2540 hostapd_drv_sta_remove(hapd
, sta
->addr
);
2541 sta
->added_unassoc
= 0;
2546 int hostapd_get_aid(struct hostapd_data
*hapd
, struct sta_info
*sta
)
2550 /* get a unique AID */
2552 wpa_printf(MSG_DEBUG
, " old AID %d", sta
->aid
);
2559 for (i
= 0; i
< AID_WORDS
; i
++) {
2560 if (hapd
->sta_aid
[i
] == (u32
) -1)
2562 for (j
= 0; j
< 32; j
++) {
2563 if (!(hapd
->sta_aid
[i
] & BIT(j
)))
2571 aid
= i
* 32 + j
+ 1;
2576 hapd
->sta_aid
[i
] |= BIT(j
);
2577 wpa_printf(MSG_DEBUG
, " new AID %d", sta
->aid
);
2582 static u16
check_ssid(struct hostapd_data
*hapd
, struct sta_info
*sta
,
2583 const u8
*ssid_ie
, size_t ssid_ie_len
)
2585 if (ssid_ie
== NULL
)
2586 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2588 if (ssid_ie_len
!= hapd
->conf
->ssid
.ssid_len
||
2589 os_memcmp(ssid_ie
, hapd
->conf
->ssid
.ssid
, ssid_ie_len
) != 0) {
2590 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
2592 "Station tried to associate with unknown SSID "
2593 "'%s'", wpa_ssid_txt(ssid_ie
, ssid_ie_len
));
2594 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2597 return WLAN_STATUS_SUCCESS
;
2601 static u16
check_wmm(struct hostapd_data
*hapd
, struct sta_info
*sta
,
2602 const u8
*wmm_ie
, size_t wmm_ie_len
)
2604 sta
->flags
&= ~WLAN_STA_WMM
;
2606 if (wmm_ie
&& hapd
->conf
->wmm_enabled
) {
2607 struct wmm_information_element
*wmm
;
2609 if (!hostapd_eid_wmm_valid(hapd
, wmm_ie
, wmm_ie_len
)) {
2610 hostapd_logger(hapd
, sta
->addr
,
2612 HOSTAPD_LEVEL_DEBUG
,
2613 "invalid WMM element in association "
2615 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2618 sta
->flags
|= WLAN_STA_WMM
;
2619 wmm
= (struct wmm_information_element
*) wmm_ie
;
2620 sta
->qosinfo
= wmm
->qos_info
;
2622 return WLAN_STATUS_SUCCESS
;
2625 static u16
check_multi_ap(struct hostapd_data
*hapd
, struct sta_info
*sta
,
2626 const u8
*multi_ap_ie
, size_t multi_ap_len
)
2628 u8 multi_ap_value
= 0;
2630 sta
->flags
&= ~WLAN_STA_MULTI_AP
;
2632 if (!hapd
->conf
->multi_ap
)
2633 return WLAN_STATUS_SUCCESS
;
2636 const u8
*multi_ap_subelem
;
2638 multi_ap_subelem
= get_ie(multi_ap_ie
+ 4,
2640 MULTI_AP_SUB_ELEM_TYPE
);
2641 if (multi_ap_subelem
&& multi_ap_subelem
[1] == 1) {
2642 multi_ap_value
= multi_ap_subelem
[2];
2644 hostapd_logger(hapd
, sta
->addr
,
2645 HOSTAPD_MODULE_IEEE80211
,
2647 "Multi-AP IE has missing or invalid Multi-AP subelement");
2648 return WLAN_STATUS_INVALID_IE
;
2652 if (multi_ap_value
&& multi_ap_value
!= MULTI_AP_BACKHAUL_STA
)
2653 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
2655 "Multi-AP IE with unexpected value 0x%02x",
2658 if (!(multi_ap_value
& MULTI_AP_BACKHAUL_STA
)) {
2659 if (hapd
->conf
->multi_ap
& FRONTHAUL_BSS
)
2660 return WLAN_STATUS_SUCCESS
;
2662 hostapd_logger(hapd
, sta
->addr
,
2663 HOSTAPD_MODULE_IEEE80211
,
2665 "Non-Multi-AP STA tries to associate with backhaul-only BSS");
2666 return WLAN_STATUS_ASSOC_DENIED_UNSPEC
;
2669 if (!(hapd
->conf
->multi_ap
& BACKHAUL_BSS
))
2670 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
2671 HOSTAPD_LEVEL_DEBUG
,
2672 "Backhaul STA tries to associate with fronthaul-only BSS");
2674 sta
->flags
|= WLAN_STA_MULTI_AP
;
2675 return WLAN_STATUS_SUCCESS
;
2679 static u16
copy_supp_rates(struct hostapd_data
*hapd
, struct sta_info
*sta
,
2680 struct ieee802_11_elems
*elems
)
2682 /* Supported rates not used in IEEE 802.11ad/DMG */
2683 if (hapd
->iface
->current_mode
&&
2684 hapd
->iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211AD
)
2685 return WLAN_STATUS_SUCCESS
;
2687 if (!elems
->supp_rates
) {
2688 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
2689 HOSTAPD_LEVEL_DEBUG
,
2690 "No supported rates element in AssocReq");
2691 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2694 if (elems
->supp_rates_len
+ elems
->ext_supp_rates_len
>
2695 sizeof(sta
->supported_rates
)) {
2696 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
2697 HOSTAPD_LEVEL_DEBUG
,
2698 "Invalid supported rates element length %d+%d",
2699 elems
->supp_rates_len
,
2700 elems
->ext_supp_rates_len
);
2701 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2704 sta
->supported_rates_len
= merge_byte_arrays(
2705 sta
->supported_rates
, sizeof(sta
->supported_rates
),
2706 elems
->supp_rates
, elems
->supp_rates_len
,
2707 elems
->ext_supp_rates
, elems
->ext_supp_rates_len
);
2709 return WLAN_STATUS_SUCCESS
;
2713 static u16
check_ext_capab(struct hostapd_data
*hapd
, struct sta_info
*sta
,
2714 const u8
*ext_capab_ie
, size_t ext_capab_ie_len
)
2716 #ifdef CONFIG_INTERWORKING
2717 /* check for QoS Map support */
2718 if (ext_capab_ie_len
>= 5) {
2719 if (ext_capab_ie
[4] & 0x01)
2720 sta
->qos_map_enabled
= 1;
2722 #endif /* CONFIG_INTERWORKING */
2724 if (ext_capab_ie_len
> 0) {
2725 sta
->ecsa_supported
= !!(ext_capab_ie
[0] & BIT(2));
2726 os_free(sta
->ext_capability
);
2727 sta
->ext_capability
= os_malloc(1 + ext_capab_ie_len
);
2728 if (sta
->ext_capability
) {
2729 sta
->ext_capability
[0] = ext_capab_ie_len
;
2730 os_memcpy(sta
->ext_capability
+ 1, ext_capab_ie
,
2735 return WLAN_STATUS_SUCCESS
;
2741 static int owe_group_supported(struct hostapd_data
*hapd
, u16 group
)
2744 int *groups
= hapd
->conf
->owe_groups
;
2746 if (group
!= 19 && group
!= 20 && group
!= 21)
2752 for (i
= 0; groups
[i
] > 0; i
++) {
2753 if (groups
[i
] == group
)
2761 static u16
owe_process_assoc_req(struct hostapd_data
*hapd
,
2762 struct sta_info
*sta
, const u8
*owe_dh
,
2765 struct wpabuf
*secret
, *pub
, *hkey
;
2767 u8 prk
[SHA512_MAC_LEN
], pmkid
[SHA512_MAC_LEN
];
2768 const char *info
= "OWE Key Generation";
2772 size_t hash_len
, prime_len
;
2774 if (wpa_auth_sta_get_pmksa(sta
->wpa_sm
)) {
2775 wpa_printf(MSG_DEBUG
, "OWE: Using PMKSA caching");
2776 return WLAN_STATUS_SUCCESS
;
2779 group
= WPA_GET_LE16(owe_dh
);
2780 if (!owe_group_supported(hapd
, group
)) {
2781 wpa_printf(MSG_DEBUG
, "OWE: Unsupported DH group %u", group
);
2782 return WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED
;
2786 else if (group
== 20)
2788 else if (group
== 21)
2791 return WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED
;
2793 crypto_ecdh_deinit(sta
->owe_ecdh
);
2794 sta
->owe_ecdh
= crypto_ecdh_init(group
);
2796 return WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED
;
2797 sta
->owe_group
= group
;
2799 secret
= crypto_ecdh_set_peerkey(sta
->owe_ecdh
, 0, owe_dh
+ 2,
2801 secret
= wpabuf_zeropad(secret
, prime_len
);
2803 wpa_printf(MSG_DEBUG
, "OWE: Invalid peer DH public key");
2804 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2806 wpa_hexdump_buf_key(MSG_DEBUG
, "OWE: DH shared secret", secret
);
2808 /* prk = HKDF-extract(C | A | group, z) */
2810 pub
= crypto_ecdh_get_pubkey(sta
->owe_ecdh
, 0);
2812 wpabuf_clear_free(secret
);
2813 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2816 /* PMKID = Truncate-128(Hash(C | A)) */
2817 addr
[0] = owe_dh
+ 2;
2818 len
[0] = owe_dh_len
- 2;
2819 addr
[1] = wpabuf_head(pub
);
2820 len
[1] = wpabuf_len(pub
);
2822 res
= sha256_vector(2, addr
, len
, pmkid
);
2823 hash_len
= SHA256_MAC_LEN
;
2824 } else if (group
== 20) {
2825 res
= sha384_vector(2, addr
, len
, pmkid
);
2826 hash_len
= SHA384_MAC_LEN
;
2827 } else if (group
== 21) {
2828 res
= sha512_vector(2, addr
, len
, pmkid
);
2829 hash_len
= SHA512_MAC_LEN
;
2832 wpabuf_clear_free(secret
);
2833 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2835 pub
= wpabuf_zeropad(pub
, prime_len
);
2836 if (res
< 0 || !pub
) {
2838 wpabuf_clear_free(secret
);
2839 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2842 hkey
= wpabuf_alloc(owe_dh_len
- 2 + wpabuf_len(pub
) + 2);
2845 wpabuf_clear_free(secret
);
2846 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2849 wpabuf_put_data(hkey
, owe_dh
+ 2, owe_dh_len
- 2); /* C */
2850 wpabuf_put_buf(hkey
, pub
); /* A */
2852 wpabuf_put_le16(hkey
, group
); /* group */
2854 res
= hmac_sha256(wpabuf_head(hkey
), wpabuf_len(hkey
),
2855 wpabuf_head(secret
), wpabuf_len(secret
), prk
);
2856 else if (group
== 20)
2857 res
= hmac_sha384(wpabuf_head(hkey
), wpabuf_len(hkey
),
2858 wpabuf_head(secret
), wpabuf_len(secret
), prk
);
2859 else if (group
== 21)
2860 res
= hmac_sha512(wpabuf_head(hkey
), wpabuf_len(hkey
),
2861 wpabuf_head(secret
), wpabuf_len(secret
), prk
);
2862 wpabuf_clear_free(hkey
);
2863 wpabuf_clear_free(secret
);
2865 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2867 wpa_hexdump_key(MSG_DEBUG
, "OWE: prk", prk
, hash_len
);
2869 /* PMK = HKDF-expand(prk, "OWE Key Generation", n) */
2871 os_free(sta
->owe_pmk
);
2872 sta
->owe_pmk
= os_malloc(hash_len
);
2873 if (!sta
->owe_pmk
) {
2874 os_memset(prk
, 0, SHA512_MAC_LEN
);
2875 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2879 res
= hmac_sha256_kdf(prk
, hash_len
, NULL
, (const u8
*) info
,
2880 os_strlen(info
), sta
->owe_pmk
, hash_len
);
2881 else if (group
== 20)
2882 res
= hmac_sha384_kdf(prk
, hash_len
, NULL
, (const u8
*) info
,
2883 os_strlen(info
), sta
->owe_pmk
, hash_len
);
2884 else if (group
== 21)
2885 res
= hmac_sha512_kdf(prk
, hash_len
, NULL
, (const u8
*) info
,
2886 os_strlen(info
), sta
->owe_pmk
, hash_len
);
2887 os_memset(prk
, 0, SHA512_MAC_LEN
);
2889 os_free(sta
->owe_pmk
);
2890 sta
->owe_pmk
= NULL
;
2891 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2893 sta
->owe_pmk_len
= hash_len
;
2895 wpa_hexdump_key(MSG_DEBUG
, "OWE: PMK", sta
->owe_pmk
, sta
->owe_pmk_len
);
2896 wpa_hexdump(MSG_DEBUG
, "OWE: PMKID", pmkid
, PMKID_LEN
);
2897 wpa_auth_pmksa_add2(hapd
->wpa_auth
, sta
->addr
, sta
->owe_pmk
,
2898 sta
->owe_pmk_len
, pmkid
, 0, WPA_KEY_MGMT_OWE
);
2900 return WLAN_STATUS_SUCCESS
;
2904 u16
owe_validate_request(struct hostapd_data
*hapd
, const u8
*peer
,
2905 const u8
*rsn_ie
, size_t rsn_ie_len
,
2906 const u8
*owe_dh
, size_t owe_dh_len
)
2908 struct wpa_ie_data data
;
2911 if (!rsn_ie
|| rsn_ie_len
< 2) {
2912 wpa_printf(MSG_DEBUG
, "OWE: Invalid RSNE from " MACSTR
,
2914 return WLAN_STATUS_INVALID_IE
;
2919 res
= wpa_parse_wpa_ie_rsn(rsn_ie
, rsn_ie_len
, &data
);
2921 wpa_printf(MSG_DEBUG
, "Failed to parse RSNE from " MACSTR
2922 " (res=%d)", MAC2STR(peer
), res
);
2923 wpa_hexdump(MSG_DEBUG
, "RSNE", rsn_ie
, rsn_ie_len
);
2924 return wpa_res_to_status_code(res
);
2926 if (!(data
.key_mgmt
& WPA_KEY_MGMT_OWE
)) {
2927 wpa_printf(MSG_DEBUG
,
2928 "OWE: Unexpected key mgmt 0x%x from " MACSTR
,
2929 (unsigned int) data
.key_mgmt
, MAC2STR(peer
));
2930 return WLAN_STATUS_AKMP_NOT_VALID
;
2933 wpa_printf(MSG_DEBUG
,
2934 "OWE: No Diffie-Hellman Parameter element from "
2935 MACSTR
, MAC2STR(peer
));
2936 return WLAN_STATUS_AKMP_NOT_VALID
;
2939 return WLAN_STATUS_SUCCESS
;
2943 u16
owe_process_rsn_ie(struct hostapd_data
*hapd
,
2944 struct sta_info
*sta
,
2945 const u8
*rsn_ie
, size_t rsn_ie_len
,
2946 const u8
*owe_dh
, size_t owe_dh_len
)
2949 u8
*owe_buf
, ie
[256 * 2];
2953 if (!rsn_ie
|| rsn_ie_len
< 2) {
2954 wpa_printf(MSG_DEBUG
, "OWE: No RSNE in (Re)AssocReq");
2955 status
= WLAN_STATUS_INVALID_IE
;
2960 sta
->wpa_sm
= wpa_auth_sta_init(hapd
->wpa_auth
, sta
->addr
,
2963 wpa_printf(MSG_WARNING
,
2964 "OWE: Failed to initialize WPA state machine");
2965 status
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
2970 res
= wpa_validate_wpa_ie(hapd
->wpa_auth
, sta
->wpa_sm
,
2971 hapd
->iface
->freq
, rsn_ie
, rsn_ie_len
,
2972 NULL
, 0, NULL
, 0, owe_dh
, owe_dh_len
);
2973 status
= wpa_res_to_status_code(res
);
2974 if (status
!= WLAN_STATUS_SUCCESS
)
2976 status
= owe_process_assoc_req(hapd
, sta
, owe_dh
, owe_dh_len
);
2977 if (status
!= WLAN_STATUS_SUCCESS
)
2979 owe_buf
= wpa_auth_write_assoc_resp_owe(sta
->wpa_sm
, ie
, sizeof(ie
),
2982 status
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
2986 if (sta
->owe_ecdh
) {
2989 pub
= crypto_ecdh_get_pubkey(sta
->owe_ecdh
, 0);
2991 status
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
2995 /* OWE Diffie-Hellman Parameter element */
2996 *owe_buf
++ = WLAN_EID_EXTENSION
; /* Element ID */
2997 *owe_buf
++ = 1 + 2 + wpabuf_len(pub
); /* Length */
2998 *owe_buf
++ = WLAN_EID_EXT_OWE_DH_PARAM
; /* Element ID Extension
3000 WPA_PUT_LE16(owe_buf
, sta
->owe_group
);
3002 os_memcpy(owe_buf
, wpabuf_head(pub
), wpabuf_len(pub
));
3003 owe_buf
+= wpabuf_len(pub
);
3005 sta
->external_dh_updated
= 1;
3007 ie_len
= owe_buf
- ie
;
3010 wpa_printf(MSG_DEBUG
, "OWE: Update status %d, ie len %d for peer "
3011 MACSTR
, status
, (unsigned int) ie_len
,
3012 MAC2STR(sta
->addr
));
3013 hostapd_drv_update_dh_ie(hapd
, sta
->addr
, status
,
3014 status
== WLAN_STATUS_SUCCESS
? ie
: NULL
,
3020 #endif /* CONFIG_OWE */
3023 static u16
check_assoc_ies(struct hostapd_data
*hapd
, struct sta_info
*sta
,
3024 const u8
*ies
, size_t ies_len
, int reassoc
)
3026 struct ieee802_11_elems elems
;
3030 const u8
*p2p_dev_addr
= NULL
;
3032 if (ieee802_11_parse_elems(ies
, ies_len
, &elems
, 1) == ParseFailed
) {
3033 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
3034 HOSTAPD_LEVEL_INFO
, "Station sent an invalid "
3035 "association request");
3036 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3039 resp
= check_ssid(hapd
, sta
, elems
.ssid
, elems
.ssid_len
);
3040 if (resp
!= WLAN_STATUS_SUCCESS
)
3042 resp
= check_wmm(hapd
, sta
, elems
.wmm
, elems
.wmm_len
);
3043 if (resp
!= WLAN_STATUS_SUCCESS
)
3045 resp
= check_ext_capab(hapd
, sta
, elems
.ext_capab
, elems
.ext_capab_len
);
3046 if (resp
!= WLAN_STATUS_SUCCESS
)
3048 resp
= copy_supp_rates(hapd
, sta
, &elems
);
3049 if (resp
!= WLAN_STATUS_SUCCESS
)
3052 resp
= check_multi_ap(hapd
, sta
, elems
.multi_ap
, elems
.multi_ap_len
);
3053 if (resp
!= WLAN_STATUS_SUCCESS
)
3056 #ifdef CONFIG_IEEE80211N
3057 resp
= copy_sta_ht_capab(hapd
, sta
, elems
.ht_capabilities
);
3058 if (resp
!= WLAN_STATUS_SUCCESS
)
3060 if (hapd
->iconf
->ieee80211n
&& hapd
->iconf
->require_ht
&&
3061 !(sta
->flags
& WLAN_STA_HT
)) {
3062 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
3063 HOSTAPD_LEVEL_INFO
, "Station does not support "
3064 "mandatory HT PHY - reject association");
3065 return WLAN_STATUS_ASSOC_DENIED_NO_HT
;
3067 #endif /* CONFIG_IEEE80211N */
3069 #ifdef CONFIG_IEEE80211AC
3070 if (hapd
->iconf
->ieee80211ac
) {
3071 resp
= copy_sta_vht_capab(hapd
, sta
, elems
.vht_capabilities
);
3072 if (resp
!= WLAN_STATUS_SUCCESS
)
3075 resp
= set_sta_vht_opmode(hapd
, sta
, elems
.vht_opmode_notif
);
3076 if (resp
!= WLAN_STATUS_SUCCESS
)
3080 if (hapd
->iconf
->ieee80211ac
&& hapd
->iconf
->require_vht
&&
3081 !(sta
->flags
& WLAN_STA_VHT
)) {
3082 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
3083 HOSTAPD_LEVEL_INFO
, "Station does not support "
3084 "mandatory VHT PHY - reject association");
3085 return WLAN_STATUS_ASSOC_DENIED_NO_VHT
;
3088 if (hapd
->conf
->vendor_vht
&& !elems
.vht_capabilities
) {
3089 resp
= copy_sta_vendor_vht(hapd
, sta
, elems
.vendor_vht
,
3090 elems
.vendor_vht_len
);
3091 if (resp
!= WLAN_STATUS_SUCCESS
)
3094 #endif /* CONFIG_IEEE80211AC */
3095 #ifdef CONFIG_IEEE80211AX
3096 if (hapd
->iconf
->ieee80211ax
) {
3097 resp
= copy_sta_he_capab(hapd
, sta
, IEEE80211_MODE_AP
,
3098 elems
.he_capabilities
,
3099 elems
.he_capabilities_len
);
3100 if (resp
!= WLAN_STATUS_SUCCESS
)
3103 #endif /* CONFIG_IEEE80211AX */
3107 wpabuf_free(sta
->p2p_ie
);
3108 sta
->p2p_ie
= ieee802_11_vendor_ie_concat(ies
, ies_len
,
3109 P2P_IE_VENDOR_TYPE
);
3111 p2p_dev_addr
= p2p_get_go_dev_addr(sta
->p2p_ie
);
3113 wpabuf_free(sta
->p2p_ie
);
3116 #endif /* CONFIG_P2P */
3118 if ((hapd
->conf
->wpa
& WPA_PROTO_RSN
) && elems
.rsn_ie
) {
3119 wpa_ie
= elems
.rsn_ie
;
3120 wpa_ie_len
= elems
.rsn_ie_len
;
3121 } else if ((hapd
->conf
->wpa
& WPA_PROTO_WPA
) &&
3123 wpa_ie
= elems
.wpa_ie
;
3124 wpa_ie_len
= elems
.wpa_ie_len
;
3131 sta
->flags
&= ~(WLAN_STA_WPS
| WLAN_STA_MAYBE_WPS
| WLAN_STA_WPS2
);
3132 if (hapd
->conf
->wps_state
&& elems
.wps_ie
) {
3133 wpa_printf(MSG_DEBUG
, "STA included WPS IE in (Re)Association "
3134 "Request - assume WPS is used");
3135 sta
->flags
|= WLAN_STA_WPS
;
3136 wpabuf_free(sta
->wps_ie
);
3137 sta
->wps_ie
= ieee802_11_vendor_ie_concat(ies
, ies_len
,
3138 WPS_IE_VENDOR_TYPE
);
3139 if (sta
->wps_ie
&& wps_is_20(sta
->wps_ie
)) {
3140 wpa_printf(MSG_DEBUG
, "WPS: STA supports WPS 2.0");
3141 sta
->flags
|= WLAN_STA_WPS2
;
3145 if (sta
->wps_ie
&& wps_validate_assoc_req(sta
->wps_ie
) < 0) {
3146 wpa_printf(MSG_DEBUG
, "WPS: Invalid WPS IE in "
3147 "(Re)Association Request - reject");
3148 return WLAN_STATUS_INVALID_IE
;
3150 } else if (hapd
->conf
->wps_state
&& wpa_ie
== NULL
) {
3151 wpa_printf(MSG_DEBUG
, "STA did not include WPA/RSN IE in "
3152 "(Re)Association Request - possible WPS use");
3153 sta
->flags
|= WLAN_STA_MAYBE_WPS
;
3155 #endif /* CONFIG_WPS */
3156 if (hapd
->conf
->wpa
&& wpa_ie
== NULL
) {
3157 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
3159 "No WPA/RSN IE in association request");
3160 return WLAN_STATUS_INVALID_IE
;
3163 if (hapd
->conf
->wpa
&& wpa_ie
) {
3167 if (sta
->wpa_sm
== NULL
)
3168 sta
->wpa_sm
= wpa_auth_sta_init(hapd
->wpa_auth
,
3171 if (sta
->wpa_sm
== NULL
) {
3172 wpa_printf(MSG_WARNING
, "Failed to initialize WPA "
3174 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3176 wpa_auth_set_auth_alg(sta
->wpa_sm
, sta
->auth_alg
);
3177 res
= wpa_validate_wpa_ie(hapd
->wpa_auth
, sta
->wpa_sm
,
3180 elems
.rsnxe
? elems
.rsnxe
- 2 : NULL
,
3181 elems
.rsnxe
? elems
.rsnxe_len
+ 2 : 0,
3182 elems
.mdie
, elems
.mdie_len
,
3183 elems
.owe_dh
, elems
.owe_dh_len
);
3184 resp
= wpa_res_to_status_code(res
);
3185 if (resp
!= WLAN_STATUS_SUCCESS
)
3187 if ((sta
->flags
& (WLAN_STA_ASSOC
| WLAN_STA_MFP
)) ==
3188 (WLAN_STA_ASSOC
| WLAN_STA_MFP
) &&
3189 !sta
->sa_query_timed_out
&&
3190 sta
->sa_query_count
> 0)
3191 ap_check_sa_query_timeout(hapd
, sta
);
3192 if ((sta
->flags
& (WLAN_STA_ASSOC
| WLAN_STA_MFP
)) ==
3193 (WLAN_STA_ASSOC
| WLAN_STA_MFP
) &&
3194 !sta
->sa_query_timed_out
&&
3195 (!reassoc
|| sta
->auth_alg
!= WLAN_AUTH_FT
)) {
3197 * STA has already been associated with MFP and SA
3198 * Query timeout has not been reached. Reject the
3199 * association attempt temporarily and start SA Query,
3200 * if one is not pending.
3203 if (sta
->sa_query_count
== 0)
3204 ap_sta_start_sa_query(hapd
, sta
);
3206 return WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY
;
3209 if (wpa_auth_uses_mfp(sta
->wpa_sm
))
3210 sta
->flags
|= WLAN_STA_MFP
;
3212 sta
->flags
&= ~WLAN_STA_MFP
;
3214 #ifdef CONFIG_IEEE80211R_AP
3215 if (sta
->auth_alg
== WLAN_AUTH_FT
) {
3217 wpa_printf(MSG_DEBUG
, "FT: " MACSTR
" tried "
3218 "to use association (not "
3219 "re-association) with FT auth_alg",
3220 MAC2STR(sta
->addr
));
3221 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3224 resp
= wpa_ft_validate_reassoc(sta
->wpa_sm
, ies
,
3226 if (resp
!= WLAN_STATUS_SUCCESS
)
3229 #endif /* CONFIG_IEEE80211R_AP */
3232 if (wpa_auth_uses_sae(sta
->wpa_sm
) && sta
->sae
&&
3233 sta
->sae
->state
== SAE_ACCEPTED
)
3234 wpa_auth_add_sae_pmkid(sta
->wpa_sm
, sta
->sae
->pmkid
);
3236 if (wpa_auth_uses_sae(sta
->wpa_sm
) &&
3237 sta
->auth_alg
== WLAN_AUTH_OPEN
) {
3238 struct rsn_pmksa_cache_entry
*sa
;
3239 sa
= wpa_auth_sta_get_pmksa(sta
->wpa_sm
);
3240 if (!sa
|| sa
->akmp
!= WPA_KEY_MGMT_SAE
) {
3241 wpa_printf(MSG_DEBUG
,
3242 "SAE: No PMKSA cache entry found for "
3243 MACSTR
, MAC2STR(sta
->addr
));
3244 return WLAN_STATUS_INVALID_PMKID
;
3246 wpa_printf(MSG_DEBUG
, "SAE: " MACSTR
3247 " using PMKSA caching", MAC2STR(sta
->addr
));
3248 } else if (wpa_auth_uses_sae(sta
->wpa_sm
) &&
3249 sta
->auth_alg
!= WLAN_AUTH_SAE
&&
3250 !(sta
->auth_alg
== WLAN_AUTH_FT
&&
3251 wpa_auth_uses_ft_sae(sta
->wpa_sm
))) {
3252 wpa_printf(MSG_DEBUG
, "SAE: " MACSTR
" tried to use "
3253 "SAE AKM after non-SAE auth_alg %u",
3254 MAC2STR(sta
->addr
), sta
->auth_alg
);
3255 return WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG
;
3258 if (hapd
->conf
->sae_pwe
== 2 &&
3259 sta
->auth_alg
== WLAN_AUTH_SAE
&&
3260 sta
->sae
&& sta
->sae
->tmp
&& !sta
->sae
->tmp
->h2e
&&
3261 elems
.rsnxe
&& elems
.rsnxe_len
>= 1 &&
3262 (elems
.rsnxe
[0] & BIT(WLAN_RSNX_CAPAB_SAE_H2E
))) {
3263 wpa_printf(MSG_INFO
, "SAE: " MACSTR
3264 " indicates support for SAE H2E, but did not use it",
3265 MAC2STR(sta
->addr
));
3266 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3268 #endif /* CONFIG_SAE */
3271 if ((hapd
->conf
->wpa_key_mgmt
& WPA_KEY_MGMT_OWE
) &&
3272 wpa_auth_sta_key_mgmt(sta
->wpa_sm
) == WPA_KEY_MGMT_OWE
&&
3274 resp
= owe_process_assoc_req(hapd
, sta
, elems
.owe_dh
,
3276 if (resp
!= WLAN_STATUS_SUCCESS
)
3279 #endif /* CONFIG_OWE */
3282 dpp_pfs_free(sta
->dpp_pfs
);
3283 sta
->dpp_pfs
= NULL
;
3285 if ((hapd
->conf
->wpa_key_mgmt
& WPA_KEY_MGMT_DPP
) &&
3286 hapd
->conf
->dpp_netaccesskey
&& sta
->wpa_sm
&&
3287 wpa_auth_sta_key_mgmt(sta
->wpa_sm
) == WPA_KEY_MGMT_DPP
&&
3289 sta
->dpp_pfs
= dpp_pfs_init(
3290 wpabuf_head(hapd
->conf
->dpp_netaccesskey
),
3291 wpabuf_len(hapd
->conf
->dpp_netaccesskey
));
3292 if (!sta
->dpp_pfs
) {
3293 wpa_printf(MSG_DEBUG
,
3294 "DPP: Could not initialize PFS");
3295 /* Try to continue without PFS */
3299 if (dpp_pfs_process(sta
->dpp_pfs
, elems
.owe_dh
,
3300 elems
.owe_dh_len
) < 0) {
3301 dpp_pfs_free(sta
->dpp_pfs
);
3302 sta
->dpp_pfs
= NULL
;
3303 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3307 wpa_auth_set_dpp_z(sta
->wpa_sm
, sta
->dpp_pfs
?
3308 sta
->dpp_pfs
->secret
: NULL
);
3310 #endif /* CONFIG_DPP2 */
3312 #ifdef CONFIG_IEEE80211N
3313 if ((sta
->flags
& (WLAN_STA_HT
| WLAN_STA_VHT
)) &&
3314 wpa_auth_get_pairwise(sta
->wpa_sm
) == WPA_CIPHER_TKIP
) {
3315 hostapd_logger(hapd
, sta
->addr
,
3316 HOSTAPD_MODULE_IEEE80211
,
3318 "Station tried to use TKIP with HT "
3320 return WLAN_STATUS_CIPHER_REJECTED_PER_POLICY
;
3322 #endif /* CONFIG_IEEE80211N */
3324 } else if (hapd
->conf
->osen
) {
3325 if (elems
.osen
== NULL
) {
3327 hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
3329 "No HS 2.0 OSEN element in association request");
3330 return WLAN_STATUS_INVALID_IE
;
3333 wpa_printf(MSG_DEBUG
, "HS 2.0: OSEN association");
3334 if (sta
->wpa_sm
== NULL
)
3335 sta
->wpa_sm
= wpa_auth_sta_init(hapd
->wpa_auth
,
3337 if (sta
->wpa_sm
== NULL
) {
3338 wpa_printf(MSG_WARNING
, "Failed to initialize WPA "
3340 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3342 if (wpa_validate_osen(hapd
->wpa_auth
, sta
->wpa_sm
,
3343 elems
.osen
- 2, elems
.osen_len
+ 2) < 0)
3344 return WLAN_STATUS_INVALID_IE
;
3345 #endif /* CONFIG_HS20 */
3347 wpa_auth_sta_no_wpa(sta
->wpa_sm
);
3350 p2p_group_notif_assoc(hapd
->p2p_group
, sta
->addr
, ies
, ies_len
);
3351 #endif /* CONFIG_P2P */
3354 wpabuf_free(sta
->hs20_ie
);
3355 if (elems
.hs20
&& elems
.hs20_len
> 4) {
3358 sta
->hs20_ie
= wpabuf_alloc_copy(elems
.hs20
+ 4,
3359 elems
.hs20_len
- 4);
3360 release
= ((elems
.hs20
[4] >> 4) & 0x0f) + 1;
3361 if (release
>= 2 && !wpa_auth_uses_mfp(sta
->wpa_sm
) &&
3362 hapd
->conf
->ieee80211w
!= NO_MGMT_FRAME_PROTECTION
) {
3363 wpa_printf(MSG_DEBUG
,
3364 "HS 2.0: PMF not negotiated by release %d station "
3365 MACSTR
, release
, MAC2STR(sta
->addr
));
3366 return WLAN_STATUS_ROBUST_MGMT_FRAME_POLICY_VIOLATION
;
3369 sta
->hs20_ie
= NULL
;
3372 wpabuf_free(sta
->roaming_consortium
);
3373 if (elems
.roaming_cons_sel
)
3374 sta
->roaming_consortium
= wpabuf_alloc_copy(
3375 elems
.roaming_cons_sel
+ 4,
3376 elems
.roaming_cons_sel_len
- 4);
3378 sta
->roaming_consortium
= NULL
;
3379 #endif /* CONFIG_HS20 */
3382 wpabuf_free(sta
->mb_ies
);
3383 if (hapd
->iface
->fst
)
3384 sta
->mb_ies
= mb_ies_by_info(&elems
.mb_ies
);
3387 #endif /* CONFIG_FST */
3390 mbo_ap_check_sta_assoc(hapd
, sta
, &elems
);
3392 if (hapd
->conf
->mbo_enabled
&& (hapd
->conf
->wpa
& 2) &&
3393 elems
.mbo
&& sta
->cell_capa
&& !(sta
->flags
& WLAN_STA_MFP
) &&
3394 hapd
->conf
->ieee80211w
!= NO_MGMT_FRAME_PROTECTION
) {
3395 wpa_printf(MSG_INFO
,
3396 "MBO: Reject WPA2 association without PMF");
3397 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3399 #endif /* CONFIG_MBO */
3401 #if defined(CONFIG_FILS) && defined(CONFIG_OCV)
3402 if (wpa_auth_uses_ocv(sta
->wpa_sm
) &&
3403 (sta
->auth_alg
== WLAN_AUTH_FILS_SK
||
3404 sta
->auth_alg
== WLAN_AUTH_FILS_SK_PFS
||
3405 sta
->auth_alg
== WLAN_AUTH_FILS_PK
)) {
3406 struct wpa_channel_info ci
;
3410 if (hostapd_drv_channel_info(hapd
, &ci
) != 0) {
3411 wpa_printf(MSG_WARNING
,
3412 "Failed to get channel info to validate received OCI in FILS (Re)Association Request frame");
3413 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3416 if (get_sta_tx_parameters(sta
->wpa_sm
,
3417 channel_width_to_int(ci
.chanwidth
),
3418 ci
.seg1_idx
, &tx_chanwidth
,
3420 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3422 if (ocv_verify_tx_params(elems
.oci
, elems
.oci_len
, &ci
,
3423 tx_chanwidth
, tx_seg1_idx
) != 0) {
3424 wpa_printf(MSG_WARNING
, "FILS: %s", ocv_errorstr
);
3425 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3428 #endif /* CONFIG_FILS && CONFIG_OCV */
3430 ap_copy_sta_supp_op_classes(sta
, elems
.supp_op_classes
,
3431 elems
.supp_op_classes_len
);
3433 if ((sta
->capability
& WLAN_CAPABILITY_RADIO_MEASUREMENT
) &&
3434 elems
.rrm_enabled
&&
3435 elems
.rrm_enabled_len
>= sizeof(sta
->rrm_enabled_capa
))
3436 os_memcpy(sta
->rrm_enabled_capa
, elems
.rrm_enabled
,
3437 sizeof(sta
->rrm_enabled_capa
));
3439 if (elems
.power_capab
) {
3440 sta
->min_tx_power
= elems
.power_capab
[0];
3441 sta
->max_tx_power
= elems
.power_capab
[1];
3442 sta
->power_capab
= 1;
3444 sta
->power_capab
= 0;
3447 return WLAN_STATUS_SUCCESS
;
3451 static void send_deauth(struct hostapd_data
*hapd
, const u8
*addr
,
3455 struct ieee80211_mgmt reply
;
3457 os_memset(&reply
, 0, sizeof(reply
));
3458 reply
.frame_control
=
3459 IEEE80211_FC(WLAN_FC_TYPE_MGMT
, WLAN_FC_STYPE_DEAUTH
);
3460 os_memcpy(reply
.da
, addr
, ETH_ALEN
);
3461 os_memcpy(reply
.sa
, hapd
->own_addr
, ETH_ALEN
);
3462 os_memcpy(reply
.bssid
, hapd
->own_addr
, ETH_ALEN
);
3464 send_len
= IEEE80211_HDRLEN
+ sizeof(reply
.u
.deauth
);
3465 reply
.u
.deauth
.reason_code
= host_to_le16(reason_code
);
3467 if (hostapd_drv_send_mlme(hapd
, &reply
, send_len
, 0) < 0)
3468 wpa_printf(MSG_INFO
, "Failed to send deauth: %s",
3473 static int add_associated_sta(struct hostapd_data
*hapd
,
3474 struct sta_info
*sta
, int reassoc
)
3476 struct ieee80211_ht_capabilities ht_cap
;
3477 struct ieee80211_vht_capabilities vht_cap
;
3478 struct ieee80211_he_capabilities he_cap
;
3482 * Remove the STA entry to ensure the STA PS state gets cleared and
3483 * configuration gets updated. This is relevant for cases, such as
3484 * FT-over-the-DS, where a station re-associates back to the same AP but
3485 * skips the authentication flow, or if working with a driver that
3486 * does not support full AP client state.
3488 * Skip this if the STA has already completed FT reassociation and the
3489 * TK has been configured since the TX/RX PN must not be reset to 0 for
3492 * FT-over-the-DS has a special case where the STA entry (and as such,
3493 * the TK) has not yet been configured to the driver depending on which
3494 * driver interface is used. For that case, allow add-STA operation to
3495 * be used (instead of set-STA). This is needed to allow mac80211-based
3496 * drivers to accept the STA parameter configuration. Since this is
3497 * after a new FT-over-DS exchange, a new TK has been derived, so key
3498 * reinstallation is not a concern for this case.
3500 wpa_printf(MSG_DEBUG
, "Add associated STA " MACSTR
3501 " (added_unassoc=%d auth_alg=%u ft_over_ds=%u reassoc=%d authorized=%d ft_tk=%d fils_tk=%d)",
3502 MAC2STR(sta
->addr
), sta
->added_unassoc
, sta
->auth_alg
,
3503 sta
->ft_over_ds
, reassoc
,
3504 !!(sta
->flags
& WLAN_STA_AUTHORIZED
),
3505 wpa_auth_sta_ft_tk_already_set(sta
->wpa_sm
),
3506 wpa_auth_sta_fils_tk_already_set(sta
->wpa_sm
));
3508 if (!sta
->added_unassoc
&&
3509 (!(sta
->flags
& WLAN_STA_AUTHORIZED
) ||
3510 (reassoc
&& sta
->ft_over_ds
&& sta
->auth_alg
== WLAN_AUTH_FT
) ||
3511 (!wpa_auth_sta_ft_tk_already_set(sta
->wpa_sm
) &&
3512 !wpa_auth_sta_fils_tk_already_set(sta
->wpa_sm
)))) {
3513 hostapd_drv_sta_remove(hapd
, sta
->addr
);
3514 wpa_auth_sm_event(sta
->wpa_sm
, WPA_DRV_STA_REMOVED
);
3517 /* Do not allow the FT-over-DS exception to be used more than
3518 * once per authentication exchange to guarantee a new TK is
3520 sta
->ft_over_ds
= 0;
3523 #ifdef CONFIG_IEEE80211N
3524 if (sta
->flags
& WLAN_STA_HT
)
3525 hostapd_get_ht_capab(hapd
, sta
->ht_capabilities
, &ht_cap
);
3526 #endif /* CONFIG_IEEE80211N */
3527 #ifdef CONFIG_IEEE80211AC
3528 if (sta
->flags
& WLAN_STA_VHT
)
3529 hostapd_get_vht_capab(hapd
, sta
->vht_capabilities
, &vht_cap
);
3530 #endif /* CONFIG_IEEE80211AC */
3531 #ifdef CONFIG_IEEE80211AX
3532 if (sta
->flags
& WLAN_STA_HE
) {
3533 hostapd_get_he_capab(hapd
, sta
->he_capab
, &he_cap
,
3536 #endif /* CONFIG_IEEE80211AX */
3539 * Add the station with forced WLAN_STA_ASSOC flag. The sta->flags
3540 * will be set when the ACK frame for the (Re)Association Response frame
3541 * is processed (TX status driver event).
3543 if (hostapd_sta_add(hapd
, sta
->addr
, sta
->aid
, sta
->capability
,
3544 sta
->supported_rates
, sta
->supported_rates_len
,
3545 sta
->listen_interval
,
3546 sta
->flags
& WLAN_STA_HT
? &ht_cap
: NULL
,
3547 sta
->flags
& WLAN_STA_VHT
? &vht_cap
: NULL
,
3548 sta
->flags
& WLAN_STA_HE
? &he_cap
: NULL
,
3549 sta
->flags
& WLAN_STA_HE
? sta
->he_capab_len
: 0,
3550 sta
->flags
| WLAN_STA_ASSOC
, sta
->qosinfo
,
3551 sta
->vht_opmode
, sta
->p2p_ie
? 1 : 0,
3553 hostapd_logger(hapd
, sta
->addr
,
3554 HOSTAPD_MODULE_IEEE80211
, HOSTAPD_LEVEL_NOTICE
,
3555 "Could not %s STA to kernel driver",
3556 set
? "set" : "add");
3558 if (sta
->added_unassoc
) {
3559 hostapd_drv_sta_remove(hapd
, sta
->addr
);
3560 sta
->added_unassoc
= 0;
3566 sta
->added_unassoc
= 0;
3572 static u16
send_assoc_resp(struct hostapd_data
*hapd
, struct sta_info
*sta
,
3573 const u8
*addr
, u16 status_code
, int reassoc
,
3574 const u8
*ies
, size_t ies_len
, int rssi
)
3579 struct ieee80211_mgmt
*reply
;
3581 u16 res
= WLAN_STATUS_SUCCESS
;
3583 buflen
= sizeof(struct ieee80211_mgmt
) + 1024;
3585 if (sta
&& sta
->fils_hlp_resp
)
3586 buflen
+= wpabuf_len(sta
->fils_hlp_resp
);
3589 #endif /* CONFIG_FILS */
3591 if (sta
&& (hapd
->conf
->wpa_key_mgmt
& WPA_KEY_MGMT_OWE
))
3593 #endif /* CONFIG_OWE */
3595 if (sta
&& sta
->dpp_pfs
)
3596 buflen
+= 5 + sta
->dpp_pfs
->curve
->prime_len
;
3597 #endif /* CONFIG_DPP2 */
3598 buf
= os_zalloc(buflen
);
3600 res
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
3603 reply
= (struct ieee80211_mgmt
*) buf
;
3604 reply
->frame_control
=
3605 IEEE80211_FC(WLAN_FC_TYPE_MGMT
,
3606 (reassoc
? WLAN_FC_STYPE_REASSOC_RESP
:
3607 WLAN_FC_STYPE_ASSOC_RESP
));
3608 os_memcpy(reply
->da
, addr
, ETH_ALEN
);
3609 os_memcpy(reply
->sa
, hapd
->own_addr
, ETH_ALEN
);
3610 os_memcpy(reply
->bssid
, hapd
->own_addr
, ETH_ALEN
);
3612 send_len
= IEEE80211_HDRLEN
;
3613 send_len
+= sizeof(reply
->u
.assoc_resp
);
3614 reply
->u
.assoc_resp
.capab_info
=
3615 host_to_le16(hostapd_own_capab_info(hapd
));
3616 reply
->u
.assoc_resp
.status_code
= host_to_le16(status_code
);
3618 reply
->u
.assoc_resp
.aid
= host_to_le16((sta
? sta
->aid
: 0) |
3620 /* Supported rates */
3621 p
= hostapd_eid_supp_rates(hapd
, reply
->u
.assoc_resp
.variable
);
3622 /* Extended supported rates */
3623 p
= hostapd_eid_ext_supp_rates(hapd
, p
);
3626 if (status_code
== WLAN_STATUS_DENIED_POOR_CHANNEL_CONDITIONS
&&
3628 int delta
= hapd
->iconf
->rssi_reject_assoc_rssi
- rssi
;
3630 p
= hostapd_eid_mbo_rssi_assoc_rej(hapd
, p
, buf
+ buflen
- p
,
3633 #endif /* CONFIG_MBO */
3635 #ifdef CONFIG_IEEE80211R_AP
3636 if (sta
&& status_code
== WLAN_STATUS_SUCCESS
) {
3637 /* IEEE 802.11r: Mobility Domain Information, Fast BSS
3638 * Transition Information, RSN, [RIC Response] */
3639 p
= wpa_sm_write_assoc_resp_ies(sta
->wpa_sm
, p
,
3641 sta
->auth_alg
, ies
, ies_len
);
3643 wpa_printf(MSG_DEBUG
,
3644 "FT: Failed to write AssocResp IEs");
3645 res
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
3649 #endif /* CONFIG_IEEE80211R_AP */
3651 if (sta
&& status_code
== WLAN_STATUS_SUCCESS
&&
3652 (sta
->auth_alg
== WLAN_AUTH_FILS_SK
||
3653 sta
->auth_alg
== WLAN_AUTH_FILS_SK_PFS
||
3654 sta
->auth_alg
== WLAN_AUTH_FILS_PK
))
3655 p
= wpa_auth_write_assoc_resp_fils(sta
->wpa_sm
, p
,
3658 #endif /* CONFIG_FILS */
3661 if (sta
&& status_code
== WLAN_STATUS_SUCCESS
&&
3662 (hapd
->conf
->wpa_key_mgmt
& WPA_KEY_MGMT_OWE
))
3663 p
= wpa_auth_write_assoc_resp_owe(sta
->wpa_sm
, p
,
3666 #endif /* CONFIG_OWE */
3668 if (sta
&& status_code
== WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY
)
3669 p
= hostapd_eid_assoc_comeback_time(hapd
, sta
, p
);
3671 #ifdef CONFIG_IEEE80211N
3672 p
= hostapd_eid_ht_capabilities(hapd
, p
);
3673 p
= hostapd_eid_ht_operation(hapd
, p
);
3674 #endif /* CONFIG_IEEE80211N */
3676 #ifdef CONFIG_IEEE80211AC
3677 if (hapd
->iconf
->ieee80211ac
&& !hapd
->conf
->disable_11ac
&&
3678 !is_6ghz_op_class(hapd
->iconf
->op_class
)) {
3679 u32 nsts
= 0, sta_nsts
;
3681 if (sta
&& hapd
->conf
->use_sta_nsts
&& sta
->vht_capabilities
) {
3682 struct ieee80211_vht_capabilities
*capa
;
3684 nsts
= (hapd
->iface
->conf
->vht_capab
>>
3685 VHT_CAP_BEAMFORMEE_STS_OFFSET
) & 7;
3686 capa
= sta
->vht_capabilities
;
3687 sta_nsts
= (le_to_host32(capa
->vht_capabilities_info
) >>
3688 VHT_CAP_BEAMFORMEE_STS_OFFSET
) & 7;
3690 if (nsts
< sta_nsts
)
3695 p
= hostapd_eid_vht_capabilities(hapd
, p
, nsts
);
3696 p
= hostapd_eid_vht_operation(hapd
, p
);
3698 #endif /* CONFIG_IEEE80211AC */
3700 #ifdef CONFIG_IEEE80211AX
3701 if (hapd
->iconf
->ieee80211ax
) {
3702 p
= hostapd_eid_he_capab(hapd
, p
, IEEE80211_MODE_AP
);
3703 p
= hostapd_eid_he_operation(hapd
, p
);
3704 p
= hostapd_eid_spatial_reuse(hapd
, p
);
3705 p
= hostapd_eid_he_mu_edca_parameter_set(hapd
, p
);
3707 #endif /* CONFIG_IEEE80211AX */
3709 p
= hostapd_eid_ext_capab(hapd
, p
);
3710 p
= hostapd_eid_bss_max_idle_period(hapd
, p
);
3711 if (sta
&& sta
->qos_map_enabled
)
3712 p
= hostapd_eid_qos_map_set(hapd
, p
);
3715 if (hapd
->iface
->fst_ies
) {
3716 os_memcpy(p
, wpabuf_head(hapd
->iface
->fst_ies
),
3717 wpabuf_len(hapd
->iface
->fst_ies
));
3718 p
+= wpabuf_len(hapd
->iface
->fst_ies
);
3720 #endif /* CONFIG_FST */
3722 p
= hostapd_eid_rsnxe(hapd
, p
, buf
+ buflen
- p
);
3725 if ((hapd
->conf
->wpa_key_mgmt
& WPA_KEY_MGMT_OWE
) &&
3726 sta
&& sta
->owe_ecdh
&& status_code
== WLAN_STATUS_SUCCESS
&&
3727 wpa_auth_sta_key_mgmt(sta
->wpa_sm
) == WPA_KEY_MGMT_OWE
) {
3730 pub
= crypto_ecdh_get_pubkey(sta
->owe_ecdh
, 0);
3732 res
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
3735 /* OWE Diffie-Hellman Parameter element */
3736 *p
++ = WLAN_EID_EXTENSION
; /* Element ID */
3737 *p
++ = 1 + 2 + wpabuf_len(pub
); /* Length */
3738 *p
++ = WLAN_EID_EXT_OWE_DH_PARAM
; /* Element ID Extension */
3739 WPA_PUT_LE16(p
, sta
->owe_group
);
3741 os_memcpy(p
, wpabuf_head(pub
), wpabuf_len(pub
));
3742 p
+= wpabuf_len(pub
);
3745 #endif /* CONFIG_OWE */
3748 if ((hapd
->conf
->wpa_key_mgmt
& WPA_KEY_MGMT_DPP
) &&
3749 sta
&& sta
->dpp_pfs
&& status_code
== WLAN_STATUS_SUCCESS
&&
3750 wpa_auth_sta_key_mgmt(sta
->wpa_sm
) == WPA_KEY_MGMT_DPP
) {
3751 os_memcpy(p
, wpabuf_head(sta
->dpp_pfs
->ie
),
3752 wpabuf_len(sta
->dpp_pfs
->ie
));
3753 p
+= wpabuf_len(sta
->dpp_pfs
->ie
);
3755 #endif /* CONFIG_DPP2 */
3757 #ifdef CONFIG_IEEE80211AC
3758 if (sta
&& hapd
->conf
->vendor_vht
&& (sta
->flags
& WLAN_STA_VENDOR_VHT
))
3759 p
= hostapd_eid_vendor_vht(hapd
, p
);
3760 #endif /* CONFIG_IEEE80211AC */
3762 if (sta
&& (sta
->flags
& WLAN_STA_WMM
))
3763 p
= hostapd_eid_wmm(hapd
, p
);
3767 ((sta
->flags
& WLAN_STA_WPS
) ||
3768 ((sta
->flags
& WLAN_STA_MAYBE_WPS
) && hapd
->conf
->wpa
))) {
3769 struct wpabuf
*wps
= wps_build_assoc_resp_ie();
3771 os_memcpy(p
, wpabuf_head(wps
), wpabuf_len(wps
));
3772 p
+= wpabuf_len(wps
);
3776 #endif /* CONFIG_WPS */
3778 if (sta
&& (sta
->flags
& WLAN_STA_MULTI_AP
))
3779 p
= hostapd_eid_multi_ap(hapd
, p
);
3782 if (sta
&& sta
->p2p_ie
&& hapd
->p2p_group
) {
3783 struct wpabuf
*p2p_resp_ie
;
3784 enum p2p_status_code status
;
3785 switch (status_code
) {
3786 case WLAN_STATUS_SUCCESS
:
3787 status
= P2P_SC_SUCCESS
;
3789 case WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
:
3790 status
= P2P_SC_FAIL_LIMIT_REACHED
;
3793 status
= P2P_SC_FAIL_INVALID_PARAMS
;
3796 p2p_resp_ie
= p2p_group_assoc_resp_ie(hapd
->p2p_group
, status
);
3798 os_memcpy(p
, wpabuf_head(p2p_resp_ie
),
3799 wpabuf_len(p2p_resp_ie
));
3800 p
+= wpabuf_len(p2p_resp_ie
);
3801 wpabuf_free(p2p_resp_ie
);
3804 #endif /* CONFIG_P2P */
3806 #ifdef CONFIG_P2P_MANAGER
3807 if (hapd
->conf
->p2p
& P2P_MANAGE
)
3808 p
= hostapd_eid_p2p_manage(hapd
, p
);
3809 #endif /* CONFIG_P2P_MANAGER */
3811 p
= hostapd_eid_mbo(hapd
, p
, buf
+ buflen
- p
);
3813 if (hapd
->conf
->assocresp_elements
&&
3814 (size_t) (buf
+ buflen
- p
) >=
3815 wpabuf_len(hapd
->conf
->assocresp_elements
)) {
3816 os_memcpy(p
, wpabuf_head(hapd
->conf
->assocresp_elements
),
3817 wpabuf_len(hapd
->conf
->assocresp_elements
));
3818 p
+= wpabuf_len(hapd
->conf
->assocresp_elements
);
3821 send_len
+= p
- reply
->u
.assoc_resp
.variable
;
3825 (sta
->auth_alg
== WLAN_AUTH_FILS_SK
||
3826 sta
->auth_alg
== WLAN_AUTH_FILS_SK_PFS
||
3827 sta
->auth_alg
== WLAN_AUTH_FILS_PK
) &&
3828 status_code
== WLAN_STATUS_SUCCESS
) {
3829 struct ieee802_11_elems elems
;
3831 if (ieee802_11_parse_elems(ies
, ies_len
, &elems
, 0) ==
3832 ParseFailed
|| !elems
.fils_session
) {
3833 res
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
3838 *p
++ = WLAN_EID_EXTENSION
; /* Element ID */
3839 *p
++ = 1 + FILS_SESSION_LEN
; /* Length */
3840 *p
++ = WLAN_EID_EXT_FILS_SESSION
; /* Element ID Extension */
3841 os_memcpy(p
, elems
.fils_session
, FILS_SESSION_LEN
);
3842 send_len
+= 2 + 1 + FILS_SESSION_LEN
;
3844 send_len
= fils_encrypt_assoc(sta
->wpa_sm
, buf
, send_len
,
3845 buflen
, sta
->fils_hlp_resp
);
3847 res
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
3851 #endif /* CONFIG_FILS */
3853 if (hostapd_drv_send_mlme(hapd
, reply
, send_len
, 0) < 0) {
3854 wpa_printf(MSG_INFO
, "Failed to send assoc resp: %s",
3856 res
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
3866 u8
* owe_assoc_req_process(struct hostapd_data
*hapd
, struct sta_info
*sta
,
3867 const u8
*owe_dh
, u8 owe_dh_len
,
3868 u8
*owe_buf
, size_t owe_buf_len
, u16
*reason
)
3870 #ifdef CONFIG_TESTING_OPTIONS
3871 if (hapd
->conf
->own_ie_override
) {
3872 wpa_printf(MSG_DEBUG
, "OWE: Using IE override");
3873 *reason
= WLAN_STATUS_SUCCESS
;
3874 return wpa_auth_write_assoc_resp_owe(sta
->wpa_sm
, owe_buf
,
3875 owe_buf_len
, NULL
, 0);
3877 #endif /* CONFIG_TESTING_OPTIONS */
3879 if (wpa_auth_sta_get_pmksa(sta
->wpa_sm
)) {
3880 wpa_printf(MSG_DEBUG
, "OWE: Using PMKSA caching");
3881 owe_buf
= wpa_auth_write_assoc_resp_owe(sta
->wpa_sm
, owe_buf
,
3882 owe_buf_len
, NULL
, 0);
3883 *reason
= WLAN_STATUS_SUCCESS
;
3887 if (sta
->owe_pmk
&& sta
->external_dh_updated
) {
3888 wpa_printf(MSG_DEBUG
, "OWE: Using previously derived PMK");
3889 *reason
= WLAN_STATUS_SUCCESS
;
3893 *reason
= owe_process_assoc_req(hapd
, sta
, owe_dh
, owe_dh_len
);
3894 if (*reason
!= WLAN_STATUS_SUCCESS
)
3897 owe_buf
= wpa_auth_write_assoc_resp_owe(sta
->wpa_sm
, owe_buf
,
3898 owe_buf_len
, NULL
, 0);
3900 if (sta
->owe_ecdh
&& owe_buf
) {
3903 pub
= crypto_ecdh_get_pubkey(sta
->owe_ecdh
, 0);
3905 *reason
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
3909 /* OWE Diffie-Hellman Parameter element */
3910 *owe_buf
++ = WLAN_EID_EXTENSION
; /* Element ID */
3911 *owe_buf
++ = 1 + 2 + wpabuf_len(pub
); /* Length */
3912 *owe_buf
++ = WLAN_EID_EXT_OWE_DH_PARAM
; /* Element ID Extension
3914 WPA_PUT_LE16(owe_buf
, sta
->owe_group
);
3916 os_memcpy(owe_buf
, wpabuf_head(pub
), wpabuf_len(pub
));
3917 owe_buf
+= wpabuf_len(pub
);
3923 #endif /* CONFIG_OWE */
3928 void fils_hlp_finish_assoc(struct hostapd_data
*hapd
, struct sta_info
*sta
)
3932 wpa_printf(MSG_DEBUG
, "FILS: Finish association with " MACSTR
,
3933 MAC2STR(sta
->addr
));
3934 eloop_cancel_timeout(fils_hlp_timeout
, hapd
, sta
);
3935 if (!sta
->fils_pending_assoc_req
)
3937 reply_res
= send_assoc_resp(hapd
, sta
, sta
->addr
, WLAN_STATUS_SUCCESS
,
3938 sta
->fils_pending_assoc_is_reassoc
,
3939 sta
->fils_pending_assoc_req
,
3940 sta
->fils_pending_assoc_req_len
, 0);
3941 os_free(sta
->fils_pending_assoc_req
);
3942 sta
->fils_pending_assoc_req
= NULL
;
3943 sta
->fils_pending_assoc_req_len
= 0;
3944 wpabuf_free(sta
->fils_hlp_resp
);
3945 sta
->fils_hlp_resp
= NULL
;
3946 wpabuf_free(sta
->hlp_dhcp_discover
);
3947 sta
->hlp_dhcp_discover
= NULL
;
3950 * Remove the station in case transmission of a success response fails.
3951 * At this point the station was already added associated to the driver.
3953 if (reply_res
!= WLAN_STATUS_SUCCESS
)
3954 hostapd_drv_sta_remove(hapd
, sta
->addr
);
3958 void fils_hlp_timeout(void *eloop_ctx
, void *eloop_data
)
3960 struct hostapd_data
*hapd
= eloop_ctx
;
3961 struct sta_info
*sta
= eloop_data
;
3963 wpa_printf(MSG_DEBUG
,
3964 "FILS: HLP response timeout - continue with association response for "
3965 MACSTR
, MAC2STR(sta
->addr
));
3966 if (sta
->fils_drv_assoc_finish
)
3967 hostapd_notify_assoc_fils_finish(hapd
, sta
);
3969 fils_hlp_finish_assoc(hapd
, sta
);
3972 #endif /* CONFIG_FILS */
3975 static void handle_assoc(struct hostapd_data
*hapd
,
3976 const struct ieee80211_mgmt
*mgmt
, size_t len
,
3977 int reassoc
, int rssi
)
3979 u16 capab_info
, listen_interval
, seq_ctrl
, fc
;
3980 u16 resp
= WLAN_STATUS_SUCCESS
, reply_res
;
3983 struct sta_info
*sta
;
3986 int delay_assoc
= 0;
3987 #endif /* CONFIG_FILS */
3989 if (len
< IEEE80211_HDRLEN
+ (reassoc
? sizeof(mgmt
->u
.reassoc_req
) :
3990 sizeof(mgmt
->u
.assoc_req
))) {
3991 wpa_printf(MSG_INFO
, "handle_assoc(reassoc=%d) - too short payload (len=%lu)",
3992 reassoc
, (unsigned long) len
);
3996 #ifdef CONFIG_TESTING_OPTIONS
3998 if (hapd
->iconf
->ignore_reassoc_probability
> 0.0 &&
3999 drand48() < hapd
->iconf
->ignore_reassoc_probability
) {
4000 wpa_printf(MSG_INFO
,
4001 "TESTING: ignoring reassoc request from "
4002 MACSTR
, MAC2STR(mgmt
->sa
));
4006 if (hapd
->iconf
->ignore_assoc_probability
> 0.0 &&
4007 drand48() < hapd
->iconf
->ignore_assoc_probability
) {
4008 wpa_printf(MSG_INFO
,
4009 "TESTING: ignoring assoc request from "
4010 MACSTR
, MAC2STR(mgmt
->sa
));
4014 #endif /* CONFIG_TESTING_OPTIONS */
4016 fc
= le_to_host16(mgmt
->frame_control
);
4017 seq_ctrl
= le_to_host16(mgmt
->seq_ctrl
);
4020 capab_info
= le_to_host16(mgmt
->u
.reassoc_req
.capab_info
);
4021 listen_interval
= le_to_host16(
4022 mgmt
->u
.reassoc_req
.listen_interval
);
4023 wpa_printf(MSG_DEBUG
, "reassociation request: STA=" MACSTR
4024 " capab_info=0x%02x listen_interval=%d current_ap="
4025 MACSTR
" seq_ctrl=0x%x%s",
4026 MAC2STR(mgmt
->sa
), capab_info
, listen_interval
,
4027 MAC2STR(mgmt
->u
.reassoc_req
.current_ap
),
4028 seq_ctrl
, (fc
& WLAN_FC_RETRY
) ? " retry" : "");
4029 left
= len
- (IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.reassoc_req
));
4030 pos
= mgmt
->u
.reassoc_req
.variable
;
4032 capab_info
= le_to_host16(mgmt
->u
.assoc_req
.capab_info
);
4033 listen_interval
= le_to_host16(
4034 mgmt
->u
.assoc_req
.listen_interval
);
4035 wpa_printf(MSG_DEBUG
, "association request: STA=" MACSTR
4036 " capab_info=0x%02x listen_interval=%d "
4038 MAC2STR(mgmt
->sa
), capab_info
, listen_interval
,
4039 seq_ctrl
, (fc
& WLAN_FC_RETRY
) ? " retry" : "");
4040 left
= len
- (IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.assoc_req
));
4041 pos
= mgmt
->u
.assoc_req
.variable
;
4044 sta
= ap_get_sta(hapd
, mgmt
->sa
);
4045 #ifdef CONFIG_IEEE80211R_AP
4046 if (sta
&& sta
->auth_alg
== WLAN_AUTH_FT
&&
4047 (sta
->flags
& WLAN_STA_AUTH
) == 0) {
4048 wpa_printf(MSG_DEBUG
, "FT: Allow STA " MACSTR
" to associate "
4049 "prior to authentication since it is using "
4050 "over-the-DS FT", MAC2STR(mgmt
->sa
));
4053 * Mark station as authenticated, to avoid adding station
4054 * entry in the driver as associated and not authenticated
4056 sta
->flags
|= WLAN_STA_AUTH
;
4058 #endif /* CONFIG_IEEE80211R_AP */
4059 if (sta
== NULL
|| (sta
->flags
& WLAN_STA_AUTH
) == 0) {
4060 if (hapd
->iface
->current_mode
&&
4061 hapd
->iface
->current_mode
->mode
==
4062 HOSTAPD_MODE_IEEE80211AD
) {
4064 struct radius_sta info
;
4066 acl_res
= ieee802_11_allowed_address(hapd
, mgmt
->sa
,
4069 if (acl_res
== HOSTAPD_ACL_REJECT
) {
4070 wpa_msg(hapd
->msg_ctx
, MSG_DEBUG
,
4071 "Ignore Association Request frame from "
4072 MACSTR
" due to ACL reject",
4074 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
4077 if (acl_res
== HOSTAPD_ACL_PENDING
)
4080 /* DMG/IEEE 802.11ad does not use authentication.
4081 * Allocate sta entry upon association. */
4082 sta
= ap_sta_add(hapd
, mgmt
->sa
);
4084 hostapd_logger(hapd
, mgmt
->sa
,
4085 HOSTAPD_MODULE_IEEE80211
,
4087 "Failed to add STA");
4088 resp
= WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
;
4092 acl_res
= ieee802_11_set_radius_info(
4093 hapd
, sta
, acl_res
, &info
);
4095 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
4099 hostapd_logger(hapd
, sta
->addr
,
4100 HOSTAPD_MODULE_IEEE80211
,
4101 HOSTAPD_LEVEL_DEBUG
,
4102 "Skip authentication for DMG/IEEE 802.11ad");
4103 sta
->flags
|= WLAN_STA_AUTH
;
4104 wpa_auth_sm_event(sta
->wpa_sm
, WPA_AUTH
);
4105 sta
->auth_alg
= WLAN_AUTH_OPEN
;
4107 hostapd_logger(hapd
, mgmt
->sa
,
4108 HOSTAPD_MODULE_IEEE80211
,
4110 "Station tried to associate before authentication (aid=%d flags=0x%x)",
4111 sta
? sta
->aid
: -1,
4112 sta
? sta
->flags
: 0);
4113 send_deauth(hapd
, mgmt
->sa
,
4114 WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA
);
4119 if ((fc
& WLAN_FC_RETRY
) &&
4120 sta
->last_seq_ctrl
!= WLAN_INVALID_MGMT_SEQ
&&
4121 sta
->last_seq_ctrl
== seq_ctrl
&&
4122 sta
->last_subtype
== (reassoc
? WLAN_FC_STYPE_REASSOC_REQ
:
4123 WLAN_FC_STYPE_ASSOC_REQ
)) {
4124 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
4125 HOSTAPD_LEVEL_DEBUG
,
4126 "Drop repeated association frame seq_ctrl=0x%x",
4130 sta
->last_seq_ctrl
= seq_ctrl
;
4131 sta
->last_subtype
= reassoc
? WLAN_FC_STYPE_REASSOC_REQ
:
4132 WLAN_FC_STYPE_ASSOC_REQ
;
4134 if (hapd
->tkip_countermeasures
) {
4135 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
4139 if (listen_interval
> hapd
->conf
->max_listen_interval
) {
4140 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
4141 HOSTAPD_LEVEL_DEBUG
,
4142 "Too large Listen Interval (%d)",
4144 resp
= WLAN_STATUS_ASSOC_DENIED_LISTEN_INT_TOO_LARGE
;
4149 if (hapd
->conf
->mbo_enabled
&& hapd
->mbo_assoc_disallow
) {
4150 resp
= WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
;
4154 if (hapd
->iconf
->rssi_reject_assoc_rssi
&& rssi
&&
4155 rssi
< hapd
->iconf
->rssi_reject_assoc_rssi
&&
4156 (sta
->auth_rssi
== 0 ||
4157 sta
->auth_rssi
< hapd
->iconf
->rssi_reject_assoc_rssi
)) {
4158 resp
= WLAN_STATUS_DENIED_POOR_CHANNEL_CONDITIONS
;
4161 #endif /* CONFIG_MBO */
4164 * sta->capability is used in check_assoc_ies() for RRM enabled
4165 * capability element.
4167 sta
->capability
= capab_info
;
4170 if (sta
->auth_alg
== WLAN_AUTH_FILS_SK
||
4171 sta
->auth_alg
== WLAN_AUTH_FILS_SK_PFS
||
4172 sta
->auth_alg
== WLAN_AUTH_FILS_PK
) {
4175 /* The end of the payload is encrypted. Need to decrypt it
4176 * before parsing. */
4178 tmp
= os_memdup(pos
, left
);
4180 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
4184 res
= fils_decrypt_assoc(sta
->wpa_sm
, sta
->fils_session
, mgmt
,
4187 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
4193 #endif /* CONFIG_FILS */
4195 /* followed by SSID and Supported rates; and HT capabilities if 802.11n
4197 resp
= check_assoc_ies(hapd
, sta
, pos
, left
, reassoc
);
4198 if (resp
!= WLAN_STATUS_SUCCESS
)
4201 if (hostapd_get_aid(hapd
, sta
) < 0) {
4202 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
4203 HOSTAPD_LEVEL_INFO
, "No room for more AIDs");
4204 resp
= WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
;
4208 sta
->listen_interval
= listen_interval
;
4210 if (hapd
->iface
->current_mode
&&
4211 hapd
->iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211G
)
4212 sta
->flags
|= WLAN_STA_NONERP
;
4213 for (i
= 0; i
< sta
->supported_rates_len
; i
++) {
4214 if ((sta
->supported_rates
[i
] & 0x7f) > 22) {
4215 sta
->flags
&= ~WLAN_STA_NONERP
;
4219 if (sta
->flags
& WLAN_STA_NONERP
&& !sta
->nonerp_set
) {
4220 sta
->nonerp_set
= 1;
4221 hapd
->iface
->num_sta_non_erp
++;
4222 if (hapd
->iface
->num_sta_non_erp
== 1)
4223 ieee802_11_set_beacons(hapd
->iface
);
4226 if (!(sta
->capability
& WLAN_CAPABILITY_SHORT_SLOT_TIME
) &&
4227 !sta
->no_short_slot_time_set
) {
4228 sta
->no_short_slot_time_set
= 1;
4229 hapd
->iface
->num_sta_no_short_slot_time
++;
4230 if (hapd
->iface
->current_mode
&&
4231 hapd
->iface
->current_mode
->mode
==
4232 HOSTAPD_MODE_IEEE80211G
&&
4233 hapd
->iface
->num_sta_no_short_slot_time
== 1)
4234 ieee802_11_set_beacons(hapd
->iface
);
4237 if (sta
->capability
& WLAN_CAPABILITY_SHORT_PREAMBLE
)
4238 sta
->flags
|= WLAN_STA_SHORT_PREAMBLE
;
4240 sta
->flags
&= ~WLAN_STA_SHORT_PREAMBLE
;
4242 if (!(sta
->capability
& WLAN_CAPABILITY_SHORT_PREAMBLE
) &&
4243 !sta
->no_short_preamble_set
) {
4244 sta
->no_short_preamble_set
= 1;
4245 hapd
->iface
->num_sta_no_short_preamble
++;
4246 if (hapd
->iface
->current_mode
&&
4247 hapd
->iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211G
4248 && hapd
->iface
->num_sta_no_short_preamble
== 1)
4249 ieee802_11_set_beacons(hapd
->iface
);
4252 #ifdef CONFIG_IEEE80211N
4253 update_ht_state(hapd
, sta
);
4254 #endif /* CONFIG_IEEE80211N */
4256 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
4257 HOSTAPD_LEVEL_DEBUG
,
4258 "association OK (aid %d)", sta
->aid
);
4259 /* Station will be marked associated, after it acknowledges AssocResp
4261 sta
->flags
|= WLAN_STA_ASSOC_REQ_OK
;
4263 if ((sta
->flags
& WLAN_STA_MFP
) && sta
->sa_query_timed_out
) {
4264 wpa_printf(MSG_DEBUG
, "Allowing %sassociation after timed out "
4265 "SA Query procedure", reassoc
? "re" : "");
4266 /* TODO: Send a protected Disassociate frame to the STA using
4267 * the old key and Reason Code "Previous Authentication no
4268 * longer valid". Make sure this is only sent protected since
4269 * unprotected frame would be received by the STA that is now
4270 * trying to associate.
4274 /* Make sure that the previously registered inactivity timer will not
4275 * remove the STA immediately. */
4276 sta
->timeout_next
= STA_NULLFUNC
;
4278 #ifdef CONFIG_TAXONOMY
4279 taxonomy_sta_info_assoc_req(hapd
, sta
, pos
, left
);
4280 #endif /* CONFIG_TAXONOMY */
4282 sta
->pending_wds_enable
= 0;
4285 if (sta
->auth_alg
== WLAN_AUTH_FILS_SK
||
4286 sta
->auth_alg
== WLAN_AUTH_FILS_SK_PFS
||
4287 sta
->auth_alg
== WLAN_AUTH_FILS_PK
) {
4288 if (fils_process_hlp(hapd
, sta
, pos
, left
) > 0)
4291 #endif /* CONFIG_FILS */
4296 * In case of a successful response, add the station to the driver.
4297 * Otherwise, the kernel may ignore Data frames before we process the
4298 * ACK frame (TX status). In case of a failure, this station will be
4301 * Note that this is not compliant with the IEEE 802.11 standard that
4302 * states that a non-AP station should transition into the
4303 * authenticated/associated state only after the station acknowledges
4304 * the (Re)Association Response frame. However, still do this as:
4306 * 1. In case the station does not acknowledge the (Re)Association
4307 * Response frame, it will be removed.
4308 * 2. Data frames will be dropped in the kernel until the station is
4309 * set into authorized state, and there are no significant known
4310 * issues with processing other non-Data Class 3 frames during this
4313 if (resp
== WLAN_STATUS_SUCCESS
&& sta
&&
4314 add_associated_sta(hapd
, sta
, reassoc
))
4315 resp
= WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
;
4318 if (sta
&& delay_assoc
&& resp
== WLAN_STATUS_SUCCESS
&&
4319 eloop_is_timeout_registered(fils_hlp_timeout
, hapd
, sta
) &&
4320 sta
->fils_pending_assoc_req
) {
4321 /* Do not reschedule fils_hlp_timeout in case the station
4322 * retransmits (Re)Association Request frame while waiting for
4323 * the previously started FILS HLP wait, so that the timeout can
4324 * be determined from the first pending attempt. */
4325 wpa_printf(MSG_DEBUG
,
4326 "FILS: Continue waiting for HLP processing before sending (Re)Association Response frame to "
4327 MACSTR
, MAC2STR(sta
->addr
));
4332 eloop_cancel_timeout(fils_hlp_timeout
, hapd
, sta
);
4333 os_free(sta
->fils_pending_assoc_req
);
4334 sta
->fils_pending_assoc_req
= NULL
;
4335 sta
->fils_pending_assoc_req_len
= 0;
4336 wpabuf_free(sta
->fils_hlp_resp
);
4337 sta
->fils_hlp_resp
= NULL
;
4339 if (sta
&& delay_assoc
&& resp
== WLAN_STATUS_SUCCESS
) {
4340 sta
->fils_pending_assoc_req
= tmp
;
4341 sta
->fils_pending_assoc_req_len
= left
;
4342 sta
->fils_pending_assoc_is_reassoc
= reassoc
;
4343 sta
->fils_drv_assoc_finish
= 0;
4344 wpa_printf(MSG_DEBUG
,
4345 "FILS: Waiting for HLP processing before sending (Re)Association Response frame to "
4346 MACSTR
, MAC2STR(sta
->addr
));
4347 eloop_cancel_timeout(fils_hlp_timeout
, hapd
, sta
);
4348 eloop_register_timeout(0, hapd
->conf
->fils_hlp_wait_time
* 1024,
4349 fils_hlp_timeout
, hapd
, sta
);
4352 #endif /* CONFIG_FILS */
4354 reply_res
= send_assoc_resp(hapd
, sta
, mgmt
->sa
, resp
, reassoc
, pos
,
4359 * Remove the station in case tranmission of a success response fails
4360 * (the STA was added associated to the driver) or if the station was
4361 * previously added unassociated.
4363 if (sta
&& ((reply_res
!= WLAN_STATUS_SUCCESS
&&
4364 resp
== WLAN_STATUS_SUCCESS
) || sta
->added_unassoc
)) {
4365 hostapd_drv_sta_remove(hapd
, sta
->addr
);
4366 sta
->added_unassoc
= 0;
4371 static void handle_disassoc(struct hostapd_data
*hapd
,
4372 const struct ieee80211_mgmt
*mgmt
, size_t len
)
4374 struct sta_info
*sta
;
4376 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.disassoc
)) {
4377 wpa_printf(MSG_INFO
, "handle_disassoc - too short payload (len=%lu)",
4378 (unsigned long) len
);
4382 wpa_printf(MSG_DEBUG
, "disassocation: STA=" MACSTR
" reason_code=%d",
4384 le_to_host16(mgmt
->u
.disassoc
.reason_code
));
4386 sta
= ap_get_sta(hapd
, mgmt
->sa
);
4388 wpa_printf(MSG_INFO
, "Station " MACSTR
" trying to disassociate, but it is not associated",
4393 ap_sta_set_authorized(hapd
, sta
, 0);
4394 sta
->last_seq_ctrl
= WLAN_INVALID_MGMT_SEQ
;
4395 sta
->flags
&= ~(WLAN_STA_ASSOC
| WLAN_STA_ASSOC_REQ_OK
);
4396 wpa_auth_sm_event(sta
->wpa_sm
, WPA_DISASSOC
);
4397 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
4398 HOSTAPD_LEVEL_INFO
, "disassociated");
4399 sta
->acct_terminate_cause
= RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST
;
4400 ieee802_1x_notify_port_enabled(sta
->eapol_sm
, 0);
4401 /* Stop Accounting and IEEE 802.1X sessions, but leave the STA
4403 accounting_sta_stop(hapd
, sta
);
4404 ieee802_1x_free_station(hapd
, sta
);
4406 hostapd_drv_br_delete_ip_neigh(hapd
, 4, (u8
*) &sta
->ipaddr
);
4407 ap_sta_ip6addr_del(hapd
, sta
);
4408 hostapd_drv_sta_remove(hapd
, sta
->addr
);
4409 sta
->added_unassoc
= 0;
4411 if (sta
->timeout_next
== STA_NULLFUNC
||
4412 sta
->timeout_next
== STA_DISASSOC
) {
4413 sta
->timeout_next
= STA_DEAUTH
;
4414 eloop_cancel_timeout(ap_handle_timer
, hapd
, sta
);
4415 eloop_register_timeout(AP_DEAUTH_DELAY
, 0, ap_handle_timer
,
4419 mlme_disassociate_indication(
4420 hapd
, sta
, le_to_host16(mgmt
->u
.disassoc
.reason_code
));
4422 /* DMG/IEEE 802.11ad does not use deauthication. Deallocate sta upon
4423 * disassociation. */
4424 if (hapd
->iface
->current_mode
&&
4425 hapd
->iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211AD
) {
4426 sta
->flags
&= ~WLAN_STA_AUTH
;
4427 wpa_auth_sm_event(sta
->wpa_sm
, WPA_DEAUTH
);
4428 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
4429 HOSTAPD_LEVEL_DEBUG
, "deauthenticated");
4430 ap_free_sta(hapd
, sta
);
4435 static void handle_deauth(struct hostapd_data
*hapd
,
4436 const struct ieee80211_mgmt
*mgmt
, size_t len
)
4438 struct sta_info
*sta
;
4440 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.deauth
)) {
4441 wpa_msg(hapd
->msg_ctx
, MSG_DEBUG
, "handle_deauth - too short "
4442 "payload (len=%lu)", (unsigned long) len
);
4446 wpa_msg(hapd
->msg_ctx
, MSG_DEBUG
, "deauthentication: STA=" MACSTR
4448 MAC2STR(mgmt
->sa
), le_to_host16(mgmt
->u
.deauth
.reason_code
));
4450 sta
= ap_get_sta(hapd
, mgmt
->sa
);
4452 wpa_msg(hapd
->msg_ctx
, MSG_DEBUG
, "Station " MACSTR
" trying "
4453 "to deauthenticate, but it is not authenticated",
4458 ap_sta_set_authorized(hapd
, sta
, 0);
4459 sta
->last_seq_ctrl
= WLAN_INVALID_MGMT_SEQ
;
4460 sta
->flags
&= ~(WLAN_STA_AUTH
| WLAN_STA_ASSOC
|
4461 WLAN_STA_ASSOC_REQ_OK
);
4462 wpa_auth_sm_event(sta
->wpa_sm
, WPA_DEAUTH
);
4463 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
4464 HOSTAPD_LEVEL_DEBUG
, "deauthenticated");
4465 mlme_deauthenticate_indication(
4466 hapd
, sta
, le_to_host16(mgmt
->u
.deauth
.reason_code
));
4467 sta
->acct_terminate_cause
= RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST
;
4468 ieee802_1x_notify_port_enabled(sta
->eapol_sm
, 0);
4469 ap_free_sta(hapd
, sta
);
4473 static void handle_beacon(struct hostapd_data
*hapd
,
4474 const struct ieee80211_mgmt
*mgmt
, size_t len
,
4475 struct hostapd_frame_info
*fi
)
4477 struct ieee802_11_elems elems
;
4479 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.beacon
)) {
4480 wpa_printf(MSG_INFO
, "handle_beacon - too short payload (len=%lu)",
4481 (unsigned long) len
);
4485 (void) ieee802_11_parse_elems(mgmt
->u
.beacon
.variable
,
4486 len
- (IEEE80211_HDRLEN
+
4487 sizeof(mgmt
->u
.beacon
)), &elems
,
4490 ap_list_process_beacon(hapd
->iface
, mgmt
, &elems
, fi
);
4494 static int robust_action_frame(u8 category
)
4496 return category
!= WLAN_ACTION_PUBLIC
&&
4497 category
!= WLAN_ACTION_HT
;
4501 static int handle_action(struct hostapd_data
*hapd
,
4502 const struct ieee80211_mgmt
*mgmt
, size_t len
,
4505 struct sta_info
*sta
;
4506 u8
*action __maybe_unused
;
4508 if (len
< IEEE80211_HDRLEN
+ 2 + 1) {
4509 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
4510 HOSTAPD_LEVEL_DEBUG
,
4511 "handle_action - too short payload (len=%lu)",
4512 (unsigned long) len
);
4516 action
= (u8
*) &mgmt
->u
.action
.u
;
4517 wpa_printf(MSG_DEBUG
, "RX_ACTION category %u action %u sa " MACSTR
4518 " da " MACSTR
" len %d freq %u",
4519 mgmt
->u
.action
.category
, *action
,
4520 MAC2STR(mgmt
->sa
), MAC2STR(mgmt
->da
), (int) len
, freq
);
4522 sta
= ap_get_sta(hapd
, mgmt
->sa
);
4524 if (mgmt
->u
.action
.category
!= WLAN_ACTION_PUBLIC
&&
4525 (sta
== NULL
|| !(sta
->flags
& WLAN_STA_ASSOC
))) {
4526 wpa_printf(MSG_DEBUG
, "IEEE 802.11: Ignored Action "
4527 "frame (category=%u) from unassociated STA " MACSTR
,
4528 mgmt
->u
.action
.category
, MAC2STR(mgmt
->sa
));
4532 if (sta
&& (sta
->flags
& WLAN_STA_MFP
) &&
4533 !(mgmt
->frame_control
& host_to_le16(WLAN_FC_ISWEP
)) &&
4534 robust_action_frame(mgmt
->u
.action
.category
)) {
4535 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
4536 HOSTAPD_LEVEL_DEBUG
,
4537 "Dropped unprotected Robust Action frame from "
4543 u16 fc
= le_to_host16(mgmt
->frame_control
);
4544 u16 seq_ctrl
= le_to_host16(mgmt
->seq_ctrl
);
4546 if ((fc
& WLAN_FC_RETRY
) &&
4547 sta
->last_seq_ctrl
!= WLAN_INVALID_MGMT_SEQ
&&
4548 sta
->last_seq_ctrl
== seq_ctrl
&&
4549 sta
->last_subtype
== WLAN_FC_STYPE_ACTION
) {
4550 hostapd_logger(hapd
, sta
->addr
,
4551 HOSTAPD_MODULE_IEEE80211
,
4552 HOSTAPD_LEVEL_DEBUG
,
4553 "Drop repeated action frame seq_ctrl=0x%x",
4558 sta
->last_seq_ctrl
= seq_ctrl
;
4559 sta
->last_subtype
= WLAN_FC_STYPE_ACTION
;
4562 switch (mgmt
->u
.action
.category
) {
4563 #ifdef CONFIG_IEEE80211R_AP
4564 case WLAN_ACTION_FT
:
4566 wpa_ft_action_rx(sta
->wpa_sm
, (u8
*) &mgmt
->u
.action
,
4567 len
- IEEE80211_HDRLEN
))
4570 #endif /* CONFIG_IEEE80211R_AP */
4571 case WLAN_ACTION_WMM
:
4572 hostapd_wmm_action(hapd
, mgmt
, len
);
4574 case WLAN_ACTION_SA_QUERY
:
4575 ieee802_11_sa_query_action(hapd
, mgmt
, len
);
4577 #ifdef CONFIG_WNM_AP
4578 case WLAN_ACTION_WNM
:
4579 ieee802_11_rx_wnm_action_ap(hapd
, mgmt
, len
);
4581 #endif /* CONFIG_WNM_AP */
4583 case WLAN_ACTION_FST
:
4584 if (hapd
->iface
->fst
)
4585 fst_rx_action(hapd
->iface
->fst
, mgmt
, len
);
4587 wpa_printf(MSG_DEBUG
,
4588 "FST: Ignore FST Action frame - no FST attached");
4590 #endif /* CONFIG_FST */
4591 case WLAN_ACTION_PUBLIC
:
4592 case WLAN_ACTION_PROTECTED_DUAL
:
4593 #ifdef CONFIG_IEEE80211N
4594 if (len
>= IEEE80211_HDRLEN
+ 2 &&
4595 mgmt
->u
.action
.u
.public_action
.action
==
4596 WLAN_PA_20_40_BSS_COEX
) {
4597 hostapd_2040_coex_action(hapd
, mgmt
, len
);
4600 #endif /* CONFIG_IEEE80211N */
4602 if (len
>= IEEE80211_HDRLEN
+ 6 &&
4603 mgmt
->u
.action
.u
.vs_public_action
.action
==
4604 WLAN_PA_VENDOR_SPECIFIC
&&
4605 WPA_GET_BE24(mgmt
->u
.action
.u
.vs_public_action
.oui
) ==
4607 mgmt
->u
.action
.u
.vs_public_action
.variable
[0] ==
4609 const u8
*pos
, *end
;
4611 pos
= mgmt
->u
.action
.u
.vs_public_action
.oui
;
4612 end
= ((const u8
*) mgmt
) + len
;
4613 hostapd_dpp_rx_action(hapd
, mgmt
->sa
, pos
, end
- pos
,
4617 if (len
>= IEEE80211_HDRLEN
+ 2 &&
4618 (mgmt
->u
.action
.u
.public_action
.action
==
4619 WLAN_PA_GAS_INITIAL_RESP
||
4620 mgmt
->u
.action
.u
.public_action
.action
==
4621 WLAN_PA_GAS_COMEBACK_RESP
)) {
4622 const u8
*pos
, *end
;
4624 pos
= &mgmt
->u
.action
.u
.public_action
.action
;
4625 end
= ((const u8
*) mgmt
) + len
;
4626 gas_query_ap_rx(hapd
->gas
, mgmt
->sa
,
4627 mgmt
->u
.action
.category
,
4628 pos
, end
- pos
, hapd
->iface
->freq
);
4631 #endif /* CONFIG_DPP */
4632 if (hapd
->public_action_cb
) {
4633 hapd
->public_action_cb(hapd
->public_action_cb_ctx
,
4637 if (hapd
->public_action_cb2
) {
4638 hapd
->public_action_cb2(hapd
->public_action_cb2_ctx
,
4642 if (hapd
->public_action_cb
|| hapd
->public_action_cb2
)
4645 case WLAN_ACTION_VENDOR_SPECIFIC
:
4646 if (hapd
->vendor_action_cb
) {
4647 if (hapd
->vendor_action_cb(hapd
->vendor_action_cb_ctx
,
4649 hapd
->iface
->freq
) == 0)
4653 case WLAN_ACTION_RADIO_MEASUREMENT
:
4654 hostapd_handle_radio_measurement(hapd
, (const u8
*) mgmt
, len
);
4658 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
4659 HOSTAPD_LEVEL_DEBUG
,
4660 "handle_action - unknown action category %d or invalid "
4662 mgmt
->u
.action
.category
);
4663 if (!is_multicast_ether_addr(mgmt
->da
) &&
4664 !(mgmt
->u
.action
.category
& 0x80) &&
4665 !is_multicast_ether_addr(mgmt
->sa
)) {
4666 struct ieee80211_mgmt
*resp
;
4669 * IEEE 802.11-REVma/D9.0 - 7.3.1.11
4670 * Return the Action frame to the source without change
4671 * except that MSB of the Category set to 1.
4673 wpa_printf(MSG_DEBUG
, "IEEE 802.11: Return unknown Action "
4674 "frame back to sender");
4675 resp
= os_memdup(mgmt
, len
);
4678 os_memcpy(resp
->da
, resp
->sa
, ETH_ALEN
);
4679 os_memcpy(resp
->sa
, hapd
->own_addr
, ETH_ALEN
);
4680 os_memcpy(resp
->bssid
, hapd
->own_addr
, ETH_ALEN
);
4681 resp
->u
.action
.category
|= 0x80;
4683 if (hostapd_drv_send_mlme(hapd
, resp
, len
, 0) < 0) {
4684 wpa_printf(MSG_ERROR
, "IEEE 802.11: Failed to send "
4695 * ieee802_11_mgmt - process incoming IEEE 802.11 management frames
4696 * @hapd: hostapd BSS data structure (the BSS to which the management frame was
4698 * @buf: management frame data (starting from IEEE 802.11 header)
4699 * @len: length of frame data in octets
4700 * @fi: meta data about received frame (signal level, etc.)
4702 * Process all incoming IEEE 802.11 management frames. This will be called for
4703 * each frame received from the kernel driver through wlan#ap interface. In
4704 * addition, it can be called to re-inserted pending frames (e.g., when using
4705 * external RADIUS server as an MAC ACL).
4707 int ieee802_11_mgmt(struct hostapd_data
*hapd
, const u8
*buf
, size_t len
,
4708 struct hostapd_frame_info
*fi
)
4710 struct ieee80211_mgmt
*mgmt
;
4714 int ssi_signal
= fi
? fi
->ssi_signal
: 0;
4722 freq
= hapd
->iface
->freq
;
4724 mgmt
= (struct ieee80211_mgmt
*) buf
;
4725 fc
= le_to_host16(mgmt
->frame_control
);
4726 stype
= WLAN_FC_GET_STYPE(fc
);
4728 if (is_multicast_ether_addr(mgmt
->sa
) ||
4729 is_zero_ether_addr(mgmt
->sa
) ||
4730 os_memcmp(mgmt
->sa
, hapd
->own_addr
, ETH_ALEN
) == 0) {
4731 /* Do not process any frames with unexpected/invalid SA so that
4732 * we do not add any state for unexpected STA addresses or end
4733 * up sending out frames to unexpected destination. */
4734 wpa_printf(MSG_DEBUG
, "MGMT: Invalid SA=" MACSTR
4735 " in received frame - ignore this frame silently",
4740 if (stype
== WLAN_FC_STYPE_BEACON
) {
4741 handle_beacon(hapd
, mgmt
, len
, fi
);
4745 if (!is_broadcast_ether_addr(mgmt
->bssid
) &&
4747 /* Invitation responses can be sent with the peer MAC as BSSID */
4748 !((hapd
->conf
->p2p
& P2P_GROUP_OWNER
) &&
4749 stype
== WLAN_FC_STYPE_ACTION
) &&
4750 #endif /* CONFIG_P2P */
4752 !(hapd
->conf
->mesh
& MESH_ENABLED
) &&
4753 #endif /* CONFIG_MESH */
4754 os_memcmp(mgmt
->bssid
, hapd
->own_addr
, ETH_ALEN
) != 0) {
4755 wpa_printf(MSG_INFO
, "MGMT: BSSID=" MACSTR
" not our address",
4756 MAC2STR(mgmt
->bssid
));
4761 if (stype
== WLAN_FC_STYPE_PROBE_REQ
) {
4762 handle_probe_req(hapd
, mgmt
, len
, ssi_signal
);
4766 if ((!is_broadcast_ether_addr(mgmt
->da
) ||
4767 stype
!= WLAN_FC_STYPE_ACTION
) &&
4768 os_memcmp(mgmt
->da
, hapd
->own_addr
, ETH_ALEN
) != 0) {
4769 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
4770 HOSTAPD_LEVEL_DEBUG
,
4771 "MGMT: DA=" MACSTR
" not our address",
4776 if (hapd
->iconf
->track_sta_max_num
)
4777 sta_track_add(hapd
->iface
, mgmt
->sa
, ssi_signal
);
4780 case WLAN_FC_STYPE_AUTH
:
4781 wpa_printf(MSG_DEBUG
, "mgmt::auth");
4782 handle_auth(hapd
, mgmt
, len
, ssi_signal
, 0);
4785 case WLAN_FC_STYPE_ASSOC_REQ
:
4786 wpa_printf(MSG_DEBUG
, "mgmt::assoc_req");
4787 handle_assoc(hapd
, mgmt
, len
, 0, ssi_signal
);
4790 case WLAN_FC_STYPE_REASSOC_REQ
:
4791 wpa_printf(MSG_DEBUG
, "mgmt::reassoc_req");
4792 handle_assoc(hapd
, mgmt
, len
, 1, ssi_signal
);
4795 case WLAN_FC_STYPE_DISASSOC
:
4796 wpa_printf(MSG_DEBUG
, "mgmt::disassoc");
4797 handle_disassoc(hapd
, mgmt
, len
);
4800 case WLAN_FC_STYPE_DEAUTH
:
4801 wpa_msg(hapd
->msg_ctx
, MSG_DEBUG
, "mgmt::deauth");
4802 handle_deauth(hapd
, mgmt
, len
);
4805 case WLAN_FC_STYPE_ACTION
:
4806 wpa_printf(MSG_DEBUG
, "mgmt::action");
4807 ret
= handle_action(hapd
, mgmt
, len
, freq
);
4810 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
4811 HOSTAPD_LEVEL_DEBUG
,
4812 "unknown mgmt frame subtype %d", stype
);
4820 static void handle_auth_cb(struct hostapd_data
*hapd
,
4821 const struct ieee80211_mgmt
*mgmt
,
4824 u16 auth_alg
, auth_transaction
, status_code
;
4825 struct sta_info
*sta
;
4827 sta
= ap_get_sta(hapd
, mgmt
->da
);
4829 wpa_printf(MSG_DEBUG
, "handle_auth_cb: STA " MACSTR
4835 auth_alg
= le_to_host16(mgmt
->u
.auth
.auth_alg
);
4836 auth_transaction
= le_to_host16(mgmt
->u
.auth
.auth_transaction
);
4837 status_code
= le_to_host16(mgmt
->u
.auth
.status_code
);
4840 hostapd_logger(hapd
, mgmt
->da
, HOSTAPD_MODULE_IEEE80211
,
4841 HOSTAPD_LEVEL_NOTICE
,
4842 "did not acknowledge authentication response");
4846 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.auth
)) {
4847 wpa_printf(MSG_INFO
, "handle_auth_cb - too short payload (len=%lu)",
4848 (unsigned long) len
);
4852 if (status_code
== WLAN_STATUS_SUCCESS
&&
4853 ((auth_alg
== WLAN_AUTH_OPEN
&& auth_transaction
== 2) ||
4854 (auth_alg
== WLAN_AUTH_SHARED_KEY
&& auth_transaction
== 4))) {
4855 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
4856 HOSTAPD_LEVEL_INFO
, "authenticated");
4857 sta
->flags
|= WLAN_STA_AUTH
;
4858 if (sta
->added_unassoc
)
4859 hostapd_set_sta_flags(hapd
, sta
);
4864 if (status_code
!= WLAN_STATUS_SUCCESS
&& sta
->added_unassoc
) {
4865 hostapd_drv_sta_remove(hapd
, sta
->addr
);
4866 sta
->added_unassoc
= 0;
4871 static void hostapd_set_wds_encryption(struct hostapd_data
*hapd
,
4872 struct sta_info
*sta
,
4876 struct hostapd_ssid
*ssid
= &hapd
->conf
->ssid
;
4878 if (hapd
->conf
->ieee802_1x
|| hapd
->conf
->wpa
)
4881 for (i
= 0; i
< 4; i
++) {
4882 if (ssid
->wep
.key
[i
] &&
4883 hostapd_drv_set_key(ifname_wds
, hapd
, WPA_ALG_WEP
, NULL
, i
,
4884 i
== ssid
->wep
.idx
, NULL
, 0,
4885 ssid
->wep
.key
[i
], ssid
->wep
.len
[i
])) {
4886 wpa_printf(MSG_WARNING
,
4887 "Could not set WEP keys for WDS interface; %s",
4895 static void handle_assoc_cb(struct hostapd_data
*hapd
,
4896 const struct ieee80211_mgmt
*mgmt
,
4897 size_t len
, int reassoc
, int ok
)
4900 struct sta_info
*sta
;
4903 sta
= ap_get_sta(hapd
, mgmt
->da
);
4905 wpa_printf(MSG_INFO
, "handle_assoc_cb: STA " MACSTR
" not found",
4910 if (len
< IEEE80211_HDRLEN
+ (reassoc
? sizeof(mgmt
->u
.reassoc_resp
) :
4911 sizeof(mgmt
->u
.assoc_resp
))) {
4912 wpa_printf(MSG_INFO
,
4913 "handle_assoc_cb(reassoc=%d) - too short payload (len=%lu)",
4914 reassoc
, (unsigned long) len
);
4915 hostapd_drv_sta_remove(hapd
, sta
->addr
);
4920 status
= le_to_host16(mgmt
->u
.reassoc_resp
.status_code
);
4922 status
= le_to_host16(mgmt
->u
.assoc_resp
.status_code
);
4925 hostapd_logger(hapd
, mgmt
->da
, HOSTAPD_MODULE_IEEE80211
,
4926 HOSTAPD_LEVEL_DEBUG
,
4927 "did not acknowledge association response");
4928 sta
->flags
&= ~WLAN_STA_ASSOC_REQ_OK
;
4929 /* The STA is added only in case of SUCCESS */
4930 if (status
== WLAN_STATUS_SUCCESS
)
4931 hostapd_drv_sta_remove(hapd
, sta
->addr
);
4936 if (status
!= WLAN_STATUS_SUCCESS
)
4939 /* Stop previous accounting session, if one is started, and allocate
4940 * new session id for the new session. */
4941 accounting_sta_stop(hapd
, sta
);
4943 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
4945 "associated (aid %d)",
4948 if (sta
->flags
& WLAN_STA_ASSOC
)
4950 sta
->flags
|= WLAN_STA_ASSOC
;
4951 sta
->flags
&= ~WLAN_STA_WNM_SLEEP_MODE
;
4952 if ((!hapd
->conf
->ieee802_1x
&& !hapd
->conf
->wpa
&&
4953 !hapd
->conf
->osen
) ||
4954 sta
->auth_alg
== WLAN_AUTH_FILS_SK
||
4955 sta
->auth_alg
== WLAN_AUTH_FILS_SK_PFS
||
4956 sta
->auth_alg
== WLAN_AUTH_FILS_PK
||
4957 sta
->auth_alg
== WLAN_AUTH_FT
) {
4959 * Open, static WEP, FT protocol, or FILS; no separate
4960 * authorization step.
4962 ap_sta_set_authorized(hapd
, sta
, 1);
4966 mlme_reassociate_indication(hapd
, sta
);
4968 mlme_associate_indication(hapd
, sta
);
4970 sta
->sa_query_timed_out
= 0;
4972 if (sta
->eapol_sm
== NULL
) {
4974 * This STA does not use RADIUS server for EAP authentication,
4975 * so bind it to the selected VLAN interface now, since the
4976 * interface selection is not going to change anymore.
4978 if (ap_sta_bind_vlan(hapd
, sta
) < 0)
4980 } else if (sta
->vlan_id
) {
4981 /* VLAN ID already set (e.g., by PMKSA caching), so bind STA */
4982 if (ap_sta_bind_vlan(hapd
, sta
) < 0)
4986 hostapd_set_sta_flags(hapd
, sta
);
4988 if (!(sta
->flags
& WLAN_STA_WDS
) && sta
->pending_wds_enable
) {
4989 wpa_printf(MSG_DEBUG
, "Enable 4-address WDS mode for STA "
4990 MACSTR
" based on pending request",
4991 MAC2STR(sta
->addr
));
4992 sta
->pending_wds_enable
= 0;
4993 sta
->flags
|= WLAN_STA_WDS
;
4996 if (sta
->flags
& (WLAN_STA_WDS
| WLAN_STA_MULTI_AP
)) {
4998 char ifname_wds
[IFNAMSIZ
+ 1];
5000 wpa_printf(MSG_DEBUG
, "Reenable 4-address WDS mode for STA "
5002 MAC2STR(sta
->addr
), sta
->aid
);
5003 ret
= hostapd_set_wds_sta(hapd
, ifname_wds
, sta
->addr
,
5006 hostapd_set_wds_encryption(hapd
, sta
, ifname_wds
);
5009 if (sta
->auth_alg
== WLAN_AUTH_FT
)
5010 wpa_auth_sm_event(sta
->wpa_sm
, WPA_ASSOC_FT
);
5012 wpa_auth_sm_event(sta
->wpa_sm
, WPA_ASSOC
);
5013 hapd
->new_assoc_sta_cb(hapd
, sta
, !new_assoc
);
5014 ieee802_1x_notify_port_enabled(sta
->eapol_sm
, 1);
5017 if ((sta
->auth_alg
== WLAN_AUTH_FILS_SK
||
5018 sta
->auth_alg
== WLAN_AUTH_FILS_SK_PFS
||
5019 sta
->auth_alg
== WLAN_AUTH_FILS_PK
) &&
5020 fils_set_tk(sta
->wpa_sm
) < 0) {
5021 wpa_printf(MSG_DEBUG
, "FILS: TK configuration failed");
5022 ap_sta_disconnect(hapd
, sta
, sta
->addr
,
5023 WLAN_REASON_UNSPECIFIED
);
5026 #endif /* CONFIG_FILS */
5028 if (sta
->pending_eapol_rx
) {
5029 struct os_reltime now
, age
;
5031 os_get_reltime(&now
);
5032 os_reltime_sub(&now
, &sta
->pending_eapol_rx
->rx_time
, &age
);
5033 if (age
.sec
== 0 && age
.usec
< 200000) {
5034 wpa_printf(MSG_DEBUG
,
5035 "Process pending EAPOL frame that was received from " MACSTR
" just before association notification",
5036 MAC2STR(sta
->addr
));
5039 wpabuf_head(sta
->pending_eapol_rx
->buf
),
5040 wpabuf_len(sta
->pending_eapol_rx
->buf
));
5042 wpabuf_free(sta
->pending_eapol_rx
->buf
);
5043 os_free(sta
->pending_eapol_rx
);
5044 sta
->pending_eapol_rx
= NULL
;
5049 static void handle_deauth_cb(struct hostapd_data
*hapd
,
5050 const struct ieee80211_mgmt
*mgmt
,
5053 struct sta_info
*sta
;
5054 if (is_multicast_ether_addr(mgmt
->da
))
5056 sta
= ap_get_sta(hapd
, mgmt
->da
);
5058 wpa_printf(MSG_DEBUG
, "handle_deauth_cb: STA " MACSTR
5059 " not found", MAC2STR(mgmt
->da
));
5063 wpa_printf(MSG_DEBUG
, "STA " MACSTR
" acknowledged deauth",
5064 MAC2STR(sta
->addr
));
5066 wpa_printf(MSG_DEBUG
, "STA " MACSTR
" did not acknowledge "
5067 "deauth", MAC2STR(sta
->addr
));
5069 ap_sta_deauth_cb(hapd
, sta
);
5073 static void handle_disassoc_cb(struct hostapd_data
*hapd
,
5074 const struct ieee80211_mgmt
*mgmt
,
5077 struct sta_info
*sta
;
5078 if (is_multicast_ether_addr(mgmt
->da
))
5080 sta
= ap_get_sta(hapd
, mgmt
->da
);
5082 wpa_printf(MSG_DEBUG
, "handle_disassoc_cb: STA " MACSTR
5083 " not found", MAC2STR(mgmt
->da
));
5087 wpa_printf(MSG_DEBUG
, "STA " MACSTR
" acknowledged disassoc",
5088 MAC2STR(sta
->addr
));
5090 wpa_printf(MSG_DEBUG
, "STA " MACSTR
" did not acknowledge "
5091 "disassoc", MAC2STR(sta
->addr
));
5093 ap_sta_disassoc_cb(hapd
, sta
);
5097 static void handle_action_cb(struct hostapd_data
*hapd
,
5098 const struct ieee80211_mgmt
*mgmt
,
5101 struct sta_info
*sta
;
5102 const struct rrm_measurement_report_element
*report
;
5104 if (is_multicast_ether_addr(mgmt
->da
))
5107 if (len
>= IEEE80211_HDRLEN
+ 6 &&
5108 mgmt
->u
.action
.category
== WLAN_ACTION_PUBLIC
&&
5109 mgmt
->u
.action
.u
.vs_public_action
.action
==
5110 WLAN_PA_VENDOR_SPECIFIC
&&
5111 WPA_GET_BE24(mgmt
->u
.action
.u
.vs_public_action
.oui
) ==
5113 mgmt
->u
.action
.u
.vs_public_action
.variable
[0] ==
5115 const u8
*pos
, *end
;
5117 pos
= &mgmt
->u
.action
.u
.vs_public_action
.variable
[1];
5118 end
= ((const u8
*) mgmt
) + len
;
5119 hostapd_dpp_tx_status(hapd
, mgmt
->da
, pos
, end
- pos
, ok
);
5122 if (len
>= IEEE80211_HDRLEN
+ 2 &&
5123 mgmt
->u
.action
.category
== WLAN_ACTION_PUBLIC
&&
5124 (mgmt
->u
.action
.u
.public_action
.action
==
5125 WLAN_PA_GAS_INITIAL_REQ
||
5126 mgmt
->u
.action
.u
.public_action
.action
==
5127 WLAN_PA_GAS_COMEBACK_REQ
)) {
5128 const u8
*pos
, *end
;
5130 pos
= mgmt
->u
.action
.u
.public_action
.variable
;
5131 end
= ((const u8
*) mgmt
) + len
;
5132 gas_query_ap_tx_status(hapd
->gas
, mgmt
->da
, pos
, end
- pos
, ok
);
5135 #endif /* CONFIG_DPP */
5136 sta
= ap_get_sta(hapd
, mgmt
->da
);
5138 wpa_printf(MSG_DEBUG
, "handle_action_cb: STA " MACSTR
5139 " not found", MAC2STR(mgmt
->da
));
5143 if (len
< 24 + 5 + sizeof(*report
))
5145 report
= (const struct rrm_measurement_report_element
*)
5146 &mgmt
->u
.action
.u
.rrm
.variable
[2];
5147 if (mgmt
->u
.action
.category
== WLAN_ACTION_RADIO_MEASUREMENT
&&
5148 mgmt
->u
.action
.u
.rrm
.action
== WLAN_RRM_RADIO_MEASUREMENT_REQUEST
&&
5149 report
->eid
== WLAN_EID_MEASURE_REQUEST
&&
5151 report
->type
== MEASURE_TYPE_BEACON
)
5152 hostapd_rrm_beacon_req_tx_status(hapd
, mgmt
, len
, ok
);
5157 * ieee802_11_mgmt_cb - Process management frame TX status callback
5158 * @hapd: hostapd BSS data structure (the BSS from which the management frame
5160 * @buf: management frame data (starting from IEEE 802.11 header)
5161 * @len: length of frame data in octets
5162 * @stype: management frame subtype from frame control field
5163 * @ok: Whether the frame was ACK'ed
5165 void ieee802_11_mgmt_cb(struct hostapd_data
*hapd
, const u8
*buf
, size_t len
,
5168 const struct ieee80211_mgmt
*mgmt
;
5169 mgmt
= (const struct ieee80211_mgmt
*) buf
;
5171 #ifdef CONFIG_TESTING_OPTIONS
5172 if (hapd
->ext_mgmt_frame_handling
) {
5173 size_t hex_len
= 2 * len
+ 1;
5174 char *hex
= os_malloc(hex_len
);
5177 wpa_snprintf_hex(hex
, hex_len
, buf
, len
);
5178 wpa_msg(hapd
->msg_ctx
, MSG_INFO
,
5179 "MGMT-TX-STATUS stype=%u ok=%d buf=%s",
5185 #endif /* CONFIG_TESTING_OPTIONS */
5188 case WLAN_FC_STYPE_AUTH
:
5189 wpa_printf(MSG_DEBUG
, "mgmt::auth cb");
5190 handle_auth_cb(hapd
, mgmt
, len
, ok
);
5192 case WLAN_FC_STYPE_ASSOC_RESP
:
5193 wpa_printf(MSG_DEBUG
, "mgmt::assoc_resp cb");
5194 handle_assoc_cb(hapd
, mgmt
, len
, 0, ok
);
5196 case WLAN_FC_STYPE_REASSOC_RESP
:
5197 wpa_printf(MSG_DEBUG
, "mgmt::reassoc_resp cb");
5198 handle_assoc_cb(hapd
, mgmt
, len
, 1, ok
);
5200 case WLAN_FC_STYPE_PROBE_RESP
:
5201 wpa_printf(MSG_EXCESSIVE
, "mgmt::proberesp cb ok=%d", ok
);
5203 case WLAN_FC_STYPE_DEAUTH
:
5204 wpa_printf(MSG_DEBUG
, "mgmt::deauth cb");
5205 handle_deauth_cb(hapd
, mgmt
, len
, ok
);
5207 case WLAN_FC_STYPE_DISASSOC
:
5208 wpa_printf(MSG_DEBUG
, "mgmt::disassoc cb");
5209 handle_disassoc_cb(hapd
, mgmt
, len
, ok
);
5211 case WLAN_FC_STYPE_ACTION
:
5212 wpa_printf(MSG_DEBUG
, "mgmt::action cb ok=%d", ok
);
5213 handle_action_cb(hapd
, mgmt
, len
, ok
);
5216 wpa_printf(MSG_INFO
, "unknown mgmt cb frame subtype %d", stype
);
5222 int ieee802_11_get_mib(struct hostapd_data
*hapd
, char *buf
, size_t buflen
)
5229 int ieee802_11_get_mib_sta(struct hostapd_data
*hapd
, struct sta_info
*sta
,
5230 char *buf
, size_t buflen
)
5237 void hostapd_tx_status(struct hostapd_data
*hapd
, const u8
*addr
,
5238 const u8
*buf
, size_t len
, int ack
)
5240 struct sta_info
*sta
;
5241 struct hostapd_iface
*iface
= hapd
->iface
;
5243 sta
= ap_get_sta(hapd
, addr
);
5244 if (sta
== NULL
&& iface
->num_bss
> 1) {
5246 for (j
= 0; j
< iface
->num_bss
; j
++) {
5247 hapd
= iface
->bss
[j
];
5248 sta
= ap_get_sta(hapd
, addr
);
5253 if (sta
== NULL
|| !(sta
->flags
& WLAN_STA_ASSOC
))
5255 if (sta
->flags
& WLAN_STA_PENDING_POLL
) {
5256 wpa_printf(MSG_DEBUG
, "STA " MACSTR
" %s pending "
5257 "activity poll", MAC2STR(sta
->addr
),
5258 ack
? "ACKed" : "did not ACK");
5260 sta
->flags
&= ~WLAN_STA_PENDING_POLL
;
5263 ieee802_1x_tx_status(hapd
, sta
, buf
, len
, ack
);
5267 void hostapd_eapol_tx_status(struct hostapd_data
*hapd
, const u8
*dst
,
5268 const u8
*data
, size_t len
, int ack
)
5270 struct sta_info
*sta
;
5271 struct hostapd_iface
*iface
= hapd
->iface
;
5273 sta
= ap_get_sta(hapd
, dst
);
5274 if (sta
== NULL
&& iface
->num_bss
> 1) {
5276 for (j
= 0; j
< iface
->num_bss
; j
++) {
5277 hapd
= iface
->bss
[j
];
5278 sta
= ap_get_sta(hapd
, dst
);
5283 if (sta
== NULL
|| !(sta
->flags
& WLAN_STA_ASSOC
)) {
5284 wpa_printf(MSG_DEBUG
, "Ignore TX status for Data frame to STA "
5285 MACSTR
" that is not currently associated",
5290 ieee802_1x_eapol_tx_status(hapd
, sta
, data
, len
, ack
);
5294 void hostapd_client_poll_ok(struct hostapd_data
*hapd
, const u8
*addr
)
5296 struct sta_info
*sta
;
5297 struct hostapd_iface
*iface
= hapd
->iface
;
5299 sta
= ap_get_sta(hapd
, addr
);
5300 if (sta
== NULL
&& iface
->num_bss
> 1) {
5302 for (j
= 0; j
< iface
->num_bss
; j
++) {
5303 hapd
= iface
->bss
[j
];
5304 sta
= ap_get_sta(hapd
, addr
);
5311 wpa_msg(hapd
->msg_ctx
, MSG_INFO
, AP_STA_POLL_OK MACSTR
,
5312 MAC2STR(sta
->addr
));
5313 if (!(sta
->flags
& WLAN_STA_PENDING_POLL
))
5316 wpa_printf(MSG_DEBUG
, "STA " MACSTR
" ACKed pending "
5317 "activity poll", MAC2STR(sta
->addr
));
5318 sta
->flags
&= ~WLAN_STA_PENDING_POLL
;
5322 void ieee802_11_rx_from_unknown(struct hostapd_data
*hapd
, const u8
*src
,
5325 struct sta_info
*sta
;
5327 sta
= ap_get_sta(hapd
, src
);
5329 ((sta
->flags
& WLAN_STA_ASSOC
) ||
5330 ((sta
->flags
& WLAN_STA_ASSOC_REQ_OK
) && wds
))) {
5331 if (!hapd
->conf
->wds_sta
)
5334 if ((sta
->flags
& (WLAN_STA_ASSOC
| WLAN_STA_ASSOC_REQ_OK
)) ==
5335 WLAN_STA_ASSOC_REQ_OK
) {
5336 wpa_printf(MSG_DEBUG
,
5337 "Postpone 4-address WDS mode enabling for STA "
5338 MACSTR
" since TX status for AssocResp is not yet known",
5339 MAC2STR(sta
->addr
));
5340 sta
->pending_wds_enable
= 1;
5344 if (wds
&& !(sta
->flags
& WLAN_STA_WDS
)) {
5346 char ifname_wds
[IFNAMSIZ
+ 1];
5348 wpa_printf(MSG_DEBUG
, "Enable 4-address WDS mode for "
5349 "STA " MACSTR
" (aid %u)",
5350 MAC2STR(sta
->addr
), sta
->aid
);
5351 sta
->flags
|= WLAN_STA_WDS
;
5352 ret
= hostapd_set_wds_sta(hapd
, ifname_wds
,
5353 sta
->addr
, sta
->aid
, 1);
5355 hostapd_set_wds_encryption(hapd
, sta
,
5361 wpa_printf(MSG_DEBUG
, "Data/PS-poll frame from not associated STA "
5362 MACSTR
, MAC2STR(src
));
5363 if (is_multicast_ether_addr(src
) || is_zero_ether_addr(src
) ||
5364 os_memcmp(src
, hapd
->own_addr
, ETH_ALEN
) == 0) {
5365 /* Broadcast bit set in SA or unexpected SA?! Ignore the frame
5370 if (sta
&& (sta
->flags
& WLAN_STA_ASSOC_REQ_OK
)) {
5371 wpa_printf(MSG_DEBUG
, "Association Response to the STA has "
5372 "already been sent, but no TX status yet known - "
5373 "ignore Class 3 frame issue with " MACSTR
,
5378 if (sta
&& (sta
->flags
& WLAN_STA_AUTH
))
5379 hostapd_drv_sta_disassoc(
5381 WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA
);
5383 hostapd_drv_sta_deauth(
5385 WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA
);
5389 #endif /* CONFIG_NATIVE_WINDOWS */