• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * EAP peer state machines (RFC 4137)
3  * Copyright (c) 2004-2006, 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  * This file implements the Peer State Machine as defined in RFC 4137. The used
15  * states and state transitions match mostly with the RFC. However, there are
16  * couple of additional transitions for working around small issues noticed
17  * during testing. These exceptions are explained in comments within the
18  * functions in this file. The method functions, m.func(), are similar to the
19  * ones used in RFC 4137, but some small changes have used here to optimize
20  * operations and to add functionality needed for fast re-authentication
21  * (session resumption).
22  */
23 
24 #include "includes.h"
25 
26 #include "common.h"
27 #include "eap_i.h"
28 #include "config_ssid.h"
29 #include "tls.h"
30 #include "crypto.h"
31 #include "pcsc_funcs.h"
32 #include "wpa_ctrl.h"
33 #include "state_machine.h"
34 
35 #define STATE_MACHINE_DATA struct eap_sm
36 #define STATE_MACHINE_DEBUG_PREFIX "EAP"
37 
38 #define EAP_MAX_AUTH_ROUNDS 50
39 
40 
41 static Boolean eap_sm_allowMethod(struct eap_sm *sm, int vendor,
42 				  EapType method);
43 static u8 * eap_sm_buildNak(struct eap_sm *sm, int id, size_t *len);
44 static void eap_sm_processIdentity(struct eap_sm *sm, const u8 *req);
45 static void eap_sm_processNotify(struct eap_sm *sm, const u8 *req);
46 static u8 * eap_sm_buildNotify(int id, size_t *len);
47 static void eap_sm_parseEapReq(struct eap_sm *sm, const u8 *req, size_t len);
48 #if defined(CONFIG_CTRL_IFACE) || !defined(CONFIG_NO_STDOUT_DEBUG)
49 static const char * eap_sm_method_state_txt(EapMethodState state);
50 static const char * eap_sm_decision_txt(EapDecision decision);
51 #endif /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */
52 
53 
54 
eapol_get_bool(struct eap_sm * sm,enum eapol_bool_var var)55 static Boolean eapol_get_bool(struct eap_sm *sm, enum eapol_bool_var var)
56 {
57 	return sm->eapol_cb->get_bool(sm->eapol_ctx, var);
58 }
59 
60 
eapol_set_bool(struct eap_sm * sm,enum eapol_bool_var var,Boolean value)61 static void eapol_set_bool(struct eap_sm *sm, enum eapol_bool_var var,
62 			   Boolean value)
63 {
64 	sm->eapol_cb->set_bool(sm->eapol_ctx, var, value);
65 }
66 
67 
eapol_get_int(struct eap_sm * sm,enum eapol_int_var var)68 static unsigned int eapol_get_int(struct eap_sm *sm, enum eapol_int_var var)
69 {
70 	return sm->eapol_cb->get_int(sm->eapol_ctx, var);
71 }
72 
73 
eapol_set_int(struct eap_sm * sm,enum eapol_int_var var,unsigned int value)74 static void eapol_set_int(struct eap_sm *sm, enum eapol_int_var var,
75 			  unsigned int value)
76 {
77 	sm->eapol_cb->set_int(sm->eapol_ctx, var, value);
78 }
79 
80 
eapol_get_eapReqData(struct eap_sm * sm,size_t * len)81 static u8 * eapol_get_eapReqData(struct eap_sm *sm, size_t *len)
82 {
83 	return sm->eapol_cb->get_eapReqData(sm->eapol_ctx, len);
84 }
85 
86 
eap_deinit_prev_method(struct eap_sm * sm,const char * txt)87 static void eap_deinit_prev_method(struct eap_sm *sm, const char *txt)
88 {
89 	if (sm->m == NULL || sm->eap_method_priv == NULL)
90 		return;
91 
92 	wpa_printf(MSG_DEBUG, "EAP: deinitialize previously used EAP method "
93 		   "(%d, %s) at %s", sm->selectedMethod, sm->m->name, txt);
94 	sm->m->deinit(sm, sm->eap_method_priv);
95 	sm->eap_method_priv = NULL;
96 	sm->m = NULL;
97 }
98 
99 
100 /*
101  * This state initializes state machine variables when the machine is
102  * activated (portEnabled = TRUE). This is also used when re-starting
103  * authentication (eapRestart == TRUE).
104  */
SM_STATE(EAP,INITIALIZE)105 SM_STATE(EAP, INITIALIZE)
106 {
107 	SM_ENTRY(EAP, INITIALIZE);
108 	if (sm->fast_reauth && sm->m && sm->m->has_reauth_data &&
109 	    sm->m->has_reauth_data(sm, sm->eap_method_priv)) {
110 		wpa_printf(MSG_DEBUG, "EAP: maintaining EAP method data for "
111 			   "fast reauthentication");
112 		sm->m->deinit_for_reauth(sm, sm->eap_method_priv);
113 	} else {
114 		eap_deinit_prev_method(sm, "INITIALIZE");
115 	}
116 	sm->selectedMethod = EAP_TYPE_NONE;
117 	sm->methodState = METHOD_NONE;
118 	sm->allowNotifications = TRUE;
119 	sm->decision = DECISION_FAIL;
120 	eapol_set_int(sm, EAPOL_idleWhile, sm->ClientTimeout);
121 	eapol_set_bool(sm, EAPOL_eapSuccess, FALSE);
122 	eapol_set_bool(sm, EAPOL_eapFail, FALSE);
123 	os_free(sm->eapKeyData);
124 	sm->eapKeyData = NULL;
125 	sm->eapKeyAvailable = FALSE;
126 	eapol_set_bool(sm, EAPOL_eapRestart, FALSE);
127 	sm->lastId = -1; /* new session - make sure this does not match with
128 			  * the first EAP-Packet */
129 	/*
130 	 * RFC 4137 does not reset eapResp and eapNoResp here. However, this
131 	 * seemed to be able to trigger cases where both were set and if EAPOL
132 	 * state machine uses eapNoResp first, it may end up not sending a real
133 	 * reply correctly. This occurred when the workaround in FAIL state set
134 	 * eapNoResp = TRUE.. Maybe that workaround needs to be fixed to do
135 	 * something else(?)
136 	 */
137 	eapol_set_bool(sm, EAPOL_eapResp, FALSE);
138 	eapol_set_bool(sm, EAPOL_eapNoResp, FALSE);
139 	sm->num_rounds = 0;
140 }
141 
142 
143 /*
144  * This state is reached whenever service from the lower layer is interrupted
145  * or unavailable (portEnabled == FALSE). Immediate transition to INITIALIZE
146  * occurs when the port becomes enabled.
147  */
SM_STATE(EAP,DISABLED)148 SM_STATE(EAP, DISABLED)
149 {
150 	SM_ENTRY(EAP, DISABLED);
151 	sm->num_rounds = 0;
152 }
153 
154 
155 /*
156  * The state machine spends most of its time here, waiting for something to
157  * happen. This state is entered unconditionally from INITIALIZE, DISCARD, and
158  * SEND_RESPONSE states.
159  */
SM_STATE(EAP,IDLE)160 SM_STATE(EAP, IDLE)
161 {
162 	SM_ENTRY(EAP, IDLE);
163 }
164 
165 
166 /*
167  * This state is entered when an EAP packet is received (eapReq == TRUE) to
168  * parse the packet header.
169  */
SM_STATE(EAP,RECEIVED)170 SM_STATE(EAP, RECEIVED)
171 {
172 	const u8 *eapReqData;
173 	size_t eapReqDataLen;
174 
175 	SM_ENTRY(EAP, RECEIVED);
176 	eapReqData = eapol_get_eapReqData(sm, &eapReqDataLen);
177 	/* parse rxReq, rxSuccess, rxFailure, reqId, reqMethod */
178 	eap_sm_parseEapReq(sm, eapReqData, eapReqDataLen);
179 	sm->num_rounds++;
180 }
181 
182 
183 /*
184  * This state is entered when a request for a new type comes in. Either the
185  * correct method is started, or a Nak response is built.
186  */
SM_STATE(EAP,GET_METHOD)187 SM_STATE(EAP, GET_METHOD)
188 {
189 	int reinit;
190 	EapType method;
191 
192 	SM_ENTRY(EAP, GET_METHOD);
193 
194 	if (sm->reqMethod == EAP_TYPE_EXPANDED)
195 		method = sm->reqVendorMethod;
196 	else
197 		method = sm->reqMethod;
198 
199 	if (!eap_sm_allowMethod(sm, sm->reqVendor, method)) {
200 		wpa_printf(MSG_DEBUG, "EAP: vendor %u method %u not allowed",
201 			   sm->reqVendor, method);
202 		goto nak;
203 	}
204 
205 	/*
206 	 * RFC 4137 does not define specific operation for fast
207 	 * re-authentication (session resumption). The design here is to allow
208 	 * the previously used method data to be maintained for
209 	 * re-authentication if the method support session resumption.
210 	 * Otherwise, the previously used method data is freed and a new method
211 	 * is allocated here.
212 	 */
213 	if (sm->fast_reauth &&
214 	    sm->m && sm->m->vendor == sm->reqVendor &&
215 	    sm->m->method == method &&
216 	    sm->m->has_reauth_data &&
217 	    sm->m->has_reauth_data(sm, sm->eap_method_priv)) {
218 		wpa_printf(MSG_DEBUG, "EAP: Using previous method data"
219 			   " for fast re-authentication");
220 		reinit = 1;
221 	} else {
222 		eap_deinit_prev_method(sm, "GET_METHOD");
223 		reinit = 0;
224 	}
225 
226 	sm->selectedMethod = sm->reqMethod;
227 	if (sm->m == NULL)
228 		sm->m = eap_sm_get_eap_methods(sm->reqVendor, method);
229 	if (!sm->m) {
230 		wpa_printf(MSG_DEBUG, "EAP: Could not find selected method: "
231 			   "vendor %d method %d",
232 			   sm->reqVendor, method);
233 		goto nak;
234 	}
235 
236 	wpa_printf(MSG_DEBUG, "EAP: Initialize selected EAP method: "
237 		   "vendor %u method %u (%s)",
238 		   sm->reqVendor, method, sm->m->name);
239 	if (reinit)
240 		sm->eap_method_priv = sm->m->init_for_reauth(
241 			sm, sm->eap_method_priv);
242 	else
243 		sm->eap_method_priv = sm->m->init(sm);
244 
245 	if (sm->eap_method_priv == NULL) {
246 		struct wpa_ssid *config = eap_get_config(sm);
247 		wpa_msg(sm->msg_ctx, MSG_INFO,
248 			"EAP: Failed to initialize EAP method: vendor %u "
249 			"method %u (%s)",
250 			sm->reqVendor, method, sm->m->name);
251 		sm->m = NULL;
252 		sm->methodState = METHOD_NONE;
253 		sm->selectedMethod = EAP_TYPE_NONE;
254 		if (sm->reqMethod == EAP_TYPE_TLS && config &&
255 		    (config->pending_req_pin ||
256 		     config->pending_req_passphrase)) {
257 			/*
258 			 * Return without generating Nak in order to allow
259 			 * entering of PIN code or passphrase to retry the
260 			 * current EAP packet.
261 			 */
262 			wpa_printf(MSG_DEBUG, "EAP: Pending PIN/passphrase "
263 				   "request - skip Nak");
264 			return;
265 		}
266 
267 		goto nak;
268 	}
269 
270 	sm->methodState = METHOD_INIT;
271 	wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_METHOD
272 		"EAP vendor %u method %u (%s) selected",
273 		sm->reqVendor, method, sm->m->name);
274 	return;
275 
276 nak:
277 	os_free(sm->eapRespData);
278 	sm->eapRespData = NULL;
279 	sm->eapRespData = eap_sm_buildNak(sm, sm->reqId, &sm->eapRespDataLen);
280 }
281 
282 
283 /*
284  * The method processing happens here. The request from the authenticator is
285  * processed, and an appropriate response packet is built.
286  */
SM_STATE(EAP,METHOD)287 SM_STATE(EAP, METHOD)
288 {
289 	u8 *eapReqData;
290 	size_t eapReqDataLen;
291 	struct eap_method_ret ret;
292 
293 	SM_ENTRY(EAP, METHOD);
294 	if (sm->m == NULL) {
295 		wpa_printf(MSG_WARNING, "EAP::METHOD - method not selected");
296 		return;
297 	}
298 
299 	eapReqData = eapol_get_eapReqData(sm, &eapReqDataLen);
300 
301 	/*
302 	 * Get ignore, methodState, decision, allowNotifications, and
303 	 * eapRespData. RFC 4137 uses three separate method procedure (check,
304 	 * process, and buildResp) in this state. These have been combined into
305 	 * a single function call to m->process() in order to optimize EAP
306 	 * method implementation interface a bit. These procedures are only
307 	 * used from within this METHOD state, so there is no need to keep
308 	 * these as separate C functions.
309 	 *
310 	 * The RFC 4137 procedures return values as follows:
311 	 * ignore = m.check(eapReqData)
312 	 * (methodState, decision, allowNotifications) = m.process(eapReqData)
313 	 * eapRespData = m.buildResp(reqId)
314 	 */
315 	os_memset(&ret, 0, sizeof(ret));
316 	ret.ignore = sm->ignore;
317 	ret.methodState = sm->methodState;
318 	ret.decision = sm->decision;
319 	ret.allowNotifications = sm->allowNotifications;
320 	os_free(sm->eapRespData);
321 	sm->eapRespData = NULL;
322 	sm->eapRespData = sm->m->process(sm, sm->eap_method_priv, &ret,
323 					 eapReqData, eapReqDataLen,
324 					 &sm->eapRespDataLen);
325 	wpa_printf(MSG_DEBUG, "EAP: method process -> ignore=%s "
326 		   "methodState=%s decision=%s",
327 		   ret.ignore ? "TRUE" : "FALSE",
328 		   eap_sm_method_state_txt(ret.methodState),
329 		   eap_sm_decision_txt(ret.decision));
330 
331 	sm->ignore = ret.ignore;
332 	if (sm->ignore)
333 		return;
334 	sm->methodState = ret.methodState;
335 	sm->decision = ret.decision;
336 	sm->allowNotifications = ret.allowNotifications;
337 
338 	if (sm->m->isKeyAvailable && sm->m->getKey &&
339 	    sm->m->isKeyAvailable(sm, sm->eap_method_priv)) {
340 		os_free(sm->eapKeyData);
341 		sm->eapKeyData = sm->m->getKey(sm, sm->eap_method_priv,
342 					       &sm->eapKeyDataLen);
343 	}
344 }
345 
346 
347 /*
348  * This state signals the lower layer that a response packet is ready to be
349  * sent.
350  */
SM_STATE(EAP,SEND_RESPONSE)351 SM_STATE(EAP, SEND_RESPONSE)
352 {
353 	SM_ENTRY(EAP, SEND_RESPONSE);
354 	os_free(sm->lastRespData);
355 	if (sm->eapRespData) {
356 		if (sm->workaround)
357 			os_memcpy(sm->last_md5, sm->req_md5, 16);
358 		sm->lastId = sm->reqId;
359 		sm->lastRespData = os_malloc(sm->eapRespDataLen);
360 		if (sm->lastRespData) {
361 			os_memcpy(sm->lastRespData, sm->eapRespData,
362 				  sm->eapRespDataLen);
363 			sm->lastRespDataLen = sm->eapRespDataLen;
364 		}
365 		eapol_set_bool(sm, EAPOL_eapResp, TRUE);
366 	} else
367 		sm->lastRespData = NULL;
368 	eapol_set_bool(sm, EAPOL_eapReq, FALSE);
369 	eapol_set_int(sm, EAPOL_idleWhile, sm->ClientTimeout);
370 }
371 
372 
373 /*
374  * This state signals the lower layer that the request was discarded, and no
375  * response packet will be sent at this time.
376  */
SM_STATE(EAP,DISCARD)377 SM_STATE(EAP, DISCARD)
378 {
379 	SM_ENTRY(EAP, DISCARD);
380 	eapol_set_bool(sm, EAPOL_eapReq, FALSE);
381 	eapol_set_bool(sm, EAPOL_eapNoResp, TRUE);
382 }
383 
384 
385 /*
386  * Handles requests for Identity method and builds a response.
387  */
SM_STATE(EAP,IDENTITY)388 SM_STATE(EAP, IDENTITY)
389 {
390 	const u8 *eapReqData;
391 	size_t eapReqDataLen;
392 
393 	SM_ENTRY(EAP, IDENTITY);
394 	eapReqData = eapol_get_eapReqData(sm, &eapReqDataLen);
395 	eap_sm_processIdentity(sm, eapReqData);
396 	os_free(sm->eapRespData);
397 	sm->eapRespData = NULL;
398 	sm->eapRespData = eap_sm_buildIdentity(sm, sm->reqId,
399 					       &sm->eapRespDataLen, 0);
400 }
401 
402 
403 /*
404  * Handles requests for Notification method and builds a response.
405  */
SM_STATE(EAP,NOTIFICATION)406 SM_STATE(EAP, NOTIFICATION)
407 {
408 	const u8 *eapReqData;
409 	size_t eapReqDataLen;
410 
411 	SM_ENTRY(EAP, NOTIFICATION);
412 	eapReqData = eapol_get_eapReqData(sm, &eapReqDataLen);
413 	eap_sm_processNotify(sm, eapReqData);
414 	os_free(sm->eapRespData);
415 	sm->eapRespData = NULL;
416 	sm->eapRespData = eap_sm_buildNotify(sm->reqId, &sm->eapRespDataLen);
417 }
418 
419 
420 /*
421  * This state retransmits the previous response packet.
422  */
SM_STATE(EAP,RETRANSMIT)423 SM_STATE(EAP, RETRANSMIT)
424 {
425 	SM_ENTRY(EAP, RETRANSMIT);
426 	os_free(sm->eapRespData);
427 	if (sm->lastRespData) {
428 		sm->eapRespData = os_malloc(sm->lastRespDataLen);
429 		if (sm->eapRespData) {
430 			os_memcpy(sm->eapRespData, sm->lastRespData,
431 				  sm->lastRespDataLen);
432 			sm->eapRespDataLen = sm->lastRespDataLen;
433 		}
434 	} else
435 		sm->eapRespData = NULL;
436 }
437 
438 
439 /*
440  * This state is entered in case of a successful completion of authentication
441  * and state machine waits here until port is disabled or EAP authentication is
442  * restarted.
443  */
SM_STATE(EAP,SUCCESS)444 SM_STATE(EAP, SUCCESS)
445 {
446 	SM_ENTRY(EAP, SUCCESS);
447 	if (sm->eapKeyData != NULL)
448 		sm->eapKeyAvailable = TRUE;
449 	eapol_set_bool(sm, EAPOL_eapSuccess, TRUE);
450 
451 	/*
452 	 * RFC 4137 does not clear eapReq here, but this seems to be required
453 	 * to avoid processing the same request twice when state machine is
454 	 * initialized.
455 	 */
456 	eapol_set_bool(sm, EAPOL_eapReq, FALSE);
457 
458 	/*
459 	 * RFC 4137 does not set eapNoResp here, but this seems to be required
460 	 * to get EAPOL Supplicant backend state machine into SUCCESS state. In
461 	 * addition, either eapResp or eapNoResp is required to be set after
462 	 * processing the received EAP frame.
463 	 */
464 	eapol_set_bool(sm, EAPOL_eapNoResp, TRUE);
465 
466 	wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_SUCCESS
467 		"EAP authentication completed successfully");
468 }
469 
470 
471 /*
472  * This state is entered in case of a failure and state machine waits here
473  * until port is disabled or EAP authentication is restarted.
474  */
SM_STATE(EAP,FAILURE)475 SM_STATE(EAP, FAILURE)
476 {
477 	SM_ENTRY(EAP, FAILURE);
478 	eapol_set_bool(sm, EAPOL_eapFail, TRUE);
479 
480 	/*
481 	 * RFC 4137 does not clear eapReq here, but this seems to be required
482 	 * to avoid processing the same request twice when state machine is
483 	 * initialized.
484 	 */
485 	eapol_set_bool(sm, EAPOL_eapReq, FALSE);
486 
487 	/*
488 	 * RFC 4137 does not set eapNoResp here. However, either eapResp or
489 	 * eapNoResp is required to be set after processing the received EAP
490 	 * frame.
491 	 */
492 	eapol_set_bool(sm, EAPOL_eapNoResp, TRUE);
493 
494 	wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_FAILURE
495 		"EAP authentication failed");
496 }
497 
498 
eap_success_workaround(struct eap_sm * sm,int reqId,int lastId)499 static int eap_success_workaround(struct eap_sm *sm, int reqId, int lastId)
500 {
501 	/*
502 	 * At least Microsoft IAS and Meetinghouse Aegis seem to be sending
503 	 * EAP-Success/Failure with lastId + 1 even though RFC 3748 and
504 	 * RFC 4137 require that reqId == lastId. In addition, it looks like
505 	 * Ringmaster v2.1.2.0 would be using lastId + 2 in EAP-Success.
506 	 *
507 	 * Accept this kind of Id if EAP workarounds are enabled. These are
508 	 * unauthenticated plaintext messages, so this should have minimal
509 	 * security implications (bit easier to fake EAP-Success/Failure).
510 	 */
511 	if (sm->workaround && (reqId == ((lastId + 1) & 0xff) ||
512 			       reqId == ((lastId + 2) & 0xff))) {
513 		wpa_printf(MSG_DEBUG, "EAP: Workaround for unexpected "
514 			   "identifier field in EAP Success: "
515 			   "reqId=%d lastId=%d (these are supposed to be "
516 			   "same)", reqId, lastId);
517 		return 1;
518 	}
519 	wpa_printf(MSG_DEBUG, "EAP: EAP-Success Id mismatch - reqId=%d "
520 		   "lastId=%d", reqId, lastId);
521 	return 0;
522 }
523 
524 
525 /*
526  * RFC 4137 - Appendix A.1: EAP Peer State Machine - State transitions
527  */
SM_STEP(EAP)528 SM_STEP(EAP)
529 {
530 	int duplicate;
531 
532 	if (eapol_get_bool(sm, EAPOL_eapRestart) &&
533 	    eapol_get_bool(sm, EAPOL_portEnabled))
534 		SM_ENTER_GLOBAL(EAP, INITIALIZE);
535 	else if (!eapol_get_bool(sm, EAPOL_portEnabled) || sm->force_disabled)
536 		SM_ENTER_GLOBAL(EAP, DISABLED);
537 	else if (sm->num_rounds > EAP_MAX_AUTH_ROUNDS) {
538 		/* RFC 4137 does not place any limit on number of EAP messages
539 		 * in an authentication session. However, some error cases have
540 		 * ended up in a state were EAP messages were sent between the
541 		 * peer and server in a loop (e.g., TLS ACK frame in both
542 		 * direction). Since this is quite undesired outcome, limit the
543 		 * total number of EAP round-trips and abort authentication if
544 		 * this limit is exceeded.
545 		 */
546 		if (sm->num_rounds == EAP_MAX_AUTH_ROUNDS + 1) {
547 			wpa_msg(sm->msg_ctx, MSG_INFO, "EAP: more than %d "
548 				"authentication rounds - abort",
549 				EAP_MAX_AUTH_ROUNDS);
550 			sm->num_rounds++;
551 			SM_ENTER_GLOBAL(EAP, FAILURE);
552 		}
553 	} else switch (sm->EAP_state) {
554 	case EAP_INITIALIZE:
555 		SM_ENTER(EAP, IDLE);
556 		break;
557 	case EAP_DISABLED:
558 		if (eapol_get_bool(sm, EAPOL_portEnabled) &&
559 		    !sm->force_disabled)
560 			SM_ENTER(EAP, INITIALIZE);
561 		break;
562 	case EAP_IDLE:
563 		/*
564 		 * The first three transitions are from RFC 4137. The last two
565 		 * are local additions to handle special cases with LEAP and
566 		 * PEAP server not sending EAP-Success in some cases.
567 		 */
568 		if (eapol_get_bool(sm, EAPOL_eapReq))
569 			SM_ENTER(EAP, RECEIVED);
570 		else if ((eapol_get_bool(sm, EAPOL_altAccept) &&
571 			  sm->decision != DECISION_FAIL) ||
572 			 (eapol_get_int(sm, EAPOL_idleWhile) == 0 &&
573 			  sm->decision == DECISION_UNCOND_SUCC))
574 			SM_ENTER(EAP, SUCCESS);
575 		else if (eapol_get_bool(sm, EAPOL_altReject) ||
576 			 (eapol_get_int(sm, EAPOL_idleWhile) == 0 &&
577 			  sm->decision != DECISION_UNCOND_SUCC) ||
578 			 (eapol_get_bool(sm, EAPOL_altAccept) &&
579 			  sm->methodState != METHOD_CONT &&
580 			  sm->decision == DECISION_FAIL))
581 			SM_ENTER(EAP, FAILURE);
582 		else if (sm->selectedMethod == EAP_TYPE_LEAP &&
583 			 sm->leap_done && sm->decision != DECISION_FAIL &&
584 			 sm->methodState == METHOD_DONE)
585 			SM_ENTER(EAP, SUCCESS);
586 		else if (sm->selectedMethod == EAP_TYPE_PEAP &&
587 			 sm->peap_done && sm->decision != DECISION_FAIL &&
588 			 sm->methodState == METHOD_DONE)
589 			SM_ENTER(EAP, SUCCESS);
590 		break;
591 	case EAP_RECEIVED:
592 		duplicate = (sm->reqId == sm->lastId) && sm->rxReq;
593 		if (sm->workaround && duplicate &&
594 		    os_memcmp(sm->req_md5, sm->last_md5, 16) != 0) {
595 			/*
596 			 * RFC 4137 uses (reqId == lastId) as the only
597 			 * verification for duplicate EAP requests. However,
598 			 * this misses cases where the AS is incorrectly using
599 			 * the same id again; and unfortunately, such
600 			 * implementations exist. Use MD5 hash as an extra
601 			 * verification for the packets being duplicate to
602 			 * workaround these issues.
603 			 */
604 			wpa_printf(MSG_DEBUG, "EAP: AS used the same Id again,"
605 				   " but EAP packets were not identical");
606 			wpa_printf(MSG_DEBUG, "EAP: workaround - assume this "
607 				   "is not a duplicate packet");
608 			duplicate = 0;
609 		}
610 
611 		/*
612 		 * Two special cases below for LEAP are local additions to work
613 		 * around odd LEAP behavior (EAP-Success in the middle of
614 		 * authentication and then swapped roles). Other transitions
615 		 * are based on RFC 4137.
616 		 */
617 		if (sm->rxSuccess && sm->decision != DECISION_FAIL &&
618 		    (sm->reqId == sm->lastId ||
619 		     eap_success_workaround(sm, sm->reqId, sm->lastId)))
620 			SM_ENTER(EAP, SUCCESS);
621 		else if (sm->methodState != METHOD_CONT &&
622 			 ((sm->rxFailure &&
623 			   sm->decision != DECISION_UNCOND_SUCC) ||
624 			  (sm->rxSuccess && sm->decision == DECISION_FAIL &&
625 			   (sm->selectedMethod != EAP_TYPE_LEAP ||
626 			    sm->methodState != METHOD_MAY_CONT))) &&
627 			 (sm->reqId == sm->lastId ||
628 			  eap_success_workaround(sm, sm->reqId, sm->lastId)))
629 			SM_ENTER(EAP, FAILURE);
630 		else if (sm->rxReq && duplicate)
631 			SM_ENTER(EAP, RETRANSMIT);
632 		else if (sm->rxReq && !duplicate &&
633 			 sm->reqMethod == EAP_TYPE_NOTIFICATION &&
634 			 sm->allowNotifications)
635 			SM_ENTER(EAP, NOTIFICATION);
636 		else if (sm->rxReq && !duplicate &&
637 			 sm->selectedMethod == EAP_TYPE_NONE &&
638 			 sm->reqMethod == EAP_TYPE_IDENTITY)
639 			SM_ENTER(EAP, IDENTITY);
640 		else if (sm->rxReq && !duplicate &&
641 			 sm->selectedMethod == EAP_TYPE_NONE &&
642 			 sm->reqMethod != EAP_TYPE_IDENTITY &&
643 			 sm->reqMethod != EAP_TYPE_NOTIFICATION)
644 			SM_ENTER(EAP, GET_METHOD);
645 		else if (sm->rxReq && !duplicate &&
646 			 sm->reqMethod == sm->selectedMethod &&
647 			 sm->methodState != METHOD_DONE)
648 			SM_ENTER(EAP, METHOD);
649 		else if (sm->selectedMethod == EAP_TYPE_LEAP &&
650 			 (sm->rxSuccess || sm->rxResp))
651 			SM_ENTER(EAP, METHOD);
652 		else
653 			SM_ENTER(EAP, DISCARD);
654 		break;
655 	case EAP_GET_METHOD:
656 		if (sm->selectedMethod == sm->reqMethod)
657 			SM_ENTER(EAP, METHOD);
658 		else
659 			SM_ENTER(EAP, SEND_RESPONSE);
660 		break;
661 	case EAP_METHOD:
662 		if (sm->ignore)
663 			SM_ENTER(EAP, DISCARD);
664 		else
665 			SM_ENTER(EAP, SEND_RESPONSE);
666 		break;
667 	case EAP_SEND_RESPONSE:
668 		SM_ENTER(EAP, IDLE);
669 		break;
670 	case EAP_DISCARD:
671 		SM_ENTER(EAP, IDLE);
672 		break;
673 	case EAP_IDENTITY:
674 		SM_ENTER(EAP, SEND_RESPONSE);
675 		break;
676 	case EAP_NOTIFICATION:
677 		SM_ENTER(EAP, SEND_RESPONSE);
678 		break;
679 	case EAP_RETRANSMIT:
680 		SM_ENTER(EAP, SEND_RESPONSE);
681 		break;
682 	case EAP_SUCCESS:
683 		break;
684 	case EAP_FAILURE:
685 		break;
686 	}
687 }
688 
689 
eap_sm_allowMethod(struct eap_sm * sm,int vendor,EapType method)690 static Boolean eap_sm_allowMethod(struct eap_sm *sm, int vendor,
691 				  EapType method)
692 {
693 	struct wpa_ssid *config = eap_get_config(sm);
694 
695 	if (!wpa_config_allowed_eap_method(config, vendor, method)) {
696 		wpa_printf(MSG_DEBUG, "EAP: configuration does not allow: "
697 			   "vendor %u method %u", vendor, method);
698 		return FALSE;
699 	}
700 	if (eap_sm_get_eap_methods(vendor, method))
701 		return TRUE;
702 	wpa_printf(MSG_DEBUG, "EAP: not included in build: "
703 		   "vendor %u method %u", vendor, method);
704 	return FALSE;
705 }
706 
707 
eap_sm_build_expanded_nak(struct eap_sm * sm,int id,size_t * len,const struct eap_method * methods,size_t count)708 static u8 * eap_sm_build_expanded_nak(struct eap_sm *sm, int id, size_t *len,
709 				      const struct eap_method *methods,
710 				      size_t count)
711 {
712 	struct wpa_ssid *config = eap_get_config(sm);
713 	struct eap_hdr *resp;
714 	u8 *pos;
715 	int found = 0;
716 	const struct eap_method *m;
717 
718 	wpa_printf(MSG_DEBUG, "EAP: Building expanded EAP-Nak");
719 
720 	/* RFC 3748 - 5.3.2: Expanded Nak */
721 	*len = sizeof(struct eap_hdr) + 8;
722 	resp = os_malloc(*len + 8 * (count + 1));
723 	if (resp == NULL)
724 		return NULL;
725 
726 	resp->code = EAP_CODE_RESPONSE;
727 	resp->identifier = id;
728 	pos = (u8 *) (resp + 1);
729 	*pos++ = EAP_TYPE_EXPANDED;
730 	WPA_PUT_BE24(pos, EAP_VENDOR_IETF);
731 	pos += 3;
732 	WPA_PUT_BE32(pos, EAP_TYPE_NAK);
733 	pos += 4;
734 
735 	for (m = methods; m; m = m->next) {
736 		if (sm->reqVendor == m->vendor &&
737 		    sm->reqVendorMethod == m->method)
738 			continue; /* do not allow the current method again */
739 		if (wpa_config_allowed_eap_method(config, m->vendor,
740 						  m->method)) {
741 			wpa_printf(MSG_DEBUG, "EAP: allowed type: "
742 				   "vendor=%u method=%u",
743 				   m->vendor, m->method);
744 			*pos++ = EAP_TYPE_EXPANDED;
745 			WPA_PUT_BE24(pos, m->vendor);
746 			pos += 3;
747 			WPA_PUT_BE32(pos, m->method);
748 			pos += 4;
749 
750 			(*len) += 8;
751 			found++;
752 		}
753 	}
754 	if (!found) {
755 		wpa_printf(MSG_DEBUG, "EAP: no more allowed methods");
756 		*pos++ = EAP_TYPE_EXPANDED;
757 		WPA_PUT_BE24(pos, EAP_VENDOR_IETF);
758 		pos += 3;
759 		WPA_PUT_BE32(pos, EAP_TYPE_NONE);
760 		pos += 4;
761 
762 		(*len) += 8;
763 	}
764 
765 	resp->length = host_to_be16(*len);
766 
767 	return (u8 *) resp;
768 }
769 
770 
eap_sm_buildNak(struct eap_sm * sm,int id,size_t * len)771 static u8 * eap_sm_buildNak(struct eap_sm *sm, int id, size_t *len)
772 {
773 	struct wpa_ssid *config = eap_get_config(sm);
774 	struct eap_hdr *resp;
775 	u8 *pos;
776 	int found = 0, expanded_found = 0;
777 	size_t count;
778 	const struct eap_method *methods, *m;
779 
780 	wpa_printf(MSG_DEBUG, "EAP: Building EAP-Nak (requested type %u "
781 		   "vendor=%u method=%u not allowed)", sm->reqMethod,
782 		   sm->reqVendor, sm->reqVendorMethod);
783 	methods = eap_peer_get_methods(&count);
784 	if (methods == NULL)
785 		return NULL;
786 	if (sm->reqMethod == EAP_TYPE_EXPANDED)
787 		return eap_sm_build_expanded_nak(sm, id, len, methods, count);
788 
789 	/* RFC 3748 - 5.3.1: Legacy Nak */
790 	*len = sizeof(struct eap_hdr) + 1;
791 	resp = os_malloc(*len + count + 1);
792 	if (resp == NULL)
793 		return NULL;
794 
795 	resp->code = EAP_CODE_RESPONSE;
796 	resp->identifier = id;
797 	pos = (u8 *) (resp + 1);
798 	*pos++ = EAP_TYPE_NAK;
799 
800 	for (m = methods; m; m = m->next) {
801 		if (m->vendor == EAP_VENDOR_IETF && m->method == sm->reqMethod)
802 			continue; /* do not allow the current method again */
803 		if (wpa_config_allowed_eap_method(config, m->vendor,
804 						  m->method)) {
805 			if (m->vendor != EAP_VENDOR_IETF) {
806 				if (expanded_found)
807 					continue;
808 				expanded_found = 1;
809 				*pos++ = EAP_TYPE_EXPANDED;
810 			} else
811 				*pos++ = m->method;
812 			(*len)++;
813 			found++;
814 		}
815 	}
816 	if (!found) {
817 		*pos = EAP_TYPE_NONE;
818 		(*len)++;
819 	}
820 	wpa_hexdump(MSG_DEBUG, "EAP: allowed methods",
821 		    ((u8 *) (resp + 1)) + 1, found);
822 
823 	resp->length = host_to_be16(*len);
824 
825 	return (u8 *) resp;
826 }
827 
828 
eap_sm_processIdentity(struct eap_sm * sm,const u8 * req)829 static void eap_sm_processIdentity(struct eap_sm *sm, const u8 *req)
830 {
831 	const struct eap_hdr *hdr = (const struct eap_hdr *) req;
832 	const u8 *pos = (const u8 *) (hdr + 1);
833 	pos++;
834 
835 	wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_STARTED
836 		"EAP authentication started");
837 
838 	/*
839 	 * RFC 3748 - 5.1: Identity
840 	 * Data field may contain a displayable message in UTF-8. If this
841 	 * includes NUL-character, only the data before that should be
842 	 * displayed. Some EAP implementasitons may piggy-back additional
843 	 * options after the NUL.
844 	 */
845 	/* TODO: could save displayable message so that it can be shown to the
846 	 * user in case of interaction is required */
847 	wpa_hexdump_ascii(MSG_DEBUG, "EAP: EAP-Request Identity data",
848 			  pos, be_to_host16(hdr->length) - 5);
849 }
850 
851 
852 #ifdef PCSC_FUNCS
eap_sm_imsi_identity(struct eap_sm * sm,struct wpa_ssid * ssid)853 static int eap_sm_imsi_identity(struct eap_sm *sm, struct wpa_ssid *ssid)
854 {
855 	int aka = 0;
856 	char imsi[100];
857 	size_t imsi_len;
858 	struct eap_method_type *m = ssid->eap_methods;
859 	int i;
860 
861 	imsi_len = sizeof(imsi);
862 	if (scard_get_imsi(sm->scard_ctx, imsi, &imsi_len)) {
863 		wpa_printf(MSG_WARNING, "Failed to get IMSI from SIM");
864 		return -1;
865 	}
866 
867 	wpa_hexdump_ascii(MSG_DEBUG, "IMSI", (u8 *) imsi, imsi_len);
868 
869 	for (i = 0; m && (m[i].vendor != EAP_VENDOR_IETF ||
870 			  m[i].method != EAP_TYPE_NONE); i++) {
871 		if (m[i].vendor == EAP_VENDOR_IETF &&
872 		    m[i].method == EAP_TYPE_AKA) {
873 			aka = 1;
874 			break;
875 		}
876 	}
877 
878 	os_free(ssid->identity);
879 	ssid->identity = os_malloc(1 + imsi_len);
880 	if (ssid->identity == NULL) {
881 		wpa_printf(MSG_WARNING, "Failed to allocate buffer for "
882 			   "IMSI-based identity");
883 		return -1;
884 	}
885 
886 	ssid->identity[0] = aka ? '0' : '1';
887 	os_memcpy(ssid->identity + 1, imsi, imsi_len);
888 	ssid->identity_len = 1 + imsi_len;
889 
890 	return 0;
891 }
892 #endif /* PCSC_FUNCS */
893 
894 
eap_sm_set_scard_pin(struct eap_sm * sm,struct wpa_ssid * ssid)895 static int eap_sm_set_scard_pin(struct eap_sm *sm, struct wpa_ssid *ssid)
896 {
897 #ifdef PCSC_FUNCS
898 	if (scard_set_pin(sm->scard_ctx, ssid->pin)) {
899 		/*
900 		 * Make sure the same PIN is not tried again in order to avoid
901 		 * blocking SIM.
902 		 */
903 		os_free(ssid->pin);
904 		ssid->pin = NULL;
905 
906 		wpa_printf(MSG_WARNING, "PIN validation failed");
907 		eap_sm_request_pin(sm);
908 		return -1;
909 	}
910 	return 0;
911 #else /* PCSC_FUNCS */
912 	return -1;
913 #endif /* PCSC_FUNCS */
914 }
915 
eap_sm_get_scard_identity(struct eap_sm * sm,struct wpa_ssid * ssid)916 static int eap_sm_get_scard_identity(struct eap_sm *sm, struct wpa_ssid *ssid)
917 {
918 #ifdef PCSC_FUNCS
919 	if (eap_sm_set_scard_pin(sm, ssid))
920 		return -1;
921 
922 	return eap_sm_imsi_identity(sm, ssid);
923 #else /* PCSC_FUNCS */
924 	return -1;
925 #endif /* PCSC_FUNCS */
926 }
927 
928 
929 /**
930  * eap_sm_buildIdentity - Build EAP-Identity/Response for the current network
931  * @sm: Pointer to EAP state machine allocated with eap_sm_init()
932  * @id: EAP identifier for the packet
933  * @len: Pointer to a variable that will be set to the length of the response
934  * @encrypted: Whether the packet is for encrypted tunnel (EAP phase 2)
935  * Returns: Pointer to the allocated EAP-Identity/Response packet or %NULL on
936  * failure
937  *
938  * This function allocates and builds an EAP-Identity/Response packet for the
939  * current network. The caller is responsible for freeing the returned data.
940  */
eap_sm_buildIdentity(struct eap_sm * sm,int id,size_t * len,int encrypted)941 u8 * eap_sm_buildIdentity(struct eap_sm *sm, int id, size_t *len,
942 			  int encrypted)
943 {
944 	struct wpa_ssid *config = eap_get_config(sm);
945 	struct eap_hdr *resp;
946 	u8 *pos;
947 	const u8 *identity;
948 	size_t identity_len;
949 
950 	if (config == NULL) {
951 		wpa_printf(MSG_WARNING, "EAP: buildIdentity: configuration "
952 			   "was not available");
953 		return NULL;
954 	}
955 
956 	if (sm->m && sm->m->get_identity &&
957 	    (identity = sm->m->get_identity(sm, sm->eap_method_priv,
958 					    &identity_len)) != NULL) {
959 		wpa_hexdump_ascii(MSG_DEBUG, "EAP: using method re-auth "
960 				  "identity", identity, identity_len);
961 	} else if (!encrypted && config->anonymous_identity) {
962 		identity = config->anonymous_identity;
963 		identity_len = config->anonymous_identity_len;
964 		wpa_hexdump_ascii(MSG_DEBUG, "EAP: using anonymous identity",
965 				  identity, identity_len);
966 	} else {
967 		identity = config->identity;
968 		identity_len = config->identity_len;
969 		wpa_hexdump_ascii(MSG_DEBUG, "EAP: using real identity",
970 				  identity, identity_len);
971 	}
972 
973 	if (identity == NULL) {
974 		wpa_printf(MSG_WARNING, "EAP: buildIdentity: identity "
975 			   "configuration was not available");
976 		if (config->pcsc) {
977 			if (eap_sm_get_scard_identity(sm, config) < 0)
978 				return NULL;
979 			identity = config->identity;
980 			identity_len = config->identity_len;
981 			wpa_hexdump_ascii(MSG_DEBUG, "permanent identity from "
982 					  "IMSI", identity, identity_len);
983 		} else {
984 			eap_sm_request_identity(sm);
985 			return NULL;
986 		}
987 	} else if (config->pcsc) {
988 		if (eap_sm_set_scard_pin(sm, config) < 0)
989 			return NULL;
990 	}
991 
992 	*len = sizeof(struct eap_hdr) + 1 + identity_len;
993 	resp = os_malloc(*len);
994 	if (resp == NULL)
995 		return NULL;
996 
997 	resp->code = EAP_CODE_RESPONSE;
998 	resp->identifier = id;
999 	resp->length = host_to_be16(*len);
1000 	pos = (u8 *) (resp + 1);
1001 	*pos++ = EAP_TYPE_IDENTITY;
1002 	os_memcpy(pos, identity, identity_len);
1003 
1004 	return (u8 *) resp;
1005 }
1006 
1007 
eap_sm_processNotify(struct eap_sm * sm,const u8 * req)1008 static void eap_sm_processNotify(struct eap_sm *sm, const u8 *req)
1009 {
1010 	const struct eap_hdr *hdr = (const struct eap_hdr *) req;
1011 	const u8 *pos;
1012 	char *msg;
1013 	size_t i, msg_len;
1014 
1015 	pos = (const u8 *) (hdr + 1);
1016 	pos++;
1017 
1018 	msg_len = be_to_host16(hdr->length);
1019 	if (msg_len < 5)
1020 		return;
1021 	msg_len -= 5;
1022 	wpa_hexdump_ascii(MSG_DEBUG, "EAP: EAP-Request Notification data",
1023 			  pos, msg_len);
1024 
1025 	msg = os_malloc(msg_len + 1);
1026 	if (msg == NULL)
1027 		return;
1028 	for (i = 0; i < msg_len; i++)
1029 		msg[i] = isprint(pos[i]) ? (char) pos[i] : '_';
1030 	msg[msg_len] = '\0';
1031 	wpa_msg(sm->msg_ctx, MSG_INFO, "%s%s",
1032 		WPA_EVENT_EAP_NOTIFICATION, msg);
1033 	os_free(msg);
1034 }
1035 
1036 
eap_sm_buildNotify(int id,size_t * len)1037 static u8 * eap_sm_buildNotify(int id, size_t *len)
1038 {
1039 	struct eap_hdr *resp;
1040 	u8 *pos;
1041 
1042 	wpa_printf(MSG_DEBUG, "EAP: Generating EAP-Response Notification");
1043 	*len = sizeof(struct eap_hdr) + 1;
1044 	resp = os_malloc(*len);
1045 	if (resp == NULL)
1046 		return NULL;
1047 
1048 	resp->code = EAP_CODE_RESPONSE;
1049 	resp->identifier = id;
1050 	resp->length = host_to_be16(*len);
1051 	pos = (u8 *) (resp + 1);
1052 	*pos = EAP_TYPE_NOTIFICATION;
1053 
1054 	return (u8 *) resp;
1055 }
1056 
1057 
eap_sm_parseEapReq(struct eap_sm * sm,const u8 * req,size_t len)1058 static void eap_sm_parseEapReq(struct eap_sm *sm, const u8 *req, size_t len)
1059 {
1060 	const struct eap_hdr *hdr;
1061 	size_t plen;
1062 	const u8 *pos;
1063 
1064 	sm->rxReq = sm->rxResp = sm->rxSuccess = sm->rxFailure = FALSE;
1065 	sm->reqId = 0;
1066 	sm->reqMethod = EAP_TYPE_NONE;
1067 	sm->reqVendor = EAP_VENDOR_IETF;
1068 	sm->reqVendorMethod = EAP_TYPE_NONE;
1069 
1070 	if (req == NULL || len < sizeof(*hdr))
1071 		return;
1072 
1073 	hdr = (const struct eap_hdr *) req;
1074 	plen = be_to_host16(hdr->length);
1075 	if (plen > len) {
1076 		wpa_printf(MSG_DEBUG, "EAP: Ignored truncated EAP-Packet "
1077 			   "(len=%lu plen=%lu)",
1078 			   (unsigned long) len, (unsigned long) plen);
1079 		return;
1080 	}
1081 
1082 	sm->reqId = hdr->identifier;
1083 
1084 	if (sm->workaround) {
1085 		md5_vector(1, (const u8 **) &req, &plen, sm->req_md5);
1086 	}
1087 
1088 	switch (hdr->code) {
1089 	case EAP_CODE_REQUEST:
1090 		if (plen < sizeof(*hdr) + 1) {
1091 			wpa_printf(MSG_DEBUG, "EAP: Too short EAP-Request - "
1092 				   "no Type field");
1093 			return;
1094 		}
1095 		sm->rxReq = TRUE;
1096 		pos = (const u8 *) (hdr + 1);
1097 		sm->reqMethod = *pos++;
1098 		if (sm->reqMethod == EAP_TYPE_EXPANDED) {
1099 			if (plen < sizeof(*hdr) + 8) {
1100 				wpa_printf(MSG_DEBUG, "EAP: Ignored truncated "
1101 					   "expanded EAP-Packet (plen=%lu)",
1102 					   (unsigned long) plen);
1103 				return;
1104 			}
1105 			sm->reqVendor = WPA_GET_BE24(pos);
1106 			pos += 3;
1107 			sm->reqVendorMethod = WPA_GET_BE32(pos);
1108 		}
1109 		wpa_printf(MSG_DEBUG, "EAP: Received EAP-Request id=%d "
1110 			   "method=%u vendor=%u vendorMethod=%u",
1111 			   sm->reqId, sm->reqMethod, sm->reqVendor,
1112 			   sm->reqVendorMethod);
1113 		break;
1114 	case EAP_CODE_RESPONSE:
1115 		if (sm->selectedMethod == EAP_TYPE_LEAP) {
1116 			/*
1117 			 * LEAP differs from RFC 4137 by using reversed roles
1118 			 * for mutual authentication and because of this, we
1119 			 * need to accept EAP-Response frames if LEAP is used.
1120 			 */
1121 			if (plen < sizeof(*hdr) + 1) {
1122 				wpa_printf(MSG_DEBUG, "EAP: Too short "
1123 					   "EAP-Response - no Type field");
1124 				return;
1125 			}
1126 			sm->rxResp = TRUE;
1127 			pos = (const u8 *) (hdr + 1);
1128 			sm->reqMethod = *pos;
1129 			wpa_printf(MSG_DEBUG, "EAP: Received EAP-Response for "
1130 				   "LEAP method=%d id=%d",
1131 				   sm->reqMethod, sm->reqId);
1132 			break;
1133 		}
1134 		wpa_printf(MSG_DEBUG, "EAP: Ignored EAP-Response");
1135 		break;
1136 	case EAP_CODE_SUCCESS:
1137 		wpa_printf(MSG_DEBUG, "EAP: Received EAP-Success");
1138 		sm->rxSuccess = TRUE;
1139 		break;
1140 	case EAP_CODE_FAILURE:
1141 		wpa_printf(MSG_DEBUG, "EAP: Received EAP-Failure");
1142 		sm->rxFailure = TRUE;
1143 		break;
1144 	default:
1145 		wpa_printf(MSG_DEBUG, "EAP: Ignored EAP-Packet with unknown "
1146 			   "code %d", hdr->code);
1147 		break;
1148 	}
1149 }
1150 
1151 
1152 /**
1153  * eap_sm_init - Allocate and initialize EAP state machine
1154  * @eapol_ctx: Context data to be used with eapol_cb calls
1155  * @eapol_cb: Pointer to EAPOL callback functions
1156  * @msg_ctx: Context data for wpa_msg() calls
1157  * @conf: EAP configuration
1158  * Returns: Pointer to the allocated EAP state machine or %NULL on failure
1159  *
1160  * This function allocates and initializes an EAP state machine. In addition,
1161  * this initializes TLS library for the new EAP state machine. eapol_cb pointer
1162  * will be in use until eap_sm_deinit() is used to deinitialize this EAP state
1163  * machine. Consequently, the caller must make sure that this data structure
1164  * remains alive while the EAP state machine is active.
1165  */
eap_sm_init(void * eapol_ctx,struct eapol_callbacks * eapol_cb,void * msg_ctx,struct eap_config * conf)1166 struct eap_sm * eap_sm_init(void *eapol_ctx, struct eapol_callbacks *eapol_cb,
1167 			    void *msg_ctx, struct eap_config *conf)
1168 {
1169 	struct eap_sm *sm;
1170 	struct tls_config tlsconf;
1171 
1172 	sm = os_zalloc(sizeof(*sm));
1173 	if (sm == NULL)
1174 		return NULL;
1175 	sm->eapol_ctx = eapol_ctx;
1176 	sm->eapol_cb = eapol_cb;
1177 	sm->msg_ctx = msg_ctx;
1178 	sm->ClientTimeout = 60;
1179 
1180 	os_memset(&tlsconf, 0, sizeof(tlsconf));
1181 	tlsconf.opensc_engine_path = conf->opensc_engine_path;
1182 	tlsconf.pkcs11_engine_path = conf->pkcs11_engine_path;
1183 	tlsconf.pkcs11_module_path = conf->pkcs11_module_path;
1184 	sm->ssl_ctx = tls_init(&tlsconf);
1185 	if (sm->ssl_ctx == NULL) {
1186 		wpa_printf(MSG_WARNING, "SSL: Failed to initialize TLS "
1187 			   "context.");
1188 		os_free(sm);
1189 		return NULL;
1190 	}
1191 
1192 	return sm;
1193 }
1194 
1195 
1196 /**
1197  * eap_sm_deinit - Deinitialize and free an EAP state machine
1198  * @sm: Pointer to EAP state machine allocated with eap_sm_init()
1199  *
1200  * This function deinitializes EAP state machine and frees all allocated
1201  * resources.
1202  */
eap_sm_deinit(struct eap_sm * sm)1203 void eap_sm_deinit(struct eap_sm *sm)
1204 {
1205 	if (sm == NULL)
1206 		return;
1207 	eap_deinit_prev_method(sm, "EAP deinit");
1208 	eap_sm_abort(sm);
1209 	tls_deinit(sm->ssl_ctx);
1210 	os_free(sm);
1211 }
1212 
1213 
1214 /**
1215  * eap_sm_step - Step EAP state machine
1216  * @sm: Pointer to EAP state machine allocated with eap_sm_init()
1217  * Returns: 1 if EAP state was changed or 0 if not
1218  *
1219  * This function advances EAP state machine to a new state to match with the
1220  * current variables. This should be called whenever variables used by the EAP
1221  * state machine have changed.
1222  */
eap_sm_step(struct eap_sm * sm)1223 int eap_sm_step(struct eap_sm *sm)
1224 {
1225 	int res = 0;
1226 	do {
1227 		sm->changed = FALSE;
1228 		SM_STEP_RUN(EAP);
1229 		if (sm->changed)
1230 			res = 1;
1231 	} while (sm->changed);
1232 	return res;
1233 }
1234 
1235 
1236 /**
1237  * eap_sm_abort - Abort EAP authentication
1238  * @sm: Pointer to EAP state machine allocated with eap_sm_init()
1239  *
1240  * Release system resources that have been allocated for the authentication
1241  * session without fully deinitializing the EAP state machine.
1242  */
eap_sm_abort(struct eap_sm * sm)1243 void eap_sm_abort(struct eap_sm *sm)
1244 {
1245 	os_free(sm->lastRespData);
1246 	sm->lastRespData = NULL;
1247 	os_free(sm->eapRespData);
1248 	sm->eapRespData = NULL;
1249 	os_free(sm->eapKeyData);
1250 	sm->eapKeyData = NULL;
1251 
1252 	/* This is not clearly specified in the EAP statemachines draft, but
1253 	 * it seems necessary to make sure that some of the EAPOL variables get
1254 	 * cleared for the next authentication. */
1255 	eapol_set_bool(sm, EAPOL_eapSuccess, FALSE);
1256 }
1257 
1258 
1259 #ifdef CONFIG_CTRL_IFACE
eap_sm_state_txt(int state)1260 static const char * eap_sm_state_txt(int state)
1261 {
1262 	switch (state) {
1263 	case EAP_INITIALIZE:
1264 		return "INITIALIZE";
1265 	case EAP_DISABLED:
1266 		return "DISABLED";
1267 	case EAP_IDLE:
1268 		return "IDLE";
1269 	case EAP_RECEIVED:
1270 		return "RECEIVED";
1271 	case EAP_GET_METHOD:
1272 		return "GET_METHOD";
1273 	case EAP_METHOD:
1274 		return "METHOD";
1275 	case EAP_SEND_RESPONSE:
1276 		return "SEND_RESPONSE";
1277 	case EAP_DISCARD:
1278 		return "DISCARD";
1279 	case EAP_IDENTITY:
1280 		return "IDENTITY";
1281 	case EAP_NOTIFICATION:
1282 		return "NOTIFICATION";
1283 	case EAP_RETRANSMIT:
1284 		return "RETRANSMIT";
1285 	case EAP_SUCCESS:
1286 		return "SUCCESS";
1287 	case EAP_FAILURE:
1288 		return "FAILURE";
1289 	default:
1290 		return "UNKNOWN";
1291 	}
1292 }
1293 #endif /* CONFIG_CTRL_IFACE */
1294 
1295 
1296 #if defined(CONFIG_CTRL_IFACE) || !defined(CONFIG_NO_STDOUT_DEBUG)
eap_sm_method_state_txt(EapMethodState state)1297 static const char * eap_sm_method_state_txt(EapMethodState state)
1298 {
1299 	switch (state) {
1300 	case METHOD_NONE:
1301 		return "NONE";
1302 	case METHOD_INIT:
1303 		return "INIT";
1304 	case METHOD_CONT:
1305 		return "CONT";
1306 	case METHOD_MAY_CONT:
1307 		return "MAY_CONT";
1308 	case METHOD_DONE:
1309 		return "DONE";
1310 	default:
1311 		return "UNKNOWN";
1312 	}
1313 }
1314 
1315 
eap_sm_decision_txt(EapDecision decision)1316 static const char * eap_sm_decision_txt(EapDecision decision)
1317 {
1318 	switch (decision) {
1319 	case DECISION_FAIL:
1320 		return "FAIL";
1321 	case DECISION_COND_SUCC:
1322 		return "COND_SUCC";
1323 	case DECISION_UNCOND_SUCC:
1324 		return "UNCOND_SUCC";
1325 	default:
1326 		return "UNKNOWN";
1327 	}
1328 }
1329 #endif /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */
1330 
1331 
1332 #ifdef CONFIG_CTRL_IFACE
1333 
1334 /**
1335  * eap_sm_get_status - Get EAP state machine status
1336  * @sm: Pointer to EAP state machine allocated with eap_sm_init()
1337  * @buf: Buffer for status information
1338  * @buflen: Maximum buffer length
1339  * @verbose: Whether to include verbose status information
1340  * Returns: Number of bytes written to buf.
1341  *
1342  * Query EAP state machine for status information. This function fills in a
1343  * text area with current status information from the EAPOL state machine. If
1344  * the buffer (buf) is not large enough, status information will be truncated
1345  * to fit the buffer.
1346  */
eap_sm_get_status(struct eap_sm * sm,char * buf,size_t buflen,int verbose)1347 int eap_sm_get_status(struct eap_sm *sm, char *buf, size_t buflen, int verbose)
1348 {
1349 	int len, ret;
1350 
1351 	if (sm == NULL)
1352 		return 0;
1353 
1354 	len = os_snprintf(buf, buflen,
1355 			  "EAP state=%s\n",
1356 			  eap_sm_state_txt(sm->EAP_state));
1357 	if (len < 0 || (size_t) len >= buflen)
1358 		return 0;
1359 
1360 	if (sm->selectedMethod != EAP_TYPE_NONE) {
1361 		const char *name;
1362 		if (sm->m) {
1363 			name = sm->m->name;
1364 		} else {
1365 			const struct eap_method *m =
1366 				eap_sm_get_eap_methods(EAP_VENDOR_IETF,
1367 						       sm->selectedMethod);
1368 			if (m)
1369 				name = m->name;
1370 			else
1371 				name = "?";
1372 		}
1373 		ret = os_snprintf(buf + len, buflen - len,
1374 				  "selectedMethod=%d (EAP-%s)\n",
1375 				  sm->selectedMethod, name);
1376 		if (ret < 0 || (size_t) ret >= buflen - len)
1377 			return len;
1378 		len += ret;
1379 
1380 		if (sm->m && sm->m->get_status) {
1381 			len += sm->m->get_status(sm, sm->eap_method_priv,
1382 						 buf + len, buflen - len,
1383 						 verbose);
1384 		}
1385 	}
1386 
1387 	if (verbose) {
1388 		ret = os_snprintf(buf + len, buflen - len,
1389 				  "reqMethod=%d\n"
1390 				  "methodState=%s\n"
1391 				  "decision=%s\n"
1392 				  "ClientTimeout=%d\n",
1393 				  sm->reqMethod,
1394 				  eap_sm_method_state_txt(sm->methodState),
1395 				  eap_sm_decision_txt(sm->decision),
1396 				  sm->ClientTimeout);
1397 		if (ret < 0 || (size_t) ret >= buflen - len)
1398 			return len;
1399 		len += ret;
1400 	}
1401 
1402 	return len;
1403 }
1404 #endif /* CONFIG_CTRL_IFACE */
1405 
1406 
1407 #if defined(CONFIG_CTRL_IFACE) || !defined(CONFIG_NO_STDOUT_DEBUG)
1408 typedef enum {
1409 	TYPE_IDENTITY, TYPE_PASSWORD, TYPE_OTP, TYPE_PIN, TYPE_NEW_PASSWORD,
1410 	TYPE_PASSPHRASE
1411 } eap_ctrl_req_type;
1412 
eap_sm_request(struct eap_sm * sm,eap_ctrl_req_type type,const char * msg,size_t msglen)1413 static void eap_sm_request(struct eap_sm *sm, eap_ctrl_req_type type,
1414 			   const char *msg, size_t msglen)
1415 {
1416 	struct wpa_ssid *config;
1417 	char *buf;
1418 	size_t buflen;
1419 	int len;
1420 	char *field;
1421 	char *txt, *tmp;
1422 
1423 	if (sm == NULL)
1424 		return;
1425 	config = eap_get_config(sm);
1426 	if (config == NULL)
1427 		return;
1428 
1429 	switch (type) {
1430 	case TYPE_IDENTITY:
1431 		field = "IDENTITY";
1432 		txt = "Identity";
1433 		config->pending_req_identity++;
1434 		break;
1435 	case TYPE_PASSWORD:
1436 		field = "PASSWORD";
1437 		txt = "Password";
1438 		config->pending_req_password++;
1439 		break;
1440 	case TYPE_NEW_PASSWORD:
1441 		field = "NEW_PASSWORD";
1442 		txt = "New Password";
1443 		config->pending_req_new_password++;
1444 		break;
1445 	case TYPE_PIN:
1446 		field = "PIN";
1447 		txt = "PIN";
1448 		config->pending_req_pin++;
1449 		break;
1450 	case TYPE_OTP:
1451 		field = "OTP";
1452 		if (msg) {
1453 			tmp = os_malloc(msglen + 3);
1454 			if (tmp == NULL)
1455 				return;
1456 			tmp[0] = '[';
1457 			os_memcpy(tmp + 1, msg, msglen);
1458 			tmp[msglen + 1] = ']';
1459 			tmp[msglen + 2] = '\0';
1460 			txt = tmp;
1461 			os_free(config->pending_req_otp);
1462 			config->pending_req_otp = tmp;
1463 			config->pending_req_otp_len = msglen + 3;
1464 		} else {
1465 			if (config->pending_req_otp == NULL)
1466 				return;
1467 			txt = config->pending_req_otp;
1468 		}
1469 		break;
1470 	case TYPE_PASSPHRASE:
1471 		field = "PASSPHRASE";
1472 		txt = "Private key passphrase";
1473 		config->pending_req_passphrase++;
1474 		break;
1475 	default:
1476 		return;
1477 	}
1478 
1479 	buflen = 100 + os_strlen(txt) + config->ssid_len;
1480 	buf = os_malloc(buflen);
1481 	if (buf == NULL)
1482 		return;
1483 	len = os_snprintf(buf, buflen,
1484 			  WPA_CTRL_REQ "%s-%d:%s needed for SSID ",
1485 			  field, config->id, txt);
1486 	if (len < 0 || (size_t) len >= buflen) {
1487 		os_free(buf);
1488 		return;
1489 	}
1490 	if (config->ssid && buflen > len + config->ssid_len) {
1491 		os_memcpy(buf + len, config->ssid, config->ssid_len);
1492 		len += config->ssid_len;
1493 		buf[len] = '\0';
1494 	}
1495 	buf[buflen - 1] = '\0';
1496 	wpa_msg(sm->msg_ctx, MSG_INFO, "%s", buf);
1497 	os_free(buf);
1498 }
1499 #else /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */
1500 #define eap_sm_request(sm, type, msg, msglen) do { } while (0)
1501 #endif /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */
1502 
1503 
1504 /**
1505  * eap_sm_request_identity - Request identity from user (ctrl_iface)
1506  * @sm: Pointer to EAP state machine allocated with eap_sm_init()
1507  *
1508  * EAP methods can call this function to request identity information for the
1509  * current network. This is normally called when the identity is not included
1510  * in the network configuration. The request will be sent to monitor programs
1511  * through the control interface.
1512  */
eap_sm_request_identity(struct eap_sm * sm)1513 void eap_sm_request_identity(struct eap_sm *sm)
1514 {
1515 	eap_sm_request(sm, TYPE_IDENTITY, NULL, 0);
1516 }
1517 
1518 
1519 /**
1520  * eap_sm_request_password - Request password from user (ctrl_iface)
1521  * @sm: Pointer to EAP state machine allocated with eap_sm_init()
1522  *
1523  * EAP methods can call this function to request password information for the
1524  * current network. This is normally called when the password is not included
1525  * in the network configuration. The request will be sent to monitor programs
1526  * through the control interface.
1527  */
eap_sm_request_password(struct eap_sm * sm)1528 void eap_sm_request_password(struct eap_sm *sm)
1529 {
1530 	eap_sm_request(sm, TYPE_PASSWORD, NULL, 0);
1531 }
1532 
1533 
1534 /**
1535  * eap_sm_request_new_password - Request new password from user (ctrl_iface)
1536  * @sm: Pointer to EAP state machine allocated with eap_sm_init()
1537  *
1538  * EAP methods can call this function to request new password information for
1539  * the current network. This is normally called when the EAP method indicates
1540  * that the current password has expired and password change is required. The
1541  * request will be sent to monitor programs through the control interface.
1542  */
eap_sm_request_new_password(struct eap_sm * sm)1543 void eap_sm_request_new_password(struct eap_sm *sm)
1544 {
1545 	eap_sm_request(sm, TYPE_NEW_PASSWORD, NULL, 0);
1546 }
1547 
1548 
1549 /**
1550  * eap_sm_request_pin - Request SIM or smart card PIN from user (ctrl_iface)
1551  * @sm: Pointer to EAP state machine allocated with eap_sm_init()
1552  *
1553  * EAP methods can call this function to request SIM or smart card PIN
1554  * information for the current network. This is normally called when the PIN is
1555  * not included in the network configuration. The request will be sent to
1556  * monitor programs through the control interface.
1557  */
eap_sm_request_pin(struct eap_sm * sm)1558 void eap_sm_request_pin(struct eap_sm *sm)
1559 {
1560 	eap_sm_request(sm, TYPE_PIN, NULL, 0);
1561 }
1562 
1563 
1564 /**
1565  * eap_sm_request_otp - Request one time password from user (ctrl_iface)
1566  * @sm: Pointer to EAP state machine allocated with eap_sm_init()
1567  * @msg: Message to be displayed to the user when asking for OTP
1568  * @msg_len: Length of the user displayable message
1569  *
1570  * EAP methods can call this function to request open time password (OTP) for
1571  * the current network. The request will be sent to monitor programs through
1572  * the control interface.
1573  */
eap_sm_request_otp(struct eap_sm * sm,const char * msg,size_t msg_len)1574 void eap_sm_request_otp(struct eap_sm *sm, const char *msg, size_t msg_len)
1575 {
1576 	eap_sm_request(sm, TYPE_OTP, msg, msg_len);
1577 }
1578 
1579 
1580 /**
1581  * eap_sm_request_passphrase - Request passphrase from user (ctrl_iface)
1582  * @sm: Pointer to EAP state machine allocated with eap_sm_init()
1583  *
1584  * EAP methods can call this function to request passphrase for a private key
1585  * for the current network. This is normally called when the passphrase is not
1586  * included in the network configuration. The request will be sent to monitor
1587  * programs through the control interface.
1588  */
eap_sm_request_passphrase(struct eap_sm * sm)1589 void eap_sm_request_passphrase(struct eap_sm *sm)
1590 {
1591 	eap_sm_request(sm, TYPE_PASSPHRASE, NULL, 0);
1592 }
1593 
1594 
1595 /**
1596  * eap_sm_notify_ctrl_attached - Notification of attached monitor
1597  * @sm: Pointer to EAP state machine allocated with eap_sm_init()
1598  *
1599  * Notify EAP state machines that a monitor was attached to the control
1600  * interface to trigger re-sending of pending requests for user input.
1601  */
eap_sm_notify_ctrl_attached(struct eap_sm * sm)1602 void eap_sm_notify_ctrl_attached(struct eap_sm *sm)
1603 {
1604 	struct wpa_ssid *config = eap_get_config(sm);
1605 
1606 	if (config == NULL)
1607 		return;
1608 
1609 	/* Re-send any pending requests for user data since a new control
1610 	 * interface was added. This handles cases where the EAP authentication
1611 	 * starts immediately after system startup when the user interface is
1612 	 * not yet running. */
1613 	if (config->pending_req_identity)
1614 		eap_sm_request_identity(sm);
1615 	if (config->pending_req_password)
1616 		eap_sm_request_password(sm);
1617 	if (config->pending_req_new_password)
1618 		eap_sm_request_new_password(sm);
1619 	if (config->pending_req_otp)
1620 		eap_sm_request_otp(sm, NULL, 0);
1621 	if (config->pending_req_pin)
1622 		eap_sm_request_pin(sm);
1623 	if (config->pending_req_passphrase)
1624 		eap_sm_request_passphrase(sm);
1625 }
1626 
1627 
eap_allowed_phase2_type(int vendor,int type)1628 static int eap_allowed_phase2_type(int vendor, int type)
1629 {
1630 	if (vendor != EAP_VENDOR_IETF)
1631 		return 0;
1632 	return type != EAP_TYPE_PEAP && type != EAP_TYPE_TTLS &&
1633 		type != EAP_TYPE_FAST;
1634 }
1635 
1636 
1637 /**
1638  * eap_get_phase2_type - Get EAP type for the given EAP phase 2 method name
1639  * @name: EAP method name, e.g., MD5
1640  * @vendor: Buffer for returning EAP Vendor-Id
1641  * Returns: EAP method type or %EAP_TYPE_NONE if not found
1642  *
1643  * This function maps EAP type names into EAP type numbers that are allowed for
1644  * Phase 2, i.e., for tunneled authentication. Phase 2 is used, e.g., with
1645  * EAP-PEAP, EAP-TTLS, and EAP-FAST.
1646  */
eap_get_phase2_type(const char * name,int * vendor)1647 u32 eap_get_phase2_type(const char *name, int *vendor)
1648 {
1649 	int v;
1650 	u8 type = eap_get_type(name, &v);
1651 	if (eap_allowed_phase2_type(v, type)) {
1652 		*vendor = v;
1653 		return type;
1654 	}
1655 	*vendor = EAP_VENDOR_IETF;
1656 	return EAP_TYPE_NONE;
1657 }
1658 
1659 
1660 /**
1661  * eap_get_phase2_types - Get list of allowed EAP phase 2 types
1662  * @config: Pointer to a network configuration
1663  * @count: Pointer to a variable to be filled with number of returned EAP types
1664  * Returns: Pointer to allocated type list or %NULL on failure
1665  *
1666  * This function generates an array of allowed EAP phase 2 (tunneled) types for
1667  * the given network configuration.
1668  */
eap_get_phase2_types(struct wpa_ssid * config,size_t * count)1669 struct eap_method_type * eap_get_phase2_types(struct wpa_ssid *config,
1670 					      size_t *count)
1671 {
1672 	struct eap_method_type *buf;
1673 	u32 method;
1674 	int vendor;
1675 	size_t mcount;
1676 	const struct eap_method *methods, *m;
1677 
1678 	methods = eap_peer_get_methods(&mcount);
1679 	if (methods == NULL)
1680 		return NULL;
1681 	*count = 0;
1682 	buf = os_malloc(mcount * sizeof(struct eap_method_type));
1683 	if (buf == NULL)
1684 		return NULL;
1685 
1686 	for (m = methods; m; m = m->next) {
1687 		vendor = m->vendor;
1688 		method = m->method;
1689 		if (eap_allowed_phase2_type(vendor, method)) {
1690 			if (vendor == EAP_VENDOR_IETF &&
1691 			    method == EAP_TYPE_TLS && config &&
1692 			    config->private_key2 == NULL)
1693 				continue;
1694 			buf[*count].vendor = vendor;
1695 			buf[*count].method = method;
1696 			(*count)++;
1697 		}
1698 	}
1699 
1700 	return buf;
1701 }
1702 
1703 
1704 /**
1705  * eap_set_fast_reauth - Update fast_reauth setting
1706  * @sm: Pointer to EAP state machine allocated with eap_sm_init()
1707  * @enabled: 1 = Fast reauthentication is enabled, 0 = Disabled
1708  */
eap_set_fast_reauth(struct eap_sm * sm,int enabled)1709 void eap_set_fast_reauth(struct eap_sm *sm, int enabled)
1710 {
1711 	sm->fast_reauth = enabled;
1712 }
1713 
1714 
1715 /**
1716  * eap_set_workaround - Update EAP workarounds setting
1717  * @sm: Pointer to EAP state machine allocated with eap_sm_init()
1718  * @workaround: 1 = Enable EAP workarounds, 0 = Disable EAP workarounds
1719  */
eap_set_workaround(struct eap_sm * sm,unsigned int workaround)1720 void eap_set_workaround(struct eap_sm *sm, unsigned int workaround)
1721 {
1722 	sm->workaround = workaround;
1723 }
1724 
1725 
1726 /**
1727  * eap_get_config - Get current network configuration
1728  * @sm: Pointer to EAP state machine allocated with eap_sm_init()
1729  * Returns: Pointer to the current network configuration or %NULL if not found
1730  *
1731  * EAP peer methods should avoid using this function if they can use other
1732  * access functions, like eap_get_config_identity() and
1733  * eap_get_config_password(), that do not require direct access to
1734  * struct wpa_ssid.
1735  */
eap_get_config(struct eap_sm * sm)1736 struct wpa_ssid * eap_get_config(struct eap_sm *sm)
1737 {
1738 	return sm->eapol_cb->get_config(sm->eapol_ctx);
1739 }
1740 
1741 
1742 /**
1743  * eap_get_config_password - Get identity from the network configuration
1744  * @sm: Pointer to EAP state machine allocated with eap_sm_init()
1745  * @len: Buffer for the length of the identity
1746  * Returns: Pointer to the identity or %NULL if not found
1747  */
eap_get_config_identity(struct eap_sm * sm,size_t * len)1748 const u8 * eap_get_config_identity(struct eap_sm *sm, size_t *len)
1749 {
1750 	struct wpa_ssid *config = eap_get_config(sm);
1751 	if (config == NULL)
1752 		return NULL;
1753 	*len = config->identity_len;
1754 	return config->identity;
1755 }
1756 
1757 
1758 /**
1759  * eap_get_config_password - Get password from the network configuration
1760  * @sm: Pointer to EAP state machine allocated with eap_sm_init()
1761  * @len: Buffer for the length of the password
1762  * Returns: Pointer to the password or %NULL if not found
1763  */
eap_get_config_password(struct eap_sm * sm,size_t * len)1764 const u8 * eap_get_config_password(struct eap_sm *sm, size_t *len)
1765 {
1766 	struct wpa_ssid *config = eap_get_config(sm);
1767 	if (config == NULL)
1768 		return NULL;
1769 	*len = config->password_len;
1770 	return config->password;
1771 }
1772 
1773 
1774 /**
1775  * eap_get_config_new_password - Get new password from network configuration
1776  * @sm: Pointer to EAP state machine allocated with eap_sm_init()
1777  * @len: Buffer for the length of the new password
1778  * Returns: Pointer to the new password or %NULL if not found
1779  */
eap_get_config_new_password(struct eap_sm * sm,size_t * len)1780 const u8 * eap_get_config_new_password(struct eap_sm *sm, size_t *len)
1781 {
1782 	struct wpa_ssid *config = eap_get_config(sm);
1783 	if (config == NULL)
1784 		return NULL;
1785 	*len = config->new_password_len;
1786 	return config->new_password;
1787 }
1788 
1789 
1790 /**
1791  * eap_get_config_otp - Get one-time password from the network configuration
1792  * @sm: Pointer to EAP state machine allocated with eap_sm_init()
1793  * @len: Buffer for the length of the one-time password
1794  * Returns: Pointer to the one-time password or %NULL if not found
1795  */
eap_get_config_otp(struct eap_sm * sm,size_t * len)1796 const u8 * eap_get_config_otp(struct eap_sm *sm, size_t *len)
1797 {
1798 	struct wpa_ssid *config = eap_get_config(sm);
1799 	if (config == NULL)
1800 		return NULL;
1801 	*len = config->otp_len;
1802 	return config->otp;
1803 }
1804 
1805 
1806 /**
1807  * eap_clear_config_otp - Clear used one-time password
1808  * @sm: Pointer to EAP state machine allocated with eap_sm_init()
1809  *
1810  * This function clears a used one-time password (OTP) from the current network
1811  * configuration. This should be called when the OTP has been used and is not
1812  * needed anymore.
1813  */
eap_clear_config_otp(struct eap_sm * sm)1814 void eap_clear_config_otp(struct eap_sm *sm)
1815 {
1816 	struct wpa_ssid *config = eap_get_config(sm);
1817 	if (config == NULL)
1818 		return;
1819 	os_memset(config->otp, 0, config->otp_len);
1820 	os_free(config->otp);
1821 	config->otp = NULL;
1822 	config->otp_len = 0;
1823 }
1824 
1825 
1826 /**
1827  * eap_key_available - Get key availability (eapKeyAvailable variable)
1828  * @sm: Pointer to EAP state machine allocated with eap_sm_init()
1829  * Returns: 1 if EAP keying material is available, 0 if not
1830  */
eap_key_available(struct eap_sm * sm)1831 int eap_key_available(struct eap_sm *sm)
1832 {
1833 	return sm ? sm->eapKeyAvailable : 0;
1834 }
1835 
1836 
1837 /**
1838  * eap_notify_success - Notify EAP state machine about external success trigger
1839  * @sm: Pointer to EAP state machine allocated with eap_sm_init()
1840  *
1841  * This function is called when external event, e.g., successful completion of
1842  * WPA-PSK key handshake, is indicating that EAP state machine should move to
1843  * success state. This is mainly used with security modes that do not use EAP
1844  * state machine (e.g., WPA-PSK).
1845  */
eap_notify_success(struct eap_sm * sm)1846 void eap_notify_success(struct eap_sm *sm)
1847 {
1848 	if (sm) {
1849 		sm->decision = DECISION_COND_SUCC;
1850 		sm->EAP_state = EAP_SUCCESS;
1851 	}
1852 }
1853 
1854 
1855 /**
1856  * eap_notify_lower_layer_success - Notification of lower layer success
1857  * @sm: Pointer to EAP state machine allocated with eap_sm_init()
1858  *
1859  * Notify EAP state machines that a lower layer has detected a successful
1860  * authentication. This is used to recover from dropped EAP-Success messages.
1861  */
eap_notify_lower_layer_success(struct eap_sm * sm)1862 void eap_notify_lower_layer_success(struct eap_sm *sm)
1863 {
1864 	if (sm == NULL)
1865 		return;
1866 
1867 	if (eapol_get_bool(sm, EAPOL_eapSuccess) ||
1868 	    sm->decision == DECISION_FAIL ||
1869 	    (sm->methodState != METHOD_MAY_CONT &&
1870 	     sm->methodState != METHOD_DONE))
1871 		return;
1872 
1873 	if (sm->eapKeyData != NULL)
1874 		sm->eapKeyAvailable = TRUE;
1875 	eapol_set_bool(sm, EAPOL_eapSuccess, TRUE);
1876 	wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_SUCCESS
1877 		"EAP authentication completed successfully (based on lower "
1878 		"layer success)");
1879 }
1880 
1881 
1882 /**
1883  * eap_get_eapKeyData - Get master session key (MSK) from EAP state machine
1884  * @sm: Pointer to EAP state machine allocated with eap_sm_init()
1885  * @len: Pointer to variable that will be set to number of bytes in the key
1886  * Returns: Pointer to the EAP keying data or %NULL on failure
1887  *
1888  * Fetch EAP keying material (MSK, eapKeyData) from the EAP state machine. The
1889  * key is available only after a successful authentication. EAP state machine
1890  * continues to manage the key data and the caller must not change or free the
1891  * returned data.
1892  */
eap_get_eapKeyData(struct eap_sm * sm,size_t * len)1893 const u8 * eap_get_eapKeyData(struct eap_sm *sm, size_t *len)
1894 {
1895 	if (sm == NULL || sm->eapKeyData == NULL) {
1896 		*len = 0;
1897 		return NULL;
1898 	}
1899 
1900 	*len = sm->eapKeyDataLen;
1901 	return sm->eapKeyData;
1902 }
1903 
1904 
1905 /**
1906  * eap_get_eapKeyData - Get EAP response data
1907  * @sm: Pointer to EAP state machine allocated with eap_sm_init()
1908  * @len: Pointer to variable that will be set to the length of the response
1909  * Returns: Pointer to the EAP response (eapRespData) or %NULL on failure
1910  *
1911  * Fetch EAP response (eapRespData) from the EAP state machine. This data is
1912  * available when EAP state machine has processed an incoming EAP request. The
1913  * EAP state machine does not maintain a reference to the response after this
1914  * function is called and the caller is responsible for freeing the data.
1915  */
eap_get_eapRespData(struct eap_sm * sm,size_t * len)1916 u8 * eap_get_eapRespData(struct eap_sm *sm, size_t *len)
1917 {
1918 	u8 *resp;
1919 
1920 	if (sm == NULL || sm->eapRespData == NULL) {
1921 		*len = 0;
1922 		return NULL;
1923 	}
1924 
1925 	resp = sm->eapRespData;
1926 	*len = sm->eapRespDataLen;
1927 	sm->eapRespData = NULL;
1928 	sm->eapRespDataLen = 0;
1929 
1930 	return resp;
1931 }
1932 
1933 
1934 /**
1935  * eap_sm_register_scard_ctx - Notification of smart card context
1936  * @sm: Pointer to EAP state machine allocated with eap_sm_init()
1937  * @ctx: Context data for smart card operations
1938  *
1939  * Notify EAP state machines of context data for smart card operations. This
1940  * context data will be used as a parameter for scard_*() functions.
1941  */
eap_register_scard_ctx(struct eap_sm * sm,void * ctx)1942 void eap_register_scard_ctx(struct eap_sm *sm, void *ctx)
1943 {
1944 	if (sm)
1945 		sm->scard_ctx = ctx;
1946 }
1947 
1948 
1949 /**
1950  * eap_hdr_validate - Validate EAP header
1951  * @vendor: Expected EAP Vendor-Id (0 = IETF)
1952  * @eap_type: Expected EAP type number
1953  * @msg: EAP frame (starting with EAP header)
1954  * @msglen: Length of msg
1955  * @plen: Pointer to variable to contain the returned payload length
1956  * Returns: Pointer to EAP payload (after type field), or %NULL on failure
1957  *
1958  * This is a helper function for EAP method implementations. This is usually
1959  * called in the beginning of struct eap_method::process() function to verify
1960  * that the received EAP request packet has a valid header. This function is
1961  * able to process both legacy and expanded EAP headers and in most cases, the
1962  * caller can just use the returned payload pointer (into *plen) for processing
1963  * the payload regardless of whether the packet used the expanded EAP header or
1964  * not.
1965  */
eap_hdr_validate(int vendor,EapType eap_type,const u8 * msg,size_t msglen,size_t * plen)1966 const u8 * eap_hdr_validate(int vendor, EapType eap_type,
1967 			    const u8 *msg, size_t msglen, size_t *plen)
1968 {
1969 	const struct eap_hdr *hdr;
1970 	const u8 *pos;
1971 	size_t len;
1972 
1973 	hdr = (const struct eap_hdr *) msg;
1974 
1975 	if (msglen < sizeof(*hdr)) {
1976 		wpa_printf(MSG_INFO, "EAP: Too short EAP frame");
1977 		return NULL;
1978 	}
1979 
1980 	len = be_to_host16(hdr->length);
1981 	if (len < sizeof(*hdr) + 1 || len > msglen) {
1982 		wpa_printf(MSG_INFO, "EAP: Invalid EAP length");
1983 		return NULL;
1984 	}
1985 
1986 	pos = (const u8 *) (hdr + 1);
1987 
1988 	if (*pos == EAP_TYPE_EXPANDED) {
1989 		int exp_vendor;
1990 		u32 exp_type;
1991 		if (len < sizeof(*hdr) + 8) {
1992 			wpa_printf(MSG_INFO, "EAP: Invalid expanded EAP "
1993 				   "length");
1994 			return NULL;
1995 		}
1996 		pos++;
1997 		exp_vendor = WPA_GET_BE24(pos);
1998 		pos += 3;
1999 		exp_type = WPA_GET_BE32(pos);
2000 		pos += 4;
2001 		if (exp_vendor != vendor || exp_type != (u32) eap_type) {
2002 			wpa_printf(MSG_INFO, "EAP: Invalid expanded frame "
2003 				   "type");
2004 			return NULL;
2005 		}
2006 
2007 		*plen = len - sizeof(*hdr) - 8;
2008 		return pos;
2009 	} else {
2010 		if (vendor != EAP_VENDOR_IETF || *pos != eap_type) {
2011 			wpa_printf(MSG_INFO, "EAP: Invalid frame type");
2012 			return NULL;
2013 		}
2014 		*plen = len - sizeof(*hdr) - 1;
2015 		return pos + 1;
2016 	}
2017 }
2018 
2019 
2020 /**
2021  * eap_set_config_blob - Set or add a named configuration blob
2022  * @sm: Pointer to EAP state machine allocated with eap_sm_init()
2023  * @blob: New value for the blob
2024  *
2025  * Adds a new configuration blob or replaces the current value of an existing
2026  * blob.
2027  */
eap_set_config_blob(struct eap_sm * sm,struct wpa_config_blob * blob)2028 void eap_set_config_blob(struct eap_sm *sm, struct wpa_config_blob *blob)
2029 {
2030 	sm->eapol_cb->set_config_blob(sm->eapol_ctx, blob);
2031 }
2032 
2033 
2034 /**
2035  * eap_get_config_blob - Get a named configuration blob
2036  * @sm: Pointer to EAP state machine allocated with eap_sm_init()
2037  * @name: Name of the blob
2038  * Returns: Pointer to blob data or %NULL if not found
2039  */
eap_get_config_blob(struct eap_sm * sm,const char * name)2040 const struct wpa_config_blob * eap_get_config_blob(struct eap_sm *sm,
2041 						   const char *name)
2042 {
2043 	return sm->eapol_cb->get_config_blob(sm->eapol_ctx, name);
2044 }
2045 
2046 
2047 /**
2048  * eap_set_force_disabled - Set force_disabled flag
2049  * @sm: Pointer to EAP state machine allocated with eap_sm_init()
2050  * @disabled: 1 = EAP disabled, 0 = EAP enabled
2051  *
2052  * This function is used to force EAP state machine to be disabled when it is
2053  * not in use (e.g., with WPA-PSK or plaintext connections).
2054  */
eap_set_force_disabled(struct eap_sm * sm,int disabled)2055 void eap_set_force_disabled(struct eap_sm *sm, int disabled)
2056 {
2057 	sm->force_disabled = disabled;
2058 }
2059 
2060 
2061 /**
2062  * eap_msg_alloc - Allocate a buffer for an EAP message
2063  * @vendor: Vendor-Id (0 = IETF)
2064  * @type: EAP type
2065  * @len: Buffer for returning message length
2066  * @payload_len: Payload length in bytes (data after Type)
2067  * @code: Message Code (EAP_CODE_*)
2068  * @identifier: Identifier
2069  * @payload: Pointer to payload pointer that will be set to point to the
2070  * beginning of the payload or %NULL if payload pointer is not needed
2071  * Returns: Pointer to the allocated message buffer or %NULL on error
2072  *
2073  * This function can be used to allocate a buffer for an EAP message and fill
2074  * in the EAP header. This function is automatically using expanded EAP header
2075  * if the selected Vendor-Id is not IETF. In other words, most EAP methods do
2076  * not need to separately select which header type to use when using this
2077  * function to allocate the message buffers.
2078  */
eap_msg_alloc(int vendor,EapType type,size_t * len,size_t payload_len,u8 code,u8 identifier,u8 ** payload)2079 struct eap_hdr * eap_msg_alloc(int vendor, EapType type, size_t *len,
2080 			       size_t payload_len, u8 code, u8 identifier,
2081 			       u8 **payload)
2082 {
2083 	struct eap_hdr *hdr;
2084 	u8 *pos;
2085 
2086 	*len = sizeof(struct eap_hdr) + (vendor == EAP_VENDOR_IETF ? 1 : 8) +
2087 		payload_len;
2088 	hdr = os_malloc(*len);
2089 	if (hdr) {
2090 		hdr->code = code;
2091 		hdr->identifier = identifier;
2092 		hdr->length = host_to_be16(*len);
2093 		pos = (u8 *) (hdr + 1);
2094 		if (vendor == EAP_VENDOR_IETF) {
2095 			*pos++ = type;
2096 		} else {
2097 			*pos++ = EAP_TYPE_EXPANDED;
2098 			WPA_PUT_BE24(pos, vendor);
2099 			pos += 3;
2100 			WPA_PUT_BE32(pos, type);
2101 			pos += 4;
2102 		}
2103 		if (payload)
2104 			*payload = pos;
2105 	}
2106 
2107 	return hdr;
2108 }
2109 
2110 
2111  /**
2112  * eap_notify_pending - Notify that EAP method is ready to re-process a request
2113  * @sm: Pointer to EAP state machine allocated with eap_sm_init()
2114  *
2115  * An EAP method can perform a pending operation (e.g., to get a response from
2116  * an external process). Once the response is available, this function can be
2117  * used to request EAPOL state machine to retry delivering the previously
2118  * received (and still unanswered) EAP request to EAP state machine.
2119  */
eap_notify_pending(struct eap_sm * sm)2120 void eap_notify_pending(struct eap_sm *sm)
2121 {
2122 	sm->eapol_cb->notify_pending(sm->eapol_ctx);
2123 }
2124 
2125 
2126 /**
2127  * eap_invalidate_cached_session - Mark cached session data invalid
2128  * @sm: Pointer to EAP state machine allocated with eap_sm_init()
2129  */
eap_invalidate_cached_session(struct eap_sm * sm)2130 void eap_invalidate_cached_session(struct eap_sm *sm)
2131 {
2132 	if (sm)
2133 		eap_deinit_prev_method(sm, "invalidate");
2134 }
2135