]> git.ipfire.org Git - thirdparty/hostap.git/blame - src/ap/ieee802_11.c
WNM: Differentiate between WNM for station and for AP in build
[thirdparty/hostap.git] / src / ap / ieee802_11.c
CommitLineData
6fc6879b
JM
1/*
2 * hostapd / IEEE 802.11 Management
f3383366 3 * Copyright (c) 2002-2017, Jouni Malinen <j@w1.fi>
6fc6879b 4 *
0f3d578e
JM
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
6fc6879b
JM
7 */
8
1057d78e 9#include "utils/includes.h"
6fc6879b
JM
10
11#ifndef CONFIG_NATIVE_WINDOWS
12
1057d78e
JM
13#include "utils/common.h"
14#include "utils/eloop.h"
03da66bd 15#include "crypto/crypto.h"
d136c376
JM
16#include "crypto/sha256.h"
17#include "crypto/random.h"
81f4f619
JM
18#include "common/ieee802_11_defs.h"
19#include "common/ieee802_11_common.h"
03da66bd 20#include "common/wpa_ctrl.h"
98efcc41 21#include "common/sae.h"
03da66bd
JM
22#include "radius/radius.h"
23#include "radius/radius_client.h"
e44f8bf2 24#include "p2p/p2p.h"
ed7a09f9 25#include "wps/wps.h"
037378ff 26#include "fst/fst.h"
6fc6879b 27#include "hostapd.h"
6fc6879b 28#include "beacon.h"
6fc6879b
JM
29#include "ieee802_11_auth.h"
30#include "sta_info.h"
6fc6879b 31#include "ieee802_1x.h"
6226e38d 32#include "wpa_auth.h"
f2991170 33#include "pmksa_cache_auth.h"
1057d78e 34#include "wmm.h"
6fc6879b
JM
35#include "ap_list.h"
36#include "accounting.h"
6226e38d
JM
37#include "ap_config.h"
38#include "ap_mlme.h"
dce044cc 39#include "p2p_hostapd.h"
cee7d66b 40#include "ap_drv_ops.h"
c79938a5 41#include "wnm_ap.h"
0e2412d0 42#include "hw_features.h"
6226e38d 43#include "ieee802_11.h"
3d7ad2f6 44#include "dfs.h"
6332aaf3 45#include "mbo_ap.h"
2572df34 46#include "rrm.h"
04059ab8 47#include "taxonomy.h"
54b04d6f 48#include "fils_hlp.h"
9c2b8204
JM
49#include "dpp_hostapd.h"
50#include "gas_query_ap.h"
6fc6879b
JM
51
52
5e5f8c81
JM
53#ifdef CONFIG_FILS
54static struct wpabuf *
55prepare_auth_resp_fils(struct hostapd_data *hapd,
56 struct sta_info *sta, u16 *resp,
57 struct rsn_pmksa_cache_entry *pmksa,
58 struct wpabuf *erp_resp,
59 const u8 *msk, size_t msk_len,
60 int *is_pub);
61#endif /* CONFIG_FILS */
62
6fc6879b
JM
63u8 * hostapd_eid_supp_rates(struct hostapd_data *hapd, u8 *eid)
64{
65 u8 *pos = eid;
66 int i, num, count;
67
68 if (hapd->iface->current_rates == NULL)
69 return eid;
70
71 *pos++ = WLAN_EID_SUPP_RATES;
72 num = hapd->iface->num_rates;
29448243
JM
73 if (hapd->iconf->ieee80211n && hapd->iconf->require_ht)
74 num++;
202d97d4
JB
75 if (hapd->iconf->ieee80211ac && hapd->iconf->require_vht)
76 num++;
6fc6879b
JM
77 if (num > 8) {
78 /* rest of the rates are encoded in Extended supported
79 * rates element */
80 num = 8;
81 }
82
83 *pos++ = num;
6fc6879b
JM
84 for (i = 0, count = 0; i < hapd->iface->num_rates && count < num;
85 i++) {
86 count++;
87 *pos = hapd->iface->current_rates[i].rate / 5;
88 if (hapd->iface->current_rates[i].flags & HOSTAPD_RATE_BASIC)
89 *pos |= 0x80;
90 pos++;
91 }
92
202d97d4
JB
93 if (hapd->iconf->ieee80211n && hapd->iconf->require_ht && count < 8) {
94 count++;
29448243 95 *pos++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_HT_PHY;
202d97d4
JB
96 }
97
98 if (hapd->iconf->ieee80211ac && hapd->iconf->require_vht && count < 8) {
99 count++;
100 *pos++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_VHT_PHY;
101 }
29448243 102
6fc6879b
JM
103 return pos;
104}
105
106
107u8 * hostapd_eid_ext_supp_rates(struct hostapd_data *hapd, u8 *eid)
108{
109 u8 *pos = eid;
110 int i, num, count;
111
112 if (hapd->iface->current_rates == NULL)
113 return eid;
114
115 num = hapd->iface->num_rates;
29448243
JM
116 if (hapd->iconf->ieee80211n && hapd->iconf->require_ht)
117 num++;
202d97d4
JB
118 if (hapd->iconf->ieee80211ac && hapd->iconf->require_vht)
119 num++;
6fc6879b
JM
120 if (num <= 8)
121 return eid;
122 num -= 8;
123
124 *pos++ = WLAN_EID_EXT_SUPP_RATES;
125 *pos++ = num;
6fc6879b
JM
126 for (i = 0, count = 0; i < hapd->iface->num_rates && count < num + 8;
127 i++) {
128 count++;
129 if (count <= 8)
130 continue; /* already in SuppRates IE */
131 *pos = hapd->iface->current_rates[i].rate / 5;
132 if (hapd->iface->current_rates[i].flags & HOSTAPD_RATE_BASIC)
133 *pos |= 0x80;
134 pos++;
135 }
136
202d97d4
JB
137 if (hapd->iconf->ieee80211n && hapd->iconf->require_ht) {
138 count++;
139 if (count > 8)
140 *pos++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_HT_PHY;
141 }
142
143 if (hapd->iconf->ieee80211ac && hapd->iconf->require_vht) {
144 count++;
145 if (count > 8)
146 *pos++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_VHT_PHY;
147 }
29448243 148
6fc6879b
JM
149 return pos;
150}
151
152
f41ded6f 153u16 hostapd_own_capab_info(struct hostapd_data *hapd)
6fc6879b
JM
154{
155 int capab = WLAN_CAPABILITY_ESS;
156 int privacy;
3d7ad2f6 157 int dfs;
01018212 158 int i;
3d7ad2f6
C
159
160 /* Check if any of configured channels require DFS */
161 dfs = hostapd_is_dfs_required(hapd->iface);
162 if (dfs < 0) {
163 wpa_printf(MSG_WARNING, "Failed to check if DFS is required; ret=%d",
164 dfs);
165 dfs = 0;
166 }
6fc6879b
JM
167
168 if (hapd->iface->num_sta_no_short_preamble == 0 &&
169 hapd->iconf->preamble == SHORT_PREAMBLE)
170 capab |= WLAN_CAPABILITY_SHORT_PREAMBLE;
171
172 privacy = hapd->conf->ssid.wep.keys_set;
173
174 if (hapd->conf->ieee802_1x &&
175 (hapd->conf->default_wep_key_len ||
176 hapd->conf->individual_wep_key_len))
177 privacy = 1;
178
179 if (hapd->conf->wpa)
180 privacy = 1;
181
a14896e8
JM
182#ifdef CONFIG_HS20
183 if (hapd->conf->osen)
184 privacy = 1;
185#endif /* CONFIG_HS20 */
186
6fc6879b
JM
187 if (privacy)
188 capab |= WLAN_CAPABILITY_PRIVACY;
189
190 if (hapd->iface->current_mode &&
191 hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G &&
192 hapd->iface->num_sta_no_short_slot_time == 0)
193 capab |= WLAN_CAPABILITY_SHORT_SLOT_TIME;
194
3d7ad2f6
C
195 /*
196 * Currently, Spectrum Management capability bit is set when directly
197 * requested in configuration by spectrum_mgmt_required or when AP is
198 * running on DFS channel.
199 * TODO: Also consider driver support for TPC to set Spectrum Mgmt bit
200 */
201 if (hapd->iface->current_mode &&
202 hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211A &&
203 (hapd->iconf->spectrum_mgmt_required || dfs))
204 capab |= WLAN_CAPABILITY_SPECTRUM_MGMT;
205
01018212
DS
206 for (i = 0; i < RRM_CAPABILITIES_IE_LEN; i++) {
207 if (hapd->conf->radio_measurements[i]) {
208 capab |= IEEE80211_CAP_RRM;
209 break;
210 }
211 }
0629eeb4 212
6fc6879b
JM
213 return capab;
214}
215
216
7cb53ded 217#ifndef CONFIG_NO_RC4
6fc6879b 218static u16 auth_shared_key(struct hostapd_data *hapd, struct sta_info *sta,
b57e086c
JM
219 u16 auth_transaction, const u8 *challenge,
220 int iswep)
6fc6879b
JM
221{
222 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
223 HOSTAPD_LEVEL_DEBUG,
224 "authentication (shared key, transaction %d)",
225 auth_transaction);
226
227 if (auth_transaction == 1) {
228 if (!sta->challenge) {
229 /* Generate a pseudo-random challenge */
230 u8 key[8];
f441e5af 231
6fc6879b
JM
232 sta->challenge = os_zalloc(WLAN_AUTH_CHALLENGE_LEN);
233 if (sta->challenge == NULL)
234 return WLAN_STATUS_UNSPECIFIED_FAILURE;
235
f441e5af
NL
236 if (os_get_random(key, sizeof(key)) < 0) {
237 os_free(sta->challenge);
238 sta->challenge = NULL;
239 return WLAN_STATUS_UNSPECIFIED_FAILURE;
240 }
241
8ef16831
JM
242 rc4_skip(key, sizeof(key), 0,
243 sta->challenge, WLAN_AUTH_CHALLENGE_LEN);
6fc6879b
JM
244 }
245 return 0;
246 }
247
248 if (auth_transaction != 3)
249 return WLAN_STATUS_UNSPECIFIED_FAILURE;
250
251 /* Transaction 3 */
252 if (!iswep || !sta->challenge || !challenge ||
34ef46ce
JM
253 os_memcmp_const(sta->challenge, challenge,
254 WLAN_AUTH_CHALLENGE_LEN)) {
6fc6879b
JM
255 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
256 HOSTAPD_LEVEL_INFO,
257 "shared key authentication - invalid "
258 "challenge-response");
259 return WLAN_STATUS_CHALLENGE_FAIL;
260 }
261
262 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
263 HOSTAPD_LEVEL_DEBUG,
264 "authentication OK (shared key)");
6fc6879b
JM
265 sta->flags |= WLAN_STA_AUTH;
266 wpa_auth_sm_event(sta->wpa_sm, WPA_AUTH);
6fc6879b
JM
267 os_free(sta->challenge);
268 sta->challenge = NULL;
269
270 return 0;
271}
7cb53ded 272#endif /* CONFIG_NO_RC4 */
6fc6879b
JM
273
274
bb598c3b
AB
275static int send_auth_reply(struct hostapd_data *hapd,
276 const u8 *dst, const u8 *bssid,
277 u16 auth_alg, u16 auth_transaction, u16 resp,
278 const u8 *ies, size_t ies_len)
6fc6879b
JM
279{
280 struct ieee80211_mgmt *reply;
281 u8 *buf;
282 size_t rlen;
bb598c3b 283 int reply_res = WLAN_STATUS_UNSPECIFIED_FAILURE;
6fc6879b
JM
284
285 rlen = IEEE80211_HDRLEN + sizeof(reply->u.auth) + ies_len;
286 buf = os_zalloc(rlen);
287 if (buf == NULL)
bb598c3b 288 return -1;
6fc6879b
JM
289
290 reply = (struct ieee80211_mgmt *) buf;
291 reply->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
292 WLAN_FC_STYPE_AUTH);
6fc6879b
JM
293 os_memcpy(reply->da, dst, ETH_ALEN);
294 os_memcpy(reply->sa, hapd->own_addr, ETH_ALEN);
295 os_memcpy(reply->bssid, bssid, ETH_ALEN);
296
297 reply->u.auth.auth_alg = host_to_le16(auth_alg);
298 reply->u.auth.auth_transaction = host_to_le16(auth_transaction);
299 reply->u.auth.status_code = host_to_le16(resp);
300
301 if (ies && ies_len)
302 os_memcpy(reply->u.auth.variable, ies, ies_len);
303
304 wpa_printf(MSG_DEBUG, "authentication reply: STA=" MACSTR
305 " auth_alg=%d auth_transaction=%d resp=%d (IE len=%lu)",
306 MAC2STR(dst), auth_alg, auth_transaction,
307 resp, (unsigned long) ies_len);
8cfa3527 308 if (hostapd_drv_send_mlme(hapd, reply, rlen, 0) < 0)
bb598c3b
AB
309 wpa_printf(MSG_INFO, "send_auth_reply: send failed");
310 else
311 reply_res = WLAN_STATUS_SUCCESS;
6fc6879b
JM
312
313 os_free(buf);
bb598c3b
AB
314
315 return reply_res;
6fc6879b
JM
316}
317
318
4ec1fd8e 319#ifdef CONFIG_IEEE80211R_AP
6fc6879b
JM
320static void handle_auth_ft_finish(void *ctx, const u8 *dst, const u8 *bssid,
321 u16 auth_transaction, u16 status,
322 const u8 *ies, size_t ies_len)
323{
324 struct hostapd_data *hapd = ctx;
325 struct sta_info *sta;
bb598c3b 326 int reply_res;
6fc6879b 327
bb598c3b
AB
328 reply_res = send_auth_reply(hapd, dst, bssid, WLAN_AUTH_FT,
329 auth_transaction, status, ies, ies_len);
6fc6879b
JM
330
331 sta = ap_get_sta(hapd, dst);
332 if (sta == NULL)
333 return;
334
bb598c3b
AB
335 if (sta->added_unassoc && (reply_res != WLAN_STATUS_SUCCESS ||
336 status != WLAN_STATUS_SUCCESS)) {
337 hostapd_drv_sta_remove(hapd, sta->addr);
338 sta->added_unassoc = 0;
339 return;
340 }
341
342 if (status != WLAN_STATUS_SUCCESS)
343 return;
344
6fc6879b
JM
345 hostapd_logger(hapd, dst, HOSTAPD_MODULE_IEEE80211,
346 HOSTAPD_LEVEL_DEBUG, "authentication OK (FT)");
347 sta->flags |= WLAN_STA_AUTH;
348 mlme_authenticate_indication(hapd, sta);
349}
4ec1fd8e 350#endif /* CONFIG_IEEE80211R_AP */
6fc6879b
JM
351
352
c10347f2 353#ifdef CONFIG_SAE
21af6d15 354
f3b8ad4d
BC
355#define dot11RSNASAESync 5 /* attempts */
356
357
e96da42b 358static struct wpabuf * auth_build_sae_commit(struct hostapd_data *hapd,
872b7545 359 struct sta_info *sta, int update)
21af6d15
JM
360{
361 struct wpabuf *buf;
362
146f6c9a
JM
363 if (hapd->conf->ssid.wpa_passphrase == NULL) {
364 wpa_printf(MSG_DEBUG, "SAE: No password available");
365 return NULL;
366 }
367
872b7545
MH
368 if (update &&
369 sae_prepare_commit(hapd->own_addr, sta->addr,
8e31e955
JM
370 (u8 *) hapd->conf->ssid.wpa_passphrase,
371 os_strlen(hapd->conf->ssid.wpa_passphrase),
372 sta->sae) < 0) {
373 wpa_printf(MSG_DEBUG, "SAE: Could not pick PWE");
21af6d15 374 return NULL;
8e31e955 375 }
21af6d15 376
8e31e955
JM
377 buf = wpabuf_alloc(SAE_COMMIT_MAX_LEN);
378 if (buf == NULL)
379 return NULL;
872b7545
MH
380 sae_write_commit(sta->sae, buf, sta->sae->tmp ?
381 sta->sae->tmp->anti_clogging_token : NULL);
21af6d15
JM
382
383 return buf;
384}
385
386
387static struct wpabuf * auth_build_sae_confirm(struct hostapd_data *hapd,
388 struct sta_info *sta)
389{
390 struct wpabuf *buf;
391
fb8fcc29 392 buf = wpabuf_alloc(SAE_CONFIRM_MAX_LEN);
21af6d15
JM
393 if (buf == NULL)
394 return NULL;
395
fb8fcc29 396 sae_write_confirm(sta->sae, buf);
21af6d15
JM
397
398 return buf;
399}
400
401
e96da42b
BC
402static int auth_sae_send_commit(struct hostapd_data *hapd,
403 struct sta_info *sta,
872b7545 404 const u8 *bssid, int update)
e96da42b
BC
405{
406 struct wpabuf *data;
bb598c3b 407 int reply_res;
e96da42b 408
872b7545 409 data = auth_build_sae_commit(hapd, sta, update);
e96da42b
BC
410 if (data == NULL)
411 return WLAN_STATUS_UNSPECIFIED_FAILURE;
412
bb598c3b
AB
413 reply_res = send_auth_reply(hapd, sta->addr, bssid, WLAN_AUTH_SAE, 1,
414 WLAN_STATUS_SUCCESS, wpabuf_head(data),
415 wpabuf_len(data));
e96da42b
BC
416
417 wpabuf_free(data);
418
bb598c3b 419 return reply_res;
e96da42b
BC
420}
421
422
423static int auth_sae_send_confirm(struct hostapd_data *hapd,
424 struct sta_info *sta,
425 const u8 *bssid)
426{
427 struct wpabuf *data;
bb598c3b 428 int reply_res;
e96da42b
BC
429
430 data = auth_build_sae_confirm(hapd, sta);
431 if (data == NULL)
432 return WLAN_STATUS_UNSPECIFIED_FAILURE;
433
bb598c3b
AB
434 reply_res = send_auth_reply(hapd, sta->addr, bssid, WLAN_AUTH_SAE, 2,
435 WLAN_STATUS_SUCCESS, wpabuf_head(data),
436 wpabuf_len(data));
e96da42b
BC
437
438 wpabuf_free(data);
439
bb598c3b 440 return reply_res;
e96da42b
BC
441}
442
443
d136c376
JM
444static int use_sae_anti_clogging(struct hostapd_data *hapd)
445{
446 struct sta_info *sta;
447 unsigned int open = 0;
448
449 if (hapd->conf->sae_anti_clogging_threshold == 0)
450 return 1;
451
452 for (sta = hapd->sta_list; sta; sta = sta->next) {
453 if (!sta->sae)
454 continue;
455 if (sta->sae->state != SAE_COMMITTED &&
456 sta->sae->state != SAE_CONFIRMED)
457 continue;
458 open++;
459 if (open >= hapd->conf->sae_anti_clogging_threshold)
460 return 1;
461 }
462
463 return 0;
464}
465
466
467static int check_sae_token(struct hostapd_data *hapd, const u8 *addr,
468 const u8 *token, size_t token_len)
469{
470 u8 mac[SHA256_MAC_LEN];
471
472 if (token_len != SHA256_MAC_LEN)
473 return -1;
474 if (hmac_sha256(hapd->sae_token_key, sizeof(hapd->sae_token_key),
475 addr, ETH_ALEN, mac) < 0 ||
0233dcac 476 os_memcmp_const(token, mac, SHA256_MAC_LEN) != 0)
d136c376
JM
477 return -1;
478
479 return 0;
480}
481
482
483static struct wpabuf * auth_build_token_req(struct hostapd_data *hapd,
a959a3b6 484 int group, const u8 *addr)
d136c376
JM
485{
486 struct wpabuf *buf;
487 u8 *token;
fe52c210 488 struct os_reltime now;
d136c376 489
fe52c210
JB
490 os_get_reltime(&now);
491 if (!os_reltime_initialized(&hapd->last_sae_token_key_update) ||
492 os_reltime_expired(&now, &hapd->last_sae_token_key_update, 60)) {
a50414c3
JM
493 if (random_get_bytes(hapd->sae_token_key,
494 sizeof(hapd->sae_token_key)) < 0)
495 return NULL;
d136c376
JM
496 wpa_hexdump(MSG_DEBUG, "SAE: Updated token key",
497 hapd->sae_token_key, sizeof(hapd->sae_token_key));
fe52c210 498 hapd->last_sae_token_key_update = now;
d136c376
JM
499 }
500
a959a3b6 501 buf = wpabuf_alloc(sizeof(le16) + SHA256_MAC_LEN);
d136c376
JM
502 if (buf == NULL)
503 return NULL;
504
a959a3b6
MH
505 wpabuf_put_le16(buf, group); /* Finite Cyclic Group */
506
d136c376
JM
507 token = wpabuf_put(buf, SHA256_MAC_LEN);
508 hmac_sha256(hapd->sae_token_key, sizeof(hapd->sae_token_key),
509 addr, ETH_ALEN, token);
510
511 return buf;
512}
513
514
f3b8ad4d
BC
515static int sae_check_big_sync(struct sta_info *sta)
516{
517 if (sta->sae->sync > dot11RSNASAESync) {
518 sta->sae->state = SAE_NOTHING;
519 sta->sae->sync = 0;
520 return -1;
521 }
522 return 0;
523}
524
525
526static void auth_sae_retransmit_timer(void *eloop_ctx, void *eloop_data)
527{
528 struct hostapd_data *hapd = eloop_ctx;
529 struct sta_info *sta = eloop_data;
530 int ret;
531
532 if (sae_check_big_sync(sta))
533 return;
534 sta->sae->sync++;
dad01292
JM
535 wpa_printf(MSG_DEBUG, "SAE: Auth SAE retransmit timer for " MACSTR
536 " (sync=%d state=%d)",
537 MAC2STR(sta->addr), sta->sae->sync, sta->sae->state);
f3b8ad4d
BC
538
539 switch (sta->sae->state) {
540 case SAE_COMMITTED:
541 ret = auth_sae_send_commit(hapd, sta, hapd->own_addr, 0);
ecd40fef
MH
542 eloop_register_timeout(0,
543 hapd->dot11RSNASAERetransPeriod * 1000,
f3b8ad4d
BC
544 auth_sae_retransmit_timer, hapd, sta);
545 break;
546 case SAE_CONFIRMED:
547 ret = auth_sae_send_confirm(hapd, sta, hapd->own_addr);
ecd40fef
MH
548 eloop_register_timeout(0,
549 hapd->dot11RSNASAERetransPeriod * 1000,
f3b8ad4d
BC
550 auth_sae_retransmit_timer, hapd, sta);
551 break;
552 default:
553 ret = -1;
554 break;
555 }
556
557 if (ret != WLAN_STATUS_SUCCESS)
558 wpa_printf(MSG_INFO, "SAE: Failed to retransmit: ret=%d", ret);
559}
560
561
562void sae_clear_retransmit_timer(struct hostapd_data *hapd, struct sta_info *sta)
563{
564 eloop_cancel_timeout(auth_sae_retransmit_timer, hapd, sta);
565}
566
567
568static void sae_set_retransmit_timer(struct hostapd_data *hapd,
569 struct sta_info *sta)
570{
571 if (!(hapd->conf->mesh & MESH_ENABLED))
572 return;
573
574 eloop_cancel_timeout(auth_sae_retransmit_timer, hapd, sta);
ecd40fef 575 eloop_register_timeout(0, hapd->dot11RSNASAERetransPeriod * 1000,
f3b8ad4d
BC
576 auth_sae_retransmit_timer, hapd, sta);
577}
578
579
9f2cf23e
MH
580void sae_accept_sta(struct hostapd_data *hapd, struct sta_info *sta)
581{
582 sta->flags |= WLAN_STA_AUTH;
583 sta->auth_alg = WLAN_AUTH_SAE;
584 mlme_authenticate_indication(hapd, sta);
585 wpa_auth_sm_event(sta->wpa_sm, WPA_AUTH);
586 sta->sae->state = SAE_ACCEPTED;
587 wpa_auth_pmksa_add_sae(hapd->wpa_auth, sta->addr,
588 sta->sae->pmk, sta->sae->pmkid);
589}
590
591
e96da42b
BC
592static int sae_sm_step(struct hostapd_data *hapd, struct sta_info *sta,
593 const u8 *bssid, u8 auth_transaction)
594{
595 int ret;
596
597 if (auth_transaction != 1 && auth_transaction != 2)
598 return WLAN_STATUS_UNSPECIFIED_FAILURE;
599
600 switch (sta->sae->state) {
601 case SAE_NOTHING:
602 if (auth_transaction == 1) {
872b7545 603 ret = auth_sae_send_commit(hapd, sta, bssid, 1);
e96da42b
BC
604 if (ret)
605 return ret;
606 sta->sae->state = SAE_COMMITTED;
607
608 if (sae_process_commit(sta->sae) < 0)
609 return WLAN_STATUS_UNSPECIFIED_FAILURE;
610
611 /*
612 * In mesh case, both Commit and Confirm can be sent
613 * immediately. In infrastructure BSS, only a single
614 * Authentication frame (Commit) is expected from the AP
615 * here and the second one (Confirm) will be sent once
616 * the STA has sent its second Authentication frame
617 * (Confirm).
618 */
619 if (hapd->conf->mesh & MESH_ENABLED) {
620 /*
621 * Send both Commit and Confirm immediately
622 * based on SAE finite state machine
623 * Nothing -> Confirm transition.
624 */
625 ret = auth_sae_send_confirm(hapd, sta, bssid);
626 if (ret)
627 return ret;
628 sta->sae->state = SAE_CONFIRMED;
629 } else {
630 /*
631 * For infrastructure BSS, send only the Commit
632 * message now to get alternating sequence of
633 * Authentication frames between the AP and STA.
634 * Confirm will be sent in
746e5c25 635 * Committed -> Confirmed/Accepted transition
e96da42b
BC
636 * when receiving Confirm from STA.
637 */
638 }
f3b8ad4d
BC
639 sta->sae->sync = 0;
640 sae_set_retransmit_timer(hapd, sta);
e96da42b
BC
641 } else {
642 hostapd_logger(hapd, sta->addr,
643 HOSTAPD_MODULE_IEEE80211,
644 HOSTAPD_LEVEL_DEBUG,
645 "SAE confirm before commit");
646 }
647 break;
648 case SAE_COMMITTED:
f3b8ad4d 649 sae_clear_retransmit_timer(hapd, sta);
e96da42b
BC
650 if (auth_transaction == 1) {
651 if (sae_process_commit(sta->sae) < 0)
652 return WLAN_STATUS_UNSPECIFIED_FAILURE;
653
654 ret = auth_sae_send_confirm(hapd, sta, bssid);
655 if (ret)
656 return ret;
657 sta->sae->state = SAE_CONFIRMED;
f3b8ad4d
BC
658 sta->sae->sync = 0;
659 sae_set_retransmit_timer(hapd, sta);
e96da42b
BC
660 } else if (hapd->conf->mesh & MESH_ENABLED) {
661 /*
662 * In mesh case, follow SAE finite state machine and
f3b8ad4d 663 * send Commit now, if sync count allows.
e96da42b 664 */
f3b8ad4d
BC
665 if (sae_check_big_sync(sta))
666 return WLAN_STATUS_SUCCESS;
667 sta->sae->sync++;
668
fabc6dd8 669 ret = auth_sae_send_commit(hapd, sta, bssid, 0);
e96da42b
BC
670 if (ret)
671 return ret;
f3b8ad4d
BC
672
673 sae_set_retransmit_timer(hapd, sta);
e96da42b
BC
674 } else {
675 /*
676 * For instructure BSS, send the postponed Confirm from
677 * Nothing -> Confirmed transition that was reduced to
678 * Nothing -> Committed above.
679 */
680 ret = auth_sae_send_confirm(hapd, sta, bssid);
681 if (ret)
682 return ret;
683
684 sta->sae->state = SAE_CONFIRMED;
685
686 /*
687 * Since this was triggered on Confirm RX, run another
688 * step to get to Accepted without waiting for
689 * additional events.
690 */
691 return sae_sm_step(hapd, sta, bssid, auth_transaction);
692 }
693 break;
694 case SAE_CONFIRMED:
f3b8ad4d 695 sae_clear_retransmit_timer(hapd, sta);
e96da42b 696 if (auth_transaction == 1) {
f3b8ad4d
BC
697 if (sae_check_big_sync(sta))
698 return WLAN_STATUS_SUCCESS;
699 sta->sae->sync++;
700
872b7545 701 ret = auth_sae_send_commit(hapd, sta, bssid, 1);
e96da42b
BC
702 if (ret)
703 return ret;
704
705 if (sae_process_commit(sta->sae) < 0)
706 return WLAN_STATUS_UNSPECIFIED_FAILURE;
707
708 ret = auth_sae_send_confirm(hapd, sta, bssid);
709 if (ret)
710 return ret;
f3b8ad4d
BC
711
712 sae_set_retransmit_timer(hapd, sta);
e96da42b 713 } else {
9f2cf23e 714 sae_accept_sta(hapd, sta);
e96da42b
BC
715 }
716 break;
717 case SAE_ACCEPTED:
718 if (auth_transaction == 1) {
719 wpa_printf(MSG_DEBUG, "SAE: remove the STA (" MACSTR
720 ") doing reauthentication",
721 MAC2STR(sta->addr));
722 ap_free_sta(hapd, sta);
9f2cf23e 723 wpa_auth_pmksa_remove(hapd->wpa_auth, sta->addr);
e96da42b 724 } else {
f3b8ad4d
BC
725 if (sae_check_big_sync(sta))
726 return WLAN_STATUS_SUCCESS;
727 sta->sae->sync++;
728
e96da42b
BC
729 ret = auth_sae_send_confirm(hapd, sta, bssid);
730 sae_clear_temp_data(sta->sae);
731 if (ret)
732 return ret;
733 }
734 break;
735 default:
736 wpa_printf(MSG_ERROR, "SAE: invalid state %d",
737 sta->sae->state);
738 return WLAN_STATUS_UNSPECIFIED_FAILURE;
739 }
740 return WLAN_STATUS_SUCCESS;
741}
742
743
dad01292
JM
744static void sae_pick_next_group(struct hostapd_data *hapd, struct sta_info *sta)
745{
746 struct sae_data *sae = sta->sae;
747 int i, *groups = hapd->conf->sae_groups;
748
749 if (sae->state != SAE_COMMITTED)
750 return;
751
752 wpa_printf(MSG_DEBUG, "SAE: Previously selected group: %d", sae->group);
753
754 for (i = 0; groups && groups[i] > 0; i++) {
755 if (sae->group == groups[i])
756 break;
757 }
758
759 if (!groups || groups[i] <= 0) {
760 wpa_printf(MSG_DEBUG,
761 "SAE: Previously selected group not found from the current configuration");
762 return;
763 }
764
765 for (;;) {
766 i++;
767 if (groups[i] <= 0) {
768 wpa_printf(MSG_DEBUG,
769 "SAE: No alternative group enabled");
770 return;
771 }
772
773 if (sae_set_group(sae, groups[i]) < 0)
774 continue;
775
776 break;
777 }
778 wpa_printf(MSG_DEBUG, "SAE: Selected new group: %d", groups[i]);
779}
780
781
c10347f2
JM
782static void handle_auth_sae(struct hostapd_data *hapd, struct sta_info *sta,
783 const struct ieee80211_mgmt *mgmt, size_t len,
afa2ffb4 784 u16 auth_transaction, u16 status_code)
c10347f2 785{
bb598c3b 786 int resp = WLAN_STATUS_SUCCESS;
750efe6e 787 struct wpabuf *data = NULL;
c10347f2 788
98efcc41 789 if (!sta->sae) {
bb598c3b
AB
790 if (auth_transaction != 1 ||
791 status_code != WLAN_STATUS_SUCCESS) {
792 resp = -1;
793 goto remove_sta;
794 }
98efcc41 795 sta->sae = os_zalloc(sizeof(*sta->sae));
bb598c3b
AB
796 if (!sta->sae) {
797 resp = -1;
798 goto remove_sta;
799 }
dd43026a 800 sta->sae->state = SAE_NOTHING;
f3b8ad4d 801 sta->sae->sync = 0;
98efcc41
JM
802 }
803
9f2cf23e
MH
804 if (sta->mesh_sae_pmksa_caching) {
805 wpa_printf(MSG_DEBUG,
806 "SAE: Cancel use of mesh PMKSA caching because peer starts SAE authentication");
807 wpa_auth_pmksa_remove(hapd->wpa_auth, sta->addr);
808 sta->mesh_sae_pmksa_caching = 0;
809 }
810
c10347f2 811 if (auth_transaction == 1) {
a959a3b6 812 const u8 *token = NULL, *pos, *end;
d136c376 813 size_t token_len = 0;
c10347f2
JM
814 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
815 HOSTAPD_LEVEL_DEBUG,
afa2ffb4
JM
816 "start SAE authentication (RX commit, status=%u)",
817 status_code);
872b7545
MH
818
819 if ((hapd->conf->mesh & MESH_ENABLED) &&
afa2ffb4
JM
820 status_code == WLAN_STATUS_ANTI_CLOGGING_TOKEN_REQ &&
821 sta->sae->tmp) {
a959a3b6
MH
822 pos = mgmt->u.auth.variable;
823 end = ((const u8 *) mgmt) + len;
824 if (pos + sizeof(le16) > end) {
825 wpa_printf(MSG_ERROR,
826 "SAE: Too short anti-clogging token request");
827 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
828 goto reply;
829 }
830 resp = sae_group_allowed(sta->sae,
831 hapd->conf->sae_groups,
832 WPA_GET_LE16(pos));
833 if (resp != WLAN_STATUS_SUCCESS) {
834 wpa_printf(MSG_ERROR,
835 "SAE: Invalid group in anti-clogging token request");
836 goto reply;
837 }
838 pos += sizeof(le16);
839
872b7545
MH
840 wpabuf_free(sta->sae->tmp->anti_clogging_token);
841 sta->sae->tmp->anti_clogging_token =
a959a3b6 842 wpabuf_alloc_copy(pos, end - pos);
872b7545
MH
843 if (sta->sae->tmp->anti_clogging_token == NULL) {
844 wpa_printf(MSG_ERROR,
845 "SAE: Failed to alloc for anti-clogging token");
bb598c3b
AB
846 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
847 goto remove_sta;
872b7545
MH
848 }
849
850 /*
851 * IEEE Std 802.11-2012, 11.3.8.6.4: If the Status code
852 * is 76, a new Commit Message shall be constructed
853 * with the Anti-Clogging Token from the received
854 * Authentication frame, and the commit-scalar and
855 * COMMIT-ELEMENT previously sent.
856 */
bb598c3b
AB
857 resp = auth_sae_send_commit(hapd, sta, mgmt->bssid, 0);
858 if (resp != WLAN_STATUS_SUCCESS) {
872b7545
MH
859 wpa_printf(MSG_ERROR,
860 "SAE: Failed to send commit message");
bb598c3b 861 goto remove_sta;
872b7545
MH
862 }
863 sta->sae->state = SAE_COMMITTED;
f3b8ad4d
BC
864 sta->sae->sync = 0;
865 sae_set_retransmit_timer(hapd, sta);
872b7545
MH
866 return;
867 }
868
dad01292
JM
869 if ((hapd->conf->mesh & MESH_ENABLED) &&
870 status_code ==
871 WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED &&
872 sta->sae->tmp) {
873 wpa_printf(MSG_DEBUG,
874 "SAE: Peer did not accept our SAE group");
875 sae_pick_next_group(hapd, sta);
876 goto remove_sta;
877 }
878
afa2ffb4 879 if (status_code != WLAN_STATUS_SUCCESS)
bb598c3b 880 goto remove_sta;
afa2ffb4 881
146f6c9a
JM
882 resp = sae_parse_commit(sta->sae, mgmt->u.auth.variable,
883 ((const u8 *) mgmt) + len -
d136c376 884 mgmt->u.auth.variable, &token,
625f202a 885 &token_len, hapd->conf->sae_groups);
6a58444d
JM
886 if (resp == SAE_SILENTLY_DISCARD) {
887 wpa_printf(MSG_DEBUG,
888 "SAE: Drop commit message from " MACSTR " due to reflection attack",
889 MAC2STR(sta->addr));
bb598c3b 890 goto remove_sta;
6a58444d 891 }
d136c376
JM
892 if (token && check_sae_token(hapd, sta->addr, token, token_len)
893 < 0) {
894 wpa_printf(MSG_DEBUG, "SAE: Drop commit message with "
895 "incorrect token from " MACSTR,
896 MAC2STR(sta->addr));
bb598c3b
AB
897 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
898 goto remove_sta;
d136c376
JM
899 }
900
e96da42b
BC
901 if (resp != WLAN_STATUS_SUCCESS)
902 goto reply;
903
904 if (!token && use_sae_anti_clogging(hapd)) {
905 wpa_printf(MSG_DEBUG,
906 "SAE: Request anti-clogging token from "
907 MACSTR, MAC2STR(sta->addr));
a959a3b6
MH
908 data = auth_build_token_req(hapd, sta->sae->group,
909 sta->addr);
e96da42b 910 resp = WLAN_STATUS_ANTI_CLOGGING_TOKEN_REQ;
872b7545
MH
911 if (hapd->conf->mesh & MESH_ENABLED)
912 sta->sae->state = SAE_NOTHING;
e96da42b 913 goto reply;
750efe6e 914 }
e96da42b
BC
915
916 resp = sae_sm_step(hapd, sta, mgmt->bssid, auth_transaction);
c10347f2 917 } else if (auth_transaction == 2) {
c10347f2
JM
918 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
919 HOSTAPD_LEVEL_DEBUG,
afa2ffb4
JM
920 "SAE authentication (RX confirm, status=%u)",
921 status_code);
922 if (status_code != WLAN_STATUS_SUCCESS)
bb598c3b 923 goto remove_sta;
e96da42b
BC
924 if (sta->sae->state >= SAE_CONFIRMED ||
925 !(hapd->conf->mesh & MESH_ENABLED)) {
926 if (sae_check_confirm(sta->sae, mgmt->u.auth.variable,
927 ((u8 *) mgmt) + len -
928 mgmt->u.auth.variable) < 0) {
750efe6e 929 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
e96da42b 930 goto reply;
b4fd3613 931 }
21af6d15 932 }
e96da42b 933 resp = sae_sm_step(hapd, sta, mgmt->bssid, auth_transaction);
c10347f2
JM
934 } else {
935 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
936 HOSTAPD_LEVEL_DEBUG,
afa2ffb4
JM
937 "unexpected SAE authentication transaction %u (status=%u)",
938 auth_transaction, status_code);
939 if (status_code != WLAN_STATUS_SUCCESS)
bb598c3b 940 goto remove_sta;
c10347f2
JM
941 resp = WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION;
942 }
943
e96da42b
BC
944reply:
945 if (resp != WLAN_STATUS_SUCCESS) {
946 send_auth_reply(hapd, mgmt->sa, mgmt->bssid, WLAN_AUTH_SAE,
947 auth_transaction, resp,
948 data ? wpabuf_head(data) : (u8 *) "",
949 data ? wpabuf_len(data) : 0);
950 }
bb598c3b
AB
951
952remove_sta:
953 if (sta->added_unassoc && (resp != WLAN_STATUS_SUCCESS ||
954 status_code != WLAN_STATUS_SUCCESS)) {
955 hostapd_drv_sta_remove(hapd, sta->addr);
956 sta->added_unassoc = 0;
957 }
21af6d15 958 wpabuf_free(data);
c10347f2 959}
a206e2a1
BC
960
961
962/**
963 * auth_sae_init_committed - Send COMMIT and start SAE in committed state
964 * @hapd: BSS data for the device initiating the authentication
965 * @sta: the peer to which commit authentication frame is sent
966 *
967 * This function implements Init event handling (IEEE Std 802.11-2012,
968 * 11.3.8.6.3) in which initial COMMIT message is sent. Prior to calling, the
969 * sta->sae structure should be initialized appropriately via a call to
970 * sae_prepare_commit().
971 */
972int auth_sae_init_committed(struct hostapd_data *hapd, struct sta_info *sta)
973{
974 int ret;
975
976 if (!sta->sae || !sta->sae->tmp)
977 return -1;
978
979 if (sta->sae->state != SAE_NOTHING)
980 return -1;
981
982 ret = auth_sae_send_commit(hapd, sta, hapd->own_addr, 0);
983 if (ret)
984 return -1;
985
986 sta->sae->state = SAE_COMMITTED;
f3b8ad4d
BC
987 sta->sae->sync = 0;
988 sae_set_retransmit_timer(hapd, sta);
a206e2a1
BC
989
990 return 0;
991}
992
c10347f2
JM
993#endif /* CONFIG_SAE */
994
995
ffb62f22
JM
996static u16 wpa_res_to_status_code(int res)
997{
998 if (res == WPA_INVALID_GROUP)
999 return WLAN_STATUS_GROUP_CIPHER_NOT_VALID;
1000 if (res == WPA_INVALID_PAIRWISE)
1001 return WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID;
1002 if (res == WPA_INVALID_AKMP)
1003 return WLAN_STATUS_AKMP_NOT_VALID;
1004 if (res == WPA_ALLOC_FAIL)
1005 return WLAN_STATUS_UNSPECIFIED_FAILURE;
1006#ifdef CONFIG_IEEE80211W
1007 if (res == WPA_MGMT_FRAME_PROTECTION_VIOLATION)
1008 return WLAN_STATUS_ROBUST_MGMT_FRAME_POLICY_VIOLATION;
1009 if (res == WPA_INVALID_MGMT_GROUP_CIPHER)
1010 return WLAN_STATUS_ROBUST_MGMT_FRAME_POLICY_VIOLATION;
1011#endif /* CONFIG_IEEE80211W */
1012 if (res == WPA_INVALID_MDIE)
1013 return WLAN_STATUS_INVALID_MDIE;
567da5bb
JM
1014 if (res == WPA_INVALID_PMKID)
1015 return WLAN_STATUS_INVALID_PMKID;
ffb62f22
JM
1016 if (res != WPA_IE_OK)
1017 return WLAN_STATUS_INVALID_IE;
1018 return WLAN_STATUS_SUCCESS;
1019}
1020
1021
c4fd6d8a
JM
1022#ifdef CONFIG_FILS
1023
1024static void handle_auth_fils_finish(struct hostapd_data *hapd,
1025 struct sta_info *sta, u16 resp,
5cee22ca
JM
1026 struct wpabuf *data, int pub);
1027
1028void handle_auth_fils(struct hostapd_data *hapd, struct sta_info *sta,
1029 const u8 *pos, size_t len, u16 auth_alg,
1030 u16 auth_transaction, u16 status_code,
1031 void (*cb)(struct hostapd_data *hapd,
1032 struct sta_info *sta, u16 resp,
1033 struct wpabuf *data, int pub))
c4fd6d8a
JM
1034{
1035 u16 resp = WLAN_STATUS_SUCCESS;
b8a3453a 1036 const u8 *end;
c4fd6d8a
JM
1037 struct ieee802_11_elems elems;
1038 int res;
1039 struct wpa_ie_data rsn;
1040 struct rsn_pmksa_cache_entry *pmksa = NULL;
1041
1042 if (auth_transaction != 1 || status_code != WLAN_STATUS_SUCCESS)
1043 return;
1044
b8a3453a 1045 end = pos + len;
c4fd6d8a
JM
1046
1047 wpa_hexdump(MSG_DEBUG, "FILS: Authentication frame fields",
1048 pos, end - pos);
1049
1764559e
JM
1050 /* TODO: FILS PK */
1051#ifdef CONFIG_FILS_SK_PFS
1052 if (auth_alg == WLAN_AUTH_FILS_SK_PFS) {
1053 u16 group;
1054 struct wpabuf *pub;
1055 size_t elem_len;
1056
1057 /* Using FILS PFS */
1058
1059 /* Finite Cyclic Group */
1060 if (end - pos < 2) {
1061 wpa_printf(MSG_DEBUG,
1062 "FILS: No room for Finite Cyclic Group");
1063 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1064 goto fail;
1065 }
1066 group = WPA_GET_LE16(pos);
1067 pos += 2;
1068 if (group != hapd->conf->fils_dh_group) {
1069 wpa_printf(MSG_DEBUG,
1070 "FILS: Unsupported Finite Cyclic Group: %u (expected %u)",
1071 group, hapd->conf->fils_dh_group);
1072 resp = WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED;
1073 goto fail;
1074 }
1075
1076 crypto_ecdh_deinit(sta->fils_ecdh);
1077 sta->fils_ecdh = crypto_ecdh_init(group);
1078 if (!sta->fils_ecdh) {
1079 wpa_printf(MSG_INFO,
1080 "FILS: Could not initialize ECDH with group %d",
1081 group);
1082 resp = WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED;
1083 goto fail;
1084 }
1085
1086 pub = crypto_ecdh_get_pubkey(sta->fils_ecdh, 1);
1087 if (!pub) {
1088 wpa_printf(MSG_DEBUG,
1089 "FILS: Failed to derive ECDH public key");
1090 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1091 goto fail;
1092 }
1093 elem_len = wpabuf_len(pub);
1094 wpabuf_free(pub);
1095
1096 /* Element */
1097 if ((size_t) (end - pos) < elem_len) {
1098 wpa_printf(MSG_DEBUG, "FILS: No room for Element");
1099 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1100 goto fail;
1101 }
1102
80ddf5d9
JM
1103 wpabuf_free(sta->fils_g_sta);
1104 sta->fils_g_sta = wpabuf_alloc_copy(pos, elem_len);
1764559e
JM
1105 wpabuf_clear_free(sta->fils_dh_ss);
1106 sta->fils_dh_ss = crypto_ecdh_set_peerkey(sta->fils_ecdh, 1,
1107 pos, elem_len);
1108 if (!sta->fils_dh_ss) {
1109 wpa_printf(MSG_DEBUG, "FILS: ECDH operation failed");
1110 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1111 goto fail;
1112 }
1113 wpa_hexdump_buf_key(MSG_DEBUG, "FILS: DH_SS", sta->fils_dh_ss);
1114 pos += elem_len;
1115 } else {
1116 crypto_ecdh_deinit(sta->fils_ecdh);
1117 sta->fils_ecdh = NULL;
1118 wpabuf_clear_free(sta->fils_dh_ss);
1119 sta->fils_dh_ss = NULL;
1120 }
1121#endif /* CONFIG_FILS_SK_PFS */
c4fd6d8a
JM
1122
1123 wpa_hexdump(MSG_DEBUG, "FILS: Remaining IEs", pos, end - pos);
1124 if (ieee802_11_parse_elems(pos, end - pos, &elems, 1) == ParseFailed) {
1125 wpa_printf(MSG_DEBUG, "FILS: Could not parse elements");
1126 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1127 goto fail;
1128 }
1129
1130 /* RSNE */
1131 wpa_hexdump(MSG_DEBUG, "FILS: RSN element",
1132 elems.rsn_ie, elems.rsn_ie_len);
1133 if (!elems.rsn_ie ||
1134 wpa_parse_wpa_ie_rsn(elems.rsn_ie - 2, elems.rsn_ie_len + 2,
1135 &rsn) < 0) {
1136 wpa_printf(MSG_DEBUG, "FILS: No valid RSN element");
1137 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1138 goto fail;
1139 }
1140
1141 if (!sta->wpa_sm)
1142 sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth, sta->addr,
1143 NULL);
1144 if (!sta->wpa_sm) {
1145 wpa_printf(MSG_DEBUG,
1146 "FILS: Failed to initialize RSN state machine");
1147 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1148 goto fail;
1149 }
1150
1151 res = wpa_validate_wpa_ie(hapd->wpa_auth, sta->wpa_sm,
1152 elems.rsn_ie - 2, elems.rsn_ie_len + 2,
09368515 1153 elems.mdie, elems.mdie_len, NULL, 0);
c4fd6d8a
JM
1154 resp = wpa_res_to_status_code(res);
1155 if (resp != WLAN_STATUS_SUCCESS)
1156 goto fail;
1157
c4fd6d8a
JM
1158 if (!elems.fils_nonce) {
1159 wpa_printf(MSG_DEBUG, "FILS: No FILS Nonce field");
1160 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1161 goto fail;
1162 }
1163 wpa_hexdump(MSG_DEBUG, "FILS: SNonce", elems.fils_nonce,
1164 FILS_NONCE_LEN);
1165 os_memcpy(sta->fils_snonce, elems.fils_nonce, FILS_NONCE_LEN);
1166
1167 /* PMKID List */
1168 if (rsn.pmkid && rsn.num_pmkid > 0) {
1169 u8 num;
1170 const u8 *pmkid;
1171
1172 wpa_hexdump(MSG_DEBUG, "FILS: PMKID List",
1173 rsn.pmkid, rsn.num_pmkid * PMKID_LEN);
1174
1175 pmkid = rsn.pmkid;
1176 num = rsn.num_pmkid;
1177 while (num) {
1178 wpa_hexdump(MSG_DEBUG, "FILS: PMKID", pmkid, PMKID_LEN);
1179 pmksa = wpa_auth_pmksa_get(hapd->wpa_auth, sta->addr,
1180 pmkid);
1181 if (pmksa)
1182 break;
7eace378
JM
1183 pmksa = wpa_auth_pmksa_get_fils_cache_id(hapd->wpa_auth,
1184 sta->addr,
1185 pmkid);
1186 if (pmksa)
1187 break;
c4fd6d8a
JM
1188 pmkid += PMKID_LEN;
1189 num--;
1190 }
1191 }
1192 if (pmksa && wpa_auth_sta_key_mgmt(sta->wpa_sm) != pmksa->akmp) {
1193 wpa_printf(MSG_DEBUG,
1194 "FILS: Matching PMKSA cache entry has different AKMP (0x%x != 0x%x) - ignore",
1195 wpa_auth_sta_key_mgmt(sta->wpa_sm), pmksa->akmp);
1196 pmksa = NULL;
1197 }
1198 if (pmksa)
1199 wpa_printf(MSG_DEBUG, "FILS: Found matching PMKSA cache entry");
1200
1201 /* FILS Session */
1202 if (!elems.fils_session) {
1203 wpa_printf(MSG_DEBUG, "FILS: No FILS Session element");
1204 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1205 goto fail;
1206 }
1207 wpa_hexdump(MSG_DEBUG, "FILS: FILS Session", elems.fils_session,
1208 FILS_SESSION_LEN);
1209 os_memcpy(sta->fils_session, elems.fils_session, FILS_SESSION_LEN);
1210
1211 /* FILS Wrapped Data */
1212 if (elems.fils_wrapped_data) {
1213 wpa_hexdump(MSG_DEBUG, "FILS: Wrapped Data",
1214 elems.fils_wrapped_data,
1215 elems.fils_wrapped_data_len);
1216 if (!pmksa) {
1217#ifndef CONFIG_NO_RADIUS
1218 if (!sta->eapol_sm) {
1219 sta->eapol_sm =
1220 ieee802_1x_alloc_eapol_sm(hapd, sta);
1221 }
1222 wpa_printf(MSG_DEBUG,
bfe44833 1223 "FILS: Forward EAP-Initiate/Re-auth to authentication server");
c4fd6d8a
JM
1224 ieee802_1x_encapsulate_radius(
1225 hapd, sta, elems.fils_wrapped_data,
1226 elems.fils_wrapped_data_len);
5cee22ca 1227 sta->fils_pending_cb = cb;
c4fd6d8a
JM
1228 wpa_printf(MSG_DEBUG,
1229 "FILS: Will send Authentication frame once the response from authentication server is available");
1230 sta->flags |= WLAN_STA_PENDING_FILS_ERP;
b3e567c8
JM
1231 /* Calculate pending PMKID here so that we do not need
1232 * to maintain a copy of the EAP-Initiate/Reauth
1233 * message. */
1234 if (fils_pmkid_erp(wpa_auth_sta_key_mgmt(sta->wpa_sm),
1235 elems.fils_wrapped_data,
1236 elems.fils_wrapped_data_len,
1237 sta->fils_erp_pmkid) == 0)
1238 sta->fils_erp_pmkid_set = 1;
c4fd6d8a
JM
1239 return;
1240#else /* CONFIG_NO_RADIUS */
1241 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1242 goto fail;
1243#endif /* CONFIG_NO_RADIUS */
1244 }
1245 }
1246
1247fail:
5cee22ca
JM
1248 if (cb) {
1249 struct wpabuf *data;
1250 int pub = 0;
1251
1252 data = prepare_auth_resp_fils(hapd, sta, &resp, pmksa, NULL,
1253 NULL, 0, &pub);
1254 if (!data) {
1255 wpa_printf(MSG_DEBUG,
1256 "%s: prepare_auth_resp_fils() returned failure",
1257 __func__);
1258 }
1259
1260 cb(hapd, sta, resp, data, pub);
1261 }
c4fd6d8a
JM
1262}
1263
1264
5e5f8c81
JM
1265static struct wpabuf *
1266prepare_auth_resp_fils(struct hostapd_data *hapd,
1267 struct sta_info *sta, u16 *resp,
1268 struct rsn_pmksa_cache_entry *pmksa,
1269 struct wpabuf *erp_resp,
1270 const u8 *msk, size_t msk_len,
1271 int *is_pub)
c4fd6d8a
JM
1272{
1273 u8 fils_nonce[FILS_NONCE_LEN];
1274 size_t ielen;
1275 struct wpabuf *data = NULL;
1276 const u8 *ie;
1277 u8 *ie_buf = NULL;
1278 const u8 *pmk = NULL;
1279 size_t pmk_len = 0;
fcd3d6ce 1280 u8 pmk_buf[PMK_LEN_MAX];
1764559e 1281 struct wpabuf *pub = NULL;
c4fd6d8a 1282
5e5f8c81 1283 if (*resp != WLAN_STATUS_SUCCESS)
c4fd6d8a
JM
1284 goto fail;
1285
1286 ie = wpa_auth_get_wpa_ie(hapd->wpa_auth, &ielen);
1287 if (!ie) {
5e5f8c81 1288 *resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
c4fd6d8a
JM
1289 goto fail;
1290 }
5e5f8c81 1291
c4fd6d8a
JM
1292 if (pmksa) {
1293 /* Add PMKID of the selected PMKSA into RSNE */
1294 ie_buf = os_malloc(ielen + 2 + 2 + PMKID_LEN);
1295 if (!ie_buf) {
5e5f8c81 1296 *resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
c4fd6d8a
JM
1297 goto fail;
1298 }
5e5f8c81 1299
c4fd6d8a
JM
1300 os_memcpy(ie_buf, ie, ielen);
1301 if (wpa_insert_pmkid(ie_buf, &ielen, pmksa->pmkid) < 0) {
5e5f8c81 1302 *resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
c4fd6d8a
JM
1303 goto fail;
1304 }
1305 ie = ie_buf;
1306 }
1307
1308 if (random_get_bytes(fils_nonce, FILS_NONCE_LEN) < 0) {
5e5f8c81 1309 *resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
c4fd6d8a
JM
1310 goto fail;
1311 }
1312 wpa_hexdump(MSG_DEBUG, "RSN: Generated FILS Nonce",
1313 fils_nonce, FILS_NONCE_LEN);
1314
1764559e
JM
1315#ifdef CONFIG_FILS_SK_PFS
1316 if (sta->fils_dh_ss && sta->fils_ecdh) {
1317 pub = crypto_ecdh_get_pubkey(sta->fils_ecdh, 1);
1318 if (!pub) {
5e5f8c81 1319 *resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1764559e
JM
1320 goto fail;
1321 }
1322 }
1323#endif /* CONFIG_FILS_SK_PFS */
1324
1325 data = wpabuf_alloc(1000 + ielen + (pub ? wpabuf_len(pub) : 0));
c4fd6d8a 1326 if (!data) {
5e5f8c81 1327 *resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
c4fd6d8a
JM
1328 goto fail;
1329 }
1330
1764559e
JM
1331 /* TODO: FILS PK */
1332#ifdef CONFIG_FILS_SK_PFS
1333 if (pub) {
1334 /* Finite Cyclic Group */
1335 wpabuf_put_le16(data, hapd->conf->fils_dh_group);
1336
1337 /* Element */
1338 wpabuf_put_buf(data, pub);
1339 }
1340#endif /* CONFIG_FILS_SK_PFS */
c4fd6d8a
JM
1341
1342 /* RSNE */
1343 wpabuf_put_data(data, ie, ielen);
1344
5db997e3
JM
1345 /* MDE when using FILS+FT (already included in ie,ielen with RSNE) */
1346
1347#ifdef CONFIG_IEEE80211R_AP
1348 if (wpa_key_mgmt_ft(wpa_auth_sta_key_mgmt(sta->wpa_sm))) {
1349 /* FTE[R1KH-ID,R0KH-ID] when using FILS+FT */
1350 int res;
1351
1352 res = wpa_auth_write_fte(hapd->wpa_auth, wpabuf_put(data, 0),
1353 wpabuf_tailroom(data));
1354 if (res < 0) {
5e5f8c81 1355 *resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
5db997e3
JM
1356 goto fail;
1357 }
1358 wpabuf_put(data, res);
1359 }
1360#endif /* CONFIG_IEEE80211R_AP */
c4fd6d8a
JM
1361
1362 /* FILS Nonce */
1363 wpabuf_put_u8(data, WLAN_EID_EXTENSION); /* Element ID */
1364 wpabuf_put_u8(data, 1 + FILS_NONCE_LEN); /* Length */
1365 /* Element ID Extension */
1366 wpabuf_put_u8(data, WLAN_EID_EXT_FILS_NONCE);
1367 wpabuf_put_data(data, fils_nonce, FILS_NONCE_LEN);
1368
1369 /* FILS Session */
1370 wpabuf_put_u8(data, WLAN_EID_EXTENSION); /* Element ID */
1371 wpabuf_put_u8(data, 1 + FILS_SESSION_LEN); /* Length */
1372 /* Element ID Extension */
1373 wpabuf_put_u8(data, WLAN_EID_EXT_FILS_SESSION);
1374 wpabuf_put_data(data, sta->fils_session, FILS_SESSION_LEN);
1375
1376 /* FILS Wrapped Data */
1377 if (!pmksa && erp_resp) {
1378 wpabuf_put_u8(data, WLAN_EID_EXTENSION); /* Element ID */
1379 wpabuf_put_u8(data, 1 + wpabuf_len(erp_resp)); /* Length */
1380 /* Element ID Extension */
1381 wpabuf_put_u8(data, WLAN_EID_EXT_FILS_WRAPPED_DATA);
1382 wpabuf_put_buf(data, erp_resp);
1383
fcd3d6ce
JM
1384 if (fils_rmsk_to_pmk(wpa_auth_sta_key_mgmt(sta->wpa_sm),
1385 msk, msk_len, sta->fils_snonce, fils_nonce,
1764559e
JM
1386 sta->fils_dh_ss ?
1387 wpabuf_head(sta->fils_dh_ss) : NULL,
1388 sta->fils_dh_ss ?
1389 wpabuf_len(sta->fils_dh_ss) : 0,
1390 pmk_buf, &pmk_len)) {
fcd3d6ce 1391 wpa_printf(MSG_DEBUG, "FILS: Failed to derive PMK");
5e5f8c81 1392 *resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
fcd3d6ce
JM
1393 wpabuf_free(data);
1394 data = NULL;
1395 goto fail;
1396 }
1397 pmk = pmk_buf;
b3e567c8
JM
1398
1399 if (sta->fils_erp_pmkid_set) {
1400 /* TODO: get PMKLifetime from WPA parameters */
1401 unsigned int dot11RSNAConfigPMKLifetime = 43200;
1402
1403 sta->fils_erp_pmkid_set = 0;
1404 if (wpa_auth_pmksa_add2(
1405 hapd->wpa_auth, sta->addr,
1406 pmk, pmk_len,
1407 sta->fils_erp_pmkid,
1408 sta->session_timeout_set ?
1409 sta->session_timeout :
1410 dot11RSNAConfigPMKLifetime,
1411 wpa_auth_sta_key_mgmt(sta->wpa_sm)) < 0) {
1412 wpa_printf(MSG_ERROR,
1413 "FILS: Failed to add PMKSA cache entry based on ERP");
1414 }
1415 }
c4fd6d8a
JM
1416 } else if (pmksa) {
1417 pmk = pmksa->pmk;
1418 pmk_len = pmksa->pmk_len;
1419 }
1420
1421 if (!pmk) {
1422 wpa_printf(MSG_DEBUG, "FILS: No PMK available");
5e5f8c81 1423 *resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
c4fd6d8a
JM
1424 wpabuf_free(data);
1425 data = NULL;
1426 goto fail;
1427 }
1428
1429 if (fils_auth_pmk_to_ptk(sta->wpa_sm, pmk, pmk_len,
80ddf5d9
JM
1430 sta->fils_snonce, fils_nonce,
1431 sta->fils_g_sta, pub) < 0) {
5e5f8c81 1432 *resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
c4fd6d8a
JM
1433 wpabuf_free(data);
1434 data = NULL;
1435 goto fail;
1436 }
1437
1438fail:
5e5f8c81
JM
1439 if (is_pub)
1440 *is_pub = pub != NULL;
1441 os_free(ie_buf);
1442 wpabuf_free(pub);
1443 wpabuf_clear_free(sta->fils_dh_ss);
1444 sta->fils_dh_ss = NULL;
1445#ifdef CONFIG_FILS_SK_PFS
1446 crypto_ecdh_deinit(sta->fils_ecdh);
1447 sta->fils_ecdh = NULL;
1448#endif /* CONFIG_FILS_SK_PFS */
1449 return data;
1450}
1451
1452
1453static void handle_auth_fils_finish(struct hostapd_data *hapd,
1454 struct sta_info *sta, u16 resp,
5cee22ca 1455 struct wpabuf *data, int pub)
5e5f8c81 1456{
5e5f8c81 1457 u16 auth_alg;
5e5f8c81 1458
1764559e
JM
1459 auth_alg = (pub ||
1460 resp == WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED) ?
1461 WLAN_AUTH_FILS_SK_PFS : WLAN_AUTH_FILS_SK;
1462 send_auth_reply(hapd, sta->addr, hapd->own_addr, auth_alg, 2, resp,
c4fd6d8a
JM
1463 data ? wpabuf_head(data) : (u8 *) "",
1464 data ? wpabuf_len(data) : 0);
1465 wpabuf_free(data);
1466
1467 if (resp == WLAN_STATUS_SUCCESS) {
1468 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
1469 HOSTAPD_LEVEL_DEBUG,
1470 "authentication OK (FILS)");
1471 sta->flags |= WLAN_STA_AUTH;
1472 wpa_auth_sm_event(sta->wpa_sm, WPA_AUTH);
1764559e 1473 sta->auth_alg = pub ? WLAN_AUTH_FILS_SK_PFS : WLAN_AUTH_FILS_SK;
c4fd6d8a
JM
1474 mlme_authenticate_indication(hapd, sta);
1475 }
c4fd6d8a
JM
1476}
1477
1478
1479void ieee802_11_finish_fils_auth(struct hostapd_data *hapd,
1480 struct sta_info *sta, int success,
1481 struct wpabuf *erp_resp,
1482 const u8 *msk, size_t msk_len)
1483{
5cee22ca
JM
1484 struct wpabuf *data;
1485 int pub = 0;
1486 u16 resp;
1487
c4fd6d8a 1488 sta->flags &= ~WLAN_STA_PENDING_FILS_ERP;
5cee22ca
JM
1489
1490 if (!sta->fils_pending_cb)
1491 return;
1492 resp = success ? WLAN_STATUS_SUCCESS : WLAN_STATUS_UNSPECIFIED_FAILURE;
1493 data = prepare_auth_resp_fils(hapd, sta, &resp, NULL, erp_resp,
1494 msk, msk_len, &pub);
1495 if (!data) {
1496 wpa_printf(MSG_DEBUG,
1497 "%s: prepare_auth_resp_fils() returned failure",
1498 __func__);
1499 }
1500 sta->fils_pending_cb(hapd, sta, resp, data, pub);
c4fd6d8a
JM
1501}
1502
1503#endif /* CONFIG_FILS */
1504
1505
53d17144
DL
1506static int
1507ieee802_11_allowed_address(struct hostapd_data *hapd, const u8 *addr,
1508 const u8 *msg, size_t len, u32 *session_timeout,
1509 u32 *acct_interim_interval,
1510 struct vlan_description *vlan_id,
1511 struct hostapd_sta_wpa_psk_short **psk,
1512 char **identity, char **radius_cui)
1513{
1514 int res;
1515
1516 os_memset(vlan_id, 0, sizeof(*vlan_id));
1517 res = hostapd_allowed_address(hapd, addr, msg, len,
1518 session_timeout, acct_interim_interval,
1519 vlan_id, psk, identity, radius_cui);
1520
1521 if (res == HOSTAPD_ACL_REJECT) {
1522 wpa_printf(MSG_INFO,
1523 "Station " MACSTR " not allowed to authenticate",
1524 MAC2STR(addr));
1525 return HOSTAPD_ACL_REJECT;
1526 }
1527
1528 if (res == HOSTAPD_ACL_PENDING) {
1529 wpa_printf(MSG_DEBUG, "Authentication frame from " MACSTR
1530 " waiting for an external authentication",
1531 MAC2STR(addr));
1532 /* Authentication code will re-send the authentication frame
1533 * after it has received (and cached) information from the
1534 * external source. */
1535 return HOSTAPD_ACL_PENDING;
1536 }
1537
1538 return res;
1539}
1540
1541
1542static int
1543ieee802_11_set_radius_info(struct hostapd_data *hapd, struct sta_info *sta,
1544 int res, u32 session_timeout,
1545 u32 acct_interim_interval,
1546 struct vlan_description *vlan_id,
1547 struct hostapd_sta_wpa_psk_short **psk,
1548 char **identity, char **radius_cui)
1549{
1550 if (vlan_id->notempty &&
1551 !hostapd_vlan_valid(hapd->conf->vlan, vlan_id)) {
1552 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_RADIUS,
1553 HOSTAPD_LEVEL_INFO,
1554 "Invalid VLAN %d%s received from RADIUS server",
1555 vlan_id->untagged,
1556 vlan_id->tagged[0] ? "+" : "");
1557 return -1;
1558 }
1559 if (ap_sta_set_vlan(hapd, sta, vlan_id) < 0)
1560 return -1;
1561 if (sta->vlan_id)
1562 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_RADIUS,
1563 HOSTAPD_LEVEL_INFO, "VLAN ID %d", sta->vlan_id);
1564
1565 hostapd_free_psk_list(sta->psk);
1566 if (hapd->conf->wpa_psk_radius != PSK_RADIUS_IGNORED) {
1567 sta->psk = *psk;
1568 *psk = NULL;
1569 } else {
1570 sta->psk = NULL;
1571 }
1572
1573 sta->identity = *identity;
1574 *identity = NULL;
1575 sta->radius_cui = *radius_cui;
1576 *radius_cui = NULL;
1577
1578 if (hapd->conf->acct_interim_interval == 0 && acct_interim_interval)
1579 sta->acct_interim_interval = acct_interim_interval;
1580 if (res == HOSTAPD_ACL_ACCEPT_TIMEOUT)
1581 ap_sta_session_timeout(hapd, sta, session_timeout);
1582 else
1583 ap_sta_no_session_timeout(hapd, sta);
1584
1585 return 0;
1586}
1587
1588
b57e086c
JM
1589static void handle_auth(struct hostapd_data *hapd,
1590 const struct ieee80211_mgmt *mgmt, size_t len)
6fc6879b
JM
1591{
1592 u16 auth_alg, auth_transaction, status_code;
1593 u16 resp = WLAN_STATUS_SUCCESS;
1594 struct sta_info *sta = NULL;
bb598c3b 1595 int res, reply_res;
6fc6879b 1596 u16 fc;
b57e086c 1597 const u8 *challenge = NULL;
6fc6879b 1598 u32 session_timeout, acct_interim_interval;
1889af2e 1599 struct vlan_description vlan_id;
2ad3e6c8 1600 struct hostapd_sta_wpa_psk_short *psk = NULL;
6fc6879b
JM
1601 u8 resp_ies[2 + WLAN_AUTH_CHALLENGE_LEN];
1602 size_t resp_ies_len = 0;
2092597f
MB
1603 char *identity = NULL;
1604 char *radius_cui = NULL;
38cb0a2d 1605 u16 seq_ctrl;
6fc6879b
JM
1606
1607 if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.auth)) {
61323e70
JM
1608 wpa_printf(MSG_INFO, "handle_auth - too short payload (len=%lu)",
1609 (unsigned long) len);
6fc6879b
JM
1610 return;
1611 }
1612
c2aff6b1 1613#ifdef CONFIG_TESTING_OPTIONS
06df2aa6 1614 if (hapd->iconf->ignore_auth_probability > 0.0 &&
c2aff6b1
JB
1615 drand48() < hapd->iconf->ignore_auth_probability) {
1616 wpa_printf(MSG_INFO,
1617 "TESTING: ignoring auth frame from " MACSTR,
1618 MAC2STR(mgmt->sa));
1619 return;
1620 }
1621#endif /* CONFIG_TESTING_OPTIONS */
1622
6fc6879b
JM
1623 auth_alg = le_to_host16(mgmt->u.auth.auth_alg);
1624 auth_transaction = le_to_host16(mgmt->u.auth.auth_transaction);
1625 status_code = le_to_host16(mgmt->u.auth.status_code);
1626 fc = le_to_host16(mgmt->frame_control);
38cb0a2d 1627 seq_ctrl = le_to_host16(mgmt->seq_ctrl);
6fc6879b
JM
1628
1629 if (len >= IEEE80211_HDRLEN + sizeof(mgmt->u.auth) +
1630 2 + WLAN_AUTH_CHALLENGE_LEN &&
1631 mgmt->u.auth.variable[0] == WLAN_EID_CHALLENGE &&
1632 mgmt->u.auth.variable[1] == WLAN_AUTH_CHALLENGE_LEN)
1633 challenge = &mgmt->u.auth.variable[2];
1634
1635 wpa_printf(MSG_DEBUG, "authentication: STA=" MACSTR " auth_alg=%d "
38cb0a2d
IP
1636 "auth_transaction=%d status_code=%d wep=%d%s "
1637 "seq_ctrl=0x%x%s",
6fc6879b
JM
1638 MAC2STR(mgmt->sa), auth_alg, auth_transaction,
1639 status_code, !!(fc & WLAN_FC_ISWEP),
38cb0a2d
IP
1640 challenge ? " challenge" : "",
1641 seq_ctrl, (fc & WLAN_FC_RETRY) ? " retry" : "");
6fc6879b 1642
7cb53ded
JM
1643#ifdef CONFIG_NO_RC4
1644 if (auth_alg == WLAN_AUTH_SHARED_KEY) {
1645 wpa_printf(MSG_INFO,
1646 "Unsupported authentication algorithm (%d)",
1647 auth_alg);
1648 resp = WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG;
1649 goto fail;
1650 }
1651#endif /* CONFIG_NO_RC4 */
1652
6fc6879b
JM
1653 if (hapd->tkip_countermeasures) {
1654 resp = WLAN_REASON_MICHAEL_MIC_FAILURE;
1655 goto fail;
1656 }
1657
1658 if (!(((hapd->conf->auth_algs & WPA_AUTH_ALG_OPEN) &&
1659 auth_alg == WLAN_AUTH_OPEN) ||
4ec1fd8e 1660#ifdef CONFIG_IEEE80211R_AP
0bf927a0 1661 (hapd->conf->wpa && wpa_key_mgmt_ft(hapd->conf->wpa_key_mgmt) &&
6fc6879b 1662 auth_alg == WLAN_AUTH_FT) ||
4ec1fd8e 1663#endif /* CONFIG_IEEE80211R_AP */
c10347f2
JM
1664#ifdef CONFIG_SAE
1665 (hapd->conf->wpa && wpa_key_mgmt_sae(hapd->conf->wpa_key_mgmt) &&
1666 auth_alg == WLAN_AUTH_SAE) ||
1667#endif /* CONFIG_SAE */
c4fd6d8a
JM
1668#ifdef CONFIG_FILS
1669 (hapd->conf->wpa && wpa_key_mgmt_fils(hapd->conf->wpa_key_mgmt) &&
1670 auth_alg == WLAN_AUTH_FILS_SK) ||
1764559e
JM
1671 (hapd->conf->wpa && wpa_key_mgmt_fils(hapd->conf->wpa_key_mgmt) &&
1672 hapd->conf->fils_dh_group &&
1673 auth_alg == WLAN_AUTH_FILS_SK_PFS) ||
c4fd6d8a 1674#endif /* CONFIG_FILS */
6fc6879b
JM
1675 ((hapd->conf->auth_algs & WPA_AUTH_ALG_SHARED) &&
1676 auth_alg == WLAN_AUTH_SHARED_KEY))) {
61323e70
JM
1677 wpa_printf(MSG_INFO, "Unsupported authentication algorithm (%d)",
1678 auth_alg);
6fc6879b
JM
1679 resp = WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG;
1680 goto fail;
1681 }
1682
c10347f2 1683 if (!(auth_transaction == 1 || auth_alg == WLAN_AUTH_SAE ||
6fc6879b 1684 (auth_alg == WLAN_AUTH_SHARED_KEY && auth_transaction == 3))) {
61323e70
JM
1685 wpa_printf(MSG_INFO, "Unknown authentication transaction number (%d)",
1686 auth_transaction);
6fc6879b
JM
1687 resp = WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION;
1688 goto fail;
1689 }
1690
1691 if (os_memcmp(mgmt->sa, hapd->own_addr, ETH_ALEN) == 0) {
61323e70
JM
1692 wpa_printf(MSG_INFO, "Station " MACSTR " not allowed to authenticate",
1693 MAC2STR(mgmt->sa));
6fc6879b
JM
1694 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1695 goto fail;
1696 }
1697
0e2412d0
JM
1698 if (hapd->conf->no_auth_if_seen_on) {
1699 struct hostapd_data *other;
1700
1701 other = sta_track_seen_on(hapd->iface, mgmt->sa,
1702 hapd->conf->no_auth_if_seen_on);
1703 if (other) {
1704 u8 *pos;
1705 u32 info;
1706 u8 op_class, channel, phytype;
1707
1708 wpa_printf(MSG_DEBUG, "%s: Reject authentication from "
1709 MACSTR " since STA has been seen on %s",
1710 hapd->conf->iface, MAC2STR(mgmt->sa),
1711 hapd->conf->no_auth_if_seen_on);
1712
1713 resp = WLAN_STATUS_REJECTED_WITH_SUGGESTED_BSS_TRANSITION;
1714 pos = &resp_ies[0];
1715 *pos++ = WLAN_EID_NEIGHBOR_REPORT;
1716 *pos++ = 13;
1717 os_memcpy(pos, other->own_addr, ETH_ALEN);
1718 pos += ETH_ALEN;
1719 info = 0; /* TODO: BSSID Information */
1720 WPA_PUT_LE32(pos, info);
1721 pos += 4;
1722 if (other->iconf->hw_mode == HOSTAPD_MODE_IEEE80211AD)
1723 phytype = 8; /* dmg */
1724 else if (other->iconf->ieee80211ac)
1725 phytype = 9; /* vht */
1726 else if (other->iconf->ieee80211n)
1727 phytype = 7; /* ht */
1728 else if (other->iconf->hw_mode ==
1729 HOSTAPD_MODE_IEEE80211A)
1730 phytype = 4; /* ofdm */
1731 else if (other->iconf->hw_mode ==
1732 HOSTAPD_MODE_IEEE80211G)
1733 phytype = 6; /* erp */
1734 else
1735 phytype = 5; /* hrdsss */
1736 if (ieee80211_freq_to_channel_ext(
1737 hostapd_hw_get_freq(other,
1738 other->iconf->channel),
1739 other->iconf->secondary_channel,
1740 other->iconf->ieee80211ac,
1741 &op_class, &channel) == NUM_HOSTAPD_MODES) {
1742 op_class = 0;
1743 channel = other->iconf->channel;
1744 }
1745 *pos++ = op_class;
1746 *pos++ = channel;
1747 *pos++ = phytype;
1748 resp_ies_len = pos - &resp_ies[0];
1749 goto fail;
1750 }
1751 }
1752
53d17144
DL
1753 res = ieee802_11_allowed_address(
1754 hapd, mgmt->sa, (const u8 *) mgmt, len, &session_timeout,
1755 &acct_interim_interval, &vlan_id, &psk, &identity, &radius_cui);
6fc6879b 1756 if (res == HOSTAPD_ACL_REJECT) {
6fc6879b
JM
1757 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1758 goto fail;
1759 }
53d17144 1760 if (res == HOSTAPD_ACL_PENDING)
6fc6879b 1761 return;
6fc6879b 1762
38cb0a2d
IP
1763 sta = ap_get_sta(hapd, mgmt->sa);
1764 if (sta) {
c4fd6d8a 1765 sta->flags &= ~WLAN_STA_PENDING_FILS_ERP;
38cb0a2d
IP
1766 if ((fc & WLAN_FC_RETRY) &&
1767 sta->last_seq_ctrl != WLAN_INVALID_MGMT_SEQ &&
1768 sta->last_seq_ctrl == seq_ctrl &&
1769 sta->last_subtype == WLAN_FC_STYPE_AUTH) {
1770 hostapd_logger(hapd, sta->addr,
1771 HOSTAPD_MODULE_IEEE80211,
1772 HOSTAPD_LEVEL_DEBUG,
1773 "Drop repeated authentication frame seq_ctrl=0x%x",
1774 seq_ctrl);
1775 return;
1776 }
09d96de0
MH
1777#ifdef CONFIG_MESH
1778 if ((hapd->conf->mesh & MESH_ENABLED) &&
1779 sta->plink_state == PLINK_BLOCKED) {
1780 wpa_printf(MSG_DEBUG, "Mesh peer " MACSTR
1781 " is blocked - drop Authentication frame",
1782 MAC2STR(mgmt->sa));
1783 return;
1784 }
1785#endif /* CONFIG_MESH */
38cb0a2d 1786 } else {
c50d94f1 1787#ifdef CONFIG_MESH
38cb0a2d
IP
1788 if (hapd->conf->mesh & MESH_ENABLED) {
1789 /* if the mesh peer is not available, we don't do auth.
1790 */
3a322496 1791 wpa_printf(MSG_DEBUG, "Mesh peer " MACSTR
09d96de0 1792 " not yet known - drop Authentication frame",
3a322496
JM
1793 MAC2STR(mgmt->sa));
1794 /*
1795 * Save a copy of the frame so that it can be processed
1796 * if a new peer entry is added shortly after this.
1797 */
1798 wpabuf_free(hapd->mesh_pending_auth);
1799 hapd->mesh_pending_auth = wpabuf_alloc_copy(mgmt, len);
1800 os_get_reltime(&hapd->mesh_pending_auth_time);
c50d94f1 1801 return;
38cb0a2d 1802 }
c50d94f1 1803#endif /* CONFIG_MESH */
38cb0a2d 1804
c50d94f1
BC
1805 sta = ap_sta_add(hapd, mgmt->sa);
1806 if (!sta) {
1807 resp = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
1808 goto fail;
1809 }
6fc6879b 1810 }
38cb0a2d
IP
1811 sta->last_seq_ctrl = seq_ctrl;
1812 sta->last_subtype = WLAN_FC_STYPE_AUTH;
6fc6879b 1813
53d17144
DL
1814 res = ieee802_11_set_radius_info(
1815 hapd, sta, res, session_timeout, acct_interim_interval,
1816 &vlan_id, &psk, &identity, &radius_cui);
1817 if (res) {
8be640b7
MB
1818 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1819 goto fail;
6fc6879b 1820 }
2092597f 1821
6fc6879b
JM
1822 sta->flags &= ~WLAN_STA_PREAUTH;
1823 ieee802_1x_notify_pre_auth(sta->eapol_sm, 0);
1824
bb598c3b
AB
1825 /*
1826 * If the driver supports full AP client state, add a station to the
1827 * driver before sending authentication reply to make sure the driver
1828 * has resources, and not to go through the entire authentication and
1829 * association handshake, and fail it at the end.
1830 *
1831 * If this is not the first transaction, in a multi-step authentication
1832 * algorithm, the station already exists in the driver
1833 * (sta->added_unassoc = 1) so skip it.
1834 *
1835 * In mesh mode, the station was already added to the driver when the
1836 * NEW_PEER_CANDIDATE event is received.
2ab09656
JM
1837 *
1838 * If PMF was negotiated for the existing association, skip this to
1839 * avoid dropping the STA entry and the associated keys. This is needed
1840 * to allow the original connection work until the attempt can complete
1841 * (re)association, so that unprotected Authentication frame cannot be
1842 * used to bypass PMF protection.
bb598c3b
AB
1843 */
1844 if (FULL_AP_CLIENT_STATE_SUPP(hapd->iface->drv_flags) &&
2ab09656 1845 (!(sta->flags & WLAN_STA_MFP) || !ap_sta_is_authorized(sta)) &&
bb598c3b
AB
1846 !(hapd->conf->mesh & MESH_ENABLED) &&
1847 !(sta->added_unassoc)) {
1848 /*
1849 * If a station that is already associated to the AP, is trying
1850 * to authenticate again, remove the STA entry, in order to make
1851 * sure the STA PS state gets cleared and configuration gets
1852 * updated. To handle this, station's added_unassoc flag is
1853 * cleared once the station has completed association.
1854 */
1855 hostapd_drv_sta_remove(hapd, sta->addr);
1856 sta->flags &= ~(WLAN_STA_ASSOC | WLAN_STA_AUTH |
1857 WLAN_STA_AUTHORIZED);
1858
468b7b12 1859 if (hostapd_sta_add(hapd, sta->addr, 0, 0, NULL, 0, 0,
ae33239c 1860 NULL, NULL, sta->flags, 0, 0, 0, 0)) {
bb598c3b
AB
1861 hostapd_logger(hapd, sta->addr,
1862 HOSTAPD_MODULE_IEEE80211,
1863 HOSTAPD_LEVEL_NOTICE,
1864 "Could not add STA to kernel driver");
1865 resp = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
1866 goto fail;
1867 }
1868
1869 sta->added_unassoc = 1;
1870 }
1871
6fc6879b
JM
1872 switch (auth_alg) {
1873 case WLAN_AUTH_OPEN:
1874 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
1875 HOSTAPD_LEVEL_DEBUG,
1876 "authentication OK (open system)");
6fc6879b
JM
1877 sta->flags |= WLAN_STA_AUTH;
1878 wpa_auth_sm_event(sta->wpa_sm, WPA_AUTH);
1879 sta->auth_alg = WLAN_AUTH_OPEN;
1880 mlme_authenticate_indication(hapd, sta);
6fc6879b 1881 break;
7cb53ded 1882#ifndef CONFIG_NO_RC4
6fc6879b
JM
1883 case WLAN_AUTH_SHARED_KEY:
1884 resp = auth_shared_key(hapd, sta, auth_transaction, challenge,
1885 fc & WLAN_FC_ISWEP);
1886 sta->auth_alg = WLAN_AUTH_SHARED_KEY;
1887 mlme_authenticate_indication(hapd, sta);
1888 if (sta->challenge && auth_transaction == 1) {
1889 resp_ies[0] = WLAN_EID_CHALLENGE;
1890 resp_ies[1] = WLAN_AUTH_CHALLENGE_LEN;
1891 os_memcpy(resp_ies + 2, sta->challenge,
1892 WLAN_AUTH_CHALLENGE_LEN);
1893 resp_ies_len = 2 + WLAN_AUTH_CHALLENGE_LEN;
1894 }
1895 break;
7cb53ded 1896#endif /* CONFIG_NO_RC4 */
4ec1fd8e 1897#ifdef CONFIG_IEEE80211R_AP
6fc6879b
JM
1898 case WLAN_AUTH_FT:
1899 sta->auth_alg = WLAN_AUTH_FT;
1900 if (sta->wpa_sm == NULL)
1901 sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth,
94ddef3e 1902 sta->addr, NULL);
6fc6879b
JM
1903 if (sta->wpa_sm == NULL) {
1904 wpa_printf(MSG_DEBUG, "FT: Failed to initialize WPA "
1905 "state machine");
1906 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1907 goto fail;
1908 }
1909 wpa_ft_process_auth(sta->wpa_sm, mgmt->bssid,
1910 auth_transaction, mgmt->u.auth.variable,
1911 len - IEEE80211_HDRLEN -
1912 sizeof(mgmt->u.auth),
1913 handle_auth_ft_finish, hapd);
1914 /* handle_auth_ft_finish() callback will complete auth. */
1915 return;
4ec1fd8e 1916#endif /* CONFIG_IEEE80211R_AP */
c10347f2
JM
1917#ifdef CONFIG_SAE
1918 case WLAN_AUTH_SAE:
c50d94f1 1919#ifdef CONFIG_MESH
afa2ffb4
JM
1920 if (status_code == WLAN_STATUS_SUCCESS &&
1921 hapd->conf->mesh & MESH_ENABLED) {
c50d94f1
BC
1922 if (sta->wpa_sm == NULL)
1923 sta->wpa_sm =
1924 wpa_auth_sta_init(hapd->wpa_auth,
1925 sta->addr, NULL);
1926 if (sta->wpa_sm == NULL) {
1927 wpa_printf(MSG_DEBUG,
1928 "SAE: Failed to initialize WPA state machine");
1929 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1930 goto fail;
1931 }
1932 }
1933#endif /* CONFIG_MESH */
afa2ffb4
JM
1934 handle_auth_sae(hapd, sta, mgmt, len, auth_transaction,
1935 status_code);
c10347f2
JM
1936 return;
1937#endif /* CONFIG_SAE */
c4fd6d8a
JM
1938#ifdef CONFIG_FILS
1939 case WLAN_AUTH_FILS_SK:
1764559e 1940 case WLAN_AUTH_FILS_SK_PFS:
b8a3453a
JM
1941 handle_auth_fils(hapd, sta, mgmt->u.auth.variable,
1942 len - IEEE80211_HDRLEN - sizeof(mgmt->u.auth),
5cee22ca
JM
1943 auth_alg, auth_transaction, status_code,
1944 handle_auth_fils_finish);
c4fd6d8a
JM
1945 return;
1946#endif /* CONFIG_FILS */
6fc6879b
JM
1947 }
1948
1949 fail:
2092597f
MB
1950 os_free(identity);
1951 os_free(radius_cui);
f2a14be7 1952 hostapd_free_psk_list(psk);
2092597f 1953
bb598c3b
AB
1954 reply_res = send_auth_reply(hapd, mgmt->sa, mgmt->bssid, auth_alg,
1955 auth_transaction + 1, resp, resp_ies,
1956 resp_ies_len);
1957
1958 if (sta && sta->added_unassoc && (resp != WLAN_STATUS_SUCCESS ||
1959 reply_res != WLAN_STATUS_SUCCESS)) {
1960 hostapd_drv_sta_remove(hapd, sta->addr);
1961 sta->added_unassoc = 0;
1962 }
6fc6879b
JM
1963}
1964
1965
681753f2 1966int hostapd_get_aid(struct hostapd_data *hapd, struct sta_info *sta)
d42a62b3 1967{
2991469c
JM
1968 int i, j = 32, aid;
1969
d42a62b3
JM
1970 /* get a unique AID */
1971 if (sta->aid > 0) {
1972 wpa_printf(MSG_DEBUG, " old AID %d", sta->aid);
1973 return 0;
1974 }
1975
d7358113
JM
1976 if (TEST_FAIL())
1977 return -1;
1978
2991469c
JM
1979 for (i = 0; i < AID_WORDS; i++) {
1980 if (hapd->sta_aid[i] == (u32) -1)
1981 continue;
1982 for (j = 0; j < 32; j++) {
1983 if (!(hapd->sta_aid[i] & BIT(j)))
1984 break;
1985 }
1986 if (j < 32)
d42a62b3 1987 break;
d42a62b3 1988 }
2991469c
JM
1989 if (j == 32)
1990 return -1;
1991 aid = i * 32 + j + 1;
1992 if (aid > 2007)
1993 return -1;
d42a62b3 1994
2991469c
JM
1995 sta->aid = aid;
1996 hapd->sta_aid[i] |= BIT(j);
d42a62b3
JM
1997 wpa_printf(MSG_DEBUG, " new AID %d", sta->aid);
1998 return 0;
1999}
2000
2001
5586f500
JM
2002static u16 check_ssid(struct hostapd_data *hapd, struct sta_info *sta,
2003 const u8 *ssid_ie, size_t ssid_ie_len)
6fc6879b 2004{
5586f500
JM
2005 if (ssid_ie == NULL)
2006 return WLAN_STATUS_UNSPECIFIED_FAILURE;
6fc6879b 2007
5586f500
JM
2008 if (ssid_ie_len != hapd->conf->ssid.ssid_len ||
2009 os_memcmp(ssid_ie, hapd->conf->ssid.ssid, ssid_ie_len) != 0) {
5586f500
JM
2010 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
2011 HOSTAPD_LEVEL_INFO,
2012 "Station tried to associate with unknown SSID "
b37d582e 2013 "'%s'", wpa_ssid_txt(ssid_ie, ssid_ie_len));
5586f500 2014 return WLAN_STATUS_UNSPECIFIED_FAILURE;
b0194fe0
JM
2015 }
2016
5586f500
JM
2017 return WLAN_STATUS_SUCCESS;
2018}
6fc6879b 2019
6fc6879b 2020
5586f500
JM
2021static u16 check_wmm(struct hostapd_data *hapd, struct sta_info *sta,
2022 const u8 *wmm_ie, size_t wmm_ie_len)
2023{
3ae0800c 2024 sta->flags &= ~WLAN_STA_WMM;
5d061637 2025 sta->qosinfo = 0;
5586f500 2026 if (wmm_ie && hapd->conf->wmm_enabled) {
5f32f79c 2027 struct wmm_information_element *wmm;
5f32f79c 2028
c84b868a 2029 if (!hostapd_eid_wmm_valid(hapd, wmm_ie, wmm_ie_len)) {
6fc6879b
JM
2030 hostapd_logger(hapd, sta->addr,
2031 HOSTAPD_MODULE_WPA,
2032 HOSTAPD_LEVEL_DEBUG,
3ae0800c 2033 "invalid WMM element in association "
6fc6879b 2034 "request");
5f32f79c
EP
2035 return WLAN_STATUS_UNSPECIFIED_FAILURE;
2036 }
2037
2038 sta->flags |= WLAN_STA_WMM;
2039 wmm = (struct wmm_information_element *) wmm_ie;
5d061637 2040 sta->qosinfo = wmm->qos_info;
6fc6879b 2041 }
5586f500
JM
2042 return WLAN_STATUS_SUCCESS;
2043}
6fc6879b 2044
5586f500
JM
2045
2046static u16 copy_supp_rates(struct hostapd_data *hapd, struct sta_info *sta,
2047 struct ieee802_11_elems *elems)
2048{
0c4b9025
DL
2049 /* Supported rates not used in IEEE 802.11ad/DMG */
2050 if (hapd->iface->current_mode &&
2051 hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211AD)
2052 return WLAN_STATUS_SUCCESS;
2053
5586f500
JM
2054 if (!elems->supp_rates) {
2055 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
6fc6879b
JM
2056 HOSTAPD_LEVEL_DEBUG,
2057 "No supported rates element in AssocReq");
5586f500 2058 return WLAN_STATUS_UNSPECIFIED_FAILURE;
6fc6879b
JM
2059 }
2060
3489cfb0
JM
2061 if (elems->supp_rates_len + elems->ext_supp_rates_len >
2062 sizeof(sta->supported_rates)) {
5586f500 2063 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
6fc6879b 2064 HOSTAPD_LEVEL_DEBUG,
3489cfb0
JM
2065 "Invalid supported rates element length %d+%d",
2066 elems->supp_rates_len,
2067 elems->ext_supp_rates_len);
5586f500 2068 return WLAN_STATUS_UNSPECIFIED_FAILURE;
6fc6879b
JM
2069 }
2070
3489cfb0
JM
2071 sta->supported_rates_len = merge_byte_arrays(
2072 sta->supported_rates, sizeof(sta->supported_rates),
2073 elems->supp_rates, elems->supp_rates_len,
2074 elems->ext_supp_rates, elems->ext_supp_rates_len);
6fc6879b 2075
5586f500
JM
2076 return WLAN_STATUS_SUCCESS;
2077}
2078
2079
c551700f
KP
2080static u16 check_ext_capab(struct hostapd_data *hapd, struct sta_info *sta,
2081 const u8 *ext_capab_ie, size_t ext_capab_ie_len)
2082{
2083#ifdef CONFIG_INTERWORKING
2084 /* check for QoS Map support */
2085 if (ext_capab_ie_len >= 5) {
2086 if (ext_capab_ie[4] & 0x01)
2087 sta->qos_map_enabled = 1;
2088 }
2089#endif /* CONFIG_INTERWORKING */
2090
98b05081
AO
2091 if (ext_capab_ie_len > 0)
2092 sta->ecsa_supported = !!(ext_capab_ie[0] & BIT(2));
2093
c551700f
KP
2094 return WLAN_STATUS_SUCCESS;
2095}
2096
2097
09368515
JM
2098#ifdef CONFIG_OWE
2099static u16 owe_process_assoc_req(struct sta_info *sta, const u8 *owe_dh,
2100 u8 owe_dh_len)
2101{
2102 struct wpabuf *secret, *pub, *hkey;
2103 int res;
2104 u8 prk[SHA256_MAC_LEN], pmkid[SHA256_MAC_LEN];
2105 const char *info = "OWE Key Generation";
2106 const u8 *addr[2];
2107 size_t len[2];
2108
2109 if (WPA_GET_LE16(owe_dh) != OWE_DH_GROUP)
2110 return WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED;
2111
2112 crypto_ecdh_deinit(sta->owe_ecdh);
2113 sta->owe_ecdh = crypto_ecdh_init(OWE_DH_GROUP);
2114 if (!sta->owe_ecdh)
2115 return WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED;
2116
2117 secret = crypto_ecdh_set_peerkey(sta->owe_ecdh, 0, owe_dh + 2,
2118 owe_dh_len - 2);
2119 if (!secret) {
2120 wpa_printf(MSG_DEBUG, "OWE: Invalid peer DH public key");
2121 return WLAN_STATUS_UNSPECIFIED_FAILURE;
2122 }
2123 wpa_hexdump_buf_key(MSG_DEBUG, "OWE: DH shared secret", secret);
2124
2125 /* prk = HKDF-extract(C | A | group, z) */
2126
2127 pub = crypto_ecdh_get_pubkey(sta->owe_ecdh, 0);
2128 if (!pub) {
2129 wpabuf_clear_free(secret);
2130 return WLAN_STATUS_UNSPECIFIED_FAILURE;
2131 }
2132
2133 /* PMKID = Truncate-128(Hash(C | A)) */
2134 addr[0] = owe_dh + 2;
2135 len[0] = owe_dh_len - 2;
2136 addr[1] = wpabuf_head(pub);
2137 len[1] = wpabuf_len(pub);
2138 res = sha256_vector(2, addr, len, pmkid);
2139 if (res < 0) {
2140 wpabuf_free(pub);
2141 wpabuf_clear_free(secret);
2142 return WLAN_STATUS_UNSPECIFIED_FAILURE;
2143 }
2144
2145 hkey = wpabuf_alloc(owe_dh_len - 2 + wpabuf_len(pub) + 2);
2146 if (!hkey) {
2147 wpabuf_free(pub);
2148 wpabuf_clear_free(secret);
2149 return WLAN_STATUS_UNSPECIFIED_FAILURE;
2150 }
2151
2152 wpabuf_put_data(hkey, owe_dh + 2, owe_dh_len - 2); /* C */
2153 wpabuf_put_buf(hkey, pub); /* A */
2154 wpabuf_free(pub);
2155 wpabuf_put_le16(hkey, OWE_DH_GROUP); /* group */
2156 res = hmac_sha256(wpabuf_head(hkey), wpabuf_len(hkey),
2157 wpabuf_head(secret), wpabuf_len(secret), prk);
2158 wpabuf_clear_free(hkey);
2159 wpabuf_clear_free(secret);
2160 if (res < 0)
2161 return WLAN_STATUS_UNSPECIFIED_FAILURE;
2162
2163 wpa_hexdump_key(MSG_DEBUG, "OWE: prk", prk, SHA256_MAC_LEN);
2164
2165 /* PMK = HKDF-expand(prk, "OWE Key Generation", n) */
2166
2167 os_free(sta->owe_pmk);
2168 sta->owe_pmk = os_malloc(PMK_LEN);
2169 if (!sta->owe_pmk) {
2170 os_memset(prk, 0, SHA256_MAC_LEN);
2171 return WLAN_STATUS_UNSPECIFIED_FAILURE;
2172 }
2173
2174 res = hmac_sha256_kdf(prk, SHA256_MAC_LEN, NULL, (const u8 *) info,
2175 os_strlen(info), sta->owe_pmk, PMK_LEN);
2176 os_memset(prk, 0, SHA256_MAC_LEN);
2177 if (res < 0) {
2178 os_free(sta->owe_pmk);
2179 sta->owe_pmk = NULL;
2180 return WLAN_STATUS_UNSPECIFIED_FAILURE;
2181 }
2182
2183 wpa_hexdump_key(MSG_DEBUG, "OWE: PMK", sta->owe_pmk, PMK_LEN);
2184 wpa_hexdump(MSG_DEBUG, "OWE: PMKID", pmkid, PMKID_LEN);
2185 /* TODO: Add PMKSA cache entry */
2186
2187 return WLAN_STATUS_SUCCESS;
2188}
2189#endif /* CONFIG_OWE */
2190
2191
5586f500 2192static u16 check_assoc_ies(struct hostapd_data *hapd, struct sta_info *sta,
b57e086c 2193 const u8 *ies, size_t ies_len, int reassoc)
5586f500
JM
2194{
2195 struct ieee802_11_elems elems;
2196 u16 resp;
ba091c06 2197 const u8 *wpa_ie;
5586f500 2198 size_t wpa_ie_len;
94ddef3e 2199 const u8 *p2p_dev_addr = NULL;
5586f500
JM
2200
2201 if (ieee802_11_parse_elems(ies, ies_len, &elems, 1) == ParseFailed) {
2202 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
2203 HOSTAPD_LEVEL_INFO, "Station sent an invalid "
2204 "association request");
2205 return WLAN_STATUS_UNSPECIFIED_FAILURE;
2206 }
2207
2208 resp = check_ssid(hapd, sta, elems.ssid, elems.ssid_len);
2209 if (resp != WLAN_STATUS_SUCCESS)
2210 return resp;
2211 resp = check_wmm(hapd, sta, elems.wmm, elems.wmm_len);
c551700f
KP
2212 if (resp != WLAN_STATUS_SUCCESS)
2213 return resp;
2214 resp = check_ext_capab(hapd, sta, elems.ext_capab, elems.ext_capab_len);
5586f500
JM
2215 if (resp != WLAN_STATUS_SUCCESS)
2216 return resp;
2217 resp = copy_supp_rates(hapd, sta, &elems);
2218 if (resp != WLAN_STATUS_SUCCESS)
2219 return resp;
d45354be 2220#ifdef CONFIG_IEEE80211N
baae4cb9 2221 resp = copy_sta_ht_capab(hapd, sta, elems.ht_capabilities);
5586f500
JM
2222 if (resp != WLAN_STATUS_SUCCESS)
2223 return resp;
29448243
JM
2224 if (hapd->iconf->ieee80211n && hapd->iconf->require_ht &&
2225 !(sta->flags & WLAN_STA_HT)) {
2226 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
2227 HOSTAPD_LEVEL_INFO, "Station does not support "
2228 "mandatory HT PHY - reject association");
2229 return WLAN_STATUS_ASSOC_DENIED_NO_HT;
2230 }
d45354be 2231#endif /* CONFIG_IEEE80211N */
5586f500 2232
de3cdf35 2233#ifdef CONFIG_IEEE80211AC
28ffd21c
ARN
2234 if (hapd->iconf->ieee80211ac) {
2235 resp = copy_sta_vht_capab(hapd, sta, elems.vht_capabilities);
2236 if (resp != WLAN_STATUS_SUCCESS)
2237 return resp;
8a458116 2238
28ffd21c
ARN
2239 resp = set_sta_vht_opmode(hapd, sta, elems.vht_opmode_notif);
2240 if (resp != WLAN_STATUS_SUCCESS)
2241 return resp;
2242 }
8a458116 2243
140e850a
MP
2244 if (hapd->iconf->ieee80211ac && hapd->iconf->require_vht &&
2245 !(sta->flags & WLAN_STA_VHT)) {
2246 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
2247 HOSTAPD_LEVEL_INFO, "Station does not support "
2248 "mandatory VHT PHY - reject association");
13b24a76 2249 return WLAN_STATUS_ASSOC_DENIED_NO_VHT;
140e850a 2250 }
e7d0e97b
YL
2251
2252 if (hapd->conf->vendor_vht && !elems.vht_capabilities) {
2253 resp = copy_sta_vendor_vht(hapd, sta, elems.vendor_vht,
2254 elems.vendor_vht_len);
2255 if (resp != WLAN_STATUS_SUCCESS)
2256 return resp;
2257 }
de3cdf35
MP
2258#endif /* CONFIG_IEEE80211AC */
2259
94ddef3e
JM
2260#ifdef CONFIG_P2P
2261 if (elems.p2p) {
2262 wpabuf_free(sta->p2p_ie);
2263 sta->p2p_ie = ieee802_11_vendor_ie_concat(ies, ies_len,
2264 P2P_IE_VENDOR_TYPE);
2265 if (sta->p2p_ie)
2266 p2p_dev_addr = p2p_get_go_dev_addr(sta->p2p_ie);
2267 } else {
2268 wpabuf_free(sta->p2p_ie);
2269 sta->p2p_ie = NULL;
2270 }
2271#endif /* CONFIG_P2P */
2272
6fc6879b
JM
2273 if ((hapd->conf->wpa & WPA_PROTO_RSN) && elems.rsn_ie) {
2274 wpa_ie = elems.rsn_ie;
2275 wpa_ie_len = elems.rsn_ie_len;
2276 } else if ((hapd->conf->wpa & WPA_PROTO_WPA) &&
2277 elems.wpa_ie) {
2278 wpa_ie = elems.wpa_ie;
2279 wpa_ie_len = elems.wpa_ie_len;
2280 } else {
2281 wpa_ie = NULL;
2282 wpa_ie_len = 0;
2283 }
5586f500 2284
ad08c363 2285#ifdef CONFIG_WPS
17f6b900 2286 sta->flags &= ~(WLAN_STA_WPS | WLAN_STA_MAYBE_WPS | WLAN_STA_WPS2);
c47cf42e
JM
2287 if (hapd->conf->wps_state && elems.wps_ie) {
2288 wpa_printf(MSG_DEBUG, "STA included WPS IE in (Re)Association "
2289 "Request - assume WPS is used");
2290 sta->flags |= WLAN_STA_WPS;
2291 wpabuf_free(sta->wps_ie);
16e46ec0
JM
2292 sta->wps_ie = ieee802_11_vendor_ie_concat(ies, ies_len,
2293 WPS_IE_VENDOR_TYPE);
17f6b900
JM
2294 if (sta->wps_ie && wps_is_20(sta->wps_ie)) {
2295 wpa_printf(MSG_DEBUG, "WPS: STA supports WPS 2.0");
2296 sta->flags |= WLAN_STA_WPS2;
2297 }
c47cf42e
JM
2298 wpa_ie = NULL;
2299 wpa_ie_len = 0;
54f489be
JM
2300 if (sta->wps_ie && wps_validate_assoc_req(sta->wps_ie) < 0) {
2301 wpa_printf(MSG_DEBUG, "WPS: Invalid WPS IE in "
2302 "(Re)Association Request - reject");
2303 return WLAN_STATUS_INVALID_IE;
2304 }
c47cf42e
JM
2305 } else if (hapd->conf->wps_state && wpa_ie == NULL) {
2306 wpa_printf(MSG_DEBUG, "STA did not include WPA/RSN IE in "
2307 "(Re)Association Request - possible WPS use");
2308 sta->flags |= WLAN_STA_MAYBE_WPS;
ad08c363
JM
2309 } else
2310#endif /* CONFIG_WPS */
6fc6879b 2311 if (hapd->conf->wpa && wpa_ie == NULL) {
5586f500
JM
2312 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
2313 HOSTAPD_LEVEL_INFO,
2314 "No WPA/RSN IE in association request");
2315 return WLAN_STATUS_INVALID_IE;
6fc6879b
JM
2316 }
2317
2318 if (hapd->conf->wpa && wpa_ie) {
2319 int res;
2320 wpa_ie -= 2;
2321 wpa_ie_len += 2;
2322 if (sta->wpa_sm == NULL)
2323 sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth,
94ddef3e
JM
2324 sta->addr,
2325 p2p_dev_addr);
6fc6879b 2326 if (sta->wpa_sm == NULL) {
5586f500
JM
2327 wpa_printf(MSG_WARNING, "Failed to initialize WPA "
2328 "state machine");
2329 return WLAN_STATUS_UNSPECIFIED_FAILURE;
6fc6879b
JM
2330 }
2331 res = wpa_validate_wpa_ie(hapd->wpa_auth, sta->wpa_sm,
2332 wpa_ie, wpa_ie_len,
09368515
JM
2333 elems.mdie, elems.mdie_len,
2334 elems.owe_dh, elems.owe_dh_len);
ffb62f22 2335 resp = wpa_res_to_status_code(res);
6fc6879b 2336 if (resp != WLAN_STATUS_SUCCESS)
5586f500 2337 return resp;
f3f7540e 2338#ifdef CONFIG_IEEE80211W
45c94154
JM
2339 if ((sta->flags & WLAN_STA_MFP) && !sta->sa_query_timed_out &&
2340 sta->sa_query_count > 0)
2341 ap_check_sa_query_timeout(hapd, sta);
8f4617c6
JM
2342 if ((sta->flags & WLAN_STA_MFP) && !sta->sa_query_timed_out &&
2343 (!reassoc || sta->auth_alg != WLAN_AUTH_FT)) {
5d22a1d5 2344 /*
93b76319
JM
2345 * STA has already been associated with MFP and SA
2346 * Query timeout has not been reached. Reject the
2347 * association attempt temporarily and start SA Query,
2348 * if one is not pending.
5d22a1d5
JM
2349 */
2350
93b76319
JM
2351 if (sta->sa_query_count == 0)
2352 ap_sta_start_sa_query(hapd, sta);
5d22a1d5 2353
5586f500 2354 return WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY;
5d22a1d5
JM
2355 }
2356
f3f7540e
JM
2357 if (wpa_auth_uses_mfp(sta->wpa_sm))
2358 sta->flags |= WLAN_STA_MFP;
2359 else
2360 sta->flags &= ~WLAN_STA_MFP;
2361#endif /* CONFIG_IEEE80211W */
6fc6879b 2362
4ec1fd8e 2363#ifdef CONFIG_IEEE80211R_AP
6fc6879b
JM
2364 if (sta->auth_alg == WLAN_AUTH_FT) {
2365 if (!reassoc) {
2366 wpa_printf(MSG_DEBUG, "FT: " MACSTR " tried "
2367 "to use association (not "
2368 "re-association) with FT auth_alg",
2369 MAC2STR(sta->addr));
5586f500 2370 return WLAN_STATUS_UNSPECIFIED_FAILURE;
6fc6879b
JM
2371 }
2372
5586f500
JM
2373 resp = wpa_ft_validate_reassoc(sta->wpa_sm, ies,
2374 ies_len);
6fc6879b 2375 if (resp != WLAN_STATUS_SUCCESS)
5586f500 2376 return resp;
6fc6879b 2377 }
4ec1fd8e 2378#endif /* CONFIG_IEEE80211R_AP */
5586f500 2379
c10347f2
JM
2380#ifdef CONFIG_SAE
2381 if (wpa_auth_uses_sae(sta->wpa_sm) &&
f2991170
JM
2382 sta->auth_alg == WLAN_AUTH_OPEN) {
2383 struct rsn_pmksa_cache_entry *sa;
2384 sa = wpa_auth_sta_get_pmksa(sta->wpa_sm);
2385 if (!sa || sa->akmp != WPA_KEY_MGMT_SAE) {
2386 wpa_printf(MSG_DEBUG,
2387 "SAE: No PMKSA cache entry found for "
2388 MACSTR, MAC2STR(sta->addr));
2389 return WLAN_STATUS_INVALID_PMKID;
2390 }
2391 wpa_printf(MSG_DEBUG, "SAE: " MACSTR
2392 " using PMKSA caching", MAC2STR(sta->addr));
2393 } else if (wpa_auth_uses_sae(sta->wpa_sm) &&
2394 sta->auth_alg != WLAN_AUTH_SAE &&
2395 !(sta->auth_alg == WLAN_AUTH_FT &&
2396 wpa_auth_uses_ft_sae(sta->wpa_sm))) {
c10347f2
JM
2397 wpa_printf(MSG_DEBUG, "SAE: " MACSTR " tried to use "
2398 "SAE AKM after non-SAE auth_alg %u",
2399 MAC2STR(sta->addr), sta->auth_alg);
2400 return WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG;
2401 }
2402#endif /* CONFIG_SAE */
2403
09368515
JM
2404#ifdef CONFIG_OWE
2405 if ((hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_OWE) &&
2406 wpa_auth_sta_key_mgmt(sta->wpa_sm) == WPA_KEY_MGMT_OWE &&
2407 elems.owe_dh) {
2408 resp = owe_process_assoc_req(sta, elems.owe_dh,
2409 elems.owe_dh_len);
2410 if (resp != WLAN_STATUS_SUCCESS)
2411 return resp;
2412 }
2413#endif /* CONFIG_OWE */
2414
ff36ff00 2415#ifdef CONFIG_IEEE80211N
f0c7a986 2416 if ((sta->flags & (WLAN_STA_HT | WLAN_STA_VHT)) &&
ff36ff00 2417 wpa_auth_get_pairwise(sta->wpa_sm) == WPA_CIPHER_TKIP) {
5586f500
JM
2418 hostapd_logger(hapd, sta->addr,
2419 HOSTAPD_MODULE_IEEE80211,
2420 HOSTAPD_LEVEL_INFO,
2421 "Station tried to use TKIP with HT "
2422 "association");
2423 return WLAN_STATUS_CIPHER_REJECTED_PER_POLICY;
ff36ff00
JM
2424 }
2425#endif /* CONFIG_IEEE80211N */
a14896e8
JM
2426#ifdef CONFIG_HS20
2427 } else if (hapd->conf->osen) {
2428 if (elems.osen == NULL) {
2429 hostapd_logger(
2430 hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
2431 HOSTAPD_LEVEL_INFO,
2432 "No HS 2.0 OSEN element in association request");
2433 return WLAN_STATUS_INVALID_IE;
2434 }
2435
2436 wpa_printf(MSG_DEBUG, "HS 2.0: OSEN association");
2437 if (sta->wpa_sm == NULL)
2438 sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth,
2439 sta->addr, NULL);
2440 if (sta->wpa_sm == NULL) {
2441 wpa_printf(MSG_WARNING, "Failed to initialize WPA "
2442 "state machine");
2443 return WLAN_STATUS_UNSPECIFIED_FAILURE;
2444 }
2445 if (wpa_validate_osen(hapd->wpa_auth, sta->wpa_sm,
2446 elems.osen - 2, elems.osen_len + 2) < 0)
2447 return WLAN_STATUS_INVALID_IE;
2448#endif /* CONFIG_HS20 */
a8d05fca
JM
2449 } else
2450 wpa_auth_sta_no_wpa(sta->wpa_sm);
6fc6879b 2451
b305c684 2452#ifdef CONFIG_P2P
3f4ce13f 2453 p2p_group_notif_assoc(hapd->p2p_group, sta->addr, ies, ies_len);
b305c684
JM
2454#endif /* CONFIG_P2P */
2455
f403dcd6
JM
2456#ifdef CONFIG_HS20
2457 wpabuf_free(sta->hs20_ie);
2458 if (elems.hs20 && elems.hs20_len > 4) {
2459 sta->hs20_ie = wpabuf_alloc_copy(elems.hs20 + 4,
2460 elems.hs20_len - 4);
2461 } else
2462 sta->hs20_ie = NULL;
2463#endif /* CONFIG_HS20 */
2464
ae667c08
AN
2465#ifdef CONFIG_FST
2466 wpabuf_free(sta->mb_ies);
2467 if (hapd->iface->fst)
2468 sta->mb_ies = mb_ies_by_info(&elems.mb_ies);
2469 else
2470 sta->mb_ies = NULL;
2471#endif /* CONFIG_FST */
2472
4c572281 2473#ifdef CONFIG_MBO
6332aaf3
JM
2474 mbo_ap_check_sta_assoc(hapd, sta, &elems);
2475
4c572281
JM
2476 if (hapd->conf->mbo_enabled && (hapd->conf->wpa & 2) &&
2477 elems.mbo && sta->cell_capa && !(sta->flags & WLAN_STA_MFP) &&
2478 hapd->conf->ieee80211w != NO_MGMT_FRAME_PROTECTION) {
2479 wpa_printf(MSG_INFO,
2480 "MBO: Reject WPA2 association without PMF");
2481 return WLAN_STATUS_UNSPECIFIED_FAILURE;
2482 }
2483#endif /* CONFIG_MBO */
2484
adf0478e
JM
2485 ap_copy_sta_supp_op_classes(sta, elems.supp_op_classes,
2486 elems.supp_op_classes_len);
2487
629e1804
DS
2488 if ((sta->capability & WLAN_CAPABILITY_RADIO_MEASUREMENT) &&
2489 elems.rrm_enabled &&
2490 elems.rrm_enabled_len >= sizeof(sta->rrm_enabled_capa))
2491 os_memcpy(sta->rrm_enabled_capa, elems.rrm_enabled,
2492 sizeof(sta->rrm_enabled_capa));
2493
5586f500
JM
2494 return WLAN_STATUS_SUCCESS;
2495}
2496
2497
2498static void send_deauth(struct hostapd_data *hapd, const u8 *addr,
2499 u16 reason_code)
2500{
2501 int send_len;
2502 struct ieee80211_mgmt reply;
2503
2504 os_memset(&reply, 0, sizeof(reply));
2505 reply.frame_control =
2506 IEEE80211_FC(WLAN_FC_TYPE_MGMT, WLAN_FC_STYPE_DEAUTH);
2507 os_memcpy(reply.da, addr, ETH_ALEN);
2508 os_memcpy(reply.sa, hapd->own_addr, ETH_ALEN);
2509 os_memcpy(reply.bssid, hapd->own_addr, ETH_ALEN);
2510
2511 send_len = IEEE80211_HDRLEN + sizeof(reply.u.deauth);
2512 reply.u.deauth.reason_code = host_to_le16(reason_code);
2513
8cfa3527 2514 if (hostapd_drv_send_mlme(hapd, &reply, send_len, 0) < 0)
5586f500
JM
2515 wpa_printf(MSG_INFO, "Failed to send deauth: %s",
2516 strerror(errno));
2517}
2518
2519
3f81ac07
AO
2520static int add_associated_sta(struct hostapd_data *hapd,
2521 struct sta_info *sta)
2522{
2523 struct ieee80211_ht_capabilities ht_cap;
2524 struct ieee80211_vht_capabilities vht_cap;
2525
2526 /*
2527 * Remove the STA entry to ensure the STA PS state gets cleared and
2528 * configuration gets updated. This is relevant for cases, such as
2529 * FT-over-the-DS, where a station re-associates back to the same AP but
2530 * skips the authentication flow, or if working with a driver that
2531 * does not support full AP client state.
2532 */
2533 if (!sta->added_unassoc)
2534 hostapd_drv_sta_remove(hapd, sta->addr);
2535
2536#ifdef CONFIG_IEEE80211N
2537 if (sta->flags & WLAN_STA_HT)
2538 hostapd_get_ht_capab(hapd, sta->ht_capabilities, &ht_cap);
2539#endif /* CONFIG_IEEE80211N */
2540#ifdef CONFIG_IEEE80211AC
2541 if (sta->flags & WLAN_STA_VHT)
2542 hostapd_get_vht_capab(hapd, sta->vht_capabilities, &vht_cap);
2543#endif /* CONFIG_IEEE80211AC */
2544
2545 /*
2546 * Add the station with forced WLAN_STA_ASSOC flag. The sta->flags
2547 * will be set when the ACK frame for the (Re)Association Response frame
2548 * is processed (TX status driver event).
2549 */
2550 if (hostapd_sta_add(hapd, sta->addr, sta->aid, sta->capability,
2551 sta->supported_rates, sta->supported_rates_len,
2552 sta->listen_interval,
2553 sta->flags & WLAN_STA_HT ? &ht_cap : NULL,
2554 sta->flags & WLAN_STA_VHT ? &vht_cap : NULL,
2555 sta->flags | WLAN_STA_ASSOC, sta->qosinfo,
ae33239c
AB
2556 sta->vht_opmode, sta->p2p_ie ? 1 : 0,
2557 sta->added_unassoc)) {
3f81ac07
AO
2558 hostapd_logger(hapd, sta->addr,
2559 HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_NOTICE,
2560 "Could not %s STA to kernel driver",
2561 sta->added_unassoc ? "set" : "add");
2562
2563 if (sta->added_unassoc) {
2564 hostapd_drv_sta_remove(hapd, sta->addr);
2565 sta->added_unassoc = 0;
2566 }
2567
2568 return -1;
2569 }
2570
2571 sta->added_unassoc = 0;
2572
2573 return 0;
2574}
2575
2576
bb598c3b 2577static u16 send_assoc_resp(struct hostapd_data *hapd, struct sta_info *sta,
05e5e615
DL
2578 const u8 *addr, u16 status_code, int reassoc,
2579 const u8 *ies, size_t ies_len)
5586f500
JM
2580{
2581 int send_len;
91d91abf
JM
2582 u8 *buf;
2583 size_t buflen;
5586f500
JM
2584 struct ieee80211_mgmt *reply;
2585 u8 *p;
91d91abf 2586 u16 res = WLAN_STATUS_SUCCESS;
5586f500 2587
91d91abf
JM
2588 buflen = sizeof(struct ieee80211_mgmt) + 1024;
2589#ifdef CONFIG_FILS
84bb12aa 2590 if (sta && sta->fils_hlp_resp)
91d91abf
JM
2591 buflen += wpabuf_len(sta->fils_hlp_resp);
2592#endif /* CONFIG_FILS */
09368515
JM
2593#ifdef CONFIG_OWE
2594 if (sta && (hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_OWE))
2595 buflen += 50;
2596#endif /* CONFIG_OWE */
91d91abf
JM
2597 buf = os_zalloc(buflen);
2598 if (!buf) {
2599 res = WLAN_STATUS_UNSPECIFIED_FAILURE;
2600 goto done;
2601 }
5586f500
JM
2602 reply = (struct ieee80211_mgmt *) buf;
2603 reply->frame_control =
2604 IEEE80211_FC(WLAN_FC_TYPE_MGMT,
2605 (reassoc ? WLAN_FC_STYPE_REASSOC_RESP :
2606 WLAN_FC_STYPE_ASSOC_RESP));
05e5e615 2607 os_memcpy(reply->da, addr, ETH_ALEN);
5586f500
JM
2608 os_memcpy(reply->sa, hapd->own_addr, ETH_ALEN);
2609 os_memcpy(reply->bssid, hapd->own_addr, ETH_ALEN);
2610
2611 send_len = IEEE80211_HDRLEN;
2612 send_len += sizeof(reply->u.assoc_resp);
2613 reply->u.assoc_resp.capab_info =
f41ded6f 2614 host_to_le16(hostapd_own_capab_info(hapd));
5586f500 2615 reply->u.assoc_resp.status_code = host_to_le16(status_code);
05e5e615
DL
2616
2617 reply->u.assoc_resp.aid = host_to_le16((sta ? sta->aid : 0) |
2618 BIT(14) | BIT(15));
5586f500
JM
2619 /* Supported rates */
2620 p = hostapd_eid_supp_rates(hapd, reply->u.assoc_resp.variable);
2621 /* Extended supported rates */
2622 p = hostapd_eid_ext_supp_rates(hapd, p);
5586f500 2623
4ec1fd8e 2624#ifdef CONFIG_IEEE80211R_AP
05e5e615 2625 if (sta && status_code == WLAN_STATUS_SUCCESS) {
5586f500
JM
2626 /* IEEE 802.11r: Mobility Domain Information, Fast BSS
2627 * Transition Information, RSN, [RIC Response] */
2628 p = wpa_sm_write_assoc_resp_ies(sta->wpa_sm, p,
91d91abf 2629 buf + buflen - p,
5586f500
JM
2630 sta->auth_alg, ies, ies_len);
2631 }
4ec1fd8e 2632#endif /* CONFIG_IEEE80211R_AP */
5586f500
JM
2633
2634#ifdef CONFIG_IEEE80211W
05e5e615 2635 if (sta && status_code == WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY)
5586f500
JM
2636 p = hostapd_eid_assoc_comeback_time(hapd, sta, p);
2637#endif /* CONFIG_IEEE80211W */
2638
1bc774a1
JM
2639#ifdef CONFIG_IEEE80211N
2640 p = hostapd_eid_ht_capabilities(hapd, p);
2641 p = hostapd_eid_ht_operation(hapd, p);
2642#endif /* CONFIG_IEEE80211N */
2643
14708b50 2644#ifdef CONFIG_IEEE80211AC
e7d0e97b 2645 if (hapd->iconf->ieee80211ac && !hapd->conf->disable_11ac) {
fc72a48a
T
2646 u32 nsts = 0, sta_nsts;
2647
05e5e615 2648 if (sta && hapd->conf->use_sta_nsts && sta->vht_capabilities) {
fc72a48a
T
2649 struct ieee80211_vht_capabilities *capa;
2650
2651 nsts = (hapd->iface->conf->vht_capab >>
2652 VHT_CAP_BEAMFORMEE_STS_OFFSET) & 7;
2653 capa = sta->vht_capabilities;
2654 sta_nsts = (le_to_host32(capa->vht_capabilities_info) >>
2655 VHT_CAP_BEAMFORMEE_STS_OFFSET) & 7;
2656
2657 if (nsts < sta_nsts)
2658 nsts = 0;
2659 else
2660 nsts = sta_nsts;
2661 }
2662 p = hostapd_eid_vht_capabilities(hapd, p, nsts);
e7d0e97b
YL
2663 p = hostapd_eid_vht_operation(hapd, p);
2664 }
14708b50
MP
2665#endif /* CONFIG_IEEE80211AC */
2666
1161ff1e 2667 p = hostapd_eid_ext_capab(hapd, p);
b6668734 2668 p = hostapd_eid_bss_max_idle_period(hapd, p);
05e5e615 2669 if (sta && sta->qos_map_enabled)
c551700f 2670 p = hostapd_eid_qos_map_set(hapd, p);
1161ff1e 2671
347827ff
AN
2672#ifdef CONFIG_FST
2673 if (hapd->iface->fst_ies) {
2674 os_memcpy(p, wpabuf_head(hapd->iface->fst_ies),
2675 wpabuf_len(hapd->iface->fst_ies));
2676 p += wpabuf_len(hapd->iface->fst_ies);
2677 }
2678#endif /* CONFIG_FST */
2679
e7d0e97b 2680#ifdef CONFIG_IEEE80211AC
05e5e615 2681 if (sta && hapd->conf->vendor_vht && (sta->flags & WLAN_STA_VENDOR_VHT))
e7d0e97b
YL
2682 p = hostapd_eid_vendor_vht(hapd, p);
2683#endif /* CONFIG_IEEE80211AC */
2684
05e5e615 2685 if (sta && (sta->flags & WLAN_STA_WMM))
1bc774a1
JM
2686 p = hostapd_eid_wmm(hapd, p);
2687
ed7a09f9 2688#ifdef CONFIG_WPS
05e5e615
DL
2689 if (sta &&
2690 ((sta->flags & WLAN_STA_WPS) ||
2691 ((sta->flags & WLAN_STA_MAYBE_WPS) && hapd->conf->wpa))) {
ed7a09f9
JM
2692 struct wpabuf *wps = wps_build_assoc_resp_ie();
2693 if (wps) {
2694 os_memcpy(p, wpabuf_head(wps), wpabuf_len(wps));
2695 p += wpabuf_len(wps);
2696 wpabuf_free(wps);
2697 }
2698 }
2699#endif /* CONFIG_WPS */
2700
8ccbe415 2701#ifdef CONFIG_P2P
05e5e615 2702 if (sta && sta->p2p_ie && hapd->p2p_group) {
8ccbe415
JM
2703 struct wpabuf *p2p_resp_ie;
2704 enum p2p_status_code status;
2705 switch (status_code) {
2706 case WLAN_STATUS_SUCCESS:
2707 status = P2P_SC_SUCCESS;
2708 break;
2709 case WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA:
2710 status = P2P_SC_FAIL_LIMIT_REACHED;
2711 break;
2712 default:
2713 status = P2P_SC_FAIL_INVALID_PARAMS;
2714 break;
2715 }
2716 p2p_resp_ie = p2p_group_assoc_resp_ie(hapd->p2p_group, status);
2717 if (p2p_resp_ie) {
2718 os_memcpy(p, wpabuf_head(p2p_resp_ie),
2719 wpabuf_len(p2p_resp_ie));
2720 p += wpabuf_len(p2p_resp_ie);
2721 wpabuf_free(p2p_resp_ie);
2722 }
2723 }
2724#endif /* CONFIG_P2P */
2725
962473c1
JM
2726#ifdef CONFIG_P2P_MANAGER
2727 if (hapd->conf->p2p & P2P_MANAGE)
2728 p = hostapd_eid_p2p_manage(hapd, p);
2729#endif /* CONFIG_P2P_MANAGER */
2730
91d91abf 2731 p = hostapd_eid_mbo(hapd, p, buf + buflen - p);
fb9a1c3e 2732
a9112270 2733 if (hapd->conf->assocresp_elements &&
91d91abf 2734 (size_t) (buf + buflen - p) >=
a9112270
BKB
2735 wpabuf_len(hapd->conf->assocresp_elements)) {
2736 os_memcpy(p, wpabuf_head(hapd->conf->assocresp_elements),
2737 wpabuf_len(hapd->conf->assocresp_elements));
2738 p += wpabuf_len(hapd->conf->assocresp_elements);
2739 }
2740
5586f500
JM
2741 send_len += p - reply->u.assoc_resp.variable;
2742
e73ffa09 2743#ifdef CONFIG_FILS
05e5e615
DL
2744 if (sta &&
2745 (sta->auth_alg == WLAN_AUTH_FILS_SK ||
e73ffa09
JM
2746 sta->auth_alg == WLAN_AUTH_FILS_SK_PFS ||
2747 sta->auth_alg == WLAN_AUTH_FILS_PK) &&
2748 status_code == WLAN_STATUS_SUCCESS) {
2749 struct ieee802_11_elems elems;
2750
2751 if (ieee802_11_parse_elems(ies, ies_len, &elems, 0) ==
91d91abf
JM
2752 ParseFailed || !elems.fils_session) {
2753 res = WLAN_STATUS_UNSPECIFIED_FAILURE;
2754 goto done;
2755 }
e73ffa09
JM
2756
2757 /* FILS Session */
2758 *p++ = WLAN_EID_EXTENSION; /* Element ID */
2759 *p++ = 1 + FILS_SESSION_LEN; /* Length */
2760 *p++ = WLAN_EID_EXT_FILS_SESSION; /* Element ID Extension */
2761 os_memcpy(p, elems.fils_session, FILS_SESSION_LEN);
2762 send_len += 2 + 1 + FILS_SESSION_LEN;
2763
2764 send_len = fils_encrypt_assoc(sta->wpa_sm, buf, send_len,
91d91abf
JM
2765 buflen, sta->fils_hlp_resp);
2766 if (send_len < 0) {
2767 res = WLAN_STATUS_UNSPECIFIED_FAILURE;
2768 goto done;
2769 }
e73ffa09
JM
2770 }
2771#endif /* CONFIG_FILS */
2772
09368515
JM
2773#ifdef CONFIG_OWE
2774 if ((hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_OWE) &&
2775 sta && sta->owe_ecdh &&
2776 wpa_auth_sta_key_mgmt(sta->wpa_sm) == WPA_KEY_MGMT_OWE) {
2777 struct wpabuf *pub;
2778
2779 pub = crypto_ecdh_get_pubkey(sta->owe_ecdh, 0);
2780 if (!pub) {
2781 res = WLAN_STATUS_UNSPECIFIED_FAILURE;
2782 goto done;
2783 }
2784 /* OWE Diffie-Hellman Parameter element */
2785 *p++ = WLAN_EID_EXTENSION; /* Element ID */
2786 *p++ = 1 + 2 + wpabuf_len(pub); /* Length */
2787 *p++ = WLAN_EID_EXT_OWE_DH_PARAM; /* Element ID Extension */
2788 WPA_PUT_LE16(p, OWE_DH_GROUP);
2789 p += 2;
2790 os_memcpy(p, wpabuf_head(pub), wpabuf_len(pub));
2791 p += wpabuf_len(pub);
2792 send_len += 3 + 2 + wpabuf_len(pub);
2793 wpabuf_free(pub);
2794 }
2795#endif /* CONFIG_OWE */
2796
bb598c3b 2797 if (hostapd_drv_send_mlme(hapd, reply, send_len, 0) < 0) {
5586f500
JM
2798 wpa_printf(MSG_INFO, "Failed to send assoc resp: %s",
2799 strerror(errno));
91d91abf 2800 res = WLAN_STATUS_UNSPECIFIED_FAILURE;
bb598c3b
AB
2801 }
2802
91d91abf
JM
2803done:
2804 os_free(buf);
2805 return res;
5586f500
JM
2806}
2807
2808
91d91abf
JM
2809#ifdef CONFIG_FILS
2810
2811void fils_hlp_finish_assoc(struct hostapd_data *hapd, struct sta_info *sta)
2812{
2813 u16 reply_res;
2814
2815 wpa_printf(MSG_DEBUG, "FILS: Finish association with " MACSTR,
2816 MAC2STR(sta->addr));
2817 eloop_cancel_timeout(fils_hlp_timeout, hapd, sta);
2818 if (!sta->fils_pending_assoc_req)
2819 return;
2820 reply_res = send_assoc_resp(hapd, sta, sta->addr, WLAN_STATUS_SUCCESS,
2821 sta->fils_pending_assoc_is_reassoc,
2822 sta->fils_pending_assoc_req,
2823 sta->fils_pending_assoc_req_len);
2824 os_free(sta->fils_pending_assoc_req);
2825 sta->fils_pending_assoc_req = NULL;
2826 sta->fils_pending_assoc_req_len = 0;
2827 wpabuf_free(sta->fils_hlp_resp);
2828 sta->fils_hlp_resp = NULL;
2829 wpabuf_free(sta->hlp_dhcp_discover);
2830 sta->hlp_dhcp_discover = NULL;
2831
2832 /*
2833 * Remove the station in case tranmission of a success response fails
2834 * (the STA was added associated to the driver) or if the station was
2835 * previously added unassociated.
2836 */
2837 if (reply_res != WLAN_STATUS_SUCCESS || sta->added_unassoc) {
2838 hostapd_drv_sta_remove(hapd, sta->addr);
2839 sta->added_unassoc = 0;
2840 }
2841}
2842
2843
2844void fils_hlp_timeout(void *eloop_ctx, void *eloop_data)
2845{
2846 struct hostapd_data *hapd = eloop_ctx;
2847 struct sta_info *sta = eloop_data;
2848
2849 wpa_printf(MSG_DEBUG,
2850 "FILS: HLP response timeout - continue with association response for "
2851 MACSTR, MAC2STR(sta->addr));
8b5ddda5
JM
2852 if (sta->fils_drv_assoc_finish)
2853 hostapd_notify_assoc_fils_finish(hapd, sta);
2854 else
2855 fils_hlp_finish_assoc(hapd, sta);
91d91abf
JM
2856}
2857
2858#endif /* CONFIG_FILS */
2859
2860
5586f500 2861static void handle_assoc(struct hostapd_data *hapd,
b57e086c
JM
2862 const struct ieee80211_mgmt *mgmt, size_t len,
2863 int reassoc)
5586f500 2864{
38cb0a2d 2865 u16 capab_info, listen_interval, seq_ctrl, fc;
bb598c3b 2866 u16 resp = WLAN_STATUS_SUCCESS, reply_res;
b57e086c 2867 const u8 *pos;
5586f500
JM
2868 int left, i;
2869 struct sta_info *sta;
78815f3d 2870 u8 *tmp = NULL;
53d17144
DL
2871 struct hostapd_sta_wpa_psk_short *psk = NULL;
2872 char *identity = NULL;
2873 char *radius_cui = NULL;
91d91abf
JM
2874#ifdef CONFIG_FILS
2875 int delay_assoc = 0;
2876#endif /* CONFIG_FILS */
5586f500
JM
2877
2878 if (len < IEEE80211_HDRLEN + (reassoc ? sizeof(mgmt->u.reassoc_req) :
2879 sizeof(mgmt->u.assoc_req))) {
61323e70
JM
2880 wpa_printf(MSG_INFO, "handle_assoc(reassoc=%d) - too short payload (len=%lu)",
2881 reassoc, (unsigned long) len);
5586f500
JM
2882 return;
2883 }
2884
c2aff6b1
JB
2885#ifdef CONFIG_TESTING_OPTIONS
2886 if (reassoc) {
06df2aa6 2887 if (hapd->iconf->ignore_reassoc_probability > 0.0 &&
c2aff6b1
JB
2888 drand48() < hapd->iconf->ignore_reassoc_probability) {
2889 wpa_printf(MSG_INFO,
2890 "TESTING: ignoring reassoc request from "
2891 MACSTR, MAC2STR(mgmt->sa));
2892 return;
2893 }
2894 } else {
06df2aa6 2895 if (hapd->iconf->ignore_assoc_probability > 0.0 &&
c2aff6b1
JB
2896 drand48() < hapd->iconf->ignore_assoc_probability) {
2897 wpa_printf(MSG_INFO,
2898 "TESTING: ignoring assoc request from "
2899 MACSTR, MAC2STR(mgmt->sa));
2900 return;
2901 }
2902 }
2903#endif /* CONFIG_TESTING_OPTIONS */
2904
38cb0a2d
IP
2905 fc = le_to_host16(mgmt->frame_control);
2906 seq_ctrl = le_to_host16(mgmt->seq_ctrl);
2907
5586f500
JM
2908 if (reassoc) {
2909 capab_info = le_to_host16(mgmt->u.reassoc_req.capab_info);
2910 listen_interval = le_to_host16(
2911 mgmt->u.reassoc_req.listen_interval);
2912 wpa_printf(MSG_DEBUG, "reassociation request: STA=" MACSTR
2913 " capab_info=0x%02x listen_interval=%d current_ap="
38cb0a2d 2914 MACSTR " seq_ctrl=0x%x%s",
5586f500 2915 MAC2STR(mgmt->sa), capab_info, listen_interval,
38cb0a2d
IP
2916 MAC2STR(mgmt->u.reassoc_req.current_ap),
2917 seq_ctrl, (fc & WLAN_FC_RETRY) ? " retry" : "");
5586f500
JM
2918 left = len - (IEEE80211_HDRLEN + sizeof(mgmt->u.reassoc_req));
2919 pos = mgmt->u.reassoc_req.variable;
2920 } else {
2921 capab_info = le_to_host16(mgmt->u.assoc_req.capab_info);
2922 listen_interval = le_to_host16(
2923 mgmt->u.assoc_req.listen_interval);
2924 wpa_printf(MSG_DEBUG, "association request: STA=" MACSTR
38cb0a2d
IP
2925 " capab_info=0x%02x listen_interval=%d "
2926 "seq_ctrl=0x%x%s",
2927 MAC2STR(mgmt->sa), capab_info, listen_interval,
2928 seq_ctrl, (fc & WLAN_FC_RETRY) ? " retry" : "");
5586f500
JM
2929 left = len - (IEEE80211_HDRLEN + sizeof(mgmt->u.assoc_req));
2930 pos = mgmt->u.assoc_req.variable;
2931 }
2932
2933 sta = ap_get_sta(hapd, mgmt->sa);
4ec1fd8e 2934#ifdef CONFIG_IEEE80211R_AP
5586f500
JM
2935 if (sta && sta->auth_alg == WLAN_AUTH_FT &&
2936 (sta->flags & WLAN_STA_AUTH) == 0) {
2937 wpa_printf(MSG_DEBUG, "FT: Allow STA " MACSTR " to associate "
2938 "prior to authentication since it is using "
2939 "over-the-DS FT", MAC2STR(mgmt->sa));
bb598c3b
AB
2940
2941 /*
2942 * Mark station as authenticated, to avoid adding station
2943 * entry in the driver as associated and not authenticated
2944 */
2945 sta->flags |= WLAN_STA_AUTH;
5586f500 2946 } else
4ec1fd8e 2947#endif /* CONFIG_IEEE80211R_AP */
5586f500 2948 if (sta == NULL || (sta->flags & WLAN_STA_AUTH) == 0) {
05e5e615
DL
2949 if (hapd->iface->current_mode &&
2950 hapd->iface->current_mode->mode ==
2951 HOSTAPD_MODE_IEEE80211AD) {
53d17144
DL
2952 int acl_res;
2953 u32 session_timeout, acct_interim_interval;
2954 struct vlan_description vlan_id;
2955
2956 acl_res = ieee802_11_allowed_address(
2957 hapd, mgmt->sa, (const u8 *) mgmt, len,
2958 &session_timeout, &acct_interim_interval,
2959 &vlan_id, &psk, &identity, &radius_cui);
2960 if (acl_res == HOSTAPD_ACL_REJECT) {
2961 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
2962 goto fail;
2963 }
2964 if (acl_res == HOSTAPD_ACL_PENDING)
2965 return;
2966
05e5e615
DL
2967 /* DMG/IEEE 802.11ad does not use authentication.
2968 * Allocate sta entry upon association. */
2969 sta = ap_sta_add(hapd, mgmt->sa);
2970 if (!sta) {
2971 hostapd_logger(hapd, mgmt->sa,
2972 HOSTAPD_MODULE_IEEE80211,
2973 HOSTAPD_LEVEL_INFO,
2974 "Failed to add STA");
2975 resp = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
2976 goto fail;
2977 }
2978
53d17144
DL
2979 acl_res = ieee802_11_set_radius_info(
2980 hapd, sta, acl_res, session_timeout,
2981 acct_interim_interval, &vlan_id, &psk,
2982 &identity, &radius_cui);
2983 if (acl_res) {
2984 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
2985 goto fail;
2986 }
2987
05e5e615
DL
2988 hostapd_logger(hapd, sta->addr,
2989 HOSTAPD_MODULE_IEEE80211,
2990 HOSTAPD_LEVEL_DEBUG,
2991 "Skip authentication for DMG/IEEE 802.11ad");
2992 sta->flags |= WLAN_STA_AUTH;
2993 wpa_auth_sm_event(sta->wpa_sm, WPA_AUTH);
2994 sta->auth_alg = WLAN_AUTH_OPEN;
2995 } else {
2996 hostapd_logger(hapd, mgmt->sa,
2997 HOSTAPD_MODULE_IEEE80211,
2998 HOSTAPD_LEVEL_INFO,
2999 "Station tried to associate before authentication (aid=%d flags=0x%x)",
3000 sta ? sta->aid : -1,
3001 sta ? sta->flags : 0);
3002 send_deauth(hapd, mgmt->sa,
3003 WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA);
3004 return;
3005 }
5586f500
JM
3006 }
3007
38cb0a2d
IP
3008 if ((fc & WLAN_FC_RETRY) &&
3009 sta->last_seq_ctrl != WLAN_INVALID_MGMT_SEQ &&
3010 sta->last_seq_ctrl == seq_ctrl &&
fa67debf
JM
3011 sta->last_subtype == (reassoc ? WLAN_FC_STYPE_REASSOC_REQ :
3012 WLAN_FC_STYPE_ASSOC_REQ)) {
38cb0a2d
IP
3013 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
3014 HOSTAPD_LEVEL_DEBUG,
3015 "Drop repeated association frame seq_ctrl=0x%x",
3016 seq_ctrl);
3017 return;
3018 }
3019 sta->last_seq_ctrl = seq_ctrl;
3020 sta->last_subtype = reassoc ? WLAN_FC_STYPE_REASSOC_REQ :
3021 WLAN_FC_STYPE_ASSOC_REQ;
3022
5586f500
JM
3023 if (hapd->tkip_countermeasures) {
3024 resp = WLAN_REASON_MICHAEL_MIC_FAILURE;
3025 goto fail;
3026 }
3027
3028 if (listen_interval > hapd->conf->max_listen_interval) {
3029 hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
3030 HOSTAPD_LEVEL_DEBUG,
3031 "Too large Listen Interval (%d)",
3032 listen_interval);
3033 resp = WLAN_STATUS_ASSOC_DENIED_LISTEN_INT_TOO_LARGE;
3034 goto fail;
3035 }
3036
fb9a1c3e
AS
3037#ifdef CONFIG_MBO
3038 if (hapd->conf->mbo_enabled && hapd->mbo_assoc_disallow) {
3039 resp = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
3040 goto fail;
3041 }
3042#endif /* CONFIG_MBO */
3043
629e1804
DS
3044 /*
3045 * sta->capability is used in check_assoc_ies() for RRM enabled
3046 * capability element.
3047 */
3048 sta->capability = capab_info;
3049
78815f3d
JM
3050#ifdef CONFIG_FILS
3051 if (sta->auth_alg == WLAN_AUTH_FILS_SK ||
3052 sta->auth_alg == WLAN_AUTH_FILS_SK_PFS ||
3053 sta->auth_alg == WLAN_AUTH_FILS_PK) {
3054 /* The end of the payload is encrypted. Need to decrypt it
3055 * before parsing. */
3056
a1f11e34 3057 tmp = os_memdup(pos, left);
78815f3d
JM
3058 if (!tmp) {
3059 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
3060 goto fail;
3061 }
78815f3d
JM
3062
3063 left = fils_decrypt_assoc(sta->wpa_sm, sta->fils_session, mgmt,
3064 len, tmp, left);
3065 if (left < 0) {
3066 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
3067 goto fail;
3068 }
3069 pos = tmp;
3070 }
3071#endif /* CONFIG_FILS */
3072
5586f500
JM
3073 /* followed by SSID and Supported rates; and HT capabilities if 802.11n
3074 * is used */
3075 resp = check_assoc_ies(hapd, sta, pos, left, reassoc);
3076 if (resp != WLAN_STATUS_SUCCESS)
3077 goto fail;
3078
3079 if (hostapd_get_aid(hapd, sta) < 0) {
3080 hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
3081 HOSTAPD_LEVEL_INFO, "No room for more AIDs");
3082 resp = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
3083 goto fail;
3084 }
3085
5586f500
JM
3086 sta->listen_interval = listen_interval;
3087
6fc6879b
JM
3088 if (hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G)
3089 sta->flags |= WLAN_STA_NONERP;
3090 for (i = 0; i < sta->supported_rates_len; i++) {
3091 if ((sta->supported_rates[i] & 0x7f) > 22) {
3092 sta->flags &= ~WLAN_STA_NONERP;
3093 break;
3094 }
3095 }
3096 if (sta->flags & WLAN_STA_NONERP && !sta->nonerp_set) {
3097 sta->nonerp_set = 1;
3098 hapd->iface->num_sta_non_erp++;
3099 if (hapd->iface->num_sta_non_erp == 1)
3100 ieee802_11_set_beacons(hapd->iface);
3101 }
3102
3103 if (!(sta->capability & WLAN_CAPABILITY_SHORT_SLOT_TIME) &&
3104 !sta->no_short_slot_time_set) {
3105 sta->no_short_slot_time_set = 1;
3106 hapd->iface->num_sta_no_short_slot_time++;
3107 if (hapd->iface->current_mode->mode ==
3108 HOSTAPD_MODE_IEEE80211G &&
3109 hapd->iface->num_sta_no_short_slot_time == 1)
3110 ieee802_11_set_beacons(hapd->iface);
3111 }
3112
3113 if (sta->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
3114 sta->flags |= WLAN_STA_SHORT_PREAMBLE;
3115 else
3116 sta->flags &= ~WLAN_STA_SHORT_PREAMBLE;
3117
3118 if (!(sta->capability & WLAN_CAPABILITY_SHORT_PREAMBLE) &&
3119 !sta->no_short_preamble_set) {
3120 sta->no_short_preamble_set = 1;
3121 hapd->iface->num_sta_no_short_preamble++;
3122 if (hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G
3123 && hapd->iface->num_sta_no_short_preamble == 1)
3124 ieee802_11_set_beacons(hapd->iface);
3125 }
3126
d45354be 3127#ifdef CONFIG_IEEE80211N
5586f500 3128 update_ht_state(hapd, sta);
d45354be 3129#endif /* CONFIG_IEEE80211N */
de9289c8 3130
6fc6879b
JM
3131 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
3132 HOSTAPD_LEVEL_DEBUG,
3133 "association OK (aid %d)", sta->aid);
3134 /* Station will be marked associated, after it acknowledges AssocResp
3135 */
b8281964 3136 sta->flags |= WLAN_STA_ASSOC_REQ_OK;
6fc6879b 3137
6f5c8dbd
JM
3138#ifdef CONFIG_IEEE80211W
3139 if ((sta->flags & WLAN_STA_MFP) && sta->sa_query_timed_out) {
3140 wpa_printf(MSG_DEBUG, "Allowing %sassociation after timed out "
3141 "SA Query procedure", reassoc ? "re" : "");
3142 /* TODO: Send a protected Disassociate frame to the STA using
3143 * the old key and Reason Code "Previous Authentication no
3144 * longer valid". Make sure this is only sent protected since
3145 * unprotected frame would be received by the STA that is now
3146 * trying to associate.
3147 */
3148 }
3149#endif /* CONFIG_IEEE80211W */
3150
6fc6879b
JM
3151 /* Make sure that the previously registered inactivity timer will not
3152 * remove the STA immediately. */
3153 sta->timeout_next = STA_NULLFUNC;
3154
04059ab8
DG
3155#ifdef CONFIG_TAXONOMY
3156 taxonomy_sta_info_assoc_req(hapd, sta, pos, left);
3157#endif /* CONFIG_TAXONOMY */
3158
1f0fdaf0
JM
3159 sta->pending_wds_enable = 0;
3160
5208160b
JM
3161#ifdef CONFIG_FILS
3162 if (sta->auth_alg == WLAN_AUTH_FILS_SK ||
3163 sta->auth_alg == WLAN_AUTH_FILS_SK_PFS ||
91d91abf
JM
3164 sta->auth_alg == WLAN_AUTH_FILS_PK) {
3165 if (fils_process_hlp(hapd, sta, pos, left) > 0)
3166 delay_assoc = 1;
3167 }
5208160b
JM
3168#endif /* CONFIG_FILS */
3169
6fc6879b 3170 fail:
53d17144
DL
3171 os_free(identity);
3172 os_free(radius_cui);
3173 hostapd_free_psk_list(psk);
3174
3f81ac07
AO
3175 /*
3176 * In case of a successful response, add the station to the driver.
3177 * Otherwise, the kernel may ignore Data frames before we process the
3178 * ACK frame (TX status). In case of a failure, this station will be
3179 * removed.
3180 *
3181 * Note that this is not compliant with the IEEE 802.11 standard that
3182 * states that a non-AP station should transition into the
3183 * authenticated/associated state only after the station acknowledges
3184 * the (Re)Association Response frame. However, still do this as:
3185 *
3186 * 1. In case the station does not acknowledge the (Re)Association
3187 * Response frame, it will be removed.
3188 * 2. Data frames will be dropped in the kernel until the station is
3189 * set into authorized state, and there are no significant known
3190 * issues with processing other non-Data Class 3 frames during this
3191 * window.
3192 */
05e5e615 3193 if (resp == WLAN_STATUS_SUCCESS && sta && add_associated_sta(hapd, sta))
3f81ac07
AO
3194 resp = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
3195
91d91abf
JM
3196#ifdef CONFIG_FILS
3197 if (sta) {
3198 eloop_cancel_timeout(fils_hlp_timeout, hapd, sta);
3199 os_free(sta->fils_pending_assoc_req);
3200 sta->fils_pending_assoc_req = NULL;
3201 sta->fils_pending_assoc_req_len = 0;
3202 wpabuf_free(sta->fils_hlp_resp);
3203 sta->fils_hlp_resp = NULL;
3204 }
3205 if (sta && delay_assoc && resp == WLAN_STATUS_SUCCESS) {
3206 sta->fils_pending_assoc_req = tmp;
3207 sta->fils_pending_assoc_req_len = left;
3208 sta->fils_pending_assoc_is_reassoc = reassoc;
8b5ddda5 3209 sta->fils_drv_assoc_finish = 0;
91d91abf
JM
3210 wpa_printf(MSG_DEBUG,
3211 "FILS: Waiting for HLP processing before sending (Re)Association Response frame to "
3212 MACSTR, MAC2STR(sta->addr));
3213 eloop_cancel_timeout(fils_hlp_timeout, hapd, sta);
3214 eloop_register_timeout(0, hapd->conf->fils_hlp_wait_time * 1024,
3215 fils_hlp_timeout, hapd, sta);
3216 return;
3217 }
3218#endif /* CONFIG_FILS */
3219
05e5e615
DL
3220 reply_res = send_assoc_resp(hapd, sta, mgmt->sa, resp, reassoc, pos,
3221 left);
78815f3d 3222 os_free(tmp);
3f81ac07
AO
3223
3224 /*
3225 * Remove the station in case tranmission of a success response fails
3226 * (the STA was added associated to the driver) or if the station was
3227 * previously added unassociated.
3228 */
05e5e615
DL
3229 if (sta && ((reply_res != WLAN_STATUS_SUCCESS &&
3230 resp == WLAN_STATUS_SUCCESS) || sta->added_unassoc)) {
bb598c3b
AB
3231 hostapd_drv_sta_remove(hapd, sta->addr);
3232 sta->added_unassoc = 0;
3233 }
6fc6879b
JM
3234}
3235
3236
6fc6879b 3237static void handle_disassoc(struct hostapd_data *hapd,
f8b1f695 3238 const struct ieee80211_mgmt *mgmt, size_t len)
6fc6879b
JM
3239{
3240 struct sta_info *sta;
3241
3242 if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.disassoc)) {
61323e70
JM
3243 wpa_printf(MSG_INFO, "handle_disassoc - too short payload (len=%lu)",
3244 (unsigned long) len);
6fc6879b
JM
3245 return;
3246 }
3247
3248 wpa_printf(MSG_DEBUG, "disassocation: STA=" MACSTR " reason_code=%d",
3249 MAC2STR(mgmt->sa),
3250 le_to_host16(mgmt->u.disassoc.reason_code));
3251
6fc6879b
JM
3252 sta = ap_get_sta(hapd, mgmt->sa);
3253 if (sta == NULL) {
61323e70
JM
3254 wpa_printf(MSG_INFO, "Station " MACSTR " trying to disassociate, but it is not associated",
3255 MAC2STR(mgmt->sa));
6fc6879b
JM
3256 return;
3257 }
3258
ae055af4 3259 ap_sta_set_authorized(hapd, sta, 0);
38cb0a2d 3260 sta->last_seq_ctrl = WLAN_INVALID_MGMT_SEQ;
b8281964 3261 sta->flags &= ~(WLAN_STA_ASSOC | WLAN_STA_ASSOC_REQ_OK);
6fc6879b
JM
3262 wpa_auth_sm_event(sta->wpa_sm, WPA_DISASSOC);
3263 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
3264 HOSTAPD_LEVEL_INFO, "disassociated");
3265 sta->acct_terminate_cause = RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST;
3266 ieee802_1x_notify_port_enabled(sta->eapol_sm, 0);
3267 /* Stop Accounting and IEEE 802.1X sessions, but leave the STA
3268 * authenticated. */
3269 accounting_sta_stop(hapd, sta);
d7c3347f 3270 ieee802_1x_free_station(hapd, sta);
7d597d46 3271 if (sta->ipaddr)
ed4ddb6d 3272 hostapd_drv_br_delete_ip_neigh(hapd, 4, (u8 *) &sta->ipaddr);
bd00c431 3273 ap_sta_ip6addr_del(hapd, sta);
51e2a27a 3274 hostapd_drv_sta_remove(hapd, sta->addr);
bb598c3b 3275 sta->added_unassoc = 0;
6fc6879b
JM
3276
3277 if (sta->timeout_next == STA_NULLFUNC ||
3278 sta->timeout_next == STA_DISASSOC) {
3279 sta->timeout_next = STA_DEAUTH;
3280 eloop_cancel_timeout(ap_handle_timer, hapd, sta);
3281 eloop_register_timeout(AP_DEAUTH_DELAY, 0, ap_handle_timer,
3282 hapd, sta);
3283 }
3284
3285 mlme_disassociate_indication(
3286 hapd, sta, le_to_host16(mgmt->u.disassoc.reason_code));
05e5e615
DL
3287
3288 /* DMG/IEEE 802.11ad does not use deauthication. Deallocate sta upon
3289 * disassociation. */
3290 if (hapd->iface->current_mode &&
3291 hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211AD) {
3292 sta->flags &= ~WLAN_STA_AUTH;
3293 wpa_auth_sm_event(sta->wpa_sm, WPA_DEAUTH);
3294 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
3295 HOSTAPD_LEVEL_DEBUG, "deauthenticated");
3296 ap_free_sta(hapd, sta);
3297 }
6fc6879b
JM
3298}
3299
3300
3301static void handle_deauth(struct hostapd_data *hapd,
f8b1f695 3302 const struct ieee80211_mgmt *mgmt, size_t len)
6fc6879b
JM
3303{
3304 struct sta_info *sta;
3305
3306 if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.deauth)) {
3ec1e902
JM
3307 wpa_msg(hapd->msg_ctx, MSG_DEBUG, "handle_deauth - too short "
3308 "payload (len=%lu)", (unsigned long) len);
6fc6879b
JM
3309 return;
3310 }
3311
3ec1e902 3312 wpa_msg(hapd->msg_ctx, MSG_DEBUG, "deauthentication: STA=" MACSTR
24d75245
BG
3313 " reason_code=%d",
3314 MAC2STR(mgmt->sa), le_to_host16(mgmt->u.deauth.reason_code));
6fc6879b 3315
6fc6879b
JM
3316 sta = ap_get_sta(hapd, mgmt->sa);
3317 if (sta == NULL) {
3ec1e902
JM
3318 wpa_msg(hapd->msg_ctx, MSG_DEBUG, "Station " MACSTR " trying "
3319 "to deauthenticate, but it is not authenticated",
24d75245 3320 MAC2STR(mgmt->sa));
6fc6879b
JM
3321 return;
3322 }
3323
ae055af4 3324 ap_sta_set_authorized(hapd, sta, 0);
38cb0a2d 3325 sta->last_seq_ctrl = WLAN_INVALID_MGMT_SEQ;
b8281964
JM
3326 sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC |
3327 WLAN_STA_ASSOC_REQ_OK);
6fc6879b
JM
3328 wpa_auth_sm_event(sta->wpa_sm, WPA_DEAUTH);
3329 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
3330 HOSTAPD_LEVEL_DEBUG, "deauthenticated");
3331 mlme_deauthenticate_indication(
3332 hapd, sta, le_to_host16(mgmt->u.deauth.reason_code));
3333 sta->acct_terminate_cause = RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST;
3334 ieee802_1x_notify_port_enabled(sta->eapol_sm, 0);
3335 ap_free_sta(hapd, sta);
3336}
3337
3338
3339static void handle_beacon(struct hostapd_data *hapd,
b57e086c 3340 const struct ieee80211_mgmt *mgmt, size_t len,
6fc6879b
JM
3341 struct hostapd_frame_info *fi)
3342{
3343 struct ieee802_11_elems elems;
3344
3345 if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.beacon)) {
61323e70
JM
3346 wpa_printf(MSG_INFO, "handle_beacon - too short payload (len=%lu)",
3347 (unsigned long) len);
6fc6879b
JM
3348 return;
3349 }
3350
3d536eb4 3351 (void) ieee802_11_parse_elems(mgmt->u.beacon.variable,
6fc6879b
JM
3352 len - (IEEE80211_HDRLEN +
3353 sizeof(mgmt->u.beacon)), &elems,
3354 0);
3355
6fc6879b
JM
3356 ap_list_process_beacon(hapd->iface, mgmt, &elems, fi);
3357}
3358
3359
5d22a1d5 3360#ifdef CONFIG_IEEE80211W
88b4b424 3361
912b34f0
JM
3362static int hostapd_sa_query_action(struct hostapd_data *hapd,
3363 const struct ieee80211_mgmt *mgmt,
3364 size_t len)
5d22a1d5 3365{
b57e086c 3366 const u8 *end;
5d22a1d5 3367
93b76319
JM
3368 end = mgmt->u.action.u.sa_query_resp.trans_id +
3369 WLAN_SA_QUERY_TR_ID_LEN;
5d22a1d5 3370 if (((u8 *) mgmt) + len < end) {
93b76319 3371 wpa_printf(MSG_DEBUG, "IEEE 802.11: Too short SA Query Action "
5d22a1d5 3372 "frame (len=%lu)", (unsigned long) len);
912b34f0 3373 return 0;
5d22a1d5
JM
3374 }
3375
d4370eac
MP
3376 ieee802_11_sa_query_action(hapd, mgmt->sa,
3377 mgmt->u.action.u.sa_query_resp.action,
3378 mgmt->u.action.u.sa_query_resp.trans_id);
912b34f0 3379 return 1;
5d22a1d5 3380}
5d22a1d5
JM
3381
3382
c4e281fd
JM
3383static int robust_action_frame(u8 category)
3384{
3385 return category != WLAN_ACTION_PUBLIC &&
3386 category != WLAN_ACTION_HT;
3387}
9f64b827 3388#endif /* CONFIG_IEEE80211W */
c4e281fd
JM
3389
3390
912b34f0
JM
3391static int handle_action(struct hostapd_data *hapd,
3392 const struct ieee80211_mgmt *mgmt, size_t len)
6fc6879b 3393{
c4e281fd 3394 struct sta_info *sta;
46eeedac 3395 sta = ap_get_sta(hapd, mgmt->sa);
c4e281fd 3396
6fc6879b
JM
3397 if (len < IEEE80211_HDRLEN + 1) {
3398 hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
3399 HOSTAPD_LEVEL_DEBUG,
3400 "handle_action - too short payload (len=%lu)",
3401 (unsigned long) len);
912b34f0 3402 return 0;
6fc6879b
JM
3403 }
3404
c79938a5
JM
3405 if (mgmt->u.action.category != WLAN_ACTION_PUBLIC &&
3406 (sta == NULL || !(sta->flags & WLAN_STA_ASSOC))) {
3407 wpa_printf(MSG_DEBUG, "IEEE 802.11: Ignored Action "
3408 "frame (category=%u) from unassociated STA " MACSTR,
ae26d302 3409 mgmt->u.action.category, MAC2STR(mgmt->sa));
912b34f0 3410 return 0;
c79938a5
JM
3411 }
3412
c4e281fd
JM
3413#ifdef CONFIG_IEEE80211W
3414 if (sta && (sta->flags & WLAN_STA_MFP) &&
7b2c42f8
JM
3415 !(mgmt->frame_control & host_to_le16(WLAN_FC_ISWEP)) &&
3416 robust_action_frame(mgmt->u.action.category)) {
c4e281fd
JM
3417 hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
3418 HOSTAPD_LEVEL_DEBUG,
3419 "Dropped unprotected Robust Action frame from "
3420 "an MFP STA");
912b34f0 3421 return 0;
c4e281fd
JM
3422 }
3423#endif /* CONFIG_IEEE80211W */
3424
38cb0a2d
IP
3425 if (sta) {
3426 u16 fc = le_to_host16(mgmt->frame_control);
3427 u16 seq_ctrl = le_to_host16(mgmt->seq_ctrl);
3428
3429 if ((fc & WLAN_FC_RETRY) &&
3430 sta->last_seq_ctrl != WLAN_INVALID_MGMT_SEQ &&
3431 sta->last_seq_ctrl == seq_ctrl &&
3432 sta->last_subtype == WLAN_FC_STYPE_ACTION) {
3433 hostapd_logger(hapd, sta->addr,
3434 HOSTAPD_MODULE_IEEE80211,
3435 HOSTAPD_LEVEL_DEBUG,
3436 "Drop repeated action frame seq_ctrl=0x%x",
3437 seq_ctrl);
3438 return 1;
3439 }
3440
3441 sta->last_seq_ctrl = seq_ctrl;
3442 sta->last_subtype = WLAN_FC_STYPE_ACTION;
3443 }
3444
6fc6879b 3445 switch (mgmt->u.action.category) {
4ec1fd8e 3446#ifdef CONFIG_IEEE80211R_AP
6fc6879b 3447 case WLAN_ACTION_FT:
d6c6b1fb
JM
3448 if (!sta ||
3449 wpa_ft_action_rx(sta->wpa_sm, (u8 *) &mgmt->u.action,
6fc6879b
JM
3450 len - IEEE80211_HDRLEN))
3451 break;
912b34f0 3452 return 1;
4ec1fd8e 3453#endif /* CONFIG_IEEE80211R_AP */
c2a71408 3454 case WLAN_ACTION_WMM:
3ae0800c 3455 hostapd_wmm_action(hapd, mgmt, len);
912b34f0 3456 return 1;
5d22a1d5 3457#ifdef CONFIG_IEEE80211W
93b76319 3458 case WLAN_ACTION_SA_QUERY:
912b34f0 3459 return hostapd_sa_query_action(hapd, mgmt, len);
5d22a1d5 3460#endif /* CONFIG_IEEE80211W */
b5bf84ba 3461#ifdef CONFIG_WNM_AP
c79938a5 3462 case WLAN_ACTION_WNM:
dbfb8e82
JM
3463 ieee802_11_rx_wnm_action_ap(hapd, mgmt, len);
3464 return 1;
b5bf84ba 3465#endif /* CONFIG_WNM_AP */
037378ff
AN
3466#ifdef CONFIG_FST
3467 case WLAN_ACTION_FST:
3468 if (hapd->iface->fst)
3469 fst_rx_action(hapd->iface->fst, mgmt, len);
94edea89
JM
3470 else
3471 wpa_printf(MSG_DEBUG,
3472 "FST: Ignore FST Action frame - no FST attached");
037378ff
AN
3473 return 1;
3474#endif /* CONFIG_FST */
c706d5aa 3475 case WLAN_ACTION_PUBLIC:
5ce00d09 3476 case WLAN_ACTION_PROTECTED_DUAL:
587d60d2 3477#ifdef CONFIG_IEEE80211N
fd66aa63
JM
3478 if (len >= IEEE80211_HDRLEN + 2 &&
3479 mgmt->u.action.u.public_action.action ==
587d60d2
PX
3480 WLAN_PA_20_40_BSS_COEX) {
3481 wpa_printf(MSG_DEBUG,
3482 "HT20/40 coex mgmt frame received from STA "
3483 MACSTR, MAC2STR(mgmt->sa));
3484 hostapd_2040_coex_action(hapd, mgmt, len);
115d5e22 3485 return 1;
587d60d2
PX
3486 }
3487#endif /* CONFIG_IEEE80211N */
9c2b8204
JM
3488#ifdef CONFIG_DPP
3489 if (len >= IEEE80211_HDRLEN + 6 &&
3490 mgmt->u.action.u.vs_public_action.action ==
3491 WLAN_PA_VENDOR_SPECIFIC &&
3492 WPA_GET_BE24(mgmt->u.action.u.vs_public_action.oui) ==
3493 OUI_WFA &&
3494 mgmt->u.action.u.vs_public_action.variable[0] ==
3495 DPP_OUI_TYPE) {
3496 const u8 *pos, *end;
3497
3498 pos = &mgmt->u.action.u.vs_public_action.variable[1];
3499 end = ((const u8 *) mgmt) + len;
3500 hostapd_dpp_rx_action(hapd, mgmt->sa, pos, end - pos,
3501 hapd->iface->freq);
3502 return 1;
3503 }
3504 if (len >= IEEE80211_HDRLEN + 2 &&
3505 (mgmt->u.action.u.public_action.action ==
3506 WLAN_PA_GAS_INITIAL_RESP ||
3507 mgmt->u.action.u.public_action.action ==
3508 WLAN_PA_GAS_COMEBACK_RESP)) {
3509 const u8 *pos, *end;
3510
3511 pos = &mgmt->u.action.u.public_action.action;
3512 end = ((const u8 *) mgmt) + len;
3513 gas_query_ap_rx(hapd->gas, mgmt->sa,
3514 mgmt->u.action.category,
3515 pos, end - pos, hapd->iface->freq);
3516 return 1;
3517 }
3518#endif /* CONFIG_DPP */
c706d5aa
JM
3519 if (hapd->public_action_cb) {
3520 hapd->public_action_cb(hapd->public_action_cb_ctx,
3521 (u8 *) mgmt, len,
3522 hapd->iface->freq);
c706d5aa 3523 }
2d9ffe1e 3524 if (hapd->public_action_cb2) {
8dabf4bb 3525 hapd->public_action_cb2(hapd->public_action_cb2_ctx,
2d9ffe1e
JM
3526 (u8 *) mgmt, len,
3527 hapd->iface->freq);
3528 }
3529 if (hapd->public_action_cb || hapd->public_action_cb2)
912b34f0 3530 return 1;
c706d5aa 3531 break;
e44f8bf2
JM
3532 case WLAN_ACTION_VENDOR_SPECIFIC:
3533 if (hapd->vendor_action_cb) {
3534 if (hapd->vendor_action_cb(hapd->vendor_action_cb_ctx,
3535 (u8 *) mgmt, len,
3536 hapd->iface->freq) == 0)
912b34f0 3537 return 1;
e44f8bf2
JM
3538 }
3539 break;
2572df34
DS
3540 case WLAN_ACTION_RADIO_MEASUREMENT:
3541 hostapd_handle_radio_measurement(hapd, (const u8 *) mgmt, len);
3542 return 1;
6fc6879b
JM
3543 }
3544
3545 hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
3546 HOSTAPD_LEVEL_DEBUG,
3547 "handle_action - unknown action category %d or invalid "
3548 "frame",
3549 mgmt->u.action.category);
81372e34
JB
3550 if (!is_multicast_ether_addr(mgmt->da) &&
3551 !(mgmt->u.action.category & 0x80) &&
3552 !is_multicast_ether_addr(mgmt->sa)) {
b57e086c
JM
3553 struct ieee80211_mgmt *resp;
3554
6fc6879b
JM
3555 /*
3556 * IEEE 802.11-REVma/D9.0 - 7.3.1.11
3557 * Return the Action frame to the source without change
3558 * except that MSB of the Category set to 1.
3559 */
3560 wpa_printf(MSG_DEBUG, "IEEE 802.11: Return unknown Action "
3561 "frame back to sender");
a1f11e34 3562 resp = os_memdup(mgmt, len);
b57e086c 3563 if (resp == NULL)
912b34f0 3564 return 0;
b57e086c
JM
3565 os_memcpy(resp->da, resp->sa, ETH_ALEN);
3566 os_memcpy(resp->sa, hapd->own_addr, ETH_ALEN);
3567 os_memcpy(resp->bssid, hapd->own_addr, ETH_ALEN);
3568 resp->u.action.category |= 0x80;
3569
41fe8b42
JM
3570 if (hostapd_drv_send_mlme(hapd, resp, len, 0) < 0) {
3571 wpa_printf(MSG_ERROR, "IEEE 802.11: Failed to send "
3572 "Action frame");
3573 }
b57e086c 3574 os_free(resp);
6fc6879b 3575 }
912b34f0
JM
3576
3577 return 1;
6fc6879b
JM
3578}
3579
3580
3581/**
3582 * ieee802_11_mgmt - process incoming IEEE 802.11 management frames
3583 * @hapd: hostapd BSS data structure (the BSS to which the management frame was
3584 * sent to)
3585 * @buf: management frame data (starting from IEEE 802.11 header)
3586 * @len: length of frame data in octets
a17df5fb 3587 * @fi: meta data about received frame (signal level, etc.)
6fc6879b
JM
3588 *
3589 * Process all incoming IEEE 802.11 management frames. This will be called for
3590 * each frame received from the kernel driver through wlan#ap interface. In
3591 * addition, it can be called to re-inserted pending frames (e.g., when using
3592 * external RADIUS server as an MAC ACL).
3593 */
912b34f0
JM
3594int ieee802_11_mgmt(struct hostapd_data *hapd, const u8 *buf, size_t len,
3595 struct hostapd_frame_info *fi)
6fc6879b 3596{
f8b1f695 3597 struct ieee80211_mgmt *mgmt;
f8b1f695 3598 u16 fc, stype;
912b34f0 3599 int ret = 0;
f8b1f695 3600
cbcf92b4 3601 if (len < 24)
912b34f0 3602 return 0;
cbcf92b4 3603
f8b1f695
JM
3604 mgmt = (struct ieee80211_mgmt *) buf;
3605 fc = le_to_host16(mgmt->frame_control);
3606 stype = WLAN_FC_GET_STYPE(fc);
6fc6879b
JM
3607
3608 if (stype == WLAN_FC_STYPE_BEACON) {
3609 handle_beacon(hapd, mgmt, len, fi);
912b34f0 3610 return 1;
6fc6879b
JM
3611 }
3612
842c5af5 3613 if (!is_broadcast_ether_addr(mgmt->bssid) &&
3eeee931
AN
3614#ifdef CONFIG_P2P
3615 /* Invitation responses can be sent with the peer MAC as BSSID */
3616 !((hapd->conf->p2p & P2P_GROUP_OWNER) &&
3617 stype == WLAN_FC_STYPE_ACTION) &&
3618#endif /* CONFIG_P2P */
f3e9899e
BC
3619#ifdef CONFIG_MESH
3620 !(hapd->conf->mesh & MESH_ENABLED) &&
3621#endif /* CONFIG_MESH */
fe2c5241 3622 os_memcmp(mgmt->bssid, hapd->own_addr, ETH_ALEN) != 0) {
61323e70
JM
3623 wpa_printf(MSG_INFO, "MGMT: BSSID=" MACSTR " not our address",
3624 MAC2STR(mgmt->bssid));
912b34f0 3625 return 0;
6fc6879b
JM
3626 }
3627
3628
3629 if (stype == WLAN_FC_STYPE_PROBE_REQ) {
baf513d6 3630 handle_probe_req(hapd, mgmt, len, fi->ssi_signal);
912b34f0 3631 return 1;
6fc6879b
JM
3632 }
3633
efeada91
JM
3634 if ((!is_broadcast_ether_addr(mgmt->da) ||
3635 stype != WLAN_FC_STYPE_ACTION) &&
3636 os_memcmp(mgmt->da, hapd->own_addr, ETH_ALEN) != 0) {
6fc6879b
JM
3637 hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
3638 HOSTAPD_LEVEL_DEBUG,
3639 "MGMT: DA=" MACSTR " not our address",
3640 MAC2STR(mgmt->da));
912b34f0 3641 return 0;
6fc6879b
JM
3642 }
3643
b308a304 3644 if (hapd->iconf->track_sta_max_num)
a818425d 3645 sta_track_add(hapd->iface, mgmt->sa, fi->ssi_signal);
b308a304 3646
6fc6879b
JM
3647 switch (stype) {
3648 case WLAN_FC_STYPE_AUTH:
3649 wpa_printf(MSG_DEBUG, "mgmt::auth");
3650 handle_auth(hapd, mgmt, len);
912b34f0 3651 ret = 1;
6fc6879b
JM
3652 break;
3653 case WLAN_FC_STYPE_ASSOC_REQ:
3654 wpa_printf(MSG_DEBUG, "mgmt::assoc_req");
3655 handle_assoc(hapd, mgmt, len, 0);
912b34f0 3656 ret = 1;
6fc6879b 3657 break;
6fc6879b
JM
3658 case WLAN_FC_STYPE_REASSOC_REQ:
3659 wpa_printf(MSG_DEBUG, "mgmt::reassoc_req");
3660 handle_assoc(hapd, mgmt, len, 1);
912b34f0 3661 ret = 1;
6fc6879b
JM
3662 break;
3663 case WLAN_FC_STYPE_DISASSOC:
3664 wpa_printf(MSG_DEBUG, "mgmt::disassoc");
3665 handle_disassoc(hapd, mgmt, len);
912b34f0 3666 ret = 1;
6fc6879b
JM
3667 break;
3668 case WLAN_FC_STYPE_DEAUTH:
3ec1e902 3669 wpa_msg(hapd->msg_ctx, MSG_DEBUG, "mgmt::deauth");
6fc6879b 3670 handle_deauth(hapd, mgmt, len);
912b34f0 3671 ret = 1;
6fc6879b
JM
3672 break;
3673 case WLAN_FC_STYPE_ACTION:
3674 wpa_printf(MSG_DEBUG, "mgmt::action");
912b34f0 3675 ret = handle_action(hapd, mgmt, len);
6fc6879b
JM
3676 break;
3677 default:
3678 hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
3679 HOSTAPD_LEVEL_DEBUG,
3680 "unknown mgmt frame subtype %d", stype);
3681 break;
3682 }
912b34f0
JM
3683
3684 return ret;
6fc6879b
JM
3685}
3686
3687
3688static void handle_auth_cb(struct hostapd_data *hapd,
f8b1f695 3689 const struct ieee80211_mgmt *mgmt,
6fc6879b
JM
3690 size_t len, int ok)
3691{
3692 u16 auth_alg, auth_transaction, status_code;
3693 struct sta_info *sta;
3694
bb598c3b
AB
3695 sta = ap_get_sta(hapd, mgmt->da);
3696 if (!sta) {
3697 wpa_printf(MSG_INFO, "handle_auth_cb: STA " MACSTR " not found",
3698 MAC2STR(mgmt->da));
3699 return;
3700 }
3701
3702 auth_alg = le_to_host16(mgmt->u.auth.auth_alg);
3703 auth_transaction = le_to_host16(mgmt->u.auth.auth_transaction);
3704 status_code = le_to_host16(mgmt->u.auth.status_code);
3705
6fc6879b
JM
3706 if (!ok) {
3707 hostapd_logger(hapd, mgmt->da, HOSTAPD_MODULE_IEEE80211,
3708 HOSTAPD_LEVEL_NOTICE,
3709 "did not acknowledge authentication response");
bb598c3b 3710 goto fail;
6fc6879b
JM
3711 }
3712
3713 if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.auth)) {
61323e70
JM
3714 wpa_printf(MSG_INFO, "handle_auth_cb - too short payload (len=%lu)",
3715 (unsigned long) len);
bb598c3b 3716 goto fail;
6fc6879b
JM
3717 }
3718
3719 if (status_code == WLAN_STATUS_SUCCESS &&
3720 ((auth_alg == WLAN_AUTH_OPEN && auth_transaction == 2) ||
3721 (auth_alg == WLAN_AUTH_SHARED_KEY && auth_transaction == 4))) {
3722 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
3723 HOSTAPD_LEVEL_INFO, "authenticated");
3724 sta->flags |= WLAN_STA_AUTH;
bb598c3b
AB
3725 if (sta->added_unassoc)
3726 hostapd_set_sta_flags(hapd, sta);
3727 return;
3728 }
3729
3730fail:
3731 if (status_code != WLAN_STATUS_SUCCESS && sta->added_unassoc) {
3732 hostapd_drv_sta_remove(hapd, sta->addr);
3733 sta->added_unassoc = 0;
6fc6879b
JM
3734 }
3735}
3736
3737
69dd2967
SM
3738static void hostapd_set_wds_encryption(struct hostapd_data *hapd,
3739 struct sta_info *sta,
3740 char *ifname_wds)
3741{
3742 int i;
f41ded6f 3743 struct hostapd_ssid *ssid = &hapd->conf->ssid;
69dd2967
SM
3744
3745 if (hapd->conf->ieee802_1x || hapd->conf->wpa)
3746 return;
3747
3748 for (i = 0; i < 4; i++) {
3749 if (ssid->wep.key[i] &&
3750 hostapd_drv_set_key(ifname_wds, hapd, WPA_ALG_WEP, NULL, i,
3751 i == ssid->wep.idx, NULL, 0,
3752 ssid->wep.key[i], ssid->wep.len[i])) {
3753 wpa_printf(MSG_WARNING,
3754 "Could not set WEP keys for WDS interface; %s",
3755 ifname_wds);
3756 break;
3757 }
3758 }
3759}
3760
3761
6fc6879b 3762static void handle_assoc_cb(struct hostapd_data *hapd,
f8b1f695 3763 const struct ieee80211_mgmt *mgmt,
6fc6879b
JM
3764 size_t len, int reassoc, int ok)
3765{
3766 u16 status;
3767 struct sta_info *sta;
3768 int new_assoc = 1;
3769
6fc6879b
JM
3770 sta = ap_get_sta(hapd, mgmt->da);
3771 if (!sta) {
61323e70
JM
3772 wpa_printf(MSG_INFO, "handle_assoc_cb: STA " MACSTR " not found",
3773 MAC2STR(mgmt->da));
6fc6879b
JM
3774 return;
3775 }
3776
bb598c3b
AB
3777 if (len < IEEE80211_HDRLEN + (reassoc ? sizeof(mgmt->u.reassoc_resp) :
3778 sizeof(mgmt->u.assoc_resp))) {
3779 wpa_printf(MSG_INFO,
3780 "handle_assoc_cb(reassoc=%d) - too short payload (len=%lu)",
3781 reassoc, (unsigned long) len);
3f81ac07
AO
3782 hostapd_drv_sta_remove(hapd, sta->addr);
3783 return;
bb598c3b
AB
3784 }
3785
3f81ac07
AO
3786 if (reassoc)
3787 status = le_to_host16(mgmt->u.reassoc_resp.status_code);
3788 else
3789 status = le_to_host16(mgmt->u.assoc_resp.status_code);
3790
22b42372
FF
3791 if (!ok) {
3792 hostapd_logger(hapd, mgmt->da, HOSTAPD_MODULE_IEEE80211,
3793 HOSTAPD_LEVEL_DEBUG,
3794 "did not acknowledge association response");
3795 sta->flags &= ~WLAN_STA_ASSOC_REQ_OK;
3f81ac07
AO
3796 /* The STA is added only in case of SUCCESS */
3797 if (status == WLAN_STATUS_SUCCESS)
3798 hostapd_drv_sta_remove(hapd, sta->addr);
22b42372 3799
3f81ac07
AO
3800 return;
3801 }
22b42372 3802
6fc6879b 3803 if (status != WLAN_STATUS_SUCCESS)
5bdac4ab 3804 return;
6fc6879b
JM
3805
3806 /* Stop previous accounting session, if one is started, and allocate
3807 * new session id for the new session. */
3808 accounting_sta_stop(hapd, sta);
6fc6879b
JM
3809
3810 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
3811 HOSTAPD_LEVEL_INFO,
2fc98d02
JM
3812 "associated (aid %d)",
3813 sta->aid);
6fc6879b
JM
3814
3815 if (sta->flags & WLAN_STA_ASSOC)
3816 new_assoc = 0;
3817 sta->flags |= WLAN_STA_ASSOC;
3578e665 3818 sta->flags &= ~WLAN_STA_WNM_SLEEP_MODE;
07e0117d
JM
3819 if ((!hapd->conf->ieee802_1x && !hapd->conf->wpa &&
3820 !hapd->conf->osen) ||
3821 sta->auth_alg == WLAN_AUTH_FILS_SK ||
3822 sta->auth_alg == WLAN_AUTH_FILS_SK_PFS ||
3823 sta->auth_alg == WLAN_AUTH_FILS_PK ||
ef580012
JM
3824 sta->auth_alg == WLAN_AUTH_FT) {
3825 /*
07e0117d
JM
3826 * Open, static WEP, FT protocol, or FILS; no separate
3827 * authorization step.
ef580012 3828 */
6905dcb1 3829 ap_sta_set_authorized(hapd, sta, 1);
515cf93f 3830 }
6fc6879b
JM
3831
3832 if (reassoc)
3833 mlme_reassociate_indication(hapd, sta);
3834 else
3835 mlme_associate_indication(hapd, sta);
3836
5d22a1d5 3837#ifdef CONFIG_IEEE80211W
93b76319 3838 sta->sa_query_timed_out = 0;
5d22a1d5
JM
3839#endif /* CONFIG_IEEE80211W */
3840
6fc6879b
JM
3841 if (sta->eapol_sm == NULL) {
3842 /*
3843 * This STA does not use RADIUS server for EAP authentication,
3844 * so bind it to the selected VLAN interface now, since the
3845 * interface selection is not going to change anymore.
3846 */
c8e6beab 3847 if (ap_sta_bind_vlan(hapd, sta) < 0)
5bdac4ab 3848 return;
6fc6879b
JM
3849 } else if (sta->vlan_id) {
3850 /* VLAN ID already set (e.g., by PMKSA caching), so bind STA */
c8e6beab 3851 if (ap_sta_bind_vlan(hapd, sta) < 0)
5bdac4ab 3852 return;
6fc6879b 3853 }
eddd8010 3854
0e8a96a9 3855 hostapd_set_sta_flags(hapd, sta);
6fc6879b 3856
1f0fdaf0
JM
3857 if (!(sta->flags & WLAN_STA_WDS) && sta->pending_wds_enable) {
3858 wpa_printf(MSG_DEBUG, "Enable 4-address WDS mode for STA "
3859 MACSTR " based on pending request",
3860 MAC2STR(sta->addr));
3861 sta->pending_wds_enable = 0;
3862 sta->flags |= WLAN_STA_WDS;
3863 }
3864
cb2b6666
JM
3865 if (sta->flags & WLAN_STA_WDS) {
3866 int ret;
3867 char ifname_wds[IFNAMSIZ + 1];
3868
3869 wpa_printf(MSG_DEBUG, "Reenable 4-address WDS mode for STA "
3870 MACSTR " (aid %u)",
3871 MAC2STR(sta->addr), sta->aid);
3872 ret = hostapd_set_wds_sta(hapd, ifname_wds, sta->addr,
3873 sta->aid, 1);
3874 if (!ret)
3875 hostapd_set_wds_encryption(hapd, sta, ifname_wds);
3876 }
3877
6fc6879b
JM
3878 if (sta->auth_alg == WLAN_AUTH_FT)
3879 wpa_auth_sm_event(sta->wpa_sm, WPA_ASSOC_FT);
3880 else
3881 wpa_auth_sm_event(sta->wpa_sm, WPA_ASSOC);
d24df7c3 3882 hapd->new_assoc_sta_cb(hapd, sta, !new_assoc);
6fc6879b 3883 ieee802_1x_notify_port_enabled(sta->eapol_sm, 1);
f2accfe7 3884
da24c5aa
JM
3885#ifdef CONFIG_FILS
3886 if ((sta->auth_alg == WLAN_AUTH_FILS_SK ||
3887 sta->auth_alg == WLAN_AUTH_FILS_SK_PFS ||
3888 sta->auth_alg == WLAN_AUTH_FILS_PK) &&
3889 fils_set_tk(sta->wpa_sm) < 0) {
3890 wpa_printf(MSG_DEBUG, "FILS: TK configuration failed");
3891 ap_sta_disconnect(hapd, sta, sta->addr,
3892 WLAN_REASON_UNSPECIFIED);
3893 return;
3894 }
3895#endif /* CONFIG_FILS */
3896
f2accfe7
EP
3897 if (sta->pending_eapol_rx) {
3898 struct os_reltime now, age;
3899
3900 os_get_reltime(&now);
3901 os_reltime_sub(&now, &sta->pending_eapol_rx->rx_time, &age);
3902 if (age.sec == 0 && age.usec < 200000) {
3903 wpa_printf(MSG_DEBUG,
3904 "Process pending EAPOL frame that was received from " MACSTR " just before association notification",
3905 MAC2STR(sta->addr));
3906 ieee802_1x_receive(
3907 hapd, mgmt->da,
3908 wpabuf_head(sta->pending_eapol_rx->buf),
3909 wpabuf_len(sta->pending_eapol_rx->buf));
3910 }
3911 wpabuf_free(sta->pending_eapol_rx->buf);
3912 os_free(sta->pending_eapol_rx);
3913 sta->pending_eapol_rx = NULL;
3914 }
6fc6879b
JM
3915}
3916
3917
4dc03726
JM
3918static void handle_deauth_cb(struct hostapd_data *hapd,
3919 const struct ieee80211_mgmt *mgmt,
3920 size_t len, int ok)
3921{
3922 struct sta_info *sta;
81372e34 3923 if (is_multicast_ether_addr(mgmt->da))
4dc03726
JM
3924 return;
3925 sta = ap_get_sta(hapd, mgmt->da);
3926 if (!sta) {
3927 wpa_printf(MSG_DEBUG, "handle_deauth_cb: STA " MACSTR
3928 " not found", MAC2STR(mgmt->da));
3929 return;
3930 }
3931 if (ok)
3932 wpa_printf(MSG_DEBUG, "STA " MACSTR " acknowledged deauth",
3933 MAC2STR(sta->addr));
3934 else
3935 wpa_printf(MSG_DEBUG, "STA " MACSTR " did not acknowledge "
3936 "deauth", MAC2STR(sta->addr));
3937
3938 ap_sta_deauth_cb(hapd, sta);
3939}
3940
3941
3942static void handle_disassoc_cb(struct hostapd_data *hapd,
3943 const struct ieee80211_mgmt *mgmt,
3944 size_t len, int ok)
3945{
3946 struct sta_info *sta;
81372e34 3947 if (is_multicast_ether_addr(mgmt->da))
4dc03726
JM
3948 return;
3949 sta = ap_get_sta(hapd, mgmt->da);
3950 if (!sta) {
3951 wpa_printf(MSG_DEBUG, "handle_disassoc_cb: STA " MACSTR
3952 " not found", MAC2STR(mgmt->da));
3953 return;
3954 }
3955 if (ok)
3956 wpa_printf(MSG_DEBUG, "STA " MACSTR " acknowledged disassoc",
3957 MAC2STR(sta->addr));
3958 else
3959 wpa_printf(MSG_DEBUG, "STA " MACSTR " did not acknowledge "
3960 "disassoc", MAC2STR(sta->addr));
3961
3962 ap_sta_disassoc_cb(hapd, sta);
3963}
3964
3965
f3383366
JM
3966static void handle_action_cb(struct hostapd_data *hapd,
3967 const struct ieee80211_mgmt *mgmt,
3968 size_t len, int ok)
3969{
3970 struct sta_info *sta;
167f78a5 3971 const struct rrm_measurement_report_element *report;
f3383366
JM
3972
3973 if (is_multicast_ether_addr(mgmt->da))
3974 return;
9c2b8204
JM
3975#ifdef CONFIG_DPP
3976 if (len >= IEEE80211_HDRLEN + 6 &&
3977 mgmt->u.action.category == WLAN_ACTION_PUBLIC &&
3978 mgmt->u.action.u.vs_public_action.action ==
3979 WLAN_PA_VENDOR_SPECIFIC &&
3980 WPA_GET_BE24(mgmt->u.action.u.vs_public_action.oui) ==
3981 OUI_WFA &&
3982 mgmt->u.action.u.vs_public_action.variable[0] ==
3983 DPP_OUI_TYPE) {
3984 const u8 *pos, *end;
3985
3986 pos = &mgmt->u.action.u.vs_public_action.variable[1];
3987 end = ((const u8 *) mgmt) + len;
3988 hostapd_dpp_tx_status(hapd, mgmt->da, pos, end - pos, ok);
3989 return;
3990 }
3991 if (len >= IEEE80211_HDRLEN + 2 &&
3992 mgmt->u.action.category == WLAN_ACTION_PUBLIC &&
3993 (mgmt->u.action.u.public_action.action ==
3994 WLAN_PA_GAS_INITIAL_REQ ||
3995 mgmt->u.action.u.public_action.action ==
3996 WLAN_PA_GAS_COMEBACK_REQ)) {
3997 const u8 *pos, *end;
3998
3999 pos = mgmt->u.action.u.public_action.variable;
4000 end = ((const u8 *) mgmt) + len;
4001 gas_query_ap_tx_status(hapd->gas, mgmt->da, pos, end - pos, ok);
4002 return;
4003 }
4004#endif /* CONFIG_DPP */
f3383366
JM
4005 sta = ap_get_sta(hapd, mgmt->da);
4006 if (!sta) {
4007 wpa_printf(MSG_DEBUG, "handle_action_cb: STA " MACSTR
4008 " not found", MAC2STR(mgmt->da));
4009 return;
4010 }
4011
167f78a5 4012 if (len < 24 + 5 + sizeof(*report))
f3383366 4013 return;
167f78a5
JM
4014 report = (const struct rrm_measurement_report_element *)
4015 &mgmt->u.action.u.rrm.variable[2];
f3383366 4016 if (mgmt->u.action.category == WLAN_ACTION_RADIO_MEASUREMENT &&
167f78a5
JM
4017 mgmt->u.action.u.rrm.action == WLAN_RRM_RADIO_MEASUREMENT_REQUEST &&
4018 report->eid == WLAN_EID_MEASURE_REQUEST &&
4019 report->len >= 3 &&
4020 report->type == MEASURE_TYPE_BEACON)
f3383366
JM
4021 hostapd_rrm_beacon_req_tx_status(hapd, mgmt, len, ok);
4022}
4023
4024
1c6e69cc
JM
4025/**
4026 * ieee802_11_mgmt_cb - Process management frame TX status callback
4027 * @hapd: hostapd BSS data structure (the BSS from which the management frame
4028 * was sent from)
4029 * @buf: management frame data (starting from IEEE 802.11 header)
4030 * @len: length of frame data in octets
4031 * @stype: management frame subtype from frame control field
4032 * @ok: Whether the frame was ACK'ed
4033 */
f8b1f695 4034void ieee802_11_mgmt_cb(struct hostapd_data *hapd, const u8 *buf, size_t len,
6fc6879b
JM
4035 u16 stype, int ok)
4036{
f8b1f695
JM
4037 const struct ieee80211_mgmt *mgmt;
4038 mgmt = (const struct ieee80211_mgmt *) buf;
6fc6879b 4039
93827f45
JM
4040#ifdef CONFIG_TESTING_OPTIONS
4041 if (hapd->ext_mgmt_frame_handling) {
4042 wpa_msg(hapd->msg_ctx, MSG_INFO, "MGMT-TX-STATUS stype=%u ok=%d",
4043 stype, ok);
4044 return;
4045 }
4046#endif /* CONFIG_TESTING_OPTIONS */
4047
6fc6879b
JM
4048 switch (stype) {
4049 case WLAN_FC_STYPE_AUTH:
4050 wpa_printf(MSG_DEBUG, "mgmt::auth cb");
4051 handle_auth_cb(hapd, mgmt, len, ok);
4052 break;
4053 case WLAN_FC_STYPE_ASSOC_RESP:
4054 wpa_printf(MSG_DEBUG, "mgmt::assoc_resp cb");
4055 handle_assoc_cb(hapd, mgmt, len, 0, ok);
4056 break;
4057 case WLAN_FC_STYPE_REASSOC_RESP:
4058 wpa_printf(MSG_DEBUG, "mgmt::reassoc_resp cb");
4059 handle_assoc_cb(hapd, mgmt, len, 1, ok);
4060 break;
4061 case WLAN_FC_STYPE_PROBE_RESP:
077dcfb8 4062 wpa_printf(MSG_EXCESSIVE, "mgmt::proberesp cb ok=%d", ok);
6fc6879b
JM
4063 break;
4064 case WLAN_FC_STYPE_DEAUTH:
4dc03726
JM
4065 wpa_printf(MSG_DEBUG, "mgmt::deauth cb");
4066 handle_deauth_cb(hapd, mgmt, len, ok);
4067 break;
4068 case WLAN_FC_STYPE_DISASSOC:
4069 wpa_printf(MSG_DEBUG, "mgmt::disassoc cb");
4070 handle_disassoc_cb(hapd, mgmt, len, ok);
6fc6879b 4071 break;
5d22a1d5 4072 case WLAN_FC_STYPE_ACTION:
077dcfb8 4073 wpa_printf(MSG_DEBUG, "mgmt::action cb ok=%d", ok);
f3383366 4074 handle_action_cb(hapd, mgmt, len, ok);
5d22a1d5 4075 break;
6fc6879b 4076 default:
61323e70 4077 wpa_printf(MSG_INFO, "unknown mgmt cb frame subtype %d", stype);
6fc6879b
JM
4078 break;
4079 }
4080}
4081
4082
6fc6879b
JM
4083int ieee802_11_get_mib(struct hostapd_data *hapd, char *buf, size_t buflen)
4084{
4085 /* TODO */
4086 return 0;
4087}
4088
4089
4090int ieee802_11_get_mib_sta(struct hostapd_data *hapd, struct sta_info *sta,
4091 char *buf, size_t buflen)
4092{
4093 /* TODO */
4094 return 0;
4095}
4096
f8b1f695
JM
4097
4098void hostapd_tx_status(struct hostapd_data *hapd, const u8 *addr,
4099 const u8 *buf, size_t len, int ack)
4100{
4101 struct sta_info *sta;
4102 struct hostapd_iface *iface = hapd->iface;
4103
4104 sta = ap_get_sta(hapd, addr);
4105 if (sta == NULL && iface->num_bss > 1) {
4106 size_t j;
4107 for (j = 0; j < iface->num_bss; j++) {
4108 hapd = iface->bss[j];
4109 sta = ap_get_sta(hapd, addr);
4110 if (sta)
4111 break;
4112 }
4113 }
0c01d65d 4114 if (sta == NULL || !(sta->flags & WLAN_STA_ASSOC))
f8b1f695
JM
4115 return;
4116 if (sta->flags & WLAN_STA_PENDING_POLL) {
4117 wpa_printf(MSG_DEBUG, "STA " MACSTR " %s pending "
4118 "activity poll", MAC2STR(sta->addr),
4119 ack ? "ACKed" : "did not ACK");
4120 if (ack)
4121 sta->flags &= ~WLAN_STA_PENDING_POLL;
4122 }
4123
4124 ieee802_1x_tx_status(hapd, sta, buf, len, ack);
4125}
4126
4127
dd840f79
JB
4128void hostapd_eapol_tx_status(struct hostapd_data *hapd, const u8 *dst,
4129 const u8 *data, size_t len, int ack)
4130{
4131 struct sta_info *sta;
4132 struct hostapd_iface *iface = hapd->iface;
4133
4134 sta = ap_get_sta(hapd, dst);
4135 if (sta == NULL && iface->num_bss > 1) {
4136 size_t j;
4137 for (j = 0; j < iface->num_bss; j++) {
4138 hapd = iface->bss[j];
4139 sta = ap_get_sta(hapd, dst);
4140 if (sta)
4141 break;
4142 }
4143 }
d9a38716
JM
4144 if (sta == NULL || !(sta->flags & WLAN_STA_ASSOC)) {
4145 wpa_printf(MSG_DEBUG, "Ignore TX status for Data frame to STA "
4146 MACSTR " that is not currently associated",
4147 MAC2STR(dst));
dd840f79 4148 return;
d9a38716 4149 }
dd840f79
JB
4150
4151 ieee802_1x_eapol_tx_status(hapd, sta, data, len, ack);
4152}
4153
4154
bcf24348
JB
4155void hostapd_client_poll_ok(struct hostapd_data *hapd, const u8 *addr)
4156{
4157 struct sta_info *sta;
4158 struct hostapd_iface *iface = hapd->iface;
4159
4160 sta = ap_get_sta(hapd, addr);
4161 if (sta == NULL && iface->num_bss > 1) {
4162 size_t j;
4163 for (j = 0; j < iface->num_bss; j++) {
4164 hapd = iface->bss[j];
4165 sta = ap_get_sta(hapd, addr);
4166 if (sta)
4167 break;
4168 }
4169 }
4170 if (sta == NULL)
4171 return;
1854eeca
JM
4172 wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_POLL_OK MACSTR,
4173 MAC2STR(sta->addr));
bcf24348
JB
4174 if (!(sta->flags & WLAN_STA_PENDING_POLL))
4175 return;
4176
4177 wpa_printf(MSG_DEBUG, "STA " MACSTR " ACKed pending "
4178 "activity poll", MAC2STR(sta->addr));
4179 sta->flags &= ~WLAN_STA_PENDING_POLL;
4180}
4181
4182
fbbfcbac
FF
4183void ieee802_11_rx_from_unknown(struct hostapd_data *hapd, const u8 *src,
4184 int wds)
f8b1f695
JM
4185{
4186 struct sta_info *sta;
4187
4188 sta = ap_get_sta(hapd, src);
1f0fdaf0
JM
4189 if (sta &&
4190 ((sta->flags & WLAN_STA_ASSOC) ||
4191 ((sta->flags & WLAN_STA_ASSOC_REQ_OK) && wds))) {
99743811
FF
4192 if (!hapd->conf->wds_sta)
4193 return;
4194
1f0fdaf0
JM
4195 if ((sta->flags & (WLAN_STA_ASSOC | WLAN_STA_ASSOC_REQ_OK)) ==
4196 WLAN_STA_ASSOC_REQ_OK) {
4197 wpa_printf(MSG_DEBUG,
4198 "Postpone 4-address WDS mode enabling for STA "
4199 MACSTR " since TX status for AssocResp is not yet known",
4200 MAC2STR(sta->addr));
4201 sta->pending_wds_enable = 1;
4202 return;
4203 }
4204
fbbfcbac 4205 if (wds && !(sta->flags & WLAN_STA_WDS)) {
69dd2967
SM
4206 int ret;
4207 char ifname_wds[IFNAMSIZ + 1];
4208
fbbfcbac
FF
4209 wpa_printf(MSG_DEBUG, "Enable 4-address WDS mode for "
4210 "STA " MACSTR " (aid %u)",
4211 MAC2STR(sta->addr), sta->aid);
4212 sta->flags |= WLAN_STA_WDS;
69dd2967
SM
4213 ret = hostapd_set_wds_sta(hapd, ifname_wds,
4214 sta->addr, sta->aid, 1);
4215 if (!ret)
4216 hostapd_set_wds_encryption(hapd, sta,
4217 ifname_wds);
fbbfcbac 4218 }
f8b1f695 4219 return;
fbbfcbac 4220 }
f8b1f695
JM
4221
4222 wpa_printf(MSG_DEBUG, "Data/PS-poll frame from not associated STA "
4223 MACSTR, MAC2STR(src));
81372e34 4224 if (is_multicast_ether_addr(src)) {
1df492df
JM
4225 /* Broadcast bit set in SA?! Ignore the frame silently. */
4226 return;
4227 }
4228
b8281964
JM
4229 if (sta && (sta->flags & WLAN_STA_ASSOC_REQ_OK)) {
4230 wpa_printf(MSG_DEBUG, "Association Response to the STA has "
4231 "already been sent, but no TX status yet known - "
4232 "ignore Class 3 frame issue with " MACSTR,
4233 MAC2STR(src));
4234 return;
4235 }
4236
f8b1f695 4237 if (sta && (sta->flags & WLAN_STA_AUTH))
51e2a27a 4238 hostapd_drv_sta_disassoc(
f8b1f695
JM
4239 hapd, src,
4240 WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA);
4241 else
51e2a27a 4242 hostapd_drv_sta_deauth(
f8b1f695
JM
4243 hapd, src,
4244 WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA);
4245}
4246
4247
6fc6879b 4248#endif /* CONFIG_NATIVE_WINDOWS */