OSDN Git Service

Accumulative patch from commit b618a469c42120e984ab1c85ed6058504d1fca78
[android-x86/external-wpa_supplicant_8.git] / src / eapol_supp / eapol_supp_sm.c
index f90fb62..2e56086 100644 (file)
@@ -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);