1845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/* 2845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * EAP peer state machines (RFC 4137) 3845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * Copyright (c) 2004-2006, Jouni Malinen <j@w1.fi> 4845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * 5845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * This program is free software; you can redistribute it and/or modify 6845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * it under the terms of the GNU General Public License version 2 as 7845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * published by the Free Software Foundation. 8845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * 9845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * Alternatively, this software may be distributed under the terms of BSD 10845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * license. 11845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * 12845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * See README and COPYING for more details. 13845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * 14845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * This file implements the Peer State Machine as defined in RFC 4137. The used 15845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * states and state transitions match mostly with the RFC. However, there are 16845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * couple of additional transitions for working around small issues noticed 17845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * during testing. These exceptions are explained in comments within the 18845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * functions in this file. The method functions, m.func(), are similar to the 19845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * ones used in RFC 4137, but some small changes have used here to optimize 20845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * operations and to add functionality needed for fast re-authentication 21845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * (session resumption). 22845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project */ 23845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 24845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#include "includes.h" 25845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 26845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#include "common.h" 27845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#include "eap_i.h" 28845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#include "config_ssid.h" 29845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#include "tls.h" 30845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#include "crypto.h" 31845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#include "pcsc_funcs.h" 32845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#include "wpa_ctrl.h" 33845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#include "state_machine.h" 34845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 35845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#define STATE_MACHINE_DATA struct eap_sm 36845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#define STATE_MACHINE_DEBUG_PREFIX "EAP" 37845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 38845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#define EAP_MAX_AUTH_ROUNDS 50 39845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 40845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 41845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic Boolean eap_sm_allowMethod(struct eap_sm *sm, int vendor, 42845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project EapType method); 43845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic u8 * eap_sm_buildNak(struct eap_sm *sm, int id, size_t *len); 44845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic void eap_sm_processIdentity(struct eap_sm *sm, const u8 *req); 45845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic void eap_sm_processNotify(struct eap_sm *sm, const u8 *req); 46845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic u8 * eap_sm_buildNotify(int id, size_t *len); 47845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic void eap_sm_parseEapReq(struct eap_sm *sm, const u8 *req, size_t len); 48845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#if defined(CONFIG_CTRL_IFACE) || !defined(CONFIG_NO_STDOUT_DEBUG) 49845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic const char * eap_sm_method_state_txt(EapMethodState state); 50845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic const char * eap_sm_decision_txt(EapDecision decision); 51845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#endif /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */ 52845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 53845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 54845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 55845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic Boolean eapol_get_bool(struct eap_sm *sm, enum eapol_bool_var var) 56845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 57845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return sm->eapol_cb->get_bool(sm->eapol_ctx, var); 58845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 59845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 60845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 61845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic void eapol_set_bool(struct eap_sm *sm, enum eapol_bool_var var, 62845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project Boolean value) 63845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 64845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->eapol_cb->set_bool(sm->eapol_ctx, var, value); 65845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 66845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 67845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 68845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic unsigned int eapol_get_int(struct eap_sm *sm, enum eapol_int_var var) 69845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 70845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return sm->eapol_cb->get_int(sm->eapol_ctx, var); 71845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 72845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 73845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 74845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic void eapol_set_int(struct eap_sm *sm, enum eapol_int_var var, 75845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project unsigned int value) 76845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 77845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->eapol_cb->set_int(sm->eapol_ctx, var, value); 78845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 79845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 80845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 81845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic u8 * eapol_get_eapReqData(struct eap_sm *sm, size_t *len) 82845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 83845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return sm->eapol_cb->get_eapReqData(sm->eapol_ctx, len); 84845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 85845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 86845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 87845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic void eap_deinit_prev_method(struct eap_sm *sm, const char *txt) 88845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 89845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (sm->m == NULL || sm->eap_method_priv == NULL) 90845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return; 91845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 92845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP: deinitialize previously used EAP method " 93845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "(%d, %s) at %s", sm->selectedMethod, sm->m->name, txt); 94845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->m->deinit(sm, sm->eap_method_priv); 95845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->eap_method_priv = NULL; 96845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->m = NULL; 97845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 98845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 99845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 100845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/* 101845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * This state initializes state machine variables when the machine is 102845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * activated (portEnabled = TRUE). This is also used when re-starting 103845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * authentication (eapRestart == TRUE). 104845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project */ 105845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source ProjectSM_STATE(EAP, INITIALIZE) 106845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 107845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project SM_ENTRY(EAP, INITIALIZE); 108845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (sm->fast_reauth && sm->m && sm->m->has_reauth_data && 109845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->m->has_reauth_data(sm, sm->eap_method_priv)) { 110845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP: maintaining EAP method data for " 111845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "fast reauthentication"); 112845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->m->deinit_for_reauth(sm, sm->eap_method_priv); 113845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } else { 114845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project eap_deinit_prev_method(sm, "INITIALIZE"); 115845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 116845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->selectedMethod = EAP_TYPE_NONE; 117845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->methodState = METHOD_NONE; 118845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->allowNotifications = TRUE; 119845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->decision = DECISION_FAIL; 120845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project eapol_set_int(sm, EAPOL_idleWhile, sm->ClientTimeout); 121845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project eapol_set_bool(sm, EAPOL_eapSuccess, FALSE); 122845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project eapol_set_bool(sm, EAPOL_eapFail, FALSE); 123845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_free(sm->eapKeyData); 124845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->eapKeyData = NULL; 125845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->eapKeyAvailable = FALSE; 126845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project eapol_set_bool(sm, EAPOL_eapRestart, FALSE); 127845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->lastId = -1; /* new session - make sure this does not match with 128845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * the first EAP-Packet */ 129845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project /* 130845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * RFC 4137 does not reset eapResp and eapNoResp here. However, this 131845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * seemed to be able to trigger cases where both were set and if EAPOL 132845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * state machine uses eapNoResp first, it may end up not sending a real 133845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * reply correctly. This occurred when the workaround in FAIL state set 134845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * eapNoResp = TRUE.. Maybe that workaround needs to be fixed to do 135845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * something else(?) 136845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project */ 137845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project eapol_set_bool(sm, EAPOL_eapResp, FALSE); 138845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project eapol_set_bool(sm, EAPOL_eapNoResp, FALSE); 139845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->num_rounds = 0; 140845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 141845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 142845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 143845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/* 144845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * This state is reached whenever service from the lower layer is interrupted 145845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * or unavailable (portEnabled == FALSE). Immediate transition to INITIALIZE 146845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * occurs when the port becomes enabled. 147845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project */ 148845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source ProjectSM_STATE(EAP, DISABLED) 149845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 150845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project SM_ENTRY(EAP, DISABLED); 151845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->num_rounds = 0; 152845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 153845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 154845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 155845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/* 156845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * The state machine spends most of its time here, waiting for something to 157845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * happen. This state is entered unconditionally from INITIALIZE, DISCARD, and 158845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * SEND_RESPONSE states. 159845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project */ 160845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source ProjectSM_STATE(EAP, IDLE) 161845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 162845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project SM_ENTRY(EAP, IDLE); 163845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 164845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 165845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 166845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/* 167845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * This state is entered when an EAP packet is received (eapReq == TRUE) to 168845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * parse the packet header. 169845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project */ 170845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source ProjectSM_STATE(EAP, RECEIVED) 171845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 172845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project const u8 *eapReqData; 173845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project size_t eapReqDataLen; 174845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 175845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project SM_ENTRY(EAP, RECEIVED); 176845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project eapReqData = eapol_get_eapReqData(sm, &eapReqDataLen); 177845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project /* parse rxReq, rxSuccess, rxFailure, reqId, reqMethod */ 178845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project eap_sm_parseEapReq(sm, eapReqData, eapReqDataLen); 179845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->num_rounds++; 180845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 181845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 182845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 183845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/* 184845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * This state is entered when a request for a new type comes in. Either the 185845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * correct method is started, or a Nak response is built. 186845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project */ 187845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source ProjectSM_STATE(EAP, GET_METHOD) 188845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 189845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project int reinit; 190845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project EapType method; 191845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 192845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project SM_ENTRY(EAP, GET_METHOD); 193845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 194845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (sm->reqMethod == EAP_TYPE_EXPANDED) 195845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project method = sm->reqVendorMethod; 196845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project else 197845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project method = sm->reqMethod; 198845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 199845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (!eap_sm_allowMethod(sm, sm->reqVendor, method)) { 200845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP: vendor %u method %u not allowed", 201845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->reqVendor, method); 202845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project goto nak; 203845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 204845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 205845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project /* 206845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * RFC 4137 does not define specific operation for fast 207845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * re-authentication (session resumption). The design here is to allow 208845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * the previously used method data to be maintained for 209845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * re-authentication if the method support session resumption. 210845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * Otherwise, the previously used method data is freed and a new method 211845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * is allocated here. 212845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project */ 213845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (sm->fast_reauth && 214845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->m && sm->m->vendor == sm->reqVendor && 215845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->m->method == method && 216845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->m->has_reauth_data && 217845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->m->has_reauth_data(sm, sm->eap_method_priv)) { 218845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP: Using previous method data" 219845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project " for fast re-authentication"); 220845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project reinit = 1; 221845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } else { 222845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project eap_deinit_prev_method(sm, "GET_METHOD"); 223845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project reinit = 0; 224845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 225845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 226845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->selectedMethod = sm->reqMethod; 227845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (sm->m == NULL) 228845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->m = eap_sm_get_eap_methods(sm->reqVendor, method); 229845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (!sm->m) { 230845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP: Could not find selected method: " 231845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "vendor %d method %d", 232845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->reqVendor, method); 233845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project goto nak; 234845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 235845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 236845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP: Initialize selected EAP method: " 237845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "vendor %u method %u (%s)", 238845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->reqVendor, method, sm->m->name); 239845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (reinit) 240845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->eap_method_priv = sm->m->init_for_reauth( 241845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm, sm->eap_method_priv); 242845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project else 243845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->eap_method_priv = sm->m->init(sm); 244845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 245845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (sm->eap_method_priv == NULL) { 246845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project struct wpa_ssid *config = eap_get_config(sm); 247845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_msg(sm->msg_ctx, MSG_INFO, 248845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "EAP: Failed to initialize EAP method: vendor %u " 249845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "method %u (%s)", 250845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->reqVendor, method, sm->m->name); 251845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->m = NULL; 252845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->methodState = METHOD_NONE; 253845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->selectedMethod = EAP_TYPE_NONE; 254845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (sm->reqMethod == EAP_TYPE_TLS && config && 255845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project (config->pending_req_pin || 256845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project config->pending_req_passphrase)) { 257845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project /* 258845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * Return without generating Nak in order to allow 259845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * entering of PIN code or passphrase to retry the 260845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * current EAP packet. 261845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project */ 262845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP: Pending PIN/passphrase " 263845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "request - skip Nak"); 264845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return; 265845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 266845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 267845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project goto nak; 268845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 269845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 270845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->methodState = METHOD_INIT; 271845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_METHOD 272845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "EAP vendor %u method %u (%s) selected", 273845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->reqVendor, method, sm->m->name); 274845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return; 275845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 276845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectnak: 277845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_free(sm->eapRespData); 278845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->eapRespData = NULL; 279845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->eapRespData = eap_sm_buildNak(sm, sm->reqId, &sm->eapRespDataLen); 280845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 281845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 282845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 283845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/* 284845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * The method processing happens here. The request from the authenticator is 285845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * processed, and an appropriate response packet is built. 286845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project */ 287845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source ProjectSM_STATE(EAP, METHOD) 288845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 289845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project u8 *eapReqData; 290845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project size_t eapReqDataLen; 291845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project struct eap_method_ret ret; 292845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 293845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project SM_ENTRY(EAP, METHOD); 294845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (sm->m == NULL) { 295845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_WARNING, "EAP::METHOD - method not selected"); 296845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return; 297845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 298845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 299845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project eapReqData = eapol_get_eapReqData(sm, &eapReqDataLen); 300845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 301845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project /* 302845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * Get ignore, methodState, decision, allowNotifications, and 303845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * eapRespData. RFC 4137 uses three separate method procedure (check, 304845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * process, and buildResp) in this state. These have been combined into 305845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * a single function call to m->process() in order to optimize EAP 306845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * method implementation interface a bit. These procedures are only 307845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * used from within this METHOD state, so there is no need to keep 308845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * these as separate C functions. 309845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * 310845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * The RFC 4137 procedures return values as follows: 311845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * ignore = m.check(eapReqData) 312845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * (methodState, decision, allowNotifications) = m.process(eapReqData) 313845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * eapRespData = m.buildResp(reqId) 314845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project */ 315845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_memset(&ret, 0, sizeof(ret)); 316845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project ret.ignore = sm->ignore; 317845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project ret.methodState = sm->methodState; 318845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project ret.decision = sm->decision; 319845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project ret.allowNotifications = sm->allowNotifications; 320845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_free(sm->eapRespData); 321845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->eapRespData = NULL; 322845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->eapRespData = sm->m->process(sm, sm->eap_method_priv, &ret, 323845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project eapReqData, eapReqDataLen, 324845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project &sm->eapRespDataLen); 325845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP: method process -> ignore=%s " 326845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "methodState=%s decision=%s", 327845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project ret.ignore ? "TRUE" : "FALSE", 328845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project eap_sm_method_state_txt(ret.methodState), 329845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project eap_sm_decision_txt(ret.decision)); 330845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 331845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->ignore = ret.ignore; 332845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (sm->ignore) 333845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return; 334845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->methodState = ret.methodState; 335845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->decision = ret.decision; 336845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->allowNotifications = ret.allowNotifications; 337845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 338845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (sm->m->isKeyAvailable && sm->m->getKey && 339845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->m->isKeyAvailable(sm, sm->eap_method_priv)) { 340845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_free(sm->eapKeyData); 341845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->eapKeyData = sm->m->getKey(sm, sm->eap_method_priv, 342845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project &sm->eapKeyDataLen); 343845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 344845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 345845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 346845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 347845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/* 348845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * This state signals the lower layer that a response packet is ready to be 349845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * sent. 350845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project */ 351845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source ProjectSM_STATE(EAP, SEND_RESPONSE) 352845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 353845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project SM_ENTRY(EAP, SEND_RESPONSE); 354845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_free(sm->lastRespData); 355845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (sm->eapRespData) { 356845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (sm->workaround) 357845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_memcpy(sm->last_md5, sm->req_md5, 16); 358845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->lastId = sm->reqId; 359845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->lastRespData = os_malloc(sm->eapRespDataLen); 360845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (sm->lastRespData) { 361845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_memcpy(sm->lastRespData, sm->eapRespData, 362845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->eapRespDataLen); 363845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->lastRespDataLen = sm->eapRespDataLen; 364845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 365845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project eapol_set_bool(sm, EAPOL_eapResp, TRUE); 366845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } else 367845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->lastRespData = NULL; 368845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project eapol_set_bool(sm, EAPOL_eapReq, FALSE); 369845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project eapol_set_int(sm, EAPOL_idleWhile, sm->ClientTimeout); 370845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 371845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 372845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 373845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/* 374845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * This state signals the lower layer that the request was discarded, and no 375845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * response packet will be sent at this time. 376845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project */ 377845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source ProjectSM_STATE(EAP, DISCARD) 378845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 379845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project SM_ENTRY(EAP, DISCARD); 380845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project eapol_set_bool(sm, EAPOL_eapReq, FALSE); 381845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project eapol_set_bool(sm, EAPOL_eapNoResp, TRUE); 382845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 383845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 384845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 385845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/* 386845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * Handles requests for Identity method and builds a response. 387845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project */ 388845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source ProjectSM_STATE(EAP, IDENTITY) 389845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 390845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project const u8 *eapReqData; 391845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project size_t eapReqDataLen; 392845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 393845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project SM_ENTRY(EAP, IDENTITY); 394845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project eapReqData = eapol_get_eapReqData(sm, &eapReqDataLen); 395845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project eap_sm_processIdentity(sm, eapReqData); 396845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_free(sm->eapRespData); 397845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->eapRespData = NULL; 398845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->eapRespData = eap_sm_buildIdentity(sm, sm->reqId, 399845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project &sm->eapRespDataLen, 0); 400845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 401845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 402845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 403845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/* 404845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * Handles requests for Notification method and builds a response. 405845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project */ 406845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source ProjectSM_STATE(EAP, NOTIFICATION) 407845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 408845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project const u8 *eapReqData; 409845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project size_t eapReqDataLen; 410845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 411845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project SM_ENTRY(EAP, NOTIFICATION); 412845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project eapReqData = eapol_get_eapReqData(sm, &eapReqDataLen); 413845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project eap_sm_processNotify(sm, eapReqData); 414845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_free(sm->eapRespData); 415845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->eapRespData = NULL; 416845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->eapRespData = eap_sm_buildNotify(sm->reqId, &sm->eapRespDataLen); 417845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 418845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 419845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 420845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/* 421845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * This state retransmits the previous response packet. 422845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project */ 423845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source ProjectSM_STATE(EAP, RETRANSMIT) 424845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 425845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project SM_ENTRY(EAP, RETRANSMIT); 426845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_free(sm->eapRespData); 427845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (sm->lastRespData) { 428845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->eapRespData = os_malloc(sm->lastRespDataLen); 429845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (sm->eapRespData) { 430845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_memcpy(sm->eapRespData, sm->lastRespData, 431845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->lastRespDataLen); 432845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->eapRespDataLen = sm->lastRespDataLen; 433845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 434845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } else 435845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->eapRespData = NULL; 436845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 437845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 438845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 439845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/* 440845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * This state is entered in case of a successful completion of authentication 441845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * and state machine waits here until port is disabled or EAP authentication is 442845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * restarted. 443845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project */ 444845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source ProjectSM_STATE(EAP, SUCCESS) 445845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 446845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project SM_ENTRY(EAP, SUCCESS); 447845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (sm->eapKeyData != NULL) 448845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->eapKeyAvailable = TRUE; 449845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project eapol_set_bool(sm, EAPOL_eapSuccess, TRUE); 450845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 451845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project /* 452845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * RFC 4137 does not clear eapReq here, but this seems to be required 453845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * to avoid processing the same request twice when state machine is 454845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * initialized. 455845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project */ 456845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project eapol_set_bool(sm, EAPOL_eapReq, FALSE); 457845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 458845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project /* 459845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * RFC 4137 does not set eapNoResp here, but this seems to be required 460845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * to get EAPOL Supplicant backend state machine into SUCCESS state. In 461845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * addition, either eapResp or eapNoResp is required to be set after 462845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * processing the received EAP frame. 463845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project */ 464845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project eapol_set_bool(sm, EAPOL_eapNoResp, TRUE); 465845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 466845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_SUCCESS 467845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "EAP authentication completed successfully"); 468845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 469845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 470845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 471845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/* 472845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * This state is entered in case of a failure and state machine waits here 473845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * until port is disabled or EAP authentication is restarted. 474845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project */ 475845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source ProjectSM_STATE(EAP, FAILURE) 476845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 477845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project SM_ENTRY(EAP, FAILURE); 478845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project eapol_set_bool(sm, EAPOL_eapFail, TRUE); 479845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 480845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project /* 481845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * RFC 4137 does not clear eapReq here, but this seems to be required 482845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * to avoid processing the same request twice when state machine is 483845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * initialized. 484845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project */ 485845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project eapol_set_bool(sm, EAPOL_eapReq, FALSE); 486845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 487845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project /* 488845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * RFC 4137 does not set eapNoResp here. However, either eapResp or 489845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * eapNoResp is required to be set after processing the received EAP 490845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * frame. 491845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project */ 492845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project eapol_set_bool(sm, EAPOL_eapNoResp, TRUE); 493845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 494845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_FAILURE 495845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "EAP authentication failed"); 496845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 497845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 498845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 499845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic int eap_success_workaround(struct eap_sm *sm, int reqId, int lastId) 500845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 501845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project /* 502845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * At least Microsoft IAS and Meetinghouse Aegis seem to be sending 503845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * EAP-Success/Failure with lastId + 1 even though RFC 3748 and 504845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * RFC 4137 require that reqId == lastId. In addition, it looks like 505845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * Ringmaster v2.1.2.0 would be using lastId + 2 in EAP-Success. 506845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * 507845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * Accept this kind of Id if EAP workarounds are enabled. These are 508845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * unauthenticated plaintext messages, so this should have minimal 509845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * security implications (bit easier to fake EAP-Success/Failure). 510845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project */ 511845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (sm->workaround && (reqId == ((lastId + 1) & 0xff) || 512845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project reqId == ((lastId + 2) & 0xff))) { 513845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP: Workaround for unexpected " 514845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "identifier field in EAP Success: " 515845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "reqId=%d lastId=%d (these are supposed to be " 516845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "same)", reqId, lastId); 517845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return 1; 518845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 519845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP: EAP-Success Id mismatch - reqId=%d " 520845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "lastId=%d", reqId, lastId); 521845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return 0; 522845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 523845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 524845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 525845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/* 526845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * RFC 4137 - Appendix A.1: EAP Peer State Machine - State transitions 527845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project */ 528845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source ProjectSM_STEP(EAP) 529845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 530845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project int duplicate; 531845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 532845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (eapol_get_bool(sm, EAPOL_eapRestart) && 533845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project eapol_get_bool(sm, EAPOL_portEnabled)) 534845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project SM_ENTER_GLOBAL(EAP, INITIALIZE); 535845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project else if (!eapol_get_bool(sm, EAPOL_portEnabled) || sm->force_disabled) 536845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project SM_ENTER_GLOBAL(EAP, DISABLED); 537845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project else if (sm->num_rounds > EAP_MAX_AUTH_ROUNDS) { 538845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project /* RFC 4137 does not place any limit on number of EAP messages 539845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * in an authentication session. However, some error cases have 540845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * ended up in a state were EAP messages were sent between the 541845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * peer and server in a loop (e.g., TLS ACK frame in both 542845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * direction). Since this is quite undesired outcome, limit the 543845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * total number of EAP round-trips and abort authentication if 544845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * this limit is exceeded. 545845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project */ 546845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (sm->num_rounds == EAP_MAX_AUTH_ROUNDS + 1) { 547845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_msg(sm->msg_ctx, MSG_INFO, "EAP: more than %d " 548845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "authentication rounds - abort", 549845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project EAP_MAX_AUTH_ROUNDS); 550845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->num_rounds++; 551845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project SM_ENTER_GLOBAL(EAP, FAILURE); 552845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 553845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } else switch (sm->EAP_state) { 554845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project case EAP_INITIALIZE: 555845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project SM_ENTER(EAP, IDLE); 556845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project break; 557845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project case EAP_DISABLED: 558845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (eapol_get_bool(sm, EAPOL_portEnabled) && 559845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project !sm->force_disabled) 560845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project SM_ENTER(EAP, INITIALIZE); 561845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project break; 562845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project case EAP_IDLE: 563845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project /* 564845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * The first three transitions are from RFC 4137. The last two 565845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * are local additions to handle special cases with LEAP and 566845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * PEAP server not sending EAP-Success in some cases. 567845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project */ 568845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (eapol_get_bool(sm, EAPOL_eapReq)) 569845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project SM_ENTER(EAP, RECEIVED); 570845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project else if ((eapol_get_bool(sm, EAPOL_altAccept) && 571845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->decision != DECISION_FAIL) || 572845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project (eapol_get_int(sm, EAPOL_idleWhile) == 0 && 573845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->decision == DECISION_UNCOND_SUCC)) 574845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project SM_ENTER(EAP, SUCCESS); 575845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project else if (eapol_get_bool(sm, EAPOL_altReject) || 576845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project (eapol_get_int(sm, EAPOL_idleWhile) == 0 && 577845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->decision != DECISION_UNCOND_SUCC) || 578845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project (eapol_get_bool(sm, EAPOL_altAccept) && 579845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->methodState != METHOD_CONT && 580845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->decision == DECISION_FAIL)) 581845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project SM_ENTER(EAP, FAILURE); 582845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project else if (sm->selectedMethod == EAP_TYPE_LEAP && 583845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->leap_done && sm->decision != DECISION_FAIL && 584845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->methodState == METHOD_DONE) 585845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project SM_ENTER(EAP, SUCCESS); 586845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project else if (sm->selectedMethod == EAP_TYPE_PEAP && 587845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->peap_done && sm->decision != DECISION_FAIL && 588845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->methodState == METHOD_DONE) 589845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project SM_ENTER(EAP, SUCCESS); 590845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project break; 591845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project case EAP_RECEIVED: 592845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project duplicate = (sm->reqId == sm->lastId) && sm->rxReq; 593845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (sm->workaround && duplicate && 594845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_memcmp(sm->req_md5, sm->last_md5, 16) != 0) { 595845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project /* 596845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * RFC 4137 uses (reqId == lastId) as the only 597845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * verification for duplicate EAP requests. However, 598845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * this misses cases where the AS is incorrectly using 599845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * the same id again; and unfortunately, such 600845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * implementations exist. Use MD5 hash as an extra 601845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * verification for the packets being duplicate to 602845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * workaround these issues. 603845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project */ 604845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP: AS used the same Id again," 605845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project " but EAP packets were not identical"); 606845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP: workaround - assume this " 607845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "is not a duplicate packet"); 608845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project duplicate = 0; 609845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 610845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 611845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project /* 612845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * Two special cases below for LEAP are local additions to work 613845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * around odd LEAP behavior (EAP-Success in the middle of 614845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * authentication and then swapped roles). Other transitions 615845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * are based on RFC 4137. 616845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project */ 617845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (sm->rxSuccess && sm->decision != DECISION_FAIL && 618845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project (sm->reqId == sm->lastId || 619845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project eap_success_workaround(sm, sm->reqId, sm->lastId))) 620845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project SM_ENTER(EAP, SUCCESS); 621845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project else if (sm->methodState != METHOD_CONT && 622845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project ((sm->rxFailure && 623845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->decision != DECISION_UNCOND_SUCC) || 624845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project (sm->rxSuccess && sm->decision == DECISION_FAIL && 625845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project (sm->selectedMethod != EAP_TYPE_LEAP || 626845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->methodState != METHOD_MAY_CONT))) && 627845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project (sm->reqId == sm->lastId || 628845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project eap_success_workaround(sm, sm->reqId, sm->lastId))) 629845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project SM_ENTER(EAP, FAILURE); 630845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project else if (sm->rxReq && duplicate) 631845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project SM_ENTER(EAP, RETRANSMIT); 632845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project else if (sm->rxReq && !duplicate && 633845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->reqMethod == EAP_TYPE_NOTIFICATION && 634845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->allowNotifications) 635845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project SM_ENTER(EAP, NOTIFICATION); 636845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project else if (sm->rxReq && !duplicate && 637845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->selectedMethod == EAP_TYPE_NONE && 638845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->reqMethod == EAP_TYPE_IDENTITY) 639845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project SM_ENTER(EAP, IDENTITY); 640845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project else if (sm->rxReq && !duplicate && 641845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->selectedMethod == EAP_TYPE_NONE && 642845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->reqMethod != EAP_TYPE_IDENTITY && 643845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->reqMethod != EAP_TYPE_NOTIFICATION) 644845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project SM_ENTER(EAP, GET_METHOD); 645845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project else if (sm->rxReq && !duplicate && 646845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->reqMethod == sm->selectedMethod && 647845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->methodState != METHOD_DONE) 648845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project SM_ENTER(EAP, METHOD); 649845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project else if (sm->selectedMethod == EAP_TYPE_LEAP && 650845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project (sm->rxSuccess || sm->rxResp)) 651845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project SM_ENTER(EAP, METHOD); 652845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project else 653845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project SM_ENTER(EAP, DISCARD); 654845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project break; 655845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project case EAP_GET_METHOD: 656845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (sm->selectedMethod == sm->reqMethod) 657845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project SM_ENTER(EAP, METHOD); 658845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project else 659845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project SM_ENTER(EAP, SEND_RESPONSE); 660845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project break; 661845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project case EAP_METHOD: 662845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (sm->ignore) 663845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project SM_ENTER(EAP, DISCARD); 664845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project else 665845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project SM_ENTER(EAP, SEND_RESPONSE); 666845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project break; 667845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project case EAP_SEND_RESPONSE: 668845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project SM_ENTER(EAP, IDLE); 669845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project break; 670845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project case EAP_DISCARD: 671845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project SM_ENTER(EAP, IDLE); 672845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project break; 673845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project case EAP_IDENTITY: 674845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project SM_ENTER(EAP, SEND_RESPONSE); 675845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project break; 676845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project case EAP_NOTIFICATION: 677845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project SM_ENTER(EAP, SEND_RESPONSE); 678845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project break; 679845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project case EAP_RETRANSMIT: 680845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project SM_ENTER(EAP, SEND_RESPONSE); 681845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project break; 682845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project case EAP_SUCCESS: 683845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project break; 684845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project case EAP_FAILURE: 685845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project break; 686845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 687845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 688845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 689845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 690845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic Boolean eap_sm_allowMethod(struct eap_sm *sm, int vendor, 691845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project EapType method) 692845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 693845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project struct wpa_ssid *config = eap_get_config(sm); 694845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 695845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (!wpa_config_allowed_eap_method(config, vendor, method)) { 696845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP: configuration does not allow: " 697845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "vendor %u method %u", vendor, method); 698845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return FALSE; 699845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 700845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (eap_sm_get_eap_methods(vendor, method)) 701845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return TRUE; 702845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP: not included in build: " 703845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "vendor %u method %u", vendor, method); 704845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return FALSE; 705845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 706845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 707845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 708845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic u8 * eap_sm_build_expanded_nak(struct eap_sm *sm, int id, size_t *len, 709845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project const struct eap_method *methods, 710845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project size_t count) 711845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 712845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project struct wpa_ssid *config = eap_get_config(sm); 713845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project struct eap_hdr *resp; 714845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project u8 *pos; 715845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project int found = 0; 716845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project const struct eap_method *m; 717845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 718845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP: Building expanded EAP-Nak"); 719845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 720845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project /* RFC 3748 - 5.3.2: Expanded Nak */ 721845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project *len = sizeof(struct eap_hdr) + 8; 722845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project resp = os_malloc(*len + 8 * (count + 1)); 723845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (resp == NULL) 724845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 725845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 726845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project resp->code = EAP_CODE_RESPONSE; 727845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project resp->identifier = id; 728845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project pos = (u8 *) (resp + 1); 729845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project *pos++ = EAP_TYPE_EXPANDED; 730845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project WPA_PUT_BE24(pos, EAP_VENDOR_IETF); 731845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project pos += 3; 732845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project WPA_PUT_BE32(pos, EAP_TYPE_NAK); 733845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project pos += 4; 734845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 735845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project for (m = methods; m; m = m->next) { 736845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (sm->reqVendor == m->vendor && 737845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->reqVendorMethod == m->method) 738845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project continue; /* do not allow the current method again */ 739845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (wpa_config_allowed_eap_method(config, m->vendor, 740845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project m->method)) { 741845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP: allowed type: " 742845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "vendor=%u method=%u", 743845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project m->vendor, m->method); 744845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project *pos++ = EAP_TYPE_EXPANDED; 745845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project WPA_PUT_BE24(pos, m->vendor); 746845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project pos += 3; 747845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project WPA_PUT_BE32(pos, m->method); 748845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project pos += 4; 749845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 750845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project (*len) += 8; 751845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project found++; 752845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 753845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 754845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (!found) { 755845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP: no more allowed methods"); 756845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project *pos++ = EAP_TYPE_EXPANDED; 757845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project WPA_PUT_BE24(pos, EAP_VENDOR_IETF); 758845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project pos += 3; 759845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project WPA_PUT_BE32(pos, EAP_TYPE_NONE); 760845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project pos += 4; 761845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 762845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project (*len) += 8; 763845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 764845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 765845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project resp->length = host_to_be16(*len); 766845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 767845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return (u8 *) resp; 768845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 769845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 770845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 771845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic u8 * eap_sm_buildNak(struct eap_sm *sm, int id, size_t *len) 772845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 773845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project struct wpa_ssid *config = eap_get_config(sm); 774845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project struct eap_hdr *resp; 775845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project u8 *pos; 776845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project int found = 0, expanded_found = 0; 777845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project size_t count; 778845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project const struct eap_method *methods, *m; 779845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 780845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP: Building EAP-Nak (requested type %u " 781845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "vendor=%u method=%u not allowed)", sm->reqMethod, 782845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->reqVendor, sm->reqVendorMethod); 783845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project methods = eap_peer_get_methods(&count); 784845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (methods == NULL) 785845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 786845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (sm->reqMethod == EAP_TYPE_EXPANDED) 787845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return eap_sm_build_expanded_nak(sm, id, len, methods, count); 788845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 789845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project /* RFC 3748 - 5.3.1: Legacy Nak */ 790845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project *len = sizeof(struct eap_hdr) + 1; 791845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project resp = os_malloc(*len + count + 1); 792845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (resp == NULL) 793845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 794845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 795845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project resp->code = EAP_CODE_RESPONSE; 796845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project resp->identifier = id; 797845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project pos = (u8 *) (resp + 1); 798845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project *pos++ = EAP_TYPE_NAK; 799845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 800845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project for (m = methods; m; m = m->next) { 801845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (m->vendor == EAP_VENDOR_IETF && m->method == sm->reqMethod) 802845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project continue; /* do not allow the current method again */ 803845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (wpa_config_allowed_eap_method(config, m->vendor, 804845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project m->method)) { 805845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (m->vendor != EAP_VENDOR_IETF) { 806845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (expanded_found) 807845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project continue; 808845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project expanded_found = 1; 809845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project *pos++ = EAP_TYPE_EXPANDED; 810845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } else 811845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project *pos++ = m->method; 812845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project (*len)++; 813845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project found++; 814845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 815845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 816845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (!found) { 817845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project *pos = EAP_TYPE_NONE; 818845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project (*len)++; 819845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 820845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_hexdump(MSG_DEBUG, "EAP: allowed methods", 821845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project ((u8 *) (resp + 1)) + 1, found); 822845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 823845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project resp->length = host_to_be16(*len); 824845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 825845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return (u8 *) resp; 826845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 827845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 828845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 829845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic void eap_sm_processIdentity(struct eap_sm *sm, const u8 *req) 830845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 831845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project const struct eap_hdr *hdr = (const struct eap_hdr *) req; 832845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project const u8 *pos = (const u8 *) (hdr + 1); 833845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project pos++; 834845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 835845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_STARTED 836845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "EAP authentication started"); 837845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 838845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project /* 839845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * RFC 3748 - 5.1: Identity 840845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * Data field may contain a displayable message in UTF-8. If this 841845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * includes NUL-character, only the data before that should be 842845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * displayed. Some EAP implementasitons may piggy-back additional 843845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * options after the NUL. 844845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project */ 845845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project /* TODO: could save displayable message so that it can be shown to the 846845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * user in case of interaction is required */ 847845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_hexdump_ascii(MSG_DEBUG, "EAP: EAP-Request Identity data", 848845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project pos, be_to_host16(hdr->length) - 5); 849845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 850845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 851845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 852845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#ifdef PCSC_FUNCS 853845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic int eap_sm_imsi_identity(struct eap_sm *sm, struct wpa_ssid *ssid) 854845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 855845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project int aka = 0; 856845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project char imsi[100]; 857845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project size_t imsi_len; 858845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project struct eap_method_type *m = ssid->eap_methods; 859845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project int i; 860845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 861845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project imsi_len = sizeof(imsi); 862845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (scard_get_imsi(sm->scard_ctx, imsi, &imsi_len)) { 863845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_WARNING, "Failed to get IMSI from SIM"); 864845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return -1; 865845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 866845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 867845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_hexdump_ascii(MSG_DEBUG, "IMSI", (u8 *) imsi, imsi_len); 868845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 869845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project for (i = 0; m && (m[i].vendor != EAP_VENDOR_IETF || 870845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project m[i].method != EAP_TYPE_NONE); i++) { 871845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (m[i].vendor == EAP_VENDOR_IETF && 872845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project m[i].method == EAP_TYPE_AKA) { 873845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project aka = 1; 874845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project break; 875845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 876845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 877845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 878845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_free(ssid->identity); 879845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project ssid->identity = os_malloc(1 + imsi_len); 880845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (ssid->identity == NULL) { 881845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_WARNING, "Failed to allocate buffer for " 882845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "IMSI-based identity"); 883845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return -1; 884845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 885845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 886845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project ssid->identity[0] = aka ? '0' : '1'; 887845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_memcpy(ssid->identity + 1, imsi, imsi_len); 888845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project ssid->identity_len = 1 + imsi_len; 889845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 890845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return 0; 891845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 892845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#endif /* PCSC_FUNCS */ 893845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 894845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 895dc9507e42030320bf0a3dbb7d3f733d43bc94edeDmitry Shmidtstatic int eap_sm_set_scard_pin(struct eap_sm *sm, struct wpa_ssid *ssid) 896845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 897845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#ifdef PCSC_FUNCS 898845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (scard_set_pin(sm->scard_ctx, ssid->pin)) { 899845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project /* 900845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * Make sure the same PIN is not tried again in order to avoid 901845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * blocking SIM. 902845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project */ 903845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_free(ssid->pin); 904845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project ssid->pin = NULL; 905845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 906845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_WARNING, "PIN validation failed"); 907845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project eap_sm_request_pin(sm); 908845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return -1; 909845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 910dc9507e42030320bf0a3dbb7d3f733d43bc94edeDmitry Shmidt return 0; 911dc9507e42030320bf0a3dbb7d3f733d43bc94edeDmitry Shmidt#else /* PCSC_FUNCS */ 912dc9507e42030320bf0a3dbb7d3f733d43bc94edeDmitry Shmidt return -1; 913dc9507e42030320bf0a3dbb7d3f733d43bc94edeDmitry Shmidt#endif /* PCSC_FUNCS */ 914dc9507e42030320bf0a3dbb7d3f733d43bc94edeDmitry Shmidt} 915dc9507e42030320bf0a3dbb7d3f733d43bc94edeDmitry Shmidt 916dc9507e42030320bf0a3dbb7d3f733d43bc94edeDmitry Shmidtstatic int eap_sm_get_scard_identity(struct eap_sm *sm, struct wpa_ssid *ssid) 917dc9507e42030320bf0a3dbb7d3f733d43bc94edeDmitry Shmidt{ 918dc9507e42030320bf0a3dbb7d3f733d43bc94edeDmitry Shmidt#ifdef PCSC_FUNCS 919dc9507e42030320bf0a3dbb7d3f733d43bc94edeDmitry Shmidt if (eap_sm_set_scard_pin(sm, ssid)) 920dc9507e42030320bf0a3dbb7d3f733d43bc94edeDmitry Shmidt return -1; 921845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 922845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return eap_sm_imsi_identity(sm, ssid); 923845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#else /* PCSC_FUNCS */ 924845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return -1; 925845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#endif /* PCSC_FUNCS */ 926845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 927845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 928845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 929845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/** 930845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * eap_sm_buildIdentity - Build EAP-Identity/Response for the current network 931845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @sm: Pointer to EAP state machine allocated with eap_sm_init() 932845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @id: EAP identifier for the packet 933845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @len: Pointer to a variable that will be set to the length of the response 934845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @encrypted: Whether the packet is for encrypted tunnel (EAP phase 2) 935845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * Returns: Pointer to the allocated EAP-Identity/Response packet or %NULL on 936845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * failure 937845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * 938845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * This function allocates and builds an EAP-Identity/Response packet for the 939845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * current network. The caller is responsible for freeing the returned data. 940845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project */ 941845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectu8 * eap_sm_buildIdentity(struct eap_sm *sm, int id, size_t *len, 942845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project int encrypted) 943845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 944845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project struct wpa_ssid *config = eap_get_config(sm); 945845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project struct eap_hdr *resp; 946845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project u8 *pos; 947845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project const u8 *identity; 948845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project size_t identity_len; 949845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 950845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (config == NULL) { 951845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_WARNING, "EAP: buildIdentity: configuration " 952845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "was not available"); 953845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 954845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 955845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 956845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (sm->m && sm->m->get_identity && 957845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project (identity = sm->m->get_identity(sm, sm->eap_method_priv, 958845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project &identity_len)) != NULL) { 959845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_hexdump_ascii(MSG_DEBUG, "EAP: using method re-auth " 960845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "identity", identity, identity_len); 961845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } else if (!encrypted && config->anonymous_identity) { 962845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project identity = config->anonymous_identity; 963845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project identity_len = config->anonymous_identity_len; 964845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_hexdump_ascii(MSG_DEBUG, "EAP: using anonymous identity", 965845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project identity, identity_len); 966845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } else { 967845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project identity = config->identity; 968845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project identity_len = config->identity_len; 969845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_hexdump_ascii(MSG_DEBUG, "EAP: using real identity", 970845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project identity, identity_len); 971845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 972845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 973845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (identity == NULL) { 974845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_WARNING, "EAP: buildIdentity: identity " 975845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "configuration was not available"); 976845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (config->pcsc) { 977845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (eap_sm_get_scard_identity(sm, config) < 0) 978845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 979845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project identity = config->identity; 980845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project identity_len = config->identity_len; 981845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_hexdump_ascii(MSG_DEBUG, "permanent identity from " 982845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "IMSI", identity, identity_len); 983845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } else { 984845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project eap_sm_request_identity(sm); 985845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 986845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 987dc9507e42030320bf0a3dbb7d3f733d43bc94edeDmitry Shmidt } else if (config->pcsc) { 988dc9507e42030320bf0a3dbb7d3f733d43bc94edeDmitry Shmidt if (eap_sm_set_scard_pin(sm, config) < 0) 989dc9507e42030320bf0a3dbb7d3f733d43bc94edeDmitry Shmidt return NULL; 990845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 991845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 992845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project *len = sizeof(struct eap_hdr) + 1 + identity_len; 993845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project resp = os_malloc(*len); 994845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (resp == NULL) 995845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 996845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 997845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project resp->code = EAP_CODE_RESPONSE; 998845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project resp->identifier = id; 999845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project resp->length = host_to_be16(*len); 1000845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project pos = (u8 *) (resp + 1); 1001845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project *pos++ = EAP_TYPE_IDENTITY; 1002845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_memcpy(pos, identity, identity_len); 1003845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1004845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return (u8 *) resp; 1005845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 1006845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1007845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1008845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic void eap_sm_processNotify(struct eap_sm *sm, const u8 *req) 1009845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 1010845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project const struct eap_hdr *hdr = (const struct eap_hdr *) req; 1011845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project const u8 *pos; 1012845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project char *msg; 1013845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project size_t i, msg_len; 1014845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1015845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project pos = (const u8 *) (hdr + 1); 1016845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project pos++; 1017845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1018845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project msg_len = be_to_host16(hdr->length); 1019845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (msg_len < 5) 1020845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return; 1021845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project msg_len -= 5; 1022845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_hexdump_ascii(MSG_DEBUG, "EAP: EAP-Request Notification data", 1023845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project pos, msg_len); 1024845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1025845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project msg = os_malloc(msg_len + 1); 1026845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (msg == NULL) 1027845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return; 1028845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project for (i = 0; i < msg_len; i++) 1029845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project msg[i] = isprint(pos[i]) ? (char) pos[i] : '_'; 1030845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project msg[msg_len] = '\0'; 1031845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_msg(sm->msg_ctx, MSG_INFO, "%s%s", 1032845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project WPA_EVENT_EAP_NOTIFICATION, msg); 1033845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_free(msg); 1034845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 1035845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1036845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1037845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic u8 * eap_sm_buildNotify(int id, size_t *len) 1038845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 1039845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project struct eap_hdr *resp; 1040845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project u8 *pos; 1041845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1042845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP: Generating EAP-Response Notification"); 1043845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project *len = sizeof(struct eap_hdr) + 1; 1044845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project resp = os_malloc(*len); 1045845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (resp == NULL) 1046845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 1047845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1048845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project resp->code = EAP_CODE_RESPONSE; 1049845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project resp->identifier = id; 1050845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project resp->length = host_to_be16(*len); 1051845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project pos = (u8 *) (resp + 1); 1052845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project *pos = EAP_TYPE_NOTIFICATION; 1053845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1054845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return (u8 *) resp; 1055845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 1056845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1057845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1058845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic void eap_sm_parseEapReq(struct eap_sm *sm, const u8 *req, size_t len) 1059845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 1060845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project const struct eap_hdr *hdr; 1061845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project size_t plen; 1062845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project const u8 *pos; 1063845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1064845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->rxReq = sm->rxResp = sm->rxSuccess = sm->rxFailure = FALSE; 1065845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->reqId = 0; 1066845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->reqMethod = EAP_TYPE_NONE; 1067845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->reqVendor = EAP_VENDOR_IETF; 1068845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->reqVendorMethod = EAP_TYPE_NONE; 1069845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1070845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (req == NULL || len < sizeof(*hdr)) 1071845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return; 1072845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1073845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project hdr = (const struct eap_hdr *) req; 1074845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project plen = be_to_host16(hdr->length); 1075845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (plen > len) { 1076845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP: Ignored truncated EAP-Packet " 1077845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "(len=%lu plen=%lu)", 1078845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project (unsigned long) len, (unsigned long) plen); 1079845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return; 1080845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 1081845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1082845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->reqId = hdr->identifier; 1083845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1084845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (sm->workaround) { 1085845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project md5_vector(1, (const u8 **) &req, &plen, sm->req_md5); 1086845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 1087845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1088845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project switch (hdr->code) { 1089845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project case EAP_CODE_REQUEST: 1090845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (plen < sizeof(*hdr) + 1) { 1091845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP: Too short EAP-Request - " 1092845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "no Type field"); 1093845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return; 1094845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 1095845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->rxReq = TRUE; 1096845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project pos = (const u8 *) (hdr + 1); 1097845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->reqMethod = *pos++; 1098845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (sm->reqMethod == EAP_TYPE_EXPANDED) { 1099845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (plen < sizeof(*hdr) + 8) { 1100845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP: Ignored truncated " 1101845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "expanded EAP-Packet (plen=%lu)", 1102845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project (unsigned long) plen); 1103845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return; 1104845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 1105845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->reqVendor = WPA_GET_BE24(pos); 1106845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project pos += 3; 1107845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->reqVendorMethod = WPA_GET_BE32(pos); 1108845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 1109845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP: Received EAP-Request id=%d " 1110845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "method=%u vendor=%u vendorMethod=%u", 1111845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->reqId, sm->reqMethod, sm->reqVendor, 1112845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->reqVendorMethod); 1113845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project break; 1114845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project case EAP_CODE_RESPONSE: 1115845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (sm->selectedMethod == EAP_TYPE_LEAP) { 1116845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project /* 1117845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * LEAP differs from RFC 4137 by using reversed roles 1118845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * for mutual authentication and because of this, we 1119845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * need to accept EAP-Response frames if LEAP is used. 1120845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project */ 1121845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (plen < sizeof(*hdr) + 1) { 1122845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP: Too short " 1123845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "EAP-Response - no Type field"); 1124845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return; 1125845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 1126845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->rxResp = TRUE; 1127845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project pos = (const u8 *) (hdr + 1); 1128845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->reqMethod = *pos; 1129845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP: Received EAP-Response for " 1130845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "LEAP method=%d id=%d", 1131845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->reqMethod, sm->reqId); 1132845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project break; 1133845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 1134845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP: Ignored EAP-Response"); 1135845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project break; 1136845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project case EAP_CODE_SUCCESS: 1137845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP: Received EAP-Success"); 1138845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->rxSuccess = TRUE; 1139845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project break; 1140845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project case EAP_CODE_FAILURE: 1141845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP: Received EAP-Failure"); 1142845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->rxFailure = TRUE; 1143845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project break; 1144845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project default: 1145845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP: Ignored EAP-Packet with unknown " 1146845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "code %d", hdr->code); 1147845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project break; 1148845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 1149845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 1150845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1151845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1152845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/** 1153845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * eap_sm_init - Allocate and initialize EAP state machine 1154845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @eapol_ctx: Context data to be used with eapol_cb calls 1155845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @eapol_cb: Pointer to EAPOL callback functions 1156845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @msg_ctx: Context data for wpa_msg() calls 1157845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @conf: EAP configuration 1158845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * Returns: Pointer to the allocated EAP state machine or %NULL on failure 1159845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * 1160845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * This function allocates and initializes an EAP state machine. In addition, 1161845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * this initializes TLS library for the new EAP state machine. eapol_cb pointer 1162845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * will be in use until eap_sm_deinit() is used to deinitialize this EAP state 1163845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * machine. Consequently, the caller must make sure that this data structure 1164845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * remains alive while the EAP state machine is active. 1165845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project */ 1166845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstruct eap_sm * eap_sm_init(void *eapol_ctx, struct eapol_callbacks *eapol_cb, 1167845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project void *msg_ctx, struct eap_config *conf) 1168845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 1169845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project struct eap_sm *sm; 1170845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project struct tls_config tlsconf; 1171845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1172845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm = os_zalloc(sizeof(*sm)); 1173845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (sm == NULL) 1174845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 1175845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->eapol_ctx = eapol_ctx; 1176845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->eapol_cb = eapol_cb; 1177845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->msg_ctx = msg_ctx; 1178845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->ClientTimeout = 60; 1179845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1180845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_memset(&tlsconf, 0, sizeof(tlsconf)); 1181845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project tlsconf.opensc_engine_path = conf->opensc_engine_path; 1182845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project tlsconf.pkcs11_engine_path = conf->pkcs11_engine_path; 1183845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project tlsconf.pkcs11_module_path = conf->pkcs11_module_path; 1184845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->ssl_ctx = tls_init(&tlsconf); 1185845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (sm->ssl_ctx == NULL) { 1186845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_WARNING, "SSL: Failed to initialize TLS " 1187845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "context."); 1188845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_free(sm); 1189845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 1190845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 1191845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1192845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return sm; 1193845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 1194845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1195845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1196845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/** 1197845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * eap_sm_deinit - Deinitialize and free an EAP state machine 1198845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @sm: Pointer to EAP state machine allocated with eap_sm_init() 1199845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * 1200845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * This function deinitializes EAP state machine and frees all allocated 1201845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * resources. 1202845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project */ 1203845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectvoid eap_sm_deinit(struct eap_sm *sm) 1204845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 1205845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (sm == NULL) 1206845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return; 1207845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project eap_deinit_prev_method(sm, "EAP deinit"); 1208845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project eap_sm_abort(sm); 1209845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project tls_deinit(sm->ssl_ctx); 1210845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_free(sm); 1211845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 1212845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1213845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1214845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/** 1215845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * eap_sm_step - Step EAP state machine 1216845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @sm: Pointer to EAP state machine allocated with eap_sm_init() 1217845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * Returns: 1 if EAP state was changed or 0 if not 1218845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * 1219845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * This function advances EAP state machine to a new state to match with the 1220845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * current variables. This should be called whenever variables used by the EAP 1221845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * state machine have changed. 1222845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project */ 1223845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectint eap_sm_step(struct eap_sm *sm) 1224845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 1225845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project int res = 0; 1226845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project do { 1227845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->changed = FALSE; 1228845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project SM_STEP_RUN(EAP); 1229845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (sm->changed) 1230845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project res = 1; 1231845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } while (sm->changed); 1232845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return res; 1233845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 1234845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1235845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1236845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/** 1237845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * eap_sm_abort - Abort EAP authentication 1238845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @sm: Pointer to EAP state machine allocated with eap_sm_init() 1239845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * 1240845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * Release system resources that have been allocated for the authentication 1241845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * session without fully deinitializing the EAP state machine. 1242845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project */ 1243845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectvoid eap_sm_abort(struct eap_sm *sm) 1244845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 1245845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_free(sm->lastRespData); 1246845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->lastRespData = NULL; 1247845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_free(sm->eapRespData); 1248845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->eapRespData = NULL; 1249845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_free(sm->eapKeyData); 1250845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->eapKeyData = NULL; 1251845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1252845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project /* This is not clearly specified in the EAP statemachines draft, but 1253845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * it seems necessary to make sure that some of the EAPOL variables get 1254845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * cleared for the next authentication. */ 1255845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project eapol_set_bool(sm, EAPOL_eapSuccess, FALSE); 1256845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 1257845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1258845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1259845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#ifdef CONFIG_CTRL_IFACE 1260845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic const char * eap_sm_state_txt(int state) 1261845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 1262845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project switch (state) { 1263845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project case EAP_INITIALIZE: 1264845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return "INITIALIZE"; 1265845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project case EAP_DISABLED: 1266845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return "DISABLED"; 1267845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project case EAP_IDLE: 1268845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return "IDLE"; 1269845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project case EAP_RECEIVED: 1270845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return "RECEIVED"; 1271845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project case EAP_GET_METHOD: 1272845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return "GET_METHOD"; 1273845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project case EAP_METHOD: 1274845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return "METHOD"; 1275845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project case EAP_SEND_RESPONSE: 1276845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return "SEND_RESPONSE"; 1277845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project case EAP_DISCARD: 1278845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return "DISCARD"; 1279845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project case EAP_IDENTITY: 1280845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return "IDENTITY"; 1281845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project case EAP_NOTIFICATION: 1282845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return "NOTIFICATION"; 1283845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project case EAP_RETRANSMIT: 1284845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return "RETRANSMIT"; 1285845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project case EAP_SUCCESS: 1286845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return "SUCCESS"; 1287845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project case EAP_FAILURE: 1288845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return "FAILURE"; 1289845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project default: 1290845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return "UNKNOWN"; 1291845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 1292845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 1293845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#endif /* CONFIG_CTRL_IFACE */ 1294845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1295845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1296845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#if defined(CONFIG_CTRL_IFACE) || !defined(CONFIG_NO_STDOUT_DEBUG) 1297845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic const char * eap_sm_method_state_txt(EapMethodState state) 1298845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 1299845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project switch (state) { 1300845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project case METHOD_NONE: 1301845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return "NONE"; 1302845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project case METHOD_INIT: 1303845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return "INIT"; 1304845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project case METHOD_CONT: 1305845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return "CONT"; 1306845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project case METHOD_MAY_CONT: 1307845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return "MAY_CONT"; 1308845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project case METHOD_DONE: 1309845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return "DONE"; 1310845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project default: 1311845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return "UNKNOWN"; 1312845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 1313845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 1314845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1315845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1316845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic const char * eap_sm_decision_txt(EapDecision decision) 1317845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 1318845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project switch (decision) { 1319845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project case DECISION_FAIL: 1320845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return "FAIL"; 1321845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project case DECISION_COND_SUCC: 1322845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return "COND_SUCC"; 1323845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project case DECISION_UNCOND_SUCC: 1324845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return "UNCOND_SUCC"; 1325845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project default: 1326845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return "UNKNOWN"; 1327845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 1328845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 1329845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#endif /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */ 1330845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1331845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1332845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#ifdef CONFIG_CTRL_IFACE 1333845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1334845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/** 1335845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * eap_sm_get_status - Get EAP state machine status 1336845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @sm: Pointer to EAP state machine allocated with eap_sm_init() 1337845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @buf: Buffer for status information 1338845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @buflen: Maximum buffer length 1339845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @verbose: Whether to include verbose status information 1340845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * Returns: Number of bytes written to buf. 1341845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * 1342845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * Query EAP state machine for status information. This function fills in a 1343845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * text area with current status information from the EAPOL state machine. If 1344845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * the buffer (buf) is not large enough, status information will be truncated 1345845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * to fit the buffer. 1346845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project */ 1347845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectint eap_sm_get_status(struct eap_sm *sm, char *buf, size_t buflen, int verbose) 1348845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 1349845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project int len, ret; 1350845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1351845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (sm == NULL) 1352845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return 0; 1353845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1354845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project len = os_snprintf(buf, buflen, 1355845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "EAP state=%s\n", 1356845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project eap_sm_state_txt(sm->EAP_state)); 1357845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (len < 0 || (size_t) len >= buflen) 1358845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return 0; 1359845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1360845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (sm->selectedMethod != EAP_TYPE_NONE) { 1361845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project const char *name; 1362845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (sm->m) { 1363845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project name = sm->m->name; 1364845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } else { 1365845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project const struct eap_method *m = 1366845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project eap_sm_get_eap_methods(EAP_VENDOR_IETF, 1367845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->selectedMethod); 1368845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (m) 1369845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project name = m->name; 1370845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project else 1371845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project name = "?"; 1372845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 1373845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project ret = os_snprintf(buf + len, buflen - len, 1374845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "selectedMethod=%d (EAP-%s)\n", 1375845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->selectedMethod, name); 1376845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (ret < 0 || (size_t) ret >= buflen - len) 1377845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return len; 1378845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project len += ret; 1379845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1380845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (sm->m && sm->m->get_status) { 1381845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project len += sm->m->get_status(sm, sm->eap_method_priv, 1382845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project buf + len, buflen - len, 1383845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project verbose); 1384845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 1385845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 1386845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1387845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (verbose) { 1388845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project ret = os_snprintf(buf + len, buflen - len, 1389845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "reqMethod=%d\n" 1390845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "methodState=%s\n" 1391845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "decision=%s\n" 1392845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "ClientTimeout=%d\n", 1393845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->reqMethod, 1394845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project eap_sm_method_state_txt(sm->methodState), 1395845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project eap_sm_decision_txt(sm->decision), 1396845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->ClientTimeout); 1397845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (ret < 0 || (size_t) ret >= buflen - len) 1398845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return len; 1399845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project len += ret; 1400845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 1401845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1402845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return len; 1403845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 1404845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#endif /* CONFIG_CTRL_IFACE */ 1405845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1406845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1407845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#if defined(CONFIG_CTRL_IFACE) || !defined(CONFIG_NO_STDOUT_DEBUG) 1408845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projecttypedef enum { 1409845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project TYPE_IDENTITY, TYPE_PASSWORD, TYPE_OTP, TYPE_PIN, TYPE_NEW_PASSWORD, 1410845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project TYPE_PASSPHRASE 1411845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} eap_ctrl_req_type; 1412845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1413845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic void eap_sm_request(struct eap_sm *sm, eap_ctrl_req_type type, 1414845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project const char *msg, size_t msglen) 1415845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 1416845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project struct wpa_ssid *config; 1417845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project char *buf; 1418845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project size_t buflen; 1419845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project int len; 1420845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project char *field; 1421845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project char *txt, *tmp; 1422845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1423845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (sm == NULL) 1424845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return; 1425845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project config = eap_get_config(sm); 1426845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (config == NULL) 1427845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return; 1428845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1429845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project switch (type) { 1430845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project case TYPE_IDENTITY: 1431845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project field = "IDENTITY"; 1432845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project txt = "Identity"; 1433845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project config->pending_req_identity++; 1434845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project break; 1435845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project case TYPE_PASSWORD: 1436845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project field = "PASSWORD"; 1437845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project txt = "Password"; 1438845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project config->pending_req_password++; 1439845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project break; 1440845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project case TYPE_NEW_PASSWORD: 1441845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project field = "NEW_PASSWORD"; 1442845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project txt = "New Password"; 1443845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project config->pending_req_new_password++; 1444845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project break; 1445845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project case TYPE_PIN: 1446845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project field = "PIN"; 1447845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project txt = "PIN"; 1448845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project config->pending_req_pin++; 1449845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project break; 1450845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project case TYPE_OTP: 1451845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project field = "OTP"; 1452845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (msg) { 1453845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project tmp = os_malloc(msglen + 3); 1454845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (tmp == NULL) 1455845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return; 1456845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project tmp[0] = '['; 1457845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_memcpy(tmp + 1, msg, msglen); 1458845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project tmp[msglen + 1] = ']'; 1459845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project tmp[msglen + 2] = '\0'; 1460845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project txt = tmp; 1461845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_free(config->pending_req_otp); 1462845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project config->pending_req_otp = tmp; 1463845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project config->pending_req_otp_len = msglen + 3; 1464845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } else { 1465845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (config->pending_req_otp == NULL) 1466845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return; 1467845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project txt = config->pending_req_otp; 1468845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 1469845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project break; 1470845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project case TYPE_PASSPHRASE: 1471845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project field = "PASSPHRASE"; 1472845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project txt = "Private key passphrase"; 1473845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project config->pending_req_passphrase++; 1474845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project break; 1475845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project default: 1476845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return; 1477845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 1478845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1479845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project buflen = 100 + os_strlen(txt) + config->ssid_len; 1480845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project buf = os_malloc(buflen); 1481845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (buf == NULL) 1482845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return; 1483845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project len = os_snprintf(buf, buflen, 1484845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project WPA_CTRL_REQ "%s-%d:%s needed for SSID ", 1485845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project field, config->id, txt); 1486845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (len < 0 || (size_t) len >= buflen) { 1487845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_free(buf); 1488845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return; 1489845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 1490845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (config->ssid && buflen > len + config->ssid_len) { 1491845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_memcpy(buf + len, config->ssid, config->ssid_len); 1492845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project len += config->ssid_len; 1493845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project buf[len] = '\0'; 1494845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 1495845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project buf[buflen - 1] = '\0'; 1496845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_msg(sm->msg_ctx, MSG_INFO, "%s", buf); 1497845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_free(buf); 1498845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 1499845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#else /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */ 1500845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#define eap_sm_request(sm, type, msg, msglen) do { } while (0) 1501845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#endif /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */ 1502845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1503845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1504845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/** 1505845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * eap_sm_request_identity - Request identity from user (ctrl_iface) 1506845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @sm: Pointer to EAP state machine allocated with eap_sm_init() 1507845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * 1508845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * EAP methods can call this function to request identity information for the 1509845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * current network. This is normally called when the identity is not included 1510845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * in the network configuration. The request will be sent to monitor programs 1511845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * through the control interface. 1512845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project */ 1513845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectvoid eap_sm_request_identity(struct eap_sm *sm) 1514845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 1515845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project eap_sm_request(sm, TYPE_IDENTITY, NULL, 0); 1516845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 1517845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1518845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1519845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/** 1520845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * eap_sm_request_password - Request password from user (ctrl_iface) 1521845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @sm: Pointer to EAP state machine allocated with eap_sm_init() 1522845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * 1523845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * EAP methods can call this function to request password information for the 1524845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * current network. This is normally called when the password is not included 1525845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * in the network configuration. The request will be sent to monitor programs 1526845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * through the control interface. 1527845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project */ 1528845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectvoid eap_sm_request_password(struct eap_sm *sm) 1529845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 1530845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project eap_sm_request(sm, TYPE_PASSWORD, NULL, 0); 1531845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 1532845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1533845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1534845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/** 1535845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * eap_sm_request_new_password - Request new password from user (ctrl_iface) 1536845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @sm: Pointer to EAP state machine allocated with eap_sm_init() 1537845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * 1538845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * EAP methods can call this function to request new password information for 1539845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * the current network. This is normally called when the EAP method indicates 1540845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * that the current password has expired and password change is required. The 1541845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * request will be sent to monitor programs through the control interface. 1542845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project */ 1543845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectvoid eap_sm_request_new_password(struct eap_sm *sm) 1544845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 1545845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project eap_sm_request(sm, TYPE_NEW_PASSWORD, NULL, 0); 1546845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 1547845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1548845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1549845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/** 1550845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * eap_sm_request_pin - Request SIM or smart card PIN from user (ctrl_iface) 1551845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @sm: Pointer to EAP state machine allocated with eap_sm_init() 1552845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * 1553845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * EAP methods can call this function to request SIM or smart card PIN 1554845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * information for the current network. This is normally called when the PIN is 1555845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * not included in the network configuration. The request will be sent to 1556845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * monitor programs through the control interface. 1557845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project */ 1558845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectvoid eap_sm_request_pin(struct eap_sm *sm) 1559845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 1560845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project eap_sm_request(sm, TYPE_PIN, NULL, 0); 1561845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 1562845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1563845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1564845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/** 1565845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * eap_sm_request_otp - Request one time password from user (ctrl_iface) 1566845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @sm: Pointer to EAP state machine allocated with eap_sm_init() 1567845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @msg: Message to be displayed to the user when asking for OTP 1568845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @msg_len: Length of the user displayable message 1569845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * 1570845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * EAP methods can call this function to request open time password (OTP) for 1571845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * the current network. The request will be sent to monitor programs through 1572845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * the control interface. 1573845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project */ 1574845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectvoid eap_sm_request_otp(struct eap_sm *sm, const char *msg, size_t msg_len) 1575845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 1576845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project eap_sm_request(sm, TYPE_OTP, msg, msg_len); 1577845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 1578845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1579845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1580845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/** 1581845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * eap_sm_request_passphrase - Request passphrase from user (ctrl_iface) 1582845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @sm: Pointer to EAP state machine allocated with eap_sm_init() 1583845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * 1584845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * EAP methods can call this function to request passphrase for a private key 1585845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * for the current network. This is normally called when the passphrase is not 1586845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * included in the network configuration. The request will be sent to monitor 1587845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * programs through the control interface. 1588845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project */ 1589845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectvoid eap_sm_request_passphrase(struct eap_sm *sm) 1590845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 1591845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project eap_sm_request(sm, TYPE_PASSPHRASE, NULL, 0); 1592845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 1593845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1594845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1595845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/** 1596845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * eap_sm_notify_ctrl_attached - Notification of attached monitor 1597845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @sm: Pointer to EAP state machine allocated with eap_sm_init() 1598845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * 1599845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * Notify EAP state machines that a monitor was attached to the control 1600845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * interface to trigger re-sending of pending requests for user input. 1601845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project */ 1602845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectvoid eap_sm_notify_ctrl_attached(struct eap_sm *sm) 1603845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 1604845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project struct wpa_ssid *config = eap_get_config(sm); 1605845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1606845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (config == NULL) 1607845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return; 1608845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1609845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project /* Re-send any pending requests for user data since a new control 1610845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * interface was added. This handles cases where the EAP authentication 1611845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * starts immediately after system startup when the user interface is 1612845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * not yet running. */ 1613845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (config->pending_req_identity) 1614845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project eap_sm_request_identity(sm); 1615845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (config->pending_req_password) 1616845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project eap_sm_request_password(sm); 1617845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (config->pending_req_new_password) 1618845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project eap_sm_request_new_password(sm); 1619845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (config->pending_req_otp) 1620845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project eap_sm_request_otp(sm, NULL, 0); 1621845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (config->pending_req_pin) 1622845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project eap_sm_request_pin(sm); 1623845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (config->pending_req_passphrase) 1624845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project eap_sm_request_passphrase(sm); 1625845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 1626845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1627845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1628845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic int eap_allowed_phase2_type(int vendor, int type) 1629845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 1630845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (vendor != EAP_VENDOR_IETF) 1631845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return 0; 1632845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return type != EAP_TYPE_PEAP && type != EAP_TYPE_TTLS && 1633845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project type != EAP_TYPE_FAST; 1634845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 1635845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1636845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1637845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/** 1638845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * eap_get_phase2_type - Get EAP type for the given EAP phase 2 method name 1639845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @name: EAP method name, e.g., MD5 1640845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @vendor: Buffer for returning EAP Vendor-Id 1641845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * Returns: EAP method type or %EAP_TYPE_NONE if not found 1642845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * 1643845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * This function maps EAP type names into EAP type numbers that are allowed for 1644845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * Phase 2, i.e., for tunneled authentication. Phase 2 is used, e.g., with 1645845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * EAP-PEAP, EAP-TTLS, and EAP-FAST. 1646845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project */ 1647845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectu32 eap_get_phase2_type(const char *name, int *vendor) 1648845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 1649845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project int v; 1650845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project u8 type = eap_get_type(name, &v); 1651845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (eap_allowed_phase2_type(v, type)) { 1652845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project *vendor = v; 1653845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return type; 1654845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 1655845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project *vendor = EAP_VENDOR_IETF; 1656845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return EAP_TYPE_NONE; 1657845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 1658845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1659845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1660845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/** 1661845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * eap_get_phase2_types - Get list of allowed EAP phase 2 types 1662845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @config: Pointer to a network configuration 1663845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @count: Pointer to a variable to be filled with number of returned EAP types 1664845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * Returns: Pointer to allocated type list or %NULL on failure 1665845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * 1666845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * This function generates an array of allowed EAP phase 2 (tunneled) types for 1667845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * the given network configuration. 1668845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project */ 1669845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstruct eap_method_type * eap_get_phase2_types(struct wpa_ssid *config, 1670845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project size_t *count) 1671845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 1672845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project struct eap_method_type *buf; 1673845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project u32 method; 1674845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project int vendor; 1675845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project size_t mcount; 1676845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project const struct eap_method *methods, *m; 1677845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1678845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project methods = eap_peer_get_methods(&mcount); 1679845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (methods == NULL) 1680845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 1681845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project *count = 0; 1682845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project buf = os_malloc(mcount * sizeof(struct eap_method_type)); 1683845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (buf == NULL) 1684845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 1685845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1686845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project for (m = methods; m; m = m->next) { 1687845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project vendor = m->vendor; 1688845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project method = m->method; 1689845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (eap_allowed_phase2_type(vendor, method)) { 1690845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (vendor == EAP_VENDOR_IETF && 1691845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project method == EAP_TYPE_TLS && config && 1692845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project config->private_key2 == NULL) 1693845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project continue; 1694845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project buf[*count].vendor = vendor; 1695845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project buf[*count].method = method; 1696845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project (*count)++; 1697845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 1698845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 1699845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1700845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return buf; 1701845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 1702845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1703845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1704845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/** 1705845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * eap_set_fast_reauth - Update fast_reauth setting 1706845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @sm: Pointer to EAP state machine allocated with eap_sm_init() 1707845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @enabled: 1 = Fast reauthentication is enabled, 0 = Disabled 1708845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project */ 1709845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectvoid eap_set_fast_reauth(struct eap_sm *sm, int enabled) 1710845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 1711845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->fast_reauth = enabled; 1712845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 1713845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1714845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1715845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/** 1716845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * eap_set_workaround - Update EAP workarounds setting 1717845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @sm: Pointer to EAP state machine allocated with eap_sm_init() 1718845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @workaround: 1 = Enable EAP workarounds, 0 = Disable EAP workarounds 1719845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project */ 1720845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectvoid eap_set_workaround(struct eap_sm *sm, unsigned int workaround) 1721845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 1722845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->workaround = workaround; 1723845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 1724845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1725845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1726845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/** 1727845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * eap_get_config - Get current network configuration 1728845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @sm: Pointer to EAP state machine allocated with eap_sm_init() 1729845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * Returns: Pointer to the current network configuration or %NULL if not found 1730845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * 1731845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * EAP peer methods should avoid using this function if they can use other 1732845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * access functions, like eap_get_config_identity() and 1733845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * eap_get_config_password(), that do not require direct access to 1734845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * struct wpa_ssid. 1735845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project */ 1736845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstruct wpa_ssid * eap_get_config(struct eap_sm *sm) 1737845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 1738845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return sm->eapol_cb->get_config(sm->eapol_ctx); 1739845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 1740845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1741845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1742845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/** 1743845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * eap_get_config_password - Get identity from the network configuration 1744845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @sm: Pointer to EAP state machine allocated with eap_sm_init() 1745845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @len: Buffer for the length of the identity 1746845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * Returns: Pointer to the identity or %NULL if not found 1747845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project */ 1748845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectconst u8 * eap_get_config_identity(struct eap_sm *sm, size_t *len) 1749845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 1750845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project struct wpa_ssid *config = eap_get_config(sm); 1751845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (config == NULL) 1752845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 1753845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project *len = config->identity_len; 1754845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return config->identity; 1755845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 1756845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1757845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1758845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/** 1759845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * eap_get_config_password - Get password from the network configuration 1760845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @sm: Pointer to EAP state machine allocated with eap_sm_init() 1761845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @len: Buffer for the length of the password 1762845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * Returns: Pointer to the password or %NULL if not found 1763845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project */ 1764845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectconst u8 * eap_get_config_password(struct eap_sm *sm, size_t *len) 1765845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 1766845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project struct wpa_ssid *config = eap_get_config(sm); 1767845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (config == NULL) 1768845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 1769845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project *len = config->password_len; 1770845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return config->password; 1771845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 1772845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1773845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1774845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/** 1775845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * eap_get_config_new_password - Get new password from network configuration 1776845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @sm: Pointer to EAP state machine allocated with eap_sm_init() 1777845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @len: Buffer for the length of the new password 1778845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * Returns: Pointer to the new password or %NULL if not found 1779845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project */ 1780845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectconst u8 * eap_get_config_new_password(struct eap_sm *sm, size_t *len) 1781845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 1782845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project struct wpa_ssid *config = eap_get_config(sm); 1783845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (config == NULL) 1784845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 1785845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project *len = config->new_password_len; 1786845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return config->new_password; 1787845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 1788845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1789845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1790845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/** 1791845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * eap_get_config_otp - Get one-time password from the network configuration 1792845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @sm: Pointer to EAP state machine allocated with eap_sm_init() 1793845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @len: Buffer for the length of the one-time password 1794845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * Returns: Pointer to the one-time password or %NULL if not found 1795845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project */ 1796845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectconst u8 * eap_get_config_otp(struct eap_sm *sm, size_t *len) 1797845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 1798845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project struct wpa_ssid *config = eap_get_config(sm); 1799845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (config == NULL) 1800845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 1801845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project *len = config->otp_len; 1802845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return config->otp; 1803845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 1804845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1805845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1806845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/** 1807845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * eap_clear_config_otp - Clear used one-time password 1808845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @sm: Pointer to EAP state machine allocated with eap_sm_init() 1809845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * 1810845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * This function clears a used one-time password (OTP) from the current network 1811845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * configuration. This should be called when the OTP has been used and is not 1812845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * needed anymore. 1813845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project */ 1814845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectvoid eap_clear_config_otp(struct eap_sm *sm) 1815845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 1816845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project struct wpa_ssid *config = eap_get_config(sm); 1817845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (config == NULL) 1818845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return; 1819845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_memset(config->otp, 0, config->otp_len); 1820845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_free(config->otp); 1821845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project config->otp = NULL; 1822845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project config->otp_len = 0; 1823845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 1824845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1825845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1826845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/** 1827845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * eap_key_available - Get key availability (eapKeyAvailable variable) 1828845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @sm: Pointer to EAP state machine allocated with eap_sm_init() 1829845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * Returns: 1 if EAP keying material is available, 0 if not 1830845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project */ 1831845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectint eap_key_available(struct eap_sm *sm) 1832845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 1833845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return sm ? sm->eapKeyAvailable : 0; 1834845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 1835845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1836845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1837845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/** 1838845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * eap_notify_success - Notify EAP state machine about external success trigger 1839845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @sm: Pointer to EAP state machine allocated with eap_sm_init() 1840845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * 1841845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * This function is called when external event, e.g., successful completion of 1842845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * WPA-PSK key handshake, is indicating that EAP state machine should move to 1843845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * success state. This is mainly used with security modes that do not use EAP 1844845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * state machine (e.g., WPA-PSK). 1845845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project */ 1846845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectvoid eap_notify_success(struct eap_sm *sm) 1847845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 1848845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (sm) { 1849845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->decision = DECISION_COND_SUCC; 1850845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->EAP_state = EAP_SUCCESS; 1851845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 1852845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 1853845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1854845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1855845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/** 1856845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * eap_notify_lower_layer_success - Notification of lower layer success 1857845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @sm: Pointer to EAP state machine allocated with eap_sm_init() 1858845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * 1859845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * Notify EAP state machines that a lower layer has detected a successful 1860845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * authentication. This is used to recover from dropped EAP-Success messages. 1861845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project */ 1862845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectvoid eap_notify_lower_layer_success(struct eap_sm *sm) 1863845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 1864845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (sm == NULL) 1865845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return; 1866845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1867845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (eapol_get_bool(sm, EAPOL_eapSuccess) || 1868845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->decision == DECISION_FAIL || 1869845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project (sm->methodState != METHOD_MAY_CONT && 1870845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->methodState != METHOD_DONE)) 1871845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return; 1872845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1873845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (sm->eapKeyData != NULL) 1874845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->eapKeyAvailable = TRUE; 1875845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project eapol_set_bool(sm, EAPOL_eapSuccess, TRUE); 1876845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_SUCCESS 1877845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "EAP authentication completed successfully (based on lower " 1878845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "layer success)"); 1879845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 1880845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1881845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1882845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/** 1883845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * eap_get_eapKeyData - Get master session key (MSK) from EAP state machine 1884845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @sm: Pointer to EAP state machine allocated with eap_sm_init() 1885845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @len: Pointer to variable that will be set to number of bytes in the key 1886845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * Returns: Pointer to the EAP keying data or %NULL on failure 1887845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * 1888845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * Fetch EAP keying material (MSK, eapKeyData) from the EAP state machine. The 1889845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * key is available only after a successful authentication. EAP state machine 1890845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * continues to manage the key data and the caller must not change or free the 1891845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * returned data. 1892845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project */ 1893845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectconst u8 * eap_get_eapKeyData(struct eap_sm *sm, size_t *len) 1894845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 1895845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (sm == NULL || sm->eapKeyData == NULL) { 1896845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project *len = 0; 1897845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 1898845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 1899845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1900845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project *len = sm->eapKeyDataLen; 1901845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return sm->eapKeyData; 1902845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 1903845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1904845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1905845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/** 1906845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * eap_get_eapKeyData - Get EAP response data 1907845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @sm: Pointer to EAP state machine allocated with eap_sm_init() 1908845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @len: Pointer to variable that will be set to the length of the response 1909845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * Returns: Pointer to the EAP response (eapRespData) or %NULL on failure 1910845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * 1911845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * Fetch EAP response (eapRespData) from the EAP state machine. This data is 1912845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * available when EAP state machine has processed an incoming EAP request. The 1913845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * EAP state machine does not maintain a reference to the response after this 1914845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * function is called and the caller is responsible for freeing the data. 1915845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project */ 1916845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectu8 * eap_get_eapRespData(struct eap_sm *sm, size_t *len) 1917845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 1918845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project u8 *resp; 1919845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1920845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (sm == NULL || sm->eapRespData == NULL) { 1921845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project *len = 0; 1922845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 1923845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 1924845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1925845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project resp = sm->eapRespData; 1926845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project *len = sm->eapRespDataLen; 1927845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->eapRespData = NULL; 1928845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->eapRespDataLen = 0; 1929845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1930845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return resp; 1931845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 1932845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1933845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1934845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/** 1935845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * eap_sm_register_scard_ctx - Notification of smart card context 1936845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @sm: Pointer to EAP state machine allocated with eap_sm_init() 1937845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @ctx: Context data for smart card operations 1938845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * 1939845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * Notify EAP state machines of context data for smart card operations. This 1940845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * context data will be used as a parameter for scard_*() functions. 1941845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project */ 1942845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectvoid eap_register_scard_ctx(struct eap_sm *sm, void *ctx) 1943845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 1944845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (sm) 1945845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->scard_ctx = ctx; 1946845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 1947845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1948845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1949845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/** 1950845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * eap_hdr_validate - Validate EAP header 1951845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @vendor: Expected EAP Vendor-Id (0 = IETF) 1952845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @eap_type: Expected EAP type number 1953845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @msg: EAP frame (starting with EAP header) 1954845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @msglen: Length of msg 1955845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @plen: Pointer to variable to contain the returned payload length 1956845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * Returns: Pointer to EAP payload (after type field), or %NULL on failure 1957845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * 1958845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * This is a helper function for EAP method implementations. This is usually 1959845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * called in the beginning of struct eap_method::process() function to verify 1960845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * that the received EAP request packet has a valid header. This function is 1961845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * able to process both legacy and expanded EAP headers and in most cases, the 1962845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * caller can just use the returned payload pointer (into *plen) for processing 1963845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * the payload regardless of whether the packet used the expanded EAP header or 1964845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * not. 1965845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project */ 1966845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectconst u8 * eap_hdr_validate(int vendor, EapType eap_type, 1967845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project const u8 *msg, size_t msglen, size_t *plen) 1968845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 1969845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project const struct eap_hdr *hdr; 1970845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project const u8 *pos; 1971845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project size_t len; 1972845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1973845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project hdr = (const struct eap_hdr *) msg; 1974845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1975845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (msglen < sizeof(*hdr)) { 1976845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_INFO, "EAP: Too short EAP frame"); 1977845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 1978845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 1979845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1980845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project len = be_to_host16(hdr->length); 1981845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (len < sizeof(*hdr) + 1 || len > msglen) { 1982845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_INFO, "EAP: Invalid EAP length"); 1983845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 1984845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 1985845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1986845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project pos = (const u8 *) (hdr + 1); 1987845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 1988845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (*pos == EAP_TYPE_EXPANDED) { 1989845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project int exp_vendor; 1990845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project u32 exp_type; 1991845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (len < sizeof(*hdr) + 8) { 1992845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_INFO, "EAP: Invalid expanded EAP " 1993845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "length"); 1994845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 1995845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 1996845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project pos++; 1997845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project exp_vendor = WPA_GET_BE24(pos); 1998845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project pos += 3; 1999845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project exp_type = WPA_GET_BE32(pos); 2000845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project pos += 4; 2001845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (exp_vendor != vendor || exp_type != (u32) eap_type) { 2002845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_INFO, "EAP: Invalid expanded frame " 2003845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "type"); 2004845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 2005845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 2006845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 2007845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project *plen = len - sizeof(*hdr) - 8; 2008845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return pos; 2009845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } else { 2010845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (vendor != EAP_VENDOR_IETF || *pos != eap_type) { 2011845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_INFO, "EAP: Invalid frame type"); 2012845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 2013845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 2014845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project *plen = len - sizeof(*hdr) - 1; 2015845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return pos + 1; 2016845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 2017845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 2018845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 2019845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 2020845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/** 2021845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * eap_set_config_blob - Set or add a named configuration blob 2022845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @sm: Pointer to EAP state machine allocated with eap_sm_init() 2023845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @blob: New value for the blob 2024845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * 2025845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * Adds a new configuration blob or replaces the current value of an existing 2026845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * blob. 2027845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project */ 2028845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectvoid eap_set_config_blob(struct eap_sm *sm, struct wpa_config_blob *blob) 2029845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 2030845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->eapol_cb->set_config_blob(sm->eapol_ctx, blob); 2031845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 2032845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 2033845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 2034845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/** 2035845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * eap_get_config_blob - Get a named configuration blob 2036845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @sm: Pointer to EAP state machine allocated with eap_sm_init() 2037845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @name: Name of the blob 2038845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * Returns: Pointer to blob data or %NULL if not found 2039845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project */ 2040845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectconst struct wpa_config_blob * eap_get_config_blob(struct eap_sm *sm, 2041845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project const char *name) 2042845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 2043845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return sm->eapol_cb->get_config_blob(sm->eapol_ctx, name); 2044845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 2045845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 2046845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 2047845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/** 2048845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * eap_set_force_disabled - Set force_disabled flag 2049845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @sm: Pointer to EAP state machine allocated with eap_sm_init() 2050845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @disabled: 1 = EAP disabled, 0 = EAP enabled 2051845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * 2052845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * This function is used to force EAP state machine to be disabled when it is 2053845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * not in use (e.g., with WPA-PSK or plaintext connections). 2054845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project */ 2055845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectvoid eap_set_force_disabled(struct eap_sm *sm, int disabled) 2056845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 2057845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->force_disabled = disabled; 2058845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 2059845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 2060845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 2061845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/** 2062845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * eap_msg_alloc - Allocate a buffer for an EAP message 2063845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @vendor: Vendor-Id (0 = IETF) 2064845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @type: EAP type 2065845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @len: Buffer for returning message length 2066845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @payload_len: Payload length in bytes (data after Type) 2067845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @code: Message Code (EAP_CODE_*) 2068845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @identifier: Identifier 2069845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @payload: Pointer to payload pointer that will be set to point to the 2070845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * beginning of the payload or %NULL if payload pointer is not needed 2071845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * Returns: Pointer to the allocated message buffer or %NULL on error 2072845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * 2073845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * This function can be used to allocate a buffer for an EAP message and fill 2074845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * in the EAP header. This function is automatically using expanded EAP header 2075845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * if the selected Vendor-Id is not IETF. In other words, most EAP methods do 2076845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * not need to separately select which header type to use when using this 2077845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * function to allocate the message buffers. 2078845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project */ 2079845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstruct eap_hdr * eap_msg_alloc(int vendor, EapType type, size_t *len, 2080845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project size_t payload_len, u8 code, u8 identifier, 2081845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project u8 **payload) 2082845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 2083845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project struct eap_hdr *hdr; 2084845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project u8 *pos; 2085845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 2086845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project *len = sizeof(struct eap_hdr) + (vendor == EAP_VENDOR_IETF ? 1 : 8) + 2087845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project payload_len; 2088845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project hdr = os_malloc(*len); 2089845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (hdr) { 2090845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project hdr->code = code; 2091845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project hdr->identifier = identifier; 2092845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project hdr->length = host_to_be16(*len); 2093845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project pos = (u8 *) (hdr + 1); 2094845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (vendor == EAP_VENDOR_IETF) { 2095845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project *pos++ = type; 2096845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } else { 2097845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project *pos++ = EAP_TYPE_EXPANDED; 2098845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project WPA_PUT_BE24(pos, vendor); 2099845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project pos += 3; 2100845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project WPA_PUT_BE32(pos, type); 2101845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project pos += 4; 2102845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 2103845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (payload) 2104845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project *payload = pos; 2105845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 2106845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 2107845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return hdr; 2108845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 2109845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 2110845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 2111845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project /** 2112845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * eap_notify_pending - Notify that EAP method is ready to re-process a request 2113845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @sm: Pointer to EAP state machine allocated with eap_sm_init() 2114845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * 2115845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * An EAP method can perform a pending operation (e.g., to get a response from 2116845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * an external process). Once the response is available, this function can be 2117845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * used to request EAPOL state machine to retry delivering the previously 2118845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * received (and still unanswered) EAP request to EAP state machine. 2119845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project */ 2120845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectvoid eap_notify_pending(struct eap_sm *sm) 2121845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 2122845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sm->eapol_cb->notify_pending(sm->eapol_ctx); 2123845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 2124845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 2125845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 2126845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/** 2127845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * eap_invalidate_cached_session - Mark cached session data invalid 2128845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @sm: Pointer to EAP state machine allocated with eap_sm_init() 2129845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project */ 2130845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectvoid eap_invalidate_cached_session(struct eap_sm *sm) 2131845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 2132845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (sm) 2133845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project eap_deinit_prev_method(sm, "invalidate"); 2134845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 2135