18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * EAP peer state machines (RFC 4137) 304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * Copyright (c) 2004-2012, Jouni Malinen <j@w1.fi> 48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 5c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * This software may be distributed under the terms of the BSD license. 6c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * See README for more details. 78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This file implements the Peer State Machine as defined in RFC 4137. The used 98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * states and state transitions match mostly with the RFC. However, there are 108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * couple of additional transitions for working around small issues noticed 118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * during testing. These exceptions are explained in comments within the 128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * functions in this file. The method functions, m.func(), are similar to the 138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * ones used in RFC 4137, but some small changes have used here to optimize 148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * operations and to add functionality needed for fast re-authentication 158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * (session resumption). 168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "includes.h" 198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common.h" 218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "pcsc_funcs.h" 228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "state_machine.h" 2361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#include "ext_password.h" 248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "crypto/crypto.h" 258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "crypto/tls.h" 268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common/wpa_ctrl.h" 278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eap_common/eap_wsc_common.h" 288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eap_i.h" 298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eap_config.h" 308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define STATE_MACHINE_DATA struct eap_sm 328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define STATE_MACHINE_DEBUG_PREFIX "EAP" 338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define EAP_MAX_AUTH_ROUNDS 50 358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define EAP_CLIENT_TIMEOUT_DEFAULT 60 368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic Boolean eap_sm_allowMethod(struct eap_sm *sm, int vendor, 398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EapType method); 408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpabuf * eap_sm_buildNak(struct eap_sm *sm, int id); 418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eap_sm_processIdentity(struct eap_sm *sm, 428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct wpabuf *req); 438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eap_sm_processNotify(struct eap_sm *sm, const struct wpabuf *req); 448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpabuf * eap_sm_buildNotify(int id); 458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eap_sm_parseEapReq(struct eap_sm *sm, const struct wpabuf *req); 468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#if defined(CONFIG_CTRL_IFACE) || !defined(CONFIG_NO_STDOUT_DEBUG) 478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic const char * eap_sm_method_state_txt(EapMethodState state); 488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic const char * eap_sm_decision_txt(EapDecision decision); 498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */ 508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic Boolean eapol_get_bool(struct eap_sm *sm, enum eapol_bool_var var) 548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return sm->eapol_cb->get_bool(sm->eapol_ctx, var); 568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eapol_set_bool(struct eap_sm *sm, enum eapol_bool_var var, 608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Boolean value) 618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eapol_cb->set_bool(sm->eapol_ctx, var, value); 638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic unsigned int eapol_get_int(struct eap_sm *sm, enum eapol_int_var var) 678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return sm->eapol_cb->get_int(sm->eapol_ctx, var); 698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eapol_set_int(struct eap_sm *sm, enum eapol_int_var var, 738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int value) 748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eapol_cb->set_int(sm->eapol_ctx, var, value); 768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpabuf * eapol_get_eapReqData(struct eap_sm *sm) 808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return sm->eapol_cb->get_eapReqData(sm->eapol_ctx); 828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8504949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic void eap_notify_status(struct eap_sm *sm, const char *status, 8604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt const char *parameter) 8704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 8804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: Status notification: %s (param=%s)", 8904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt status, parameter); 9004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (sm->eapol_cb->notify_status) 9104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt sm->eapol_cb->notify_status(sm->eapol_ctx, status, parameter); 9204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 9304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 9404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eap_deinit_prev_method(struct eap_sm *sm, const char *txt) 968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt ext_password_free(sm->ext_pw_buf); 9861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt sm->ext_pw_buf = NULL; 9961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->m == NULL || sm->eap_method_priv == NULL) 1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: deinitialize previously used EAP method " 1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(%d, %s) at %s", sm->selectedMethod, sm->m->name, txt); 1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->m->deinit(sm, sm->eap_method_priv); 1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap_method_priv = NULL; 1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->m = NULL; 1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_allowed_method - Check whether EAP method is allowed 1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @vendor: Vendor-Id for expanded types or 0 = IETF for legacy types 1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @method: EAP type 1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 1 = allowed EAP method, 0 = not allowed 1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint eap_allowed_method(struct eap_sm *sm, int vendor, u32 method) 1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_peer_config *config = eap_get_config(sm); 1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_method_type *m; 1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (config == NULL || config->eap_methods == NULL) 1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt m = config->eap_methods; 1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; m[i].vendor != EAP_VENDOR_IETF || 1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt m[i].method != EAP_TYPE_NONE; i++) { 1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (m[i].vendor == vendor && m[i].method == method) 1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This state initializes state machine variables when the machine is 1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * activated (portEnabled = TRUE). This is also used when re-starting 1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * authentication (eapRestart == TRUE). 1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(EAP, INITIALIZE) 1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY(EAP, INITIALIZE); 1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->fast_reauth && sm->m && sm->m->has_reauth_data && 1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->m->has_reauth_data(sm, sm->eap_method_priv) && 1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !sm->prev_failure) { 1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: maintaining EAP method data for " 1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "fast reauthentication"); 1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->m->deinit_for_reauth(sm, sm->eap_method_priv); 1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_deinit_prev_method(sm, "INITIALIZE"); 1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->selectedMethod = EAP_TYPE_NONE; 1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->methodState = METHOD_NONE; 1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->allowNotifications = TRUE; 1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->decision = DECISION_FAIL; 1581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt sm->ClientTimeout = EAP_CLIENT_TIMEOUT_DEFAULT; 1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_set_int(sm, EAPOL_idleWhile, sm->ClientTimeout); 1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_set_bool(sm, EAPOL_eapSuccess, FALSE); 1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_set_bool(sm, EAPOL_eapFail, FALSE); 1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(sm->eapKeyData); 1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eapKeyData = NULL; 1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eapKeyAvailable = FALSE; 1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_set_bool(sm, EAPOL_eapRestart, FALSE); 1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->lastId = -1; /* new session - make sure this does not match with 1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * the first EAP-Packet */ 1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * RFC 4137 does not reset eapResp and eapNoResp here. However, this 1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * seemed to be able to trigger cases where both were set and if EAPOL 1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * state machine uses eapNoResp first, it may end up not sending a real 1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * reply correctly. This occurred when the workaround in FAIL state set 1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eapNoResp = TRUE.. Maybe that workaround needs to be fixed to do 1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * something else(?) 1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_set_bool(sm, EAPOL_eapResp, FALSE); 1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_set_bool(sm, EAPOL_eapNoResp, FALSE); 1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->num_rounds = 0; 1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->prev_failure = 0; 1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This state is reached whenever service from the lower layer is interrupted 1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * or unavailable (portEnabled == FALSE). Immediate transition to INITIALIZE 1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * occurs when the port becomes enabled. 1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(EAP, DISABLED) 1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY(EAP, DISABLED); 1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->num_rounds = 0; 19261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt /* 19361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * RFC 4137 does not describe clearing of idleWhile here, but doing so 19461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * allows the timer tick to be stopped more quickly when EAP is not in 19561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * use. 19661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt */ 19761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt eapol_set_int(sm, EAPOL_idleWhile, 0); 1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * The state machine spends most of its time here, waiting for something to 2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * happen. This state is entered unconditionally from INITIALIZE, DISCARD, and 2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * SEND_RESPONSE states. 2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(EAP, IDLE) 2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY(EAP, IDLE); 2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This state is entered when an EAP packet is received (eapReq == TRUE) to 2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * parse the packet header. 2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(EAP, RECEIVED) 2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct wpabuf *eapReqData; 2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY(EAP, RECEIVED); 2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapReqData = eapol_get_eapReqData(sm); 2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* parse rxReq, rxSuccess, rxFailure, reqId, reqMethod */ 2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sm_parseEapReq(sm, eapReqData); 2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->num_rounds++; 2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This state is entered when a request for a new type comes in. Either the 2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * correct method is started, or a Nak response is built. 2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(EAP, GET_METHOD) 2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int reinit; 2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EapType method; 23604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt const struct eap_method *eap_method; 2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY(EAP, GET_METHOD); 2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->reqMethod == EAP_TYPE_EXPANDED) 2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt method = sm->reqVendorMethod; 2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt method = sm->reqMethod; 2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt eap_method = eap_peer_get_eap_method(sm->reqVendor, method); 24604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!eap_sm_allowMethod(sm, sm->reqVendor, method)) { 2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: vendor %u method %u not allowed", 2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->reqVendor, method); 2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_PROPOSED_METHOD 2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "vendor=%u method=%u -> NAK", 2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->reqVendor, method); 25304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt eap_notify_status(sm, "refuse proposed method", 25404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt eap_method ? eap_method->name : "unknown"); 2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto nak; 2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_PROPOSED_METHOD 2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "vendor=%u method=%u", sm->reqVendor, method); 2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt eap_notify_status(sm, "accept proposed method", 26204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt eap_method ? eap_method->name : "unknown"); 2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 2648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * RFC 4137 does not define specific operation for fast 2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * re-authentication (session resumption). The design here is to allow 2668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * the previously used method data to be maintained for 2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * re-authentication if the method support session resumption. 2688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Otherwise, the previously used method data is freed and a new method 2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * is allocated here. 2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->fast_reauth && 2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->m && sm->m->vendor == sm->reqVendor && 2738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->m->method == method && 2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->m->has_reauth_data && 2758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->m->has_reauth_data(sm, sm->eap_method_priv)) { 2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: Using previous method data" 2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " for fast re-authentication"); 2788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reinit = 1; 2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_deinit_prev_method(sm, "GET_METHOD"); 2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reinit = 0; 2828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->selectedMethod = sm->reqMethod; 2858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->m == NULL) 28604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt sm->m = eap_method; 2878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!sm->m) { 2888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: Could not find selected method: " 2898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "vendor %d method %d", 2908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->reqVendor, method); 2918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto nak; 2928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->ClientTimeout = EAP_CLIENT_TIMEOUT_DEFAULT; 2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: Initialize selected EAP method: " 2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "vendor %u method %u (%s)", 2988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->reqVendor, method, sm->m->name); 2998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (reinit) 3008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap_method_priv = sm->m->init_for_reauth( 3018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm, sm->eap_method_priv); 3028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 3038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap_method_priv = sm->m->init(sm); 3048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->eap_method_priv == NULL) { 3068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_peer_config *config = eap_get_config(sm); 3078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(sm->msg_ctx, MSG_INFO, 3088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "EAP: Failed to initialize EAP method: vendor %u " 3098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "method %u (%s)", 3108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->reqVendor, method, sm->m->name); 3118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->m = NULL; 3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->methodState = METHOD_NONE; 3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->selectedMethod = EAP_TYPE_NONE; 3148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->reqMethod == EAP_TYPE_TLS && config && 3158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (config->pending_req_pin || 3168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt config->pending_req_passphrase)) { 3178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 3188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Return without generating Nak in order to allow 3198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * entering of PIN code or passphrase to retry the 3208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * current EAP packet. 3218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 3228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: Pending PIN/passphrase " 3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "request - skip Nak"); 3248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 3258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto nak; 3288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->methodState = METHOD_INIT; 3318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_METHOD 3328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "EAP vendor %u method %u (%s) selected", 3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->reqVendor, method, sm->m->name); 3348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 3358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtnak: 3378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(sm->eapRespData); 3388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eapRespData = NULL; 3398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eapRespData = eap_sm_buildNak(sm, sm->reqId); 3408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 3448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * The method processing happens here. The request from the authenticator is 3458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * processed, and an appropriate response packet is built. 3468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 3478d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(EAP, METHOD) 3488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *eapReqData; 3508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_method_ret ret; 3518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY(EAP, METHOD); 3538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->m == NULL) { 3548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_WARNING, "EAP::METHOD - method not selected"); 3558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 3568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapReqData = eapol_get_eapReqData(sm); 35961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (!eap_hdr_len_valid(eapReqData, 1)) 36061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return; 3618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 3638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Get ignore, methodState, decision, allowNotifications, and 3648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eapRespData. RFC 4137 uses three separate method procedure (check, 3658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * process, and buildResp) in this state. These have been combined into 3668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * a single function call to m->process() in order to optimize EAP 3678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * method implementation interface a bit. These procedures are only 3688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * used from within this METHOD state, so there is no need to keep 3698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * these as separate C functions. 3708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 3718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * The RFC 4137 procedures return values as follows: 3728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * ignore = m.check(eapReqData) 3738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * (methodState, decision, allowNotifications) = m.process(eapReqData) 3748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eapRespData = m.buildResp(reqId) 3758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 3768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&ret, 0, sizeof(ret)); 3778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret.ignore = sm->ignore; 3788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret.methodState = sm->methodState; 3798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret.decision = sm->decision; 3808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret.allowNotifications = sm->allowNotifications; 3818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(sm->eapRespData); 3828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eapRespData = NULL; 3838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eapRespData = sm->m->process(sm, sm->eap_method_priv, &ret, 3848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapReqData); 3858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: method process -> ignore=%s " 3868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "methodState=%s decision=%s", 3878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret.ignore ? "TRUE" : "FALSE", 3888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sm_method_state_txt(ret.methodState), 3898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sm_decision_txt(ret.decision)); 3908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->ignore = ret.ignore; 3928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->ignore) 3938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 3948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->methodState = ret.methodState; 3958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->decision = ret.decision; 3968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->allowNotifications = ret.allowNotifications; 3978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->m->isKeyAvailable && sm->m->getKey && 3998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->m->isKeyAvailable(sm, sm->eap_method_priv)) { 4008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(sm->eapKeyData); 4018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eapKeyData = sm->m->getKey(sm, sm->eap_method_priv, 4028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &sm->eapKeyDataLen); 4038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 4088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This state signals the lower layer that a response packet is ready to be 4098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * sent. 4108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 4118d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(EAP, SEND_RESPONSE) 4128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY(EAP, SEND_RESPONSE); 4148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(sm->lastRespData); 4158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->eapRespData) { 4168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->workaround) 4178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(sm->last_md5, sm->req_md5, 16); 4188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->lastId = sm->reqId; 4198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->lastRespData = wpabuf_dup(sm->eapRespData); 4208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_set_bool(sm, EAPOL_eapResp, TRUE); 4218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 4228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->lastRespData = NULL; 4238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_set_bool(sm, EAPOL_eapReq, FALSE); 4248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_set_int(sm, EAPOL_idleWhile, sm->ClientTimeout); 4258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 4298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This state signals the lower layer that the request was discarded, and no 4308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * response packet will be sent at this time. 4318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 4328d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(EAP, DISCARD) 4338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY(EAP, DISCARD); 4358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_set_bool(sm, EAPOL_eapReq, FALSE); 4368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_set_bool(sm, EAPOL_eapNoResp, TRUE); 4378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 4418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Handles requests for Identity method and builds a response. 4428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 4438d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(EAP, IDENTITY) 4448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct wpabuf *eapReqData; 4468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY(EAP, IDENTITY); 4488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapReqData = eapol_get_eapReqData(sm); 44961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (!eap_hdr_len_valid(eapReqData, 1)) 45061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return; 4518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sm_processIdentity(sm, eapReqData); 4528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(sm->eapRespData); 4538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eapRespData = NULL; 4548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eapRespData = eap_sm_buildIdentity(sm, sm->reqId, 0); 4558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 4598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Handles requests for Notification method and builds a response. 4608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 4618d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(EAP, NOTIFICATION) 4628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct wpabuf *eapReqData; 4648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY(EAP, NOTIFICATION); 4668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapReqData = eapol_get_eapReqData(sm); 46761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (!eap_hdr_len_valid(eapReqData, 1)) 46861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return; 4698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sm_processNotify(sm, eapReqData); 4708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(sm->eapRespData); 4718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eapRespData = NULL; 4728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eapRespData = eap_sm_buildNotify(sm->reqId); 4738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 4778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This state retransmits the previous response packet. 4788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 4798d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(EAP, RETRANSMIT) 4808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY(EAP, RETRANSMIT); 4828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(sm->eapRespData); 4838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->lastRespData) 4848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eapRespData = wpabuf_dup(sm->lastRespData); 4858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 4868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eapRespData = NULL; 4878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 4918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This state is entered in case of a successful completion of authentication 4928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * and state machine waits here until port is disabled or EAP authentication is 4938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * restarted. 4948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 4958d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(EAP, SUCCESS) 4968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY(EAP, SUCCESS); 4988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->eapKeyData != NULL) 4998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eapKeyAvailable = TRUE; 5008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_set_bool(sm, EAPOL_eapSuccess, TRUE); 5018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 5038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * RFC 4137 does not clear eapReq here, but this seems to be required 5048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * to avoid processing the same request twice when state machine is 5058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * initialized. 5068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 5078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_set_bool(sm, EAPOL_eapReq, FALSE); 5088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 5108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * RFC 4137 does not set eapNoResp here, but this seems to be required 5118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * to get EAPOL Supplicant backend state machine into SUCCESS state. In 5128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * addition, either eapResp or eapNoResp is required to be set after 5138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * processing the received EAP frame. 5148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 5158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_set_bool(sm, EAPOL_eapNoResp, TRUE); 5168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_SUCCESS 5188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "EAP authentication completed successfully"); 5198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 5238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This state is entered in case of a failure and state machine waits here 5248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * until port is disabled or EAP authentication is restarted. 5258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 5268d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(EAP, FAILURE) 5278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY(EAP, FAILURE); 5298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_set_bool(sm, EAPOL_eapFail, TRUE); 5308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 5328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * RFC 4137 does not clear eapReq here, but this seems to be required 5338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * to avoid processing the same request twice when state machine is 5348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * initialized. 5358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 5368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_set_bool(sm, EAPOL_eapReq, FALSE); 5378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 5398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * RFC 4137 does not set eapNoResp here. However, either eapResp or 5408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eapNoResp is required to be set after processing the received EAP 5418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * frame. 5428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 5438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_set_bool(sm, EAPOL_eapNoResp, TRUE); 5448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_FAILURE 5468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "EAP authentication failed"); 5478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->prev_failure = 1; 5498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int eap_success_workaround(struct eap_sm *sm, int reqId, int lastId) 5538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 5558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * At least Microsoft IAS and Meetinghouse Aegis seem to be sending 5568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * EAP-Success/Failure with lastId + 1 even though RFC 3748 and 5578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * RFC 4137 require that reqId == lastId. In addition, it looks like 5588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Ringmaster v2.1.2.0 would be using lastId + 2 in EAP-Success. 5598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 5608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Accept this kind of Id if EAP workarounds are enabled. These are 5618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * unauthenticated plaintext messages, so this should have minimal 5628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * security implications (bit easier to fake EAP-Success/Failure). 5638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 5648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->workaround && (reqId == ((lastId + 1) & 0xff) || 5658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reqId == ((lastId + 2) & 0xff))) { 5668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: Workaround for unexpected " 5678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "identifier field in EAP Success: " 5688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "reqId=%d lastId=%d (these are supposed to be " 5698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "same)", reqId, lastId); 5708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 5718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: EAP-Success Id mismatch - reqId=%d " 5738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "lastId=%d", reqId, lastId); 5748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 5758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 5798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * RFC 4137 - Appendix A.1: EAP Peer State Machine - State transitions 5808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 5818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eap_peer_sm_step_idle(struct eap_sm *sm) 5838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 5858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * The first three transitions are from RFC 4137. The last two are 5868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * local additions to handle special cases with LEAP and PEAP server 5878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * not sending EAP-Success in some cases. 5888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 5898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eapol_get_bool(sm, EAPOL_eapReq)) 5908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(EAP, RECEIVED); 5918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if ((eapol_get_bool(sm, EAPOL_altAccept) && 5928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->decision != DECISION_FAIL) || 5938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (eapol_get_int(sm, EAPOL_idleWhile) == 0 && 5948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->decision == DECISION_UNCOND_SUCC)) 5958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(EAP, SUCCESS); 5968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (eapol_get_bool(sm, EAPOL_altReject) || 5978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (eapol_get_int(sm, EAPOL_idleWhile) == 0 && 5988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->decision != DECISION_UNCOND_SUCC) || 5998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (eapol_get_bool(sm, EAPOL_altAccept) && 6008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->methodState != METHOD_CONT && 6018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->decision == DECISION_FAIL)) 6028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(EAP, FAILURE); 6038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (sm->selectedMethod == EAP_TYPE_LEAP && 6048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->leap_done && sm->decision != DECISION_FAIL && 6058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->methodState == METHOD_DONE) 6068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(EAP, SUCCESS); 6078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (sm->selectedMethod == EAP_TYPE_PEAP && 6088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->peap_done && sm->decision != DECISION_FAIL && 6098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->methodState == METHOD_DONE) 6108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(EAP, SUCCESS); 6118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int eap_peer_req_is_duplicate(struct eap_sm *sm) 6158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int duplicate; 6178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt duplicate = (sm->reqId == sm->lastId) && sm->rxReq; 6198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->workaround && duplicate && 6208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(sm->req_md5, sm->last_md5, 16) != 0) { 6218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 6228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * RFC 4137 uses (reqId == lastId) as the only verification for 6238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * duplicate EAP requests. However, this misses cases where the 6248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * AS is incorrectly using the same id again; and 6258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * unfortunately, such implementations exist. Use MD5 hash as 6268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * an extra verification for the packets being duplicate to 6278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * workaround these issues. 6288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 6298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: AS used the same Id again, but " 6308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "EAP packets were not identical"); 6318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: workaround - assume this is not a " 6328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "duplicate packet"); 6338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt duplicate = 0; 6348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return duplicate; 6378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eap_peer_sm_step_received(struct eap_sm *sm) 6418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int duplicate = eap_peer_req_is_duplicate(sm); 6438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 6458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Two special cases below for LEAP are local additions to work around 6468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * odd LEAP behavior (EAP-Success in the middle of authentication and 6478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * then swapped roles). Other transitions are based on RFC 4137. 6488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 6498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->rxSuccess && sm->decision != DECISION_FAIL && 6508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (sm->reqId == sm->lastId || 6518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_success_workaround(sm, sm->reqId, sm->lastId))) 6528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(EAP, SUCCESS); 6538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (sm->methodState != METHOD_CONT && 6548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ((sm->rxFailure && 6558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->decision != DECISION_UNCOND_SUCC) || 6568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (sm->rxSuccess && sm->decision == DECISION_FAIL && 6578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (sm->selectedMethod != EAP_TYPE_LEAP || 6588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->methodState != METHOD_MAY_CONT))) && 6598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (sm->reqId == sm->lastId || 6608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_success_workaround(sm, sm->reqId, sm->lastId))) 6618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(EAP, FAILURE); 6628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (sm->rxReq && duplicate) 6638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(EAP, RETRANSMIT); 6648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (sm->rxReq && !duplicate && 6658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->reqMethod == EAP_TYPE_NOTIFICATION && 6668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->allowNotifications) 6678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(EAP, NOTIFICATION); 6688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (sm->rxReq && !duplicate && 6698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->selectedMethod == EAP_TYPE_NONE && 6708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->reqMethod == EAP_TYPE_IDENTITY) 6718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(EAP, IDENTITY); 6728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (sm->rxReq && !duplicate && 6738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->selectedMethod == EAP_TYPE_NONE && 6748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->reqMethod != EAP_TYPE_IDENTITY && 6758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->reqMethod != EAP_TYPE_NOTIFICATION) 6768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(EAP, GET_METHOD); 6778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (sm->rxReq && !duplicate && 6788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->reqMethod == sm->selectedMethod && 6798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->methodState != METHOD_DONE) 6808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(EAP, METHOD); 6818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (sm->selectedMethod == EAP_TYPE_LEAP && 6828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (sm->rxSuccess || sm->rxResp)) 6838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(EAP, METHOD); 6848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 6858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(EAP, DISCARD); 6868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eap_peer_sm_step_local(struct eap_sm *sm) 6908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (sm->EAP_state) { 6928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_INITIALIZE: 6938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(EAP, IDLE); 6948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 6958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_DISABLED: 6968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eapol_get_bool(sm, EAPOL_portEnabled) && 6978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !sm->force_disabled) 6988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(EAP, INITIALIZE); 6998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 7008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_IDLE: 7018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_peer_sm_step_idle(sm); 7028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 7038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_RECEIVED: 7048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_peer_sm_step_received(sm); 7058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 7068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_GET_METHOD: 7078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->selectedMethod == sm->reqMethod) 7088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(EAP, METHOD); 7098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 7108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(EAP, SEND_RESPONSE); 7118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 7128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_METHOD: 7138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->ignore) 7148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(EAP, DISCARD); 7158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 7168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(EAP, SEND_RESPONSE); 7178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 7188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_SEND_RESPONSE: 7198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(EAP, IDLE); 7208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 7218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_DISCARD: 7228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(EAP, IDLE); 7238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 7248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_IDENTITY: 7258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(EAP, SEND_RESPONSE); 7268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 7278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_NOTIFICATION: 7288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(EAP, SEND_RESPONSE); 7298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 7308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_RETRANSMIT: 7318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(EAP, SEND_RESPONSE); 7328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 7338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_SUCCESS: 7348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 7358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_FAILURE: 7368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 7378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7418d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STEP(EAP) 7428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Global transitions */ 7448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eapol_get_bool(sm, EAPOL_eapRestart) && 7458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_get_bool(sm, EAPOL_portEnabled)) 7468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER_GLOBAL(EAP, INITIALIZE); 7478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (!eapol_get_bool(sm, EAPOL_portEnabled) || sm->force_disabled) 7488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER_GLOBAL(EAP, DISABLED); 7498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (sm->num_rounds > EAP_MAX_AUTH_ROUNDS) { 7508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* RFC 4137 does not place any limit on number of EAP messages 7518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * in an authentication session. However, some error cases have 7528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * ended up in a state were EAP messages were sent between the 7538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * peer and server in a loop (e.g., TLS ACK frame in both 7548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * direction). Since this is quite undesired outcome, limit the 7558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * total number of EAP round-trips and abort authentication if 7568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * this limit is exceeded. 7578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 7588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->num_rounds == EAP_MAX_AUTH_ROUNDS + 1) { 7598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(sm->msg_ctx, MSG_INFO, "EAP: more than %d " 7608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "authentication rounds - abort", 7618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EAP_MAX_AUTH_ROUNDS); 7628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->num_rounds++; 7638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER_GLOBAL(EAP, FAILURE); 7648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 7668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Local transitions */ 7678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_peer_sm_step_local(sm); 7688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic Boolean eap_sm_allowMethod(struct eap_sm *sm, int vendor, 7738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EapType method) 7748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!eap_allowed_method(sm, vendor, method)) { 7768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: configuration does not allow: " 7778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "vendor %u method %u", vendor, method); 7788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return FALSE; 7798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eap_peer_get_eap_method(vendor, method)) 7818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return TRUE; 7828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: not included in build: " 7838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "vendor %u method %u", vendor, method); 7848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return FALSE; 7858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpabuf * eap_sm_build_expanded_nak( 7898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sm *sm, int id, const struct eap_method *methods, 7908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t count) 7918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *resp; 7938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int found = 0; 7948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct eap_method *m; 7958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: Building expanded EAP-Nak"); 7978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* RFC 3748 - 5.3.2: Expanded Nak */ 7998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_EXPANDED, 8008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8 + 8 * (count + 1), EAP_CODE_RESPONSE, id); 8018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (resp == NULL) 8028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 8038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_be24(resp, EAP_VENDOR_IETF); 8058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_be32(resp, EAP_TYPE_NAK); 8068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (m = methods; m; m = m->next) { 8088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->reqVendor == m->vendor && 8098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->reqVendorMethod == m->method) 8108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; /* do not allow the current method again */ 8118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eap_allowed_method(sm, m->vendor, m->method)) { 8128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: allowed type: " 8138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "vendor=%u method=%u", 8148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt m->vendor, m->method); 8158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(resp, EAP_TYPE_EXPANDED); 8168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_be24(resp, m->vendor); 8178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_be32(resp, m->method); 8188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt found++; 8208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!found) { 8238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: no more allowed methods"); 8248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(resp, EAP_TYPE_EXPANDED); 8258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_be24(resp, EAP_VENDOR_IETF); 8268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_be32(resp, EAP_TYPE_NONE); 8278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_update_len(resp); 8308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return resp; 8328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpabuf * eap_sm_buildNak(struct eap_sm *sm, int id) 8368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 8378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *resp; 8388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *start; 8398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int found = 0, expanded_found = 0; 8408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t count; 8418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct eap_method *methods, *m; 8428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: Building EAP-Nak (requested type %u " 8448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "vendor=%u method=%u not allowed)", sm->reqMethod, 8458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->reqVendor, sm->reqVendorMethod); 8468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt methods = eap_peer_get_methods(&count); 8478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (methods == NULL) 8488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 8498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->reqMethod == EAP_TYPE_EXPANDED) 8508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return eap_sm_build_expanded_nak(sm, id, methods, count); 8518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* RFC 3748 - 5.3.1: Legacy Nak */ 8538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_NAK, 8548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(struct eap_hdr) + 1 + count + 1, 8558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EAP_CODE_RESPONSE, id); 8568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (resp == NULL) 8578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 8588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt start = wpabuf_put(resp, 0); 8608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (m = methods; m; m = m->next) { 8618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (m->vendor == EAP_VENDOR_IETF && m->method == sm->reqMethod) 8628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; /* do not allow the current method again */ 8638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eap_allowed_method(sm, m->vendor, m->method)) { 8648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (m->vendor != EAP_VENDOR_IETF) { 8658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (expanded_found) 8668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 8678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt expanded_found = 1; 8688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(resp, EAP_TYPE_EXPANDED); 8698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 8708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(resp, m->method); 8718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt found++; 8728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!found) 8758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(resp, EAP_TYPE_NONE); 8768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "EAP: allowed methods", start, found); 8778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_update_len(resp); 8798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return resp; 8818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eap_sm_processIdentity(struct eap_sm *sm, const struct wpabuf *req) 8858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 88661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt const u8 *pos; 88761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt size_t msg_len; 8888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_STARTED 8908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "EAP authentication started"); 8918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 89261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_IDENTITY, req, 89361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt &msg_len); 89461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (pos == NULL) 89561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return; 89661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 8978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 8988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * RFC 3748 - 5.1: Identity 8998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Data field may contain a displayable message in UTF-8. If this 9008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * includes NUL-character, only the data before that should be 9018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * displayed. Some EAP implementasitons may piggy-back additional 9028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * options after the NUL. 9038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 9048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: could save displayable message so that it can be shown to the 9058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * user in case of interaction is required */ 9068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_ascii(MSG_DEBUG, "EAP: EAP-Request Identity data", 90761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt pos, msg_len); 9088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef PCSC_FUNCS 912c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 913c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt/* 914c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * Rules for figuring out MNC length based on IMSI for SIM cards that do not 915c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * include MNC length field. 916c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt */ 917c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidtstatic int mnc_len_from_imsi(const char *imsi) 918c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt{ 919c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt char mcc_str[4]; 920c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt unsigned int mcc; 921c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 922c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt os_memcpy(mcc_str, imsi, 3); 923c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt mcc_str[3] = '\0'; 924c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt mcc = atoi(mcc_str); 925c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 926c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (mcc == 244) 927c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt return 2; /* Networks in Finland use 2-digit MNC */ 928c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 929c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt return -1; 930c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt} 931c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 932c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 933c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidtstatic int eap_sm_append_3gpp_realm(struct eap_sm *sm, char *imsi, 934c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt size_t max_len, size_t *imsi_len) 935c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt{ 936c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt int mnc_len; 937c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt char *pos, mnc[4]; 938c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 939c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (*imsi_len + 36 > max_len) { 940c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpa_printf(MSG_WARNING, "No room for realm in IMSI buffer"); 941c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt return -1; 942c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt } 943c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 944c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt /* MNC (2 or 3 digits) */ 945c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt mnc_len = scard_get_mnc_len(sm->scard_ctx); 946c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (mnc_len < 0) 947c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt mnc_len = mnc_len_from_imsi(imsi); 948c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (mnc_len < 0) { 949c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpa_printf(MSG_INFO, "Failed to get MNC length from (U)SIM " 950c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt "assuming 3"); 951c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt mnc_len = 3; 952c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt } 953c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 954c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (mnc_len == 2) { 955c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt mnc[0] = '0'; 956c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt mnc[1] = imsi[3]; 957c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt mnc[2] = imsi[4]; 958c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt } else if (mnc_len == 3) { 959c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt mnc[0] = imsi[3]; 960c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt mnc[1] = imsi[4]; 961c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt mnc[2] = imsi[5]; 962c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt } 963c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt mnc[3] = '\0'; 964c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 965c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt pos = imsi + *imsi_len; 966c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt pos += os_snprintf(pos, imsi + max_len - pos, 967c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt "@wlan.mnc%s.mcc%c%c%c.3gppnetwork.org", 968c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt mnc, imsi[0], imsi[1], imsi[2]); 969c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt *imsi_len = pos - imsi; 970c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 971c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt return 0; 972c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt} 973c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 974c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 9758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int eap_sm_imsi_identity(struct eap_sm *sm, 9768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_peer_config *conf) 9778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 97804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt enum { EAP_SM_SIM, EAP_SM_AKA, EAP_SM_AKA_PRIME } method = EAP_SM_SIM; 9798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char imsi[100]; 9808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t imsi_len; 9818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_method_type *m = conf->eap_methods; 9828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 9838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt imsi_len = sizeof(imsi); 9858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (scard_get_imsi(sm->scard_ctx, imsi, &imsi_len)) { 9868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_WARNING, "Failed to get IMSI from SIM"); 9878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 9888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_ascii(MSG_DEBUG, "IMSI", (u8 *) imsi, imsi_len); 9918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 992c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (imsi_len < 7) { 993c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpa_printf(MSG_WARNING, "Too short IMSI for SIM identity"); 994c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt return -1; 995c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt } 996c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 997c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (eap_sm_append_3gpp_realm(sm, imsi, sizeof(imsi), &imsi_len) < 0) { 998c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpa_printf(MSG_WARNING, "Could not add realm to SIM identity"); 999c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt return -1; 1000c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt } 1001c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpa_hexdump_ascii(MSG_DEBUG, "IMSI + realm", (u8 *) imsi, imsi_len); 1002c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 10038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; m && (m[i].vendor != EAP_VENDOR_IETF || 10048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt m[i].method != EAP_TYPE_NONE); i++) { 10058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (m[i].vendor == EAP_VENDOR_IETF && 100604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt m[i].method == EAP_TYPE_AKA_PRIME) { 100704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt method = EAP_SM_AKA_PRIME; 100804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt break; 100904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 101004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 101104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (m[i].vendor == EAP_VENDOR_IETF && 10128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt m[i].method == EAP_TYPE_AKA) { 101304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt method = EAP_SM_AKA; 10148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 10158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(conf->identity); 10198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf->identity = os_malloc(1 + imsi_len); 10208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conf->identity == NULL) { 10218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_WARNING, "Failed to allocate buffer for " 10228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "IMSI-based identity"); 10238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 102604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt switch (method) { 102704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt case EAP_SM_SIM: 102804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt conf->identity[0] = '1'; 102904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt break; 103004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt case EAP_SM_AKA: 103104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt conf->identity[0] = '0'; 103204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt break; 103304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt case EAP_SM_AKA_PRIME: 103404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt conf->identity[0] = '6'; 103504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt break; 103604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 10378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(conf->identity + 1, imsi, imsi_len); 10388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf->identity_len = 1 + imsi_len; 10398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 10418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1042c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 10438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* PCSC_FUNCS */ 10448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int eap_sm_set_scard_pin(struct eap_sm *sm, 10478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_peer_config *conf) 10488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 10498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef PCSC_FUNCS 10508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (scard_set_pin(sm->scard_ctx, conf->pin)) { 10518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 10528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Make sure the same PIN is not tried again in order to avoid 10538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * blocking SIM. 10548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 10558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(conf->pin); 10568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf->pin = NULL; 10578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_WARNING, "PIN validation failed"); 10598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sm_request_pin(sm); 10608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 10638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* PCSC_FUNCS */ 10648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* PCSC_FUNCS */ 10668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int eap_sm_get_scard_identity(struct eap_sm *sm, 10698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_peer_config *conf) 10708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 10718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef PCSC_FUNCS 10728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eap_sm_set_scard_pin(sm, conf)) 10738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return eap_sm_imsi_identity(sm, conf); 10768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* PCSC_FUNCS */ 10778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* PCSC_FUNCS */ 10798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 10838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_sm_buildIdentity - Build EAP-Identity/Response for the current network 10848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 10858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @id: EAP identifier for the packet 10868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @encrypted: Whether the packet is for encrypted tunnel (EAP phase 2) 10878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Pointer to the allocated EAP-Identity/Response packet or %NULL on 10888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * failure 10898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 10908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function allocates and builds an EAP-Identity/Response packet for the 10918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * current network. The caller is responsible for freeing the returned data. 10928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 10938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct wpabuf * eap_sm_buildIdentity(struct eap_sm *sm, int id, int encrypted) 10948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 10958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_peer_config *config = eap_get_config(sm); 10968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *resp; 10978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *identity; 10988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t identity_len; 10998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (config == NULL) { 11018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_WARNING, "EAP: buildIdentity: configuration " 11028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "was not available"); 11038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 11048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->m && sm->m->get_identity && 11078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (identity = sm->m->get_identity(sm, sm->eap_method_priv, 11088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &identity_len)) != NULL) { 11098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_ascii(MSG_DEBUG, "EAP: using method re-auth " 11108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "identity", identity, identity_len); 11118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (!encrypted && config->anonymous_identity) { 11128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt identity = config->anonymous_identity; 11138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt identity_len = config->anonymous_identity_len; 11148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_ascii(MSG_DEBUG, "EAP: using anonymous identity", 11158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt identity, identity_len); 11168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 11178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt identity = config->identity; 11188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt identity_len = config->identity_len; 11198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_ascii(MSG_DEBUG, "EAP: using real identity", 11208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt identity, identity_len); 11218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (identity == NULL) { 11248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_WARNING, "EAP: buildIdentity: identity " 11258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "configuration was not available"); 11268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (config->pcsc) { 11278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eap_sm_get_scard_identity(sm, config) < 0) 11288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 11298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt identity = config->identity; 11308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt identity_len = config->identity_len; 11318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_ascii(MSG_DEBUG, "permanent identity from " 11328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "IMSI", identity, identity_len); 11338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 11348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sm_request_identity(sm); 11358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 11368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (config->pcsc) { 11388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eap_sm_set_scard_pin(sm, config) < 0) 11398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 11408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_IDENTITY, identity_len, 11438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EAP_CODE_RESPONSE, id); 11448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (resp == NULL) 11458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 11468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_data(resp, identity, identity_len); 11488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return resp; 11508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 11518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eap_sm_processNotify(struct eap_sm *sm, const struct wpabuf *req) 11548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 11558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *pos; 11568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *msg; 11578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t i, msg_len; 11588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_NOTIFICATION, req, 11608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &msg_len); 11618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos == NULL) 11628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 11638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_ascii(MSG_DEBUG, "EAP: EAP-Request Notification data", 11648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos, msg_len); 11658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg = os_malloc(msg_len + 1); 11678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg == NULL) 11688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 11698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < msg_len; i++) 11708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg[i] = isprint(pos[i]) ? (char) pos[i] : '_'; 11718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg[msg_len] = '\0'; 11728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(sm->msg_ctx, MSG_INFO, "%s%s", 11738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_EVENT_EAP_NOTIFICATION, msg); 11748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(msg); 11758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 11768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpabuf * eap_sm_buildNotify(int id) 11798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 11808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *resp; 11818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: Generating EAP-Response Notification"); 11838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_NOTIFICATION, 0, 11848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EAP_CODE_RESPONSE, id); 11858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (resp == NULL) 11868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 11878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return resp; 11898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 11908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eap_sm_parseEapReq(struct eap_sm *sm, const struct wpabuf *req) 11938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 11948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct eap_hdr *hdr; 11958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t plen; 11968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *pos; 11978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->rxReq = sm->rxResp = sm->rxSuccess = sm->rxFailure = FALSE; 11998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->reqId = 0; 12008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->reqMethod = EAP_TYPE_NONE; 12018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->reqVendor = EAP_VENDOR_IETF; 12028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->reqVendorMethod = EAP_TYPE_NONE; 12038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (req == NULL || wpabuf_len(req) < sizeof(*hdr)) 12058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 12068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hdr = wpabuf_head(req); 12088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt plen = be_to_host16(hdr->length); 12098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (plen > wpabuf_len(req)) { 12108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: Ignored truncated EAP-Packet " 12118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(len=%lu plen=%lu)", 12128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) wpabuf_len(req), 12138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) plen); 12148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 12158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->reqId = hdr->identifier; 12188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->workaround) { 12208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *addr[1]; 12218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt addr[0] = wpabuf_head(req); 12228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt md5_vector(1, addr, &plen, sm->req_md5); 12238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (hdr->code) { 12268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_CODE_REQUEST: 12278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (plen < sizeof(*hdr) + 1) { 12288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: Too short EAP-Request - " 12298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "no Type field"); 12308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 12318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->rxReq = TRUE; 12338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = (const u8 *) (hdr + 1); 12348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->reqMethod = *pos++; 12358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->reqMethod == EAP_TYPE_EXPANDED) { 12368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (plen < sizeof(*hdr) + 8) { 12378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: Ignored truncated " 12388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "expanded EAP-Packet (plen=%lu)", 12398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) plen); 12408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 12418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->reqVendor = WPA_GET_BE24(pos); 12438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 3; 12448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->reqVendorMethod = WPA_GET_BE32(pos); 12458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: Received EAP-Request id=%d " 12478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "method=%u vendor=%u vendorMethod=%u", 12488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->reqId, sm->reqMethod, sm->reqVendor, 12498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->reqVendorMethod); 12508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 12518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_CODE_RESPONSE: 12528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->selectedMethod == EAP_TYPE_LEAP) { 12538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 12548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * LEAP differs from RFC 4137 by using reversed roles 12558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * for mutual authentication and because of this, we 12568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * need to accept EAP-Response frames if LEAP is used. 12578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 12588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (plen < sizeof(*hdr) + 1) { 12598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: Too short " 12608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "EAP-Response - no Type field"); 12618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 12628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->rxResp = TRUE; 12648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = (const u8 *) (hdr + 1); 12658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->reqMethod = *pos; 12668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: Received EAP-Response for " 12678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "LEAP method=%d id=%d", 12688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->reqMethod, sm->reqId); 12698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 12708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: Ignored EAP-Response"); 12728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 12738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_CODE_SUCCESS: 12748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: Received EAP-Success"); 127504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt eap_notify_status(sm, "completion", "success"); 12768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->rxSuccess = TRUE; 12778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 12788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_CODE_FAILURE: 12798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: Received EAP-Failure"); 128004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt eap_notify_status(sm, "completion", "failure"); 12818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->rxFailure = TRUE; 12828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 12838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 12848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: Ignored EAP-Packet with unknown " 12858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "code %d", hdr->code); 12868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 12878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 12898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eap_peer_sm_tls_event(void *ctx, enum tls_event ev, 12928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt union tls_event_data *data) 12938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 12948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sm *sm = ctx; 12958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *hash_hex = NULL; 12968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (ev) { 129804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt case TLS_CERT_CHAIN_SUCCESS: 129904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt eap_notify_status(sm, "remote certificate verification", 130004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt "success"); 130104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt break; 13028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case TLS_CERT_CHAIN_FAILURE: 13038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_TLS_CERT_ERROR 13048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "reason=%d depth=%d subject='%s' err='%s'", 13058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->cert_fail.reason, 13068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->cert_fail.depth, 13078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->cert_fail.subject, 13088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->cert_fail.reason_txt); 130904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt eap_notify_status(sm, "remote certificate verification", 131004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt data->cert_fail.reason_txt); 13118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 13128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case TLS_PEER_CERTIFICATE: 1313c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt if (!sm->eapol_cb->notify_cert) 1314c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt break; 1315c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt 13168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->peer_cert.hash) { 13178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len = data->peer_cert.hash_len * 2 + 1; 13188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hash_hex = os_malloc(len); 13198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hash_hex) { 13208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_snprintf_hex(hash_hex, len, 13218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->peer_cert.hash, 13228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->peer_cert.hash_len); 13238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1325c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt 1326c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt sm->eapol_cb->notify_cert(sm->eapol_ctx, 1327c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt data->peer_cert.depth, 1328c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt data->peer_cert.subject, 1329c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt hash_hex, data->peer_cert.cert); 13308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 133104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt case TLS_ALERT: 133204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (data->alert.is_local) 133304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt eap_notify_status(sm, "local TLS alert", 133404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt data->alert.description); 133504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt else 133604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt eap_notify_status(sm, "remote TLS alert", 133704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt data->alert.description); 133804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt break; 13398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(hash_hex); 13428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 13438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 13468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_peer_sm_init - Allocate and initialize EAP peer state machine 13478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @eapol_ctx: Context data to be used with eapol_cb calls 13488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @eapol_cb: Pointer to EAPOL callback functions 13498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @msg_ctx: Context data for wpa_msg() calls 13508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @conf: EAP configuration 13518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Pointer to the allocated EAP state machine or %NULL on failure 13528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 13538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function allocates and initializes an EAP state machine. In addition, 13548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * this initializes TLS library for the new EAP state machine. eapol_cb pointer 13558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * will be in use until eap_peer_sm_deinit() is used to deinitialize this EAP 13568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * state machine. Consequently, the caller must make sure that this data 13578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * structure remains alive while the EAP state machine is active. 13588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 13598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct eap_sm * eap_peer_sm_init(void *eapol_ctx, 13608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eapol_callbacks *eapol_cb, 13618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void *msg_ctx, struct eap_config *conf) 13628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 13638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sm *sm; 13648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tls_config tlsconf; 13658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm = os_zalloc(sizeof(*sm)); 13678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 13688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 13698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eapol_ctx = eapol_ctx; 13708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eapol_cb = eapol_cb; 13718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->msg_ctx = msg_ctx; 13728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->ClientTimeout = EAP_CLIENT_TIMEOUT_DEFAULT; 13738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->wps = conf->wps; 13748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&tlsconf, 0, sizeof(tlsconf)); 13768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsconf.opensc_engine_path = conf->opensc_engine_path; 13778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsconf.pkcs11_engine_path = conf->pkcs11_engine_path; 13788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsconf.pkcs11_module_path = conf->pkcs11_module_path; 13798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_FIPS 13808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsconf.fips_mode = 1; 13818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_FIPS */ 13828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsconf.event_cb = eap_peer_sm_tls_event; 13838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsconf.cb_ctx = sm; 13841f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt tlsconf.cert_in_cb = conf->cert_in_cb; 13858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->ssl_ctx = tls_init(&tlsconf); 13868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->ssl_ctx == NULL) { 13878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_WARNING, "SSL: Failed to initialize TLS " 13888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "context."); 13898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(sm); 13908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 13918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 139304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt sm->ssl_ctx2 = tls_init(&tlsconf); 139404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (sm->ssl_ctx2 == NULL) { 139504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_INFO, "SSL: Failed to initialize TLS " 139604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt "context (2)."); 139704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt /* Run without separate TLS context within TLS tunnel */ 139804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 139904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 14008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return sm; 14018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 14028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 14058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_peer_sm_deinit - Deinitialize and free an EAP peer state machine 14068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 14078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 14088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function deinitializes EAP state machine and frees all allocated 14098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * resources. 14108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 14118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eap_peer_sm_deinit(struct eap_sm *sm) 14128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 14138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 14148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 14158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_deinit_prev_method(sm, "EAP deinit"); 14168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sm_abort(sm); 141704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (sm->ssl_ctx2) 141804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt tls_deinit(sm->ssl_ctx2); 14198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_deinit(sm->ssl_ctx); 14208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(sm); 14218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 14228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 14258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_peer_sm_step - Step EAP peer state machine 14268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 14278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 1 if EAP state was changed or 0 if not 14288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 14298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function advances EAP state machine to a new state to match with the 14308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * current variables. This should be called whenever variables used by the EAP 14318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * state machine have changed. 14328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 14338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint eap_peer_sm_step(struct eap_sm *sm) 14348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 14358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res = 0; 14368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt do { 14378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->changed = FALSE; 14388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_STEP_RUN(EAP); 14398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->changed) 14408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = 1; 14418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } while (sm->changed); 14428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return res; 14438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 14448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 14478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_sm_abort - Abort EAP authentication 14488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 14498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 14508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Release system resources that have been allocated for the authentication 14518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * session without fully deinitializing the EAP state machine. 14528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 14538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eap_sm_abort(struct eap_sm *sm) 14548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 14558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(sm->lastRespData); 14568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->lastRespData = NULL; 14578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(sm->eapRespData); 14588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eapRespData = NULL; 14598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(sm->eapKeyData); 14608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eapKeyData = NULL; 14618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* This is not clearly specified in the EAP statemachines draft, but 14638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * it seems necessary to make sure that some of the EAPOL variables get 14648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * cleared for the next authentication. */ 14658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_set_bool(sm, EAPOL_eapSuccess, FALSE); 14668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 14678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_CTRL_IFACE 14708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic const char * eap_sm_state_txt(int state) 14718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 14728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (state) { 14738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_INITIALIZE: 14748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "INITIALIZE"; 14758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_DISABLED: 14768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "DISABLED"; 14778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_IDLE: 14788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "IDLE"; 14798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_RECEIVED: 14808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "RECEIVED"; 14818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_GET_METHOD: 14828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "GET_METHOD"; 14838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_METHOD: 14848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "METHOD"; 14858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_SEND_RESPONSE: 14868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "SEND_RESPONSE"; 14878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_DISCARD: 14888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "DISCARD"; 14898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_IDENTITY: 14908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "IDENTITY"; 14918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_NOTIFICATION: 14928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "NOTIFICATION"; 14938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_RETRANSMIT: 14948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "RETRANSMIT"; 14958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_SUCCESS: 14968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "SUCCESS"; 14978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_FAILURE: 14988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "FAILURE"; 14998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 15008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "UNKNOWN"; 15018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 15038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_CTRL_IFACE */ 15048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#if defined(CONFIG_CTRL_IFACE) || !defined(CONFIG_NO_STDOUT_DEBUG) 15078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic const char * eap_sm_method_state_txt(EapMethodState state) 15088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 15098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (state) { 15108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case METHOD_NONE: 15118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "NONE"; 15128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case METHOD_INIT: 15138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "INIT"; 15148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case METHOD_CONT: 15158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "CONT"; 15168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case METHOD_MAY_CONT: 15178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "MAY_CONT"; 15188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case METHOD_DONE: 15198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "DONE"; 15208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 15218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "UNKNOWN"; 15228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 15248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic const char * eap_sm_decision_txt(EapDecision decision) 15278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 15288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (decision) { 15298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case DECISION_FAIL: 15308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "FAIL"; 15318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case DECISION_COND_SUCC: 15328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "COND_SUCC"; 15338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case DECISION_UNCOND_SUCC: 15348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "UNCOND_SUCC"; 15358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 15368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "UNKNOWN"; 15378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 15398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */ 15408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_CTRL_IFACE 15438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 15458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_sm_get_status - Get EAP state machine status 15468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 15478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @buf: Buffer for status information 15488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @buflen: Maximum buffer length 15498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @verbose: Whether to include verbose status information 15508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Number of bytes written to buf. 15518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 15528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Query EAP state machine for status information. This function fills in a 15538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * text area with current status information from the EAPOL state machine. If 15548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * the buffer (buf) is not large enough, status information will be truncated 15558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * to fit the buffer. 15568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 15578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint eap_sm_get_status(struct eap_sm *sm, char *buf, size_t buflen, int verbose) 15588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 15598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int len, ret; 15608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 15628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 15638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = os_snprintf(buf, buflen, 15658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "EAP state=%s\n", 15668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sm_state_txt(sm->EAP_state)); 15678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < 0 || (size_t) len >= buflen) 15688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 15698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->selectedMethod != EAP_TYPE_NONE) { 15718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *name; 15728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->m) { 15738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt name = sm->m->name; 15748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 15758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct eap_method *m = 15768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_peer_get_eap_method(EAP_VENDOR_IETF, 15778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->selectedMethod); 15788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (m) 15798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt name = m->name; 15808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 15818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt name = "?"; 15828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(buf + len, buflen - len, 15848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "selectedMethod=%d (EAP-%s)\n", 15858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->selectedMethod, name); 15868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0 || (size_t) ret >= buflen - len) 15878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return len; 15888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len += ret; 15898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->m && sm->m->get_status) { 15918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len += sm->m->get_status(sm, sm->eap_method_priv, 15928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf + len, buflen - len, 15938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt verbose); 15948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (verbose) { 15988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(buf + len, buflen - len, 15998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "reqMethod=%d\n" 16008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "methodState=%s\n" 16018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "decision=%s\n" 16028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "ClientTimeout=%d\n", 16038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->reqMethod, 16048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sm_method_state_txt(sm->methodState), 16058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sm_decision_txt(sm->decision), 16068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->ClientTimeout); 16078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0 || (size_t) ret >= buflen - len) 16088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return len; 16098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len += ret; 16108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return len; 16138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 16148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_CTRL_IFACE */ 16158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#if defined(CONFIG_CTRL_IFACE) || !defined(CONFIG_NO_STDOUT_DEBUG) 16181f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic void eap_sm_request(struct eap_sm *sm, enum wpa_ctrl_req_type field, 16198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *msg, size_t msglen) 16208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 16218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_peer_config *config; 16221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt char *txt = NULL, *tmp; 16238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 16258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 16268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt config = eap_get_config(sm); 16278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (config == NULL) 16288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 16298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16301f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt switch (field) { 16311f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt case WPA_CTRL_REQ_EAP_IDENTITY: 16328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt config->pending_req_identity++; 16338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 16341f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt case WPA_CTRL_REQ_EAP_PASSWORD: 16358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt config->pending_req_password++; 16368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 16371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt case WPA_CTRL_REQ_EAP_NEW_PASSWORD: 16388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt config->pending_req_new_password++; 16398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 16401f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt case WPA_CTRL_REQ_EAP_PIN: 16418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt config->pending_req_pin++; 16428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 16431f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt case WPA_CTRL_REQ_EAP_OTP: 16448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg) { 16458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tmp = os_malloc(msglen + 3); 16468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tmp == NULL) 16478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 16488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tmp[0] = '['; 16498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(tmp + 1, msg, msglen); 16508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tmp[msglen + 1] = ']'; 16518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tmp[msglen + 2] = '\0'; 16528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt txt = tmp; 16538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(config->pending_req_otp); 16548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt config->pending_req_otp = tmp; 16558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt config->pending_req_otp_len = msglen + 3; 16568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 16578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (config->pending_req_otp == NULL) 16588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 16598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt txt = config->pending_req_otp; 16608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 16621f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt case WPA_CTRL_REQ_EAP_PASSPHRASE: 16638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt config->pending_req_passphrase++; 16648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 16658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 16668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 16678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->eapol_cb->eap_param_needed) 16708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eapol_cb->eap_param_needed(sm->eapol_ctx, field, txt); 16718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 16728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */ 16738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define eap_sm_request(sm, type, msg, msglen) do { } while (0) 16748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */ 16758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtconst char * eap_sm_get_method_name(struct eap_sm *sm) 16778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 16788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->m == NULL) 16798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "UNKNOWN"; 16808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return sm->m->name; 16818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 16828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 16858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_sm_request_identity - Request identity from user (ctrl_iface) 16868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 16878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 16888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * EAP methods can call this function to request identity information for the 16898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * current network. This is normally called when the identity is not included 16908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * in the network configuration. The request will be sent to monitor programs 16918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * through the control interface. 16928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 16938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eap_sm_request_identity(struct eap_sm *sm) 16948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 16951f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt eap_sm_request(sm, WPA_CTRL_REQ_EAP_IDENTITY, NULL, 0); 16968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 16978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 17008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_sm_request_password - Request password from user (ctrl_iface) 17018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 17028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 17038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * EAP methods can call this function to request password information for the 17048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * current network. This is normally called when the password is not included 17058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * in the network configuration. The request will be sent to monitor programs 17068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * through the control interface. 17078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 17088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eap_sm_request_password(struct eap_sm *sm) 17098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 17101f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt eap_sm_request(sm, WPA_CTRL_REQ_EAP_PASSWORD, NULL, 0); 17118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 17128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 17158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_sm_request_new_password - Request new password from user (ctrl_iface) 17168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 17178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 17188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * EAP methods can call this function to request new password information for 17198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * the current network. This is normally called when the EAP method indicates 17208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * that the current password has expired and password change is required. The 17218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * request will be sent to monitor programs through the control interface. 17228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 17238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eap_sm_request_new_password(struct eap_sm *sm) 17248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 17251f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt eap_sm_request(sm, WPA_CTRL_REQ_EAP_NEW_PASSWORD, NULL, 0); 17268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 17278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 17308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_sm_request_pin - Request SIM or smart card PIN from user (ctrl_iface) 17318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 17328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 17338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * EAP methods can call this function to request SIM or smart card PIN 17348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * information for the current network. This is normally called when the PIN is 17358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * not included in the network configuration. The request will be sent to 17368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * monitor programs through the control interface. 17378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 17388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eap_sm_request_pin(struct eap_sm *sm) 17398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 17401f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt eap_sm_request(sm, WPA_CTRL_REQ_EAP_PIN, NULL, 0); 17418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 17428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 17458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_sm_request_otp - Request one time password from user (ctrl_iface) 17468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 17478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @msg: Message to be displayed to the user when asking for OTP 17488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @msg_len: Length of the user displayable message 17498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 17508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * EAP methods can call this function to request open time password (OTP) for 17518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * the current network. The request will be sent to monitor programs through 17528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * the control interface. 17538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 17548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eap_sm_request_otp(struct eap_sm *sm, const char *msg, size_t msg_len) 17558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 17561f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt eap_sm_request(sm, WPA_CTRL_REQ_EAP_OTP, msg, msg_len); 17578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 17588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 17618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_sm_request_passphrase - Request passphrase from user (ctrl_iface) 17628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 17638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 17648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * EAP methods can call this function to request passphrase for a private key 17658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * for the current network. This is normally called when the passphrase is not 17668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * included in the network configuration. The request will be sent to monitor 17678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * programs through the control interface. 17688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 17698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eap_sm_request_passphrase(struct eap_sm *sm) 17708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 17711f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt eap_sm_request(sm, WPA_CTRL_REQ_EAP_PASSPHRASE, NULL, 0); 17728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 17738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 17768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_sm_notify_ctrl_attached - Notification of attached monitor 17778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 17788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 17798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Notify EAP state machines that a monitor was attached to the control 17808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * interface to trigger re-sending of pending requests for user input. 17818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 17828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eap_sm_notify_ctrl_attached(struct eap_sm *sm) 17838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 17848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_peer_config *config = eap_get_config(sm); 17858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (config == NULL) 17878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 17888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Re-send any pending requests for user data since a new control 17908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * interface was added. This handles cases where the EAP authentication 17918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * starts immediately after system startup when the user interface is 17928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * not yet running. */ 17938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (config->pending_req_identity) 17948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sm_request_identity(sm); 17958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (config->pending_req_password) 17968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sm_request_password(sm); 17978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (config->pending_req_new_password) 17988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sm_request_new_password(sm); 17998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (config->pending_req_otp) 18008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sm_request_otp(sm, NULL, 0); 18018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (config->pending_req_pin) 18028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sm_request_pin(sm); 18038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (config->pending_req_passphrase) 18048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sm_request_passphrase(sm); 18058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 18068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int eap_allowed_phase2_type(int vendor, int type) 18098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 18108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (vendor != EAP_VENDOR_IETF) 18118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 18128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return type != EAP_TYPE_PEAP && type != EAP_TYPE_TTLS && 18138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt type != EAP_TYPE_FAST; 18148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 18158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 18188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_get_phase2_type - Get EAP type for the given EAP phase 2 method name 18198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @name: EAP method name, e.g., MD5 18208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @vendor: Buffer for returning EAP Vendor-Id 18218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: EAP method type or %EAP_TYPE_NONE if not found 18228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 18238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function maps EAP type names into EAP type numbers that are allowed for 18248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Phase 2, i.e., for tunneled authentication. Phase 2 is used, e.g., with 18258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * EAP-PEAP, EAP-TTLS, and EAP-FAST. 18268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 18278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtu32 eap_get_phase2_type(const char *name, int *vendor) 18288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 18298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int v; 18308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 type = eap_peer_get_type(name, &v); 18318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eap_allowed_phase2_type(v, type)) { 18328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *vendor = v; 18338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return type; 18348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *vendor = EAP_VENDOR_IETF; 18368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return EAP_TYPE_NONE; 18378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 18388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 18418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_get_phase2_types - Get list of allowed EAP phase 2 types 18428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @config: Pointer to a network configuration 18438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @count: Pointer to a variable to be filled with number of returned EAP types 18448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Pointer to allocated type list or %NULL on failure 18458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 18468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function generates an array of allowed EAP phase 2 (tunneled) types for 18478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * the given network configuration. 18488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 18498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct eap_method_type * eap_get_phase2_types(struct eap_peer_config *config, 18508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t *count) 18518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 18528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_method_type *buf; 18538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u32 method; 18548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int vendor; 18558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t mcount; 18568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct eap_method *methods, *m; 18578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt methods = eap_peer_get_methods(&mcount); 18598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (methods == NULL) 18608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 18618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *count = 0; 18628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf = os_malloc(mcount * sizeof(struct eap_method_type)); 18638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf == NULL) 18648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 18658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (m = methods; m; m = m->next) { 18678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt vendor = m->vendor; 18688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt method = m->method; 18698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eap_allowed_phase2_type(vendor, method)) { 18708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (vendor == EAP_VENDOR_IETF && 18718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt method == EAP_TYPE_TLS && config && 18728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt config->private_key2 == NULL) 18738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 18748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf[*count].vendor = vendor; 18758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf[*count].method = method; 18768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (*count)++; 18778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return buf; 18818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 18828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 18858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_set_fast_reauth - Update fast_reauth setting 18868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 18878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @enabled: 1 = Fast reauthentication is enabled, 0 = Disabled 18888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 18898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eap_set_fast_reauth(struct eap_sm *sm, int enabled) 18908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 18918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->fast_reauth = enabled; 18928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 18938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 18968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_set_workaround - Update EAP workarounds setting 18978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 18988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @workaround: 1 = Enable EAP workarounds, 0 = Disable EAP workarounds 18998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 19008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eap_set_workaround(struct eap_sm *sm, unsigned int workaround) 19018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 19028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->workaround = workaround; 19038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 19048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 19078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_get_config - Get current network configuration 19088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 19098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Pointer to the current network configuration or %NULL if not found 19108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 19118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * EAP peer methods should avoid using this function if they can use other 19128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * access functions, like eap_get_config_identity() and 19138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_get_config_password(), that do not require direct access to 19148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * struct eap_peer_config. 19158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 19168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct eap_peer_config * eap_get_config(struct eap_sm *sm) 19178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 19188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return sm->eapol_cb->get_config(sm->eapol_ctx); 19198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 19208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 19238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_get_config_identity - Get identity from the network configuration 19248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 19258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @len: Buffer for the length of the identity 19268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Pointer to the identity or %NULL if not found 19278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 19288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtconst u8 * eap_get_config_identity(struct eap_sm *sm, size_t *len) 19298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 19308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_peer_config *config = eap_get_config(sm); 19318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (config == NULL) 19328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 19338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *len = config->identity_len; 19348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return config->identity; 19358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 19368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 193861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtstatic int eap_get_ext_password(struct eap_sm *sm, 193961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct eap_peer_config *config) 194061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 194161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt char *name; 194261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 194361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (config->password == NULL) 194461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 194561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 194661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt name = os_zalloc(config->password_len + 1); 194761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (name == NULL) 194861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 194961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt os_memcpy(name, config->password, config->password_len); 195061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 195161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt ext_password_free(sm->ext_pw_buf); 195261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt sm->ext_pw_buf = ext_password_get(sm->ext_pw, name); 195361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt os_free(name); 195461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 195561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return sm->ext_pw_buf == NULL ? -1 : 0; 195661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 195761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 195861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 19598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 19608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_get_config_password - Get password from the network configuration 19618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 19628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @len: Buffer for the length of the password 19638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Pointer to the password or %NULL if not found 19648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 19658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtconst u8 * eap_get_config_password(struct eap_sm *sm, size_t *len) 19668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 19678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_peer_config *config = eap_get_config(sm); 19688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (config == NULL) 19698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 197061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 197161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (config->flags & EAP_CONFIG_FLAGS_EXT_PASSWORD) { 197261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (eap_get_ext_password(sm, config) < 0) 197361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return NULL; 197461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt *len = wpabuf_len(sm->ext_pw_buf); 197561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return wpabuf_head(sm->ext_pw_buf); 197661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 197761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 19788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *len = config->password_len; 19798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return config->password; 19808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 19818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 19848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_get_config_password2 - Get password from the network configuration 19858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 19868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @len: Buffer for the length of the password 19878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @hash: Buffer for returning whether the password is stored as a 19888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * NtPasswordHash instead of plaintext password; can be %NULL if this 19898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * information is not needed 19908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Pointer to the password or %NULL if not found 19918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 19928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtconst u8 * eap_get_config_password2(struct eap_sm *sm, size_t *len, int *hash) 19938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 19948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_peer_config *config = eap_get_config(sm); 19958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (config == NULL) 19968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 199761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 199861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (config->flags & EAP_CONFIG_FLAGS_EXT_PASSWORD) { 199961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (eap_get_ext_password(sm, config) < 0) 200061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return NULL; 200161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt *len = wpabuf_len(sm->ext_pw_buf); 200261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return wpabuf_head(sm->ext_pw_buf); 200361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 200461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 20058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *len = config->password_len; 20068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hash) 20078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *hash = !!(config->flags & EAP_CONFIG_FLAGS_PASSWORD_NTHASH); 20088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return config->password; 20098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 20108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 20138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_get_config_new_password - Get new password from network configuration 20148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 20158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @len: Buffer for the length of the new password 20168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Pointer to the new password or %NULL if not found 20178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 20188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtconst u8 * eap_get_config_new_password(struct eap_sm *sm, size_t *len) 20198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 20208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_peer_config *config = eap_get_config(sm); 20218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (config == NULL) 20228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 20238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *len = config->new_password_len; 20248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return config->new_password; 20258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 20268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 20298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_get_config_otp - Get one-time password from the network configuration 20308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 20318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @len: Buffer for the length of the one-time password 20328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Pointer to the one-time password or %NULL if not found 20338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 20348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtconst u8 * eap_get_config_otp(struct eap_sm *sm, size_t *len) 20358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 20368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_peer_config *config = eap_get_config(sm); 20378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (config == NULL) 20388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 20398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *len = config->otp_len; 20408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return config->otp; 20418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 20428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 20458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_clear_config_otp - Clear used one-time password 20468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 20478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 20488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function clears a used one-time password (OTP) from the current network 20498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * configuration. This should be called when the OTP has been used and is not 20508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * needed anymore. 20518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 20528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eap_clear_config_otp(struct eap_sm *sm) 20538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 20548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_peer_config *config = eap_get_config(sm); 20558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (config == NULL) 20568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 20578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(config->otp, 0, config->otp_len); 20588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(config->otp); 20598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt config->otp = NULL; 20608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt config->otp_len = 0; 20618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 20628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 20658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_get_config_phase1 - Get phase1 data from the network configuration 20668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 20678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Pointer to the phase1 data or %NULL if not found 20688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 20698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtconst char * eap_get_config_phase1(struct eap_sm *sm) 20708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 20718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_peer_config *config = eap_get_config(sm); 20728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (config == NULL) 20738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 20748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return config->phase1; 20758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 20768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 20798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_get_config_phase2 - Get phase2 data from the network configuration 20808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 20818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Pointer to the phase1 data or %NULL if not found 20828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 20838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtconst char * eap_get_config_phase2(struct eap_sm *sm) 20848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 20858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_peer_config *config = eap_get_config(sm); 20868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (config == NULL) 20878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 20888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return config->phase2; 20898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 20908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint eap_get_config_fragment_size(struct eap_sm *sm) 20938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 20948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_peer_config *config = eap_get_config(sm); 20958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (config == NULL) 20968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 20978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return config->fragment_size; 20988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 20998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 21028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_key_available - Get key availability (eapKeyAvailable variable) 21038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 21048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 1 if EAP keying material is available, 0 if not 21058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 21068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint eap_key_available(struct eap_sm *sm) 21078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 21088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return sm ? sm->eapKeyAvailable : 0; 21098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 21108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 21138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_notify_success - Notify EAP state machine about external success trigger 21148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 21158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 21168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is called when external event, e.g., successful completion of 21178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * WPA-PSK key handshake, is indicating that EAP state machine should move to 21188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * success state. This is mainly used with security modes that do not use EAP 21198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * state machine (e.g., WPA-PSK). 21208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 21218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eap_notify_success(struct eap_sm *sm) 21228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 21238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm) { 21248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->decision = DECISION_COND_SUCC; 21258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->EAP_state = EAP_SUCCESS; 21268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 21278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 21288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 21318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_notify_lower_layer_success - Notification of lower layer success 21328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 21338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 21348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Notify EAP state machines that a lower layer has detected a successful 21358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * authentication. This is used to recover from dropped EAP-Success messages. 21368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 21378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eap_notify_lower_layer_success(struct eap_sm *sm) 21388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 21398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 21408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 21418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eapol_get_bool(sm, EAPOL_eapSuccess) || 21438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->decision == DECISION_FAIL || 21448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (sm->methodState != METHOD_MAY_CONT && 21458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->methodState != METHOD_DONE)) 21468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 21478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->eapKeyData != NULL) 21498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eapKeyAvailable = TRUE; 21508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_set_bool(sm, EAPOL_eapSuccess, TRUE); 21518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_SUCCESS 21528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "EAP authentication completed successfully (based on lower " 21538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "layer success)"); 21548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 21558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 21588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_get_eapKeyData - Get master session key (MSK) from EAP state machine 21598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 21608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @len: Pointer to variable that will be set to number of bytes in the key 21618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Pointer to the EAP keying data or %NULL on failure 21628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 21638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Fetch EAP keying material (MSK, eapKeyData) from the EAP state machine. The 21648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * key is available only after a successful authentication. EAP state machine 21658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * continues to manage the key data and the caller must not change or free the 21668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * returned data. 21678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 21688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtconst u8 * eap_get_eapKeyData(struct eap_sm *sm, size_t *len) 21698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 21708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL || sm->eapKeyData == NULL) { 21718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *len = 0; 21728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 21738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 21748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *len = sm->eapKeyDataLen; 21768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return sm->eapKeyData; 21778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 21788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 21818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_get_eapKeyData - Get EAP response data 21828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 21838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Pointer to the EAP response (eapRespData) or %NULL on failure 21848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 21858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Fetch EAP response (eapRespData) from the EAP state machine. This data is 21868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * available when EAP state machine has processed an incoming EAP request. The 21878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * EAP state machine does not maintain a reference to the response after this 21888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * function is called and the caller is responsible for freeing the data. 21898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 21908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct wpabuf * eap_get_eapRespData(struct eap_sm *sm) 21918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 21928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *resp; 21938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL || sm->eapRespData == NULL) 21958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 21968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = sm->eapRespData; 21988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eapRespData = NULL; 21998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return resp; 22018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 22028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 22058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_sm_register_scard_ctx - Notification of smart card context 22068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 22078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @ctx: Context data for smart card operations 22088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 22098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Notify EAP state machines of context data for smart card operations. This 22108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * context data will be used as a parameter for scard_*() functions. 22118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 22128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eap_register_scard_ctx(struct eap_sm *sm, void *ctx) 22138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 22148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm) 22158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->scard_ctx = ctx; 22168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 22178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 22208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_set_config_blob - Set or add a named configuration blob 22218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 22228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @blob: New value for the blob 22238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 22248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Adds a new configuration blob or replaces the current value of an existing 22258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * blob. 22268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 22278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eap_set_config_blob(struct eap_sm *sm, struct wpa_config_blob *blob) 22288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 22298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NO_CONFIG_BLOBS 22308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eapol_cb->set_config_blob(sm->eapol_ctx, blob); 22318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NO_CONFIG_BLOBS */ 22328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 22338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 22368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_get_config_blob - Get a named configuration blob 22378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 22388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @name: Name of the blob 22398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Pointer to blob data or %NULL if not found 22408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 22418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtconst struct wpa_config_blob * eap_get_config_blob(struct eap_sm *sm, 22428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *name) 22438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 22448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NO_CONFIG_BLOBS 22458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return sm->eapol_cb->get_config_blob(sm->eapol_ctx, name); 22468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* CONFIG_NO_CONFIG_BLOBS */ 22478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 22488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NO_CONFIG_BLOBS */ 22498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 22508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 22538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_set_force_disabled - Set force_disabled flag 22548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 22558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @disabled: 1 = EAP disabled, 0 = EAP enabled 22568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 22578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is used to force EAP state machine to be disabled when it is 22588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * not in use (e.g., with WPA-PSK or plaintext connections). 22598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 22608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eap_set_force_disabled(struct eap_sm *sm, int disabled) 22618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 22628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->force_disabled = disabled; 22638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 22648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /** 22678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_notify_pending - Notify that EAP method is ready to re-process a request 22688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 22698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 22708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * An EAP method can perform a pending operation (e.g., to get a response from 22718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * an external process). Once the response is available, this function can be 22728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * used to request EAPOL state machine to retry delivering the previously 22738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * received (and still unanswered) EAP request to EAP state machine. 22748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 22758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eap_notify_pending(struct eap_sm *sm) 22768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 22778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eapol_cb->notify_pending(sm->eapol_ctx); 22788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 22798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 22828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_invalidate_cached_session - Mark cached session data invalid 22838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 22848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 22858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eap_invalidate_cached_session(struct eap_sm *sm) 22868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 22878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm) 22888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_deinit_prev_method(sm, "invalidate"); 22898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 22908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint eap_is_wps_pbc_enrollee(struct eap_peer_config *conf) 22938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 22948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conf->identity_len != WSC_ID_ENROLLEE_LEN || 22958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(conf->identity, WSC_ID_ENROLLEE, WSC_ID_ENROLLEE_LEN)) 22968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; /* Not a WPS Enrollee */ 22978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conf->phase1 == NULL || os_strstr(conf->phase1, "pbc=1") == NULL) 22998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; /* Not using PBC */ 23008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 23028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 23038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint eap_is_wps_pin_enrollee(struct eap_peer_config *conf) 23068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 23078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conf->identity_len != WSC_ID_ENROLLEE_LEN || 23088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(conf->identity, WSC_ID_ENROLLEE, WSC_ID_ENROLLEE_LEN)) 23098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; /* Not a WPS Enrollee */ 23108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conf->phase1 == NULL || os_strstr(conf->phase1, "pin=") == NULL) 23128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; /* Not using PIN */ 23138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 23158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 231661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 231761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 231861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtvoid eap_sm_set_ext_pw_ctx(struct eap_sm *sm, struct ext_password_data *ext) 231961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 232061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt ext_password_free(sm->ext_pw_buf); 232161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt sm->ext_pw_buf = NULL; 232261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt sm->ext_pw = ext; 232361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 23244530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 23254530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 23264530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt/** 23274530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt * eap_set_anon_id - Set or add anonymous identity 23284530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 23294530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt * @id: Anonymous identity (e.g., EAP-SIM pseudonym) or %NULL to clear 23304530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt * @len: Length of anonymous identity in octets 23314530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt */ 23324530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidtvoid eap_set_anon_id(struct eap_sm *sm, const u8 *id, size_t len) 23334530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt{ 23344530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (sm->eapol_cb->set_anon_id) 23354530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt sm->eapol_cb->set_anon_id(sm->eapol_ctx, id, len); 23364530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt} 2337