If there is no commitid, we need to initialize Delta->commitid to NULL to
[dragonfly.git] / contrib / wpa_supplicant-0.4.9 / eap.c
blob2d2c82c26ee726956aa8a55ce026f2b84492d1f4
1 /*
2 * WPA Supplicant / EAP state machines (RFC 4137)
3 * Copyright (c) 2004-2005, Jouni Malinen <jkmaline@cc.hut.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
10 * license.
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).
24 #include <stdlib.h>
25 #include <stdio.h>
26 #include <string.h>
27 #include <ctype.h>
29 #include "common.h"
30 #include "eap_i.h"
31 #include "wpa_supplicant.h"
32 #include "config_ssid.h"
33 #include "tls.h"
34 #include "crypto.h"
35 #include "pcsc_funcs.h"
36 #include "wpa_ctrl.h"
39 #define EAP_MAX_AUTH_ROUNDS 50
42 #ifdef EAP_MD5
43 extern const struct eap_method eap_method_md5;
44 #endif
45 #ifdef EAP_TLS
46 extern const struct eap_method eap_method_tls;
47 #endif
48 #ifdef EAP_MSCHAPv2
49 extern const struct eap_method eap_method_mschapv2;
50 #endif
51 #ifdef EAP_PEAP
52 extern const struct eap_method eap_method_peap;
53 #endif
54 #ifdef EAP_TTLS
55 extern const struct eap_method eap_method_ttls;
56 #endif
57 #ifdef EAP_GTC
58 extern const struct eap_method eap_method_gtc;
59 #endif
60 #ifdef EAP_OTP
61 extern const struct eap_method eap_method_otp;
62 #endif
63 #ifdef EAP_SIM
64 extern const struct eap_method eap_method_sim;
65 #endif
66 #ifdef EAP_LEAP
67 extern const struct eap_method eap_method_leap;
68 #endif
69 #ifdef EAP_PSK
70 extern const struct eap_method eap_method_psk;
71 #endif
72 #ifdef EAP_AKA
73 extern const struct eap_method eap_method_aka;
74 #endif
75 #ifdef EAP_FAST
76 extern const struct eap_method eap_method_fast;
77 #endif
78 #ifdef EAP_PAX
79 extern const struct eap_method eap_method_pax;
80 #endif
82 static const struct eap_method *eap_methods[] =
84 #ifdef EAP_MD5
85 &eap_method_md5,
86 #endif
87 #ifdef EAP_TLS
88 &eap_method_tls,
89 #endif
90 #ifdef EAP_MSCHAPv2
91 &eap_method_mschapv2,
92 #endif
93 #ifdef EAP_PEAP
94 &eap_method_peap,
95 #endif
96 #ifdef EAP_TTLS
97 &eap_method_ttls,
98 #endif
99 #ifdef EAP_GTC
100 &eap_method_gtc,
101 #endif
102 #ifdef EAP_OTP
103 &eap_method_otp,
104 #endif
105 #ifdef EAP_SIM
106 &eap_method_sim,
107 #endif
108 #ifdef EAP_LEAP
109 &eap_method_leap,
110 #endif
111 #ifdef EAP_PSK
112 &eap_method_psk,
113 #endif
114 #ifdef EAP_AKA
115 &eap_method_aka,
116 #endif
117 #ifdef EAP_FAST
118 &eap_method_fast,
119 #endif
120 #ifdef EAP_PAX
121 &eap_method_pax,
122 #endif
124 #define NUM_EAP_METHODS (sizeof(eap_methods) / sizeof(eap_methods[0]))
128 * eap_sm_get_eap_methods - Get EAP method based on type number
129 * @method: EAP type number
130 * Returns: Pointer to EAP method of %NULL if not found
132 const struct eap_method * eap_sm_get_eap_methods(int method)
134 int i;
135 for (i = 0; i < NUM_EAP_METHODS; i++) {
136 if (eap_methods[i]->method == method)
137 return eap_methods[i];
139 return NULL;
143 static Boolean eap_sm_allowMethod(struct eap_sm *sm, EapType method);
144 static u8 * eap_sm_buildNak(struct eap_sm *sm, int id, size_t *len);
145 static void eap_sm_processIdentity(struct eap_sm *sm, const u8 *req,
146 size_t len);
147 static void eap_sm_processNotify(struct eap_sm *sm, const u8 *req, size_t len);
148 static u8 * eap_sm_buildNotify(struct eap_sm *sm, int id, size_t *len);
149 static void eap_sm_parseEapReq(struct eap_sm *sm, const u8 *req, size_t len);
150 static const char * eap_sm_method_state_txt(EapMethodState state);
151 static const char * eap_sm_decision_txt(EapDecision decision);
154 /* Definitions for clarifying state machine implementation */
155 #define SM_STATE(machine, state) \
156 static void sm_ ## machine ## _ ## state ## _Enter(struct eap_sm *sm, \
157 int global)
159 #define SM_ENTRY(machine, state) \
160 if (!global || sm->machine ## _state != machine ## _ ## state) { \
161 sm->changed = TRUE; \
162 wpa_printf(MSG_DEBUG, "EAP: " #machine " entering state " #state); \
164 sm->machine ## _state = machine ## _ ## state;
166 #define SM_ENTER(machine, state) \
167 sm_ ## machine ## _ ## state ## _Enter(sm, 0)
168 #define SM_ENTER_GLOBAL(machine, state) \
169 sm_ ## machine ## _ ## state ## _Enter(sm, 1)
171 #define SM_STEP(machine) \
172 static void sm_ ## machine ## _Step(struct eap_sm *sm)
174 #define SM_STEP_RUN(machine) sm_ ## machine ## _Step(sm)
177 static Boolean eapol_get_bool(struct eap_sm *sm, enum eapol_bool_var var)
179 return sm->eapol_cb->get_bool(sm->eapol_ctx, var);
183 static void eapol_set_bool(struct eap_sm *sm, enum eapol_bool_var var,
184 Boolean value)
186 sm->eapol_cb->set_bool(sm->eapol_ctx, var, value);
190 static unsigned int eapol_get_int(struct eap_sm *sm, enum eapol_int_var var)
192 return sm->eapol_cb->get_int(sm->eapol_ctx, var);
196 static void eapol_set_int(struct eap_sm *sm, enum eapol_int_var var,
197 unsigned int value)
199 sm->eapol_cb->set_int(sm->eapol_ctx, var, value);
203 static u8 * eapol_get_eapReqData(struct eap_sm *sm, size_t *len)
205 return sm->eapol_cb->get_eapReqData(sm->eapol_ctx, len);
209 static void eap_deinit_prev_method(struct eap_sm *sm, const char *txt)
211 if (sm->m == NULL || sm->eap_method_priv == NULL)
212 return;
214 wpa_printf(MSG_DEBUG, "EAP: deinitialize previously used EAP method "
215 "(%d, %s) at %s", sm->selectedMethod, sm->m->name, txt);
216 sm->m->deinit(sm, sm->eap_method_priv);
217 sm->eap_method_priv = NULL;
218 sm->m = NULL;
223 * This state initializes state machine variables when the machine is
224 * activated (portEnabled = TRUE). This is also used when re-starting
225 * authentication (eapRestart == TRUE).
227 SM_STATE(EAP, INITIALIZE)
229 SM_ENTRY(EAP, INITIALIZE);
230 if (sm->fast_reauth && sm->m && sm->m->has_reauth_data &&
231 sm->m->has_reauth_data(sm, sm->eap_method_priv)) {
232 wpa_printf(MSG_DEBUG, "EAP: maintaining EAP method data for "
233 "fast reauthentication");
234 sm->m->deinit_for_reauth(sm, sm->eap_method_priv);
235 } else {
236 eap_deinit_prev_method(sm, "INITIALIZE");
238 sm->selectedMethod = EAP_TYPE_NONE;
239 sm->methodState = METHOD_NONE;
240 sm->allowNotifications = TRUE;
241 sm->decision = DECISION_FAIL;
242 eapol_set_int(sm, EAPOL_idleWhile, sm->ClientTimeout);
243 eapol_set_bool(sm, EAPOL_eapSuccess, FALSE);
244 eapol_set_bool(sm, EAPOL_eapFail, FALSE);
245 free(sm->eapKeyData);
246 sm->eapKeyData = NULL;
247 sm->eapKeyAvailable = FALSE;
248 eapol_set_bool(sm, EAPOL_eapRestart, FALSE);
249 sm->lastId = -1; /* new session - make sure this does not match with
250 * the first EAP-Packet */
252 * RFC 4137 does not reset eapResp and eapNoResp here. However, this
253 * seemed to be able to trigger cases where both were set and if EAPOL
254 * state machine uses eapNoResp first, it may end up not sending a real
255 * reply correctly. This occurred when the workaround in FAIL state set
256 * eapNoResp = TRUE.. Maybe that workaround needs to be fixed to do
257 * something else(?)
259 eapol_set_bool(sm, EAPOL_eapResp, FALSE);
260 eapol_set_bool(sm, EAPOL_eapNoResp, FALSE);
261 sm->num_rounds = 0;
266 * This state is reached whenever service from the lower layer is interrupted
267 * or unavailable (portEnabled == FALSE). Immediate transition to INITIALIZE
268 * occurs when the port becomes enabled.
270 SM_STATE(EAP, DISABLED)
272 SM_ENTRY(EAP, DISABLED);
273 sm->num_rounds = 0;
278 * The state machine spends most of its time here, waiting for something to
279 * happen. This state is entered unconditionally from INITIALIZE, DISCARD, and
280 * SEND_RESPONSE states.
282 SM_STATE(EAP, IDLE)
284 SM_ENTRY(EAP, IDLE);
289 * This state is entered when an EAP packet is received (eapReq == TRUE) to
290 * parse the packet header.
292 SM_STATE(EAP, RECEIVED)
294 const u8 *eapReqData;
295 size_t eapReqDataLen;
297 SM_ENTRY(EAP, RECEIVED);
298 eapReqData = eapol_get_eapReqData(sm, &eapReqDataLen);
299 /* parse rxReq, rxSuccess, rxFailure, reqId, reqMethod */
300 eap_sm_parseEapReq(sm, eapReqData, eapReqDataLen);
301 sm->num_rounds++;
306 * This state is entered when a request for a new type comes in. Either the
307 * correct method is started, or a Nak response is built.
309 SM_STATE(EAP, GET_METHOD)
311 SM_ENTRY(EAP, GET_METHOD);
312 if (eap_sm_allowMethod(sm, sm->reqMethod)) {
313 int reinit = 0;
315 * RFC 4137 does not define specific operation for fast
316 * re-authentication (session resumption). The design here is
317 * to allow the previously used method data to be maintained
318 * for re-authentication if the method support session
319 * resumption. Otherwise, the previously used method data is
320 * freed and a new method is allocated here.
322 if (sm->fast_reauth &&
323 sm->m && sm->m->method == sm->reqMethod &&
324 sm->m->has_reauth_data &&
325 sm->m->has_reauth_data(sm, sm->eap_method_priv)) {
326 wpa_printf(MSG_DEBUG, "EAP: Using previous method data"
327 " for fast re-authentication");
328 reinit = 1;
329 } else
330 eap_deinit_prev_method(sm, "GET_METHOD");
331 sm->selectedMethod = sm->reqMethod;
332 if (sm->m == NULL)
333 sm->m = eap_sm_get_eap_methods(sm->selectedMethod);
334 if (sm->m) {
335 wpa_printf(MSG_DEBUG, "EAP: Initialize selected EAP "
336 "method (%d, %s)",
337 sm->selectedMethod, sm->m->name);
338 if (reinit)
339 sm->eap_method_priv = sm->m->init_for_reauth(
340 sm, sm->eap_method_priv);
341 else
342 sm->eap_method_priv = sm->m->init(sm);
343 if (sm->eap_method_priv == NULL) {
344 struct wpa_ssid *config = eap_get_config(sm);
345 wpa_msg(sm->msg_ctx, MSG_INFO,
346 "EAP: Failed to initialize EAP method "
347 "%d (%s)",
348 sm->selectedMethod, sm->m->name);
349 sm->m = NULL;
350 sm->methodState = METHOD_NONE;
351 sm->selectedMethod = EAP_TYPE_NONE;
352 if (sm->reqMethod == EAP_TYPE_TLS &&
353 config &&
354 (config->pending_req_pin ||
355 config->pending_req_passphrase)) {
357 * Return without generating Nak in
358 * order to allow entering of PIN code
359 * or passphrase to retry the current
360 * EAP packet.
362 wpa_printf(MSG_DEBUG, "EAP: Pending "
363 "PIN/passphrase request - "
364 "skip Nak");
365 return;
367 } else {
368 sm->methodState = METHOD_INIT;
369 wpa_msg(sm->msg_ctx, MSG_INFO,
370 WPA_EVENT_EAP_METHOD
371 "EAP method %d (%s) selected",
372 sm->selectedMethod, sm->m->name);
373 return;
378 free(sm->eapRespData);
379 sm->eapRespData = eap_sm_buildNak(sm, sm->reqId, &sm->eapRespDataLen);
384 * The method processing happens here. The request from the authenticator is
385 * processed, and an appropriate response packet is built.
387 SM_STATE(EAP, METHOD)
389 u8 *eapReqData;
390 size_t eapReqDataLen;
391 struct eap_method_ret ret;
393 SM_ENTRY(EAP, METHOD);
394 if (sm->m == NULL) {
395 wpa_printf(MSG_WARNING, "EAP::METHOD - method not selected");
396 return;
399 eapReqData = eapol_get_eapReqData(sm, &eapReqDataLen);
402 * Get ignore, methodState, decision, allowNotifications, and
403 * eapRespData. RFC 4137 uses three separate method procedure (check,
404 * process, and buildResp) in this state. These have been combined into
405 * a single function call to m->process() in order to optimize EAP
406 * method implementation interface a bit. These procedures are only
407 * used from within this METHOD state, so there is no need to keep
408 * these as separate C functions.
410 * The RFC 4137 procedures return values as follows:
411 * ignore = m.check(eapReqData)
412 * (methodState, decision, allowNotifications) = m.process(eapReqData)
413 * eapRespData = m.buildResp(reqId)
415 memset(&ret, 0, sizeof(ret));
416 ret.ignore = sm->ignore;
417 ret.methodState = sm->methodState;
418 ret.decision = sm->decision;
419 ret.allowNotifications = sm->allowNotifications;
420 free(sm->eapRespData);
421 sm->eapRespData = sm->m->process(sm, sm->eap_method_priv, &ret,
422 eapReqData, eapReqDataLen,
423 &sm->eapRespDataLen);
424 wpa_printf(MSG_DEBUG, "EAP: method process -> ignore=%s "
425 "methodState=%s decision=%s",
426 ret.ignore ? "TRUE" : "FALSE",
427 eap_sm_method_state_txt(ret.methodState),
428 eap_sm_decision_txt(ret.decision));
430 sm->ignore = ret.ignore;
431 if (sm->ignore)
432 return;
433 sm->methodState = ret.methodState;
434 sm->decision = ret.decision;
435 sm->allowNotifications = ret.allowNotifications;
437 if (sm->m->isKeyAvailable && sm->m->getKey &&
438 sm->m->isKeyAvailable(sm, sm->eap_method_priv)) {
439 free(sm->eapKeyData);
440 sm->eapKeyData = sm->m->getKey(sm, sm->eap_method_priv,
441 &sm->eapKeyDataLen);
447 * This state signals the lower layer that a response packet is ready to be
448 * sent.
450 SM_STATE(EAP, SEND_RESPONSE)
452 SM_ENTRY(EAP, SEND_RESPONSE);
453 free(sm->lastRespData);
454 if (sm->eapRespData) {
455 if (sm->workaround)
456 memcpy(sm->last_md5, sm->req_md5, 16);
457 sm->lastId = sm->reqId;
458 sm->lastRespData = malloc(sm->eapRespDataLen);
459 if (sm->lastRespData) {
460 memcpy(sm->lastRespData, sm->eapRespData,
461 sm->eapRespDataLen);
462 sm->lastRespDataLen = sm->eapRespDataLen;
464 eapol_set_bool(sm, EAPOL_eapResp, TRUE);
465 } else
466 sm->lastRespData = NULL;
467 eapol_set_bool(sm, EAPOL_eapReq, FALSE);
468 eapol_set_int(sm, EAPOL_idleWhile, sm->ClientTimeout);
473 * This state signals the lower layer that the request was discarded, and no
474 * response packet will be sent at this time.
476 SM_STATE(EAP, DISCARD)
478 SM_ENTRY(EAP, DISCARD);
479 eapol_set_bool(sm, EAPOL_eapReq, FALSE);
480 eapol_set_bool(sm, EAPOL_eapNoResp, TRUE);
485 * Handles requests for Identity method and builds a response.
487 SM_STATE(EAP, IDENTITY)
489 const u8 *eapReqData;
490 size_t eapReqDataLen;
492 SM_ENTRY(EAP, IDENTITY);
493 eapReqData = eapol_get_eapReqData(sm, &eapReqDataLen);
494 eap_sm_processIdentity(sm, eapReqData, eapReqDataLen);
495 free(sm->eapRespData);
496 sm->eapRespData = eap_sm_buildIdentity(sm, sm->reqId,
497 &sm->eapRespDataLen, 0);
502 * Handles requests for Notification method and builds a response.
504 SM_STATE(EAP, NOTIFICATION)
506 const u8 *eapReqData;
507 size_t eapReqDataLen;
509 SM_ENTRY(EAP, NOTIFICATION);
510 eapReqData = eapol_get_eapReqData(sm, &eapReqDataLen);
511 eap_sm_processNotify(sm, eapReqData, eapReqDataLen);
512 free(sm->eapRespData);
513 sm->eapRespData = eap_sm_buildNotify(sm, sm->reqId,
514 &sm->eapRespDataLen);
519 * This state retransmits the previous response packet.
521 SM_STATE(EAP, RETRANSMIT)
523 SM_ENTRY(EAP, RETRANSMIT);
524 free(sm->eapRespData);
525 if (sm->lastRespData) {
526 sm->eapRespData = malloc(sm->lastRespDataLen);
527 if (sm->eapRespData) {
528 memcpy(sm->eapRespData, sm->lastRespData,
529 sm->lastRespDataLen);
530 sm->eapRespDataLen = sm->lastRespDataLen;
532 } else
533 sm->eapRespData = NULL;
538 * This state is entered in case of a successful completion of authentication
539 * and state machine waits here until port is disabled or EAP authentication is
540 * restarted.
542 SM_STATE(EAP, SUCCESS)
544 SM_ENTRY(EAP, SUCCESS);
545 if (sm->eapKeyData != NULL)
546 sm->eapKeyAvailable = TRUE;
547 eapol_set_bool(sm, EAPOL_eapSuccess, TRUE);
550 * RFC 4137 does not clear eapReq here, but this seems to be required
551 * to avoid processing the same request twice when state machine is
552 * initialized.
554 eapol_set_bool(sm, EAPOL_eapReq, FALSE);
557 * RFC 4137 does not set eapNoResp here, but this seems to be required
558 * to get EAPOL Supplicant backend state machine into SUCCESS state. In
559 * addition, either eapResp or eapNoResp is required to be set after
560 * processing the received EAP frame.
562 eapol_set_bool(sm, EAPOL_eapNoResp, TRUE);
564 wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_SUCCESS
565 "EAP authentication completed successfully");
570 * This state is entered in case of a failure and state machine waits here
571 * until port is disabled or EAP authentication is restarted.
573 SM_STATE(EAP, FAILURE)
575 SM_ENTRY(EAP, FAILURE);
576 eapol_set_bool(sm, EAPOL_eapFail, TRUE);
579 * RFC 4137 does not clear eapReq here, but this seems to be required
580 * to avoid processing the same request twice when state machine is
581 * initialized.
583 eapol_set_bool(sm, EAPOL_eapReq, FALSE);
586 * RFC 4137 does not set eapNoResp here. However, either eapResp or
587 * eapNoResp is required to be set after processing the received EAP
588 * frame.
590 eapol_set_bool(sm, EAPOL_eapNoResp, TRUE);
592 wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_FAILURE
593 "EAP authentication failed");
597 static int eap_success_workaround(struct eap_sm *sm, int reqId, int lastId)
600 * At least Microsoft IAS and Meetinghouse Aegis seem to be sending
601 * EAP-Success/Failure with lastId + 1 even though RFC 3748 and
602 * RFC 4137 require that reqId == lastId. In addition, it looks like
603 * Ringmaster v2.1.2.0 would be using lastId + 2 in EAP-Success.
605 * Accept this kind of Id if EAP workarounds are enabled. These are
606 * unauthenticated plaintext messages, so this should have minimal
607 * security implications (bit easier to fake EAP-Success/Failure).
609 if (sm->workaround && (reqId == ((lastId + 1) & 0xff) ||
610 reqId == ((lastId + 2) & 0xff))) {
611 wpa_printf(MSG_DEBUG, "EAP: Workaround for unexpected "
612 "identifier field in EAP Success: "
613 "reqId=%d lastId=%d (these are supposed to be "
614 "same)", reqId, lastId);
615 return 1;
617 wpa_printf(MSG_DEBUG, "EAP: EAP-Success Id mismatch - reqId=%d "
618 "lastId=%d", reqId, lastId);
619 return 0;
624 * RFC 4137 - Appendix A.1: EAP Peer State Machine - State transitions
626 SM_STEP(EAP)
628 int duplicate;
630 if (eapol_get_bool(sm, EAPOL_eapRestart) &&
631 eapol_get_bool(sm, EAPOL_portEnabled))
632 SM_ENTER_GLOBAL(EAP, INITIALIZE);
633 else if (!eapol_get_bool(sm, EAPOL_portEnabled) || sm->force_disabled)
634 SM_ENTER_GLOBAL(EAP, DISABLED);
635 else if (sm->num_rounds > EAP_MAX_AUTH_ROUNDS) {
636 /* RFC 4137 does not place any limit on number of EAP messages
637 * in an authentication session. However, some error cases have
638 * ended up in a state were EAP messages were sent between the
639 * peer and server in a loop (e.g., TLS ACK frame in both
640 * direction). Since this is quite undesired outcome, limit the
641 * total number of EAP round-trips and abort authentication if
642 * this limit is exceeded.
644 if (sm->num_rounds == EAP_MAX_AUTH_ROUNDS + 1) {
645 wpa_msg(sm->msg_ctx, MSG_INFO, "EAP: more than %d "
646 "authentication rounds - abort",
647 EAP_MAX_AUTH_ROUNDS);
648 sm->num_rounds++;
649 SM_ENTER_GLOBAL(EAP, FAILURE);
651 } else switch (sm->EAP_state) {
652 case EAP_INITIALIZE:
653 SM_ENTER(EAP, IDLE);
654 break;
655 case EAP_DISABLED:
656 if (eapol_get_bool(sm, EAPOL_portEnabled) &&
657 !sm->force_disabled)
658 SM_ENTER(EAP, INITIALIZE);
659 break;
660 case EAP_IDLE:
662 * The first three transitions are from RFC 4137. The last two
663 * are local additions to handle special cases with LEAP and
664 * PEAP server not sending EAP-Success in some cases.
666 if (eapol_get_bool(sm, EAPOL_eapReq))
667 SM_ENTER(EAP, RECEIVED);
668 else if ((eapol_get_bool(sm, EAPOL_altAccept) &&
669 sm->decision != DECISION_FAIL) ||
670 (eapol_get_int(sm, EAPOL_idleWhile) == 0 &&
671 sm->decision == DECISION_UNCOND_SUCC))
672 SM_ENTER(EAP, SUCCESS);
673 else if (eapol_get_bool(sm, EAPOL_altReject) ||
674 (eapol_get_int(sm, EAPOL_idleWhile) == 0 &&
675 sm->decision != DECISION_UNCOND_SUCC) ||
676 (eapol_get_bool(sm, EAPOL_altAccept) &&
677 sm->methodState != METHOD_CONT &&
678 sm->decision == DECISION_FAIL))
679 SM_ENTER(EAP, FAILURE);
680 else if (sm->selectedMethod == EAP_TYPE_LEAP &&
681 sm->leap_done && sm->decision != DECISION_FAIL &&
682 sm->methodState == METHOD_DONE)
683 SM_ENTER(EAP, SUCCESS);
684 else if (sm->selectedMethod == EAP_TYPE_PEAP &&
685 sm->peap_done && sm->decision != DECISION_FAIL &&
686 sm->methodState == METHOD_DONE)
687 SM_ENTER(EAP, SUCCESS);
688 break;
689 case EAP_RECEIVED:
690 duplicate = (sm->reqId == sm->lastId) && sm->rxReq;
691 if (sm->workaround && duplicate &&
692 memcmp(sm->req_md5, sm->last_md5, 16) != 0) {
694 * RFC 4137 uses (reqId == lastId) as the only
695 * verification for duplicate EAP requests. However,
696 * this misses cases where the AS is incorrectly using
697 * the same id again; and unfortunately, such
698 * implementations exist. Use MD5 hash as an extra
699 * verification for the packets being duplicate to
700 * workaround these issues.
702 wpa_printf(MSG_DEBUG, "EAP: AS used the same Id again,"
703 " but EAP packets were not identical");
704 wpa_printf(MSG_DEBUG, "EAP: workaround - assume this "
705 "is not a duplicate packet");
706 duplicate = 0;
710 * Two special cases below for LEAP are local additions to work
711 * around odd LEAP behavior (EAP-Success in the middle of
712 * authentication and then swapped roles). Other transitions
713 * are based on RFC 4137.
715 if (sm->rxSuccess && sm->decision != DECISION_FAIL &&
716 (sm->reqId == sm->lastId ||
717 eap_success_workaround(sm, sm->reqId, sm->lastId)))
718 SM_ENTER(EAP, SUCCESS);
719 else if (sm->methodState != METHOD_CONT &&
720 ((sm->rxFailure &&
721 sm->decision != DECISION_UNCOND_SUCC) ||
722 (sm->rxSuccess && sm->decision == DECISION_FAIL &&
723 (sm->selectedMethod != EAP_TYPE_LEAP ||
724 sm->methodState != METHOD_MAY_CONT))) &&
725 (sm->reqId == sm->lastId ||
726 eap_success_workaround(sm, sm->reqId, sm->lastId)))
727 SM_ENTER(EAP, FAILURE);
728 else if (sm->rxReq && duplicate)
729 SM_ENTER(EAP, RETRANSMIT);
730 else if (sm->rxReq && !duplicate &&
731 sm->reqMethod == EAP_TYPE_NOTIFICATION &&
732 sm->allowNotifications)
733 SM_ENTER(EAP, NOTIFICATION);
734 else if (sm->rxReq && !duplicate &&
735 sm->selectedMethod == EAP_TYPE_NONE &&
736 sm->reqMethod == EAP_TYPE_IDENTITY)
737 SM_ENTER(EAP, IDENTITY);
738 else if (sm->rxReq && !duplicate &&
739 sm->selectedMethod == EAP_TYPE_NONE &&
740 sm->reqMethod != EAP_TYPE_IDENTITY &&
741 sm->reqMethod != EAP_TYPE_NOTIFICATION)
742 SM_ENTER(EAP, GET_METHOD);
743 else if (sm->rxReq && !duplicate &&
744 sm->reqMethod == sm->selectedMethod &&
745 sm->methodState != METHOD_DONE)
746 SM_ENTER(EAP, METHOD);
747 else if (sm->selectedMethod == EAP_TYPE_LEAP &&
748 (sm->rxSuccess || sm->rxResp))
749 SM_ENTER(EAP, METHOD);
750 else
751 SM_ENTER(EAP, DISCARD);
752 break;
753 case EAP_GET_METHOD:
754 if (sm->selectedMethod == sm->reqMethod)
755 SM_ENTER(EAP, METHOD);
756 else
757 SM_ENTER(EAP, SEND_RESPONSE);
758 break;
759 case EAP_METHOD:
760 if (sm->ignore)
761 SM_ENTER(EAP, DISCARD);
762 else
763 SM_ENTER(EAP, SEND_RESPONSE);
764 break;
765 case EAP_SEND_RESPONSE:
766 SM_ENTER(EAP, IDLE);
767 break;
768 case EAP_DISCARD:
769 SM_ENTER(EAP, IDLE);
770 break;
771 case EAP_IDENTITY:
772 SM_ENTER(EAP, SEND_RESPONSE);
773 break;
774 case EAP_NOTIFICATION:
775 SM_ENTER(EAP, SEND_RESPONSE);
776 break;
777 case EAP_RETRANSMIT:
778 SM_ENTER(EAP, SEND_RESPONSE);
779 break;
780 case EAP_SUCCESS:
781 break;
782 case EAP_FAILURE:
783 break;
788 static Boolean eap_sm_allowMethod(struct eap_sm *sm, EapType method)
790 struct wpa_ssid *config = eap_get_config(sm);
791 int i;
793 if (!wpa_config_allowed_eap_method(config, method))
794 return FALSE;
795 for (i = 0; i < NUM_EAP_METHODS; i++) {
796 if (eap_methods[i]->method == method)
797 return TRUE;
799 return FALSE;
803 static u8 * eap_sm_buildNak(struct eap_sm *sm, int id, size_t *len)
805 struct wpa_ssid *config = eap_get_config(sm);
806 struct eap_hdr *resp;
807 u8 *pos;
808 int i, found = 0;
810 wpa_printf(MSG_DEBUG, "EAP: Building EAP-Nak (requested type %d not "
811 "allowed)", sm->reqMethod);
812 *len = sizeof(struct eap_hdr) + 1;
813 resp = malloc(*len + NUM_EAP_METHODS);
814 if (resp == NULL)
815 return NULL;
817 resp->code = EAP_CODE_RESPONSE;
818 resp->identifier = id;
819 pos = (u8 *) (resp + 1);
820 *pos++ = EAP_TYPE_NAK;
822 for (i = 0; i < NUM_EAP_METHODS; i++) {
823 if (eap_methods[i]->method != sm->reqMethod &&
824 wpa_config_allowed_eap_method(config,
825 eap_methods[i]->method)) {
826 *pos++ = eap_methods[i]->method;
827 (*len)++;
828 found++;
831 if (!found) {
832 *pos = EAP_TYPE_NONE;
833 (*len)++;
835 wpa_hexdump(MSG_DEBUG, "EAP: allowed methods",
836 ((u8 *) (resp + 1)) + 1, found);
838 resp->length = host_to_be16(*len);
840 return (u8 *) resp;
844 static void eap_sm_processIdentity(struct eap_sm *sm, const u8 *req,
845 size_t len)
847 const struct eap_hdr *hdr = (const struct eap_hdr *) req;
848 const u8 *pos = (const u8 *) (hdr + 1);
849 pos++;
851 wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_STARTED
852 "EAP authentication started");
855 * RFC 3748 - 5.1: Identity
856 * Data field may contain a displayable message in UTF-8. If this
857 * includes NUL-character, only the data before that should be
858 * displayed. Some EAP implementasitons may piggy-back additional
859 * options after the NUL.
861 /* TODO: could save displayable message so that it can be shown to the
862 * user in case of interaction is required */
863 wpa_hexdump_ascii(MSG_DEBUG, "EAP: EAP-Request Identity data",
864 pos, be_to_host16(hdr->length) - 5);
868 static int eap_sm_imsi_identity(struct eap_sm *sm, struct wpa_ssid *ssid)
870 int aka = 0;
871 char imsi[100];
872 size_t imsi_len;
873 u8 *pos = ssid->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");
878 return -1;
881 wpa_hexdump_ascii(MSG_DEBUG, "IMSI", (u8 *) imsi, imsi_len);
883 while (pos && *pos != EAP_TYPE_NONE) {
884 if (*pos == EAP_TYPE_AKA) {
885 aka = 1;
886 break;
888 pos++;
891 free(ssid->identity);
892 ssid->identity = malloc(1 + imsi_len);
893 if (ssid->identity == NULL) {
894 wpa_printf(MSG_WARNING, "Failed to allocate buffer for "
895 "IMSI-based identity");
896 return -1;
899 ssid->identity[0] = aka ? '0' : '1';
900 memcpy(ssid->identity + 1, imsi, imsi_len);
901 ssid->identity_len = 1 + imsi_len;
902 return 0;
906 static int eap_sm_get_scard_identity(struct eap_sm *sm, struct wpa_ssid *ssid)
908 if (scard_set_pin(sm->scard_ctx, ssid->pin)) {
910 * Make sure the same PIN is not tried again in order to avoid
911 * blocking SIM.
913 free(ssid->pin);
914 ssid->pin = NULL;
916 wpa_printf(MSG_WARNING, "PIN validation failed");
917 eap_sm_request_pin(sm, ssid);
918 return -1;
921 return eap_sm_imsi_identity(sm, ssid);
926 * eap_sm_buildIdentity - Build EAP-Identity/Response for the current network
927 * @sm: Pointer to EAP state machine allocated with eap_sm_init()
928 * @id: EAP identifier for the packet
929 * @len: Pointer to a variable that will be set to the length of the response
930 * @encrypted: Whether the packet is for encrypted tunnel (EAP phase 2)
931 * Returns: Pointer to the allocated EAP-Identity/Response packet or %NULL on
932 * failure
934 * This function allocates and builds an EAP-Identity/Response packet for the
935 * current network. The caller is responsible for freeing the returned data.
937 u8 * eap_sm_buildIdentity(struct eap_sm *sm, int id, size_t *len,
938 int encrypted)
940 struct wpa_ssid *config = eap_get_config(sm);
941 struct eap_hdr *resp;
942 u8 *pos;
943 const u8 *identity;
944 size_t identity_len;
946 if (config == NULL) {
947 wpa_printf(MSG_WARNING, "EAP: buildIdentity: configuration "
948 "was not available");
949 return NULL;
952 if (sm->m && sm->m->get_identity &&
953 (identity = sm->m->get_identity(sm, sm->eap_method_priv,
954 &identity_len)) != NULL) {
955 wpa_hexdump_ascii(MSG_DEBUG, "EAP: using method re-auth "
956 "identity", identity, identity_len);
957 } else if (!encrypted && config->anonymous_identity) {
958 identity = config->anonymous_identity;
959 identity_len = config->anonymous_identity_len;
960 wpa_hexdump_ascii(MSG_DEBUG, "EAP: using anonymous identity",
961 identity, identity_len);
962 } else {
963 identity = config->identity;
964 identity_len = config->identity_len;
965 wpa_hexdump_ascii(MSG_DEBUG, "EAP: using real identity",
966 identity, identity_len);
969 if (identity == NULL) {
970 wpa_printf(MSG_WARNING, "EAP: buildIdentity: identity "
971 "configuration was not available");
972 if (config->pcsc) {
973 if (eap_sm_get_scard_identity(sm, config) < 0)
974 return NULL;
975 identity = config->identity;
976 identity_len = config->identity_len;
977 wpa_hexdump_ascii(MSG_DEBUG, "permanent identity from "
978 "IMSI", identity, identity_len);
979 } else {
980 eap_sm_request_identity(sm, config);
981 return NULL;
985 *len = sizeof(struct eap_hdr) + 1 + identity_len;
986 resp = malloc(*len);
987 if (resp == NULL)
988 return NULL;
990 resp->code = EAP_CODE_RESPONSE;
991 resp->identifier = id;
992 resp->length = host_to_be16(*len);
993 pos = (u8 *) (resp + 1);
994 *pos++ = EAP_TYPE_IDENTITY;
995 memcpy(pos, identity, identity_len);
997 return (u8 *) resp;
1001 static void eap_sm_processNotify(struct eap_sm *sm, const u8 *req, size_t len)
1003 const struct eap_hdr *hdr = (const struct eap_hdr *) req;
1004 const u8 *pos;
1005 char *msg;
1006 size_t msg_len;
1007 int i;
1009 pos = (const u8 *) (hdr + 1);
1010 pos++;
1012 msg_len = be_to_host16(hdr->length);
1013 if (msg_len < 5)
1014 return;
1015 msg_len -= 5;
1016 wpa_hexdump_ascii(MSG_DEBUG, "EAP: EAP-Request Notification data",
1017 pos, msg_len);
1019 msg = malloc(msg_len + 1);
1020 if (msg == NULL)
1021 return;
1022 for (i = 0; i < msg_len; i++)
1023 msg[i] = isprint(pos[i]) ? (char) pos[i] : '_';
1024 msg[msg_len] = '\0';
1025 wpa_msg(sm->msg_ctx, MSG_INFO, "%s%s",
1026 WPA_EVENT_EAP_NOTIFICATION, msg);
1027 free(msg);
1031 static u8 * eap_sm_buildNotify(struct eap_sm *sm, int id, size_t *len)
1033 struct eap_hdr *resp;
1034 u8 *pos;
1036 wpa_printf(MSG_DEBUG, "EAP: Generating EAP-Response Notification");
1037 *len = sizeof(struct eap_hdr) + 1;
1038 resp = malloc(*len);
1039 if (resp == NULL)
1040 return NULL;
1042 resp->code = EAP_CODE_RESPONSE;
1043 resp->identifier = id;
1044 resp->length = host_to_be16(*len);
1045 pos = (u8 *) (resp + 1);
1046 *pos = EAP_TYPE_NOTIFICATION;
1048 return (u8 *) resp;
1052 static void eap_sm_parseEapReq(struct eap_sm *sm, const u8 *req, size_t len)
1054 const struct eap_hdr *hdr;
1055 size_t plen;
1057 sm->rxReq = sm->rxResp = sm->rxSuccess = sm->rxFailure = FALSE;
1058 sm->reqId = 0;
1059 sm->reqMethod = EAP_TYPE_NONE;
1061 if (req == NULL || len < sizeof(*hdr))
1062 return;
1064 hdr = (const struct eap_hdr *) req;
1065 plen = be_to_host16(hdr->length);
1066 if (plen > len) {
1067 wpa_printf(MSG_DEBUG, "EAP: Ignored truncated EAP-Packet "
1068 "(len=%lu plen=%lu)",
1069 (unsigned long) len, (unsigned long) plen);
1070 return;
1073 sm->reqId = hdr->identifier;
1075 if (sm->workaround) {
1076 md5_vector(1, (const u8 **) &req, &len, sm->req_md5);
1079 switch (hdr->code) {
1080 case EAP_CODE_REQUEST:
1081 sm->rxReq = TRUE;
1082 if (plen > sizeof(*hdr))
1083 sm->reqMethod = *((u8 *) (hdr + 1));
1084 wpa_printf(MSG_DEBUG, "EAP: Received EAP-Request method=%d "
1085 "id=%d", sm->reqMethod, sm->reqId);
1086 break;
1087 case EAP_CODE_RESPONSE:
1088 if (sm->selectedMethod == EAP_TYPE_LEAP) {
1090 * LEAP differs from RFC 4137 by using reversed roles
1091 * for mutual authentication and because of this, we
1092 * need to accept EAP-Response frames if LEAP is used.
1094 sm->rxResp = TRUE;
1095 if (plen > sizeof(*hdr))
1096 sm->reqMethod = *((u8 *) (hdr + 1));
1097 wpa_printf(MSG_DEBUG, "EAP: Received EAP-Response for "
1098 "LEAP method=%d id=%d",
1099 sm->reqMethod, sm->reqId);
1100 break;
1102 wpa_printf(MSG_DEBUG, "EAP: Ignored EAP-Response");
1103 break;
1104 case EAP_CODE_SUCCESS:
1105 wpa_printf(MSG_DEBUG, "EAP: Received EAP-Success");
1106 sm->rxSuccess = TRUE;
1107 break;
1108 case EAP_CODE_FAILURE:
1109 wpa_printf(MSG_DEBUG, "EAP: Received EAP-Failure");
1110 sm->rxFailure = TRUE;
1111 break;
1112 default:
1113 wpa_printf(MSG_DEBUG, "EAP: Ignored EAP-Packet with unknown "
1114 "code %d", hdr->code);
1115 break;
1121 * eap_sm_init - Allocate and initialize EAP state machine
1122 * @eapol_ctx: Context data to be used with eapol_cb calls
1123 * @eapol_cb: Pointer to EAPOL callback functions
1124 * @msg_ctx: Context data for wpa_msg() calls
1125 * @conf: EAP configuration
1126 * Returns: Pointer to the allocated EAP state machine or %NULL on failure
1128 * This function allocates and initializes an EAP state machine. In addition,
1129 * this initializes TLS library for the new EAP state machine. eapol_cb pointer
1130 * will be in use until eap_sm_deinit() is used to deinitialize this EAP state
1131 * machine. Consequently, the caller must make sure that this data structure
1132 * remains alive while the EAP state machine is active.
1134 struct eap_sm * eap_sm_init(void *eapol_ctx, struct eapol_callbacks *eapol_cb,
1135 void *msg_ctx, struct eap_config *conf)
1137 struct eap_sm *sm;
1138 struct tls_config tlsconf;
1140 sm = malloc(sizeof(*sm));
1141 if (sm == NULL)
1142 return NULL;
1143 memset(sm, 0, sizeof(*sm));
1144 sm->eapol_ctx = eapol_ctx;
1145 sm->eapol_cb = eapol_cb;
1146 sm->msg_ctx = msg_ctx;
1147 sm->ClientTimeout = 60;
1149 memset(&tlsconf, 0, sizeof(tlsconf));
1150 tlsconf.opensc_engine_path = conf->opensc_engine_path;
1151 tlsconf.pkcs11_engine_path = conf->pkcs11_engine_path;
1152 tlsconf.pkcs11_module_path = conf->pkcs11_module_path;
1153 sm->ssl_ctx = tls_init(&tlsconf);
1154 if (sm->ssl_ctx == NULL) {
1155 wpa_printf(MSG_WARNING, "SSL: Failed to initialize TLS "
1156 "context.");
1157 free(sm);
1158 return NULL;
1161 return sm;
1166 * eap_sm_deinit - Deinitialize and free an EAP state machine
1167 * @sm: Pointer to EAP state machine allocated with eap_sm_init()
1169 * This function deinitializes EAP state machine and frees all allocated
1170 * resources.
1172 void eap_sm_deinit(struct eap_sm *sm)
1174 if (sm == NULL)
1175 return;
1176 eap_deinit_prev_method(sm, "EAP deinit");
1177 eap_sm_abort(sm);
1178 tls_deinit(sm->ssl_ctx);
1179 free(sm);
1184 * eap_sm_step - Step EAP state machine
1185 * @sm: Pointer to EAP state machine allocated with eap_sm_init()
1186 * Returns: 1 if EAP state was changed or 0 if not
1188 * This function advances EAP state machine to a new state to match with the
1189 * current variables. This should be called whenever variables used by the EAP
1190 * state machine have changed.
1192 int eap_sm_step(struct eap_sm *sm)
1194 int res = 0;
1195 do {
1196 sm->changed = FALSE;
1197 SM_STEP_RUN(EAP);
1198 if (sm->changed)
1199 res = 1;
1200 } while (sm->changed);
1201 return res;
1206 * eap_sm_abort - Abort EAP authentication
1207 * @sm: Pointer to EAP state machine allocated with eap_sm_init()
1209 * Release system resources that have been allocated for the authentication
1210 * session without fully deinitializing the EAP state machine.
1212 void eap_sm_abort(struct eap_sm *sm)
1214 free(sm->lastRespData);
1215 sm->lastRespData = NULL;
1216 free(sm->eapRespData);
1217 sm->eapRespData = NULL;
1218 free(sm->eapKeyData);
1219 sm->eapKeyData = NULL;
1223 static const char * eap_sm_state_txt(int state)
1225 switch (state) {
1226 case EAP_INITIALIZE:
1227 return "INITIALIZE";
1228 case EAP_DISABLED:
1229 return "DISABLED";
1230 case EAP_IDLE:
1231 return "IDLE";
1232 case EAP_RECEIVED:
1233 return "RECEIVED";
1234 case EAP_GET_METHOD:
1235 return "GET_METHOD";
1236 case EAP_METHOD:
1237 return "METHOD";
1238 case EAP_SEND_RESPONSE:
1239 return "SEND_RESPONSE";
1240 case EAP_DISCARD:
1241 return "DISCARD";
1242 case EAP_IDENTITY:
1243 return "IDENTITY";
1244 case EAP_NOTIFICATION:
1245 return "NOTIFICATION";
1246 case EAP_RETRANSMIT:
1247 return "RETRANSMIT";
1248 case EAP_SUCCESS:
1249 return "SUCCESS";
1250 case EAP_FAILURE:
1251 return "FAILURE";
1252 default:
1253 return "UNKNOWN";
1258 static const char * eap_sm_method_state_txt(EapMethodState state)
1260 switch (state) {
1261 case METHOD_NONE:
1262 return "NONE";
1263 case METHOD_INIT:
1264 return "INIT";
1265 case METHOD_CONT:
1266 return "CONT";
1267 case METHOD_MAY_CONT:
1268 return "MAY_CONT";
1269 case METHOD_DONE:
1270 return "DONE";
1271 default:
1272 return "UNKNOWN";
1277 static const char * eap_sm_decision_txt(EapDecision decision)
1279 switch (decision) {
1280 case DECISION_FAIL:
1281 return "FAIL";
1282 case DECISION_COND_SUCC:
1283 return "COND_SUCC";
1284 case DECISION_UNCOND_SUCC:
1285 return "UNCOND_SUCC";
1286 default:
1287 return "UNKNOWN";
1293 * eap_sm_get_status - Get EAP state machine status
1294 * @sm: Pointer to EAP state machine allocated with eap_sm_init()
1295 * @buf: Buffer for status information
1296 * @buflen: Maximum buffer length
1297 * @verbose: Whether to include verbose status information
1298 * Returns: Number of bytes written to buf.
1300 * Query EAP state machine for status information. This function fills in a
1301 * text area with current status information from the EAPOL state machine. If
1302 * the buffer (buf) is not large enough, status information will be truncated
1303 * to fit the buffer.
1305 int eap_sm_get_status(struct eap_sm *sm, char *buf, size_t buflen, int verbose)
1307 int len;
1309 if (sm == NULL)
1310 return 0;
1312 len = snprintf(buf, buflen,
1313 "EAP state=%s\n",
1314 eap_sm_state_txt(sm->EAP_state));
1316 if (sm->selectedMethod != EAP_TYPE_NONE) {
1317 const char *name;
1318 if (sm->m) {
1319 name = sm->m->name;
1320 } else {
1321 const struct eap_method *m =
1322 eap_sm_get_eap_methods(sm->selectedMethod);
1323 if (m)
1324 name = m->name;
1325 else
1326 name = "?";
1328 len += snprintf(buf + len, buflen - len,
1329 "selectedMethod=%d (EAP-%s)\n",
1330 sm->selectedMethod, name);
1332 if (sm->m && sm->m->get_status) {
1333 len += sm->m->get_status(sm, sm->eap_method_priv,
1334 buf + len, buflen - len,
1335 verbose);
1339 if (verbose) {
1340 len += snprintf(buf + len, buflen - len,
1341 "reqMethod=%d\n"
1342 "methodState=%s\n"
1343 "decision=%s\n"
1344 "ClientTimeout=%d\n",
1345 sm->reqMethod,
1346 eap_sm_method_state_txt(sm->methodState),
1347 eap_sm_decision_txt(sm->decision),
1348 sm->ClientTimeout);
1351 return len;
1355 typedef enum {
1356 TYPE_IDENTITY, TYPE_PASSWORD, TYPE_OTP, TYPE_PIN, TYPE_NEW_PASSWORD,
1357 TYPE_PASSPHRASE
1358 } eap_ctrl_req_type;
1360 static void eap_sm_request(struct eap_sm *sm, struct wpa_ssid *config,
1361 eap_ctrl_req_type type, const char *msg,
1362 size_t msglen)
1364 char *buf;
1365 size_t buflen;
1366 int len;
1367 char *field;
1368 char *txt, *tmp;
1370 if (config == NULL || sm == NULL)
1371 return;
1373 switch (type) {
1374 case TYPE_IDENTITY:
1375 field = "IDENTITY";
1376 txt = "Identity";
1377 config->pending_req_identity++;
1378 break;
1379 case TYPE_PASSWORD:
1380 field = "PASSWORD";
1381 txt = "Password";
1382 config->pending_req_password++;
1383 break;
1384 case TYPE_NEW_PASSWORD:
1385 field = "NEW_PASSWORD";
1386 txt = "New Password";
1387 config->pending_req_new_password++;
1388 break;
1389 case TYPE_PIN:
1390 field = "PIN";
1391 txt = "PIN";
1392 config->pending_req_pin++;
1393 break;
1394 case TYPE_OTP:
1395 field = "OTP";
1396 if (msg) {
1397 tmp = malloc(msglen + 3);
1398 if (tmp == NULL)
1399 return;
1400 tmp[0] = '[';
1401 memcpy(tmp + 1, msg, msglen);
1402 tmp[msglen + 1] = ']';
1403 tmp[msglen + 2] = '\0';
1404 txt = tmp;
1405 free(config->pending_req_otp);
1406 config->pending_req_otp = tmp;
1407 config->pending_req_otp_len = msglen + 3;
1408 } else {
1409 if (config->pending_req_otp == NULL)
1410 return;
1411 txt = config->pending_req_otp;
1413 break;
1414 case TYPE_PASSPHRASE:
1415 field = "PASSPHRASE";
1416 txt = "Private key passphrase";
1417 config->pending_req_passphrase++;
1418 break;
1419 default:
1420 return;
1423 buflen = 100 + strlen(txt) + config->ssid_len;
1424 buf = malloc(buflen);
1425 if (buf == NULL)
1426 return;
1427 len = snprintf(buf, buflen, WPA_CTRL_REQ "%s-%d:%s needed for SSID ",
1428 field, config->id, txt);
1429 if (config->ssid && buflen > len + config->ssid_len) {
1430 memcpy(buf + len, config->ssid, config->ssid_len);
1431 len += config->ssid_len;
1432 buf[len] = '\0';
1434 wpa_msg(sm->msg_ctx, MSG_INFO, "%s", buf);
1435 free(buf);
1440 * eap_sm_request_identity - Request identity from user (ctrl_iface)
1441 * @sm: Pointer to EAP state machine allocated with eap_sm_init()
1442 * @config: Pointer to the current network configuration
1444 * EAP methods can call this function to request identity information for the
1445 * current network. This is normally called when the identity is not included
1446 * in the network configuration. The request will be sent to monitor programs
1447 * through the control interface.
1449 void eap_sm_request_identity(struct eap_sm *sm, struct wpa_ssid *config)
1451 eap_sm_request(sm, config, TYPE_IDENTITY, NULL, 0);
1456 * eap_sm_request_password - Request password from user (ctrl_iface)
1457 * @sm: Pointer to EAP state machine allocated with eap_sm_init()
1458 * @config: Pointer to the current network configuration
1460 * EAP methods can call this function to request password information for the
1461 * current network. This is normally called when the password is not included
1462 * in the network configuration. The request will be sent to monitor programs
1463 * through the control interface.
1465 void eap_sm_request_password(struct eap_sm *sm, struct wpa_ssid *config)
1467 eap_sm_request(sm, config, TYPE_PASSWORD, NULL, 0);
1472 * eap_sm_request_new_password - Request new password from user (ctrl_iface)
1473 * @sm: Pointer to EAP state machine allocated with eap_sm_init()
1474 * @config: Pointer to the current network configuration
1476 * EAP methods can call this function to request new password information for
1477 * the current network. This is normally called when the EAP method indicates
1478 * that the current password has expired and password change is required. The
1479 * request will be sent to monitor programs through the control interface.
1481 void eap_sm_request_new_password(struct eap_sm *sm, struct wpa_ssid *config)
1483 eap_sm_request(sm, config, TYPE_NEW_PASSWORD, NULL, 0);
1488 * eap_sm_request_pin - Request SIM or smart card PIN from user (ctrl_iface)
1489 * @sm: Pointer to EAP state machine allocated with eap_sm_init()
1490 * @config: Pointer to the current network configuration
1492 * EAP methods can call this function to request SIM or smart card PIN
1493 * information for the current network. This is normally called when the PIN is
1494 * not included in the network configuration. The request will be sent to
1495 * monitor programs through the control interface.
1497 void eap_sm_request_pin(struct eap_sm *sm, struct wpa_ssid *config)
1499 eap_sm_request(sm, config, TYPE_PIN, NULL, 0);
1504 * eap_sm_request_otp - Request one time password from user (ctrl_iface)
1505 * @sm: Pointer to EAP state machine allocated with eap_sm_init()
1506 * @config: Pointer to the current network configuration
1507 * @msg: Message to be displayed to the user when asking for OTP
1508 * @msg_len: Length of the user displayable message
1510 * EAP methods can call this function to request open time password (OTP) for
1511 * the current network. The request will be sent to monitor programs through
1512 * the control interface.
1514 void eap_sm_request_otp(struct eap_sm *sm, struct wpa_ssid *config,
1515 const char *msg, size_t msg_len)
1517 eap_sm_request(sm, config, TYPE_OTP, msg, msg_len);
1522 * eap_sm_request_passphrase - Request passphrase from user (ctrl_iface)
1523 * @sm: Pointer to EAP state machine allocated with eap_sm_init()
1524 * @config: Pointer to the current network configuration
1526 * EAP methods can call this function to request passphrase for a private key
1527 * for the current network. This is normally called when the passphrase is not
1528 * included in the network configuration. The request will be sent to monitor
1529 * programs through the control interface.
1531 void eap_sm_request_passphrase(struct eap_sm *sm, struct wpa_ssid *config)
1533 eap_sm_request(sm, config, TYPE_PASSPHRASE, NULL, 0);
1538 * eap_sm_notify_ctrl_attached - Notification of attached monitor
1539 * @sm: Pointer to EAP state machine allocated with eap_sm_init()
1541 * Notify EAP state machines that a monitor was attached to the control
1542 * interface to trigger re-sending of pending requests for user input.
1544 void eap_sm_notify_ctrl_attached(struct eap_sm *sm)
1546 struct wpa_ssid *config = eap_get_config(sm);
1548 if (config == NULL)
1549 return;
1551 /* Re-send any pending requests for user data since a new control
1552 * interface was added. This handles cases where the EAP authentication
1553 * starts immediately after system startup when the user interface is
1554 * not yet running. */
1555 if (config->pending_req_identity)
1556 eap_sm_request_identity(sm, config);
1557 if (config->pending_req_password)
1558 eap_sm_request_password(sm, config);
1559 if (config->pending_req_new_password)
1560 eap_sm_request_new_password(sm, config);
1561 if (config->pending_req_otp)
1562 eap_sm_request_otp(sm, config, NULL, 0);
1563 if (config->pending_req_pin)
1564 eap_sm_request_pin(sm, config);
1565 if (config->pending_req_passphrase)
1566 eap_sm_request_passphrase(sm, config);
1571 * eap_get_type - Get EAP type for the given EAP method name
1572 * @name: EAP method name, e.g., TLS
1573 * Returns: EAP method type or %EAP_TYPE_NONE if not found
1575 * This function maps EAP type names into EAP type numbers based on the list of
1576 * EAP methods included in the build.
1578 u8 eap_get_type(const char *name)
1580 int i;
1581 for (i = 0; i < NUM_EAP_METHODS; i++) {
1582 if (strcmp(eap_methods[i]->name, name) == 0)
1583 return eap_methods[i]->method;
1585 return EAP_TYPE_NONE;
1590 * eap_get_name - Get EAP method name for the given EAP type
1591 * @type: EAP method type
1592 * Returns: EAP method name, e.g., TLS, or %NULL if not found
1594 * This function maps EAP type numbers into EAP type names based on the list of
1595 * EAP methods included in the build.
1597 const char * eap_get_name(EapType type)
1599 int i;
1600 for (i = 0; i < NUM_EAP_METHODS; i++) {
1601 if (eap_methods[i]->method == type)
1602 return eap_methods[i]->name;
1604 return NULL;
1609 * eap_get_names - Get space separated list of names for supported EAP methods
1610 * @buf: Buffer for names
1611 * @buflen: Buffer length
1612 * Returns: Number of characters written into buf (not including nul
1613 * termination)
1615 size_t eap_get_names(char *buf, size_t buflen)
1617 char *pos, *end;
1618 int i;
1620 pos = buf;
1621 end = pos + buflen;
1623 for (i = 0; i < NUM_EAP_METHODS; i++) {
1624 pos += snprintf(pos, end - pos, "%s%s",
1625 i == 0 ? "" : " ", eap_methods[i]->name);
1628 return pos - buf;
1632 static int eap_allowed_phase2_type(int type)
1634 return type != EAP_TYPE_PEAP && type != EAP_TYPE_TTLS &&
1635 type != EAP_TYPE_FAST;
1640 * eap_get_phase2_type - Get EAP type for the given EAP phase 2 method name
1641 * @name: EAP method name, e.g., MD5
1642 * Returns: EAP method type or %EAP_TYPE_NONE if not found
1644 * This function maps EAP type names into EAP type numbers that are allowed for
1645 * Phase 2, i.e., for tunneled authentication. Phase 2 is used, e.g., with
1646 * EAP-PEAP, EAP-TTLS, and EAP-FAST.
1648 u8 eap_get_phase2_type(const char *name)
1650 u8 type = eap_get_type(name);
1651 if (eap_allowed_phase2_type(type))
1652 return type;
1653 return EAP_TYPE_NONE;
1658 * eap_get_phase2_types - Get list of allowed EAP phase 2 types
1659 * @config: Pointer to a network configuration
1660 * @count: Pointer to a variable to be filled with number of returned EAP types
1661 * Returns: Pointer to allocated type list or %NULL on failure
1663 * This function generates an array of allowed EAP phase 2 (tunneled) types for
1664 * the given network configuration.
1666 u8 *eap_get_phase2_types(struct wpa_ssid *config, size_t *count)
1668 u8 *buf, method;
1669 int i;
1671 *count = 0;
1672 buf = malloc(NUM_EAP_METHODS);
1673 if (buf == NULL)
1674 return NULL;
1676 for (i = 0; i < NUM_EAP_METHODS; i++) {
1677 method = eap_methods[i]->method;
1678 if (eap_allowed_phase2_type(method)) {
1679 if (method == EAP_TYPE_TLS && config &&
1680 config->private_key2 == NULL)
1681 continue;
1682 buf[*count] = method;
1683 (*count)++;
1687 return buf;
1692 * eap_set_fast_reauth - Update fast_reauth setting
1693 * @sm: Pointer to EAP state machine allocated with eap_sm_init()
1694 * @enabled: 1 = Fast reauthentication is enabled, 0 = Disabled
1696 void eap_set_fast_reauth(struct eap_sm *sm, int enabled)
1698 sm->fast_reauth = enabled;
1703 * eap_set_workaround - Update EAP workarounds setting
1704 * @sm: Pointer to EAP state machine allocated with eap_sm_init()
1705 * @workaround: 1 = Enable EAP workarounds, 0 = Disable EAP workarounds
1707 void eap_set_workaround(struct eap_sm *sm, unsigned int workaround)
1709 sm->workaround = workaround;
1714 * eap_get_config - Get current network configuration
1715 * @sm: Pointer to EAP state machine allocated with eap_sm_init()
1716 * Returns: Pointer to the current network configuration or %NULL if not found
1718 struct wpa_ssid * eap_get_config(struct eap_sm *sm)
1720 return sm->eapol_cb->get_config(sm->eapol_ctx);
1725 * eap_key_available - Get key availability (eapKeyAvailable variable)
1726 * @sm: Pointer to EAP state machine allocated with eap_sm_init()
1727 * Returns: 1 if EAP keying material is available, 0 if not
1729 int eap_key_available(struct eap_sm *sm)
1731 return sm ? sm->eapKeyAvailable : 0;
1736 * eap_notify_success - Notify EAP state machine about external success trigger
1737 * @sm: Pointer to EAP state machine allocated with eap_sm_init()
1739 * This function is called when external event, e.g., successful completion of
1740 * WPA-PSK key handshake, is indicating that EAP state machine should move to
1741 * success state. This is mainly used with security modes that do not use EAP
1742 * state machine (e.g., WPA-PSK).
1744 void eap_notify_success(struct eap_sm *sm)
1746 if (sm) {
1747 sm->decision = DECISION_COND_SUCC;
1748 sm->EAP_state = EAP_SUCCESS;
1754 * eap_notify_lower_layer_success - Notification of lower layer success
1755 * @sm: Pointer to EAP state machine allocated with eap_sm_init()
1757 * Notify EAP state machines that a lower layer has detected a successful
1758 * authentication. This is used to recover from dropped EAP-Success messages.
1760 void eap_notify_lower_layer_success(struct eap_sm *sm)
1762 if (sm == NULL)
1763 return;
1765 if (eapol_get_bool(sm, EAPOL_eapSuccess) ||
1766 sm->decision == DECISION_FAIL ||
1767 (sm->methodState != METHOD_MAY_CONT &&
1768 sm->methodState != METHOD_DONE))
1769 return;
1771 if (sm->eapKeyData != NULL)
1772 sm->eapKeyAvailable = TRUE;
1773 eapol_set_bool(sm, EAPOL_eapSuccess, TRUE);
1774 wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_SUCCESS
1775 "EAP authentication completed successfully (based on lower "
1776 "layer success)");
1781 * eap_get_eapKeyData - Get master session key (MSK) from EAP state machine
1782 * @sm: Pointer to EAP state machine allocated with eap_sm_init()
1783 * @len: Pointer to variable that will be set to number of bytes in the key
1784 * Returns: Pointer to the EAP keying data or %NULL on failure
1786 * Fetch EAP keying material (MSK, eapKeyData) from the EAP state machine. The
1787 * key is available only after a successful authentication. EAP state machine
1788 * continues to manage the key data and the caller must not change or free the
1789 * returned data.
1791 const u8 * eap_get_eapKeyData(struct eap_sm *sm, size_t *len)
1793 if (sm == NULL || sm->eapKeyData == NULL) {
1794 *len = 0;
1795 return NULL;
1798 *len = sm->eapKeyDataLen;
1799 return sm->eapKeyData;
1804 * eap_get_eapKeyData - Get EAP response data
1805 * @sm: Pointer to EAP state machine allocated with eap_sm_init()
1806 * @len: Pointer to variable that will be set to the length of the response
1807 * Returns: Pointer to the EAP response (eapRespData) or %NULL on failure
1809 * Fetch EAP response (eapRespData) from the EAP state machine. This data is
1810 * available when EAP state machine has processed an incoming EAP request. The
1811 * EAP state machine does not maintain a reference to the response after this
1812 * function is called and the caller is responsible for freeing the data.
1814 u8 * eap_get_eapRespData(struct eap_sm *sm, size_t *len)
1816 u8 *resp;
1818 if (sm == NULL || sm->eapRespData == NULL) {
1819 *len = 0;
1820 return NULL;
1823 resp = sm->eapRespData;
1824 *len = sm->eapRespDataLen;
1825 sm->eapRespData = NULL;
1826 sm->eapRespDataLen = 0;
1828 return resp;
1833 * eap_sm_register_scard_ctx - Notification of smart card context
1834 * @sm: Pointer to EAP state machine allocated with eap_sm_init()
1835 * @ctx: Context data for smart card operations
1837 * Notify EAP state machines of context data for smart card operations. This
1838 * context data will be used as a parameter for scard_*() functions.
1840 void eap_register_scard_ctx(struct eap_sm *sm, void *ctx)
1842 if (sm)
1843 sm->scard_ctx = ctx;
1848 * eap_hdr_validate - Validate EAP header
1849 * @eap_type: Expected EAP type number
1850 * @msg: EAP frame (starting with EAP header)
1851 * @msglen: Length of msg
1852 * @plen: Pointer to variable to contain the returned payload length
1853 * Returns: Pointer to EAP payload (after type field), or %NULL on failure
1855 * This is a helper function for EAP method implementations. This is usually
1856 * called in the beginning of struct eap_method::process() function to verify
1857 * that the received EAP request packet has a valid header.
1859 const u8 * eap_hdr_validate(EapType eap_type, const u8 *msg, size_t msglen,
1860 size_t *plen)
1862 const struct eap_hdr *hdr;
1863 const u8 *pos;
1864 size_t len;
1866 hdr = (const struct eap_hdr *) msg;
1867 pos = (const u8 *) (hdr + 1);
1868 if (msglen < sizeof(*hdr) + 1 || *pos != eap_type) {
1869 wpa_printf(MSG_INFO, "EAP: Invalid frame type");
1870 return NULL;
1872 len = be_to_host16(hdr->length);
1873 if (len < sizeof(*hdr) + 1 || len > msglen) {
1874 wpa_printf(MSG_INFO, "EAP: Invalid EAP length");
1875 return NULL;
1877 *plen = len - sizeof(*hdr) - 1;
1878 return pos + 1;
1883 * eap_set_config_blob - Set or add a named configuration blob
1884 * @sm: Pointer to EAP state machine allocated with eap_sm_init()
1885 * @blob: New value for the blob
1887 * Adds a new configuration blob or replaces the current value of an existing
1888 * blob.
1890 void eap_set_config_blob(struct eap_sm *sm, struct wpa_config_blob *blob)
1892 sm->eapol_cb->set_config_blob(sm->eapol_ctx, blob);
1897 * eap_get_config_blob - Get a named configuration blob
1898 * @sm: Pointer to EAP state machine allocated with eap_sm_init()
1899 * @name: Name of the blob
1900 * Returns: Pointer to blob data or %NULL if not found
1902 const struct wpa_config_blob * eap_get_config_blob(struct eap_sm *sm,
1903 const char *name)
1905 return sm->eapol_cb->get_config_blob(sm->eapol_ctx, name);
1910 * eap_set_force_disabled - Set force_disabled flag
1911 * @sm: Pointer to EAP state machine allocated with eap_sm_init()
1912 * @disabled: 1 = EAP disabled, 0 = EAP enabled
1914 * This function is used to force EAP state machine to be disabled when it is
1915 * not in use (e.g., with WPA-PSK or plaintext connections).
1917 void eap_set_force_disabled(struct eap_sm *sm, int disabled)
1919 sm->force_disabled = disabled;