|
@@ -16,6 +16,7 @@
|
|
|
#include "crypto/md5.h"
|
|
|
#include "common/eapol_common.h"
|
|
|
#include "eap_peer/eap.h"
|
|
|
+#include "eap_peer/eap_proxy.h"
|
|
|
#include "eapol_supp_sm.h"
|
|
|
|
|
|
#define STATE_MACHINE_DATA struct eapol_sm
|
|
@@ -136,6 +137,10 @@ struct eapol_sm {
|
|
|
Boolean cached_pmk;
|
|
|
|
|
|
Boolean unicast_key_received, broadcast_key_received;
|
|
|
+#ifdef CONFIG_EAP_PROXY
|
|
|
+ Boolean use_eap_proxy;
|
|
|
+ struct eap_proxy_sm *eap_proxy;
|
|
|
+#endif /* CONFIG_EAP_PROXY */
|
|
|
};
|
|
|
|
|
|
|
|
@@ -463,6 +468,17 @@ SM_STATE(SUPP_BE, SUCCESS)
|
|
|
sm->keyRun = TRUE;
|
|
|
sm->suppSuccess = TRUE;
|
|
|
|
|
|
+#ifdef CONFIG_EAP_PROXY
|
|
|
+ if (sm->use_eap_proxy) {
|
|
|
+ if (eap_proxy_key_available(sm->eap_proxy)) {
|
|
|
+ /* New key received - clear IEEE 802.1X EAPOL-Key replay
|
|
|
+ * counter */
|
|
|
+ sm->replay_counter_valid = FALSE;
|
|
|
+ }
|
|
|
+ return;
|
|
|
+ }
|
|
|
+#endif /* CONFIG_EAP_PROXY */
|
|
|
+
|
|
|
if (eap_key_available(sm->eap)) {
|
|
|
/* New key received - clear IEEE 802.1X EAPOL-Key replay
|
|
|
* counter */
|
|
@@ -806,6 +822,19 @@ static void eapol_sm_txSuppRsp(struct eapol_sm *sm)
|
|
|
struct wpabuf *resp;
|
|
|
|
|
|
wpa_printf(MSG_DEBUG, "EAPOL: txSuppRsp");
|
|
|
+
|
|
|
+#ifdef CONFIG_EAP_PROXY
|
|
|
+ if (sm->use_eap_proxy) {
|
|
|
+ /* Get EAP Response from EAP Proxy */
|
|
|
+ resp = eap_proxy_get_eapRespData(sm->eap_proxy);
|
|
|
+ if (resp == NULL) {
|
|
|
+ wpa_printf(MSG_WARNING, "EAPOL: txSuppRsp - EAP Proxy "
|
|
|
+ "response data not available");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ } else
|
|
|
+#endif /* CONFIG_EAP_PROXY */
|
|
|
+
|
|
|
resp = eap_get_eapRespData(sm->eap);
|
|
|
if (resp == NULL) {
|
|
|
wpa_printf(MSG_WARNING, "EAPOL: txSuppRsp - EAP response data "
|
|
@@ -883,6 +912,13 @@ void eapol_sm_step(struct eapol_sm *sm)
|
|
|
SM_STEP_RUN(SUPP_PAE);
|
|
|
SM_STEP_RUN(KEY_RX);
|
|
|
SM_STEP_RUN(SUPP_BE);
|
|
|
+#ifdef CONFIG_EAP_PROXY
|
|
|
+ if (sm->use_eap_proxy) {
|
|
|
+ /* Drive the EAP proxy state machine */
|
|
|
+ if (eap_proxy_sm_step(sm->eap_proxy, sm->eap))
|
|
|
+ sm->changed = TRUE;
|
|
|
+ } else
|
|
|
+#endif /* CONFIG_EAP_PROXY */
|
|
|
if (eap_peer_sm_step(sm->eap))
|
|
|
sm->changed = TRUE;
|
|
|
if (!sm->changed)
|
|
@@ -1070,6 +1106,13 @@ int eapol_sm_get_status(struct eapol_sm *sm, char *buf, size_t buflen,
|
|
|
len += ret;
|
|
|
}
|
|
|
|
|
|
+#ifdef CONFIG_EAP_PROXY
|
|
|
+ if (sm->use_eap_proxy)
|
|
|
+ len += eap_proxy_sm_get_status(sm->eap_proxy,
|
|
|
+ buf + len, buflen - len,
|
|
|
+ verbose);
|
|
|
+ else
|
|
|
+#endif /* CONFIG_EAP_PROXY */
|
|
|
len += eap_sm_get_status(sm->eap, buf + len, buflen - len, verbose);
|
|
|
|
|
|
return len;
|
|
@@ -1227,6 +1270,16 @@ int eapol_sm_rx_eapol(struct eapol_sm *sm, const u8 *src, const u8 *buf,
|
|
|
wpa_printf(MSG_DEBUG, "EAPOL: Received EAP-Packet "
|
|
|
"frame");
|
|
|
sm->eapolEap = TRUE;
|
|
|
+#ifdef CONFIG_EAP_PROXY
|
|
|
+ if (sm->use_eap_proxy) {
|
|
|
+ eap_proxy_packet_update(
|
|
|
+ sm->eap_proxy,
|
|
|
+ wpabuf_mhead_u8(sm->eapReqData),
|
|
|
+ wpabuf_len(sm->eapReqData));
|
|
|
+ wpa_printf(MSG_DEBUG, "EAPOL: eap_proxy "
|
|
|
+ "EAP Req updated");
|
|
|
+ }
|
|
|
+#endif /* CONFIG_EAP_PROXY */
|
|
|
eapol_sm_step(sm);
|
|
|
}
|
|
|
break;
|
|
@@ -1387,6 +1440,9 @@ void eapol_sm_notify_config(struct eapol_sm *sm,
|
|
|
return;
|
|
|
|
|
|
sm->config = config;
|
|
|
+#ifdef CONFIG_EAP_PROXY
|
|
|
+ sm->use_eap_proxy = eap_proxy_notify_config(sm->eap_proxy, config) > 0;
|
|
|
+#endif /* CONFIG_EAP_PROXY */
|
|
|
|
|
|
if (conf == NULL)
|
|
|
return;
|
|
@@ -1395,6 +1451,12 @@ void eapol_sm_notify_config(struct eapol_sm *sm,
|
|
|
sm->conf.required_keys = conf->required_keys;
|
|
|
sm->conf.fast_reauth = conf->fast_reauth;
|
|
|
sm->conf.workaround = conf->workaround;
|
|
|
+#ifdef CONFIG_EAP_PROXY
|
|
|
+ if (sm->use_eap_proxy) {
|
|
|
+ /* Using EAP Proxy, so skip EAP state machine update */
|
|
|
+ return;
|
|
|
+ }
|
|
|
+#endif /* CONFIG_EAP_PROXY */
|
|
|
if (sm->eap) {
|
|
|
eap_set_fast_reauth(sm->eap, conf->fast_reauth);
|
|
|
eap_set_workaround(sm->eap, conf->workaround);
|
|
@@ -1419,6 +1481,22 @@ int eapol_sm_get_key(struct eapol_sm *sm, u8 *key, size_t len)
|
|
|
const u8 *eap_key;
|
|
|
size_t eap_len;
|
|
|
|
|
|
+#ifdef CONFIG_EAP_PROXY
|
|
|
+ if (sm->use_eap_proxy) {
|
|
|
+ /* Get key from EAP proxy */
|
|
|
+ if (sm == NULL || !eap_proxy_key_available(sm->eap_proxy)) {
|
|
|
+ wpa_printf(MSG_DEBUG, "EAPOL: EAP key not available");
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ eap_key = eap_proxy_get_eapKeyData(sm->eap_proxy, &eap_len);
|
|
|
+ if (eap_key == NULL) {
|
|
|
+ wpa_printf(MSG_DEBUG, "EAPOL: Failed to get "
|
|
|
+ "eapKeyData");
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ goto key_fetched;
|
|
|
+ }
|
|
|
+#endif /* CONFIG_EAP_PROXY */
|
|
|
if (sm == NULL || !eap_key_available(sm->eap)) {
|
|
|
wpa_printf(MSG_DEBUG, "EAPOL: EAP key not available");
|
|
|
return -1;
|
|
@@ -1428,6 +1506,9 @@ int eapol_sm_get_key(struct eapol_sm *sm, u8 *key, size_t len)
|
|
|
wpa_printf(MSG_DEBUG, "EAPOL: Failed to get eapKeyData");
|
|
|
return -1;
|
|
|
}
|
|
|
+#ifdef CONFIG_EAP_PROXY
|
|
|
+key_fetched:
|
|
|
+#endif /* CONFIG_EAP_PROXY */
|
|
|
if (len > eap_len) {
|
|
|
wpa_printf(MSG_DEBUG, "EAPOL: Requested key length (%lu) not "
|
|
|
"available (len=%lu)",
|
|
@@ -1889,6 +1970,14 @@ struct eapol_sm *eapol_sm_init(struct eapol_ctx *ctx)
|
|
|
return NULL;
|
|
|
}
|
|
|
|
|
|
+#ifdef CONFIG_EAP_PROXY
|
|
|
+ sm->use_eap_proxy = FALSE;
|
|
|
+ sm->eap_proxy = eap_proxy_init(sm, &eapol_cb, sm->ctx->msg_ctx);
|
|
|
+ if (sm->eap_proxy == NULL) {
|
|
|
+ wpa_printf(MSG_ERROR, "Unable to initialize EAP Proxy");
|
|
|
+ }
|
|
|
+#endif /* CONFIG_EAP_PROXY */
|
|
|
+
|
|
|
/* Initialize EAPOL state machines */
|
|
|
sm->initialize = TRUE;
|
|
|
eapol_sm_step(sm);
|
|
@@ -1915,6 +2004,9 @@ void eapol_sm_deinit(struct eapol_sm *sm)
|
|
|
eloop_cancel_timeout(eapol_sm_step_timeout, NULL, sm);
|
|
|
eloop_cancel_timeout(eapol_port_timers_tick, NULL, sm);
|
|
|
eap_peer_sm_deinit(sm->eap);
|
|
|
+#ifdef CONFIG_EAP_PROXY
|
|
|
+ eap_proxy_deinit(sm->eap_proxy);
|
|
|
+#endif /* CONFIG_EAP_PROXY */
|
|
|
os_free(sm->last_rx_key);
|
|
|
wpabuf_free(sm->eapReqData);
|
|
|
os_free(sm->ctx);
|