18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * EAP peer state machines (RFC 4137) 3fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt * Copyright (c) 2004-2014, 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" 266c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt#include "crypto/sha256.h" 278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common/wpa_ctrl.h" 288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eap_common/eap_wsc_common.h" 298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eap_i.h" 308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eap_config.h" 318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define STATE_MACHINE_DATA struct eap_sm 338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define STATE_MACHINE_DEBUG_PREFIX "EAP" 348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define EAP_MAX_AUTH_ROUNDS 50 368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define EAP_CLIENT_TIMEOUT_DEFAULT 60 378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic Boolean eap_sm_allowMethod(struct eap_sm *sm, int vendor, 408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EapType method); 418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpabuf * eap_sm_buildNak(struct eap_sm *sm, int id); 428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eap_sm_processIdentity(struct eap_sm *sm, 438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct wpabuf *req); 448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eap_sm_processNotify(struct eap_sm *sm, const struct wpabuf *req); 458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpabuf * eap_sm_buildNotify(int id); 468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eap_sm_parseEapReq(struct eap_sm *sm, const struct wpabuf *req); 478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#if defined(CONFIG_CTRL_IFACE) || !defined(CONFIG_NO_STDOUT_DEBUG) 488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic const char * eap_sm_method_state_txt(EapMethodState state); 498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic const char * eap_sm_decision_txt(EapDecision decision); 508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */ 518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic Boolean eapol_get_bool(struct eap_sm *sm, enum eapol_bool_var var) 558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return sm->eapol_cb->get_bool(sm->eapol_ctx, var); 578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eapol_set_bool(struct eap_sm *sm, enum eapol_bool_var var, 618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Boolean value) 628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eapol_cb->set_bool(sm->eapol_ctx, var, value); 648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic unsigned int eapol_get_int(struct eap_sm *sm, enum eapol_int_var var) 688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return sm->eapol_cb->get_int(sm->eapol_ctx, var); 708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eapol_set_int(struct eap_sm *sm, enum eapol_int_var var, 748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int value) 758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eapol_cb->set_int(sm->eapol_ctx, var, value); 778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpabuf * eapol_get_eapReqData(struct eap_sm *sm) 818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return sm->eapol_cb->get_eapReqData(sm->eapol_ctx); 838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8604949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic void eap_notify_status(struct eap_sm *sm, const char *status, 8704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt const char *parameter) 8804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 8904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: Status notification: %s (param=%s)", 9004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt status, parameter); 9104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (sm->eapol_cb->notify_status) 9204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt sm->eapol_cb->notify_status(sm->eapol_ctx, status, parameter); 9304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 9404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 9504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 96c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidtstatic void eap_sm_free_key(struct eap_sm *sm) 97c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt{ 98c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt if (sm->eapKeyData) { 99c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt bin_clear_free(sm->eapKeyData, sm->eapKeyDataLen); 100c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt sm->eapKeyData = NULL; 101c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt } 102c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt} 103c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt 104c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt 1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eap_deinit_prev_method(struct eap_sm *sm, const char *txt) 1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 10761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt ext_password_free(sm->ext_pw_buf); 10861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt sm->ext_pw_buf = NULL; 10961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->m == NULL || sm->eap_method_priv == NULL) 1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: deinitialize previously used EAP method " 1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(%d, %s) at %s", sm->selectedMethod, sm->m->name, txt); 1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->m->deinit(sm, sm->eap_method_priv); 1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap_method_priv = NULL; 1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->m = NULL; 1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_allowed_method - Check whether EAP method is allowed 1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @vendor: Vendor-Id for expanded types or 0 = IETF for legacy types 1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @method: EAP type 1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 1 = allowed EAP method, 0 = not allowed 1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint eap_allowed_method(struct eap_sm *sm, int vendor, u32 method) 1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_peer_config *config = eap_get_config(sm); 1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_method_type *m; 1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (config == NULL || config->eap_methods == NULL) 1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt m = config->eap_methods; 1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; m[i].vendor != EAP_VENDOR_IETF || 1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt m[i].method != EAP_TYPE_NONE; i++) { 1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (m[i].vendor == vendor && m[i].method == method) 1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This state initializes state machine variables when the machine is 1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * activated (portEnabled = TRUE). This is also used when re-starting 1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * authentication (eapRestart == TRUE). 1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(EAP, INITIALIZE) 1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY(EAP, INITIALIZE); 1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->fast_reauth && sm->m && sm->m->has_reauth_data && 1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->m->has_reauth_data(sm, sm->eap_method_priv) && 1577f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt !sm->prev_failure && 1587f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt sm->last_config == eap_get_config(sm)) { 1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: maintaining EAP method data for " 1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "fast reauthentication"); 1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->m->deinit_for_reauth(sm, sm->eap_method_priv); 1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 1637f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt sm->last_config = eap_get_config(sm); 1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_deinit_prev_method(sm, "INITIALIZE"); 1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->selectedMethod = EAP_TYPE_NONE; 1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->methodState = METHOD_NONE; 1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->allowNotifications = TRUE; 1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->decision = DECISION_FAIL; 1701f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt sm->ClientTimeout = EAP_CLIENT_TIMEOUT_DEFAULT; 1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_set_int(sm, EAPOL_idleWhile, sm->ClientTimeout); 1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_set_bool(sm, EAPOL_eapSuccess, FALSE); 1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_set_bool(sm, EAPOL_eapFail, FALSE); 174c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt eap_sm_free_key(sm); 175f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt os_free(sm->eapSessionId); 176f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt sm->eapSessionId = NULL; 1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eapKeyAvailable = FALSE; 1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_set_bool(sm, EAPOL_eapRestart, FALSE); 1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->lastId = -1; /* new session - make sure this does not match with 1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * the first EAP-Packet */ 1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * RFC 4137 does not reset eapResp and eapNoResp here. However, this 1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * seemed to be able to trigger cases where both were set and if EAPOL 1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * state machine uses eapNoResp first, it may end up not sending a real 1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * reply correctly. This occurred when the workaround in FAIL state set 1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eapNoResp = TRUE.. Maybe that workaround needs to be fixed to do 1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * something else(?) 1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_set_bool(sm, EAPOL_eapResp, FALSE); 1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_set_bool(sm, EAPOL_eapNoResp, FALSE); 1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->num_rounds = 0; 1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->prev_failure = 0; 193344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt sm->expected_failure = 0; 1946c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt sm->reauthInit = FALSE; 1956c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt sm->erp_seq = (u32) -1; 1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This state is reached whenever service from the lower layer is interrupted 2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * or unavailable (portEnabled == FALSE). Immediate transition to INITIALIZE 2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * occurs when the port becomes enabled. 2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(EAP, DISABLED) 2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY(EAP, DISABLED); 2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->num_rounds = 0; 20861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt /* 20961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * RFC 4137 does not describe clearing of idleWhile here, but doing so 21061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * allows the timer tick to be stopped more quickly when EAP is not in 21161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * use. 21261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt */ 21361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt eapol_set_int(sm, EAPOL_idleWhile, 0); 2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * The state machine spends most of its time here, waiting for something to 2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * happen. This state is entered unconditionally from INITIALIZE, DISCARD, and 2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * SEND_RESPONSE states. 2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(EAP, IDLE) 2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY(EAP, IDLE); 2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This state is entered when an EAP packet is received (eapReq == TRUE) to 2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * parse the packet header. 2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(EAP, RECEIVED) 2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct wpabuf *eapReqData; 2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY(EAP, RECEIVED); 2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapReqData = eapol_get_eapReqData(sm); 2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* parse rxReq, rxSuccess, rxFailure, reqId, reqMethod */ 2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sm_parseEapReq(sm, eapReqData); 2408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->num_rounds++; 2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This state is entered when a request for a new type comes in. Either the 2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * correct method is started, or a Nak response is built. 2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(EAP, GET_METHOD) 2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int reinit; 2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EapType method; 25204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt const struct eap_method *eap_method; 2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY(EAP, GET_METHOD); 2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->reqMethod == EAP_TYPE_EXPANDED) 2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt method = sm->reqVendorMethod; 2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt method = sm->reqMethod; 2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt eap_method = eap_peer_get_eap_method(sm->reqVendor, method); 26204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!eap_sm_allowMethod(sm, sm->reqVendor, method)) { 2648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: vendor %u method %u not allowed", 2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->reqVendor, method); 2668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_PROPOSED_METHOD 2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "vendor=%u method=%u -> NAK", 2688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->reqVendor, method); 26904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt eap_notify_status(sm, "refuse proposed method", 27004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt eap_method ? eap_method->name : "unknown"); 2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto nak; 2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_PROPOSED_METHOD 2758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "vendor=%u method=%u", sm->reqVendor, method); 2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt eap_notify_status(sm, "accept proposed method", 27804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt eap_method ? eap_method->name : "unknown"); 2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * RFC 4137 does not define specific operation for fast 2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * re-authentication (session resumption). The design here is to allow 2828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * the previously used method data to be maintained for 2838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * re-authentication if the method support session resumption. 2848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Otherwise, the previously used method data is freed and a new method 2858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * is allocated here. 2868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 2878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->fast_reauth && 2888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->m && sm->m->vendor == sm->reqVendor && 2898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->m->method == method && 2908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->m->has_reauth_data && 2918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->m->has_reauth_data(sm, sm->eap_method_priv)) { 2928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: Using previous method data" 2938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " for fast re-authentication"); 2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reinit = 1; 2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_deinit_prev_method(sm, "GET_METHOD"); 2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reinit = 0; 2988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->selectedMethod = sm->reqMethod; 3018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->m == NULL) 30204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt sm->m = eap_method; 3038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!sm->m) { 3048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: Could not find selected method: " 3058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "vendor %d method %d", 3068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->reqVendor, method); 3078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto nak; 3088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->ClientTimeout = EAP_CLIENT_TIMEOUT_DEFAULT; 3118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: Initialize selected EAP method: " 3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "vendor %u method %u (%s)", 3148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->reqVendor, method, sm->m->name); 3158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (reinit) 3168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap_method_priv = sm->m->init_for_reauth( 3178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm, sm->eap_method_priv); 3188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 3198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap_method_priv = sm->m->init(sm); 3208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->eap_method_priv == NULL) { 3228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_peer_config *config = eap_get_config(sm); 3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(sm->msg_ctx, MSG_INFO, 3248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "EAP: Failed to initialize EAP method: vendor %u " 3258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "method %u (%s)", 3268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->reqVendor, method, sm->m->name); 3278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->m = NULL; 3288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->methodState = METHOD_NONE; 3298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->selectedMethod = EAP_TYPE_NONE; 3308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->reqMethod == EAP_TYPE_TLS && config && 3318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (config->pending_req_pin || 3328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt config->pending_req_passphrase)) { 3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 3348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Return without generating Nak in order to allow 3358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * entering of PIN code or passphrase to retry the 3368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * current EAP packet. 3378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 3388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: Pending PIN/passphrase " 3398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "request - skip Nak"); 3408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 3418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto nak; 3448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->methodState = METHOD_INIT; 3478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_METHOD 3488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "EAP vendor %u method %u (%s) selected", 3498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->reqVendor, method, sm->m->name); 3508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 3518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtnak: 3538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(sm->eapRespData); 3548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eapRespData = NULL; 3558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eapRespData = eap_sm_buildNak(sm, sm->reqId); 3568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3596c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt#ifdef CONFIG_ERP 3606c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 3616c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidtstatic char * eap_home_realm(struct eap_sm *sm) 3626c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt{ 3636c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt struct eap_peer_config *config = eap_get_config(sm); 3646c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt char *realm; 3656c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt size_t i, realm_len; 3666c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 3676c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (!config) 3686c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return NULL; 3696c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 3706c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (config->identity) { 3716c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt for (i = 0; i < config->identity_len; i++) { 3726c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (config->identity[i] == '@') 3736c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt break; 3746c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 3756c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (i < config->identity_len) { 3766c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt realm_len = config->identity_len - i - 1; 3776c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt realm = os_malloc(realm_len + 1); 3786c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (realm == NULL) 3796c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return NULL; 3806c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt os_memcpy(realm, &config->identity[i + 1], realm_len); 3816c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt realm[realm_len] = '\0'; 3826c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return realm; 3836c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 3846c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 3856c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 3866c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (config->anonymous_identity) { 3876c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt for (i = 0; i < config->anonymous_identity_len; i++) { 3886c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (config->anonymous_identity[i] == '@') 3896c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt break; 3906c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 3916c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (i < config->anonymous_identity_len) { 3926c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt realm_len = config->anonymous_identity_len - i - 1; 3936c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt realm = os_malloc(realm_len + 1); 3946c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (realm == NULL) 3956c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return NULL; 3966c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt os_memcpy(realm, &config->anonymous_identity[i + 1], 3976c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt realm_len); 3986c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt realm[realm_len] = '\0'; 3996c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return realm; 4006c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 4016c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 4026c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 4036c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return os_strdup(""); 4046c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt} 4056c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 4066c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 4076c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidtstatic struct eap_erp_key * 4086c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidteap_erp_get_key(struct eap_sm *sm, const char *realm) 4096c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt{ 4106c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt struct eap_erp_key *erp; 4116c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 4126c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt dl_list_for_each(erp, &sm->erp_keys, struct eap_erp_key, list) { 4136c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt char *pos; 4146c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 4156c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt pos = os_strchr(erp->keyname_nai, '@'); 4166c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (!pos) 4176c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt continue; 4186c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt pos++; 4196c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (os_strcmp(pos, realm) == 0) 4206c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return erp; 4216c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 4226c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 4236c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return NULL; 4246c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt} 4256c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 4266c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 4276c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidtstatic struct eap_erp_key * 4286c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidteap_erp_get_key_nai(struct eap_sm *sm, const char *nai) 4296c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt{ 4306c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt struct eap_erp_key *erp; 4316c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 4326c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt dl_list_for_each(erp, &sm->erp_keys, struct eap_erp_key, list) { 4336c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (os_strcmp(erp->keyname_nai, nai) == 0) 4346c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return erp; 4356c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 4366c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 4376c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return NULL; 4386c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt} 4396c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 4406c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 4416c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidtstatic void eap_peer_erp_free_key(struct eap_erp_key *erp) 4426c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt{ 4436c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt dl_list_del(&erp->list); 4446c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt bin_clear_free(erp, sizeof(*erp)); 4456c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt} 4466c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 4476c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 4486c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidtstatic void eap_erp_remove_keys_realm(struct eap_sm *sm, const char *realm) 4496c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt{ 4506c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt struct eap_erp_key *erp; 4516c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 4526c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt while ((erp = eap_erp_get_key(sm, realm)) != NULL) { 4536c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: Delete old ERP key %s", 4546c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt erp->keyname_nai); 4556c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt eap_peer_erp_free_key(erp); 4566c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 4576c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt} 4586c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 4596c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt#endif /* CONFIG_ERP */ 4606c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 4616c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 4626c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidtvoid eap_peer_erp_free_keys(struct eap_sm *sm) 4636c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt{ 4646c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt#ifdef CONFIG_ERP 4656c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt struct eap_erp_key *erp, *tmp; 4666c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 4676c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt dl_list_for_each_safe(erp, tmp, &sm->erp_keys, struct eap_erp_key, list) 4686c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt eap_peer_erp_free_key(erp); 4696c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt#endif /* CONFIG_ERP */ 4706c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt} 4716c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 4726c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 4736c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidtstatic void eap_peer_erp_init(struct eap_sm *sm) 4746c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt{ 4756c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt#ifdef CONFIG_ERP 4766c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt u8 *emsk = NULL; 4776c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt size_t emsk_len = 0; 4786c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt u8 EMSKname[EAP_EMSK_NAME_LEN]; 4796c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt u8 len[2]; 4806c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt char *realm; 4816c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt size_t realm_len, nai_buf_len; 4826c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt struct eap_erp_key *erp = NULL; 4836c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt int pos; 4846c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 4856c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt realm = eap_home_realm(sm); 4866c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (!realm) 4876c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return; 4886c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt realm_len = os_strlen(realm); 4896c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: Realm for ERP keyName-NAI: %s", realm); 4906c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt eap_erp_remove_keys_realm(sm, realm); 4916c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 4926c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt nai_buf_len = 2 * EAP_EMSK_NAME_LEN + 1 + realm_len; 4936c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (nai_buf_len > 253) { 4946c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt /* 4956c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * keyName-NAI has a maximum length of 253 octet to fit in 4966c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * RADIUS attributes. 4976c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt */ 4986c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_printf(MSG_DEBUG, 4996c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt "EAP: Too long realm for ERP keyName-NAI maximum length"); 5006c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt goto fail; 5016c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 5026c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt nai_buf_len++; /* null termination */ 5036c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt erp = os_zalloc(sizeof(*erp) + nai_buf_len); 5046c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (erp == NULL) 5056c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt goto fail; 5066c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 5076c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt emsk = sm->m->get_emsk(sm, sm->eap_method_priv, &emsk_len); 5086c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (!emsk || emsk_len == 0 || emsk_len > ERP_MAX_KEY_LEN) { 5096c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_printf(MSG_DEBUG, 5106c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt "EAP: No suitable EMSK available for ERP"); 5116c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt goto fail; 5126c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 5136c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 5146c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_hexdump_key(MSG_DEBUG, "EAP: EMSK", emsk, emsk_len); 5156c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 5166c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt WPA_PUT_BE16(len, 8); 5176c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (hmac_sha256_kdf(sm->eapSessionId, sm->eapSessionIdLen, "EMSK", 5186c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt len, sizeof(len), 5196c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt EMSKname, EAP_EMSK_NAME_LEN) < 0) { 5206c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: Could not derive EMSKname"); 5216c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt goto fail; 5226c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 5236c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_hexdump(MSG_DEBUG, "EAP: EMSKname", EMSKname, EAP_EMSK_NAME_LEN); 5246c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 5256c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt pos = wpa_snprintf_hex(erp->keyname_nai, nai_buf_len, 5266c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt EMSKname, EAP_EMSK_NAME_LEN); 5276c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt erp->keyname_nai[pos] = '@'; 5286c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt os_memcpy(&erp->keyname_nai[pos + 1], realm, realm_len); 5296c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 5306c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt WPA_PUT_BE16(len, emsk_len); 5316c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (hmac_sha256_kdf(emsk, emsk_len, 5326c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt "EAP Re-authentication Root Key@ietf.org", 5336c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt len, sizeof(len), erp->rRK, emsk_len) < 0) { 5346c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: Could not derive rRK for ERP"); 5356c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt goto fail; 5366c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 5376c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt erp->rRK_len = emsk_len; 5386c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_hexdump_key(MSG_DEBUG, "EAP: ERP rRK", erp->rRK, erp->rRK_len); 5396c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 5406c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (hmac_sha256_kdf(erp->rRK, erp->rRK_len, 5416c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt "EAP Re-authentication Integrity Key@ietf.org", 5426c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt len, sizeof(len), erp->rIK, erp->rRK_len) < 0) { 5436c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: Could not derive rIK for ERP"); 5446c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt goto fail; 5456c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 5466c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt erp->rIK_len = erp->rRK_len; 5476c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_hexdump_key(MSG_DEBUG, "EAP: ERP rIK", erp->rIK, erp->rIK_len); 5486c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 5496c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: Stored ERP keys %s", erp->keyname_nai); 5506c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt dl_list_add(&sm->erp_keys, &erp->list); 5516c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt erp = NULL; 5526c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidtfail: 5536c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt bin_clear_free(emsk, emsk_len); 5546c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt bin_clear_free(erp, sizeof(*erp)); 5556c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt os_free(realm); 5566c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt#endif /* CONFIG_ERP */ 5576c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt} 5586c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 5596c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 5606c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt#ifdef CONFIG_ERP 5616c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidtstatic int eap_peer_erp_reauth_start(struct eap_sm *sm, 5626c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt const struct eap_hdr *hdr, size_t len) 5636c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt{ 5646c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt char *realm; 5656c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt struct eap_erp_key *erp; 5666c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt struct wpabuf *msg; 5676c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt u8 hash[SHA256_MAC_LEN]; 5686c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 5696c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt realm = eap_home_realm(sm); 5706c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (!realm) 5716c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return -1; 5726c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 5736c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt erp = eap_erp_get_key(sm, realm); 5746c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt os_free(realm); 5756c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt realm = NULL; 5766c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (!erp) 5776c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return -1; 5786c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 5796c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (erp->next_seq >= 65536) 5806c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return -1; /* SEQ has range of 0..65535 */ 5816c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 5826c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt /* TODO: check rRK lifetime expiration */ 5836c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 5846c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: Valid ERP key found %s (SEQ=%u)", 5856c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt erp->keyname_nai, erp->next_seq); 5866c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 5876c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt msg = eap_msg_alloc(EAP_VENDOR_IETF, EAP_ERP_TYPE_REAUTH, 5886c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 1 + 2 + 2 + os_strlen(erp->keyname_nai) + 1 + 16, 5896c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt EAP_CODE_INITIATE, hdr->identifier); 5906c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (msg == NULL) 5916c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return -1; 5926c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 5936c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpabuf_put_u8(msg, 0x20); /* Flags: R=0 B=0 L=1 */ 5946c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpabuf_put_be16(msg, erp->next_seq); 5956c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 5966c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpabuf_put_u8(msg, EAP_ERP_TLV_KEYNAME_NAI); 5976c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpabuf_put_u8(msg, os_strlen(erp->keyname_nai)); 5986c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpabuf_put_str(msg, erp->keyname_nai); 5996c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 6006c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpabuf_put_u8(msg, EAP_ERP_CS_HMAC_SHA256_128); /* Cryptosuite */ 6016c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 6026c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (hmac_sha256(erp->rIK, erp->rIK_len, 6036c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpabuf_head(msg), wpabuf_len(msg), hash) < 0) { 6046c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpabuf_free(msg); 6056c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return -1; 6066c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 6076c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpabuf_put_data(msg, hash, 16); 6086c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 6096c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: Sending EAP-Initiate/Re-auth"); 6106c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt sm->erp_seq = erp->next_seq; 6116c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt erp->next_seq++; 6126c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpabuf_free(sm->eapRespData); 6136c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt sm->eapRespData = msg; 6146c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt sm->reauthInit = TRUE; 6156c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return 0; 6166c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt} 6176c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt#endif /* CONFIG_ERP */ 6186c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 6196c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 6208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 6218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * The method processing happens here. The request from the authenticator is 6228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * processed, and an appropriate response packet is built. 6238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 6248d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(EAP, METHOD) 6258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *eapReqData; 6278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_method_ret ret; 628d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt int min_len = 1; 6298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY(EAP, METHOD); 6318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->m == NULL) { 6328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_WARNING, "EAP::METHOD - method not selected"); 6338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 6348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapReqData = eapol_get_eapReqData(sm); 637d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (sm->m->vendor == EAP_VENDOR_IETF && sm->m->method == EAP_TYPE_LEAP) 638d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt min_len = 0; /* LEAP uses EAP-Success without payload */ 639d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (!eap_hdr_len_valid(eapReqData, min_len)) 64061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return; 6418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 6438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Get ignore, methodState, decision, allowNotifications, and 6448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eapRespData. RFC 4137 uses three separate method procedure (check, 6458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * process, and buildResp) in this state. These have been combined into 6468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * a single function call to m->process() in order to optimize EAP 6478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * method implementation interface a bit. These procedures are only 6488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * used from within this METHOD state, so there is no need to keep 6498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * these as separate C functions. 6508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 6518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * The RFC 4137 procedures return values as follows: 6528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * ignore = m.check(eapReqData) 6538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * (methodState, decision, allowNotifications) = m.process(eapReqData) 6548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eapRespData = m.buildResp(reqId) 6558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 6568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&ret, 0, sizeof(ret)); 6578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret.ignore = sm->ignore; 6588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret.methodState = sm->methodState; 6598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret.decision = sm->decision; 6608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret.allowNotifications = sm->allowNotifications; 6618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(sm->eapRespData); 6628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eapRespData = NULL; 6638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eapRespData = sm->m->process(sm, sm->eap_method_priv, &ret, 6648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapReqData); 6658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: method process -> ignore=%s " 666fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt "methodState=%s decision=%s eapRespData=%p", 6678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret.ignore ? "TRUE" : "FALSE", 6688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sm_method_state_txt(ret.methodState), 669fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt eap_sm_decision_txt(ret.decision), 670fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt sm->eapRespData); 6718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->ignore = ret.ignore; 6738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->ignore) 6748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 6758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->methodState = ret.methodState; 6768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->decision = ret.decision; 6778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->allowNotifications = ret.allowNotifications; 6788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->m->isKeyAvailable && sm->m->getKey && 6808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->m->isKeyAvailable(sm, sm->eap_method_priv)) { 6816c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt struct eap_peer_config *config = eap_get_config(sm); 6826c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 683c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt eap_sm_free_key(sm); 6848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eapKeyData = sm->m->getKey(sm, sm->eap_method_priv, 6858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &sm->eapKeyDataLen); 686f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt os_free(sm->eapSessionId); 6874b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt sm->eapSessionId = NULL; 6884b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt if (sm->m->getSessionId) { 6894b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt sm->eapSessionId = sm->m->getSessionId( 6904b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt sm, sm->eap_method_priv, 6914b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt &sm->eapSessionIdLen); 692f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "EAP: Session-Id", 693f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt sm->eapSessionId, sm->eapSessionIdLen); 694f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt } 6956c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (config->erp && sm->m->get_emsk && sm->eapSessionId) 6966c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt eap_peer_erp_init(sm); 6978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 7028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This state signals the lower layer that a response packet is ready to be 7038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * sent. 7048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 7058d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(EAP, SEND_RESPONSE) 7068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY(EAP, SEND_RESPONSE); 7088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(sm->lastRespData); 7098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->eapRespData) { 7108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->workaround) 7118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(sm->last_md5, sm->req_md5, 16); 7128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->lastId = sm->reqId; 7138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->lastRespData = wpabuf_dup(sm->eapRespData); 7148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_set_bool(sm, EAPOL_eapResp, TRUE); 715fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt } else { 716fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: No eapRespData available"); 7178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->lastRespData = NULL; 718fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt } 7198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_set_bool(sm, EAPOL_eapReq, FALSE); 7208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_set_int(sm, EAPOL_idleWhile, sm->ClientTimeout); 7216c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt sm->reauthInit = FALSE; 7228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 7268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This state signals the lower layer that the request was discarded, and no 7278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * response packet will be sent at this time. 7288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 7298d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(EAP, DISCARD) 7308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY(EAP, DISCARD); 7328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_set_bool(sm, EAPOL_eapReq, FALSE); 7338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_set_bool(sm, EAPOL_eapNoResp, TRUE); 7348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 7388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Handles requests for Identity method and builds a response. 7398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 7408d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(EAP, IDENTITY) 7418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct wpabuf *eapReqData; 7438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY(EAP, IDENTITY); 7458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapReqData = eapol_get_eapReqData(sm); 74661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (!eap_hdr_len_valid(eapReqData, 1)) 74761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return; 7488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sm_processIdentity(sm, eapReqData); 7498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(sm->eapRespData); 7508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eapRespData = NULL; 7518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eapRespData = eap_sm_buildIdentity(sm, sm->reqId, 0); 7528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 7568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Handles requests for Notification method and builds a response. 7578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 7588d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(EAP, NOTIFICATION) 7598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct wpabuf *eapReqData; 7618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY(EAP, NOTIFICATION); 7638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapReqData = eapol_get_eapReqData(sm); 76461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (!eap_hdr_len_valid(eapReqData, 1)) 76561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return; 7668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sm_processNotify(sm, eapReqData); 7678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(sm->eapRespData); 7688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eapRespData = NULL; 7698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eapRespData = eap_sm_buildNotify(sm->reqId); 7708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 7748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This state retransmits the previous response packet. 7758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 7768d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(EAP, RETRANSMIT) 7778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY(EAP, RETRANSMIT); 7798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(sm->eapRespData); 7808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->lastRespData) 7818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eapRespData = wpabuf_dup(sm->lastRespData); 7828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 7838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eapRespData = NULL; 7848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 7888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This state is entered in case of a successful completion of authentication 7898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * and state machine waits here until port is disabled or EAP authentication is 7908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * restarted. 7918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 7928d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(EAP, SUCCESS) 7938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY(EAP, SUCCESS); 7958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->eapKeyData != NULL) 7968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eapKeyAvailable = TRUE; 7978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_set_bool(sm, EAPOL_eapSuccess, TRUE); 7988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 8008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * RFC 4137 does not clear eapReq here, but this seems to be required 8018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * to avoid processing the same request twice when state machine is 8028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * initialized. 8038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 8048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_set_bool(sm, EAPOL_eapReq, FALSE); 8058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 8078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * RFC 4137 does not set eapNoResp here, but this seems to be required 8088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * to get EAPOL Supplicant backend state machine into SUCCESS state. In 8098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * addition, either eapResp or eapNoResp is required to be set after 8108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * processing the received EAP frame. 8118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 8128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_set_bool(sm, EAPOL_eapNoResp, TRUE); 8138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_SUCCESS 8158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "EAP authentication completed successfully"); 8168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 8208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This state is entered in case of a failure and state machine waits here 8218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * until port is disabled or EAP authentication is restarted. 8228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 8238d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(EAP, FAILURE) 8248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 8258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY(EAP, FAILURE); 8268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_set_bool(sm, EAPOL_eapFail, TRUE); 8278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 8298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * RFC 4137 does not clear eapReq here, but this seems to be required 8308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * to avoid processing the same request twice when state machine is 8318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * initialized. 8328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 8338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_set_bool(sm, EAPOL_eapReq, FALSE); 8348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 8368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * RFC 4137 does not set eapNoResp here. However, either eapResp or 8378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eapNoResp is required to be set after processing the received EAP 8388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * frame. 8398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 8408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_set_bool(sm, EAPOL_eapNoResp, TRUE); 8418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_FAILURE 8438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "EAP authentication failed"); 8448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->prev_failure = 1; 8468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int eap_success_workaround(struct eap_sm *sm, int reqId, int lastId) 8508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 8518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 8528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * At least Microsoft IAS and Meetinghouse Aegis seem to be sending 8538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * EAP-Success/Failure with lastId + 1 even though RFC 3748 and 8548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * RFC 4137 require that reqId == lastId. In addition, it looks like 8558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Ringmaster v2.1.2.0 would be using lastId + 2 in EAP-Success. 8568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 8578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Accept this kind of Id if EAP workarounds are enabled. These are 8588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * unauthenticated plaintext messages, so this should have minimal 8598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * security implications (bit easier to fake EAP-Success/Failure). 8608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 8618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->workaround && (reqId == ((lastId + 1) & 0xff) || 8628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reqId == ((lastId + 2) & 0xff))) { 8638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: Workaround for unexpected " 8648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "identifier field in EAP Success: " 8658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "reqId=%d lastId=%d (these are supposed to be " 8668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "same)", reqId, lastId); 8678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 8688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: EAP-Success Id mismatch - reqId=%d " 8708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "lastId=%d", reqId, lastId); 8718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 8728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 8768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * RFC 4137 - Appendix A.1: EAP Peer State Machine - State transitions 8778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 8788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eap_peer_sm_step_idle(struct eap_sm *sm) 8808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 8818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 8828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * The first three transitions are from RFC 4137. The last two are 8838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * local additions to handle special cases with LEAP and PEAP server 8848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * not sending EAP-Success in some cases. 8858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 8868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eapol_get_bool(sm, EAPOL_eapReq)) 8878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(EAP, RECEIVED); 8888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if ((eapol_get_bool(sm, EAPOL_altAccept) && 8898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->decision != DECISION_FAIL) || 8908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (eapol_get_int(sm, EAPOL_idleWhile) == 0 && 8918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->decision == DECISION_UNCOND_SUCC)) 8928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(EAP, SUCCESS); 8938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (eapol_get_bool(sm, EAPOL_altReject) || 8948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (eapol_get_int(sm, EAPOL_idleWhile) == 0 && 8958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->decision != DECISION_UNCOND_SUCC) || 8968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (eapol_get_bool(sm, EAPOL_altAccept) && 8978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->methodState != METHOD_CONT && 8988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->decision == DECISION_FAIL)) 8998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(EAP, FAILURE); 9008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (sm->selectedMethod == EAP_TYPE_LEAP && 9018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->leap_done && sm->decision != DECISION_FAIL && 9028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->methodState == METHOD_DONE) 9038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(EAP, SUCCESS); 9048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (sm->selectedMethod == EAP_TYPE_PEAP && 9058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->peap_done && sm->decision != DECISION_FAIL && 9068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->methodState == METHOD_DONE) 9078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(EAP, SUCCESS); 9088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int eap_peer_req_is_duplicate(struct eap_sm *sm) 9128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int duplicate; 9148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt duplicate = (sm->reqId == sm->lastId) && sm->rxReq; 9168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->workaround && duplicate && 9178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(sm->req_md5, sm->last_md5, 16) != 0) { 9188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 9198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * RFC 4137 uses (reqId == lastId) as the only verification for 9208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * duplicate EAP requests. However, this misses cases where the 9218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * AS is incorrectly using the same id again; and 9228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * unfortunately, such implementations exist. Use MD5 hash as 9238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * an extra verification for the packets being duplicate to 9248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * workaround these issues. 9258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 9268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: AS used the same Id again, but " 9278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "EAP packets were not identical"); 9288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: workaround - assume this is not a " 9298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "duplicate packet"); 9308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt duplicate = 0; 9318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return duplicate; 9348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 937216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidtstatic int eap_peer_sm_allow_canned(struct eap_sm *sm) 938216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt{ 939216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt struct eap_peer_config *config = eap_get_config(sm); 940216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 941216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt return config && config->phase1 && 942216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt os_strstr(config->phase1, "allow_canned_success=1"); 943216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt} 944216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 945216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 9468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eap_peer_sm_step_received(struct eap_sm *sm) 9478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int duplicate = eap_peer_req_is_duplicate(sm); 9498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 9518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Two special cases below for LEAP are local additions to work around 9528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * odd LEAP behavior (EAP-Success in the middle of authentication and 9538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * then swapped roles). Other transitions are based on RFC 4137. 9548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 9558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->rxSuccess && sm->decision != DECISION_FAIL && 9568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (sm->reqId == sm->lastId || 9578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_success_workaround(sm, sm->reqId, sm->lastId))) 9588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(EAP, SUCCESS); 959216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt else if (sm->workaround && sm->lastId == -1 && sm->rxSuccess && 960216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt !sm->rxFailure && !sm->rxReq && eap_peer_sm_allow_canned(sm)) 961216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt SM_ENTER(EAP, SUCCESS); /* EAP-Success prior any EAP method */ 962216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt else if (sm->workaround && sm->lastId == -1 && sm->rxFailure && 963216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt !sm->rxReq && sm->methodState != METHOD_CONT && 964216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt eap_peer_sm_allow_canned(sm)) 965216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt SM_ENTER(EAP, FAILURE); /* EAP-Failure prior any EAP method */ 966216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt else if (sm->workaround && sm->rxSuccess && !sm->rxFailure && 967216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt !sm->rxReq && sm->methodState != METHOD_CONT && 968216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt eap_peer_sm_allow_canned(sm)) 969216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt SM_ENTER(EAP, SUCCESS); /* EAP-Success after Identity */ 9708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (sm->methodState != METHOD_CONT && 9718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ((sm->rxFailure && 9728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->decision != DECISION_UNCOND_SUCC) || 9738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (sm->rxSuccess && sm->decision == DECISION_FAIL && 9748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (sm->selectedMethod != EAP_TYPE_LEAP || 9758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->methodState != METHOD_MAY_CONT))) && 9768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (sm->reqId == sm->lastId || 9778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_success_workaround(sm, sm->reqId, sm->lastId))) 9788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(EAP, FAILURE); 9798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (sm->rxReq && duplicate) 9808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(EAP, RETRANSMIT); 9818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (sm->rxReq && !duplicate && 9828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->reqMethod == EAP_TYPE_NOTIFICATION && 9838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->allowNotifications) 9848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(EAP, NOTIFICATION); 9858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (sm->rxReq && !duplicate && 9868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->selectedMethod == EAP_TYPE_NONE && 9878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->reqMethod == EAP_TYPE_IDENTITY) 9888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(EAP, IDENTITY); 9898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (sm->rxReq && !duplicate && 9908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->selectedMethod == EAP_TYPE_NONE && 9918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->reqMethod != EAP_TYPE_IDENTITY && 9928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->reqMethod != EAP_TYPE_NOTIFICATION) 9938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(EAP, GET_METHOD); 9948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (sm->rxReq && !duplicate && 9958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->reqMethod == sm->selectedMethod && 9968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->methodState != METHOD_DONE) 9978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(EAP, METHOD); 9988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (sm->selectedMethod == EAP_TYPE_LEAP && 9998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (sm->rxSuccess || sm->rxResp)) 10008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(EAP, METHOD); 10016c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt else if (sm->reauthInit) 10026c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt SM_ENTER(EAP, SEND_RESPONSE); 10038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 10048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(EAP, DISCARD); 10058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eap_peer_sm_step_local(struct eap_sm *sm) 10098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 10108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (sm->EAP_state) { 10118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_INITIALIZE: 10128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(EAP, IDLE); 10138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 10148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_DISABLED: 10158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eapol_get_bool(sm, EAPOL_portEnabled) && 10168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !sm->force_disabled) 10178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(EAP, INITIALIZE); 10188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 10198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_IDLE: 10208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_peer_sm_step_idle(sm); 10218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 10228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_RECEIVED: 10238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_peer_sm_step_received(sm); 10248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 10258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_GET_METHOD: 10268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->selectedMethod == sm->reqMethod) 10278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(EAP, METHOD); 10288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 10298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(EAP, SEND_RESPONSE); 10308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 10318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_METHOD: 1032fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt /* 1033fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt * Note: RFC 4137 uses methodState == DONE && decision == FAIL 1034fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt * as the condition. eapRespData == NULL here is used to allow 1035fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt * final EAP method response to be sent without having to change 1036fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt * all methods to either use methodState MAY_CONT or leaving 1037fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt * decision to something else than FAIL in cases where the only 1038fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt * expected response is EAP-Failure. 1039fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt */ 10408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->ignore) 10418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(EAP, DISCARD); 1042fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt else if (sm->methodState == METHOD_DONE && 1043fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt sm->decision == DECISION_FAIL && !sm->eapRespData) 1044fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt SM_ENTER(EAP, FAILURE); 10458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 10468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(EAP, SEND_RESPONSE); 10478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 10488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_SEND_RESPONSE: 10498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(EAP, IDLE); 10508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 10518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_DISCARD: 10528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(EAP, IDLE); 10538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 10548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_IDENTITY: 10558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(EAP, SEND_RESPONSE); 10568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 10578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_NOTIFICATION: 10588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(EAP, SEND_RESPONSE); 10598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 10608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_RETRANSMIT: 10618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(EAP, SEND_RESPONSE); 10628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 10638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_SUCCESS: 10648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 10658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_FAILURE: 10668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 10678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10718d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STEP(EAP) 10728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 10738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Global transitions */ 10748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eapol_get_bool(sm, EAPOL_eapRestart) && 10758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_get_bool(sm, EAPOL_portEnabled)) 10768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER_GLOBAL(EAP, INITIALIZE); 10778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (!eapol_get_bool(sm, EAPOL_portEnabled) || sm->force_disabled) 10788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER_GLOBAL(EAP, DISABLED); 10798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (sm->num_rounds > EAP_MAX_AUTH_ROUNDS) { 10808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* RFC 4137 does not place any limit on number of EAP messages 10818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * in an authentication session. However, some error cases have 10828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * ended up in a state were EAP messages were sent between the 10838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * peer and server in a loop (e.g., TLS ACK frame in both 10848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * direction). Since this is quite undesired outcome, limit the 10858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * total number of EAP round-trips and abort authentication if 10868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * this limit is exceeded. 10878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 10888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->num_rounds == EAP_MAX_AUTH_ROUNDS + 1) { 10898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(sm->msg_ctx, MSG_INFO, "EAP: more than %d " 10908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "authentication rounds - abort", 10918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EAP_MAX_AUTH_ROUNDS); 10928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->num_rounds++; 10938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER_GLOBAL(EAP, FAILURE); 10948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 10968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Local transitions */ 10978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_peer_sm_step_local(sm); 10988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 11008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic Boolean eap_sm_allowMethod(struct eap_sm *sm, int vendor, 11038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EapType method) 11048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 11058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!eap_allowed_method(sm, vendor, method)) { 11068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: configuration does not allow: " 11078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "vendor %u method %u", vendor, method); 11088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return FALSE; 11098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eap_peer_get_eap_method(vendor, method)) 11118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return TRUE; 11128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: not included in build: " 11138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "vendor %u method %u", vendor, method); 11148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return FALSE; 11158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 11168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpabuf * eap_sm_build_expanded_nak( 11198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sm *sm, int id, const struct eap_method *methods, 11208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t count) 11218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 11228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *resp; 11238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int found = 0; 11248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct eap_method *m; 11258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: Building expanded EAP-Nak"); 11278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* RFC 3748 - 5.3.2: Expanded Nak */ 11298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_EXPANDED, 11308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8 + 8 * (count + 1), EAP_CODE_RESPONSE, id); 11318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (resp == NULL) 11328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 11338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_be24(resp, EAP_VENDOR_IETF); 11358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_be32(resp, EAP_TYPE_NAK); 11368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (m = methods; m; m = m->next) { 11388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->reqVendor == m->vendor && 11398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->reqVendorMethod == m->method) 11408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; /* do not allow the current method again */ 11418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eap_allowed_method(sm, m->vendor, m->method)) { 11428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: allowed type: " 11438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "vendor=%u method=%u", 11448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt m->vendor, m->method); 11458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(resp, EAP_TYPE_EXPANDED); 11468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_be24(resp, m->vendor); 11478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_be32(resp, m->method); 11488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt found++; 11508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!found) { 11538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: no more allowed methods"); 11548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(resp, EAP_TYPE_EXPANDED); 11558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_be24(resp, EAP_VENDOR_IETF); 11568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_be32(resp, EAP_TYPE_NONE); 11578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_update_len(resp); 11608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return resp; 11628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 11638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpabuf * eap_sm_buildNak(struct eap_sm *sm, int id) 11668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 11678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *resp; 11688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *start; 11698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int found = 0, expanded_found = 0; 11708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t count; 11718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct eap_method *methods, *m; 11728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: Building EAP-Nak (requested type %u " 11748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "vendor=%u method=%u not allowed)", sm->reqMethod, 11758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->reqVendor, sm->reqVendorMethod); 11768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt methods = eap_peer_get_methods(&count); 11778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (methods == NULL) 11788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 11798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->reqMethod == EAP_TYPE_EXPANDED) 11808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return eap_sm_build_expanded_nak(sm, id, methods, count); 11818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* RFC 3748 - 5.3.1: Legacy Nak */ 11838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_NAK, 11848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(struct eap_hdr) + 1 + count + 1, 11858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EAP_CODE_RESPONSE, id); 11868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (resp == NULL) 11878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 11888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt start = wpabuf_put(resp, 0); 11908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (m = methods; m; m = m->next) { 11918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (m->vendor == EAP_VENDOR_IETF && m->method == sm->reqMethod) 11928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; /* do not allow the current method again */ 11938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eap_allowed_method(sm, m->vendor, m->method)) { 11948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (m->vendor != EAP_VENDOR_IETF) { 11958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (expanded_found) 11968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 11978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt expanded_found = 1; 11988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(resp, EAP_TYPE_EXPANDED); 11998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 12008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(resp, m->method); 12018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt found++; 12028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!found) 12058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(resp, EAP_TYPE_NONE); 12068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "EAP: allowed methods", start, found); 12078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_update_len(resp); 12098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return resp; 12118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 12128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eap_sm_processIdentity(struct eap_sm *sm, const struct wpabuf *req) 12158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 121661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt const u8 *pos; 121761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt size_t msg_len; 12188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_STARTED 12208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "EAP authentication started"); 1221a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt eap_notify_status(sm, "started", ""); 12228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 122361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_IDENTITY, req, 122461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt &msg_len); 122561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (pos == NULL) 122661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return; 122761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 12288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 12298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * RFC 3748 - 5.1: Identity 12308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Data field may contain a displayable message in UTF-8. If this 12318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * includes NUL-character, only the data before that should be 12328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * displayed. Some EAP implementasitons may piggy-back additional 12338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * options after the NUL. 12348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 12358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: could save displayable message so that it can be shown to the 12368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * user in case of interaction is required */ 12378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_ascii(MSG_DEBUG, "EAP: EAP-Request Identity data", 123861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt pos, msg_len); 12398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 12408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef PCSC_FUNCS 1243c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 1244c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt/* 1245c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * Rules for figuring out MNC length based on IMSI for SIM cards that do not 1246c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * include MNC length field. 1247c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt */ 1248c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidtstatic int mnc_len_from_imsi(const char *imsi) 1249c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt{ 1250c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt char mcc_str[4]; 1251c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt unsigned int mcc; 1252c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 1253c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt os_memcpy(mcc_str, imsi, 3); 1254c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt mcc_str[3] = '\0'; 1255c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt mcc = atoi(mcc_str); 1256c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 1257391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (mcc == 228) 1258391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt return 2; /* Networks in Switzerland use 2-digit MNC */ 1259c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (mcc == 244) 1260c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt return 2; /* Networks in Finland use 2-digit MNC */ 1261c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 1262c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt return -1; 1263c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt} 1264c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 1265c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 1266c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidtstatic int eap_sm_append_3gpp_realm(struct eap_sm *sm, char *imsi, 1267c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt size_t max_len, size_t *imsi_len) 1268c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt{ 1269c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt int mnc_len; 1270c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt char *pos, mnc[4]; 1271c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 1272c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (*imsi_len + 36 > max_len) { 1273c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpa_printf(MSG_WARNING, "No room for realm in IMSI buffer"); 1274c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt return -1; 1275c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt } 1276c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 1277c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt /* MNC (2 or 3 digits) */ 1278c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt mnc_len = scard_get_mnc_len(sm->scard_ctx); 1279c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (mnc_len < 0) 1280c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt mnc_len = mnc_len_from_imsi(imsi); 1281c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (mnc_len < 0) { 1282c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpa_printf(MSG_INFO, "Failed to get MNC length from (U)SIM " 1283c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt "assuming 3"); 1284c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt mnc_len = 3; 1285c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt } 1286c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 1287c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (mnc_len == 2) { 1288c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt mnc[0] = '0'; 1289c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt mnc[1] = imsi[3]; 1290c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt mnc[2] = imsi[4]; 1291c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt } else if (mnc_len == 3) { 1292c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt mnc[0] = imsi[3]; 1293c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt mnc[1] = imsi[4]; 1294c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt mnc[2] = imsi[5]; 1295c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt } 1296c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt mnc[3] = '\0'; 1297c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 1298c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt pos = imsi + *imsi_len; 1299c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt pos += os_snprintf(pos, imsi + max_len - pos, 1300c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt "@wlan.mnc%s.mcc%c%c%c.3gppnetwork.org", 1301c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt mnc, imsi[0], imsi[1], imsi[2]); 1302c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt *imsi_len = pos - imsi; 1303c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 1304c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt return 0; 1305c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt} 1306c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 1307c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 13088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int eap_sm_imsi_identity(struct eap_sm *sm, 13098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_peer_config *conf) 13108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 131104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt enum { EAP_SM_SIM, EAP_SM_AKA, EAP_SM_AKA_PRIME } method = EAP_SM_SIM; 13128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char imsi[100]; 13138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t imsi_len; 13148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_method_type *m = conf->eap_methods; 13158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 13168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt imsi_len = sizeof(imsi); 13188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (scard_get_imsi(sm->scard_ctx, imsi, &imsi_len)) { 13198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_WARNING, "Failed to get IMSI from SIM"); 13208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 13218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_ascii(MSG_DEBUG, "IMSI", (u8 *) imsi, imsi_len); 13248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1325c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (imsi_len < 7) { 1326c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpa_printf(MSG_WARNING, "Too short IMSI for SIM identity"); 1327c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt return -1; 1328c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt } 1329c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 1330c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (eap_sm_append_3gpp_realm(sm, imsi, sizeof(imsi), &imsi_len) < 0) { 1331c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpa_printf(MSG_WARNING, "Could not add realm to SIM identity"); 1332c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt return -1; 1333c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt } 1334c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpa_hexdump_ascii(MSG_DEBUG, "IMSI + realm", (u8 *) imsi, imsi_len); 1335c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 13368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; m && (m[i].vendor != EAP_VENDOR_IETF || 13378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt m[i].method != EAP_TYPE_NONE); i++) { 13388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (m[i].vendor == EAP_VENDOR_IETF && 133904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt m[i].method == EAP_TYPE_AKA_PRIME) { 134004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt method = EAP_SM_AKA_PRIME; 134104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt break; 134204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 134304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 134404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (m[i].vendor == EAP_VENDOR_IETF && 13458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt m[i].method == EAP_TYPE_AKA) { 134604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt method = EAP_SM_AKA; 13478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 13488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(conf->identity); 13528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf->identity = os_malloc(1 + imsi_len); 13538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conf->identity == NULL) { 13548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_WARNING, "Failed to allocate buffer for " 13558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "IMSI-based identity"); 13568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 13578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 135904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt switch (method) { 136004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt case EAP_SM_SIM: 136104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt conf->identity[0] = '1'; 136204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt break; 136304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt case EAP_SM_AKA: 136404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt conf->identity[0] = '0'; 136504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt break; 136604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt case EAP_SM_AKA_PRIME: 136704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt conf->identity[0] = '6'; 136804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt break; 136904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 13708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(conf->identity + 1, imsi, imsi_len); 13718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf->identity_len = 1 + imsi_len; 13728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 13748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1375c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 13768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* PCSC_FUNCS */ 13778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int eap_sm_set_scard_pin(struct eap_sm *sm, 13808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_peer_config *conf) 13818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 13828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef PCSC_FUNCS 13838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (scard_set_pin(sm->scard_ctx, conf->pin)) { 13848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 13858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Make sure the same PIN is not tried again in order to avoid 13868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * blocking SIM. 13878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 13888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(conf->pin); 13898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf->pin = NULL; 13908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_WARNING, "PIN validation failed"); 13928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sm_request_pin(sm); 13938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 13948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 13968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* PCSC_FUNCS */ 13978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 13988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* PCSC_FUNCS */ 13998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 14008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int eap_sm_get_scard_identity(struct eap_sm *sm, 14028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_peer_config *conf) 14038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 14048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef PCSC_FUNCS 14058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eap_sm_set_scard_pin(sm, conf)) 14068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 14078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return eap_sm_imsi_identity(sm, conf); 14098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* PCSC_FUNCS */ 14108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 14118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* PCSC_FUNCS */ 14128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 14138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 14168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_sm_buildIdentity - Build EAP-Identity/Response for the current network 14178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 14188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @id: EAP identifier for the packet 14198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @encrypted: Whether the packet is for encrypted tunnel (EAP phase 2) 14208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Pointer to the allocated EAP-Identity/Response packet or %NULL on 14218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * failure 14228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 14238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function allocates and builds an EAP-Identity/Response packet for the 14248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * current network. The caller is responsible for freeing the returned data. 14258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 14268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct wpabuf * eap_sm_buildIdentity(struct eap_sm *sm, int id, int encrypted) 14278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 14288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_peer_config *config = eap_get_config(sm); 14298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *resp; 14308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *identity; 14318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t identity_len; 14328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (config == NULL) { 14348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_WARNING, "EAP: buildIdentity: configuration " 14358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "was not available"); 14368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 14378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->m && sm->m->get_identity && 14408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (identity = sm->m->get_identity(sm, sm->eap_method_priv, 14418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &identity_len)) != NULL) { 14428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_ascii(MSG_DEBUG, "EAP: using method re-auth " 14438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "identity", identity, identity_len); 14448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (!encrypted && config->anonymous_identity) { 14458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt identity = config->anonymous_identity; 14468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt identity_len = config->anonymous_identity_len; 14478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_ascii(MSG_DEBUG, "EAP: using anonymous identity", 14488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt identity, identity_len); 14498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 14508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt identity = config->identity; 14518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt identity_len = config->identity_len; 14528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_ascii(MSG_DEBUG, "EAP: using real identity", 14538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt identity, identity_len); 14548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (identity == NULL) { 14578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_WARNING, "EAP: buildIdentity: identity " 14588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "configuration was not available"); 14598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (config->pcsc) { 14608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eap_sm_get_scard_identity(sm, config) < 0) 14618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 14628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt identity = config->identity; 14638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt identity_len = config->identity_len; 14648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_ascii(MSG_DEBUG, "permanent identity from " 14658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "IMSI", identity, identity_len); 14668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 14678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sm_request_identity(sm); 14688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 14698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (config->pcsc) { 14718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eap_sm_set_scard_pin(sm, config) < 0) 14728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 14738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_IDENTITY, identity_len, 14768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EAP_CODE_RESPONSE, id); 14778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (resp == NULL) 14788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 14798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_data(resp, identity, identity_len); 14818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return resp; 14838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 14848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eap_sm_processNotify(struct eap_sm *sm, const struct wpabuf *req) 14878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 14888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *pos; 14898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *msg; 14908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t i, msg_len; 14918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_NOTIFICATION, req, 14938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &msg_len); 14948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos == NULL) 14958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 14968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_ascii(MSG_DEBUG, "EAP: EAP-Request Notification data", 14978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos, msg_len); 14988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg = os_malloc(msg_len + 1); 15008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg == NULL) 15018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 15028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < msg_len; i++) 15038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg[i] = isprint(pos[i]) ? (char) pos[i] : '_'; 15048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg[msg_len] = '\0'; 15058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(sm->msg_ctx, MSG_INFO, "%s%s", 15068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_EVENT_EAP_NOTIFICATION, msg); 15078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(msg); 15088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 15098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpabuf * eap_sm_buildNotify(int id) 15128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 15138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *resp; 15148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: Generating EAP-Response Notification"); 15168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_NOTIFICATION, 0, 15178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EAP_CODE_RESPONSE, id); 15188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (resp == NULL) 15198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 15208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return resp; 15228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 15238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15256c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidtstatic void eap_peer_initiate(struct eap_sm *sm, const struct eap_hdr *hdr, 15266c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt size_t len) 15276c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt{ 15286c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt#ifdef CONFIG_ERP 15296c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt const u8 *pos = (const u8 *) (hdr + 1); 15306c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt const u8 *end = ((const u8 *) hdr) + len; 15316c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt struct erp_tlvs parse; 15326c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 15336c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (len < sizeof(*hdr) + 1) { 15346c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: Ignored too short EAP-Initiate"); 15356c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return; 15366c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 15376c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 15386c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (*pos != EAP_ERP_TYPE_REAUTH_START) { 15396c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_printf(MSG_DEBUG, 15406c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt "EAP: Ignored unexpected EAP-Initiate Type=%u", 15416c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt *pos); 15426c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return; 15436c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 15446c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 15456c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt pos++; 15466c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (pos >= end) { 15476c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_printf(MSG_DEBUG, 15486c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt "EAP: Too short EAP-Initiate/Re-auth-Start"); 15496c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return; 15506c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 15516c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt pos++; /* Reserved */ 15526c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_hexdump(MSG_DEBUG, "EAP: EAP-Initiate/Re-auth-Start TVs/TLVs", 15536c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt pos, end - pos); 15546c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 15556c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (erp_parse_tlvs(pos, end, &parse, 0) < 0) 15566c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt goto invalid; 15576c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 15586c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (parse.domain) { 15596c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_hexdump_ascii(MSG_DEBUG, 15606c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt "EAP: EAP-Initiate/Re-auth-Start - Domain name", 15616c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt parse.domain, parse.domain_len); 15626c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt /* TODO: Derivation of domain specific keys for local ER */ 15636c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 15646c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 15656c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (eap_peer_erp_reauth_start(sm, hdr, len) == 0) 15666c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return; 15676c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 15686c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidtinvalid: 15696c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt#endif /* CONFIG_ERP */ 15706c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_printf(MSG_DEBUG, 15716c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt "EAP: EAP-Initiate/Re-auth-Start - No suitable ERP keys available - try to start full EAP authentication"); 15726c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt eapol_set_bool(sm, EAPOL_eapTriggerStart, TRUE); 15736c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt} 15746c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 15756c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 15766c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidtstatic void eap_peer_finish(struct eap_sm *sm, const struct eap_hdr *hdr, 15776c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt size_t len) 15786c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt{ 15796c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt#ifdef CONFIG_ERP 15806c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt const u8 *pos = (const u8 *) (hdr + 1); 15816c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt const u8 *end = ((const u8 *) hdr) + len; 15826c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt const u8 *start; 15836c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt struct erp_tlvs parse; 15846c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt u8 flags; 15856c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt u16 seq; 15866c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt u8 hash[SHA256_MAC_LEN]; 15876c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt size_t hash_len; 15886c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt struct eap_erp_key *erp; 15896c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt int max_len; 15906c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt char nai[254]; 15916c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt u8 seed[4]; 15926c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt int auth_tag_ok = 0; 15936c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 15946c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (len < sizeof(*hdr) + 1) { 15956c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: Ignored too short EAP-Finish"); 15966c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return; 15976c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 15986c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 15996c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (*pos != EAP_ERP_TYPE_REAUTH) { 16006c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_printf(MSG_DEBUG, 16016c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt "EAP: Ignored unexpected EAP-Finish Type=%u", *pos); 16026c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return; 16036c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 16046c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 16056c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (len < sizeof(*hdr) + 4) { 16066c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_printf(MSG_DEBUG, 16076c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt "EAP: Ignored too short EAP-Finish/Re-auth"); 16086c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return; 16096c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 16106c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 16116c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt pos++; 16126c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt flags = *pos++; 16136c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt seq = WPA_GET_BE16(pos); 16146c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt pos += 2; 16156c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: Flags=0x%x SEQ=%u", flags, seq); 16166c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 16176c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (seq != sm->erp_seq) { 16186c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_printf(MSG_DEBUG, 16196c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt "EAP: Unexpected EAP-Finish/Re-auth SEQ=%u", seq); 16206c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return; 16216c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 16226c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 16236c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt /* 16246c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * Parse TVs/TLVs. Since we do not yet know the length of the 16256c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * Authentication Tag, stop parsing if an unknown TV/TLV is seen and 16266c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * just try to find the keyName-NAI first so that we can check the 16276c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * Authentication Tag. 16286c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt */ 16296c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (erp_parse_tlvs(pos, end, &parse, 1) < 0) 16306c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return; 16316c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 16326c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (!parse.keyname) { 16336c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_printf(MSG_DEBUG, 16346c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt "EAP: No keyName-NAI in EAP-Finish/Re-auth Packet"); 16356c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return; 16366c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 16376c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 16386c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_hexdump_ascii(MSG_DEBUG, "EAP: EAP-Finish/Re-auth - keyName-NAI", 16396c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt parse.keyname, parse.keyname_len); 16406c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (parse.keyname_len > 253) { 16416c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_printf(MSG_DEBUG, 16426c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt "EAP: Too long keyName-NAI in EAP-Finish/Re-auth"); 16436c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return; 16446c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 16456c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt os_memcpy(nai, parse.keyname, parse.keyname_len); 16466c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt nai[parse.keyname_len] = '\0'; 16476c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 16486c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt erp = eap_erp_get_key_nai(sm, nai); 16496c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (!erp) { 16506c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: No matching ERP key found for %s", 16516c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt nai); 16526c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return; 16536c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 16546c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 16556c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt /* Is there enough room for Cryptosuite and Authentication Tag? */ 16566c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt start = parse.keyname + parse.keyname_len; 16576c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt max_len = end - start; 16586c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt hash_len = 16; 16596c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (max_len < 1 + (int) hash_len) { 16606c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_printf(MSG_DEBUG, 16616c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt "EAP: Not enough room for Authentication Tag"); 16626c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (flags & 0x80) 16636c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt goto no_auth_tag; 16646c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return; 16656c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 16666c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (end[-17] != EAP_ERP_CS_HMAC_SHA256_128) { 16676c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: Different Cryptosuite used"); 16686c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (flags & 0x80) 16696c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt goto no_auth_tag; 16706c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return; 16716c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 16726c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 16736c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (hmac_sha256(erp->rIK, erp->rIK_len, (const u8 *) hdr, 16746c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt end - ((const u8 *) hdr) - hash_len, hash) < 0) 16756c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return; 16766c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (os_memcmp(end - hash_len, hash, hash_len) != 0) { 16776c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_printf(MSG_DEBUG, 16786c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt "EAP: Authentication Tag mismatch"); 16796c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return; 16806c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 16816c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt auth_tag_ok = 1; 16826c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt end -= 1 + hash_len; 16836c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 16846c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidtno_auth_tag: 16856c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt /* 16866c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * Parse TVs/TLVs again now that we know the exact part of the buffer 16876c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * that contains them. 16886c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt */ 16896c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_hexdump(MSG_DEBUG, "EAP: EAP-Finish/Re-Auth TVs/TLVs", 16906c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt pos, end - pos); 16916c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (erp_parse_tlvs(pos, end, &parse, 0) < 0) 16926c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return; 16936c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 16946c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (flags & 0x80 || !auth_tag_ok) { 16956c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_printf(MSG_DEBUG, 16966c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt "EAP: EAP-Finish/Re-auth indicated failure"); 16976c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt eapol_set_bool(sm, EAPOL_eapFail, TRUE); 16986c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt eapol_set_bool(sm, EAPOL_eapReq, FALSE); 16996c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt eapol_set_bool(sm, EAPOL_eapNoResp, TRUE); 17006c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_FAILURE 17016c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt "EAP authentication failed"); 17026c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt sm->prev_failure = 1; 17036c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_printf(MSG_DEBUG, 17046c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt "EAP: Drop ERP key to try full authentication on next attempt"); 17056c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt eap_peer_erp_free_key(erp); 17066c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return; 17076c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 17086c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 17096c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt eap_sm_free_key(sm); 17106c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt sm->eapKeyDataLen = 0; 17116c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt sm->eapKeyData = os_malloc(erp->rRK_len); 17126c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (!sm->eapKeyData) 17136c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return; 17146c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt sm->eapKeyDataLen = erp->rRK_len; 17156c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 17166c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt WPA_PUT_BE16(seed, seq); 17176c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt WPA_PUT_BE16(&seed[2], erp->rRK_len); 17186c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (hmac_sha256_kdf(erp->rRK, erp->rRK_len, 17196c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt "Re-authentication Master Session Key@ietf.org", 17206c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt seed, sizeof(seed), 17216c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt sm->eapKeyData, erp->rRK_len) < 0) { 17226c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: Could not derive rMSK for ERP"); 17236c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt eap_sm_free_key(sm); 17246c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return; 17256c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 17266c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_hexdump_key(MSG_DEBUG, "EAP: ERP rMSK", 17276c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt sm->eapKeyData, sm->eapKeyDataLen); 17286c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt sm->eapKeyAvailable = TRUE; 17296c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt eapol_set_bool(sm, EAPOL_eapSuccess, TRUE); 17306c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt eapol_set_bool(sm, EAPOL_eapReq, FALSE); 17316c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt eapol_set_bool(sm, EAPOL_eapNoResp, TRUE); 17326c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_SUCCESS 17336c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt "EAP re-authentication completed successfully"); 17346c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt#endif /* CONFIG_ERP */ 17356c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt} 17366c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 17376c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 17388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eap_sm_parseEapReq(struct eap_sm *sm, const struct wpabuf *req) 17398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 17408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct eap_hdr *hdr; 17418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t plen; 17428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *pos; 17438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->rxReq = sm->rxResp = sm->rxSuccess = sm->rxFailure = FALSE; 17458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->reqId = 0; 17468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->reqMethod = EAP_TYPE_NONE; 17478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->reqVendor = EAP_VENDOR_IETF; 17488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->reqVendorMethod = EAP_TYPE_NONE; 17498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (req == NULL || wpabuf_len(req) < sizeof(*hdr)) 17518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 17528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hdr = wpabuf_head(req); 17548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt plen = be_to_host16(hdr->length); 17558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (plen > wpabuf_len(req)) { 17568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: Ignored truncated EAP-Packet " 17578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(len=%lu plen=%lu)", 17588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) wpabuf_len(req), 17598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) plen); 17608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 17618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->reqId = hdr->identifier; 17648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->workaround) { 17668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *addr[1]; 17678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt addr[0] = wpabuf_head(req); 17688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt md5_vector(1, addr, &plen, sm->req_md5); 17698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (hdr->code) { 17728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_CODE_REQUEST: 17738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (plen < sizeof(*hdr) + 1) { 17748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: Too short EAP-Request - " 17758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "no Type field"); 17768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 17778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->rxReq = TRUE; 17798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = (const u8 *) (hdr + 1); 17808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->reqMethod = *pos++; 17818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->reqMethod == EAP_TYPE_EXPANDED) { 17828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (plen < sizeof(*hdr) + 8) { 17838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: Ignored truncated " 17848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "expanded EAP-Packet (plen=%lu)", 17858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) plen); 17868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 17878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->reqVendor = WPA_GET_BE24(pos); 17898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 3; 17908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->reqVendorMethod = WPA_GET_BE32(pos); 17918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: Received EAP-Request id=%d " 17938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "method=%u vendor=%u vendorMethod=%u", 17948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->reqId, sm->reqMethod, sm->reqVendor, 17958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->reqVendorMethod); 17968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 17978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_CODE_RESPONSE: 17988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->selectedMethod == EAP_TYPE_LEAP) { 17998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 18008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * LEAP differs from RFC 4137 by using reversed roles 18018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * for mutual authentication and because of this, we 18028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * need to accept EAP-Response frames if LEAP is used. 18038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 18048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (plen < sizeof(*hdr) + 1) { 18058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: Too short " 18068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "EAP-Response - no Type field"); 18078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 18088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->rxResp = TRUE; 18108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = (const u8 *) (hdr + 1); 18118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->reqMethod = *pos; 18128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: Received EAP-Response for " 18138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "LEAP method=%d id=%d", 18148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->reqMethod, sm->reqId); 18158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 18168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: Ignored EAP-Response"); 18188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 18198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_CODE_SUCCESS: 18208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: Received EAP-Success"); 182104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt eap_notify_status(sm, "completion", "success"); 18228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->rxSuccess = TRUE; 18238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 18248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_CODE_FAILURE: 18258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: Received EAP-Failure"); 182604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt eap_notify_status(sm, "completion", "failure"); 18278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->rxFailure = TRUE; 18288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 18296c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt case EAP_CODE_INITIATE: 18306c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt eap_peer_initiate(sm, hdr, plen); 18316c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt break; 18326c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt case EAP_CODE_FINISH: 18336c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt eap_peer_finish(sm, hdr, plen); 18346c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt break; 18358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 18368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: Ignored EAP-Packet with unknown " 18378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "code %d", hdr->code); 18388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 18398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 18418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eap_peer_sm_tls_event(void *ctx, enum tls_event ev, 18448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt union tls_event_data *data) 18458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 18468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sm *sm = ctx; 18478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *hash_hex = NULL; 18488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (ev) { 185004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt case TLS_CERT_CHAIN_SUCCESS: 185104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt eap_notify_status(sm, "remote certificate verification", 185204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt "success"); 185304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt break; 18548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case TLS_CERT_CHAIN_FAILURE: 18558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_TLS_CERT_ERROR 18568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "reason=%d depth=%d subject='%s' err='%s'", 18578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->cert_fail.reason, 18588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->cert_fail.depth, 18598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->cert_fail.subject, 18608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->cert_fail.reason_txt); 186104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt eap_notify_status(sm, "remote certificate verification", 186204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt data->cert_fail.reason_txt); 18638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 18648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case TLS_PEER_CERTIFICATE: 1865c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt if (!sm->eapol_cb->notify_cert) 1866c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt break; 1867c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt 18688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->peer_cert.hash) { 18698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len = data->peer_cert.hash_len * 2 + 1; 18708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hash_hex = os_malloc(len); 18718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hash_hex) { 18728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_snprintf_hex(hash_hex, len, 18738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->peer_cert.hash, 18748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->peer_cert.hash_len); 18758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1877c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt 1878c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt sm->eapol_cb->notify_cert(sm->eapol_ctx, 1879c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt data->peer_cert.depth, 1880c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt data->peer_cert.subject, 18812f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt data->peer_cert.altsubject, 18822f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt data->peer_cert.num_altsubject, 1883c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt hash_hex, data->peer_cert.cert); 18848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 188504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt case TLS_ALERT: 188604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (data->alert.is_local) 188704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt eap_notify_status(sm, "local TLS alert", 188804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt data->alert.description); 188904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt else 189004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt eap_notify_status(sm, "remote TLS alert", 189104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt data->alert.description); 189204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt break; 18938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(hash_hex); 18968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 18978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 19008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_peer_sm_init - Allocate and initialize EAP peer state machine 19018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @eapol_ctx: Context data to be used with eapol_cb calls 19028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @eapol_cb: Pointer to EAPOL callback functions 19038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @msg_ctx: Context data for wpa_msg() calls 19048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @conf: EAP configuration 19058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Pointer to the allocated EAP state machine or %NULL on failure 19068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 19078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function allocates and initializes an EAP state machine. In addition, 19088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * this initializes TLS library for the new EAP state machine. eapol_cb pointer 19098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * will be in use until eap_peer_sm_deinit() is used to deinitialize this EAP 19108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * state machine. Consequently, the caller must make sure that this data 19118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * structure remains alive while the EAP state machine is active. 19128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 19138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct eap_sm * eap_peer_sm_init(void *eapol_ctx, 19141d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt const struct eapol_callbacks *eapol_cb, 19158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void *msg_ctx, struct eap_config *conf) 19168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 19178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sm *sm; 19188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tls_config tlsconf; 19198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm = os_zalloc(sizeof(*sm)); 19218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 19228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 19238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eapol_ctx = eapol_ctx; 19248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eapol_cb = eapol_cb; 19258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->msg_ctx = msg_ctx; 19268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->ClientTimeout = EAP_CLIENT_TIMEOUT_DEFAULT; 19278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->wps = conf->wps; 19286c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt dl_list_init(&sm->erp_keys); 19298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&tlsconf, 0, sizeof(tlsconf)); 19318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsconf.opensc_engine_path = conf->opensc_engine_path; 19328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsconf.pkcs11_engine_path = conf->pkcs11_engine_path; 19338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsconf.pkcs11_module_path = conf->pkcs11_module_path; 19346c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt tlsconf.openssl_ciphers = conf->openssl_ciphers; 19358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_FIPS 19368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsconf.fips_mode = 1; 19378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_FIPS */ 19388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsconf.event_cb = eap_peer_sm_tls_event; 19398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsconf.cb_ctx = sm; 19401f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt tlsconf.cert_in_cb = conf->cert_in_cb; 19418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->ssl_ctx = tls_init(&tlsconf); 19428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->ssl_ctx == NULL) { 19438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_WARNING, "SSL: Failed to initialize TLS " 19448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "context."); 19458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(sm); 19468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 19478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 194904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt sm->ssl_ctx2 = tls_init(&tlsconf); 195004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (sm->ssl_ctx2 == NULL) { 195104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_INFO, "SSL: Failed to initialize TLS " 195204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt "context (2)."); 195304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt /* Run without separate TLS context within TLS tunnel */ 195404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 195504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 19568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return sm; 19578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 19588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 19618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_peer_sm_deinit - Deinitialize and free an EAP peer state machine 19628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 19638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 19648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function deinitializes EAP state machine and frees all allocated 19658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * resources. 19668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 19678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eap_peer_sm_deinit(struct eap_sm *sm) 19688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 19698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 19708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 19718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_deinit_prev_method(sm, "EAP deinit"); 19728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sm_abort(sm); 197304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (sm->ssl_ctx2) 197404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt tls_deinit(sm->ssl_ctx2); 19758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_deinit(sm->ssl_ctx); 19766c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt eap_peer_erp_free_keys(sm); 19778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(sm); 19788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 19798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 19828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_peer_sm_step - Step EAP peer state machine 19838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 19848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 1 if EAP state was changed or 0 if not 19858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 19868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function advances EAP state machine to a new state to match with the 19878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * current variables. This should be called whenever variables used by the EAP 19888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * state machine have changed. 19898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 19908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint eap_peer_sm_step(struct eap_sm *sm) 19918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 19928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res = 0; 19938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt do { 19948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->changed = FALSE; 19958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_STEP_RUN(EAP); 19968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->changed) 19978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = 1; 19988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } while (sm->changed); 19998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return res; 20008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 20018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 20048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_sm_abort - Abort EAP authentication 20058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 20068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 20078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Release system resources that have been allocated for the authentication 20088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * session without fully deinitializing the EAP state machine. 20098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 20108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eap_sm_abort(struct eap_sm *sm) 20118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 20128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(sm->lastRespData); 20138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->lastRespData = NULL; 20148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(sm->eapRespData); 20158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eapRespData = NULL; 2016c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt eap_sm_free_key(sm); 2017f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt os_free(sm->eapSessionId); 2018f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt sm->eapSessionId = NULL; 20198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* This is not clearly specified in the EAP statemachines draft, but 20218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * it seems necessary to make sure that some of the EAPOL variables get 20228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * cleared for the next authentication. */ 20238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_set_bool(sm, EAPOL_eapSuccess, FALSE); 20248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 20258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_CTRL_IFACE 20288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic const char * eap_sm_state_txt(int state) 20298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 20308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (state) { 20318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_INITIALIZE: 20328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "INITIALIZE"; 20338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_DISABLED: 20348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "DISABLED"; 20358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_IDLE: 20368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "IDLE"; 20378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_RECEIVED: 20388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "RECEIVED"; 20398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_GET_METHOD: 20408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "GET_METHOD"; 20418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_METHOD: 20428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "METHOD"; 20438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_SEND_RESPONSE: 20448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "SEND_RESPONSE"; 20458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_DISCARD: 20468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "DISCARD"; 20478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_IDENTITY: 20488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "IDENTITY"; 20498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_NOTIFICATION: 20508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "NOTIFICATION"; 20518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_RETRANSMIT: 20528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "RETRANSMIT"; 20538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_SUCCESS: 20548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "SUCCESS"; 20558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_FAILURE: 20568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "FAILURE"; 20578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 20588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "UNKNOWN"; 20598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 20618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_CTRL_IFACE */ 20628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#if defined(CONFIG_CTRL_IFACE) || !defined(CONFIG_NO_STDOUT_DEBUG) 20658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic const char * eap_sm_method_state_txt(EapMethodState state) 20668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 20678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (state) { 20688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case METHOD_NONE: 20698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "NONE"; 20708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case METHOD_INIT: 20718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "INIT"; 20728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case METHOD_CONT: 20738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "CONT"; 20748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case METHOD_MAY_CONT: 20758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "MAY_CONT"; 20768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case METHOD_DONE: 20778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "DONE"; 20788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 20798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "UNKNOWN"; 20808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 20828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic const char * eap_sm_decision_txt(EapDecision decision) 20858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 20868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (decision) { 20878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case DECISION_FAIL: 20888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "FAIL"; 20898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case DECISION_COND_SUCC: 20908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "COND_SUCC"; 20918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case DECISION_UNCOND_SUCC: 20928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "UNCOND_SUCC"; 20938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 20948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "UNKNOWN"; 20958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 20978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */ 20988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_CTRL_IFACE 21018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 21038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_sm_get_status - Get EAP state machine status 21048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 21058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @buf: Buffer for status information 21068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @buflen: Maximum buffer length 21078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @verbose: Whether to include verbose status information 21088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Number of bytes written to buf. 21098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 21108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Query EAP state machine for status information. This function fills in a 21118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * text area with current status information from the EAPOL state machine. If 21128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * the buffer (buf) is not large enough, status information will be truncated 21138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * to fit the buffer. 21148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 21158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint eap_sm_get_status(struct eap_sm *sm, char *buf, size_t buflen, int verbose) 21168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 21178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int len, ret; 21188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 21208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 21218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = os_snprintf(buf, buflen, 21238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "EAP state=%s\n", 21248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sm_state_txt(sm->EAP_state)); 21256c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (os_snprintf_error(buflen, len)) 21268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 21278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->selectedMethod != EAP_TYPE_NONE) { 21298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *name; 21308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->m) { 21318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt name = sm->m->name; 21328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 21338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct eap_method *m = 21348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_peer_get_eap_method(EAP_VENDOR_IETF, 21358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->selectedMethod); 21368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (m) 21378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt name = m->name; 21388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 21398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt name = "?"; 21408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 21418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(buf + len, buflen - len, 21428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "selectedMethod=%d (EAP-%s)\n", 21438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->selectedMethod, name); 21446c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (os_snprintf_error(buflen - len, ret)) 21458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return len; 21468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len += ret; 21478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->m && sm->m->get_status) { 21498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len += sm->m->get_status(sm, sm->eap_method_priv, 21508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf + len, buflen - len, 21518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt verbose); 21528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 21538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 21548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (verbose) { 21568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(buf + len, buflen - len, 21578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "reqMethod=%d\n" 21588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "methodState=%s\n" 21598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "decision=%s\n" 21608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "ClientTimeout=%d\n", 21618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->reqMethod, 21628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sm_method_state_txt(sm->methodState), 21638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sm_decision_txt(sm->decision), 21648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->ClientTimeout); 21656c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (os_snprintf_error(buflen - len, ret)) 21668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return len; 21678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len += ret; 21688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 21698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return len; 21718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 21728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_CTRL_IFACE */ 21738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#if defined(CONFIG_CTRL_IFACE) || !defined(CONFIG_NO_STDOUT_DEBUG) 21761f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic void eap_sm_request(struct eap_sm *sm, enum wpa_ctrl_req_type field, 21778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *msg, size_t msglen) 21788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 21798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_peer_config *config; 2180051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt const char *txt = NULL; 2181051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt char *tmp; 21828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 21848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 21858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt config = eap_get_config(sm); 21868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (config == NULL) 21878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 21888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21891f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt switch (field) { 21901f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt case WPA_CTRL_REQ_EAP_IDENTITY: 21918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt config->pending_req_identity++; 21928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 21931f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt case WPA_CTRL_REQ_EAP_PASSWORD: 21948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt config->pending_req_password++; 21958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 21961f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt case WPA_CTRL_REQ_EAP_NEW_PASSWORD: 21978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt config->pending_req_new_password++; 21988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 21991f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt case WPA_CTRL_REQ_EAP_PIN: 22008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt config->pending_req_pin++; 22018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 22021f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt case WPA_CTRL_REQ_EAP_OTP: 22038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg) { 22048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tmp = os_malloc(msglen + 3); 22058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tmp == NULL) 22068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 22078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tmp[0] = '['; 22088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(tmp + 1, msg, msglen); 22098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tmp[msglen + 1] = ']'; 22108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tmp[msglen + 2] = '\0'; 22118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt txt = tmp; 22128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(config->pending_req_otp); 22138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt config->pending_req_otp = tmp; 22148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt config->pending_req_otp_len = msglen + 3; 22158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 22168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (config->pending_req_otp == NULL) 22178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 22188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt txt = config->pending_req_otp; 22198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 22208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 22211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt case WPA_CTRL_REQ_EAP_PASSPHRASE: 22228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt config->pending_req_passphrase++; 22238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 2224051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt case WPA_CTRL_REQ_SIM: 2225051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt txt = msg; 2226051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt break; 22278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 22288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 22298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 22308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->eapol_cb->eap_param_needed) 22328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eapol_cb->eap_param_needed(sm->eapol_ctx, field, txt); 22338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 22348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */ 22358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define eap_sm_request(sm, type, msg, msglen) do { } while (0) 22368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */ 22378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtconst char * eap_sm_get_method_name(struct eap_sm *sm) 22398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 22408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->m == NULL) 22418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "UNKNOWN"; 22428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return sm->m->name; 22438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 22448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 22478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_sm_request_identity - Request identity from user (ctrl_iface) 22488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 22498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 22508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * EAP methods can call this function to request identity information for the 22518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * current network. This is normally called when the identity is not included 22528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * in the network configuration. The request will be sent to monitor programs 22538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * through the control interface. 22548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 22558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eap_sm_request_identity(struct eap_sm *sm) 22568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 22571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt eap_sm_request(sm, WPA_CTRL_REQ_EAP_IDENTITY, NULL, 0); 22588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 22598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 22628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_sm_request_password - Request password from user (ctrl_iface) 22638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 22648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 22658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * EAP methods can call this function to request password information for the 22668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * current network. This is normally called when the password is not included 22678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * in the network configuration. The request will be sent to monitor programs 22688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * through the control interface. 22698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 22708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eap_sm_request_password(struct eap_sm *sm) 22718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 22721f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt eap_sm_request(sm, WPA_CTRL_REQ_EAP_PASSWORD, NULL, 0); 22738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 22748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 22778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_sm_request_new_password - Request new password from user (ctrl_iface) 22788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 22798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 22808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * EAP methods can call this function to request new password information for 22818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * the current network. This is normally called when the EAP method indicates 22828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * that the current password has expired and password change is required. The 22838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * request will be sent to monitor programs through the control interface. 22848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 22858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eap_sm_request_new_password(struct eap_sm *sm) 22868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 22871f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt eap_sm_request(sm, WPA_CTRL_REQ_EAP_NEW_PASSWORD, NULL, 0); 22888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 22898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 22928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_sm_request_pin - Request SIM or smart card PIN from user (ctrl_iface) 22938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 22948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 22958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * EAP methods can call this function to request SIM or smart card PIN 22968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * information for the current network. This is normally called when the PIN is 22978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * not included in the network configuration. The request will be sent to 22988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * monitor programs through the control interface. 22998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 23008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eap_sm_request_pin(struct eap_sm *sm) 23018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 23021f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt eap_sm_request(sm, WPA_CTRL_REQ_EAP_PIN, NULL, 0); 23038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 23048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 23078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_sm_request_otp - Request one time password from user (ctrl_iface) 23088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 23098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @msg: Message to be displayed to the user when asking for OTP 23108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @msg_len: Length of the user displayable message 23118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 23128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * EAP methods can call this function to request open time password (OTP) for 23138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * the current network. The request will be sent to monitor programs through 23148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * the control interface. 23158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 23168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eap_sm_request_otp(struct eap_sm *sm, const char *msg, size_t msg_len) 23178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 23181f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt eap_sm_request(sm, WPA_CTRL_REQ_EAP_OTP, msg, msg_len); 23198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 23208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 23238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_sm_request_passphrase - Request passphrase from user (ctrl_iface) 23248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 23258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 23268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * EAP methods can call this function to request passphrase for a private key 23278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * for the current network. This is normally called when the passphrase is not 23288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * included in the network configuration. The request will be sent to monitor 23298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * programs through the control interface. 23308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 23318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eap_sm_request_passphrase(struct eap_sm *sm) 23328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 23331f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt eap_sm_request(sm, WPA_CTRL_REQ_EAP_PASSPHRASE, NULL, 0); 23348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 23358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 2338051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt * eap_sm_request_sim - Request external SIM processing 2339051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 2340051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt * @req: EAP method specific request 2341051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt */ 2342051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidtvoid eap_sm_request_sim(struct eap_sm *sm, const char *req) 2343051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt{ 2344051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt eap_sm_request(sm, WPA_CTRL_REQ_SIM, req, os_strlen(req)); 2345051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt} 2346051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 2347051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 2348051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt/** 23498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_sm_notify_ctrl_attached - Notification of attached monitor 23508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 23518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 23528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Notify EAP state machines that a monitor was attached to the control 23538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * interface to trigger re-sending of pending requests for user input. 23548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 23558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eap_sm_notify_ctrl_attached(struct eap_sm *sm) 23568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 23578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_peer_config *config = eap_get_config(sm); 23588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (config == NULL) 23608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 23618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Re-send any pending requests for user data since a new control 23638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * interface was added. This handles cases where the EAP authentication 23648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * starts immediately after system startup when the user interface is 23658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * not yet running. */ 23668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (config->pending_req_identity) 23678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sm_request_identity(sm); 23688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (config->pending_req_password) 23698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sm_request_password(sm); 23708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (config->pending_req_new_password) 23718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sm_request_new_password(sm); 23728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (config->pending_req_otp) 23738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sm_request_otp(sm, NULL, 0); 23748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (config->pending_req_pin) 23758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sm_request_pin(sm); 23768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (config->pending_req_passphrase) 23778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sm_request_passphrase(sm); 23788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 23798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int eap_allowed_phase2_type(int vendor, int type) 23828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 23838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (vendor != EAP_VENDOR_IETF) 23848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 23858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return type != EAP_TYPE_PEAP && type != EAP_TYPE_TTLS && 23868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt type != EAP_TYPE_FAST; 23878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 23888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 23918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_get_phase2_type - Get EAP type for the given EAP phase 2 method name 23928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @name: EAP method name, e.g., MD5 23938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @vendor: Buffer for returning EAP Vendor-Id 23948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: EAP method type or %EAP_TYPE_NONE if not found 23958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 23968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function maps EAP type names into EAP type numbers that are allowed for 23978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Phase 2, i.e., for tunneled authentication. Phase 2 is used, e.g., with 23988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * EAP-PEAP, EAP-TTLS, and EAP-FAST. 23998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 24008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtu32 eap_get_phase2_type(const char *name, int *vendor) 24018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 24028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int v; 2403af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt u32 type = eap_peer_get_type(name, &v); 24048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eap_allowed_phase2_type(v, type)) { 24058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *vendor = v; 24068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return type; 24078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 24088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *vendor = EAP_VENDOR_IETF; 24098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return EAP_TYPE_NONE; 24108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 24118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 24148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_get_phase2_types - Get list of allowed EAP phase 2 types 24158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @config: Pointer to a network configuration 24168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @count: Pointer to a variable to be filled with number of returned EAP types 24178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Pointer to allocated type list or %NULL on failure 24188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 24198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function generates an array of allowed EAP phase 2 (tunneled) types for 24208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * the given network configuration. 24218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 24228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct eap_method_type * eap_get_phase2_types(struct eap_peer_config *config, 24238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t *count) 24248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 24258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_method_type *buf; 24268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u32 method; 24278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int vendor; 24288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t mcount; 24298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct eap_method *methods, *m; 24308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt methods = eap_peer_get_methods(&mcount); 24328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (methods == NULL) 24338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 24348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *count = 0; 24358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf = os_malloc(mcount * sizeof(struct eap_method_type)); 24368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf == NULL) 24378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 24388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (m = methods; m; m = m->next) { 24408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt vendor = m->vendor; 24418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt method = m->method; 24428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eap_allowed_phase2_type(vendor, method)) { 24438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (vendor == EAP_VENDOR_IETF && 24448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt method == EAP_TYPE_TLS && config && 24458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt config->private_key2 == NULL) 24468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 24478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf[*count].vendor = vendor; 24488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf[*count].method = method; 24498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (*count)++; 24508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 24518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 24528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return buf; 24548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 24558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 24588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_set_fast_reauth - Update fast_reauth setting 24598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 24608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @enabled: 1 = Fast reauthentication is enabled, 0 = Disabled 24618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 24628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eap_set_fast_reauth(struct eap_sm *sm, int enabled) 24638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 24648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->fast_reauth = enabled; 24658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 24668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 24698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_set_workaround - Update EAP workarounds setting 24708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 24718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @workaround: 1 = Enable EAP workarounds, 0 = Disable EAP workarounds 24728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 24738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eap_set_workaround(struct eap_sm *sm, unsigned int workaround) 24748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 24758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->workaround = workaround; 24768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 24778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 24808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_get_config - Get current network configuration 24818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 24828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Pointer to the current network configuration or %NULL if not found 24838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 24848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * EAP peer methods should avoid using this function if they can use other 24858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * access functions, like eap_get_config_identity() and 24868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_get_config_password(), that do not require direct access to 24878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * struct eap_peer_config. 24888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 24898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct eap_peer_config * eap_get_config(struct eap_sm *sm) 24908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 24918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return sm->eapol_cb->get_config(sm->eapol_ctx); 24928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 24938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 24968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_get_config_identity - Get identity from the network configuration 24978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 24988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @len: Buffer for the length of the identity 24998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Pointer to the identity or %NULL if not found 25008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 25018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtconst u8 * eap_get_config_identity(struct eap_sm *sm, size_t *len) 25028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 25038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_peer_config *config = eap_get_config(sm); 25048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (config == NULL) 25058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 25068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *len = config->identity_len; 25078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return config->identity; 25088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 25098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 251161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtstatic int eap_get_ext_password(struct eap_sm *sm, 251261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct eap_peer_config *config) 251361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 251461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt char *name; 251561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 251661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (config->password == NULL) 251761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 251861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 251961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt name = os_zalloc(config->password_len + 1); 252061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (name == NULL) 252161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 252261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt os_memcpy(name, config->password, config->password_len); 252361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 252461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt ext_password_free(sm->ext_pw_buf); 252561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt sm->ext_pw_buf = ext_password_get(sm->ext_pw, name); 252661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt os_free(name); 252761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 252861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return sm->ext_pw_buf == NULL ? -1 : 0; 252961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 253061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 253161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 25328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 25338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_get_config_password - Get password from the network configuration 25348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 25358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @len: Buffer for the length of the password 25368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Pointer to the password or %NULL if not found 25378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 25388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtconst u8 * eap_get_config_password(struct eap_sm *sm, size_t *len) 25398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 25408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_peer_config *config = eap_get_config(sm); 25418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (config == NULL) 25428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 254361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 254461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (config->flags & EAP_CONFIG_FLAGS_EXT_PASSWORD) { 254561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (eap_get_ext_password(sm, config) < 0) 254661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return NULL; 254761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt *len = wpabuf_len(sm->ext_pw_buf); 254861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return wpabuf_head(sm->ext_pw_buf); 254961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 255061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 25518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *len = config->password_len; 25528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return config->password; 25538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 25548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 25578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_get_config_password2 - Get password from the network configuration 25588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 25598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @len: Buffer for the length of the password 25608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @hash: Buffer for returning whether the password is stored as a 25618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * NtPasswordHash instead of plaintext password; can be %NULL if this 25628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * information is not needed 25638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Pointer to the password or %NULL if not found 25648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 25658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtconst u8 * eap_get_config_password2(struct eap_sm *sm, size_t *len, int *hash) 25668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 25678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_peer_config *config = eap_get_config(sm); 25688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (config == NULL) 25698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 257061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 257161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (config->flags & EAP_CONFIG_FLAGS_EXT_PASSWORD) { 257261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (eap_get_ext_password(sm, config) < 0) 257361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return NULL; 2574344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt if (hash) 2575344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt *hash = 0; 257661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt *len = wpabuf_len(sm->ext_pw_buf); 257761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return wpabuf_head(sm->ext_pw_buf); 257861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 257961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 25808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *len = config->password_len; 25818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hash) 25828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *hash = !!(config->flags & EAP_CONFIG_FLAGS_PASSWORD_NTHASH); 25838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return config->password; 25848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 25858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 25888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_get_config_new_password - Get new password from network configuration 25898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 25908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @len: Buffer for the length of the new password 25918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Pointer to the new password or %NULL if not found 25928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 25938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtconst u8 * eap_get_config_new_password(struct eap_sm *sm, size_t *len) 25948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 25958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_peer_config *config = eap_get_config(sm); 25968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (config == NULL) 25978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 25988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *len = config->new_password_len; 25998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return config->new_password; 26008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 26018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 26048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_get_config_otp - Get one-time password from the network configuration 26058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 26068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @len: Buffer for the length of the one-time password 26078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Pointer to the one-time password or %NULL if not found 26088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 26098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtconst u8 * eap_get_config_otp(struct eap_sm *sm, size_t *len) 26108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 26118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_peer_config *config = eap_get_config(sm); 26128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (config == NULL) 26138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 26148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *len = config->otp_len; 26158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return config->otp; 26168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 26178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 26208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_clear_config_otp - Clear used one-time password 26218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 26228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 26238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function clears a used one-time password (OTP) from the current network 26248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * configuration. This should be called when the OTP has been used and is not 26258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * needed anymore. 26268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 26278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eap_clear_config_otp(struct eap_sm *sm) 26288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 26298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_peer_config *config = eap_get_config(sm); 26308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (config == NULL) 26318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 26328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(config->otp, 0, config->otp_len); 26338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(config->otp); 26348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt config->otp = NULL; 26358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt config->otp_len = 0; 26368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 26378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 26408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_get_config_phase1 - Get phase1 data from the network configuration 26418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 26428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Pointer to the phase1 data or %NULL if not found 26438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 26448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtconst char * eap_get_config_phase1(struct eap_sm *sm) 26458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 26468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_peer_config *config = eap_get_config(sm); 26478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (config == NULL) 26488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 26498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return config->phase1; 26508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 26518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 26548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_get_config_phase2 - Get phase2 data from the network configuration 26558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 26568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Pointer to the phase1 data or %NULL if not found 26578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 26588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtconst char * eap_get_config_phase2(struct eap_sm *sm) 26598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 26608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_peer_config *config = eap_get_config(sm); 26618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (config == NULL) 26628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 26638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return config->phase2; 26648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 26658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint eap_get_config_fragment_size(struct eap_sm *sm) 26688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 26698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_peer_config *config = eap_get_config(sm); 26708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (config == NULL) 26718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 26728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return config->fragment_size; 26738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 26748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 26778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_key_available - Get key availability (eapKeyAvailable variable) 26788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 26798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 1 if EAP keying material is available, 0 if not 26808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 26818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint eap_key_available(struct eap_sm *sm) 26828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 26838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return sm ? sm->eapKeyAvailable : 0; 26848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 26858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 26888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_notify_success - Notify EAP state machine about external success trigger 26898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 26908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 26918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is called when external event, e.g., successful completion of 26928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * WPA-PSK key handshake, is indicating that EAP state machine should move to 26938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * success state. This is mainly used with security modes that do not use EAP 26948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * state machine (e.g., WPA-PSK). 26958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 26968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eap_notify_success(struct eap_sm *sm) 26978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 26988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm) { 26998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->decision = DECISION_COND_SUCC; 27008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->EAP_state = EAP_SUCCESS; 27018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 27028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 27038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 27068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_notify_lower_layer_success - Notification of lower layer success 27078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 27088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 27098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Notify EAP state machines that a lower layer has detected a successful 27108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * authentication. This is used to recover from dropped EAP-Success messages. 27118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 27128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eap_notify_lower_layer_success(struct eap_sm *sm) 27138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 27148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 27158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 27168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eapol_get_bool(sm, EAPOL_eapSuccess) || 27188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->decision == DECISION_FAIL || 27198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (sm->methodState != METHOD_MAY_CONT && 27208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->methodState != METHOD_DONE)) 27218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 27228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->eapKeyData != NULL) 27248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eapKeyAvailable = TRUE; 27258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_set_bool(sm, EAPOL_eapSuccess, TRUE); 27268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_SUCCESS 27278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "EAP authentication completed successfully (based on lower " 27288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "layer success)"); 27298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 27308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 2733f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * eap_get_eapSessionId - Get Session-Id from EAP state machine 2734f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 2735f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * @len: Pointer to variable that will be set to number of bytes in the session 2736f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * Returns: Pointer to the EAP Session-Id or %NULL on failure 2737f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * 2738f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * Fetch EAP Session-Id from the EAP state machine. The Session-Id is available 2739f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * only after a successful authentication. EAP state machine continues to manage 2740f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * the Session-Id and the caller must not change or free the returned data. 2741f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt */ 2742f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidtconst u8 * eap_get_eapSessionId(struct eap_sm *sm, size_t *len) 2743f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt{ 2744f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt if (sm == NULL || sm->eapSessionId == NULL) { 2745f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt *len = 0; 2746f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt return NULL; 2747f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt } 2748f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt 2749f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt *len = sm->eapSessionIdLen; 2750f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt return sm->eapSessionId; 2751f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt} 2752f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt 2753f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt 2754f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt/** 27558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_get_eapKeyData - Get master session key (MSK) from EAP state machine 27568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 27578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @len: Pointer to variable that will be set to number of bytes in the key 27588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Pointer to the EAP keying data or %NULL on failure 27598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 27608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Fetch EAP keying material (MSK, eapKeyData) from the EAP state machine. The 27618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * key is available only after a successful authentication. EAP state machine 27628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * continues to manage the key data and the caller must not change or free the 27638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * returned data. 27648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 27658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtconst u8 * eap_get_eapKeyData(struct eap_sm *sm, size_t *len) 27668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 27678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL || sm->eapKeyData == NULL) { 27688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *len = 0; 27698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 27708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 27718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *len = sm->eapKeyDataLen; 27738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return sm->eapKeyData; 27748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 27758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 27788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_get_eapKeyData - Get EAP response data 27798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 27808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Pointer to the EAP response (eapRespData) or %NULL on failure 27818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 27828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Fetch EAP response (eapRespData) from the EAP state machine. This data is 27838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * available when EAP state machine has processed an incoming EAP request. The 27848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * EAP state machine does not maintain a reference to the response after this 27858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * function is called and the caller is responsible for freeing the data. 27868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 27878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct wpabuf * eap_get_eapRespData(struct eap_sm *sm) 27888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 27898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *resp; 27908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL || sm->eapRespData == NULL) 27928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 27938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = sm->eapRespData; 27958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eapRespData = NULL; 27968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return resp; 27988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 27998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 28028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_sm_register_scard_ctx - Notification of smart card context 28038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 28048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @ctx: Context data for smart card operations 28058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 28068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Notify EAP state machines of context data for smart card operations. This 28078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * context data will be used as a parameter for scard_*() functions. 28088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 28098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eap_register_scard_ctx(struct eap_sm *sm, void *ctx) 28108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 28118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm) 28128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->scard_ctx = ctx; 28138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 28148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 28178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_set_config_blob - Set or add a named configuration blob 28188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 28198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @blob: New value for the blob 28208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 28218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Adds a new configuration blob or replaces the current value of an existing 28228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * blob. 28238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 28248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eap_set_config_blob(struct eap_sm *sm, struct wpa_config_blob *blob) 28258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 28268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NO_CONFIG_BLOBS 28278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eapol_cb->set_config_blob(sm->eapol_ctx, blob); 28288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NO_CONFIG_BLOBS */ 28298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 28308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 28338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_get_config_blob - Get a named configuration blob 28348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 28358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @name: Name of the blob 28368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Pointer to blob data or %NULL if not found 28378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 28388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtconst struct wpa_config_blob * eap_get_config_blob(struct eap_sm *sm, 28398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *name) 28408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 28418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NO_CONFIG_BLOBS 28428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return sm->eapol_cb->get_config_blob(sm->eapol_ctx, name); 28438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* CONFIG_NO_CONFIG_BLOBS */ 28448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 28458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NO_CONFIG_BLOBS */ 28468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 28478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 28508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_set_force_disabled - Set force_disabled flag 28518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 28528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @disabled: 1 = EAP disabled, 0 = EAP enabled 28538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 28548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is used to force EAP state machine to be disabled when it is 28558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * not in use (e.g., with WPA-PSK or plaintext connections). 28568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 28578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eap_set_force_disabled(struct eap_sm *sm, int disabled) 28588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 28598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->force_disabled = disabled; 28608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 28618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2863051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt/** 2864051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt * eap_set_external_sim - Set external_sim flag 2865051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 2866051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt * @external_sim: Whether external SIM/USIM processing is used 2867051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt */ 2868051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidtvoid eap_set_external_sim(struct eap_sm *sm, int external_sim) 2869051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt{ 2870051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt sm->external_sim = external_sim; 2871051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt} 2872051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 2873051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 28748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /** 28758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_notify_pending - Notify that EAP method is ready to re-process a request 28768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 28778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 28788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * An EAP method can perform a pending operation (e.g., to get a response from 28798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * an external process). Once the response is available, this function can be 28808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * used to request EAPOL state machine to retry delivering the previously 28818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * received (and still unanswered) EAP request to EAP state machine. 28828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 28838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eap_notify_pending(struct eap_sm *sm) 28848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 28858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eapol_cb->notify_pending(sm->eapol_ctx); 28868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 28878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 28908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_invalidate_cached_session - Mark cached session data invalid 28918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 28928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 28938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eap_invalidate_cached_session(struct eap_sm *sm) 28948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 28958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm) 28968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_deinit_prev_method(sm, "invalidate"); 28978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 28988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint eap_is_wps_pbc_enrollee(struct eap_peer_config *conf) 29018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 29028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conf->identity_len != WSC_ID_ENROLLEE_LEN || 29038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(conf->identity, WSC_ID_ENROLLEE, WSC_ID_ENROLLEE_LEN)) 29048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; /* Not a WPS Enrollee */ 29058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conf->phase1 == NULL || os_strstr(conf->phase1, "pbc=1") == NULL) 29078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; /* Not using PBC */ 29088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 29108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 29118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint eap_is_wps_pin_enrollee(struct eap_peer_config *conf) 29148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 29158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conf->identity_len != WSC_ID_ENROLLEE_LEN || 29168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(conf->identity, WSC_ID_ENROLLEE, WSC_ID_ENROLLEE_LEN)) 29178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; /* Not a WPS Enrollee */ 29188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conf->phase1 == NULL || os_strstr(conf->phase1, "pin=") == NULL) 29208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; /* Not using PIN */ 29218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 29238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 292461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 292561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 292661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtvoid eap_sm_set_ext_pw_ctx(struct eap_sm *sm, struct ext_password_data *ext) 292761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 292861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt ext_password_free(sm->ext_pw_buf); 292961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt sm->ext_pw_buf = NULL; 293061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt sm->ext_pw = ext; 293161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 29324530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 29334530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 29344530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt/** 29354530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt * eap_set_anon_id - Set or add anonymous identity 29364530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 29374530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt * @id: Anonymous identity (e.g., EAP-SIM pseudonym) or %NULL to clear 29384530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt * @len: Length of anonymous identity in octets 29394530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt */ 29404530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidtvoid eap_set_anon_id(struct eap_sm *sm, const u8 *id, size_t len) 29414530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt{ 29424530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (sm->eapol_cb->set_anon_id) 29434530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt sm->eapol_cb->set_anon_id(sm->eapol_ctx, id, len); 29444530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt} 2945344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt 2946344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt 2947344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidtint eap_peer_was_failure_expected(struct eap_sm *sm) 2948344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt{ 2949344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt return sm->expected_failure; 2950344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt} 2951