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