Line data Source code
1 : /*
2 : * hostapd / IEEE 802.11 Management
3 : * Copyright (c) 2002-2014, Jouni Malinen <j@w1.fi>
4 : *
5 : * This software may be distributed under the terms of the BSD license.
6 : * See README for more details.
7 : */
8 :
9 : #include "utils/includes.h"
10 :
11 : #ifndef CONFIG_NATIVE_WINDOWS
12 :
13 : #include "utils/common.h"
14 : #include "utils/eloop.h"
15 : #include "crypto/crypto.h"
16 : #include "crypto/sha256.h"
17 : #include "crypto/random.h"
18 : #include "common/ieee802_11_defs.h"
19 : #include "common/ieee802_11_common.h"
20 : #include "common/wpa_ctrl.h"
21 : #include "common/sae.h"
22 : #include "radius/radius.h"
23 : #include "radius/radius_client.h"
24 : #include "p2p/p2p.h"
25 : #include "wps/wps.h"
26 : #include "fst/fst.h"
27 : #include "hostapd.h"
28 : #include "beacon.h"
29 : #include "ieee802_11_auth.h"
30 : #include "sta_info.h"
31 : #include "ieee802_1x.h"
32 : #include "wpa_auth.h"
33 : #include "pmksa_cache_auth.h"
34 : #include "wmm.h"
35 : #include "ap_list.h"
36 : #include "accounting.h"
37 : #include "ap_config.h"
38 : #include "ap_mlme.h"
39 : #include "p2p_hostapd.h"
40 : #include "ap_drv_ops.h"
41 : #include "wnm_ap.h"
42 : #include "hw_features.h"
43 : #include "ieee802_11.h"
44 : #include "dfs.h"
45 : #include "mbo_ap.h"
46 : #include "rrm.h"
47 : #include "taxonomy.h"
48 :
49 :
50 15251 : u8 * hostapd_eid_supp_rates(struct hostapd_data *hapd, u8 *eid)
51 : {
52 15251 : u8 *pos = eid;
53 : int i, num, count;
54 :
55 15251 : if (hapd->iface->current_rates == NULL)
56 17 : return eid;
57 :
58 15234 : *pos++ = WLAN_EID_SUPP_RATES;
59 15234 : num = hapd->iface->num_rates;
60 15234 : if (hapd->iconf->ieee80211n && hapd->iconf->require_ht)
61 17 : num++;
62 15234 : if (hapd->iconf->ieee80211ac && hapd->iconf->require_vht)
63 8 : num++;
64 15234 : if (num > 8) {
65 : /* rest of the rates are encoded in Extended supported
66 : * rates element */
67 11115 : num = 8;
68 : }
69 :
70 15234 : *pos++ = num;
71 152200 : for (i = 0, count = 0; i < hapd->iface->num_rates && count < num;
72 121732 : i++) {
73 121732 : count++;
74 121732 : *pos = hapd->iface->current_rates[i].rate / 5;
75 121732 : if (hapd->iface->current_rates[i].flags & HOSTAPD_RATE_BASIC)
76 57294 : *pos |= 0x80;
77 121732 : pos++;
78 : }
79 :
80 15234 : if (hapd->iconf->ieee80211n && hapd->iconf->require_ht && count < 8) {
81 5 : count++;
82 5 : *pos++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_HT_PHY;
83 : }
84 :
85 15234 : if (hapd->iconf->ieee80211ac && hapd->iconf->require_vht && count < 8) {
86 3 : count++;
87 3 : *pos++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_VHT_PHY;
88 : }
89 :
90 15234 : return pos;
91 : }
92 :
93 :
94 15251 : u8 * hostapd_eid_ext_supp_rates(struct hostapd_data *hapd, u8 *eid)
95 : {
96 15251 : u8 *pos = eid;
97 : int i, num, count;
98 :
99 15251 : if (hapd->iface->current_rates == NULL)
100 17 : return eid;
101 :
102 15234 : num = hapd->iface->num_rates;
103 15234 : if (hapd->iconf->ieee80211n && hapd->iconf->require_ht)
104 17 : num++;
105 15234 : if (hapd->iconf->ieee80211ac && hapd->iconf->require_vht)
106 8 : num++;
107 15234 : if (num <= 8)
108 4119 : return eid;
109 11115 : num -= 8;
110 :
111 11115 : *pos++ = WLAN_EID_EXT_SUPP_RATES;
112 11115 : *pos++ = num;
113 155590 : for (i = 0, count = 0; i < hapd->iface->num_rates && count < num + 8;
114 133360 : i++) {
115 133360 : count++;
116 133360 : if (count <= 8)
117 88920 : continue; /* already in SuppRates IE */
118 44440 : *pos = hapd->iface->current_rates[i].rate / 5;
119 44440 : if (hapd->iface->current_rates[i].flags & HOSTAPD_RATE_BASIC)
120 278 : *pos |= 0x80;
121 44440 : pos++;
122 : }
123 :
124 11115 : if (hapd->iconf->ieee80211n && hapd->iconf->require_ht) {
125 12 : count++;
126 12 : if (count > 8)
127 12 : *pos++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_HT_PHY;
128 : }
129 :
130 11115 : if (hapd->iconf->ieee80211ac && hapd->iconf->require_vht) {
131 5 : count++;
132 5 : if (count > 8)
133 5 : *pos++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_VHT_PHY;
134 : }
135 :
136 11115 : return pos;
137 : }
138 :
139 :
140 17583 : u16 hostapd_own_capab_info(struct hostapd_data *hapd)
141 : {
142 17583 : int capab = WLAN_CAPABILITY_ESS;
143 : int privacy;
144 : int dfs;
145 : int i;
146 :
147 : /* Check if any of configured channels require DFS */
148 17583 : dfs = hostapd_is_dfs_required(hapd->iface);
149 17583 : if (dfs < 0) {
150 0 : wpa_printf(MSG_WARNING, "Failed to check if DFS is required; ret=%d",
151 : dfs);
152 0 : dfs = 0;
153 : }
154 :
155 34872 : if (hapd->iface->num_sta_no_short_preamble == 0 &&
156 17289 : hapd->iconf->preamble == SHORT_PREAMBLE)
157 4 : capab |= WLAN_CAPABILITY_SHORT_PREAMBLE;
158 :
159 17583 : privacy = hapd->conf->ssid.wep.keys_set;
160 :
161 22564 : if (hapd->conf->ieee802_1x &&
162 9938 : (hapd->conf->default_wep_key_len ||
163 4957 : hapd->conf->individual_wep_key_len))
164 24 : privacy = 1;
165 :
166 17583 : if (hapd->conf->wpa)
167 12860 : privacy = 1;
168 :
169 : #ifdef CONFIG_HS20
170 17583 : if (hapd->conf->osen)
171 13 : privacy = 1;
172 : #endif /* CONFIG_HS20 */
173 :
174 17583 : if (privacy)
175 12998 : capab |= WLAN_CAPABILITY_PRIVACY;
176 :
177 35142 : if (hapd->iface->current_mode &&
178 33790 : hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G &&
179 16231 : hapd->iface->num_sta_no_short_slot_time == 0)
180 16231 : capab |= WLAN_CAPABILITY_SHORT_SLOT_TIME;
181 :
182 : /*
183 : * Currently, Spectrum Management capability bit is set when directly
184 : * requested in configuration by spectrum_mgmt_required or when AP is
185 : * running on DFS channel.
186 : * TODO: Also consider driver support for TPC to set Spectrum Mgmt bit
187 : */
188 35142 : if (hapd->iface->current_mode &&
189 18847 : hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211A &&
190 2572 : (hapd->iconf->spectrum_mgmt_required || dfs))
191 29 : capab |= WLAN_CAPABILITY_SPECTRUM_MGMT;
192 :
193 105423 : for (i = 0; i < RRM_CAPABILITIES_IE_LEN; i++) {
194 87855 : if (hapd->conf->radio_measurements[i]) {
195 15 : capab |= IEEE80211_CAP_RRM;
196 15 : break;
197 : }
198 : }
199 :
200 17583 : return capab;
201 : }
202 :
203 :
204 : #ifndef CONFIG_NO_RC4
205 26 : static u16 auth_shared_key(struct hostapd_data *hapd, struct sta_info *sta,
206 : u16 auth_transaction, const u8 *challenge,
207 : int iswep)
208 : {
209 26 : hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
210 : HOSTAPD_LEVEL_DEBUG,
211 : "authentication (shared key, transaction %d)",
212 : auth_transaction);
213 :
214 26 : if (auth_transaction == 1) {
215 13 : if (!sta->challenge) {
216 : /* Generate a pseudo-random challenge */
217 : u8 key[8];
218 :
219 13 : sta->challenge = os_zalloc(WLAN_AUTH_CHALLENGE_LEN);
220 13 : if (sta->challenge == NULL)
221 0 : return WLAN_STATUS_UNSPECIFIED_FAILURE;
222 :
223 13 : if (os_get_random(key, sizeof(key)) < 0) {
224 0 : os_free(sta->challenge);
225 0 : sta->challenge = NULL;
226 0 : return WLAN_STATUS_UNSPECIFIED_FAILURE;
227 : }
228 :
229 13 : rc4_skip(key, sizeof(key), 0,
230 : sta->challenge, WLAN_AUTH_CHALLENGE_LEN);
231 : }
232 13 : return 0;
233 : }
234 :
235 13 : if (auth_transaction != 3)
236 0 : return WLAN_STATUS_UNSPECIFIED_FAILURE;
237 :
238 : /* Transaction 3 */
239 26 : if (!iswep || !sta->challenge || !challenge ||
240 13 : os_memcmp_const(sta->challenge, challenge,
241 : WLAN_AUTH_CHALLENGE_LEN)) {
242 0 : hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
243 : HOSTAPD_LEVEL_INFO,
244 : "shared key authentication - invalid "
245 : "challenge-response");
246 0 : return WLAN_STATUS_CHALLENGE_FAIL;
247 : }
248 :
249 13 : hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
250 : HOSTAPD_LEVEL_DEBUG,
251 : "authentication OK (shared key)");
252 13 : sta->flags |= WLAN_STA_AUTH;
253 13 : wpa_auth_sm_event(sta->wpa_sm, WPA_AUTH);
254 13 : os_free(sta->challenge);
255 13 : sta->challenge = NULL;
256 :
257 13 : return 0;
258 : }
259 : #endif /* CONFIG_NO_RC4 */
260 :
261 :
262 5293 : static int send_auth_reply(struct hostapd_data *hapd,
263 : const u8 *dst, const u8 *bssid,
264 : u16 auth_alg, u16 auth_transaction, u16 resp,
265 : const u8 *ies, size_t ies_len)
266 : {
267 : struct ieee80211_mgmt *reply;
268 : u8 *buf;
269 : size_t rlen;
270 5293 : int reply_res = WLAN_STATUS_UNSPECIFIED_FAILURE;
271 :
272 5293 : rlen = IEEE80211_HDRLEN + sizeof(reply->u.auth) + ies_len;
273 5293 : buf = os_zalloc(rlen);
274 5293 : if (buf == NULL)
275 0 : return -1;
276 :
277 5293 : reply = (struct ieee80211_mgmt *) buf;
278 5293 : reply->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
279 : WLAN_FC_STYPE_AUTH);
280 5293 : os_memcpy(reply->da, dst, ETH_ALEN);
281 5293 : os_memcpy(reply->sa, hapd->own_addr, ETH_ALEN);
282 5293 : os_memcpy(reply->bssid, bssid, ETH_ALEN);
283 :
284 5293 : reply->u.auth.auth_alg = host_to_le16(auth_alg);
285 5293 : reply->u.auth.auth_transaction = host_to_le16(auth_transaction);
286 5293 : reply->u.auth.status_code = host_to_le16(resp);
287 :
288 5293 : if (ies && ies_len)
289 616 : os_memcpy(reply->u.auth.variable, ies, ies_len);
290 :
291 37051 : wpa_printf(MSG_DEBUG, "authentication reply: STA=" MACSTR
292 : " auth_alg=%d auth_transaction=%d resp=%d (IE len=%lu)",
293 31758 : MAC2STR(dst), auth_alg, auth_transaction,
294 : resp, (unsigned long) ies_len);
295 5293 : if (hostapd_drv_send_mlme(hapd, reply, rlen, 0) < 0)
296 0 : wpa_printf(MSG_INFO, "send_auth_reply: send failed");
297 : else
298 5293 : reply_res = WLAN_STATUS_SUCCESS;
299 :
300 5293 : os_free(buf);
301 :
302 5293 : return reply_res;
303 : }
304 :
305 :
306 : #ifdef CONFIG_IEEE80211R
307 123 : static void handle_auth_ft_finish(void *ctx, const u8 *dst, const u8 *bssid,
308 : u16 auth_transaction, u16 status,
309 : const u8 *ies, size_t ies_len)
310 : {
311 123 : struct hostapd_data *hapd = ctx;
312 : struct sta_info *sta;
313 : int reply_res;
314 :
315 123 : reply_res = send_auth_reply(hapd, dst, bssid, WLAN_AUTH_FT,
316 : auth_transaction, status, ies, ies_len);
317 :
318 123 : sta = ap_get_sta(hapd, dst);
319 123 : if (sta == NULL)
320 0 : return;
321 :
322 123 : if (sta->added_unassoc && (reply_res != WLAN_STATUS_SUCCESS ||
323 : status != WLAN_STATUS_SUCCESS)) {
324 0 : hostapd_drv_sta_remove(hapd, sta->addr);
325 0 : sta->added_unassoc = 0;
326 0 : return;
327 : }
328 :
329 123 : if (status != WLAN_STATUS_SUCCESS)
330 0 : return;
331 :
332 123 : hostapd_logger(hapd, dst, HOSTAPD_MODULE_IEEE80211,
333 : HOSTAPD_LEVEL_DEBUG, "authentication OK (FT)");
334 123 : sta->flags |= WLAN_STA_AUTH;
335 123 : mlme_authenticate_indication(hapd, sta);
336 : }
337 : #endif /* CONFIG_IEEE80211R */
338 :
339 :
340 : #ifdef CONFIG_SAE
341 :
342 : #define dot11RSNASAESync 5 /* attempts */
343 :
344 :
345 205 : static struct wpabuf * auth_build_sae_commit(struct hostapd_data *hapd,
346 : struct sta_info *sta, int update)
347 : {
348 : struct wpabuf *buf;
349 :
350 205 : if (hapd->conf->ssid.wpa_passphrase == NULL) {
351 0 : wpa_printf(MSG_DEBUG, "SAE: No password available");
352 0 : return NULL;
353 : }
354 :
355 317 : if (update &&
356 336 : sae_prepare_commit(hapd->own_addr, sta->addr,
357 112 : (u8 *) hapd->conf->ssid.wpa_passphrase,
358 112 : os_strlen(hapd->conf->ssid.wpa_passphrase),
359 : sta->sae) < 0) {
360 0 : wpa_printf(MSG_DEBUG, "SAE: Could not pick PWE");
361 0 : return NULL;
362 : }
363 :
364 205 : buf = wpabuf_alloc(SAE_COMMIT_MAX_LEN);
365 205 : if (buf == NULL)
366 1 : return NULL;
367 408 : sae_write_commit(sta->sae, buf, sta->sae->tmp ?
368 204 : sta->sae->tmp->anti_clogging_token : NULL);
369 :
370 204 : return buf;
371 : }
372 :
373 :
374 268 : static struct wpabuf * auth_build_sae_confirm(struct hostapd_data *hapd,
375 : struct sta_info *sta)
376 : {
377 : struct wpabuf *buf;
378 :
379 268 : buf = wpabuf_alloc(SAE_CONFIRM_MAX_LEN);
380 268 : if (buf == NULL)
381 0 : return NULL;
382 :
383 268 : sae_write_confirm(sta->sae, buf);
384 :
385 268 : return buf;
386 : }
387 :
388 :
389 205 : static int auth_sae_send_commit(struct hostapd_data *hapd,
390 : struct sta_info *sta,
391 : const u8 *bssid, int update)
392 : {
393 : struct wpabuf *data;
394 : int reply_res;
395 :
396 205 : data = auth_build_sae_commit(hapd, sta, update);
397 205 : if (data == NULL)
398 1 : return WLAN_STATUS_UNSPECIFIED_FAILURE;
399 :
400 408 : reply_res = send_auth_reply(hapd, sta->addr, bssid, WLAN_AUTH_SAE, 1,
401 204 : WLAN_STATUS_SUCCESS, wpabuf_head(data),
402 : wpabuf_len(data));
403 :
404 204 : wpabuf_free(data);
405 :
406 204 : return reply_res;
407 : }
408 :
409 :
410 268 : static int auth_sae_send_confirm(struct hostapd_data *hapd,
411 : struct sta_info *sta,
412 : const u8 *bssid)
413 : {
414 : struct wpabuf *data;
415 : int reply_res;
416 :
417 268 : data = auth_build_sae_confirm(hapd, sta);
418 268 : if (data == NULL)
419 0 : return WLAN_STATUS_UNSPECIFIED_FAILURE;
420 :
421 536 : reply_res = send_auth_reply(hapd, sta->addr, bssid, WLAN_AUTH_SAE, 2,
422 268 : WLAN_STATUS_SUCCESS, wpabuf_head(data),
423 : wpabuf_len(data));
424 :
425 268 : wpabuf_free(data);
426 :
427 268 : return reply_res;
428 : }
429 :
430 :
431 190 : static int use_sae_anti_clogging(struct hostapd_data *hapd)
432 : {
433 : struct sta_info *sta;
434 190 : unsigned int open = 0;
435 :
436 190 : if (hapd->conf->sae_anti_clogging_threshold == 0)
437 4 : return 1;
438 :
439 397 : for (sta = hapd->sta_list; sta; sta = sta->next) {
440 212 : if (!sta->sae)
441 6 : continue;
442 329 : if (sta->sae->state != SAE_COMMITTED &&
443 123 : sta->sae->state != SAE_CONFIRMED)
444 91 : continue;
445 115 : open++;
446 115 : if (open >= hapd->conf->sae_anti_clogging_threshold)
447 1 : return 1;
448 : }
449 :
450 185 : return 0;
451 : }
452 :
453 :
454 5 : static int check_sae_token(struct hostapd_data *hapd, const u8 *addr,
455 : const u8 *token, size_t token_len)
456 : {
457 : u8 mac[SHA256_MAC_LEN];
458 :
459 5 : if (token_len != SHA256_MAC_LEN)
460 0 : return -1;
461 5 : if (hmac_sha256(hapd->sae_token_key, sizeof(hapd->sae_token_key),
462 5 : addr, ETH_ALEN, mac) < 0 ||
463 5 : os_memcmp_const(token, mac, SHA256_MAC_LEN) != 0)
464 0 : return -1;
465 :
466 5 : return 0;
467 : }
468 :
469 :
470 5 : static struct wpabuf * auth_build_token_req(struct hostapd_data *hapd,
471 : int group, const u8 *addr)
472 : {
473 : struct wpabuf *buf;
474 : u8 *token;
475 : struct os_reltime now;
476 :
477 5 : os_get_reltime(&now);
478 7 : if (!os_reltime_initialized(&hapd->last_sae_token_key_update) ||
479 2 : os_reltime_expired(&now, &hapd->last_sae_token_key_update, 60)) {
480 3 : if (random_get_bytes(hapd->sae_token_key,
481 : sizeof(hapd->sae_token_key)) < 0)
482 0 : return NULL;
483 3 : wpa_hexdump(MSG_DEBUG, "SAE: Updated token key",
484 3 : hapd->sae_token_key, sizeof(hapd->sae_token_key));
485 3 : hapd->last_sae_token_key_update = now;
486 : }
487 :
488 5 : buf = wpabuf_alloc(sizeof(le16) + SHA256_MAC_LEN);
489 5 : if (buf == NULL)
490 0 : return NULL;
491 :
492 5 : wpabuf_put_le16(buf, group); /* Finite Cyclic Group */
493 :
494 5 : token = wpabuf_put(buf, SHA256_MAC_LEN);
495 5 : hmac_sha256(hapd->sae_token_key, sizeof(hapd->sae_token_key),
496 : addr, ETH_ALEN, token);
497 :
498 5 : return buf;
499 : }
500 :
501 :
502 142 : static int sae_check_big_sync(struct sta_info *sta)
503 : {
504 142 : if (sta->sae->sync > dot11RSNASAESync) {
505 13 : sta->sae->state = SAE_NOTHING;
506 13 : sta->sae->sync = 0;
507 13 : return -1;
508 : }
509 129 : return 0;
510 : }
511 :
512 :
513 110 : static void auth_sae_retransmit_timer(void *eloop_ctx, void *eloop_data)
514 : {
515 110 : struct hostapd_data *hapd = eloop_ctx;
516 110 : struct sta_info *sta = eloop_data;
517 : int ret;
518 :
519 110 : if (sae_check_big_sync(sta))
520 122 : return;
521 98 : sta->sae->sync++;
522 686 : wpa_printf(MSG_DEBUG, "SAE: Auth SAE retransmit timer for " MACSTR
523 : " (sync=%d state=%d)",
524 686 : MAC2STR(sta->addr), sta->sae->sync, sta->sae->state);
525 :
526 98 : switch (sta->sae->state) {
527 : case SAE_COMMITTED:
528 7 : ret = auth_sae_send_commit(hapd, sta, hapd->own_addr, 0);
529 7 : eloop_register_timeout(0,
530 7 : hapd->dot11RSNASAERetransPeriod * 1000,
531 : auth_sae_retransmit_timer, hapd, sta);
532 7 : break;
533 : case SAE_CONFIRMED:
534 87 : ret = auth_sae_send_confirm(hapd, sta, hapd->own_addr);
535 87 : eloop_register_timeout(0,
536 87 : hapd->dot11RSNASAERetransPeriod * 1000,
537 : auth_sae_retransmit_timer, hapd, sta);
538 87 : break;
539 : default:
540 4 : ret = -1;
541 4 : break;
542 : }
543 :
544 98 : if (ret != WLAN_STATUS_SUCCESS)
545 4 : wpa_printf(MSG_INFO, "SAE: Failed to retransmit: ret=%d", ret);
546 : }
547 :
548 :
549 4819 : void sae_clear_retransmit_timer(struct hostapd_data *hapd, struct sta_info *sta)
550 : {
551 4819 : eloop_cancel_timeout(auth_sae_retransmit_timer, hapd, sta);
552 4819 : }
553 :
554 :
555 271 : static void sae_set_retransmit_timer(struct hostapd_data *hapd,
556 : struct sta_info *sta)
557 : {
558 271 : if (!(hapd->conf->mesh & MESH_ENABLED))
559 362 : return;
560 :
561 180 : eloop_cancel_timeout(auth_sae_retransmit_timer, hapd, sta);
562 180 : eloop_register_timeout(0, hapd->dot11RSNASAERetransPeriod * 1000,
563 : auth_sae_retransmit_timer, hapd, sta);
564 : }
565 :
566 :
567 138 : void sae_accept_sta(struct hostapd_data *hapd, struct sta_info *sta)
568 : {
569 138 : sta->flags |= WLAN_STA_AUTH;
570 138 : sta->auth_alg = WLAN_AUTH_SAE;
571 138 : mlme_authenticate_indication(hapd, sta);
572 138 : wpa_auth_sm_event(sta->wpa_sm, WPA_AUTH);
573 138 : sta->sae->state = SAE_ACCEPTED;
574 138 : wpa_auth_pmksa_add_sae(hapd->wpa_auth, sta->addr,
575 138 : sta->sae->pmk, sta->sae->pmkid);
576 138 : }
577 :
578 :
579 398 : static int sae_sm_step(struct hostapd_data *hapd, struct sta_info *sta,
580 : const u8 *bssid, u8 auth_transaction)
581 : {
582 : int ret;
583 :
584 398 : if (auth_transaction != 1 && auth_transaction != 2)
585 0 : return WLAN_STATUS_UNSPECIFIED_FAILURE;
586 :
587 398 : switch (sta->sae->state) {
588 : case SAE_NOTHING:
589 93 : if (auth_transaction == 1) {
590 86 : ret = auth_sae_send_commit(hapd, sta, bssid, 1);
591 86 : if (ret)
592 0 : return ret;
593 86 : sta->sae->state = SAE_COMMITTED;
594 :
595 86 : if (sae_process_commit(sta->sae) < 0)
596 0 : return WLAN_STATUS_UNSPECIFIED_FAILURE;
597 :
598 : /*
599 : * In mesh case, both Commit and Confirm can be sent
600 : * immediately. In infrastructure BSS, only a single
601 : * Authentication frame (Commit) is expected from the AP
602 : * here and the second one (Confirm) will be sent once
603 : * the STA has sent its second Authentication frame
604 : * (Confirm).
605 : */
606 86 : if (hapd->conf->mesh & MESH_ENABLED) {
607 : /*
608 : * Send both Commit and Confirm immediately
609 : * based on SAE finite state machine
610 : * Nothing -> Confirm transition.
611 : */
612 15 : ret = auth_sae_send_confirm(hapd, sta, bssid);
613 15 : if (ret)
614 0 : return ret;
615 15 : sta->sae->state = SAE_CONFIRMED;
616 : } else {
617 : /*
618 : * For infrastructure BSS, send only the Commit
619 : * message now to get alternating sequence of
620 : * Authentication frames between the AP and STA.
621 : * Confirm will be sent in
622 : * Committed -> Confirmed/Accepted transition
623 : * when receiving Confirm from STA.
624 : */
625 : }
626 86 : sta->sae->sync = 0;
627 86 : sae_set_retransmit_timer(hapd, sta);
628 : } else {
629 7 : hostapd_logger(hapd, sta->addr,
630 : HOSTAPD_MODULE_IEEE80211,
631 : HOSTAPD_LEVEL_DEBUG,
632 : "SAE confirm before commit");
633 : }
634 93 : break;
635 : case SAE_COMMITTED:
636 145 : sae_clear_retransmit_timer(hapd, sta);
637 145 : if (auth_transaction == 1) {
638 74 : if (sae_process_commit(sta->sae) < 0)
639 0 : return WLAN_STATUS_UNSPECIFIED_FAILURE;
640 :
641 74 : ret = auth_sae_send_confirm(hapd, sta, bssid);
642 74 : if (ret)
643 0 : return ret;
644 74 : sta->sae->state = SAE_CONFIRMED;
645 74 : sta->sae->sync = 0;
646 74 : sae_set_retransmit_timer(hapd, sta);
647 71 : } else if (hapd->conf->mesh & MESH_ENABLED) {
648 : /*
649 : * In mesh case, follow SAE finite state machine and
650 : * send Commit now, if sync count allows.
651 : */
652 5 : if (sae_check_big_sync(sta))
653 0 : return WLAN_STATUS_SUCCESS;
654 5 : sta->sae->sync++;
655 :
656 5 : ret = auth_sae_send_commit(hapd, sta, bssid, 0);
657 5 : if (ret)
658 0 : return ret;
659 :
660 5 : sae_set_retransmit_timer(hapd, sta);
661 : } else {
662 : /*
663 : * For instructure BSS, send the postponed Confirm from
664 : * Nothing -> Confirmed transition that was reduced to
665 : * Nothing -> Committed above.
666 : */
667 66 : ret = auth_sae_send_confirm(hapd, sta, bssid);
668 66 : if (ret)
669 0 : return ret;
670 :
671 66 : sta->sae->state = SAE_CONFIRMED;
672 :
673 : /*
674 : * Since this was triggered on Confirm RX, run another
675 : * step to get to Accepted without waiting for
676 : * additional events.
677 : */
678 66 : return sae_sm_step(hapd, sta, bssid, auth_transaction);
679 : }
680 79 : break;
681 : case SAE_CONFIRMED:
682 157 : sae_clear_retransmit_timer(hapd, sta);
683 157 : if (auth_transaction == 1) {
684 27 : if (sae_check_big_sync(sta))
685 1 : return WLAN_STATUS_SUCCESS;
686 26 : sta->sae->sync++;
687 :
688 26 : ret = auth_sae_send_commit(hapd, sta, bssid, 1);
689 26 : if (ret)
690 0 : return ret;
691 :
692 26 : if (sae_process_commit(sta->sae) < 0)
693 0 : return WLAN_STATUS_UNSPECIFIED_FAILURE;
694 :
695 26 : ret = auth_sae_send_confirm(hapd, sta, bssid);
696 26 : if (ret)
697 0 : return ret;
698 :
699 26 : sae_set_retransmit_timer(hapd, sta);
700 : } else {
701 130 : sae_accept_sta(hapd, sta);
702 : }
703 156 : break;
704 : case SAE_ACCEPTED:
705 3 : if (auth_transaction == 1) {
706 18 : wpa_printf(MSG_DEBUG, "SAE: remove the STA (" MACSTR
707 : ") doing reauthentication",
708 18 : MAC2STR(sta->addr));
709 3 : ap_free_sta(hapd, sta);
710 3 : wpa_auth_pmksa_remove(hapd->wpa_auth, sta->addr);
711 : } else {
712 0 : if (sae_check_big_sync(sta))
713 0 : return WLAN_STATUS_SUCCESS;
714 0 : sta->sae->sync++;
715 :
716 0 : ret = auth_sae_send_confirm(hapd, sta, bssid);
717 0 : sae_clear_temp_data(sta->sae);
718 0 : if (ret)
719 0 : return ret;
720 : }
721 3 : break;
722 : default:
723 0 : wpa_printf(MSG_ERROR, "SAE: invalid state %d",
724 0 : sta->sae->state);
725 0 : return WLAN_STATUS_UNSPECIFIED_FAILURE;
726 : }
727 331 : return WLAN_STATUS_SUCCESS;
728 : }
729 :
730 :
731 17 : static void sae_pick_next_group(struct hostapd_data *hapd, struct sta_info *sta)
732 : {
733 17 : struct sae_data *sae = sta->sae;
734 17 : int i, *groups = hapd->conf->sae_groups;
735 :
736 17 : if (sae->state != SAE_COMMITTED)
737 0 : return;
738 :
739 17 : wpa_printf(MSG_DEBUG, "SAE: Previously selected group: %d", sae->group);
740 :
741 18 : for (i = 0; groups && groups[i] > 0; i++) {
742 18 : if (sae->group == groups[i])
743 17 : break;
744 : }
745 :
746 17 : if (!groups || groups[i] <= 0) {
747 0 : wpa_printf(MSG_DEBUG,
748 : "SAE: Previously selected group not found from the current configuration");
749 0 : return;
750 : }
751 :
752 : for (;;) {
753 17 : i++;
754 17 : if (groups[i] <= 0) {
755 11 : wpa_printf(MSG_DEBUG,
756 : "SAE: No alternative group enabled");
757 11 : return;
758 : }
759 :
760 6 : if (sae_set_group(sae, groups[i]) < 0)
761 0 : continue;
762 :
763 6 : break;
764 0 : }
765 6 : wpa_printf(MSG_DEBUG, "SAE: Selected new group: %d", groups[i]);
766 : }
767 :
768 :
769 588 : static void handle_auth_sae(struct hostapd_data *hapd, struct sta_info *sta,
770 : const struct ieee80211_mgmt *mgmt, size_t len,
771 : u16 auth_transaction, u16 status_code)
772 : {
773 588 : int resp = WLAN_STATUS_SUCCESS;
774 588 : struct wpabuf *data = NULL;
775 :
776 588 : if (!sta->sae) {
777 77 : if (auth_transaction != 1 ||
778 : status_code != WLAN_STATUS_SUCCESS) {
779 0 : resp = -1;
780 0 : goto remove_sta;
781 : }
782 77 : sta->sae = os_zalloc(sizeof(*sta->sae));
783 77 : if (!sta->sae) {
784 0 : resp = -1;
785 0 : goto remove_sta;
786 : }
787 77 : sta->sae->state = SAE_NOTHING;
788 77 : sta->sae->sync = 0;
789 : }
790 :
791 588 : if (sta->mesh_sae_pmksa_caching) {
792 0 : wpa_printf(MSG_DEBUG,
793 : "SAE: Cancel use of mesh PMKSA caching because peer starts SAE authentication");
794 0 : wpa_auth_pmksa_remove(hapd->wpa_auth, sta->addr);
795 0 : sta->mesh_sae_pmksa_caching = 0;
796 : }
797 :
798 588 : if (auth_transaction == 1) {
799 234 : const u8 *token = NULL, *pos, *end;
800 234 : size_t token_len = 0;
801 234 : hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
802 : HOSTAPD_LEVEL_DEBUG,
803 : "start SAE authentication (RX commit, status=%u)",
804 : status_code);
805 :
806 234 : if ((hapd->conf->mesh & MESH_ENABLED) &&
807 0 : status_code == WLAN_STATUS_ANTI_CLOGGING_TOKEN_REQ &&
808 0 : sta->sae->tmp) {
809 0 : pos = mgmt->u.auth.variable;
810 0 : end = ((const u8 *) mgmt) + len;
811 0 : if (pos + sizeof(le16) > end) {
812 0 : wpa_printf(MSG_ERROR,
813 : "SAE: Too short anti-clogging token request");
814 0 : resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
815 27 : goto reply;
816 : }
817 0 : resp = sae_group_allowed(sta->sae,
818 0 : hapd->conf->sae_groups,
819 0 : WPA_GET_LE16(pos));
820 0 : if (resp != WLAN_STATUS_SUCCESS) {
821 0 : wpa_printf(MSG_ERROR,
822 : "SAE: Invalid group in anti-clogging token request");
823 0 : goto reply;
824 : }
825 0 : pos += sizeof(le16);
826 :
827 0 : wpabuf_free(sta->sae->tmp->anti_clogging_token);
828 0 : sta->sae->tmp->anti_clogging_token =
829 0 : wpabuf_alloc_copy(pos, end - pos);
830 0 : if (sta->sae->tmp->anti_clogging_token == NULL) {
831 0 : wpa_printf(MSG_ERROR,
832 : "SAE: Failed to alloc for anti-clogging token");
833 0 : resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
834 17 : goto remove_sta;
835 : }
836 :
837 : /*
838 : * IEEE Std 802.11-2012, 11.3.8.6.4: If the Status code
839 : * is 76, a new Commit Message shall be constructed
840 : * with the Anti-Clogging Token from the received
841 : * Authentication frame, and the commit-scalar and
842 : * COMMIT-ELEMENT previously sent.
843 : */
844 0 : resp = auth_sae_send_commit(hapd, sta, mgmt->bssid, 0);
845 0 : if (resp != WLAN_STATUS_SUCCESS) {
846 0 : wpa_printf(MSG_ERROR,
847 : "SAE: Failed to send commit message");
848 0 : goto remove_sta;
849 : }
850 0 : sta->sae->state = SAE_COMMITTED;
851 0 : sta->sae->sync = 0;
852 0 : sae_set_retransmit_timer(hapd, sta);
853 588 : return;
854 : }
855 :
856 234 : if ((hapd->conf->mesh & MESH_ENABLED) &&
857 : status_code ==
858 17 : WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED &&
859 17 : sta->sae->tmp) {
860 17 : wpa_printf(MSG_DEBUG,
861 : "SAE: Peer did not accept our SAE group");
862 17 : sae_pick_next_group(hapd, sta);
863 17 : goto remove_sta;
864 : }
865 :
866 217 : if (status_code != WLAN_STATUS_SUCCESS)
867 0 : goto remove_sta;
868 :
869 434 : resp = sae_parse_commit(sta->sae, mgmt->u.auth.variable,
870 217 : ((const u8 *) mgmt) + len -
871 : mgmt->u.auth.variable, &token,
872 217 : &token_len, hapd->conf->sae_groups);
873 217 : if (resp == SAE_SILENTLY_DISCARD) {
874 0 : wpa_printf(MSG_DEBUG,
875 : "SAE: Drop commit message from " MACSTR " due to reflection attack",
876 0 : MAC2STR(sta->addr));
877 0 : goto remove_sta;
878 : }
879 217 : if (token && check_sae_token(hapd, sta->addr, token, token_len)
880 : < 0) {
881 0 : wpa_printf(MSG_DEBUG, "SAE: Drop commit message with "
882 : "incorrect token from " MACSTR,
883 0 : MAC2STR(sta->addr));
884 0 : resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
885 0 : goto remove_sta;
886 : }
887 :
888 217 : if (resp != WLAN_STATUS_SUCCESS)
889 22 : goto reply;
890 :
891 195 : if (!token && use_sae_anti_clogging(hapd)) {
892 30 : wpa_printf(MSG_DEBUG,
893 : "SAE: Request anti-clogging token from "
894 30 : MACSTR, MAC2STR(sta->addr));
895 5 : data = auth_build_token_req(hapd, sta->sae->group,
896 5 : sta->addr);
897 5 : resp = WLAN_STATUS_ANTI_CLOGGING_TOKEN_REQ;
898 5 : if (hapd->conf->mesh & MESH_ENABLED)
899 0 : sta->sae->state = SAE_NOTHING;
900 5 : goto reply;
901 : }
902 :
903 190 : resp = sae_sm_step(hapd, sta, mgmt->bssid, auth_transaction);
904 354 : } else if (auth_transaction == 2) {
905 354 : hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
906 : HOSTAPD_LEVEL_DEBUG,
907 : "SAE authentication (RX confirm, status=%u)",
908 : status_code);
909 354 : if (status_code != WLAN_STATUS_SUCCESS)
910 106 : goto remove_sta;
911 326 : if (sta->sae->state >= SAE_CONFIRMED ||
912 78 : !(hapd->conf->mesh & MESH_ENABLED)) {
913 236 : if (sae_check_confirm(sta->sae, mgmt->u.auth.variable,
914 236 : ((u8 *) mgmt) + len -
915 : mgmt->u.auth.variable) < 0) {
916 106 : resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
917 106 : goto reply;
918 : }
919 : }
920 142 : resp = sae_sm_step(hapd, sta, mgmt->bssid, auth_transaction);
921 : } else {
922 0 : hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
923 : HOSTAPD_LEVEL_DEBUG,
924 : "unexpected SAE authentication transaction %u (status=%u)",
925 : auth_transaction, status_code);
926 0 : if (status_code != WLAN_STATUS_SUCCESS)
927 0 : goto remove_sta;
928 0 : resp = WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION;
929 : }
930 :
931 : reply:
932 465 : if (resp != WLAN_STATUS_SUCCESS) {
933 133 : send_auth_reply(hapd, mgmt->sa, mgmt->bssid, WLAN_AUTH_SAE,
934 : auth_transaction, resp,
935 : data ? wpabuf_head(data) : (u8 *) "",
936 : data ? wpabuf_len(data) : 0);
937 : }
938 :
939 : remove_sta:
940 588 : if (sta->added_unassoc && (resp != WLAN_STATUS_SUCCESS ||
941 : status_code != WLAN_STATUS_SUCCESS)) {
942 10 : hostapd_drv_sta_remove(hapd, sta->addr);
943 10 : sta->added_unassoc = 0;
944 : }
945 588 : wpabuf_free(data);
946 : }
947 :
948 :
949 : /**
950 : * auth_sae_init_committed - Send COMMIT and start SAE in committed state
951 : * @hapd: BSS data for the device initiating the authentication
952 : * @sta: the peer to which commit authentication frame is sent
953 : *
954 : * This function implements Init event handling (IEEE Std 802.11-2012,
955 : * 11.3.8.6.3) in which initial COMMIT message is sent. Prior to calling, the
956 : * sta->sae structure should be initialized appropriately via a call to
957 : * sae_prepare_commit().
958 : */
959 81 : int auth_sae_init_committed(struct hostapd_data *hapd, struct sta_info *sta)
960 : {
961 : int ret;
962 :
963 81 : if (!sta->sae || !sta->sae->tmp)
964 0 : return -1;
965 :
966 81 : if (sta->sae->state != SAE_NOTHING)
967 0 : return -1;
968 :
969 81 : ret = auth_sae_send_commit(hapd, sta, hapd->own_addr, 0);
970 81 : if (ret)
971 1 : return -1;
972 :
973 80 : sta->sae->state = SAE_COMMITTED;
974 80 : sta->sae->sync = 0;
975 80 : sae_set_retransmit_timer(hapd, sta);
976 :
977 80 : return 0;
978 : }
979 :
980 : #endif /* CONFIG_SAE */
981 :
982 :
983 5299 : static void handle_auth(struct hostapd_data *hapd,
984 : const struct ieee80211_mgmt *mgmt, size_t len)
985 : {
986 : u16 auth_alg, auth_transaction, status_code;
987 5299 : u16 resp = WLAN_STATUS_SUCCESS;
988 5299 : struct sta_info *sta = NULL;
989 : int res, reply_res;
990 : u16 fc;
991 5299 : const u8 *challenge = NULL;
992 : u32 session_timeout, acct_interim_interval;
993 : struct vlan_description vlan_id;
994 5299 : struct hostapd_sta_wpa_psk_short *psk = NULL;
995 : u8 resp_ies[2 + WLAN_AUTH_CHALLENGE_LEN];
996 5299 : size_t resp_ies_len = 0;
997 5299 : char *identity = NULL;
998 5299 : char *radius_cui = NULL;
999 : u16 seq_ctrl;
1000 :
1001 5299 : os_memset(&vlan_id, 0, sizeof(vlan_id));
1002 :
1003 5299 : if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.auth)) {
1004 0 : wpa_printf(MSG_INFO, "handle_auth - too short payload (len=%lu)",
1005 : (unsigned long) len);
1006 0 : return;
1007 : }
1008 :
1009 : #ifdef CONFIG_TESTING_OPTIONS
1010 5310 : if (hapd->iconf->ignore_auth_probability > 0.0 &&
1011 11 : drand48() < hapd->iconf->ignore_auth_probability) {
1012 48 : wpa_printf(MSG_INFO,
1013 : "TESTING: ignoring auth frame from " MACSTR,
1014 48 : MAC2STR(mgmt->sa));
1015 8 : return;
1016 : }
1017 : #endif /* CONFIG_TESTING_OPTIONS */
1018 :
1019 5291 : auth_alg = le_to_host16(mgmt->u.auth.auth_alg);
1020 5291 : auth_transaction = le_to_host16(mgmt->u.auth.auth_transaction);
1021 5291 : status_code = le_to_host16(mgmt->u.auth.status_code);
1022 5291 : fc = le_to_host16(mgmt->frame_control);
1023 5291 : seq_ctrl = le_to_host16(mgmt->seq_ctrl);
1024 :
1025 5291 : if (len >= IEEE80211_HDRLEN + sizeof(mgmt->u.auth) +
1026 186 : 2 + WLAN_AUTH_CHALLENGE_LEN &&
1027 200 : mgmt->u.auth.variable[0] == WLAN_EID_CHALLENGE &&
1028 14 : mgmt->u.auth.variable[1] == WLAN_AUTH_CHALLENGE_LEN)
1029 13 : challenge = &mgmt->u.auth.variable[2];
1030 :
1031 42328 : wpa_printf(MSG_DEBUG, "authentication: STA=" MACSTR " auth_alg=%d "
1032 : "auth_transaction=%d status_code=%d wep=%d%s "
1033 : "seq_ctrl=0x%x%s",
1034 31746 : MAC2STR(mgmt->sa), auth_alg, auth_transaction,
1035 5291 : status_code, !!(fc & WLAN_FC_ISWEP),
1036 : challenge ? " challenge" : "",
1037 5291 : seq_ctrl, (fc & WLAN_FC_RETRY) ? " retry" : "");
1038 :
1039 : #ifdef CONFIG_NO_RC4
1040 : if (auth_alg == WLAN_AUTH_SHARED_KEY) {
1041 : wpa_printf(MSG_INFO,
1042 : "Unsupported authentication algorithm (%d)",
1043 : auth_alg);
1044 : resp = WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG;
1045 : goto fail;
1046 : }
1047 : #endif /* CONFIG_NO_RC4 */
1048 :
1049 5291 : if (hapd->tkip_countermeasures) {
1050 2 : resp = WLAN_REASON_MICHAEL_MIC_FAILURE;
1051 2 : goto fail;
1052 : }
1053 :
1054 5323 : if (!(((hapd->conf->auth_algs & WPA_AUTH_ALG_OPEN) &&
1055 750 : auth_alg == WLAN_AUTH_OPEN) ||
1056 : #ifdef CONFIG_IEEE80211R
1057 1466 : (hapd->conf->wpa && wpa_key_mgmt_ft(hapd->conf->wpa_key_mgmt) &&
1058 624 : auth_alg == WLAN_AUTH_FT) ||
1059 : #endif /* CONFIG_IEEE80211R */
1060 : #ifdef CONFIG_SAE
1061 1214 : (hapd->conf->wpa && wpa_key_mgmt_sae(hapd->conf->wpa_key_mgmt) &&
1062 : auth_alg == WLAN_AUTH_SAE) ||
1063 : #endif /* CONFIG_SAE */
1064 64 : ((hapd->conf->auth_algs & WPA_AUTH_ALG_SHARED) &&
1065 : auth_alg == WLAN_AUTH_SHARED_KEY))) {
1066 8 : wpa_printf(MSG_INFO, "Unsupported authentication algorithm (%d)",
1067 : auth_alg);
1068 8 : resp = WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG;
1069 8 : goto fail;
1070 : }
1071 :
1072 5281 : if (!(auth_transaction == 1 || auth_alg == WLAN_AUTH_SAE ||
1073 13 : (auth_alg == WLAN_AUTH_SHARED_KEY && auth_transaction == 3))) {
1074 0 : wpa_printf(MSG_INFO, "Unknown authentication transaction number (%d)",
1075 : auth_transaction);
1076 0 : resp = WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION;
1077 0 : goto fail;
1078 : }
1079 :
1080 5281 : if (os_memcmp(mgmt->sa, hapd->own_addr, ETH_ALEN) == 0) {
1081 0 : wpa_printf(MSG_INFO, "Station " MACSTR " not allowed to authenticate",
1082 0 : MAC2STR(mgmt->sa));
1083 0 : resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1084 0 : goto fail;
1085 : }
1086 :
1087 5281 : if (hapd->conf->no_auth_if_seen_on) {
1088 : struct hostapd_data *other;
1089 :
1090 4 : other = sta_track_seen_on(hapd->iface, mgmt->sa,
1091 4 : hapd->conf->no_auth_if_seen_on);
1092 4 : if (other) {
1093 : u8 *pos;
1094 : u32 info;
1095 : u8 op_class, channel, phytype;
1096 :
1097 24 : wpa_printf(MSG_DEBUG, "%s: Reject authentication from "
1098 : MACSTR " since STA has been seen on %s",
1099 21 : hapd->conf->iface, MAC2STR(mgmt->sa),
1100 3 : hapd->conf->no_auth_if_seen_on);
1101 :
1102 3 : resp = WLAN_STATUS_REJECTED_WITH_SUGGESTED_BSS_TRANSITION;
1103 3 : pos = &resp_ies[0];
1104 3 : *pos++ = WLAN_EID_NEIGHBOR_REPORT;
1105 3 : *pos++ = 13;
1106 3 : os_memcpy(pos, other->own_addr, ETH_ALEN);
1107 3 : pos += ETH_ALEN;
1108 3 : info = 0; /* TODO: BSSID Information */
1109 3 : WPA_PUT_LE32(pos, info);
1110 3 : pos += 4;
1111 3 : if (other->iconf->hw_mode == HOSTAPD_MODE_IEEE80211AD)
1112 0 : phytype = 8; /* dmg */
1113 3 : else if (other->iconf->ieee80211ac)
1114 0 : phytype = 9; /* vht */
1115 3 : else if (other->iconf->ieee80211n)
1116 3 : phytype = 7; /* ht */
1117 0 : else if (other->iconf->hw_mode ==
1118 : HOSTAPD_MODE_IEEE80211A)
1119 0 : phytype = 4; /* ofdm */
1120 0 : else if (other->iconf->hw_mode ==
1121 : HOSTAPD_MODE_IEEE80211G)
1122 0 : phytype = 6; /* erp */
1123 : else
1124 0 : phytype = 5; /* hrdsss */
1125 9 : if (ieee80211_freq_to_channel_ext(
1126 3 : hostapd_hw_get_freq(other,
1127 3 : other->iconf->channel),
1128 3 : other->iconf->secondary_channel,
1129 3 : other->iconf->ieee80211ac,
1130 : &op_class, &channel) == NUM_HOSTAPD_MODES) {
1131 0 : op_class = 0;
1132 0 : channel = other->iconf->channel;
1133 : }
1134 3 : *pos++ = op_class;
1135 3 : *pos++ = channel;
1136 3 : *pos++ = phytype;
1137 3 : resp_ies_len = pos - &resp_ies[0];
1138 3 : goto fail;
1139 : }
1140 : }
1141 :
1142 5278 : res = hostapd_allowed_address(hapd, mgmt->sa, (u8 *) mgmt, len,
1143 : &session_timeout,
1144 : &acct_interim_interval, &vlan_id,
1145 : &psk, &identity, &radius_cui);
1146 :
1147 5278 : if (res == HOSTAPD_ACL_REJECT) {
1148 126 : wpa_printf(MSG_INFO, "Station " MACSTR " not allowed to authenticate",
1149 126 : MAC2STR(mgmt->sa));
1150 21 : resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1151 21 : goto fail;
1152 : }
1153 5257 : if (res == HOSTAPD_ACL_PENDING) {
1154 60 : wpa_printf(MSG_DEBUG, "Authentication frame from " MACSTR
1155 : " waiting for an external authentication",
1156 60 : MAC2STR(mgmt->sa));
1157 : /* Authentication code will re-send the authentication frame
1158 : * after it has received (and cached) information from the
1159 : * external source. */
1160 10 : return;
1161 : }
1162 :
1163 5247 : sta = ap_get_sta(hapd, mgmt->sa);
1164 5247 : if (sta) {
1165 914 : if ((fc & WLAN_FC_RETRY) &&
1166 0 : sta->last_seq_ctrl != WLAN_INVALID_MGMT_SEQ &&
1167 0 : sta->last_seq_ctrl == seq_ctrl &&
1168 0 : sta->last_subtype == WLAN_FC_STYPE_AUTH) {
1169 0 : hostapd_logger(hapd, sta->addr,
1170 : HOSTAPD_MODULE_IEEE80211,
1171 : HOSTAPD_LEVEL_DEBUG,
1172 : "Drop repeated authentication frame seq_ctrl=0x%x",
1173 : seq_ctrl);
1174 0 : return;
1175 : }
1176 : #ifdef CONFIG_MESH
1177 850 : if ((hapd->conf->mesh & MESH_ENABLED) &&
1178 420 : sta->plink_state == PLINK_BLOCKED) {
1179 0 : wpa_printf(MSG_DEBUG, "Mesh peer " MACSTR
1180 : " is blocked - drop Authentication frame",
1181 0 : MAC2STR(mgmt->sa));
1182 0 : return;
1183 : }
1184 : #endif /* CONFIG_MESH */
1185 : } else {
1186 : #ifdef CONFIG_MESH
1187 568 : if (hapd->conf->mesh & MESH_ENABLED) {
1188 : /* if the mesh peer is not available, we don't do auth.
1189 : */
1190 12 : wpa_printf(MSG_DEBUG, "Mesh peer " MACSTR
1191 : " not yet known - drop Authentication frame",
1192 12 : MAC2STR(mgmt->sa));
1193 : /*
1194 : * Save a copy of the frame so that it can be processed
1195 : * if a new peer entry is added shortly after this.
1196 : */
1197 2 : wpabuf_free(hapd->mesh_pending_auth);
1198 2 : hapd->mesh_pending_auth = wpabuf_alloc_copy(mgmt, len);
1199 2 : os_get_reltime(&hapd->mesh_pending_auth_time);
1200 2 : return;
1201 : }
1202 : #endif /* CONFIG_MESH */
1203 :
1204 4331 : sta = ap_sta_add(hapd, mgmt->sa);
1205 4331 : if (!sta) {
1206 4 : resp = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
1207 4 : goto fail;
1208 : }
1209 : }
1210 5241 : sta->last_seq_ctrl = seq_ctrl;
1211 5241 : sta->last_subtype = WLAN_FC_STYPE_AUTH;
1212 :
1213 5253 : if (vlan_id.notempty &&
1214 12 : !hostapd_vlan_valid(hapd->conf->vlan, &vlan_id)) {
1215 0 : hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_RADIUS,
1216 : HOSTAPD_LEVEL_INFO,
1217 : "Invalid VLAN %d%s received from RADIUS server",
1218 : vlan_id.untagged,
1219 0 : vlan_id.tagged[0] ? "+" : "");
1220 0 : resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1221 0 : goto fail;
1222 : }
1223 5241 : if (ap_sta_set_vlan(hapd, sta, &vlan_id) < 0) {
1224 0 : resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1225 0 : goto fail;
1226 : }
1227 5241 : if (sta->vlan_id)
1228 22 : hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_RADIUS,
1229 : HOSTAPD_LEVEL_INFO, "VLAN ID %d", sta->vlan_id);
1230 :
1231 5241 : hostapd_free_psk_list(sta->psk);
1232 5241 : if (hapd->conf->wpa_psk_radius != PSK_RADIUS_IGNORED) {
1233 2 : sta->psk = psk;
1234 2 : psk = NULL;
1235 : } else {
1236 5239 : sta->psk = NULL;
1237 : }
1238 :
1239 5241 : sta->identity = identity;
1240 5241 : identity = NULL;
1241 5241 : sta->radius_cui = radius_cui;
1242 5241 : radius_cui = NULL;
1243 :
1244 5241 : sta->flags &= ~WLAN_STA_PREAUTH;
1245 5241 : ieee802_1x_notify_pre_auth(sta->eapol_sm, 0);
1246 :
1247 5241 : if (hapd->conf->acct_interim_interval == 0 && acct_interim_interval)
1248 0 : sta->acct_interim_interval = acct_interim_interval;
1249 5241 : if (res == HOSTAPD_ACL_ACCEPT_TIMEOUT)
1250 0 : ap_sta_session_timeout(hapd, sta, session_timeout);
1251 : else
1252 5241 : ap_sta_no_session_timeout(hapd, sta);
1253 :
1254 : /*
1255 : * If the driver supports full AP client state, add a station to the
1256 : * driver before sending authentication reply to make sure the driver
1257 : * has resources, and not to go through the entire authentication and
1258 : * association handshake, and fail it at the end.
1259 : *
1260 : * If this is not the first transaction, in a multi-step authentication
1261 : * algorithm, the station already exists in the driver
1262 : * (sta->added_unassoc = 1) so skip it.
1263 : *
1264 : * In mesh mode, the station was already added to the driver when the
1265 : * NEW_PEER_CANDIDATE event is received.
1266 : */
1267 10482 : if (FULL_AP_CLIENT_STATE_SUPP(hapd->iface->drv_flags) &&
1268 10062 : !(hapd->conf->mesh & MESH_ENABLED) &&
1269 4821 : !(sta->added_unassoc)) {
1270 : /*
1271 : * If a station that is already associated to the AP, is trying
1272 : * to authenticate again, remove the STA entry, in order to make
1273 : * sure the STA PS state gets cleared and configuration gets
1274 : * updated. To handle this, station's added_unassoc flag is
1275 : * cleared once the station has completed association.
1276 : */
1277 4708 : hostapd_drv_sta_remove(hapd, sta->addr);
1278 4708 : sta->flags &= ~(WLAN_STA_ASSOC | WLAN_STA_AUTH |
1279 : WLAN_STA_AUTHORIZED);
1280 :
1281 4708 : if (hostapd_sta_add(hapd, sta->addr, 0, 0, NULL, 0, 0,
1282 : NULL, NULL, sta->flags, 0, 0, 0, 0)) {
1283 0 : hostapd_logger(hapd, sta->addr,
1284 : HOSTAPD_MODULE_IEEE80211,
1285 : HOSTAPD_LEVEL_NOTICE,
1286 : "Could not add STA to kernel driver");
1287 0 : resp = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
1288 0 : goto fail;
1289 : }
1290 :
1291 4708 : sta->added_unassoc = 1;
1292 : }
1293 :
1294 5241 : switch (auth_alg) {
1295 : case WLAN_AUTH_OPEN:
1296 4501 : hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
1297 : HOSTAPD_LEVEL_DEBUG,
1298 : "authentication OK (open system)");
1299 4501 : sta->flags |= WLAN_STA_AUTH;
1300 4501 : wpa_auth_sm_event(sta->wpa_sm, WPA_AUTH);
1301 4501 : sta->auth_alg = WLAN_AUTH_OPEN;
1302 4501 : mlme_authenticate_indication(hapd, sta);
1303 4501 : break;
1304 : #ifndef CONFIG_NO_RC4
1305 : case WLAN_AUTH_SHARED_KEY:
1306 26 : resp = auth_shared_key(hapd, sta, auth_transaction, challenge,
1307 : fc & WLAN_FC_ISWEP);
1308 26 : sta->auth_alg = WLAN_AUTH_SHARED_KEY;
1309 26 : mlme_authenticate_indication(hapd, sta);
1310 26 : if (sta->challenge && auth_transaction == 1) {
1311 13 : resp_ies[0] = WLAN_EID_CHALLENGE;
1312 13 : resp_ies[1] = WLAN_AUTH_CHALLENGE_LEN;
1313 13 : os_memcpy(resp_ies + 2, sta->challenge,
1314 : WLAN_AUTH_CHALLENGE_LEN);
1315 13 : resp_ies_len = 2 + WLAN_AUTH_CHALLENGE_LEN;
1316 : }
1317 26 : break;
1318 : #endif /* CONFIG_NO_RC4 */
1319 : #ifdef CONFIG_IEEE80211R
1320 : case WLAN_AUTH_FT:
1321 126 : sta->auth_alg = WLAN_AUTH_FT;
1322 126 : if (sta->wpa_sm == NULL)
1323 12 : sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth,
1324 12 : sta->addr, NULL);
1325 126 : if (sta->wpa_sm == NULL) {
1326 0 : wpa_printf(MSG_DEBUG, "FT: Failed to initialize WPA "
1327 : "state machine");
1328 0 : resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1329 0 : goto fail;
1330 : }
1331 252 : wpa_ft_process_auth(sta->wpa_sm, mgmt->bssid,
1332 126 : auth_transaction, mgmt->u.auth.variable,
1333 : len - IEEE80211_HDRLEN -
1334 : sizeof(mgmt->u.auth),
1335 : handle_auth_ft_finish, hapd);
1336 : /* handle_auth_ft_finish() callback will complete auth. */
1337 126 : return;
1338 : #endif /* CONFIG_IEEE80211R */
1339 : #ifdef CONFIG_SAE
1340 : case WLAN_AUTH_SAE:
1341 : #ifdef CONFIG_MESH
1342 717 : if (status_code == WLAN_STATUS_SUCCESS &&
1343 297 : hapd->conf->mesh & MESH_ENABLED) {
1344 297 : if (sta->wpa_sm == NULL)
1345 78 : sta->wpa_sm =
1346 78 : wpa_auth_sta_init(hapd->wpa_auth,
1347 78 : sta->addr, NULL);
1348 297 : if (sta->wpa_sm == NULL) {
1349 0 : wpa_printf(MSG_DEBUG,
1350 : "SAE: Failed to initialize WPA state machine");
1351 0 : resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1352 0 : goto fail;
1353 : }
1354 : }
1355 : #endif /* CONFIG_MESH */
1356 588 : handle_auth_sae(hapd, sta, mgmt, len, auth_transaction,
1357 : status_code);
1358 588 : return;
1359 : #endif /* CONFIG_SAE */
1360 : }
1361 :
1362 : fail:
1363 4565 : os_free(identity);
1364 4565 : os_free(radius_cui);
1365 4565 : hostapd_free_psk_list(psk);
1366 :
1367 4565 : reply_res = send_auth_reply(hapd, mgmt->sa, mgmt->bssid, auth_alg,
1368 : auth_transaction + 1, resp, resp_ies,
1369 : resp_ies_len);
1370 :
1371 4565 : if (sta && sta->added_unassoc && (resp != WLAN_STATUS_SUCCESS ||
1372 : reply_res != WLAN_STATUS_SUCCESS)) {
1373 0 : hostapd_drv_sta_remove(hapd, sta->addr);
1374 0 : sta->added_unassoc = 0;
1375 : }
1376 : }
1377 :
1378 :
1379 4913 : int hostapd_get_aid(struct hostapd_data *hapd, struct sta_info *sta)
1380 : {
1381 4913 : int i, j = 32, aid;
1382 :
1383 : /* get a unique AID */
1384 4913 : if (sta->aid > 0) {
1385 448 : wpa_printf(MSG_DEBUG, " old AID %d", sta->aid);
1386 448 : return 0;
1387 : }
1388 :
1389 4465 : if (TEST_FAIL())
1390 1 : return -1;
1391 :
1392 4464 : for (i = 0; i < AID_WORDS; i++) {
1393 4464 : if (hapd->sta_aid[i] == (u32) -1)
1394 0 : continue;
1395 5201 : for (j = 0; j < 32; j++) {
1396 5201 : if (!(hapd->sta_aid[i] & BIT(j)))
1397 4464 : break;
1398 : }
1399 4464 : if (j < 32)
1400 4464 : break;
1401 : }
1402 4464 : if (j == 32)
1403 0 : return -1;
1404 4464 : aid = i * 32 + j + 1;
1405 4464 : if (aid > 2007)
1406 0 : return -1;
1407 :
1408 4464 : sta->aid = aid;
1409 4464 : hapd->sta_aid[i] |= BIT(j);
1410 4464 : wpa_printf(MSG_DEBUG, " new AID %d", sta->aid);
1411 4464 : return 0;
1412 : }
1413 :
1414 :
1415 4803 : static u16 check_ssid(struct hostapd_data *hapd, struct sta_info *sta,
1416 : const u8 *ssid_ie, size_t ssid_ie_len)
1417 : {
1418 4803 : if (ssid_ie == NULL)
1419 0 : return WLAN_STATUS_UNSPECIFIED_FAILURE;
1420 :
1421 9606 : if (ssid_ie_len != hapd->conf->ssid.ssid_len ||
1422 4803 : os_memcmp(ssid_ie, hapd->conf->ssid.ssid, ssid_ie_len) != 0) {
1423 0 : hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
1424 : HOSTAPD_LEVEL_INFO,
1425 : "Station tried to associate with unknown SSID "
1426 : "'%s'", wpa_ssid_txt(ssid_ie, ssid_ie_len));
1427 0 : return WLAN_STATUS_UNSPECIFIED_FAILURE;
1428 : }
1429 :
1430 4803 : return WLAN_STATUS_SUCCESS;
1431 : }
1432 :
1433 :
1434 4803 : static u16 check_wmm(struct hostapd_data *hapd, struct sta_info *sta,
1435 : const u8 *wmm_ie, size_t wmm_ie_len)
1436 : {
1437 4803 : sta->flags &= ~WLAN_STA_WMM;
1438 4803 : sta->qosinfo = 0;
1439 4803 : if (wmm_ie && hapd->conf->wmm_enabled) {
1440 : struct wmm_information_element *wmm;
1441 :
1442 4792 : if (!hostapd_eid_wmm_valid(hapd, wmm_ie, wmm_ie_len)) {
1443 0 : hostapd_logger(hapd, sta->addr,
1444 : HOSTAPD_MODULE_WPA,
1445 : HOSTAPD_LEVEL_DEBUG,
1446 : "invalid WMM element in association "
1447 : "request");
1448 0 : return WLAN_STATUS_UNSPECIFIED_FAILURE;
1449 : }
1450 :
1451 4792 : sta->flags |= WLAN_STA_WMM;
1452 4792 : wmm = (struct wmm_information_element *) wmm_ie;
1453 4792 : sta->qosinfo = wmm->qos_info;
1454 : }
1455 4803 : return WLAN_STATUS_SUCCESS;
1456 : }
1457 :
1458 :
1459 4803 : static u16 copy_supp_rates(struct hostapd_data *hapd, struct sta_info *sta,
1460 : struct ieee802_11_elems *elems)
1461 : {
1462 4803 : if (!elems->supp_rates) {
1463 0 : hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
1464 : HOSTAPD_LEVEL_DEBUG,
1465 : "No supported rates element in AssocReq");
1466 0 : return WLAN_STATUS_UNSPECIFIED_FAILURE;
1467 : }
1468 :
1469 4803 : if (elems->supp_rates_len + elems->ext_supp_rates_len >
1470 : sizeof(sta->supported_rates)) {
1471 0 : hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
1472 : HOSTAPD_LEVEL_DEBUG,
1473 : "Invalid supported rates element length %d+%d",
1474 0 : elems->supp_rates_len,
1475 0 : elems->ext_supp_rates_len);
1476 0 : return WLAN_STATUS_UNSPECIFIED_FAILURE;
1477 : }
1478 :
1479 14409 : sta->supported_rates_len = merge_byte_arrays(
1480 4803 : sta->supported_rates, sizeof(sta->supported_rates),
1481 4803 : elems->supp_rates, elems->supp_rates_len,
1482 4803 : elems->ext_supp_rates, elems->ext_supp_rates_len);
1483 :
1484 4803 : return WLAN_STATUS_SUCCESS;
1485 : }
1486 :
1487 :
1488 4803 : static u16 check_ext_capab(struct hostapd_data *hapd, struct sta_info *sta,
1489 : const u8 *ext_capab_ie, size_t ext_capab_ie_len)
1490 : {
1491 : #ifdef CONFIG_INTERWORKING
1492 : /* check for QoS Map support */
1493 4803 : if (ext_capab_ie_len >= 5) {
1494 4573 : if (ext_capab_ie[4] & 0x01)
1495 4554 : sta->qos_map_enabled = 1;
1496 : }
1497 : #endif /* CONFIG_INTERWORKING */
1498 :
1499 4803 : if (ext_capab_ie_len > 0)
1500 4573 : sta->ecsa_supported = !!(ext_capab_ie[0] & BIT(2));
1501 :
1502 4803 : return WLAN_STATUS_SUCCESS;
1503 : }
1504 :
1505 :
1506 4803 : static u16 check_assoc_ies(struct hostapd_data *hapd, struct sta_info *sta,
1507 : const u8 *ies, size_t ies_len, int reassoc)
1508 : {
1509 : struct ieee802_11_elems elems;
1510 : u16 resp;
1511 : const u8 *wpa_ie;
1512 : size_t wpa_ie_len;
1513 4803 : const u8 *p2p_dev_addr = NULL;
1514 :
1515 4803 : if (ieee802_11_parse_elems(ies, ies_len, &elems, 1) == ParseFailed) {
1516 0 : hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
1517 : HOSTAPD_LEVEL_INFO, "Station sent an invalid "
1518 : "association request");
1519 0 : return WLAN_STATUS_UNSPECIFIED_FAILURE;
1520 : }
1521 :
1522 4803 : resp = check_ssid(hapd, sta, elems.ssid, elems.ssid_len);
1523 4803 : if (resp != WLAN_STATUS_SUCCESS)
1524 0 : return resp;
1525 4803 : resp = check_wmm(hapd, sta, elems.wmm, elems.wmm_len);
1526 4803 : if (resp != WLAN_STATUS_SUCCESS)
1527 0 : return resp;
1528 4803 : resp = check_ext_capab(hapd, sta, elems.ext_capab, elems.ext_capab_len);
1529 4803 : if (resp != WLAN_STATUS_SUCCESS)
1530 0 : return resp;
1531 4803 : resp = copy_supp_rates(hapd, sta, &elems);
1532 4803 : if (resp != WLAN_STATUS_SUCCESS)
1533 0 : return resp;
1534 : #ifdef CONFIG_IEEE80211N
1535 4803 : resp = copy_sta_ht_capab(hapd, sta, elems.ht_capabilities);
1536 4803 : if (resp != WLAN_STATUS_SUCCESS)
1537 0 : return resp;
1538 4810 : if (hapd->iconf->ieee80211n && hapd->iconf->require_ht &&
1539 7 : !(sta->flags & WLAN_STA_HT)) {
1540 4 : hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
1541 : HOSTAPD_LEVEL_INFO, "Station does not support "
1542 : "mandatory HT PHY - reject association");
1543 4 : return WLAN_STATUS_ASSOC_DENIED_NO_HT;
1544 : }
1545 : #endif /* CONFIG_IEEE80211N */
1546 :
1547 : #ifdef CONFIG_IEEE80211AC
1548 4799 : if (hapd->iconf->ieee80211ac) {
1549 36 : resp = copy_sta_vht_capab(hapd, sta, elems.vht_capabilities);
1550 36 : if (resp != WLAN_STATUS_SUCCESS)
1551 0 : return resp;
1552 :
1553 36 : resp = set_sta_vht_opmode(hapd, sta, elems.vht_opmode_notif);
1554 36 : if (resp != WLAN_STATUS_SUCCESS)
1555 0 : return resp;
1556 : }
1557 :
1558 4802 : if (hapd->iconf->ieee80211ac && hapd->iconf->require_vht &&
1559 3 : !(sta->flags & WLAN_STA_VHT)) {
1560 1 : hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
1561 : HOSTAPD_LEVEL_INFO, "Station does not support "
1562 : "mandatory VHT PHY - reject association");
1563 1 : return WLAN_STATUS_ASSOC_DENIED_NO_VHT;
1564 : }
1565 :
1566 4798 : if (hapd->conf->vendor_vht && !elems.vht_capabilities) {
1567 2 : resp = copy_sta_vendor_vht(hapd, sta, elems.vendor_vht,
1568 2 : elems.vendor_vht_len);
1569 2 : if (resp != WLAN_STATUS_SUCCESS)
1570 0 : return resp;
1571 : }
1572 : #endif /* CONFIG_IEEE80211AC */
1573 :
1574 : #ifdef CONFIG_P2P
1575 577 : if (elems.p2p) {
1576 524 : wpabuf_free(sta->p2p_ie);
1577 524 : sta->p2p_ie = ieee802_11_vendor_ie_concat(ies, ies_len,
1578 : P2P_IE_VENDOR_TYPE);
1579 524 : if (sta->p2p_ie)
1580 524 : p2p_dev_addr = p2p_get_go_dev_addr(sta->p2p_ie);
1581 : } else {
1582 53 : wpabuf_free(sta->p2p_ie);
1583 53 : sta->p2p_ie = NULL;
1584 : }
1585 : #endif /* CONFIG_P2P */
1586 :
1587 4798 : if ((hapd->conf->wpa & WPA_PROTO_RSN) && elems.rsn_ie) {
1588 3453 : wpa_ie = elems.rsn_ie;
1589 3453 : wpa_ie_len = elems.rsn_ie_len;
1590 1410 : } else if ((hapd->conf->wpa & WPA_PROTO_WPA) &&
1591 65 : elems.wpa_ie) {
1592 47 : wpa_ie = elems.wpa_ie;
1593 47 : wpa_ie_len = elems.wpa_ie_len;
1594 : } else {
1595 1298 : wpa_ie = NULL;
1596 1298 : wpa_ie_len = 0;
1597 : }
1598 :
1599 : #ifdef CONFIG_WPS
1600 4798 : sta->flags &= ~(WLAN_STA_WPS | WLAN_STA_MAYBE_WPS | WLAN_STA_WPS2);
1601 4798 : if (hapd->conf->wps_state && elems.wps_ie) {
1602 535 : wpa_printf(MSG_DEBUG, "STA included WPS IE in (Re)Association "
1603 : "Request - assume WPS is used");
1604 535 : sta->flags |= WLAN_STA_WPS;
1605 535 : wpabuf_free(sta->wps_ie);
1606 535 : sta->wps_ie = ieee802_11_vendor_ie_concat(ies, ies_len,
1607 : WPS_IE_VENDOR_TYPE);
1608 535 : if (sta->wps_ie && wps_is_20(sta->wps_ie)) {
1609 532 : wpa_printf(MSG_DEBUG, "WPS: STA supports WPS 2.0");
1610 532 : sta->flags |= WLAN_STA_WPS2;
1611 : }
1612 535 : wpa_ie = NULL;
1613 535 : wpa_ie_len = 0;
1614 1070 : if (sta->wps_ie && wps_validate_assoc_req(sta->wps_ie) < 0) {
1615 0 : wpa_printf(MSG_DEBUG, "WPS: Invalid WPS IE in "
1616 : "(Re)Association Request - reject");
1617 0 : return WLAN_STATUS_INVALID_IE;
1618 : }
1619 4263 : } else if (hapd->conf->wps_state && wpa_ie == NULL) {
1620 18 : wpa_printf(MSG_DEBUG, "STA did not include WPA/RSN IE in "
1621 : "(Re)Association Request - possible WPS use");
1622 18 : sta->flags |= WLAN_STA_MAYBE_WPS;
1623 : } else
1624 : #endif /* CONFIG_WPS */
1625 4245 : if (hapd->conf->wpa && wpa_ie == NULL) {
1626 1 : hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
1627 : HOSTAPD_LEVEL_INFO,
1628 : "No WPA/RSN IE in association request");
1629 1 : return WLAN_STATUS_INVALID_IE;
1630 : }
1631 :
1632 8259 : if (hapd->conf->wpa && wpa_ie) {
1633 : int res;
1634 3500 : wpa_ie -= 2;
1635 3500 : wpa_ie_len += 2;
1636 3500 : if (sta->wpa_sm == NULL)
1637 3023 : sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth,
1638 3023 : sta->addr,
1639 : p2p_dev_addr);
1640 3500 : if (sta->wpa_sm == NULL) {
1641 0 : wpa_printf(MSG_WARNING, "Failed to initialize WPA "
1642 : "state machine");
1643 0 : return WLAN_STATUS_UNSPECIFIED_FAILURE;
1644 : }
1645 3500 : res = wpa_validate_wpa_ie(hapd->wpa_auth, sta->wpa_sm,
1646 : wpa_ie, wpa_ie_len,
1647 3500 : elems.mdie, elems.mdie_len);
1648 3500 : if (res == WPA_INVALID_GROUP)
1649 1 : resp = WLAN_STATUS_GROUP_CIPHER_NOT_VALID;
1650 3499 : else if (res == WPA_INVALID_PAIRWISE)
1651 1 : resp = WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID;
1652 3498 : else if (res == WPA_INVALID_AKMP)
1653 4 : resp = WLAN_STATUS_AKMP_NOT_VALID;
1654 3494 : else if (res == WPA_ALLOC_FAIL)
1655 0 : resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1656 : #ifdef CONFIG_IEEE80211W
1657 3494 : else if (res == WPA_MGMT_FRAME_PROTECTION_VIOLATION)
1658 1 : resp = WLAN_STATUS_ROBUST_MGMT_FRAME_POLICY_VIOLATION;
1659 3493 : else if (res == WPA_INVALID_MGMT_GROUP_CIPHER)
1660 1 : resp = WLAN_STATUS_ROBUST_MGMT_FRAME_POLICY_VIOLATION;
1661 : #endif /* CONFIG_IEEE80211W */
1662 3492 : else if (res == WPA_INVALID_MDIE)
1663 0 : resp = WLAN_STATUS_INVALID_MDIE;
1664 3492 : else if (res != WPA_IE_OK)
1665 22 : resp = WLAN_STATUS_INVALID_IE;
1666 3500 : if (resp != WLAN_STATUS_SUCCESS)
1667 30 : return resp;
1668 : #ifdef CONFIG_IEEE80211W
1669 3476 : if ((sta->flags & WLAN_STA_MFP) && !sta->sa_query_timed_out &&
1670 6 : sta->sa_query_count > 0)
1671 0 : ap_check_sa_query_timeout(hapd, sta);
1672 3470 : if ((sta->flags & WLAN_STA_MFP) && !sta->sa_query_timed_out &&
1673 4 : (!reassoc || sta->auth_alg != WLAN_AUTH_FT)) {
1674 : /*
1675 : * STA has already been associated with MFP and SA
1676 : * Query timeout has not been reached. Reject the
1677 : * association attempt temporarily and start SA Query,
1678 : * if one is not pending.
1679 : */
1680 :
1681 4 : if (sta->sa_query_count == 0)
1682 4 : ap_sta_start_sa_query(hapd, sta);
1683 :
1684 4 : return WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY;
1685 : }
1686 :
1687 3466 : if (wpa_auth_uses_mfp(sta->wpa_sm))
1688 73 : sta->flags |= WLAN_STA_MFP;
1689 : else
1690 3393 : sta->flags &= ~WLAN_STA_MFP;
1691 : #endif /* CONFIG_IEEE80211W */
1692 :
1693 : #ifdef CONFIG_IEEE80211R
1694 3466 : if (sta->auth_alg == WLAN_AUTH_FT) {
1695 230 : if (!reassoc) {
1696 12 : wpa_printf(MSG_DEBUG, "FT: " MACSTR " tried "
1697 : "to use association (not "
1698 : "re-association) with FT auth_alg",
1699 12 : MAC2STR(sta->addr));
1700 2 : return WLAN_STATUS_UNSPECIFIED_FAILURE;
1701 : }
1702 :
1703 228 : resp = wpa_ft_validate_reassoc(sta->wpa_sm, ies,
1704 : ies_len);
1705 228 : if (resp != WLAN_STATUS_SUCCESS)
1706 1 : return resp;
1707 : }
1708 : #endif /* CONFIG_IEEE80211R */
1709 :
1710 : #ifdef CONFIG_SAE
1711 3535 : if (wpa_auth_uses_sae(sta->wpa_sm) &&
1712 73 : sta->auth_alg == WLAN_AUTH_OPEN) {
1713 : struct rsn_pmksa_cache_entry *sa;
1714 2 : sa = wpa_auth_sta_get_pmksa(sta->wpa_sm);
1715 2 : if (!sa || sa->akmp != WPA_KEY_MGMT_SAE) {
1716 6 : wpa_printf(MSG_DEBUG,
1717 : "SAE: No PMKSA cache entry found for "
1718 6 : MACSTR, MAC2STR(sta->addr));
1719 1 : return WLAN_STATUS_INVALID_PMKID;
1720 : }
1721 6 : wpa_printf(MSG_DEBUG, "SAE: " MACSTR
1722 6 : " using PMKSA caching", MAC2STR(sta->addr));
1723 3531 : } else if (wpa_auth_uses_sae(sta->wpa_sm) &&
1724 74 : sta->auth_alg != WLAN_AUTH_SAE &&
1725 8 : !(sta->auth_alg == WLAN_AUTH_FT &&
1726 4 : wpa_auth_uses_ft_sae(sta->wpa_sm))) {
1727 0 : wpa_printf(MSG_DEBUG, "SAE: " MACSTR " tried to use "
1728 : "SAE AKM after non-SAE auth_alg %u",
1729 0 : MAC2STR(sta->addr), sta->auth_alg);
1730 0 : return WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG;
1731 : }
1732 : #endif /* CONFIG_SAE */
1733 :
1734 : #ifdef CONFIG_IEEE80211N
1735 6898 : if ((sta->flags & (WLAN_STA_HT | WLAN_STA_VHT)) &&
1736 3436 : wpa_auth_get_pairwise(sta->wpa_sm) == WPA_CIPHER_TKIP) {
1737 0 : hostapd_logger(hapd, sta->addr,
1738 : HOSTAPD_MODULE_IEEE80211,
1739 : HOSTAPD_LEVEL_INFO,
1740 : "Station tried to use TKIP with HT "
1741 : "association");
1742 0 : return WLAN_STATUS_CIPHER_REJECTED_PER_POLICY;
1743 : }
1744 : #endif /* CONFIG_IEEE80211N */
1745 : #ifdef CONFIG_HS20
1746 1297 : } else if (hapd->conf->osen) {
1747 5 : if (elems.osen == NULL) {
1748 3 : hostapd_logger(
1749 3 : hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
1750 : HOSTAPD_LEVEL_INFO,
1751 : "No HS 2.0 OSEN element in association request");
1752 3 : return WLAN_STATUS_INVALID_IE;
1753 : }
1754 :
1755 2 : wpa_printf(MSG_DEBUG, "HS 2.0: OSEN association");
1756 2 : if (sta->wpa_sm == NULL)
1757 2 : sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth,
1758 2 : sta->addr, NULL);
1759 2 : if (sta->wpa_sm == NULL) {
1760 0 : wpa_printf(MSG_WARNING, "Failed to initialize WPA "
1761 : "state machine");
1762 0 : return WLAN_STATUS_UNSPECIFIED_FAILURE;
1763 : }
1764 4 : if (wpa_validate_osen(hapd->wpa_auth, sta->wpa_sm,
1765 4 : elems.osen - 2, elems.osen_len + 2) < 0)
1766 0 : return WLAN_STATUS_INVALID_IE;
1767 : #endif /* CONFIG_HS20 */
1768 : } else
1769 1292 : wpa_auth_sta_no_wpa(sta->wpa_sm);
1770 :
1771 : #ifdef CONFIG_P2P
1772 576 : p2p_group_notif_assoc(hapd->p2p_group, sta->addr, ies, ies_len);
1773 : #endif /* CONFIG_P2P */
1774 :
1775 : #ifdef CONFIG_HS20
1776 4756 : wpabuf_free(sta->hs20_ie);
1777 4756 : if (elems.hs20 && elems.hs20_len > 4) {
1778 114 : sta->hs20_ie = wpabuf_alloc_copy(elems.hs20 + 4,
1779 114 : elems.hs20_len - 4);
1780 : } else
1781 4642 : sta->hs20_ie = NULL;
1782 : #endif /* CONFIG_HS20 */
1783 :
1784 : #ifdef CONFIG_FST
1785 4756 : wpabuf_free(sta->mb_ies);
1786 4756 : if (hapd->iface->fst)
1787 247 : sta->mb_ies = mb_ies_by_info(&elems.mb_ies);
1788 : else
1789 4509 : sta->mb_ies = NULL;
1790 : #endif /* CONFIG_FST */
1791 :
1792 : #ifdef CONFIG_MBO
1793 4756 : mbo_ap_check_sta_assoc(hapd, sta, &elems);
1794 :
1795 4757 : if (hapd->conf->mbo_enabled && (hapd->conf->wpa & 2) &&
1796 2 : elems.mbo && sta->cell_capa && !(sta->flags & WLAN_STA_MFP) &&
1797 0 : hapd->conf->ieee80211w != NO_MGMT_FRAME_PROTECTION) {
1798 0 : wpa_printf(MSG_INFO,
1799 : "MBO: Reject WPA2 association without PMF");
1800 0 : return WLAN_STATUS_UNSPECIFIED_FAILURE;
1801 : }
1802 : #endif /* CONFIG_MBO */
1803 :
1804 4756 : ap_copy_sta_supp_op_classes(sta, elems.supp_op_classes,
1805 4756 : elems.supp_op_classes_len);
1806 :
1807 4760 : if ((sta->capability & WLAN_CAPABILITY_RADIO_MEASUREMENT) &&
1808 8 : elems.rrm_enabled &&
1809 4 : elems.rrm_enabled_len >= sizeof(sta->rrm_enabled_capa))
1810 4 : os_memcpy(sta->rrm_enabled_capa, elems.rrm_enabled,
1811 : sizeof(sta->rrm_enabled_capa));
1812 :
1813 4756 : return WLAN_STATUS_SUCCESS;
1814 : }
1815 :
1816 :
1817 0 : static void send_deauth(struct hostapd_data *hapd, const u8 *addr,
1818 : u16 reason_code)
1819 : {
1820 : int send_len;
1821 : struct ieee80211_mgmt reply;
1822 :
1823 0 : os_memset(&reply, 0, sizeof(reply));
1824 0 : reply.frame_control =
1825 : IEEE80211_FC(WLAN_FC_TYPE_MGMT, WLAN_FC_STYPE_DEAUTH);
1826 0 : os_memcpy(reply.da, addr, ETH_ALEN);
1827 0 : os_memcpy(reply.sa, hapd->own_addr, ETH_ALEN);
1828 0 : os_memcpy(reply.bssid, hapd->own_addr, ETH_ALEN);
1829 :
1830 0 : send_len = IEEE80211_HDRLEN + sizeof(reply.u.deauth);
1831 0 : reply.u.deauth.reason_code = host_to_le16(reason_code);
1832 :
1833 0 : if (hostapd_drv_send_mlme(hapd, &reply, send_len, 0) < 0)
1834 0 : wpa_printf(MSG_INFO, "Failed to send deauth: %s",
1835 0 : strerror(errno));
1836 0 : }
1837 :
1838 :
1839 4756 : static int add_associated_sta(struct hostapd_data *hapd,
1840 : struct sta_info *sta)
1841 : {
1842 : struct ieee80211_ht_capabilities ht_cap;
1843 : struct ieee80211_vht_capabilities vht_cap;
1844 :
1845 : /*
1846 : * Remove the STA entry to ensure the STA PS state gets cleared and
1847 : * configuration gets updated. This is relevant for cases, such as
1848 : * FT-over-the-DS, where a station re-associates back to the same AP but
1849 : * skips the authentication flow, or if working with a driver that
1850 : * does not support full AP client state.
1851 : */
1852 4756 : if (!sta->added_unassoc)
1853 114 : hostapd_drv_sta_remove(hapd, sta->addr);
1854 :
1855 : #ifdef CONFIG_IEEE80211N
1856 4756 : if (sta->flags & WLAN_STA_HT)
1857 4699 : hostapd_get_ht_capab(hapd, sta->ht_capabilities, &ht_cap);
1858 : #endif /* CONFIG_IEEE80211N */
1859 : #ifdef CONFIG_IEEE80211AC
1860 4756 : if (sta->flags & WLAN_STA_VHT)
1861 35 : hostapd_get_vht_capab(hapd, sta->vht_capabilities, &vht_cap);
1862 : #endif /* CONFIG_IEEE80211AC */
1863 :
1864 : /*
1865 : * Add the station with forced WLAN_STA_ASSOC flag. The sta->flags
1866 : * will be set when the ACK frame for the (Re)Association Response frame
1867 : * is processed (TX status driver event).
1868 : */
1869 47560 : if (hostapd_sta_add(hapd, sta->addr, sta->aid, sta->capability,
1870 9512 : sta->supported_rates, sta->supported_rates_len,
1871 4756 : sta->listen_interval,
1872 4756 : sta->flags & WLAN_STA_HT ? &ht_cap : NULL,
1873 4756 : sta->flags & WLAN_STA_VHT ? &vht_cap : NULL,
1874 9512 : sta->flags | WLAN_STA_ASSOC, sta->qosinfo,
1875 9512 : sta->vht_opmode, sta->p2p_ie ? 1 : 0,
1876 4756 : sta->added_unassoc)) {
1877 0 : hostapd_logger(hapd, sta->addr,
1878 : HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_NOTICE,
1879 : "Could not %s STA to kernel driver",
1880 0 : sta->added_unassoc ? "set" : "add");
1881 :
1882 0 : if (sta->added_unassoc) {
1883 0 : hostapd_drv_sta_remove(hapd, sta->addr);
1884 0 : sta->added_unassoc = 0;
1885 : }
1886 :
1887 0 : return -1;
1888 : }
1889 :
1890 4756 : sta->added_unassoc = 0;
1891 :
1892 4756 : return 0;
1893 : }
1894 :
1895 :
1896 4806 : static u16 send_assoc_resp(struct hostapd_data *hapd, struct sta_info *sta,
1897 : u16 status_code, int reassoc, const u8 *ies,
1898 : size_t ies_len)
1899 : {
1900 : int send_len;
1901 : u8 buf[sizeof(struct ieee80211_mgmt) + 1024];
1902 : struct ieee80211_mgmt *reply;
1903 : u8 *p;
1904 :
1905 4806 : os_memset(buf, 0, sizeof(buf));
1906 4806 : reply = (struct ieee80211_mgmt *) buf;
1907 4806 : reply->frame_control =
1908 4806 : IEEE80211_FC(WLAN_FC_TYPE_MGMT,
1909 : (reassoc ? WLAN_FC_STYPE_REASSOC_RESP :
1910 : WLAN_FC_STYPE_ASSOC_RESP));
1911 4806 : os_memcpy(reply->da, sta->addr, ETH_ALEN);
1912 4806 : os_memcpy(reply->sa, hapd->own_addr, ETH_ALEN);
1913 4806 : os_memcpy(reply->bssid, hapd->own_addr, ETH_ALEN);
1914 :
1915 4806 : send_len = IEEE80211_HDRLEN;
1916 4806 : send_len += sizeof(reply->u.assoc_resp);
1917 4806 : reply->u.assoc_resp.capab_info =
1918 4806 : host_to_le16(hostapd_own_capab_info(hapd));
1919 4806 : reply->u.assoc_resp.status_code = host_to_le16(status_code);
1920 4806 : reply->u.assoc_resp.aid = host_to_le16(sta->aid | BIT(14) | BIT(15));
1921 : /* Supported rates */
1922 4806 : p = hostapd_eid_supp_rates(hapd, reply->u.assoc_resp.variable);
1923 : /* Extended supported rates */
1924 4806 : p = hostapd_eid_ext_supp_rates(hapd, p);
1925 :
1926 : #ifdef CONFIG_IEEE80211R
1927 4806 : if (status_code == WLAN_STATUS_SUCCESS) {
1928 : /* IEEE 802.11r: Mobility Domain Information, Fast BSS
1929 : * Transition Information, RSN, [RIC Response] */
1930 9512 : p = wpa_sm_write_assoc_resp_ies(sta->wpa_sm, p,
1931 4756 : buf + sizeof(buf) - p,
1932 4756 : sta->auth_alg, ies, ies_len);
1933 : }
1934 : #endif /* CONFIG_IEEE80211R */
1935 :
1936 : #ifdef CONFIG_IEEE80211W
1937 4806 : if (status_code == WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY)
1938 4 : p = hostapd_eid_assoc_comeback_time(hapd, sta, p);
1939 : #endif /* CONFIG_IEEE80211W */
1940 :
1941 : #ifdef CONFIG_IEEE80211N
1942 4806 : p = hostapd_eid_ht_capabilities(hapd, p);
1943 4806 : p = hostapd_eid_ht_operation(hapd, p);
1944 : #endif /* CONFIG_IEEE80211N */
1945 :
1946 : #ifdef CONFIG_IEEE80211AC
1947 4806 : if (hapd->iconf->ieee80211ac && !hapd->conf->disable_11ac) {
1948 35 : u32 nsts = 0, sta_nsts;
1949 :
1950 35 : if (hapd->conf->use_sta_nsts && sta->vht_capabilities) {
1951 : struct ieee80211_vht_capabilities *capa;
1952 :
1953 1 : nsts = (hapd->iface->conf->vht_capab >>
1954 : VHT_CAP_BEAMFORMEE_STS_OFFSET) & 7;
1955 1 : capa = sta->vht_capabilities;
1956 1 : sta_nsts = (le_to_host32(capa->vht_capabilities_info) >>
1957 : VHT_CAP_BEAMFORMEE_STS_OFFSET) & 7;
1958 :
1959 1 : if (nsts < sta_nsts)
1960 0 : nsts = 0;
1961 : else
1962 1 : nsts = sta_nsts;
1963 : }
1964 35 : p = hostapd_eid_vht_capabilities(hapd, p, nsts);
1965 35 : p = hostapd_eid_vht_operation(hapd, p);
1966 : }
1967 : #endif /* CONFIG_IEEE80211AC */
1968 :
1969 4806 : p = hostapd_eid_ext_capab(hapd, p);
1970 4806 : p = hostapd_eid_bss_max_idle_period(hapd, p);
1971 4806 : if (sta->qos_map_enabled)
1972 4669 : p = hostapd_eid_qos_map_set(hapd, p);
1973 :
1974 : #ifdef CONFIG_FST
1975 4806 : if (hapd->iface->fst_ies) {
1976 247 : os_memcpy(p, wpabuf_head(hapd->iface->fst_ies),
1977 : wpabuf_len(hapd->iface->fst_ies));
1978 247 : p += wpabuf_len(hapd->iface->fst_ies);
1979 : }
1980 : #endif /* CONFIG_FST */
1981 :
1982 : #ifdef CONFIG_IEEE80211AC
1983 4806 : if (hapd->conf->vendor_vht && (sta->flags & WLAN_STA_VENDOR_VHT))
1984 1 : p = hostapd_eid_vendor_vht(hapd, p);
1985 : #endif /* CONFIG_IEEE80211AC */
1986 :
1987 4806 : if (sta->flags & WLAN_STA_WMM)
1988 4792 : p = hostapd_eid_wmm(hapd, p);
1989 :
1990 : #ifdef CONFIG_WPS
1991 9077 : if ((sta->flags & WLAN_STA_WPS) ||
1992 4289 : ((sta->flags & WLAN_STA_MAYBE_WPS) && hapd->conf->wpa)) {
1993 535 : struct wpabuf *wps = wps_build_assoc_resp_ie();
1994 535 : if (wps) {
1995 534 : os_memcpy(p, wpabuf_head(wps), wpabuf_len(wps));
1996 534 : p += wpabuf_len(wps);
1997 534 : wpabuf_free(wps);
1998 : }
1999 : }
2000 : #endif /* CONFIG_WPS */
2001 :
2002 : #ifdef CONFIG_P2P
2003 577 : if (sta->p2p_ie && hapd->p2p_group) {
2004 : struct wpabuf *p2p_resp_ie;
2005 : enum p2p_status_code status;
2006 523 : switch (status_code) {
2007 : case WLAN_STATUS_SUCCESS:
2008 523 : status = P2P_SC_SUCCESS;
2009 523 : break;
2010 : case WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA:
2011 0 : status = P2P_SC_FAIL_LIMIT_REACHED;
2012 0 : break;
2013 : default:
2014 0 : status = P2P_SC_FAIL_INVALID_PARAMS;
2015 0 : break;
2016 : }
2017 523 : p2p_resp_ie = p2p_group_assoc_resp_ie(hapd->p2p_group, status);
2018 523 : if (p2p_resp_ie) {
2019 523 : os_memcpy(p, wpabuf_head(p2p_resp_ie),
2020 : wpabuf_len(p2p_resp_ie));
2021 523 : p += wpabuf_len(p2p_resp_ie);
2022 523 : wpabuf_free(p2p_resp_ie);
2023 : }
2024 : }
2025 : #endif /* CONFIG_P2P */
2026 :
2027 : #ifdef CONFIG_P2P_MANAGER
2028 4229 : if (hapd->conf->p2p & P2P_MANAGE)
2029 5 : p = hostapd_eid_p2p_manage(hapd, p);
2030 : #endif /* CONFIG_P2P_MANAGER */
2031 :
2032 4806 : p = hostapd_eid_mbo(hapd, p, buf + sizeof(buf) - p);
2033 :
2034 4807 : if (hapd->conf->assocresp_elements &&
2035 1 : (size_t) (buf + sizeof(buf) - p) >=
2036 1 : wpabuf_len(hapd->conf->assocresp_elements)) {
2037 1 : os_memcpy(p, wpabuf_head(hapd->conf->assocresp_elements),
2038 : wpabuf_len(hapd->conf->assocresp_elements));
2039 1 : p += wpabuf_len(hapd->conf->assocresp_elements);
2040 : }
2041 :
2042 4806 : send_len += p - reply->u.assoc_resp.variable;
2043 :
2044 4806 : if (hostapd_drv_send_mlme(hapd, reply, send_len, 0) < 0) {
2045 0 : wpa_printf(MSG_INFO, "Failed to send assoc resp: %s",
2046 0 : strerror(errno));
2047 0 : return WLAN_STATUS_UNSPECIFIED_FAILURE;
2048 : }
2049 :
2050 4806 : return WLAN_STATUS_SUCCESS;
2051 : }
2052 :
2053 :
2054 4806 : static void handle_assoc(struct hostapd_data *hapd,
2055 : const struct ieee80211_mgmt *mgmt, size_t len,
2056 : int reassoc)
2057 : {
2058 : u16 capab_info, listen_interval, seq_ctrl, fc;
2059 4806 : u16 resp = WLAN_STATUS_SUCCESS, reply_res;
2060 : const u8 *pos;
2061 : int left, i;
2062 : struct sta_info *sta;
2063 :
2064 4806 : if (len < IEEE80211_HDRLEN + (reassoc ? sizeof(mgmt->u.reassoc_req) :
2065 : sizeof(mgmt->u.assoc_req))) {
2066 0 : wpa_printf(MSG_INFO, "handle_assoc(reassoc=%d) - too short payload (len=%lu)",
2067 : reassoc, (unsigned long) len);
2068 0 : return;
2069 : }
2070 :
2071 : #ifdef CONFIG_TESTING_OPTIONS
2072 4806 : if (reassoc) {
2073 339 : if (hapd->iconf->ignore_reassoc_probability > 0.0 &&
2074 0 : drand48() < hapd->iconf->ignore_reassoc_probability) {
2075 0 : wpa_printf(MSG_INFO,
2076 : "TESTING: ignoring reassoc request from "
2077 0 : MACSTR, MAC2STR(mgmt->sa));
2078 0 : return;
2079 : }
2080 : } else {
2081 4470 : if (hapd->iconf->ignore_assoc_probability > 0.0 &&
2082 3 : drand48() < hapd->iconf->ignore_assoc_probability) {
2083 0 : wpa_printf(MSG_INFO,
2084 : "TESTING: ignoring assoc request from "
2085 0 : MACSTR, MAC2STR(mgmt->sa));
2086 0 : return;
2087 : }
2088 : }
2089 : #endif /* CONFIG_TESTING_OPTIONS */
2090 :
2091 4806 : fc = le_to_host16(mgmt->frame_control);
2092 4806 : seq_ctrl = le_to_host16(mgmt->seq_ctrl);
2093 :
2094 4806 : if (reassoc) {
2095 339 : capab_info = le_to_host16(mgmt->u.reassoc_req.capab_info);
2096 339 : listen_interval = le_to_host16(
2097 : mgmt->u.reassoc_req.listen_interval);
2098 4407 : wpa_printf(MSG_DEBUG, "reassociation request: STA=" MACSTR
2099 : " capab_info=0x%02x listen_interval=%d current_ap="
2100 : MACSTR " seq_ctrl=0x%x%s",
2101 2034 : MAC2STR(mgmt->sa), capab_info, listen_interval,
2102 2034 : MAC2STR(mgmt->u.reassoc_req.current_ap),
2103 339 : seq_ctrl, (fc & WLAN_FC_RETRY) ? " retry" : "");
2104 339 : left = len - (IEEE80211_HDRLEN + sizeof(mgmt->u.reassoc_req));
2105 339 : pos = mgmt->u.reassoc_req.variable;
2106 : } else {
2107 4467 : capab_info = le_to_host16(mgmt->u.assoc_req.capab_info);
2108 4467 : listen_interval = le_to_host16(
2109 : mgmt->u.assoc_req.listen_interval);
2110 31269 : wpa_printf(MSG_DEBUG, "association request: STA=" MACSTR
2111 : " capab_info=0x%02x listen_interval=%d "
2112 : "seq_ctrl=0x%x%s",
2113 26802 : MAC2STR(mgmt->sa), capab_info, listen_interval,
2114 4467 : seq_ctrl, (fc & WLAN_FC_RETRY) ? " retry" : "");
2115 4467 : left = len - (IEEE80211_HDRLEN + sizeof(mgmt->u.assoc_req));
2116 4467 : pos = mgmt->u.assoc_req.variable;
2117 : }
2118 :
2119 4806 : sta = ap_get_sta(hapd, mgmt->sa);
2120 : #ifdef CONFIG_IEEE80211R
2121 5036 : if (sta && sta->auth_alg == WLAN_AUTH_FT &&
2122 230 : (sta->flags & WLAN_STA_AUTH) == 0) {
2123 30 : wpa_printf(MSG_DEBUG, "FT: Allow STA " MACSTR " to associate "
2124 : "prior to authentication since it is using "
2125 30 : "over-the-DS FT", MAC2STR(mgmt->sa));
2126 :
2127 : /*
2128 : * Mark station as authenticated, to avoid adding station
2129 : * entry in the driver as associated and not authenticated
2130 : */
2131 5 : sta->flags |= WLAN_STA_AUTH;
2132 : } else
2133 : #endif /* CONFIG_IEEE80211R */
2134 4801 : if (sta == NULL || (sta->flags & WLAN_STA_AUTH) == 0) {
2135 0 : hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
2136 : HOSTAPD_LEVEL_INFO, "Station tried to "
2137 : "associate before authentication "
2138 : "(aid=%d flags=0x%x)",
2139 0 : sta ? sta->aid : -1,
2140 : sta ? sta->flags : 0);
2141 0 : send_deauth(hapd, mgmt->sa,
2142 : WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA);
2143 0 : return;
2144 : }
2145 :
2146 4806 : if ((fc & WLAN_FC_RETRY) &&
2147 0 : sta->last_seq_ctrl != WLAN_INVALID_MGMT_SEQ &&
2148 0 : sta->last_seq_ctrl == seq_ctrl &&
2149 0 : sta->last_subtype == reassoc ? WLAN_FC_STYPE_REASSOC_REQ :
2150 : WLAN_FC_STYPE_ASSOC_REQ) {
2151 0 : hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
2152 : HOSTAPD_LEVEL_DEBUG,
2153 : "Drop repeated association frame seq_ctrl=0x%x",
2154 : seq_ctrl);
2155 0 : return;
2156 : }
2157 4806 : sta->last_seq_ctrl = seq_ctrl;
2158 4806 : sta->last_subtype = reassoc ? WLAN_FC_STYPE_REASSOC_REQ :
2159 : WLAN_FC_STYPE_ASSOC_REQ;
2160 :
2161 4806 : if (hapd->tkip_countermeasures) {
2162 0 : resp = WLAN_REASON_MICHAEL_MIC_FAILURE;
2163 0 : goto fail;
2164 : }
2165 :
2166 4806 : if (listen_interval > hapd->conf->max_listen_interval) {
2167 2 : hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
2168 : HOSTAPD_LEVEL_DEBUG,
2169 : "Too large Listen Interval (%d)",
2170 : listen_interval);
2171 2 : resp = WLAN_STATUS_ASSOC_DENIED_LISTEN_INT_TOO_LARGE;
2172 2 : goto fail;
2173 : }
2174 :
2175 : #ifdef CONFIG_MBO
2176 4804 : if (hapd->conf->mbo_enabled && hapd->mbo_assoc_disallow) {
2177 1 : resp = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
2178 1 : goto fail;
2179 : }
2180 : #endif /* CONFIG_MBO */
2181 :
2182 : /*
2183 : * sta->capability is used in check_assoc_ies() for RRM enabled
2184 : * capability element.
2185 : */
2186 4803 : sta->capability = capab_info;
2187 :
2188 : /* followed by SSID and Supported rates; and HT capabilities if 802.11n
2189 : * is used */
2190 4803 : resp = check_assoc_ies(hapd, sta, pos, left, reassoc);
2191 4803 : if (resp != WLAN_STATUS_SUCCESS)
2192 47 : goto fail;
2193 :
2194 4756 : if (hostapd_get_aid(hapd, sta) < 0) {
2195 0 : hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
2196 : HOSTAPD_LEVEL_INFO, "No room for more AIDs");
2197 0 : resp = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
2198 0 : goto fail;
2199 : }
2200 :
2201 4756 : sta->listen_interval = listen_interval;
2202 :
2203 4756 : if (hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G)
2204 4540 : sta->flags |= WLAN_STA_NONERP;
2205 30380 : for (i = 0; i < sta->supported_rates_len; i++) {
2206 30375 : if ((sta->supported_rates[i] & 0x7f) > 22) {
2207 4751 : sta->flags &= ~WLAN_STA_NONERP;
2208 4751 : break;
2209 : }
2210 : }
2211 4756 : if (sta->flags & WLAN_STA_NONERP && !sta->nonerp_set) {
2212 0 : sta->nonerp_set = 1;
2213 0 : hapd->iface->num_sta_non_erp++;
2214 0 : if (hapd->iface->num_sta_non_erp == 1)
2215 0 : ieee802_11_set_beacons(hapd->iface);
2216 : }
2217 :
2218 4967 : if (!(sta->capability & WLAN_CAPABILITY_SHORT_SLOT_TIME) &&
2219 211 : !sta->no_short_slot_time_set) {
2220 210 : sta->no_short_slot_time_set = 1;
2221 210 : hapd->iface->num_sta_no_short_slot_time++;
2222 210 : if (hapd->iface->current_mode->mode ==
2223 0 : HOSTAPD_MODE_IEEE80211G &&
2224 0 : hapd->iface->num_sta_no_short_slot_time == 1)
2225 0 : ieee802_11_set_beacons(hapd->iface);
2226 : }
2227 :
2228 4756 : if (sta->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
2229 4545 : sta->flags |= WLAN_STA_SHORT_PREAMBLE;
2230 : else
2231 211 : sta->flags &= ~WLAN_STA_SHORT_PREAMBLE;
2232 :
2233 4967 : if (!(sta->capability & WLAN_CAPABILITY_SHORT_PREAMBLE) &&
2234 211 : !sta->no_short_preamble_set) {
2235 210 : sta->no_short_preamble_set = 1;
2236 210 : hapd->iface->num_sta_no_short_preamble++;
2237 210 : if (hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G
2238 0 : && hapd->iface->num_sta_no_short_preamble == 1)
2239 0 : ieee802_11_set_beacons(hapd->iface);
2240 : }
2241 :
2242 : #ifdef CONFIG_IEEE80211N
2243 4756 : update_ht_state(hapd, sta);
2244 : #endif /* CONFIG_IEEE80211N */
2245 :
2246 4756 : hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
2247 : HOSTAPD_LEVEL_DEBUG,
2248 4756 : "association OK (aid %d)", sta->aid);
2249 : /* Station will be marked associated, after it acknowledges AssocResp
2250 : */
2251 4756 : sta->flags |= WLAN_STA_ASSOC_REQ_OK;
2252 :
2253 : #ifdef CONFIG_IEEE80211W
2254 4756 : if ((sta->flags & WLAN_STA_MFP) && sta->sa_query_timed_out) {
2255 3 : wpa_printf(MSG_DEBUG, "Allowing %sassociation after timed out "
2256 : "SA Query procedure", reassoc ? "re" : "");
2257 : /* TODO: Send a protected Disassociate frame to the STA using
2258 : * the old key and Reason Code "Previous Authentication no
2259 : * longer valid". Make sure this is only sent protected since
2260 : * unprotected frame would be received by the STA that is now
2261 : * trying to associate.
2262 : */
2263 : }
2264 : #endif /* CONFIG_IEEE80211W */
2265 :
2266 : /* Make sure that the previously registered inactivity timer will not
2267 : * remove the STA immediately. */
2268 4756 : sta->timeout_next = STA_NULLFUNC;
2269 :
2270 : #ifdef CONFIG_TAXONOMY
2271 4180 : taxonomy_sta_info_assoc_req(hapd, sta, pos, left);
2272 : #endif /* CONFIG_TAXONOMY */
2273 :
2274 : fail:
2275 : /*
2276 : * In case of a successful response, add the station to the driver.
2277 : * Otherwise, the kernel may ignore Data frames before we process the
2278 : * ACK frame (TX status). In case of a failure, this station will be
2279 : * removed.
2280 : *
2281 : * Note that this is not compliant with the IEEE 802.11 standard that
2282 : * states that a non-AP station should transition into the
2283 : * authenticated/associated state only after the station acknowledges
2284 : * the (Re)Association Response frame. However, still do this as:
2285 : *
2286 : * 1. In case the station does not acknowledge the (Re)Association
2287 : * Response frame, it will be removed.
2288 : * 2. Data frames will be dropped in the kernel until the station is
2289 : * set into authorized state, and there are no significant known
2290 : * issues with processing other non-Data Class 3 frames during this
2291 : * window.
2292 : */
2293 4806 : if (resp == WLAN_STATUS_SUCCESS && add_associated_sta(hapd, sta))
2294 0 : resp = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
2295 :
2296 4806 : reply_res = send_assoc_resp(hapd, sta, resp, reassoc, pos, left);
2297 :
2298 : /*
2299 : * Remove the station in case tranmission of a success response fails
2300 : * (the STA was added associated to the driver) or if the station was
2301 : * previously added unassociated.
2302 : */
2303 4806 : if ((reply_res != WLAN_STATUS_SUCCESS &&
2304 4806 : resp == WLAN_STATUS_SUCCESS) || sta->added_unassoc) {
2305 49 : hostapd_drv_sta_remove(hapd, sta->addr);
2306 49 : sta->added_unassoc = 0;
2307 : }
2308 : }
2309 :
2310 :
2311 1 : static void handle_disassoc(struct hostapd_data *hapd,
2312 : const struct ieee80211_mgmt *mgmt, size_t len)
2313 : {
2314 : struct sta_info *sta;
2315 :
2316 1 : if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.disassoc)) {
2317 0 : wpa_printf(MSG_INFO, "handle_disassoc - too short payload (len=%lu)",
2318 : (unsigned long) len);
2319 0 : return;
2320 : }
2321 :
2322 7 : wpa_printf(MSG_DEBUG, "disassocation: STA=" MACSTR " reason_code=%d",
2323 6 : MAC2STR(mgmt->sa),
2324 1 : le_to_host16(mgmt->u.disassoc.reason_code));
2325 :
2326 1 : sta = ap_get_sta(hapd, mgmt->sa);
2327 1 : if (sta == NULL) {
2328 0 : wpa_printf(MSG_INFO, "Station " MACSTR " trying to disassociate, but it is not associated",
2329 0 : MAC2STR(mgmt->sa));
2330 0 : return;
2331 : }
2332 :
2333 1 : ap_sta_set_authorized(hapd, sta, 0);
2334 1 : sta->last_seq_ctrl = WLAN_INVALID_MGMT_SEQ;
2335 1 : sta->flags &= ~(WLAN_STA_ASSOC | WLAN_STA_ASSOC_REQ_OK);
2336 1 : wpa_auth_sm_event(sta->wpa_sm, WPA_DISASSOC);
2337 1 : hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
2338 : HOSTAPD_LEVEL_INFO, "disassociated");
2339 1 : sta->acct_terminate_cause = RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST;
2340 1 : ieee802_1x_notify_port_enabled(sta->eapol_sm, 0);
2341 : /* Stop Accounting and IEEE 802.1X sessions, but leave the STA
2342 : * authenticated. */
2343 1 : accounting_sta_stop(hapd, sta);
2344 1 : ieee802_1x_free_station(hapd, sta);
2345 1 : if (sta->ipaddr)
2346 0 : hostapd_drv_br_delete_ip_neigh(hapd, 4, (u8 *) &sta->ipaddr);
2347 1 : ap_sta_ip6addr_del(hapd, sta);
2348 1 : hostapd_drv_sta_remove(hapd, sta->addr);
2349 1 : sta->added_unassoc = 0;
2350 :
2351 1 : if (sta->timeout_next == STA_NULLFUNC ||
2352 0 : sta->timeout_next == STA_DISASSOC) {
2353 1 : sta->timeout_next = STA_DEAUTH;
2354 1 : eloop_cancel_timeout(ap_handle_timer, hapd, sta);
2355 1 : eloop_register_timeout(AP_DEAUTH_DELAY, 0, ap_handle_timer,
2356 : hapd, sta);
2357 : }
2358 :
2359 1 : mlme_disassociate_indication(
2360 1 : hapd, sta, le_to_host16(mgmt->u.disassoc.reason_code));
2361 : }
2362 :
2363 :
2364 3882 : static void handle_deauth(struct hostapd_data *hapd,
2365 : const struct ieee80211_mgmt *mgmt, size_t len)
2366 : {
2367 : struct sta_info *sta;
2368 :
2369 3882 : if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.deauth)) {
2370 0 : wpa_msg(hapd->msg_ctx, MSG_DEBUG, "handle_deauth - too short "
2371 : "payload (len=%lu)", (unsigned long) len);
2372 0 : return;
2373 : }
2374 :
2375 27174 : wpa_msg(hapd->msg_ctx, MSG_DEBUG, "deauthentication: STA=" MACSTR
2376 : " reason_code=%d",
2377 27174 : MAC2STR(mgmt->sa), le_to_host16(mgmt->u.deauth.reason_code));
2378 :
2379 3882 : sta = ap_get_sta(hapd, mgmt->sa);
2380 3882 : if (sta == NULL) {
2381 0 : wpa_msg(hapd->msg_ctx, MSG_DEBUG, "Station " MACSTR " trying "
2382 : "to deauthenticate, but it is not authenticated",
2383 0 : MAC2STR(mgmt->sa));
2384 0 : return;
2385 : }
2386 :
2387 3882 : ap_sta_set_authorized(hapd, sta, 0);
2388 3882 : sta->last_seq_ctrl = WLAN_INVALID_MGMT_SEQ;
2389 3882 : sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC |
2390 : WLAN_STA_ASSOC_REQ_OK);
2391 3882 : wpa_auth_sm_event(sta->wpa_sm, WPA_DEAUTH);
2392 3882 : hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
2393 : HOSTAPD_LEVEL_DEBUG, "deauthenticated");
2394 3882 : mlme_deauthenticate_indication(
2395 3882 : hapd, sta, le_to_host16(mgmt->u.deauth.reason_code));
2396 3882 : sta->acct_terminate_cause = RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST;
2397 3882 : ieee802_1x_notify_port_enabled(sta->eapol_sm, 0);
2398 3882 : ap_free_sta(hapd, sta);
2399 : }
2400 :
2401 :
2402 11630 : static void handle_beacon(struct hostapd_data *hapd,
2403 : const struct ieee80211_mgmt *mgmt, size_t len,
2404 : struct hostapd_frame_info *fi)
2405 : {
2406 : struct ieee802_11_elems elems;
2407 :
2408 11630 : if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.beacon)) {
2409 0 : wpa_printf(MSG_INFO, "handle_beacon - too short payload (len=%lu)",
2410 : (unsigned long) len);
2411 11630 : return;
2412 : }
2413 :
2414 11630 : (void) ieee802_11_parse_elems(mgmt->u.beacon.variable,
2415 : len - (IEEE80211_HDRLEN +
2416 : sizeof(mgmt->u.beacon)), &elems,
2417 : 0);
2418 :
2419 11630 : ap_list_process_beacon(hapd->iface, mgmt, &elems, fi);
2420 : }
2421 :
2422 :
2423 : #ifdef CONFIG_IEEE80211W
2424 :
2425 5 : static int hostapd_sa_query_action(struct hostapd_data *hapd,
2426 : const struct ieee80211_mgmt *mgmt,
2427 : size_t len)
2428 : {
2429 : const u8 *end;
2430 :
2431 5 : end = mgmt->u.action.u.sa_query_resp.trans_id +
2432 : WLAN_SA_QUERY_TR_ID_LEN;
2433 5 : if (((u8 *) mgmt) + len < end) {
2434 0 : wpa_printf(MSG_DEBUG, "IEEE 802.11: Too short SA Query Action "
2435 : "frame (len=%lu)", (unsigned long) len);
2436 0 : return 0;
2437 : }
2438 :
2439 5 : ieee802_11_sa_query_action(hapd, mgmt->sa,
2440 5 : mgmt->u.action.u.sa_query_resp.action,
2441 5 : mgmt->u.action.u.sa_query_resp.trans_id);
2442 5 : return 1;
2443 : }
2444 :
2445 :
2446 0 : static int robust_action_frame(u8 category)
2447 : {
2448 0 : return category != WLAN_ACTION_PUBLIC &&
2449 : category != WLAN_ACTION_HT;
2450 : }
2451 : #endif /* CONFIG_IEEE80211W */
2452 :
2453 :
2454 1671 : static int handle_action(struct hostapd_data *hapd,
2455 : const struct ieee80211_mgmt *mgmt, size_t len)
2456 : {
2457 : struct sta_info *sta;
2458 1671 : sta = ap_get_sta(hapd, mgmt->sa);
2459 :
2460 1671 : if (len < IEEE80211_HDRLEN + 1) {
2461 0 : hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
2462 : HOSTAPD_LEVEL_DEBUG,
2463 : "handle_action - too short payload (len=%lu)",
2464 : (unsigned long) len);
2465 0 : return 0;
2466 : }
2467 :
2468 1671 : if (mgmt->u.action.category != WLAN_ACTION_PUBLIC &&
2469 1067 : (sta == NULL || !(sta->flags & WLAN_STA_ASSOC))) {
2470 0 : wpa_printf(MSG_DEBUG, "IEEE 802.11: Ignored Action "
2471 : "frame (category=%u) from unassociated STA " MACSTR,
2472 0 : MAC2STR(mgmt->sa), mgmt->u.action.category);
2473 0 : return 0;
2474 : }
2475 :
2476 : #ifdef CONFIG_IEEE80211W
2477 1689 : if (sta && (sta->flags & WLAN_STA_MFP) &&
2478 18 : !(mgmt->frame_control & host_to_le16(WLAN_FC_ISWEP)) &&
2479 0 : robust_action_frame(mgmt->u.action.category)) {
2480 0 : hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
2481 : HOSTAPD_LEVEL_DEBUG,
2482 : "Dropped unprotected Robust Action frame from "
2483 : "an MFP STA");
2484 0 : return 0;
2485 : }
2486 : #endif /* CONFIG_IEEE80211W */
2487 :
2488 1671 : if (sta) {
2489 1276 : u16 fc = le_to_host16(mgmt->frame_control);
2490 1276 : u16 seq_ctrl = le_to_host16(mgmt->seq_ctrl);
2491 :
2492 1276 : if ((fc & WLAN_FC_RETRY) &&
2493 0 : sta->last_seq_ctrl != WLAN_INVALID_MGMT_SEQ &&
2494 0 : sta->last_seq_ctrl == seq_ctrl &&
2495 0 : sta->last_subtype == WLAN_FC_STYPE_ACTION) {
2496 0 : hostapd_logger(hapd, sta->addr,
2497 : HOSTAPD_MODULE_IEEE80211,
2498 : HOSTAPD_LEVEL_DEBUG,
2499 : "Drop repeated action frame seq_ctrl=0x%x",
2500 : seq_ctrl);
2501 0 : return 1;
2502 : }
2503 :
2504 1276 : sta->last_seq_ctrl = seq_ctrl;
2505 1276 : sta->last_subtype = WLAN_FC_STYPE_ACTION;
2506 : }
2507 :
2508 1671 : switch (mgmt->u.action.category) {
2509 : #ifdef CONFIG_IEEE80211R
2510 : case WLAN_ACTION_FT:
2511 230 : if (!sta ||
2512 115 : wpa_ft_action_rx(sta->wpa_sm, (u8 *) &mgmt->u.action,
2513 : len - IEEE80211_HDRLEN))
2514 : break;
2515 115 : return 1;
2516 : #endif /* CONFIG_IEEE80211R */
2517 : case WLAN_ACTION_WMM:
2518 6 : hostapd_wmm_action(hapd, mgmt, len);
2519 6 : return 1;
2520 : #ifdef CONFIG_IEEE80211W
2521 : case WLAN_ACTION_SA_QUERY:
2522 5 : return hostapd_sa_query_action(hapd, mgmt, len);
2523 : #endif /* CONFIG_IEEE80211W */
2524 : #ifdef CONFIG_WNM
2525 : case WLAN_ACTION_WNM:
2526 323 : ieee802_11_rx_wnm_action_ap(hapd, mgmt, len);
2527 323 : return 1;
2528 : #endif /* CONFIG_WNM */
2529 : #ifdef CONFIG_FST
2530 : case WLAN_ACTION_FST:
2531 592 : if (hapd->iface->fst)
2532 592 : fst_rx_action(hapd->iface->fst, mgmt, len);
2533 : else
2534 0 : wpa_printf(MSG_DEBUG,
2535 : "FST: Ignore FST Action frame - no FST attached");
2536 592 : return 1;
2537 : #endif /* CONFIG_FST */
2538 : case WLAN_ACTION_PUBLIC:
2539 : case WLAN_ACTION_PROTECTED_DUAL:
2540 : #ifdef CONFIG_IEEE80211N
2541 1214 : if (len >= IEEE80211_HDRLEN + 2 &&
2542 607 : mgmt->u.action.u.public_action.action ==
2543 : WLAN_PA_20_40_BSS_COEX) {
2544 84 : wpa_printf(MSG_DEBUG,
2545 : "HT20/40 coex mgmt frame received from STA "
2546 84 : MACSTR, MAC2STR(mgmt->sa));
2547 14 : hostapd_2040_coex_action(hapd, mgmt, len);
2548 : }
2549 : #endif /* CONFIG_IEEE80211N */
2550 607 : if (hapd->public_action_cb) {
2551 168 : hapd->public_action_cb(hapd->public_action_cb_ctx,
2552 : (u8 *) mgmt, len,
2553 84 : hapd->iface->freq);
2554 : }
2555 607 : if (hapd->public_action_cb2) {
2556 1214 : hapd->public_action_cb2(hapd->public_action_cb2_ctx,
2557 : (u8 *) mgmt, len,
2558 607 : hapd->iface->freq);
2559 : }
2560 607 : if (hapd->public_action_cb || hapd->public_action_cb2)
2561 607 : return 1;
2562 0 : break;
2563 : case WLAN_ACTION_VENDOR_SPECIFIC:
2564 5 : if (hapd->vendor_action_cb) {
2565 10 : if (hapd->vendor_action_cb(hapd->vendor_action_cb_ctx,
2566 : (u8 *) mgmt, len,
2567 5 : hapd->iface->freq) == 0)
2568 5 : return 1;
2569 : }
2570 0 : break;
2571 : case WLAN_ACTION_RADIO_MEASUREMENT:
2572 18 : hostapd_handle_radio_measurement(hapd, (const u8 *) mgmt, len);
2573 18 : return 1;
2574 : }
2575 :
2576 0 : hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
2577 : HOSTAPD_LEVEL_DEBUG,
2578 : "handle_action - unknown action category %d or invalid "
2579 : "frame",
2580 0 : mgmt->u.action.category);
2581 0 : if (!is_multicast_ether_addr(mgmt->da) &&
2582 0 : !(mgmt->u.action.category & 0x80) &&
2583 0 : !is_multicast_ether_addr(mgmt->sa)) {
2584 : struct ieee80211_mgmt *resp;
2585 :
2586 : /*
2587 : * IEEE 802.11-REVma/D9.0 - 7.3.1.11
2588 : * Return the Action frame to the source without change
2589 : * except that MSB of the Category set to 1.
2590 : */
2591 0 : wpa_printf(MSG_DEBUG, "IEEE 802.11: Return unknown Action "
2592 : "frame back to sender");
2593 0 : resp = os_malloc(len);
2594 0 : if (resp == NULL)
2595 0 : return 0;
2596 0 : os_memcpy(resp, mgmt, len);
2597 0 : os_memcpy(resp->da, resp->sa, ETH_ALEN);
2598 0 : os_memcpy(resp->sa, hapd->own_addr, ETH_ALEN);
2599 0 : os_memcpy(resp->bssid, hapd->own_addr, ETH_ALEN);
2600 0 : resp->u.action.category |= 0x80;
2601 :
2602 0 : if (hostapd_drv_send_mlme(hapd, resp, len, 0) < 0) {
2603 0 : wpa_printf(MSG_ERROR, "IEEE 802.11: Failed to send "
2604 : "Action frame");
2605 : }
2606 0 : os_free(resp);
2607 : }
2608 :
2609 0 : return 1;
2610 : }
2611 :
2612 :
2613 : /**
2614 : * ieee802_11_mgmt - process incoming IEEE 802.11 management frames
2615 : * @hapd: hostapd BSS data structure (the BSS to which the management frame was
2616 : * sent to)
2617 : * @buf: management frame data (starting from IEEE 802.11 header)
2618 : * @len: length of frame data in octets
2619 : * @fi: meta data about received frame (signal level, etc.)
2620 : *
2621 : * Process all incoming IEEE 802.11 management frames. This will be called for
2622 : * each frame received from the kernel driver through wlan#ap interface. In
2623 : * addition, it can be called to re-inserted pending frames (e.g., when using
2624 : * external RADIUS server as an MAC ACL).
2625 : */
2626 32268 : int ieee802_11_mgmt(struct hostapd_data *hapd, const u8 *buf, size_t len,
2627 : struct hostapd_frame_info *fi)
2628 : {
2629 : struct ieee80211_mgmt *mgmt;
2630 : u16 fc, stype;
2631 32268 : int ret = 0;
2632 :
2633 32268 : if (len < 24)
2634 0 : return 0;
2635 :
2636 32268 : mgmt = (struct ieee80211_mgmt *) buf;
2637 32268 : fc = le_to_host16(mgmt->frame_control);
2638 32268 : stype = WLAN_FC_GET_STYPE(fc);
2639 :
2640 32268 : if (stype == WLAN_FC_STYPE_BEACON) {
2641 11630 : handle_beacon(hapd, mgmt, len, fi);
2642 11630 : return 1;
2643 : }
2644 :
2645 36536 : if (!is_broadcast_ether_addr(mgmt->bssid) &&
2646 : #ifdef CONFIG_P2P
2647 : /* Invitation responses can be sent with the peer MAC as BSSID */
2648 3512 : !((hapd->conf->p2p & P2P_GROUP_OWNER) &&
2649 1937 : stype == WLAN_FC_STYPE_ACTION) &&
2650 : #endif /* CONFIG_P2P */
2651 : #ifdef CONFIG_MESH
2652 3452 : !(hapd->conf->mesh & MESH_ENABLED) &&
2653 : #endif /* CONFIG_MESH */
2654 15387 : os_memcmp(mgmt->bssid, hapd->own_addr, ETH_ALEN) != 0) {
2655 0 : wpa_printf(MSG_INFO, "MGMT: BSSID=" MACSTR " not our address",
2656 0 : MAC2STR(mgmt->bssid));
2657 0 : return 0;
2658 : }
2659 :
2660 :
2661 20638 : if (stype == WLAN_FC_STYPE_PROBE_REQ) {
2662 4979 : handle_probe_req(hapd, mgmt, len, fi->ssi_signal);
2663 4979 : return 1;
2664 : }
2665 :
2666 15659 : if (os_memcmp(mgmt->da, hapd->own_addr, ETH_ALEN) != 0) {
2667 0 : hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
2668 : HOSTAPD_LEVEL_DEBUG,
2669 : "MGMT: DA=" MACSTR " not our address",
2670 0 : MAC2STR(mgmt->da));
2671 0 : return 0;
2672 : }
2673 :
2674 15659 : if (hapd->iconf->track_sta_max_num)
2675 23 : sta_track_add(hapd->iface, mgmt->sa);
2676 :
2677 15659 : switch (stype) {
2678 : case WLAN_FC_STYPE_AUTH:
2679 5299 : wpa_printf(MSG_DEBUG, "mgmt::auth");
2680 5299 : handle_auth(hapd, mgmt, len);
2681 5299 : ret = 1;
2682 5299 : break;
2683 : case WLAN_FC_STYPE_ASSOC_REQ:
2684 4467 : wpa_printf(MSG_DEBUG, "mgmt::assoc_req");
2685 4467 : handle_assoc(hapd, mgmt, len, 0);
2686 4467 : ret = 1;
2687 4467 : break;
2688 : case WLAN_FC_STYPE_REASSOC_REQ:
2689 339 : wpa_printf(MSG_DEBUG, "mgmt::reassoc_req");
2690 339 : handle_assoc(hapd, mgmt, len, 1);
2691 339 : ret = 1;
2692 339 : break;
2693 : case WLAN_FC_STYPE_DISASSOC:
2694 1 : wpa_printf(MSG_DEBUG, "mgmt::disassoc");
2695 1 : handle_disassoc(hapd, mgmt, len);
2696 1 : ret = 1;
2697 1 : break;
2698 : case WLAN_FC_STYPE_DEAUTH:
2699 3882 : wpa_msg(hapd->msg_ctx, MSG_DEBUG, "mgmt::deauth");
2700 3882 : handle_deauth(hapd, mgmt, len);
2701 3882 : ret = 1;
2702 3882 : break;
2703 : case WLAN_FC_STYPE_ACTION:
2704 1671 : wpa_printf(MSG_DEBUG, "mgmt::action");
2705 1671 : ret = handle_action(hapd, mgmt, len);
2706 1671 : break;
2707 : default:
2708 0 : hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
2709 : HOSTAPD_LEVEL_DEBUG,
2710 : "unknown mgmt frame subtype %d", stype);
2711 0 : break;
2712 : }
2713 :
2714 15659 : return ret;
2715 : }
2716 :
2717 :
2718 4863 : static void handle_auth_cb(struct hostapd_data *hapd,
2719 : const struct ieee80211_mgmt *mgmt,
2720 : size_t len, int ok)
2721 : {
2722 : u16 auth_alg, auth_transaction, status_code;
2723 : struct sta_info *sta;
2724 :
2725 4863 : sta = ap_get_sta(hapd, mgmt->da);
2726 4863 : if (!sta) {
2727 222 : wpa_printf(MSG_INFO, "handle_auth_cb: STA " MACSTR " not found",
2728 222 : MAC2STR(mgmt->da));
2729 37 : return;
2730 : }
2731 :
2732 4826 : auth_alg = le_to_host16(mgmt->u.auth.auth_alg);
2733 4826 : auth_transaction = le_to_host16(mgmt->u.auth.auth_transaction);
2734 4826 : status_code = le_to_host16(mgmt->u.auth.status_code);
2735 :
2736 4826 : if (!ok) {
2737 1 : hostapd_logger(hapd, mgmt->da, HOSTAPD_MODULE_IEEE80211,
2738 : HOSTAPD_LEVEL_NOTICE,
2739 : "did not acknowledge authentication response");
2740 1 : goto fail;
2741 : }
2742 :
2743 4825 : if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.auth)) {
2744 0 : wpa_printf(MSG_INFO, "handle_auth_cb - too short payload (len=%lu)",
2745 : (unsigned long) len);
2746 0 : goto fail;
2747 : }
2748 :
2749 4825 : if (status_code == WLAN_STATUS_SUCCESS &&
2750 4492 : ((auth_alg == WLAN_AUTH_OPEN && auth_transaction == 2) ||
2751 26 : (auth_alg == WLAN_AUTH_SHARED_KEY && auth_transaction == 4))) {
2752 4505 : hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
2753 : HOSTAPD_LEVEL_INFO, "authenticated");
2754 4505 : sta->flags |= WLAN_STA_AUTH;
2755 4505 : if (sta->added_unassoc)
2756 4427 : hostapd_set_sta_flags(hapd, sta);
2757 4505 : return;
2758 : }
2759 :
2760 : fail:
2761 321 : if (status_code != WLAN_STATUS_SUCCESS && sta->added_unassoc) {
2762 0 : hostapd_drv_sta_remove(hapd, sta->addr);
2763 0 : sta->added_unassoc = 0;
2764 : }
2765 : }
2766 :
2767 :
2768 1 : static void hostapd_set_wds_encryption(struct hostapd_data *hapd,
2769 : struct sta_info *sta,
2770 : char *ifname_wds)
2771 : {
2772 : int i;
2773 1 : struct hostapd_ssid *ssid = &hapd->conf->ssid;
2774 :
2775 1 : if (hapd->conf->ieee802_1x || hapd->conf->wpa)
2776 2 : return;
2777 :
2778 0 : for (i = 0; i < 4; i++) {
2779 0 : if (ssid->wep.key[i] &&
2780 0 : hostapd_drv_set_key(ifname_wds, hapd, WPA_ALG_WEP, NULL, i,
2781 0 : i == ssid->wep.idx, NULL, 0,
2782 0 : ssid->wep.key[i], ssid->wep.len[i])) {
2783 0 : wpa_printf(MSG_WARNING,
2784 : "Could not set WEP keys for WDS interface; %s",
2785 : ifname_wds);
2786 0 : break;
2787 : }
2788 : }
2789 : }
2790 :
2791 :
2792 4806 : static void handle_assoc_cb(struct hostapd_data *hapd,
2793 : const struct ieee80211_mgmt *mgmt,
2794 : size_t len, int reassoc, int ok)
2795 : {
2796 : u16 status;
2797 : struct sta_info *sta;
2798 4806 : int new_assoc = 1;
2799 :
2800 4806 : sta = ap_get_sta(hapd, mgmt->da);
2801 4806 : if (!sta) {
2802 0 : wpa_printf(MSG_INFO, "handle_assoc_cb: STA " MACSTR " not found",
2803 0 : MAC2STR(mgmt->da));
2804 0 : return;
2805 : }
2806 :
2807 4806 : if (len < IEEE80211_HDRLEN + (reassoc ? sizeof(mgmt->u.reassoc_resp) :
2808 : sizeof(mgmt->u.assoc_resp))) {
2809 0 : wpa_printf(MSG_INFO,
2810 : "handle_assoc_cb(reassoc=%d) - too short payload (len=%lu)",
2811 : reassoc, (unsigned long) len);
2812 0 : hostapd_drv_sta_remove(hapd, sta->addr);
2813 0 : return;
2814 : }
2815 :
2816 4806 : if (reassoc)
2817 339 : status = le_to_host16(mgmt->u.reassoc_resp.status_code);
2818 : else
2819 4467 : status = le_to_host16(mgmt->u.assoc_resp.status_code);
2820 :
2821 4806 : if (!ok) {
2822 0 : hostapd_logger(hapd, mgmt->da, HOSTAPD_MODULE_IEEE80211,
2823 : HOSTAPD_LEVEL_DEBUG,
2824 : "did not acknowledge association response");
2825 0 : sta->flags &= ~WLAN_STA_ASSOC_REQ_OK;
2826 : /* The STA is added only in case of SUCCESS */
2827 0 : if (status == WLAN_STATUS_SUCCESS)
2828 0 : hostapd_drv_sta_remove(hapd, sta->addr);
2829 :
2830 0 : return;
2831 : }
2832 :
2833 4806 : if (status != WLAN_STATUS_SUCCESS)
2834 50 : return;
2835 :
2836 : /* Stop previous accounting session, if one is started, and allocate
2837 : * new session id for the new session. */
2838 4756 : accounting_sta_stop(hapd, sta);
2839 :
2840 4756 : hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
2841 : HOSTAPD_LEVEL_INFO,
2842 : "associated (aid %d)",
2843 4756 : sta->aid);
2844 :
2845 4756 : if (sta->flags & WLAN_STA_ASSOC)
2846 3 : new_assoc = 0;
2847 4756 : sta->flags |= WLAN_STA_ASSOC;
2848 4756 : sta->flags &= ~WLAN_STA_WNM_SLEEP_MODE;
2849 8750 : if ((!hapd->conf->ieee802_1x && !hapd->conf->wpa && !hapd->conf->osen) ||
2850 3994 : sta->auth_alg == WLAN_AUTH_FT) {
2851 : /*
2852 : * Open, static WEP, or FT protocol; no separate authorization
2853 : * step.
2854 : */
2855 989 : ap_sta_set_authorized(hapd, sta, 1);
2856 : }
2857 :
2858 4756 : if (reassoc)
2859 336 : mlme_reassociate_indication(hapd, sta);
2860 : else
2861 4420 : mlme_associate_indication(hapd, sta);
2862 :
2863 : #ifdef CONFIG_IEEE80211W
2864 4756 : sta->sa_query_timed_out = 0;
2865 : #endif /* CONFIG_IEEE80211W */
2866 :
2867 4756 : if (sta->flags & WLAN_STA_WDS) {
2868 : int ret;
2869 : char ifname_wds[IFNAMSIZ + 1];
2870 :
2871 0 : ret = hostapd_set_wds_sta(hapd, ifname_wds, sta->addr,
2872 0 : sta->aid, 1);
2873 0 : if (!ret)
2874 0 : hostapd_set_wds_encryption(hapd, sta, ifname_wds);
2875 : }
2876 :
2877 4756 : if (sta->eapol_sm == NULL) {
2878 : /*
2879 : * This STA does not use RADIUS server for EAP authentication,
2880 : * so bind it to the selected VLAN interface now, since the
2881 : * interface selection is not going to change anymore.
2882 : */
2883 4586 : if (ap_sta_bind_vlan(hapd, sta) < 0)
2884 0 : return;
2885 170 : } else if (sta->vlan_id) {
2886 : /* VLAN ID already set (e.g., by PMKSA caching), so bind STA */
2887 0 : if (ap_sta_bind_vlan(hapd, sta) < 0)
2888 0 : return;
2889 : }
2890 :
2891 4756 : hostapd_set_sta_flags(hapd, sta);
2892 :
2893 4756 : if (sta->auth_alg == WLAN_AUTH_FT)
2894 227 : wpa_auth_sm_event(sta->wpa_sm, WPA_ASSOC_FT);
2895 : else
2896 4529 : wpa_auth_sm_event(sta->wpa_sm, WPA_ASSOC);
2897 4756 : hapd->new_assoc_sta_cb(hapd, sta, !new_assoc);
2898 4756 : ieee802_1x_notify_port_enabled(sta->eapol_sm, 1);
2899 :
2900 4756 : if (sta->pending_eapol_rx) {
2901 : struct os_reltime now, age;
2902 :
2903 0 : os_get_reltime(&now);
2904 0 : os_reltime_sub(&now, &sta->pending_eapol_rx->rx_time, &age);
2905 0 : if (age.sec == 0 && age.usec < 200000) {
2906 0 : wpa_printf(MSG_DEBUG,
2907 : "Process pending EAPOL frame that was received from " MACSTR " just before association notification",
2908 0 : MAC2STR(sta->addr));
2909 0 : ieee802_1x_receive(
2910 0 : hapd, mgmt->da,
2911 0 : wpabuf_head(sta->pending_eapol_rx->buf),
2912 0 : wpabuf_len(sta->pending_eapol_rx->buf));
2913 : }
2914 0 : wpabuf_free(sta->pending_eapol_rx->buf);
2915 0 : os_free(sta->pending_eapol_rx);
2916 0 : sta->pending_eapol_rx = NULL;
2917 : }
2918 : }
2919 :
2920 :
2921 871 : static void handle_deauth_cb(struct hostapd_data *hapd,
2922 : const struct ieee80211_mgmt *mgmt,
2923 : size_t len, int ok)
2924 : {
2925 : struct sta_info *sta;
2926 871 : if (is_multicast_ether_addr(mgmt->da))
2927 31 : return;
2928 840 : sta = ap_get_sta(hapd, mgmt->da);
2929 840 : if (!sta) {
2930 3042 : wpa_printf(MSG_DEBUG, "handle_deauth_cb: STA " MACSTR
2931 3042 : " not found", MAC2STR(mgmt->da));
2932 507 : return;
2933 : }
2934 333 : if (ok)
2935 1986 : wpa_printf(MSG_DEBUG, "STA " MACSTR " acknowledged deauth",
2936 1986 : MAC2STR(sta->addr));
2937 : else
2938 12 : wpa_printf(MSG_DEBUG, "STA " MACSTR " did not acknowledge "
2939 12 : "deauth", MAC2STR(sta->addr));
2940 :
2941 333 : ap_sta_deauth_cb(hapd, sta);
2942 : }
2943 :
2944 :
2945 29 : static void handle_disassoc_cb(struct hostapd_data *hapd,
2946 : const struct ieee80211_mgmt *mgmt,
2947 : size_t len, int ok)
2948 : {
2949 : struct sta_info *sta;
2950 29 : if (is_multicast_ether_addr(mgmt->da))
2951 1 : return;
2952 28 : sta = ap_get_sta(hapd, mgmt->da);
2953 28 : if (!sta) {
2954 0 : wpa_printf(MSG_DEBUG, "handle_disassoc_cb: STA " MACSTR
2955 0 : " not found", MAC2STR(mgmt->da));
2956 0 : return;
2957 : }
2958 28 : if (ok)
2959 156 : wpa_printf(MSG_DEBUG, "STA " MACSTR " acknowledged disassoc",
2960 156 : MAC2STR(sta->addr));
2961 : else
2962 12 : wpa_printf(MSG_DEBUG, "STA " MACSTR " did not acknowledge "
2963 12 : "disassoc", MAC2STR(sta->addr));
2964 :
2965 28 : ap_sta_disassoc_cb(hapd, sta);
2966 : }
2967 :
2968 :
2969 : /**
2970 : * ieee802_11_mgmt_cb - Process management frame TX status callback
2971 : * @hapd: hostapd BSS data structure (the BSS from which the management frame
2972 : * was sent from)
2973 : * @buf: management frame data (starting from IEEE 802.11 header)
2974 : * @len: length of frame data in octets
2975 : * @stype: management frame subtype from frame control field
2976 : * @ok: Whether the frame was ACK'ed
2977 : */
2978 12567 : void ieee802_11_mgmt_cb(struct hostapd_data *hapd, const u8 *buf, size_t len,
2979 : u16 stype, int ok)
2980 : {
2981 : const struct ieee80211_mgmt *mgmt;
2982 12567 : mgmt = (const struct ieee80211_mgmt *) buf;
2983 :
2984 : #ifdef CONFIG_TESTING_OPTIONS
2985 12567 : if (hapd->ext_mgmt_frame_handling) {
2986 359 : wpa_msg(hapd->msg_ctx, MSG_INFO, "MGMT-TX-STATUS stype=%u ok=%d",
2987 : stype, ok);
2988 12926 : return;
2989 : }
2990 : #endif /* CONFIG_TESTING_OPTIONS */
2991 :
2992 12208 : switch (stype) {
2993 : case WLAN_FC_STYPE_AUTH:
2994 4863 : wpa_printf(MSG_DEBUG, "mgmt::auth cb");
2995 4863 : handle_auth_cb(hapd, mgmt, len, ok);
2996 4863 : break;
2997 : case WLAN_FC_STYPE_ASSOC_RESP:
2998 4467 : wpa_printf(MSG_DEBUG, "mgmt::assoc_resp cb");
2999 4467 : handle_assoc_cb(hapd, mgmt, len, 0, ok);
3000 4467 : break;
3001 : case WLAN_FC_STYPE_REASSOC_RESP:
3002 339 : wpa_printf(MSG_DEBUG, "mgmt::reassoc_resp cb");
3003 339 : handle_assoc_cb(hapd, mgmt, len, 1, ok);
3004 339 : break;
3005 : case WLAN_FC_STYPE_PROBE_RESP:
3006 599 : wpa_printf(MSG_EXCESSIVE, "mgmt::proberesp cb ok=%d", ok);
3007 599 : break;
3008 : case WLAN_FC_STYPE_DEAUTH:
3009 871 : wpa_printf(MSG_DEBUG, "mgmt::deauth cb");
3010 871 : handle_deauth_cb(hapd, mgmt, len, ok);
3011 871 : break;
3012 : case WLAN_FC_STYPE_DISASSOC:
3013 29 : wpa_printf(MSG_DEBUG, "mgmt::disassoc cb");
3014 29 : handle_disassoc_cb(hapd, mgmt, len, ok);
3015 29 : break;
3016 : case WLAN_FC_STYPE_ACTION:
3017 1040 : wpa_printf(MSG_DEBUG, "mgmt::action cb ok=%d", ok);
3018 1040 : break;
3019 : default:
3020 0 : wpa_printf(MSG_INFO, "unknown mgmt cb frame subtype %d", stype);
3021 0 : break;
3022 : }
3023 : }
3024 :
3025 :
3026 13 : int ieee802_11_get_mib(struct hostapd_data *hapd, char *buf, size_t buflen)
3027 : {
3028 : /* TODO */
3029 13 : return 0;
3030 : }
3031 :
3032 :
3033 221 : int ieee802_11_get_mib_sta(struct hostapd_data *hapd, struct sta_info *sta,
3034 : char *buf, size_t buflen)
3035 : {
3036 : /* TODO */
3037 221 : return 0;
3038 : }
3039 :
3040 :
3041 2347 : void hostapd_tx_status(struct hostapd_data *hapd, const u8 *addr,
3042 : const u8 *buf, size_t len, int ack)
3043 : {
3044 : struct sta_info *sta;
3045 2347 : struct hostapd_iface *iface = hapd->iface;
3046 :
3047 2347 : sta = ap_get_sta(hapd, addr);
3048 2347 : if (sta == NULL && iface->num_bss > 1) {
3049 : size_t j;
3050 0 : for (j = 0; j < iface->num_bss; j++) {
3051 0 : hapd = iface->bss[j];
3052 0 : sta = ap_get_sta(hapd, addr);
3053 0 : if (sta)
3054 0 : break;
3055 : }
3056 : }
3057 2347 : if (sta == NULL || !(sta->flags & WLAN_STA_ASSOC))
3058 2602 : return;
3059 2092 : if (sta->flags & WLAN_STA_PENDING_POLL) {
3060 0 : wpa_printf(MSG_DEBUG, "STA " MACSTR " %s pending "
3061 0 : "activity poll", MAC2STR(sta->addr),
3062 : ack ? "ACKed" : "did not ACK");
3063 0 : if (ack)
3064 0 : sta->flags &= ~WLAN_STA_PENDING_POLL;
3065 : }
3066 :
3067 2092 : ieee802_1x_tx_status(hapd, sta, buf, len, ack);
3068 : }
3069 :
3070 :
3071 16402 : void hostapd_eapol_tx_status(struct hostapd_data *hapd, const u8 *dst,
3072 : const u8 *data, size_t len, int ack)
3073 : {
3074 : struct sta_info *sta;
3075 16402 : struct hostapd_iface *iface = hapd->iface;
3076 :
3077 16402 : sta = ap_get_sta(hapd, dst);
3078 16402 : if (sta == NULL && iface->num_bss > 1) {
3079 : size_t j;
3080 61 : for (j = 0; j < iface->num_bss; j++) {
3081 61 : hapd = iface->bss[j];
3082 61 : sta = ap_get_sta(hapd, dst);
3083 61 : if (sta)
3084 29 : break;
3085 : }
3086 : }
3087 16402 : if (sta == NULL || !(sta->flags & WLAN_STA_ASSOC)) {
3088 3210 : wpa_printf(MSG_DEBUG, "Ignore TX status for Data frame to STA "
3089 : MACSTR " that is not currently associated",
3090 3210 : MAC2STR(dst));
3091 16937 : return;
3092 : }
3093 :
3094 15867 : ieee802_1x_eapol_tx_status(hapd, sta, data, len, ack);
3095 : }
3096 :
3097 :
3098 2 : void hostapd_client_poll_ok(struct hostapd_data *hapd, const u8 *addr)
3099 : {
3100 : struct sta_info *sta;
3101 2 : struct hostapd_iface *iface = hapd->iface;
3102 :
3103 2 : sta = ap_get_sta(hapd, addr);
3104 2 : if (sta == NULL && iface->num_bss > 1) {
3105 : size_t j;
3106 0 : for (j = 0; j < iface->num_bss; j++) {
3107 0 : hapd = iface->bss[j];
3108 0 : sta = ap_get_sta(hapd, addr);
3109 0 : if (sta)
3110 0 : break;
3111 : }
3112 : }
3113 2 : if (sta == NULL)
3114 0 : return;
3115 12 : wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_POLL_OK MACSTR,
3116 12 : MAC2STR(sta->addr));
3117 2 : if (!(sta->flags & WLAN_STA_PENDING_POLL))
3118 1 : return;
3119 :
3120 6 : wpa_printf(MSG_DEBUG, "STA " MACSTR " ACKed pending "
3121 6 : "activity poll", MAC2STR(sta->addr));
3122 1 : sta->flags &= ~WLAN_STA_PENDING_POLL;
3123 : }
3124 :
3125 :
3126 10 : void ieee802_11_rx_from_unknown(struct hostapd_data *hapd, const u8 *src,
3127 : int wds)
3128 : {
3129 : struct sta_info *sta;
3130 :
3131 10 : sta = ap_get_sta(hapd, src);
3132 10 : if (sta && (sta->flags & WLAN_STA_ASSOC)) {
3133 5 : if (!hapd->conf->wds_sta)
3134 4 : return;
3135 :
3136 1 : if (wds && !(sta->flags & WLAN_STA_WDS)) {
3137 : int ret;
3138 : char ifname_wds[IFNAMSIZ + 1];
3139 :
3140 7 : wpa_printf(MSG_DEBUG, "Enable 4-address WDS mode for "
3141 : "STA " MACSTR " (aid %u)",
3142 7 : MAC2STR(sta->addr), sta->aid);
3143 1 : sta->flags |= WLAN_STA_WDS;
3144 2 : ret = hostapd_set_wds_sta(hapd, ifname_wds,
3145 2 : sta->addr, sta->aid, 1);
3146 1 : if (!ret)
3147 1 : hostapd_set_wds_encryption(hapd, sta,
3148 : ifname_wds);
3149 : }
3150 1 : return;
3151 : }
3152 :
3153 30 : wpa_printf(MSG_DEBUG, "Data/PS-poll frame from not associated STA "
3154 30 : MACSTR, MAC2STR(src));
3155 5 : if (is_multicast_ether_addr(src)) {
3156 : /* Broadcast bit set in SA?! Ignore the frame silently. */
3157 0 : return;
3158 : }
3159 :
3160 5 : if (sta && (sta->flags & WLAN_STA_ASSOC_REQ_OK)) {
3161 0 : wpa_printf(MSG_DEBUG, "Association Response to the STA has "
3162 : "already been sent, but no TX status yet known - "
3163 : "ignore Class 3 frame issue with " MACSTR,
3164 0 : MAC2STR(src));
3165 0 : return;
3166 : }
3167 :
3168 5 : if (sta && (sta->flags & WLAN_STA_AUTH))
3169 1 : hostapd_drv_sta_disassoc(
3170 : hapd, src,
3171 : WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA);
3172 : else
3173 4 : hostapd_drv_sta_deauth(
3174 : hapd, src,
3175 : WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA);
3176 : }
3177 :
3178 :
3179 : #endif /* CONFIG_NATIVE_WINDOWS */
|