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