1 /* 2 * EAP peer state machines (RFC 4137) 3 * Copyright (c) 2004-2006, Jouni Malinen <j (at) w1.fi> 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License version 2 as 7 * published by the Free Software Foundation. 8 * 9 * Alternatively, this software may be distributed under the terms of BSD 10 * license. 11 * 12 * See README and COPYING for more details. 13 * 14 * This file implements the Peer State Machine as defined in RFC 4137. The used 15 * states and state transitions match mostly with the RFC. However, there are 16 * couple of additional transitions for working around small issues noticed 17 * during testing. These exceptions are explained in comments within the 18 * functions in this file. The method functions, m.func(), are similar to the 19 * ones used in RFC 4137, but some small changes have used here to optimize 20 * operations and to add functionality needed for fast re-authentication 21 * (session resumption). 22 */ 23 24 #include "includes.h" 25 26 #include "common.h" 27 #include "eap_i.h" 28 #include "config_ssid.h" 29 #include "tls.h" 30 #include "crypto.h" 31 #include "pcsc_funcs.h" 32 #include "wpa_ctrl.h" 33 #include "state_machine.h" 34 35 #define STATE_MACHINE_DATA struct eap_sm 36 #define STATE_MACHINE_DEBUG_PREFIX "EAP" 37 38 #define EAP_MAX_AUTH_ROUNDS 50 39 40 41 static Boolean eap_sm_allowMethod(struct eap_sm *sm, int vendor, 42 EapType method); 43 static u8 * eap_sm_buildNak(struct eap_sm *sm, int id, size_t *len); 44 static void eap_sm_processIdentity(struct eap_sm *sm, const u8 *req); 45 static void eap_sm_processNotify(struct eap_sm *sm, const u8 *req); 46 static u8 * eap_sm_buildNotify(int id, size_t *len); 47 static void eap_sm_parseEapReq(struct eap_sm *sm, const u8 *req, size_t len); 48 #if defined(CONFIG_CTRL_IFACE) || !defined(CONFIG_NO_STDOUT_DEBUG) 49 static const char * eap_sm_method_state_txt(EapMethodState state); 50 static const char * eap_sm_decision_txt(EapDecision decision); 51 #endif /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */ 52 53 54 55 static Boolean eapol_get_bool(struct eap_sm *sm, enum eapol_bool_var var) 56 { 57 return sm->eapol_cb->get_bool(sm->eapol_ctx, var); 58 } 59 60 61 static void eapol_set_bool(struct eap_sm *sm, enum eapol_bool_var var, 62 Boolean value) 63 { 64 sm->eapol_cb->set_bool(sm->eapol_ctx, var, value); 65 } 66 67 68 static unsigned int eapol_get_int(struct eap_sm *sm, enum eapol_int_var var) 69 { 70 return sm->eapol_cb->get_int(sm->eapol_ctx, var); 71 } 72 73 74 static void eapol_set_int(struct eap_sm *sm, enum eapol_int_var var, 75 unsigned int value) 76 { 77 sm->eapol_cb->set_int(sm->eapol_ctx, var, value); 78 } 79 80 81 static u8 * eapol_get_eapReqData(struct eap_sm *sm, size_t *len) 82 { 83 return sm->eapol_cb->get_eapReqData(sm->eapol_ctx, len); 84 } 85 86 87 static void eap_deinit_prev_method(struct eap_sm *sm, const char *txt) 88 { 89 if (sm->m == NULL || sm->eap_method_priv == NULL) 90 return; 91 92 wpa_printf(MSG_DEBUG, "EAP: deinitialize previously used EAP method " 93 "(%d, %s) at %s", sm->selectedMethod, sm->m->name, txt); 94 sm->m->deinit(sm, sm->eap_method_priv); 95 sm->eap_method_priv = NULL; 96 sm->m = NULL; 97 } 98 99 100 /* 101 * This state initializes state machine variables when the machine is 102 * activated (portEnabled = TRUE). This is also used when re-starting 103 * authentication (eapRestart == TRUE). 104 */ 105 SM_STATE(EAP, INITIALIZE) 106 { 107 SM_ENTRY(EAP, INITIALIZE); 108 if (sm->fast_reauth && sm->m && sm->m->has_reauth_data && 109 sm->m->has_reauth_data(sm, sm->eap_method_priv)) { 110 wpa_printf(MSG_DEBUG, "EAP: maintaining EAP method data for " 111 "fast reauthentication"); 112 sm->m->deinit_for_reauth(sm, sm->eap_method_priv); 113 } else { 114 eap_deinit_prev_method(sm, "INITIALIZE"); 115 } 116 sm->selectedMethod = EAP_TYPE_NONE; 117 sm->methodState = METHOD_NONE; 118 sm->allowNotifications = TRUE; 119 sm->decision = DECISION_FAIL; 120 eapol_set_int(sm, EAPOL_idleWhile, sm->ClientTimeout); 121 eapol_set_bool(sm, EAPOL_eapSuccess, FALSE); 122 eapol_set_bool(sm, EAPOL_eapFail, FALSE); 123 os_free(sm->eapKeyData); 124 sm->eapKeyData = NULL; 125 sm->eapKeyAvailable = FALSE; 126 eapol_set_bool(sm, EAPOL_eapRestart, FALSE); 127 sm->lastId = -1; /* new session - make sure this does not match with 128 * the first EAP-Packet */ 129 /* 130 * RFC 4137 does not reset eapResp and eapNoResp here. However, this 131 * seemed to be able to trigger cases where both were set and if EAPOL 132 * state machine uses eapNoResp first, it may end up not sending a real 133 * reply correctly. This occurred when the workaround in FAIL state set 134 * eapNoResp = TRUE.. Maybe that workaround needs to be fixed to do 135 * something else(?) 136 */ 137 eapol_set_bool(sm, EAPOL_eapResp, FALSE); 138 eapol_set_bool(sm, EAPOL_eapNoResp, FALSE); 139 sm->num_rounds = 0; 140 } 141 142 143 /* 144 * This state is reached whenever service from the lower layer is interrupted 145 * or unavailable (portEnabled == FALSE). Immediate transition to INITIALIZE 146 * occurs when the port becomes enabled. 147 */ 148 SM_STATE(EAP, DISABLED) 149 { 150 SM_ENTRY(EAP, DISABLED); 151 sm->num_rounds = 0; 152 } 153 154 155 /* 156 * The state machine spends most of its time here, waiting for something to 157 * happen. This state is entered unconditionally from INITIALIZE, DISCARD, and 158 * SEND_RESPONSE states. 159 */ 160 SM_STATE(EAP, IDLE) 161 { 162 SM_ENTRY(EAP, IDLE); 163 } 164 165 166 /* 167 * This state is entered when an EAP packet is received (eapReq == TRUE) to 168 * parse the packet header. 169 */ 170 SM_STATE(EAP, RECEIVED) 171 { 172 const u8 *eapReqData; 173 size_t eapReqDataLen; 174 175 SM_ENTRY(EAP, RECEIVED); 176 eapReqData = eapol_get_eapReqData(sm, &eapReqDataLen); 177 /* parse rxReq, rxSuccess, rxFailure, reqId, reqMethod */ 178 eap_sm_parseEapReq(sm, eapReqData, eapReqDataLen); 179 sm->num_rounds++; 180 } 181 182 183 /* 184 * This state is entered when a request for a new type comes in. Either the 185 * correct method is started, or a Nak response is built. 186 */ 187 SM_STATE(EAP, GET_METHOD) 188 { 189 int reinit; 190 EapType method; 191 192 SM_ENTRY(EAP, GET_METHOD); 193 194 if (sm->reqMethod == EAP_TYPE_EXPANDED) 195 method = sm->reqVendorMethod; 196 else 197 method = sm->reqMethod; 198 199 if (!eap_sm_allowMethod(sm, sm->reqVendor, method)) { 200 wpa_printf(MSG_DEBUG, "EAP: vendor %u method %u not allowed", 201 sm->reqVendor, method); 202 goto nak; 203 } 204 205 /* 206 * RFC 4137 does not define specific operation for fast 207 * re-authentication (session resumption). The design here is to allow 208 * the previously used method data to be maintained for 209 * re-authentication if the method support session resumption. 210 * Otherwise, the previously used method data is freed and a new method 211 * is allocated here. 212 */ 213 if (sm->fast_reauth && 214 sm->m && sm->m->vendor == sm->reqVendor && 215 sm->m->method == method && 216 sm->m->has_reauth_data && 217 sm->m->has_reauth_data(sm, sm->eap_method_priv)) { 218 wpa_printf(MSG_DEBUG, "EAP: Using previous method data" 219 " for fast re-authentication"); 220 reinit = 1; 221 } else { 222 eap_deinit_prev_method(sm, "GET_METHOD"); 223 reinit = 0; 224 } 225 226 sm->selectedMethod = sm->reqMethod; 227 if (sm->m == NULL) 228 sm->m = eap_sm_get_eap_methods(sm->reqVendor, method); 229 if (!sm->m) { 230 wpa_printf(MSG_DEBUG, "EAP: Could not find selected method: " 231 "vendor %d method %d", 232 sm->reqVendor, method); 233 goto nak; 234 } 235 236 wpa_printf(MSG_DEBUG, "EAP: Initialize selected EAP method: " 237 "vendor %u method %u (%s)", 238 sm->reqVendor, method, sm->m->name); 239 if (reinit) 240 sm->eap_method_priv = sm->m->init_for_reauth( 241 sm, sm->eap_method_priv); 242 else 243 sm->eap_method_priv = sm->m->init(sm); 244 245 if (sm->eap_method_priv == NULL) { 246 struct wpa_ssid *config = eap_get_config(sm); 247 wpa_msg(sm->msg_ctx, MSG_INFO, 248 "EAP: Failed to initialize EAP method: vendor %u " 249 "method %u (%s)", 250 sm->reqVendor, method, sm->m->name); 251 sm->m = NULL; 252 sm->methodState = METHOD_NONE; 253 sm->selectedMethod = EAP_TYPE_NONE; 254 if (sm->reqMethod == EAP_TYPE_TLS && config && 255 (config->pending_req_pin || 256 config->pending_req_passphrase)) { 257 /* 258 * Return without generating Nak in order to allow 259 * entering of PIN code or passphrase to retry the 260 * current EAP packet. 261 */ 262 wpa_printf(MSG_DEBUG, "EAP: Pending PIN/passphrase " 263 "request - skip Nak"); 264 return; 265 } 266 267 goto nak; 268 } 269 270 sm->methodState = METHOD_INIT; 271 wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_METHOD 272 "EAP vendor %u method %u (%s) selected", 273 sm->reqVendor, method, sm->m->name); 274 return; 275 276 nak: 277 os_free(sm->eapRespData); 278 sm->eapRespData = NULL; 279 sm->eapRespData = eap_sm_buildNak(sm, sm->reqId, &sm->eapRespDataLen); 280 } 281 282 283 /* 284 * The method processing happens here. The request from the authenticator is 285 * processed, and an appropriate response packet is built. 286 */ 287 SM_STATE(EAP, METHOD) 288 { 289 u8 *eapReqData; 290 size_t eapReqDataLen; 291 struct eap_method_ret ret; 292 293 SM_ENTRY(EAP, METHOD); 294 if (sm->m == NULL) { 295 wpa_printf(MSG_WARNING, "EAP::METHOD - method not selected"); 296 return; 297 } 298 299 eapReqData = eapol_get_eapReqData(sm, &eapReqDataLen); 300 301 /* 302 * Get ignore, methodState, decision, allowNotifications, and 303 * eapRespData. RFC 4137 uses three separate method procedure (check, 304 * process, and buildResp) in this state. These have been combined into 305 * a single function call to m->process() in order to optimize EAP 306 * method implementation interface a bit. These procedures are only 307 * used from within this METHOD state, so there is no need to keep 308 * these as separate C functions. 309 * 310 * The RFC 4137 procedures return values as follows: 311 * ignore = m.check(eapReqData) 312 * (methodState, decision, allowNotifications) = m.process(eapReqData) 313 * eapRespData = m.buildResp(reqId) 314 */ 315 os_memset(&ret, 0, sizeof(ret)); 316 ret.ignore = sm->ignore; 317 ret.methodState = sm->methodState; 318 ret.decision = sm->decision; 319 ret.allowNotifications = sm->allowNotifications; 320 os_free(sm->eapRespData); 321 sm->eapRespData = NULL; 322 sm->eapRespData = sm->m->process(sm, sm->eap_method_priv, &ret, 323 eapReqData, eapReqDataLen, 324 &sm->eapRespDataLen); 325 wpa_printf(MSG_DEBUG, "EAP: method process -> ignore=%s " 326 "methodState=%s decision=%s", 327 ret.ignore ? "TRUE" : "FALSE", 328 eap_sm_method_state_txt(ret.methodState), 329 eap_sm_decision_txt(ret.decision)); 330 331 sm->ignore = ret.ignore; 332 if (sm->ignore) 333 return; 334 sm->methodState = ret.methodState; 335 sm->decision = ret.decision; 336 sm->allowNotifications = ret.allowNotifications; 337 338 if (sm->m->isKeyAvailable && sm->m->getKey && 339 sm->m->isKeyAvailable(sm, sm->eap_method_priv)) { 340 os_free(sm->eapKeyData); 341 sm->eapKeyData = sm->m->getKey(sm, sm->eap_method_priv, 342 &sm->eapKeyDataLen); 343 } 344 } 345 346 347 /* 348 * This state signals the lower layer that a response packet is ready to be 349 * sent. 350 */ 351 SM_STATE(EAP, SEND_RESPONSE) 352 { 353 SM_ENTRY(EAP, SEND_RESPONSE); 354 os_free(sm->lastRespData); 355 if (sm->eapRespData) { 356 if (sm->workaround) 357 os_memcpy(sm->last_md5, sm->req_md5, 16); 358 sm->lastId = sm->reqId; 359 sm->lastRespData = os_malloc(sm->eapRespDataLen); 360 if (sm->lastRespData) { 361 os_memcpy(sm->lastRespData, sm->eapRespData, 362 sm->eapRespDataLen); 363 sm->lastRespDataLen = sm->eapRespDataLen; 364 } 365 eapol_set_bool(sm, EAPOL_eapResp, TRUE); 366 } else 367 sm->lastRespData = NULL; 368 eapol_set_bool(sm, EAPOL_eapReq, FALSE); 369 eapol_set_int(sm, EAPOL_idleWhile, sm->ClientTimeout); 370 } 371 372 373 /* 374 * This state signals the lower layer that the request was discarded, and no 375 * response packet will be sent at this time. 376 */ 377 SM_STATE(EAP, DISCARD) 378 { 379 SM_ENTRY(EAP, DISCARD); 380 eapol_set_bool(sm, EAPOL_eapReq, FALSE); 381 eapol_set_bool(sm, EAPOL_eapNoResp, TRUE); 382 } 383 384 385 /* 386 * Handles requests for Identity method and builds a response. 387 */ 388 SM_STATE(EAP, IDENTITY) 389 { 390 const u8 *eapReqData; 391 size_t eapReqDataLen; 392 393 SM_ENTRY(EAP, IDENTITY); 394 eapReqData = eapol_get_eapReqData(sm, &eapReqDataLen); 395 eap_sm_processIdentity(sm, eapReqData); 396 os_free(sm->eapRespData); 397 sm->eapRespData = NULL; 398 sm->eapRespData = eap_sm_buildIdentity(sm, sm->reqId, 399 &sm->eapRespDataLen, 0); 400 } 401 402 403 /* 404 * Handles requests for Notification method and builds a response. 405 */ 406 SM_STATE(EAP, NOTIFICATION) 407 { 408 const u8 *eapReqData; 409 size_t eapReqDataLen; 410 411 SM_ENTRY(EAP, NOTIFICATION); 412 eapReqData = eapol_get_eapReqData(sm, &eapReqDataLen); 413 eap_sm_processNotify(sm, eapReqData); 414 os_free(sm->eapRespData); 415 sm->eapRespData = NULL; 416 sm->eapRespData = eap_sm_buildNotify(sm->reqId, &sm->eapRespDataLen); 417 } 418 419 420 /* 421 * This state retransmits the previous response packet. 422 */ 423 SM_STATE(EAP, RETRANSMIT) 424 { 425 SM_ENTRY(EAP, RETRANSMIT); 426 os_free(sm->eapRespData); 427 if (sm->lastRespData) { 428 sm->eapRespData = os_malloc(sm->lastRespDataLen); 429 if (sm->eapRespData) { 430 os_memcpy(sm->eapRespData, sm->lastRespData, 431 sm->lastRespDataLen); 432 sm->eapRespDataLen = sm->lastRespDataLen; 433 } 434 } else 435 sm->eapRespData = NULL; 436 } 437 438 439 /* 440 * This state is entered in case of a successful completion of authentication 441 * and state machine waits here until port is disabled or EAP authentication is 442 * restarted. 443 */ 444 SM_STATE(EAP, SUCCESS) 445 { 446 SM_ENTRY(EAP, SUCCESS); 447 if (sm->eapKeyData != NULL) 448 sm->eapKeyAvailable = TRUE; 449 eapol_set_bool(sm, EAPOL_eapSuccess, TRUE); 450 451 /* 452 * RFC 4137 does not clear eapReq here, but this seems to be required 453 * to avoid processing the same request twice when state machine is 454 * initialized. 455 */ 456 eapol_set_bool(sm, EAPOL_eapReq, FALSE); 457 458 /* 459 * RFC 4137 does not set eapNoResp here, but this seems to be required 460 * to get EAPOL Supplicant backend state machine into SUCCESS state. In 461 * addition, either eapResp or eapNoResp is required to be set after 462 * processing the received EAP frame. 463 */ 464 eapol_set_bool(sm, EAPOL_eapNoResp, TRUE); 465 466 wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_SUCCESS 467 "EAP authentication completed successfully"); 468 } 469 470 471 /* 472 * This state is entered in case of a failure and state machine waits here 473 * until port is disabled or EAP authentication is restarted. 474 */ 475 SM_STATE(EAP, FAILURE) 476 { 477 SM_ENTRY(EAP, FAILURE); 478 eapol_set_bool(sm, EAPOL_eapFail, TRUE); 479 480 /* 481 * RFC 4137 does not clear eapReq here, but this seems to be required 482 * to avoid processing the same request twice when state machine is 483 * initialized. 484 */ 485 eapol_set_bool(sm, EAPOL_eapReq, FALSE); 486 487 /* 488 * RFC 4137 does not set eapNoResp here. However, either eapResp or 489 * eapNoResp is required to be set after processing the received EAP 490 * frame. 491 */ 492 eapol_set_bool(sm, EAPOL_eapNoResp, TRUE); 493 494 wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_FAILURE 495 "EAP authentication failed"); 496 } 497 498 499 static int eap_success_workaround(struct eap_sm *sm, int reqId, int lastId) 500 { 501 /* 502 * At least Microsoft IAS and Meetinghouse Aegis seem to be sending 503 * EAP-Success/Failure with lastId + 1 even though RFC 3748 and 504 * RFC 4137 require that reqId == lastId. In addition, it looks like 505 * Ringmaster v2.1.2.0 would be using lastId + 2 in EAP-Success. 506 * 507 * Accept this kind of Id if EAP workarounds are enabled. These are 508 * unauthenticated plaintext messages, so this should have minimal 509 * security implications (bit easier to fake EAP-Success/Failure). 510 */ 511 if (sm->workaround && (reqId == ((lastId + 1) & 0xff) || 512 reqId == ((lastId + 2) & 0xff))) { 513 wpa_printf(MSG_DEBUG, "EAP: Workaround for unexpected " 514 "identifier field in EAP Success: " 515 "reqId=%d lastId=%d (these are supposed to be " 516 "same)", reqId, lastId); 517 return 1; 518 } 519 wpa_printf(MSG_DEBUG, "EAP: EAP-Success Id mismatch - reqId=%d " 520 "lastId=%d", reqId, lastId); 521 return 0; 522 } 523 524 525 /* 526 * RFC 4137 - Appendix A.1: EAP Peer State Machine - State transitions 527 */ 528 SM_STEP(EAP) 529 { 530 int duplicate; 531 532 if (eapol_get_bool(sm, EAPOL_eapRestart) && 533 eapol_get_bool(sm, EAPOL_portEnabled)) 534 SM_ENTER_GLOBAL(EAP, INITIALIZE); 535 else if (!eapol_get_bool(sm, EAPOL_portEnabled) || sm->force_disabled) 536 SM_ENTER_GLOBAL(EAP, DISABLED); 537 else if (sm->num_rounds > EAP_MAX_AUTH_ROUNDS) { 538 /* RFC 4137 does not place any limit on number of EAP messages 539 * in an authentication session. However, some error cases have 540 * ended up in a state were EAP messages were sent between the 541 * peer and server in a loop (e.g., TLS ACK frame in both 542 * direction). Since this is quite undesired outcome, limit the 543 * total number of EAP round-trips and abort authentication if 544 * this limit is exceeded. 545 */ 546 if (sm->num_rounds == EAP_MAX_AUTH_ROUNDS + 1) { 547 wpa_msg(sm->msg_ctx, MSG_INFO, "EAP: more than %d " 548 "authentication rounds - abort", 549 EAP_MAX_AUTH_ROUNDS); 550 sm->num_rounds++; 551 SM_ENTER_GLOBAL(EAP, FAILURE); 552 } 553 } else switch (sm->EAP_state) { 554 case EAP_INITIALIZE: 555 SM_ENTER(EAP, IDLE); 556 break; 557 case EAP_DISABLED: 558 if (eapol_get_bool(sm, EAPOL_portEnabled) && 559 !sm->force_disabled) 560 SM_ENTER(EAP, INITIALIZE); 561 break; 562 case EAP_IDLE: 563 /* 564 * The first three transitions are from RFC 4137. The last two 565 * are local additions to handle special cases with LEAP and 566 * PEAP server not sending EAP-Success in some cases. 567 */ 568 if (eapol_get_bool(sm, EAPOL_eapReq)) 569 SM_ENTER(EAP, RECEIVED); 570 else if ((eapol_get_bool(sm, EAPOL_altAccept) && 571 sm->decision != DECISION_FAIL) || 572 (eapol_get_int(sm, EAPOL_idleWhile) == 0 && 573 sm->decision == DECISION_UNCOND_SUCC)) 574 SM_ENTER(EAP, SUCCESS); 575 else if (eapol_get_bool(sm, EAPOL_altReject) || 576 (eapol_get_int(sm, EAPOL_idleWhile) == 0 && 577 sm->decision != DECISION_UNCOND_SUCC) || 578 (eapol_get_bool(sm, EAPOL_altAccept) && 579 sm->methodState != METHOD_CONT && 580 sm->decision == DECISION_FAIL)) 581 SM_ENTER(EAP, FAILURE); 582 else if (sm->selectedMethod == EAP_TYPE_LEAP && 583 sm->leap_done && sm->decision != DECISION_FAIL && 584 sm->methodState == METHOD_DONE) 585 SM_ENTER(EAP, SUCCESS); 586 else if (sm->selectedMethod == EAP_TYPE_PEAP && 587 sm->peap_done && sm->decision != DECISION_FAIL && 588 sm->methodState == METHOD_DONE) 589 SM_ENTER(EAP, SUCCESS); 590 break; 591 case EAP_RECEIVED: 592 duplicate = (sm->reqId == sm->lastId) && sm->rxReq; 593 if (sm->workaround && duplicate && 594 os_memcmp(sm->req_md5, sm->last_md5, 16) != 0) { 595 /* 596 * RFC 4137 uses (reqId == lastId) as the only 597 * verification for duplicate EAP requests. However, 598 * this misses cases where the AS is incorrectly using 599 * the same id again; and unfortunately, such 600 * implementations exist. Use MD5 hash as an extra 601 * verification for the packets being duplicate to 602 * workaround these issues. 603 */ 604 wpa_printf(MSG_DEBUG, "EAP: AS used the same Id again," 605 " but EAP packets were not identical"); 606 wpa_printf(MSG_DEBUG, "EAP: workaround - assume this " 607 "is not a duplicate packet"); 608 duplicate = 0; 609 } 610 611 /* 612 * Two special cases below for LEAP are local additions to work 613 * around odd LEAP behavior (EAP-Success in the middle of 614 * authentication and then swapped roles). Other transitions 615 * are based on RFC 4137. 616 */ 617 if (sm->rxSuccess && sm->decision != DECISION_FAIL && 618 (sm->reqId == sm->lastId || 619 eap_success_workaround(sm, sm->reqId, sm->lastId))) 620 SM_ENTER(EAP, SUCCESS); 621 else if (sm->methodState != METHOD_CONT && 622 ((sm->rxFailure && 623 sm->decision != DECISION_UNCOND_SUCC) || 624 (sm->rxSuccess && sm->decision == DECISION_FAIL && 625 (sm->selectedMethod != EAP_TYPE_LEAP || 626 sm->methodState != METHOD_MAY_CONT))) && 627 (sm->reqId == sm->lastId || 628 eap_success_workaround(sm, sm->reqId, sm->lastId))) 629 SM_ENTER(EAP, FAILURE); 630 else if (sm->rxReq && duplicate) 631 SM_ENTER(EAP, RETRANSMIT); 632 else if (sm->rxReq && !duplicate && 633 sm->reqMethod == EAP_TYPE_NOTIFICATION && 634 sm->allowNotifications) 635 SM_ENTER(EAP, NOTIFICATION); 636 else if (sm->rxReq && !duplicate && 637 sm->selectedMethod == EAP_TYPE_NONE && 638 sm->reqMethod == EAP_TYPE_IDENTITY) 639 SM_ENTER(EAP, IDENTITY); 640 else if (sm->rxReq && !duplicate && 641 sm->selectedMethod == EAP_TYPE_NONE && 642 sm->reqMethod != EAP_TYPE_IDENTITY && 643 sm->reqMethod != EAP_TYPE_NOTIFICATION) 644 SM_ENTER(EAP, GET_METHOD); 645 else if (sm->rxReq && !duplicate && 646 sm->reqMethod == sm->selectedMethod && 647 sm->methodState != METHOD_DONE) 648 SM_ENTER(EAP, METHOD); 649 else if (sm->selectedMethod == EAP_TYPE_LEAP && 650 (sm->rxSuccess || sm->rxResp)) 651 SM_ENTER(EAP, METHOD); 652 else 653 SM_ENTER(EAP, DISCARD); 654 break; 655 case EAP_GET_METHOD: 656 if (sm->selectedMethod == sm->reqMethod) 657 SM_ENTER(EAP, METHOD); 658 else 659 SM_ENTER(EAP, SEND_RESPONSE); 660 break; 661 case EAP_METHOD: 662 if (sm->ignore) 663 SM_ENTER(EAP, DISCARD); 664 else 665 SM_ENTER(EAP, SEND_RESPONSE); 666 break; 667 case EAP_SEND_RESPONSE: 668 SM_ENTER(EAP, IDLE); 669 break; 670 case EAP_DISCARD: 671 SM_ENTER(EAP, IDLE); 672 break; 673 case EAP_IDENTITY: 674 SM_ENTER(EAP, SEND_RESPONSE); 675 break; 676 case EAP_NOTIFICATION: 677 SM_ENTER(EAP, SEND_RESPONSE); 678 break; 679 case EAP_RETRANSMIT: 680 SM_ENTER(EAP, SEND_RESPONSE); 681 break; 682 case EAP_SUCCESS: 683 break; 684 case EAP_FAILURE: 685 break; 686 } 687 } 688 689 690 static Boolean eap_sm_allowMethod(struct eap_sm *sm, int vendor, 691 EapType method) 692 { 693 struct wpa_ssid *config = eap_get_config(sm); 694 695 if (!wpa_config_allowed_eap_method(config, vendor, method)) { 696 wpa_printf(MSG_DEBUG, "EAP: configuration does not allow: " 697 "vendor %u method %u", vendor, method); 698 return FALSE; 699 } 700 if (eap_sm_get_eap_methods(vendor, method)) 701 return TRUE; 702 wpa_printf(MSG_DEBUG, "EAP: not included in build: " 703 "vendor %u method %u", vendor, method); 704 return FALSE; 705 } 706 707 708 static u8 * eap_sm_build_expanded_nak(struct eap_sm *sm, int id, size_t *len, 709 const struct eap_method *methods, 710 size_t count) 711 { 712 struct wpa_ssid *config = eap_get_config(sm); 713 struct eap_hdr *resp; 714 u8 *pos; 715 int found = 0; 716 const struct eap_method *m; 717 718 wpa_printf(MSG_DEBUG, "EAP: Building expanded EAP-Nak"); 719 720 /* RFC 3748 - 5.3.2: Expanded Nak */ 721 *len = sizeof(struct eap_hdr) + 8; 722 resp = os_malloc(*len + 8 * (count + 1)); 723 if (resp == NULL) 724 return NULL; 725 726 resp->code = EAP_CODE_RESPONSE; 727 resp->identifier = id; 728 pos = (u8 *) (resp + 1); 729 *pos++ = EAP_TYPE_EXPANDED; 730 WPA_PUT_BE24(pos, EAP_VENDOR_IETF); 731 pos += 3; 732 WPA_PUT_BE32(pos, EAP_TYPE_NAK); 733 pos += 4; 734 735 for (m = methods; m; m = m->next) { 736 if (sm->reqVendor == m->vendor && 737 sm->reqVendorMethod == m->method) 738 continue; /* do not allow the current method again */ 739 if (wpa_config_allowed_eap_method(config, m->vendor, 740 m->method)) { 741 wpa_printf(MSG_DEBUG, "EAP: allowed type: " 742 "vendor=%u method=%u", 743 m->vendor, m->method); 744 *pos++ = EAP_TYPE_EXPANDED; 745 WPA_PUT_BE24(pos, m->vendor); 746 pos += 3; 747 WPA_PUT_BE32(pos, m->method); 748 pos += 4; 749 750 (*len) += 8; 751 found++; 752 } 753 } 754 if (!found) { 755 wpa_printf(MSG_DEBUG, "EAP: no more allowed methods"); 756 *pos++ = EAP_TYPE_EXPANDED; 757 WPA_PUT_BE24(pos, EAP_VENDOR_IETF); 758 pos += 3; 759 WPA_PUT_BE32(pos, EAP_TYPE_NONE); 760 pos += 4; 761 762 (*len) += 8; 763 } 764 765 resp->length = host_to_be16(*len); 766 767 return (u8 *) resp; 768 } 769 770 771 static u8 * eap_sm_buildNak(struct eap_sm *sm, int id, size_t *len) 772 { 773 struct wpa_ssid *config = eap_get_config(sm); 774 struct eap_hdr *resp; 775 u8 *pos; 776 int found = 0, expanded_found = 0; 777 size_t count; 778 const struct eap_method *methods, *m; 779 780 wpa_printf(MSG_DEBUG, "EAP: Building EAP-Nak (requested type %u " 781 "vendor=%u method=%u not allowed)", sm->reqMethod, 782 sm->reqVendor, sm->reqVendorMethod); 783 methods = eap_peer_get_methods(&count); 784 if (methods == NULL) 785 return NULL; 786 if (sm->reqMethod == EAP_TYPE_EXPANDED) 787 return eap_sm_build_expanded_nak(sm, id, len, methods, count); 788 789 /* RFC 3748 - 5.3.1: Legacy Nak */ 790 *len = sizeof(struct eap_hdr) + 1; 791 resp = os_malloc(*len + count + 1); 792 if (resp == NULL) 793 return NULL; 794 795 resp->code = EAP_CODE_RESPONSE; 796 resp->identifier = id; 797 pos = (u8 *) (resp + 1); 798 *pos++ = EAP_TYPE_NAK; 799 800 for (m = methods; m; m = m->next) { 801 if (m->vendor == EAP_VENDOR_IETF && m->method == sm->reqMethod) 802 continue; /* do not allow the current method again */ 803 if (wpa_config_allowed_eap_method(config, m->vendor, 804 m->method)) { 805 if (m->vendor != EAP_VENDOR_IETF) { 806 if (expanded_found) 807 continue; 808 expanded_found = 1; 809 *pos++ = EAP_TYPE_EXPANDED; 810 } else 811 *pos++ = m->method; 812 (*len)++; 813 found++; 814 } 815 } 816 if (!found) { 817 *pos = EAP_TYPE_NONE; 818 (*len)++; 819 } 820 wpa_hexdump(MSG_DEBUG, "EAP: allowed methods", 821 ((u8 *) (resp + 1)) + 1, found); 822 823 resp->length = host_to_be16(*len); 824 825 return (u8 *) resp; 826 } 827 828 829 static void eap_sm_processIdentity(struct eap_sm *sm, const u8 *req) 830 { 831 const struct eap_hdr *hdr = (const struct eap_hdr *) req; 832 const u8 *pos = (const u8 *) (hdr + 1); 833 pos++; 834 835 wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_STARTED 836 "EAP authentication started"); 837 838 /* 839 * RFC 3748 - 5.1: Identity 840 * Data field may contain a displayable message in UTF-8. If this 841 * includes NUL-character, only the data before that should be 842 * displayed. Some EAP implementasitons may piggy-back additional 843 * options after the NUL. 844 */ 845 /* TODO: could save displayable message so that it can be shown to the 846 * user in case of interaction is required */ 847 wpa_hexdump_ascii(MSG_DEBUG, "EAP: EAP-Request Identity data", 848 pos, be_to_host16(hdr->length) - 5); 849 } 850 851 852 #ifdef PCSC_FUNCS 853 static int eap_sm_imsi_identity(struct eap_sm *sm, struct wpa_ssid *ssid) 854 { 855 int aka = 0; 856 char imsi[100]; 857 size_t imsi_len; 858 struct eap_method_type *m = ssid->eap_methods; 859 int i; 860 861 imsi_len = sizeof(imsi); 862 if (scard_get_imsi(sm->scard_ctx, imsi, &imsi_len)) { 863 wpa_printf(MSG_WARNING, "Failed to get IMSI from SIM"); 864 return -1; 865 } 866 867 wpa_hexdump_ascii(MSG_DEBUG, "IMSI", (u8 *) imsi, imsi_len); 868 869 for (i = 0; m && (m[i].vendor != EAP_VENDOR_IETF || 870 m[i].method != EAP_TYPE_NONE); i++) { 871 if (m[i].vendor == EAP_VENDOR_IETF && 872 m[i].method == EAP_TYPE_AKA) { 873 aka = 1; 874 break; 875 } 876 } 877 878 os_free(ssid->identity); 879 ssid->identity = os_malloc(1 + imsi_len); 880 if (ssid->identity == NULL) { 881 wpa_printf(MSG_WARNING, "Failed to allocate buffer for " 882 "IMSI-based identity"); 883 return -1; 884 } 885 886 ssid->identity[0] = aka ? '0' : '1'; 887 os_memcpy(ssid->identity + 1, imsi, imsi_len); 888 ssid->identity_len = 1 + imsi_len; 889 890 return 0; 891 } 892 #endif /* PCSC_FUNCS */ 893 894 895 static int eap_sm_set_scard_pin(struct eap_sm *sm, struct wpa_ssid *ssid) 896 { 897 #ifdef PCSC_FUNCS 898 if (scard_set_pin(sm->scard_ctx, ssid->pin)) { 899 /* 900 * Make sure the same PIN is not tried again in order to avoid 901 * blocking SIM. 902 */ 903 os_free(ssid->pin); 904 ssid->pin = NULL; 905 906 wpa_printf(MSG_WARNING, "PIN validation failed"); 907 eap_sm_request_pin(sm); 908 return -1; 909 } 910 return 0; 911 #else /* PCSC_FUNCS */ 912 return -1; 913 #endif /* PCSC_FUNCS */ 914 } 915 916 static int eap_sm_get_scard_identity(struct eap_sm *sm, struct wpa_ssid *ssid) 917 { 918 #ifdef PCSC_FUNCS 919 if (eap_sm_set_scard_pin(sm, ssid)) 920 return -1; 921 922 return eap_sm_imsi_identity(sm, ssid); 923 #else /* PCSC_FUNCS */ 924 return -1; 925 #endif /* PCSC_FUNCS */ 926 } 927 928 929 /** 930 * eap_sm_buildIdentity - Build EAP-Identity/Response for the current network 931 * @sm: Pointer to EAP state machine allocated with eap_sm_init() 932 * @id: EAP identifier for the packet 933 * @len: Pointer to a variable that will be set to the length of the response 934 * @encrypted: Whether the packet is for encrypted tunnel (EAP phase 2) 935 * Returns: Pointer to the allocated EAP-Identity/Response packet or %NULL on 936 * failure 937 * 938 * This function allocates and builds an EAP-Identity/Response packet for the 939 * current network. The caller is responsible for freeing the returned data. 940 */ 941 u8 * eap_sm_buildIdentity(struct eap_sm *sm, int id, size_t *len, 942 int encrypted) 943 { 944 struct wpa_ssid *config = eap_get_config(sm); 945 struct eap_hdr *resp; 946 u8 *pos; 947 const u8 *identity; 948 size_t identity_len; 949 950 if (config == NULL) { 951 wpa_printf(MSG_WARNING, "EAP: buildIdentity: configuration " 952 "was not available"); 953 return NULL; 954 } 955 956 if (sm->m && sm->m->get_identity && 957 (identity = sm->m->get_identity(sm, sm->eap_method_priv, 958 &identity_len)) != NULL) { 959 wpa_hexdump_ascii(MSG_DEBUG, "EAP: using method re-auth " 960 "identity", identity, identity_len); 961 } else if (!encrypted && config->anonymous_identity) { 962 identity = config->anonymous_identity; 963 identity_len = config->anonymous_identity_len; 964 wpa_hexdump_ascii(MSG_DEBUG, "EAP: using anonymous identity", 965 identity, identity_len); 966 } else { 967 identity = config->identity; 968 identity_len = config->identity_len; 969 wpa_hexdump_ascii(MSG_DEBUG, "EAP: using real identity", 970 identity, identity_len); 971 } 972 973 if (identity == NULL) { 974 wpa_printf(MSG_WARNING, "EAP: buildIdentity: identity " 975 "configuration was not available"); 976 if (config->pcsc) { 977 if (eap_sm_get_scard_identity(sm, config) < 0) 978 return NULL; 979 identity = config->identity; 980 identity_len = config->identity_len; 981 wpa_hexdump_ascii(MSG_DEBUG, "permanent identity from " 982 "IMSI", identity, identity_len); 983 } else { 984 eap_sm_request_identity(sm); 985 return NULL; 986 } 987 } else if (config->pcsc) { 988 if (eap_sm_set_scard_pin(sm, config) < 0) 989 return NULL; 990 } 991 992 *len = sizeof(struct eap_hdr) + 1 + identity_len; 993 resp = os_malloc(*len); 994 if (resp == NULL) 995 return NULL; 996 997 resp->code = EAP_CODE_RESPONSE; 998 resp->identifier = id; 999 resp->length = host_to_be16(*len); 1000 pos = (u8 *) (resp + 1); 1001 *pos++ = EAP_TYPE_IDENTITY; 1002 os_memcpy(pos, identity, identity_len); 1003 1004 return (u8 *) resp; 1005 } 1006 1007 1008 static void eap_sm_processNotify(struct eap_sm *sm, const u8 *req) 1009 { 1010 const struct eap_hdr *hdr = (const struct eap_hdr *) req; 1011 const u8 *pos; 1012 char *msg; 1013 size_t i, msg_len; 1014 1015 pos = (const u8 *) (hdr + 1); 1016 pos++; 1017 1018 msg_len = be_to_host16(hdr->length); 1019 if (msg_len < 5) 1020 return; 1021 msg_len -= 5; 1022 wpa_hexdump_ascii(MSG_DEBUG, "EAP: EAP-Request Notification data", 1023 pos, msg_len); 1024 1025 msg = os_malloc(msg_len + 1); 1026 if (msg == NULL) 1027 return; 1028 for (i = 0; i < msg_len; i++) 1029 msg[i] = isprint(pos[i]) ? (char) pos[i] : '_'; 1030 msg[msg_len] = '\0'; 1031 wpa_msg(sm->msg_ctx, MSG_INFO, "%s%s", 1032 WPA_EVENT_EAP_NOTIFICATION, msg); 1033 os_free(msg); 1034 } 1035 1036 1037 static u8 * eap_sm_buildNotify(int id, size_t *len) 1038 { 1039 struct eap_hdr *resp; 1040 u8 *pos; 1041 1042 wpa_printf(MSG_DEBUG, "EAP: Generating EAP-Response Notification"); 1043 *len = sizeof(struct eap_hdr) + 1; 1044 resp = os_malloc(*len); 1045 if (resp == NULL) 1046 return NULL; 1047 1048 resp->code = EAP_CODE_RESPONSE; 1049 resp->identifier = id; 1050 resp->length = host_to_be16(*len); 1051 pos = (u8 *) (resp + 1); 1052 *pos = EAP_TYPE_NOTIFICATION; 1053 1054 return (u8 *) resp; 1055 } 1056 1057 1058 static void eap_sm_parseEapReq(struct eap_sm *sm, const u8 *req, size_t len) 1059 { 1060 const struct eap_hdr *hdr; 1061 size_t plen; 1062 const u8 *pos; 1063 1064 sm->rxReq = sm->rxResp = sm->rxSuccess = sm->rxFailure = FALSE; 1065 sm->reqId = 0; 1066 sm->reqMethod = EAP_TYPE_NONE; 1067 sm->reqVendor = EAP_VENDOR_IETF; 1068 sm->reqVendorMethod = EAP_TYPE_NONE; 1069 1070 if (req == NULL || len < sizeof(*hdr)) 1071 return; 1072 1073 hdr = (const struct eap_hdr *) req; 1074 plen = be_to_host16(hdr->length); 1075 if (plen > len) { 1076 wpa_printf(MSG_DEBUG, "EAP: Ignored truncated EAP-Packet " 1077 "(len=%lu plen=%lu)", 1078 (unsigned long) len, (unsigned long) plen); 1079 return; 1080 } 1081 1082 sm->reqId = hdr->identifier; 1083 1084 if (sm->workaround) { 1085 md5_vector(1, (const u8 **) &req, &plen, sm->req_md5); 1086 } 1087 1088 switch (hdr->code) { 1089 case EAP_CODE_REQUEST: 1090 if (plen < sizeof(*hdr) + 1) { 1091 wpa_printf(MSG_DEBUG, "EAP: Too short EAP-Request - " 1092 "no Type field"); 1093 return; 1094 } 1095 sm->rxReq = TRUE; 1096 pos = (const u8 *) (hdr + 1); 1097 sm->reqMethod = *pos++; 1098 if (sm->reqMethod == EAP_TYPE_EXPANDED) { 1099 if (plen < sizeof(*hdr) + 8) { 1100 wpa_printf(MSG_DEBUG, "EAP: Ignored truncated " 1101 "expanded EAP-Packet (plen=%lu)", 1102 (unsigned long) plen); 1103 return; 1104 } 1105 sm->reqVendor = WPA_GET_BE24(pos); 1106 pos += 3; 1107 sm->reqVendorMethod = WPA_GET_BE32(pos); 1108 } 1109 wpa_printf(MSG_DEBUG, "EAP: Received EAP-Request id=%d " 1110 "method=%u vendor=%u vendorMethod=%u", 1111 sm->reqId, sm->reqMethod, sm->reqVendor, 1112 sm->reqVendorMethod); 1113 break; 1114 case EAP_CODE_RESPONSE: 1115 if (sm->selectedMethod == EAP_TYPE_LEAP) { 1116 /* 1117 * LEAP differs from RFC 4137 by using reversed roles 1118 * for mutual authentication and because of this, we 1119 * need to accept EAP-Response frames if LEAP is used. 1120 */ 1121 if (plen < sizeof(*hdr) + 1) { 1122 wpa_printf(MSG_DEBUG, "EAP: Too short " 1123 "EAP-Response - no Type field"); 1124 return; 1125 } 1126 sm->rxResp = TRUE; 1127 pos = (const u8 *) (hdr + 1); 1128 sm->reqMethod = *pos; 1129 wpa_printf(MSG_DEBUG, "EAP: Received EAP-Response for " 1130 "LEAP method=%d id=%d", 1131 sm->reqMethod, sm->reqId); 1132 break; 1133 } 1134 wpa_printf(MSG_DEBUG, "EAP: Ignored EAP-Response"); 1135 break; 1136 case EAP_CODE_SUCCESS: 1137 wpa_printf(MSG_DEBUG, "EAP: Received EAP-Success"); 1138 sm->rxSuccess = TRUE; 1139 break; 1140 case EAP_CODE_FAILURE: 1141 wpa_printf(MSG_DEBUG, "EAP: Received EAP-Failure"); 1142 sm->rxFailure = TRUE; 1143 break; 1144 default: 1145 wpa_printf(MSG_DEBUG, "EAP: Ignored EAP-Packet with unknown " 1146 "code %d", hdr->code); 1147 break; 1148 } 1149 } 1150 1151 1152 /** 1153 * eap_sm_init - Allocate and initialize EAP state machine 1154 * @eapol_ctx: Context data to be used with eapol_cb calls 1155 * @eapol_cb: Pointer to EAPOL callback functions 1156 * @msg_ctx: Context data for wpa_msg() calls 1157 * @conf: EAP configuration 1158 * Returns: Pointer to the allocated EAP state machine or %NULL on failure 1159 * 1160 * This function allocates and initializes an EAP state machine. In addition, 1161 * this initializes TLS library for the new EAP state machine. eapol_cb pointer 1162 * will be in use until eap_sm_deinit() is used to deinitialize this EAP state 1163 * machine. Consequently, the caller must make sure that this data structure 1164 * remains alive while the EAP state machine is active. 1165 */ 1166 struct eap_sm * eap_sm_init(void *eapol_ctx, struct eapol_callbacks *eapol_cb, 1167 void *msg_ctx, struct eap_config *conf) 1168 { 1169 struct eap_sm *sm; 1170 struct tls_config tlsconf; 1171 1172 sm = os_zalloc(sizeof(*sm)); 1173 if (sm == NULL) 1174 return NULL; 1175 sm->eapol_ctx = eapol_ctx; 1176 sm->eapol_cb = eapol_cb; 1177 sm->msg_ctx = msg_ctx; 1178 sm->ClientTimeout = 60; 1179 1180 os_memset(&tlsconf, 0, sizeof(tlsconf)); 1181 tlsconf.opensc_engine_path = conf->opensc_engine_path; 1182 tlsconf.pkcs11_engine_path = conf->pkcs11_engine_path; 1183 tlsconf.pkcs11_module_path = conf->pkcs11_module_path; 1184 sm->ssl_ctx = tls_init(&tlsconf); 1185 if (sm->ssl_ctx == NULL) { 1186 wpa_printf(MSG_WARNING, "SSL: Failed to initialize TLS " 1187 "context."); 1188 os_free(sm); 1189 return NULL; 1190 } 1191 1192 return sm; 1193 } 1194 1195 1196 /** 1197 * eap_sm_deinit - Deinitialize and free an EAP state machine 1198 * @sm: Pointer to EAP state machine allocated with eap_sm_init() 1199 * 1200 * This function deinitializes EAP state machine and frees all allocated 1201 * resources. 1202 */ 1203 void eap_sm_deinit(struct eap_sm *sm) 1204 { 1205 if (sm == NULL) 1206 return; 1207 eap_deinit_prev_method(sm, "EAP deinit"); 1208 eap_sm_abort(sm); 1209 tls_deinit(sm->ssl_ctx); 1210 os_free(sm); 1211 } 1212 1213 1214 /** 1215 * eap_sm_step - Step EAP state machine 1216 * @sm: Pointer to EAP state machine allocated with eap_sm_init() 1217 * Returns: 1 if EAP state was changed or 0 if not 1218 * 1219 * This function advances EAP state machine to a new state to match with the 1220 * current variables. This should be called whenever variables used by the EAP 1221 * state machine have changed. 1222 */ 1223 int eap_sm_step(struct eap_sm *sm) 1224 { 1225 int res = 0; 1226 do { 1227 sm->changed = FALSE; 1228 SM_STEP_RUN(EAP); 1229 if (sm->changed) 1230 res = 1; 1231 } while (sm->changed); 1232 return res; 1233 } 1234 1235 1236 /** 1237 * eap_sm_abort - Abort EAP authentication 1238 * @sm: Pointer to EAP state machine allocated with eap_sm_init() 1239 * 1240 * Release system resources that have been allocated for the authentication 1241 * session without fully deinitializing the EAP state machine. 1242 */ 1243 void eap_sm_abort(struct eap_sm *sm) 1244 { 1245 os_free(sm->lastRespData); 1246 sm->lastRespData = NULL; 1247 os_free(sm->eapRespData); 1248 sm->eapRespData = NULL; 1249 os_free(sm->eapKeyData); 1250 sm->eapKeyData = NULL; 1251 1252 /* This is not clearly specified in the EAP statemachines draft, but 1253 * it seems necessary to make sure that some of the EAPOL variables get 1254 * cleared for the next authentication. */ 1255 eapol_set_bool(sm, EAPOL_eapSuccess, FALSE); 1256 } 1257 1258 1259 #ifdef CONFIG_CTRL_IFACE 1260 static const char * eap_sm_state_txt(int state) 1261 { 1262 switch (state) { 1263 case EAP_INITIALIZE: 1264 return "INITIALIZE"; 1265 case EAP_DISABLED: 1266 return "DISABLED"; 1267 case EAP_IDLE: 1268 return "IDLE"; 1269 case EAP_RECEIVED: 1270 return "RECEIVED"; 1271 case EAP_GET_METHOD: 1272 return "GET_METHOD"; 1273 case EAP_METHOD: 1274 return "METHOD"; 1275 case EAP_SEND_RESPONSE: 1276 return "SEND_RESPONSE"; 1277 case EAP_DISCARD: 1278 return "DISCARD"; 1279 case EAP_IDENTITY: 1280 return "IDENTITY"; 1281 case EAP_NOTIFICATION: 1282 return "NOTIFICATION"; 1283 case EAP_RETRANSMIT: 1284 return "RETRANSMIT"; 1285 case EAP_SUCCESS: 1286 return "SUCCESS"; 1287 case EAP_FAILURE: 1288 return "FAILURE"; 1289 default: 1290 return "UNKNOWN"; 1291 } 1292 } 1293 #endif /* CONFIG_CTRL_IFACE */ 1294 1295 1296 #if defined(CONFIG_CTRL_IFACE) || !defined(CONFIG_NO_STDOUT_DEBUG) 1297 static const char * eap_sm_method_state_txt(EapMethodState state) 1298 { 1299 switch (state) { 1300 case METHOD_NONE: 1301 return "NONE"; 1302 case METHOD_INIT: 1303 return "INIT"; 1304 case METHOD_CONT: 1305 return "CONT"; 1306 case METHOD_MAY_CONT: 1307 return "MAY_CONT"; 1308 case METHOD_DONE: 1309 return "DONE"; 1310 default: 1311 return "UNKNOWN"; 1312 } 1313 } 1314 1315 1316 static const char * eap_sm_decision_txt(EapDecision decision) 1317 { 1318 switch (decision) { 1319 case DECISION_FAIL: 1320 return "FAIL"; 1321 case DECISION_COND_SUCC: 1322 return "COND_SUCC"; 1323 case DECISION_UNCOND_SUCC: 1324 return "UNCOND_SUCC"; 1325 default: 1326 return "UNKNOWN"; 1327 } 1328 } 1329 #endif /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */ 1330 1331 1332 #ifdef CONFIG_CTRL_IFACE 1333 1334 /** 1335 * eap_sm_get_status - Get EAP state machine status 1336 * @sm: Pointer to EAP state machine allocated with eap_sm_init() 1337 * @buf: Buffer for status information 1338 * @buflen: Maximum buffer length 1339 * @verbose: Whether to include verbose status information 1340 * Returns: Number of bytes written to buf. 1341 * 1342 * Query EAP state machine for status information. This function fills in a 1343 * text area with current status information from the EAPOL state machine. If 1344 * the buffer (buf) is not large enough, status information will be truncated 1345 * to fit the buffer. 1346 */ 1347 int eap_sm_get_status(struct eap_sm *sm, char *buf, size_t buflen, int verbose) 1348 { 1349 int len, ret; 1350 1351 if (sm == NULL) 1352 return 0; 1353 1354 len = os_snprintf(buf, buflen, 1355 "EAP state=%s\n", 1356 eap_sm_state_txt(sm->EAP_state)); 1357 if (len < 0 || (size_t) len >= buflen) 1358 return 0; 1359 1360 if (sm->selectedMethod != EAP_TYPE_NONE) { 1361 const char *name; 1362 if (sm->m) { 1363 name = sm->m->name; 1364 } else { 1365 const struct eap_method *m = 1366 eap_sm_get_eap_methods(EAP_VENDOR_IETF, 1367 sm->selectedMethod); 1368 if (m) 1369 name = m->name; 1370 else 1371 name = "?"; 1372 } 1373 ret = os_snprintf(buf + len, buflen - len, 1374 "selectedMethod=%d (EAP-%s)\n", 1375 sm->selectedMethod, name); 1376 if (ret < 0 || (size_t) ret >= buflen - len) 1377 return len; 1378 len += ret; 1379 1380 if (sm->m && sm->m->get_status) { 1381 len += sm->m->get_status(sm, sm->eap_method_priv, 1382 buf + len, buflen - len, 1383 verbose); 1384 } 1385 } 1386 1387 if (verbose) { 1388 ret = os_snprintf(buf + len, buflen - len, 1389 "reqMethod=%d\n" 1390 "methodState=%s\n" 1391 "decision=%s\n" 1392 "ClientTimeout=%d\n", 1393 sm->reqMethod, 1394 eap_sm_method_state_txt(sm->methodState), 1395 eap_sm_decision_txt(sm->decision), 1396 sm->ClientTimeout); 1397 if (ret < 0 || (size_t) ret >= buflen - len) 1398 return len; 1399 len += ret; 1400 } 1401 1402 return len; 1403 } 1404 #endif /* CONFIG_CTRL_IFACE */ 1405 1406 1407 #if defined(CONFIG_CTRL_IFACE) || !defined(CONFIG_NO_STDOUT_DEBUG) 1408 typedef enum { 1409 TYPE_IDENTITY, TYPE_PASSWORD, TYPE_OTP, TYPE_PIN, TYPE_NEW_PASSWORD, 1410 TYPE_PASSPHRASE 1411 } eap_ctrl_req_type; 1412 1413 static void eap_sm_request(struct eap_sm *sm, eap_ctrl_req_type type, 1414 const char *msg, size_t msglen) 1415 { 1416 struct wpa_ssid *config; 1417 char *buf; 1418 size_t buflen; 1419 int len; 1420 char *field; 1421 char *txt, *tmp; 1422 1423 if (sm == NULL) 1424 return; 1425 config = eap_get_config(sm); 1426 if (config == NULL) 1427 return; 1428 1429 switch (type) { 1430 case TYPE_IDENTITY: 1431 field = "IDENTITY"; 1432 txt = "Identity"; 1433 config->pending_req_identity++; 1434 break; 1435 case TYPE_PASSWORD: 1436 field = "PASSWORD"; 1437 txt = "Password"; 1438 config->pending_req_password++; 1439 break; 1440 case TYPE_NEW_PASSWORD: 1441 field = "NEW_PASSWORD"; 1442 txt = "New Password"; 1443 config->pending_req_new_password++; 1444 break; 1445 case TYPE_PIN: 1446 field = "PIN"; 1447 txt = "PIN"; 1448 config->pending_req_pin++; 1449 break; 1450 case TYPE_OTP: 1451 field = "OTP"; 1452 if (msg) { 1453 tmp = os_malloc(msglen + 3); 1454 if (tmp == NULL) 1455 return; 1456 tmp[0] = '['; 1457 os_memcpy(tmp + 1, msg, msglen); 1458 tmp[msglen + 1] = ']'; 1459 tmp[msglen + 2] = '\0'; 1460 txt = tmp; 1461 os_free(config->pending_req_otp); 1462 config->pending_req_otp = tmp; 1463 config->pending_req_otp_len = msglen + 3; 1464 } else { 1465 if (config->pending_req_otp == NULL) 1466 return; 1467 txt = config->pending_req_otp; 1468 } 1469 break; 1470 case TYPE_PASSPHRASE: 1471 field = "PASSPHRASE"; 1472 txt = "Private key passphrase"; 1473 config->pending_req_passphrase++; 1474 break; 1475 default: 1476 return; 1477 } 1478 1479 buflen = 100 + os_strlen(txt) + config->ssid_len; 1480 buf = os_malloc(buflen); 1481 if (buf == NULL) 1482 return; 1483 len = os_snprintf(buf, buflen, 1484 WPA_CTRL_REQ "%s-%d:%s needed for SSID ", 1485 field, config->id, txt); 1486 if (len < 0 || (size_t) len >= buflen) { 1487 os_free(buf); 1488 return; 1489 } 1490 if (config->ssid && buflen > len + config->ssid_len) { 1491 os_memcpy(buf + len, config->ssid, config->ssid_len); 1492 len += config->ssid_len; 1493 buf[len] = '\0'; 1494 } 1495 buf[buflen - 1] = '\0'; 1496 wpa_msg(sm->msg_ctx, MSG_INFO, "%s", buf); 1497 os_free(buf); 1498 } 1499 #else /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */ 1500 #define eap_sm_request(sm, type, msg, msglen) do { } while (0) 1501 #endif /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */ 1502 1503 1504 /** 1505 * eap_sm_request_identity - Request identity from user (ctrl_iface) 1506 * @sm: Pointer to EAP state machine allocated with eap_sm_init() 1507 * 1508 * EAP methods can call this function to request identity information for the 1509 * current network. This is normally called when the identity is not included 1510 * in the network configuration. The request will be sent to monitor programs 1511 * through the control interface. 1512 */ 1513 void eap_sm_request_identity(struct eap_sm *sm) 1514 { 1515 eap_sm_request(sm, TYPE_IDENTITY, NULL, 0); 1516 } 1517 1518 1519 /** 1520 * eap_sm_request_password - Request password from user (ctrl_iface) 1521 * @sm: Pointer to EAP state machine allocated with eap_sm_init() 1522 * 1523 * EAP methods can call this function to request password information for the 1524 * current network. This is normally called when the password is not included 1525 * in the network configuration. The request will be sent to monitor programs 1526 * through the control interface. 1527 */ 1528 void eap_sm_request_password(struct eap_sm *sm) 1529 { 1530 eap_sm_request(sm, TYPE_PASSWORD, NULL, 0); 1531 } 1532 1533 1534 /** 1535 * eap_sm_request_new_password - Request new password from user (ctrl_iface) 1536 * @sm: Pointer to EAP state machine allocated with eap_sm_init() 1537 * 1538 * EAP methods can call this function to request new password information for 1539 * the current network. This is normally called when the EAP method indicates 1540 * that the current password has expired and password change is required. The 1541 * request will be sent to monitor programs through the control interface. 1542 */ 1543 void eap_sm_request_new_password(struct eap_sm *sm) 1544 { 1545 eap_sm_request(sm, TYPE_NEW_PASSWORD, NULL, 0); 1546 } 1547 1548 1549 /** 1550 * eap_sm_request_pin - Request SIM or smart card PIN from user (ctrl_iface) 1551 * @sm: Pointer to EAP state machine allocated with eap_sm_init() 1552 * 1553 * EAP methods can call this function to request SIM or smart card PIN 1554 * information for the current network. This is normally called when the PIN is 1555 * not included in the network configuration. The request will be sent to 1556 * monitor programs through the control interface. 1557 */ 1558 void eap_sm_request_pin(struct eap_sm *sm) 1559 { 1560 eap_sm_request(sm, TYPE_PIN, NULL, 0); 1561 } 1562 1563 1564 /** 1565 * eap_sm_request_otp - Request one time password from user (ctrl_iface) 1566 * @sm: Pointer to EAP state machine allocated with eap_sm_init() 1567 * @msg: Message to be displayed to the user when asking for OTP 1568 * @msg_len: Length of the user displayable message 1569 * 1570 * EAP methods can call this function to request open time password (OTP) for 1571 * the current network. The request will be sent to monitor programs through 1572 * the control interface. 1573 */ 1574 void eap_sm_request_otp(struct eap_sm *sm, const char *msg, size_t msg_len) 1575 { 1576 eap_sm_request(sm, TYPE_OTP, msg, msg_len); 1577 } 1578 1579 1580 /** 1581 * eap_sm_request_passphrase - Request passphrase from user (ctrl_iface) 1582 * @sm: Pointer to EAP state machine allocated with eap_sm_init() 1583 * 1584 * EAP methods can call this function to request passphrase for a private key 1585 * for the current network. This is normally called when the passphrase is not 1586 * included in the network configuration. The request will be sent to monitor 1587 * programs through the control interface. 1588 */ 1589 void eap_sm_request_passphrase(struct eap_sm *sm) 1590 { 1591 eap_sm_request(sm, TYPE_PASSPHRASE, NULL, 0); 1592 } 1593 1594 1595 /** 1596 * eap_sm_notify_ctrl_attached - Notification of attached monitor 1597 * @sm: Pointer to EAP state machine allocated with eap_sm_init() 1598 * 1599 * Notify EAP state machines that a monitor was attached to the control 1600 * interface to trigger re-sending of pending requests for user input. 1601 */ 1602 void eap_sm_notify_ctrl_attached(struct eap_sm *sm) 1603 { 1604 struct wpa_ssid *config = eap_get_config(sm); 1605 1606 if (config == NULL) 1607 return; 1608 1609 /* Re-send any pending requests for user data since a new control 1610 * interface was added. This handles cases where the EAP authentication 1611 * starts immediately after system startup when the user interface is 1612 * not yet running. */ 1613 if (config->pending_req_identity) 1614 eap_sm_request_identity(sm); 1615 if (config->pending_req_password) 1616 eap_sm_request_password(sm); 1617 if (config->pending_req_new_password) 1618 eap_sm_request_new_password(sm); 1619 if (config->pending_req_otp) 1620 eap_sm_request_otp(sm, NULL, 0); 1621 if (config->pending_req_pin) 1622 eap_sm_request_pin(sm); 1623 if (config->pending_req_passphrase) 1624 eap_sm_request_passphrase(sm); 1625 } 1626 1627 1628 static int eap_allowed_phase2_type(int vendor, int type) 1629 { 1630 if (vendor != EAP_VENDOR_IETF) 1631 return 0; 1632 return type != EAP_TYPE_PEAP && type != EAP_TYPE_TTLS && 1633 type != EAP_TYPE_FAST; 1634 } 1635 1636 1637 /** 1638 * eap_get_phase2_type - Get EAP type for the given EAP phase 2 method name 1639 * @name: EAP method name, e.g., MD5 1640 * @vendor: Buffer for returning EAP Vendor-Id 1641 * Returns: EAP method type or %EAP_TYPE_NONE if not found 1642 * 1643 * This function maps EAP type names into EAP type numbers that are allowed for 1644 * Phase 2, i.e., for tunneled authentication. Phase 2 is used, e.g., with 1645 * EAP-PEAP, EAP-TTLS, and EAP-FAST. 1646 */ 1647 u32 eap_get_phase2_type(const char *name, int *vendor) 1648 { 1649 int v; 1650 u8 type = eap_get_type(name, &v); 1651 if (eap_allowed_phase2_type(v, type)) { 1652 *vendor = v; 1653 return type; 1654 } 1655 *vendor = EAP_VENDOR_IETF; 1656 return EAP_TYPE_NONE; 1657 } 1658 1659 1660 /** 1661 * eap_get_phase2_types - Get list of allowed EAP phase 2 types 1662 * @config: Pointer to a network configuration 1663 * @count: Pointer to a variable to be filled with number of returned EAP types 1664 * Returns: Pointer to allocated type list or %NULL on failure 1665 * 1666 * This function generates an array of allowed EAP phase 2 (tunneled) types for 1667 * the given network configuration. 1668 */ 1669 struct eap_method_type * eap_get_phase2_types(struct wpa_ssid *config, 1670 size_t *count) 1671 { 1672 struct eap_method_type *buf; 1673 u32 method; 1674 int vendor; 1675 size_t mcount; 1676 const struct eap_method *methods, *m; 1677 1678 methods = eap_peer_get_methods(&mcount); 1679 if (methods == NULL) 1680 return NULL; 1681 *count = 0; 1682 buf = os_malloc(mcount * sizeof(struct eap_method_type)); 1683 if (buf == NULL) 1684 return NULL; 1685 1686 for (m = methods; m; m = m->next) { 1687 vendor = m->vendor; 1688 method = m->method; 1689 if (eap_allowed_phase2_type(vendor, method)) { 1690 if (vendor == EAP_VENDOR_IETF && 1691 method == EAP_TYPE_TLS && config && 1692 config->private_key2 == NULL) 1693 continue; 1694 buf[*count].vendor = vendor; 1695 buf[*count].method = method; 1696 (*count)++; 1697 } 1698 } 1699 1700 return buf; 1701 } 1702 1703 1704 /** 1705 * eap_set_fast_reauth - Update fast_reauth setting 1706 * @sm: Pointer to EAP state machine allocated with eap_sm_init() 1707 * @enabled: 1 = Fast reauthentication is enabled, 0 = Disabled 1708 */ 1709 void eap_set_fast_reauth(struct eap_sm *sm, int enabled) 1710 { 1711 sm->fast_reauth = enabled; 1712 } 1713 1714 1715 /** 1716 * eap_set_workaround - Update EAP workarounds setting 1717 * @sm: Pointer to EAP state machine allocated with eap_sm_init() 1718 * @workaround: 1 = Enable EAP workarounds, 0 = Disable EAP workarounds 1719 */ 1720 void eap_set_workaround(struct eap_sm *sm, unsigned int workaround) 1721 { 1722 sm->workaround = workaround; 1723 } 1724 1725 1726 /** 1727 * eap_get_config - Get current network configuration 1728 * @sm: Pointer to EAP state machine allocated with eap_sm_init() 1729 * Returns: Pointer to the current network configuration or %NULL if not found 1730 * 1731 * EAP peer methods should avoid using this function if they can use other 1732 * access functions, like eap_get_config_identity() and 1733 * eap_get_config_password(), that do not require direct access to 1734 * struct wpa_ssid. 1735 */ 1736 struct wpa_ssid * eap_get_config(struct eap_sm *sm) 1737 { 1738 return sm->eapol_cb->get_config(sm->eapol_ctx); 1739 } 1740 1741 1742 /** 1743 * eap_get_config_password - Get identity from the network configuration 1744 * @sm: Pointer to EAP state machine allocated with eap_sm_init() 1745 * @len: Buffer for the length of the identity 1746 * Returns: Pointer to the identity or %NULL if not found 1747 */ 1748 const u8 * eap_get_config_identity(struct eap_sm *sm, size_t *len) 1749 { 1750 struct wpa_ssid *config = eap_get_config(sm); 1751 if (config == NULL) 1752 return NULL; 1753 *len = config->identity_len; 1754 return config->identity; 1755 } 1756 1757 1758 /** 1759 * eap_get_config_password - Get password from the network configuration 1760 * @sm: Pointer to EAP state machine allocated with eap_sm_init() 1761 * @len: Buffer for the length of the password 1762 * Returns: Pointer to the password or %NULL if not found 1763 */ 1764 const u8 * eap_get_config_password(struct eap_sm *sm, size_t *len) 1765 { 1766 struct wpa_ssid *config = eap_get_config(sm); 1767 if (config == NULL) 1768 return NULL; 1769 *len = config->password_len; 1770 return config->password; 1771 } 1772 1773 1774 /** 1775 * eap_get_config_new_password - Get new password from network configuration 1776 * @sm: Pointer to EAP state machine allocated with eap_sm_init() 1777 * @len: Buffer for the length of the new password 1778 * Returns: Pointer to the new password or %NULL if not found 1779 */ 1780 const u8 * eap_get_config_new_password(struct eap_sm *sm, size_t *len) 1781 { 1782 struct wpa_ssid *config = eap_get_config(sm); 1783 if (config == NULL) 1784 return NULL; 1785 *len = config->new_password_len; 1786 return config->new_password; 1787 } 1788 1789 1790 /** 1791 * eap_get_config_otp - Get one-time password from the network configuration 1792 * @sm: Pointer to EAP state machine allocated with eap_sm_init() 1793 * @len: Buffer for the length of the one-time password 1794 * Returns: Pointer to the one-time password or %NULL if not found 1795 */ 1796 const u8 * eap_get_config_otp(struct eap_sm *sm, size_t *len) 1797 { 1798 struct wpa_ssid *config = eap_get_config(sm); 1799 if (config == NULL) 1800 return NULL; 1801 *len = config->otp_len; 1802 return config->otp; 1803 } 1804 1805 1806 /** 1807 * eap_clear_config_otp - Clear used one-time password 1808 * @sm: Pointer to EAP state machine allocated with eap_sm_init() 1809 * 1810 * This function clears a used one-time password (OTP) from the current network 1811 * configuration. This should be called when the OTP has been used and is not 1812 * needed anymore. 1813 */ 1814 void eap_clear_config_otp(struct eap_sm *sm) 1815 { 1816 struct wpa_ssid *config = eap_get_config(sm); 1817 if (config == NULL) 1818 return; 1819 os_memset(config->otp, 0, config->otp_len); 1820 os_free(config->otp); 1821 config->otp = NULL; 1822 config->otp_len = 0; 1823 } 1824 1825 1826 /** 1827 * eap_key_available - Get key availability (eapKeyAvailable variable) 1828 * @sm: Pointer to EAP state machine allocated with eap_sm_init() 1829 * Returns: 1 if EAP keying material is available, 0 if not 1830 */ 1831 int eap_key_available(struct eap_sm *sm) 1832 { 1833 return sm ? sm->eapKeyAvailable : 0; 1834 } 1835 1836 1837 /** 1838 * eap_notify_success - Notify EAP state machine about external success trigger 1839 * @sm: Pointer to EAP state machine allocated with eap_sm_init() 1840 * 1841 * This function is called when external event, e.g., successful completion of 1842 * WPA-PSK key handshake, is indicating that EAP state machine should move to 1843 * success state. This is mainly used with security modes that do not use EAP 1844 * state machine (e.g., WPA-PSK). 1845 */ 1846 void eap_notify_success(struct eap_sm *sm) 1847 { 1848 if (sm) { 1849 sm->decision = DECISION_COND_SUCC; 1850 sm->EAP_state = EAP_SUCCESS; 1851 } 1852 } 1853 1854 1855 /** 1856 * eap_notify_lower_layer_success - Notification of lower layer success 1857 * @sm: Pointer to EAP state machine allocated with eap_sm_init() 1858 * 1859 * Notify EAP state machines that a lower layer has detected a successful 1860 * authentication. This is used to recover from dropped EAP-Success messages. 1861 */ 1862 void eap_notify_lower_layer_success(struct eap_sm *sm) 1863 { 1864 if (sm == NULL) 1865 return; 1866 1867 if (eapol_get_bool(sm, EAPOL_eapSuccess) || 1868 sm->decision == DECISION_FAIL || 1869 (sm->methodState != METHOD_MAY_CONT && 1870 sm->methodState != METHOD_DONE)) 1871 return; 1872 1873 if (sm->eapKeyData != NULL) 1874 sm->eapKeyAvailable = TRUE; 1875 eapol_set_bool(sm, EAPOL_eapSuccess, TRUE); 1876 wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_SUCCESS 1877 "EAP authentication completed successfully (based on lower " 1878 "layer success)"); 1879 } 1880 1881 1882 /** 1883 * eap_get_eapKeyData - Get master session key (MSK) from EAP state machine 1884 * @sm: Pointer to EAP state machine allocated with eap_sm_init() 1885 * @len: Pointer to variable that will be set to number of bytes in the key 1886 * Returns: Pointer to the EAP keying data or %NULL on failure 1887 * 1888 * Fetch EAP keying material (MSK, eapKeyData) from the EAP state machine. The 1889 * key is available only after a successful authentication. EAP state machine 1890 * continues to manage the key data and the caller must not change or free the 1891 * returned data. 1892 */ 1893 const u8 * eap_get_eapKeyData(struct eap_sm *sm, size_t *len) 1894 { 1895 if (sm == NULL || sm->eapKeyData == NULL) { 1896 *len = 0; 1897 return NULL; 1898 } 1899 1900 *len = sm->eapKeyDataLen; 1901 return sm->eapKeyData; 1902 } 1903 1904 1905 /** 1906 * eap_get_eapKeyData - Get EAP response data 1907 * @sm: Pointer to EAP state machine allocated with eap_sm_init() 1908 * @len: Pointer to variable that will be set to the length of the response 1909 * Returns: Pointer to the EAP response (eapRespData) or %NULL on failure 1910 * 1911 * Fetch EAP response (eapRespData) from the EAP state machine. This data is 1912 * available when EAP state machine has processed an incoming EAP request. The 1913 * EAP state machine does not maintain a reference to the response after this 1914 * function is called and the caller is responsible for freeing the data. 1915 */ 1916 u8 * eap_get_eapRespData(struct eap_sm *sm, size_t *len) 1917 { 1918 u8 *resp; 1919 1920 if (sm == NULL || sm->eapRespData == NULL) { 1921 *len = 0; 1922 return NULL; 1923 } 1924 1925 resp = sm->eapRespData; 1926 *len = sm->eapRespDataLen; 1927 sm->eapRespData = NULL; 1928 sm->eapRespDataLen = 0; 1929 1930 return resp; 1931 } 1932 1933 1934 /** 1935 * eap_sm_register_scard_ctx - Notification of smart card context 1936 * @sm: Pointer to EAP state machine allocated with eap_sm_init() 1937 * @ctx: Context data for smart card operations 1938 * 1939 * Notify EAP state machines of context data for smart card operations. This 1940 * context data will be used as a parameter for scard_*() functions. 1941 */ 1942 void eap_register_scard_ctx(struct eap_sm *sm, void *ctx) 1943 { 1944 if (sm) 1945 sm->scard_ctx = ctx; 1946 } 1947 1948 1949 /** 1950 * eap_hdr_validate - Validate EAP header 1951 * @vendor: Expected EAP Vendor-Id (0 = IETF) 1952 * @eap_type: Expected EAP type number 1953 * @msg: EAP frame (starting with EAP header) 1954 * @msglen: Length of msg 1955 * @plen: Pointer to variable to contain the returned payload length 1956 * Returns: Pointer to EAP payload (after type field), or %NULL on failure 1957 * 1958 * This is a helper function for EAP method implementations. This is usually 1959 * called in the beginning of struct eap_method::process() function to verify 1960 * that the received EAP request packet has a valid header. This function is 1961 * able to process both legacy and expanded EAP headers and in most cases, the 1962 * caller can just use the returned payload pointer (into *plen) for processing 1963 * the payload regardless of whether the packet used the expanded EAP header or 1964 * not. 1965 */ 1966 const u8 * eap_hdr_validate(int vendor, EapType eap_type, 1967 const u8 *msg, size_t msglen, size_t *plen) 1968 { 1969 const struct eap_hdr *hdr; 1970 const u8 *pos; 1971 size_t len; 1972 1973 hdr = (const struct eap_hdr *) msg; 1974 1975 if (msglen < sizeof(*hdr)) { 1976 wpa_printf(MSG_INFO, "EAP: Too short EAP frame"); 1977 return NULL; 1978 } 1979 1980 len = be_to_host16(hdr->length); 1981 if (len < sizeof(*hdr) + 1 || len > msglen) { 1982 wpa_printf(MSG_INFO, "EAP: Invalid EAP length"); 1983 return NULL; 1984 } 1985 1986 pos = (const u8 *) (hdr + 1); 1987 1988 if (*pos == EAP_TYPE_EXPANDED) { 1989 int exp_vendor; 1990 u32 exp_type; 1991 if (len < sizeof(*hdr) + 8) { 1992 wpa_printf(MSG_INFO, "EAP: Invalid expanded EAP " 1993 "length"); 1994 return NULL; 1995 } 1996 pos++; 1997 exp_vendor = WPA_GET_BE24(pos); 1998 pos += 3; 1999 exp_type = WPA_GET_BE32(pos); 2000 pos += 4; 2001 if (exp_vendor != vendor || exp_type != (u32) eap_type) { 2002 wpa_printf(MSG_INFO, "EAP: Invalid expanded frame " 2003 "type"); 2004 return NULL; 2005 } 2006 2007 *plen = len - sizeof(*hdr) - 8; 2008 return pos; 2009 } else { 2010 if (vendor != EAP_VENDOR_IETF || *pos != eap_type) { 2011 wpa_printf(MSG_INFO, "EAP: Invalid frame type"); 2012 return NULL; 2013 } 2014 *plen = len - sizeof(*hdr) - 1; 2015 return pos + 1; 2016 } 2017 } 2018 2019 2020 /** 2021 * eap_set_config_blob - Set or add a named configuration blob 2022 * @sm: Pointer to EAP state machine allocated with eap_sm_init() 2023 * @blob: New value for the blob 2024 * 2025 * Adds a new configuration blob or replaces the current value of an existing 2026 * blob. 2027 */ 2028 void eap_set_config_blob(struct eap_sm *sm, struct wpa_config_blob *blob) 2029 { 2030 sm->eapol_cb->set_config_blob(sm->eapol_ctx, blob); 2031 } 2032 2033 2034 /** 2035 * eap_get_config_blob - Get a named configuration blob 2036 * @sm: Pointer to EAP state machine allocated with eap_sm_init() 2037 * @name: Name of the blob 2038 * Returns: Pointer to blob data or %NULL if not found 2039 */ 2040 const struct wpa_config_blob * eap_get_config_blob(struct eap_sm *sm, 2041 const char *name) 2042 { 2043 return sm->eapol_cb->get_config_blob(sm->eapol_ctx, name); 2044 } 2045 2046 2047 /** 2048 * eap_set_force_disabled - Set force_disabled flag 2049 * @sm: Pointer to EAP state machine allocated with eap_sm_init() 2050 * @disabled: 1 = EAP disabled, 0 = EAP enabled 2051 * 2052 * This function is used to force EAP state machine to be disabled when it is 2053 * not in use (e.g., with WPA-PSK or plaintext connections). 2054 */ 2055 void eap_set_force_disabled(struct eap_sm *sm, int disabled) 2056 { 2057 sm->force_disabled = disabled; 2058 } 2059 2060 2061 /** 2062 * eap_msg_alloc - Allocate a buffer for an EAP message 2063 * @vendor: Vendor-Id (0 = IETF) 2064 * @type: EAP type 2065 * @len: Buffer for returning message length 2066 * @payload_len: Payload length in bytes (data after Type) 2067 * @code: Message Code (EAP_CODE_*) 2068 * @identifier: Identifier 2069 * @payload: Pointer to payload pointer that will be set to point to the 2070 * beginning of the payload or %NULL if payload pointer is not needed 2071 * Returns: Pointer to the allocated message buffer or %NULL on error 2072 * 2073 * This function can be used to allocate a buffer for an EAP message and fill 2074 * in the EAP header. This function is automatically using expanded EAP header 2075 * if the selected Vendor-Id is not IETF. In other words, most EAP methods do 2076 * not need to separately select which header type to use when using this 2077 * function to allocate the message buffers. 2078 */ 2079 struct eap_hdr * eap_msg_alloc(int vendor, EapType type, size_t *len, 2080 size_t payload_len, u8 code, u8 identifier, 2081 u8 **payload) 2082 { 2083 struct eap_hdr *hdr; 2084 u8 *pos; 2085 2086 *len = sizeof(struct eap_hdr) + (vendor == EAP_VENDOR_IETF ? 1 : 8) + 2087 payload_len; 2088 hdr = os_malloc(*len); 2089 if (hdr) { 2090 hdr->code = code; 2091 hdr->identifier = identifier; 2092 hdr->length = host_to_be16(*len); 2093 pos = (u8 *) (hdr + 1); 2094 if (vendor == EAP_VENDOR_IETF) { 2095 *pos++ = type; 2096 } else { 2097 *pos++ = EAP_TYPE_EXPANDED; 2098 WPA_PUT_BE24(pos, vendor); 2099 pos += 3; 2100 WPA_PUT_BE32(pos, type); 2101 pos += 4; 2102 } 2103 if (payload) 2104 *payload = pos; 2105 } 2106 2107 return hdr; 2108 } 2109 2110 2111 /** 2112 * eap_notify_pending - Notify that EAP method is ready to re-process a request 2113 * @sm: Pointer to EAP state machine allocated with eap_sm_init() 2114 * 2115 * An EAP method can perform a pending operation (e.g., to get a response from 2116 * an external process). Once the response is available, this function can be 2117 * used to request EAPOL state machine to retry delivering the previously 2118 * received (and still unanswered) EAP request to EAP state machine. 2119 */ 2120 void eap_notify_pending(struct eap_sm *sm) 2121 { 2122 sm->eapol_cb->notify_pending(sm->eapol_ctx); 2123 } 2124 2125 2126 /** 2127 * eap_invalidate_cached_session - Mark cached session data invalid 2128 * @sm: Pointer to EAP state machine allocated with eap_sm_init() 2129 */ 2130 void eap_invalidate_cached_session(struct eap_sm *sm) 2131 { 2132 if (sm) 2133 eap_deinit_prev_method(sm, "invalidate"); 2134 } 2135