Update changes file and submitted to OBS
[framework/connectivity/wpasupplicant.git] / src / eap_server / eap_server.c
1 /*
2  * hostapd / EAP Full Authenticator state machine (RFC 4137)
3  * Copyright (c) 2004-2007, Jouni Malinen <j@w1.fi>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation.
8  *
9  * Alternatively, this software may be distributed under the terms of BSD
10  * license.
11  *
12  * See README and COPYING for more details.
13  *
14  * This state machine is based on the full authenticator state machine defined
15  * in RFC 4137. However, to support backend authentication in RADIUS
16  * authentication server functionality, parts of backend authenticator (also
17  * from RFC 4137) are mixed in. This functionality is enabled by setting
18  * backend_auth configuration variable to TRUE.
19  */
20
21 #include "includes.h"
22
23 #include "common.h"
24 #include "eap_i.h"
25 #include "state_machine.h"
26 #include "common/wpa_ctrl.h"
27
28 #define STATE_MACHINE_DATA struct eap_sm
29 #define STATE_MACHINE_DEBUG_PREFIX "EAP"
30
31 #define EAP_MAX_AUTH_ROUNDS 50
32
33 static void eap_user_free(struct eap_user *user);
34
35
36 /* EAP state machines are described in RFC 4137 */
37
38 static int eap_sm_calculateTimeout(struct eap_sm *sm, int retransCount,
39                                    int eapSRTT, int eapRTTVAR,
40                                    int methodTimeout);
41 static void eap_sm_parseEapResp(struct eap_sm *sm, const struct wpabuf *resp);
42 static int eap_sm_getId(const struct wpabuf *data);
43 static struct wpabuf * eap_sm_buildSuccess(struct eap_sm *sm, u8 id);
44 static struct wpabuf * eap_sm_buildFailure(struct eap_sm *sm, u8 id);
45 static int eap_sm_nextId(struct eap_sm *sm, int id);
46 static void eap_sm_Policy_update(struct eap_sm *sm, const u8 *nak_list,
47                                  size_t len);
48 static EapType eap_sm_Policy_getNextMethod(struct eap_sm *sm, int *vendor);
49 static int eap_sm_Policy_getDecision(struct eap_sm *sm);
50 static Boolean eap_sm_Policy_doPickUp(struct eap_sm *sm, EapType method);
51
52
53 static int eap_copy_buf(struct wpabuf **dst, const struct wpabuf *src)
54 {
55         if (src == NULL)
56                 return -1;
57
58         wpabuf_free(*dst);
59         *dst = wpabuf_dup(src);
60         return *dst ? 0 : -1;
61 }
62
63
64 static int eap_copy_data(u8 **dst, size_t *dst_len,
65                          const u8 *src, size_t src_len)
66 {
67         if (src == NULL)
68                 return -1;
69
70         os_free(*dst);
71         *dst = os_malloc(src_len);
72         if (*dst) {
73                 os_memcpy(*dst, src, src_len);
74                 *dst_len = src_len;
75                 return 0;
76         } else {
77                 *dst_len = 0;
78                 return -1;
79         }
80 }
81
82 #define EAP_COPY(dst, src) \
83         eap_copy_data((dst), (dst ## Len), (src), (src ## Len))
84
85
86 /**
87  * eap_user_get - Fetch user information from the database
88  * @sm: Pointer to EAP state machine allocated with eap_server_sm_init()
89  * @identity: Identity (User-Name) of the user
90  * @identity_len: Length of identity in bytes
91  * @phase2: 0 = EAP phase1 user, 1 = EAP phase2 (tunneled) user
92  * Returns: 0 on success, or -1 on failure
93  *
94  * This function is used to fetch user information for EAP. The user will be
95  * selected based on the specified identity. sm->user and
96  * sm->user_eap_method_index are updated for the new user when a matching user
97  * is found. sm->user can be used to get user information (e.g., password).
98  */
99 int eap_user_get(struct eap_sm *sm, const u8 *identity, size_t identity_len,
100                  int phase2)
101 {
102         struct eap_user *user;
103
104         if (sm == NULL || sm->eapol_cb == NULL ||
105             sm->eapol_cb->get_eap_user == NULL)
106                 return -1;
107
108         eap_user_free(sm->user);
109         sm->user = NULL;
110
111         user = os_zalloc(sizeof(*user));
112         if (user == NULL)
113             return -1;
114
115         if (sm->eapol_cb->get_eap_user(sm->eapol_ctx, identity,
116                                        identity_len, phase2, user) != 0) {
117                 eap_user_free(user);
118                 return -1;
119         }
120
121         sm->user = user;
122         sm->user_eap_method_index = 0;
123
124         return 0;
125 }
126
127
128 SM_STATE(EAP, DISABLED)
129 {
130         SM_ENTRY(EAP, DISABLED);
131         sm->num_rounds = 0;
132 }
133
134
135 SM_STATE(EAP, INITIALIZE)
136 {
137         SM_ENTRY(EAP, INITIALIZE);
138
139         if (sm->eap_if.eapRestart && !sm->eap_server && sm->identity) {
140                 /*
141                  * Need to allow internal Identity method to be used instead
142                  * of passthrough at the beginning of reauthentication.
143                  */
144                 eap_server_clear_identity(sm);
145         }
146
147         sm->currentId = -1;
148         sm->eap_if.eapSuccess = FALSE;
149         sm->eap_if.eapFail = FALSE;
150         sm->eap_if.eapTimeout = FALSE;
151         os_free(sm->eap_if.eapKeyData);
152         sm->eap_if.eapKeyData = NULL;
153         sm->eap_if.eapKeyDataLen = 0;
154         sm->eap_if.eapKeyAvailable = FALSE;
155         sm->eap_if.eapRestart = FALSE;
156
157         /*
158          * This is not defined in RFC 4137, but method state needs to be
159          * reseted here so that it does not remain in success state when
160          * re-authentication starts.
161          */
162         if (sm->m && sm->eap_method_priv) {
163                 sm->m->reset(sm, sm->eap_method_priv);
164                 sm->eap_method_priv = NULL;
165         }
166         sm->m = NULL;
167         sm->user_eap_method_index = 0;
168
169         if (sm->backend_auth) {
170                 sm->currentMethod = EAP_TYPE_NONE;
171                 /* parse rxResp, respId, respMethod */
172                 eap_sm_parseEapResp(sm, sm->eap_if.eapRespData);
173                 if (sm->rxResp) {
174                         sm->currentId = sm->respId;
175                 }
176         }
177         sm->num_rounds = 0;
178         sm->method_pending = METHOD_PENDING_NONE;
179
180         wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_STARTED
181                 MACSTR, MAC2STR(sm->peer_addr));
182 }
183
184
185 SM_STATE(EAP, PICK_UP_METHOD)
186 {
187         SM_ENTRY(EAP, PICK_UP_METHOD);
188
189         if (eap_sm_Policy_doPickUp(sm, sm->respMethod)) {
190                 sm->currentMethod = sm->respMethod;
191                 if (sm->m && sm->eap_method_priv) {
192                         sm->m->reset(sm, sm->eap_method_priv);
193                         sm->eap_method_priv = NULL;
194                 }
195                 sm->m = eap_server_get_eap_method(EAP_VENDOR_IETF,
196                                                   sm->currentMethod);
197                 if (sm->m && sm->m->initPickUp) {
198                         sm->eap_method_priv = sm->m->initPickUp(sm);
199                         if (sm->eap_method_priv == NULL) {
200                                 wpa_printf(MSG_DEBUG, "EAP: Failed to "
201                                            "initialize EAP method %d",
202                                            sm->currentMethod);
203                                 sm->m = NULL;
204                                 sm->currentMethod = EAP_TYPE_NONE;
205                         }
206                 } else {
207                         sm->m = NULL;
208                         sm->currentMethod = EAP_TYPE_NONE;
209                 }
210         }
211
212         wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_PROPOSED_METHOD
213                 "method=%u", sm->currentMethod);
214 }
215
216
217 SM_STATE(EAP, IDLE)
218 {
219         SM_ENTRY(EAP, IDLE);
220
221         sm->eap_if.retransWhile = eap_sm_calculateTimeout(
222                 sm, sm->retransCount, sm->eap_if.eapSRTT, sm->eap_if.eapRTTVAR,
223                 sm->methodTimeout);
224 }
225
226
227 SM_STATE(EAP, RETRANSMIT)
228 {
229         SM_ENTRY(EAP, RETRANSMIT);
230
231         sm->retransCount++;
232         if (sm->retransCount <= sm->MaxRetrans && sm->lastReqData) {
233                 if (eap_copy_buf(&sm->eap_if.eapReqData, sm->lastReqData) == 0)
234                         sm->eap_if.eapReq = TRUE;
235         }
236 }
237
238
239 SM_STATE(EAP, RECEIVED)
240 {
241         SM_ENTRY(EAP, RECEIVED);
242
243         /* parse rxResp, respId, respMethod */
244         eap_sm_parseEapResp(sm, sm->eap_if.eapRespData);
245         sm->num_rounds++;
246 }
247
248
249 SM_STATE(EAP, DISCARD)
250 {
251         SM_ENTRY(EAP, DISCARD);
252         sm->eap_if.eapResp = FALSE;
253         sm->eap_if.eapNoReq = TRUE;
254 }
255
256
257 SM_STATE(EAP, SEND_REQUEST)
258 {
259         SM_ENTRY(EAP, SEND_REQUEST);
260
261         sm->retransCount = 0;
262         if (sm->eap_if.eapReqData) {
263                 if (eap_copy_buf(&sm->lastReqData, sm->eap_if.eapReqData) == 0)
264                 {
265                         sm->eap_if.eapResp = FALSE;
266                         sm->eap_if.eapReq = TRUE;
267                 } else {
268                         sm->eap_if.eapResp = FALSE;
269                         sm->eap_if.eapReq = FALSE;
270                 }
271         } else {
272                 wpa_printf(MSG_INFO, "EAP: SEND_REQUEST - no eapReqData");
273                 sm->eap_if.eapResp = FALSE;
274                 sm->eap_if.eapReq = FALSE;
275                 sm->eap_if.eapNoReq = TRUE;
276         }
277 }
278
279
280 SM_STATE(EAP, INTEGRITY_CHECK)
281 {
282         SM_ENTRY(EAP, INTEGRITY_CHECK);
283
284         if (sm->m->check) {
285                 sm->ignore = sm->m->check(sm, sm->eap_method_priv,
286                                           sm->eap_if.eapRespData);
287         }
288 }
289
290
291 SM_STATE(EAP, METHOD_REQUEST)
292 {
293         SM_ENTRY(EAP, METHOD_REQUEST);
294
295         if (sm->m == NULL) {
296                 wpa_printf(MSG_DEBUG, "EAP: method not initialized");
297                 return;
298         }
299
300         sm->currentId = eap_sm_nextId(sm, sm->currentId);
301         wpa_printf(MSG_DEBUG, "EAP: building EAP-Request: Identifier %d",
302                    sm->currentId);
303         sm->lastId = sm->currentId;
304         wpabuf_free(sm->eap_if.eapReqData);
305         sm->eap_if.eapReqData = sm->m->buildReq(sm, sm->eap_method_priv,
306                                                 sm->currentId);
307         if (sm->m->getTimeout)
308                 sm->methodTimeout = sm->m->getTimeout(sm, sm->eap_method_priv);
309         else
310                 sm->methodTimeout = 0;
311 }
312
313
314 SM_STATE(EAP, METHOD_RESPONSE)
315 {
316         SM_ENTRY(EAP, METHOD_RESPONSE);
317
318         sm->m->process(sm, sm->eap_method_priv, sm->eap_if.eapRespData);
319         if (sm->m->isDone(sm, sm->eap_method_priv)) {
320                 eap_sm_Policy_update(sm, NULL, 0);
321                 os_free(sm->eap_if.eapKeyData);
322                 if (sm->m->getKey) {
323                         sm->eap_if.eapKeyData = sm->m->getKey(
324                                 sm, sm->eap_method_priv,
325                                 &sm->eap_if.eapKeyDataLen);
326                 } else {
327                         sm->eap_if.eapKeyData = NULL;
328                         sm->eap_if.eapKeyDataLen = 0;
329                 }
330                 sm->methodState = METHOD_END;
331         } else {
332                 sm->methodState = METHOD_CONTINUE;
333         }
334 }
335
336
337 SM_STATE(EAP, PROPOSE_METHOD)
338 {
339         int vendor;
340         EapType type;
341
342         SM_ENTRY(EAP, PROPOSE_METHOD);
343
344         type = eap_sm_Policy_getNextMethod(sm, &vendor);
345         if (vendor == EAP_VENDOR_IETF)
346                 sm->currentMethod = type;
347         else
348                 sm->currentMethod = EAP_TYPE_EXPANDED;
349         if (sm->m && sm->eap_method_priv) {
350                 sm->m->reset(sm, sm->eap_method_priv);
351                 sm->eap_method_priv = NULL;
352         }
353         sm->m = eap_server_get_eap_method(vendor, type);
354         if (sm->m) {
355                 sm->eap_method_priv = sm->m->init(sm);
356                 if (sm->eap_method_priv == NULL) {
357                         wpa_printf(MSG_DEBUG, "EAP: Failed to initialize EAP "
358                                    "method %d", sm->currentMethod);
359                         sm->m = NULL;
360                         sm->currentMethod = EAP_TYPE_NONE;
361                 }
362         }
363         if (sm->currentMethod == EAP_TYPE_IDENTITY ||
364             sm->currentMethod == EAP_TYPE_NOTIFICATION)
365                 sm->methodState = METHOD_CONTINUE;
366         else
367                 sm->methodState = METHOD_PROPOSED;
368
369         wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_PROPOSED_METHOD
370                 "vendor=%u method=%u", vendor, sm->currentMethod);
371 }
372
373
374 SM_STATE(EAP, NAK)
375 {
376         const struct eap_hdr *nak;
377         size_t len = 0;
378         const u8 *pos;
379         const u8 *nak_list = NULL;
380
381         SM_ENTRY(EAP, NAK);
382
383         if (sm->eap_method_priv) {
384                 sm->m->reset(sm, sm->eap_method_priv);
385                 sm->eap_method_priv = NULL;
386         }
387         sm->m = NULL;
388
389         nak = wpabuf_head(sm->eap_if.eapRespData);
390         if (nak && wpabuf_len(sm->eap_if.eapRespData) > sizeof(*nak)) {
391                 len = be_to_host16(nak->length);
392                 if (len > wpabuf_len(sm->eap_if.eapRespData))
393                         len = wpabuf_len(sm->eap_if.eapRespData);
394                 pos = (const u8 *) (nak + 1);
395                 len -= sizeof(*nak);
396                 if (*pos == EAP_TYPE_NAK) {
397                         pos++;
398                         len--;
399                         nak_list = pos;
400                 }
401         }
402         eap_sm_Policy_update(sm, nak_list, len);
403 }
404
405
406 SM_STATE(EAP, SELECT_ACTION)
407 {
408         SM_ENTRY(EAP, SELECT_ACTION);
409
410         sm->decision = eap_sm_Policy_getDecision(sm);
411 }
412
413
414 SM_STATE(EAP, TIMEOUT_FAILURE)
415 {
416         SM_ENTRY(EAP, TIMEOUT_FAILURE);
417
418         sm->eap_if.eapTimeout = TRUE;
419 }
420
421
422 SM_STATE(EAP, FAILURE)
423 {
424         SM_ENTRY(EAP, FAILURE);
425
426         wpabuf_free(sm->eap_if.eapReqData);
427         sm->eap_if.eapReqData = eap_sm_buildFailure(sm, sm->currentId);
428         wpabuf_free(sm->lastReqData);
429         sm->lastReqData = NULL;
430         sm->eap_if.eapFail = TRUE;
431
432         wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_FAILURE
433                 MACSTR, MAC2STR(sm->peer_addr));
434 }
435
436
437 SM_STATE(EAP, SUCCESS)
438 {
439         SM_ENTRY(EAP, SUCCESS);
440
441         wpabuf_free(sm->eap_if.eapReqData);
442         sm->eap_if.eapReqData = eap_sm_buildSuccess(sm, sm->currentId);
443         wpabuf_free(sm->lastReqData);
444         sm->lastReqData = NULL;
445         if (sm->eap_if.eapKeyData)
446                 sm->eap_if.eapKeyAvailable = TRUE;
447         sm->eap_if.eapSuccess = TRUE;
448
449         wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_SUCCESS
450                 MACSTR, MAC2STR(sm->peer_addr));
451 }
452
453
454 SM_STATE(EAP, INITIALIZE_PASSTHROUGH)
455 {
456         SM_ENTRY(EAP, INITIALIZE_PASSTHROUGH);
457
458         wpabuf_free(sm->eap_if.aaaEapRespData);
459         sm->eap_if.aaaEapRespData = NULL;
460 }
461
462
463 SM_STATE(EAP, IDLE2)
464 {
465         SM_ENTRY(EAP, IDLE2);
466
467         sm->eap_if.retransWhile = eap_sm_calculateTimeout(
468                 sm, sm->retransCount, sm->eap_if.eapSRTT, sm->eap_if.eapRTTVAR,
469                 sm->methodTimeout);
470 }
471
472
473 SM_STATE(EAP, RETRANSMIT2)
474 {
475         SM_ENTRY(EAP, RETRANSMIT2);
476
477         sm->retransCount++;
478         if (sm->retransCount <= sm->MaxRetrans && sm->lastReqData) {
479                 if (eap_copy_buf(&sm->eap_if.eapReqData, sm->lastReqData) == 0)
480                         sm->eap_if.eapReq = TRUE;
481         }
482 }
483
484
485 SM_STATE(EAP, RECEIVED2)
486 {
487         SM_ENTRY(EAP, RECEIVED2);
488
489         /* parse rxResp, respId, respMethod */
490         eap_sm_parseEapResp(sm, sm->eap_if.eapRespData);
491 }
492
493
494 SM_STATE(EAP, DISCARD2)
495 {
496         SM_ENTRY(EAP, DISCARD2);
497         sm->eap_if.eapResp = FALSE;
498         sm->eap_if.eapNoReq = TRUE;
499 }
500
501
502 SM_STATE(EAP, SEND_REQUEST2)
503 {
504         SM_ENTRY(EAP, SEND_REQUEST2);
505
506         sm->retransCount = 0;
507         if (sm->eap_if.eapReqData) {
508                 if (eap_copy_buf(&sm->lastReqData, sm->eap_if.eapReqData) == 0)
509                 {
510                         sm->eap_if.eapResp = FALSE;
511                         sm->eap_if.eapReq = TRUE;
512                 } else {
513                         sm->eap_if.eapResp = FALSE;
514                         sm->eap_if.eapReq = FALSE;
515                 }
516         } else {
517                 wpa_printf(MSG_INFO, "EAP: SEND_REQUEST2 - no eapReqData");
518                 sm->eap_if.eapResp = FALSE;
519                 sm->eap_if.eapReq = FALSE;
520                 sm->eap_if.eapNoReq = TRUE;
521         }
522 }
523
524
525 SM_STATE(EAP, AAA_REQUEST)
526 {
527         SM_ENTRY(EAP, AAA_REQUEST);
528
529         if (sm->eap_if.eapRespData == NULL) {
530                 wpa_printf(MSG_INFO, "EAP: AAA_REQUEST - no eapRespData");
531                 return;
532         }
533
534         /*
535          * if (respMethod == IDENTITY)
536          *      aaaIdentity = eapRespData
537          * This is already taken care of by the EAP-Identity method which
538          * stores the identity into sm->identity.
539          */
540
541         eap_copy_buf(&sm->eap_if.aaaEapRespData, sm->eap_if.eapRespData);
542 }
543
544
545 SM_STATE(EAP, AAA_RESPONSE)
546 {
547         SM_ENTRY(EAP, AAA_RESPONSE);
548
549         eap_copy_buf(&sm->eap_if.eapReqData, sm->eap_if.aaaEapReqData);
550         sm->currentId = eap_sm_getId(sm->eap_if.eapReqData);
551         sm->methodTimeout = sm->eap_if.aaaMethodTimeout;
552 }
553
554
555 SM_STATE(EAP, AAA_IDLE)
556 {
557         SM_ENTRY(EAP, AAA_IDLE);
558
559         sm->eap_if.aaaFail = FALSE;
560         sm->eap_if.aaaSuccess = FALSE;
561         sm->eap_if.aaaEapReq = FALSE;
562         sm->eap_if.aaaEapNoReq = FALSE;
563         sm->eap_if.aaaEapResp = TRUE;
564 }
565
566
567 SM_STATE(EAP, TIMEOUT_FAILURE2)
568 {
569         SM_ENTRY(EAP, TIMEOUT_FAILURE2);
570
571         sm->eap_if.eapTimeout = TRUE;
572 }
573
574
575 SM_STATE(EAP, FAILURE2)
576 {
577         SM_ENTRY(EAP, FAILURE2);
578
579         eap_copy_buf(&sm->eap_if.eapReqData, sm->eap_if.aaaEapReqData);
580         sm->eap_if.eapFail = TRUE;
581 }
582
583
584 SM_STATE(EAP, SUCCESS2)
585 {
586         SM_ENTRY(EAP, SUCCESS2);
587
588         eap_copy_buf(&sm->eap_if.eapReqData, sm->eap_if.aaaEapReqData);
589
590         sm->eap_if.eapKeyAvailable = sm->eap_if.aaaEapKeyAvailable;
591         if (sm->eap_if.aaaEapKeyAvailable) {
592                 EAP_COPY(&sm->eap_if.eapKeyData, sm->eap_if.aaaEapKeyData);
593         } else {
594                 os_free(sm->eap_if.eapKeyData);
595                 sm->eap_if.eapKeyData = NULL;
596                 sm->eap_if.eapKeyDataLen = 0;
597         }
598
599         sm->eap_if.eapSuccess = TRUE;
600
601         /*
602          * Start reauthentication with identity request even though we know the
603          * previously used identity. This is needed to get reauthentication
604          * started properly.
605          */
606         sm->start_reauth = TRUE;
607 }
608
609
610 SM_STEP(EAP)
611 {
612         if (sm->eap_if.eapRestart && sm->eap_if.portEnabled)
613                 SM_ENTER_GLOBAL(EAP, INITIALIZE);
614         else if (!sm->eap_if.portEnabled)
615                 SM_ENTER_GLOBAL(EAP, DISABLED);
616         else if (sm->num_rounds > EAP_MAX_AUTH_ROUNDS) {
617                 if (sm->num_rounds == EAP_MAX_AUTH_ROUNDS + 1) {
618                         wpa_printf(MSG_DEBUG, "EAP: more than %d "
619                                    "authentication rounds - abort",
620                                    EAP_MAX_AUTH_ROUNDS);
621                         sm->num_rounds++;
622                         SM_ENTER_GLOBAL(EAP, FAILURE);
623                 }
624         } else switch (sm->EAP_state) {
625         case EAP_INITIALIZE:
626                 if (sm->backend_auth) {
627                         if (!sm->rxResp)
628                                 SM_ENTER(EAP, SELECT_ACTION);
629                         else if (sm->rxResp &&
630                                  (sm->respMethod == EAP_TYPE_NAK ||
631                                   (sm->respMethod == EAP_TYPE_EXPANDED &&
632                                    sm->respVendor == EAP_VENDOR_IETF &&
633                                    sm->respVendorMethod == EAP_TYPE_NAK)))
634                                 SM_ENTER(EAP, NAK);
635                         else
636                                 SM_ENTER(EAP, PICK_UP_METHOD);
637                 } else {
638                         SM_ENTER(EAP, SELECT_ACTION);
639                 }
640                 break;
641         case EAP_PICK_UP_METHOD:
642                 if (sm->currentMethod == EAP_TYPE_NONE) {
643                         SM_ENTER(EAP, SELECT_ACTION);
644                 } else {
645                         SM_ENTER(EAP, METHOD_RESPONSE);
646                 }
647                 break;
648         case EAP_DISABLED:
649                 if (sm->eap_if.portEnabled)
650                         SM_ENTER(EAP, INITIALIZE);
651                 break;
652         case EAP_IDLE:
653                 if (sm->eap_if.retransWhile == 0)
654                         SM_ENTER(EAP, RETRANSMIT);
655                 else if (sm->eap_if.eapResp)
656                         SM_ENTER(EAP, RECEIVED);
657                 break;
658         case EAP_RETRANSMIT:
659                 if (sm->retransCount > sm->MaxRetrans)
660                         SM_ENTER(EAP, TIMEOUT_FAILURE);
661                 else
662                         SM_ENTER(EAP, IDLE);
663                 break;
664         case EAP_RECEIVED:
665                 if (sm->rxResp && (sm->respId == sm->currentId) &&
666                     (sm->respMethod == EAP_TYPE_NAK ||
667                      (sm->respMethod == EAP_TYPE_EXPANDED &&
668                       sm->respVendor == EAP_VENDOR_IETF &&
669                       sm->respVendorMethod == EAP_TYPE_NAK))
670                     && (sm->methodState == METHOD_PROPOSED))
671                         SM_ENTER(EAP, NAK);
672                 else if (sm->rxResp && (sm->respId == sm->currentId) &&
673                          ((sm->respMethod == sm->currentMethod) ||
674                           (sm->respMethod == EAP_TYPE_EXPANDED &&
675                            sm->respVendor == EAP_VENDOR_IETF &&
676                            sm->respVendorMethod == sm->currentMethod)))
677                         SM_ENTER(EAP, INTEGRITY_CHECK);
678                 else {
679                         wpa_printf(MSG_DEBUG, "EAP: RECEIVED->DISCARD: "
680                                    "rxResp=%d respId=%d currentId=%d "
681                                    "respMethod=%d currentMethod=%d",
682                                    sm->rxResp, sm->respId, sm->currentId,
683                                    sm->respMethod, sm->currentMethod);
684                         SM_ENTER(EAP, DISCARD);
685                 }
686                 break;
687         case EAP_DISCARD:
688                 SM_ENTER(EAP, IDLE);
689                 break;
690         case EAP_SEND_REQUEST:
691                 SM_ENTER(EAP, IDLE);
692                 break;
693         case EAP_INTEGRITY_CHECK:
694                 if (sm->ignore)
695                         SM_ENTER(EAP, DISCARD);
696                 else
697                         SM_ENTER(EAP, METHOD_RESPONSE);
698                 break;
699         case EAP_METHOD_REQUEST:
700                 SM_ENTER(EAP, SEND_REQUEST);
701                 break;
702         case EAP_METHOD_RESPONSE:
703                 /*
704                  * Note: Mechanism to allow EAP methods to wait while going
705                  * through pending processing is an extension to RFC 4137
706                  * which only defines the transits to SELECT_ACTION and
707                  * METHOD_REQUEST from this METHOD_RESPONSE state.
708                  */
709                 if (sm->methodState == METHOD_END)
710                         SM_ENTER(EAP, SELECT_ACTION);
711                 else if (sm->method_pending == METHOD_PENDING_WAIT) {
712                         wpa_printf(MSG_DEBUG, "EAP: Method has pending "
713                                    "processing - wait before proceeding to "
714                                    "METHOD_REQUEST state");
715                 } else if (sm->method_pending == METHOD_PENDING_CONT) {
716                         wpa_printf(MSG_DEBUG, "EAP: Method has completed "
717                                    "pending processing - reprocess pending "
718                                    "EAP message");
719                         sm->method_pending = METHOD_PENDING_NONE;
720                         SM_ENTER(EAP, METHOD_RESPONSE);
721                 } else
722                         SM_ENTER(EAP, METHOD_REQUEST);
723                 break;
724         case EAP_PROPOSE_METHOD:
725                 /*
726                  * Note: Mechanism to allow EAP methods to wait while going
727                  * through pending processing is an extension to RFC 4137
728                  * which only defines the transit to METHOD_REQUEST from this
729                  * PROPOSE_METHOD state.
730                  */
731                 if (sm->method_pending == METHOD_PENDING_WAIT) {
732                         wpa_printf(MSG_DEBUG, "EAP: Method has pending "
733                                    "processing - wait before proceeding to "
734                                    "METHOD_REQUEST state");
735                         if (sm->user_eap_method_index > 0)
736                                 sm->user_eap_method_index--;
737                 } else if (sm->method_pending == METHOD_PENDING_CONT) {
738                         wpa_printf(MSG_DEBUG, "EAP: Method has completed "
739                                    "pending processing - reprocess pending "
740                                    "EAP message");
741                         sm->method_pending = METHOD_PENDING_NONE;
742                         SM_ENTER(EAP, PROPOSE_METHOD);
743                 } else
744                         SM_ENTER(EAP, METHOD_REQUEST);
745                 break;
746         case EAP_NAK:
747                 SM_ENTER(EAP, SELECT_ACTION);
748                 break;
749         case EAP_SELECT_ACTION:
750                 if (sm->decision == DECISION_FAILURE)
751                         SM_ENTER(EAP, FAILURE);
752                 else if (sm->decision == DECISION_SUCCESS)
753                         SM_ENTER(EAP, SUCCESS);
754                 else if (sm->decision == DECISION_PASSTHROUGH)
755                         SM_ENTER(EAP, INITIALIZE_PASSTHROUGH);
756                 else
757                         SM_ENTER(EAP, PROPOSE_METHOD);
758                 break;
759         case EAP_TIMEOUT_FAILURE:
760                 break;
761         case EAP_FAILURE:
762                 break;
763         case EAP_SUCCESS:
764                 break;
765
766         case EAP_INITIALIZE_PASSTHROUGH:
767                 if (sm->currentId == -1)
768                         SM_ENTER(EAP, AAA_IDLE);
769                 else
770                         SM_ENTER(EAP, AAA_REQUEST);
771                 break;
772         case EAP_IDLE2:
773                 if (sm->eap_if.eapResp)
774                         SM_ENTER(EAP, RECEIVED2);
775                 else if (sm->eap_if.retransWhile == 0)
776                         SM_ENTER(EAP, RETRANSMIT2);
777                 break;
778         case EAP_RETRANSMIT2:
779                 if (sm->retransCount > sm->MaxRetrans)
780                         SM_ENTER(EAP, TIMEOUT_FAILURE2);
781                 else
782                         SM_ENTER(EAP, IDLE2);
783                 break;
784         case EAP_RECEIVED2:
785                 if (sm->rxResp && (sm->respId == sm->currentId))
786                         SM_ENTER(EAP, AAA_REQUEST);
787                 else
788                         SM_ENTER(EAP, DISCARD2);
789                 break;
790         case EAP_DISCARD2:
791                 SM_ENTER(EAP, IDLE2);
792                 break;
793         case EAP_SEND_REQUEST2:
794                 SM_ENTER(EAP, IDLE2);
795                 break;
796         case EAP_AAA_REQUEST:
797                 SM_ENTER(EAP, AAA_IDLE);
798                 break;
799         case EAP_AAA_RESPONSE:
800                 SM_ENTER(EAP, SEND_REQUEST2);
801                 break;
802         case EAP_AAA_IDLE:
803                 if (sm->eap_if.aaaFail)
804                         SM_ENTER(EAP, FAILURE2);
805                 else if (sm->eap_if.aaaSuccess)
806                         SM_ENTER(EAP, SUCCESS2);
807                 else if (sm->eap_if.aaaEapReq)
808                         SM_ENTER(EAP, AAA_RESPONSE);
809                 else if (sm->eap_if.aaaTimeout)
810                         SM_ENTER(EAP, TIMEOUT_FAILURE2);
811                 break;
812         case EAP_TIMEOUT_FAILURE2:
813                 break;
814         case EAP_FAILURE2:
815                 break;
816         case EAP_SUCCESS2:
817                 break;
818         }
819 }
820
821
822 static int eap_sm_calculateTimeout(struct eap_sm *sm, int retransCount,
823                                    int eapSRTT, int eapRTTVAR,
824                                    int methodTimeout)
825 {
826         int rto, i;
827
828         if (methodTimeout) {
829                 /*
830                  * EAP method (either internal or through AAA server, provided
831                  * timeout hint. Use that as-is as a timeout for retransmitting
832                  * the EAP request if no response is received.
833                  */
834                 wpa_printf(MSG_DEBUG, "EAP: retransmit timeout %d seconds "
835                            "(from EAP method hint)", methodTimeout);
836                 return methodTimeout;
837         }
838
839         /*
840          * RFC 3748 recommends algorithms described in RFC 2988 for estimation
841          * of the retransmission timeout. This should be implemented once
842          * round-trip time measurements are available. For nowm a simple
843          * backoff mechanism is used instead if there are no EAP method
844          * specific hints.
845          *
846          * SRTT = smoothed round-trip time
847          * RTTVAR = round-trip time variation
848          * RTO = retransmission timeout
849          */
850
851         /*
852          * RFC 2988, 2.1: before RTT measurement, set RTO to 3 seconds for
853          * initial retransmission and then double the RTO to provide back off
854          * per 5.5. Limit the maximum RTO to 20 seconds per RFC 3748, 4.3
855          * modified RTOmax.
856          */
857         rto = 3;
858         for (i = 0; i < retransCount; i++) {
859                 rto *= 2;
860                 if (rto >= 20) {
861                         rto = 20;
862                         break;
863                 }
864         }
865
866         wpa_printf(MSG_DEBUG, "EAP: retransmit timeout %d seconds "
867                    "(from dynamic back off; retransCount=%d)",
868                    rto, retransCount);
869
870         return rto;
871 }
872
873
874 static void eap_sm_parseEapResp(struct eap_sm *sm, const struct wpabuf *resp)
875 {
876         const struct eap_hdr *hdr;
877         size_t plen;
878
879         /* parse rxResp, respId, respMethod */
880         sm->rxResp = FALSE;
881         sm->respId = -1;
882         sm->respMethod = EAP_TYPE_NONE;
883         sm->respVendor = EAP_VENDOR_IETF;
884         sm->respVendorMethod = EAP_TYPE_NONE;
885
886         if (resp == NULL || wpabuf_len(resp) < sizeof(*hdr)) {
887                 wpa_printf(MSG_DEBUG, "EAP: parseEapResp: invalid resp=%p "
888                            "len=%lu", resp,
889                            resp ? (unsigned long) wpabuf_len(resp) : 0);
890                 return;
891         }
892
893         hdr = wpabuf_head(resp);
894         plen = be_to_host16(hdr->length);
895         if (plen > wpabuf_len(resp)) {
896                 wpa_printf(MSG_DEBUG, "EAP: Ignored truncated EAP-Packet "
897                            "(len=%lu plen=%lu)",
898                            (unsigned long) wpabuf_len(resp),
899                            (unsigned long) plen);
900                 return;
901         }
902
903         sm->respId = hdr->identifier;
904
905         if (hdr->code == EAP_CODE_RESPONSE)
906                 sm->rxResp = TRUE;
907
908         if (plen > sizeof(*hdr)) {
909                 u8 *pos = (u8 *) (hdr + 1);
910                 sm->respMethod = *pos++;
911                 if (sm->respMethod == EAP_TYPE_EXPANDED) {
912                         if (plen < sizeof(*hdr) + 8) {
913                                 wpa_printf(MSG_DEBUG, "EAP: Ignored truncated "
914                                            "expanded EAP-Packet (plen=%lu)",
915                                            (unsigned long) plen);
916                                 return;
917                         }
918                         sm->respVendor = WPA_GET_BE24(pos);
919                         pos += 3;
920                         sm->respVendorMethod = WPA_GET_BE32(pos);
921                 }
922         }
923
924         wpa_printf(MSG_DEBUG, "EAP: parseEapResp: rxResp=%d respId=%d "
925                    "respMethod=%u respVendor=%u respVendorMethod=%u",
926                    sm->rxResp, sm->respId, sm->respMethod, sm->respVendor,
927                    sm->respVendorMethod);
928 }
929
930
931 static int eap_sm_getId(const struct wpabuf *data)
932 {
933         const struct eap_hdr *hdr;
934
935         if (data == NULL || wpabuf_len(data) < sizeof(*hdr))
936                 return -1;
937
938         hdr = wpabuf_head(data);
939         wpa_printf(MSG_DEBUG, "EAP: getId: id=%d", hdr->identifier);
940         return hdr->identifier;
941 }
942
943
944 static struct wpabuf * eap_sm_buildSuccess(struct eap_sm *sm, u8 id)
945 {
946         struct wpabuf *msg;
947         struct eap_hdr *resp;
948         wpa_printf(MSG_DEBUG, "EAP: Building EAP-Success (id=%d)", id);
949
950         msg = wpabuf_alloc(sizeof(*resp));
951         if (msg == NULL)
952                 return NULL;
953         resp = wpabuf_put(msg, sizeof(*resp));
954         resp->code = EAP_CODE_SUCCESS;
955         resp->identifier = id;
956         resp->length = host_to_be16(sizeof(*resp));
957
958         return msg;
959 }
960
961
962 static struct wpabuf * eap_sm_buildFailure(struct eap_sm *sm, u8 id)
963 {
964         struct wpabuf *msg;
965         struct eap_hdr *resp;
966         wpa_printf(MSG_DEBUG, "EAP: Building EAP-Failure (id=%d)", id);
967
968         msg = wpabuf_alloc(sizeof(*resp));
969         if (msg == NULL)
970                 return NULL;
971         resp = wpabuf_put(msg, sizeof(*resp));
972         resp->code = EAP_CODE_FAILURE;
973         resp->identifier = id;
974         resp->length = host_to_be16(sizeof(*resp));
975
976         return msg;
977 }
978
979
980 static int eap_sm_nextId(struct eap_sm *sm, int id)
981 {
982         if (id < 0) {
983                 /* RFC 3748 Ch 4.1: recommended to initialize Identifier with a
984                  * random number */
985                 id = rand() & 0xff;
986                 if (id != sm->lastId)
987                         return id;
988         }
989         return (id + 1) & 0xff;
990 }
991
992
993 /**
994  * eap_sm_process_nak - Process EAP-Response/Nak
995  * @sm: Pointer to EAP state machine allocated with eap_server_sm_init()
996  * @nak_list: Nak list (allowed methods) from the supplicant
997  * @len: Length of nak_list in bytes
998  *
999  * This function is called when EAP-Response/Nak is received from the
1000  * supplicant. This can happen for both phase 1 and phase 2 authentications.
1001  */
1002 void eap_sm_process_nak(struct eap_sm *sm, const u8 *nak_list, size_t len)
1003 {
1004         int i;
1005         size_t j;
1006
1007         if (sm->user == NULL)
1008                 return;
1009
1010         wpa_printf(MSG_MSGDUMP, "EAP: processing NAK (current EAP method "
1011                    "index %d)", sm->user_eap_method_index);
1012
1013         wpa_hexdump(MSG_MSGDUMP, "EAP: configured methods",
1014                     (u8 *) sm->user->methods,
1015                     EAP_MAX_METHODS * sizeof(sm->user->methods[0]));
1016         wpa_hexdump(MSG_MSGDUMP, "EAP: list of methods supported by the peer",
1017                     nak_list, len);
1018
1019         i = sm->user_eap_method_index;
1020         while (i < EAP_MAX_METHODS &&
1021                (sm->user->methods[i].vendor != EAP_VENDOR_IETF ||
1022                 sm->user->methods[i].method != EAP_TYPE_NONE)) {
1023                 if (sm->user->methods[i].vendor != EAP_VENDOR_IETF)
1024                         goto not_found;
1025                 for (j = 0; j < len; j++) {
1026                         if (nak_list[j] == sm->user->methods[i].method) {
1027                                 break;
1028                         }
1029                 }
1030
1031                 if (j < len) {
1032                         /* found */
1033                         i++;
1034                         continue;
1035                 }
1036
1037         not_found:
1038                 /* not found - remove from the list */
1039                 if (i + 1 < EAP_MAX_METHODS) {
1040                         os_memmove(&sm->user->methods[i],
1041                                    &sm->user->methods[i + 1],
1042                                    (EAP_MAX_METHODS - i - 1) *
1043                                    sizeof(sm->user->methods[0]));
1044                 }
1045                 sm->user->methods[EAP_MAX_METHODS - 1].vendor =
1046                         EAP_VENDOR_IETF;
1047                 sm->user->methods[EAP_MAX_METHODS - 1].method = EAP_TYPE_NONE;
1048         }
1049
1050         wpa_hexdump(MSG_MSGDUMP, "EAP: new list of configured methods",
1051                     (u8 *) sm->user->methods, EAP_MAX_METHODS *
1052                     sizeof(sm->user->methods[0]));
1053 }
1054
1055
1056 static void eap_sm_Policy_update(struct eap_sm *sm, const u8 *nak_list,
1057                                  size_t len)
1058 {
1059         if (nak_list == NULL || sm == NULL || sm->user == NULL)
1060                 return;
1061
1062         if (sm->user->phase2) {
1063                 wpa_printf(MSG_DEBUG, "EAP: EAP-Nak received after Phase2 user"
1064                            " info was selected - reject");
1065                 sm->decision = DECISION_FAILURE;
1066                 return;
1067         }
1068
1069         eap_sm_process_nak(sm, nak_list, len);
1070 }
1071
1072
1073 static EapType eap_sm_Policy_getNextMethod(struct eap_sm *sm, int *vendor)
1074 {
1075         EapType next;
1076         int idx = sm->user_eap_method_index;
1077
1078         /* In theory, there should be no problems with starting
1079          * re-authentication with something else than EAP-Request/Identity and
1080          * this does indeed work with wpa_supplicant. However, at least Funk
1081          * Supplicant seemed to ignore re-auth if it skipped
1082          * EAP-Request/Identity.
1083          * Re-auth sets currentId == -1, so that can be used here to select
1084          * whether Identity needs to be requested again. */
1085         if (sm->identity == NULL || sm->currentId == -1) {
1086                 *vendor = EAP_VENDOR_IETF;
1087                 next = EAP_TYPE_IDENTITY;
1088                 sm->update_user = TRUE;
1089         } else if (sm->user && idx < EAP_MAX_METHODS &&
1090                    (sm->user->methods[idx].vendor != EAP_VENDOR_IETF ||
1091                     sm->user->methods[idx].method != EAP_TYPE_NONE)) {
1092                 *vendor = sm->user->methods[idx].vendor;
1093                 next = sm->user->methods[idx].method;
1094                 sm->user_eap_method_index++;
1095         } else {
1096                 *vendor = EAP_VENDOR_IETF;
1097                 next = EAP_TYPE_NONE;
1098         }
1099         wpa_printf(MSG_DEBUG, "EAP: getNextMethod: vendor %d type %d",
1100                    *vendor, next);
1101         return next;
1102 }
1103
1104
1105 static int eap_sm_Policy_getDecision(struct eap_sm *sm)
1106 {
1107         if (!sm->eap_server && sm->identity && !sm->start_reauth) {
1108                 wpa_printf(MSG_DEBUG, "EAP: getDecision: -> PASSTHROUGH");
1109                 return DECISION_PASSTHROUGH;
1110         }
1111
1112         if (sm->m && sm->currentMethod != EAP_TYPE_IDENTITY &&
1113             sm->m->isSuccess(sm, sm->eap_method_priv)) {
1114                 wpa_printf(MSG_DEBUG, "EAP: getDecision: method succeeded -> "
1115                            "SUCCESS");
1116                 sm->update_user = TRUE;
1117                 return DECISION_SUCCESS;
1118         }
1119
1120         if (sm->m && sm->m->isDone(sm, sm->eap_method_priv) &&
1121             !sm->m->isSuccess(sm, sm->eap_method_priv)) {
1122                 wpa_printf(MSG_DEBUG, "EAP: getDecision: method failed -> "
1123                            "FAILURE");
1124                 sm->update_user = TRUE;
1125                 return DECISION_FAILURE;
1126         }
1127
1128         if ((sm->user == NULL || sm->update_user) && sm->identity &&
1129             !sm->start_reauth) {
1130                 /*
1131                  * Allow Identity method to be started once to allow identity
1132                  * selection hint to be sent from the authentication server,
1133                  * but prevent a loop of Identity requests by only allowing
1134                  * this to happen once.
1135                  */
1136                 int id_req = 0;
1137                 if (sm->user && sm->currentMethod == EAP_TYPE_IDENTITY &&
1138                     sm->user->methods[0].vendor == EAP_VENDOR_IETF &&
1139                     sm->user->methods[0].method == EAP_TYPE_IDENTITY)
1140                         id_req = 1;
1141                 if (eap_user_get(sm, sm->identity, sm->identity_len, 0) != 0) {
1142                         wpa_printf(MSG_DEBUG, "EAP: getDecision: user not "
1143                                    "found from database -> FAILURE");
1144                         return DECISION_FAILURE;
1145                 }
1146                 if (id_req && sm->user &&
1147                     sm->user->methods[0].vendor == EAP_VENDOR_IETF &&
1148                     sm->user->methods[0].method == EAP_TYPE_IDENTITY) {
1149                         wpa_printf(MSG_DEBUG, "EAP: getDecision: stop "
1150                                    "identity request loop -> FAILURE");
1151                         sm->update_user = TRUE;
1152                         return DECISION_FAILURE;
1153                 }
1154                 sm->update_user = FALSE;
1155         }
1156         sm->start_reauth = FALSE;
1157
1158         if (sm->user && sm->user_eap_method_index < EAP_MAX_METHODS &&
1159             (sm->user->methods[sm->user_eap_method_index].vendor !=
1160              EAP_VENDOR_IETF ||
1161              sm->user->methods[sm->user_eap_method_index].method !=
1162              EAP_TYPE_NONE)) {
1163                 wpa_printf(MSG_DEBUG, "EAP: getDecision: another method "
1164                            "available -> CONTINUE");
1165                 return DECISION_CONTINUE;
1166         }
1167
1168         if (sm->identity == NULL || sm->currentId == -1) {
1169                 wpa_printf(MSG_DEBUG, "EAP: getDecision: no identity known "
1170                            "yet -> CONTINUE");
1171                 return DECISION_CONTINUE;
1172         }
1173
1174         wpa_printf(MSG_DEBUG, "EAP: getDecision: no more methods available -> "
1175                    "FAILURE");
1176         return DECISION_FAILURE;
1177 }
1178
1179
1180 static Boolean eap_sm_Policy_doPickUp(struct eap_sm *sm, EapType method)
1181 {
1182         return method == EAP_TYPE_IDENTITY ? TRUE : FALSE;
1183 }
1184
1185
1186 /**
1187  * eap_server_sm_step - Step EAP server state machine
1188  * @sm: Pointer to EAP state machine allocated with eap_server_sm_init()
1189  * Returns: 1 if EAP state was changed or 0 if not
1190  *
1191  * This function advances EAP state machine to a new state to match with the
1192  * current variables. This should be called whenever variables used by the EAP
1193  * state machine have changed.
1194  */
1195 int eap_server_sm_step(struct eap_sm *sm)
1196 {
1197         int res = 0;
1198         do {
1199                 sm->changed = FALSE;
1200                 SM_STEP_RUN(EAP);
1201                 if (sm->changed)
1202                         res = 1;
1203         } while (sm->changed);
1204         return res;
1205 }
1206
1207
1208 static void eap_user_free(struct eap_user *user)
1209 {
1210         if (user == NULL)
1211                 return;
1212         os_free(user->password);
1213         user->password = NULL;
1214         os_free(user);
1215 }
1216
1217
1218 /**
1219  * eap_server_sm_init - Allocate and initialize EAP server state machine
1220  * @eapol_ctx: Context data to be used with eapol_cb calls
1221  * @eapol_cb: Pointer to EAPOL callback functions
1222  * @conf: EAP configuration
1223  * Returns: Pointer to the allocated EAP state machine or %NULL on failure
1224  *
1225  * This function allocates and initializes an EAP state machine.
1226  */
1227 struct eap_sm * eap_server_sm_init(void *eapol_ctx,
1228                                    struct eapol_callbacks *eapol_cb,
1229                                    struct eap_config *conf)
1230 {
1231         struct eap_sm *sm;
1232
1233         sm = os_zalloc(sizeof(*sm));
1234         if (sm == NULL)
1235                 return NULL;
1236         sm->eapol_ctx = eapol_ctx;
1237         sm->eapol_cb = eapol_cb;
1238         sm->MaxRetrans = 5; /* RFC 3748: max 3-5 retransmissions suggested */
1239         sm->ssl_ctx = conf->ssl_ctx;
1240         sm->msg_ctx = conf->msg_ctx;
1241         sm->eap_sim_db_priv = conf->eap_sim_db_priv;
1242         sm->backend_auth = conf->backend_auth;
1243         sm->eap_server = conf->eap_server;
1244         if (conf->pac_opaque_encr_key) {
1245                 sm->pac_opaque_encr_key = os_malloc(16);
1246                 if (sm->pac_opaque_encr_key) {
1247                         os_memcpy(sm->pac_opaque_encr_key,
1248                                   conf->pac_opaque_encr_key, 16);
1249                 }
1250         }
1251         if (conf->eap_fast_a_id) {
1252                 sm->eap_fast_a_id = os_malloc(conf->eap_fast_a_id_len);
1253                 if (sm->eap_fast_a_id) {
1254                         os_memcpy(sm->eap_fast_a_id, conf->eap_fast_a_id,
1255                                   conf->eap_fast_a_id_len);
1256                         sm->eap_fast_a_id_len = conf->eap_fast_a_id_len;
1257                 }
1258         }
1259         if (conf->eap_fast_a_id_info)
1260                 sm->eap_fast_a_id_info = os_strdup(conf->eap_fast_a_id_info);
1261         sm->eap_fast_prov = conf->eap_fast_prov;
1262         sm->pac_key_lifetime = conf->pac_key_lifetime;
1263         sm->pac_key_refresh_time = conf->pac_key_refresh_time;
1264         sm->eap_sim_aka_result_ind = conf->eap_sim_aka_result_ind;
1265         sm->tnc = conf->tnc;
1266         sm->wps = conf->wps;
1267         if (conf->assoc_wps_ie)
1268                 sm->assoc_wps_ie = wpabuf_dup(conf->assoc_wps_ie);
1269         if (conf->assoc_p2p_ie)
1270                 sm->assoc_p2p_ie = wpabuf_dup(conf->assoc_p2p_ie);
1271         if (conf->peer_addr)
1272                 os_memcpy(sm->peer_addr, conf->peer_addr, ETH_ALEN);
1273         sm->fragment_size = conf->fragment_size;
1274         sm->pwd_group = conf->pwd_group;
1275         sm->pbc_in_m1 = conf->pbc_in_m1;
1276
1277         wpa_printf(MSG_DEBUG, "EAP: Server state machine created");
1278
1279         return sm;
1280 }
1281
1282
1283 /**
1284  * eap_server_sm_deinit - Deinitialize and free an EAP server state machine
1285  * @sm: Pointer to EAP state machine allocated with eap_server_sm_init()
1286  *
1287  * This function deinitializes EAP state machine and frees all allocated
1288  * resources.
1289  */
1290 void eap_server_sm_deinit(struct eap_sm *sm)
1291 {
1292         if (sm == NULL)
1293                 return;
1294         wpa_printf(MSG_DEBUG, "EAP: Server state machine removed");
1295         if (sm->m && sm->eap_method_priv)
1296                 sm->m->reset(sm, sm->eap_method_priv);
1297         wpabuf_free(sm->eap_if.eapReqData);
1298         os_free(sm->eap_if.eapKeyData);
1299         wpabuf_free(sm->lastReqData);
1300         wpabuf_free(sm->eap_if.eapRespData);
1301         os_free(sm->identity);
1302         os_free(sm->pac_opaque_encr_key);
1303         os_free(sm->eap_fast_a_id);
1304         os_free(sm->eap_fast_a_id_info);
1305         wpabuf_free(sm->eap_if.aaaEapReqData);
1306         wpabuf_free(sm->eap_if.aaaEapRespData);
1307         os_free(sm->eap_if.aaaEapKeyData);
1308         eap_user_free(sm->user);
1309         wpabuf_free(sm->assoc_wps_ie);
1310         wpabuf_free(sm->assoc_p2p_ie);
1311         os_free(sm);
1312 }
1313
1314
1315 /**
1316  * eap_sm_notify_cached - Notify EAP state machine of cached PMK
1317  * @sm: Pointer to EAP state machine allocated with eap_server_sm_init()
1318  *
1319  * This function is called when PMKSA caching is used to skip EAP
1320  * authentication.
1321  */
1322 void eap_sm_notify_cached(struct eap_sm *sm)
1323 {
1324         if (sm == NULL)
1325                 return;
1326
1327         sm->EAP_state = EAP_SUCCESS;
1328 }
1329
1330
1331 /**
1332  * eap_sm_pending_cb - EAP state machine callback for a pending EAP request
1333  * @sm: Pointer to EAP state machine allocated with eap_server_sm_init()
1334  *
1335  * This function is called when data for a pending EAP-Request is received.
1336  */
1337 void eap_sm_pending_cb(struct eap_sm *sm)
1338 {
1339         if (sm == NULL)
1340                 return;
1341         wpa_printf(MSG_DEBUG, "EAP: Callback for pending request received");
1342         if (sm->method_pending == METHOD_PENDING_WAIT)
1343                 sm->method_pending = METHOD_PENDING_CONT;
1344 }
1345
1346
1347 /**
1348  * eap_sm_method_pending - Query whether EAP method is waiting for pending data
1349  * @sm: Pointer to EAP state machine allocated with eap_server_sm_init()
1350  * Returns: 1 if method is waiting for pending data or 0 if not
1351  */
1352 int eap_sm_method_pending(struct eap_sm *sm)
1353 {
1354         if (sm == NULL)
1355                 return 0;
1356         return sm->method_pending == METHOD_PENDING_WAIT;
1357 }
1358
1359
1360 /**
1361  * eap_get_identity - Get the user identity (from EAP-Response/Identity)
1362  * @sm: Pointer to EAP state machine allocated with eap_server_sm_init()
1363  * @len: Buffer for returning identity length
1364  * Returns: Pointer to the user identity or %NULL if not available
1365  */
1366 const u8 * eap_get_identity(struct eap_sm *sm, size_t *len)
1367 {
1368         *len = sm->identity_len;
1369         return sm->identity;
1370 }
1371
1372
1373 /**
1374  * eap_get_interface - Get pointer to EAP-EAPOL interface data
1375  * @sm: Pointer to EAP state machine allocated with eap_server_sm_init()
1376  * Returns: Pointer to the EAP-EAPOL interface data
1377  */
1378 struct eap_eapol_interface * eap_get_interface(struct eap_sm *sm)
1379 {
1380         return &sm->eap_if;
1381 }
1382
1383
1384 /**
1385  * eap_server_clear_identity - Clear EAP identity information
1386  * @sm: Pointer to EAP state machine allocated with eap_server_sm_init()
1387  *
1388  * This function can be used to clear the EAP identity information in the EAP
1389  * server context. This allows the EAP/Identity method to be used again after
1390  * EAPOL-Start or EAPOL-Logoff.
1391  */
1392 void eap_server_clear_identity(struct eap_sm *sm)
1393 {
1394         os_free(sm->identity);
1395         sm->identity = NULL;
1396 }