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)
104 /* rest of the rates are encoded in Extended supported
110 for (i
= 0, count
= 0; i
< hapd
->iface
->num_rates
&& count
< num
;
113 *pos
= hapd
->iface
->current_rates
[i
].rate
/ 5;
114 if (hapd
->iface
->current_rates
[i
].flags
& HOSTAPD_RATE_BASIC
)
119 if (hapd
->iconf
->ieee80211n
&& hapd
->iconf
->require_ht
&& count
< 8) {
121 *pos
++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_HT_PHY
;
124 if (hapd
->iconf
->ieee80211ac
&& hapd
->iconf
->require_vht
&& count
< 8) {
126 *pos
++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_VHT_PHY
;
129 if (hapd
->conf
->sae_pwe
== 1 && count
< 8) {
131 *pos
++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_SAE_H2E_ONLY
;
138 u8
* hostapd_eid_ext_supp_rates(struct hostapd_data
*hapd
, u8
*eid
)
143 if (hapd
->iface
->current_rates
== NULL
)
146 num
= hapd
->iface
->num_rates
;
147 if (hapd
->iconf
->ieee80211n
&& hapd
->iconf
->require_ht
)
149 if (hapd
->iconf
->ieee80211ac
&& hapd
->iconf
->require_vht
)
151 if (hapd
->conf
->sae_pwe
== 1)
157 *pos
++ = WLAN_EID_EXT_SUPP_RATES
;
159 for (i
= 0, count
= 0; i
< hapd
->iface
->num_rates
&& count
< num
+ 8;
163 continue; /* already in SuppRates IE */
164 *pos
= hapd
->iface
->current_rates
[i
].rate
/ 5;
165 if (hapd
->iface
->current_rates
[i
].flags
& HOSTAPD_RATE_BASIC
)
170 if (hapd
->iconf
->ieee80211n
&& hapd
->iconf
->require_ht
) {
173 *pos
++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_HT_PHY
;
176 if (hapd
->iconf
->ieee80211ac
&& hapd
->iconf
->require_vht
) {
179 *pos
++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_VHT_PHY
;
182 if (hapd
->conf
->sae_pwe
== 1) {
185 *pos
++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_SAE_H2E_ONLY
;
192 u16
hostapd_own_capab_info(struct hostapd_data
*hapd
)
194 int capab
= WLAN_CAPABILITY_ESS
;
199 /* Check if any of configured channels require DFS */
200 dfs
= hostapd_is_dfs_required(hapd
->iface
);
202 wpa_printf(MSG_WARNING
, "Failed to check if DFS is required; ret=%d",
207 if (hapd
->iface
->num_sta_no_short_preamble
== 0 &&
208 hapd
->iconf
->preamble
== SHORT_PREAMBLE
)
209 capab
|= WLAN_CAPABILITY_SHORT_PREAMBLE
;
211 privacy
= hapd
->conf
->ssid
.wep
.keys_set
;
213 if (hapd
->conf
->ieee802_1x
&&
214 (hapd
->conf
->default_wep_key_len
||
215 hapd
->conf
->individual_wep_key_len
))
222 if (hapd
->conf
->osen
)
224 #endif /* CONFIG_HS20 */
227 capab
|= WLAN_CAPABILITY_PRIVACY
;
229 if (hapd
->iface
->current_mode
&&
230 hapd
->iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211G
&&
231 hapd
->iface
->num_sta_no_short_slot_time
== 0)
232 capab
|= WLAN_CAPABILITY_SHORT_SLOT_TIME
;
235 * Currently, Spectrum Management capability bit is set when directly
236 * requested in configuration by spectrum_mgmt_required or when AP is
237 * running on DFS channel.
238 * TODO: Also consider driver support for TPC to set Spectrum Mgmt bit
240 if (hapd
->iface
->current_mode
&&
241 hapd
->iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211A
&&
242 (hapd
->iconf
->spectrum_mgmt_required
|| dfs
))
243 capab
|= WLAN_CAPABILITY_SPECTRUM_MGMT
;
245 for (i
= 0; i
< RRM_CAPABILITIES_IE_LEN
; i
++) {
246 if (hapd
->conf
->radio_measurements
[i
]) {
247 capab
|= IEEE80211_CAP_RRM
;
256 #ifndef CONFIG_NO_RC4
257 static u16
auth_shared_key(struct hostapd_data
*hapd
, struct sta_info
*sta
,
258 u16 auth_transaction
, const u8
*challenge
,
261 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
263 "authentication (shared key, transaction %d)",
266 if (auth_transaction
== 1) {
267 if (!sta
->challenge
) {
268 /* Generate a pseudo-random challenge */
271 sta
->challenge
= os_zalloc(WLAN_AUTH_CHALLENGE_LEN
);
272 if (sta
->challenge
== NULL
)
273 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
275 if (os_get_random(key
, sizeof(key
)) < 0) {
276 os_free(sta
->challenge
);
277 sta
->challenge
= NULL
;
278 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
281 rc4_skip(key
, sizeof(key
), 0,
282 sta
->challenge
, WLAN_AUTH_CHALLENGE_LEN
);
287 if (auth_transaction
!= 3)
288 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
291 if (!iswep
|| !sta
->challenge
|| !challenge
||
292 os_memcmp_const(sta
->challenge
, challenge
,
293 WLAN_AUTH_CHALLENGE_LEN
)) {
294 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
296 "shared key authentication - invalid "
297 "challenge-response");
298 return WLAN_STATUS_CHALLENGE_FAIL
;
301 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
303 "authentication OK (shared key)");
304 sta
->flags
|= WLAN_STA_AUTH
;
305 wpa_auth_sm_event(sta
->wpa_sm
, WPA_AUTH
);
306 os_free(sta
->challenge
);
307 sta
->challenge
= NULL
;
311 #endif /* CONFIG_NO_RC4 */
314 static int send_auth_reply(struct hostapd_data
*hapd
,
315 const u8
*dst
, const u8
*bssid
,
316 u16 auth_alg
, u16 auth_transaction
, u16 resp
,
317 const u8
*ies
, size_t ies_len
, const char *dbg
)
319 struct ieee80211_mgmt
*reply
;
322 int reply_res
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
324 rlen
= IEEE80211_HDRLEN
+ sizeof(reply
->u
.auth
) + ies_len
;
325 buf
= os_zalloc(rlen
);
329 reply
= (struct ieee80211_mgmt
*) buf
;
330 reply
->frame_control
= IEEE80211_FC(WLAN_FC_TYPE_MGMT
,
332 os_memcpy(reply
->da
, dst
, ETH_ALEN
);
333 os_memcpy(reply
->sa
, hapd
->own_addr
, ETH_ALEN
);
334 os_memcpy(reply
->bssid
, bssid
, ETH_ALEN
);
336 reply
->u
.auth
.auth_alg
= host_to_le16(auth_alg
);
337 reply
->u
.auth
.auth_transaction
= host_to_le16(auth_transaction
);
338 reply
->u
.auth
.status_code
= host_to_le16(resp
);
341 os_memcpy(reply
->u
.auth
.variable
, ies
, ies_len
);
343 wpa_printf(MSG_DEBUG
, "authentication reply: STA=" MACSTR
344 " auth_alg=%d auth_transaction=%d resp=%d (IE len=%lu) (dbg=%s)",
345 MAC2STR(dst
), auth_alg
, auth_transaction
,
346 resp
, (unsigned long) ies_len
, dbg
);
347 if (hostapd_drv_send_mlme(hapd
, reply
, rlen
, 0) < 0)
348 wpa_printf(MSG_INFO
, "send_auth_reply: send failed");
350 reply_res
= WLAN_STATUS_SUCCESS
;
358 #ifdef CONFIG_IEEE80211R_AP
359 static void handle_auth_ft_finish(void *ctx
, const u8
*dst
, const u8
*bssid
,
360 u16 auth_transaction
, u16 status
,
361 const u8
*ies
, size_t ies_len
)
363 struct hostapd_data
*hapd
= ctx
;
364 struct sta_info
*sta
;
367 reply_res
= send_auth_reply(hapd
, dst
, bssid
, WLAN_AUTH_FT
,
368 auth_transaction
, status
, ies
, ies_len
,
371 sta
= ap_get_sta(hapd
, dst
);
375 if (sta
->added_unassoc
&& (reply_res
!= WLAN_STATUS_SUCCESS
||
376 status
!= WLAN_STATUS_SUCCESS
)) {
377 hostapd_drv_sta_remove(hapd
, sta
->addr
);
378 sta
->added_unassoc
= 0;
382 if (status
!= WLAN_STATUS_SUCCESS
)
385 hostapd_logger(hapd
, dst
, HOSTAPD_MODULE_IEEE80211
,
386 HOSTAPD_LEVEL_DEBUG
, "authentication OK (FT)");
387 sta
->flags
|= WLAN_STA_AUTH
;
388 mlme_authenticate_indication(hapd
, sta
);
390 #endif /* CONFIG_IEEE80211R_AP */
395 static void sae_set_state(struct sta_info
*sta
, enum sae_state state
,
398 wpa_printf(MSG_DEBUG
, "SAE: State %s -> %s for peer " MACSTR
" (%s)",
399 sae_state_txt(sta
->sae
->state
), sae_state_txt(state
),
400 MAC2STR(sta
->addr
), reason
);
401 sta
->sae
->state
= state
;
405 static struct wpabuf
* auth_build_sae_commit(struct hostapd_data
*hapd
,
406 struct sta_info
*sta
, int update
)
409 const char *password
= NULL
;
410 struct sae_password_entry
*pw
;
411 const char *rx_id
= NULL
;
413 struct sae_pt
*pt
= NULL
;
416 rx_id
= sta
->sae
->tmp
->pw_id
;
417 use_pt
= sta
->sae
->tmp
->h2e
;
420 for (pw
= hapd
->conf
->sae_passwords
; pw
; pw
= pw
->next
) {
421 if (!is_broadcast_ether_addr(pw
->peer_addr
) &&
422 os_memcmp(pw
->peer_addr
, sta
->addr
, ETH_ALEN
) != 0)
424 if ((rx_id
&& !pw
->identifier
) || (!rx_id
&& pw
->identifier
))
426 if (rx_id
&& pw
->identifier
&&
427 os_strcmp(rx_id
, pw
->identifier
) != 0)
429 password
= pw
->password
;
434 password
= hapd
->conf
->ssid
.wpa_passphrase
;
435 pt
= hapd
->conf
->ssid
.pt
;
437 if (!password
|| (use_pt
&& !pt
)) {
438 wpa_printf(MSG_DEBUG
, "SAE: No password available");
442 if (update
&& use_pt
&&
443 sae_prepare_commit_pt(sta
->sae
, pt
, hapd
->own_addr
, sta
->addr
,
447 if (update
&& !use_pt
&&
448 sae_prepare_commit(hapd
->own_addr
, sta
->addr
,
449 (u8
*) password
, os_strlen(password
), rx_id
,
451 wpa_printf(MSG_DEBUG
, "SAE: Could not pick PWE");
455 if (pw
&& pw
->vlan_id
) {
456 if (!sta
->sae
->tmp
) {
458 "SAE: No temporary data allocated - cannot store VLAN ID");
461 sta
->sae
->tmp
->vlan_id
= pw
->vlan_id
;
464 buf
= wpabuf_alloc(SAE_COMMIT_MAX_LEN
+
465 (rx_id
? 3 + os_strlen(rx_id
) : 0));
468 sae_write_commit(sta
->sae
, buf
, sta
->sae
->tmp
?
469 sta
->sae
->tmp
->anti_clogging_token
: NULL
, rx_id
);
475 static struct wpabuf
* auth_build_sae_confirm(struct hostapd_data
*hapd
,
476 struct sta_info
*sta
)
480 buf
= wpabuf_alloc(SAE_CONFIRM_MAX_LEN
);
484 sae_write_confirm(sta
->sae
, buf
);
490 static int auth_sae_send_commit(struct hostapd_data
*hapd
,
491 struct sta_info
*sta
,
492 const u8
*bssid
, int update
)
498 data
= auth_build_sae_commit(hapd
, sta
, update
);
499 if (!data
&& sta
->sae
->tmp
&& sta
->sae
->tmp
->pw_id
)
500 return WLAN_STATUS_UNKNOWN_PASSWORD_IDENTIFIER
;
502 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
504 status
= (sta
->sae
->tmp
&& sta
->sae
->tmp
->h2e
) ?
505 WLAN_STATUS_SAE_HASH_TO_ELEMENT
: WLAN_STATUS_SUCCESS
;
506 reply_res
= send_auth_reply(hapd
, sta
->addr
, bssid
, WLAN_AUTH_SAE
, 1,
507 status
, wpabuf_head(data
),
508 wpabuf_len(data
), "sae-send-commit");
516 static int auth_sae_send_confirm(struct hostapd_data
*hapd
,
517 struct sta_info
*sta
,
523 data
= auth_build_sae_confirm(hapd
, sta
);
525 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
527 reply_res
= send_auth_reply(hapd
, sta
->addr
, bssid
, WLAN_AUTH_SAE
, 2,
528 WLAN_STATUS_SUCCESS
, wpabuf_head(data
),
529 wpabuf_len(data
), "sae-send-confirm");
537 static int use_sae_anti_clogging(struct hostapd_data
*hapd
)
539 struct sta_info
*sta
;
540 unsigned int open
= 0;
542 if (hapd
->conf
->sae_anti_clogging_threshold
== 0)
545 for (sta
= hapd
->sta_list
; sta
; sta
= sta
->next
) {
548 if (sta
->sae
->state
!= SAE_COMMITTED
&&
549 sta
->sae
->state
!= SAE_CONFIRMED
)
552 if (open
>= hapd
->conf
->sae_anti_clogging_threshold
)
556 /* In addition to already existing open SAE sessions, check whether
557 * there are enough pending commit messages in the processing queue to
558 * potentially result in too many open sessions. */
559 if (open
+ dl_list_len(&hapd
->sae_commit_queue
) >=
560 hapd
->conf
->sae_anti_clogging_threshold
)
567 static u8
sae_token_hash(struct hostapd_data
*hapd
, const u8
*addr
)
569 u8 hash
[SHA256_MAC_LEN
];
571 hmac_sha256(hapd
->sae_token_key
, sizeof(hapd
->sae_token_key
),
572 addr
, ETH_ALEN
, hash
);
577 static int check_sae_token(struct hostapd_data
*hapd
, const u8
*addr
,
578 const u8
*token
, size_t token_len
)
580 u8 mac
[SHA256_MAC_LEN
];
586 if (token_len
!= SHA256_MAC_LEN
)
588 idx
= sae_token_hash(hapd
, addr
);
589 token_idx
= hapd
->sae_pending_token_idx
[idx
];
590 if (token_idx
== 0 || token_idx
!= WPA_GET_BE16(token
)) {
591 wpa_printf(MSG_DEBUG
, "SAE: Invalid anti-clogging token from "
592 MACSTR
" - token_idx 0x%04x, expected 0x%04x",
593 MAC2STR(addr
), WPA_GET_BE16(token
), token_idx
);
601 if (hmac_sha256_vector(hapd
->sae_token_key
, sizeof(hapd
->sae_token_key
),
602 2, addrs
, len
, mac
) < 0 ||
603 os_memcmp_const(token
+ 2, &mac
[2], SHA256_MAC_LEN
- 2) != 0)
606 hapd
->sae_pending_token_idx
[idx
] = 0; /* invalidate used token */
612 static struct wpabuf
* auth_build_token_req(struct hostapd_data
*hapd
,
613 int group
, const u8
*addr
)
617 struct os_reltime now
;
624 os_get_reltime(&now
);
625 if (!os_reltime_initialized(&hapd
->last_sae_token_key_update
) ||
626 os_reltime_expired(&now
, &hapd
->last_sae_token_key_update
, 60) ||
627 hapd
->sae_token_idx
== 0xffff) {
628 if (random_get_bytes(hapd
->sae_token_key
,
629 sizeof(hapd
->sae_token_key
)) < 0)
631 wpa_hexdump(MSG_DEBUG
, "SAE: Updated token key",
632 hapd
->sae_token_key
, sizeof(hapd
->sae_token_key
));
633 hapd
->last_sae_token_key_update
= now
;
634 hapd
->sae_token_idx
= 0;
635 os_memset(hapd
->sae_pending_token_idx
, 0,
636 sizeof(hapd
->sae_pending_token_idx
));
639 buf
= wpabuf_alloc(sizeof(le16
) + SHA256_MAC_LEN
);
643 wpabuf_put_le16(buf
, group
); /* Finite Cyclic Group */
645 p_idx
= sae_token_hash(hapd
, addr
);
646 token_idx
= hapd
->sae_pending_token_idx
[p_idx
];
648 hapd
->sae_token_idx
++;
649 token_idx
= hapd
->sae_token_idx
;
650 hapd
->sae_pending_token_idx
[p_idx
] = token_idx
;
652 WPA_PUT_BE16(idx
, token_idx
);
653 token
= wpabuf_put(buf
, SHA256_MAC_LEN
);
657 len
[1] = sizeof(idx
);
658 if (hmac_sha256_vector(hapd
->sae_token_key
, sizeof(hapd
->sae_token_key
),
659 2, addrs
, len
, token
) < 0) {
663 WPA_PUT_BE16(token
, token_idx
);
669 static int sae_check_big_sync(struct hostapd_data
*hapd
, struct sta_info
*sta
)
671 if (sta
->sae
->sync
> hapd
->conf
->sae_sync
) {
672 sae_set_state(sta
, SAE_NOTHING
, "Sync > dot11RSNASAESync");
680 static void auth_sae_retransmit_timer(void *eloop_ctx
, void *eloop_data
)
682 struct hostapd_data
*hapd
= eloop_ctx
;
683 struct sta_info
*sta
= eloop_data
;
686 if (sae_check_big_sync(hapd
, sta
))
689 wpa_printf(MSG_DEBUG
, "SAE: Auth SAE retransmit timer for " MACSTR
690 " (sync=%d state=%s)",
691 MAC2STR(sta
->addr
), sta
->sae
->sync
,
692 sae_state_txt(sta
->sae
->state
));
694 switch (sta
->sae
->state
) {
696 ret
= auth_sae_send_commit(hapd
, sta
, hapd
->own_addr
, 0);
697 eloop_register_timeout(0,
698 hapd
->dot11RSNASAERetransPeriod
* 1000,
699 auth_sae_retransmit_timer
, hapd
, sta
);
702 ret
= auth_sae_send_confirm(hapd
, sta
, hapd
->own_addr
);
703 eloop_register_timeout(0,
704 hapd
->dot11RSNASAERetransPeriod
* 1000,
705 auth_sae_retransmit_timer
, hapd
, sta
);
712 if (ret
!= WLAN_STATUS_SUCCESS
)
713 wpa_printf(MSG_INFO
, "SAE: Failed to retransmit: ret=%d", ret
);
717 void sae_clear_retransmit_timer(struct hostapd_data
*hapd
, struct sta_info
*sta
)
719 eloop_cancel_timeout(auth_sae_retransmit_timer
, hapd
, sta
);
723 static void sae_set_retransmit_timer(struct hostapd_data
*hapd
,
724 struct sta_info
*sta
)
726 if (!(hapd
->conf
->mesh
& MESH_ENABLED
))
729 eloop_cancel_timeout(auth_sae_retransmit_timer
, hapd
, sta
);
730 eloop_register_timeout(0, hapd
->dot11RSNASAERetransPeriod
* 1000,
731 auth_sae_retransmit_timer
, hapd
, sta
);
735 static void sae_sme_send_external_auth_status(struct hostapd_data
*hapd
,
736 struct sta_info
*sta
, u16 status
)
738 struct external_auth params
;
740 os_memset(¶ms
, 0, sizeof(params
));
741 params
.status
= status
;
742 params
.bssid
= sta
->addr
;
743 if (status
== WLAN_STATUS_SUCCESS
&& sta
->sae
&&
744 !hapd
->conf
->disable_pmksa_caching
)
745 params
.pmkid
= sta
->sae
->pmkid
;
747 hostapd_drv_send_external_auth_status(hapd
, ¶ms
);
751 void sae_accept_sta(struct hostapd_data
*hapd
, struct sta_info
*sta
)
753 #ifndef CONFIG_NO_VLAN
754 struct vlan_description vlan_desc
;
756 if (sta
->sae
->tmp
&& sta
->sae
->tmp
->vlan_id
> 0) {
757 wpa_printf(MSG_DEBUG
, "SAE: Assign STA " MACSTR
759 MAC2STR(sta
->addr
), sta
->sae
->tmp
->vlan_id
);
761 os_memset(&vlan_desc
, 0, sizeof(vlan_desc
));
762 vlan_desc
.notempty
= 1;
763 vlan_desc
.untagged
= sta
->sae
->tmp
->vlan_id
;
764 if (!hostapd_vlan_valid(hapd
->conf
->vlan
, &vlan_desc
)) {
766 "Invalid VLAN ID %d in sae_password",
767 sta
->sae
->tmp
->vlan_id
);
771 if (ap_sta_set_vlan(hapd
, sta
, &vlan_desc
) < 0 ||
772 ap_sta_bind_vlan(hapd
, sta
) < 0) {
774 "Failed to assign VLAN ID %d from sae_password to "
775 MACSTR
, sta
->sae
->tmp
->vlan_id
,
780 #endif /* CONFIG_NO_VLAN */
782 sta
->flags
|= WLAN_STA_AUTH
;
783 sta
->auth_alg
= WLAN_AUTH_SAE
;
784 mlme_authenticate_indication(hapd
, sta
);
785 wpa_auth_sm_event(sta
->wpa_sm
, WPA_AUTH
);
786 sae_set_state(sta
, SAE_ACCEPTED
, "Accept Confirm");
787 wpa_auth_pmksa_add_sae(hapd
->wpa_auth
, sta
->addr
,
788 sta
->sae
->pmk
, sta
->sae
->pmkid
);
789 sae_sme_send_external_auth_status(hapd
, sta
, WLAN_STATUS_SUCCESS
);
793 static int sae_sm_step(struct hostapd_data
*hapd
, struct sta_info
*sta
,
794 const u8
*bssid
, u16 auth_transaction
, u16 status_code
,
795 int allow_reuse
, int *sta_removed
)
801 if (auth_transaction
!= 1 && auth_transaction
!= 2)
802 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
804 wpa_printf(MSG_DEBUG
, "SAE: Peer " MACSTR
" state=%s auth_trans=%u",
805 MAC2STR(sta
->addr
), sae_state_txt(sta
->sae
->state
),
807 switch (sta
->sae
->state
) {
809 if (auth_transaction
== 1) {
811 sta
->sae
->tmp
->h2e
= status_code
==
812 WLAN_STATUS_SAE_HASH_TO_ELEMENT
;
813 ret
= auth_sae_send_commit(hapd
, sta
, bssid
,
817 sae_set_state(sta
, SAE_COMMITTED
, "Sent Commit");
819 if (sae_process_commit(sta
->sae
) < 0)
820 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
823 * In mesh case, both Commit and Confirm are sent
824 * immediately. In infrastructure BSS, by default, only
825 * a single Authentication frame (Commit) is expected
826 * from the AP here and the second one (Confirm) will
827 * be sent once the STA has sent its second
828 * Authentication frame (Confirm). This behavior can be
829 * overridden with explicit configuration so that the
830 * infrastructure BSS case sends both frames together.
832 if ((hapd
->conf
->mesh
& MESH_ENABLED
) ||
833 hapd
->conf
->sae_confirm_immediate
) {
835 * Send both Commit and Confirm immediately
836 * based on SAE finite state machine
837 * Nothing -> Confirm transition.
839 ret
= auth_sae_send_confirm(hapd
, sta
, bssid
);
842 sae_set_state(sta
, SAE_CONFIRMED
,
843 "Sent Confirm (mesh)");
846 * For infrastructure BSS, send only the Commit
847 * message now to get alternating sequence of
848 * Authentication frames between the AP and STA.
849 * Confirm will be sent in
850 * Committed -> Confirmed/Accepted transition
851 * when receiving Confirm from STA.
855 sae_set_retransmit_timer(hapd
, sta
);
857 hostapd_logger(hapd
, sta
->addr
,
858 HOSTAPD_MODULE_IEEE80211
,
860 "SAE confirm before commit");
864 sae_clear_retransmit_timer(hapd
, sta
);
865 if (auth_transaction
== 1) {
866 if (sae_process_commit(sta
->sae
) < 0)
867 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
869 ret
= auth_sae_send_confirm(hapd
, sta
, bssid
);
872 sae_set_state(sta
, SAE_CONFIRMED
, "Sent Confirm");
874 sae_set_retransmit_timer(hapd
, sta
);
875 } else if (hapd
->conf
->mesh
& MESH_ENABLED
) {
877 * In mesh case, follow SAE finite state machine and
878 * send Commit now, if sync count allows.
880 if (sae_check_big_sync(hapd
, sta
))
881 return WLAN_STATUS_SUCCESS
;
884 ret
= auth_sae_send_commit(hapd
, sta
, bssid
, 0);
888 sae_set_retransmit_timer(hapd
, sta
);
891 * For instructure BSS, send the postponed Confirm from
892 * Nothing -> Confirmed transition that was reduced to
893 * Nothing -> Committed above.
895 ret
= auth_sae_send_confirm(hapd
, sta
, bssid
);
899 sae_set_state(sta
, SAE_CONFIRMED
, "Sent Confirm");
902 * Since this was triggered on Confirm RX, run another
903 * step to get to Accepted without waiting for
906 return sae_sm_step(hapd
, sta
, bssid
, auth_transaction
,
907 WLAN_STATUS_SUCCESS
, 0, sta_removed
);
911 sae_clear_retransmit_timer(hapd
, sta
);
912 if (auth_transaction
== 1) {
913 if (sae_check_big_sync(hapd
, sta
))
914 return WLAN_STATUS_SUCCESS
;
917 ret
= auth_sae_send_commit(hapd
, sta
, bssid
, 1);
921 if (sae_process_commit(sta
->sae
) < 0)
922 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
924 ret
= auth_sae_send_confirm(hapd
, sta
, bssid
);
928 sae_set_retransmit_timer(hapd
, sta
);
930 sta
->sae
->send_confirm
= 0xffff;
931 sae_accept_sta(hapd
, sta
);
935 if (auth_transaction
== 1 &&
936 (hapd
->conf
->mesh
& MESH_ENABLED
)) {
937 wpa_printf(MSG_DEBUG
, "SAE: remove the STA (" MACSTR
938 ") doing reauthentication",
940 wpa_auth_pmksa_remove(hapd
->wpa_auth
, sta
->addr
);
941 ap_free_sta(hapd
, sta
);
943 } else if (auth_transaction
== 1) {
944 wpa_printf(MSG_DEBUG
, "SAE: Start reauthentication");
945 ret
= auth_sae_send_commit(hapd
, sta
, bssid
, 1);
948 sae_set_state(sta
, SAE_COMMITTED
, "Sent Commit");
950 if (sae_process_commit(sta
->sae
) < 0)
951 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
953 sae_set_retransmit_timer(hapd
, sta
);
955 if (sae_check_big_sync(hapd
, sta
))
956 return WLAN_STATUS_SUCCESS
;
959 ret
= auth_sae_send_confirm(hapd
, sta
, bssid
);
960 sae_clear_temp_data(sta
->sae
);
966 wpa_printf(MSG_ERROR
, "SAE: invalid state %d",
968 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
970 return WLAN_STATUS_SUCCESS
;
974 static void sae_pick_next_group(struct hostapd_data
*hapd
, struct sta_info
*sta
)
976 struct sae_data
*sae
= sta
->sae
;
977 int i
, *groups
= hapd
->conf
->sae_groups
;
978 int default_groups
[] = { 19, 0 };
980 if (sae
->state
!= SAE_COMMITTED
)
983 wpa_printf(MSG_DEBUG
, "SAE: Previously selected group: %d", sae
->group
);
986 groups
= default_groups
;
987 for (i
= 0; groups
[i
] > 0; i
++) {
988 if (sae
->group
== groups
[i
])
992 if (groups
[i
] <= 0) {
993 wpa_printf(MSG_DEBUG
,
994 "SAE: Previously selected group not found from the current configuration");
1000 if (groups
[i
] <= 0) {
1001 wpa_printf(MSG_DEBUG
,
1002 "SAE: No alternative group enabled");
1006 if (sae_set_group(sae
, groups
[i
]) < 0)
1011 wpa_printf(MSG_DEBUG
, "SAE: Selected new group: %d", groups
[i
]);
1015 static int sae_status_success(struct hostapd_data
*hapd
, u16 status_code
)
1017 return (hapd
->conf
->sae_pwe
== 0 &&
1018 status_code
== WLAN_STATUS_SUCCESS
) ||
1019 (hapd
->conf
->sae_pwe
== 1 &&
1020 status_code
== WLAN_STATUS_SAE_HASH_TO_ELEMENT
) ||
1021 (hapd
->conf
->sae_pwe
== 2 &&
1022 (status_code
== WLAN_STATUS_SUCCESS
||
1023 status_code
== WLAN_STATUS_SAE_HASH_TO_ELEMENT
));
1027 static int sae_is_group_enabled(struct hostapd_data
*hapd
, int group
)
1029 int *groups
= hapd
->conf
->sae_groups
;
1030 int default_groups
[] = { 19, 0 };
1034 groups
= default_groups
;
1036 for (i
= 0; groups
[i
] > 0; i
++) {
1037 if (groups
[i
] == group
)
1045 static int check_sae_rejected_groups(struct hostapd_data
*hapd
,
1046 const struct wpabuf
*groups
)
1054 pos
= wpabuf_head(groups
);
1055 count
= wpabuf_len(groups
) / 2;
1056 for (i
= 0; i
< count
; i
++) {
1060 group
= WPA_GET_LE16(pos
);
1062 enabled
= sae_is_group_enabled(hapd
, group
);
1063 wpa_printf(MSG_DEBUG
, "SAE: Rejected group %u is %s",
1064 group
, enabled
? "enabled" : "disabled");
1073 static void handle_auth_sae(struct hostapd_data
*hapd
, struct sta_info
*sta
,
1074 const struct ieee80211_mgmt
*mgmt
, size_t len
,
1075 u16 auth_transaction
, u16 status_code
)
1077 int resp
= WLAN_STATUS_SUCCESS
;
1078 struct wpabuf
*data
= NULL
;
1079 int *groups
= hapd
->conf
->sae_groups
;
1080 int default_groups
[] = { 19, 0 };
1081 const u8
*pos
, *end
;
1082 int sta_removed
= 0;
1085 groups
= default_groups
;
1087 #ifdef CONFIG_TESTING_OPTIONS
1088 if (hapd
->conf
->sae_reflection_attack
&& auth_transaction
== 1) {
1089 wpa_printf(MSG_DEBUG
, "SAE: TESTING - reflection attack");
1090 pos
= mgmt
->u
.auth
.variable
;
1091 end
= ((const u8
*) mgmt
) + len
;
1092 send_auth_reply(hapd
, mgmt
->sa
, mgmt
->bssid
, WLAN_AUTH_SAE
,
1093 auth_transaction
, resp
, pos
, end
- pos
,
1094 "auth-sae-reflection-attack");
1098 if (hapd
->conf
->sae_commit_override
&& auth_transaction
== 1) {
1099 wpa_printf(MSG_DEBUG
, "SAE: TESTING - commit override");
1100 send_auth_reply(hapd
, mgmt
->sa
, mgmt
->bssid
, WLAN_AUTH_SAE
,
1101 auth_transaction
, resp
,
1102 wpabuf_head(hapd
->conf
->sae_commit_override
),
1103 wpabuf_len(hapd
->conf
->sae_commit_override
),
1104 "sae-commit-override");
1107 #endif /* CONFIG_TESTING_OPTIONS */
1109 if (auth_transaction
!= 1 ||
1110 !sae_status_success(hapd
, status_code
)) {
1114 sta
->sae
= os_zalloc(sizeof(*sta
->sae
));
1119 sae_set_state(sta
, SAE_NOTHING
, "Init");
1123 if (sta
->mesh_sae_pmksa_caching
) {
1124 wpa_printf(MSG_DEBUG
,
1125 "SAE: Cancel use of mesh PMKSA caching because peer starts SAE authentication");
1126 wpa_auth_pmksa_remove(hapd
->wpa_auth
, sta
->addr
);
1127 sta
->mesh_sae_pmksa_caching
= 0;
1130 if (auth_transaction
== 1) {
1131 const u8
*token
= NULL
;
1132 size_t token_len
= 0;
1133 int allow_reuse
= 0;
1135 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1136 HOSTAPD_LEVEL_DEBUG
,
1137 "start SAE authentication (RX commit, status=%u (%s))",
1138 status_code
, status2str(status_code
));
1140 if ((hapd
->conf
->mesh
& MESH_ENABLED
) &&
1141 status_code
== WLAN_STATUS_ANTI_CLOGGING_TOKEN_REQ
&&
1143 pos
= mgmt
->u
.auth
.variable
;
1144 end
= ((const u8
*) mgmt
) + len
;
1145 if (pos
+ sizeof(le16
) > end
) {
1146 wpa_printf(MSG_ERROR
,
1147 "SAE: Too short anti-clogging token request");
1148 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1151 resp
= sae_group_allowed(sta
->sae
, groups
,
1153 if (resp
!= WLAN_STATUS_SUCCESS
) {
1154 wpa_printf(MSG_ERROR
,
1155 "SAE: Invalid group in anti-clogging token request");
1158 pos
+= sizeof(le16
);
1160 wpabuf_free(sta
->sae
->tmp
->anti_clogging_token
);
1161 sta
->sae
->tmp
->anti_clogging_token
=
1162 wpabuf_alloc_copy(pos
, end
- pos
);
1163 if (sta
->sae
->tmp
->anti_clogging_token
== NULL
) {
1164 wpa_printf(MSG_ERROR
,
1165 "SAE: Failed to alloc for anti-clogging token");
1166 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1171 * IEEE Std 802.11-2012, 11.3.8.6.4: If the Status code
1172 * is 76, a new Commit Message shall be constructed
1173 * with the Anti-Clogging Token from the received
1174 * Authentication frame, and the commit-scalar and
1175 * COMMIT-ELEMENT previously sent.
1177 resp
= auth_sae_send_commit(hapd
, sta
, mgmt
->bssid
, 0);
1178 if (resp
!= WLAN_STATUS_SUCCESS
) {
1179 wpa_printf(MSG_ERROR
,
1180 "SAE: Failed to send commit message");
1183 sae_set_state(sta
, SAE_COMMITTED
,
1184 "Sent Commit (anti-clogging token case in mesh)");
1186 sae_set_retransmit_timer(hapd
, sta
);
1190 if ((hapd
->conf
->mesh
& MESH_ENABLED
) &&
1192 WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED
&&
1194 wpa_printf(MSG_DEBUG
,
1195 "SAE: Peer did not accept our SAE group");
1196 sae_pick_next_group(hapd
, sta
);
1200 if (!sae_status_success(hapd
, status_code
))
1203 if (!(hapd
->conf
->mesh
& MESH_ENABLED
) &&
1204 sta
->sae
->state
== SAE_COMMITTED
) {
1205 /* This is needed in the infrastructure BSS case to
1206 * address a sequence where a STA entry may remain in
1207 * hostapd across two attempts to do SAE authentication
1208 * by the same STA. The second attempt may end up trying
1209 * to use a different group and that would not be
1210 * allowed if we remain in Committed state with the
1211 * previously set parameters. */
1212 pos
= mgmt
->u
.auth
.variable
;
1213 end
= ((const u8
*) mgmt
) + len
;
1214 if (end
- pos
>= (int) sizeof(le16
) &&
1215 sae_group_allowed(sta
->sae
, groups
,
1216 WPA_GET_LE16(pos
)) ==
1217 WLAN_STATUS_SUCCESS
) {
1218 /* Do not waste resources deriving the same PWE
1219 * again since the same group is reused. */
1220 sae_set_state(sta
, SAE_NOTHING
,
1221 "Allow previous PWE to be reused");
1224 sae_set_state(sta
, SAE_NOTHING
,
1225 "Clear existing state to allow restart");
1226 sae_clear_data(sta
->sae
);
1230 resp
= sae_parse_commit(sta
->sae
, mgmt
->u
.auth
.variable
,
1231 ((const u8
*) mgmt
) + len
-
1232 mgmt
->u
.auth
.variable
, &token
,
1233 &token_len
, groups
, status_code
==
1234 WLAN_STATUS_SAE_HASH_TO_ELEMENT
);
1235 if (resp
== SAE_SILENTLY_DISCARD
) {
1236 wpa_printf(MSG_DEBUG
,
1237 "SAE: Drop commit message from " MACSTR
" due to reflection attack",
1238 MAC2STR(sta
->addr
));
1242 if (resp
== WLAN_STATUS_UNKNOWN_PASSWORD_IDENTIFIER
) {
1243 wpa_msg(hapd
->msg_ctx
, MSG_INFO
,
1244 WPA_EVENT_SAE_UNKNOWN_PASSWORD_IDENTIFIER
1245 MACSTR
, MAC2STR(sta
->addr
));
1246 sae_clear_retransmit_timer(hapd
, sta
);
1247 sae_set_state(sta
, SAE_NOTHING
,
1248 "Unknown Password Identifier");
1252 if (token
&& check_sae_token(hapd
, sta
->addr
, token
, token_len
)
1254 wpa_printf(MSG_DEBUG
, "SAE: Drop commit message with "
1255 "incorrect token from " MACSTR
,
1256 MAC2STR(sta
->addr
));
1257 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1261 if (resp
!= WLAN_STATUS_SUCCESS
)
1264 if (sta
->sae
->tmp
&&
1265 check_sae_rejected_groups(
1266 hapd
, sta
->sae
->tmp
->peer_rejected_groups
) < 0) {
1267 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1271 if (!token
&& use_sae_anti_clogging(hapd
) && !allow_reuse
) {
1272 wpa_printf(MSG_DEBUG
,
1273 "SAE: Request anti-clogging token from "
1274 MACSTR
, MAC2STR(sta
->addr
));
1275 data
= auth_build_token_req(hapd
, sta
->sae
->group
,
1277 resp
= WLAN_STATUS_ANTI_CLOGGING_TOKEN_REQ
;
1278 if (hapd
->conf
->mesh
& MESH_ENABLED
)
1279 sae_set_state(sta
, SAE_NOTHING
,
1280 "Request anti-clogging token case in mesh");
1284 resp
= sae_sm_step(hapd
, sta
, mgmt
->bssid
, auth_transaction
,
1285 status_code
, allow_reuse
, &sta_removed
);
1286 } else if (auth_transaction
== 2) {
1287 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1288 HOSTAPD_LEVEL_DEBUG
,
1289 "SAE authentication (RX confirm, status=%u (%s))",
1290 status_code
, status2str(status_code
));
1291 if (status_code
!= WLAN_STATUS_SUCCESS
)
1293 if (sta
->sae
->state
>= SAE_CONFIRMED
||
1294 !(hapd
->conf
->mesh
& MESH_ENABLED
)) {
1297 u16 peer_send_confirm
;
1299 var
= mgmt
->u
.auth
.variable
;
1300 var_len
= ((u8
*) mgmt
) + len
- mgmt
->u
.auth
.variable
;
1302 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1306 peer_send_confirm
= WPA_GET_LE16(var
);
1308 if (sta
->sae
->state
== SAE_ACCEPTED
&&
1309 (peer_send_confirm
<= sta
->sae
->rc
||
1310 peer_send_confirm
== 0xffff)) {
1311 wpa_printf(MSG_DEBUG
,
1312 "SAE: Silently ignore unexpected Confirm from peer "
1314 " (peer-send-confirm=%u Rc=%u)",
1316 peer_send_confirm
, sta
->sae
->rc
);
1320 if (sae_check_confirm(sta
->sae
, var
, var_len
) < 0) {
1321 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1324 sta
->sae
->rc
= peer_send_confirm
;
1326 resp
= sae_sm_step(hapd
, sta
, mgmt
->bssid
, auth_transaction
,
1327 status_code
, 0, &sta_removed
);
1329 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1330 HOSTAPD_LEVEL_DEBUG
,
1331 "unexpected SAE authentication transaction %u (status=%u (%s))",
1332 auth_transaction
, status_code
,
1333 status2str(status_code
));
1334 if (status_code
!= WLAN_STATUS_SUCCESS
)
1336 resp
= WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION
;
1340 if (!sta_removed
&& resp
!= WLAN_STATUS_SUCCESS
) {
1341 pos
= mgmt
->u
.auth
.variable
;
1342 end
= ((const u8
*) mgmt
) + len
;
1344 /* Copy the Finite Cyclic Group field from the request if we
1345 * rejected it as unsupported group. */
1346 if (resp
== WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED
&&
1347 !data
&& end
- pos
>= 2)
1348 data
= wpabuf_alloc_copy(pos
, 2);
1350 sae_sme_send_external_auth_status(hapd
, sta
, resp
);
1351 send_auth_reply(hapd
, mgmt
->sa
, mgmt
->bssid
, WLAN_AUTH_SAE
,
1352 auth_transaction
, resp
,
1353 data
? wpabuf_head(data
) : (u8
*) "",
1354 data
? wpabuf_len(data
) : 0, "auth-sae");
1358 if (!sta_removed
&& sta
->added_unassoc
&&
1359 (resp
!= WLAN_STATUS_SUCCESS
||
1360 status_code
!= WLAN_STATUS_SUCCESS
)) {
1361 hostapd_drv_sta_remove(hapd
, sta
->addr
);
1362 sta
->added_unassoc
= 0;
1369 * auth_sae_init_committed - Send COMMIT and start SAE in committed state
1370 * @hapd: BSS data for the device initiating the authentication
1371 * @sta: the peer to which commit authentication frame is sent
1373 * This function implements Init event handling (IEEE Std 802.11-2012,
1374 * 11.3.8.6.3) in which initial COMMIT message is sent. Prior to calling, the
1375 * sta->sae structure should be initialized appropriately via a call to
1376 * sae_prepare_commit().
1378 int auth_sae_init_committed(struct hostapd_data
*hapd
, struct sta_info
*sta
)
1382 if (!sta
->sae
|| !sta
->sae
->tmp
)
1385 if (sta
->sae
->state
!= SAE_NOTHING
)
1388 ret
= auth_sae_send_commit(hapd
, sta
, hapd
->own_addr
, 0);
1392 sae_set_state(sta
, SAE_COMMITTED
, "Init and sent commit");
1394 sae_set_retransmit_timer(hapd
, sta
);
1400 void auth_sae_process_commit(void *eloop_ctx
, void *user_ctx
)
1402 struct hostapd_data
*hapd
= eloop_ctx
;
1403 struct hostapd_sae_commit_queue
*q
;
1404 unsigned int queue_len
;
1406 q
= dl_list_first(&hapd
->sae_commit_queue
,
1407 struct hostapd_sae_commit_queue
, list
);
1410 wpa_printf(MSG_DEBUG
,
1411 "SAE: Process next available message from queue");
1412 dl_list_del(&q
->list
);
1413 handle_auth(hapd
, (const struct ieee80211_mgmt
*) q
->msg
, q
->len
,
1417 if (eloop_is_timeout_registered(auth_sae_process_commit
, hapd
, NULL
))
1419 queue_len
= dl_list_len(&hapd
->sae_commit_queue
);
1420 eloop_register_timeout(0, queue_len
* 10000, auth_sae_process_commit
,
1425 static void auth_sae_queue(struct hostapd_data
*hapd
,
1426 const struct ieee80211_mgmt
*mgmt
, size_t len
,
1429 struct hostapd_sae_commit_queue
*q
, *q2
;
1430 unsigned int queue_len
;
1431 const struct ieee80211_mgmt
*mgmt2
;
1433 queue_len
= dl_list_len(&hapd
->sae_commit_queue
);
1434 if (queue_len
>= 15) {
1435 wpa_printf(MSG_DEBUG
,
1436 "SAE: No more room in message queue - drop the new frame from "
1437 MACSTR
, MAC2STR(mgmt
->sa
));
1441 wpa_printf(MSG_DEBUG
, "SAE: Queue Authentication message from "
1442 MACSTR
" for processing (queue_len %u)", MAC2STR(mgmt
->sa
),
1444 q
= os_zalloc(sizeof(*q
) + len
);
1449 os_memcpy(q
->msg
, mgmt
, len
);
1451 /* Check whether there is already a queued Authentication frame from the
1452 * same station with the same transaction number and if so, replace that
1453 * queue entry with the new one. This avoids issues with a peer that
1454 * sends multiple times (e.g., due to frequent SAE retries). There is no
1455 * point in us trying to process the old attempts after a new one has
1456 * obsoleted them. */
1457 dl_list_for_each(q2
, &hapd
->sae_commit_queue
,
1458 struct hostapd_sae_commit_queue
, list
) {
1459 mgmt2
= (const struct ieee80211_mgmt
*) q2
->msg
;
1460 if (os_memcmp(mgmt
->sa
, mgmt2
->sa
, ETH_ALEN
) == 0 &&
1461 mgmt
->u
.auth
.auth_transaction
==
1462 mgmt2
->u
.auth
.auth_transaction
) {
1463 wpa_printf(MSG_DEBUG
,
1464 "SAE: Replace queued message from same STA with same transaction number");
1465 dl_list_add(&q2
->list
, &q
->list
);
1466 dl_list_del(&q2
->list
);
1472 /* No pending identical entry, so add to the end of the queue */
1473 dl_list_add_tail(&hapd
->sae_commit_queue
, &q
->list
);
1476 if (eloop_is_timeout_registered(auth_sae_process_commit
, hapd
, NULL
))
1478 eloop_register_timeout(0, queue_len
* 10000, auth_sae_process_commit
,
1483 static int auth_sae_queued_addr(struct hostapd_data
*hapd
, const u8
*addr
)
1485 struct hostapd_sae_commit_queue
*q
;
1486 const struct ieee80211_mgmt
*mgmt
;
1488 dl_list_for_each(q
, &hapd
->sae_commit_queue
,
1489 struct hostapd_sae_commit_queue
, list
) {
1490 mgmt
= (const struct ieee80211_mgmt
*) q
->msg
;
1491 if (os_memcmp(addr
, mgmt
->sa
, ETH_ALEN
) == 0)
1498 #endif /* CONFIG_SAE */
1501 static u16
wpa_res_to_status_code(int res
)
1503 if (res
== WPA_INVALID_GROUP
)
1504 return WLAN_STATUS_GROUP_CIPHER_NOT_VALID
;
1505 if (res
== WPA_INVALID_PAIRWISE
)
1506 return WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID
;
1507 if (res
== WPA_INVALID_AKMP
)
1508 return WLAN_STATUS_AKMP_NOT_VALID
;
1509 if (res
== WPA_ALLOC_FAIL
)
1510 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
1511 if (res
== WPA_MGMT_FRAME_PROTECTION_VIOLATION
)
1512 return WLAN_STATUS_ROBUST_MGMT_FRAME_POLICY_VIOLATION
;
1513 if (res
== WPA_INVALID_MGMT_GROUP_CIPHER
)
1514 return WLAN_STATUS_CIPHER_REJECTED_PER_POLICY
;
1515 if (res
== WPA_INVALID_MDIE
)
1516 return WLAN_STATUS_INVALID_MDIE
;
1517 if (res
== WPA_INVALID_PMKID
)
1518 return WLAN_STATUS_INVALID_PMKID
;
1519 if (res
!= WPA_IE_OK
)
1520 return WLAN_STATUS_INVALID_IE
;
1521 return WLAN_STATUS_SUCCESS
;
1527 static void handle_auth_fils_finish(struct hostapd_data
*hapd
,
1528 struct sta_info
*sta
, u16 resp
,
1529 struct wpabuf
*data
, int pub
);
1531 void handle_auth_fils(struct hostapd_data
*hapd
, struct sta_info
*sta
,
1532 const u8
*pos
, size_t len
, u16 auth_alg
,
1533 u16 auth_transaction
, u16 status_code
,
1534 void (*cb
)(struct hostapd_data
*hapd
,
1535 struct sta_info
*sta
, u16 resp
,
1536 struct wpabuf
*data
, int pub
))
1538 u16 resp
= WLAN_STATUS_SUCCESS
;
1540 struct ieee802_11_elems elems
;
1542 struct wpa_ie_data rsn
;
1543 struct rsn_pmksa_cache_entry
*pmksa
= NULL
;
1545 if (auth_transaction
!= 1 || status_code
!= WLAN_STATUS_SUCCESS
)
1550 wpa_hexdump(MSG_DEBUG
, "FILS: Authentication frame fields",
1554 #ifdef CONFIG_FILS_SK_PFS
1555 if (auth_alg
== WLAN_AUTH_FILS_SK_PFS
) {
1560 /* Using FILS PFS */
1562 /* Finite Cyclic Group */
1563 if (end
- pos
< 2) {
1564 wpa_printf(MSG_DEBUG
,
1565 "FILS: No room for Finite Cyclic Group");
1566 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1569 group
= WPA_GET_LE16(pos
);
1571 if (group
!= hapd
->conf
->fils_dh_group
) {
1572 wpa_printf(MSG_DEBUG
,
1573 "FILS: Unsupported Finite Cyclic Group: %u (expected %u)",
1574 group
, hapd
->conf
->fils_dh_group
);
1575 resp
= WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED
;
1579 crypto_ecdh_deinit(sta
->fils_ecdh
);
1580 sta
->fils_ecdh
= crypto_ecdh_init(group
);
1581 if (!sta
->fils_ecdh
) {
1582 wpa_printf(MSG_INFO
,
1583 "FILS: Could not initialize ECDH with group %d",
1585 resp
= WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED
;
1589 pub
= crypto_ecdh_get_pubkey(sta
->fils_ecdh
, 1);
1591 wpa_printf(MSG_DEBUG
,
1592 "FILS: Failed to derive ECDH public key");
1593 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1596 elem_len
= wpabuf_len(pub
);
1600 if ((size_t) (end
- pos
) < elem_len
) {
1601 wpa_printf(MSG_DEBUG
, "FILS: No room for Element");
1602 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1606 wpabuf_free(sta
->fils_g_sta
);
1607 sta
->fils_g_sta
= wpabuf_alloc_copy(pos
, elem_len
);
1608 wpabuf_clear_free(sta
->fils_dh_ss
);
1609 sta
->fils_dh_ss
= crypto_ecdh_set_peerkey(sta
->fils_ecdh
, 1,
1611 if (!sta
->fils_dh_ss
) {
1612 wpa_printf(MSG_DEBUG
, "FILS: ECDH operation failed");
1613 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1616 wpa_hexdump_buf_key(MSG_DEBUG
, "FILS: DH_SS", sta
->fils_dh_ss
);
1619 crypto_ecdh_deinit(sta
->fils_ecdh
);
1620 sta
->fils_ecdh
= NULL
;
1621 wpabuf_clear_free(sta
->fils_dh_ss
);
1622 sta
->fils_dh_ss
= NULL
;
1624 #endif /* CONFIG_FILS_SK_PFS */
1626 wpa_hexdump(MSG_DEBUG
, "FILS: Remaining IEs", pos
, end
- pos
);
1627 if (ieee802_11_parse_elems(pos
, end
- pos
, &elems
, 1) == ParseFailed
) {
1628 wpa_printf(MSG_DEBUG
, "FILS: Could not parse elements");
1629 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1634 wpa_hexdump(MSG_DEBUG
, "FILS: RSN element",
1635 elems
.rsn_ie
, elems
.rsn_ie_len
);
1636 if (!elems
.rsn_ie
||
1637 wpa_parse_wpa_ie_rsn(elems
.rsn_ie
- 2, elems
.rsn_ie_len
+ 2,
1639 wpa_printf(MSG_DEBUG
, "FILS: No valid RSN element");
1640 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1645 sta
->wpa_sm
= wpa_auth_sta_init(hapd
->wpa_auth
, sta
->addr
,
1648 wpa_printf(MSG_DEBUG
,
1649 "FILS: Failed to initialize RSN state machine");
1650 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1654 res
= wpa_validate_wpa_ie(hapd
->wpa_auth
, sta
->wpa_sm
,
1656 elems
.rsn_ie
- 2, elems
.rsn_ie_len
+ 2,
1657 elems
.mdie
, elems
.mdie_len
, NULL
, 0);
1658 resp
= wpa_res_to_status_code(res
);
1659 if (resp
!= WLAN_STATUS_SUCCESS
)
1662 if (!elems
.fils_nonce
) {
1663 wpa_printf(MSG_DEBUG
, "FILS: No FILS Nonce field");
1664 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1667 wpa_hexdump(MSG_DEBUG
, "FILS: SNonce", elems
.fils_nonce
,
1669 os_memcpy(sta
->fils_snonce
, elems
.fils_nonce
, FILS_NONCE_LEN
);
1672 if (rsn
.pmkid
&& rsn
.num_pmkid
> 0) {
1676 wpa_hexdump(MSG_DEBUG
, "FILS: PMKID List",
1677 rsn
.pmkid
, rsn
.num_pmkid
* PMKID_LEN
);
1680 num
= rsn
.num_pmkid
;
1682 wpa_hexdump(MSG_DEBUG
, "FILS: PMKID", pmkid
, PMKID_LEN
);
1683 pmksa
= wpa_auth_pmksa_get(hapd
->wpa_auth
, sta
->addr
,
1687 pmksa
= wpa_auth_pmksa_get_fils_cache_id(hapd
->wpa_auth
,
1696 if (pmksa
&& wpa_auth_sta_key_mgmt(sta
->wpa_sm
) != pmksa
->akmp
) {
1697 wpa_printf(MSG_DEBUG
,
1698 "FILS: Matching PMKSA cache entry has different AKMP (0x%x != 0x%x) - ignore",
1699 wpa_auth_sta_key_mgmt(sta
->wpa_sm
), pmksa
->akmp
);
1703 wpa_printf(MSG_DEBUG
, "FILS: Found matching PMKSA cache entry");
1706 if (!elems
.fils_session
) {
1707 wpa_printf(MSG_DEBUG
, "FILS: No FILS Session element");
1708 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1711 wpa_hexdump(MSG_DEBUG
, "FILS: FILS Session", elems
.fils_session
,
1713 os_memcpy(sta
->fils_session
, elems
.fils_session
, FILS_SESSION_LEN
);
1715 /* FILS Wrapped Data */
1716 if (elems
.fils_wrapped_data
) {
1717 wpa_hexdump(MSG_DEBUG
, "FILS: Wrapped Data",
1718 elems
.fils_wrapped_data
,
1719 elems
.fils_wrapped_data_len
);
1721 #ifndef CONFIG_NO_RADIUS
1722 if (!sta
->eapol_sm
) {
1724 ieee802_1x_alloc_eapol_sm(hapd
, sta
);
1726 wpa_printf(MSG_DEBUG
,
1727 "FILS: Forward EAP-Initiate/Re-auth to authentication server");
1728 ieee802_1x_encapsulate_radius(
1729 hapd
, sta
, elems
.fils_wrapped_data
,
1730 elems
.fils_wrapped_data_len
);
1731 sta
->fils_pending_cb
= cb
;
1732 wpa_printf(MSG_DEBUG
,
1733 "FILS: Will send Authentication frame once the response from authentication server is available");
1734 sta
->flags
|= WLAN_STA_PENDING_FILS_ERP
;
1735 /* Calculate pending PMKID here so that we do not need
1736 * to maintain a copy of the EAP-Initiate/Reauth
1738 if (fils_pmkid_erp(wpa_auth_sta_key_mgmt(sta
->wpa_sm
),
1739 elems
.fils_wrapped_data
,
1740 elems
.fils_wrapped_data_len
,
1741 sta
->fils_erp_pmkid
) == 0)
1742 sta
->fils_erp_pmkid_set
= 1;
1744 #else /* CONFIG_NO_RADIUS */
1745 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1747 #endif /* CONFIG_NO_RADIUS */
1753 struct wpabuf
*data
;
1756 data
= prepare_auth_resp_fils(hapd
, sta
, &resp
, pmksa
, NULL
,
1759 wpa_printf(MSG_DEBUG
,
1760 "%s: prepare_auth_resp_fils() returned failure",
1764 cb(hapd
, sta
, resp
, data
, pub
);
1769 static struct wpabuf
*
1770 prepare_auth_resp_fils(struct hostapd_data
*hapd
,
1771 struct sta_info
*sta
, u16
*resp
,
1772 struct rsn_pmksa_cache_entry
*pmksa
,
1773 struct wpabuf
*erp_resp
,
1774 const u8
*msk
, size_t msk_len
,
1777 u8 fils_nonce
[FILS_NONCE_LEN
];
1779 struct wpabuf
*data
= NULL
;
1782 const u8
*pmk
= NULL
;
1784 u8 pmk_buf
[PMK_LEN_MAX
];
1785 struct wpabuf
*pub
= NULL
;
1787 if (*resp
!= WLAN_STATUS_SUCCESS
)
1790 ie
= wpa_auth_get_wpa_ie(hapd
->wpa_auth
, &ielen
);
1792 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1797 /* Add PMKID of the selected PMKSA into RSNE */
1798 ie_buf
= os_malloc(ielen
+ 2 + 2 + PMKID_LEN
);
1800 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1804 os_memcpy(ie_buf
, ie
, ielen
);
1805 if (wpa_insert_pmkid(ie_buf
, &ielen
, pmksa
->pmkid
) < 0) {
1806 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1812 if (random_get_bytes(fils_nonce
, FILS_NONCE_LEN
) < 0) {
1813 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1816 wpa_hexdump(MSG_DEBUG
, "RSN: Generated FILS Nonce",
1817 fils_nonce
, FILS_NONCE_LEN
);
1819 #ifdef CONFIG_FILS_SK_PFS
1820 if (sta
->fils_dh_ss
&& sta
->fils_ecdh
) {
1821 pub
= crypto_ecdh_get_pubkey(sta
->fils_ecdh
, 1);
1823 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1827 #endif /* CONFIG_FILS_SK_PFS */
1829 data
= wpabuf_alloc(1000 + ielen
+ (pub
? wpabuf_len(pub
) : 0));
1831 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1836 #ifdef CONFIG_FILS_SK_PFS
1838 /* Finite Cyclic Group */
1839 wpabuf_put_le16(data
, hapd
->conf
->fils_dh_group
);
1842 wpabuf_put_buf(data
, pub
);
1844 #endif /* CONFIG_FILS_SK_PFS */
1847 wpabuf_put_data(data
, ie
, ielen
);
1849 /* MDE when using FILS+FT (already included in ie,ielen with RSNE) */
1851 #ifdef CONFIG_IEEE80211R_AP
1852 if (wpa_key_mgmt_ft(wpa_auth_sta_key_mgmt(sta
->wpa_sm
))) {
1853 /* FTE[R1KH-ID,R0KH-ID] when using FILS+FT */
1855 int use_sha384
= wpa_key_mgmt_sha384(
1856 wpa_auth_sta_key_mgmt(sta
->wpa_sm
));
1858 res
= wpa_auth_write_fte(hapd
->wpa_auth
, use_sha384
,
1859 wpabuf_put(data
, 0),
1860 wpabuf_tailroom(data
));
1862 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1865 wpabuf_put(data
, res
);
1867 #endif /* CONFIG_IEEE80211R_AP */
1870 wpabuf_put_u8(data
, WLAN_EID_EXTENSION
); /* Element ID */
1871 wpabuf_put_u8(data
, 1 + FILS_NONCE_LEN
); /* Length */
1872 /* Element ID Extension */
1873 wpabuf_put_u8(data
, WLAN_EID_EXT_FILS_NONCE
);
1874 wpabuf_put_data(data
, fils_nonce
, FILS_NONCE_LEN
);
1877 wpabuf_put_u8(data
, WLAN_EID_EXTENSION
); /* Element ID */
1878 wpabuf_put_u8(data
, 1 + FILS_SESSION_LEN
); /* Length */
1879 /* Element ID Extension */
1880 wpabuf_put_u8(data
, WLAN_EID_EXT_FILS_SESSION
);
1881 wpabuf_put_data(data
, sta
->fils_session
, FILS_SESSION_LEN
);
1883 /* FILS Wrapped Data */
1884 if (!pmksa
&& erp_resp
) {
1885 wpabuf_put_u8(data
, WLAN_EID_EXTENSION
); /* Element ID */
1886 wpabuf_put_u8(data
, 1 + wpabuf_len(erp_resp
)); /* Length */
1887 /* Element ID Extension */
1888 wpabuf_put_u8(data
, WLAN_EID_EXT_FILS_WRAPPED_DATA
);
1889 wpabuf_put_buf(data
, erp_resp
);
1891 if (fils_rmsk_to_pmk(wpa_auth_sta_key_mgmt(sta
->wpa_sm
),
1892 msk
, msk_len
, sta
->fils_snonce
, fils_nonce
,
1894 wpabuf_head(sta
->fils_dh_ss
) : NULL
,
1896 wpabuf_len(sta
->fils_dh_ss
) : 0,
1897 pmk_buf
, &pmk_len
)) {
1898 wpa_printf(MSG_DEBUG
, "FILS: Failed to derive PMK");
1899 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1906 /* Don't use DHss in PTK derivation if PMKSA caching is not
1908 wpabuf_clear_free(sta
->fils_dh_ss
);
1909 sta
->fils_dh_ss
= NULL
;
1911 if (sta
->fils_erp_pmkid_set
) {
1912 /* TODO: get PMKLifetime from WPA parameters */
1913 unsigned int dot11RSNAConfigPMKLifetime
= 43200;
1914 int session_timeout
;
1916 session_timeout
= dot11RSNAConfigPMKLifetime
;
1917 if (sta
->session_timeout_set
) {
1918 struct os_reltime now
, diff
;
1920 os_get_reltime(&now
);
1921 os_reltime_sub(&sta
->session_timeout
, &now
,
1923 session_timeout
= diff
.sec
;
1926 sta
->fils_erp_pmkid_set
= 0;
1927 wpa_auth_add_fils_pmk_pmkid(sta
->wpa_sm
, pmk
, pmk_len
,
1928 sta
->fils_erp_pmkid
);
1929 if (!hapd
->conf
->disable_pmksa_caching
&&
1930 wpa_auth_pmksa_add2(
1931 hapd
->wpa_auth
, sta
->addr
,
1933 sta
->fils_erp_pmkid
,
1935 wpa_auth_sta_key_mgmt(sta
->wpa_sm
)) < 0) {
1936 wpa_printf(MSG_ERROR
,
1937 "FILS: Failed to add PMKSA cache entry based on ERP");
1942 pmk_len
= pmksa
->pmk_len
;
1946 wpa_printf(MSG_DEBUG
, "FILS: No PMK available");
1947 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1953 if (fils_auth_pmk_to_ptk(sta
->wpa_sm
, pmk
, pmk_len
,
1954 sta
->fils_snonce
, fils_nonce
,
1956 wpabuf_head(sta
->fils_dh_ss
) : NULL
,
1958 wpabuf_len(sta
->fils_dh_ss
) : 0,
1959 sta
->fils_g_sta
, pub
) < 0) {
1960 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1968 *is_pub
= pub
!= NULL
;
1971 wpabuf_clear_free(sta
->fils_dh_ss
);
1972 sta
->fils_dh_ss
= NULL
;
1973 #ifdef CONFIG_FILS_SK_PFS
1974 crypto_ecdh_deinit(sta
->fils_ecdh
);
1975 sta
->fils_ecdh
= NULL
;
1976 #endif /* CONFIG_FILS_SK_PFS */
1981 static void handle_auth_fils_finish(struct hostapd_data
*hapd
,
1982 struct sta_info
*sta
, u16 resp
,
1983 struct wpabuf
*data
, int pub
)
1988 resp
== WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED
) ?
1989 WLAN_AUTH_FILS_SK_PFS
: WLAN_AUTH_FILS_SK
;
1990 send_auth_reply(hapd
, sta
->addr
, hapd
->own_addr
, auth_alg
, 2, resp
,
1991 data
? wpabuf_head(data
) : (u8
*) "",
1992 data
? wpabuf_len(data
) : 0, "auth-fils-finish");
1995 if (resp
== WLAN_STATUS_SUCCESS
) {
1996 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1997 HOSTAPD_LEVEL_DEBUG
,
1998 "authentication OK (FILS)");
1999 sta
->flags
|= WLAN_STA_AUTH
;
2000 wpa_auth_sm_event(sta
->wpa_sm
, WPA_AUTH
);
2001 sta
->auth_alg
= pub
? WLAN_AUTH_FILS_SK_PFS
: WLAN_AUTH_FILS_SK
;
2002 mlme_authenticate_indication(hapd
, sta
);
2007 void ieee802_11_finish_fils_auth(struct hostapd_data
*hapd
,
2008 struct sta_info
*sta
, int success
,
2009 struct wpabuf
*erp_resp
,
2010 const u8
*msk
, size_t msk_len
)
2012 struct wpabuf
*data
;
2016 sta
->flags
&= ~WLAN_STA_PENDING_FILS_ERP
;
2018 if (!sta
->fils_pending_cb
)
2020 resp
= success
? WLAN_STATUS_SUCCESS
: WLAN_STATUS_UNSPECIFIED_FAILURE
;
2021 data
= prepare_auth_resp_fils(hapd
, sta
, &resp
, NULL
, erp_resp
,
2022 msk
, msk_len
, &pub
);
2024 wpa_printf(MSG_DEBUG
,
2025 "%s: prepare_auth_resp_fils() returned failure",
2028 sta
->fils_pending_cb(hapd
, sta
, resp
, data
, pub
);
2031 #endif /* CONFIG_FILS */
2035 ieee802_11_allowed_address(struct hostapd_data
*hapd
, const u8
*addr
,
2036 const u8
*msg
, size_t len
, u32
*session_timeout
,
2037 u32
*acct_interim_interval
,
2038 struct vlan_description
*vlan_id
,
2039 struct hostapd_sta_wpa_psk_short
**psk
,
2040 char **identity
, char **radius_cui
, int is_probe_req
)
2044 os_memset(vlan_id
, 0, sizeof(*vlan_id
));
2045 res
= hostapd_allowed_address(hapd
, addr
, msg
, len
,
2046 session_timeout
, acct_interim_interval
,
2047 vlan_id
, psk
, identity
, radius_cui
,
2050 if (res
== HOSTAPD_ACL_REJECT
) {
2052 wpa_printf(MSG_DEBUG
,
2054 " not allowed to authenticate",
2056 return HOSTAPD_ACL_REJECT
;
2059 if (res
== HOSTAPD_ACL_PENDING
) {
2060 wpa_printf(MSG_DEBUG
, "Authentication frame from " MACSTR
2061 " waiting for an external authentication",
2063 /* Authentication code will re-send the authentication frame
2064 * after it has received (and cached) information from the
2065 * external source. */
2066 return HOSTAPD_ACL_PENDING
;
2074 ieee802_11_set_radius_info(struct hostapd_data
*hapd
, struct sta_info
*sta
,
2075 int res
, u32 session_timeout
,
2076 u32 acct_interim_interval
,
2077 struct vlan_description
*vlan_id
,
2078 struct hostapd_sta_wpa_psk_short
**psk
,
2079 char **identity
, char **radius_cui
)
2081 if (vlan_id
->notempty
&&
2082 !hostapd_vlan_valid(hapd
->conf
->vlan
, vlan_id
)) {
2083 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_RADIUS
,
2085 "Invalid VLAN %d%s received from RADIUS server",
2087 vlan_id
->tagged
[0] ? "+" : "");
2090 if (ap_sta_set_vlan(hapd
, sta
, vlan_id
) < 0)
2093 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_RADIUS
,
2094 HOSTAPD_LEVEL_INFO
, "VLAN ID %d", sta
->vlan_id
);
2096 hostapd_free_psk_list(sta
->psk
);
2097 if (hapd
->conf
->wpa_psk_radius
!= PSK_RADIUS_IGNORED
) {
2104 os_free(sta
->identity
);
2105 sta
->identity
= *identity
;
2108 os_free(sta
->radius_cui
);
2109 sta
->radius_cui
= *radius_cui
;
2112 if (hapd
->conf
->acct_interim_interval
== 0 && acct_interim_interval
)
2113 sta
->acct_interim_interval
= acct_interim_interval
;
2114 if (res
== HOSTAPD_ACL_ACCEPT_TIMEOUT
) {
2115 sta
->session_timeout_set
= 1;
2116 os_get_reltime(&sta
->session_timeout
);
2117 sta
->session_timeout
.sec
+= session_timeout
;
2118 ap_sta_session_timeout(hapd
, sta
, session_timeout
);
2120 sta
->session_timeout_set
= 0;
2121 ap_sta_no_session_timeout(hapd
, sta
);
2128 static void handle_auth(struct hostapd_data
*hapd
,
2129 const struct ieee80211_mgmt
*mgmt
, size_t len
,
2130 int rssi
, int from_queue
)
2132 u16 auth_alg
, auth_transaction
, status_code
;
2133 u16 resp
= WLAN_STATUS_SUCCESS
;
2134 struct sta_info
*sta
= NULL
;
2137 const u8
*challenge
= NULL
;
2138 u32 session_timeout
, acct_interim_interval
;
2139 struct vlan_description vlan_id
;
2140 struct hostapd_sta_wpa_psk_short
*psk
= NULL
;
2141 u8 resp_ies
[2 + WLAN_AUTH_CHALLENGE_LEN
];
2142 size_t resp_ies_len
= 0;
2143 char *identity
= NULL
;
2144 char *radius_cui
= NULL
;
2147 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.auth
)) {
2148 wpa_printf(MSG_INFO
, "handle_auth - too short payload (len=%lu)",
2149 (unsigned long) len
);
2153 #ifdef CONFIG_TESTING_OPTIONS
2154 if (hapd
->iconf
->ignore_auth_probability
> 0.0 &&
2155 drand48() < hapd
->iconf
->ignore_auth_probability
) {
2156 wpa_printf(MSG_INFO
,
2157 "TESTING: ignoring auth frame from " MACSTR
,
2161 #endif /* CONFIG_TESTING_OPTIONS */
2163 auth_alg
= le_to_host16(mgmt
->u
.auth
.auth_alg
);
2164 auth_transaction
= le_to_host16(mgmt
->u
.auth
.auth_transaction
);
2165 status_code
= le_to_host16(mgmt
->u
.auth
.status_code
);
2166 fc
= le_to_host16(mgmt
->frame_control
);
2167 seq_ctrl
= le_to_host16(mgmt
->seq_ctrl
);
2169 if (len
>= IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.auth
) +
2170 2 + WLAN_AUTH_CHALLENGE_LEN
&&
2171 mgmt
->u
.auth
.variable
[0] == WLAN_EID_CHALLENGE
&&
2172 mgmt
->u
.auth
.variable
[1] == WLAN_AUTH_CHALLENGE_LEN
)
2173 challenge
= &mgmt
->u
.auth
.variable
[2];
2175 wpa_printf(MSG_DEBUG
, "authentication: STA=" MACSTR
" auth_alg=%d "
2176 "auth_transaction=%d status_code=%d wep=%d%s "
2177 "seq_ctrl=0x%x%s%s",
2178 MAC2STR(mgmt
->sa
), auth_alg
, auth_transaction
,
2179 status_code
, !!(fc
& WLAN_FC_ISWEP
),
2180 challenge
? " challenge" : "",
2181 seq_ctrl
, (fc
& WLAN_FC_RETRY
) ? " retry" : "",
2182 from_queue
? " (from queue)" : "");
2184 #ifdef CONFIG_NO_RC4
2185 if (auth_alg
== WLAN_AUTH_SHARED_KEY
) {
2186 wpa_printf(MSG_INFO
,
2187 "Unsupported authentication algorithm (%d)",
2189 resp
= WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG
;
2192 #endif /* CONFIG_NO_RC4 */
2194 if (hapd
->tkip_countermeasures
) {
2195 wpa_printf(MSG_DEBUG
,
2196 "Ongoing TKIP countermeasures (Michael MIC failure) - reject authentication");
2197 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
2201 if (!(((hapd
->conf
->auth_algs
& WPA_AUTH_ALG_OPEN
) &&
2202 auth_alg
== WLAN_AUTH_OPEN
) ||
2203 #ifdef CONFIG_IEEE80211R_AP
2204 (hapd
->conf
->wpa
&& wpa_key_mgmt_ft(hapd
->conf
->wpa_key_mgmt
) &&
2205 auth_alg
== WLAN_AUTH_FT
) ||
2206 #endif /* CONFIG_IEEE80211R_AP */
2208 (hapd
->conf
->wpa
&& wpa_key_mgmt_sae(hapd
->conf
->wpa_key_mgmt
) &&
2209 auth_alg
== WLAN_AUTH_SAE
) ||
2210 #endif /* CONFIG_SAE */
2212 (hapd
->conf
->wpa
&& wpa_key_mgmt_fils(hapd
->conf
->wpa_key_mgmt
) &&
2213 auth_alg
== WLAN_AUTH_FILS_SK
) ||
2214 (hapd
->conf
->wpa
&& wpa_key_mgmt_fils(hapd
->conf
->wpa_key_mgmt
) &&
2215 hapd
->conf
->fils_dh_group
&&
2216 auth_alg
== WLAN_AUTH_FILS_SK_PFS
) ||
2217 #endif /* CONFIG_FILS */
2218 ((hapd
->conf
->auth_algs
& WPA_AUTH_ALG_SHARED
) &&
2219 auth_alg
== WLAN_AUTH_SHARED_KEY
))) {
2220 wpa_printf(MSG_INFO
, "Unsupported authentication algorithm (%d)",
2222 resp
= WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG
;
2226 if (!(auth_transaction
== 1 || auth_alg
== WLAN_AUTH_SAE
||
2227 (auth_alg
== WLAN_AUTH_SHARED_KEY
&& auth_transaction
== 3))) {
2228 wpa_printf(MSG_INFO
, "Unknown authentication transaction number (%d)",
2230 resp
= WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION
;
2234 if (os_memcmp(mgmt
->sa
, hapd
->own_addr
, ETH_ALEN
) == 0) {
2235 wpa_printf(MSG_INFO
, "Station " MACSTR
" not allowed to authenticate",
2237 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
2241 if (hapd
->conf
->no_auth_if_seen_on
) {
2242 struct hostapd_data
*other
;
2244 other
= sta_track_seen_on(hapd
->iface
, mgmt
->sa
,
2245 hapd
->conf
->no_auth_if_seen_on
);
2249 u8 op_class
, channel
, phytype
;
2251 wpa_printf(MSG_DEBUG
, "%s: Reject authentication from "
2252 MACSTR
" since STA has been seen on %s",
2253 hapd
->conf
->iface
, MAC2STR(mgmt
->sa
),
2254 hapd
->conf
->no_auth_if_seen_on
);
2256 resp
= WLAN_STATUS_REJECTED_WITH_SUGGESTED_BSS_TRANSITION
;
2258 *pos
++ = WLAN_EID_NEIGHBOR_REPORT
;
2260 os_memcpy(pos
, other
->own_addr
, ETH_ALEN
);
2262 info
= 0; /* TODO: BSSID Information */
2263 WPA_PUT_LE32(pos
, info
);
2265 if (other
->iconf
->hw_mode
== HOSTAPD_MODE_IEEE80211AD
)
2266 phytype
= 8; /* dmg */
2267 else if (other
->iconf
->ieee80211ac
)
2268 phytype
= 9; /* vht */
2269 else if (other
->iconf
->ieee80211n
)
2270 phytype
= 7; /* ht */
2271 else if (other
->iconf
->hw_mode
==
2272 HOSTAPD_MODE_IEEE80211A
)
2273 phytype
= 4; /* ofdm */
2274 else if (other
->iconf
->hw_mode
==
2275 HOSTAPD_MODE_IEEE80211G
)
2276 phytype
= 6; /* erp */
2278 phytype
= 5; /* hrdsss */
2279 if (ieee80211_freq_to_channel_ext(
2280 hostapd_hw_get_freq(other
,
2281 other
->iconf
->channel
),
2282 other
->iconf
->secondary_channel
,
2283 other
->iconf
->ieee80211ac
,
2284 &op_class
, &channel
) == NUM_HOSTAPD_MODES
) {
2286 channel
= other
->iconf
->channel
;
2291 resp_ies_len
= pos
- &resp_ies
[0];
2296 res
= ieee802_11_allowed_address(
2297 hapd
, mgmt
->sa
, (const u8
*) mgmt
, len
, &session_timeout
,
2298 &acct_interim_interval
, &vlan_id
, &psk
, &identity
, &radius_cui
,
2300 if (res
== HOSTAPD_ACL_REJECT
) {
2301 wpa_msg(hapd
->msg_ctx
, MSG_DEBUG
,
2302 "Ignore Authentication frame from " MACSTR
2303 " due to ACL reject", MAC2STR(mgmt
->sa
));
2304 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
2307 if (res
== HOSTAPD_ACL_PENDING
)
2311 if (auth_alg
== WLAN_AUTH_SAE
&& !from_queue
&&
2312 (auth_transaction
== 1 ||
2313 (auth_transaction
== 2 && auth_sae_queued_addr(hapd
, mgmt
->sa
)))) {
2314 /* Handle SAE Authentication commit message through a queue to
2315 * provide more control for postponing the needed heavy
2316 * processing under a possible DoS attack scenario. In addition,
2317 * queue SAE Authentication confirm message if there happens to
2318 * be a queued commit message from the same peer. This is needed
2319 * to avoid reordering Authentication frames within the same
2321 auth_sae_queue(hapd
, mgmt
, len
, rssi
);
2324 #endif /* CONFIG_SAE */
2326 sta
= ap_get_sta(hapd
, mgmt
->sa
);
2328 sta
->flags
&= ~WLAN_STA_PENDING_FILS_ERP
;
2329 sta
->ft_over_ds
= 0;
2330 if ((fc
& WLAN_FC_RETRY
) &&
2331 sta
->last_seq_ctrl
!= WLAN_INVALID_MGMT_SEQ
&&
2332 sta
->last_seq_ctrl
== seq_ctrl
&&
2333 sta
->last_subtype
== WLAN_FC_STYPE_AUTH
) {
2334 hostapd_logger(hapd
, sta
->addr
,
2335 HOSTAPD_MODULE_IEEE80211
,
2336 HOSTAPD_LEVEL_DEBUG
,
2337 "Drop repeated authentication frame seq_ctrl=0x%x",
2342 if ((hapd
->conf
->mesh
& MESH_ENABLED
) &&
2343 sta
->plink_state
== PLINK_BLOCKED
) {
2344 wpa_printf(MSG_DEBUG
, "Mesh peer " MACSTR
2345 " is blocked - drop Authentication frame",
2349 #endif /* CONFIG_MESH */
2352 if (hapd
->conf
->mesh
& MESH_ENABLED
) {
2353 /* if the mesh peer is not available, we don't do auth.
2355 wpa_printf(MSG_DEBUG
, "Mesh peer " MACSTR
2356 " not yet known - drop Authentication frame",
2359 * Save a copy of the frame so that it can be processed
2360 * if a new peer entry is added shortly after this.
2362 wpabuf_free(hapd
->mesh_pending_auth
);
2363 hapd
->mesh_pending_auth
= wpabuf_alloc_copy(mgmt
, len
);
2364 os_get_reltime(&hapd
->mesh_pending_auth_time
);
2367 #endif /* CONFIG_MESH */
2369 sta
= ap_sta_add(hapd
, mgmt
->sa
);
2371 wpa_printf(MSG_DEBUG
, "ap_sta_add() failed");
2372 resp
= WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
;
2376 sta
->last_seq_ctrl
= seq_ctrl
;
2377 sta
->last_subtype
= WLAN_FC_STYPE_AUTH
;
2379 sta
->auth_rssi
= rssi
;
2380 #endif /* CONFIG_MBO */
2382 res
= ieee802_11_set_radius_info(
2383 hapd
, sta
, res
, session_timeout
, acct_interim_interval
,
2384 &vlan_id
, &psk
, &identity
, &radius_cui
);
2386 wpa_printf(MSG_DEBUG
, "ieee802_11_set_radius_info() failed");
2387 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
2391 sta
->flags
&= ~WLAN_STA_PREAUTH
;
2392 ieee802_1x_notify_pre_auth(sta
->eapol_sm
, 0);
2395 * If the driver supports full AP client state, add a station to the
2396 * driver before sending authentication reply to make sure the driver
2397 * has resources, and not to go through the entire authentication and
2398 * association handshake, and fail it at the end.
2400 * If this is not the first transaction, in a multi-step authentication
2401 * algorithm, the station already exists in the driver
2402 * (sta->added_unassoc = 1) so skip it.
2404 * In mesh mode, the station was already added to the driver when the
2405 * NEW_PEER_CANDIDATE event is received.
2407 * If PMF was negotiated for the existing association, skip this to
2408 * avoid dropping the STA entry and the associated keys. This is needed
2409 * to allow the original connection work until the attempt can complete
2410 * (re)association, so that unprotected Authentication frame cannot be
2411 * used to bypass PMF protection.
2413 if (FULL_AP_CLIENT_STATE_SUPP(hapd
->iface
->drv_flags
) &&
2414 (!(sta
->flags
& WLAN_STA_MFP
) || !ap_sta_is_authorized(sta
)) &&
2415 !(hapd
->conf
->mesh
& MESH_ENABLED
) &&
2416 !(sta
->added_unassoc
)) {
2418 * If a station that is already associated to the AP, is trying
2419 * to authenticate again, remove the STA entry, in order to make
2420 * sure the STA PS state gets cleared and configuration gets
2421 * updated. To handle this, station's added_unassoc flag is
2422 * cleared once the station has completed association.
2424 ap_sta_set_authorized(hapd
, sta
, 0);
2425 hostapd_drv_sta_remove(hapd
, sta
->addr
);
2426 sta
->flags
&= ~(WLAN_STA_ASSOC
| WLAN_STA_AUTH
|
2427 WLAN_STA_AUTHORIZED
);
2429 if (hostapd_sta_add(hapd
, sta
->addr
, 0, 0,
2430 sta
->supported_rates
,
2431 sta
->supported_rates_len
,
2432 0, NULL
, NULL
, NULL
, 0,
2433 sta
->flags
, 0, 0, 0, 0)) {
2434 hostapd_logger(hapd
, sta
->addr
,
2435 HOSTAPD_MODULE_IEEE80211
,
2436 HOSTAPD_LEVEL_NOTICE
,
2437 "Could not add STA to kernel driver");
2438 resp
= WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
;
2442 sta
->added_unassoc
= 1;
2446 case WLAN_AUTH_OPEN
:
2447 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
2448 HOSTAPD_LEVEL_DEBUG
,
2449 "authentication OK (open system)");
2450 sta
->flags
|= WLAN_STA_AUTH
;
2451 wpa_auth_sm_event(sta
->wpa_sm
, WPA_AUTH
);
2452 sta
->auth_alg
= WLAN_AUTH_OPEN
;
2453 mlme_authenticate_indication(hapd
, sta
);
2455 #ifndef CONFIG_NO_RC4
2456 case WLAN_AUTH_SHARED_KEY
:
2457 resp
= auth_shared_key(hapd
, sta
, auth_transaction
, challenge
,
2458 fc
& WLAN_FC_ISWEP
);
2460 wpa_printf(MSG_DEBUG
,
2461 "auth_shared_key() failed: status=%d", resp
);
2462 sta
->auth_alg
= WLAN_AUTH_SHARED_KEY
;
2463 mlme_authenticate_indication(hapd
, sta
);
2464 if (sta
->challenge
&& auth_transaction
== 1) {
2465 resp_ies
[0] = WLAN_EID_CHALLENGE
;
2466 resp_ies
[1] = WLAN_AUTH_CHALLENGE_LEN
;
2467 os_memcpy(resp_ies
+ 2, sta
->challenge
,
2468 WLAN_AUTH_CHALLENGE_LEN
);
2469 resp_ies_len
= 2 + WLAN_AUTH_CHALLENGE_LEN
;
2472 #endif /* CONFIG_NO_RC4 */
2473 #ifdef CONFIG_IEEE80211R_AP
2475 sta
->auth_alg
= WLAN_AUTH_FT
;
2476 if (sta
->wpa_sm
== NULL
)
2477 sta
->wpa_sm
= wpa_auth_sta_init(hapd
->wpa_auth
,
2479 if (sta
->wpa_sm
== NULL
) {
2480 wpa_printf(MSG_DEBUG
, "FT: Failed to initialize WPA "
2482 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
2485 wpa_ft_process_auth(sta
->wpa_sm
, mgmt
->bssid
,
2486 auth_transaction
, mgmt
->u
.auth
.variable
,
2487 len
- IEEE80211_HDRLEN
-
2488 sizeof(mgmt
->u
.auth
),
2489 handle_auth_ft_finish
, hapd
);
2490 /* handle_auth_ft_finish() callback will complete auth. */
2492 #endif /* CONFIG_IEEE80211R_AP */
2496 if (status_code
== WLAN_STATUS_SUCCESS
&&
2497 hapd
->conf
->mesh
& MESH_ENABLED
) {
2498 if (sta
->wpa_sm
== NULL
)
2500 wpa_auth_sta_init(hapd
->wpa_auth
,
2502 if (sta
->wpa_sm
== NULL
) {
2503 wpa_printf(MSG_DEBUG
,
2504 "SAE: Failed to initialize WPA state machine");
2505 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
2509 #endif /* CONFIG_MESH */
2510 handle_auth_sae(hapd
, sta
, mgmt
, len
, auth_transaction
,
2513 #endif /* CONFIG_SAE */
2515 case WLAN_AUTH_FILS_SK
:
2516 case WLAN_AUTH_FILS_SK_PFS
:
2517 handle_auth_fils(hapd
, sta
, mgmt
->u
.auth
.variable
,
2518 len
- IEEE80211_HDRLEN
- sizeof(mgmt
->u
.auth
),
2519 auth_alg
, auth_transaction
, status_code
,
2520 handle_auth_fils_finish
);
2522 #endif /* CONFIG_FILS */
2527 os_free(radius_cui
);
2528 hostapd_free_psk_list(psk
);
2530 reply_res
= send_auth_reply(hapd
, mgmt
->sa
, mgmt
->bssid
, auth_alg
,
2531 auth_transaction
+ 1, resp
, resp_ies
,
2532 resp_ies_len
, "handle-auth");
2534 if (sta
&& sta
->added_unassoc
&& (resp
!= WLAN_STATUS_SUCCESS
||
2535 reply_res
!= WLAN_STATUS_SUCCESS
)) {
2536 hostapd_drv_sta_remove(hapd
, sta
->addr
);
2537 sta
->added_unassoc
= 0;
2542 int hostapd_get_aid(struct hostapd_data
*hapd
, struct sta_info
*sta
)
2546 /* get a unique AID */
2548 wpa_printf(MSG_DEBUG
, " old AID %d", sta
->aid
);
2555 for (i
= 0; i
< AID_WORDS
; i
++) {
2556 if (hapd
->sta_aid
[i
] == (u32
) -1)
2558 for (j
= 0; j
< 32; j
++) {
2559 if (!(hapd
->sta_aid
[i
] & BIT(j
)))
2567 aid
= i
* 32 + j
+ 1;
2572 hapd
->sta_aid
[i
] |= BIT(j
);
2573 wpa_printf(MSG_DEBUG
, " new AID %d", sta
->aid
);
2578 static u16
check_ssid(struct hostapd_data
*hapd
, struct sta_info
*sta
,
2579 const u8
*ssid_ie
, size_t ssid_ie_len
)
2581 if (ssid_ie
== NULL
)
2582 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2584 if (ssid_ie_len
!= hapd
->conf
->ssid
.ssid_len
||
2585 os_memcmp(ssid_ie
, hapd
->conf
->ssid
.ssid
, ssid_ie_len
) != 0) {
2586 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
2588 "Station tried to associate with unknown SSID "
2589 "'%s'", wpa_ssid_txt(ssid_ie
, ssid_ie_len
));
2590 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2593 return WLAN_STATUS_SUCCESS
;
2597 static u16
check_wmm(struct hostapd_data
*hapd
, struct sta_info
*sta
,
2598 const u8
*wmm_ie
, size_t wmm_ie_len
)
2600 sta
->flags
&= ~WLAN_STA_WMM
;
2602 if (wmm_ie
&& hapd
->conf
->wmm_enabled
) {
2603 struct wmm_information_element
*wmm
;
2605 if (!hostapd_eid_wmm_valid(hapd
, wmm_ie
, wmm_ie_len
)) {
2606 hostapd_logger(hapd
, sta
->addr
,
2608 HOSTAPD_LEVEL_DEBUG
,
2609 "invalid WMM element in association "
2611 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2614 sta
->flags
|= WLAN_STA_WMM
;
2615 wmm
= (struct wmm_information_element
*) wmm_ie
;
2616 sta
->qosinfo
= wmm
->qos_info
;
2618 return WLAN_STATUS_SUCCESS
;
2621 static u16
check_multi_ap(struct hostapd_data
*hapd
, struct sta_info
*sta
,
2622 const u8
*multi_ap_ie
, size_t multi_ap_len
)
2624 u8 multi_ap_value
= 0;
2626 sta
->flags
&= ~WLAN_STA_MULTI_AP
;
2628 if (!hapd
->conf
->multi_ap
)
2629 return WLAN_STATUS_SUCCESS
;
2632 const u8
*multi_ap_subelem
;
2634 multi_ap_subelem
= get_ie(multi_ap_ie
+ 4,
2636 MULTI_AP_SUB_ELEM_TYPE
);
2637 if (multi_ap_subelem
&& multi_ap_subelem
[1] == 1) {
2638 multi_ap_value
= multi_ap_subelem
[2];
2640 hostapd_logger(hapd
, sta
->addr
,
2641 HOSTAPD_MODULE_IEEE80211
,
2643 "Multi-AP IE has missing or invalid Multi-AP subelement");
2644 return WLAN_STATUS_INVALID_IE
;
2648 if (multi_ap_value
&& multi_ap_value
!= MULTI_AP_BACKHAUL_STA
)
2649 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
2651 "Multi-AP IE with unexpected value 0x%02x",
2654 if (!(multi_ap_value
& MULTI_AP_BACKHAUL_STA
)) {
2655 if (hapd
->conf
->multi_ap
& FRONTHAUL_BSS
)
2656 return WLAN_STATUS_SUCCESS
;
2658 hostapd_logger(hapd
, sta
->addr
,
2659 HOSTAPD_MODULE_IEEE80211
,
2661 "Non-Multi-AP STA tries to associate with backhaul-only BSS");
2662 return WLAN_STATUS_ASSOC_DENIED_UNSPEC
;
2665 if (!(hapd
->conf
->multi_ap
& BACKHAUL_BSS
))
2666 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
2667 HOSTAPD_LEVEL_DEBUG
,
2668 "Backhaul STA tries to associate with fronthaul-only BSS");
2670 sta
->flags
|= WLAN_STA_MULTI_AP
;
2671 return WLAN_STATUS_SUCCESS
;
2675 static u16
copy_supp_rates(struct hostapd_data
*hapd
, struct sta_info
*sta
,
2676 struct ieee802_11_elems
*elems
)
2678 /* Supported rates not used in IEEE 802.11ad/DMG */
2679 if (hapd
->iface
->current_mode
&&
2680 hapd
->iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211AD
)
2681 return WLAN_STATUS_SUCCESS
;
2683 if (!elems
->supp_rates
) {
2684 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
2685 HOSTAPD_LEVEL_DEBUG
,
2686 "No supported rates element in AssocReq");
2687 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2690 if (elems
->supp_rates_len
+ elems
->ext_supp_rates_len
>
2691 sizeof(sta
->supported_rates
)) {
2692 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
2693 HOSTAPD_LEVEL_DEBUG
,
2694 "Invalid supported rates element length %d+%d",
2695 elems
->supp_rates_len
,
2696 elems
->ext_supp_rates_len
);
2697 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2700 sta
->supported_rates_len
= merge_byte_arrays(
2701 sta
->supported_rates
, sizeof(sta
->supported_rates
),
2702 elems
->supp_rates
, elems
->supp_rates_len
,
2703 elems
->ext_supp_rates
, elems
->ext_supp_rates_len
);
2705 return WLAN_STATUS_SUCCESS
;
2709 static u16
check_ext_capab(struct hostapd_data
*hapd
, struct sta_info
*sta
,
2710 const u8
*ext_capab_ie
, size_t ext_capab_ie_len
)
2712 #ifdef CONFIG_INTERWORKING
2713 /* check for QoS Map support */
2714 if (ext_capab_ie_len
>= 5) {
2715 if (ext_capab_ie
[4] & 0x01)
2716 sta
->qos_map_enabled
= 1;
2718 #endif /* CONFIG_INTERWORKING */
2720 if (ext_capab_ie_len
> 0) {
2721 sta
->ecsa_supported
= !!(ext_capab_ie
[0] & BIT(2));
2722 os_free(sta
->ext_capability
);
2723 sta
->ext_capability
= os_malloc(1 + ext_capab_ie_len
);
2724 if (sta
->ext_capability
) {
2725 sta
->ext_capability
[0] = ext_capab_ie_len
;
2726 os_memcpy(sta
->ext_capability
+ 1, ext_capab_ie
,
2731 return WLAN_STATUS_SUCCESS
;
2737 static int owe_group_supported(struct hostapd_data
*hapd
, u16 group
)
2740 int *groups
= hapd
->conf
->owe_groups
;
2742 if (group
!= 19 && group
!= 20 && group
!= 21)
2748 for (i
= 0; groups
[i
] > 0; i
++) {
2749 if (groups
[i
] == group
)
2757 static u16
owe_process_assoc_req(struct hostapd_data
*hapd
,
2758 struct sta_info
*sta
, const u8
*owe_dh
,
2761 struct wpabuf
*secret
, *pub
, *hkey
;
2763 u8 prk
[SHA512_MAC_LEN
], pmkid
[SHA512_MAC_LEN
];
2764 const char *info
= "OWE Key Generation";
2768 size_t hash_len
, prime_len
;
2770 if (wpa_auth_sta_get_pmksa(sta
->wpa_sm
)) {
2771 wpa_printf(MSG_DEBUG
, "OWE: Using PMKSA caching");
2772 return WLAN_STATUS_SUCCESS
;
2775 group
= WPA_GET_LE16(owe_dh
);
2776 if (!owe_group_supported(hapd
, group
)) {
2777 wpa_printf(MSG_DEBUG
, "OWE: Unsupported DH group %u", group
);
2778 return WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED
;
2782 else if (group
== 20)
2784 else if (group
== 21)
2787 return WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED
;
2789 crypto_ecdh_deinit(sta
->owe_ecdh
);
2790 sta
->owe_ecdh
= crypto_ecdh_init(group
);
2792 return WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED
;
2793 sta
->owe_group
= group
;
2795 secret
= crypto_ecdh_set_peerkey(sta
->owe_ecdh
, 0, owe_dh
+ 2,
2797 secret
= wpabuf_zeropad(secret
, prime_len
);
2799 wpa_printf(MSG_DEBUG
, "OWE: Invalid peer DH public key");
2800 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2802 wpa_hexdump_buf_key(MSG_DEBUG
, "OWE: DH shared secret", secret
);
2804 /* prk = HKDF-extract(C | A | group, z) */
2806 pub
= crypto_ecdh_get_pubkey(sta
->owe_ecdh
, 0);
2808 wpabuf_clear_free(secret
);
2809 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2812 /* PMKID = Truncate-128(Hash(C | A)) */
2813 addr
[0] = owe_dh
+ 2;
2814 len
[0] = owe_dh_len
- 2;
2815 addr
[1] = wpabuf_head(pub
);
2816 len
[1] = wpabuf_len(pub
);
2818 res
= sha256_vector(2, addr
, len
, pmkid
);
2819 hash_len
= SHA256_MAC_LEN
;
2820 } else if (group
== 20) {
2821 res
= sha384_vector(2, addr
, len
, pmkid
);
2822 hash_len
= SHA384_MAC_LEN
;
2823 } else if (group
== 21) {
2824 res
= sha512_vector(2, addr
, len
, pmkid
);
2825 hash_len
= SHA512_MAC_LEN
;
2828 wpabuf_clear_free(secret
);
2829 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2831 pub
= wpabuf_zeropad(pub
, prime_len
);
2832 if (res
< 0 || !pub
) {
2834 wpabuf_clear_free(secret
);
2835 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2838 hkey
= wpabuf_alloc(owe_dh_len
- 2 + wpabuf_len(pub
) + 2);
2841 wpabuf_clear_free(secret
);
2842 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2845 wpabuf_put_data(hkey
, owe_dh
+ 2, owe_dh_len
- 2); /* C */
2846 wpabuf_put_buf(hkey
, pub
); /* A */
2848 wpabuf_put_le16(hkey
, group
); /* group */
2850 res
= hmac_sha256(wpabuf_head(hkey
), wpabuf_len(hkey
),
2851 wpabuf_head(secret
), wpabuf_len(secret
), prk
);
2852 else if (group
== 20)
2853 res
= hmac_sha384(wpabuf_head(hkey
), wpabuf_len(hkey
),
2854 wpabuf_head(secret
), wpabuf_len(secret
), prk
);
2855 else if (group
== 21)
2856 res
= hmac_sha512(wpabuf_head(hkey
), wpabuf_len(hkey
),
2857 wpabuf_head(secret
), wpabuf_len(secret
), prk
);
2858 wpabuf_clear_free(hkey
);
2859 wpabuf_clear_free(secret
);
2861 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2863 wpa_hexdump_key(MSG_DEBUG
, "OWE: prk", prk
, hash_len
);
2865 /* PMK = HKDF-expand(prk, "OWE Key Generation", n) */
2867 os_free(sta
->owe_pmk
);
2868 sta
->owe_pmk
= os_malloc(hash_len
);
2869 if (!sta
->owe_pmk
) {
2870 os_memset(prk
, 0, SHA512_MAC_LEN
);
2871 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2875 res
= hmac_sha256_kdf(prk
, hash_len
, NULL
, (const u8
*) info
,
2876 os_strlen(info
), sta
->owe_pmk
, hash_len
);
2877 else if (group
== 20)
2878 res
= hmac_sha384_kdf(prk
, hash_len
, NULL
, (const u8
*) info
,
2879 os_strlen(info
), sta
->owe_pmk
, hash_len
);
2880 else if (group
== 21)
2881 res
= hmac_sha512_kdf(prk
, hash_len
, NULL
, (const u8
*) info
,
2882 os_strlen(info
), sta
->owe_pmk
, hash_len
);
2883 os_memset(prk
, 0, SHA512_MAC_LEN
);
2885 os_free(sta
->owe_pmk
);
2886 sta
->owe_pmk
= NULL
;
2887 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2889 sta
->owe_pmk_len
= hash_len
;
2891 wpa_hexdump_key(MSG_DEBUG
, "OWE: PMK", sta
->owe_pmk
, sta
->owe_pmk_len
);
2892 wpa_hexdump(MSG_DEBUG
, "OWE: PMKID", pmkid
, PMKID_LEN
);
2893 wpa_auth_pmksa_add2(hapd
->wpa_auth
, sta
->addr
, sta
->owe_pmk
,
2894 sta
->owe_pmk_len
, pmkid
, 0, WPA_KEY_MGMT_OWE
);
2896 return WLAN_STATUS_SUCCESS
;
2900 u16
owe_validate_request(struct hostapd_data
*hapd
, const u8
*peer
,
2901 const u8
*rsn_ie
, size_t rsn_ie_len
,
2902 const u8
*owe_dh
, size_t owe_dh_len
)
2904 struct wpa_ie_data data
;
2907 if (!rsn_ie
|| rsn_ie_len
< 2) {
2908 wpa_printf(MSG_DEBUG
, "OWE: Invalid RSNE from " MACSTR
,
2910 return WLAN_STATUS_INVALID_IE
;
2915 res
= wpa_parse_wpa_ie_rsn(rsn_ie
, rsn_ie_len
, &data
);
2917 wpa_printf(MSG_DEBUG
, "Failed to parse RSNE from " MACSTR
2918 " (res=%d)", MAC2STR(peer
), res
);
2919 wpa_hexdump(MSG_DEBUG
, "RSNE", rsn_ie
, rsn_ie_len
);
2920 return wpa_res_to_status_code(res
);
2922 if (!(data
.key_mgmt
& WPA_KEY_MGMT_OWE
)) {
2923 wpa_printf(MSG_DEBUG
,
2924 "OWE: Unexpected key mgmt 0x%x from " MACSTR
,
2925 (unsigned int) data
.key_mgmt
, MAC2STR(peer
));
2926 return WLAN_STATUS_AKMP_NOT_VALID
;
2929 wpa_printf(MSG_DEBUG
,
2930 "OWE: No Diffie-Hellman Parameter element from "
2931 MACSTR
, MAC2STR(peer
));
2932 return WLAN_STATUS_AKMP_NOT_VALID
;
2935 return WLAN_STATUS_SUCCESS
;
2939 u16
owe_process_rsn_ie(struct hostapd_data
*hapd
,
2940 struct sta_info
*sta
,
2941 const u8
*rsn_ie
, size_t rsn_ie_len
,
2942 const u8
*owe_dh
, size_t owe_dh_len
)
2945 u8
*owe_buf
, ie
[256 * 2];
2949 if (!rsn_ie
|| rsn_ie_len
< 2) {
2950 wpa_printf(MSG_DEBUG
, "OWE: No RSNE in (Re)AssocReq");
2951 status
= WLAN_STATUS_INVALID_IE
;
2956 sta
->wpa_sm
= wpa_auth_sta_init(hapd
->wpa_auth
, sta
->addr
,
2959 wpa_printf(MSG_WARNING
,
2960 "OWE: Failed to initialize WPA state machine");
2961 status
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
2966 res
= wpa_validate_wpa_ie(hapd
->wpa_auth
, sta
->wpa_sm
,
2967 hapd
->iface
->freq
, rsn_ie
, rsn_ie_len
,
2968 NULL
, 0, owe_dh
, owe_dh_len
);
2969 status
= wpa_res_to_status_code(res
);
2970 if (status
!= WLAN_STATUS_SUCCESS
)
2972 status
= owe_process_assoc_req(hapd
, sta
, owe_dh
, owe_dh_len
);
2973 if (status
!= WLAN_STATUS_SUCCESS
)
2975 owe_buf
= wpa_auth_write_assoc_resp_owe(sta
->wpa_sm
, ie
, sizeof(ie
),
2978 status
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
2982 if (sta
->owe_ecdh
) {
2985 pub
= crypto_ecdh_get_pubkey(sta
->owe_ecdh
, 0);
2987 status
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
2991 /* OWE Diffie-Hellman Parameter element */
2992 *owe_buf
++ = WLAN_EID_EXTENSION
; /* Element ID */
2993 *owe_buf
++ = 1 + 2 + wpabuf_len(pub
); /* Length */
2994 *owe_buf
++ = WLAN_EID_EXT_OWE_DH_PARAM
; /* Element ID Extension
2996 WPA_PUT_LE16(owe_buf
, sta
->owe_group
);
2998 os_memcpy(owe_buf
, wpabuf_head(pub
), wpabuf_len(pub
));
2999 owe_buf
+= wpabuf_len(pub
);
3001 sta
->external_dh_updated
= 1;
3003 ie_len
= owe_buf
- ie
;
3006 wpa_printf(MSG_DEBUG
, "OWE: Update status %d, ie len %d for peer "
3007 MACSTR
, status
, (unsigned int) ie_len
,
3008 MAC2STR(sta
->addr
));
3009 hostapd_drv_update_dh_ie(hapd
, sta
->addr
, status
,
3010 status
== WLAN_STATUS_SUCCESS
? ie
: NULL
,
3016 #endif /* CONFIG_OWE */
3019 static u16
check_assoc_ies(struct hostapd_data
*hapd
, struct sta_info
*sta
,
3020 const u8
*ies
, size_t ies_len
, int reassoc
)
3022 struct ieee802_11_elems elems
;
3026 const u8
*p2p_dev_addr
= NULL
;
3028 if (ieee802_11_parse_elems(ies
, ies_len
, &elems
, 1) == ParseFailed
) {
3029 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
3030 HOSTAPD_LEVEL_INFO
, "Station sent an invalid "
3031 "association request");
3032 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3035 resp
= check_ssid(hapd
, sta
, elems
.ssid
, elems
.ssid_len
);
3036 if (resp
!= WLAN_STATUS_SUCCESS
)
3038 resp
= check_wmm(hapd
, sta
, elems
.wmm
, elems
.wmm_len
);
3039 if (resp
!= WLAN_STATUS_SUCCESS
)
3041 resp
= check_ext_capab(hapd
, sta
, elems
.ext_capab
, elems
.ext_capab_len
);
3042 if (resp
!= WLAN_STATUS_SUCCESS
)
3044 resp
= copy_supp_rates(hapd
, sta
, &elems
);
3045 if (resp
!= WLAN_STATUS_SUCCESS
)
3048 resp
= check_multi_ap(hapd
, sta
, elems
.multi_ap
, elems
.multi_ap_len
);
3049 if (resp
!= WLAN_STATUS_SUCCESS
)
3052 #ifdef CONFIG_IEEE80211N
3053 resp
= copy_sta_ht_capab(hapd
, sta
, elems
.ht_capabilities
);
3054 if (resp
!= WLAN_STATUS_SUCCESS
)
3056 if (hapd
->iconf
->ieee80211n
&& hapd
->iconf
->require_ht
&&
3057 !(sta
->flags
& WLAN_STA_HT
)) {
3058 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
3059 HOSTAPD_LEVEL_INFO
, "Station does not support "
3060 "mandatory HT PHY - reject association");
3061 return WLAN_STATUS_ASSOC_DENIED_NO_HT
;
3063 #endif /* CONFIG_IEEE80211N */
3065 #ifdef CONFIG_IEEE80211AC
3066 if (hapd
->iconf
->ieee80211ac
) {
3067 resp
= copy_sta_vht_capab(hapd
, sta
, elems
.vht_capabilities
);
3068 if (resp
!= WLAN_STATUS_SUCCESS
)
3071 resp
= set_sta_vht_opmode(hapd
, sta
, elems
.vht_opmode_notif
);
3072 if (resp
!= WLAN_STATUS_SUCCESS
)
3076 if (hapd
->iconf
->ieee80211ac
&& hapd
->iconf
->require_vht
&&
3077 !(sta
->flags
& WLAN_STA_VHT
)) {
3078 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
3079 HOSTAPD_LEVEL_INFO
, "Station does not support "
3080 "mandatory VHT PHY - reject association");
3081 return WLAN_STATUS_ASSOC_DENIED_NO_VHT
;
3084 if (hapd
->conf
->vendor_vht
&& !elems
.vht_capabilities
) {
3085 resp
= copy_sta_vendor_vht(hapd
, sta
, elems
.vendor_vht
,
3086 elems
.vendor_vht_len
);
3087 if (resp
!= WLAN_STATUS_SUCCESS
)
3090 #endif /* CONFIG_IEEE80211AC */
3091 #ifdef CONFIG_IEEE80211AX
3092 if (hapd
->iconf
->ieee80211ax
) {
3093 resp
= copy_sta_he_capab(hapd
, sta
, IEEE80211_MODE_AP
,
3094 elems
.he_capabilities
,
3095 elems
.he_capabilities_len
);
3096 if (resp
!= WLAN_STATUS_SUCCESS
)
3099 #endif /* CONFIG_IEEE80211AX */
3103 wpabuf_free(sta
->p2p_ie
);
3104 sta
->p2p_ie
= ieee802_11_vendor_ie_concat(ies
, ies_len
,
3105 P2P_IE_VENDOR_TYPE
);
3107 p2p_dev_addr
= p2p_get_go_dev_addr(sta
->p2p_ie
);
3109 wpabuf_free(sta
->p2p_ie
);
3112 #endif /* CONFIG_P2P */
3114 if ((hapd
->conf
->wpa
& WPA_PROTO_RSN
) && elems
.rsn_ie
) {
3115 wpa_ie
= elems
.rsn_ie
;
3116 wpa_ie_len
= elems
.rsn_ie_len
;
3117 } else if ((hapd
->conf
->wpa
& WPA_PROTO_WPA
) &&
3119 wpa_ie
= elems
.wpa_ie
;
3120 wpa_ie_len
= elems
.wpa_ie_len
;
3127 sta
->flags
&= ~(WLAN_STA_WPS
| WLAN_STA_MAYBE_WPS
| WLAN_STA_WPS2
);
3128 if (hapd
->conf
->wps_state
&& elems
.wps_ie
) {
3129 wpa_printf(MSG_DEBUG
, "STA included WPS IE in (Re)Association "
3130 "Request - assume WPS is used");
3131 sta
->flags
|= WLAN_STA_WPS
;
3132 wpabuf_free(sta
->wps_ie
);
3133 sta
->wps_ie
= ieee802_11_vendor_ie_concat(ies
, ies_len
,
3134 WPS_IE_VENDOR_TYPE
);
3135 if (sta
->wps_ie
&& wps_is_20(sta
->wps_ie
)) {
3136 wpa_printf(MSG_DEBUG
, "WPS: STA supports WPS 2.0");
3137 sta
->flags
|= WLAN_STA_WPS2
;
3141 if (sta
->wps_ie
&& wps_validate_assoc_req(sta
->wps_ie
) < 0) {
3142 wpa_printf(MSG_DEBUG
, "WPS: Invalid WPS IE in "
3143 "(Re)Association Request - reject");
3144 return WLAN_STATUS_INVALID_IE
;
3146 } else if (hapd
->conf
->wps_state
&& wpa_ie
== NULL
) {
3147 wpa_printf(MSG_DEBUG
, "STA did not include WPA/RSN IE in "
3148 "(Re)Association Request - possible WPS use");
3149 sta
->flags
|= WLAN_STA_MAYBE_WPS
;
3151 #endif /* CONFIG_WPS */
3152 if (hapd
->conf
->wpa
&& wpa_ie
== NULL
) {
3153 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
3155 "No WPA/RSN IE in association request");
3156 return WLAN_STATUS_INVALID_IE
;
3159 if (hapd
->conf
->wpa
&& wpa_ie
) {
3163 if (sta
->wpa_sm
== NULL
)
3164 sta
->wpa_sm
= wpa_auth_sta_init(hapd
->wpa_auth
,
3167 if (sta
->wpa_sm
== NULL
) {
3168 wpa_printf(MSG_WARNING
, "Failed to initialize WPA "
3170 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3172 wpa_auth_set_auth_alg(sta
->wpa_sm
, sta
->auth_alg
);
3173 res
= wpa_validate_wpa_ie(hapd
->wpa_auth
, sta
->wpa_sm
,
3176 elems
.mdie
, elems
.mdie_len
,
3177 elems
.owe_dh
, elems
.owe_dh_len
);
3178 resp
= wpa_res_to_status_code(res
);
3179 if (resp
!= WLAN_STATUS_SUCCESS
)
3181 if ((sta
->flags
& (WLAN_STA_ASSOC
| WLAN_STA_MFP
)) ==
3182 (WLAN_STA_ASSOC
| WLAN_STA_MFP
) &&
3183 !sta
->sa_query_timed_out
&&
3184 sta
->sa_query_count
> 0)
3185 ap_check_sa_query_timeout(hapd
, sta
);
3186 if ((sta
->flags
& (WLAN_STA_ASSOC
| WLAN_STA_MFP
)) ==
3187 (WLAN_STA_ASSOC
| WLAN_STA_MFP
) &&
3188 !sta
->sa_query_timed_out
&&
3189 (!reassoc
|| sta
->auth_alg
!= WLAN_AUTH_FT
)) {
3191 * STA has already been associated with MFP and SA
3192 * Query timeout has not been reached. Reject the
3193 * association attempt temporarily and start SA Query,
3194 * if one is not pending.
3197 if (sta
->sa_query_count
== 0)
3198 ap_sta_start_sa_query(hapd
, sta
);
3200 return WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY
;
3203 if (wpa_auth_uses_mfp(sta
->wpa_sm
))
3204 sta
->flags
|= WLAN_STA_MFP
;
3206 sta
->flags
&= ~WLAN_STA_MFP
;
3208 #ifdef CONFIG_IEEE80211R_AP
3209 if (sta
->auth_alg
== WLAN_AUTH_FT
) {
3211 wpa_printf(MSG_DEBUG
, "FT: " MACSTR
" tried "
3212 "to use association (not "
3213 "re-association) with FT auth_alg",
3214 MAC2STR(sta
->addr
));
3215 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3218 resp
= wpa_ft_validate_reassoc(sta
->wpa_sm
, ies
,
3220 if (resp
!= WLAN_STATUS_SUCCESS
)
3223 #endif /* CONFIG_IEEE80211R_AP */
3226 if (wpa_auth_uses_sae(sta
->wpa_sm
) && sta
->sae
&&
3227 sta
->sae
->state
== SAE_ACCEPTED
)
3228 wpa_auth_add_sae_pmkid(sta
->wpa_sm
, sta
->sae
->pmkid
);
3230 if (wpa_auth_uses_sae(sta
->wpa_sm
) &&
3231 sta
->auth_alg
== WLAN_AUTH_OPEN
) {
3232 struct rsn_pmksa_cache_entry
*sa
;
3233 sa
= wpa_auth_sta_get_pmksa(sta
->wpa_sm
);
3234 if (!sa
|| sa
->akmp
!= WPA_KEY_MGMT_SAE
) {
3235 wpa_printf(MSG_DEBUG
,
3236 "SAE: No PMKSA cache entry found for "
3237 MACSTR
, MAC2STR(sta
->addr
));
3238 return WLAN_STATUS_INVALID_PMKID
;
3240 wpa_printf(MSG_DEBUG
, "SAE: " MACSTR
3241 " using PMKSA caching", MAC2STR(sta
->addr
));
3242 } else if (wpa_auth_uses_sae(sta
->wpa_sm
) &&
3243 sta
->auth_alg
!= WLAN_AUTH_SAE
&&
3244 !(sta
->auth_alg
== WLAN_AUTH_FT
&&
3245 wpa_auth_uses_ft_sae(sta
->wpa_sm
))) {
3246 wpa_printf(MSG_DEBUG
, "SAE: " MACSTR
" tried to use "
3247 "SAE AKM after non-SAE auth_alg %u",
3248 MAC2STR(sta
->addr
), sta
->auth_alg
);
3249 return WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG
;
3251 #endif /* CONFIG_SAE */
3254 if ((hapd
->conf
->wpa_key_mgmt
& WPA_KEY_MGMT_OWE
) &&
3255 wpa_auth_sta_key_mgmt(sta
->wpa_sm
) == WPA_KEY_MGMT_OWE
&&
3257 resp
= owe_process_assoc_req(hapd
, sta
, elems
.owe_dh
,
3259 if (resp
!= WLAN_STATUS_SUCCESS
)
3262 #endif /* CONFIG_OWE */
3265 dpp_pfs_free(sta
->dpp_pfs
);
3266 sta
->dpp_pfs
= NULL
;
3268 if ((hapd
->conf
->wpa_key_mgmt
& WPA_KEY_MGMT_DPP
) &&
3269 hapd
->conf
->dpp_netaccesskey
&& sta
->wpa_sm
&&
3270 wpa_auth_sta_key_mgmt(sta
->wpa_sm
) == WPA_KEY_MGMT_DPP
&&
3272 sta
->dpp_pfs
= dpp_pfs_init(
3273 wpabuf_head(hapd
->conf
->dpp_netaccesskey
),
3274 wpabuf_len(hapd
->conf
->dpp_netaccesskey
));
3275 if (!sta
->dpp_pfs
) {
3276 wpa_printf(MSG_DEBUG
,
3277 "DPP: Could not initialize PFS");
3278 /* Try to continue without PFS */
3282 if (dpp_pfs_process(sta
->dpp_pfs
, elems
.owe_dh
,
3283 elems
.owe_dh_len
) < 0) {
3284 dpp_pfs_free(sta
->dpp_pfs
);
3285 sta
->dpp_pfs
= NULL
;
3286 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3290 wpa_auth_set_dpp_z(sta
->wpa_sm
, sta
->dpp_pfs
?
3291 sta
->dpp_pfs
->secret
: NULL
);
3293 #endif /* CONFIG_DPP2 */
3295 #ifdef CONFIG_IEEE80211N
3296 if ((sta
->flags
& (WLAN_STA_HT
| WLAN_STA_VHT
)) &&
3297 wpa_auth_get_pairwise(sta
->wpa_sm
) == WPA_CIPHER_TKIP
) {
3298 hostapd_logger(hapd
, sta
->addr
,
3299 HOSTAPD_MODULE_IEEE80211
,
3301 "Station tried to use TKIP with HT "
3303 return WLAN_STATUS_CIPHER_REJECTED_PER_POLICY
;
3305 #endif /* CONFIG_IEEE80211N */
3307 } else if (hapd
->conf
->osen
) {
3308 if (elems
.osen
== NULL
) {
3310 hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
3312 "No HS 2.0 OSEN element in association request");
3313 return WLAN_STATUS_INVALID_IE
;
3316 wpa_printf(MSG_DEBUG
, "HS 2.0: OSEN association");
3317 if (sta
->wpa_sm
== NULL
)
3318 sta
->wpa_sm
= wpa_auth_sta_init(hapd
->wpa_auth
,
3320 if (sta
->wpa_sm
== NULL
) {
3321 wpa_printf(MSG_WARNING
, "Failed to initialize WPA "
3323 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3325 if (wpa_validate_osen(hapd
->wpa_auth
, sta
->wpa_sm
,
3326 elems
.osen
- 2, elems
.osen_len
+ 2) < 0)
3327 return WLAN_STATUS_INVALID_IE
;
3328 #endif /* CONFIG_HS20 */
3330 wpa_auth_sta_no_wpa(sta
->wpa_sm
);
3333 p2p_group_notif_assoc(hapd
->p2p_group
, sta
->addr
, ies
, ies_len
);
3334 #endif /* CONFIG_P2P */
3337 wpabuf_free(sta
->hs20_ie
);
3338 if (elems
.hs20
&& elems
.hs20_len
> 4) {
3341 sta
->hs20_ie
= wpabuf_alloc_copy(elems
.hs20
+ 4,
3342 elems
.hs20_len
- 4);
3343 release
= ((elems
.hs20
[4] >> 4) & 0x0f) + 1;
3344 if (release
>= 2 && !wpa_auth_uses_mfp(sta
->wpa_sm
) &&
3345 hapd
->conf
->ieee80211w
!= NO_MGMT_FRAME_PROTECTION
) {
3346 wpa_printf(MSG_DEBUG
,
3347 "HS 2.0: PMF not negotiated by release %d station "
3348 MACSTR
, release
, MAC2STR(sta
->addr
));
3349 return WLAN_STATUS_ROBUST_MGMT_FRAME_POLICY_VIOLATION
;
3352 sta
->hs20_ie
= NULL
;
3355 wpabuf_free(sta
->roaming_consortium
);
3356 if (elems
.roaming_cons_sel
)
3357 sta
->roaming_consortium
= wpabuf_alloc_copy(
3358 elems
.roaming_cons_sel
+ 4,
3359 elems
.roaming_cons_sel_len
- 4);
3361 sta
->roaming_consortium
= NULL
;
3362 #endif /* CONFIG_HS20 */
3365 wpabuf_free(sta
->mb_ies
);
3366 if (hapd
->iface
->fst
)
3367 sta
->mb_ies
= mb_ies_by_info(&elems
.mb_ies
);
3370 #endif /* CONFIG_FST */
3373 mbo_ap_check_sta_assoc(hapd
, sta
, &elems
);
3375 if (hapd
->conf
->mbo_enabled
&& (hapd
->conf
->wpa
& 2) &&
3376 elems
.mbo
&& sta
->cell_capa
&& !(sta
->flags
& WLAN_STA_MFP
) &&
3377 hapd
->conf
->ieee80211w
!= NO_MGMT_FRAME_PROTECTION
) {
3378 wpa_printf(MSG_INFO
,
3379 "MBO: Reject WPA2 association without PMF");
3380 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3382 #endif /* CONFIG_MBO */
3384 #if defined(CONFIG_FILS) && defined(CONFIG_OCV)
3385 if (wpa_auth_uses_ocv(sta
->wpa_sm
) &&
3386 (sta
->auth_alg
== WLAN_AUTH_FILS_SK
||
3387 sta
->auth_alg
== WLAN_AUTH_FILS_SK_PFS
||
3388 sta
->auth_alg
== WLAN_AUTH_FILS_PK
)) {
3389 struct wpa_channel_info ci
;
3393 if (hostapd_drv_channel_info(hapd
, &ci
) != 0) {
3394 wpa_printf(MSG_WARNING
,
3395 "Failed to get channel info to validate received OCI in FILS (Re)Association Request frame");
3396 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3399 if (get_sta_tx_parameters(sta
->wpa_sm
,
3400 channel_width_to_int(ci
.chanwidth
),
3401 ci
.seg1_idx
, &tx_chanwidth
,
3403 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3405 if (ocv_verify_tx_params(elems
.oci
, elems
.oci_len
, &ci
,
3406 tx_chanwidth
, tx_seg1_idx
) != 0) {
3407 wpa_printf(MSG_WARNING
, "FILS: %s", ocv_errorstr
);
3408 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3411 #endif /* CONFIG_FILS && CONFIG_OCV */
3413 ap_copy_sta_supp_op_classes(sta
, elems
.supp_op_classes
,
3414 elems
.supp_op_classes_len
);
3416 if ((sta
->capability
& WLAN_CAPABILITY_RADIO_MEASUREMENT
) &&
3417 elems
.rrm_enabled
&&
3418 elems
.rrm_enabled_len
>= sizeof(sta
->rrm_enabled_capa
))
3419 os_memcpy(sta
->rrm_enabled_capa
, elems
.rrm_enabled
,
3420 sizeof(sta
->rrm_enabled_capa
));
3422 if (elems
.power_capab
) {
3423 sta
->min_tx_power
= elems
.power_capab
[0];
3424 sta
->max_tx_power
= elems
.power_capab
[1];
3425 sta
->power_capab
= 1;
3427 sta
->power_capab
= 0;
3430 return WLAN_STATUS_SUCCESS
;
3434 static void send_deauth(struct hostapd_data
*hapd
, const u8
*addr
,
3438 struct ieee80211_mgmt reply
;
3440 os_memset(&reply
, 0, sizeof(reply
));
3441 reply
.frame_control
=
3442 IEEE80211_FC(WLAN_FC_TYPE_MGMT
, WLAN_FC_STYPE_DEAUTH
);
3443 os_memcpy(reply
.da
, addr
, ETH_ALEN
);
3444 os_memcpy(reply
.sa
, hapd
->own_addr
, ETH_ALEN
);
3445 os_memcpy(reply
.bssid
, hapd
->own_addr
, ETH_ALEN
);
3447 send_len
= IEEE80211_HDRLEN
+ sizeof(reply
.u
.deauth
);
3448 reply
.u
.deauth
.reason_code
= host_to_le16(reason_code
);
3450 if (hostapd_drv_send_mlme(hapd
, &reply
, send_len
, 0) < 0)
3451 wpa_printf(MSG_INFO
, "Failed to send deauth: %s",
3456 static int add_associated_sta(struct hostapd_data
*hapd
,
3457 struct sta_info
*sta
, int reassoc
)
3459 struct ieee80211_ht_capabilities ht_cap
;
3460 struct ieee80211_vht_capabilities vht_cap
;
3461 struct ieee80211_he_capabilities he_cap
;
3465 * Remove the STA entry to ensure the STA PS state gets cleared and
3466 * configuration gets updated. This is relevant for cases, such as
3467 * FT-over-the-DS, where a station re-associates back to the same AP but
3468 * skips the authentication flow, or if working with a driver that
3469 * does not support full AP client state.
3471 * Skip this if the STA has already completed FT reassociation and the
3472 * TK has been configured since the TX/RX PN must not be reset to 0 for
3475 * FT-over-the-DS has a special case where the STA entry (and as such,
3476 * the TK) has not yet been configured to the driver depending on which
3477 * driver interface is used. For that case, allow add-STA operation to
3478 * be used (instead of set-STA). This is needed to allow mac80211-based
3479 * drivers to accept the STA parameter configuration. Since this is
3480 * after a new FT-over-DS exchange, a new TK has been derived, so key
3481 * reinstallation is not a concern for this case.
3483 wpa_printf(MSG_DEBUG
, "Add associated STA " MACSTR
3484 " (added_unassoc=%d auth_alg=%u ft_over_ds=%u reassoc=%d authorized=%d ft_tk=%d fils_tk=%d)",
3485 MAC2STR(sta
->addr
), sta
->added_unassoc
, sta
->auth_alg
,
3486 sta
->ft_over_ds
, reassoc
,
3487 !!(sta
->flags
& WLAN_STA_AUTHORIZED
),
3488 wpa_auth_sta_ft_tk_already_set(sta
->wpa_sm
),
3489 wpa_auth_sta_fils_tk_already_set(sta
->wpa_sm
));
3491 if (!sta
->added_unassoc
&&
3492 (!(sta
->flags
& WLAN_STA_AUTHORIZED
) ||
3493 (reassoc
&& sta
->ft_over_ds
&& sta
->auth_alg
== WLAN_AUTH_FT
) ||
3494 (!wpa_auth_sta_ft_tk_already_set(sta
->wpa_sm
) &&
3495 !wpa_auth_sta_fils_tk_already_set(sta
->wpa_sm
)))) {
3496 hostapd_drv_sta_remove(hapd
, sta
->addr
);
3497 wpa_auth_sm_event(sta
->wpa_sm
, WPA_DRV_STA_REMOVED
);
3500 /* Do not allow the FT-over-DS exception to be used more than
3501 * once per authentication exchange to guarantee a new TK is
3503 sta
->ft_over_ds
= 0;
3506 #ifdef CONFIG_IEEE80211N
3507 if (sta
->flags
& WLAN_STA_HT
)
3508 hostapd_get_ht_capab(hapd
, sta
->ht_capabilities
, &ht_cap
);
3509 #endif /* CONFIG_IEEE80211N */
3510 #ifdef CONFIG_IEEE80211AC
3511 if (sta
->flags
& WLAN_STA_VHT
)
3512 hostapd_get_vht_capab(hapd
, sta
->vht_capabilities
, &vht_cap
);
3513 #endif /* CONFIG_IEEE80211AC */
3514 #ifdef CONFIG_IEEE80211AX
3515 if (sta
->flags
& WLAN_STA_HE
) {
3516 hostapd_get_he_capab(hapd
, sta
->he_capab
, &he_cap
,
3519 #endif /* CONFIG_IEEE80211AX */
3522 * Add the station with forced WLAN_STA_ASSOC flag. The sta->flags
3523 * will be set when the ACK frame for the (Re)Association Response frame
3524 * is processed (TX status driver event).
3526 if (hostapd_sta_add(hapd
, sta
->addr
, sta
->aid
, sta
->capability
,
3527 sta
->supported_rates
, sta
->supported_rates_len
,
3528 sta
->listen_interval
,
3529 sta
->flags
& WLAN_STA_HT
? &ht_cap
: NULL
,
3530 sta
->flags
& WLAN_STA_VHT
? &vht_cap
: NULL
,
3531 sta
->flags
& WLAN_STA_HE
? &he_cap
: NULL
,
3532 sta
->flags
& WLAN_STA_HE
? sta
->he_capab_len
: 0,
3533 sta
->flags
| WLAN_STA_ASSOC
, sta
->qosinfo
,
3534 sta
->vht_opmode
, sta
->p2p_ie
? 1 : 0,
3536 hostapd_logger(hapd
, sta
->addr
,
3537 HOSTAPD_MODULE_IEEE80211
, HOSTAPD_LEVEL_NOTICE
,
3538 "Could not %s STA to kernel driver",
3539 set
? "set" : "add");
3541 if (sta
->added_unassoc
) {
3542 hostapd_drv_sta_remove(hapd
, sta
->addr
);
3543 sta
->added_unassoc
= 0;
3549 sta
->added_unassoc
= 0;
3555 static u16
send_assoc_resp(struct hostapd_data
*hapd
, struct sta_info
*sta
,
3556 const u8
*addr
, u16 status_code
, int reassoc
,
3557 const u8
*ies
, size_t ies_len
, int rssi
)
3562 struct ieee80211_mgmt
*reply
;
3564 u16 res
= WLAN_STATUS_SUCCESS
;
3566 buflen
= sizeof(struct ieee80211_mgmt
) + 1024;
3568 if (sta
&& sta
->fils_hlp_resp
)
3569 buflen
+= wpabuf_len(sta
->fils_hlp_resp
);
3572 #endif /* CONFIG_FILS */
3574 if (sta
&& (hapd
->conf
->wpa_key_mgmt
& WPA_KEY_MGMT_OWE
))
3576 #endif /* CONFIG_OWE */
3578 if (sta
&& sta
->dpp_pfs
)
3579 buflen
+= 5 + sta
->dpp_pfs
->curve
->prime_len
;
3580 #endif /* CONFIG_DPP2 */
3581 buf
= os_zalloc(buflen
);
3583 res
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
3586 reply
= (struct ieee80211_mgmt
*) buf
;
3587 reply
->frame_control
=
3588 IEEE80211_FC(WLAN_FC_TYPE_MGMT
,
3589 (reassoc
? WLAN_FC_STYPE_REASSOC_RESP
:
3590 WLAN_FC_STYPE_ASSOC_RESP
));
3591 os_memcpy(reply
->da
, addr
, ETH_ALEN
);
3592 os_memcpy(reply
->sa
, hapd
->own_addr
, ETH_ALEN
);
3593 os_memcpy(reply
->bssid
, hapd
->own_addr
, ETH_ALEN
);
3595 send_len
= IEEE80211_HDRLEN
;
3596 send_len
+= sizeof(reply
->u
.assoc_resp
);
3597 reply
->u
.assoc_resp
.capab_info
=
3598 host_to_le16(hostapd_own_capab_info(hapd
));
3599 reply
->u
.assoc_resp
.status_code
= host_to_le16(status_code
);
3601 reply
->u
.assoc_resp
.aid
= host_to_le16((sta
? sta
->aid
: 0) |
3603 /* Supported rates */
3604 p
= hostapd_eid_supp_rates(hapd
, reply
->u
.assoc_resp
.variable
);
3605 /* Extended supported rates */
3606 p
= hostapd_eid_ext_supp_rates(hapd
, p
);
3609 if (status_code
== WLAN_STATUS_DENIED_POOR_CHANNEL_CONDITIONS
&&
3611 int delta
= hapd
->iconf
->rssi_reject_assoc_rssi
- rssi
;
3613 p
= hostapd_eid_mbo_rssi_assoc_rej(hapd
, p
, buf
+ buflen
- p
,
3616 #endif /* CONFIG_MBO */
3618 #ifdef CONFIG_IEEE80211R_AP
3619 if (sta
&& status_code
== WLAN_STATUS_SUCCESS
) {
3620 /* IEEE 802.11r: Mobility Domain Information, Fast BSS
3621 * Transition Information, RSN, [RIC Response] */
3622 p
= wpa_sm_write_assoc_resp_ies(sta
->wpa_sm
, p
,
3624 sta
->auth_alg
, ies
, ies_len
);
3626 wpa_printf(MSG_DEBUG
,
3627 "FT: Failed to write AssocResp IEs");
3628 res
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
3632 #endif /* CONFIG_IEEE80211R_AP */
3634 if (sta
&& status_code
== WLAN_STATUS_SUCCESS
&&
3635 (sta
->auth_alg
== WLAN_AUTH_FILS_SK
||
3636 sta
->auth_alg
== WLAN_AUTH_FILS_SK_PFS
||
3637 sta
->auth_alg
== WLAN_AUTH_FILS_PK
))
3638 p
= wpa_auth_write_assoc_resp_fils(sta
->wpa_sm
, p
,
3641 #endif /* CONFIG_FILS */
3644 if (sta
&& status_code
== WLAN_STATUS_SUCCESS
&&
3645 (hapd
->conf
->wpa_key_mgmt
& WPA_KEY_MGMT_OWE
))
3646 p
= wpa_auth_write_assoc_resp_owe(sta
->wpa_sm
, p
,
3649 #endif /* CONFIG_OWE */
3651 if (sta
&& status_code
== WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY
)
3652 p
= hostapd_eid_assoc_comeback_time(hapd
, sta
, p
);
3654 #ifdef CONFIG_IEEE80211N
3655 p
= hostapd_eid_ht_capabilities(hapd
, p
);
3656 p
= hostapd_eid_ht_operation(hapd
, p
);
3657 #endif /* CONFIG_IEEE80211N */
3659 #ifdef CONFIG_IEEE80211AC
3660 if (hapd
->iconf
->ieee80211ac
&& !hapd
->conf
->disable_11ac
&&
3661 !is_6ghz_op_class(hapd
->iconf
->op_class
)) {
3662 u32 nsts
= 0, sta_nsts
;
3664 if (sta
&& hapd
->conf
->use_sta_nsts
&& sta
->vht_capabilities
) {
3665 struct ieee80211_vht_capabilities
*capa
;
3667 nsts
= (hapd
->iface
->conf
->vht_capab
>>
3668 VHT_CAP_BEAMFORMEE_STS_OFFSET
) & 7;
3669 capa
= sta
->vht_capabilities
;
3670 sta_nsts
= (le_to_host32(capa
->vht_capabilities_info
) >>
3671 VHT_CAP_BEAMFORMEE_STS_OFFSET
) & 7;
3673 if (nsts
< sta_nsts
)
3678 p
= hostapd_eid_vht_capabilities(hapd
, p
, nsts
);
3679 p
= hostapd_eid_vht_operation(hapd
, p
);
3681 #endif /* CONFIG_IEEE80211AC */
3683 #ifdef CONFIG_IEEE80211AX
3684 if (hapd
->iconf
->ieee80211ax
) {
3685 p
= hostapd_eid_he_capab(hapd
, p
, IEEE80211_MODE_AP
);
3686 p
= hostapd_eid_he_operation(hapd
, p
);
3687 p
= hostapd_eid_spatial_reuse(hapd
, p
);
3688 p
= hostapd_eid_he_mu_edca_parameter_set(hapd
, p
);
3690 #endif /* CONFIG_IEEE80211AX */
3692 p
= hostapd_eid_ext_capab(hapd
, p
);
3693 p
= hostapd_eid_bss_max_idle_period(hapd
, p
);
3694 if (sta
&& sta
->qos_map_enabled
)
3695 p
= hostapd_eid_qos_map_set(hapd
, p
);
3698 if (hapd
->iface
->fst_ies
) {
3699 os_memcpy(p
, wpabuf_head(hapd
->iface
->fst_ies
),
3700 wpabuf_len(hapd
->iface
->fst_ies
));
3701 p
+= wpabuf_len(hapd
->iface
->fst_ies
);
3703 #endif /* CONFIG_FST */
3706 if ((hapd
->conf
->wpa_key_mgmt
& WPA_KEY_MGMT_OWE
) &&
3707 sta
&& sta
->owe_ecdh
&& status_code
== WLAN_STATUS_SUCCESS
&&
3708 wpa_auth_sta_key_mgmt(sta
->wpa_sm
) == WPA_KEY_MGMT_OWE
) {
3711 pub
= crypto_ecdh_get_pubkey(sta
->owe_ecdh
, 0);
3713 res
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
3716 /* OWE Diffie-Hellman Parameter element */
3717 *p
++ = WLAN_EID_EXTENSION
; /* Element ID */
3718 *p
++ = 1 + 2 + wpabuf_len(pub
); /* Length */
3719 *p
++ = WLAN_EID_EXT_OWE_DH_PARAM
; /* Element ID Extension */
3720 WPA_PUT_LE16(p
, sta
->owe_group
);
3722 os_memcpy(p
, wpabuf_head(pub
), wpabuf_len(pub
));
3723 p
+= wpabuf_len(pub
);
3726 #endif /* CONFIG_OWE */
3729 if ((hapd
->conf
->wpa_key_mgmt
& WPA_KEY_MGMT_DPP
) &&
3730 sta
&& sta
->dpp_pfs
&& status_code
== WLAN_STATUS_SUCCESS
&&
3731 wpa_auth_sta_key_mgmt(sta
->wpa_sm
) == WPA_KEY_MGMT_DPP
) {
3732 os_memcpy(p
, wpabuf_head(sta
->dpp_pfs
->ie
),
3733 wpabuf_len(sta
->dpp_pfs
->ie
));
3734 p
+= wpabuf_len(sta
->dpp_pfs
->ie
);
3736 #endif /* CONFIG_DPP2 */
3738 #ifdef CONFIG_IEEE80211AC
3739 if (sta
&& hapd
->conf
->vendor_vht
&& (sta
->flags
& WLAN_STA_VENDOR_VHT
))
3740 p
= hostapd_eid_vendor_vht(hapd
, p
);
3741 #endif /* CONFIG_IEEE80211AC */
3743 if (sta
&& (sta
->flags
& WLAN_STA_WMM
))
3744 p
= hostapd_eid_wmm(hapd
, p
);
3748 ((sta
->flags
& WLAN_STA_WPS
) ||
3749 ((sta
->flags
& WLAN_STA_MAYBE_WPS
) && hapd
->conf
->wpa
))) {
3750 struct wpabuf
*wps
= wps_build_assoc_resp_ie();
3752 os_memcpy(p
, wpabuf_head(wps
), wpabuf_len(wps
));
3753 p
+= wpabuf_len(wps
);
3757 #endif /* CONFIG_WPS */
3759 if (sta
&& (sta
->flags
& WLAN_STA_MULTI_AP
))
3760 p
= hostapd_eid_multi_ap(hapd
, p
);
3763 if (sta
&& sta
->p2p_ie
&& hapd
->p2p_group
) {
3764 struct wpabuf
*p2p_resp_ie
;
3765 enum p2p_status_code status
;
3766 switch (status_code
) {
3767 case WLAN_STATUS_SUCCESS
:
3768 status
= P2P_SC_SUCCESS
;
3770 case WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
:
3771 status
= P2P_SC_FAIL_LIMIT_REACHED
;
3774 status
= P2P_SC_FAIL_INVALID_PARAMS
;
3777 p2p_resp_ie
= p2p_group_assoc_resp_ie(hapd
->p2p_group
, status
);
3779 os_memcpy(p
, wpabuf_head(p2p_resp_ie
),
3780 wpabuf_len(p2p_resp_ie
));
3781 p
+= wpabuf_len(p2p_resp_ie
);
3782 wpabuf_free(p2p_resp_ie
);
3785 #endif /* CONFIG_P2P */
3787 #ifdef CONFIG_P2P_MANAGER
3788 if (hapd
->conf
->p2p
& P2P_MANAGE
)
3789 p
= hostapd_eid_p2p_manage(hapd
, p
);
3790 #endif /* CONFIG_P2P_MANAGER */
3792 p
= hostapd_eid_mbo(hapd
, p
, buf
+ buflen
- p
);
3794 if (hapd
->conf
->assocresp_elements
&&
3795 (size_t) (buf
+ buflen
- p
) >=
3796 wpabuf_len(hapd
->conf
->assocresp_elements
)) {
3797 os_memcpy(p
, wpabuf_head(hapd
->conf
->assocresp_elements
),
3798 wpabuf_len(hapd
->conf
->assocresp_elements
));
3799 p
+= wpabuf_len(hapd
->conf
->assocresp_elements
);
3802 send_len
+= p
- reply
->u
.assoc_resp
.variable
;
3806 (sta
->auth_alg
== WLAN_AUTH_FILS_SK
||
3807 sta
->auth_alg
== WLAN_AUTH_FILS_SK_PFS
||
3808 sta
->auth_alg
== WLAN_AUTH_FILS_PK
) &&
3809 status_code
== WLAN_STATUS_SUCCESS
) {
3810 struct ieee802_11_elems elems
;
3812 if (ieee802_11_parse_elems(ies
, ies_len
, &elems
, 0) ==
3813 ParseFailed
|| !elems
.fils_session
) {
3814 res
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
3819 *p
++ = WLAN_EID_EXTENSION
; /* Element ID */
3820 *p
++ = 1 + FILS_SESSION_LEN
; /* Length */
3821 *p
++ = WLAN_EID_EXT_FILS_SESSION
; /* Element ID Extension */
3822 os_memcpy(p
, elems
.fils_session
, FILS_SESSION_LEN
);
3823 send_len
+= 2 + 1 + FILS_SESSION_LEN
;
3825 send_len
= fils_encrypt_assoc(sta
->wpa_sm
, buf
, send_len
,
3826 buflen
, sta
->fils_hlp_resp
);
3828 res
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
3832 #endif /* CONFIG_FILS */
3834 if (hostapd_drv_send_mlme(hapd
, reply
, send_len
, 0) < 0) {
3835 wpa_printf(MSG_INFO
, "Failed to send assoc resp: %s",
3837 res
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
3847 u8
* owe_assoc_req_process(struct hostapd_data
*hapd
, struct sta_info
*sta
,
3848 const u8
*owe_dh
, u8 owe_dh_len
,
3849 u8
*owe_buf
, size_t owe_buf_len
, u16
*reason
)
3851 #ifdef CONFIG_TESTING_OPTIONS
3852 if (hapd
->conf
->own_ie_override
) {
3853 wpa_printf(MSG_DEBUG
, "OWE: Using IE override");
3854 *reason
= WLAN_STATUS_SUCCESS
;
3855 return wpa_auth_write_assoc_resp_owe(sta
->wpa_sm
, owe_buf
,
3856 owe_buf_len
, NULL
, 0);
3858 #endif /* CONFIG_TESTING_OPTIONS */
3860 if (wpa_auth_sta_get_pmksa(sta
->wpa_sm
)) {
3861 wpa_printf(MSG_DEBUG
, "OWE: Using PMKSA caching");
3862 owe_buf
= wpa_auth_write_assoc_resp_owe(sta
->wpa_sm
, owe_buf
,
3863 owe_buf_len
, NULL
, 0);
3864 *reason
= WLAN_STATUS_SUCCESS
;
3868 if (sta
->owe_pmk
&& sta
->external_dh_updated
) {
3869 wpa_printf(MSG_DEBUG
, "OWE: Using previously derived PMK");
3870 *reason
= WLAN_STATUS_SUCCESS
;
3874 *reason
= owe_process_assoc_req(hapd
, sta
, owe_dh
, owe_dh_len
);
3875 if (*reason
!= WLAN_STATUS_SUCCESS
)
3878 owe_buf
= wpa_auth_write_assoc_resp_owe(sta
->wpa_sm
, owe_buf
,
3879 owe_buf_len
, NULL
, 0);
3881 if (sta
->owe_ecdh
&& owe_buf
) {
3884 pub
= crypto_ecdh_get_pubkey(sta
->owe_ecdh
, 0);
3886 *reason
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
3890 /* OWE Diffie-Hellman Parameter element */
3891 *owe_buf
++ = WLAN_EID_EXTENSION
; /* Element ID */
3892 *owe_buf
++ = 1 + 2 + wpabuf_len(pub
); /* Length */
3893 *owe_buf
++ = WLAN_EID_EXT_OWE_DH_PARAM
; /* Element ID Extension
3895 WPA_PUT_LE16(owe_buf
, sta
->owe_group
);
3897 os_memcpy(owe_buf
, wpabuf_head(pub
), wpabuf_len(pub
));
3898 owe_buf
+= wpabuf_len(pub
);
3904 #endif /* CONFIG_OWE */
3909 void fils_hlp_finish_assoc(struct hostapd_data
*hapd
, struct sta_info
*sta
)
3913 wpa_printf(MSG_DEBUG
, "FILS: Finish association with " MACSTR
,
3914 MAC2STR(sta
->addr
));
3915 eloop_cancel_timeout(fils_hlp_timeout
, hapd
, sta
);
3916 if (!sta
->fils_pending_assoc_req
)
3918 reply_res
= send_assoc_resp(hapd
, sta
, sta
->addr
, WLAN_STATUS_SUCCESS
,
3919 sta
->fils_pending_assoc_is_reassoc
,
3920 sta
->fils_pending_assoc_req
,
3921 sta
->fils_pending_assoc_req_len
, 0);
3922 os_free(sta
->fils_pending_assoc_req
);
3923 sta
->fils_pending_assoc_req
= NULL
;
3924 sta
->fils_pending_assoc_req_len
= 0;
3925 wpabuf_free(sta
->fils_hlp_resp
);
3926 sta
->fils_hlp_resp
= NULL
;
3927 wpabuf_free(sta
->hlp_dhcp_discover
);
3928 sta
->hlp_dhcp_discover
= NULL
;
3931 * Remove the station in case transmission of a success response fails.
3932 * At this point the station was already added associated to the driver.
3934 if (reply_res
!= WLAN_STATUS_SUCCESS
)
3935 hostapd_drv_sta_remove(hapd
, sta
->addr
);
3939 void fils_hlp_timeout(void *eloop_ctx
, void *eloop_data
)
3941 struct hostapd_data
*hapd
= eloop_ctx
;
3942 struct sta_info
*sta
= eloop_data
;
3944 wpa_printf(MSG_DEBUG
,
3945 "FILS: HLP response timeout - continue with association response for "
3946 MACSTR
, MAC2STR(sta
->addr
));
3947 if (sta
->fils_drv_assoc_finish
)
3948 hostapd_notify_assoc_fils_finish(hapd
, sta
);
3950 fils_hlp_finish_assoc(hapd
, sta
);
3953 #endif /* CONFIG_FILS */
3956 static void handle_assoc(struct hostapd_data
*hapd
,
3957 const struct ieee80211_mgmt
*mgmt
, size_t len
,
3958 int reassoc
, int rssi
)
3960 u16 capab_info
, listen_interval
, seq_ctrl
, fc
;
3961 u16 resp
= WLAN_STATUS_SUCCESS
, reply_res
;
3964 struct sta_info
*sta
;
3966 struct hostapd_sta_wpa_psk_short
*psk
= NULL
;
3967 char *identity
= NULL
;
3968 char *radius_cui
= NULL
;
3970 int delay_assoc
= 0;
3971 #endif /* CONFIG_FILS */
3973 if (len
< IEEE80211_HDRLEN
+ (reassoc
? sizeof(mgmt
->u
.reassoc_req
) :
3974 sizeof(mgmt
->u
.assoc_req
))) {
3975 wpa_printf(MSG_INFO
, "handle_assoc(reassoc=%d) - too short payload (len=%lu)",
3976 reassoc
, (unsigned long) len
);
3980 #ifdef CONFIG_TESTING_OPTIONS
3982 if (hapd
->iconf
->ignore_reassoc_probability
> 0.0 &&
3983 drand48() < hapd
->iconf
->ignore_reassoc_probability
) {
3984 wpa_printf(MSG_INFO
,
3985 "TESTING: ignoring reassoc request from "
3986 MACSTR
, MAC2STR(mgmt
->sa
));
3990 if (hapd
->iconf
->ignore_assoc_probability
> 0.0 &&
3991 drand48() < hapd
->iconf
->ignore_assoc_probability
) {
3992 wpa_printf(MSG_INFO
,
3993 "TESTING: ignoring assoc request from "
3994 MACSTR
, MAC2STR(mgmt
->sa
));
3998 #endif /* CONFIG_TESTING_OPTIONS */
4000 fc
= le_to_host16(mgmt
->frame_control
);
4001 seq_ctrl
= le_to_host16(mgmt
->seq_ctrl
);
4004 capab_info
= le_to_host16(mgmt
->u
.reassoc_req
.capab_info
);
4005 listen_interval
= le_to_host16(
4006 mgmt
->u
.reassoc_req
.listen_interval
);
4007 wpa_printf(MSG_DEBUG
, "reassociation request: STA=" MACSTR
4008 " capab_info=0x%02x listen_interval=%d current_ap="
4009 MACSTR
" seq_ctrl=0x%x%s",
4010 MAC2STR(mgmt
->sa
), capab_info
, listen_interval
,
4011 MAC2STR(mgmt
->u
.reassoc_req
.current_ap
),
4012 seq_ctrl
, (fc
& WLAN_FC_RETRY
) ? " retry" : "");
4013 left
= len
- (IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.reassoc_req
));
4014 pos
= mgmt
->u
.reassoc_req
.variable
;
4016 capab_info
= le_to_host16(mgmt
->u
.assoc_req
.capab_info
);
4017 listen_interval
= le_to_host16(
4018 mgmt
->u
.assoc_req
.listen_interval
);
4019 wpa_printf(MSG_DEBUG
, "association request: STA=" MACSTR
4020 " capab_info=0x%02x listen_interval=%d "
4022 MAC2STR(mgmt
->sa
), capab_info
, listen_interval
,
4023 seq_ctrl
, (fc
& WLAN_FC_RETRY
) ? " retry" : "");
4024 left
= len
- (IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.assoc_req
));
4025 pos
= mgmt
->u
.assoc_req
.variable
;
4028 sta
= ap_get_sta(hapd
, mgmt
->sa
);
4029 #ifdef CONFIG_IEEE80211R_AP
4030 if (sta
&& sta
->auth_alg
== WLAN_AUTH_FT
&&
4031 (sta
->flags
& WLAN_STA_AUTH
) == 0) {
4032 wpa_printf(MSG_DEBUG
, "FT: Allow STA " MACSTR
" to associate "
4033 "prior to authentication since it is using "
4034 "over-the-DS FT", MAC2STR(mgmt
->sa
));
4037 * Mark station as authenticated, to avoid adding station
4038 * entry in the driver as associated and not authenticated
4040 sta
->flags
|= WLAN_STA_AUTH
;
4042 #endif /* CONFIG_IEEE80211R_AP */
4043 if (sta
== NULL
|| (sta
->flags
& WLAN_STA_AUTH
) == 0) {
4044 if (hapd
->iface
->current_mode
&&
4045 hapd
->iface
->current_mode
->mode
==
4046 HOSTAPD_MODE_IEEE80211AD
) {
4048 u32 session_timeout
, acct_interim_interval
;
4049 struct vlan_description vlan_id
;
4051 acl_res
= ieee802_11_allowed_address(
4052 hapd
, mgmt
->sa
, (const u8
*) mgmt
, len
,
4053 &session_timeout
, &acct_interim_interval
,
4054 &vlan_id
, &psk
, &identity
, &radius_cui
, 0);
4055 if (acl_res
== HOSTAPD_ACL_REJECT
) {
4056 wpa_msg(hapd
->msg_ctx
, MSG_DEBUG
,
4057 "Ignore Association Request frame from "
4058 MACSTR
" due to ACL reject",
4060 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
4063 if (acl_res
== HOSTAPD_ACL_PENDING
)
4066 /* DMG/IEEE 802.11ad does not use authentication.
4067 * Allocate sta entry upon association. */
4068 sta
= ap_sta_add(hapd
, mgmt
->sa
);
4070 hostapd_logger(hapd
, mgmt
->sa
,
4071 HOSTAPD_MODULE_IEEE80211
,
4073 "Failed to add STA");
4074 resp
= WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
;
4078 acl_res
= ieee802_11_set_radius_info(
4079 hapd
, sta
, acl_res
, session_timeout
,
4080 acct_interim_interval
, &vlan_id
, &psk
,
4081 &identity
, &radius_cui
);
4083 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
4087 hostapd_logger(hapd
, sta
->addr
,
4088 HOSTAPD_MODULE_IEEE80211
,
4089 HOSTAPD_LEVEL_DEBUG
,
4090 "Skip authentication for DMG/IEEE 802.11ad");
4091 sta
->flags
|= WLAN_STA_AUTH
;
4092 wpa_auth_sm_event(sta
->wpa_sm
, WPA_AUTH
);
4093 sta
->auth_alg
= WLAN_AUTH_OPEN
;
4095 hostapd_logger(hapd
, mgmt
->sa
,
4096 HOSTAPD_MODULE_IEEE80211
,
4098 "Station tried to associate before authentication (aid=%d flags=0x%x)",
4099 sta
? sta
->aid
: -1,
4100 sta
? sta
->flags
: 0);
4101 send_deauth(hapd
, mgmt
->sa
,
4102 WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA
);
4107 if ((fc
& WLAN_FC_RETRY
) &&
4108 sta
->last_seq_ctrl
!= WLAN_INVALID_MGMT_SEQ
&&
4109 sta
->last_seq_ctrl
== seq_ctrl
&&
4110 sta
->last_subtype
== (reassoc
? WLAN_FC_STYPE_REASSOC_REQ
:
4111 WLAN_FC_STYPE_ASSOC_REQ
)) {
4112 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
4113 HOSTAPD_LEVEL_DEBUG
,
4114 "Drop repeated association frame seq_ctrl=0x%x",
4118 sta
->last_seq_ctrl
= seq_ctrl
;
4119 sta
->last_subtype
= reassoc
? WLAN_FC_STYPE_REASSOC_REQ
:
4120 WLAN_FC_STYPE_ASSOC_REQ
;
4122 if (hapd
->tkip_countermeasures
) {
4123 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
4127 if (listen_interval
> hapd
->conf
->max_listen_interval
) {
4128 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
4129 HOSTAPD_LEVEL_DEBUG
,
4130 "Too large Listen Interval (%d)",
4132 resp
= WLAN_STATUS_ASSOC_DENIED_LISTEN_INT_TOO_LARGE
;
4137 if (hapd
->conf
->mbo_enabled
&& hapd
->mbo_assoc_disallow
) {
4138 resp
= WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
;
4142 if (hapd
->iconf
->rssi_reject_assoc_rssi
&& rssi
&&
4143 rssi
< hapd
->iconf
->rssi_reject_assoc_rssi
&&
4144 (sta
->auth_rssi
== 0 ||
4145 sta
->auth_rssi
< hapd
->iconf
->rssi_reject_assoc_rssi
)) {
4146 resp
= WLAN_STATUS_DENIED_POOR_CHANNEL_CONDITIONS
;
4149 #endif /* CONFIG_MBO */
4152 * sta->capability is used in check_assoc_ies() for RRM enabled
4153 * capability element.
4155 sta
->capability
= capab_info
;
4158 if (sta
->auth_alg
== WLAN_AUTH_FILS_SK
||
4159 sta
->auth_alg
== WLAN_AUTH_FILS_SK_PFS
||
4160 sta
->auth_alg
== WLAN_AUTH_FILS_PK
) {
4163 /* The end of the payload is encrypted. Need to decrypt it
4164 * before parsing. */
4166 tmp
= os_memdup(pos
, left
);
4168 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
4172 res
= fils_decrypt_assoc(sta
->wpa_sm
, sta
->fils_session
, mgmt
,
4175 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
4181 #endif /* CONFIG_FILS */
4183 /* followed by SSID and Supported rates; and HT capabilities if 802.11n
4185 resp
= check_assoc_ies(hapd
, sta
, pos
, left
, reassoc
);
4186 if (resp
!= WLAN_STATUS_SUCCESS
)
4189 if (hostapd_get_aid(hapd
, sta
) < 0) {
4190 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
4191 HOSTAPD_LEVEL_INFO
, "No room for more AIDs");
4192 resp
= WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
;
4196 sta
->listen_interval
= listen_interval
;
4198 if (hapd
->iface
->current_mode
&&
4199 hapd
->iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211G
)
4200 sta
->flags
|= WLAN_STA_NONERP
;
4201 for (i
= 0; i
< sta
->supported_rates_len
; i
++) {
4202 if ((sta
->supported_rates
[i
] & 0x7f) > 22) {
4203 sta
->flags
&= ~WLAN_STA_NONERP
;
4207 if (sta
->flags
& WLAN_STA_NONERP
&& !sta
->nonerp_set
) {
4208 sta
->nonerp_set
= 1;
4209 hapd
->iface
->num_sta_non_erp
++;
4210 if (hapd
->iface
->num_sta_non_erp
== 1)
4211 ieee802_11_set_beacons(hapd
->iface
);
4214 if (!(sta
->capability
& WLAN_CAPABILITY_SHORT_SLOT_TIME
) &&
4215 !sta
->no_short_slot_time_set
) {
4216 sta
->no_short_slot_time_set
= 1;
4217 hapd
->iface
->num_sta_no_short_slot_time
++;
4218 if (hapd
->iface
->current_mode
&&
4219 hapd
->iface
->current_mode
->mode
==
4220 HOSTAPD_MODE_IEEE80211G
&&
4221 hapd
->iface
->num_sta_no_short_slot_time
== 1)
4222 ieee802_11_set_beacons(hapd
->iface
);
4225 if (sta
->capability
& WLAN_CAPABILITY_SHORT_PREAMBLE
)
4226 sta
->flags
|= WLAN_STA_SHORT_PREAMBLE
;
4228 sta
->flags
&= ~WLAN_STA_SHORT_PREAMBLE
;
4230 if (!(sta
->capability
& WLAN_CAPABILITY_SHORT_PREAMBLE
) &&
4231 !sta
->no_short_preamble_set
) {
4232 sta
->no_short_preamble_set
= 1;
4233 hapd
->iface
->num_sta_no_short_preamble
++;
4234 if (hapd
->iface
->current_mode
&&
4235 hapd
->iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211G
4236 && hapd
->iface
->num_sta_no_short_preamble
== 1)
4237 ieee802_11_set_beacons(hapd
->iface
);
4240 #ifdef CONFIG_IEEE80211N
4241 update_ht_state(hapd
, sta
);
4242 #endif /* CONFIG_IEEE80211N */
4244 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
4245 HOSTAPD_LEVEL_DEBUG
,
4246 "association OK (aid %d)", sta
->aid
);
4247 /* Station will be marked associated, after it acknowledges AssocResp
4249 sta
->flags
|= WLAN_STA_ASSOC_REQ_OK
;
4251 if ((sta
->flags
& WLAN_STA_MFP
) && sta
->sa_query_timed_out
) {
4252 wpa_printf(MSG_DEBUG
, "Allowing %sassociation after timed out "
4253 "SA Query procedure", reassoc
? "re" : "");
4254 /* TODO: Send a protected Disassociate frame to the STA using
4255 * the old key and Reason Code "Previous Authentication no
4256 * longer valid". Make sure this is only sent protected since
4257 * unprotected frame would be received by the STA that is now
4258 * trying to associate.
4262 /* Make sure that the previously registered inactivity timer will not
4263 * remove the STA immediately. */
4264 sta
->timeout_next
= STA_NULLFUNC
;
4266 #ifdef CONFIG_TAXONOMY
4267 taxonomy_sta_info_assoc_req(hapd
, sta
, pos
, left
);
4268 #endif /* CONFIG_TAXONOMY */
4270 sta
->pending_wds_enable
= 0;
4273 if (sta
->auth_alg
== WLAN_AUTH_FILS_SK
||
4274 sta
->auth_alg
== WLAN_AUTH_FILS_SK_PFS
||
4275 sta
->auth_alg
== WLAN_AUTH_FILS_PK
) {
4276 if (fils_process_hlp(hapd
, sta
, pos
, left
) > 0)
4279 #endif /* CONFIG_FILS */
4283 os_free(radius_cui
);
4284 hostapd_free_psk_list(psk
);
4287 * In case of a successful response, add the station to the driver.
4288 * Otherwise, the kernel may ignore Data frames before we process the
4289 * ACK frame (TX status). In case of a failure, this station will be
4292 * Note that this is not compliant with the IEEE 802.11 standard that
4293 * states that a non-AP station should transition into the
4294 * authenticated/associated state only after the station acknowledges
4295 * the (Re)Association Response frame. However, still do this as:
4297 * 1. In case the station does not acknowledge the (Re)Association
4298 * Response frame, it will be removed.
4299 * 2. Data frames will be dropped in the kernel until the station is
4300 * set into authorized state, and there are no significant known
4301 * issues with processing other non-Data Class 3 frames during this
4304 if (resp
== WLAN_STATUS_SUCCESS
&& sta
&&
4305 add_associated_sta(hapd
, sta
, reassoc
))
4306 resp
= WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
;
4309 if (sta
&& delay_assoc
&& resp
== WLAN_STATUS_SUCCESS
&&
4310 eloop_is_timeout_registered(fils_hlp_timeout
, hapd
, sta
) &&
4311 sta
->fils_pending_assoc_req
) {
4312 /* Do not reschedule fils_hlp_timeout in case the station
4313 * retransmits (Re)Association Request frame while waiting for
4314 * the previously started FILS HLP wait, so that the timeout can
4315 * be determined from the first pending attempt. */
4316 wpa_printf(MSG_DEBUG
,
4317 "FILS: Continue waiting for HLP processing before sending (Re)Association Response frame to "
4318 MACSTR
, MAC2STR(sta
->addr
));
4323 eloop_cancel_timeout(fils_hlp_timeout
, hapd
, sta
);
4324 os_free(sta
->fils_pending_assoc_req
);
4325 sta
->fils_pending_assoc_req
= NULL
;
4326 sta
->fils_pending_assoc_req_len
= 0;
4327 wpabuf_free(sta
->fils_hlp_resp
);
4328 sta
->fils_hlp_resp
= NULL
;
4330 if (sta
&& delay_assoc
&& resp
== WLAN_STATUS_SUCCESS
) {
4331 sta
->fils_pending_assoc_req
= tmp
;
4332 sta
->fils_pending_assoc_req_len
= left
;
4333 sta
->fils_pending_assoc_is_reassoc
= reassoc
;
4334 sta
->fils_drv_assoc_finish
= 0;
4335 wpa_printf(MSG_DEBUG
,
4336 "FILS: Waiting for HLP processing before sending (Re)Association Response frame to "
4337 MACSTR
, MAC2STR(sta
->addr
));
4338 eloop_cancel_timeout(fils_hlp_timeout
, hapd
, sta
);
4339 eloop_register_timeout(0, hapd
->conf
->fils_hlp_wait_time
* 1024,
4340 fils_hlp_timeout
, hapd
, sta
);
4343 #endif /* CONFIG_FILS */
4345 reply_res
= send_assoc_resp(hapd
, sta
, mgmt
->sa
, resp
, reassoc
, pos
,
4350 * Remove the station in case tranmission of a success response fails
4351 * (the STA was added associated to the driver) or if the station was
4352 * previously added unassociated.
4354 if (sta
&& ((reply_res
!= WLAN_STATUS_SUCCESS
&&
4355 resp
== WLAN_STATUS_SUCCESS
) || sta
->added_unassoc
)) {
4356 hostapd_drv_sta_remove(hapd
, sta
->addr
);
4357 sta
->added_unassoc
= 0;
4362 static void handle_disassoc(struct hostapd_data
*hapd
,
4363 const struct ieee80211_mgmt
*mgmt
, size_t len
)
4365 struct sta_info
*sta
;
4367 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.disassoc
)) {
4368 wpa_printf(MSG_INFO
, "handle_disassoc - too short payload (len=%lu)",
4369 (unsigned long) len
);
4373 wpa_printf(MSG_DEBUG
, "disassocation: STA=" MACSTR
" reason_code=%d",
4375 le_to_host16(mgmt
->u
.disassoc
.reason_code
));
4377 sta
= ap_get_sta(hapd
, mgmt
->sa
);
4379 wpa_printf(MSG_INFO
, "Station " MACSTR
" trying to disassociate, but it is not associated",
4384 ap_sta_set_authorized(hapd
, sta
, 0);
4385 sta
->last_seq_ctrl
= WLAN_INVALID_MGMT_SEQ
;
4386 sta
->flags
&= ~(WLAN_STA_ASSOC
| WLAN_STA_ASSOC_REQ_OK
);
4387 wpa_auth_sm_event(sta
->wpa_sm
, WPA_DISASSOC
);
4388 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
4389 HOSTAPD_LEVEL_INFO
, "disassociated");
4390 sta
->acct_terminate_cause
= RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST
;
4391 ieee802_1x_notify_port_enabled(sta
->eapol_sm
, 0);
4392 /* Stop Accounting and IEEE 802.1X sessions, but leave the STA
4394 accounting_sta_stop(hapd
, sta
);
4395 ieee802_1x_free_station(hapd
, sta
);
4397 hostapd_drv_br_delete_ip_neigh(hapd
, 4, (u8
*) &sta
->ipaddr
);
4398 ap_sta_ip6addr_del(hapd
, sta
);
4399 hostapd_drv_sta_remove(hapd
, sta
->addr
);
4400 sta
->added_unassoc
= 0;
4402 if (sta
->timeout_next
== STA_NULLFUNC
||
4403 sta
->timeout_next
== STA_DISASSOC
) {
4404 sta
->timeout_next
= STA_DEAUTH
;
4405 eloop_cancel_timeout(ap_handle_timer
, hapd
, sta
);
4406 eloop_register_timeout(AP_DEAUTH_DELAY
, 0, ap_handle_timer
,
4410 mlme_disassociate_indication(
4411 hapd
, sta
, le_to_host16(mgmt
->u
.disassoc
.reason_code
));
4413 /* DMG/IEEE 802.11ad does not use deauthication. Deallocate sta upon
4414 * disassociation. */
4415 if (hapd
->iface
->current_mode
&&
4416 hapd
->iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211AD
) {
4417 sta
->flags
&= ~WLAN_STA_AUTH
;
4418 wpa_auth_sm_event(sta
->wpa_sm
, WPA_DEAUTH
);
4419 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
4420 HOSTAPD_LEVEL_DEBUG
, "deauthenticated");
4421 ap_free_sta(hapd
, sta
);
4426 static void handle_deauth(struct hostapd_data
*hapd
,
4427 const struct ieee80211_mgmt
*mgmt
, size_t len
)
4429 struct sta_info
*sta
;
4431 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.deauth
)) {
4432 wpa_msg(hapd
->msg_ctx
, MSG_DEBUG
, "handle_deauth - too short "
4433 "payload (len=%lu)", (unsigned long) len
);
4437 wpa_msg(hapd
->msg_ctx
, MSG_DEBUG
, "deauthentication: STA=" MACSTR
4439 MAC2STR(mgmt
->sa
), le_to_host16(mgmt
->u
.deauth
.reason_code
));
4441 sta
= ap_get_sta(hapd
, mgmt
->sa
);
4443 wpa_msg(hapd
->msg_ctx
, MSG_DEBUG
, "Station " MACSTR
" trying "
4444 "to deauthenticate, but it is not authenticated",
4449 ap_sta_set_authorized(hapd
, sta
, 0);
4450 sta
->last_seq_ctrl
= WLAN_INVALID_MGMT_SEQ
;
4451 sta
->flags
&= ~(WLAN_STA_AUTH
| WLAN_STA_ASSOC
|
4452 WLAN_STA_ASSOC_REQ_OK
);
4453 wpa_auth_sm_event(sta
->wpa_sm
, WPA_DEAUTH
);
4454 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
4455 HOSTAPD_LEVEL_DEBUG
, "deauthenticated");
4456 mlme_deauthenticate_indication(
4457 hapd
, sta
, le_to_host16(mgmt
->u
.deauth
.reason_code
));
4458 sta
->acct_terminate_cause
= RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST
;
4459 ieee802_1x_notify_port_enabled(sta
->eapol_sm
, 0);
4460 ap_free_sta(hapd
, sta
);
4464 static void handle_beacon(struct hostapd_data
*hapd
,
4465 const struct ieee80211_mgmt
*mgmt
, size_t len
,
4466 struct hostapd_frame_info
*fi
)
4468 struct ieee802_11_elems elems
;
4470 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.beacon
)) {
4471 wpa_printf(MSG_INFO
, "handle_beacon - too short payload (len=%lu)",
4472 (unsigned long) len
);
4476 (void) ieee802_11_parse_elems(mgmt
->u
.beacon
.variable
,
4477 len
- (IEEE80211_HDRLEN
+
4478 sizeof(mgmt
->u
.beacon
)), &elems
,
4481 ap_list_process_beacon(hapd
->iface
, mgmt
, &elems
, fi
);
4485 static int robust_action_frame(u8 category
)
4487 return category
!= WLAN_ACTION_PUBLIC
&&
4488 category
!= WLAN_ACTION_HT
;
4492 static int handle_action(struct hostapd_data
*hapd
,
4493 const struct ieee80211_mgmt
*mgmt
, size_t len
,
4496 struct sta_info
*sta
;
4497 u8
*action __maybe_unused
;
4499 if (len
< IEEE80211_HDRLEN
+ 2 + 1) {
4500 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
4501 HOSTAPD_LEVEL_DEBUG
,
4502 "handle_action - too short payload (len=%lu)",
4503 (unsigned long) len
);
4507 action
= (u8
*) &mgmt
->u
.action
.u
;
4508 wpa_printf(MSG_DEBUG
, "RX_ACTION category %u action %u sa " MACSTR
4509 " da " MACSTR
" len %d freq %u",
4510 mgmt
->u
.action
.category
, *action
,
4511 MAC2STR(mgmt
->sa
), MAC2STR(mgmt
->da
), (int) len
, freq
);
4513 sta
= ap_get_sta(hapd
, mgmt
->sa
);
4515 if (mgmt
->u
.action
.category
!= WLAN_ACTION_PUBLIC
&&
4516 (sta
== NULL
|| !(sta
->flags
& WLAN_STA_ASSOC
))) {
4517 wpa_printf(MSG_DEBUG
, "IEEE 802.11: Ignored Action "
4518 "frame (category=%u) from unassociated STA " MACSTR
,
4519 mgmt
->u
.action
.category
, MAC2STR(mgmt
->sa
));
4523 if (sta
&& (sta
->flags
& WLAN_STA_MFP
) &&
4524 !(mgmt
->frame_control
& host_to_le16(WLAN_FC_ISWEP
)) &&
4525 robust_action_frame(mgmt
->u
.action
.category
)) {
4526 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
4527 HOSTAPD_LEVEL_DEBUG
,
4528 "Dropped unprotected Robust Action frame from "
4534 u16 fc
= le_to_host16(mgmt
->frame_control
);
4535 u16 seq_ctrl
= le_to_host16(mgmt
->seq_ctrl
);
4537 if ((fc
& WLAN_FC_RETRY
) &&
4538 sta
->last_seq_ctrl
!= WLAN_INVALID_MGMT_SEQ
&&
4539 sta
->last_seq_ctrl
== seq_ctrl
&&
4540 sta
->last_subtype
== WLAN_FC_STYPE_ACTION
) {
4541 hostapd_logger(hapd
, sta
->addr
,
4542 HOSTAPD_MODULE_IEEE80211
,
4543 HOSTAPD_LEVEL_DEBUG
,
4544 "Drop repeated action frame seq_ctrl=0x%x",
4549 sta
->last_seq_ctrl
= seq_ctrl
;
4550 sta
->last_subtype
= WLAN_FC_STYPE_ACTION
;
4553 switch (mgmt
->u
.action
.category
) {
4554 #ifdef CONFIG_IEEE80211R_AP
4555 case WLAN_ACTION_FT
:
4557 wpa_ft_action_rx(sta
->wpa_sm
, (u8
*) &mgmt
->u
.action
,
4558 len
- IEEE80211_HDRLEN
))
4561 #endif /* CONFIG_IEEE80211R_AP */
4562 case WLAN_ACTION_WMM
:
4563 hostapd_wmm_action(hapd
, mgmt
, len
);
4565 case WLAN_ACTION_SA_QUERY
:
4566 ieee802_11_sa_query_action(hapd
, mgmt
, len
);
4568 #ifdef CONFIG_WNM_AP
4569 case WLAN_ACTION_WNM
:
4570 ieee802_11_rx_wnm_action_ap(hapd
, mgmt
, len
);
4572 #endif /* CONFIG_WNM_AP */
4574 case WLAN_ACTION_FST
:
4575 if (hapd
->iface
->fst
)
4576 fst_rx_action(hapd
->iface
->fst
, mgmt
, len
);
4578 wpa_printf(MSG_DEBUG
,
4579 "FST: Ignore FST Action frame - no FST attached");
4581 #endif /* CONFIG_FST */
4582 case WLAN_ACTION_PUBLIC
:
4583 case WLAN_ACTION_PROTECTED_DUAL
:
4584 #ifdef CONFIG_IEEE80211N
4585 if (len
>= IEEE80211_HDRLEN
+ 2 &&
4586 mgmt
->u
.action
.u
.public_action
.action
==
4587 WLAN_PA_20_40_BSS_COEX
) {
4588 hostapd_2040_coex_action(hapd
, mgmt
, len
);
4591 #endif /* CONFIG_IEEE80211N */
4593 if (len
>= IEEE80211_HDRLEN
+ 6 &&
4594 mgmt
->u
.action
.u
.vs_public_action
.action
==
4595 WLAN_PA_VENDOR_SPECIFIC
&&
4596 WPA_GET_BE24(mgmt
->u
.action
.u
.vs_public_action
.oui
) ==
4598 mgmt
->u
.action
.u
.vs_public_action
.variable
[0] ==
4600 const u8
*pos
, *end
;
4602 pos
= mgmt
->u
.action
.u
.vs_public_action
.oui
;
4603 end
= ((const u8
*) mgmt
) + len
;
4604 hostapd_dpp_rx_action(hapd
, mgmt
->sa
, pos
, end
- pos
,
4608 if (len
>= IEEE80211_HDRLEN
+ 2 &&
4609 (mgmt
->u
.action
.u
.public_action
.action
==
4610 WLAN_PA_GAS_INITIAL_RESP
||
4611 mgmt
->u
.action
.u
.public_action
.action
==
4612 WLAN_PA_GAS_COMEBACK_RESP
)) {
4613 const u8
*pos
, *end
;
4615 pos
= &mgmt
->u
.action
.u
.public_action
.action
;
4616 end
= ((const u8
*) mgmt
) + len
;
4617 gas_query_ap_rx(hapd
->gas
, mgmt
->sa
,
4618 mgmt
->u
.action
.category
,
4619 pos
, end
- pos
, hapd
->iface
->freq
);
4622 #endif /* CONFIG_DPP */
4623 if (hapd
->public_action_cb
) {
4624 hapd
->public_action_cb(hapd
->public_action_cb_ctx
,
4628 if (hapd
->public_action_cb2
) {
4629 hapd
->public_action_cb2(hapd
->public_action_cb2_ctx
,
4633 if (hapd
->public_action_cb
|| hapd
->public_action_cb2
)
4636 case WLAN_ACTION_VENDOR_SPECIFIC
:
4637 if (hapd
->vendor_action_cb
) {
4638 if (hapd
->vendor_action_cb(hapd
->vendor_action_cb_ctx
,
4640 hapd
->iface
->freq
) == 0)
4644 case WLAN_ACTION_RADIO_MEASUREMENT
:
4645 hostapd_handle_radio_measurement(hapd
, (const u8
*) mgmt
, len
);
4649 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
4650 HOSTAPD_LEVEL_DEBUG
,
4651 "handle_action - unknown action category %d or invalid "
4653 mgmt
->u
.action
.category
);
4654 if (!is_multicast_ether_addr(mgmt
->da
) &&
4655 !(mgmt
->u
.action
.category
& 0x80) &&
4656 !is_multicast_ether_addr(mgmt
->sa
)) {
4657 struct ieee80211_mgmt
*resp
;
4660 * IEEE 802.11-REVma/D9.0 - 7.3.1.11
4661 * Return the Action frame to the source without change
4662 * except that MSB of the Category set to 1.
4664 wpa_printf(MSG_DEBUG
, "IEEE 802.11: Return unknown Action "
4665 "frame back to sender");
4666 resp
= os_memdup(mgmt
, len
);
4669 os_memcpy(resp
->da
, resp
->sa
, ETH_ALEN
);
4670 os_memcpy(resp
->sa
, hapd
->own_addr
, ETH_ALEN
);
4671 os_memcpy(resp
->bssid
, hapd
->own_addr
, ETH_ALEN
);
4672 resp
->u
.action
.category
|= 0x80;
4674 if (hostapd_drv_send_mlme(hapd
, resp
, len
, 0) < 0) {
4675 wpa_printf(MSG_ERROR
, "IEEE 802.11: Failed to send "
4686 * ieee802_11_mgmt - process incoming IEEE 802.11 management frames
4687 * @hapd: hostapd BSS data structure (the BSS to which the management frame was
4689 * @buf: management frame data (starting from IEEE 802.11 header)
4690 * @len: length of frame data in octets
4691 * @fi: meta data about received frame (signal level, etc.)
4693 * Process all incoming IEEE 802.11 management frames. This will be called for
4694 * each frame received from the kernel driver through wlan#ap interface. In
4695 * addition, it can be called to re-inserted pending frames (e.g., when using
4696 * external RADIUS server as an MAC ACL).
4698 int ieee802_11_mgmt(struct hostapd_data
*hapd
, const u8
*buf
, size_t len
,
4699 struct hostapd_frame_info
*fi
)
4701 struct ieee80211_mgmt
*mgmt
;
4705 int ssi_signal
= fi
? fi
->ssi_signal
: 0;
4713 freq
= hapd
->iface
->freq
;
4715 mgmt
= (struct ieee80211_mgmt
*) buf
;
4716 fc
= le_to_host16(mgmt
->frame_control
);
4717 stype
= WLAN_FC_GET_STYPE(fc
);
4719 if (is_multicast_ether_addr(mgmt
->sa
) ||
4720 is_zero_ether_addr(mgmt
->sa
) ||
4721 os_memcmp(mgmt
->sa
, hapd
->own_addr
, ETH_ALEN
) == 0) {
4722 /* Do not process any frames with unexpected/invalid SA so that
4723 * we do not add any state for unexpected STA addresses or end
4724 * up sending out frames to unexpected destination. */
4725 wpa_printf(MSG_DEBUG
, "MGMT: Invalid SA=" MACSTR
4726 " in received frame - ignore this frame silently",
4731 if (stype
== WLAN_FC_STYPE_BEACON
) {
4732 handle_beacon(hapd
, mgmt
, len
, fi
);
4736 if (!is_broadcast_ether_addr(mgmt
->bssid
) &&
4738 /* Invitation responses can be sent with the peer MAC as BSSID */
4739 !((hapd
->conf
->p2p
& P2P_GROUP_OWNER
) &&
4740 stype
== WLAN_FC_STYPE_ACTION
) &&
4741 #endif /* CONFIG_P2P */
4743 !(hapd
->conf
->mesh
& MESH_ENABLED
) &&
4744 #endif /* CONFIG_MESH */
4745 os_memcmp(mgmt
->bssid
, hapd
->own_addr
, ETH_ALEN
) != 0) {
4746 wpa_printf(MSG_INFO
, "MGMT: BSSID=" MACSTR
" not our address",
4747 MAC2STR(mgmt
->bssid
));
4752 if (stype
== WLAN_FC_STYPE_PROBE_REQ
) {
4753 handle_probe_req(hapd
, mgmt
, len
, ssi_signal
);
4757 if ((!is_broadcast_ether_addr(mgmt
->da
) ||
4758 stype
!= WLAN_FC_STYPE_ACTION
) &&
4759 os_memcmp(mgmt
->da
, hapd
->own_addr
, ETH_ALEN
) != 0) {
4760 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
4761 HOSTAPD_LEVEL_DEBUG
,
4762 "MGMT: DA=" MACSTR
" not our address",
4767 if (hapd
->iconf
->track_sta_max_num
)
4768 sta_track_add(hapd
->iface
, mgmt
->sa
, ssi_signal
);
4771 case WLAN_FC_STYPE_AUTH
:
4772 wpa_printf(MSG_DEBUG
, "mgmt::auth");
4773 handle_auth(hapd
, mgmt
, len
, ssi_signal
, 0);
4776 case WLAN_FC_STYPE_ASSOC_REQ
:
4777 wpa_printf(MSG_DEBUG
, "mgmt::assoc_req");
4778 handle_assoc(hapd
, mgmt
, len
, 0, ssi_signal
);
4781 case WLAN_FC_STYPE_REASSOC_REQ
:
4782 wpa_printf(MSG_DEBUG
, "mgmt::reassoc_req");
4783 handle_assoc(hapd
, mgmt
, len
, 1, ssi_signal
);
4786 case WLAN_FC_STYPE_DISASSOC
:
4787 wpa_printf(MSG_DEBUG
, "mgmt::disassoc");
4788 handle_disassoc(hapd
, mgmt
, len
);
4791 case WLAN_FC_STYPE_DEAUTH
:
4792 wpa_msg(hapd
->msg_ctx
, MSG_DEBUG
, "mgmt::deauth");
4793 handle_deauth(hapd
, mgmt
, len
);
4796 case WLAN_FC_STYPE_ACTION
:
4797 wpa_printf(MSG_DEBUG
, "mgmt::action");
4798 ret
= handle_action(hapd
, mgmt
, len
, freq
);
4801 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
4802 HOSTAPD_LEVEL_DEBUG
,
4803 "unknown mgmt frame subtype %d", stype
);
4811 static void handle_auth_cb(struct hostapd_data
*hapd
,
4812 const struct ieee80211_mgmt
*mgmt
,
4815 u16 auth_alg
, auth_transaction
, status_code
;
4816 struct sta_info
*sta
;
4818 sta
= ap_get_sta(hapd
, mgmt
->da
);
4820 wpa_printf(MSG_DEBUG
, "handle_auth_cb: STA " MACSTR
4826 auth_alg
= le_to_host16(mgmt
->u
.auth
.auth_alg
);
4827 auth_transaction
= le_to_host16(mgmt
->u
.auth
.auth_transaction
);
4828 status_code
= le_to_host16(mgmt
->u
.auth
.status_code
);
4831 hostapd_logger(hapd
, mgmt
->da
, HOSTAPD_MODULE_IEEE80211
,
4832 HOSTAPD_LEVEL_NOTICE
,
4833 "did not acknowledge authentication response");
4837 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.auth
)) {
4838 wpa_printf(MSG_INFO
, "handle_auth_cb - too short payload (len=%lu)",
4839 (unsigned long) len
);
4843 if (status_code
== WLAN_STATUS_SUCCESS
&&
4844 ((auth_alg
== WLAN_AUTH_OPEN
&& auth_transaction
== 2) ||
4845 (auth_alg
== WLAN_AUTH_SHARED_KEY
&& auth_transaction
== 4))) {
4846 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
4847 HOSTAPD_LEVEL_INFO
, "authenticated");
4848 sta
->flags
|= WLAN_STA_AUTH
;
4849 if (sta
->added_unassoc
)
4850 hostapd_set_sta_flags(hapd
, sta
);
4855 if (status_code
!= WLAN_STATUS_SUCCESS
&& sta
->added_unassoc
) {
4856 hostapd_drv_sta_remove(hapd
, sta
->addr
);
4857 sta
->added_unassoc
= 0;
4862 static void hostapd_set_wds_encryption(struct hostapd_data
*hapd
,
4863 struct sta_info
*sta
,
4867 struct hostapd_ssid
*ssid
= &hapd
->conf
->ssid
;
4869 if (hapd
->conf
->ieee802_1x
|| hapd
->conf
->wpa
)
4872 for (i
= 0; i
< 4; i
++) {
4873 if (ssid
->wep
.key
[i
] &&
4874 hostapd_drv_set_key(ifname_wds
, hapd
, WPA_ALG_WEP
, NULL
, i
,
4875 i
== ssid
->wep
.idx
, NULL
, 0,
4876 ssid
->wep
.key
[i
], ssid
->wep
.len
[i
])) {
4877 wpa_printf(MSG_WARNING
,
4878 "Could not set WEP keys for WDS interface; %s",
4886 static void handle_assoc_cb(struct hostapd_data
*hapd
,
4887 const struct ieee80211_mgmt
*mgmt
,
4888 size_t len
, int reassoc
, int ok
)
4891 struct sta_info
*sta
;
4894 sta
= ap_get_sta(hapd
, mgmt
->da
);
4896 wpa_printf(MSG_INFO
, "handle_assoc_cb: STA " MACSTR
" not found",
4901 if (len
< IEEE80211_HDRLEN
+ (reassoc
? sizeof(mgmt
->u
.reassoc_resp
) :
4902 sizeof(mgmt
->u
.assoc_resp
))) {
4903 wpa_printf(MSG_INFO
,
4904 "handle_assoc_cb(reassoc=%d) - too short payload (len=%lu)",
4905 reassoc
, (unsigned long) len
);
4906 hostapd_drv_sta_remove(hapd
, sta
->addr
);
4911 status
= le_to_host16(mgmt
->u
.reassoc_resp
.status_code
);
4913 status
= le_to_host16(mgmt
->u
.assoc_resp
.status_code
);
4916 hostapd_logger(hapd
, mgmt
->da
, HOSTAPD_MODULE_IEEE80211
,
4917 HOSTAPD_LEVEL_DEBUG
,
4918 "did not acknowledge association response");
4919 sta
->flags
&= ~WLAN_STA_ASSOC_REQ_OK
;
4920 /* The STA is added only in case of SUCCESS */
4921 if (status
== WLAN_STATUS_SUCCESS
)
4922 hostapd_drv_sta_remove(hapd
, sta
->addr
);
4927 if (status
!= WLAN_STATUS_SUCCESS
)
4930 /* Stop previous accounting session, if one is started, and allocate
4931 * new session id for the new session. */
4932 accounting_sta_stop(hapd
, sta
);
4934 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
4936 "associated (aid %d)",
4939 if (sta
->flags
& WLAN_STA_ASSOC
)
4941 sta
->flags
|= WLAN_STA_ASSOC
;
4942 sta
->flags
&= ~WLAN_STA_WNM_SLEEP_MODE
;
4943 if ((!hapd
->conf
->ieee802_1x
&& !hapd
->conf
->wpa
&&
4944 !hapd
->conf
->osen
) ||
4945 sta
->auth_alg
== WLAN_AUTH_FILS_SK
||
4946 sta
->auth_alg
== WLAN_AUTH_FILS_SK_PFS
||
4947 sta
->auth_alg
== WLAN_AUTH_FILS_PK
||
4948 sta
->auth_alg
== WLAN_AUTH_FT
) {
4950 * Open, static WEP, FT protocol, or FILS; no separate
4951 * authorization step.
4953 ap_sta_set_authorized(hapd
, sta
, 1);
4957 mlme_reassociate_indication(hapd
, sta
);
4959 mlme_associate_indication(hapd
, sta
);
4961 sta
->sa_query_timed_out
= 0;
4963 if (sta
->eapol_sm
== NULL
) {
4965 * This STA does not use RADIUS server for EAP authentication,
4966 * so bind it to the selected VLAN interface now, since the
4967 * interface selection is not going to change anymore.
4969 if (ap_sta_bind_vlan(hapd
, sta
) < 0)
4971 } else if (sta
->vlan_id
) {
4972 /* VLAN ID already set (e.g., by PMKSA caching), so bind STA */
4973 if (ap_sta_bind_vlan(hapd
, sta
) < 0)
4977 hostapd_set_sta_flags(hapd
, sta
);
4979 if (!(sta
->flags
& WLAN_STA_WDS
) && sta
->pending_wds_enable
) {
4980 wpa_printf(MSG_DEBUG
, "Enable 4-address WDS mode for STA "
4981 MACSTR
" based on pending request",
4982 MAC2STR(sta
->addr
));
4983 sta
->pending_wds_enable
= 0;
4984 sta
->flags
|= WLAN_STA_WDS
;
4987 if (sta
->flags
& (WLAN_STA_WDS
| WLAN_STA_MULTI_AP
)) {
4989 char ifname_wds
[IFNAMSIZ
+ 1];
4991 wpa_printf(MSG_DEBUG
, "Reenable 4-address WDS mode for STA "
4993 MAC2STR(sta
->addr
), sta
->aid
);
4994 ret
= hostapd_set_wds_sta(hapd
, ifname_wds
, sta
->addr
,
4997 hostapd_set_wds_encryption(hapd
, sta
, ifname_wds
);
5000 if (sta
->auth_alg
== WLAN_AUTH_FT
)
5001 wpa_auth_sm_event(sta
->wpa_sm
, WPA_ASSOC_FT
);
5003 wpa_auth_sm_event(sta
->wpa_sm
, WPA_ASSOC
);
5004 hapd
->new_assoc_sta_cb(hapd
, sta
, !new_assoc
);
5005 ieee802_1x_notify_port_enabled(sta
->eapol_sm
, 1);
5008 if ((sta
->auth_alg
== WLAN_AUTH_FILS_SK
||
5009 sta
->auth_alg
== WLAN_AUTH_FILS_SK_PFS
||
5010 sta
->auth_alg
== WLAN_AUTH_FILS_PK
) &&
5011 fils_set_tk(sta
->wpa_sm
) < 0) {
5012 wpa_printf(MSG_DEBUG
, "FILS: TK configuration failed");
5013 ap_sta_disconnect(hapd
, sta
, sta
->addr
,
5014 WLAN_REASON_UNSPECIFIED
);
5017 #endif /* CONFIG_FILS */
5019 if (sta
->pending_eapol_rx
) {
5020 struct os_reltime now
, age
;
5022 os_get_reltime(&now
);
5023 os_reltime_sub(&now
, &sta
->pending_eapol_rx
->rx_time
, &age
);
5024 if (age
.sec
== 0 && age
.usec
< 200000) {
5025 wpa_printf(MSG_DEBUG
,
5026 "Process pending EAPOL frame that was received from " MACSTR
" just before association notification",
5027 MAC2STR(sta
->addr
));
5030 wpabuf_head(sta
->pending_eapol_rx
->buf
),
5031 wpabuf_len(sta
->pending_eapol_rx
->buf
));
5033 wpabuf_free(sta
->pending_eapol_rx
->buf
);
5034 os_free(sta
->pending_eapol_rx
);
5035 sta
->pending_eapol_rx
= NULL
;
5040 static void handle_deauth_cb(struct hostapd_data
*hapd
,
5041 const struct ieee80211_mgmt
*mgmt
,
5044 struct sta_info
*sta
;
5045 if (is_multicast_ether_addr(mgmt
->da
))
5047 sta
= ap_get_sta(hapd
, mgmt
->da
);
5049 wpa_printf(MSG_DEBUG
, "handle_deauth_cb: STA " MACSTR
5050 " not found", MAC2STR(mgmt
->da
));
5054 wpa_printf(MSG_DEBUG
, "STA " MACSTR
" acknowledged deauth",
5055 MAC2STR(sta
->addr
));
5057 wpa_printf(MSG_DEBUG
, "STA " MACSTR
" did not acknowledge "
5058 "deauth", MAC2STR(sta
->addr
));
5060 ap_sta_deauth_cb(hapd
, sta
);
5064 static void handle_disassoc_cb(struct hostapd_data
*hapd
,
5065 const struct ieee80211_mgmt
*mgmt
,
5068 struct sta_info
*sta
;
5069 if (is_multicast_ether_addr(mgmt
->da
))
5071 sta
= ap_get_sta(hapd
, mgmt
->da
);
5073 wpa_printf(MSG_DEBUG
, "handle_disassoc_cb: STA " MACSTR
5074 " not found", MAC2STR(mgmt
->da
));
5078 wpa_printf(MSG_DEBUG
, "STA " MACSTR
" acknowledged disassoc",
5079 MAC2STR(sta
->addr
));
5081 wpa_printf(MSG_DEBUG
, "STA " MACSTR
" did not acknowledge "
5082 "disassoc", MAC2STR(sta
->addr
));
5084 ap_sta_disassoc_cb(hapd
, sta
);
5088 static void handle_action_cb(struct hostapd_data
*hapd
,
5089 const struct ieee80211_mgmt
*mgmt
,
5092 struct sta_info
*sta
;
5093 const struct rrm_measurement_report_element
*report
;
5095 if (is_multicast_ether_addr(mgmt
->da
))
5098 if (len
>= IEEE80211_HDRLEN
+ 6 &&
5099 mgmt
->u
.action
.category
== WLAN_ACTION_PUBLIC
&&
5100 mgmt
->u
.action
.u
.vs_public_action
.action
==
5101 WLAN_PA_VENDOR_SPECIFIC
&&
5102 WPA_GET_BE24(mgmt
->u
.action
.u
.vs_public_action
.oui
) ==
5104 mgmt
->u
.action
.u
.vs_public_action
.variable
[0] ==
5106 const u8
*pos
, *end
;
5108 pos
= &mgmt
->u
.action
.u
.vs_public_action
.variable
[1];
5109 end
= ((const u8
*) mgmt
) + len
;
5110 hostapd_dpp_tx_status(hapd
, mgmt
->da
, pos
, end
- pos
, ok
);
5113 if (len
>= IEEE80211_HDRLEN
+ 2 &&
5114 mgmt
->u
.action
.category
== WLAN_ACTION_PUBLIC
&&
5115 (mgmt
->u
.action
.u
.public_action
.action
==
5116 WLAN_PA_GAS_INITIAL_REQ
||
5117 mgmt
->u
.action
.u
.public_action
.action
==
5118 WLAN_PA_GAS_COMEBACK_REQ
)) {
5119 const u8
*pos
, *end
;
5121 pos
= mgmt
->u
.action
.u
.public_action
.variable
;
5122 end
= ((const u8
*) mgmt
) + len
;
5123 gas_query_ap_tx_status(hapd
->gas
, mgmt
->da
, pos
, end
- pos
, ok
);
5126 #endif /* CONFIG_DPP */
5127 sta
= ap_get_sta(hapd
, mgmt
->da
);
5129 wpa_printf(MSG_DEBUG
, "handle_action_cb: STA " MACSTR
5130 " not found", MAC2STR(mgmt
->da
));
5134 if (len
< 24 + 5 + sizeof(*report
))
5136 report
= (const struct rrm_measurement_report_element
*)
5137 &mgmt
->u
.action
.u
.rrm
.variable
[2];
5138 if (mgmt
->u
.action
.category
== WLAN_ACTION_RADIO_MEASUREMENT
&&
5139 mgmt
->u
.action
.u
.rrm
.action
== WLAN_RRM_RADIO_MEASUREMENT_REQUEST
&&
5140 report
->eid
== WLAN_EID_MEASURE_REQUEST
&&
5142 report
->type
== MEASURE_TYPE_BEACON
)
5143 hostapd_rrm_beacon_req_tx_status(hapd
, mgmt
, len
, ok
);
5148 * ieee802_11_mgmt_cb - Process management frame TX status callback
5149 * @hapd: hostapd BSS data structure (the BSS from which the management frame
5151 * @buf: management frame data (starting from IEEE 802.11 header)
5152 * @len: length of frame data in octets
5153 * @stype: management frame subtype from frame control field
5154 * @ok: Whether the frame was ACK'ed
5156 void ieee802_11_mgmt_cb(struct hostapd_data
*hapd
, const u8
*buf
, size_t len
,
5159 const struct ieee80211_mgmt
*mgmt
;
5160 mgmt
= (const struct ieee80211_mgmt
*) buf
;
5162 #ifdef CONFIG_TESTING_OPTIONS
5163 if (hapd
->ext_mgmt_frame_handling
) {
5164 size_t hex_len
= 2 * len
+ 1;
5165 char *hex
= os_malloc(hex_len
);
5168 wpa_snprintf_hex(hex
, hex_len
, buf
, len
);
5169 wpa_msg(hapd
->msg_ctx
, MSG_INFO
,
5170 "MGMT-TX-STATUS stype=%u ok=%d buf=%s",
5176 #endif /* CONFIG_TESTING_OPTIONS */
5179 case WLAN_FC_STYPE_AUTH
:
5180 wpa_printf(MSG_DEBUG
, "mgmt::auth cb");
5181 handle_auth_cb(hapd
, mgmt
, len
, ok
);
5183 case WLAN_FC_STYPE_ASSOC_RESP
:
5184 wpa_printf(MSG_DEBUG
, "mgmt::assoc_resp cb");
5185 handle_assoc_cb(hapd
, mgmt
, len
, 0, ok
);
5187 case WLAN_FC_STYPE_REASSOC_RESP
:
5188 wpa_printf(MSG_DEBUG
, "mgmt::reassoc_resp cb");
5189 handle_assoc_cb(hapd
, mgmt
, len
, 1, ok
);
5191 case WLAN_FC_STYPE_PROBE_RESP
:
5192 wpa_printf(MSG_EXCESSIVE
, "mgmt::proberesp cb ok=%d", ok
);
5194 case WLAN_FC_STYPE_DEAUTH
:
5195 wpa_printf(MSG_DEBUG
, "mgmt::deauth cb");
5196 handle_deauth_cb(hapd
, mgmt
, len
, ok
);
5198 case WLAN_FC_STYPE_DISASSOC
:
5199 wpa_printf(MSG_DEBUG
, "mgmt::disassoc cb");
5200 handle_disassoc_cb(hapd
, mgmt
, len
, ok
);
5202 case WLAN_FC_STYPE_ACTION
:
5203 wpa_printf(MSG_DEBUG
, "mgmt::action cb ok=%d", ok
);
5204 handle_action_cb(hapd
, mgmt
, len
, ok
);
5207 wpa_printf(MSG_INFO
, "unknown mgmt cb frame subtype %d", stype
);
5213 int ieee802_11_get_mib(struct hostapd_data
*hapd
, char *buf
, size_t buflen
)
5220 int ieee802_11_get_mib_sta(struct hostapd_data
*hapd
, struct sta_info
*sta
,
5221 char *buf
, size_t buflen
)
5228 void hostapd_tx_status(struct hostapd_data
*hapd
, const u8
*addr
,
5229 const u8
*buf
, size_t len
, int ack
)
5231 struct sta_info
*sta
;
5232 struct hostapd_iface
*iface
= hapd
->iface
;
5234 sta
= ap_get_sta(hapd
, addr
);
5235 if (sta
== NULL
&& iface
->num_bss
> 1) {
5237 for (j
= 0; j
< iface
->num_bss
; j
++) {
5238 hapd
= iface
->bss
[j
];
5239 sta
= ap_get_sta(hapd
, addr
);
5244 if (sta
== NULL
|| !(sta
->flags
& WLAN_STA_ASSOC
))
5246 if (sta
->flags
& WLAN_STA_PENDING_POLL
) {
5247 wpa_printf(MSG_DEBUG
, "STA " MACSTR
" %s pending "
5248 "activity poll", MAC2STR(sta
->addr
),
5249 ack
? "ACKed" : "did not ACK");
5251 sta
->flags
&= ~WLAN_STA_PENDING_POLL
;
5254 ieee802_1x_tx_status(hapd
, sta
, buf
, len
, ack
);
5258 void hostapd_eapol_tx_status(struct hostapd_data
*hapd
, const u8
*dst
,
5259 const u8
*data
, size_t len
, int ack
)
5261 struct sta_info
*sta
;
5262 struct hostapd_iface
*iface
= hapd
->iface
;
5264 sta
= ap_get_sta(hapd
, dst
);
5265 if (sta
== NULL
&& iface
->num_bss
> 1) {
5267 for (j
= 0; j
< iface
->num_bss
; j
++) {
5268 hapd
= iface
->bss
[j
];
5269 sta
= ap_get_sta(hapd
, dst
);
5274 if (sta
== NULL
|| !(sta
->flags
& WLAN_STA_ASSOC
)) {
5275 wpa_printf(MSG_DEBUG
, "Ignore TX status for Data frame to STA "
5276 MACSTR
" that is not currently associated",
5281 ieee802_1x_eapol_tx_status(hapd
, sta
, data
, len
, ack
);
5285 void hostapd_client_poll_ok(struct hostapd_data
*hapd
, const u8
*addr
)
5287 struct sta_info
*sta
;
5288 struct hostapd_iface
*iface
= hapd
->iface
;
5290 sta
= ap_get_sta(hapd
, addr
);
5291 if (sta
== NULL
&& iface
->num_bss
> 1) {
5293 for (j
= 0; j
< iface
->num_bss
; j
++) {
5294 hapd
= iface
->bss
[j
];
5295 sta
= ap_get_sta(hapd
, addr
);
5302 wpa_msg(hapd
->msg_ctx
, MSG_INFO
, AP_STA_POLL_OK MACSTR
,
5303 MAC2STR(sta
->addr
));
5304 if (!(sta
->flags
& WLAN_STA_PENDING_POLL
))
5307 wpa_printf(MSG_DEBUG
, "STA " MACSTR
" ACKed pending "
5308 "activity poll", MAC2STR(sta
->addr
));
5309 sta
->flags
&= ~WLAN_STA_PENDING_POLL
;
5313 void ieee802_11_rx_from_unknown(struct hostapd_data
*hapd
, const u8
*src
,
5316 struct sta_info
*sta
;
5318 sta
= ap_get_sta(hapd
, src
);
5320 ((sta
->flags
& WLAN_STA_ASSOC
) ||
5321 ((sta
->flags
& WLAN_STA_ASSOC_REQ_OK
) && wds
))) {
5322 if (!hapd
->conf
->wds_sta
)
5325 if ((sta
->flags
& (WLAN_STA_ASSOC
| WLAN_STA_ASSOC_REQ_OK
)) ==
5326 WLAN_STA_ASSOC_REQ_OK
) {
5327 wpa_printf(MSG_DEBUG
,
5328 "Postpone 4-address WDS mode enabling for STA "
5329 MACSTR
" since TX status for AssocResp is not yet known",
5330 MAC2STR(sta
->addr
));
5331 sta
->pending_wds_enable
= 1;
5335 if (wds
&& !(sta
->flags
& WLAN_STA_WDS
)) {
5337 char ifname_wds
[IFNAMSIZ
+ 1];
5339 wpa_printf(MSG_DEBUG
, "Enable 4-address WDS mode for "
5340 "STA " MACSTR
" (aid %u)",
5341 MAC2STR(sta
->addr
), sta
->aid
);
5342 sta
->flags
|= WLAN_STA_WDS
;
5343 ret
= hostapd_set_wds_sta(hapd
, ifname_wds
,
5344 sta
->addr
, sta
->aid
, 1);
5346 hostapd_set_wds_encryption(hapd
, sta
,
5352 wpa_printf(MSG_DEBUG
, "Data/PS-poll frame from not associated STA "
5353 MACSTR
, MAC2STR(src
));
5354 if (is_multicast_ether_addr(src
) || is_zero_ether_addr(src
) ||
5355 os_memcmp(src
, hapd
->own_addr
, ETH_ALEN
) == 0) {
5356 /* Broadcast bit set in SA or unexpected SA?! Ignore the frame
5361 if (sta
&& (sta
->flags
& WLAN_STA_ASSOC_REQ_OK
)) {
5362 wpa_printf(MSG_DEBUG
, "Association Response to the STA has "
5363 "already been sent, but no TX status yet known - "
5364 "ignore Class 3 frame issue with " MACSTR
,
5369 if (sta
&& (sta
->flags
& WLAN_STA_AUTH
))
5370 hostapd_drv_sta_disassoc(
5372 WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA
);
5374 hostapd_drv_sta_deauth(
5376 WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA
);
5380 #endif /* CONFIG_NATIVE_WINDOWS */