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