xref: /netbsd-src/external/bsd/wpa/dist/src/ap/drv_callbacks.c (revision 6a493d6bc668897c91594964a732d38505b70cbb)
1 /*
2  * hostapd / Callback functions for driver wrappers
3  * Copyright (c) 2002-2009, Jouni Malinen <j@w1.fi>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation.
8  *
9  * Alternatively, this software may be distributed under the terms of BSD
10  * license.
11  *
12  * See README and COPYING for more details.
13  */
14 
15 #include "utils/includes.h"
16 
17 #include "utils/common.h"
18 #include "radius/radius.h"
19 #include "drivers/driver.h"
20 #include "common/ieee802_11_defs.h"
21 #include "common/ieee802_11_common.h"
22 #include "common/wpa_ctrl.h"
23 #include "crypto/random.h"
24 #include "p2p/p2p.h"
25 #include "wps/wps.h"
26 #include "hostapd.h"
27 #include "ieee802_11.h"
28 #include "sta_info.h"
29 #include "accounting.h"
30 #include "tkip_countermeasures.h"
31 #include "iapp.h"
32 #include "ieee802_1x.h"
33 #include "wpa_auth.h"
34 #include "wmm.h"
35 #include "wps_hostapd.h"
36 #include "ap_drv_ops.h"
37 #include "ap_config.h"
38 
39 
40 int hostapd_notif_assoc(struct hostapd_data *hapd, const u8 *addr,
41 			const u8 *req_ies, size_t req_ies_len, int reassoc)
42 {
43 	struct sta_info *sta;
44 	int new_assoc, res;
45 	struct ieee802_11_elems elems;
46 	const u8 *ie;
47 	size_t ielen;
48 	u16 reason = WLAN_REASON_UNSPECIFIED;
49 
50 	if (addr == NULL) {
51 		/*
52 		 * This could potentially happen with unexpected event from the
53 		 * driver wrapper. This was seen at least in one case where the
54 		 * driver ended up being set to station mode while hostapd was
55 		 * running, so better make sure we stop processing such an
56 		 * event here.
57 		 */
58 		wpa_printf(MSG_DEBUG, "hostapd_notif_assoc: Skip event with "
59 			   "no address");
60 		return -1;
61 	}
62 	random_add_randomness(addr, ETH_ALEN);
63 
64 	hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211,
65 		       HOSTAPD_LEVEL_INFO, "associated");
66 
67 	ieee802_11_parse_elems(req_ies, req_ies_len, &elems, 0);
68 	if (elems.wps_ie) {
69 		ie = elems.wps_ie - 2;
70 		ielen = elems.wps_ie_len + 2;
71 		wpa_printf(MSG_DEBUG, "STA included WPS IE in (Re)AssocReq");
72 	} else if (elems.rsn_ie) {
73 		ie = elems.rsn_ie - 2;
74 		ielen = elems.rsn_ie_len + 2;
75 		wpa_printf(MSG_DEBUG, "STA included RSN IE in (Re)AssocReq");
76 	} else if (elems.wpa_ie) {
77 		ie = elems.wpa_ie - 2;
78 		ielen = elems.wpa_ie_len + 2;
79 		wpa_printf(MSG_DEBUG, "STA included WPA IE in (Re)AssocReq");
80 	} else {
81 		ie = NULL;
82 		ielen = 0;
83 		wpa_printf(MSG_DEBUG, "STA did not include WPS/RSN/WPA IE in "
84 			   "(Re)AssocReq");
85 	}
86 
87 	sta = ap_get_sta(hapd, addr);
88 	if (sta) {
89 		accounting_sta_stop(hapd, sta);
90 
91 		/*
92 		 * Make sure that the previously registered inactivity timer
93 		 * will not remove the STA immediately.
94 		 */
95 		sta->timeout_next = STA_NULLFUNC;
96 	} else {
97 		sta = ap_sta_add(hapd, addr);
98 		if (sta == NULL)
99 			return -1;
100 	}
101 	sta->flags &= ~(WLAN_STA_WPS | WLAN_STA_MAYBE_WPS | WLAN_STA_WPS2);
102 
103 #ifdef CONFIG_P2P
104 	if (elems.p2p) {
105 		wpabuf_free(sta->p2p_ie);
106 		sta->p2p_ie = ieee802_11_vendor_ie_concat(req_ies, req_ies_len,
107 							  P2P_IE_VENDOR_TYPE);
108 	}
109 #endif /* CONFIG_P2P */
110 
111 	if (hapd->conf->wpa) {
112 		if (ie == NULL || ielen == 0) {
113 #ifdef CONFIG_WPS
114 			if (hapd->conf->wps_state) {
115 				wpa_printf(MSG_DEBUG, "STA did not include "
116 					   "WPA/RSN IE in (Re)Association "
117 					   "Request - possible WPS use");
118 				sta->flags |= WLAN_STA_MAYBE_WPS;
119 				goto skip_wpa_check;
120 			}
121 #endif /* CONFIG_WPS */
122 
123 			wpa_printf(MSG_DEBUG, "No WPA/RSN IE from STA");
124 			return -1;
125 		}
126 #ifdef CONFIG_WPS
127 		if (hapd->conf->wps_state && ie[0] == 0xdd && ie[1] >= 4 &&
128 		    os_memcmp(ie + 2, "\x00\x50\xf2\x04", 4) == 0) {
129 			struct wpabuf *wps;
130 			sta->flags |= WLAN_STA_WPS;
131 			wps = ieee802_11_vendor_ie_concat(ie, ielen,
132 							  WPS_IE_VENDOR_TYPE);
133 			if (wps) {
134 				if (wps_is_20(wps)) {
135 					wpa_printf(MSG_DEBUG, "WPS: STA "
136 						   "supports WPS 2.0");
137 					sta->flags |= WLAN_STA_WPS2;
138 				}
139 				wpabuf_free(wps);
140 			}
141 			goto skip_wpa_check;
142 		}
143 #endif /* CONFIG_WPS */
144 
145 		if (sta->wpa_sm == NULL)
146 			sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth,
147 							sta->addr);
148 		if (sta->wpa_sm == NULL) {
149 			wpa_printf(MSG_ERROR, "Failed to initialize WPA state "
150 				   "machine");
151 			return -1;
152 		}
153 		res = wpa_validate_wpa_ie(hapd->wpa_auth, sta->wpa_sm,
154 					  ie, ielen, NULL, 0);
155 		if (res != WPA_IE_OK) {
156 			wpa_printf(MSG_DEBUG, "WPA/RSN information element "
157 				   "rejected? (res %u)", res);
158 			wpa_hexdump(MSG_DEBUG, "IE", ie, ielen);
159 			if (res == WPA_INVALID_GROUP)
160 				reason = WLAN_REASON_GROUP_CIPHER_NOT_VALID;
161 			else if (res == WPA_INVALID_PAIRWISE)
162 				reason = WLAN_REASON_PAIRWISE_CIPHER_NOT_VALID;
163 			else if (res == WPA_INVALID_AKMP)
164 				reason = WLAN_REASON_AKMP_NOT_VALID;
165 #ifdef CONFIG_IEEE80211W
166 			else if (res == WPA_MGMT_FRAME_PROTECTION_VIOLATION)
167 				reason = WLAN_REASON_INVALID_IE;
168 			else if (res == WPA_INVALID_MGMT_GROUP_CIPHER)
169 				reason = WLAN_REASON_GROUP_CIPHER_NOT_VALID;
170 #endif /* CONFIG_IEEE80211W */
171 			else
172 				reason = WLAN_REASON_INVALID_IE;
173 			goto fail;
174 		}
175 	} else if (hapd->conf->wps_state) {
176 #ifdef CONFIG_WPS
177 		struct wpabuf *wps;
178 		if (req_ies)
179 			wps = ieee802_11_vendor_ie_concat(req_ies, req_ies_len,
180 							  WPS_IE_VENDOR_TYPE);
181 		else
182 			wps = NULL;
183 #ifdef CONFIG_WPS_STRICT
184 		if (wps && wps_validate_assoc_req(wps) < 0) {
185 			reason = WLAN_REASON_INVALID_IE;
186 			wpabuf_free(wps);
187 			goto fail;
188 		}
189 #endif /* CONFIG_WPS_STRICT */
190 		if (wps) {
191 			sta->flags |= WLAN_STA_WPS;
192 			if (wps_is_20(wps)) {
193 				wpa_printf(MSG_DEBUG, "WPS: STA supports "
194 					   "WPS 2.0");
195 				sta->flags |= WLAN_STA_WPS2;
196 			}
197 		} else
198 			sta->flags |= WLAN_STA_MAYBE_WPS;
199 		wpabuf_free(wps);
200 #endif /* CONFIG_WPS */
201 	}
202 #ifdef CONFIG_WPS
203 skip_wpa_check:
204 #endif /* CONFIG_WPS */
205 
206 	new_assoc = (sta->flags & WLAN_STA_ASSOC) == 0;
207 	sta->flags |= WLAN_STA_AUTH | WLAN_STA_ASSOC;
208 	wpa_auth_sm_event(sta->wpa_sm, WPA_ASSOC);
209 
210 	hostapd_new_assoc_sta(hapd, sta, !new_assoc);
211 
212 	ieee802_1x_notify_port_enabled(sta->eapol_sm, 1);
213 
214 #ifdef CONFIG_P2P
215 	if (req_ies) {
216 		p2p_group_notif_assoc(hapd->p2p_group, sta->addr,
217 				      req_ies, req_ies_len);
218 	}
219 #endif /* CONFIG_P2P */
220 
221 	return 0;
222 
223 fail:
224 	hostapd_drv_sta_disassoc(hapd, sta->addr, reason);
225 	ap_free_sta(hapd, sta);
226 	return -1;
227 }
228 
229 
230 void hostapd_notif_disassoc(struct hostapd_data *hapd, const u8 *addr)
231 {
232 	struct sta_info *sta;
233 
234 	if (addr == NULL) {
235 		/*
236 		 * This could potentially happen with unexpected event from the
237 		 * driver wrapper. This was seen at least in one case where the
238 		 * driver ended up reporting a station mode event while hostapd
239 		 * was running, so better make sure we stop processing such an
240 		 * event here.
241 		 */
242 		wpa_printf(MSG_DEBUG, "hostapd_notif_disassoc: Skip event "
243 			   "with no address");
244 		return;
245 	}
246 
247 	hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211,
248 		       HOSTAPD_LEVEL_INFO, "disassociated");
249 
250 	sta = ap_get_sta(hapd, addr);
251 	if (sta == NULL) {
252 		wpa_printf(MSG_DEBUG, "Disassociation notification for "
253 			   "unknown STA " MACSTR, MAC2STR(addr));
254 		return;
255 	}
256 
257 	ap_sta_set_authorized(hapd, sta, 0);
258 	sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC);
259 	wpa_auth_sm_event(sta->wpa_sm, WPA_DISASSOC);
260 	sta->acct_terminate_cause = RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST;
261 	ieee802_1x_notify_port_enabled(sta->eapol_sm, 0);
262 	ap_free_sta(hapd, sta);
263 }
264 
265 
266 void hostapd_event_sta_low_ack(struct hostapd_data *hapd, const u8 *addr)
267 {
268 	struct sta_info *sta = ap_get_sta(hapd, addr);
269 
270 	if (!sta || !hapd->conf->disassoc_low_ack)
271 		return;
272 
273 	hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211,
274 		       HOSTAPD_LEVEL_INFO, "disconnected due to excessive "
275 		       "missing ACKs");
276 	hostapd_drv_sta_disassoc(hapd, addr, WLAN_REASON_DISASSOC_LOW_ACK);
277 	if (sta)
278 		ap_sta_disassociate(hapd, sta, WLAN_REASON_DISASSOC_LOW_ACK);
279 }
280 
281 
282 int hostapd_probe_req_rx(struct hostapd_data *hapd, const u8 *sa, const u8 *da,
283 			 const u8 *bssid, const u8 *ie, size_t ie_len)
284 {
285 	size_t i;
286 	int ret = 0;
287 
288 	if (sa == NULL || ie == NULL)
289 		return -1;
290 
291 	random_add_randomness(sa, ETH_ALEN);
292 	for (i = 0; hapd->probereq_cb && i < hapd->num_probereq_cb; i++) {
293 		if (hapd->probereq_cb[i].cb(hapd->probereq_cb[i].ctx,
294 					    sa, da, bssid, ie, ie_len) > 0) {
295 			ret = 1;
296 			break;
297 		}
298 	}
299 	return ret;
300 }
301 
302 
303 #ifdef HOSTAPD
304 
305 #ifdef NEED_AP_MLME
306 
307 #define HAPD_BROADCAST ((struct hostapd_data *) -1)
308 
309 static struct hostapd_data * get_hapd_bssid(struct hostapd_iface *iface,
310 					    const u8 *bssid)
311 {
312 	size_t i;
313 
314 	if (bssid == NULL)
315 		return NULL;
316 	if (bssid[0] == 0xff && bssid[1] == 0xff && bssid[2] == 0xff &&
317 	    bssid[3] == 0xff && bssid[4] == 0xff && bssid[5] == 0xff)
318 		return HAPD_BROADCAST;
319 
320 	for (i = 0; i < iface->num_bss; i++) {
321 		if (os_memcmp(bssid, iface->bss[i]->own_addr, ETH_ALEN) == 0)
322 			return iface->bss[i];
323 	}
324 
325 	return NULL;
326 }
327 
328 
329 static void hostapd_rx_from_unknown_sta(struct hostapd_data *hapd,
330 					const u8 *bssid, const u8 *addr,
331 					int wds)
332 {
333 	hapd = get_hapd_bssid(hapd->iface, bssid);
334 	if (hapd == NULL || hapd == HAPD_BROADCAST)
335 		return;
336 
337 	ieee802_11_rx_from_unknown(hapd, addr, wds);
338 }
339 
340 
341 static void hostapd_mgmt_rx(struct hostapd_data *hapd, struct rx_mgmt *rx_mgmt)
342 {
343 	struct hostapd_iface *iface = hapd->iface;
344 	const struct ieee80211_hdr *hdr;
345 	const u8 *bssid;
346 	struct hostapd_frame_info fi;
347 
348 	hdr = (const struct ieee80211_hdr *) rx_mgmt->frame;
349 	bssid = get_hdr_bssid(hdr, rx_mgmt->frame_len);
350 	if (bssid == NULL)
351 		return;
352 
353 	hapd = get_hapd_bssid(iface, bssid);
354 	if (hapd == NULL) {
355 		u16 fc;
356 		fc = le_to_host16(hdr->frame_control);
357 
358 		/*
359 		 * Drop frames to unknown BSSIDs except for Beacon frames which
360 		 * could be used to update neighbor information.
361 		 */
362 		if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT &&
363 		    WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_BEACON)
364 			hapd = iface->bss[0];
365 		else
366 			return;
367 	}
368 
369 	os_memset(&fi, 0, sizeof(fi));
370 	fi.datarate = rx_mgmt->datarate;
371 	fi.ssi_signal = rx_mgmt->ssi_signal;
372 
373 	if (hapd == HAPD_BROADCAST) {
374 		size_t i;
375 		for (i = 0; i < iface->num_bss; i++)
376 			ieee802_11_mgmt(iface->bss[i], rx_mgmt->frame,
377 					rx_mgmt->frame_len, &fi);
378 	} else
379 		ieee802_11_mgmt(hapd, rx_mgmt->frame, rx_mgmt->frame_len, &fi);
380 
381 	random_add_randomness(&fi, sizeof(fi));
382 }
383 
384 
385 static void hostapd_rx_action(struct hostapd_data *hapd,
386 			      struct rx_action *rx_action)
387 {
388 	struct rx_mgmt rx_mgmt;
389 	u8 *buf;
390 	struct ieee80211_hdr *hdr;
391 
392 	wpa_printf(MSG_DEBUG, "EVENT_RX_ACTION DA=" MACSTR " SA=" MACSTR
393 		   " BSSID=" MACSTR " category=%u",
394 		   MAC2STR(rx_action->da), MAC2STR(rx_action->sa),
395 		   MAC2STR(rx_action->bssid), rx_action->category);
396 	wpa_hexdump(MSG_MSGDUMP, "Received action frame contents",
397 		    rx_action->data, rx_action->len);
398 
399 	buf = os_zalloc(24 + 1 + rx_action->len);
400 	if (buf == NULL)
401 		return;
402 	hdr = (struct ieee80211_hdr *) buf;
403 	hdr->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
404 					  WLAN_FC_STYPE_ACTION);
405 	if (rx_action->category == WLAN_ACTION_SA_QUERY) {
406 		/*
407 		 * Assume frame was protected; it would have been dropped if
408 		 * not.
409 		 */
410 		hdr->frame_control |= host_to_le16(WLAN_FC_ISWEP);
411 	}
412 	os_memcpy(hdr->addr1, rx_action->da, ETH_ALEN);
413 	os_memcpy(hdr->addr2, rx_action->sa, ETH_ALEN);
414 	os_memcpy(hdr->addr3, rx_action->bssid, ETH_ALEN);
415 	buf[24] = rx_action->category;
416 	os_memcpy(buf + 24 + 1, rx_action->data, rx_action->len);
417 	os_memset(&rx_mgmt, 0, sizeof(rx_mgmt));
418 	rx_mgmt.frame = buf;
419 	rx_mgmt.frame_len = 24 + 1 + rx_action->len;
420 	hostapd_mgmt_rx(hapd, &rx_mgmt);
421 	os_free(buf);
422 }
423 
424 
425 static void hostapd_mgmt_tx_cb(struct hostapd_data *hapd, const u8 *buf,
426 			       size_t len, u16 stype, int ok)
427 {
428 	struct ieee80211_hdr *hdr;
429 	hdr = (struct ieee80211_hdr *) buf;
430 	hapd = get_hapd_bssid(hapd->iface, get_hdr_bssid(hdr, len));
431 	if (hapd == NULL || hapd == HAPD_BROADCAST)
432 		return;
433 	ieee802_11_mgmt_cb(hapd, buf, len, stype, ok);
434 }
435 
436 #endif /* NEED_AP_MLME */
437 
438 
439 static int hostapd_event_new_sta(struct hostapd_data *hapd, const u8 *addr)
440 {
441 	struct sta_info *sta = ap_get_sta(hapd, addr);
442 	if (sta)
443 		return 0;
444 
445 	wpa_printf(MSG_DEBUG, "Data frame from unknown STA " MACSTR
446 		   " - adding a new STA", MAC2STR(addr));
447 	sta = ap_sta_add(hapd, addr);
448 	if (sta) {
449 		hostapd_new_assoc_sta(hapd, sta, 0);
450 	} else {
451 		wpa_printf(MSG_DEBUG, "Failed to add STA entry for " MACSTR,
452 			   MAC2STR(addr));
453 		return -1;
454 	}
455 
456 	return 0;
457 }
458 
459 
460 static void hostapd_event_eapol_rx(struct hostapd_data *hapd, const u8 *src,
461 				   const u8 *data, size_t data_len)
462 {
463 	struct hostapd_iface *iface = hapd->iface;
464 	struct sta_info *sta;
465 	size_t j;
466 
467 	for (j = 0; j < iface->num_bss; j++) {
468 		if ((sta = ap_get_sta(iface->bss[j], src))) {
469 			if (sta->flags & WLAN_STA_ASSOC) {
470 				hapd = iface->bss[j];
471 				break;
472 			}
473 		}
474 	}
475 
476 	ieee802_1x_receive(hapd, src, data, data_len);
477 }
478 
479 
480 void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
481 			  union wpa_event_data *data)
482 {
483 	struct hostapd_data *hapd = ctx;
484 
485 	switch (event) {
486 	case EVENT_MICHAEL_MIC_FAILURE:
487 		michael_mic_failure(hapd, data->michael_mic_failure.src, 1);
488 		break;
489 	case EVENT_SCAN_RESULTS:
490 		if (hapd->iface->scan_cb)
491 			hapd->iface->scan_cb(hapd->iface);
492 		break;
493 #ifdef CONFIG_IEEE80211R
494 	case EVENT_FT_RRB_RX:
495 		wpa_ft_rrb_rx(hapd->wpa_auth, data->ft_rrb_rx.src,
496 			      data->ft_rrb_rx.data, data->ft_rrb_rx.data_len);
497 		break;
498 #endif /* CONFIG_IEEE80211R */
499 	case EVENT_WPS_BUTTON_PUSHED:
500 		hostapd_wps_button_pushed(hapd, NULL);
501 		break;
502 #ifdef NEED_AP_MLME
503 	case EVENT_TX_STATUS:
504 		switch (data->tx_status.type) {
505 		case WLAN_FC_TYPE_MGMT:
506 			hostapd_mgmt_tx_cb(hapd, data->tx_status.data,
507 					   data->tx_status.data_len,
508 					   data->tx_status.stype,
509 					   data->tx_status.ack);
510 			break;
511 		case WLAN_FC_TYPE_DATA:
512 			hostapd_tx_status(hapd, data->tx_status.dst,
513 					  data->tx_status.data,
514 					  data->tx_status.data_len,
515 					  data->tx_status.ack);
516 			break;
517 		}
518 		break;
519 	case EVENT_DRIVER_CLIENT_POLL_OK:
520 		hostapd_client_poll_ok(hapd, data->client_poll.addr);
521 		break;
522 	case EVENT_RX_FROM_UNKNOWN:
523 		hostapd_rx_from_unknown_sta(hapd, data->rx_from_unknown.bssid,
524 					    data->rx_from_unknown.addr,
525 					    data->rx_from_unknown.wds);
526 		break;
527 	case EVENT_RX_MGMT:
528 		hostapd_mgmt_rx(hapd, &data->rx_mgmt);
529 		break;
530 #endif /* NEED_AP_MLME */
531 	case EVENT_RX_PROBE_REQ:
532 		if (data->rx_probe_req.sa == NULL ||
533 		    data->rx_probe_req.ie == NULL)
534 			break;
535 		hostapd_probe_req_rx(hapd, data->rx_probe_req.sa,
536 				     data->rx_probe_req.da,
537 				     data->rx_probe_req.bssid,
538 				     data->rx_probe_req.ie,
539 				     data->rx_probe_req.ie_len);
540 		break;
541 	case EVENT_NEW_STA:
542 		hostapd_event_new_sta(hapd, data->new_sta.addr);
543 		break;
544 	case EVENT_EAPOL_RX:
545 		hostapd_event_eapol_rx(hapd, data->eapol_rx.src,
546 				       data->eapol_rx.data,
547 				       data->eapol_rx.data_len);
548 		break;
549 	case EVENT_ASSOC:
550 		hostapd_notif_assoc(hapd, data->assoc_info.addr,
551 				    data->assoc_info.req_ies,
552 				    data->assoc_info.req_ies_len,
553 				    data->assoc_info.reassoc);
554 		break;
555 	case EVENT_DISASSOC:
556 		if (data)
557 			hostapd_notif_disassoc(hapd, data->disassoc_info.addr);
558 		break;
559 	case EVENT_DEAUTH:
560 		if (data)
561 			hostapd_notif_disassoc(hapd, data->deauth_info.addr);
562 		break;
563 	case EVENT_STATION_LOW_ACK:
564 		if (!data)
565 			break;
566 		hostapd_event_sta_low_ack(hapd, data->low_ack.addr);
567 		break;
568 #ifdef NEED_AP_MLME
569 	case EVENT_RX_ACTION:
570 		if (data->rx_action.da == NULL || data->rx_action.sa == NULL ||
571 		    data->rx_action.bssid == NULL)
572 			break;
573 		hostapd_rx_action(hapd, &data->rx_action);
574 		break;
575 #endif /* NEED_AP_MLME */
576 	default:
577 		wpa_printf(MSG_DEBUG, "Unknown event %d", event);
578 		break;
579 	}
580 }
581 
582 #endif /* HOSTAPD */
583