aboutsummaryrefslogtreecommitdiff
path: root/contrib/hostapd/ieee802_1x.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/hostapd/ieee802_1x.c')
-rw-r--r--contrib/hostapd/ieee802_1x.c42
1 files changed, 37 insertions, 5 deletions
diff --git a/contrib/hostapd/ieee802_1x.c b/contrib/hostapd/ieee802_1x.c
index 870d52ab5cac..7f3fe0c56fe2 100644
--- a/contrib/hostapd/ieee802_1x.c
+++ b/contrib/hostapd/ieee802_1x.c
@@ -755,7 +755,6 @@ void ieee802_1x_receive(hostapd *hapd, u8 *sa, u8 *buf, size_t len)
sta->eapol_sm->auth_pae.eapolStart = TRUE;
sta->eapol_sm->dot1xAuthEapolStartFramesRx++;
wpa_sm_event(hapd, sta, WPA_REAUTH_EAPOL);
- eapol_sm_step(sta->eapol_sm);
break;
case IEEE802_1X_TYPE_EAPOL_LOGOFF:
@@ -766,7 +765,6 @@ void ieee802_1x_receive(hostapd *hapd, u8 *sa, u8 *buf, size_t len)
RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST;
sta->eapol_sm->auth_pae.eapolLogoff = TRUE;
sta->eapol_sm->dot1xAuthEapolLogoffFramesRx++;
- eapol_sm_step(sta->eapol_sm);
break;
case IEEE802_1X_TYPE_EAPOL_KEY:
@@ -809,8 +807,27 @@ void ieee802_1x_new_station(hostapd *hapd, struct sta_info *sta)
hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X,
HOSTAPD_LEVEL_DEBUG, "start authentication");
sta->eapol_sm = eapol_sm_alloc(hapd, sta);
- if (sta->eapol_sm)
- sta->eapol_sm->portEnabled = TRUE;
+ if (sta->eapol_sm == NULL) {
+ hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X,
+ HOSTAPD_LEVEL_INFO, "failed to allocate "
+ "state machine");
+ return;
+ }
+
+ sta->eapol_sm->portEnabled = TRUE;
+
+ if (sta->pmksa) {
+ hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X,
+ HOSTAPD_LEVEL_DEBUG,
+ "PMK from PMKSA cache - skip IEEE 802.1X/EAP");
+ /* Setup EAPOL state machines to already authenticated state
+ * because of existing PMKSA information in the cache. */
+ sta->eapol_sm->keyRun = TRUE;
+ sta->eapol_sm->keyAvailable = TRUE;
+ sta->eapol_sm->auth_pae.state = AUTH_PAE_AUTHENTICATING;
+ sta->eapol_sm->be_auth.state = BE_AUTH_SUCCESS;
+ sta->eapol_sm->authSuccess = TRUE;
+ }
}
@@ -1136,6 +1153,7 @@ ieee802_1x_receive_auth(struct radius_msg *msg, struct radius_msg *req,
session_timeout_set ?
session_timeout : -1);
}
+ ieee802_1x_store_radius_class(hapd, sta, msg);
break;
case RADIUS_CODE_ACCESS_REJECT:
sm->eapFail = TRUE;
@@ -1159,7 +1177,6 @@ ieee802_1x_receive_auth(struct radius_msg *msg, struct radius_msg *req,
break;
}
- ieee802_1x_store_radius_class(hapd, sta, msg);
ieee802_1x_decapsulate_radius(hapd, sta);
if (override_eapReq)
sm->be_auth.eapReq = FALSE;
@@ -1647,3 +1664,18 @@ int ieee802_1x_get_mib_sta(struct hostapd_data *hapd, struct sta_info *sta,
return len;
}
+
+
+void ieee802_1x_finished(struct hostapd_data *hapd, struct sta_info *sta,
+ int success)
+{
+ u8 *key;
+ size_t len;
+ /* TODO: get PMKLifetime from WPA parameters */
+ static const int dot11RSNAConfigPMKLifetime = 43200;
+
+ key = ieee802_1x_get_key_crypt(sta->eapol_sm, &len);
+ if (success && key) {
+ pmksa_cache_add(hapd, sta, key, dot11RSNAConfigPMKLifetime);
+ }
+}