]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - src/eap_server/eap_server.c
Import wpa_supplicant/hostapd 2.7
[FreeBSD/FreeBSD.git] / src / eap_server / eap_server.c
1 /*
2  * hostapd / EAP Full Authenticator state machine (RFC 4137)
3  * Copyright (c) 2004-2014, 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 "crypto/sha256.h"
19 #include "eap_i.h"
20 #include "state_machine.h"
21 #include "common/wpa_ctrl.h"
22
23 #define STATE_MACHINE_DATA struct eap_sm
24 #define STATE_MACHINE_DEBUG_PREFIX "EAP"
25
26 #define EAP_MAX_AUTH_ROUNDS 50
27
28 static void eap_user_free(struct eap_user *user);
29
30
31 /* EAP state machines are described in RFC 4137 */
32
33 static int eap_sm_calculateTimeout(struct eap_sm *sm, int retransCount,
34                                    int eapSRTT, int eapRTTVAR,
35                                    int methodTimeout);
36 static void eap_sm_parseEapResp(struct eap_sm *sm, const struct wpabuf *resp);
37 static int eap_sm_getId(const struct wpabuf *data);
38 static struct wpabuf * eap_sm_buildSuccess(struct eap_sm *sm, u8 id);
39 static struct wpabuf * eap_sm_buildFailure(struct eap_sm *sm, u8 id);
40 static int eap_sm_nextId(struct eap_sm *sm, int id);
41 static void eap_sm_Policy_update(struct eap_sm *sm, const u8 *nak_list,
42                                  size_t len);
43 static EapType eap_sm_Policy_getNextMethod(struct eap_sm *sm, int *vendor);
44 static int eap_sm_Policy_getDecision(struct eap_sm *sm);
45 static Boolean eap_sm_Policy_doPickUp(struct eap_sm *sm, EapType method);
46
47
48 static int eap_get_erp_send_reauth_start(struct eap_sm *sm)
49 {
50         if (sm->eapol_cb->get_erp_send_reauth_start)
51                 return sm->eapol_cb->get_erp_send_reauth_start(sm->eapol_ctx);
52         return 0;
53 }
54
55
56 static const char * eap_get_erp_domain(struct eap_sm *sm)
57 {
58         if (sm->eapol_cb->get_erp_domain)
59                 return sm->eapol_cb->get_erp_domain(sm->eapol_ctx);
60         return NULL;
61 }
62
63
64 #ifdef CONFIG_ERP
65
66 static struct eap_server_erp_key * eap_erp_get_key(struct eap_sm *sm,
67                                                    const char *keyname)
68 {
69         if (sm->eapol_cb->erp_get_key)
70                 return sm->eapol_cb->erp_get_key(sm->eapol_ctx, keyname);
71         return NULL;
72 }
73
74
75 static int eap_erp_add_key(struct eap_sm *sm, struct eap_server_erp_key *erp)
76 {
77         if (sm->eapol_cb->erp_add_key)
78                 return sm->eapol_cb->erp_add_key(sm->eapol_ctx, erp);
79         return -1;
80 }
81
82 #endif /* CONFIG_ERP */
83
84
85 static struct wpabuf * eap_sm_buildInitiateReauthStart(struct eap_sm *sm,
86                                                        u8 id)
87 {
88         const char *domain;
89         size_t plen = 1;
90         struct wpabuf *msg;
91         size_t domain_len = 0;
92
93         domain = eap_get_erp_domain(sm);
94         if (domain) {
95                 domain_len = os_strlen(domain);
96                 plen += 2 + domain_len;
97         }
98
99         msg = eap_msg_alloc(EAP_VENDOR_IETF,
100                             (EapType) EAP_ERP_TYPE_REAUTH_START, plen,
101                             EAP_CODE_INITIATE, id);
102         if (msg == NULL)
103                 return NULL;
104         wpabuf_put_u8(msg, 0); /* Reserved */
105         if (domain) {
106                 /* Domain name TLV */
107                 wpabuf_put_u8(msg, EAP_ERP_TLV_DOMAIN_NAME);
108                 wpabuf_put_u8(msg, domain_len);
109                 wpabuf_put_data(msg, domain, domain_len);
110         }
111
112         return msg;
113 }
114
115
116 static int eap_copy_buf(struct wpabuf **dst, const struct wpabuf *src)
117 {
118         if (src == NULL)
119                 return -1;
120
121         wpabuf_free(*dst);
122         *dst = wpabuf_dup(src);
123         return *dst ? 0 : -1;
124 }
125
126
127 static int eap_copy_data(u8 **dst, size_t *dst_len,
128                          const u8 *src, size_t src_len)
129 {
130         if (src == NULL)
131                 return -1;
132
133         os_free(*dst);
134         *dst = os_malloc(src_len);
135         if (*dst) {
136                 os_memcpy(*dst, src, src_len);
137                 *dst_len = src_len;
138                 return 0;
139         } else {
140                 *dst_len = 0;
141                 return -1;
142         }
143 }
144
145 #define EAP_COPY(dst, src) \
146         eap_copy_data((dst), (dst ## Len), (src), (src ## Len))
147
148
149 /**
150  * eap_user_get - Fetch user information from the database
151  * @sm: Pointer to EAP state machine allocated with eap_server_sm_init()
152  * @identity: Identity (User-Name) of the user
153  * @identity_len: Length of identity in bytes
154  * @phase2: 0 = EAP phase1 user, 1 = EAP phase2 (tunneled) user
155  * Returns: 0 on success, or -1 on failure
156  *
157  * This function is used to fetch user information for EAP. The user will be
158  * selected based on the specified identity. sm->user and
159  * sm->user_eap_method_index are updated for the new user when a matching user
160  * is found. sm->user can be used to get user information (e.g., password).
161  */
162 int eap_user_get(struct eap_sm *sm, const u8 *identity, size_t identity_len,
163                  int phase2)
164 {
165         struct eap_user *user;
166
167         if (sm == NULL || sm->eapol_cb == NULL ||
168             sm->eapol_cb->get_eap_user == NULL)
169                 return -1;
170
171         eap_user_free(sm->user);
172         sm->user = NULL;
173
174         user = os_zalloc(sizeof(*user));
175         if (user == NULL)
176             return -1;
177
178         if (sm->eapol_cb->get_eap_user(sm->eapol_ctx, identity,
179                                        identity_len, phase2, user) != 0) {
180                 eap_user_free(user);
181                 return -1;
182         }
183
184         sm->user = user;
185         sm->user_eap_method_index = 0;
186
187         return 0;
188 }
189
190
191 void eap_log_msg(struct eap_sm *sm, const char *fmt, ...)
192 {
193         va_list ap;
194         char *buf;
195         int buflen;
196
197         if (sm == NULL || sm->eapol_cb == NULL || sm->eapol_cb->log_msg == NULL)
198                 return;
199
200         va_start(ap, fmt);
201         buflen = vsnprintf(NULL, 0, fmt, ap) + 1;
202         va_end(ap);
203
204         buf = os_malloc(buflen);
205         if (buf == NULL)
206                 return;
207         va_start(ap, fmt);
208         vsnprintf(buf, buflen, fmt, ap);
209         va_end(ap);
210
211         sm->eapol_cb->log_msg(sm->eapol_ctx, buf);
212
213         os_free(buf);
214 }
215
216
217 SM_STATE(EAP, DISABLED)
218 {
219         SM_ENTRY(EAP, DISABLED);
220         sm->num_rounds = 0;
221 }
222
223
224 SM_STATE(EAP, INITIALIZE)
225 {
226         SM_ENTRY(EAP, INITIALIZE);
227
228         if (sm->eap_if.eapRestart && !sm->eap_server && sm->identity) {
229                 /*
230                  * Need to allow internal Identity method to be used instead
231                  * of passthrough at the beginning of reauthentication.
232                  */
233                 eap_server_clear_identity(sm);
234         }
235
236         sm->try_initiate_reauth = FALSE;
237         sm->currentId = -1;
238         sm->eap_if.eapSuccess = FALSE;
239         sm->eap_if.eapFail = FALSE;
240         sm->eap_if.eapTimeout = FALSE;
241         bin_clear_free(sm->eap_if.eapKeyData, sm->eap_if.eapKeyDataLen);
242         sm->eap_if.eapKeyData = NULL;
243         sm->eap_if.eapKeyDataLen = 0;
244         os_free(sm->eap_if.eapSessionId);
245         sm->eap_if.eapSessionId = NULL;
246         sm->eap_if.eapSessionIdLen = 0;
247         sm->eap_if.eapKeyAvailable = FALSE;
248         sm->eap_if.eapRestart = FALSE;
249
250         /*
251          * This is not defined in RFC 4137, but method state needs to be
252          * reseted here so that it does not remain in success state when
253          * re-authentication starts.
254          */
255         if (sm->m && sm->eap_method_priv) {
256                 sm->m->reset(sm, sm->eap_method_priv);
257                 sm->eap_method_priv = NULL;
258         }
259         sm->m = NULL;
260         sm->user_eap_method_index = 0;
261
262         if (sm->backend_auth) {
263                 sm->currentMethod = EAP_TYPE_NONE;
264                 /* parse rxResp, respId, respMethod */
265                 eap_sm_parseEapResp(sm, sm->eap_if.eapRespData);
266                 if (sm->rxResp) {
267                         sm->currentId = sm->respId;
268                 }
269         }
270         sm->num_rounds = 0;
271         sm->method_pending = METHOD_PENDING_NONE;
272
273         wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_STARTED
274                 MACSTR, MAC2STR(sm->peer_addr));
275 }
276
277
278 SM_STATE(EAP, PICK_UP_METHOD)
279 {
280         SM_ENTRY(EAP, PICK_UP_METHOD);
281
282         if (eap_sm_Policy_doPickUp(sm, sm->respMethod)) {
283                 sm->currentMethod = sm->respMethod;
284                 if (sm->m && sm->eap_method_priv) {
285                         sm->m->reset(sm, sm->eap_method_priv);
286                         sm->eap_method_priv = NULL;
287                 }
288                 sm->m = eap_server_get_eap_method(EAP_VENDOR_IETF,
289                                                   sm->currentMethod);
290                 if (sm->m && sm->m->initPickUp) {
291                         sm->eap_method_priv = sm->m->initPickUp(sm);
292                         if (sm->eap_method_priv == NULL) {
293                                 wpa_printf(MSG_DEBUG, "EAP: Failed to "
294                                            "initialize EAP method %d",
295                                            sm->currentMethod);
296                                 sm->m = NULL;
297                                 sm->currentMethod = EAP_TYPE_NONE;
298                         }
299                 } else {
300                         sm->m = NULL;
301                         sm->currentMethod = EAP_TYPE_NONE;
302                 }
303         }
304
305         wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_PROPOSED_METHOD
306                 "method=%u", sm->currentMethod);
307 }
308
309
310 SM_STATE(EAP, IDLE)
311 {
312         SM_ENTRY(EAP, IDLE);
313
314         sm->eap_if.retransWhile = eap_sm_calculateTimeout(
315                 sm, sm->retransCount, sm->eap_if.eapSRTT, sm->eap_if.eapRTTVAR,
316                 sm->methodTimeout);
317 }
318
319
320 SM_STATE(EAP, RETRANSMIT)
321 {
322         SM_ENTRY(EAP, RETRANSMIT);
323
324         sm->retransCount++;
325         if (sm->retransCount <= sm->MaxRetrans && sm->lastReqData) {
326                 if (eap_copy_buf(&sm->eap_if.eapReqData, sm->lastReqData) == 0)
327                         sm->eap_if.eapReq = TRUE;
328         }
329
330         wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_RETRANSMIT MACSTR,
331                 MAC2STR(sm->peer_addr));
332 }
333
334
335 SM_STATE(EAP, RECEIVED)
336 {
337         SM_ENTRY(EAP, RECEIVED);
338
339         /* parse rxResp, respId, respMethod */
340         eap_sm_parseEapResp(sm, sm->eap_if.eapRespData);
341         sm->num_rounds++;
342 }
343
344
345 SM_STATE(EAP, DISCARD)
346 {
347         SM_ENTRY(EAP, DISCARD);
348         sm->eap_if.eapResp = FALSE;
349         sm->eap_if.eapNoReq = TRUE;
350 }
351
352
353 SM_STATE(EAP, SEND_REQUEST)
354 {
355         SM_ENTRY(EAP, SEND_REQUEST);
356
357         sm->retransCount = 0;
358         if (sm->eap_if.eapReqData) {
359                 if (eap_copy_buf(&sm->lastReqData, sm->eap_if.eapReqData) == 0)
360                 {
361                         sm->eap_if.eapResp = FALSE;
362                         sm->eap_if.eapReq = TRUE;
363                 } else {
364                         sm->eap_if.eapResp = FALSE;
365                         sm->eap_if.eapReq = FALSE;
366                 }
367         } else {
368                 wpa_printf(MSG_INFO, "EAP: SEND_REQUEST - no eapReqData");
369                 sm->eap_if.eapResp = FALSE;
370                 sm->eap_if.eapReq = FALSE;
371                 sm->eap_if.eapNoReq = TRUE;
372         }
373 }
374
375
376 SM_STATE(EAP, INTEGRITY_CHECK)
377 {
378         SM_ENTRY(EAP, INTEGRITY_CHECK);
379
380         if (!eap_hdr_len_valid(sm->eap_if.eapRespData, 1)) {
381                 sm->ignore = TRUE;
382                 return;
383         }
384
385         if (sm->m->check) {
386                 sm->ignore = sm->m->check(sm, sm->eap_method_priv,
387                                           sm->eap_if.eapRespData);
388         }
389 }
390
391
392 SM_STATE(EAP, METHOD_REQUEST)
393 {
394         SM_ENTRY(EAP, METHOD_REQUEST);
395
396         if (sm->m == NULL) {
397                 wpa_printf(MSG_DEBUG, "EAP: method not initialized");
398                 return;
399         }
400
401         sm->currentId = eap_sm_nextId(sm, sm->currentId);
402         wpa_printf(MSG_DEBUG, "EAP: building EAP-Request: Identifier %d",
403                    sm->currentId);
404         sm->lastId = sm->currentId;
405         wpabuf_free(sm->eap_if.eapReqData);
406         sm->eap_if.eapReqData = sm->m->buildReq(sm, sm->eap_method_priv,
407                                                 sm->currentId);
408         if (sm->m->getTimeout)
409                 sm->methodTimeout = sm->m->getTimeout(sm, sm->eap_method_priv);
410         else
411                 sm->methodTimeout = 0;
412 }
413
414
415 static void eap_server_erp_init(struct eap_sm *sm)
416 {
417 #ifdef CONFIG_ERP
418         u8 *emsk = NULL;
419         size_t emsk_len = 0;
420         u8 EMSKname[EAP_EMSK_NAME_LEN];
421         u8 len[2], ctx[3];
422         const char *domain;
423         size_t domain_len, nai_buf_len;
424         struct eap_server_erp_key *erp = NULL;
425         int pos;
426
427         domain = eap_get_erp_domain(sm);
428         if (!domain)
429                 return;
430
431         domain_len = os_strlen(domain);
432
433         nai_buf_len = 2 * EAP_EMSK_NAME_LEN + 1 + domain_len;
434         if (nai_buf_len > 253) {
435                 /*
436                  * keyName-NAI has a maximum length of 253 octet to fit in
437                  * RADIUS attributes.
438                  */
439                 wpa_printf(MSG_DEBUG,
440                            "EAP: Too long realm for ERP keyName-NAI maximum length");
441                 return;
442         }
443         nai_buf_len++; /* null termination */
444         erp = os_zalloc(sizeof(*erp) + nai_buf_len);
445         if (erp == NULL)
446                 goto fail;
447         erp->recv_seq = (u32) -1;
448
449         emsk = sm->m->get_emsk(sm, sm->eap_method_priv, &emsk_len);
450         if (!emsk || emsk_len == 0 || emsk_len > ERP_MAX_KEY_LEN) {
451                 wpa_printf(MSG_DEBUG,
452                            "EAP: No suitable EMSK available for ERP");
453                 goto fail;
454         }
455
456         wpa_hexdump_key(MSG_DEBUG, "EAP: EMSK", emsk, emsk_len);
457
458         WPA_PUT_BE16(len, EAP_EMSK_NAME_LEN);
459         if (hmac_sha256_kdf(sm->eap_if.eapSessionId, sm->eap_if.eapSessionIdLen,
460                             "EMSK", len, sizeof(len),
461                             EMSKname, EAP_EMSK_NAME_LEN) < 0) {
462                 wpa_printf(MSG_DEBUG, "EAP: Could not derive EMSKname");
463                 goto fail;
464         }
465         wpa_hexdump(MSG_DEBUG, "EAP: EMSKname", EMSKname, EAP_EMSK_NAME_LEN);
466
467         pos = wpa_snprintf_hex(erp->keyname_nai, nai_buf_len,
468                                EMSKname, EAP_EMSK_NAME_LEN);
469         erp->keyname_nai[pos] = '@';
470         os_memcpy(&erp->keyname_nai[pos + 1], domain, domain_len);
471
472         WPA_PUT_BE16(len, emsk_len);
473         if (hmac_sha256_kdf(emsk, emsk_len,
474                             "EAP Re-authentication Root Key@ietf.org",
475                             len, sizeof(len), erp->rRK, emsk_len) < 0) {
476                 wpa_printf(MSG_DEBUG, "EAP: Could not derive rRK for ERP");
477                 goto fail;
478         }
479         erp->rRK_len = emsk_len;
480         wpa_hexdump_key(MSG_DEBUG, "EAP: ERP rRK", erp->rRK, erp->rRK_len);
481
482         ctx[0] = EAP_ERP_CS_HMAC_SHA256_128;
483         WPA_PUT_BE16(&ctx[1], erp->rRK_len);
484         if (hmac_sha256_kdf(erp->rRK, erp->rRK_len,
485                             "Re-authentication Integrity Key@ietf.org",
486                             ctx, sizeof(ctx), erp->rIK, erp->rRK_len) < 0) {
487                 wpa_printf(MSG_DEBUG, "EAP: Could not derive rIK for ERP");
488                 goto fail;
489         }
490         erp->rIK_len = erp->rRK_len;
491         wpa_hexdump_key(MSG_DEBUG, "EAP: ERP rIK", erp->rIK, erp->rIK_len);
492
493         if (eap_erp_add_key(sm, erp) == 0) {
494                 wpa_printf(MSG_DEBUG, "EAP: Stored ERP keys %s",
495                            erp->keyname_nai);
496                 erp = NULL;
497         }
498
499 fail:
500         bin_clear_free(emsk, emsk_len);
501         bin_clear_free(erp, sizeof(*erp));
502 #endif /* CONFIG_ERP */
503 }
504
505
506 SM_STATE(EAP, METHOD_RESPONSE)
507 {
508         SM_ENTRY(EAP, METHOD_RESPONSE);
509
510         if (!eap_hdr_len_valid(sm->eap_if.eapRespData, 1))
511                 return;
512
513         sm->m->process(sm, sm->eap_method_priv, sm->eap_if.eapRespData);
514         if (sm->m->isDone(sm, sm->eap_method_priv)) {
515                 eap_sm_Policy_update(sm, NULL, 0);
516                 bin_clear_free(sm->eap_if.eapKeyData, sm->eap_if.eapKeyDataLen);
517                 if (sm->m->getKey) {
518                         sm->eap_if.eapKeyData = sm->m->getKey(
519                                 sm, sm->eap_method_priv,
520                                 &sm->eap_if.eapKeyDataLen);
521                 } else {
522                         sm->eap_if.eapKeyData = NULL;
523                         sm->eap_if.eapKeyDataLen = 0;
524                 }
525                 os_free(sm->eap_if.eapSessionId);
526                 sm->eap_if.eapSessionId = NULL;
527                 if (sm->m->getSessionId) {
528                         sm->eap_if.eapSessionId = sm->m->getSessionId(
529                                 sm, sm->eap_method_priv,
530                                 &sm->eap_if.eapSessionIdLen);
531                         wpa_hexdump(MSG_DEBUG, "EAP: Session-Id",
532                                     sm->eap_if.eapSessionId,
533                                     sm->eap_if.eapSessionIdLen);
534                 }
535                 if (sm->erp && sm->m->get_emsk && sm->eap_if.eapSessionId)
536                         eap_server_erp_init(sm);
537                 sm->methodState = METHOD_END;
538         } else {
539                 sm->methodState = METHOD_CONTINUE;
540         }
541 }
542
543
544 SM_STATE(EAP, PROPOSE_METHOD)
545 {
546         int vendor;
547         EapType type;
548
549         SM_ENTRY(EAP, PROPOSE_METHOD);
550
551         sm->try_initiate_reauth = FALSE;
552 try_another_method:
553         type = eap_sm_Policy_getNextMethod(sm, &vendor);
554         if (vendor == EAP_VENDOR_IETF)
555                 sm->currentMethod = type;
556         else
557                 sm->currentMethod = EAP_TYPE_EXPANDED;
558         if (sm->m && sm->eap_method_priv) {
559                 sm->m->reset(sm, sm->eap_method_priv);
560                 sm->eap_method_priv = NULL;
561         }
562         sm->m = eap_server_get_eap_method(vendor, type);
563         if (sm->m) {
564                 sm->eap_method_priv = sm->m->init(sm);
565                 if (sm->eap_method_priv == NULL) {
566                         wpa_printf(MSG_DEBUG, "EAP: Failed to initialize EAP "
567                                    "method %d", sm->currentMethod);
568                         sm->m = NULL;
569                         sm->currentMethod = EAP_TYPE_NONE;
570                         goto try_another_method;
571                 }
572         }
573         if (sm->m == NULL) {
574                 wpa_printf(MSG_DEBUG, "EAP: Could not find suitable EAP method");
575                 eap_log_msg(sm, "Could not find suitable EAP method");
576                 sm->decision = DECISION_FAILURE;
577                 return;
578         }
579         if (sm->currentMethod == EAP_TYPE_IDENTITY ||
580             sm->currentMethod == EAP_TYPE_NOTIFICATION)
581                 sm->methodState = METHOD_CONTINUE;
582         else
583                 sm->methodState = METHOD_PROPOSED;
584
585         wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_PROPOSED_METHOD
586                 "vendor=%u method=%u", vendor, sm->currentMethod);
587         eap_log_msg(sm, "Propose EAP method vendor=%u method=%u",
588                     vendor, sm->currentMethod);
589 }
590
591
592 SM_STATE(EAP, NAK)
593 {
594         const struct eap_hdr *nak;
595         size_t len = 0;
596         const u8 *pos;
597         const u8 *nak_list = NULL;
598
599         SM_ENTRY(EAP, NAK);
600
601         if (sm->eap_method_priv) {
602                 sm->m->reset(sm, sm->eap_method_priv);
603                 sm->eap_method_priv = NULL;
604         }
605         sm->m = NULL;
606
607         if (!eap_hdr_len_valid(sm->eap_if.eapRespData, 1))
608                 return;
609
610         nak = wpabuf_head(sm->eap_if.eapRespData);
611         if (nak && wpabuf_len(sm->eap_if.eapRespData) > sizeof(*nak)) {
612                 len = be_to_host16(nak->length);
613                 if (len > wpabuf_len(sm->eap_if.eapRespData))
614                         len = wpabuf_len(sm->eap_if.eapRespData);
615                 pos = (const u8 *) (nak + 1);
616                 len -= sizeof(*nak);
617                 if (*pos == EAP_TYPE_NAK) {
618                         pos++;
619                         len--;
620                         nak_list = pos;
621                 }
622         }
623         eap_sm_Policy_update(sm, nak_list, len);
624 }
625
626
627 SM_STATE(EAP, SELECT_ACTION)
628 {
629         SM_ENTRY(EAP, SELECT_ACTION);
630
631         sm->decision = eap_sm_Policy_getDecision(sm);
632 }
633
634
635 SM_STATE(EAP, TIMEOUT_FAILURE)
636 {
637         SM_ENTRY(EAP, TIMEOUT_FAILURE);
638
639         sm->eap_if.eapTimeout = TRUE;
640
641         wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_TIMEOUT_FAILURE MACSTR,
642                 MAC2STR(sm->peer_addr));
643 }
644
645
646 SM_STATE(EAP, FAILURE)
647 {
648         SM_ENTRY(EAP, FAILURE);
649
650         wpabuf_free(sm->eap_if.eapReqData);
651         sm->eap_if.eapReqData = eap_sm_buildFailure(sm, sm->currentId);
652         wpabuf_free(sm->lastReqData);
653         sm->lastReqData = NULL;
654         sm->eap_if.eapFail = TRUE;
655
656         wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_FAILURE
657                 MACSTR, MAC2STR(sm->peer_addr));
658 }
659
660
661 SM_STATE(EAP, SUCCESS)
662 {
663         SM_ENTRY(EAP, SUCCESS);
664
665         wpabuf_free(sm->eap_if.eapReqData);
666         sm->eap_if.eapReqData = eap_sm_buildSuccess(sm, sm->currentId);
667         wpabuf_free(sm->lastReqData);
668         sm->lastReqData = NULL;
669         if (sm->eap_if.eapKeyData)
670                 sm->eap_if.eapKeyAvailable = TRUE;
671         sm->eap_if.eapSuccess = TRUE;
672
673         wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_SUCCESS
674                 MACSTR, MAC2STR(sm->peer_addr));
675 }
676
677
678 SM_STATE(EAP, INITIATE_REAUTH_START)
679 {
680         SM_ENTRY(EAP, INITIATE_REAUTH_START);
681
682         sm->initiate_reauth_start_sent = TRUE;
683         sm->try_initiate_reauth = TRUE;
684         sm->currentId = eap_sm_nextId(sm, sm->currentId);
685         wpa_printf(MSG_DEBUG,
686                    "EAP: building EAP-Initiate-Re-auth-Start: Identifier %d",
687                    sm->currentId);
688         sm->lastId = sm->currentId;
689         wpabuf_free(sm->eap_if.eapReqData);
690         sm->eap_if.eapReqData = eap_sm_buildInitiateReauthStart(sm,
691                                                                 sm->currentId);
692         wpabuf_free(sm->lastReqData);
693         sm->lastReqData = NULL;
694 }
695
696
697 #ifdef CONFIG_ERP
698
699 static void erp_send_finish_reauth(struct eap_sm *sm,
700                                    struct eap_server_erp_key *erp, u8 id,
701                                    u8 flags, u16 seq, const char *nai)
702 {
703         size_t plen;
704         struct wpabuf *msg;
705         u8 hash[SHA256_MAC_LEN];
706         size_t hash_len;
707         u8 seed[4];
708
709         if (erp) {
710                 switch (erp->cryptosuite) {
711                 case EAP_ERP_CS_HMAC_SHA256_256:
712                         hash_len = 32;
713                         break;
714                 case EAP_ERP_CS_HMAC_SHA256_128:
715                         hash_len = 16;
716                         break;
717                 default:
718                         return;
719                 }
720         } else
721                 hash_len = 0;
722
723         plen = 1 + 2 + 2 + os_strlen(nai);
724         if (hash_len)
725                 plen += 1 + hash_len;
726         msg = eap_msg_alloc(EAP_VENDOR_IETF, (EapType) EAP_ERP_TYPE_REAUTH,
727                             plen, EAP_CODE_FINISH, id);
728         if (msg == NULL)
729                 return;
730         wpabuf_put_u8(msg, flags);
731         wpabuf_put_be16(msg, seq);
732
733         wpabuf_put_u8(msg, EAP_ERP_TLV_KEYNAME_NAI);
734         wpabuf_put_u8(msg, os_strlen(nai));
735         wpabuf_put_str(msg, nai);
736
737         if (erp) {
738                 wpabuf_put_u8(msg, erp->cryptosuite);
739                 if (hmac_sha256(erp->rIK, erp->rIK_len,
740                                 wpabuf_head(msg), wpabuf_len(msg), hash) < 0) {
741                         wpabuf_free(msg);
742                         return;
743                 }
744                 wpabuf_put_data(msg, hash, hash_len);
745         }
746
747         wpa_printf(MSG_DEBUG, "EAP: Send EAP-Finish/Re-auth (%s)",
748                    flags & 0x80 ? "failure" : "success");
749
750         sm->lastId = sm->currentId;
751         sm->currentId = id;
752         wpabuf_free(sm->eap_if.eapReqData);
753         sm->eap_if.eapReqData = msg;
754         wpabuf_free(sm->lastReqData);
755         sm->lastReqData = NULL;
756
757         if ((flags & 0x80) || !erp) {
758                 sm->eap_if.eapFail = TRUE;
759                 wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_FAILURE
760                         MACSTR, MAC2STR(sm->peer_addr));
761                 return;
762         }
763
764         bin_clear_free(sm->eap_if.eapKeyData, sm->eap_if.eapKeyDataLen);
765         sm->eap_if.eapKeyDataLen = 0;
766         sm->eap_if.eapKeyData = os_malloc(erp->rRK_len);
767         if (!sm->eap_if.eapKeyData)
768                 return;
769
770         WPA_PUT_BE16(seed, seq);
771         WPA_PUT_BE16(&seed[2], erp->rRK_len);
772         if (hmac_sha256_kdf(erp->rRK, erp->rRK_len,
773                             "Re-authentication Master Session Key@ietf.org",
774                             seed, sizeof(seed),
775                             sm->eap_if.eapKeyData, erp->rRK_len) < 0) {
776                 wpa_printf(MSG_DEBUG, "EAP: Could not derive rMSK for ERP");
777                 bin_clear_free(sm->eap_if.eapKeyData, erp->rRK_len);
778                 sm->eap_if.eapKeyData = NULL;
779                 return;
780         }
781         sm->eap_if.eapKeyDataLen = erp->rRK_len;
782         sm->eap_if.eapKeyAvailable = TRUE;
783         wpa_hexdump_key(MSG_DEBUG, "EAP: ERP rMSK",
784                         sm->eap_if.eapKeyData, sm->eap_if.eapKeyDataLen);
785         sm->eap_if.eapSuccess = TRUE;
786
787         wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_SUCCESS
788                 MACSTR, MAC2STR(sm->peer_addr));
789 }
790
791
792 SM_STATE(EAP, INITIATE_RECEIVED)
793 {
794         const u8 *pos, *end, *start, *tlvs, *hdr;
795         const struct eap_hdr *ehdr;
796         size_t len;
797         u8 flags;
798         u16 seq;
799         char nai[254];
800         struct eap_server_erp_key *erp;
801         int max_len;
802         u8 hash[SHA256_MAC_LEN];
803         size_t hash_len;
804         struct erp_tlvs parse;
805         u8 resp_flags = 0x80; /* default to failure; cleared on success */
806
807         SM_ENTRY(EAP, INITIATE_RECEIVED);
808
809         sm->rxInitiate = FALSE;
810
811         pos = eap_hdr_validate(EAP_VENDOR_IETF, (EapType) EAP_ERP_TYPE_REAUTH,
812                                sm->eap_if.eapRespData, &len);
813         if (pos == NULL) {
814                 wpa_printf(MSG_INFO, "EAP-Initiate: Invalid frame");
815                 goto fail;
816         }
817         hdr = wpabuf_head(sm->eap_if.eapRespData);
818         ehdr = wpabuf_head(sm->eap_if.eapRespData);
819
820         wpa_hexdump(MSG_DEBUG, "EAP: EAP-Initiate/Re-Auth", pos, len);
821         if (len < 4) {
822                 wpa_printf(MSG_INFO, "EAP: Too short EAP-Initiate/Re-auth");
823                 goto fail;
824         }
825         end = pos + len;
826
827         flags = *pos++;
828         seq = WPA_GET_BE16(pos);
829         pos += 2;
830         wpa_printf(MSG_DEBUG, "EAP: Flags=0x%x SEQ=%u", flags, seq);
831         tlvs = pos;
832
833         /*
834          * Parse TVs/TLVs. Since we do not yet know the length of the
835          * Authentication Tag, stop parsing if an unknown TV/TLV is seen and
836          * just try to find the keyName-NAI first so that we can check the
837          * Authentication Tag.
838          */
839         if (erp_parse_tlvs(tlvs, end, &parse, 1) < 0)
840                 goto fail;
841
842         if (!parse.keyname) {
843                 wpa_printf(MSG_DEBUG,
844                            "EAP: No keyName-NAI in EAP-Initiate/Re-auth Packet");
845                 goto fail;
846         }
847
848         wpa_hexdump_ascii(MSG_DEBUG, "EAP: EAP-Initiate/Re-auth - keyName-NAI",
849                           parse.keyname, parse.keyname_len);
850         if (parse.keyname_len > 253) {
851                 wpa_printf(MSG_DEBUG,
852                            "EAP: Too long keyName-NAI in EAP-Initiate/Re-auth");
853                 goto fail;
854         }
855         os_memcpy(nai, parse.keyname, parse.keyname_len);
856         nai[parse.keyname_len] = '\0';
857
858         if (!sm->eap_server) {
859                 /*
860                  * In passthrough case, EAP-Initiate/Re-auth replaces
861                  * EAP Identity exchange. Use keyName-NAI as the user identity
862                  * and forward EAP-Initiate/Re-auth to the backend
863                  * authentication server.
864                  */
865                 wpa_printf(MSG_DEBUG,
866                            "EAP: Use keyName-NAI as user identity for backend authentication");
867                 eap_server_clear_identity(sm);
868                 sm->identity = (u8 *) dup_binstr(parse.keyname,
869                                                  parse.keyname_len);
870                 if (!sm->identity)
871                         goto fail;
872                 sm->identity_len = parse.keyname_len;
873                 return;
874         }
875
876         erp = eap_erp_get_key(sm, nai);
877         if (!erp) {
878                 wpa_printf(MSG_DEBUG, "EAP: No matching ERP key found for %s",
879                            nai);
880                 goto report_error;
881         }
882
883         if (erp->recv_seq != (u32) -1 && erp->recv_seq >= seq) {
884                 wpa_printf(MSG_DEBUG,
885                            "EAP: SEQ=%u replayed (already received SEQ=%u)",
886                            seq, erp->recv_seq);
887                 goto fail;
888         }
889
890         /* Is there enough room for Cryptosuite and Authentication Tag? */
891         start = parse.keyname + parse.keyname_len;
892         max_len = end - start;
893         if (max_len <
894             1 + (erp->cryptosuite == EAP_ERP_CS_HMAC_SHA256_256 ? 32 : 16)) {
895                 wpa_printf(MSG_DEBUG,
896                            "EAP: Not enough room for Authentication Tag");
897                 goto fail;
898         }
899
900         switch (erp->cryptosuite) {
901         case EAP_ERP_CS_HMAC_SHA256_256:
902                 if (end[-33] != erp->cryptosuite) {
903                         wpa_printf(MSG_DEBUG,
904                                    "EAP: Different Cryptosuite used");
905                         goto fail;
906                 }
907                 hash_len = 32;
908                 break;
909         case EAP_ERP_CS_HMAC_SHA256_128:
910                 if (end[-17] != erp->cryptosuite) {
911                         wpa_printf(MSG_DEBUG,
912                                    "EAP: Different Cryptosuite used");
913                         goto fail;
914                 }
915                 hash_len = 16;
916                 break;
917         default:
918                 hash_len = 0;
919                 break;
920         }
921
922         if (hash_len) {
923                 if (hmac_sha256(erp->rIK, erp->rIK_len, hdr,
924                                 end - hdr - hash_len, hash) < 0)
925                         goto fail;
926                 if (os_memcmp(end - hash_len, hash, hash_len) != 0) {
927                         wpa_printf(MSG_DEBUG,
928                                    "EAP: Authentication Tag mismatch");
929                         goto fail;
930                 }
931         }
932
933         /* Check if any supported CS results in matching tag */
934         if (!hash_len && max_len >= 1 + 32 &&
935             end[-33] == EAP_ERP_CS_HMAC_SHA256_256) {
936                 if (hmac_sha256(erp->rIK, erp->rIK_len, hdr,
937                                 end - hdr - 32, hash) < 0)
938                         goto fail;
939                 if (os_memcmp(end - 32, hash, 32) == 0) {
940                         wpa_printf(MSG_DEBUG,
941                                    "EAP: Authentication Tag match using HMAC-SHA256-256");
942                         hash_len = 32;
943                         erp->cryptosuite = EAP_ERP_CS_HMAC_SHA256_256;
944                 }
945         }
946
947         if (!hash_len && end[-17] == EAP_ERP_CS_HMAC_SHA256_128) {
948                 if (hmac_sha256(erp->rIK, erp->rIK_len, hdr,
949                                 end - hdr - 16, hash) < 0)
950                         goto fail;
951                 if (os_memcmp(end - 16, hash, 16) == 0) {
952                         wpa_printf(MSG_DEBUG,
953                                    "EAP: Authentication Tag match using HMAC-SHA256-128");
954                         hash_len = 16;
955                         erp->cryptosuite = EAP_ERP_CS_HMAC_SHA256_128;
956                 }
957         }
958
959         if (!hash_len) {
960                 wpa_printf(MSG_DEBUG,
961                            "EAP: No supported cryptosuite matched Authentication Tag");
962                 goto fail;
963         }
964         end -= 1 + hash_len;
965
966         /*
967          * Parse TVs/TLVs again now that we know the exact part of the buffer
968          * that contains them.
969          */
970         wpa_hexdump(MSG_DEBUG, "EAP: EAP-Initiate/Re-Auth TVs/TLVs",
971                     tlvs, end - tlvs);
972         if (erp_parse_tlvs(tlvs, end, &parse, 0) < 0)
973                 goto fail;
974
975         wpa_printf(MSG_DEBUG, "EAP: ERP key %s SEQ updated to %u",
976                    erp->keyname_nai, seq);
977         erp->recv_seq = seq;
978         resp_flags &= ~0x80; /* R=0 - success */
979
980 report_error:
981         erp_send_finish_reauth(sm, erp, ehdr->identifier, resp_flags, seq, nai);
982         return;
983
984 fail:
985         sm->ignore = TRUE;
986 }
987
988 #endif /* CONFIG_ERP */
989
990
991 SM_STATE(EAP, INITIALIZE_PASSTHROUGH)
992 {
993         SM_ENTRY(EAP, INITIALIZE_PASSTHROUGH);
994
995         wpabuf_free(sm->eap_if.aaaEapRespData);
996         sm->eap_if.aaaEapRespData = NULL;
997         sm->try_initiate_reauth = FALSE;
998 }
999
1000
1001 SM_STATE(EAP, IDLE2)
1002 {
1003         SM_ENTRY(EAP, IDLE2);
1004
1005         sm->eap_if.retransWhile = eap_sm_calculateTimeout(
1006                 sm, sm->retransCount, sm->eap_if.eapSRTT, sm->eap_if.eapRTTVAR,
1007                 sm->methodTimeout);
1008 }
1009
1010
1011 SM_STATE(EAP, RETRANSMIT2)
1012 {
1013         SM_ENTRY(EAP, RETRANSMIT2);
1014
1015         sm->retransCount++;
1016         if (sm->retransCount <= sm->MaxRetrans && sm->lastReqData) {
1017                 if (eap_copy_buf(&sm->eap_if.eapReqData, sm->lastReqData) == 0)
1018                         sm->eap_if.eapReq = TRUE;
1019         }
1020
1021         wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_RETRANSMIT2 MACSTR,
1022                 MAC2STR(sm->peer_addr));
1023 }
1024
1025
1026 SM_STATE(EAP, RECEIVED2)
1027 {
1028         SM_ENTRY(EAP, RECEIVED2);
1029
1030         /* parse rxResp, respId, respMethod */
1031         eap_sm_parseEapResp(sm, sm->eap_if.eapRespData);
1032 }
1033
1034
1035 SM_STATE(EAP, DISCARD2)
1036 {
1037         SM_ENTRY(EAP, DISCARD2);
1038         sm->eap_if.eapResp = FALSE;
1039         sm->eap_if.eapNoReq = TRUE;
1040 }
1041
1042
1043 SM_STATE(EAP, SEND_REQUEST2)
1044 {
1045         SM_ENTRY(EAP, SEND_REQUEST2);
1046
1047         sm->retransCount = 0;
1048         if (sm->eap_if.eapReqData) {
1049                 if (eap_copy_buf(&sm->lastReqData, sm->eap_if.eapReqData) == 0)
1050                 {
1051                         sm->eap_if.eapResp = FALSE;
1052                         sm->eap_if.eapReq = TRUE;
1053                 } else {
1054                         sm->eap_if.eapResp = FALSE;
1055                         sm->eap_if.eapReq = FALSE;
1056                 }
1057         } else {
1058                 wpa_printf(MSG_INFO, "EAP: SEND_REQUEST2 - no eapReqData");
1059                 sm->eap_if.eapResp = FALSE;
1060                 sm->eap_if.eapReq = FALSE;
1061                 sm->eap_if.eapNoReq = TRUE;
1062         }
1063 }
1064
1065
1066 SM_STATE(EAP, AAA_REQUEST)
1067 {
1068         SM_ENTRY(EAP, AAA_REQUEST);
1069
1070         if (sm->eap_if.eapRespData == NULL) {
1071                 wpa_printf(MSG_INFO, "EAP: AAA_REQUEST - no eapRespData");
1072                 return;
1073         }
1074
1075         /*
1076          * if (respMethod == IDENTITY)
1077          *      aaaIdentity = eapRespData
1078          * This is already taken care of by the EAP-Identity method which
1079          * stores the identity into sm->identity.
1080          */
1081
1082         eap_copy_buf(&sm->eap_if.aaaEapRespData, sm->eap_if.eapRespData);
1083 }
1084
1085
1086 SM_STATE(EAP, AAA_RESPONSE)
1087 {
1088         SM_ENTRY(EAP, AAA_RESPONSE);
1089
1090         eap_copy_buf(&sm->eap_if.eapReqData, sm->eap_if.aaaEapReqData);
1091         sm->currentId = eap_sm_getId(sm->eap_if.eapReqData);
1092         sm->methodTimeout = sm->eap_if.aaaMethodTimeout;
1093 }
1094
1095
1096 SM_STATE(EAP, AAA_IDLE)
1097 {
1098         SM_ENTRY(EAP, AAA_IDLE);
1099
1100         sm->eap_if.aaaFail = FALSE;
1101         sm->eap_if.aaaSuccess = FALSE;
1102         sm->eap_if.aaaEapReq = FALSE;
1103         sm->eap_if.aaaEapNoReq = FALSE;
1104         sm->eap_if.aaaEapResp = TRUE;
1105 }
1106
1107
1108 SM_STATE(EAP, TIMEOUT_FAILURE2)
1109 {
1110         SM_ENTRY(EAP, TIMEOUT_FAILURE2);
1111
1112         sm->eap_if.eapTimeout = TRUE;
1113
1114         wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_TIMEOUT_FAILURE2 MACSTR,
1115                 MAC2STR(sm->peer_addr));
1116 }
1117
1118
1119 SM_STATE(EAP, FAILURE2)
1120 {
1121         SM_ENTRY(EAP, FAILURE2);
1122
1123         eap_copy_buf(&sm->eap_if.eapReqData, sm->eap_if.aaaEapReqData);
1124         sm->eap_if.eapFail = TRUE;
1125
1126         wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_FAILURE2 MACSTR,
1127                 MAC2STR(sm->peer_addr));
1128 }
1129
1130
1131 SM_STATE(EAP, SUCCESS2)
1132 {
1133         SM_ENTRY(EAP, SUCCESS2);
1134
1135         eap_copy_buf(&sm->eap_if.eapReqData, sm->eap_if.aaaEapReqData);
1136
1137         sm->eap_if.eapKeyAvailable = sm->eap_if.aaaEapKeyAvailable;
1138         if (sm->eap_if.aaaEapKeyAvailable) {
1139                 EAP_COPY(&sm->eap_if.eapKeyData, sm->eap_if.aaaEapKeyData);
1140         } else {
1141                 bin_clear_free(sm->eap_if.eapKeyData, sm->eap_if.eapKeyDataLen);
1142                 sm->eap_if.eapKeyData = NULL;
1143                 sm->eap_if.eapKeyDataLen = 0;
1144         }
1145
1146         sm->eap_if.eapSuccess = TRUE;
1147
1148         /*
1149          * Start reauthentication with identity request even though we know the
1150          * previously used identity. This is needed to get reauthentication
1151          * started properly.
1152          */
1153         sm->start_reauth = TRUE;
1154
1155         wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_SUCCESS2 MACSTR,
1156                 MAC2STR(sm->peer_addr));
1157 }
1158
1159
1160 SM_STEP(EAP)
1161 {
1162         if (sm->eap_if.eapRestart && sm->eap_if.portEnabled)
1163                 SM_ENTER_GLOBAL(EAP, INITIALIZE);
1164         else if (!sm->eap_if.portEnabled)
1165                 SM_ENTER_GLOBAL(EAP, DISABLED);
1166         else if (sm->num_rounds > EAP_MAX_AUTH_ROUNDS) {
1167                 if (sm->num_rounds == EAP_MAX_AUTH_ROUNDS + 1) {
1168                         wpa_printf(MSG_DEBUG, "EAP: more than %d "
1169                                    "authentication rounds - abort",
1170                                    EAP_MAX_AUTH_ROUNDS);
1171                         sm->num_rounds++;
1172                         SM_ENTER_GLOBAL(EAP, FAILURE);
1173                 }
1174         } else switch (sm->EAP_state) {
1175         case EAP_INITIALIZE:
1176                 if (sm->backend_auth) {
1177                         if (!sm->rxResp)
1178                                 SM_ENTER(EAP, SELECT_ACTION);
1179                         else if (sm->rxResp &&
1180                                  (sm->respMethod == EAP_TYPE_NAK ||
1181                                   (sm->respMethod == EAP_TYPE_EXPANDED &&
1182                                    sm->respVendor == EAP_VENDOR_IETF &&
1183                                    sm->respVendorMethod == EAP_TYPE_NAK)))
1184                                 SM_ENTER(EAP, NAK);
1185                         else
1186                                 SM_ENTER(EAP, PICK_UP_METHOD);
1187                 } else {
1188                         SM_ENTER(EAP, SELECT_ACTION);
1189                 }
1190                 break;
1191         case EAP_PICK_UP_METHOD:
1192                 if (sm->currentMethod == EAP_TYPE_NONE) {
1193                         SM_ENTER(EAP, SELECT_ACTION);
1194                 } else {
1195                         SM_ENTER(EAP, METHOD_RESPONSE);
1196                 }
1197                 break;
1198         case EAP_DISABLED:
1199                 if (sm->eap_if.portEnabled)
1200                         SM_ENTER(EAP, INITIALIZE);
1201                 break;
1202         case EAP_IDLE:
1203                 if (sm->eap_if.retransWhile == 0) {
1204                         if (sm->try_initiate_reauth) {
1205                                 sm->try_initiate_reauth = FALSE;
1206                                 SM_ENTER(EAP, SELECT_ACTION);
1207                         } else {
1208                                 SM_ENTER(EAP, RETRANSMIT);
1209                         }
1210                 } else if (sm->eap_if.eapResp)
1211                         SM_ENTER(EAP, RECEIVED);
1212                 break;
1213         case EAP_RETRANSMIT:
1214                 if (sm->retransCount > sm->MaxRetrans)
1215                         SM_ENTER(EAP, TIMEOUT_FAILURE);
1216                 else
1217                         SM_ENTER(EAP, IDLE);
1218                 break;
1219         case EAP_RECEIVED:
1220                 if (sm->rxResp && (sm->respId == sm->currentId) &&
1221                     (sm->respMethod == EAP_TYPE_NAK ||
1222                      (sm->respMethod == EAP_TYPE_EXPANDED &&
1223                       sm->respVendor == EAP_VENDOR_IETF &&
1224                       sm->respVendorMethod == EAP_TYPE_NAK))
1225                     && (sm->methodState == METHOD_PROPOSED))
1226                         SM_ENTER(EAP, NAK);
1227                 else if (sm->rxResp && (sm->respId == sm->currentId) &&
1228                          ((sm->respMethod == sm->currentMethod) ||
1229                           (sm->respMethod == EAP_TYPE_EXPANDED &&
1230                            sm->respVendor == EAP_VENDOR_IETF &&
1231                            sm->respVendorMethod == sm->currentMethod)))
1232                         SM_ENTER(EAP, INTEGRITY_CHECK);
1233 #ifdef CONFIG_ERP
1234                 else if (sm->rxInitiate)
1235                         SM_ENTER(EAP, INITIATE_RECEIVED);
1236 #endif /* CONFIG_ERP */
1237                 else {
1238                         wpa_printf(MSG_DEBUG, "EAP: RECEIVED->DISCARD: "
1239                                    "rxResp=%d respId=%d currentId=%d "
1240                                    "respMethod=%d currentMethod=%d",
1241                                    sm->rxResp, sm->respId, sm->currentId,
1242                                    sm->respMethod, sm->currentMethod);
1243                         eap_log_msg(sm, "Discard received EAP message");
1244                         SM_ENTER(EAP, DISCARD);
1245                 }
1246                 break;
1247         case EAP_DISCARD:
1248                 SM_ENTER(EAP, IDLE);
1249                 break;
1250         case EAP_SEND_REQUEST:
1251                 SM_ENTER(EAP, IDLE);
1252                 break;
1253         case EAP_INTEGRITY_CHECK:
1254                 if (sm->ignore)
1255                         SM_ENTER(EAP, DISCARD);
1256                 else
1257                         SM_ENTER(EAP, METHOD_RESPONSE);
1258                 break;
1259         case EAP_METHOD_REQUEST:
1260                 if (sm->m == NULL) {
1261                         /*
1262                          * This transition is not mentioned in RFC 4137, but it
1263                          * is needed to handle cleanly a case where EAP method
1264                          * initialization fails.
1265                          */
1266                         SM_ENTER(EAP, FAILURE);
1267                         break;
1268                 }
1269                 SM_ENTER(EAP, SEND_REQUEST);
1270                 if (sm->eap_if.eapNoReq && !sm->eap_if.eapReq) {
1271                         /*
1272                          * This transition is not mentioned in RFC 4137, but it
1273                          * is needed to handle cleanly a case where EAP method
1274                          * buildReq fails.
1275                          */
1276                         wpa_printf(MSG_DEBUG,
1277                                    "EAP: Method did not return a request");
1278                         SM_ENTER(EAP, FAILURE);
1279                         break;
1280                 }
1281                 break;
1282         case EAP_METHOD_RESPONSE:
1283                 /*
1284                  * Note: Mechanism to allow EAP methods to wait while going
1285                  * through pending processing is an extension to RFC 4137
1286                  * which only defines the transits to SELECT_ACTION and
1287                  * METHOD_REQUEST from this METHOD_RESPONSE state.
1288                  */
1289                 if (sm->methodState == METHOD_END)
1290                         SM_ENTER(EAP, SELECT_ACTION);
1291                 else if (sm->method_pending == METHOD_PENDING_WAIT) {
1292                         wpa_printf(MSG_DEBUG, "EAP: Method has pending "
1293                                    "processing - wait before proceeding to "
1294                                    "METHOD_REQUEST state");
1295                 } else if (sm->method_pending == METHOD_PENDING_CONT) {
1296                         wpa_printf(MSG_DEBUG, "EAP: Method has completed "
1297                                    "pending processing - reprocess pending "
1298                                    "EAP message");
1299                         sm->method_pending = METHOD_PENDING_NONE;
1300                         SM_ENTER(EAP, METHOD_RESPONSE);
1301                 } else
1302                         SM_ENTER(EAP, METHOD_REQUEST);
1303                 break;
1304         case EAP_PROPOSE_METHOD:
1305                 /*
1306                  * Note: Mechanism to allow EAP methods to wait while going
1307                  * through pending processing is an extension to RFC 4137
1308                  * which only defines the transit to METHOD_REQUEST from this
1309                  * PROPOSE_METHOD state.
1310                  */
1311                 if (sm->method_pending == METHOD_PENDING_WAIT) {
1312                         wpa_printf(MSG_DEBUG, "EAP: Method has pending "
1313                                    "processing - wait before proceeding to "
1314                                    "METHOD_REQUEST state");
1315                         if (sm->user_eap_method_index > 0)
1316                                 sm->user_eap_method_index--;
1317                 } else if (sm->method_pending == METHOD_PENDING_CONT) {
1318                         wpa_printf(MSG_DEBUG, "EAP: Method has completed "
1319                                    "pending processing - reprocess pending "
1320                                    "EAP message");
1321                         sm->method_pending = METHOD_PENDING_NONE;
1322                         SM_ENTER(EAP, PROPOSE_METHOD);
1323                 } else
1324                         SM_ENTER(EAP, METHOD_REQUEST);
1325                 break;
1326         case EAP_NAK:
1327                 SM_ENTER(EAP, SELECT_ACTION);
1328                 break;
1329         case EAP_SELECT_ACTION:
1330                 if (sm->decision == DECISION_FAILURE)
1331                         SM_ENTER(EAP, FAILURE);
1332                 else if (sm->decision == DECISION_SUCCESS)
1333                         SM_ENTER(EAP, SUCCESS);
1334                 else if (sm->decision == DECISION_PASSTHROUGH)
1335                         SM_ENTER(EAP, INITIALIZE_PASSTHROUGH);
1336                 else if (sm->decision == DECISION_INITIATE_REAUTH_START)
1337                         SM_ENTER(EAP, INITIATE_REAUTH_START);
1338 #ifdef CONFIG_ERP
1339                 else if (sm->eap_server && sm->erp && sm->rxInitiate)
1340                         SM_ENTER(EAP, INITIATE_RECEIVED);
1341 #endif /* CONFIG_ERP */
1342                 else
1343                         SM_ENTER(EAP, PROPOSE_METHOD);
1344                 break;
1345         case EAP_INITIATE_REAUTH_START:
1346                 SM_ENTER(EAP, SEND_REQUEST);
1347                 break;
1348         case EAP_INITIATE_RECEIVED:
1349                 if (!sm->eap_server)
1350                         SM_ENTER(EAP, SELECT_ACTION);
1351                 break;
1352         case EAP_TIMEOUT_FAILURE:
1353                 break;
1354         case EAP_FAILURE:
1355                 break;
1356         case EAP_SUCCESS:
1357                 break;
1358
1359         case EAP_INITIALIZE_PASSTHROUGH:
1360                 if (sm->currentId == -1)
1361                         SM_ENTER(EAP, AAA_IDLE);
1362                 else
1363                         SM_ENTER(EAP, AAA_REQUEST);
1364                 break;
1365         case EAP_IDLE2:
1366                 if (sm->eap_if.eapResp)
1367                         SM_ENTER(EAP, RECEIVED2);
1368                 else if (sm->eap_if.retransWhile == 0)
1369                         SM_ENTER(EAP, RETRANSMIT2);
1370                 break;
1371         case EAP_RETRANSMIT2:
1372                 if (sm->retransCount > sm->MaxRetrans)
1373                         SM_ENTER(EAP, TIMEOUT_FAILURE2);
1374                 else
1375                         SM_ENTER(EAP, IDLE2);
1376                 break;
1377         case EAP_RECEIVED2:
1378                 if (sm->rxResp && (sm->respId == sm->currentId))
1379                         SM_ENTER(EAP, AAA_REQUEST);
1380                 else
1381                         SM_ENTER(EAP, DISCARD2);
1382                 break;
1383         case EAP_DISCARD2:
1384                 SM_ENTER(EAP, IDLE2);
1385                 break;
1386         case EAP_SEND_REQUEST2:
1387                 SM_ENTER(EAP, IDLE2);
1388                 break;
1389         case EAP_AAA_REQUEST:
1390                 SM_ENTER(EAP, AAA_IDLE);
1391                 break;
1392         case EAP_AAA_RESPONSE:
1393                 SM_ENTER(EAP, SEND_REQUEST2);
1394                 break;
1395         case EAP_AAA_IDLE:
1396                 if (sm->eap_if.aaaFail)
1397                         SM_ENTER(EAP, FAILURE2);
1398                 else if (sm->eap_if.aaaSuccess)
1399                         SM_ENTER(EAP, SUCCESS2);
1400                 else if (sm->eap_if.aaaEapReq)
1401                         SM_ENTER(EAP, AAA_RESPONSE);
1402                 else if (sm->eap_if.aaaTimeout)
1403                         SM_ENTER(EAP, TIMEOUT_FAILURE2);
1404                 break;
1405         case EAP_TIMEOUT_FAILURE2:
1406                 break;
1407         case EAP_FAILURE2:
1408                 break;
1409         case EAP_SUCCESS2:
1410                 break;
1411         }
1412 }
1413
1414
1415 static int eap_sm_calculateTimeout(struct eap_sm *sm, int retransCount,
1416                                    int eapSRTT, int eapRTTVAR,
1417                                    int methodTimeout)
1418 {
1419         int rto, i;
1420
1421         if (sm->try_initiate_reauth) {
1422                 wpa_printf(MSG_DEBUG,
1423                            "EAP: retransmit timeout 1 second for EAP-Initiate-Re-auth-Start");
1424                 return 1;
1425         }
1426
1427         if (methodTimeout) {
1428                 /*
1429                  * EAP method (either internal or through AAA server, provided
1430                  * timeout hint. Use that as-is as a timeout for retransmitting
1431                  * the EAP request if no response is received.
1432                  */
1433                 wpa_printf(MSG_DEBUG, "EAP: retransmit timeout %d seconds "
1434                            "(from EAP method hint)", methodTimeout);
1435                 return methodTimeout;
1436         }
1437
1438         /*
1439          * RFC 3748 recommends algorithms described in RFC 2988 for estimation
1440          * of the retransmission timeout. This should be implemented once
1441          * round-trip time measurements are available. For nowm a simple
1442          * backoff mechanism is used instead if there are no EAP method
1443          * specific hints.
1444          *
1445          * SRTT = smoothed round-trip time
1446          * RTTVAR = round-trip time variation
1447          * RTO = retransmission timeout
1448          */
1449
1450         /*
1451          * RFC 2988, 2.1: before RTT measurement, set RTO to 3 seconds for
1452          * initial retransmission and then double the RTO to provide back off
1453          * per 5.5. Limit the maximum RTO to 20 seconds per RFC 3748, 4.3
1454          * modified RTOmax.
1455          */
1456         rto = 3;
1457         for (i = 0; i < retransCount; i++) {
1458                 rto *= 2;
1459                 if (rto >= 20) {
1460                         rto = 20;
1461                         break;
1462                 }
1463         }
1464
1465         wpa_printf(MSG_DEBUG, "EAP: retransmit timeout %d seconds "
1466                    "(from dynamic back off; retransCount=%d)",
1467                    rto, retransCount);
1468
1469         return rto;
1470 }
1471
1472
1473 static void eap_sm_parseEapResp(struct eap_sm *sm, const struct wpabuf *resp)
1474 {
1475         const struct eap_hdr *hdr;
1476         size_t plen;
1477
1478         /* parse rxResp, respId, respMethod */
1479         sm->rxResp = FALSE;
1480         sm->rxInitiate = FALSE;
1481         sm->respId = -1;
1482         sm->respMethod = EAP_TYPE_NONE;
1483         sm->respVendor = EAP_VENDOR_IETF;
1484         sm->respVendorMethod = EAP_TYPE_NONE;
1485
1486         if (resp == NULL || wpabuf_len(resp) < sizeof(*hdr)) {
1487                 wpa_printf(MSG_DEBUG, "EAP: parseEapResp: invalid resp=%p "
1488                            "len=%lu", resp,
1489                            resp ? (unsigned long) wpabuf_len(resp) : 0);
1490                 return;
1491         }
1492
1493         hdr = wpabuf_head(resp);
1494         plen = be_to_host16(hdr->length);
1495         if (plen > wpabuf_len(resp)) {
1496                 wpa_printf(MSG_DEBUG, "EAP: Ignored truncated EAP-Packet "
1497                            "(len=%lu plen=%lu)",
1498                            (unsigned long) wpabuf_len(resp),
1499                            (unsigned long) plen);
1500                 return;
1501         }
1502
1503         sm->respId = hdr->identifier;
1504
1505         if (hdr->code == EAP_CODE_RESPONSE)
1506                 sm->rxResp = TRUE;
1507         else if (hdr->code == EAP_CODE_INITIATE)
1508                 sm->rxInitiate = TRUE;
1509
1510         if (plen > sizeof(*hdr)) {
1511                 u8 *pos = (u8 *) (hdr + 1);
1512                 sm->respMethod = *pos++;
1513                 if (sm->respMethod == EAP_TYPE_EXPANDED) {
1514                         if (plen < sizeof(*hdr) + 8) {
1515                                 wpa_printf(MSG_DEBUG, "EAP: Ignored truncated "
1516                                            "expanded EAP-Packet (plen=%lu)",
1517                                            (unsigned long) plen);
1518                                 return;
1519                         }
1520                         sm->respVendor = WPA_GET_BE24(pos);
1521                         pos += 3;
1522                         sm->respVendorMethod = WPA_GET_BE32(pos);
1523                 }
1524         }
1525
1526         wpa_printf(MSG_DEBUG,
1527                    "EAP: parseEapResp: rxResp=%d rxInitiate=%d respId=%d respMethod=%u respVendor=%u respVendorMethod=%u",
1528                    sm->rxResp, sm->rxInitiate, sm->respId, sm->respMethod,
1529                    sm->respVendor, sm->respVendorMethod);
1530 }
1531
1532
1533 static int eap_sm_getId(const struct wpabuf *data)
1534 {
1535         const struct eap_hdr *hdr;
1536
1537         if (data == NULL || wpabuf_len(data) < sizeof(*hdr))
1538                 return -1;
1539
1540         hdr = wpabuf_head(data);
1541         wpa_printf(MSG_DEBUG, "EAP: getId: id=%d", hdr->identifier);
1542         return hdr->identifier;
1543 }
1544
1545
1546 static struct wpabuf * eap_sm_buildSuccess(struct eap_sm *sm, u8 id)
1547 {
1548         struct wpabuf *msg;
1549         struct eap_hdr *resp;
1550         wpa_printf(MSG_DEBUG, "EAP: Building EAP-Success (id=%d)", id);
1551
1552         msg = wpabuf_alloc(sizeof(*resp));
1553         if (msg == NULL)
1554                 return NULL;
1555         resp = wpabuf_put(msg, sizeof(*resp));
1556         resp->code = EAP_CODE_SUCCESS;
1557         resp->identifier = id;
1558         resp->length = host_to_be16(sizeof(*resp));
1559
1560         return msg;
1561 }
1562
1563
1564 static struct wpabuf * eap_sm_buildFailure(struct eap_sm *sm, u8 id)
1565 {
1566         struct wpabuf *msg;
1567         struct eap_hdr *resp;
1568         wpa_printf(MSG_DEBUG, "EAP: Building EAP-Failure (id=%d)", id);
1569
1570         msg = wpabuf_alloc(sizeof(*resp));
1571         if (msg == NULL)
1572                 return NULL;
1573         resp = wpabuf_put(msg, sizeof(*resp));
1574         resp->code = EAP_CODE_FAILURE;
1575         resp->identifier = id;
1576         resp->length = host_to_be16(sizeof(*resp));
1577
1578         return msg;
1579 }
1580
1581
1582 static int eap_sm_nextId(struct eap_sm *sm, int id)
1583 {
1584         if (id < 0) {
1585                 /* RFC 3748 Ch 4.1: recommended to initialize Identifier with a
1586                  * random number */
1587                 id = rand() & 0xff;
1588                 if (id != sm->lastId)
1589                         return id;
1590         }
1591         return (id + 1) & 0xff;
1592 }
1593
1594
1595 /**
1596  * eap_sm_process_nak - Process EAP-Response/Nak
1597  * @sm: Pointer to EAP state machine allocated with eap_server_sm_init()
1598  * @nak_list: Nak list (allowed methods) from the supplicant
1599  * @len: Length of nak_list in bytes
1600  *
1601  * This function is called when EAP-Response/Nak is received from the
1602  * supplicant. This can happen for both phase 1 and phase 2 authentications.
1603  */
1604 void eap_sm_process_nak(struct eap_sm *sm, const u8 *nak_list, size_t len)
1605 {
1606         int i;
1607         size_t j;
1608
1609         if (sm->user == NULL)
1610                 return;
1611
1612         wpa_printf(MSG_MSGDUMP, "EAP: processing NAK (current EAP method "
1613                    "index %d)", sm->user_eap_method_index);
1614
1615         wpa_hexdump(MSG_MSGDUMP, "EAP: configured methods",
1616                     (u8 *) sm->user->methods,
1617                     EAP_MAX_METHODS * sizeof(sm->user->methods[0]));
1618         wpa_hexdump(MSG_MSGDUMP, "EAP: list of methods supported by the peer",
1619                     nak_list, len);
1620
1621         i = sm->user_eap_method_index;
1622         while (i < EAP_MAX_METHODS &&
1623                (sm->user->methods[i].vendor != EAP_VENDOR_IETF ||
1624                 sm->user->methods[i].method != EAP_TYPE_NONE)) {
1625                 if (sm->user->methods[i].vendor != EAP_VENDOR_IETF)
1626                         goto not_found;
1627                 for (j = 0; j < len; j++) {
1628                         if (nak_list[j] == sm->user->methods[i].method) {
1629                                 break;
1630                         }
1631                 }
1632
1633                 if (j < len) {
1634                         /* found */
1635                         i++;
1636                         continue;
1637                 }
1638
1639         not_found:
1640                 /* not found - remove from the list */
1641                 if (i + 1 < EAP_MAX_METHODS) {
1642                         os_memmove(&sm->user->methods[i],
1643                                    &sm->user->methods[i + 1],
1644                                    (EAP_MAX_METHODS - i - 1) *
1645                                    sizeof(sm->user->methods[0]));
1646                 }
1647                 sm->user->methods[EAP_MAX_METHODS - 1].vendor =
1648                         EAP_VENDOR_IETF;
1649                 sm->user->methods[EAP_MAX_METHODS - 1].method = EAP_TYPE_NONE;
1650         }
1651
1652         wpa_hexdump(MSG_MSGDUMP, "EAP: new list of configured methods",
1653                     (u8 *) sm->user->methods, EAP_MAX_METHODS *
1654                     sizeof(sm->user->methods[0]));
1655 }
1656
1657
1658 static void eap_sm_Policy_update(struct eap_sm *sm, const u8 *nak_list,
1659                                  size_t len)
1660 {
1661         if (nak_list == NULL || sm == NULL || sm->user == NULL)
1662                 return;
1663
1664         if (sm->user->phase2) {
1665                 wpa_printf(MSG_DEBUG, "EAP: EAP-Nak received after Phase2 user"
1666                            " info was selected - reject");
1667                 sm->decision = DECISION_FAILURE;
1668                 return;
1669         }
1670
1671         eap_sm_process_nak(sm, nak_list, len);
1672 }
1673
1674
1675 static EapType eap_sm_Policy_getNextMethod(struct eap_sm *sm, int *vendor)
1676 {
1677         EapType next;
1678         int idx = sm->user_eap_method_index;
1679
1680         /* In theory, there should be no problems with starting
1681          * re-authentication with something else than EAP-Request/Identity and
1682          * this does indeed work with wpa_supplicant. However, at least Funk
1683          * Supplicant seemed to ignore re-auth if it skipped
1684          * EAP-Request/Identity.
1685          * Re-auth sets currentId == -1, so that can be used here to select
1686          * whether Identity needs to be requested again. */
1687         if (sm->identity == NULL || sm->currentId == -1) {
1688                 *vendor = EAP_VENDOR_IETF;
1689                 next = EAP_TYPE_IDENTITY;
1690                 sm->update_user = TRUE;
1691         } else if (sm->user && idx < EAP_MAX_METHODS &&
1692                    (sm->user->methods[idx].vendor != EAP_VENDOR_IETF ||
1693                     sm->user->methods[idx].method != EAP_TYPE_NONE)) {
1694                 *vendor = sm->user->methods[idx].vendor;
1695                 next = sm->user->methods[idx].method;
1696                 sm->user_eap_method_index++;
1697         } else {
1698                 *vendor = EAP_VENDOR_IETF;
1699                 next = EAP_TYPE_NONE;
1700         }
1701         wpa_printf(MSG_DEBUG, "EAP: getNextMethod: vendor %d type %d",
1702                    *vendor, next);
1703         return next;
1704 }
1705
1706
1707 static int eap_sm_Policy_getDecision(struct eap_sm *sm)
1708 {
1709         if (!sm->eap_server && sm->identity && !sm->start_reauth) {
1710                 wpa_printf(MSG_DEBUG, "EAP: getDecision: -> PASSTHROUGH");
1711                 return DECISION_PASSTHROUGH;
1712         }
1713
1714         if (sm->m && sm->currentMethod != EAP_TYPE_IDENTITY &&
1715             sm->m->isSuccess(sm, sm->eap_method_priv)) {
1716                 wpa_printf(MSG_DEBUG, "EAP: getDecision: method succeeded -> "
1717                            "SUCCESS");
1718                 sm->update_user = TRUE;
1719                 return DECISION_SUCCESS;
1720         }
1721
1722         if (sm->m && sm->m->isDone(sm, sm->eap_method_priv) &&
1723             !sm->m->isSuccess(sm, sm->eap_method_priv)) {
1724                 wpa_printf(MSG_DEBUG, "EAP: getDecision: method failed -> "
1725                            "FAILURE");
1726                 sm->update_user = TRUE;
1727                 return DECISION_FAILURE;
1728         }
1729
1730         if ((sm->user == NULL || sm->update_user) && sm->identity &&
1731             !sm->start_reauth) {
1732                 /*
1733                  * Allow Identity method to be started once to allow identity
1734                  * selection hint to be sent from the authentication server,
1735                  * but prevent a loop of Identity requests by only allowing
1736                  * this to happen once.
1737                  */
1738                 int id_req = 0;
1739                 if (sm->user && sm->currentMethod == EAP_TYPE_IDENTITY &&
1740                     sm->user->methods[0].vendor == EAP_VENDOR_IETF &&
1741                     sm->user->methods[0].method == EAP_TYPE_IDENTITY)
1742                         id_req = 1;
1743                 if (eap_user_get(sm, sm->identity, sm->identity_len, 0) != 0) {
1744                         wpa_printf(MSG_DEBUG, "EAP: getDecision: user not "
1745                                    "found from database -> FAILURE");
1746                         return DECISION_FAILURE;
1747                 }
1748                 if (id_req && sm->user &&
1749                     sm->user->methods[0].vendor == EAP_VENDOR_IETF &&
1750                     sm->user->methods[0].method == EAP_TYPE_IDENTITY) {
1751                         wpa_printf(MSG_DEBUG, "EAP: getDecision: stop "
1752                                    "identity request loop -> FAILURE");
1753                         sm->update_user = TRUE;
1754                         return DECISION_FAILURE;
1755                 }
1756                 sm->update_user = FALSE;
1757         }
1758         sm->start_reauth = FALSE;
1759
1760         if (sm->user && sm->user_eap_method_index < EAP_MAX_METHODS &&
1761             (sm->user->methods[sm->user_eap_method_index].vendor !=
1762              EAP_VENDOR_IETF ||
1763              sm->user->methods[sm->user_eap_method_index].method !=
1764              EAP_TYPE_NONE)) {
1765                 wpa_printf(MSG_DEBUG, "EAP: getDecision: another method "
1766                            "available -> CONTINUE");
1767                 return DECISION_CONTINUE;
1768         }
1769
1770         if (!sm->identity && eap_get_erp_send_reauth_start(sm) &&
1771             !sm->initiate_reauth_start_sent) {
1772                 wpa_printf(MSG_DEBUG,
1773                            "EAP: getDecision: send EAP-Initiate/Re-auth-Start");
1774                 return DECISION_INITIATE_REAUTH_START;
1775         }
1776
1777         if (sm->identity == NULL || sm->currentId == -1) {
1778                 wpa_printf(MSG_DEBUG, "EAP: getDecision: no identity known "
1779                            "yet -> CONTINUE");
1780                 return DECISION_CONTINUE;
1781         }
1782
1783         wpa_printf(MSG_DEBUG, "EAP: getDecision: no more methods available -> "
1784                    "FAILURE");
1785         return DECISION_FAILURE;
1786 }
1787
1788
1789 static Boolean eap_sm_Policy_doPickUp(struct eap_sm *sm, EapType method)
1790 {
1791         return method == EAP_TYPE_IDENTITY ? TRUE : FALSE;
1792 }
1793
1794
1795 /**
1796  * eap_server_sm_step - Step EAP server state machine
1797  * @sm: Pointer to EAP state machine allocated with eap_server_sm_init()
1798  * Returns: 1 if EAP state was changed or 0 if not
1799  *
1800  * This function advances EAP state machine to a new state to match with the
1801  * current variables. This should be called whenever variables used by the EAP
1802  * state machine have changed.
1803  */
1804 int eap_server_sm_step(struct eap_sm *sm)
1805 {
1806         int res = 0;
1807         do {
1808                 sm->changed = FALSE;
1809                 SM_STEP_RUN(EAP);
1810                 if (sm->changed)
1811                         res = 1;
1812         } while (sm->changed);
1813         return res;
1814 }
1815
1816
1817 static void eap_user_free(struct eap_user *user)
1818 {
1819         if (user == NULL)
1820                 return;
1821         bin_clear_free(user->password, user->password_len);
1822         user->password = NULL;
1823         bin_clear_free(user->salt, user->salt_len);
1824         user->salt = NULL;
1825         os_free(user);
1826 }
1827
1828
1829 /**
1830  * eap_server_sm_init - Allocate and initialize EAP server state machine
1831  * @eapol_ctx: Context data to be used with eapol_cb calls
1832  * @eapol_cb: Pointer to EAPOL callback functions
1833  * @conf: EAP configuration
1834  * Returns: Pointer to the allocated EAP state machine or %NULL on failure
1835  *
1836  * This function allocates and initializes an EAP state machine.
1837  */
1838 struct eap_sm * eap_server_sm_init(void *eapol_ctx,
1839                                    const struct eapol_callbacks *eapol_cb,
1840                                    struct eap_config *conf)
1841 {
1842         struct eap_sm *sm;
1843
1844         sm = os_zalloc(sizeof(*sm));
1845         if (sm == NULL)
1846                 return NULL;
1847         sm->eapol_ctx = eapol_ctx;
1848         sm->eapol_cb = eapol_cb;
1849         sm->MaxRetrans = 5; /* RFC 3748: max 3-5 retransmissions suggested */
1850         sm->ssl_ctx = conf->ssl_ctx;
1851         sm->msg_ctx = conf->msg_ctx;
1852         sm->eap_sim_db_priv = conf->eap_sim_db_priv;
1853         sm->backend_auth = conf->backend_auth;
1854         sm->eap_server = conf->eap_server;
1855         if (conf->pac_opaque_encr_key) {
1856                 sm->pac_opaque_encr_key = os_malloc(16);
1857                 if (sm->pac_opaque_encr_key) {
1858                         os_memcpy(sm->pac_opaque_encr_key,
1859                                   conf->pac_opaque_encr_key, 16);
1860                 }
1861         }
1862         if (conf->eap_fast_a_id) {
1863                 sm->eap_fast_a_id = os_malloc(conf->eap_fast_a_id_len);
1864                 if (sm->eap_fast_a_id) {
1865                         os_memcpy(sm->eap_fast_a_id, conf->eap_fast_a_id,
1866                                   conf->eap_fast_a_id_len);
1867                         sm->eap_fast_a_id_len = conf->eap_fast_a_id_len;
1868                 }
1869         }
1870         if (conf->eap_fast_a_id_info)
1871                 sm->eap_fast_a_id_info = os_strdup(conf->eap_fast_a_id_info);
1872         sm->eap_fast_prov = conf->eap_fast_prov;
1873         sm->pac_key_lifetime = conf->pac_key_lifetime;
1874         sm->pac_key_refresh_time = conf->pac_key_refresh_time;
1875         sm->eap_sim_aka_result_ind = conf->eap_sim_aka_result_ind;
1876         sm->tnc = conf->tnc;
1877         sm->wps = conf->wps;
1878         if (conf->assoc_wps_ie)
1879                 sm->assoc_wps_ie = wpabuf_dup(conf->assoc_wps_ie);
1880         if (conf->assoc_p2p_ie)
1881                 sm->assoc_p2p_ie = wpabuf_dup(conf->assoc_p2p_ie);
1882         if (conf->peer_addr)
1883                 os_memcpy(sm->peer_addr, conf->peer_addr, ETH_ALEN);
1884         sm->fragment_size = conf->fragment_size;
1885         sm->pwd_group = conf->pwd_group;
1886         sm->pbc_in_m1 = conf->pbc_in_m1;
1887         sm->server_id = conf->server_id;
1888         sm->server_id_len = conf->server_id_len;
1889         sm->erp = conf->erp;
1890         sm->tls_session_lifetime = conf->tls_session_lifetime;
1891         sm->tls_flags = conf->tls_flags;
1892
1893 #ifdef CONFIG_TESTING_OPTIONS
1894         sm->tls_test_flags = conf->tls_test_flags;
1895 #endif /* CONFIG_TESTING_OPTIONS */
1896
1897         wpa_printf(MSG_DEBUG, "EAP: Server state machine created");
1898
1899         return sm;
1900 }
1901
1902
1903 /**
1904  * eap_server_sm_deinit - Deinitialize and free an EAP server state machine
1905  * @sm: Pointer to EAP state machine allocated with eap_server_sm_init()
1906  *
1907  * This function deinitializes EAP state machine and frees all allocated
1908  * resources.
1909  */
1910 void eap_server_sm_deinit(struct eap_sm *sm)
1911 {
1912         if (sm == NULL)
1913                 return;
1914         wpa_printf(MSG_DEBUG, "EAP: Server state machine removed");
1915         if (sm->m && sm->eap_method_priv)
1916                 sm->m->reset(sm, sm->eap_method_priv);
1917         wpabuf_free(sm->eap_if.eapReqData);
1918         bin_clear_free(sm->eap_if.eapKeyData, sm->eap_if.eapKeyDataLen);
1919         os_free(sm->eap_if.eapSessionId);
1920         wpabuf_free(sm->lastReqData);
1921         wpabuf_free(sm->eap_if.eapRespData);
1922         os_free(sm->identity);
1923         os_free(sm->serial_num);
1924         os_free(sm->pac_opaque_encr_key);
1925         os_free(sm->eap_fast_a_id);
1926         os_free(sm->eap_fast_a_id_info);
1927         wpabuf_free(sm->eap_if.aaaEapReqData);
1928         wpabuf_free(sm->eap_if.aaaEapRespData);
1929         bin_clear_free(sm->eap_if.aaaEapKeyData, sm->eap_if.aaaEapKeyDataLen);
1930         eap_user_free(sm->user);
1931         wpabuf_free(sm->assoc_wps_ie);
1932         wpabuf_free(sm->assoc_p2p_ie);
1933         os_free(sm);
1934 }
1935
1936
1937 /**
1938  * eap_sm_notify_cached - Notify EAP state machine of cached PMK
1939  * @sm: Pointer to EAP state machine allocated with eap_server_sm_init()
1940  *
1941  * This function is called when PMKSA caching is used to skip EAP
1942  * authentication.
1943  */
1944 void eap_sm_notify_cached(struct eap_sm *sm)
1945 {
1946         if (sm == NULL)
1947                 return;
1948
1949         sm->EAP_state = EAP_SUCCESS;
1950 }
1951
1952
1953 /**
1954  * eap_sm_pending_cb - EAP state machine callback for a pending EAP request
1955  * @sm: Pointer to EAP state machine allocated with eap_server_sm_init()
1956  *
1957  * This function is called when data for a pending EAP-Request is received.
1958  */
1959 void eap_sm_pending_cb(struct eap_sm *sm)
1960 {
1961         if (sm == NULL)
1962                 return;
1963         wpa_printf(MSG_DEBUG, "EAP: Callback for pending request received");
1964         if (sm->method_pending == METHOD_PENDING_WAIT)
1965                 sm->method_pending = METHOD_PENDING_CONT;
1966 }
1967
1968
1969 /**
1970  * eap_sm_method_pending - Query whether EAP method is waiting for pending data
1971  * @sm: Pointer to EAP state machine allocated with eap_server_sm_init()
1972  * Returns: 1 if method is waiting for pending data or 0 if not
1973  */
1974 int eap_sm_method_pending(struct eap_sm *sm)
1975 {
1976         if (sm == NULL)
1977                 return 0;
1978         return sm->method_pending == METHOD_PENDING_WAIT;
1979 }
1980
1981
1982 /**
1983  * eap_get_identity - Get the user identity (from EAP-Response/Identity)
1984  * @sm: Pointer to EAP state machine allocated with eap_server_sm_init()
1985  * @len: Buffer for returning identity length
1986  * Returns: Pointer to the user identity or %NULL if not available
1987  */
1988 const u8 * eap_get_identity(struct eap_sm *sm, size_t *len)
1989 {
1990         *len = sm->identity_len;
1991         return sm->identity;
1992 }
1993
1994
1995 /**
1996  * eap_get_serial_num - Get the serial number of user certificate
1997  * @sm: Pointer to EAP state machine allocated with eap_server_sm_init()
1998  * Returns: Pointer to the serial number or %NULL if not available
1999  */
2000 const char * eap_get_serial_num(struct eap_sm *sm)
2001 {
2002         return sm->serial_num;
2003 }
2004
2005
2006 void eap_erp_update_identity(struct eap_sm *sm, const u8 *eap, size_t len)
2007 {
2008 #ifdef CONFIG_ERP
2009         const struct eap_hdr *hdr;
2010         const u8 *pos, *end;
2011         struct erp_tlvs parse;
2012
2013         if (len < sizeof(*hdr) + 1)
2014                 return;
2015         hdr = (const struct eap_hdr *) eap;
2016         end = eap + len;
2017         pos = (const u8 *) (hdr + 1);
2018         if (hdr->code != EAP_CODE_INITIATE || *pos != EAP_ERP_TYPE_REAUTH)
2019                 return;
2020         pos++;
2021         if (pos + 3 > end)
2022                 return;
2023
2024         /* Skip Flags and SEQ */
2025         pos += 3;
2026
2027         if (erp_parse_tlvs(pos, end, &parse, 1) < 0 || !parse.keyname)
2028                 return;
2029         wpa_hexdump_ascii(MSG_DEBUG,
2030                           "EAP: Update identity based on EAP-Initiate/Re-auth keyName-NAI",
2031                           parse.keyname, parse.keyname_len);
2032         os_free(sm->identity);
2033         sm->identity = os_malloc(parse.keyname_len);
2034         if (sm->identity) {
2035                 os_memcpy(sm->identity, parse.keyname, parse.keyname_len);
2036                 sm->identity_len = parse.keyname_len;
2037         } else {
2038                 sm->identity_len = 0;
2039         }
2040 #endif /* CONFIG_ERP */
2041 }
2042
2043
2044 /**
2045  * eap_get_interface - Get pointer to EAP-EAPOL interface data
2046  * @sm: Pointer to EAP state machine allocated with eap_server_sm_init()
2047  * Returns: Pointer to the EAP-EAPOL interface data
2048  */
2049 struct eap_eapol_interface * eap_get_interface(struct eap_sm *sm)
2050 {
2051         return &sm->eap_if;
2052 }
2053
2054
2055 /**
2056  * eap_server_clear_identity - Clear EAP identity information
2057  * @sm: Pointer to EAP state machine allocated with eap_server_sm_init()
2058  *
2059  * This function can be used to clear the EAP identity information in the EAP
2060  * server context. This allows the EAP/Identity method to be used again after
2061  * EAPOL-Start or EAPOL-Logoff.
2062  */
2063 void eap_server_clear_identity(struct eap_sm *sm)
2064 {
2065         os_free(sm->identity);
2066         sm->identity = NULL;
2067 }
2068
2069
2070 #ifdef CONFIG_TESTING_OPTIONS
2071 void eap_server_mschap_rx_callback(struct eap_sm *sm, const char *source,
2072                                    const u8 *username, size_t username_len,
2073                                    const u8 *challenge, const u8 *response)
2074 {
2075         char hex_challenge[30], hex_response[90], user[100];
2076
2077         /* Print out Challenge and Response in format supported by asleap. */
2078         if (username)
2079                 printf_encode(user, sizeof(user), username, username_len);
2080         else
2081                 user[0] = '\0';
2082         wpa_snprintf_hex_sep(hex_challenge, sizeof(hex_challenge),
2083                              challenge, sizeof(challenge), ':');
2084         wpa_snprintf_hex_sep(hex_response, sizeof(hex_response), response, 24,
2085                              ':');
2086         wpa_printf(MSG_DEBUG, "[%s/user=%s] asleap -C %s -R %s",
2087                    source, user, hex_challenge, hex_response);
2088 }
2089 #endif /* CONFIG_TESTING_OPTIONS */