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