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