1 /*
2  * hostapd / IEEE 802.1X-2004 Authenticator
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 #include "utils/common.h"
12 #include "utils/eloop.h"
13 #include "crypto/crypto.h"
14 #include "common/ieee802_11_defs.h"
15 #include "hostapd.h"
16 #include "ap/sta_info.h"
17 #include "ap/wpa_auth.h"
18 #include "eap_server/eap.h"
19 #include "ap/ap_config.h"
20 #include "eap_common/eap_wsc_common.h"
21 #include "ap/ieee802_1x.h"
22 #include "utils/wpa_debug.h"
23 #include "eapol_auth/eapol_auth_sm.h"
24 #include "eapol_auth/eapol_auth_sm_i.h"
25 #include "eap_server/eap.h"
26 #include "sta_info.h"
27 #include "ieee802_1x.h"
28 
29 int hostapd_send_eapol(const u8 *source, const u8 *sta_addr,
30 		       const u8 *data, size_t data_len);
31 
32 static void ieee802_1x_finished(struct hostapd_data *hapd,
33                                 struct sta_info *sta, int success,
34                                 int remediation);
35 
ieee802_1x_send(struct hostapd_data * hapd,struct sta_info * sta,u8 type,const u8 * data,size_t datalen)36 static void ieee802_1x_send(struct hostapd_data *hapd, struct sta_info *sta,
37 			    u8 type, const u8 *data, size_t datalen)
38 {
39 	u8 *buf;
40 	struct ieee802_1x_hdr *xhdr;
41 	size_t len;
42 
43 	len = sizeof(*xhdr) + datalen;
44 	buf = os_zalloc(len);
45 	if (!buf) {
46 		wpa_printf(MSG_ERROR, "malloc() failed for %s(len=%lu)",
47 			   __func__, (unsigned long) len);
48 		return;
49 	}
50 
51 	xhdr = (struct ieee802_1x_hdr *) buf;
52 	xhdr->version = EAPOL_VERSION;
53 	xhdr->type = type;
54 	xhdr->length = host_to_be16(datalen);
55 
56 	if (datalen > 0 && data != NULL)
57 		os_memcpy(xhdr + 1, data, datalen);
58 
59 	hostapd_send_eapol(hapd->own_addr, sta->addr, buf, len);
60 	os_free(buf);
61 }
62 
63 
64 
handle_eap_response(struct hostapd_data * hapd,struct sta_info * sta,struct eap_hdr * eap,size_t len)65 static void handle_eap_response(struct hostapd_data *hapd,
66 				struct sta_info *sta, struct eap_hdr *eap,
67 				size_t len)
68 {
69 	u8 type, *data;
70 	struct eapol_state_machine *sm = sta->eapol_sm;
71 
72 	if (!sm)
73 		return;
74 
75 	data = (u8 *) (eap + 1);
76 
77 	if (len < sizeof(*eap) + 1) {
78 		wpa_printf(MSG_INFO, "%s: too short response data", __func__);
79 		return;
80 	}
81 
82 	sm->eap_type_supp = type = data[0];
83 
84 	sm->dot1xAuthEapolRespFramesRx++;
85 
86 	wpabuf_free(sm->eap_if->eapRespData);
87 	sm->eap_if->eapRespData = wpabuf_alloc_copy(eap, len);
88 	sm->eapolEap = true;
89 }
90 
91 /* Process incoming EAP packet from Supplicant */
handle_eap(struct hostapd_data * hapd,struct sta_info * sta,u8 * buf,size_t len)92 static void handle_eap(struct hostapd_data *hapd, struct sta_info *sta,
93 		       u8 *buf, size_t len)
94 {
95 	struct eap_hdr *eap;
96 	u16 eap_len;
97 
98 	if (len < sizeof(*eap)) {
99 		wpa_printf(MSG_INFO, "   too short EAP packet");
100 		return;
101 	}
102 
103 	eap = (struct eap_hdr *) buf;
104 
105 	eap_len = be_to_host16(eap->length);
106 	wpa_printf(MSG_DEBUG, "EAP: code=%d identifier=%d length=%d",
107 		   eap->code, eap->identifier,
108 		   eap_len);
109 	if (eap_len < sizeof(*eap)) {
110 		wpa_printf(MSG_DEBUG, "   Invalid EAP length");
111 		return;
112 	} else if (eap_len > len) {
113 		wpa_printf(MSG_DEBUG,
114 			   "   Too short frame to contain this EAP packet");
115 		return;
116 	} else if (eap_len < len) {
117 		wpa_printf(MSG_DEBUG,
118 			   "   Ignoring %lu extra bytes after EAP packet",
119 			   (unsigned long) len - eap_len);
120 	}
121 
122 	switch (eap->code) {
123 	case EAP_CODE_RESPONSE:
124 		handle_eap_response(hapd, sta, eap, eap_len);
125 		break;
126 	case EAP_CODE_INITIATE:
127 		break;
128 	}
129 }
130 
131 struct eapol_state_machine *
ieee802_1x_alloc_eapol_sm(struct hostapd_data * hapd,struct sta_info * sta)132 ieee802_1x_alloc_eapol_sm(struct hostapd_data *hapd, struct sta_info *sta)
133 {
134 	int flags = 0;
135 
136 	if (sta->wpa_sm) {
137 		flags |= EAPOL_SM_USES_WPA;
138 	}
139 	return eapol_auth_alloc(hapd->eapol_auth, sta->addr, flags,
140 			sta->wps_ie, NULL, sta,
141 			sta->identity, NULL);
142 }
143 
144 
145 /**
146  * ieee802_1x_receive - Process the EAPOL frames from the Supplicant
147  * @hapd: hostapd BSS data
148  * @sa: Source address (sender of the EAPOL frame)
149  * @buf: EAPOL frame
150  * @len: Length of buf in octets
151  *
152  * This function is called for each incoming EAPOL frame from the interface
153  */
ieee802_1x_receive(struct hostapd_data * hapd,const u8 * sa,const u8 * buf,size_t len)154 void ieee802_1x_receive(struct hostapd_data *hapd, const u8 *sa, const u8 *buf,
155 			size_t len)
156 {
157 	struct sta_info *sta;
158 	struct ieee802_1x_hdr *hdr;
159 	struct ieee802_1x_eapol_key *key;
160 	u16 datalen;
161 
162 	wpa_printf(MSG_DEBUG, "IEEE 802.1X: %lu bytes from " MACSTR,
163 		   (unsigned long) len, MAC2STR(sa));
164 	sta = ap_get_sta(hapd, sa);
165 	if (!sta) {
166 		wpa_printf(MSG_DEBUG,
167 			   "IEEE 802.1X data frame from not associated/Pre-authenticating STA");
168 
169 		return;
170 	}
171 
172 	if (len < sizeof(*hdr)) {
173 		wpa_printf(MSG_INFO, "   too short IEEE 802.1X packet");
174 		return;
175 	}
176 
177 	hdr = (struct ieee802_1x_hdr *) buf;
178 	datalen = be_to_host16(hdr->length);
179 	wpa_printf(MSG_DEBUG, "   IEEE 802.1X: version=%d type=%d length=%d",
180 		   hdr->version, hdr->type, datalen);
181 
182 	if (len - sizeof(*hdr) < datalen) {
183 		wpa_printf(MSG_INFO,
184 			   "   frame too short for this IEEE 802.1X packet");
185 		if (sta->eapol_sm)
186 			sta->eapol_sm->dot1xAuthEapLengthErrorFramesRx++;
187 		return;
188 	}
189 	if (len - sizeof(*hdr) > datalen) {
190 		wpa_printf(MSG_DEBUG,
191 			   "   ignoring %lu extra octets after IEEE 802.1X packet",
192 			   (unsigned long) len - sizeof(*hdr) - datalen);
193 	}
194 
195 	if (sta->eapol_sm) {
196 		sta->eapol_sm->dot1xAuthLastEapolFrameVersion = hdr->version;
197 		sta->eapol_sm->dot1xAuthEapolFramesRx++;
198 	}
199 
200 	key = (struct ieee802_1x_eapol_key *) (hdr + 1);
201 	if (datalen >= sizeof(struct ieee802_1x_eapol_key) &&
202 	    hdr->type == IEEE802_1X_TYPE_EAPOL_KEY &&
203 	    (key->type == EAPOL_KEY_TYPE_WPA ||
204 	     key->type == EAPOL_KEY_TYPE_RSN)) {
205 		wpa_receive(hapd->wpa_auth, sta->wpa_sm, (u8 *) hdr,
206 			    sizeof(*hdr) + datalen);
207 		return;
208 	}
209 
210 	if (!sta->eapol_sm) {
211 		sta->eapol_sm = ieee802_1x_alloc_eapol_sm(hapd, sta);
212 		if (!sta->eapol_sm)
213 			return;
214 
215 #ifdef CONFIG_WPS
216 		if (!hapd->conf->ieee802_1x && hapd->conf->wps_state) {
217 			u32 wflags = sta->flags & (WLAN_STA_WPS |
218 						   WLAN_STA_WPS2 |
219 						   WLAN_STA_MAYBE_WPS);
220 			if (wflags == WLAN_STA_MAYBE_WPS ||
221 			    wflags == (WLAN_STA_WPS | WLAN_STA_MAYBE_WPS)) {
222 				/*
223 				 * Delay EAPOL frame transmission until a
224 				 * possible WPS STA initiates the handshake
225 				 * with EAPOL-Start. Only allow the wait to be
226 				 * skipped if the STA is known to support WPS
227 				 * 2.0.
228 				 */
229 				wpa_printf(MSG_DEBUG,
230 					   "WPS: Do not start EAPOL until EAPOL-Start is received");
231 				sta->eapol_sm->flags |= EAPOL_SM_WAIT_START;
232 			}
233 		}
234 #endif /* CONFIG_WPS */
235 
236 		sta->eapol_sm->eap_if->portEnabled = true;
237 	}
238 
239 	/* since we support version 1, we can ignore version field and proceed
240 	 * as specified in version 1 standard [IEEE Std 802.1X-2001, 7.5.5] */
241 	/* TODO: actually, we are not version 1 anymore.. However, Version 2
242 	 * does not change frame contents, so should be ok to process frames
243 	 * more or less identically. Some changes might be needed for
244 	 * verification of fields. */
245 
246 	switch (hdr->type) {
247 	case IEEE802_1X_TYPE_EAP_PACKET:
248 		handle_eap(hapd, sta, (u8 *) (hdr + 1), datalen);
249 		break;
250 
251 	case IEEE802_1X_TYPE_EAPOL_START:
252 		sta->eapol_sm->flags &= ~EAPOL_SM_WAIT_START;
253 		sta->eapol_sm->eapolStart = true;
254 		sta->eapol_sm->dot1xAuthEapolStartFramesRx++;
255 		eap_server_clear_identity(sta->eapol_sm->eap);
256 		wpa_auth_sm_event(sta->wpa_sm, WPA_REAUTH_EAPOL);
257 		break;
258 
259 
260 	case IEEE802_1X_TYPE_EAPOL_LOGOFF:
261 		break;
262 
263 	case IEEE802_1X_TYPE_EAPOL_KEY:
264 		wpa_printf(MSG_DEBUG, "   EAPOL-Key");
265 		break;
266 
267 	case IEEE802_1X_TYPE_EAPOL_ENCAPSULATED_ASF_ALERT:
268 		wpa_printf(MSG_DEBUG, "   EAPOL-Encapsulated-ASF-Alert");
269 		/* TODO: implement support for this; show data */
270 		break;
271 
272 	default:
273 		wpa_printf(MSG_DEBUG, "   unknown IEEE 802.1X packet type");
274 		sta->eapol_sm->dot1xAuthInvalidEapolFramesRx++;
275 		break;
276 	}
277 
278 	eapol_auth_step(sta->eapol_sm);
279 }
280 
281 
ieee802_1x_free_station(struct hostapd_data * hapd,struct sta_info * sta)282 void ieee802_1x_free_station(struct hostapd_data *hapd, struct sta_info *sta)
283 {
284 	struct eapol_state_machine *sm = sta->eapol_sm;
285 
286 	if (!sm)
287 		return;
288 
289 	sta->eapol_sm = NULL;
290 	eapol_auth_free(sm);
291 }
292 
293 
ieee802_1x_eapol_send(void * ctx,void * sta_ctx,u8 type,const u8 * data,size_t datalen)294 static void ieee802_1x_eapol_send(void *ctx, void *sta_ctx, u8 type,
295 				  const u8 *data, size_t datalen)
296 {
297 #ifdef CONFIG_WPS
298 	struct sta_info *sta = sta_ctx;
299 
300 	if ((sta->flags & (WLAN_STA_WPS | WLAN_STA_MAYBE_WPS)) ==
301 	    WLAN_STA_MAYBE_WPS) {
302 		const u8 *identity;
303 		size_t identity_len;
304 		struct eapol_state_machine *sm = sta->eapol_sm;
305 
306 		identity = eap_get_identity(sm->eap, &identity_len);
307 		if (identity &&
308 		    ((identity_len == WSC_ID_ENROLLEE_LEN &&
309 		      os_memcmp(identity, WSC_ID_ENROLLEE,
310 				WSC_ID_ENROLLEE_LEN) == 0) ||
311 		     (identity_len == WSC_ID_REGISTRAR_LEN &&
312 		      os_memcmp(identity, WSC_ID_REGISTRAR,
313 				WSC_ID_REGISTRAR_LEN) == 0))) {
314 			wpa_printf(MSG_DEBUG,
315 				   "WPS: WLAN_STA_MAYBE_WPS -> WLAN_STA_WPS");
316 			sta->flags |= WLAN_STA_WPS;
317 		}
318 	}
319 #endif /* CONFIG_WPS */
320 
321 	ieee802_1x_send(ctx, sta_ctx, type, data, datalen);
322 }
323 
324 
ieee802_1x_aaa_send(void * ctx,void * sta_ctx,const u8 * data,size_t datalen)325 static void ieee802_1x_aaa_send(void *ctx, void *sta_ctx,
326 				const u8 *data, size_t datalen)
327 {
328 #ifndef CONFIG_NO_RADIUS
329 	struct hostapd_data *hapd = ctx;
330 	struct sta_info *sta = sta_ctx;
331 
332 	ieee802_1x_encapsulate_radius(hapd, sta, data, datalen);
333 #endif /* CONFIG_NO_RADIUS */
334 }
335 
336 
_ieee802_1x_finished(void * ctx,void * sta_ctx,int success,int preauth,int remediation)337 static void _ieee802_1x_finished(void *ctx, void *sta_ctx, int success,
338 				 int preauth, int remediation)
339 {
340 	struct hostapd_data *hapd = ctx;
341 	struct sta_info *sta = sta_ctx;
342 	ieee802_1x_finished(hapd, sta, success, remediation);
343 }
344 
345 
ieee802_1x_get_eap_user(void * ctx,const u8 * identity,size_t identity_len,int phase2,struct eap_user * user)346 static int ieee802_1x_get_eap_user(void *ctx, const u8 *identity,
347 				   size_t identity_len, int phase2,
348 				   struct eap_user *user)
349 {
350 	struct hostapd_data *hapd = ctx;
351 	const struct hostapd_eap_user *eap_user;
352 	int i;
353 	int rv = -1;
354 
355 	eap_user = hostapd_get_eap_user(hapd, identity, identity_len, phase2);
356 	if (!eap_user)
357 		goto out;
358 
359 	os_memset(user, 0, sizeof(*user));
360 	user->phase2 = phase2;
361 	for (i = 0; i < EAP_MAX_METHODS; i++) {
362 		user->methods[i].vendor = eap_user->methods[i].vendor;
363 		user->methods[i].method = eap_user->methods[i].method;
364 	}
365 
366 	if (eap_user->password) {
367 		user->password = os_memdup(eap_user->password,
368 					   eap_user->password_len);
369 		if (!user->password)
370 			goto out;
371 		user->password_len = eap_user->password_len;
372 		user->password_hash = eap_user->password_hash;
373 	}
374 	user->force_version = eap_user->force_version;
375 	user->ttls_auth = eap_user->ttls_auth;
376 	rv = 0;
377 
378 out:
379 	if (rv)
380 		wpa_printf(MSG_DEBUG, "%s: Failed to find user", __func__);
381 
382 	return rv;
383 }
384 
385 
ieee802_1x_sta_entry_alive(void * ctx,const u8 * addr)386 static int ieee802_1x_sta_entry_alive(void *ctx, const u8 *addr)
387 {
388 	struct hostapd_data *hapd = ctx;
389 	struct sta_info *sta;
390 
391 	sta = ap_get_sta(hapd, addr);
392 	if (!sta || !sta->eapol_sm)
393 		return 0;
394 	return 1;
395 }
396 
397 
ieee802_1x_set_port_authorized(void * ctx,void * sta_ctx,int authorized)398 static void ieee802_1x_set_port_authorized(void *ctx, void *sta_ctx,
399 					   int authorized)
400 {
401 }
402 
403 
_ieee802_1x_abort_auth(void * ctx,void * sta_ctx)404 static void _ieee802_1x_abort_auth(void *ctx, void *sta_ctx)
405 {
406 }
407 
408 
ieee802_1x_eapol_event(void * ctx,void * sta_ctx,enum eapol_event type)409 static void ieee802_1x_eapol_event(void *ctx, void *sta_ctx,
410 				   enum eapol_event type)
411 {
412 #if 0
413 	/* struct hostapd_data *hapd = ctx; */
414 	struct sta_info *sta = sta_ctx;
415 
416 	switch (type) {
417 	case EAPOL_AUTH_SM_CHANGE:
418 		wpa_auth_sm_notify(sta->wpa_sm);
419 		break;
420 	case EAPOL_AUTH_REAUTHENTICATE:
421 		wpa_auth_sm_event(sta->wpa_sm, WPA_REAUTH_EAPOL);
422 		break;
423 	}
424 #endif
425 }
426 
427 
ieee802_1x_init(struct hostapd_data * hapd)428 int ieee802_1x_init(struct hostapd_data *hapd)
429 {
430 	struct eapol_auth_config conf;
431 	struct eapol_auth_cb cb;
432 	struct eap_config *eap_cfg;
433 
434 	os_memset(&conf, 0, sizeof(conf));
435 	eap_cfg = os_zalloc(sizeof(struct eap_config));
436 	eap_cfg->max_auth_rounds = 100;
437 	eap_cfg->max_auth_rounds_short = 50;
438 	//eap_cfg->backend_auth = 1;
439 	eap_cfg->eap_server = 1;
440 	conf.eap_cfg = eap_cfg;
441 	conf.ctx = hapd;
442 	conf.wpa = hapd->conf->wpa;
443 
444 	os_memset(&cb, 0, sizeof(cb));
445 	cb.eapol_send = ieee802_1x_eapol_send;
446 	cb.aaa_send = ieee802_1x_aaa_send;
447 	cb.finished = _ieee802_1x_finished;
448 	cb.get_eap_user = ieee802_1x_get_eap_user;
449 	cb.sta_entry_alive = ieee802_1x_sta_entry_alive;
450 	cb.set_port_authorized = ieee802_1x_set_port_authorized;
451 	cb.abort_auth = _ieee802_1x_abort_auth;
452 	cb.eapol_event = ieee802_1x_eapol_event;
453 
454 	hapd->eapol_auth = eapol_auth_init(&conf, &cb);
455 	if (!hapd->eapol_auth)
456 		return -1;
457 
458 	return 0;
459 }
460 
461 
ieee802_1x_finished(struct hostapd_data * hapd,struct sta_info * sta,int success,int remediation)462 static void ieee802_1x_finished(struct hostapd_data *hapd,
463 				struct sta_info *sta, int success,
464 				int remediation)
465 {
466 	if (!success) {
467 		/*
468 		 * Many devices require deauthentication after WPS provisioning
469 		 * and some may not be be able to do that themselves, so
470 		 * disconnect the client here. In addition, this may also
471 		 * benefit IEEE 802.1X/EAPOL authentication cases, too since
472 		 * the EAPOL PAE state machine would remain in HELD state for
473 		 * considerable amount of time and some EAP methods, like
474 		 * EAP-FAST with anonymous provisioning, may require another
475 		 * EAPOL authentication to be started to complete connection.
476 		 */
477 		ap_sta_delayed_1x_auth_fail_disconnect(hapd, sta);
478 	}
479 }
480