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