00001
00016 #include "includes.h"
00017
00018 #include "common.h"
00019 #include "ieee802_1x.h"
00020 #include "eapol_sm.h"
00021 #include "eloop.h"
00022 #include "wpa.h"
00023 #include "preauth.h"
00024 #include "sta_info.h"
00025 #include "eap_server/eap.h"
00026 #include "state_machine.h"
00027 #include "eap_common/eap_common.h"
00028
00029 #define STATE_MACHINE_DATA struct eapol_state_machine
00030 #define STATE_MACHINE_DEBUG_PREFIX "IEEE 802.1X"
00031 #define STATE_MACHINE_ADDR sm->addr
00032
00033 static struct eapol_callbacks eapol_cb;
00034
00035
00036
00037 #define setPortAuthorized() \
00038 sm->eapol->cb.set_port_authorized(sm->hapd, sm->sta, 1)
00039 #define setPortUnauthorized() \
00040 sm->eapol->cb.set_port_authorized(sm->hapd, sm->sta, 0)
00041
00042
00043 #define txCannedFail() eapol_auth_tx_canned_eap(sm, 0)
00044 #define txCannedSuccess() eapol_auth_tx_canned_eap(sm, 1)
00045 #define txReq() eapol_auth_tx_req(sm)
00046 #define abortAuth() sm->eapol->cb.abort_auth(sm->hapd, sm->sta)
00047 #define txKey() sm->eapol->cb.tx_key(sm->hapd, sm->sta)
00048 #define processKey() do { } while (0)
00049
00050
00051 static void eapol_sm_step_run(struct eapol_state_machine *sm);
00052 static void eapol_sm_step_cb(void *eloop_ctx, void *timeout_ctx);
00053
00054
00055 static void eapol_auth_logger(struct eapol_authenticator *eapol,
00056 const u8 *addr, logger_level level,
00057 const char *txt)
00058 {
00059 if (eapol->cb.logger == NULL)
00060 return;
00061 eapol->cb.logger(eapol->conf.hapd, addr, level, txt);
00062 }
00063
00064
00065 static void eapol_auth_vlogger(struct eapol_authenticator *eapol,
00066 const u8 *addr, logger_level level,
00067 const char *fmt, ...)
00068 {
00069 char *format;
00070 int maxlen;
00071 va_list ap;
00072
00073 if (eapol->cb.logger == NULL)
00074 return;
00075
00076 maxlen = os_strlen(fmt) + 100;
00077 format = os_malloc(maxlen);
00078 if (!format)
00079 return;
00080
00081 va_start(ap, fmt);
00082 vsnprintf(format, maxlen, fmt, ap);
00083 va_end(ap);
00084
00085 eapol_auth_logger(eapol, addr, level, format);
00086
00087 os_free(format);
00088 }
00089
00090
00091 static void eapol_auth_tx_canned_eap(struct eapol_state_machine *sm,
00092 int success)
00093 {
00094 struct eap_hdr eap;
00095
00096 os_memset(&eap, 0, sizeof(eap));
00097
00098 eap.code = success ? EAP_CODE_SUCCESS : EAP_CODE_FAILURE;
00099 eap.identifier = ++sm->last_eap_id;
00100 eap.length = host_to_be16(sizeof(eap));
00101
00102 eapol_auth_vlogger(sm->eapol, sm->addr, EAPOL_LOGGER_DEBUG,
00103 "Sending canned EAP packet %s (identifier %d)",
00104 success ? "SUCCESS" : "FAILURE", eap.identifier);
00105 sm->eapol->cb.eapol_send(sm->hapd, sm->sta, IEEE802_1X_TYPE_EAP_PACKET,
00106 (u8 *) &eap, sizeof(eap));
00107 sm->dot1xAuthEapolFramesTx++;
00108 }
00109
00110
00111 static void eapol_auth_tx_req(struct eapol_state_machine *sm)
00112 {
00113 if (sm->eap_if->eapReqData == NULL ||
00114 wpabuf_len(sm->eap_if->eapReqData) < sizeof(struct eap_hdr)) {
00115 eapol_auth_logger(sm->eapol, sm->addr,
00116 EAPOL_LOGGER_DEBUG,
00117 "TxReq called, but there is no EAP request "
00118 "from authentication server");
00119 return;
00120 }
00121
00122 if (sm->flags & EAPOL_SM_WAIT_START) {
00123 wpa_printf(MSG_DEBUG, "EAPOL: Drop EAPOL TX to " MACSTR
00124 " while waiting for EAPOL-Start",
00125 MAC2STR(sm->addr));
00126 return;
00127 }
00128
00129 sm->last_eap_id = eap_get_id(sm->eap_if->eapReqData);
00130 eapol_auth_vlogger(sm->eapol, sm->addr, EAPOL_LOGGER_DEBUG,
00131 "Sending EAP Packet (identifier %d)",
00132 sm->last_eap_id);
00133 sm->eapol->cb.eapol_send(sm->hapd, sm->sta, IEEE802_1X_TYPE_EAP_PACKET,
00134 wpabuf_head(sm->eap_if->eapReqData),
00135 wpabuf_len(sm->eap_if->eapReqData));
00136 sm->dot1xAuthEapolFramesTx++;
00137 if (eap_get_type(sm->eap_if->eapReqData) == EAP_TYPE_IDENTITY)
00138 sm->dot1xAuthEapolReqIdFramesTx++;
00139 else
00140 sm->dot1xAuthEapolReqFramesTx++;
00141 }
00142
00143
00153 static void eapol_port_timers_tick(void *eloop_ctx, void *timeout_ctx)
00154 {
00155 struct eapol_state_machine *state = timeout_ctx;
00156
00157 if (state->aWhile > 0) {
00158 state->aWhile--;
00159 if (state->aWhile == 0) {
00160 wpa_printf(MSG_DEBUG, "IEEE 802.1X: " MACSTR
00161 " - aWhile --> 0",
00162 MAC2STR(state->addr));
00163 }
00164 }
00165
00166 if (state->quietWhile > 0) {
00167 state->quietWhile--;
00168 if (state->quietWhile == 0) {
00169 wpa_printf(MSG_DEBUG, "IEEE 802.1X: " MACSTR
00170 " - quietWhile --> 0",
00171 MAC2STR(state->addr));
00172 }
00173 }
00174
00175 if (state->reAuthWhen > 0) {
00176 state->reAuthWhen--;
00177 if (state->reAuthWhen == 0) {
00178 wpa_printf(MSG_DEBUG, "IEEE 802.1X: " MACSTR
00179 " - reAuthWhen --> 0",
00180 MAC2STR(state->addr));
00181 }
00182 }
00183
00184 if (state->eap_if->retransWhile > 0) {
00185 state->eap_if->retransWhile--;
00186 if (state->eap_if->retransWhile == 0) {
00187 wpa_printf(MSG_DEBUG, "IEEE 802.1X: " MACSTR
00188 " - (EAP) retransWhile --> 0",
00189 MAC2STR(state->addr));
00190 }
00191 }
00192
00193 eapol_sm_step_run(state);
00194
00195 eloop_register_timeout(1, 0, eapol_port_timers_tick, eloop_ctx, state);
00196 }
00197
00198
00199
00200
00201
00202 SM_STATE(AUTH_PAE, INITIALIZE)
00203 {
00204 SM_ENTRY_MA(AUTH_PAE, INITIALIZE, auth_pae);
00205 sm->portMode = Auto;
00206 }
00207
00208
00209 SM_STATE(AUTH_PAE, DISCONNECTED)
00210 {
00211 int from_initialize = sm->auth_pae_state == AUTH_PAE_INITIALIZE;
00212
00213 if (sm->eapolLogoff) {
00214 if (sm->auth_pae_state == AUTH_PAE_CONNECTING)
00215 sm->authEapLogoffsWhileConnecting++;
00216 else if (sm->auth_pae_state == AUTH_PAE_AUTHENTICATED)
00217 sm->authAuthEapLogoffWhileAuthenticated++;
00218 }
00219
00220 SM_ENTRY_MA(AUTH_PAE, DISCONNECTED, auth_pae);
00221
00222 sm->authPortStatus = Unauthorized;
00223 setPortUnauthorized();
00224 sm->reAuthCount = 0;
00225 sm->eapolLogoff = FALSE;
00226 if (!from_initialize) {
00227 sm->eapol->cb.finished(sm->hapd, sm->sta, 0,
00228 sm->flags & EAPOL_SM_PREAUTH);
00229 }
00230 }
00231
00232
00233 SM_STATE(AUTH_PAE, RESTART)
00234 {
00235 if (sm->auth_pae_state == AUTH_PAE_AUTHENTICATED) {
00236 if (sm->reAuthenticate)
00237 sm->authAuthReauthsWhileAuthenticated++;
00238 if (sm->eapolStart)
00239 sm->authAuthEapStartsWhileAuthenticated++;
00240 if (sm->eapolLogoff)
00241 sm->authAuthEapLogoffWhileAuthenticated++;
00242 }
00243
00244 SM_ENTRY_MA(AUTH_PAE, RESTART, auth_pae);
00245
00246 sm->eap_if->eapRestart = TRUE;
00247 }
00248
00249
00250 SM_STATE(AUTH_PAE, CONNECTING)
00251 {
00252 if (sm->auth_pae_state != AUTH_PAE_CONNECTING)
00253 sm->authEntersConnecting++;
00254
00255 SM_ENTRY_MA(AUTH_PAE, CONNECTING, auth_pae);
00256
00257 sm->reAuthenticate = FALSE;
00258 sm->reAuthCount++;
00259 }
00260
00261
00262 SM_STATE(AUTH_PAE, HELD)
00263 {
00264 if (sm->auth_pae_state == AUTH_PAE_AUTHENTICATING && sm->authFail)
00265 sm->authAuthFailWhileAuthenticating++;
00266
00267 SM_ENTRY_MA(AUTH_PAE, HELD, auth_pae);
00268
00269 sm->authPortStatus = Unauthorized;
00270 setPortUnauthorized();
00271 sm->quietWhile = sm->quietPeriod;
00272 sm->eapolLogoff = FALSE;
00273
00274 eapol_auth_vlogger(sm->eapol, sm->addr, EAPOL_LOGGER_WARNING,
00275 "authentication failed - EAP type: %d (%s)",
00276 sm->eap_type_authsrv,
00277 eap_type_text(sm->eap_type_authsrv));
00278 if (sm->eap_type_authsrv != sm->eap_type_supp) {
00279 eapol_auth_vlogger(sm->eapol, sm->addr, EAPOL_LOGGER_INFO,
00280 "Supplicant used different EAP type: "
00281 "%d (%s)", sm->eap_type_supp,
00282 eap_type_text(sm->eap_type_supp));
00283 }
00284 sm->eapol->cb.finished(sm->hapd, sm->sta, 0,
00285 sm->flags & EAPOL_SM_PREAUTH);
00286 }
00287
00288
00289 SM_STATE(AUTH_PAE, AUTHENTICATED)
00290 {
00291 char *extra = "";
00292
00293 if (sm->auth_pae_state == AUTH_PAE_AUTHENTICATING && sm->authSuccess)
00294 sm->authAuthSuccessesWhileAuthenticating++;
00295
00296 SM_ENTRY_MA(AUTH_PAE, AUTHENTICATED, auth_pae);
00297
00298 sm->authPortStatus = Authorized;
00299 setPortAuthorized();
00300 sm->reAuthCount = 0;
00301 if (sm->flags & EAPOL_SM_PREAUTH)
00302 extra = " (pre-authentication)";
00303 else if (wpa_auth_sta_get_pmksa(sm->sta->wpa_sm))
00304 extra = " (PMKSA cache)";
00305 eapol_auth_vlogger(sm->eapol, sm->addr, EAPOL_LOGGER_INFO,
00306 "authenticated - EAP type: %d (%s)%s",
00307 sm->eap_type_authsrv,
00308 eap_type_text(sm->eap_type_authsrv), extra);
00309 sm->eapol->cb.finished(sm->hapd, sm->sta, 1,
00310 sm->flags & EAPOL_SM_PREAUTH);
00311 }
00312
00313
00314 SM_STATE(AUTH_PAE, AUTHENTICATING)
00315 {
00316 SM_ENTRY_MA(AUTH_PAE, AUTHENTICATING, auth_pae);
00317
00318 sm->eapolStart = FALSE;
00319 sm->authSuccess = FALSE;
00320 sm->authFail = FALSE;
00321 sm->authTimeout = FALSE;
00322 sm->authStart = TRUE;
00323 sm->keyRun = FALSE;
00324 sm->keyDone = FALSE;
00325 }
00326
00327
00328 SM_STATE(AUTH_PAE, ABORTING)
00329 {
00330 if (sm->auth_pae_state == AUTH_PAE_AUTHENTICATING) {
00331 if (sm->authTimeout)
00332 sm->authAuthTimeoutsWhileAuthenticating++;
00333 if (sm->eapolStart)
00334 sm->authAuthEapStartsWhileAuthenticating++;
00335 if (sm->eapolLogoff)
00336 sm->authAuthEapLogoffWhileAuthenticating++;
00337 }
00338
00339 SM_ENTRY_MA(AUTH_PAE, ABORTING, auth_pae);
00340
00341 sm->authAbort = TRUE;
00342 sm->keyRun = FALSE;
00343 sm->keyDone = FALSE;
00344 }
00345
00346
00347 SM_STATE(AUTH_PAE, FORCE_AUTH)
00348 {
00349 SM_ENTRY_MA(AUTH_PAE, FORCE_AUTH, auth_pae);
00350
00351 sm->authPortStatus = Authorized;
00352 setPortAuthorized();
00353 sm->portMode = ForceAuthorized;
00354 sm->eapolStart = FALSE;
00355 txCannedSuccess();
00356 }
00357
00358
00359 SM_STATE(AUTH_PAE, FORCE_UNAUTH)
00360 {
00361 SM_ENTRY_MA(AUTH_PAE, FORCE_UNAUTH, auth_pae);
00362
00363 sm->authPortStatus = Unauthorized;
00364 setPortUnauthorized();
00365 sm->portMode = ForceUnauthorized;
00366 sm->eapolStart = FALSE;
00367 txCannedFail();
00368 }
00369
00370
00371 SM_STEP(AUTH_PAE)
00372 {
00373 if ((sm->portControl == Auto && sm->portMode != sm->portControl) ||
00374 sm->initialize || !sm->eap_if->portEnabled)
00375 SM_ENTER_GLOBAL(AUTH_PAE, INITIALIZE);
00376 else if (sm->portControl == ForceAuthorized &&
00377 sm->portMode != sm->portControl &&
00378 !(sm->initialize || !sm->eap_if->portEnabled))
00379 SM_ENTER_GLOBAL(AUTH_PAE, FORCE_AUTH);
00380 else if (sm->portControl == ForceUnauthorized &&
00381 sm->portMode != sm->portControl &&
00382 !(sm->initialize || !sm->eap_if->portEnabled))
00383 SM_ENTER_GLOBAL(AUTH_PAE, FORCE_UNAUTH);
00384 else {
00385 switch (sm->auth_pae_state) {
00386 case AUTH_PAE_INITIALIZE:
00387 SM_ENTER(AUTH_PAE, DISCONNECTED);
00388 break;
00389 case AUTH_PAE_DISCONNECTED:
00390 SM_ENTER(AUTH_PAE, RESTART);
00391 break;
00392 case AUTH_PAE_RESTART:
00393 if (!sm->eap_if->eapRestart)
00394 SM_ENTER(AUTH_PAE, CONNECTING);
00395 break;
00396 case AUTH_PAE_HELD:
00397 if (sm->quietWhile == 0)
00398 SM_ENTER(AUTH_PAE, RESTART);
00399 break;
00400 case AUTH_PAE_CONNECTING:
00401 if (sm->eapolLogoff || sm->reAuthCount > sm->reAuthMax)
00402 SM_ENTER(AUTH_PAE, DISCONNECTED);
00403 else if ((sm->eap_if->eapReq &&
00404 sm->reAuthCount <= sm->reAuthMax) ||
00405 sm->eap_if->eapSuccess || sm->eap_if->eapFail)
00406 SM_ENTER(AUTH_PAE, AUTHENTICATING);
00407 break;
00408 case AUTH_PAE_AUTHENTICATED:
00409 if (sm->eapolStart || sm->reAuthenticate)
00410 SM_ENTER(AUTH_PAE, RESTART);
00411 else if (sm->eapolLogoff || !sm->portValid)
00412 SM_ENTER(AUTH_PAE, DISCONNECTED);
00413 break;
00414 case AUTH_PAE_AUTHENTICATING:
00415 if (sm->authSuccess && sm->portValid)
00416 SM_ENTER(AUTH_PAE, AUTHENTICATED);
00417 else if (sm->authFail ||
00418 (sm->keyDone && !sm->portValid))
00419 SM_ENTER(AUTH_PAE, HELD);
00420 else if (sm->eapolStart || sm->eapolLogoff ||
00421 sm->authTimeout)
00422 SM_ENTER(AUTH_PAE, ABORTING);
00423 break;
00424 case AUTH_PAE_ABORTING:
00425 if (sm->eapolLogoff && !sm->authAbort)
00426 SM_ENTER(AUTH_PAE, DISCONNECTED);
00427 else if (!sm->eapolLogoff && !sm->authAbort)
00428 SM_ENTER(AUTH_PAE, RESTART);
00429 break;
00430 case AUTH_PAE_FORCE_AUTH:
00431 if (sm->eapolStart)
00432 SM_ENTER(AUTH_PAE, FORCE_AUTH);
00433 break;
00434 case AUTH_PAE_FORCE_UNAUTH:
00435 if (sm->eapolStart)
00436 SM_ENTER(AUTH_PAE, FORCE_UNAUTH);
00437 break;
00438 }
00439 }
00440 }
00441
00442
00443
00444
00445
00446 SM_STATE(BE_AUTH, INITIALIZE)
00447 {
00448 SM_ENTRY_MA(BE_AUTH, INITIALIZE, be_auth);
00449
00450 abortAuth();
00451 sm->eap_if->eapNoReq = FALSE;
00452 sm->authAbort = FALSE;
00453 }
00454
00455
00456 SM_STATE(BE_AUTH, REQUEST)
00457 {
00458 SM_ENTRY_MA(BE_AUTH, REQUEST, be_auth);
00459
00460 txReq();
00461 sm->eap_if->eapReq = FALSE;
00462 sm->backendOtherRequestsToSupplicant++;
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475 sm->eapolEap = FALSE;
00476 }
00477
00478
00479 SM_STATE(BE_AUTH, RESPONSE)
00480 {
00481 SM_ENTRY_MA(BE_AUTH, RESPONSE, be_auth);
00482
00483 sm->authTimeout = FALSE;
00484 sm->eapolEap = FALSE;
00485 sm->eap_if->eapNoReq = FALSE;
00486 sm->aWhile = sm->serverTimeout;
00487 sm->eap_if->eapResp = TRUE;
00488
00489 sm->backendResponses++;
00490 }
00491
00492
00493 SM_STATE(BE_AUTH, SUCCESS)
00494 {
00495 SM_ENTRY_MA(BE_AUTH, SUCCESS, be_auth);
00496
00497 txReq();
00498 sm->authSuccess = TRUE;
00499 sm->keyRun = TRUE;
00500 }
00501
00502
00503 SM_STATE(BE_AUTH, FAIL)
00504 {
00505 SM_ENTRY_MA(BE_AUTH, FAIL, be_auth);
00506
00507 txReq();
00508 sm->authFail = TRUE;
00509 }
00510
00511
00512 SM_STATE(BE_AUTH, TIMEOUT)
00513 {
00514 SM_ENTRY_MA(BE_AUTH, TIMEOUT, be_auth);
00515
00516 sm->authTimeout = TRUE;
00517 }
00518
00519
00520 SM_STATE(BE_AUTH, IDLE)
00521 {
00522 SM_ENTRY_MA(BE_AUTH, IDLE, be_auth);
00523
00524 sm->authStart = FALSE;
00525 }
00526
00527
00528 SM_STATE(BE_AUTH, IGNORE)
00529 {
00530 SM_ENTRY_MA(BE_AUTH, IGNORE, be_auth);
00531
00532 sm->eap_if->eapNoReq = FALSE;
00533 }
00534
00535
00536 SM_STEP(BE_AUTH)
00537 {
00538 if (sm->portControl != Auto || sm->initialize || sm->authAbort) {
00539 SM_ENTER_GLOBAL(BE_AUTH, INITIALIZE);
00540 return;
00541 }
00542
00543 switch (sm->be_auth_state) {
00544 case BE_AUTH_INITIALIZE:
00545 SM_ENTER(BE_AUTH, IDLE);
00546 break;
00547 case BE_AUTH_REQUEST:
00548 if (sm->eapolEap)
00549 SM_ENTER(BE_AUTH, RESPONSE);
00550 else if (sm->eap_if->eapReq)
00551 SM_ENTER(BE_AUTH, REQUEST);
00552 else if (sm->eap_if->eapTimeout)
00553 SM_ENTER(BE_AUTH, TIMEOUT);
00554 break;
00555 case BE_AUTH_RESPONSE:
00556 if (sm->eap_if->eapNoReq)
00557 SM_ENTER(BE_AUTH, IGNORE);
00558 if (sm->eap_if->eapReq) {
00559 sm->backendAccessChallenges++;
00560 SM_ENTER(BE_AUTH, REQUEST);
00561 } else if (sm->aWhile == 0)
00562 SM_ENTER(BE_AUTH, TIMEOUT);
00563 else if (sm->eap_if->eapFail) {
00564 sm->backendAuthFails++;
00565 SM_ENTER(BE_AUTH, FAIL);
00566 } else if (sm->eap_if->eapSuccess) {
00567 sm->backendAuthSuccesses++;
00568 SM_ENTER(BE_AUTH, SUCCESS);
00569 }
00570 break;
00571 case BE_AUTH_SUCCESS:
00572 SM_ENTER(BE_AUTH, IDLE);
00573 break;
00574 case BE_AUTH_FAIL:
00575 SM_ENTER(BE_AUTH, IDLE);
00576 break;
00577 case BE_AUTH_TIMEOUT:
00578 SM_ENTER(BE_AUTH, IDLE);
00579 break;
00580 case BE_AUTH_IDLE:
00581 if (sm->eap_if->eapFail && sm->authStart)
00582 SM_ENTER(BE_AUTH, FAIL);
00583 else if (sm->eap_if->eapReq && sm->authStart)
00584 SM_ENTER(BE_AUTH, REQUEST);
00585 else if (sm->eap_if->eapSuccess && sm->authStart)
00586 SM_ENTER(BE_AUTH, SUCCESS);
00587 break;
00588 case BE_AUTH_IGNORE:
00589 if (sm->eapolEap)
00590 SM_ENTER(BE_AUTH, RESPONSE);
00591 else if (sm->eap_if->eapReq)
00592 SM_ENTER(BE_AUTH, REQUEST);
00593 else if (sm->eap_if->eapTimeout)
00594 SM_ENTER(BE_AUTH, TIMEOUT);
00595 break;
00596 }
00597 }
00598
00599
00600
00601
00602
00603 SM_STATE(REAUTH_TIMER, INITIALIZE)
00604 {
00605 SM_ENTRY_MA(REAUTH_TIMER, INITIALIZE, reauth_timer);
00606
00607 sm->reAuthWhen = sm->reAuthPeriod;
00608 }
00609
00610
00611 SM_STATE(REAUTH_TIMER, REAUTHENTICATE)
00612 {
00613 SM_ENTRY_MA(REAUTH_TIMER, REAUTHENTICATE, reauth_timer);
00614
00615 sm->reAuthenticate = TRUE;
00616 wpa_auth_sm_event(sm->sta->wpa_sm, WPA_REAUTH_EAPOL);
00617 }
00618
00619
00620 SM_STEP(REAUTH_TIMER)
00621 {
00622 if (sm->portControl != Auto || sm->initialize ||
00623 sm->authPortStatus == Unauthorized || !sm->reAuthEnabled) {
00624 SM_ENTER_GLOBAL(REAUTH_TIMER, INITIALIZE);
00625 return;
00626 }
00627
00628 switch (sm->reauth_timer_state) {
00629 case REAUTH_TIMER_INITIALIZE:
00630 if (sm->reAuthWhen == 0)
00631 SM_ENTER(REAUTH_TIMER, REAUTHENTICATE);
00632 break;
00633 case REAUTH_TIMER_REAUTHENTICATE:
00634 SM_ENTER(REAUTH_TIMER, INITIALIZE);
00635 break;
00636 }
00637 }
00638
00639
00640
00641
00642
00643 SM_STATE(AUTH_KEY_TX, NO_KEY_TRANSMIT)
00644 {
00645 SM_ENTRY_MA(AUTH_KEY_TX, NO_KEY_TRANSMIT, auth_key_tx);
00646 }
00647
00648
00649 SM_STATE(AUTH_KEY_TX, KEY_TRANSMIT)
00650 {
00651 SM_ENTRY_MA(AUTH_KEY_TX, KEY_TRANSMIT, auth_key_tx);
00652
00653 txKey();
00654 sm->eap_if->eapKeyAvailable = FALSE;
00655 sm->keyDone = TRUE;
00656 }
00657
00658
00659 SM_STEP(AUTH_KEY_TX)
00660 {
00661 if (sm->initialize || sm->portControl != Auto) {
00662 SM_ENTER_GLOBAL(AUTH_KEY_TX, NO_KEY_TRANSMIT);
00663 return;
00664 }
00665
00666 switch (sm->auth_key_tx_state) {
00667 case AUTH_KEY_TX_NO_KEY_TRANSMIT:
00668 if (sm->keyTxEnabled && sm->eap_if->eapKeyAvailable &&
00669 sm->keyRun && !wpa_auth_sta_wpa_version(sm->sta->wpa_sm))
00670 SM_ENTER(AUTH_KEY_TX, KEY_TRANSMIT);
00671 break;
00672 case AUTH_KEY_TX_KEY_TRANSMIT:
00673 if (!sm->keyTxEnabled || !sm->keyRun)
00674 SM_ENTER(AUTH_KEY_TX, NO_KEY_TRANSMIT);
00675 else if (sm->eap_if->eapKeyAvailable)
00676 SM_ENTER(AUTH_KEY_TX, KEY_TRANSMIT);
00677 break;
00678 }
00679 }
00680
00681
00682
00683
00684
00685 SM_STATE(KEY_RX, NO_KEY_RECEIVE)
00686 {
00687 SM_ENTRY_MA(KEY_RX, NO_KEY_RECEIVE, key_rx);
00688 }
00689
00690
00691 SM_STATE(KEY_RX, KEY_RECEIVE)
00692 {
00693 SM_ENTRY_MA(KEY_RX, KEY_RECEIVE, key_rx);
00694
00695 processKey();
00696 sm->rxKey = FALSE;
00697 }
00698
00699
00700 SM_STEP(KEY_RX)
00701 {
00702 if (sm->initialize || !sm->eap_if->portEnabled) {
00703 SM_ENTER_GLOBAL(KEY_RX, NO_KEY_RECEIVE);
00704 return;
00705 }
00706
00707 switch (sm->key_rx_state) {
00708 case KEY_RX_NO_KEY_RECEIVE:
00709 if (sm->rxKey)
00710 SM_ENTER(KEY_RX, KEY_RECEIVE);
00711 break;
00712 case KEY_RX_KEY_RECEIVE:
00713 if (sm->rxKey)
00714 SM_ENTER(KEY_RX, KEY_RECEIVE);
00715 break;
00716 }
00717 }
00718
00719
00720
00721
00722
00723 SM_STATE(CTRL_DIR, FORCE_BOTH)
00724 {
00725 SM_ENTRY_MA(CTRL_DIR, FORCE_BOTH, ctrl_dir);
00726 sm->operControlledDirections = Both;
00727 }
00728
00729
00730 SM_STATE(CTRL_DIR, IN_OR_BOTH)
00731 {
00732 SM_ENTRY_MA(CTRL_DIR, IN_OR_BOTH, ctrl_dir);
00733 sm->operControlledDirections = sm->adminControlledDirections;
00734 }
00735
00736
00737 SM_STEP(CTRL_DIR)
00738 {
00739 if (sm->initialize) {
00740 SM_ENTER_GLOBAL(CTRL_DIR, IN_OR_BOTH);
00741 return;
00742 }
00743
00744 switch (sm->ctrl_dir_state) {
00745 case CTRL_DIR_FORCE_BOTH:
00746 if (sm->eap_if->portEnabled && sm->operEdge)
00747 SM_ENTER(CTRL_DIR, IN_OR_BOTH);
00748 break;
00749 case CTRL_DIR_IN_OR_BOTH:
00750 if (sm->operControlledDirections !=
00751 sm->adminControlledDirections)
00752 SM_ENTER(CTRL_DIR, IN_OR_BOTH);
00753 if (!sm->eap_if->portEnabled || !sm->operEdge)
00754 SM_ENTER(CTRL_DIR, FORCE_BOTH);
00755 break;
00756 }
00757 }
00758
00759
00760
00761 struct eapol_state_machine *
00762 eapol_auth_alloc(struct eapol_authenticator *eapol, const u8 *addr,
00763 int preauth, struct sta_info *sta)
00764 {
00765 struct eapol_state_machine *sm;
00766 struct hostapd_data *hapd;
00767 struct eap_config eap_conf;
00768
00769 if (eapol == NULL)
00770 return NULL;
00771 hapd = eapol->conf.hapd;
00772
00773 sm = os_zalloc(sizeof(*sm));
00774 if (sm == NULL) {
00775 wpa_printf(MSG_DEBUG, "IEEE 802.1X state machine allocation "
00776 "failed");
00777 return NULL;
00778 }
00779 sm->radius_identifier = -1;
00780 os_memcpy(sm->addr, addr, ETH_ALEN);
00781 if (preauth)
00782 sm->flags |= EAPOL_SM_PREAUTH;
00783
00784 sm->hapd = hapd;
00785 sm->eapol = eapol;
00786 sm->sta = sta;
00787
00788
00789 sm->auth_pae_state = AUTH_PAE_INITIALIZE;
00790 sm->quietPeriod = AUTH_PAE_DEFAULT_quietPeriod;
00791 sm->reAuthMax = AUTH_PAE_DEFAULT_reAuthMax;
00792
00793 sm->be_auth_state = BE_AUTH_INITIALIZE;
00794 sm->serverTimeout = BE_AUTH_DEFAULT_serverTimeout;
00795
00796 sm->reauth_timer_state = REAUTH_TIMER_INITIALIZE;
00797 sm->reAuthPeriod = eapol->conf.eap_reauth_period;
00798 sm->reAuthEnabled = eapol->conf.eap_reauth_period > 0 ? TRUE : FALSE;
00799
00800 sm->auth_key_tx_state = AUTH_KEY_TX_NO_KEY_TRANSMIT;
00801
00802 sm->key_rx_state = KEY_RX_NO_KEY_RECEIVE;
00803
00804 sm->ctrl_dir_state = CTRL_DIR_IN_OR_BOTH;
00805
00806 sm->portControl = Auto;
00807
00808 if (!eapol->conf.wpa &&
00809 (eapol->default_wep_key || eapol->conf.individual_wep_key_len > 0))
00810 sm->keyTxEnabled = TRUE;
00811 else
00812 sm->keyTxEnabled = FALSE;
00813 if (eapol->conf.wpa)
00814 sm->portValid = FALSE;
00815 else
00816 sm->portValid = TRUE;
00817
00818 os_memset(&eap_conf, 0, sizeof(eap_conf));
00819 eap_conf.eap_server = eapol->conf.eap_server;
00820 eap_conf.ssl_ctx = eapol->conf.ssl_ctx;
00821 eap_conf.eap_sim_db_priv = eapol->conf.eap_sim_db_priv;
00822 eap_conf.pac_opaque_encr_key = eapol->conf.pac_opaque_encr_key;
00823 eap_conf.eap_fast_a_id = eapol->conf.eap_fast_a_id;
00824 eap_conf.eap_fast_a_id_len = eapol->conf.eap_fast_a_id_len;
00825 eap_conf.eap_fast_a_id_info = eapol->conf.eap_fast_a_id_info;
00826 eap_conf.eap_fast_prov = eapol->conf.eap_fast_prov;
00827 eap_conf.pac_key_lifetime = eapol->conf.pac_key_lifetime;
00828 eap_conf.pac_key_refresh_time = eapol->conf.pac_key_refresh_time;
00829 eap_conf.eap_sim_aka_result_ind = eapol->conf.eap_sim_aka_result_ind;
00830 eap_conf.tnc = eapol->conf.tnc;
00831 eap_conf.wps = eapol->conf.wps;
00832 eap_conf.assoc_wps_ie = sta->wps_ie;
00833 eap_conf.peer_addr = addr;
00834 sm->eap = eap_server_sm_init(sm, &eapol_cb, &eap_conf);
00835 if (sm->eap == NULL) {
00836 eapol_auth_free(sm);
00837 return NULL;
00838 }
00839 sm->eap_if = eap_get_interface(sm->eap);
00840
00841 eapol_auth_initialize(sm);
00842
00843 return sm;
00844 }
00845
00846
00847 void eapol_auth_free(struct eapol_state_machine *sm)
00848 {
00849 if (sm == NULL)
00850 return;
00851
00852 eloop_cancel_timeout(eapol_port_timers_tick, NULL, sm);
00853 eloop_cancel_timeout(eapol_sm_step_cb, sm, NULL);
00854 if (sm->eap)
00855 eap_server_sm_deinit(sm->eap);
00856 os_free(sm);
00857 }
00858
00859
00860 static int eapol_sm_sta_entry_alive(struct eapol_authenticator *eapol,
00861 const u8 *addr)
00862 {
00863 return eapol->cb.sta_entry_alive(eapol->conf.hapd, addr);
00864 }
00865
00866
00867 static void eapol_sm_step_run(struct eapol_state_machine *sm)
00868 {
00869 struct eapol_authenticator *eapol = sm->eapol;
00870 u8 addr[ETH_ALEN];
00871 unsigned int prev_auth_pae, prev_be_auth, prev_reauth_timer,
00872 prev_auth_key_tx, prev_key_rx, prev_ctrl_dir;
00873 int max_steps = 100;
00874
00875 os_memcpy(addr, sm->addr, ETH_ALEN);
00876
00877
00878
00879
00880
00881
00882
00883 restart:
00884 prev_auth_pae = sm->auth_pae_state;
00885 prev_be_auth = sm->be_auth_state;
00886 prev_reauth_timer = sm->reauth_timer_state;
00887 prev_auth_key_tx = sm->auth_key_tx_state;
00888 prev_key_rx = sm->key_rx_state;
00889 prev_ctrl_dir = sm->ctrl_dir_state;
00890
00891 SM_STEP_RUN(AUTH_PAE);
00892 if (sm->initializing || eapol_sm_sta_entry_alive(eapol, addr))
00893 SM_STEP_RUN(BE_AUTH);
00894 if (sm->initializing || eapol_sm_sta_entry_alive(eapol, addr))
00895 SM_STEP_RUN(REAUTH_TIMER);
00896 if (sm->initializing || eapol_sm_sta_entry_alive(eapol, addr))
00897 SM_STEP_RUN(AUTH_KEY_TX);
00898 if (sm->initializing || eapol_sm_sta_entry_alive(eapol, addr))
00899 SM_STEP_RUN(KEY_RX);
00900 if (sm->initializing || eapol_sm_sta_entry_alive(eapol, addr))
00901 SM_STEP_RUN(CTRL_DIR);
00902
00903 if (prev_auth_pae != sm->auth_pae_state ||
00904 prev_be_auth != sm->be_auth_state ||
00905 prev_reauth_timer != sm->reauth_timer_state ||
00906 prev_auth_key_tx != sm->auth_key_tx_state ||
00907 prev_key_rx != sm->key_rx_state ||
00908 prev_ctrl_dir != sm->ctrl_dir_state) {
00909 if (--max_steps > 0)
00910 goto restart;
00911
00912 eapol_auth_step(sm);
00913 return;
00914 }
00915
00916 if (eapol_sm_sta_entry_alive(eapol, addr) && sm->eap) {
00917 if (eap_server_sm_step(sm->eap)) {
00918 if (--max_steps > 0)
00919 goto restart;
00920
00921 eapol_auth_step(sm);
00922 return;
00923 }
00924
00925
00926 if (sm->eap_if->aaaEapResp) {
00927 sm->eap_if->aaaEapResp = FALSE;
00928 if (sm->eap_if->aaaEapRespData == NULL) {
00929 wpa_printf(MSG_DEBUG, "EAPOL: aaaEapResp set, "
00930 "but no aaaEapRespData available");
00931 return;
00932 }
00933 sm->eapol->cb.aaa_send(
00934 sm->hapd, sm->sta,
00935 wpabuf_head(sm->eap_if->aaaEapRespData),
00936 wpabuf_len(sm->eap_if->aaaEapRespData));
00937 }
00938 }
00939
00940 if (eapol_sm_sta_entry_alive(eapol, addr))
00941 wpa_auth_sm_notify(sm->sta->wpa_sm);
00942 }
00943
00944
00945 static void eapol_sm_step_cb(void *eloop_ctx, void *timeout_ctx)
00946 {
00947 struct eapol_state_machine *sm = eloop_ctx;
00948 eapol_sm_step_run(sm);
00949 }
00950
00951
00960 void eapol_auth_step(struct eapol_state_machine *sm)
00961 {
00962
00963
00964
00965
00966
00967
00968 eloop_register_timeout(0, 0, eapol_sm_step_cb, sm, NULL);
00969 }
00970
00971
00972 void eapol_auth_initialize(struct eapol_state_machine *sm)
00973 {
00974 sm->initializing = TRUE;
00975
00976
00977 sm->initialize = TRUE;
00978 eapol_sm_step_run(sm);
00979 sm->initialize = FALSE;
00980 eapol_sm_step_run(sm);
00981 sm->initializing = FALSE;
00982
00983
00984 eloop_cancel_timeout(eapol_port_timers_tick, NULL, sm);
00985 eloop_register_timeout(1, 0, eapol_port_timers_tick, NULL, sm);
00986 }
00987
00988
00989 #ifdef HOSTAPD_DUMP_STATE
00990 static inline const char * port_type_txt(PortTypes pt)
00991 {
00992 switch (pt) {
00993 case ForceUnauthorized: return "ForceUnauthorized";
00994 case ForceAuthorized: return "ForceAuthorized";
00995 case Auto: return "Auto";
00996 default: return "Unknown";
00997 }
00998 }
00999
01000
01001 static inline const char * port_state_txt(PortState ps)
01002 {
01003 switch (ps) {
01004 case Unauthorized: return "Unauthorized";
01005 case Authorized: return "Authorized";
01006 default: return "Unknown";
01007 }
01008 }
01009
01010
01011 static inline const char * ctrl_dir_txt(ControlledDirection dir)
01012 {
01013 switch (dir) {
01014 case Both: return "Both";
01015 case In: return "In";
01016 default: return "Unknown";
01017 }
01018 }
01019
01020
01021 static inline const char * auth_pae_state_txt(int s)
01022 {
01023 switch (s) {
01024 case AUTH_PAE_INITIALIZE: return "INITIALIZE";
01025 case AUTH_PAE_DISCONNECTED: return "DISCONNECTED";
01026 case AUTH_PAE_CONNECTING: return "CONNECTING";
01027 case AUTH_PAE_AUTHENTICATING: return "AUTHENTICATING";
01028 case AUTH_PAE_AUTHENTICATED: return "AUTHENTICATED";
01029 case AUTH_PAE_ABORTING: return "ABORTING";
01030 case AUTH_PAE_HELD: return "HELD";
01031 case AUTH_PAE_FORCE_AUTH: return "FORCE_AUTH";
01032 case AUTH_PAE_FORCE_UNAUTH: return "FORCE_UNAUTH";
01033 case AUTH_PAE_RESTART: return "RESTART";
01034 default: return "Unknown";
01035 }
01036 }
01037
01038
01039 static inline const char * be_auth_state_txt(int s)
01040 {
01041 switch (s) {
01042 case BE_AUTH_REQUEST: return "REQUEST";
01043 case BE_AUTH_RESPONSE: return "RESPONSE";
01044 case BE_AUTH_SUCCESS: return "SUCCESS";
01045 case BE_AUTH_FAIL: return "FAIL";
01046 case BE_AUTH_TIMEOUT: return "TIMEOUT";
01047 case BE_AUTH_IDLE: return "IDLE";
01048 case BE_AUTH_INITIALIZE: return "INITIALIZE";
01049 case BE_AUTH_IGNORE: return "IGNORE";
01050 default: return "Unknown";
01051 }
01052 }
01053
01054
01055 static inline const char * reauth_timer_state_txt(int s)
01056 {
01057 switch (s) {
01058 case REAUTH_TIMER_INITIALIZE: return "INITIALIZE";
01059 case REAUTH_TIMER_REAUTHENTICATE: return "REAUTHENTICATE";
01060 default: return "Unknown";
01061 }
01062 }
01063
01064
01065 static inline const char * auth_key_tx_state_txt(int s)
01066 {
01067 switch (s) {
01068 case AUTH_KEY_TX_NO_KEY_TRANSMIT: return "NO_KEY_TRANSMIT";
01069 case AUTH_KEY_TX_KEY_TRANSMIT: return "KEY_TRANSMIT";
01070 default: return "Unknown";
01071 }
01072 }
01073
01074
01075 static inline const char * key_rx_state_txt(int s)
01076 {
01077 switch (s) {
01078 case KEY_RX_NO_KEY_RECEIVE: return "NO_KEY_RECEIVE";
01079 case KEY_RX_KEY_RECEIVE: return "KEY_RECEIVE";
01080 default: return "Unknown";
01081 }
01082 }
01083
01084
01085 static inline const char * ctrl_dir_state_txt(int s)
01086 {
01087 switch (s) {
01088 case CTRL_DIR_FORCE_BOTH: return "FORCE_BOTH";
01089 case CTRL_DIR_IN_OR_BOTH: return "IN_OR_BOTH";
01090 default: return "Unknown";
01091 }
01092 }
01093
01094
01095 void eapol_auth_dump_state(FILE *f, const char *prefix,
01096 struct eapol_state_machine *sm)
01097 {
01098 fprintf(f, "%sEAPOL state machine:\n", prefix);
01099 fprintf(f, "%s aWhile=%d quietWhile=%d reAuthWhen=%d\n", prefix,
01100 sm->aWhile, sm->quietWhile, sm->reAuthWhen);
01101 #define _SB(b) ((b) ? "TRUE" : "FALSE")
01102 fprintf(f,
01103 "%s authAbort=%s authFail=%s authPortStatus=%s authStart=%s\n"
01104 "%s authTimeout=%s authSuccess=%s eapFail=%s eapolEap=%s\n"
01105 "%s eapSuccess=%s eapTimeout=%s initialize=%s "
01106 "keyAvailable=%s\n"
01107 "%s keyDone=%s keyRun=%s keyTxEnabled=%s portControl=%s\n"
01108 "%s portEnabled=%s portValid=%s reAuthenticate=%s\n",
01109 prefix, _SB(sm->authAbort), _SB(sm->authFail),
01110 port_state_txt(sm->authPortStatus), _SB(sm->authStart),
01111 prefix, _SB(sm->authTimeout), _SB(sm->authSuccess),
01112 _SB(sm->eap_if->eapFail), _SB(sm->eapolEap),
01113 prefix, _SB(sm->eap_if->eapSuccess),
01114 _SB(sm->eap_if->eapTimeout),
01115 _SB(sm->initialize), _SB(sm->eap_if->eapKeyAvailable),
01116 prefix, _SB(sm->keyDone), _SB(sm->keyRun),
01117 _SB(sm->keyTxEnabled), port_type_txt(sm->portControl),
01118 prefix, _SB(sm->eap_if->portEnabled), _SB(sm->portValid),
01119 _SB(sm->reAuthenticate));
01120
01121 fprintf(f, "%s Authenticator PAE:\n"
01122 "%s state=%s\n"
01123 "%s eapolLogoff=%s eapolStart=%s eapRestart=%s\n"
01124 "%s portMode=%s reAuthCount=%d\n"
01125 "%s quietPeriod=%d reAuthMax=%d\n"
01126 "%s authEntersConnecting=%d\n"
01127 "%s authEapLogoffsWhileConnecting=%d\n"
01128 "%s authEntersAuthenticating=%d\n"
01129 "%s authAuthSuccessesWhileAuthenticating=%d\n"
01130 "%s authAuthTimeoutsWhileAuthenticating=%d\n"
01131 "%s authAuthFailWhileAuthenticating=%d\n"
01132 "%s authAuthEapStartsWhileAuthenticating=%d\n"
01133 "%s authAuthEapLogoffWhileAuthenticating=%d\n"
01134 "%s authAuthReauthsWhileAuthenticated=%d\n"
01135 "%s authAuthEapStartsWhileAuthenticated=%d\n"
01136 "%s authAuthEapLogoffWhileAuthenticated=%d\n",
01137 prefix, prefix, auth_pae_state_txt(sm->auth_pae_state), prefix,
01138 _SB(sm->eapolLogoff), _SB(sm->eapolStart),
01139 _SB(sm->eap_if->eapRestart),
01140 prefix, port_type_txt(sm->portMode), sm->reAuthCount,
01141 prefix, sm->quietPeriod, sm->reAuthMax,
01142 prefix, sm->authEntersConnecting,
01143 prefix, sm->authEapLogoffsWhileConnecting,
01144 prefix, sm->authEntersAuthenticating,
01145 prefix, sm->authAuthSuccessesWhileAuthenticating,
01146 prefix, sm->authAuthTimeoutsWhileAuthenticating,
01147 prefix, sm->authAuthFailWhileAuthenticating,
01148 prefix, sm->authAuthEapStartsWhileAuthenticating,
01149 prefix, sm->authAuthEapLogoffWhileAuthenticating,
01150 prefix, sm->authAuthReauthsWhileAuthenticated,
01151 prefix, sm->authAuthEapStartsWhileAuthenticated,
01152 prefix, sm->authAuthEapLogoffWhileAuthenticated);
01153
01154 fprintf(f, "%s Backend Authentication:\n"
01155 "%s state=%s\n"
01156 "%s eapNoReq=%s eapReq=%s eapResp=%s\n"
01157 "%s serverTimeout=%d\n"
01158 "%s backendResponses=%d\n"
01159 "%s backendAccessChallenges=%d\n"
01160 "%s backendOtherRequestsToSupplicant=%d\n"
01161 "%s backendAuthSuccesses=%d\n"
01162 "%s backendAuthFails=%d\n",
01163 prefix, prefix,
01164 be_auth_state_txt(sm->be_auth_state),
01165 prefix, _SB(sm->eap_if->eapNoReq), _SB(sm->eap_if->eapReq),
01166 _SB(sm->eap_if->eapResp),
01167 prefix, sm->serverTimeout,
01168 prefix, sm->backendResponses,
01169 prefix, sm->backendAccessChallenges,
01170 prefix, sm->backendOtherRequestsToSupplicant,
01171 prefix, sm->backendAuthSuccesses,
01172 prefix, sm->backendAuthFails);
01173
01174 fprintf(f, "%s Reauthentication Timer:\n"
01175 "%s state=%s\n"
01176 "%s reAuthPeriod=%d reAuthEnabled=%s\n", prefix, prefix,
01177 reauth_timer_state_txt(sm->reauth_timer_state), prefix,
01178 sm->reAuthPeriod, _SB(sm->reAuthEnabled));
01179
01180 fprintf(f, "%s Authenticator Key Transmit:\n"
01181 "%s state=%s\n", prefix, prefix,
01182 auth_key_tx_state_txt(sm->auth_key_tx_state));
01183
01184 fprintf(f, "%s Key Receive:\n"
01185 "%s state=%s\n"
01186 "%s rxKey=%s\n", prefix, prefix,
01187 key_rx_state_txt(sm->key_rx_state), prefix, _SB(sm->rxKey));
01188
01189 fprintf(f, "%s Controlled Directions:\n"
01190 "%s state=%s\n"
01191 "%s adminControlledDirections=%s "
01192 "operControlledDirections=%s\n"
01193 "%s operEdge=%s\n", prefix, prefix,
01194 ctrl_dir_state_txt(sm->ctrl_dir_state),
01195 prefix, ctrl_dir_txt(sm->adminControlledDirections),
01196 ctrl_dir_txt(sm->operControlledDirections),
01197 prefix, _SB(sm->operEdge));
01198 #undef _SB
01199 }
01200 #endif
01201
01202
01203 static int eapol_sm_get_eap_user(void *ctx, const u8 *identity,
01204 size_t identity_len, int phase2,
01205 struct eap_user *user)
01206 {
01207 struct eapol_state_machine *sm = ctx;
01208 return sm->eapol->cb.get_eap_user(sm->hapd, identity, identity_len,
01209 phase2, user);
01210 }
01211
01212
01213 static const char * eapol_sm_get_eap_req_id_text(void *ctx, size_t *len)
01214 {
01215 struct eapol_state_machine *sm = ctx;
01216 *len = sm->eapol->conf.eap_req_id_text_len;
01217 return sm->eapol->conf.eap_req_id_text;
01218 }
01219
01220
01221 static struct eapol_callbacks eapol_cb =
01222 {
01223 .get_eap_user = eapol_sm_get_eap_user,
01224 .get_eap_req_id_text = eapol_sm_get_eap_req_id_text,
01225 };
01226
01227
01228 int eapol_auth_eap_pending_cb(struct eapol_state_machine *sm, void *ctx)
01229 {
01230 if (sm == NULL || ctx != sm->eap)
01231 return -1;
01232
01233 eap_sm_pending_cb(sm->eap);
01234 eapol_auth_step(sm);
01235
01236 return 0;
01237 }
01238
01239
01240 static int eapol_auth_conf_clone(struct eapol_auth_config *dst,
01241 struct eapol_auth_config *src)
01242 {
01243 dst->hapd = src->hapd;
01244 dst->eap_reauth_period = src->eap_reauth_period;
01245 dst->wpa = src->wpa;
01246 dst->individual_wep_key_len = src->individual_wep_key_len;
01247 dst->eap_server = src->eap_server;
01248 dst->ssl_ctx = src->ssl_ctx;
01249 dst->eap_sim_db_priv = src->eap_sim_db_priv;
01250 os_free(dst->eap_req_id_text);
01251 if (src->eap_req_id_text) {
01252 dst->eap_req_id_text = os_malloc(src->eap_req_id_text_len);
01253 if (dst->eap_req_id_text == NULL)
01254 return -1;
01255 os_memcpy(dst->eap_req_id_text, src->eap_req_id_text,
01256 src->eap_req_id_text_len);
01257 dst->eap_req_id_text_len = src->eap_req_id_text_len;
01258 } else {
01259 dst->eap_req_id_text = NULL;
01260 dst->eap_req_id_text_len = 0;
01261 }
01262 if (src->pac_opaque_encr_key) {
01263 dst->pac_opaque_encr_key = os_malloc(16);
01264 os_memcpy(dst->pac_opaque_encr_key, src->pac_opaque_encr_key,
01265 16);
01266 } else
01267 dst->pac_opaque_encr_key = NULL;
01268 if (src->eap_fast_a_id) {
01269 dst->eap_fast_a_id = os_malloc(src->eap_fast_a_id_len);
01270 if (dst->eap_fast_a_id == NULL) {
01271 os_free(dst->eap_req_id_text);
01272 return -1;
01273 }
01274 os_memcpy(dst->eap_fast_a_id, src->eap_fast_a_id,
01275 src->eap_fast_a_id_len);
01276 dst->eap_fast_a_id_len = src->eap_fast_a_id_len;
01277 } else
01278 dst->eap_fast_a_id = NULL;
01279 if (src->eap_fast_a_id_info) {
01280 dst->eap_fast_a_id_info = os_strdup(src->eap_fast_a_id_info);
01281 if (dst->eap_fast_a_id_info == NULL) {
01282 os_free(dst->eap_req_id_text);
01283 os_free(dst->eap_fast_a_id);
01284 return -1;
01285 }
01286 } else
01287 dst->eap_fast_a_id_info = NULL;
01288 dst->eap_fast_prov = src->eap_fast_prov;
01289 dst->pac_key_lifetime = src->pac_key_lifetime;
01290 dst->pac_key_refresh_time = src->pac_key_refresh_time;
01291 dst->eap_sim_aka_result_ind = src->eap_sim_aka_result_ind;
01292 dst->tnc = src->tnc;
01293 dst->wps = src->wps;
01294 return 0;
01295 }
01296
01297
01298 static void eapol_auth_conf_free(struct eapol_auth_config *conf)
01299 {
01300 os_free(conf->eap_req_id_text);
01301 conf->eap_req_id_text = NULL;
01302 os_free(conf->pac_opaque_encr_key);
01303 conf->pac_opaque_encr_key = NULL;
01304 os_free(conf->eap_fast_a_id);
01305 conf->eap_fast_a_id = NULL;
01306 os_free(conf->eap_fast_a_id_info);
01307 conf->eap_fast_a_id_info = NULL;
01308 }
01309
01310
01311 struct eapol_authenticator * eapol_auth_init(struct eapol_auth_config *conf,
01312 struct eapol_auth_cb *cb)
01313 {
01314 struct eapol_authenticator *eapol;
01315
01316 eapol = os_zalloc(sizeof(*eapol));
01317 if (eapol == NULL)
01318 return NULL;
01319
01320 if (eapol_auth_conf_clone(&eapol->conf, conf) < 0) {
01321 os_free(eapol);
01322 return NULL;
01323 }
01324
01325 if (conf->individual_wep_key_len > 0) {
01326
01327 eapol->default_wep_key_idx = 1;
01328 }
01329
01330 eapol->cb.eapol_send = cb->eapol_send;
01331 eapol->cb.aaa_send = cb->aaa_send;
01332 eapol->cb.finished = cb->finished;
01333 eapol->cb.get_eap_user = cb->get_eap_user;
01334 eapol->cb.sta_entry_alive = cb->sta_entry_alive;
01335 eapol->cb.logger = cb->logger;
01336 eapol->cb.set_port_authorized = cb->set_port_authorized;
01337 eapol->cb.abort_auth = cb->abort_auth;
01338 eapol->cb.tx_key = cb->tx_key;
01339
01340 return eapol;
01341 }
01342
01343
01344 void eapol_auth_deinit(struct eapol_authenticator *eapol)
01345 {
01346 if (eapol == NULL)
01347 return;
01348
01349 eapol_auth_conf_free(&eapol->conf);
01350 os_free(eapol->default_wep_key);
01351 os_free(eapol);
01352 }
01353