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