]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/wpa_supplicant/eap.c
This commit was generated by cvs2svn to compensate for changes in r165670,
[FreeBSD/FreeBSD.git] / contrib / wpa_supplicant / eap.c
1 /*
2  * WPA Supplicant / EAP state machines (RFC 4137)
3  * Copyright (c) 2004-2005, Jouni Malinen <jkmaline@cc.hut.fi>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation.
8  *
9  * Alternatively, this software may be distributed under the terms of BSD
10  * license.
11  *
12  * See README and COPYING for more details.
13  */
14
15 #include <stdlib.h>
16 #include <stdio.h>
17 #include <string.h>
18 #include <ctype.h>
19
20 #include "common.h"
21 #include "eap_i.h"
22 #include "wpa_supplicant.h"
23 #include "config_ssid.h"
24 #include "tls.h"
25 #include "crypto.h"
26 #include "pcsc_funcs.h"
27 #include "wpa_ctrl.h"
28
29
30 #define EAP_MAX_AUTH_ROUNDS 50
31
32
33 #ifdef EAP_MD5
34 extern const struct eap_method eap_method_md5;
35 #endif
36 #ifdef EAP_TLS
37 extern const struct eap_method eap_method_tls;
38 #endif
39 #ifdef EAP_MSCHAPv2
40 extern const struct eap_method eap_method_mschapv2;
41 #endif
42 #ifdef EAP_PEAP
43 extern const struct eap_method eap_method_peap;
44 #endif
45 #ifdef EAP_TTLS
46 extern const struct eap_method eap_method_ttls;
47 #endif
48 #ifdef EAP_GTC
49 extern const struct eap_method eap_method_gtc;
50 #endif
51 #ifdef EAP_OTP
52 extern const struct eap_method eap_method_otp;
53 #endif
54 #ifdef EAP_SIM
55 extern const struct eap_method eap_method_sim;
56 #endif
57 #ifdef EAP_LEAP
58 extern const struct eap_method eap_method_leap;
59 #endif
60 #ifdef EAP_PSK
61 extern const struct eap_method eap_method_psk;
62 #endif
63 #ifdef EAP_AKA
64 extern const struct eap_method eap_method_aka;
65 #endif
66 #ifdef EAP_FAST
67 extern const struct eap_method eap_method_fast;
68 #endif
69 #ifdef EAP_PAX
70 extern const struct eap_method eap_method_pax;
71 #endif
72
73 static const struct eap_method *eap_methods[] =
74 {
75 #ifdef EAP_MD5
76         &eap_method_md5,
77 #endif
78 #ifdef EAP_TLS
79         &eap_method_tls,
80 #endif
81 #ifdef EAP_MSCHAPv2
82         &eap_method_mschapv2,
83 #endif
84 #ifdef EAP_PEAP
85         &eap_method_peap,
86 #endif
87 #ifdef EAP_TTLS
88         &eap_method_ttls,
89 #endif
90 #ifdef EAP_GTC
91         &eap_method_gtc,
92 #endif
93 #ifdef EAP_OTP
94         &eap_method_otp,
95 #endif
96 #ifdef EAP_SIM
97         &eap_method_sim,
98 #endif
99 #ifdef EAP_LEAP
100         &eap_method_leap,
101 #endif
102 #ifdef EAP_PSK
103         &eap_method_psk,
104 #endif
105 #ifdef EAP_AKA
106         &eap_method_aka,
107 #endif
108 #ifdef EAP_FAST
109         &eap_method_fast,
110 #endif
111 #ifdef EAP_PAX
112         &eap_method_pax,
113 #endif
114 };
115 #define NUM_EAP_METHODS (sizeof(eap_methods) / sizeof(eap_methods[0]))
116
117
118 /**
119  * eap_sm_get_eap_methods - Get EAP method based on type number
120  * @method: EAP type number
121  * Returns: Pointer to EAP method of %NULL if not found
122  */
123 const struct eap_method * eap_sm_get_eap_methods(int method)
124 {
125         int i;
126         for (i = 0; i < NUM_EAP_METHODS; i++) {
127                 if (eap_methods[i]->method == method)
128                         return eap_methods[i];
129         }
130         return NULL;
131 }
132
133
134 static Boolean eap_sm_allowMethod(struct eap_sm *sm, EapType method);
135 static u8 * eap_sm_buildNak(struct eap_sm *sm, int id, size_t *len);
136 static void eap_sm_processIdentity(struct eap_sm *sm, const u8 *req,
137                                    size_t len);
138 static void eap_sm_processNotify(struct eap_sm *sm, const u8 *req, size_t len);
139 static u8 * eap_sm_buildNotify(struct eap_sm *sm, int id, size_t *len);
140 static void eap_sm_parseEapReq(struct eap_sm *sm, const u8 *req, size_t len);
141 static const char * eap_sm_method_state_txt(int state);
142 static const char * eap_sm_decision_txt(int decision);
143
144
145 /* Definitions for clarifying state machine implementation */
146 #define SM_STATE(machine, state) \
147 static void sm_ ## machine ## _ ## state ## _Enter(struct eap_sm *sm, \
148         int global)
149
150 #define SM_ENTRY(machine, state) \
151 if (!global || sm->machine ## _state != machine ## _ ## state) { \
152         sm->changed = TRUE; \
153         wpa_printf(MSG_DEBUG, "EAP: " #machine " entering state " #state); \
154 } \
155 sm->machine ## _state = machine ## _ ## state;
156
157 #define SM_ENTER(machine, state) \
158 sm_ ## machine ## _ ## state ## _Enter(sm, 0)
159 #define SM_ENTER_GLOBAL(machine, state) \
160 sm_ ## machine ## _ ## state ## _Enter(sm, 1)
161
162 #define SM_STEP(machine) \
163 static void sm_ ## machine ## _Step(struct eap_sm *sm)
164
165 #define SM_STEP_RUN(machine) sm_ ## machine ## _Step(sm)
166
167
168 static Boolean eapol_get_bool(struct eap_sm *sm, enum eapol_bool_var var)
169 {
170         return sm->eapol_cb->get_bool(sm->eapol_ctx, var);
171 }
172
173
174 static void eapol_set_bool(struct eap_sm *sm, enum eapol_bool_var var,
175                            Boolean value)
176 {
177         sm->eapol_cb->set_bool(sm->eapol_ctx, var, value);
178 }
179
180
181 static unsigned int eapol_get_int(struct eap_sm *sm, enum eapol_int_var var)
182 {
183         return sm->eapol_cb->get_int(sm->eapol_ctx, var);
184 }
185
186
187 static void eapol_set_int(struct eap_sm *sm, enum eapol_int_var var,
188                           unsigned int value)
189 {
190         sm->eapol_cb->set_int(sm->eapol_ctx, var, value);
191 }
192
193
194 static u8 * eapol_get_eapReqData(struct eap_sm *sm, size_t *len)
195 {
196         return sm->eapol_cb->get_eapReqData(sm->eapol_ctx, len);
197 }
198
199
200 static void eap_deinit_prev_method(struct eap_sm *sm, const char *txt)
201 {
202         if (sm->m == NULL || sm->eap_method_priv == NULL)
203                 return;
204
205         wpa_printf(MSG_DEBUG, "EAP: deinitialize previously used EAP method "
206                    "(%d, %s) at %s", sm->selectedMethod, sm->m->name, txt);
207         sm->m->deinit(sm, sm->eap_method_priv);
208         sm->eap_method_priv = NULL;
209         sm->m = NULL;
210 }
211
212
213 SM_STATE(EAP, INITIALIZE)
214 {
215         SM_ENTRY(EAP, INITIALIZE);
216         if (sm->fast_reauth && sm->m && sm->m->has_reauth_data &&
217             sm->m->has_reauth_data(sm, sm->eap_method_priv)) {
218                 wpa_printf(MSG_DEBUG, "EAP: maintaining EAP method data for "
219                            "fast reauthentication");
220                 sm->m->deinit_for_reauth(sm, sm->eap_method_priv);
221         } else {
222                 eap_deinit_prev_method(sm, "INITIALIZE");
223         }
224         sm->selectedMethod = EAP_TYPE_NONE;
225         sm->methodState = METHOD_NONE;
226         sm->allowNotifications = TRUE;
227         sm->decision = DECISION_FAIL;
228         eapol_set_int(sm, EAPOL_idleWhile, sm->ClientTimeout);
229         eapol_set_bool(sm, EAPOL_eapSuccess, FALSE);
230         eapol_set_bool(sm, EAPOL_eapFail, FALSE);
231         free(sm->eapKeyData);
232         sm->eapKeyData = NULL;
233         sm->eapKeyAvailable = FALSE;
234         eapol_set_bool(sm, EAPOL_eapRestart, FALSE);
235         sm->lastId = -1; /* new session - make sure this does not match with
236                           * the first EAP-Packet */
237         /*
238          * RFC 4137 does not reset eapResp and eapNoResp here. However, this
239          * seemed to be able to trigger cases where both were set and if EAPOL
240          * state machine uses eapNoResp first, it may end up not sending a real
241          * reply correctly. This occurred when the workaround in FAIL state set
242          * eapNoResp = TRUE.. Maybe that workaround needs to be fixed to do
243          * something else(?)
244          */
245         eapol_set_bool(sm, EAPOL_eapResp, FALSE);
246         eapol_set_bool(sm, EAPOL_eapNoResp, FALSE);
247         sm->num_rounds = 0;
248 }
249
250
251 SM_STATE(EAP, DISABLED)
252 {
253         SM_ENTRY(EAP, DISABLED);
254         sm->num_rounds = 0;
255 }
256
257
258 SM_STATE(EAP, IDLE)
259 {
260         SM_ENTRY(EAP, IDLE);
261 }
262
263
264 SM_STATE(EAP, RECEIVED)
265 {
266         const u8 *eapReqData;
267         size_t eapReqDataLen;
268
269         SM_ENTRY(EAP, RECEIVED);
270         eapReqData = eapol_get_eapReqData(sm, &eapReqDataLen);
271         /* parse rxReq, rxSuccess, rxFailure, reqId, reqMethod */
272         eap_sm_parseEapReq(sm, eapReqData, eapReqDataLen);
273         sm->num_rounds++;
274 }
275
276
277 SM_STATE(EAP, GET_METHOD)
278 {
279         SM_ENTRY(EAP, GET_METHOD);
280         if (eap_sm_allowMethod(sm, sm->reqMethod)) {
281                 int reinit = 0;
282                 if (sm->fast_reauth &&
283                     sm->m && sm->m->method == sm->reqMethod &&
284                     sm->m->has_reauth_data &&
285                     sm->m->has_reauth_data(sm, sm->eap_method_priv)) {
286                         wpa_printf(MSG_DEBUG, "EAP: using previous method data"
287                                    " for fast re-authentication");
288                         reinit = 1;
289                 } else
290                         eap_deinit_prev_method(sm, "GET_METHOD");
291                 sm->selectedMethod = sm->reqMethod;
292                 if (sm->m == NULL)
293                         sm->m = eap_sm_get_eap_methods(sm->selectedMethod);
294                 if (sm->m) {
295                         wpa_printf(MSG_DEBUG, "EAP: initialize selected EAP "
296                                    "method (%d, %s)",
297                                    sm->selectedMethod, sm->m->name);
298                         if (reinit)
299                                 sm->eap_method_priv = sm->m->init_for_reauth(
300                                         sm, sm->eap_method_priv);
301                         else
302                                 sm->eap_method_priv = sm->m->init(sm);
303                         if (sm->eap_method_priv == NULL) {
304                                 struct wpa_ssid *config = eap_get_config(sm);
305                                 wpa_msg(sm->msg_ctx, MSG_INFO,
306                                         "EAP: Failed to initialize EAP method "
307                                         "%d (%s)",
308                                         sm->selectedMethod, sm->m->name);
309                                 sm->m = NULL;
310                                 sm->methodState = METHOD_NONE;
311                                 sm->selectedMethod = EAP_TYPE_NONE;
312                                 if (sm->reqMethod == EAP_TYPE_TLS &&
313                                     config &&
314                                     (config->pending_req_pin ||
315                                      config->pending_req_passphrase)) {
316                                         /*
317                                          * Return without generating Nak in
318                                          * order to allow entering of PIN code
319                                          * or passphrase to retry the current
320                                          * EAP packet.
321                                          */
322                                         wpa_printf(MSG_DEBUG, "EAP: Pending "
323                                                    "PIN/passphrase request - "
324                                                    "skip Nak");
325                                         return;
326                                 }
327                         } else {
328                                 sm->methodState = METHOD_INIT;
329                                 wpa_msg(sm->msg_ctx, MSG_INFO,
330                                         WPA_EVENT_EAP_METHOD
331                                         "EAP method %d (%s) selected",
332                                         sm->selectedMethod, sm->m->name);
333                                 return;
334                         }
335                 }
336         }
337
338         free(sm->eapRespData);
339         sm->eapRespData = eap_sm_buildNak(sm, sm->reqId, &sm->eapRespDataLen);
340 }
341
342
343 SM_STATE(EAP, METHOD)
344 {
345         u8 *eapReqData;
346         size_t eapReqDataLen;
347         struct eap_method_ret ret;
348
349         SM_ENTRY(EAP, METHOD);
350         if (sm->m == NULL) {
351                 wpa_printf(MSG_WARNING, "EAP::METHOD - method not selected");
352                 return;
353         }
354
355         eapReqData = eapol_get_eapReqData(sm, &eapReqDataLen);
356
357         /* Get ignore, methodState, decision, allowNotifications, and
358          * eapRespData. */
359         memset(&ret, 0, sizeof(ret));
360         ret.ignore = sm->ignore;
361         ret.methodState = sm->methodState;
362         ret.decision = sm->decision;
363         ret.allowNotifications = sm->allowNotifications;
364         free(sm->eapRespData);
365         sm->eapRespData = sm->m->process(sm, sm->eap_method_priv, &ret,
366                                          eapReqData, eapReqDataLen,
367                                          &sm->eapRespDataLen);
368         wpa_printf(MSG_DEBUG, "EAP: method process -> ignore=%s "
369                    "methodState=%s decision=%s",
370                    ret.ignore ? "TRUE" : "FALSE",
371                    eap_sm_method_state_txt(ret.methodState),
372                    eap_sm_decision_txt(ret.decision));
373
374         sm->ignore = ret.ignore;
375         if (sm->ignore)
376                 return;
377         sm->methodState = ret.methodState;
378         sm->decision = ret.decision;
379         sm->allowNotifications = ret.allowNotifications;
380
381         if (sm->m->isKeyAvailable && sm->m->getKey &&
382             sm->m->isKeyAvailable(sm, sm->eap_method_priv)) {
383                 free(sm->eapKeyData);
384                 sm->eapKeyData = sm->m->getKey(sm, sm->eap_method_priv,
385                                                &sm->eapKeyDataLen);
386         }
387 }
388
389
390 SM_STATE(EAP, SEND_RESPONSE)
391 {
392         SM_ENTRY(EAP, SEND_RESPONSE);
393         free(sm->lastRespData);
394         if (sm->eapRespData) {
395                 if (sm->workaround)
396                         memcpy(sm->last_md5, sm->req_md5, 16);
397                 sm->lastId = sm->reqId;
398                 sm->lastRespData = malloc(sm->eapRespDataLen);
399                 if (sm->lastRespData) {
400                         memcpy(sm->lastRespData, sm->eapRespData,
401                                sm->eapRespDataLen);
402                         sm->lastRespDataLen = sm->eapRespDataLen;
403                 }
404                 eapol_set_bool(sm, EAPOL_eapResp, TRUE);
405         } else
406                 sm->lastRespData = NULL;
407         eapol_set_bool(sm, EAPOL_eapReq, FALSE);
408         eapol_set_int(sm, EAPOL_idleWhile, sm->ClientTimeout);
409 }
410
411
412 SM_STATE(EAP, DISCARD)
413 {
414         SM_ENTRY(EAP, DISCARD);
415         eapol_set_bool(sm, EAPOL_eapReq, FALSE);
416         eapol_set_bool(sm, EAPOL_eapNoResp, TRUE);
417 }
418
419
420 SM_STATE(EAP, IDENTITY)
421 {
422         const u8 *eapReqData;
423         size_t eapReqDataLen;
424
425         SM_ENTRY(EAP, IDENTITY);
426         eapReqData = eapol_get_eapReqData(sm, &eapReqDataLen);
427         eap_sm_processIdentity(sm, eapReqData, eapReqDataLen);
428         free(sm->eapRespData);
429         sm->eapRespData = eap_sm_buildIdentity(sm, sm->reqId,
430                                                &sm->eapRespDataLen, 0);
431 }
432
433
434 SM_STATE(EAP, NOTIFICATION)
435 {
436         const u8 *eapReqData;
437         size_t eapReqDataLen;
438
439         SM_ENTRY(EAP, NOTIFICATION);
440         eapReqData = eapol_get_eapReqData(sm, &eapReqDataLen);
441         eap_sm_processNotify(sm, eapReqData, eapReqDataLen);
442         free(sm->eapRespData);
443         sm->eapRespData = eap_sm_buildNotify(sm, sm->reqId,
444                                              &sm->eapRespDataLen);
445 }
446
447
448 SM_STATE(EAP, RETRANSMIT)
449 {
450         SM_ENTRY(EAP, RETRANSMIT);
451         free(sm->eapRespData);
452         if (sm->lastRespData) {
453                 sm->eapRespData = malloc(sm->lastRespDataLen);
454                 if (sm->eapRespData) {
455                         memcpy(sm->eapRespData, sm->lastRespData,
456                                sm->lastRespDataLen);
457                         sm->eapRespDataLen = sm->lastRespDataLen;
458                 }
459         } else
460                 sm->eapRespData = NULL;
461 }
462
463
464 SM_STATE(EAP, SUCCESS)
465 {
466         SM_ENTRY(EAP, SUCCESS);
467         if (sm->eapKeyData != NULL)
468                 sm->eapKeyAvailable = TRUE;
469         eapol_set_bool(sm, EAPOL_eapSuccess, TRUE);
470
471         /*
472          * RFC 4137 does not clear eapReq here, but this seems to be required
473          * to avoid processing the same request twice when state machine is
474          * initialized.
475          */
476         eapol_set_bool(sm, EAPOL_eapReq, FALSE);
477
478         /*
479          * RFC 4137 does not set eapNoResp here, but this seems to be required
480          * to get EAPOL Supplicant backend state machine into SUCCESS state. In
481          * addition, either eapResp or eapNoResp is required to be set after
482          * processing the received EAP frame.
483          */
484         eapol_set_bool(sm, EAPOL_eapNoResp, TRUE);
485
486         wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_SUCCESS
487                 "EAP authentication completed successfully");
488 }
489
490
491 SM_STATE(EAP, FAILURE)
492 {
493         SM_ENTRY(EAP, FAILURE);
494         eapol_set_bool(sm, EAPOL_eapFail, TRUE);
495
496         /*
497          * RFC 4137 does not clear eapReq here, but this seems to be required
498          * to avoid processing the same request twice when state machine is
499          * initialized.
500          */
501         eapol_set_bool(sm, EAPOL_eapReq, FALSE);
502
503         /*
504          * RFC 4137 does not set eapNoResp here. However, either eapResp or
505          * eapNoResp is required to be set after processing the received EAP
506          * frame.
507          */
508         eapol_set_bool(sm, EAPOL_eapNoResp, TRUE);
509
510         wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_FAILURE
511                 "EAP authentication failed");
512 }
513
514
515 static int eap_success_workaround(struct eap_sm *sm, int reqId, int lastId)
516 {
517         /*
518          * At least Microsoft IAS and Meetinghouse Aegis seem to be sending
519          * EAP-Success/Failure with lastId + 1 even though RFC 3748 and
520          * RFC 4137 require that reqId == lastId. In addition, it looks like
521          * Ringmaster v2.1.2.0 would be using lastId + 2 in EAP-Success.
522          *
523          * Accept this kind of Id if EAP workarounds are enabled. These are
524          * unauthenticated plaintext messages, so this should have minimal
525          * security implications (bit easier to fake EAP-Success/Failure).
526          */
527         if (sm->workaround && (reqId == ((lastId + 1) & 0xff) ||
528                                reqId == ((lastId + 2) & 0xff))) {
529                 wpa_printf(MSG_DEBUG, "EAP: Workaround for unexpected "
530                            "identifier field in EAP Success: "
531                            "reqId=%d lastId=%d (these are supposed to be "
532                            "same)", reqId, lastId);
533                 return 1;
534         }
535         wpa_printf(MSG_DEBUG, "EAP: EAP-Success Id mismatch - reqId=%d "
536                    "lastId=%d", reqId, lastId);
537         return 0;
538 }
539
540
541 SM_STEP(EAP)
542 {
543         int duplicate;
544
545         if (eapol_get_bool(sm, EAPOL_eapRestart) &&
546             eapol_get_bool(sm, EAPOL_portEnabled))
547                 SM_ENTER_GLOBAL(EAP, INITIALIZE);
548         else if (!eapol_get_bool(sm, EAPOL_portEnabled) || sm->force_disabled)
549                 SM_ENTER_GLOBAL(EAP, DISABLED);
550         else if (sm->num_rounds > EAP_MAX_AUTH_ROUNDS) {
551                 if (sm->num_rounds == EAP_MAX_AUTH_ROUNDS + 1) {
552                         wpa_msg(sm->msg_ctx, MSG_INFO, "EAP: more than %d "
553                                 "authentication rounds - abort",
554                                 EAP_MAX_AUTH_ROUNDS);
555                         sm->num_rounds++;
556                         SM_ENTER_GLOBAL(EAP, FAILURE);
557                 }
558         } else switch (sm->EAP_state) {
559         case EAP_INITIALIZE:
560                 SM_ENTER(EAP, IDLE);
561                 break;
562         case EAP_DISABLED:
563                 if (eapol_get_bool(sm, EAPOL_portEnabled) &&
564                     !sm->force_disabled)
565                         SM_ENTER(EAP, INITIALIZE);
566                 break;
567         case EAP_IDLE:
568                 if (eapol_get_bool(sm, EAPOL_eapReq))
569                         SM_ENTER(EAP, RECEIVED);
570                 else if ((eapol_get_bool(sm, EAPOL_altAccept) &&
571                           sm->decision != DECISION_FAIL) ||
572                          (eapol_get_int(sm, EAPOL_idleWhile) == 0 &&
573                           sm->decision == DECISION_UNCOND_SUCC))
574                         SM_ENTER(EAP, SUCCESS);
575                 else if (eapol_get_bool(sm, EAPOL_altReject) ||
576                          (eapol_get_int(sm, EAPOL_idleWhile) == 0 &&
577                           sm->decision != DECISION_UNCOND_SUCC) ||
578                          (eapol_get_bool(sm, EAPOL_altAccept) &&
579                           sm->methodState != METHOD_CONT &&
580                           sm->decision == DECISION_FAIL))
581                         SM_ENTER(EAP, FAILURE);
582                 else if (sm->selectedMethod == EAP_TYPE_LEAP &&
583                          sm->leap_done && sm->decision != DECISION_FAIL &&
584                          sm->methodState == METHOD_DONE)
585                         SM_ENTER(EAP, SUCCESS);
586                 else if (sm->selectedMethod == EAP_TYPE_PEAP &&
587                          sm->peap_done && sm->decision != DECISION_FAIL &&
588                          sm->methodState == METHOD_DONE)
589                         SM_ENTER(EAP, SUCCESS);
590                 break;
591         case EAP_RECEIVED:
592                 duplicate = (sm->reqId == sm->lastId) && sm->rxReq;
593                 if (sm->workaround && duplicate &&
594                     memcmp(sm->req_md5, sm->last_md5, 16) != 0) {
595                         /*
596                          * RFC 4137 uses (reqId == lastId) as the only
597                          * verification for duplicate EAP requests. However,
598                          * this misses cases where the AS is incorrectly using
599                          * the same id again; and unfortunately, such
600                          * implementations exist. Use MD5 hash as an extra
601                          * verification for the packets being duplicate to
602                          * workaround these issues.
603                          */
604                         wpa_printf(MSG_DEBUG, "EAP: AS used the same Id again,"
605                                    " but EAP packets were not identical");
606                         wpa_printf(MSG_DEBUG, "EAP: workaround - assume this "
607                                    "is not a duplicate packet");
608                         duplicate = 0;
609                 }
610
611                 if (sm->rxSuccess &&
612                     (sm->reqId == sm->lastId ||
613                      eap_success_workaround(sm, sm->reqId, sm->lastId)) &&
614                     sm->decision != DECISION_FAIL)
615                         SM_ENTER(EAP, SUCCESS);
616                 else if (sm->methodState != METHOD_CONT &&
617                          ((sm->rxFailure &&
618                            sm->decision != DECISION_UNCOND_SUCC) ||
619                           (sm->rxSuccess && sm->decision == DECISION_FAIL &&
620                            (sm->selectedMethod != EAP_TYPE_LEAP ||
621                             sm->methodState != METHOD_MAY_CONT))) &&
622                          (sm->reqId == sm->lastId ||
623                           eap_success_workaround(sm, sm->reqId, sm->lastId)))
624                         SM_ENTER(EAP, FAILURE);
625                 else if (sm->rxReq && duplicate)
626                         SM_ENTER(EAP, RETRANSMIT);
627                 else if (sm->rxReq && !duplicate &&
628                          sm->reqMethod == EAP_TYPE_NOTIFICATION &&
629                          sm->allowNotifications)
630                         SM_ENTER(EAP, NOTIFICATION);
631                 else if (sm->rxReq && !duplicate &&
632                          sm->selectedMethod == EAP_TYPE_NONE &&
633                          sm->reqMethod == EAP_TYPE_IDENTITY)
634                         SM_ENTER(EAP, IDENTITY);
635                 else if (sm->rxReq && !duplicate &&
636                          sm->selectedMethod == EAP_TYPE_NONE &&
637                          sm->reqMethod != EAP_TYPE_IDENTITY &&
638                          sm->reqMethod != EAP_TYPE_NOTIFICATION)
639                         SM_ENTER(EAP, GET_METHOD);
640                 else if (sm->rxReq && !duplicate &&
641                          sm->reqMethod == sm->selectedMethod &&
642                          sm->methodState != METHOD_DONE)
643                         SM_ENTER(EAP, METHOD);
644                 else if (sm->selectedMethod == EAP_TYPE_LEAP &&
645                          (sm->rxSuccess || sm->rxResp))
646                         SM_ENTER(EAP, METHOD);
647                 else
648                         SM_ENTER(EAP, DISCARD);
649                 break;
650         case EAP_GET_METHOD:
651                 if (sm->selectedMethod == sm->reqMethod)
652                         SM_ENTER(EAP, METHOD);
653                 else
654                         SM_ENTER(EAP, SEND_RESPONSE);
655                 break;
656         case EAP_METHOD:
657                 if (sm->ignore)
658                         SM_ENTER(EAP, DISCARD);
659                 else
660                         SM_ENTER(EAP, SEND_RESPONSE);
661                 break;
662         case EAP_SEND_RESPONSE:
663                 SM_ENTER(EAP, IDLE);
664                 break;
665         case EAP_DISCARD:
666                 SM_ENTER(EAP, IDLE);
667                 break;
668         case EAP_IDENTITY:
669                 SM_ENTER(EAP, SEND_RESPONSE);
670                 break;
671         case EAP_NOTIFICATION:
672                 SM_ENTER(EAP, SEND_RESPONSE);
673                 break;
674         case EAP_RETRANSMIT:
675                 SM_ENTER(EAP, SEND_RESPONSE);
676                 break;
677         case EAP_SUCCESS:
678                 break;
679         case EAP_FAILURE:
680                 break;
681         }
682 }
683
684
685 static Boolean eap_sm_allowMethod(struct eap_sm *sm, EapType method)
686 {
687         struct wpa_ssid *config = eap_get_config(sm);
688         int i;
689
690         if (!wpa_config_allowed_eap_method(config, method))
691                 return FALSE;
692         for (i = 0; i < NUM_EAP_METHODS; i++) {
693                 if (eap_methods[i]->method == method)
694                         return TRUE;
695         }
696         return FALSE;
697 }
698
699
700 static u8 *eap_sm_buildNak(struct eap_sm *sm, int id, size_t *len)
701 {
702         struct wpa_ssid *config = eap_get_config(sm);
703         struct eap_hdr *resp;
704         u8 *pos;
705         int i, found = 0;
706
707         wpa_printf(MSG_DEBUG, "EAP: Building EAP-Nak (requested type %d not "
708                    "allowed)", sm->reqMethod);
709         *len = sizeof(struct eap_hdr) + 1;
710         resp = malloc(*len + NUM_EAP_METHODS);
711         if (resp == NULL)
712                 return NULL;
713
714         resp->code = EAP_CODE_RESPONSE;
715         resp->identifier = id;
716         pos = (u8 *) (resp + 1);
717         *pos++ = EAP_TYPE_NAK;
718
719         for (i = 0; i < NUM_EAP_METHODS; i++) {
720                 if (eap_methods[i]->method != sm->reqMethod &&
721                     wpa_config_allowed_eap_method(config,
722                                                   eap_methods[i]->method)) {
723                         *pos++ = eap_methods[i]->method;
724                         (*len)++;
725                         found++;
726                 }
727         }
728         if (!found) {
729                 *pos = EAP_TYPE_NONE;
730                 (*len)++;
731         }
732         wpa_hexdump(MSG_DEBUG, "EAP: allowed methods",
733                     ((u8 *) (resp + 1)) + 1, found);
734
735         resp->length = host_to_be16(*len);
736
737         return (u8 *) resp;
738 }
739
740
741 static void eap_sm_processIdentity(struct eap_sm *sm, const u8 *req,
742                                    size_t len)
743 {
744         const struct eap_hdr *hdr = (const struct eap_hdr *) req;
745         const u8 *pos = (const u8 *) (hdr + 1);
746         pos++;
747
748         wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_STARTED
749                 "EAP authentication started");
750
751         /* TODO: could save displayable message so that it can be shown to the
752          * user in case of interaction is required */
753         wpa_hexdump_ascii(MSG_DEBUG, "EAP: EAP-Request Identity data",
754                           pos, be_to_host16(hdr->length) - 5);
755 }
756
757
758 static int eap_sm_imsi_identity(struct eap_sm *sm, struct wpa_ssid *ssid)
759 {
760         int aka = 0;
761         char imsi[100];
762         size_t imsi_len;
763         u8 *pos = ssid->eap_methods;
764
765         imsi_len = sizeof(imsi);
766         if (scard_get_imsi(sm->scard_ctx, imsi, &imsi_len)) {
767                 wpa_printf(MSG_WARNING, "Failed to get IMSI from SIM");
768                 return -1;
769         }
770
771         wpa_hexdump_ascii(MSG_DEBUG, "IMSI", (u8 *) imsi, imsi_len);
772
773         while (pos && *pos != EAP_TYPE_NONE) {
774                 if (*pos == EAP_TYPE_AKA) {
775                         aka = 1;
776                         break;
777                 }
778                 pos++;
779         }
780
781         free(ssid->identity);
782         ssid->identity = malloc(1 + imsi_len);
783         if (ssid->identity == NULL) {
784                 wpa_printf(MSG_WARNING, "Failed to allocate buffer for "
785                            "IMSI-based identity");
786                 return -1;
787         }
788
789         ssid->identity[0] = aka ? '0' : '1';
790         memcpy(ssid->identity + 1, imsi, imsi_len);
791         ssid->identity_len = 1 + imsi_len;
792         return 0;
793 }
794
795
796 static int eap_sm_get_scard_identity(struct eap_sm *sm, struct wpa_ssid *ssid)
797 {
798         if (scard_set_pin(sm->scard_ctx, ssid->pin)) {
799                 /*
800                  * Make sure the same PIN is not tried again in order to avoid
801                  * blocking SIM.
802                  */
803                 free(ssid->pin);
804                 ssid->pin = NULL;
805
806                 wpa_printf(MSG_WARNING, "PIN validation failed");
807                 eap_sm_request_pin(sm, ssid);
808                 return -1;
809         }
810
811         return eap_sm_imsi_identity(sm, ssid);
812 }
813
814
815 /**
816  * eap_sm_buildIdentity - Build EAP-Identity/Response for the current network
817  * @sm: Pointer to EAP state machine allocated with eap_sm_init()
818  * @id: EAP identifier for the packet
819  * @len: Pointer to variable that will be set to the length of the response
820  * @encrypted: Whether the packet is for enrypted tunnel (EAP phase 2)
821  * Returns: Pointer to the allocated EAP-Identity/Response packet or %NULL on
822  * failure
823  *
824  * This function allocates and builds an EAP-Identity/Response packet for the
825  * current network. The caller is responsible for freeing the returned data.
826  */
827 u8 * eap_sm_buildIdentity(struct eap_sm *sm, int id, size_t *len,
828                           int encrypted)
829 {
830         struct wpa_ssid *config = eap_get_config(sm);
831         struct eap_hdr *resp;
832         u8 *pos;
833         const u8 *identity;
834         size_t identity_len;
835
836         if (config == NULL) {
837                 wpa_printf(MSG_WARNING, "EAP: buildIdentity: configuration "
838                            "was not available");
839                 return NULL;
840         }
841
842         if (sm->m && sm->m->get_identity &&
843             (identity = sm->m->get_identity(sm, sm->eap_method_priv,
844                                             &identity_len)) != NULL) {
845                 wpa_hexdump_ascii(MSG_DEBUG, "EAP: using method re-auth "
846                                   "identity", identity, identity_len);
847         } else if (!encrypted && config->anonymous_identity) {
848                 identity = config->anonymous_identity;
849                 identity_len = config->anonymous_identity_len;
850                 wpa_hexdump_ascii(MSG_DEBUG, "EAP: using anonymous identity",
851                                   identity, identity_len);
852         } else {
853                 identity = config->identity;
854                 identity_len = config->identity_len;
855                 wpa_hexdump_ascii(MSG_DEBUG, "EAP: using real identity",
856                                   identity, identity_len);
857         }
858
859         if (identity == NULL) {
860                 wpa_printf(MSG_WARNING, "EAP: buildIdentity: identity "
861                            "configuration was not available");
862                 if (config->pcsc) {
863                         if (eap_sm_get_scard_identity(sm, config) < 0)
864                                 return NULL;
865                         identity = config->identity;
866                         identity_len = config->identity_len;
867                         wpa_hexdump_ascii(MSG_DEBUG, "permanent identity from "
868                                           "IMSI", identity, identity_len);
869                 } else {
870                         eap_sm_request_identity(sm, config);
871                         return NULL;
872                 }
873         }
874
875
876         *len = sizeof(struct eap_hdr) + 1 + identity_len;
877         resp = malloc(*len);
878         if (resp == NULL)
879                 return NULL;
880
881         resp->code = EAP_CODE_RESPONSE;
882         resp->identifier = id;
883         resp->length = host_to_be16(*len);
884         pos = (u8 *) (resp + 1);
885         *pos++ = EAP_TYPE_IDENTITY;
886         memcpy(pos, identity, identity_len);
887
888         return (u8 *) resp;
889 }
890
891
892 static void eap_sm_processNotify(struct eap_sm *sm, const u8 *req, size_t len)
893 {
894         const struct eap_hdr *hdr = (const struct eap_hdr *) req;
895         const u8 *pos;
896         char *msg;
897         size_t msg_len;
898         int i;
899
900         pos = (const u8 *) (hdr + 1);
901         pos++;
902
903         msg_len = be_to_host16(hdr->length);
904         if (msg_len < 5)
905                 return;
906         msg_len -= 5;
907         wpa_hexdump_ascii(MSG_DEBUG, "EAP: EAP-Request Notification data",
908                           pos, msg_len);
909
910         msg = malloc(msg_len + 1);
911         if (msg == NULL)
912                 return;
913         for (i = 0; i < msg_len; i++)
914                 msg[i] = isprint(pos[i]) ? (char) pos[i] : '_';
915         msg[msg_len] = '\0';
916         wpa_msg(sm->msg_ctx, MSG_INFO, "%s%s",
917                 WPA_EVENT_EAP_NOTIFICATION, msg);
918         free(msg);
919 }
920
921
922 static u8 *eap_sm_buildNotify(struct eap_sm *sm, int id, size_t *len)
923 {
924         struct eap_hdr *resp;
925         u8 *pos;
926
927         wpa_printf(MSG_DEBUG, "EAP: Generating EAP-Response Notification");
928         *len = sizeof(struct eap_hdr) + 1;
929         resp = malloc(*len);
930         if (resp == NULL)
931                 return NULL;
932
933         resp->code = EAP_CODE_RESPONSE;
934         resp->identifier = id;
935         resp->length = host_to_be16(*len);
936         pos = (u8 *) (resp + 1);
937         *pos = EAP_TYPE_NOTIFICATION;
938
939         return (u8 *) resp;
940 }
941
942
943 static void eap_sm_parseEapReq(struct eap_sm *sm, const u8 *req, size_t len)
944 {
945         const struct eap_hdr *hdr;
946         size_t plen;
947
948         sm->rxReq = sm->rxSuccess = sm->rxFailure = FALSE;
949         sm->reqId = 0;
950         sm->reqMethod = EAP_TYPE_NONE;
951
952         if (req == NULL || len < sizeof(*hdr))
953                 return;
954
955         hdr = (const struct eap_hdr *) req;
956         plen = be_to_host16(hdr->length);
957         if (plen > len) {
958                 wpa_printf(MSG_DEBUG, "EAP: Ignored truncated EAP-Packet "
959                            "(len=%lu plen=%lu)",
960                            (unsigned long) len, (unsigned long) plen);
961                 return;
962         }
963
964         sm->reqId = hdr->identifier;
965
966         if (sm->workaround) {
967                 md5_vector(1, (const u8 **) &req, &len, sm->req_md5);
968         }
969
970         switch (hdr->code) {
971         case EAP_CODE_REQUEST:
972                 sm->rxReq = TRUE;
973                 if (plen > sizeof(*hdr))
974                         sm->reqMethod = *((u8 *) (hdr + 1));
975                 wpa_printf(MSG_DEBUG, "EAP: Received EAP-Request method=%d "
976                            "id=%d", sm->reqMethod, sm->reqId);
977                 break;
978         case EAP_CODE_RESPONSE:
979                 if (sm->selectedMethod == EAP_TYPE_LEAP) {
980                         sm->rxResp = TRUE;
981                         if (plen > sizeof(*hdr))
982                                 sm->reqMethod = *((u8 *) (hdr + 1));
983                         wpa_printf(MSG_DEBUG, "EAP: Received EAP-Response for "
984                                    "LEAP method=%d id=%d",
985                                    sm->reqMethod, sm->reqId);
986                         break;
987                 }
988                 wpa_printf(MSG_DEBUG, "EAP: Ignored EAP-Response");
989                 break;
990         case EAP_CODE_SUCCESS:
991                 wpa_printf(MSG_DEBUG, "EAP: Received EAP-Success");
992                 sm->rxSuccess = TRUE;
993                 break;
994         case EAP_CODE_FAILURE:
995                 wpa_printf(MSG_DEBUG, "EAP: Received EAP-Failure");
996                 sm->rxFailure = TRUE;
997                 break;
998         default:
999                 wpa_printf(MSG_DEBUG, "EAP: Ignored EAP-Packet with unknown "
1000                            "code %d", hdr->code);
1001                 break;
1002         }
1003 }
1004
1005
1006 /**
1007  * eap_sm_init - Allocate and initialize EAP state machine
1008  * @eapol_ctx: Context data to be used with eapol_cb calls
1009  * @eapol_cb: Pointer to EAPOL callback functions
1010  * @msg_ctx: Context data for wpa_msg() calls
1011  * @conf: EAP configuration
1012  * Returns: Pointer to the allocated EAP state machine or %NULL on failure
1013  *
1014  * This function allocates and initializes an EAP state machine. In addition,
1015  * this initializes TLS library for the new EAP state machine.
1016  */
1017 struct eap_sm * eap_sm_init(void *eapol_ctx, struct eapol_callbacks *eapol_cb,
1018                             void *msg_ctx, struct eap_config *conf)
1019 {
1020         struct eap_sm *sm;
1021         struct tls_config tlsconf;
1022
1023         sm = malloc(sizeof(*sm));
1024         if (sm == NULL)
1025                 return NULL;
1026         memset(sm, 0, sizeof(*sm));
1027         sm->eapol_ctx = eapol_ctx;
1028         sm->eapol_cb = eapol_cb;
1029         sm->msg_ctx = msg_ctx;
1030         sm->ClientTimeout = 60;
1031
1032         memset(&tlsconf, 0, sizeof(tlsconf));
1033         tlsconf.opensc_engine_path = conf->opensc_engine_path;
1034         tlsconf.pkcs11_engine_path = conf->pkcs11_engine_path;
1035         tlsconf.pkcs11_module_path = conf->pkcs11_module_path;
1036         sm->ssl_ctx = tls_init(&tlsconf);
1037         if (sm->ssl_ctx == NULL) {
1038                 wpa_printf(MSG_WARNING, "SSL: Failed to initialize TLS "
1039                            "context.");
1040                 free(sm);
1041                 return NULL;
1042         }
1043
1044         return sm;
1045 }
1046
1047
1048 /**
1049  * eap_sm_deinit - Deinitialize and free an EAP state machine
1050  * @sm: Pointer to EAP state machine allocated with eap_sm_init()
1051  *
1052  * This function deinitializes EAP state machine and frees all allocated
1053  * resources.
1054  */
1055 void eap_sm_deinit(struct eap_sm *sm)
1056 {
1057         if (sm == NULL)
1058                 return;
1059         eap_deinit_prev_method(sm, "EAP deinit");
1060         free(sm->lastRespData);
1061         free(sm->eapRespData);
1062         free(sm->eapKeyData);
1063         tls_deinit(sm->ssl_ctx);
1064         free(sm);
1065 }
1066
1067
1068 /**
1069  * eap_sm_step - Step EAP state machine
1070  * @sm: Pointer to EAP state machine allocated with eap_sm_init()
1071  * Returns: 1 if EAP state was changed or 0 if not
1072  *
1073  * This function advances EAP state machine to a new state to match with the
1074  * current variables. This should be called whenever variables used by the EAP
1075  * state machine have changed.
1076  */
1077 int eap_sm_step(struct eap_sm *sm)
1078 {
1079         int res = 0;
1080         do {
1081                 sm->changed = FALSE;
1082                 SM_STEP_RUN(EAP);
1083                 if (sm->changed)
1084                         res = 1;
1085         } while (sm->changed);
1086         return res;
1087 }
1088
1089
1090 /**
1091  * eap_sm_abort - Abort EAP authentication
1092  * @sm: Pointer to EAP state machine allocated with eap_sm_init()
1093  *
1094  * Release system resources that have been allocated for the authentication
1095  * session without fully deinitializing the EAP state machine.
1096  */
1097 void eap_sm_abort(struct eap_sm *sm)
1098 {
1099         free(sm->eapRespData);
1100         sm->eapRespData = NULL;
1101         free(sm->eapKeyData);
1102         sm->eapKeyData = NULL;
1103 }
1104
1105
1106 static const char * eap_sm_state_txt(int state)
1107 {
1108         switch (state) {
1109         case EAP_INITIALIZE:
1110                 return "INITIALIZE";
1111         case EAP_DISABLED:
1112                 return "DISABLED";
1113         case EAP_IDLE:
1114                 return "IDLE";
1115         case EAP_RECEIVED:
1116                 return "RECEIVED";
1117         case EAP_GET_METHOD:
1118                 return "GET_METHOD";
1119         case EAP_METHOD:
1120                 return "METHOD";
1121         case EAP_SEND_RESPONSE:
1122                 return "SEND_RESPONSE";
1123         case EAP_DISCARD:
1124                 return "DISCARD";
1125         case EAP_IDENTITY:
1126                 return "IDENTITY";
1127         case EAP_NOTIFICATION:
1128                 return "NOTIFICATION";
1129         case EAP_RETRANSMIT:
1130                 return "RETRANSMIT";
1131         case EAP_SUCCESS:
1132                 return "SUCCESS";
1133         case EAP_FAILURE:
1134                 return "FAILURE";
1135         default:
1136                 return "UNKNOWN";
1137         }
1138 }
1139
1140
1141 static const char * eap_sm_method_state_txt(int state)
1142 {
1143         switch (state) {
1144         case METHOD_NONE:
1145                 return "NONE";
1146         case METHOD_INIT:
1147                 return "INIT";
1148         case METHOD_CONT:
1149                 return "CONT";
1150         case METHOD_MAY_CONT:
1151                 return "MAY_CONT";
1152         case METHOD_DONE:
1153                 return "DONE";
1154         default:
1155                 return "UNKNOWN";
1156         }
1157 }
1158
1159
1160 static const char * eap_sm_decision_txt(int decision)
1161 {
1162         switch (decision) {
1163         case DECISION_FAIL:
1164                 return "FAIL";
1165         case DECISION_COND_SUCC:
1166                 return "COND_SUCC";
1167         case DECISION_UNCOND_SUCC:
1168                 return "UNCOND_SUCC";
1169         default:
1170                 return "UNKNOWN";
1171         }
1172 }
1173
1174
1175 /**
1176  * eap_sm_get_status - Get EAP state machine status
1177  * @sm: Pointer to EAP state machine allocated with eap_sm_init()
1178  * @buf: buffer for status information
1179  * @buflen: maximum buffer length
1180  * @verbose: whether to include verbose status information
1181  * Returns: number of bytes written to buf.
1182  *
1183  * Query EAP state machine for status information. This function fills in a
1184  * text area with current status information from the EAPOL state machine. If
1185  * the buffer (buf) is not large enough, status information will be truncated
1186  * to fit the buffer.
1187  */
1188 int eap_sm_get_status(struct eap_sm *sm, char *buf, size_t buflen, int verbose)
1189 {
1190         int len;
1191
1192         if (sm == NULL)
1193                 return 0;
1194
1195         len = snprintf(buf, buflen,
1196                        "EAP state=%s\n",
1197                        eap_sm_state_txt(sm->EAP_state));
1198
1199         if (sm->selectedMethod != EAP_TYPE_NONE) {
1200                 const char *name;
1201                 if (sm->m) {
1202                         name = sm->m->name;
1203                 } else {
1204                         const struct eap_method *m =
1205                                 eap_sm_get_eap_methods(sm->selectedMethod);
1206                         if (m)
1207                                 name = m->name;
1208                         else
1209                                 name = "?";
1210                 }
1211                 len += snprintf(buf + len, buflen - len,
1212                                 "selectedMethod=%d (EAP-%s)\n",
1213                                 sm->selectedMethod, name);
1214
1215                 if (sm->m && sm->m->get_status) {
1216                         len += sm->m->get_status(sm, sm->eap_method_priv,
1217                                                  buf + len, buflen - len,
1218                                                  verbose);
1219                 }
1220         }
1221
1222         if (verbose) {
1223                 len += snprintf(buf + len, buflen - len,
1224                                 "reqMethod=%d\n"
1225                                 "methodState=%s\n"
1226                                 "decision=%s\n"
1227                                 "ClientTimeout=%d\n",
1228                                 sm->reqMethod,
1229                                 eap_sm_method_state_txt(sm->methodState),
1230                                 eap_sm_decision_txt(sm->decision),
1231                                 sm->ClientTimeout);
1232         }
1233
1234         return len;
1235 }
1236
1237
1238 typedef enum {
1239         TYPE_IDENTITY, TYPE_PASSWORD, TYPE_OTP, TYPE_PIN, TYPE_NEW_PASSWORD,
1240         TYPE_PASSPHRASE
1241 } eap_ctrl_req_type;
1242
1243 static void eap_sm_request(struct eap_sm *sm, struct wpa_ssid *config,
1244                            eap_ctrl_req_type type, const char *msg,
1245                            size_t msglen)
1246 {
1247         char *buf;
1248         size_t buflen;
1249         int len;
1250         char *field;
1251         char *txt, *tmp;
1252
1253         if (config == NULL || sm == NULL)
1254                 return;
1255
1256         switch (type) {
1257         case TYPE_IDENTITY:
1258                 field = "IDENTITY";
1259                 txt = "Identity";
1260                 config->pending_req_identity++;
1261                 break;
1262         case TYPE_PASSWORD:
1263                 field = "PASSWORD";
1264                 txt = "Password";
1265                 config->pending_req_password++;
1266                 break;
1267         case TYPE_NEW_PASSWORD:
1268                 field = "NEW_PASSWORD";
1269                 txt = "New Password";
1270                 config->pending_req_new_password++;
1271                 break;
1272         case TYPE_PIN:
1273                 field = "PIN";
1274                 txt = "PIN";
1275                 config->pending_req_pin++;
1276                 break;
1277         case TYPE_OTP:
1278                 field = "OTP";
1279                 if (msg) {
1280                         tmp = malloc(msglen + 3);
1281                         if (tmp == NULL)
1282                                 return;
1283                         tmp[0] = '[';
1284                         memcpy(tmp + 1, msg, msglen);
1285                         tmp[msglen + 1] = ']';
1286                         tmp[msglen + 2] = '\0';
1287                         txt = tmp;
1288                         free(config->pending_req_otp);
1289                         config->pending_req_otp = tmp;
1290                         config->pending_req_otp_len = msglen + 3;
1291                 } else {
1292                         if (config->pending_req_otp == NULL)
1293                                 return;
1294                         txt = config->pending_req_otp;
1295                 }
1296                 break;
1297         case TYPE_PASSPHRASE:
1298                 field = "PASSPHRASE";
1299                 txt = "Private key passphrase";
1300                 config->pending_req_passphrase++;
1301                 break;
1302         default:
1303                 return;
1304         }
1305
1306         buflen = 100 + strlen(txt) + config->ssid_len;
1307         buf = malloc(buflen);
1308         if (buf == NULL)
1309                 return;
1310         len = snprintf(buf, buflen, WPA_CTRL_REQ "%s-%d:%s needed for SSID ",
1311                        field, config->id, txt);
1312         if (config->ssid && buflen > len + config->ssid_len) {
1313                 memcpy(buf + len, config->ssid, config->ssid_len);
1314                 len += config->ssid_len;
1315                 buf[len] = '\0';
1316         }
1317         wpa_msg(sm->msg_ctx, MSG_INFO, "%s", buf);
1318         free(buf);
1319 }
1320
1321
1322 /**
1323  * eap_sm_request_identity - Request identity from user (ctrl_iface)
1324  * @sm: Pointer to EAP state machine allocated with eap_sm_init()
1325  * @config: Pointer to the current network configuration
1326  *
1327  * EAP methods can call this function to request identity information for the
1328  * current network. This is normally called when the identity is not included
1329  * in the network configuration. The request will be sent to monitor programs
1330  * through the control interface.
1331  */
1332 void eap_sm_request_identity(struct eap_sm *sm, struct wpa_ssid *config)
1333 {
1334         eap_sm_request(sm, config, TYPE_IDENTITY, NULL, 0);
1335 }
1336
1337
1338 /**
1339  * eap_sm_request_password - Request password from user (ctrl_iface)
1340  * @sm: Pointer to EAP state machine allocated with eap_sm_init()
1341  * @config: Pointer to the current network configuration
1342  *
1343  * EAP methods can call this function to request password information for the
1344  * current network. This is normally called when the password is not included
1345  * in the network configuration. The request will be sent to monitor programs
1346  * through the control interface.
1347  */
1348 void eap_sm_request_password(struct eap_sm *sm, struct wpa_ssid *config)
1349 {
1350         eap_sm_request(sm, config, TYPE_PASSWORD, NULL, 0);
1351 }
1352
1353
1354 /**
1355  * eap_sm_request_new_password - Request new password from user (ctrl_iface)
1356  * @sm: Pointer to EAP state machine allocated with eap_sm_init()
1357  * @config: Pointer to the current network configuration
1358  *
1359  * EAP methods can call this function to request new password information for
1360  * the current network. This is normally called when the EAP method indicates
1361  * that the current password has expired and password change is required. The
1362  * request will be sent to monitor programs through the control interface.
1363  */
1364 void eap_sm_request_new_password(struct eap_sm *sm, struct wpa_ssid *config)
1365 {
1366         eap_sm_request(sm, config, TYPE_NEW_PASSWORD, NULL, 0);
1367 }
1368
1369
1370 /**
1371  * eap_sm_request_pin - Request SIM or smart card PIN from user (ctrl_iface)
1372  * @sm: Pointer to EAP state machine allocated with eap_sm_init()
1373  * @config: Pointer to the current network configuration
1374  *
1375  * EAP methods can call this function to request SIM or smart card PIN
1376  * information for the current network. This is normally called when the PIN is
1377  * not included in the network configuration. The request will be sent to
1378  * monitor programs through the control interface.
1379  */
1380 void eap_sm_request_pin(struct eap_sm *sm, struct wpa_ssid *config)
1381 {
1382         eap_sm_request(sm, config, TYPE_PIN, NULL, 0);
1383 }
1384
1385
1386 /**
1387  * eap_sm_request_otp - Request one time password from user (ctrl_iface)
1388  * @sm: Pointer to EAP state machine allocated with eap_sm_init()
1389  * @config: Pointer to the current network configuration
1390  * @msg: Message to be displayed to the user when asking for OTP
1391  * @msg_len: Length of the user displayable message
1392  *
1393  * EAP methods can call this function to request open time password (OTP) for
1394  * the current network. The request will be sent to monitor programs through
1395  * the control interface.
1396  */
1397 void eap_sm_request_otp(struct eap_sm *sm, struct wpa_ssid *config,
1398                         const char *msg, size_t msg_len)
1399 {
1400         eap_sm_request(sm, config, TYPE_OTP, msg, msg_len);
1401 }
1402
1403
1404 /**
1405  * eap_sm_request_passphrase - Request passphrase from user (ctrl_iface)
1406  * @sm: Pointer to EAP state machine allocated with eap_sm_init()
1407  * @config: Pointer to the current network configuration
1408  *
1409  * EAP methods can call this function to request passphrase for a private key
1410  * for the current network. This is normally called when the passphrase is not
1411  * included in the network configuration. The request will be sent to monitor
1412  * programs through the control interface.
1413  */
1414 void eap_sm_request_passphrase(struct eap_sm *sm, struct wpa_ssid *config)
1415 {
1416         eap_sm_request(sm, config, TYPE_PASSPHRASE, NULL, 0);
1417 }
1418
1419
1420 /**
1421  * eap_sm_notify_ctrl_attached - Notification of attached monitor
1422  * @sm: Pointer to EAP state machine allocated with eap_sm_init()
1423  *
1424  * Notify EAP state machines that a monitor was attached to the control
1425  * interface to trigger re-sending of pending requests for user input.
1426  */
1427 void eap_sm_notify_ctrl_attached(struct eap_sm *sm)
1428 {
1429         struct wpa_ssid *config = eap_get_config(sm);
1430
1431         if (config == NULL)
1432                 return;
1433
1434         /* Re-send any pending requests for user data since a new control
1435          * interface was added. This handles cases where the EAP authentication
1436          * starts immediately after system startup when the user interface is
1437          * not yet running. */
1438         if (config->pending_req_identity)
1439                 eap_sm_request_identity(sm, config);
1440         if (config->pending_req_password)
1441                 eap_sm_request_password(sm, config);
1442         if (config->pending_req_new_password)
1443                 eap_sm_request_new_password(sm, config);
1444         if (config->pending_req_otp)
1445                 eap_sm_request_otp(sm, config, NULL, 0);
1446         if (config->pending_req_pin)
1447                 eap_sm_request_pin(sm, config);
1448         if (config->pending_req_passphrase)
1449                 eap_sm_request_passphrase(sm, config);
1450 }
1451
1452
1453 /**
1454  * eap_get_type - Get EAP type for the given EAP method name
1455  * @name: EAP method name, e.g., TLS
1456  * Returns: EAP method type or %EAP_TYPE_NONE if not found
1457  *
1458  * This function maps EAP type names into EAP type numbers based on the list of
1459  * EAP methods included in the build.
1460  */
1461 u8 eap_get_type(const char *name)
1462 {
1463         int i;
1464         for (i = 0; i < NUM_EAP_METHODS; i++) {
1465                 if (strcmp(eap_methods[i]->name, name) == 0)
1466                         return eap_methods[i]->method;
1467         }
1468         return EAP_TYPE_NONE;
1469 }
1470
1471
1472 /**
1473  * eap_get_name - Get EAP method name for the given EAP type
1474  * @type: EAP method type
1475  * Returns: EAP method name, e.g., TLS, or %NULL if not found
1476  *
1477  * This function maps EAP type numbers into EAP type names based on the list of
1478  * EAP methods included in the build.
1479  */
1480 const char * eap_get_name(EapType type)
1481 {
1482         int i;
1483         for (i = 0; i < NUM_EAP_METHODS; i++) {
1484                 if (eap_methods[i]->method == type)
1485                         return eap_methods[i]->name;
1486         }
1487         return NULL;
1488 }
1489
1490
1491 /**
1492  * eap_get_names - Get space separated list of names for supported EAP methods
1493  * @buf: Buffer for names
1494  * @buflen: Buffer length
1495  * Returns: Number of characters written into buf (not including nul
1496  * termination)
1497  */
1498 size_t eap_get_names(char *buf, size_t buflen)
1499 {
1500         char *pos, *end;
1501         int i;
1502
1503         pos = buf;
1504         end = pos + buflen;
1505
1506         for (i = 0; i < NUM_EAP_METHODS; i++) {
1507                 pos += snprintf(pos, end - pos, "%s%s",
1508                                 i == 0 ? "" : " ", eap_methods[i]->name);
1509         }
1510
1511         return pos - buf;
1512 }
1513
1514
1515 static int eap_allowed_phase2_type(int type)
1516 {
1517         return type != EAP_TYPE_PEAP && type != EAP_TYPE_TTLS &&
1518                 type != EAP_TYPE_FAST;
1519 }
1520
1521
1522 /**
1523  * eap_get_phase2_type - Get EAP type for the given EAP phase 2 method name
1524  * @name: EAP method name, e.g., MD5
1525  * Returns: EAP method type or %EAP_TYPE_NONE if not found
1526  *
1527  * This function maps EAP type names into EAP type numbers that are allowed for
1528  * Phase 2, i.e., for tunneled authentication. Phase 2 is used, e.g., with
1529  * EAP-PEAP, EAP-TTLS, and EAP-FAST.
1530  */
1531 u8 eap_get_phase2_type(const char *name)
1532 {
1533         u8 type = eap_get_type(name);
1534         if (eap_allowed_phase2_type(type))
1535                 return type;
1536         return EAP_TYPE_NONE;
1537 }
1538
1539
1540 /**
1541  * eap_get_phase2_types - Get list of allowed EAP phase 2 types
1542  * @config: Pointer to a network configuration
1543  * @count: Pointer to variable filled with number of returned EAP types
1544  * Returns: Pointer to allocated type list or %NULL on failure
1545  *
1546  * This function generates an array of allowed EAP phase 2 (tunneled) types for
1547  * the given network configuration.
1548  */
1549 u8 *eap_get_phase2_types(struct wpa_ssid *config, size_t *count)
1550 {
1551         u8 *buf, method;
1552         int i;
1553
1554         *count = 0;
1555         buf = malloc(NUM_EAP_METHODS);
1556         if (buf == NULL)
1557                 return NULL;
1558
1559         for (i = 0; i < NUM_EAP_METHODS; i++) {
1560                 method = eap_methods[i]->method;
1561                 if (eap_allowed_phase2_type(method)) {
1562                         if (method == EAP_TYPE_TLS && config &&
1563                             config->private_key2 == NULL)
1564                                 continue;
1565                         buf[*count] = method;
1566                         (*count)++;
1567                 }
1568         }
1569
1570         return buf;
1571 }
1572
1573
1574 /**
1575  * eap_set_fast_reauth - Update fast_reauth setting
1576  * @sm: Pointer to EAP state machine allocated with eap_sm_init()
1577  * @enabled: 1 = fast reauthentication is enabled, 0 = disabled
1578  */
1579 void eap_set_fast_reauth(struct eap_sm *sm, int enabled)
1580 {
1581         sm->fast_reauth = enabled;
1582 }
1583
1584
1585 /**
1586  * eap_set_workaround - Update EAP workarounds setting
1587  * @sm: Pointer to EAP state machine allocated with eap_sm_init()
1588  * @workaround: 1 = Enable EAP workarounds, 0 = Disable EAP workarounds
1589  */
1590 void eap_set_workaround(struct eap_sm *sm, unsigned int workaround)
1591 {
1592         sm->workaround = workaround;
1593 }
1594
1595
1596 /**
1597  * eap_get_config - Get current network configuration
1598  * @sm: Pointer to EAP state machine allocated with eap_sm_init()
1599  * Returns: Pointer to the current network configuration or %NULL if not found
1600  */
1601 struct wpa_ssid * eap_get_config(struct eap_sm *sm)
1602 {
1603         return sm->eapol_cb->get_config(sm->eapol_ctx);
1604 }
1605
1606
1607 /**
1608  * eap_key_available - Get key availability (eapKeyAvailable variable)
1609  * @sm: Pointer to EAP state machine allocated with eap_sm_init()
1610  * Returns: 1 if EAP keying material is available, 0 if not
1611  */
1612 int eap_key_available(struct eap_sm *sm)
1613 {
1614         return sm ? sm->eapKeyAvailable : 0;
1615 }
1616
1617
1618 /**
1619  * eap_notify_success - Notify EAP state machine about external success trigger
1620  * @sm: Pointer to EAP state machine allocated with eap_sm_init()
1621  *
1622  * This function is called when external event, e.g., successful completion of
1623  * WPA-PSK key handshake, is indicating that EAP state machine should move to
1624  * success state. This is mainly used with security modes that do not use EAP
1625  * state machine (e.g., WPA-PSK).
1626  */
1627 void eap_notify_success(struct eap_sm *sm)
1628 {
1629         if (sm) {
1630                 sm->decision = DECISION_COND_SUCC;
1631                 sm->EAP_state = EAP_SUCCESS;
1632         }
1633 }
1634 /**
1635  * eap_notify_lower_layer_success - Notification of lower layer success
1636  * @sm: Pointer to EAP state machine allocated with eap_sm_init()
1637  *
1638  * Notify EAP state machines that a lower layer has detected a successful
1639  * authentication. This is used to recover from dropped EAP-Success messages.
1640  */
1641 void eap_notify_lower_layer_success(struct eap_sm *sm)
1642 {
1643         if (sm == NULL)
1644                 return;
1645
1646         if (eapol_get_bool(sm, EAPOL_eapSuccess) ||
1647             sm->decision == DECISION_FAIL ||
1648             (sm->methodState != METHOD_MAY_CONT &&
1649              sm->methodState != METHOD_DONE))
1650                 return;
1651
1652         if (sm->eapKeyData != NULL)
1653                 sm->eapKeyAvailable = TRUE;
1654         eapol_set_bool(sm, EAPOL_eapSuccess, TRUE);
1655         wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_SUCCESS
1656                 "EAP authentication completed successfully (based on lower "
1657                 "layer success)");
1658 }
1659
1660
1661 /**
1662  * eap_get_eapKeyData - Get master session key (MSK) from EAP state machine
1663  * @sm: Pointer to EAP state machine allocated with eap_sm_init()
1664  * @len: Pointer to variable that will be set to number of bytes in the key
1665  * Returns: Pointer to the EAP keying data or %NULL on failure
1666  *
1667  * Fetch EAP keying material (MSK, eapKeyData) from the EAP state machine. The
1668  * key is available only after a successful authentication. EAP state machine
1669  * continues to manage the key data and the caller must not change or free the
1670  * returned data.
1671  */
1672 const u8 * eap_get_eapKeyData(struct eap_sm *sm, size_t *len)
1673 {
1674         if (sm == NULL || sm->eapKeyData == NULL) {
1675                 *len = 0;
1676                 return NULL;
1677         }
1678
1679         *len = sm->eapKeyDataLen;
1680         return sm->eapKeyData;
1681 }
1682
1683
1684 /**
1685  * eap_get_eapKeyData - Get EAP response data
1686  * @sm: Pointer to EAP state machine allocated with eap_sm_init()
1687  * @len: Pointer to variable that will be set to the length of the response
1688  * Returns: Pointer to the EAP response (eapRespData) or %NULL on failure
1689  *
1690  * Fetch EAP response (eapRespData) from the EAP state machine. This data is
1691  * available when EAP state machine has processed an incoming EAP request. The
1692  * EAP state machine does not maintain a reference to the response after this
1693  * function is called and the caller is responsible for freeing the data.
1694  */
1695 u8 * eap_get_eapRespData(struct eap_sm *sm, size_t *len)
1696 {
1697         u8 *resp;
1698
1699         if (sm == NULL || sm->eapRespData == NULL) {
1700                 *len = 0;
1701                 return NULL;
1702         }
1703
1704         resp = sm->eapRespData;
1705         *len = sm->eapRespDataLen;
1706         sm->eapRespData = NULL;
1707         sm->eapRespDataLen = 0;
1708
1709         return resp;
1710 }
1711
1712
1713 /**
1714  * eap_sm_register_scard_ctx - Notification of smart card context
1715  * @sm: Pointer to EAP state machine allocated with eap_sm_init()
1716  * @ctx: context data for smart card operations
1717  *
1718  * Notify EAP state machines of context data for smart card operations. This
1719  * context data will be used as a parameter for scard_*() functions.
1720  */
1721 void eap_register_scard_ctx(struct eap_sm *sm, void *ctx)
1722 {
1723         if (sm)
1724                 sm->scard_ctx = ctx;
1725 }
1726
1727
1728 /**
1729  * eap_hdr_validate - Validate EAP header
1730  * @eap_type: Expected EAP type number
1731  * @msg: EAP frame (starting with EAP header)
1732  * @msglen: Length of msg
1733  * @plen: Pointer for return payload length
1734  * Returns: Pointer to EAP payload (after type field), or %NULL on failure
1735  *
1736  * This is a helper function for EAP method implementations. This is usually
1737  * called in the beginning of struct eap_method::process() function.
1738  */
1739 const u8 * eap_hdr_validate(EapType eap_type, const u8 *msg, size_t msglen,
1740                             size_t *plen)
1741 {
1742         const struct eap_hdr *hdr;
1743         const u8 *pos;
1744         size_t len;
1745
1746         hdr = (const struct eap_hdr *) msg;
1747         pos = (const u8 *) (hdr + 1);
1748         if (msglen < sizeof(*hdr) + 1 || *pos != eap_type) {
1749                 wpa_printf(MSG_INFO, "EAP: Invalid frame type");
1750                 return NULL;
1751         }
1752         len = be_to_host16(hdr->length);
1753         if (len < sizeof(*hdr) + 1 || len > msglen) {
1754                 wpa_printf(MSG_INFO, "EAP: Invalid EAP length");
1755                 return NULL;
1756         }
1757         *plen = len - sizeof(*hdr) - 1;
1758         return pos + 1;
1759 }
1760
1761
1762 /**
1763  * eap_set_config_blob - Set or add a named configuration blob
1764  * @sm: Pointer to EAP state machine allocated with eap_sm_init()
1765  * @blob: New value for the blob
1766  *
1767  * Adds a new configuration blob or replaces the current value of an existing
1768  * blob.
1769  */
1770 void eap_set_config_blob(struct eap_sm *sm, struct wpa_config_blob *blob)
1771 {
1772         sm->eapol_cb->set_config_blob(sm->eapol_ctx, blob);
1773 }
1774
1775
1776 /**
1777  * eap_get_config_blob - Get a named configuration blob
1778  * @sm: Pointer to EAP state machine allocated with eap_sm_init()
1779  * @name: Name of the blob
1780  * Returns: Pointer to blob data or %NULL if not found
1781  */
1782 const struct wpa_config_blob * eap_get_config_blob(struct eap_sm *sm,
1783                                                    const char *name)
1784 {
1785         return sm->eapol_cb->get_config_blob(sm->eapol_ctx, name);
1786 }
1787
1788
1789 /**
1790  * eap_set_force_disabled - Set force_disabled flag
1791  * @sm: Pointer to EAP state machine allocated with eap_sm_init()
1792  * @disabled: 1 = EAP disabled, 0 = EAP enabled
1793  *
1794  * This function is used to force EAP state machine to be disabled when it is
1795  * not in use (e.g., with WPA-PSK or plaintext connections).
1796  */
1797 void eap_set_force_disabled(struct eap_sm *sm, int disabled)
1798 {
1799         sm->force_disabled = disabled;
1800 }