• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * hostapd / IEEE 802.11 Management
3  * Copyright (c) 2002-2012, 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 "drivers/driver.h"
17 #include "common/ieee802_11_defs.h"
18 #include "common/ieee802_11_common.h"
19 #include "common/wpa_ctrl.h"
20 #include "radius/radius.h"
21 #include "radius/radius_client.h"
22 #include "p2p/p2p.h"
23 #include "wps/wps.h"
24 #include "hostapd.h"
25 #include "beacon.h"
26 #include "ieee802_11_auth.h"
27 #include "sta_info.h"
28 #include "ieee802_1x.h"
29 #include "wpa_auth.h"
30 #include "wmm.h"
31 #include "ap_list.h"
32 #include "accounting.h"
33 #include "ap_config.h"
34 #include "ap_mlme.h"
35 #include "p2p_hostapd.h"
36 #include "ap_drv_ops.h"
37 #include "ieee802_11.h"
38 
39 
hostapd_eid_supp_rates(struct hostapd_data * hapd,u8 * eid)40 u8 * hostapd_eid_supp_rates(struct hostapd_data *hapd, u8 *eid)
41 {
42 	u8 *pos = eid;
43 	int i, num, count;
44 
45 	if (hapd->iface->current_rates == NULL)
46 		return eid;
47 
48 	*pos++ = WLAN_EID_SUPP_RATES;
49 	num = hapd->iface->num_rates;
50 	if (hapd->iconf->ieee80211n && hapd->iconf->require_ht)
51 		num++;
52 	if (num > 8) {
53 		/* rest of the rates are encoded in Extended supported
54 		 * rates element */
55 		num = 8;
56 	}
57 
58 	*pos++ = num;
59 	count = 0;
60 	for (i = 0, count = 0; i < hapd->iface->num_rates && count < num;
61 	     i++) {
62 		count++;
63 		*pos = hapd->iface->current_rates[i].rate / 5;
64 		if (hapd->iface->current_rates[i].flags & HOSTAPD_RATE_BASIC)
65 			*pos |= 0x80;
66 		pos++;
67 	}
68 
69 	if (hapd->iconf->ieee80211n && hapd->iconf->require_ht &&
70 	    hapd->iface->num_rates < 8)
71 		*pos++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_HT_PHY;
72 
73 	return pos;
74 }
75 
76 
hostapd_eid_ext_supp_rates(struct hostapd_data * hapd,u8 * eid)77 u8 * hostapd_eid_ext_supp_rates(struct hostapd_data *hapd, u8 *eid)
78 {
79 	u8 *pos = eid;
80 	int i, num, count;
81 
82 	if (hapd->iface->current_rates == NULL)
83 		return eid;
84 
85 	num = hapd->iface->num_rates;
86 	if (hapd->iconf->ieee80211n && hapd->iconf->require_ht)
87 		num++;
88 	if (num <= 8)
89 		return eid;
90 	num -= 8;
91 
92 	*pos++ = WLAN_EID_EXT_SUPP_RATES;
93 	*pos++ = num;
94 	count = 0;
95 	for (i = 0, count = 0; i < hapd->iface->num_rates && count < num + 8;
96 	     i++) {
97 		count++;
98 		if (count <= 8)
99 			continue; /* already in SuppRates IE */
100 		*pos = hapd->iface->current_rates[i].rate / 5;
101 		if (hapd->iface->current_rates[i].flags & HOSTAPD_RATE_BASIC)
102 			*pos |= 0x80;
103 		pos++;
104 	}
105 
106 	if (hapd->iconf->ieee80211n && hapd->iconf->require_ht &&
107 	    hapd->iface->num_rates >= 8)
108 		*pos++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_HT_PHY;
109 
110 	return pos;
111 }
112 
113 
hostapd_own_capab_info(struct hostapd_data * hapd,struct sta_info * sta,int probe)114 u16 hostapd_own_capab_info(struct hostapd_data *hapd, struct sta_info *sta,
115 			   int probe)
116 {
117 	int capab = WLAN_CAPABILITY_ESS;
118 	int privacy;
119 
120 	if (hapd->iface->num_sta_no_short_preamble == 0 &&
121 	    hapd->iconf->preamble == SHORT_PREAMBLE)
122 		capab |= WLAN_CAPABILITY_SHORT_PREAMBLE;
123 
124 	privacy = hapd->conf->ssid.wep.keys_set;
125 
126 	if (hapd->conf->ieee802_1x &&
127 	    (hapd->conf->default_wep_key_len ||
128 	     hapd->conf->individual_wep_key_len))
129 		privacy = 1;
130 
131 	if (hapd->conf->wpa)
132 		privacy = 1;
133 
134 	if (sta) {
135 		int policy, def_klen;
136 		if (probe && sta->ssid_probe) {
137 			policy = sta->ssid_probe->security_policy;
138 			def_klen = sta->ssid_probe->wep.default_len;
139 		} else {
140 			policy = sta->ssid->security_policy;
141 			def_klen = sta->ssid->wep.default_len;
142 		}
143 		privacy = policy != SECURITY_PLAINTEXT;
144 		if (policy == SECURITY_IEEE_802_1X && def_klen == 0)
145 			privacy = 0;
146 	}
147 
148 	if (privacy)
149 		capab |= WLAN_CAPABILITY_PRIVACY;
150 
151 	if (hapd->iface->current_mode &&
152 	    hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G &&
153 	    hapd->iface->num_sta_no_short_slot_time == 0)
154 		capab |= WLAN_CAPABILITY_SHORT_SLOT_TIME;
155 
156 	return capab;
157 }
158 
159 
ieee802_11_print_ssid(char * buf,const u8 * ssid,u8 len)160 void ieee802_11_print_ssid(char *buf, const u8 *ssid, u8 len)
161 {
162 	int i;
163 	if (len > HOSTAPD_MAX_SSID_LEN)
164 		len = HOSTAPD_MAX_SSID_LEN;
165 	for (i = 0; i < len; i++) {
166 		if (ssid[i] >= 32 && ssid[i] < 127)
167 			buf[i] = ssid[i];
168 		else
169 			buf[i] = '.';
170 	}
171 	buf[len] = '\0';
172 }
173 
174 
auth_shared_key(struct hostapd_data * hapd,struct sta_info * sta,u16 auth_transaction,const u8 * challenge,int iswep)175 static u16 auth_shared_key(struct hostapd_data *hapd, struct sta_info *sta,
176 			   u16 auth_transaction, const u8 *challenge,
177 			   int iswep)
178 {
179 	hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
180 		       HOSTAPD_LEVEL_DEBUG,
181 		       "authentication (shared key, transaction %d)",
182 		       auth_transaction);
183 
184 	if (auth_transaction == 1) {
185 		if (!sta->challenge) {
186 			/* Generate a pseudo-random challenge */
187 			u8 key[8];
188 			struct os_time now;
189 			int r;
190 			sta->challenge = os_zalloc(WLAN_AUTH_CHALLENGE_LEN);
191 			if (sta->challenge == NULL)
192 				return WLAN_STATUS_UNSPECIFIED_FAILURE;
193 
194 			os_get_time(&now);
195 			r = os_random();
196 			os_memcpy(key, &now.sec, 4);
197 			os_memcpy(key + 4, &r, 4);
198 			rc4_skip(key, sizeof(key), 0,
199 				 sta->challenge, WLAN_AUTH_CHALLENGE_LEN);
200 		}
201 		return 0;
202 	}
203 
204 	if (auth_transaction != 3)
205 		return WLAN_STATUS_UNSPECIFIED_FAILURE;
206 
207 	/* Transaction 3 */
208 	if (!iswep || !sta->challenge || !challenge ||
209 	    os_memcmp(sta->challenge, challenge, WLAN_AUTH_CHALLENGE_LEN)) {
210 		hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
211 			       HOSTAPD_LEVEL_INFO,
212 			       "shared key authentication - invalid "
213 			       "challenge-response");
214 		return WLAN_STATUS_CHALLENGE_FAIL;
215 	}
216 
217 	hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
218 		       HOSTAPD_LEVEL_DEBUG,
219 		       "authentication OK (shared key)");
220 #ifdef IEEE80211_REQUIRE_AUTH_ACK
221 	/* Station will be marked authenticated if it ACKs the
222 	 * authentication reply. */
223 #else
224 	sta->flags |= WLAN_STA_AUTH;
225 	wpa_auth_sm_event(sta->wpa_sm, WPA_AUTH);
226 #endif
227 	os_free(sta->challenge);
228 	sta->challenge = NULL;
229 
230 	return 0;
231 }
232 
233 
send_auth_reply(struct hostapd_data * hapd,const u8 * dst,const u8 * bssid,u16 auth_alg,u16 auth_transaction,u16 resp,const u8 * ies,size_t ies_len)234 static void send_auth_reply(struct hostapd_data *hapd,
235 			    const u8 *dst, const u8 *bssid,
236 			    u16 auth_alg, u16 auth_transaction, u16 resp,
237 			    const u8 *ies, size_t ies_len)
238 {
239 	struct ieee80211_mgmt *reply;
240 	u8 *buf;
241 	size_t rlen;
242 
243 	rlen = IEEE80211_HDRLEN + sizeof(reply->u.auth) + ies_len;
244 	buf = os_zalloc(rlen);
245 	if (buf == NULL)
246 		return;
247 
248 	reply = (struct ieee80211_mgmt *) buf;
249 	reply->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
250 					    WLAN_FC_STYPE_AUTH);
251 	os_memcpy(reply->da, dst, ETH_ALEN);
252 	os_memcpy(reply->sa, hapd->own_addr, ETH_ALEN);
253 	os_memcpy(reply->bssid, bssid, ETH_ALEN);
254 
255 	reply->u.auth.auth_alg = host_to_le16(auth_alg);
256 	reply->u.auth.auth_transaction = host_to_le16(auth_transaction);
257 	reply->u.auth.status_code = host_to_le16(resp);
258 
259 	if (ies && ies_len)
260 		os_memcpy(reply->u.auth.variable, ies, ies_len);
261 
262 	wpa_printf(MSG_DEBUG, "authentication reply: STA=" MACSTR
263 		   " auth_alg=%d auth_transaction=%d resp=%d (IE len=%lu)",
264 		   MAC2STR(dst), auth_alg, auth_transaction,
265 		   resp, (unsigned long) ies_len);
266 	if (hostapd_drv_send_mlme(hapd, reply, rlen, 0) < 0)
267 		perror("send_auth_reply: send");
268 
269 	os_free(buf);
270 }
271 
272 
273 #ifdef CONFIG_IEEE80211R
handle_auth_ft_finish(void * ctx,const u8 * dst,const u8 * bssid,u16 auth_transaction,u16 status,const u8 * ies,size_t ies_len)274 static void handle_auth_ft_finish(void *ctx, const u8 *dst, const u8 *bssid,
275 				  u16 auth_transaction, u16 status,
276 				  const u8 *ies, size_t ies_len)
277 {
278 	struct hostapd_data *hapd = ctx;
279 	struct sta_info *sta;
280 
281 	send_auth_reply(hapd, dst, bssid, WLAN_AUTH_FT, auth_transaction,
282 			status, ies, ies_len);
283 
284 	if (status != WLAN_STATUS_SUCCESS)
285 		return;
286 
287 	sta = ap_get_sta(hapd, dst);
288 	if (sta == NULL)
289 		return;
290 
291 	hostapd_logger(hapd, dst, HOSTAPD_MODULE_IEEE80211,
292 		       HOSTAPD_LEVEL_DEBUG, "authentication OK (FT)");
293 	sta->flags |= WLAN_STA_AUTH;
294 	mlme_authenticate_indication(hapd, sta);
295 }
296 #endif /* CONFIG_IEEE80211R */
297 
298 
handle_auth(struct hostapd_data * hapd,const struct ieee80211_mgmt * mgmt,size_t len)299 static void handle_auth(struct hostapd_data *hapd,
300 			const struct ieee80211_mgmt *mgmt, size_t len)
301 {
302 	u16 auth_alg, auth_transaction, status_code;
303 	u16 resp = WLAN_STATUS_SUCCESS;
304 	struct sta_info *sta = NULL;
305 	int res;
306 	u16 fc;
307 	const u8 *challenge = NULL;
308 	u32 session_timeout, acct_interim_interval;
309 	int vlan_id = 0;
310 	u8 psk[PMK_LEN];
311 	int has_psk = 0;
312 	u8 resp_ies[2 + WLAN_AUTH_CHALLENGE_LEN];
313 	size_t resp_ies_len = 0;
314 
315 	if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.auth)) {
316 		printf("handle_auth - too short payload (len=%lu)\n",
317 		       (unsigned long) len);
318 		return;
319 	}
320 
321 	auth_alg = le_to_host16(mgmt->u.auth.auth_alg);
322 	auth_transaction = le_to_host16(mgmt->u.auth.auth_transaction);
323 	status_code = le_to_host16(mgmt->u.auth.status_code);
324 	fc = le_to_host16(mgmt->frame_control);
325 
326 	if (len >= IEEE80211_HDRLEN + sizeof(mgmt->u.auth) +
327 	    2 + WLAN_AUTH_CHALLENGE_LEN &&
328 	    mgmt->u.auth.variable[0] == WLAN_EID_CHALLENGE &&
329 	    mgmt->u.auth.variable[1] == WLAN_AUTH_CHALLENGE_LEN)
330 		challenge = &mgmt->u.auth.variable[2];
331 
332 	wpa_printf(MSG_DEBUG, "authentication: STA=" MACSTR " auth_alg=%d "
333 		   "auth_transaction=%d status_code=%d wep=%d%s",
334 		   MAC2STR(mgmt->sa), auth_alg, auth_transaction,
335 		   status_code, !!(fc & WLAN_FC_ISWEP),
336 		   challenge ? " challenge" : "");
337 
338 	if (hapd->tkip_countermeasures) {
339 		resp = WLAN_REASON_MICHAEL_MIC_FAILURE;
340 		goto fail;
341 	}
342 
343 	if (!(((hapd->conf->auth_algs & WPA_AUTH_ALG_OPEN) &&
344 	       auth_alg == WLAN_AUTH_OPEN) ||
345 #ifdef CONFIG_IEEE80211R
346 	      (hapd->conf->wpa && wpa_key_mgmt_ft(hapd->conf->wpa_key_mgmt) &&
347 	       auth_alg == WLAN_AUTH_FT) ||
348 #endif /* CONFIG_IEEE80211R */
349 	      ((hapd->conf->auth_algs & WPA_AUTH_ALG_SHARED) &&
350 	       auth_alg == WLAN_AUTH_SHARED_KEY))) {
351 		printf("Unsupported authentication algorithm (%d)\n",
352 		       auth_alg);
353 		resp = WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG;
354 		goto fail;
355 	}
356 
357 	if (!(auth_transaction == 1 ||
358 	      (auth_alg == WLAN_AUTH_SHARED_KEY && auth_transaction == 3))) {
359 		printf("Unknown authentication transaction number (%d)\n",
360 		       auth_transaction);
361 		resp = WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION;
362 		goto fail;
363 	}
364 
365 	if (os_memcmp(mgmt->sa, hapd->own_addr, ETH_ALEN) == 0) {
366 		printf("Station " MACSTR " not allowed to authenticate.\n",
367 		       MAC2STR(mgmt->sa));
368 		resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
369 		goto fail;
370 	}
371 
372 	res = hostapd_allowed_address(hapd, mgmt->sa, (u8 *) mgmt, len,
373 				      &session_timeout,
374 				      &acct_interim_interval, &vlan_id,
375 				      psk, &has_psk);
376 
377 	if (res == HOSTAPD_ACL_REJECT) {
378 		printf("Station " MACSTR " not allowed to authenticate.\n",
379 		       MAC2STR(mgmt->sa));
380 		resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
381 		goto fail;
382 	}
383 	if (res == HOSTAPD_ACL_PENDING) {
384 		wpa_printf(MSG_DEBUG, "Authentication frame from " MACSTR
385 			   " waiting for an external authentication",
386 			   MAC2STR(mgmt->sa));
387 		/* Authentication code will re-send the authentication frame
388 		 * after it has received (and cached) information from the
389 		 * external source. */
390 		return;
391 	}
392 
393 	sta = ap_sta_add(hapd, mgmt->sa);
394 	if (!sta) {
395 		resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
396 		goto fail;
397 	}
398 
399 	if (vlan_id > 0) {
400 		if (hostapd_get_vlan_id_ifname(hapd->conf->vlan,
401 					       vlan_id) == NULL) {
402 			hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_RADIUS,
403 				       HOSTAPD_LEVEL_INFO, "Invalid VLAN ID "
404 				       "%d received from RADIUS server",
405 				       vlan_id);
406 			resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
407 			goto fail;
408 		}
409 		sta->vlan_id = vlan_id;
410 		hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_RADIUS,
411 			       HOSTAPD_LEVEL_INFO, "VLAN ID %d", sta->vlan_id);
412 	}
413 
414 	if (has_psk && hapd->conf->wpa_psk_radius != PSK_RADIUS_IGNORED) {
415 		os_free(sta->psk);
416 		sta->psk = os_malloc(PMK_LEN);
417 		if (sta->psk)
418 			os_memcpy(sta->psk, psk, PMK_LEN);
419 	} else {
420 		os_free(sta->psk);
421 		sta->psk = NULL;
422 	}
423 
424 	sta->flags &= ~WLAN_STA_PREAUTH;
425 	ieee802_1x_notify_pre_auth(sta->eapol_sm, 0);
426 
427 	if (hapd->conf->acct_interim_interval == 0 && acct_interim_interval)
428 		sta->acct_interim_interval = acct_interim_interval;
429 	if (res == HOSTAPD_ACL_ACCEPT_TIMEOUT)
430 		ap_sta_session_timeout(hapd, sta, session_timeout);
431 	else
432 		ap_sta_no_session_timeout(hapd, sta);
433 
434 	switch (auth_alg) {
435 	case WLAN_AUTH_OPEN:
436 		hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
437 			       HOSTAPD_LEVEL_DEBUG,
438 			       "authentication OK (open system)");
439 #ifdef IEEE80211_REQUIRE_AUTH_ACK
440 		/* Station will be marked authenticated if it ACKs the
441 		 * authentication reply. */
442 #else
443 		sta->flags |= WLAN_STA_AUTH;
444 		wpa_auth_sm_event(sta->wpa_sm, WPA_AUTH);
445 		sta->auth_alg = WLAN_AUTH_OPEN;
446 		mlme_authenticate_indication(hapd, sta);
447 #endif
448 		break;
449 	case WLAN_AUTH_SHARED_KEY:
450 		resp = auth_shared_key(hapd, sta, auth_transaction, challenge,
451 				       fc & WLAN_FC_ISWEP);
452 		sta->auth_alg = WLAN_AUTH_SHARED_KEY;
453 		mlme_authenticate_indication(hapd, sta);
454 		if (sta->challenge && auth_transaction == 1) {
455 			resp_ies[0] = WLAN_EID_CHALLENGE;
456 			resp_ies[1] = WLAN_AUTH_CHALLENGE_LEN;
457 			os_memcpy(resp_ies + 2, sta->challenge,
458 				  WLAN_AUTH_CHALLENGE_LEN);
459 			resp_ies_len = 2 + WLAN_AUTH_CHALLENGE_LEN;
460 		}
461 		break;
462 #ifdef CONFIG_IEEE80211R
463 	case WLAN_AUTH_FT:
464 		sta->auth_alg = WLAN_AUTH_FT;
465 		if (sta->wpa_sm == NULL)
466 			sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth,
467 							sta->addr);
468 		if (sta->wpa_sm == NULL) {
469 			wpa_printf(MSG_DEBUG, "FT: Failed to initialize WPA "
470 				   "state machine");
471 			resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
472 			goto fail;
473 		}
474 		wpa_ft_process_auth(sta->wpa_sm, mgmt->bssid,
475 				    auth_transaction, mgmt->u.auth.variable,
476 				    len - IEEE80211_HDRLEN -
477 				    sizeof(mgmt->u.auth),
478 				    handle_auth_ft_finish, hapd);
479 		/* handle_auth_ft_finish() callback will complete auth. */
480 		return;
481 #endif /* CONFIG_IEEE80211R */
482 	}
483 
484  fail:
485 	send_auth_reply(hapd, mgmt->sa, mgmt->bssid, auth_alg,
486 			auth_transaction + 1, resp, resp_ies, resp_ies_len);
487 }
488 
489 
hostapd_get_aid(struct hostapd_data * hapd,struct sta_info * sta)490 static int hostapd_get_aid(struct hostapd_data *hapd, struct sta_info *sta)
491 {
492 	int i, j = 32, aid;
493 
494 	/* get a unique AID */
495 	if (sta->aid > 0) {
496 		wpa_printf(MSG_DEBUG, "  old AID %d", sta->aid);
497 		return 0;
498 	}
499 
500 	for (i = 0; i < AID_WORDS; i++) {
501 		if (hapd->sta_aid[i] == (u32) -1)
502 			continue;
503 		for (j = 0; j < 32; j++) {
504 			if (!(hapd->sta_aid[i] & BIT(j)))
505 				break;
506 		}
507 		if (j < 32)
508 			break;
509 	}
510 	if (j == 32)
511 		return -1;
512 	aid = i * 32 + j + 1;
513 	if (aid > 2007)
514 		return -1;
515 
516 	sta->aid = aid;
517 	hapd->sta_aid[i] |= BIT(j);
518 	wpa_printf(MSG_DEBUG, "  new AID %d", sta->aid);
519 	return 0;
520 }
521 
522 
check_ssid(struct hostapd_data * hapd,struct sta_info * sta,const u8 * ssid_ie,size_t ssid_ie_len)523 static u16 check_ssid(struct hostapd_data *hapd, struct sta_info *sta,
524 		      const u8 *ssid_ie, size_t ssid_ie_len)
525 {
526 	if (ssid_ie == NULL)
527 		return WLAN_STATUS_UNSPECIFIED_FAILURE;
528 
529 	if (ssid_ie_len != hapd->conf->ssid.ssid_len ||
530 	    os_memcmp(ssid_ie, hapd->conf->ssid.ssid, ssid_ie_len) != 0) {
531 		char ssid_txt[33];
532 		ieee802_11_print_ssid(ssid_txt, ssid_ie, ssid_ie_len);
533 		hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
534 			       HOSTAPD_LEVEL_INFO,
535 			       "Station tried to associate with unknown SSID "
536 			       "'%s'", ssid_txt);
537 		return WLAN_STATUS_UNSPECIFIED_FAILURE;
538 	}
539 
540 	return WLAN_STATUS_SUCCESS;
541 }
542 
543 
check_wmm(struct hostapd_data * hapd,struct sta_info * sta,const u8 * wmm_ie,size_t wmm_ie_len)544 static u16 check_wmm(struct hostapd_data *hapd, struct sta_info *sta,
545 		     const u8 *wmm_ie, size_t wmm_ie_len)
546 {
547 	sta->flags &= ~WLAN_STA_WMM;
548 	sta->qosinfo = 0;
549 	if (wmm_ie && hapd->conf->wmm_enabled) {
550 		struct wmm_information_element *wmm;
551 
552 		if (!hostapd_eid_wmm_valid(hapd, wmm_ie, wmm_ie_len)) {
553 			hostapd_logger(hapd, sta->addr,
554 				       HOSTAPD_MODULE_WPA,
555 				       HOSTAPD_LEVEL_DEBUG,
556 				       "invalid WMM element in association "
557 				       "request");
558 			return WLAN_STATUS_UNSPECIFIED_FAILURE;
559 		}
560 
561 		sta->flags |= WLAN_STA_WMM;
562 		wmm = (struct wmm_information_element *) wmm_ie;
563 		sta->qosinfo = wmm->qos_info;
564 	}
565 	return WLAN_STATUS_SUCCESS;
566 }
567 
568 
copy_supp_rates(struct hostapd_data * hapd,struct sta_info * sta,struct ieee802_11_elems * elems)569 static u16 copy_supp_rates(struct hostapd_data *hapd, struct sta_info *sta,
570 			   struct ieee802_11_elems *elems)
571 {
572 	if (!elems->supp_rates) {
573 		hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
574 			       HOSTAPD_LEVEL_DEBUG,
575 			       "No supported rates element in AssocReq");
576 		return WLAN_STATUS_UNSPECIFIED_FAILURE;
577 	}
578 
579 	if (elems->supp_rates_len > sizeof(sta->supported_rates)) {
580 		hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
581 			       HOSTAPD_LEVEL_DEBUG,
582 			       "Invalid supported rates element length %d",
583 			       elems->supp_rates_len);
584 		return WLAN_STATUS_UNSPECIFIED_FAILURE;
585 	}
586 
587 	os_memset(sta->supported_rates, 0, sizeof(sta->supported_rates));
588 	os_memcpy(sta->supported_rates, elems->supp_rates,
589 		  elems->supp_rates_len);
590 	sta->supported_rates_len = elems->supp_rates_len;
591 
592 	if (elems->ext_supp_rates) {
593 		if (elems->supp_rates_len + elems->ext_supp_rates_len >
594 		    sizeof(sta->supported_rates)) {
595 			hostapd_logger(hapd, sta->addr,
596 				       HOSTAPD_MODULE_IEEE80211,
597 				       HOSTAPD_LEVEL_DEBUG,
598 				       "Invalid supported rates element length"
599 				       " %d+%d", elems->supp_rates_len,
600 				       elems->ext_supp_rates_len);
601 			return WLAN_STATUS_UNSPECIFIED_FAILURE;
602 		}
603 
604 		os_memcpy(sta->supported_rates + elems->supp_rates_len,
605 			  elems->ext_supp_rates, elems->ext_supp_rates_len);
606 		sta->supported_rates_len += elems->ext_supp_rates_len;
607 	}
608 
609 	return WLAN_STATUS_SUCCESS;
610 }
611 
612 
check_assoc_ies(struct hostapd_data * hapd,struct sta_info * sta,const u8 * ies,size_t ies_len,int reassoc)613 static u16 check_assoc_ies(struct hostapd_data *hapd, struct sta_info *sta,
614 			   const u8 *ies, size_t ies_len, int reassoc)
615 {
616 	struct ieee802_11_elems elems;
617 	u16 resp;
618 	const u8 *wpa_ie;
619 	size_t wpa_ie_len;
620 
621 	if (ieee802_11_parse_elems(ies, ies_len, &elems, 1) == ParseFailed) {
622 		hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
623 			       HOSTAPD_LEVEL_INFO, "Station sent an invalid "
624 			       "association request");
625 		return WLAN_STATUS_UNSPECIFIED_FAILURE;
626 	}
627 
628 	resp = check_ssid(hapd, sta, elems.ssid, elems.ssid_len);
629 	if (resp != WLAN_STATUS_SUCCESS)
630 		return resp;
631 	resp = check_wmm(hapd, sta, elems.wmm, elems.wmm_len);
632 	if (resp != WLAN_STATUS_SUCCESS)
633 		return resp;
634 	resp = copy_supp_rates(hapd, sta, &elems);
635 	if (resp != WLAN_STATUS_SUCCESS)
636 		return resp;
637 #ifdef CONFIG_IEEE80211N
638 	resp = copy_sta_ht_capab(hapd, sta, elems.ht_capabilities,
639 				 elems.ht_capabilities_len);
640 	if (resp != WLAN_STATUS_SUCCESS)
641 		return resp;
642 	if (hapd->iconf->ieee80211n && hapd->iconf->require_ht &&
643 	    !(sta->flags & WLAN_STA_HT)) {
644 		hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
645 			       HOSTAPD_LEVEL_INFO, "Station does not support "
646 			       "mandatory HT PHY - reject association");
647 		return WLAN_STATUS_ASSOC_DENIED_NO_HT;
648 	}
649 #endif /* CONFIG_IEEE80211N */
650 
651 	if ((hapd->conf->wpa & WPA_PROTO_RSN) && elems.rsn_ie) {
652 		wpa_ie = elems.rsn_ie;
653 		wpa_ie_len = elems.rsn_ie_len;
654 	} else if ((hapd->conf->wpa & WPA_PROTO_WPA) &&
655 		   elems.wpa_ie) {
656 		wpa_ie = elems.wpa_ie;
657 		wpa_ie_len = elems.wpa_ie_len;
658 	} else {
659 		wpa_ie = NULL;
660 		wpa_ie_len = 0;
661 	}
662 
663 #ifdef CONFIG_WPS
664 	sta->flags &= ~(WLAN_STA_WPS | WLAN_STA_MAYBE_WPS | WLAN_STA_WPS2);
665 	if (hapd->conf->wps_state && elems.wps_ie) {
666 		wpa_printf(MSG_DEBUG, "STA included WPS IE in (Re)Association "
667 			   "Request - assume WPS is used");
668 		sta->flags |= WLAN_STA_WPS;
669 		wpabuf_free(sta->wps_ie);
670 		sta->wps_ie = ieee802_11_vendor_ie_concat(ies, ies_len,
671 							  WPS_IE_VENDOR_TYPE);
672 		if (sta->wps_ie && wps_is_20(sta->wps_ie)) {
673 			wpa_printf(MSG_DEBUG, "WPS: STA supports WPS 2.0");
674 			sta->flags |= WLAN_STA_WPS2;
675 		}
676 		wpa_ie = NULL;
677 		wpa_ie_len = 0;
678 		if (sta->wps_ie && wps_validate_assoc_req(sta->wps_ie) < 0) {
679 			wpa_printf(MSG_DEBUG, "WPS: Invalid WPS IE in "
680 				   "(Re)Association Request - reject");
681 			return WLAN_STATUS_INVALID_IE;
682 		}
683 	} else if (hapd->conf->wps_state && wpa_ie == NULL) {
684 		wpa_printf(MSG_DEBUG, "STA did not include WPA/RSN IE in "
685 			   "(Re)Association Request - possible WPS use");
686 		sta->flags |= WLAN_STA_MAYBE_WPS;
687 	} else
688 #endif /* CONFIG_WPS */
689 	if (hapd->conf->wpa && wpa_ie == NULL) {
690 		hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
691 			       HOSTAPD_LEVEL_INFO,
692 			       "No WPA/RSN IE in association request");
693 		return WLAN_STATUS_INVALID_IE;
694 	}
695 
696 	if (hapd->conf->wpa && wpa_ie) {
697 		int res;
698 		wpa_ie -= 2;
699 		wpa_ie_len += 2;
700 		if (sta->wpa_sm == NULL)
701 			sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth,
702 							sta->addr);
703 		if (sta->wpa_sm == NULL) {
704 			wpa_printf(MSG_WARNING, "Failed to initialize WPA "
705 				   "state machine");
706 			return WLAN_STATUS_UNSPECIFIED_FAILURE;
707 		}
708 		res = wpa_validate_wpa_ie(hapd->wpa_auth, sta->wpa_sm,
709 					  wpa_ie, wpa_ie_len,
710 					  elems.mdie, elems.mdie_len);
711 		if (res == WPA_INVALID_GROUP)
712 			resp = WLAN_STATUS_GROUP_CIPHER_NOT_VALID;
713 		else if (res == WPA_INVALID_PAIRWISE)
714 			resp = WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID;
715 		else if (res == WPA_INVALID_AKMP)
716 			resp = WLAN_STATUS_AKMP_NOT_VALID;
717 		else if (res == WPA_ALLOC_FAIL)
718 			resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
719 #ifdef CONFIG_IEEE80211W
720 		else if (res == WPA_MGMT_FRAME_PROTECTION_VIOLATION)
721 			resp = WLAN_STATUS_ROBUST_MGMT_FRAME_POLICY_VIOLATION;
722 		else if (res == WPA_INVALID_MGMT_GROUP_CIPHER)
723 			resp = WLAN_STATUS_ROBUST_MGMT_FRAME_POLICY_VIOLATION;
724 #endif /* CONFIG_IEEE80211W */
725 		else if (res == WPA_INVALID_MDIE)
726 			resp = WLAN_STATUS_INVALID_MDIE;
727 		else if (res != WPA_IE_OK)
728 			resp = WLAN_STATUS_INVALID_IE;
729 		if (resp != WLAN_STATUS_SUCCESS)
730 			return resp;
731 #ifdef CONFIG_IEEE80211W
732 		if ((sta->flags & WLAN_STA_MFP) && !sta->sa_query_timed_out &&
733 		    sta->sa_query_count > 0)
734 			ap_check_sa_query_timeout(hapd, sta);
735 		if ((sta->flags & WLAN_STA_MFP) && !sta->sa_query_timed_out &&
736 		    (!reassoc || sta->auth_alg != WLAN_AUTH_FT)) {
737 			/*
738 			 * STA has already been associated with MFP and SA
739 			 * Query timeout has not been reached. Reject the
740 			 * association attempt temporarily and start SA Query,
741 			 * if one is not pending.
742 			 */
743 
744 			if (sta->sa_query_count == 0)
745 				ap_sta_start_sa_query(hapd, sta);
746 
747 			return WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY;
748 		}
749 
750 		if (wpa_auth_uses_mfp(sta->wpa_sm))
751 			sta->flags |= WLAN_STA_MFP;
752 		else
753 			sta->flags &= ~WLAN_STA_MFP;
754 #endif /* CONFIG_IEEE80211W */
755 
756 #ifdef CONFIG_IEEE80211R
757 		if (sta->auth_alg == WLAN_AUTH_FT) {
758 			if (!reassoc) {
759 				wpa_printf(MSG_DEBUG, "FT: " MACSTR " tried "
760 					   "to use association (not "
761 					   "re-association) with FT auth_alg",
762 					   MAC2STR(sta->addr));
763 				return WLAN_STATUS_UNSPECIFIED_FAILURE;
764 			}
765 
766 			resp = wpa_ft_validate_reassoc(sta->wpa_sm, ies,
767 						       ies_len);
768 			if (resp != WLAN_STATUS_SUCCESS)
769 				return resp;
770 		}
771 #endif /* CONFIG_IEEE80211R */
772 
773 #ifdef CONFIG_IEEE80211N
774 		if ((sta->flags & WLAN_STA_HT) &&
775 		    wpa_auth_get_pairwise(sta->wpa_sm) == WPA_CIPHER_TKIP) {
776 			hostapd_logger(hapd, sta->addr,
777 				       HOSTAPD_MODULE_IEEE80211,
778 				       HOSTAPD_LEVEL_INFO,
779 				       "Station tried to use TKIP with HT "
780 				       "association");
781 			return WLAN_STATUS_CIPHER_REJECTED_PER_POLICY;
782 		}
783 #endif /* CONFIG_IEEE80211N */
784 	} else
785 		wpa_auth_sta_no_wpa(sta->wpa_sm);
786 
787 #ifdef CONFIG_P2P
788 	if (elems.p2p) {
789 		wpabuf_free(sta->p2p_ie);
790 		sta->p2p_ie = ieee802_11_vendor_ie_concat(ies, ies_len,
791 							  P2P_IE_VENDOR_TYPE);
792 
793 	} else {
794 		wpabuf_free(sta->p2p_ie);
795 		sta->p2p_ie = NULL;
796 	}
797 
798 	p2p_group_notif_assoc(hapd->p2p_group, sta->addr, ies, ies_len);
799 #endif /* CONFIG_P2P */
800 
801 	return WLAN_STATUS_SUCCESS;
802 }
803 
804 
send_deauth(struct hostapd_data * hapd,const u8 * addr,u16 reason_code)805 static void send_deauth(struct hostapd_data *hapd, const u8 *addr,
806 			u16 reason_code)
807 {
808 	int send_len;
809 	struct ieee80211_mgmt reply;
810 
811 	os_memset(&reply, 0, sizeof(reply));
812 	reply.frame_control =
813 		IEEE80211_FC(WLAN_FC_TYPE_MGMT, WLAN_FC_STYPE_DEAUTH);
814 	os_memcpy(reply.da, addr, ETH_ALEN);
815 	os_memcpy(reply.sa, hapd->own_addr, ETH_ALEN);
816 	os_memcpy(reply.bssid, hapd->own_addr, ETH_ALEN);
817 
818 	send_len = IEEE80211_HDRLEN + sizeof(reply.u.deauth);
819 	reply.u.deauth.reason_code = host_to_le16(reason_code);
820 
821 	if (hostapd_drv_send_mlme(hapd, &reply, send_len, 0) < 0)
822 		wpa_printf(MSG_INFO, "Failed to send deauth: %s",
823 			   strerror(errno));
824 }
825 
826 
send_assoc_resp(struct hostapd_data * hapd,struct sta_info * sta,u16 status_code,int reassoc,const u8 * ies,size_t ies_len)827 static void send_assoc_resp(struct hostapd_data *hapd, struct sta_info *sta,
828 			    u16 status_code, int reassoc, const u8 *ies,
829 			    size_t ies_len)
830 {
831 	int send_len;
832 	u8 buf[sizeof(struct ieee80211_mgmt) + 1024];
833 	struct ieee80211_mgmt *reply;
834 	u8 *p;
835 
836 	os_memset(buf, 0, sizeof(buf));
837 	reply = (struct ieee80211_mgmt *) buf;
838 	reply->frame_control =
839 		IEEE80211_FC(WLAN_FC_TYPE_MGMT,
840 			     (reassoc ? WLAN_FC_STYPE_REASSOC_RESP :
841 			      WLAN_FC_STYPE_ASSOC_RESP));
842 	os_memcpy(reply->da, sta->addr, ETH_ALEN);
843 	os_memcpy(reply->sa, hapd->own_addr, ETH_ALEN);
844 	os_memcpy(reply->bssid, hapd->own_addr, ETH_ALEN);
845 
846 	send_len = IEEE80211_HDRLEN;
847 	send_len += sizeof(reply->u.assoc_resp);
848 	reply->u.assoc_resp.capab_info =
849 		host_to_le16(hostapd_own_capab_info(hapd, sta, 0));
850 	reply->u.assoc_resp.status_code = host_to_le16(status_code);
851 	reply->u.assoc_resp.aid = host_to_le16((sta ? sta->aid : 0)
852 					       | BIT(14) | BIT(15));
853 	/* Supported rates */
854 	p = hostapd_eid_supp_rates(hapd, reply->u.assoc_resp.variable);
855 	/* Extended supported rates */
856 	p = hostapd_eid_ext_supp_rates(hapd, p);
857 
858 #ifdef CONFIG_IEEE80211R
859 	if (status_code == WLAN_STATUS_SUCCESS) {
860 		/* IEEE 802.11r: Mobility Domain Information, Fast BSS
861 		 * Transition Information, RSN, [RIC Response] */
862 		p = wpa_sm_write_assoc_resp_ies(sta->wpa_sm, p,
863 						buf + sizeof(buf) - p,
864 						sta->auth_alg, ies, ies_len);
865 	}
866 #endif /* CONFIG_IEEE80211R */
867 
868 #ifdef CONFIG_IEEE80211W
869 	if (status_code == WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY)
870 		p = hostapd_eid_assoc_comeback_time(hapd, sta, p);
871 #endif /* CONFIG_IEEE80211W */
872 
873 #ifdef CONFIG_IEEE80211N
874 	p = hostapd_eid_ht_capabilities(hapd, p);
875 	p = hostapd_eid_ht_operation(hapd, p);
876 #endif /* CONFIG_IEEE80211N */
877 
878 	p = hostapd_eid_ext_capab(hapd, p);
879 
880 	if (sta->flags & WLAN_STA_WMM)
881 		p = hostapd_eid_wmm(hapd, p);
882 
883 #ifdef CONFIG_WPS
884 	if ((sta->flags & WLAN_STA_WPS) ||
885 	    ((sta->flags & WLAN_STA_MAYBE_WPS) && hapd->conf->wpa)) {
886 		struct wpabuf *wps = wps_build_assoc_resp_ie();
887 		if (wps) {
888 			os_memcpy(p, wpabuf_head(wps), wpabuf_len(wps));
889 			p += wpabuf_len(wps);
890 			wpabuf_free(wps);
891 		}
892 	}
893 #endif /* CONFIG_WPS */
894 
895 #ifdef CONFIG_P2P
896 	if (sta->p2p_ie) {
897 		struct wpabuf *p2p_resp_ie;
898 		enum p2p_status_code status;
899 		switch (status_code) {
900 		case WLAN_STATUS_SUCCESS:
901 			status = P2P_SC_SUCCESS;
902 			break;
903 		case WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA:
904 			status = P2P_SC_FAIL_LIMIT_REACHED;
905 			break;
906 		default:
907 			status = P2P_SC_FAIL_INVALID_PARAMS;
908 			break;
909 		}
910 		p2p_resp_ie = p2p_group_assoc_resp_ie(hapd->p2p_group, status);
911 		if (p2p_resp_ie) {
912 			os_memcpy(p, wpabuf_head(p2p_resp_ie),
913 				  wpabuf_len(p2p_resp_ie));
914 			p += wpabuf_len(p2p_resp_ie);
915 			wpabuf_free(p2p_resp_ie);
916 		}
917 	}
918 #endif /* CONFIG_P2P */
919 
920 #ifdef CONFIG_P2P_MANAGER
921 	if (hapd->conf->p2p & P2P_MANAGE)
922 		p = hostapd_eid_p2p_manage(hapd, p);
923 #endif /* CONFIG_P2P_MANAGER */
924 
925 	send_len += p - reply->u.assoc_resp.variable;
926 
927 	if (hostapd_drv_send_mlme(hapd, reply, send_len, 0) < 0)
928 		wpa_printf(MSG_INFO, "Failed to send assoc resp: %s",
929 			   strerror(errno));
930 }
931 
932 
handle_assoc(struct hostapd_data * hapd,const struct ieee80211_mgmt * mgmt,size_t len,int reassoc)933 static void handle_assoc(struct hostapd_data *hapd,
934 			 const struct ieee80211_mgmt *mgmt, size_t len,
935 			 int reassoc)
936 {
937 	u16 capab_info, listen_interval;
938 	u16 resp = WLAN_STATUS_SUCCESS;
939 	const u8 *pos;
940 	int left, i;
941 	struct sta_info *sta;
942 
943 	if (len < IEEE80211_HDRLEN + (reassoc ? sizeof(mgmt->u.reassoc_req) :
944 				      sizeof(mgmt->u.assoc_req))) {
945 		printf("handle_assoc(reassoc=%d) - too short payload (len=%lu)"
946 		       "\n", reassoc, (unsigned long) len);
947 		return;
948 	}
949 
950 	if (reassoc) {
951 		capab_info = le_to_host16(mgmt->u.reassoc_req.capab_info);
952 		listen_interval = le_to_host16(
953 			mgmt->u.reassoc_req.listen_interval);
954 		wpa_printf(MSG_DEBUG, "reassociation request: STA=" MACSTR
955 			   " capab_info=0x%02x listen_interval=%d current_ap="
956 			   MACSTR,
957 			   MAC2STR(mgmt->sa), capab_info, listen_interval,
958 			   MAC2STR(mgmt->u.reassoc_req.current_ap));
959 		left = len - (IEEE80211_HDRLEN + sizeof(mgmt->u.reassoc_req));
960 		pos = mgmt->u.reassoc_req.variable;
961 	} else {
962 		capab_info = le_to_host16(mgmt->u.assoc_req.capab_info);
963 		listen_interval = le_to_host16(
964 			mgmt->u.assoc_req.listen_interval);
965 		wpa_printf(MSG_DEBUG, "association request: STA=" MACSTR
966 			   " capab_info=0x%02x listen_interval=%d",
967 			   MAC2STR(mgmt->sa), capab_info, listen_interval);
968 		left = len - (IEEE80211_HDRLEN + sizeof(mgmt->u.assoc_req));
969 		pos = mgmt->u.assoc_req.variable;
970 	}
971 
972 	sta = ap_get_sta(hapd, mgmt->sa);
973 #ifdef CONFIG_IEEE80211R
974 	if (sta && sta->auth_alg == WLAN_AUTH_FT &&
975 	    (sta->flags & WLAN_STA_AUTH) == 0) {
976 		wpa_printf(MSG_DEBUG, "FT: Allow STA " MACSTR " to associate "
977 			   "prior to authentication since it is using "
978 			   "over-the-DS FT", MAC2STR(mgmt->sa));
979 	} else
980 #endif /* CONFIG_IEEE80211R */
981 	if (sta == NULL || (sta->flags & WLAN_STA_AUTH) == 0) {
982 		hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
983 			       HOSTAPD_LEVEL_INFO, "Station tried to "
984 			       "associate before authentication "
985 			       "(aid=%d flags=0x%x)",
986 			       sta ? sta->aid : -1,
987 			       sta ? sta->flags : 0);
988 		send_deauth(hapd, mgmt->sa,
989 			    WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA);
990 		return;
991 	}
992 
993 	if (hapd->tkip_countermeasures) {
994 		resp = WLAN_REASON_MICHAEL_MIC_FAILURE;
995 		goto fail;
996 	}
997 
998 	if (listen_interval > hapd->conf->max_listen_interval) {
999 		hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
1000 			       HOSTAPD_LEVEL_DEBUG,
1001 			       "Too large Listen Interval (%d)",
1002 			       listen_interval);
1003 		resp = WLAN_STATUS_ASSOC_DENIED_LISTEN_INT_TOO_LARGE;
1004 		goto fail;
1005 	}
1006 
1007 	/* followed by SSID and Supported rates; and HT capabilities if 802.11n
1008 	 * is used */
1009 	resp = check_assoc_ies(hapd, sta, pos, left, reassoc);
1010 	if (resp != WLAN_STATUS_SUCCESS)
1011 		goto fail;
1012 
1013 	if (hostapd_get_aid(hapd, sta) < 0) {
1014 		hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
1015 			       HOSTAPD_LEVEL_INFO, "No room for more AIDs");
1016 		resp = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
1017 		goto fail;
1018 	}
1019 
1020 	sta->capability = capab_info;
1021 	sta->listen_interval = listen_interval;
1022 
1023 	if (hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G)
1024 		sta->flags |= WLAN_STA_NONERP;
1025 	for (i = 0; i < sta->supported_rates_len; i++) {
1026 		if ((sta->supported_rates[i] & 0x7f) > 22) {
1027 			sta->flags &= ~WLAN_STA_NONERP;
1028 			break;
1029 		}
1030 	}
1031 	if (sta->flags & WLAN_STA_NONERP && !sta->nonerp_set) {
1032 		sta->nonerp_set = 1;
1033 		hapd->iface->num_sta_non_erp++;
1034 		if (hapd->iface->num_sta_non_erp == 1)
1035 			ieee802_11_set_beacons(hapd->iface);
1036 	}
1037 
1038 	if (!(sta->capability & WLAN_CAPABILITY_SHORT_SLOT_TIME) &&
1039 	    !sta->no_short_slot_time_set) {
1040 		sta->no_short_slot_time_set = 1;
1041 		hapd->iface->num_sta_no_short_slot_time++;
1042 		if (hapd->iface->current_mode->mode ==
1043 		    HOSTAPD_MODE_IEEE80211G &&
1044 		    hapd->iface->num_sta_no_short_slot_time == 1)
1045 			ieee802_11_set_beacons(hapd->iface);
1046 	}
1047 
1048 	if (sta->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
1049 		sta->flags |= WLAN_STA_SHORT_PREAMBLE;
1050 	else
1051 		sta->flags &= ~WLAN_STA_SHORT_PREAMBLE;
1052 
1053 	if (!(sta->capability & WLAN_CAPABILITY_SHORT_PREAMBLE) &&
1054 	    !sta->no_short_preamble_set) {
1055 		sta->no_short_preamble_set = 1;
1056 		hapd->iface->num_sta_no_short_preamble++;
1057 		if (hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G
1058 		    && hapd->iface->num_sta_no_short_preamble == 1)
1059 			ieee802_11_set_beacons(hapd->iface);
1060 	}
1061 
1062 #ifdef CONFIG_IEEE80211N
1063 	update_ht_state(hapd, sta);
1064 #endif /* CONFIG_IEEE80211N */
1065 
1066 	hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
1067 		       HOSTAPD_LEVEL_DEBUG,
1068 		       "association OK (aid %d)", sta->aid);
1069 	/* Station will be marked associated, after it acknowledges AssocResp
1070 	 */
1071 	sta->flags |= WLAN_STA_ASSOC_REQ_OK;
1072 
1073 #ifdef CONFIG_IEEE80211W
1074 	if ((sta->flags & WLAN_STA_MFP) && sta->sa_query_timed_out) {
1075 		wpa_printf(MSG_DEBUG, "Allowing %sassociation after timed out "
1076 			   "SA Query procedure", reassoc ? "re" : "");
1077 		/* TODO: Send a protected Disassociate frame to the STA using
1078 		 * the old key and Reason Code "Previous Authentication no
1079 		 * longer valid". Make sure this is only sent protected since
1080 		 * unprotected frame would be received by the STA that is now
1081 		 * trying to associate.
1082 		 */
1083 	}
1084 #endif /* CONFIG_IEEE80211W */
1085 
1086 	if (reassoc) {
1087 		os_memcpy(sta->previous_ap, mgmt->u.reassoc_req.current_ap,
1088 			  ETH_ALEN);
1089 	}
1090 
1091 	if (sta->last_assoc_req)
1092 		os_free(sta->last_assoc_req);
1093 	sta->last_assoc_req = os_malloc(len);
1094 	if (sta->last_assoc_req)
1095 		os_memcpy(sta->last_assoc_req, mgmt, len);
1096 
1097 	/* Make sure that the previously registered inactivity timer will not
1098 	 * remove the STA immediately. */
1099 	sta->timeout_next = STA_NULLFUNC;
1100 
1101  fail:
1102 	send_assoc_resp(hapd, sta, resp, reassoc, pos, left);
1103 }
1104 
1105 
handle_disassoc(struct hostapd_data * hapd,const struct ieee80211_mgmt * mgmt,size_t len)1106 static void handle_disassoc(struct hostapd_data *hapd,
1107 			    const struct ieee80211_mgmt *mgmt, size_t len)
1108 {
1109 	struct sta_info *sta;
1110 
1111 	if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.disassoc)) {
1112 		printf("handle_disassoc - too short payload (len=%lu)\n",
1113 		       (unsigned long) len);
1114 		return;
1115 	}
1116 
1117 	wpa_printf(MSG_DEBUG, "disassocation: STA=" MACSTR " reason_code=%d",
1118 		   MAC2STR(mgmt->sa),
1119 		   le_to_host16(mgmt->u.disassoc.reason_code));
1120 
1121 	sta = ap_get_sta(hapd, mgmt->sa);
1122 	if (sta == NULL) {
1123 		printf("Station " MACSTR " trying to disassociate, but it "
1124 		       "is not associated.\n", MAC2STR(mgmt->sa));
1125 		return;
1126 	}
1127 
1128 	ap_sta_set_authorized(hapd, sta, 0);
1129 	sta->flags &= ~(WLAN_STA_ASSOC | WLAN_STA_ASSOC_REQ_OK);
1130 	wpa_auth_sm_event(sta->wpa_sm, WPA_DISASSOC);
1131 	hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
1132 		       HOSTAPD_LEVEL_INFO, "disassociated");
1133 	sta->acct_terminate_cause = RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST;
1134 	ieee802_1x_notify_port_enabled(sta->eapol_sm, 0);
1135 	/* Stop Accounting and IEEE 802.1X sessions, but leave the STA
1136 	 * authenticated. */
1137 	accounting_sta_stop(hapd, sta);
1138 	ieee802_1x_free_station(sta);
1139 	hostapd_drv_sta_remove(hapd, sta->addr);
1140 
1141 	if (sta->timeout_next == STA_NULLFUNC ||
1142 	    sta->timeout_next == STA_DISASSOC) {
1143 		sta->timeout_next = STA_DEAUTH;
1144 		eloop_cancel_timeout(ap_handle_timer, hapd, sta);
1145 		eloop_register_timeout(AP_DEAUTH_DELAY, 0, ap_handle_timer,
1146 				       hapd, sta);
1147 	}
1148 
1149 	mlme_disassociate_indication(
1150 		hapd, sta, le_to_host16(mgmt->u.disassoc.reason_code));
1151 }
1152 
1153 
handle_deauth(struct hostapd_data * hapd,const struct ieee80211_mgmt * mgmt,size_t len)1154 static void handle_deauth(struct hostapd_data *hapd,
1155 			  const struct ieee80211_mgmt *mgmt, size_t len)
1156 {
1157 	struct sta_info *sta;
1158 
1159 	if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.deauth)) {
1160 		wpa_msg(hapd->msg_ctx, MSG_DEBUG, "handle_deauth - too short "
1161 			"payload (len=%lu)", (unsigned long) len);
1162 		return;
1163 	}
1164 
1165 	wpa_msg(hapd->msg_ctx, MSG_DEBUG, "deauthentication: STA=" MACSTR
1166 		" reason_code=%d",
1167 		MAC2STR(mgmt->sa), le_to_host16(mgmt->u.deauth.reason_code));
1168 
1169 	sta = ap_get_sta(hapd, mgmt->sa);
1170 	if (sta == NULL) {
1171 		wpa_msg(hapd->msg_ctx, MSG_DEBUG, "Station " MACSTR " trying "
1172 			"to deauthenticate, but it is not authenticated",
1173 			MAC2STR(mgmt->sa));
1174 		return;
1175 	}
1176 
1177 	ap_sta_set_authorized(hapd, sta, 0);
1178 	sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC |
1179 			WLAN_STA_ASSOC_REQ_OK);
1180 	wpa_auth_sm_event(sta->wpa_sm, WPA_DEAUTH);
1181 	hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
1182 		       HOSTAPD_LEVEL_DEBUG, "deauthenticated");
1183 	mlme_deauthenticate_indication(
1184 		hapd, sta, le_to_host16(mgmt->u.deauth.reason_code));
1185 	sta->acct_terminate_cause = RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST;
1186 	ieee802_1x_notify_port_enabled(sta->eapol_sm, 0);
1187 	ap_free_sta(hapd, sta);
1188 }
1189 
1190 
handle_beacon(struct hostapd_data * hapd,const struct ieee80211_mgmt * mgmt,size_t len,struct hostapd_frame_info * fi)1191 static void handle_beacon(struct hostapd_data *hapd,
1192 			  const struct ieee80211_mgmt *mgmt, size_t len,
1193 			  struct hostapd_frame_info *fi)
1194 {
1195 	struct ieee802_11_elems elems;
1196 
1197 	if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.beacon)) {
1198 		printf("handle_beacon - too short payload (len=%lu)\n",
1199 		       (unsigned long) len);
1200 		return;
1201 	}
1202 
1203 	(void) ieee802_11_parse_elems(mgmt->u.beacon.variable,
1204 				      len - (IEEE80211_HDRLEN +
1205 					     sizeof(mgmt->u.beacon)), &elems,
1206 				      0);
1207 
1208 	ap_list_process_beacon(hapd->iface, mgmt, &elems, fi);
1209 }
1210 
1211 
1212 #ifdef CONFIG_IEEE80211W
1213 
hostapd_sa_query_action(struct hostapd_data * hapd,const struct ieee80211_mgmt * mgmt,size_t len)1214 static void hostapd_sa_query_action(struct hostapd_data *hapd,
1215 				    const struct ieee80211_mgmt *mgmt,
1216 				    size_t len)
1217 {
1218 	const u8 *end;
1219 
1220 	end = mgmt->u.action.u.sa_query_resp.trans_id +
1221 		WLAN_SA_QUERY_TR_ID_LEN;
1222 	if (((u8 *) mgmt) + len < end) {
1223 		wpa_printf(MSG_DEBUG, "IEEE 802.11: Too short SA Query Action "
1224 			   "frame (len=%lu)", (unsigned long) len);
1225 		return;
1226 	}
1227 
1228 	ieee802_11_sa_query_action(hapd, mgmt->sa,
1229 				   mgmt->u.action.u.sa_query_resp.action,
1230 				   mgmt->u.action.u.sa_query_resp.trans_id);
1231 }
1232 
1233 
robust_action_frame(u8 category)1234 static int robust_action_frame(u8 category)
1235 {
1236 	return category != WLAN_ACTION_PUBLIC &&
1237 		category != WLAN_ACTION_HT;
1238 }
1239 #endif /* CONFIG_IEEE80211W */
1240 
1241 
handle_action(struct hostapd_data * hapd,const struct ieee80211_mgmt * mgmt,size_t len)1242 static void handle_action(struct hostapd_data *hapd,
1243 			  const struct ieee80211_mgmt *mgmt, size_t len)
1244 {
1245 #if defined(CONFIG_IEEE80211W) || defined(CONFIG_IEEE80211R)
1246 	struct sta_info *sta;
1247 	sta = ap_get_sta(hapd, mgmt->sa);
1248 #endif /* CONFIG_IEEE80211W || CONFIG_IEEE80211R */
1249 
1250 	if (len < IEEE80211_HDRLEN + 1) {
1251 		hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
1252 			       HOSTAPD_LEVEL_DEBUG,
1253 			       "handle_action - too short payload (len=%lu)",
1254 			       (unsigned long) len);
1255 		return;
1256 	}
1257 
1258 #ifdef CONFIG_IEEE80211W
1259 	if (sta && (sta->flags & WLAN_STA_MFP) &&
1260 	    !(mgmt->frame_control & host_to_le16(WLAN_FC_ISWEP) &&
1261 	      robust_action_frame(mgmt->u.action.category))) {
1262 		hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
1263 			       HOSTAPD_LEVEL_DEBUG,
1264 			       "Dropped unprotected Robust Action frame from "
1265 			       "an MFP STA");
1266 		return;
1267 	}
1268 #endif /* CONFIG_IEEE80211W */
1269 
1270 	switch (mgmt->u.action.category) {
1271 #ifdef CONFIG_IEEE80211R
1272 	case WLAN_ACTION_FT:
1273 	{
1274 		if (sta == NULL || !(sta->flags & WLAN_STA_ASSOC)) {
1275 			wpa_printf(MSG_DEBUG, "IEEE 802.11: Ignored FT Action "
1276 				   "frame from unassociated STA " MACSTR,
1277 				   MAC2STR(mgmt->sa));
1278 			return;
1279 		}
1280 
1281 		if (wpa_ft_action_rx(sta->wpa_sm, (u8 *) &mgmt->u.action,
1282 				     len - IEEE80211_HDRLEN))
1283 			break;
1284 
1285 		return;
1286 	}
1287 #endif /* CONFIG_IEEE80211R */
1288 	case WLAN_ACTION_WMM:
1289 		hostapd_wmm_action(hapd, mgmt, len);
1290 		return;
1291 #ifdef CONFIG_IEEE80211W
1292 	case WLAN_ACTION_SA_QUERY:
1293 		hostapd_sa_query_action(hapd, mgmt, len);
1294 		return;
1295 #endif /* CONFIG_IEEE80211W */
1296 	case WLAN_ACTION_PUBLIC:
1297 		if (hapd->public_action_cb) {
1298 			hapd->public_action_cb(hapd->public_action_cb_ctx,
1299 					       (u8 *) mgmt, len,
1300 					       hapd->iface->freq);
1301 			return;
1302 		}
1303 		break;
1304 	case WLAN_ACTION_VENDOR_SPECIFIC:
1305 		if (hapd->vendor_action_cb) {
1306 			if (hapd->vendor_action_cb(hapd->vendor_action_cb_ctx,
1307 						   (u8 *) mgmt, len,
1308 						   hapd->iface->freq) == 0)
1309 				return;
1310 		}
1311 		break;
1312 	}
1313 
1314 	hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
1315 		       HOSTAPD_LEVEL_DEBUG,
1316 		       "handle_action - unknown action category %d or invalid "
1317 		       "frame",
1318 		       mgmt->u.action.category);
1319 	if (!(mgmt->da[0] & 0x01) && !(mgmt->u.action.category & 0x80) &&
1320 	    !(mgmt->sa[0] & 0x01)) {
1321 		struct ieee80211_mgmt *resp;
1322 
1323 		/*
1324 		 * IEEE 802.11-REVma/D9.0 - 7.3.1.11
1325 		 * Return the Action frame to the source without change
1326 		 * except that MSB of the Category set to 1.
1327 		 */
1328 		wpa_printf(MSG_DEBUG, "IEEE 802.11: Return unknown Action "
1329 			   "frame back to sender");
1330 		resp = os_malloc(len);
1331 		if (resp == NULL)
1332 			return;
1333 		os_memcpy(resp, mgmt, len);
1334 		os_memcpy(resp->da, resp->sa, ETH_ALEN);
1335 		os_memcpy(resp->sa, hapd->own_addr, ETH_ALEN);
1336 		os_memcpy(resp->bssid, hapd->own_addr, ETH_ALEN);
1337 		resp->u.action.category |= 0x80;
1338 
1339 		hostapd_drv_send_mlme(hapd, resp, len, 0);
1340 		os_free(resp);
1341 	}
1342 }
1343 
1344 
1345 /**
1346  * ieee802_11_mgmt - process incoming IEEE 802.11 management frames
1347  * @hapd: hostapd BSS data structure (the BSS to which the management frame was
1348  * sent to)
1349  * @buf: management frame data (starting from IEEE 802.11 header)
1350  * @len: length of frame data in octets
1351  * @fi: meta data about received frame (signal level, etc.)
1352  *
1353  * Process all incoming IEEE 802.11 management frames. This will be called for
1354  * each frame received from the kernel driver through wlan#ap interface. In
1355  * addition, it can be called to re-inserted pending frames (e.g., when using
1356  * external RADIUS server as an MAC ACL).
1357  */
ieee802_11_mgmt(struct hostapd_data * hapd,const u8 * buf,size_t len,struct hostapd_frame_info * fi)1358 void ieee802_11_mgmt(struct hostapd_data *hapd, const u8 *buf, size_t len,
1359 		     struct hostapd_frame_info *fi)
1360 {
1361 	struct ieee80211_mgmt *mgmt;
1362 	int broadcast;
1363 	u16 fc, stype;
1364 
1365 	if (len < 24)
1366 		return;
1367 
1368 	mgmt = (struct ieee80211_mgmt *) buf;
1369 	fc = le_to_host16(mgmt->frame_control);
1370 	stype = WLAN_FC_GET_STYPE(fc);
1371 
1372 	if (stype == WLAN_FC_STYPE_BEACON) {
1373 		handle_beacon(hapd, mgmt, len, fi);
1374 		return;
1375 	}
1376 
1377 	broadcast = mgmt->bssid[0] == 0xff && mgmt->bssid[1] == 0xff &&
1378 		mgmt->bssid[2] == 0xff && mgmt->bssid[3] == 0xff &&
1379 		mgmt->bssid[4] == 0xff && mgmt->bssid[5] == 0xff;
1380 
1381 	if (!broadcast &&
1382 #ifdef CONFIG_P2P
1383 	    /* Invitation responses can be sent with the peer MAC as BSSID */
1384 	    !((hapd->conf->p2p & P2P_GROUP_OWNER) &&
1385 	      stype == WLAN_FC_STYPE_ACTION) &&
1386 #endif /* CONFIG_P2P */
1387 	    os_memcmp(mgmt->bssid, hapd->own_addr, ETH_ALEN) != 0) {
1388 		printf("MGMT: BSSID=" MACSTR " not our address\n",
1389 		       MAC2STR(mgmt->bssid));
1390 		return;
1391 	}
1392 
1393 
1394 	if (stype == WLAN_FC_STYPE_PROBE_REQ) {
1395 		handle_probe_req(hapd, mgmt, len);
1396 		return;
1397 	}
1398 
1399 	if (os_memcmp(mgmt->da, hapd->own_addr, ETH_ALEN) != 0) {
1400 		hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
1401 			       HOSTAPD_LEVEL_DEBUG,
1402 			       "MGMT: DA=" MACSTR " not our address",
1403 			       MAC2STR(mgmt->da));
1404 		return;
1405 	}
1406 
1407 	switch (stype) {
1408 	case WLAN_FC_STYPE_AUTH:
1409 		wpa_printf(MSG_DEBUG, "mgmt::auth");
1410 		handle_auth(hapd, mgmt, len);
1411 		break;
1412 	case WLAN_FC_STYPE_ASSOC_REQ:
1413 		wpa_printf(MSG_DEBUG, "mgmt::assoc_req");
1414 		handle_assoc(hapd, mgmt, len, 0);
1415 		break;
1416 	case WLAN_FC_STYPE_REASSOC_REQ:
1417 		wpa_printf(MSG_DEBUG, "mgmt::reassoc_req");
1418 		handle_assoc(hapd, mgmt, len, 1);
1419 		break;
1420 	case WLAN_FC_STYPE_DISASSOC:
1421 		wpa_printf(MSG_DEBUG, "mgmt::disassoc");
1422 		handle_disassoc(hapd, mgmt, len);
1423 		break;
1424 	case WLAN_FC_STYPE_DEAUTH:
1425 		wpa_msg(hapd->msg_ctx, MSG_DEBUG, "mgmt::deauth");
1426 		handle_deauth(hapd, mgmt, len);
1427 		break;
1428 	case WLAN_FC_STYPE_ACTION:
1429 		wpa_printf(MSG_DEBUG, "mgmt::action");
1430 		handle_action(hapd, mgmt, len);
1431 		break;
1432 	default:
1433 		hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
1434 			       HOSTAPD_LEVEL_DEBUG,
1435 			       "unknown mgmt frame subtype %d", stype);
1436 		break;
1437 	}
1438 }
1439 
1440 
handle_auth_cb(struct hostapd_data * hapd,const struct ieee80211_mgmt * mgmt,size_t len,int ok)1441 static void handle_auth_cb(struct hostapd_data *hapd,
1442 			   const struct ieee80211_mgmt *mgmt,
1443 			   size_t len, int ok)
1444 {
1445 	u16 auth_alg, auth_transaction, status_code;
1446 	struct sta_info *sta;
1447 
1448 	if (!ok) {
1449 		hostapd_logger(hapd, mgmt->da, HOSTAPD_MODULE_IEEE80211,
1450 			       HOSTAPD_LEVEL_NOTICE,
1451 			       "did not acknowledge authentication response");
1452 		return;
1453 	}
1454 
1455 	if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.auth)) {
1456 		printf("handle_auth_cb - too short payload (len=%lu)\n",
1457 		       (unsigned long) len);
1458 		return;
1459 	}
1460 
1461 	auth_alg = le_to_host16(mgmt->u.auth.auth_alg);
1462 	auth_transaction = le_to_host16(mgmt->u.auth.auth_transaction);
1463 	status_code = le_to_host16(mgmt->u.auth.status_code);
1464 
1465 	sta = ap_get_sta(hapd, mgmt->da);
1466 	if (!sta) {
1467 		printf("handle_auth_cb: STA " MACSTR " not found\n",
1468 		       MAC2STR(mgmt->da));
1469 		return;
1470 	}
1471 
1472 	if (status_code == WLAN_STATUS_SUCCESS &&
1473 	    ((auth_alg == WLAN_AUTH_OPEN && auth_transaction == 2) ||
1474 	     (auth_alg == WLAN_AUTH_SHARED_KEY && auth_transaction == 4))) {
1475 		hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
1476 			       HOSTAPD_LEVEL_INFO, "authenticated");
1477 		sta->flags |= WLAN_STA_AUTH;
1478 	}
1479 }
1480 
1481 
handle_assoc_cb(struct hostapd_data * hapd,const struct ieee80211_mgmt * mgmt,size_t len,int reassoc,int ok)1482 static void handle_assoc_cb(struct hostapd_data *hapd,
1483 			    const struct ieee80211_mgmt *mgmt,
1484 			    size_t len, int reassoc, int ok)
1485 {
1486 	u16 status;
1487 	struct sta_info *sta;
1488 	int new_assoc = 1;
1489 	struct ieee80211_ht_capabilities ht_cap;
1490 
1491 	if (!ok) {
1492 		hostapd_logger(hapd, mgmt->da, HOSTAPD_MODULE_IEEE80211,
1493 			       HOSTAPD_LEVEL_DEBUG,
1494 			       "did not acknowledge association response");
1495 		return;
1496 	}
1497 
1498 	if (len < IEEE80211_HDRLEN + (reassoc ? sizeof(mgmt->u.reassoc_resp) :
1499 				      sizeof(mgmt->u.assoc_resp))) {
1500 		printf("handle_assoc_cb(reassoc=%d) - too short payload "
1501 		       "(len=%lu)\n", reassoc, (unsigned long) len);
1502 		return;
1503 	}
1504 
1505 	if (reassoc)
1506 		status = le_to_host16(mgmt->u.reassoc_resp.status_code);
1507 	else
1508 		status = le_to_host16(mgmt->u.assoc_resp.status_code);
1509 
1510 	sta = ap_get_sta(hapd, mgmt->da);
1511 	if (!sta) {
1512 		printf("handle_assoc_cb: STA " MACSTR " not found\n",
1513 		       MAC2STR(mgmt->da));
1514 		return;
1515 	}
1516 
1517 	if (status != WLAN_STATUS_SUCCESS)
1518 		goto fail;
1519 
1520 	/* Stop previous accounting session, if one is started, and allocate
1521 	 * new session id for the new session. */
1522 	accounting_sta_stop(hapd, sta);
1523 
1524 	hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
1525 		       HOSTAPD_LEVEL_INFO,
1526 		       "associated (aid %d)",
1527 		       sta->aid);
1528 
1529 	if (sta->flags & WLAN_STA_ASSOC)
1530 		new_assoc = 0;
1531 	sta->flags |= WLAN_STA_ASSOC;
1532 	if ((!hapd->conf->ieee802_1x && !hapd->conf->wpa) ||
1533 	    sta->auth_alg == WLAN_AUTH_FT) {
1534 		/*
1535 		 * Open, static WEP, or FT protocol; no separate authorization
1536 		 * step.
1537 		 */
1538 		ap_sta_set_authorized(hapd, sta, 1);
1539 	}
1540 
1541 	if (reassoc)
1542 		mlme_reassociate_indication(hapd, sta);
1543 	else
1544 		mlme_associate_indication(hapd, sta);
1545 
1546 #ifdef CONFIG_IEEE80211W
1547 	sta->sa_query_timed_out = 0;
1548 #endif /* CONFIG_IEEE80211W */
1549 
1550 	/*
1551 	 * Remove the STA entry in order to make sure the STA PS state gets
1552 	 * cleared and configuration gets updated in case of reassociation back
1553 	 * to the same AP.
1554 	 */
1555 	hostapd_drv_sta_remove(hapd, sta->addr);
1556 
1557 #ifdef CONFIG_IEEE80211N
1558 	if (sta->flags & WLAN_STA_HT)
1559 		hostapd_get_ht_capab(hapd, sta->ht_capabilities, &ht_cap);
1560 #endif /* CONFIG_IEEE80211N */
1561 
1562 	if (hostapd_sta_add(hapd, sta->addr, sta->aid, sta->capability,
1563 			    sta->supported_rates, sta->supported_rates_len,
1564 			    sta->listen_interval,
1565 			    sta->flags & WLAN_STA_HT ? &ht_cap : NULL,
1566 			    sta->flags, sta->qosinfo)) {
1567 		hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
1568 			       HOSTAPD_LEVEL_NOTICE,
1569 			       "Could not add STA to kernel driver");
1570 
1571 		ap_sta_disconnect(hapd, sta, sta->addr,
1572 				  WLAN_REASON_DISASSOC_AP_BUSY);
1573 
1574 		goto fail;
1575 	}
1576 
1577 	if (sta->flags & WLAN_STA_WDS)
1578 		hostapd_set_wds_sta(hapd, sta->addr, sta->aid, 1);
1579 
1580 	if (sta->eapol_sm == NULL) {
1581 		/*
1582 		 * This STA does not use RADIUS server for EAP authentication,
1583 		 * so bind it to the selected VLAN interface now, since the
1584 		 * interface selection is not going to change anymore.
1585 		 */
1586 		if (ap_sta_bind_vlan(hapd, sta, 0) < 0)
1587 			goto fail;
1588 	} else if (sta->vlan_id) {
1589 		/* VLAN ID already set (e.g., by PMKSA caching), so bind STA */
1590 		if (ap_sta_bind_vlan(hapd, sta, 0) < 0)
1591 			goto fail;
1592 	}
1593 
1594 	hostapd_set_sta_flags(hapd, sta);
1595 
1596 	if (sta->auth_alg == WLAN_AUTH_FT)
1597 		wpa_auth_sm_event(sta->wpa_sm, WPA_ASSOC_FT);
1598 	else
1599 		wpa_auth_sm_event(sta->wpa_sm, WPA_ASSOC);
1600 	hapd->new_assoc_sta_cb(hapd, sta, !new_assoc);
1601 
1602 	ieee802_1x_notify_port_enabled(sta->eapol_sm, 1);
1603 
1604  fail:
1605 	/* Copy of the association request is not needed anymore */
1606 	if (sta->last_assoc_req) {
1607 		os_free(sta->last_assoc_req);
1608 		sta->last_assoc_req = NULL;
1609 	}
1610 }
1611 
1612 
handle_deauth_cb(struct hostapd_data * hapd,const struct ieee80211_mgmt * mgmt,size_t len,int ok)1613 static void handle_deauth_cb(struct hostapd_data *hapd,
1614 			     const struct ieee80211_mgmt *mgmt,
1615 			     size_t len, int ok)
1616 {
1617 	struct sta_info *sta;
1618 	if (mgmt->da[0] & 0x01)
1619 		return;
1620 	sta = ap_get_sta(hapd, mgmt->da);
1621 	if (!sta) {
1622 		wpa_printf(MSG_DEBUG, "handle_deauth_cb: STA " MACSTR
1623 			   " not found", MAC2STR(mgmt->da));
1624 		return;
1625 	}
1626 	if (ok)
1627 		wpa_printf(MSG_DEBUG, "STA " MACSTR " acknowledged deauth",
1628 			   MAC2STR(sta->addr));
1629 	else
1630 		wpa_printf(MSG_DEBUG, "STA " MACSTR " did not acknowledge "
1631 			   "deauth", MAC2STR(sta->addr));
1632 
1633 	ap_sta_deauth_cb(hapd, sta);
1634 }
1635 
1636 
handle_disassoc_cb(struct hostapd_data * hapd,const struct ieee80211_mgmt * mgmt,size_t len,int ok)1637 static void handle_disassoc_cb(struct hostapd_data *hapd,
1638 			       const struct ieee80211_mgmt *mgmt,
1639 			       size_t len, int ok)
1640 {
1641 	struct sta_info *sta;
1642 	if (mgmt->da[0] & 0x01)
1643 		return;
1644 	sta = ap_get_sta(hapd, mgmt->da);
1645 	if (!sta) {
1646 		wpa_printf(MSG_DEBUG, "handle_disassoc_cb: STA " MACSTR
1647 			   " not found", MAC2STR(mgmt->da));
1648 		return;
1649 	}
1650 	if (ok)
1651 		wpa_printf(MSG_DEBUG, "STA " MACSTR " acknowledged disassoc",
1652 			   MAC2STR(sta->addr));
1653 	else
1654 		wpa_printf(MSG_DEBUG, "STA " MACSTR " did not acknowledge "
1655 			   "disassoc", MAC2STR(sta->addr));
1656 
1657 	ap_sta_disassoc_cb(hapd, sta);
1658 }
1659 
1660 
1661 /**
1662  * ieee802_11_mgmt_cb - Process management frame TX status callback
1663  * @hapd: hostapd BSS data structure (the BSS from which the management frame
1664  * was sent from)
1665  * @buf: management frame data (starting from IEEE 802.11 header)
1666  * @len: length of frame data in octets
1667  * @stype: management frame subtype from frame control field
1668  * @ok: Whether the frame was ACK'ed
1669  */
ieee802_11_mgmt_cb(struct hostapd_data * hapd,const u8 * buf,size_t len,u16 stype,int ok)1670 void ieee802_11_mgmt_cb(struct hostapd_data *hapd, const u8 *buf, size_t len,
1671 			u16 stype, int ok)
1672 {
1673 	const struct ieee80211_mgmt *mgmt;
1674 	mgmt = (const struct ieee80211_mgmt *) buf;
1675 
1676 	switch (stype) {
1677 	case WLAN_FC_STYPE_AUTH:
1678 		wpa_printf(MSG_DEBUG, "mgmt::auth cb");
1679 		handle_auth_cb(hapd, mgmt, len, ok);
1680 		break;
1681 	case WLAN_FC_STYPE_ASSOC_RESP:
1682 		wpa_printf(MSG_DEBUG, "mgmt::assoc_resp cb");
1683 		handle_assoc_cb(hapd, mgmt, len, 0, ok);
1684 		break;
1685 	case WLAN_FC_STYPE_REASSOC_RESP:
1686 		wpa_printf(MSG_DEBUG, "mgmt::reassoc_resp cb");
1687 		handle_assoc_cb(hapd, mgmt, len, 1, ok);
1688 		break;
1689 	case WLAN_FC_STYPE_PROBE_RESP:
1690 		wpa_printf(MSG_EXCESSIVE, "mgmt::proberesp cb");
1691 		break;
1692 	case WLAN_FC_STYPE_DEAUTH:
1693 		wpa_printf(MSG_DEBUG, "mgmt::deauth cb");
1694 		handle_deauth_cb(hapd, mgmt, len, ok);
1695 		break;
1696 	case WLAN_FC_STYPE_DISASSOC:
1697 		wpa_printf(MSG_DEBUG, "mgmt::disassoc cb");
1698 		handle_disassoc_cb(hapd, mgmt, len, ok);
1699 		break;
1700 	case WLAN_FC_STYPE_ACTION:
1701 		wpa_printf(MSG_DEBUG, "mgmt::action cb");
1702 		break;
1703 	default:
1704 		printf("unknown mgmt cb frame subtype %d\n", stype);
1705 		break;
1706 	}
1707 }
1708 
1709 
ieee802_11_get_mib(struct hostapd_data * hapd,char * buf,size_t buflen)1710 int ieee802_11_get_mib(struct hostapd_data *hapd, char *buf, size_t buflen)
1711 {
1712 	/* TODO */
1713 	return 0;
1714 }
1715 
1716 
ieee802_11_get_mib_sta(struct hostapd_data * hapd,struct sta_info * sta,char * buf,size_t buflen)1717 int ieee802_11_get_mib_sta(struct hostapd_data *hapd, struct sta_info *sta,
1718 			   char *buf, size_t buflen)
1719 {
1720 	/* TODO */
1721 	return 0;
1722 }
1723 
1724 
hostapd_tx_status(struct hostapd_data * hapd,const u8 * addr,const u8 * buf,size_t len,int ack)1725 void hostapd_tx_status(struct hostapd_data *hapd, const u8 *addr,
1726 		       const u8 *buf, size_t len, int ack)
1727 {
1728 	struct sta_info *sta;
1729 	struct hostapd_iface *iface = hapd->iface;
1730 
1731 	sta = ap_get_sta(hapd, addr);
1732 	if (sta == NULL && iface->num_bss > 1) {
1733 		size_t j;
1734 		for (j = 0; j < iface->num_bss; j++) {
1735 			hapd = iface->bss[j];
1736 			sta = ap_get_sta(hapd, addr);
1737 			if (sta)
1738 				break;
1739 		}
1740 	}
1741 	if (sta == NULL || !(sta->flags & WLAN_STA_ASSOC))
1742 		return;
1743 	if (sta->flags & WLAN_STA_PENDING_POLL) {
1744 		wpa_printf(MSG_DEBUG, "STA " MACSTR " %s pending "
1745 			   "activity poll", MAC2STR(sta->addr),
1746 			   ack ? "ACKed" : "did not ACK");
1747 		if (ack)
1748 			sta->flags &= ~WLAN_STA_PENDING_POLL;
1749 	}
1750 
1751 	ieee802_1x_tx_status(hapd, sta, buf, len, ack);
1752 }
1753 
1754 
hostapd_eapol_tx_status(struct hostapd_data * hapd,const u8 * dst,const u8 * data,size_t len,int ack)1755 void hostapd_eapol_tx_status(struct hostapd_data *hapd, const u8 *dst,
1756 			     const u8 *data, size_t len, int ack)
1757 {
1758 	struct sta_info *sta;
1759 	struct hostapd_iface *iface = hapd->iface;
1760 
1761 	sta = ap_get_sta(hapd, dst);
1762 	if (sta == NULL && iface->num_bss > 1) {
1763 		size_t j;
1764 		for (j = 0; j < iface->num_bss; j++) {
1765 			hapd = iface->bss[j];
1766 			sta = ap_get_sta(hapd, dst);
1767 			if (sta)
1768 				break;
1769 		}
1770 	}
1771 	if (sta == NULL || !(sta->flags & WLAN_STA_ASSOC)) {
1772 		wpa_printf(MSG_DEBUG, "Ignore TX status for Data frame to STA "
1773 			   MACSTR " that is not currently associated",
1774 			   MAC2STR(dst));
1775 		return;
1776 	}
1777 
1778 	ieee802_1x_eapol_tx_status(hapd, sta, data, len, ack);
1779 }
1780 
1781 
hostapd_client_poll_ok(struct hostapd_data * hapd,const u8 * addr)1782 void hostapd_client_poll_ok(struct hostapd_data *hapd, const u8 *addr)
1783 {
1784 	struct sta_info *sta;
1785 	struct hostapd_iface *iface = hapd->iface;
1786 
1787 	sta = ap_get_sta(hapd, addr);
1788 	if (sta == NULL && iface->num_bss > 1) {
1789 		size_t j;
1790 		for (j = 0; j < iface->num_bss; j++) {
1791 			hapd = iface->bss[j];
1792 			sta = ap_get_sta(hapd, addr);
1793 			if (sta)
1794 				break;
1795 		}
1796 	}
1797 	if (sta == NULL)
1798 		return;
1799 	if (!(sta->flags & WLAN_STA_PENDING_POLL))
1800 		return;
1801 
1802 	wpa_printf(MSG_DEBUG, "STA " MACSTR " ACKed pending "
1803 		   "activity poll", MAC2STR(sta->addr));
1804 	sta->flags &= ~WLAN_STA_PENDING_POLL;
1805 }
1806 
1807 
ieee802_11_rx_from_unknown(struct hostapd_data * hapd,const u8 * src,int wds)1808 void ieee802_11_rx_from_unknown(struct hostapd_data *hapd, const u8 *src,
1809 				int wds)
1810 {
1811 	struct sta_info *sta;
1812 
1813 	sta = ap_get_sta(hapd, src);
1814 	if (sta && (sta->flags & WLAN_STA_ASSOC)) {
1815 		if (wds && !(sta->flags & WLAN_STA_WDS)) {
1816 			wpa_printf(MSG_DEBUG, "Enable 4-address WDS mode for "
1817 				   "STA " MACSTR " (aid %u)",
1818 				   MAC2STR(sta->addr), sta->aid);
1819 			sta->flags |= WLAN_STA_WDS;
1820 			hostapd_set_wds_sta(hapd, sta->addr, sta->aid, 1);
1821 		}
1822 		return;
1823 	}
1824 
1825 	wpa_printf(MSG_DEBUG, "Data/PS-poll frame from not associated STA "
1826 		   MACSTR, MAC2STR(src));
1827 	if (src[0] & 0x01) {
1828 		/* Broadcast bit set in SA?! Ignore the frame silently. */
1829 		return;
1830 	}
1831 
1832 	if (sta && (sta->flags & WLAN_STA_ASSOC_REQ_OK)) {
1833 		wpa_printf(MSG_DEBUG, "Association Response to the STA has "
1834 			   "already been sent, but no TX status yet known - "
1835 			   "ignore Class 3 frame issue with " MACSTR,
1836 			   MAC2STR(src));
1837 		return;
1838 	}
1839 
1840 	if (sta && (sta->flags & WLAN_STA_AUTH))
1841 		hostapd_drv_sta_disassoc(
1842 			hapd, src,
1843 			WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA);
1844 	else
1845 		hostapd_drv_sta_deauth(
1846 			hapd, src,
1847 			WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA);
1848 }
1849 
1850 
1851 #endif /* CONFIG_NATIVE_WINDOWS */
1852