2 * EAP peer state machines (RFC 4137)
3 * Copyright (c) 2004-2008, Jouni Malinen <j@w1.fi>
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.
9 * Alternatively, this software may be distributed under the terms of BSD
12 * See README and COPYING for more details.
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).
28 #include "eap_config.h"
31 #include "pcsc_funcs.h"
33 #include "state_machine.h"
35 #define STATE_MACHINE_DATA struct eap_sm
36 #define STATE_MACHINE_DEBUG_PREFIX "EAP"
38 #define EAP_MAX_AUTH_ROUNDS 50
41 static Boolean
eap_sm_allowMethod(struct eap_sm
*sm
, int vendor
,
43 static struct wpabuf
* eap_sm_buildNak(struct eap_sm
*sm
, int id
);
44 static void eap_sm_processIdentity(struct eap_sm
*sm
,
45 const struct wpabuf
*req
);
46 static void eap_sm_processNotify(struct eap_sm
*sm
, const struct wpabuf
*req
);
47 static struct wpabuf
* eap_sm_buildNotify(int id
);
48 static void eap_sm_parseEapReq(struct eap_sm
*sm
, const struct wpabuf
*req
);
49 #if defined(CONFIG_CTRL_IFACE) || !defined(CONFIG_NO_STDOUT_DEBUG)
50 static const char * eap_sm_method_state_txt(EapMethodState state
);
51 static const char * eap_sm_decision_txt(EapDecision decision
);
52 #endif /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */
56 static Boolean
eapol_get_bool(struct eap_sm
*sm
, enum eapol_bool_var var
)
58 return sm
->eapol_cb
->get_bool(sm
->eapol_ctx
, var
);
62 static void eapol_set_bool(struct eap_sm
*sm
, enum eapol_bool_var var
,
65 sm
->eapol_cb
->set_bool(sm
->eapol_ctx
, var
, value
);
69 static unsigned int eapol_get_int(struct eap_sm
*sm
, enum eapol_int_var var
)
71 return sm
->eapol_cb
->get_int(sm
->eapol_ctx
, var
);
75 static void eapol_set_int(struct eap_sm
*sm
, enum eapol_int_var var
,
78 sm
->eapol_cb
->set_int(sm
->eapol_ctx
, var
, value
);
82 static struct wpabuf
* eapol_get_eapReqData(struct eap_sm
*sm
)
84 return sm
->eapol_cb
->get_eapReqData(sm
->eapol_ctx
);
88 static void eap_deinit_prev_method(struct eap_sm
*sm
, const char *txt
)
90 if (sm
->m
== NULL
|| sm
->eap_method_priv
== NULL
)
93 wpa_printf(MSG_DEBUG
, "EAP: deinitialize previously used EAP method "
94 "(%d, %s) at %s", sm
->selectedMethod
, sm
->m
->name
, txt
);
95 sm
->m
->deinit(sm
, sm
->eap_method_priv
);
96 sm
->eap_method_priv
= NULL
;
102 * eap_allowed_method - Check whether EAP method is allowed
103 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
104 * @vendor: Vendor-Id for expanded types or 0 = IETF for legacy types
106 * Returns: 1 = allowed EAP method, 0 = not allowed
108 static int eap_allowed_method(struct eap_sm
*sm
, int vendor
, u32 method
)
110 struct eap_peer_config
*config
= eap_get_config(sm
);
112 struct eap_method_type
*m
;
114 if (config
== NULL
|| config
->eap_methods
== NULL
)
117 m
= config
->eap_methods
;
118 for (i
= 0; m
[i
].vendor
!= EAP_VENDOR_IETF
||
119 m
[i
].method
!= EAP_TYPE_NONE
; i
++) {
120 if (m
[i
].vendor
== vendor
&& m
[i
].method
== method
)
128 * This state initializes state machine variables when the machine is
129 * activated (portEnabled = TRUE). This is also used when re-starting
130 * authentication (eapRestart == TRUE).
132 SM_STATE(EAP
, INITIALIZE
)
134 SM_ENTRY(EAP
, INITIALIZE
);
135 if (sm
->fast_reauth
&& sm
->m
&& sm
->m
->has_reauth_data
&&
136 sm
->m
->has_reauth_data(sm
, sm
->eap_method_priv
)) {
137 wpa_printf(MSG_DEBUG
, "EAP: maintaining EAP method data for "
138 "fast reauthentication");
139 sm
->m
->deinit_for_reauth(sm
, sm
->eap_method_priv
);
141 eap_deinit_prev_method(sm
, "INITIALIZE");
143 sm
->selectedMethod
= EAP_TYPE_NONE
;
144 sm
->methodState
= METHOD_NONE
;
145 sm
->allowNotifications
= TRUE
;
146 sm
->decision
= DECISION_FAIL
;
147 eapol_set_int(sm
, EAPOL_idleWhile
, sm
->ClientTimeout
);
148 eapol_set_bool(sm
, EAPOL_eapSuccess
, FALSE
);
149 eapol_set_bool(sm
, EAPOL_eapFail
, FALSE
);
150 os_free(sm
->eapKeyData
);
151 sm
->eapKeyData
= NULL
;
152 sm
->eapKeyAvailable
= FALSE
;
153 eapol_set_bool(sm
, EAPOL_eapRestart
, FALSE
);
154 sm
->lastId
= -1; /* new session - make sure this does not match with
155 * the first EAP-Packet */
157 * RFC 4137 does not reset eapResp and eapNoResp here. However, this
158 * seemed to be able to trigger cases where both were set and if EAPOL
159 * state machine uses eapNoResp first, it may end up not sending a real
160 * reply correctly. This occurred when the workaround in FAIL state set
161 * eapNoResp = TRUE.. Maybe that workaround needs to be fixed to do
164 eapol_set_bool(sm
, EAPOL_eapResp
, FALSE
);
165 eapol_set_bool(sm
, EAPOL_eapNoResp
, FALSE
);
171 * This state is reached whenever service from the lower layer is interrupted
172 * or unavailable (portEnabled == FALSE). Immediate transition to INITIALIZE
173 * occurs when the port becomes enabled.
175 SM_STATE(EAP
, DISABLED
)
177 SM_ENTRY(EAP
, DISABLED
);
183 * The state machine spends most of its time here, waiting for something to
184 * happen. This state is entered unconditionally from INITIALIZE, DISCARD, and
185 * SEND_RESPONSE states.
194 * This state is entered when an EAP packet is received (eapReq == TRUE) to
195 * parse the packet header.
197 SM_STATE(EAP
, RECEIVED
)
199 const struct wpabuf
*eapReqData
;
201 SM_ENTRY(EAP
, RECEIVED
);
202 eapReqData
= eapol_get_eapReqData(sm
);
203 /* parse rxReq, rxSuccess, rxFailure, reqId, reqMethod */
204 eap_sm_parseEapReq(sm
, eapReqData
);
210 * This state is entered when a request for a new type comes in. Either the
211 * correct method is started, or a Nak response is built.
213 SM_STATE(EAP
, GET_METHOD
)
218 SM_ENTRY(EAP
, GET_METHOD
);
220 if (sm
->reqMethod
== EAP_TYPE_EXPANDED
)
221 method
= sm
->reqVendorMethod
;
223 method
= sm
->reqMethod
;
225 if (!eap_sm_allowMethod(sm
, sm
->reqVendor
, method
)) {
226 wpa_printf(MSG_DEBUG
, "EAP: vendor %u method %u not allowed",
227 sm
->reqVendor
, method
);
232 * RFC 4137 does not define specific operation for fast
233 * re-authentication (session resumption). The design here is to allow
234 * the previously used method data to be maintained for
235 * re-authentication if the method support session resumption.
236 * Otherwise, the previously used method data is freed and a new method
239 if (sm
->fast_reauth
&&
240 sm
->m
&& sm
->m
->vendor
== sm
->reqVendor
&&
241 sm
->m
->method
== method
&&
242 sm
->m
->has_reauth_data
&&
243 sm
->m
->has_reauth_data(sm
, sm
->eap_method_priv
)) {
244 wpa_printf(MSG_DEBUG
, "EAP: Using previous method data"
245 " for fast re-authentication");
248 eap_deinit_prev_method(sm
, "GET_METHOD");
252 sm
->selectedMethod
= sm
->reqMethod
;
254 sm
->m
= eap_peer_get_eap_method(sm
->reqVendor
, method
);
256 wpa_printf(MSG_DEBUG
, "EAP: Could not find selected method: "
257 "vendor %d method %d",
258 sm
->reqVendor
, method
);
262 wpa_printf(MSG_DEBUG
, "EAP: Initialize selected EAP method: "
263 "vendor %u method %u (%s)",
264 sm
->reqVendor
, method
, sm
->m
->name
);
266 sm
->eap_method_priv
= sm
->m
->init_for_reauth(
267 sm
, sm
->eap_method_priv
);
269 sm
->eap_method_priv
= sm
->m
->init(sm
);
271 if (sm
->eap_method_priv
== NULL
) {
272 struct eap_peer_config
*config
= eap_get_config(sm
);
273 wpa_msg(sm
->msg_ctx
, MSG_INFO
,
274 "EAP: Failed to initialize EAP method: vendor %u "
276 sm
->reqVendor
, method
, sm
->m
->name
);
278 sm
->methodState
= METHOD_NONE
;
279 sm
->selectedMethod
= EAP_TYPE_NONE
;
280 if (sm
->reqMethod
== EAP_TYPE_TLS
&& config
&&
281 (config
->pending_req_pin
||
282 config
->pending_req_passphrase
)) {
284 * Return without generating Nak in order to allow
285 * entering of PIN code or passphrase to retry the
286 * current EAP packet.
288 wpa_printf(MSG_DEBUG
, "EAP: Pending PIN/passphrase "
289 "request - skip Nak");
296 sm
->methodState
= METHOD_INIT
;
297 wpa_msg(sm
->msg_ctx
, MSG_INFO
, WPA_EVENT_EAP_METHOD
298 "EAP vendor %u method %u (%s) selected",
299 sm
->reqVendor
, method
, sm
->m
->name
);
303 wpabuf_free(sm
->eapRespData
);
304 sm
->eapRespData
= NULL
;
305 sm
->eapRespData
= eap_sm_buildNak(sm
, sm
->reqId
);
310 * The method processing happens here. The request from the authenticator is
311 * processed, and an appropriate response packet is built.
313 SM_STATE(EAP
, METHOD
)
315 struct wpabuf
*eapReqData
;
316 struct eap_method_ret ret
;
318 SM_ENTRY(EAP
, METHOD
);
320 wpa_printf(MSG_WARNING
, "EAP::METHOD - method not selected");
324 eapReqData
= eapol_get_eapReqData(sm
);
327 * Get ignore, methodState, decision, allowNotifications, and
328 * eapRespData. RFC 4137 uses three separate method procedure (check,
329 * process, and buildResp) in this state. These have been combined into
330 * a single function call to m->process() in order to optimize EAP
331 * method implementation interface a bit. These procedures are only
332 * used from within this METHOD state, so there is no need to keep
333 * these as separate C functions.
335 * The RFC 4137 procedures return values as follows:
336 * ignore = m.check(eapReqData)
337 * (methodState, decision, allowNotifications) = m.process(eapReqData)
338 * eapRespData = m.buildResp(reqId)
340 os_memset(&ret
, 0, sizeof(ret
));
341 ret
.ignore
= sm
->ignore
;
342 ret
.methodState
= sm
->methodState
;
343 ret
.decision
= sm
->decision
;
344 ret
.allowNotifications
= sm
->allowNotifications
;
345 wpabuf_free(sm
->eapRespData
);
346 sm
->eapRespData
= NULL
;
347 sm
->eapRespData
= sm
->m
->process(sm
, sm
->eap_method_priv
, &ret
,
349 wpa_printf(MSG_DEBUG
, "EAP: method process -> ignore=%s "
350 "methodState=%s decision=%s",
351 ret
.ignore
? "TRUE" : "FALSE",
352 eap_sm_method_state_txt(ret
.methodState
),
353 eap_sm_decision_txt(ret
.decision
));
355 sm
->ignore
= ret
.ignore
;
358 sm
->methodState
= ret
.methodState
;
359 sm
->decision
= ret
.decision
;
360 sm
->allowNotifications
= ret
.allowNotifications
;
362 if (sm
->m
->isKeyAvailable
&& sm
->m
->getKey
&&
363 sm
->m
->isKeyAvailable(sm
, sm
->eap_method_priv
)) {
364 os_free(sm
->eapKeyData
);
365 sm
->eapKeyData
= sm
->m
->getKey(sm
, sm
->eap_method_priv
,
372 * This state signals the lower layer that a response packet is ready to be
375 SM_STATE(EAP
, SEND_RESPONSE
)
377 SM_ENTRY(EAP
, SEND_RESPONSE
);
378 wpabuf_free(sm
->lastRespData
);
379 if (sm
->eapRespData
) {
381 os_memcpy(sm
->last_md5
, sm
->req_md5
, 16);
382 sm
->lastId
= sm
->reqId
;
383 sm
->lastRespData
= wpabuf_dup(sm
->eapRespData
);
384 eapol_set_bool(sm
, EAPOL_eapResp
, TRUE
);
386 sm
->lastRespData
= NULL
;
387 eapol_set_bool(sm
, EAPOL_eapReq
, FALSE
);
388 eapol_set_int(sm
, EAPOL_idleWhile
, sm
->ClientTimeout
);
393 * This state signals the lower layer that the request was discarded, and no
394 * response packet will be sent at this time.
396 SM_STATE(EAP
, DISCARD
)
398 SM_ENTRY(EAP
, DISCARD
);
399 eapol_set_bool(sm
, EAPOL_eapReq
, FALSE
);
400 eapol_set_bool(sm
, EAPOL_eapNoResp
, TRUE
);
405 * Handles requests for Identity method and builds a response.
407 SM_STATE(EAP
, IDENTITY
)
409 const struct wpabuf
*eapReqData
;
411 SM_ENTRY(EAP
, IDENTITY
);
412 eapReqData
= eapol_get_eapReqData(sm
);
413 eap_sm_processIdentity(sm
, eapReqData
);
414 wpabuf_free(sm
->eapRespData
);
415 sm
->eapRespData
= NULL
;
416 sm
->eapRespData
= eap_sm_buildIdentity(sm
, sm
->reqId
, 0);
421 * Handles requests for Notification method and builds a response.
423 SM_STATE(EAP
, NOTIFICATION
)
425 const struct wpabuf
*eapReqData
;
427 SM_ENTRY(EAP
, NOTIFICATION
);
428 eapReqData
= eapol_get_eapReqData(sm
);
429 eap_sm_processNotify(sm
, eapReqData
);
430 wpabuf_free(sm
->eapRespData
);
431 sm
->eapRespData
= NULL
;
432 sm
->eapRespData
= eap_sm_buildNotify(sm
->reqId
);
437 * This state retransmits the previous response packet.
439 SM_STATE(EAP
, RETRANSMIT
)
441 SM_ENTRY(EAP
, RETRANSMIT
);
442 wpabuf_free(sm
->eapRespData
);
443 if (sm
->lastRespData
)
444 sm
->eapRespData
= wpabuf_dup(sm
->lastRespData
);
446 sm
->eapRespData
= NULL
;
451 * This state is entered in case of a successful completion of authentication
452 * and state machine waits here until port is disabled or EAP authentication is
455 SM_STATE(EAP
, SUCCESS
)
457 SM_ENTRY(EAP
, SUCCESS
);
458 if (sm
->eapKeyData
!= NULL
)
459 sm
->eapKeyAvailable
= TRUE
;
460 eapol_set_bool(sm
, EAPOL_eapSuccess
, TRUE
);
463 * RFC 4137 does not clear eapReq here, but this seems to be required
464 * to avoid processing the same request twice when state machine is
467 eapol_set_bool(sm
, EAPOL_eapReq
, FALSE
);
470 * RFC 4137 does not set eapNoResp here, but this seems to be required
471 * to get EAPOL Supplicant backend state machine into SUCCESS state. In
472 * addition, either eapResp or eapNoResp is required to be set after
473 * processing the received EAP frame.
475 eapol_set_bool(sm
, EAPOL_eapNoResp
, TRUE
);
477 wpa_msg(sm
->msg_ctx
, MSG_INFO
, WPA_EVENT_EAP_SUCCESS
478 "EAP authentication completed successfully");
483 * This state is entered in case of a failure and state machine waits here
484 * until port is disabled or EAP authentication is restarted.
486 SM_STATE(EAP
, FAILURE
)
488 SM_ENTRY(EAP
, FAILURE
);
489 eapol_set_bool(sm
, EAPOL_eapFail
, TRUE
);
492 * RFC 4137 does not clear eapReq here, but this seems to be required
493 * to avoid processing the same request twice when state machine is
496 eapol_set_bool(sm
, EAPOL_eapReq
, FALSE
);
499 * RFC 4137 does not set eapNoResp here. However, either eapResp or
500 * eapNoResp is required to be set after processing the received EAP
503 eapol_set_bool(sm
, EAPOL_eapNoResp
, TRUE
);
505 wpa_msg(sm
->msg_ctx
, MSG_INFO
, WPA_EVENT_EAP_FAILURE
506 "EAP authentication failed");
510 static int eap_success_workaround(struct eap_sm
*sm
, int reqId
, int lastId
)
513 * At least Microsoft IAS and Meetinghouse Aegis seem to be sending
514 * EAP-Success/Failure with lastId + 1 even though RFC 3748 and
515 * RFC 4137 require that reqId == lastId. In addition, it looks like
516 * Ringmaster v2.1.2.0 would be using lastId + 2 in EAP-Success.
518 * Accept this kind of Id if EAP workarounds are enabled. These are
519 * unauthenticated plaintext messages, so this should have minimal
520 * security implications (bit easier to fake EAP-Success/Failure).
522 if (sm
->workaround
&& (reqId
== ((lastId
+ 1) & 0xff) ||
523 reqId
== ((lastId
+ 2) & 0xff))) {
524 wpa_printf(MSG_DEBUG
, "EAP: Workaround for unexpected "
525 "identifier field in EAP Success: "
526 "reqId=%d lastId=%d (these are supposed to be "
527 "same)", reqId
, lastId
);
530 wpa_printf(MSG_DEBUG
, "EAP: EAP-Success Id mismatch - reqId=%d "
531 "lastId=%d", reqId
, lastId
);
537 * RFC 4137 - Appendix A.1: EAP Peer State Machine - State transitions
540 static void eap_peer_sm_step_idle(struct eap_sm
*sm
)
543 * The first three transitions are from RFC 4137. The last two are
544 * local additions to handle special cases with LEAP and PEAP server
545 * not sending EAP-Success in some cases.
547 if (eapol_get_bool(sm
, EAPOL_eapReq
))
548 SM_ENTER(EAP
, RECEIVED
);
549 else if ((eapol_get_bool(sm
, EAPOL_altAccept
) &&
550 sm
->decision
!= DECISION_FAIL
) ||
551 (eapol_get_int(sm
, EAPOL_idleWhile
) == 0 &&
552 sm
->decision
== DECISION_UNCOND_SUCC
))
553 SM_ENTER(EAP
, SUCCESS
);
554 else if (eapol_get_bool(sm
, EAPOL_altReject
) ||
555 (eapol_get_int(sm
, EAPOL_idleWhile
) == 0 &&
556 sm
->decision
!= DECISION_UNCOND_SUCC
) ||
557 (eapol_get_bool(sm
, EAPOL_altAccept
) &&
558 sm
->methodState
!= METHOD_CONT
&&
559 sm
->decision
== DECISION_FAIL
))
560 SM_ENTER(EAP
, FAILURE
);
561 else if (sm
->selectedMethod
== EAP_TYPE_LEAP
&&
562 sm
->leap_done
&& sm
->decision
!= DECISION_FAIL
&&
563 sm
->methodState
== METHOD_DONE
)
564 SM_ENTER(EAP
, SUCCESS
);
565 else if (sm
->selectedMethod
== EAP_TYPE_PEAP
&&
566 sm
->peap_done
&& sm
->decision
!= DECISION_FAIL
&&
567 sm
->methodState
== METHOD_DONE
)
568 SM_ENTER(EAP
, SUCCESS
);
572 static int eap_peer_req_is_duplicate(struct eap_sm
*sm
)
576 duplicate
= (sm
->reqId
== sm
->lastId
) && sm
->rxReq
;
577 if (sm
->workaround
&& duplicate
&&
578 os_memcmp(sm
->req_md5
, sm
->last_md5
, 16) != 0) {
580 * RFC 4137 uses (reqId == lastId) as the only verification for
581 * duplicate EAP requests. However, this misses cases where the
582 * AS is incorrectly using the same id again; and
583 * unfortunately, such implementations exist. Use MD5 hash as
584 * an extra verification for the packets being duplicate to
585 * workaround these issues.
587 wpa_printf(MSG_DEBUG
, "EAP: AS used the same Id again, but "
588 "EAP packets were not identical");
589 wpa_printf(MSG_DEBUG
, "EAP: workaround - assume this is not a "
598 static void eap_peer_sm_step_received(struct eap_sm
*sm
)
600 int duplicate
= eap_peer_req_is_duplicate(sm
);
603 * Two special cases below for LEAP are local additions to work around
604 * odd LEAP behavior (EAP-Success in the middle of authentication and
605 * then swapped roles). Other transitions are based on RFC 4137.
607 if (sm
->rxSuccess
&& sm
->decision
!= DECISION_FAIL
&&
608 (sm
->reqId
== sm
->lastId
||
609 eap_success_workaround(sm
, sm
->reqId
, sm
->lastId
)))
610 SM_ENTER(EAP
, SUCCESS
);
611 else if (sm
->methodState
!= METHOD_CONT
&&
613 sm
->decision
!= DECISION_UNCOND_SUCC
) ||
614 (sm
->rxSuccess
&& sm
->decision
== DECISION_FAIL
&&
615 (sm
->selectedMethod
!= EAP_TYPE_LEAP
||
616 sm
->methodState
!= METHOD_MAY_CONT
))) &&
617 (sm
->reqId
== sm
->lastId
||
618 eap_success_workaround(sm
, sm
->reqId
, sm
->lastId
)))
619 SM_ENTER(EAP
, FAILURE
);
620 else if (sm
->rxReq
&& duplicate
)
621 SM_ENTER(EAP
, RETRANSMIT
);
622 else if (sm
->rxReq
&& !duplicate
&&
623 sm
->reqMethod
== EAP_TYPE_NOTIFICATION
&&
624 sm
->allowNotifications
)
625 SM_ENTER(EAP
, NOTIFICATION
);
626 else if (sm
->rxReq
&& !duplicate
&&
627 sm
->selectedMethod
== EAP_TYPE_NONE
&&
628 sm
->reqMethod
== EAP_TYPE_IDENTITY
)
629 SM_ENTER(EAP
, IDENTITY
);
630 else if (sm
->rxReq
&& !duplicate
&&
631 sm
->selectedMethod
== EAP_TYPE_NONE
&&
632 sm
->reqMethod
!= EAP_TYPE_IDENTITY
&&
633 sm
->reqMethod
!= EAP_TYPE_NOTIFICATION
)
634 SM_ENTER(EAP
, GET_METHOD
);
635 else if (sm
->rxReq
&& !duplicate
&&
636 sm
->reqMethod
== sm
->selectedMethod
&&
637 sm
->methodState
!= METHOD_DONE
)
638 SM_ENTER(EAP
, METHOD
);
639 else if (sm
->selectedMethod
== EAP_TYPE_LEAP
&&
640 (sm
->rxSuccess
|| sm
->rxResp
))
641 SM_ENTER(EAP
, METHOD
);
643 SM_ENTER(EAP
, DISCARD
);
647 static void eap_peer_sm_step_local(struct eap_sm
*sm
)
649 switch (sm
->EAP_state
) {
654 if (eapol_get_bool(sm
, EAPOL_portEnabled
) &&
656 SM_ENTER(EAP
, INITIALIZE
);
659 eap_peer_sm_step_idle(sm
);
662 eap_peer_sm_step_received(sm
);
665 if (sm
->selectedMethod
== sm
->reqMethod
)
666 SM_ENTER(EAP
, METHOD
);
668 SM_ENTER(EAP
, SEND_RESPONSE
);
672 SM_ENTER(EAP
, DISCARD
);
674 SM_ENTER(EAP
, SEND_RESPONSE
);
676 case EAP_SEND_RESPONSE
:
683 SM_ENTER(EAP
, SEND_RESPONSE
);
685 case EAP_NOTIFICATION
:
686 SM_ENTER(EAP
, SEND_RESPONSE
);
689 SM_ENTER(EAP
, SEND_RESPONSE
);
701 /* Global transitions */
702 if (eapol_get_bool(sm
, EAPOL_eapRestart
) &&
703 eapol_get_bool(sm
, EAPOL_portEnabled
))
704 SM_ENTER_GLOBAL(EAP
, INITIALIZE
);
705 else if (!eapol_get_bool(sm
, EAPOL_portEnabled
) || sm
->force_disabled
)
706 SM_ENTER_GLOBAL(EAP
, DISABLED
);
707 else if (sm
->num_rounds
> EAP_MAX_AUTH_ROUNDS
) {
708 /* RFC 4137 does not place any limit on number of EAP messages
709 * in an authentication session. However, some error cases have
710 * ended up in a state were EAP messages were sent between the
711 * peer and server in a loop (e.g., TLS ACK frame in both
712 * direction). Since this is quite undesired outcome, limit the
713 * total number of EAP round-trips and abort authentication if
714 * this limit is exceeded.
716 if (sm
->num_rounds
== EAP_MAX_AUTH_ROUNDS
+ 1) {
717 wpa_msg(sm
->msg_ctx
, MSG_INFO
, "EAP: more than %d "
718 "authentication rounds - abort",
719 EAP_MAX_AUTH_ROUNDS
);
721 SM_ENTER_GLOBAL(EAP
, FAILURE
);
724 /* Local transitions */
725 eap_peer_sm_step_local(sm
);
730 static Boolean
eap_sm_allowMethod(struct eap_sm
*sm
, int vendor
,
733 if (!eap_allowed_method(sm
, vendor
, method
)) {
734 wpa_printf(MSG_DEBUG
, "EAP: configuration does not allow: "
735 "vendor %u method %u", vendor
, method
);
738 if (eap_peer_get_eap_method(vendor
, method
))
740 wpa_printf(MSG_DEBUG
, "EAP: not included in build: "
741 "vendor %u method %u", vendor
, method
);
746 static struct wpabuf
* eap_sm_build_expanded_nak(
747 struct eap_sm
*sm
, int id
, const struct eap_method
*methods
,
752 const struct eap_method
*m
;
754 wpa_printf(MSG_DEBUG
, "EAP: Building expanded EAP-Nak");
756 /* RFC 3748 - 5.3.2: Expanded Nak */
757 resp
= eap_msg_alloc(EAP_VENDOR_IETF
, EAP_TYPE_EXPANDED
,
758 8 + 8 * (count
+ 1), EAP_CODE_RESPONSE
, id
);
762 wpabuf_put_be24(resp
, EAP_VENDOR_IETF
);
763 wpabuf_put_be32(resp
, EAP_TYPE_NAK
);
765 for (m
= methods
; m
; m
= m
->next
) {
766 if (sm
->reqVendor
== m
->vendor
&&
767 sm
->reqVendorMethod
== m
->method
)
768 continue; /* do not allow the current method again */
769 if (eap_allowed_method(sm
, m
->vendor
, m
->method
)) {
770 wpa_printf(MSG_DEBUG
, "EAP: allowed type: "
771 "vendor=%u method=%u",
772 m
->vendor
, m
->method
);
773 wpabuf_put_u8(resp
, EAP_TYPE_EXPANDED
);
774 wpabuf_put_be24(resp
, m
->vendor
);
775 wpabuf_put_be32(resp
, m
->method
);
781 wpa_printf(MSG_DEBUG
, "EAP: no more allowed methods");
782 wpabuf_put_u8(resp
, EAP_TYPE_EXPANDED
);
783 wpabuf_put_be24(resp
, EAP_VENDOR_IETF
);
784 wpabuf_put_be32(resp
, EAP_TYPE_NONE
);
787 eap_update_len(resp
);
793 static struct wpabuf
* eap_sm_buildNak(struct eap_sm
*sm
, int id
)
797 int found
= 0, expanded_found
= 0;
799 const struct eap_method
*methods
, *m
;
801 wpa_printf(MSG_DEBUG
, "EAP: Building EAP-Nak (requested type %u "
802 "vendor=%u method=%u not allowed)", sm
->reqMethod
,
803 sm
->reqVendor
, sm
->reqVendorMethod
);
804 methods
= eap_peer_get_methods(&count
);
807 if (sm
->reqMethod
== EAP_TYPE_EXPANDED
)
808 return eap_sm_build_expanded_nak(sm
, id
, methods
, count
);
810 /* RFC 3748 - 5.3.1: Legacy Nak */
811 resp
= eap_msg_alloc(EAP_VENDOR_IETF
, EAP_TYPE_NAK
,
812 sizeof(struct eap_hdr
) + 1 + count
+ 1,
813 EAP_CODE_RESPONSE
, id
);
817 start
= wpabuf_put(resp
, 0);
818 for (m
= methods
; m
; m
= m
->next
) {
819 if (m
->vendor
== EAP_VENDOR_IETF
&& m
->method
== sm
->reqMethod
)
820 continue; /* do not allow the current method again */
821 if (eap_allowed_method(sm
, m
->vendor
, m
->method
)) {
822 if (m
->vendor
!= EAP_VENDOR_IETF
) {
826 wpabuf_put_u8(resp
, EAP_TYPE_EXPANDED
);
828 wpabuf_put_u8(resp
, m
->method
);
833 wpabuf_put_u8(resp
, EAP_TYPE_NONE
);
834 wpa_hexdump(MSG_DEBUG
, "EAP: allowed methods", start
, found
);
836 eap_update_len(resp
);
842 static void eap_sm_processIdentity(struct eap_sm
*sm
, const struct wpabuf
*req
)
844 const struct eap_hdr
*hdr
= wpabuf_head(req
);
845 const u8
*pos
= (const u8
*) (hdr
+ 1);
848 wpa_msg(sm
->msg_ctx
, MSG_INFO
, WPA_EVENT_EAP_STARTED
849 "EAP authentication started");
852 * RFC 3748 - 5.1: Identity
853 * Data field may contain a displayable message in UTF-8. If this
854 * includes NUL-character, only the data before that should be
855 * displayed. Some EAP implementasitons may piggy-back additional
856 * options after the NUL.
858 /* TODO: could save displayable message so that it can be shown to the
859 * user in case of interaction is required */
860 wpa_hexdump_ascii(MSG_DEBUG
, "EAP: EAP-Request Identity data",
861 pos
, be_to_host16(hdr
->length
) - 5);
866 static int eap_sm_imsi_identity(struct eap_sm
*sm
,
867 struct eap_peer_config
*conf
)
872 struct eap_method_type
*m
= conf
->eap_methods
;
875 imsi_len
= sizeof(imsi
);
876 if (scard_get_imsi(sm
->scard_ctx
, imsi
, &imsi_len
)) {
877 wpa_printf(MSG_WARNING
, "Failed to get IMSI from SIM");
881 wpa_hexdump_ascii(MSG_DEBUG
, "IMSI", (u8
*) imsi
, imsi_len
);
883 for (i
= 0; m
&& (m
[i
].vendor
!= EAP_VENDOR_IETF
||
884 m
[i
].method
!= EAP_TYPE_NONE
); i
++) {
885 if (m
[i
].vendor
== EAP_VENDOR_IETF
&&
886 m
[i
].method
== EAP_TYPE_AKA
) {
892 os_free(conf
->identity
);
893 conf
->identity
= os_malloc(1 + imsi_len
);
894 if (conf
->identity
== NULL
) {
895 wpa_printf(MSG_WARNING
, "Failed to allocate buffer for "
896 "IMSI-based identity");
900 conf
->identity
[0] = aka
? '0' : '1';
901 os_memcpy(conf
->identity
+ 1, imsi
, imsi_len
);
902 conf
->identity_len
= 1 + imsi_len
;
906 #endif /* PCSC_FUNCS */
909 static int eap_sm_get_scard_identity(struct eap_sm
*sm
,
910 struct eap_peer_config
*conf
)
913 if (scard_set_pin(sm
->scard_ctx
, conf
->pin
)) {
915 * Make sure the same PIN is not tried again in order to avoid
921 wpa_printf(MSG_WARNING
, "PIN validation failed");
922 eap_sm_request_pin(sm
);
926 return eap_sm_imsi_identity(sm
, conf
);
927 #else /* PCSC_FUNCS */
929 #endif /* PCSC_FUNCS */
934 * eap_sm_buildIdentity - Build EAP-Identity/Response for the current network
935 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
936 * @id: EAP identifier for the packet
937 * @encrypted: Whether the packet is for encrypted tunnel (EAP phase 2)
938 * Returns: Pointer to the allocated EAP-Identity/Response packet or %NULL on
941 * This function allocates and builds an EAP-Identity/Response packet for the
942 * current network. The caller is responsible for freeing the returned data.
944 struct wpabuf
* eap_sm_buildIdentity(struct eap_sm
*sm
, int id
, int encrypted
)
946 struct eap_peer_config
*config
= eap_get_config(sm
);
951 if (config
== NULL
) {
952 wpa_printf(MSG_WARNING
, "EAP: buildIdentity: configuration "
953 "was not available");
957 if (sm
->m
&& sm
->m
->get_identity
&&
958 (identity
= sm
->m
->get_identity(sm
, sm
->eap_method_priv
,
959 &identity_len
)) != NULL
) {
960 wpa_hexdump_ascii(MSG_DEBUG
, "EAP: using method re-auth "
961 "identity", identity
, identity_len
);
962 } else if (!encrypted
&& config
->anonymous_identity
) {
963 identity
= config
->anonymous_identity
;
964 identity_len
= config
->anonymous_identity_len
;
965 wpa_hexdump_ascii(MSG_DEBUG
, "EAP: using anonymous identity",
966 identity
, identity_len
);
968 identity
= config
->identity
;
969 identity_len
= config
->identity_len
;
970 wpa_hexdump_ascii(MSG_DEBUG
, "EAP: using real identity",
971 identity
, identity_len
);
974 if (identity
== NULL
) {
975 wpa_printf(MSG_WARNING
, "EAP: buildIdentity: identity "
976 "configuration was not available");
978 if (eap_sm_get_scard_identity(sm
, config
) < 0)
980 identity
= config
->identity
;
981 identity_len
= config
->identity_len
;
982 wpa_hexdump_ascii(MSG_DEBUG
, "permanent identity from "
983 "IMSI", identity
, identity_len
);
985 eap_sm_request_identity(sm
);
990 resp
= eap_msg_alloc(EAP_VENDOR_IETF
, EAP_TYPE_IDENTITY
, identity_len
,
991 EAP_CODE_RESPONSE
, id
);
995 wpabuf_put_data(resp
, identity
, identity_len
);
1001 static void eap_sm_processNotify(struct eap_sm
*sm
, const struct wpabuf
*req
)
1007 pos
= eap_hdr_validate(EAP_VENDOR_IETF
, EAP_TYPE_NOTIFICATION
, req
,
1011 wpa_hexdump_ascii(MSG_DEBUG
, "EAP: EAP-Request Notification data",
1014 msg
= os_malloc(msg_len
+ 1);
1017 for (i
= 0; i
< msg_len
; i
++)
1018 msg
[i
] = isprint(pos
[i
]) ? (char) pos
[i
] : '_';
1019 msg
[msg_len
] = '\0';
1020 wpa_msg(sm
->msg_ctx
, MSG_INFO
, "%s%s",
1021 WPA_EVENT_EAP_NOTIFICATION
, msg
);
1026 static struct wpabuf
* eap_sm_buildNotify(int id
)
1028 struct wpabuf
*resp
;
1030 wpa_printf(MSG_DEBUG
, "EAP: Generating EAP-Response Notification");
1031 resp
= eap_msg_alloc(EAP_VENDOR_IETF
, EAP_TYPE_NOTIFICATION
, 0,
1032 EAP_CODE_RESPONSE
, id
);
1040 static void eap_sm_parseEapReq(struct eap_sm
*sm
, const struct wpabuf
*req
)
1042 const struct eap_hdr
*hdr
;
1046 sm
->rxReq
= sm
->rxResp
= sm
->rxSuccess
= sm
->rxFailure
= FALSE
;
1048 sm
->reqMethod
= EAP_TYPE_NONE
;
1049 sm
->reqVendor
= EAP_VENDOR_IETF
;
1050 sm
->reqVendorMethod
= EAP_TYPE_NONE
;
1052 if (req
== NULL
|| wpabuf_len(req
) < sizeof(*hdr
))
1055 hdr
= wpabuf_head(req
);
1056 plen
= be_to_host16(hdr
->length
);
1057 if (plen
> wpabuf_len(req
)) {
1058 wpa_printf(MSG_DEBUG
, "EAP: Ignored truncated EAP-Packet "
1059 "(len=%lu plen=%lu)",
1060 (unsigned long) wpabuf_len(req
),
1061 (unsigned long) plen
);
1065 sm
->reqId
= hdr
->identifier
;
1067 if (sm
->workaround
) {
1069 addr
[0] = wpabuf_head(req
);
1070 md5_vector(1, addr
, &plen
, sm
->req_md5
);
1073 switch (hdr
->code
) {
1074 case EAP_CODE_REQUEST
:
1075 if (plen
< sizeof(*hdr
) + 1) {
1076 wpa_printf(MSG_DEBUG
, "EAP: Too short EAP-Request - "
1081 pos
= (const u8
*) (hdr
+ 1);
1082 sm
->reqMethod
= *pos
++;
1083 if (sm
->reqMethod
== EAP_TYPE_EXPANDED
) {
1084 if (plen
< sizeof(*hdr
) + 8) {
1085 wpa_printf(MSG_DEBUG
, "EAP: Ignored truncated "
1086 "expanded EAP-Packet (plen=%lu)",
1087 (unsigned long) plen
);
1090 sm
->reqVendor
= WPA_GET_BE24(pos
);
1092 sm
->reqVendorMethod
= WPA_GET_BE32(pos
);
1094 wpa_printf(MSG_DEBUG
, "EAP: Received EAP-Request id=%d "
1095 "method=%u vendor=%u vendorMethod=%u",
1096 sm
->reqId
, sm
->reqMethod
, sm
->reqVendor
,
1097 sm
->reqVendorMethod
);
1099 case EAP_CODE_RESPONSE
:
1100 if (sm
->selectedMethod
== EAP_TYPE_LEAP
) {
1102 * LEAP differs from RFC 4137 by using reversed roles
1103 * for mutual authentication and because of this, we
1104 * need to accept EAP-Response frames if LEAP is used.
1106 if (plen
< sizeof(*hdr
) + 1) {
1107 wpa_printf(MSG_DEBUG
, "EAP: Too short "
1108 "EAP-Response - no Type field");
1112 pos
= (const u8
*) (hdr
+ 1);
1113 sm
->reqMethod
= *pos
;
1114 wpa_printf(MSG_DEBUG
, "EAP: Received EAP-Response for "
1115 "LEAP method=%d id=%d",
1116 sm
->reqMethod
, sm
->reqId
);
1119 wpa_printf(MSG_DEBUG
, "EAP: Ignored EAP-Response");
1121 case EAP_CODE_SUCCESS
:
1122 wpa_printf(MSG_DEBUG
, "EAP: Received EAP-Success");
1123 sm
->rxSuccess
= TRUE
;
1125 case EAP_CODE_FAILURE
:
1126 wpa_printf(MSG_DEBUG
, "EAP: Received EAP-Failure");
1127 sm
->rxFailure
= TRUE
;
1130 wpa_printf(MSG_DEBUG
, "EAP: Ignored EAP-Packet with unknown "
1131 "code %d", hdr
->code
);
1138 * eap_peer_sm_init - Allocate and initialize EAP peer state machine
1139 * @eapol_ctx: Context data to be used with eapol_cb calls
1140 * @eapol_cb: Pointer to EAPOL callback functions
1141 * @msg_ctx: Context data for wpa_msg() calls
1142 * @conf: EAP configuration
1143 * Returns: Pointer to the allocated EAP state machine or %NULL on failure
1145 * This function allocates and initializes an EAP state machine. In addition,
1146 * this initializes TLS library for the new EAP state machine. eapol_cb pointer
1147 * will be in use until eap_peer_sm_deinit() is used to deinitialize this EAP
1148 * state machine. Consequently, the caller must make sure that this data
1149 * structure remains alive while the EAP state machine is active.
1151 struct eap_sm
* eap_peer_sm_init(void *eapol_ctx
,
1152 struct eapol_callbacks
*eapol_cb
,
1153 void *msg_ctx
, struct eap_config
*conf
)
1156 struct tls_config tlsconf
;
1158 sm
= os_zalloc(sizeof(*sm
));
1161 sm
->eapol_ctx
= eapol_ctx
;
1162 sm
->eapol_cb
= eapol_cb
;
1163 sm
->msg_ctx
= msg_ctx
;
1164 sm
->ClientTimeout
= 60;
1166 os_memcpy(sm
->mac_addr
, conf
->mac_addr
, ETH_ALEN
);
1168 os_memset(&tlsconf
, 0, sizeof(tlsconf
));
1169 tlsconf
.opensc_engine_path
= conf
->opensc_engine_path
;
1170 tlsconf
.pkcs11_engine_path
= conf
->pkcs11_engine_path
;
1171 tlsconf
.pkcs11_module_path
= conf
->pkcs11_module_path
;
1172 sm
->ssl_ctx
= tls_init(&tlsconf
);
1173 if (sm
->ssl_ctx
== NULL
) {
1174 wpa_printf(MSG_WARNING
, "SSL: Failed to initialize TLS "
1185 * eap_peer_sm_deinit - Deinitialize and free an EAP peer state machine
1186 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
1188 * This function deinitializes EAP state machine and frees all allocated
1191 void eap_peer_sm_deinit(struct eap_sm
*sm
)
1195 eap_deinit_prev_method(sm
, "EAP deinit");
1197 tls_deinit(sm
->ssl_ctx
);
1203 * eap_peer_sm_step - Step EAP peer state machine
1204 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
1205 * Returns: 1 if EAP state was changed or 0 if not
1207 * This function advances EAP state machine to a new state to match with the
1208 * current variables. This should be called whenever variables used by the EAP
1209 * state machine have changed.
1211 int eap_peer_sm_step(struct eap_sm
*sm
)
1215 sm
->changed
= FALSE
;
1219 } while (sm
->changed
);
1225 * eap_sm_abort - Abort EAP authentication
1226 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
1228 * Release system resources that have been allocated for the authentication
1229 * session without fully deinitializing the EAP state machine.
1231 void eap_sm_abort(struct eap_sm
*sm
)
1233 wpabuf_free(sm
->lastRespData
);
1234 sm
->lastRespData
= NULL
;
1235 wpabuf_free(sm
->eapRespData
);
1236 sm
->eapRespData
= NULL
;
1237 os_free(sm
->eapKeyData
);
1238 sm
->eapKeyData
= NULL
;
1240 /* This is not clearly specified in the EAP statemachines draft, but
1241 * it seems necessary to make sure that some of the EAPOL variables get
1242 * cleared for the next authentication. */
1243 eapol_set_bool(sm
, EAPOL_eapSuccess
, FALSE
);
1247 #ifdef CONFIG_CTRL_IFACE
1248 static const char * eap_sm_state_txt(int state
)
1251 case EAP_INITIALIZE
:
1252 return "INITIALIZE";
1259 case EAP_GET_METHOD
:
1260 return "GET_METHOD";
1263 case EAP_SEND_RESPONSE
:
1264 return "SEND_RESPONSE";
1269 case EAP_NOTIFICATION
:
1270 return "NOTIFICATION";
1271 case EAP_RETRANSMIT
:
1272 return "RETRANSMIT";
1281 #endif /* CONFIG_CTRL_IFACE */
1284 #if defined(CONFIG_CTRL_IFACE) || !defined(CONFIG_NO_STDOUT_DEBUG)
1285 static const char * eap_sm_method_state_txt(EapMethodState state
)
1294 case METHOD_MAY_CONT
:
1304 static const char * eap_sm_decision_txt(EapDecision decision
)
1309 case DECISION_COND_SUCC
:
1311 case DECISION_UNCOND_SUCC
:
1312 return "UNCOND_SUCC";
1317 #endif /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */
1320 #ifdef CONFIG_CTRL_IFACE
1323 * eap_sm_get_status - Get EAP state machine status
1324 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
1325 * @buf: Buffer for status information
1326 * @buflen: Maximum buffer length
1327 * @verbose: Whether to include verbose status information
1328 * Returns: Number of bytes written to buf.
1330 * Query EAP state machine for status information. This function fills in a
1331 * text area with current status information from the EAPOL state machine. If
1332 * the buffer (buf) is not large enough, status information will be truncated
1333 * to fit the buffer.
1335 int eap_sm_get_status(struct eap_sm
*sm
, char *buf
, size_t buflen
, int verbose
)
1342 len
= os_snprintf(buf
, buflen
,
1344 eap_sm_state_txt(sm
->EAP_state
));
1345 if (len
< 0 || (size_t) len
>= buflen
)
1348 if (sm
->selectedMethod
!= EAP_TYPE_NONE
) {
1353 const struct eap_method
*m
=
1354 eap_peer_get_eap_method(EAP_VENDOR_IETF
,
1355 sm
->selectedMethod
);
1361 ret
= os_snprintf(buf
+ len
, buflen
- len
,
1362 "selectedMethod=%d (EAP-%s)\n",
1363 sm
->selectedMethod
, name
);
1364 if (ret
< 0 || (size_t) ret
>= buflen
- len
)
1368 if (sm
->m
&& sm
->m
->get_status
) {
1369 len
+= sm
->m
->get_status(sm
, sm
->eap_method_priv
,
1370 buf
+ len
, buflen
- len
,
1376 ret
= os_snprintf(buf
+ len
, buflen
- len
,
1380 "ClientTimeout=%d\n",
1382 eap_sm_method_state_txt(sm
->methodState
),
1383 eap_sm_decision_txt(sm
->decision
),
1385 if (ret
< 0 || (size_t) ret
>= buflen
- len
)
1392 #endif /* CONFIG_CTRL_IFACE */
1395 #if defined(CONFIG_CTRL_IFACE) || !defined(CONFIG_NO_STDOUT_DEBUG)
1397 TYPE_IDENTITY
, TYPE_PASSWORD
, TYPE_OTP
, TYPE_PIN
, TYPE_NEW_PASSWORD
,
1399 } eap_ctrl_req_type
;
1401 static void eap_sm_request(struct eap_sm
*sm
, eap_ctrl_req_type type
,
1402 const char *msg
, size_t msglen
)
1404 struct eap_peer_config
*config
;
1405 char *field
, *txt
, *tmp
;
1409 config
= eap_get_config(sm
);
1417 config
->pending_req_identity
++;
1422 config
->pending_req_password
++;
1424 case TYPE_NEW_PASSWORD
:
1425 field
= "NEW_PASSWORD";
1426 txt
= "New Password";
1427 config
->pending_req_new_password
++;
1432 config
->pending_req_pin
++;
1437 tmp
= os_malloc(msglen
+ 3);
1441 os_memcpy(tmp
+ 1, msg
, msglen
);
1442 tmp
[msglen
+ 1] = ']';
1443 tmp
[msglen
+ 2] = '\0';
1445 os_free(config
->pending_req_otp
);
1446 config
->pending_req_otp
= tmp
;
1447 config
->pending_req_otp_len
= msglen
+ 3;
1449 if (config
->pending_req_otp
== NULL
)
1451 txt
= config
->pending_req_otp
;
1454 case TYPE_PASSPHRASE
:
1455 field
= "PASSPHRASE";
1456 txt
= "Private key passphrase";
1457 config
->pending_req_passphrase
++;
1463 if (sm
->eapol_cb
->eap_param_needed
)
1464 sm
->eapol_cb
->eap_param_needed(sm
->eapol_ctx
, field
, txt
);
1466 #else /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */
1467 #define eap_sm_request(sm, type, msg, msglen) do { } while (0)
1468 #endif /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */
1472 * eap_sm_request_identity - Request identity from user (ctrl_iface)
1473 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
1475 * EAP methods can call this function to request identity information for the
1476 * current network. This is normally called when the identity is not included
1477 * in the network configuration. The request will be sent to monitor programs
1478 * through the control interface.
1480 void eap_sm_request_identity(struct eap_sm
*sm
)
1482 eap_sm_request(sm
, TYPE_IDENTITY
, NULL
, 0);
1487 * eap_sm_request_password - Request password from user (ctrl_iface)
1488 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
1490 * EAP methods can call this function to request password information for the
1491 * current network. This is normally called when the password is not included
1492 * in the network configuration. The request will be sent to monitor programs
1493 * through the control interface.
1495 void eap_sm_request_password(struct eap_sm
*sm
)
1497 eap_sm_request(sm
, TYPE_PASSWORD
, NULL
, 0);
1502 * eap_sm_request_new_password - Request new password from user (ctrl_iface)
1503 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
1505 * EAP methods can call this function to request new password information for
1506 * the current network. This is normally called when the EAP method indicates
1507 * that the current password has expired and password change is required. The
1508 * request will be sent to monitor programs through the control interface.
1510 void eap_sm_request_new_password(struct eap_sm
*sm
)
1512 eap_sm_request(sm
, TYPE_NEW_PASSWORD
, NULL
, 0);
1517 * eap_sm_request_pin - Request SIM or smart card PIN from user (ctrl_iface)
1518 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
1520 * EAP methods can call this function to request SIM or smart card PIN
1521 * information for the current network. This is normally called when the PIN is
1522 * not included in the network configuration. The request will be sent to
1523 * monitor programs through the control interface.
1525 void eap_sm_request_pin(struct eap_sm
*sm
)
1527 eap_sm_request(sm
, TYPE_PIN
, NULL
, 0);
1532 * eap_sm_request_otp - Request one time password from user (ctrl_iface)
1533 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
1534 * @msg: Message to be displayed to the user when asking for OTP
1535 * @msg_len: Length of the user displayable message
1537 * EAP methods can call this function to request open time password (OTP) for
1538 * the current network. The request will be sent to monitor programs through
1539 * the control interface.
1541 void eap_sm_request_otp(struct eap_sm
*sm
, const char *msg
, size_t msg_len
)
1543 eap_sm_request(sm
, TYPE_OTP
, msg
, msg_len
);
1548 * eap_sm_request_passphrase - Request passphrase from user (ctrl_iface)
1549 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
1551 * EAP methods can call this function to request passphrase for a private key
1552 * for the current network. This is normally called when the passphrase is not
1553 * included in the network configuration. The request will be sent to monitor
1554 * programs through the control interface.
1556 void eap_sm_request_passphrase(struct eap_sm
*sm
)
1558 eap_sm_request(sm
, TYPE_PASSPHRASE
, NULL
, 0);
1563 * eap_sm_notify_ctrl_attached - Notification of attached monitor
1564 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
1566 * Notify EAP state machines that a monitor was attached to the control
1567 * interface to trigger re-sending of pending requests for user input.
1569 void eap_sm_notify_ctrl_attached(struct eap_sm
*sm
)
1571 struct eap_peer_config
*config
= eap_get_config(sm
);
1576 /* Re-send any pending requests for user data since a new control
1577 * interface was added. This handles cases where the EAP authentication
1578 * starts immediately after system startup when the user interface is
1579 * not yet running. */
1580 if (config
->pending_req_identity
)
1581 eap_sm_request_identity(sm
);
1582 if (config
->pending_req_password
)
1583 eap_sm_request_password(sm
);
1584 if (config
->pending_req_new_password
)
1585 eap_sm_request_new_password(sm
);
1586 if (config
->pending_req_otp
)
1587 eap_sm_request_otp(sm
, NULL
, 0);
1588 if (config
->pending_req_pin
)
1589 eap_sm_request_pin(sm
);
1590 if (config
->pending_req_passphrase
)
1591 eap_sm_request_passphrase(sm
);
1595 static int eap_allowed_phase2_type(int vendor
, int type
)
1597 if (vendor
!= EAP_VENDOR_IETF
)
1599 return type
!= EAP_TYPE_PEAP
&& type
!= EAP_TYPE_TTLS
&&
1600 type
!= EAP_TYPE_FAST
;
1605 * eap_get_phase2_type - Get EAP type for the given EAP phase 2 method name
1606 * @name: EAP method name, e.g., MD5
1607 * @vendor: Buffer for returning EAP Vendor-Id
1608 * Returns: EAP method type or %EAP_TYPE_NONE if not found
1610 * This function maps EAP type names into EAP type numbers that are allowed for
1611 * Phase 2, i.e., for tunneled authentication. Phase 2 is used, e.g., with
1612 * EAP-PEAP, EAP-TTLS, and EAP-FAST.
1614 u32
eap_get_phase2_type(const char *name
, int *vendor
)
1617 u8 type
= eap_peer_get_type(name
, &v
);
1618 if (eap_allowed_phase2_type(v
, type
)) {
1622 *vendor
= EAP_VENDOR_IETF
;
1623 return EAP_TYPE_NONE
;
1628 * eap_get_phase2_types - Get list of allowed EAP phase 2 types
1629 * @config: Pointer to a network configuration
1630 * @count: Pointer to a variable to be filled with number of returned EAP types
1631 * Returns: Pointer to allocated type list or %NULL on failure
1633 * This function generates an array of allowed EAP phase 2 (tunneled) types for
1634 * the given network configuration.
1636 struct eap_method_type
* eap_get_phase2_types(struct eap_peer_config
*config
,
1639 struct eap_method_type
*buf
;
1643 const struct eap_method
*methods
, *m
;
1645 methods
= eap_peer_get_methods(&mcount
);
1646 if (methods
== NULL
)
1649 buf
= os_malloc(mcount
* sizeof(struct eap_method_type
));
1653 for (m
= methods
; m
; m
= m
->next
) {
1656 if (eap_allowed_phase2_type(vendor
, method
)) {
1657 if (vendor
== EAP_VENDOR_IETF
&&
1658 method
== EAP_TYPE_TLS
&& config
&&
1659 config
->private_key2
== NULL
)
1661 buf
[*count
].vendor
= vendor
;
1662 buf
[*count
].method
= method
;
1672 * eap_set_fast_reauth - Update fast_reauth setting
1673 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
1674 * @enabled: 1 = Fast reauthentication is enabled, 0 = Disabled
1676 void eap_set_fast_reauth(struct eap_sm
*sm
, int enabled
)
1678 sm
->fast_reauth
= enabled
;
1683 * eap_set_workaround - Update EAP workarounds setting
1684 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
1685 * @workaround: 1 = Enable EAP workarounds, 0 = Disable EAP workarounds
1687 void eap_set_workaround(struct eap_sm
*sm
, unsigned int workaround
)
1689 sm
->workaround
= workaround
;
1694 * eap_get_config - Get current network configuration
1695 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
1696 * Returns: Pointer to the current network configuration or %NULL if not found
1698 * EAP peer methods should avoid using this function if they can use other
1699 * access functions, like eap_get_config_identity() and
1700 * eap_get_config_password(), that do not require direct access to
1701 * struct eap_peer_config.
1703 struct eap_peer_config
* eap_get_config(struct eap_sm
*sm
)
1705 return sm
->eapol_cb
->get_config(sm
->eapol_ctx
);
1710 * eap_get_config_identity - Get identity from the network configuration
1711 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
1712 * @len: Buffer for the length of the identity
1713 * Returns: Pointer to the identity or %NULL if not found
1715 const u8
* eap_get_config_identity(struct eap_sm
*sm
, size_t *len
)
1717 struct eap_peer_config
*config
= eap_get_config(sm
);
1720 *len
= config
->identity_len
;
1721 return config
->identity
;
1726 * eap_get_config_password - Get password from the network configuration
1727 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
1728 * @len: Buffer for the length of the password
1729 * Returns: Pointer to the password or %NULL if not found
1731 const u8
* eap_get_config_password(struct eap_sm
*sm
, size_t *len
)
1733 struct eap_peer_config
*config
= eap_get_config(sm
);
1736 *len
= config
->password_len
;
1737 return config
->password
;
1742 * eap_get_config_password2 - Get password from the network configuration
1743 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
1744 * @len: Buffer for the length of the password
1745 * @hash: Buffer for returning whether the password is stored as a
1746 * NtPasswordHash instead of plaintext password; can be %NULL if this
1747 * information is not needed
1748 * Returns: Pointer to the password or %NULL if not found
1750 const u8
* eap_get_config_password2(struct eap_sm
*sm
, size_t *len
, int *hash
)
1752 struct eap_peer_config
*config
= eap_get_config(sm
);
1755 *len
= config
->password_len
;
1757 *hash
= !!(config
->flags
& EAP_CONFIG_FLAGS_PASSWORD_NTHASH
);
1758 return config
->password
;
1763 * eap_get_config_new_password - Get new password from network configuration
1764 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
1765 * @len: Buffer for the length of the new password
1766 * Returns: Pointer to the new password or %NULL if not found
1768 const u8
* eap_get_config_new_password(struct eap_sm
*sm
, size_t *len
)
1770 struct eap_peer_config
*config
= eap_get_config(sm
);
1773 *len
= config
->new_password_len
;
1774 return config
->new_password
;
1779 * eap_get_config_otp - Get one-time password from the network configuration
1780 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
1781 * @len: Buffer for the length of the one-time password
1782 * Returns: Pointer to the one-time password or %NULL if not found
1784 const u8
* eap_get_config_otp(struct eap_sm
*sm
, size_t *len
)
1786 struct eap_peer_config
*config
= eap_get_config(sm
);
1789 *len
= config
->otp_len
;
1795 * eap_clear_config_otp - Clear used one-time password
1796 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
1798 * This function clears a used one-time password (OTP) from the current network
1799 * configuration. This should be called when the OTP has been used and is not
1802 void eap_clear_config_otp(struct eap_sm
*sm
)
1804 struct eap_peer_config
*config
= eap_get_config(sm
);
1807 os_memset(config
->otp
, 0, config
->otp_len
);
1808 os_free(config
->otp
);
1810 config
->otp_len
= 0;
1815 * eap_get_config_phase1 - Get phase1 data from the network configuration
1816 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
1817 * Returns: Pointer to the phase1 data or %NULL if not found
1819 const char * eap_get_config_phase1(struct eap_sm
*sm
)
1821 struct eap_peer_config
*config
= eap_get_config(sm
);
1824 return config
->phase1
;
1829 * eap_get_config_phase2 - Get phase2 data from the network configuration
1830 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
1831 * Returns: Pointer to the phase1 data or %NULL if not found
1833 const char * eap_get_config_phase2(struct eap_sm
*sm
)
1835 struct eap_peer_config
*config
= eap_get_config(sm
);
1838 return config
->phase2
;
1843 * eap_key_available - Get key availability (eapKeyAvailable variable)
1844 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
1845 * Returns: 1 if EAP keying material is available, 0 if not
1847 int eap_key_available(struct eap_sm
*sm
)
1849 return sm
? sm
->eapKeyAvailable
: 0;
1854 * eap_notify_success - Notify EAP state machine about external success trigger
1855 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
1857 * This function is called when external event, e.g., successful completion of
1858 * WPA-PSK key handshake, is indicating that EAP state machine should move to
1859 * success state. This is mainly used with security modes that do not use EAP
1860 * state machine (e.g., WPA-PSK).
1862 void eap_notify_success(struct eap_sm
*sm
)
1865 sm
->decision
= DECISION_COND_SUCC
;
1866 sm
->EAP_state
= EAP_SUCCESS
;
1872 * eap_notify_lower_layer_success - Notification of lower layer success
1873 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
1875 * Notify EAP state machines that a lower layer has detected a successful
1876 * authentication. This is used to recover from dropped EAP-Success messages.
1878 void eap_notify_lower_layer_success(struct eap_sm
*sm
)
1883 if (eapol_get_bool(sm
, EAPOL_eapSuccess
) ||
1884 sm
->decision
== DECISION_FAIL
||
1885 (sm
->methodState
!= METHOD_MAY_CONT
&&
1886 sm
->methodState
!= METHOD_DONE
))
1889 if (sm
->eapKeyData
!= NULL
)
1890 sm
->eapKeyAvailable
= TRUE
;
1891 eapol_set_bool(sm
, EAPOL_eapSuccess
, TRUE
);
1892 wpa_msg(sm
->msg_ctx
, MSG_INFO
, WPA_EVENT_EAP_SUCCESS
1893 "EAP authentication completed successfully (based on lower "
1899 * eap_get_eapKeyData - Get master session key (MSK) from EAP state machine
1900 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
1901 * @len: Pointer to variable that will be set to number of bytes in the key
1902 * Returns: Pointer to the EAP keying data or %NULL on failure
1904 * Fetch EAP keying material (MSK, eapKeyData) from the EAP state machine. The
1905 * key is available only after a successful authentication. EAP state machine
1906 * continues to manage the key data and the caller must not change or free the
1909 const u8
* eap_get_eapKeyData(struct eap_sm
*sm
, size_t *len
)
1911 if (sm
== NULL
|| sm
->eapKeyData
== NULL
) {
1916 *len
= sm
->eapKeyDataLen
;
1917 return sm
->eapKeyData
;
1922 * eap_get_eapKeyData - Get EAP response data
1923 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
1924 * Returns: Pointer to the EAP response (eapRespData) or %NULL on failure
1926 * Fetch EAP response (eapRespData) from the EAP state machine. This data is
1927 * available when EAP state machine has processed an incoming EAP request. The
1928 * EAP state machine does not maintain a reference to the response after this
1929 * function is called and the caller is responsible for freeing the data.
1931 struct wpabuf
* eap_get_eapRespData(struct eap_sm
*sm
)
1933 struct wpabuf
*resp
;
1935 if (sm
== NULL
|| sm
->eapRespData
== NULL
)
1938 resp
= sm
->eapRespData
;
1939 sm
->eapRespData
= NULL
;
1946 * eap_sm_register_scard_ctx - Notification of smart card context
1947 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
1948 * @ctx: Context data for smart card operations
1950 * Notify EAP state machines of context data for smart card operations. This
1951 * context data will be used as a parameter for scard_*() functions.
1953 void eap_register_scard_ctx(struct eap_sm
*sm
, void *ctx
)
1956 sm
->scard_ctx
= ctx
;
1961 * eap_set_config_blob - Set or add a named configuration blob
1962 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
1963 * @blob: New value for the blob
1965 * Adds a new configuration blob or replaces the current value of an existing
1968 void eap_set_config_blob(struct eap_sm
*sm
, struct wpa_config_blob
*blob
)
1970 #ifndef CONFIG_NO_CONFIG_BLOBS
1971 sm
->eapol_cb
->set_config_blob(sm
->eapol_ctx
, blob
);
1972 #endif /* CONFIG_NO_CONFIG_BLOBS */
1977 * eap_get_config_blob - Get a named configuration blob
1978 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
1979 * @name: Name of the blob
1980 * Returns: Pointer to blob data or %NULL if not found
1982 const struct wpa_config_blob
* eap_get_config_blob(struct eap_sm
*sm
,
1985 #ifndef CONFIG_NO_CONFIG_BLOBS
1986 return sm
->eapol_cb
->get_config_blob(sm
->eapol_ctx
, name
);
1987 #else /* CONFIG_NO_CONFIG_BLOBS */
1989 #endif /* CONFIG_NO_CONFIG_BLOBS */
1994 * eap_set_force_disabled - Set force_disabled flag
1995 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
1996 * @disabled: 1 = EAP disabled, 0 = EAP enabled
1998 * This function is used to force EAP state machine to be disabled when it is
1999 * not in use (e.g., with WPA-PSK or plaintext connections).
2001 void eap_set_force_disabled(struct eap_sm
*sm
, int disabled
)
2003 sm
->force_disabled
= disabled
;
2008 * eap_notify_pending - Notify that EAP method is ready to re-process a request
2009 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
2011 * An EAP method can perform a pending operation (e.g., to get a response from
2012 * an external process). Once the response is available, this function can be
2013 * used to request EAPOL state machine to retry delivering the previously
2014 * received (and still unanswered) EAP request to EAP state machine.
2016 void eap_notify_pending(struct eap_sm
*sm
)
2018 sm
->eapol_cb
->notify_pending(sm
->eapol_ctx
);
2023 * eap_invalidate_cached_session - Mark cached session data invalid
2024 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
2026 void eap_invalidate_cached_session(struct eap_sm
*sm
)
2029 eap_deinit_prev_method(sm
, "invalidate");