Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b98d878f authored by Irfan Sheriff's avatar Irfan Sheriff
Browse files

Handle EAP authentication failure

Avoid the scenario of an EAP network indefinitely trying to connect
due to an EAP authentication failure by disabling the network

Bug: 2149114
Change-Id: Iec8da7551c2dff9b153f41a2139529133130399d
parent 54973710
Loading
Loading
Loading
Loading
+11 −12
Original line number Diff line number Diff line
@@ -31,7 +31,7 @@ import android.util.Log;
 * Tracks the state changes in supplicant and provides functionality
 * that is based on these state changes:
 * - detect a failed WPA handshake that loops indefinitely
 * - password failure handling
 * - authentication failure handling
 */
class SupplicantStateTracker extends HierarchicalStateMachine {

@@ -39,14 +39,14 @@ class SupplicantStateTracker extends HierarchicalStateMachine {
    private static final boolean DBG = false;

    private WifiStateMachine mWifiStateMachine;
    private int mPasswordFailuresCount = 0;
    private int mAuthenticationFailuresCount = 0;
    /* Indicates authentication failure in supplicant broadcast.
     * TODO: enhance auth failure reporting to include notification
     * for all type of failures: EAP, WPS & WPA networks */
    private boolean mAuthFailureInSupplicantBroadcast = false;

    /* Maximum retries on a password failure notification */
    private static final int MAX_RETRIES_ON_PASSWORD_FAILURE = 2;
    /* Maximum retries on a authentication failure notification */
    private static final int MAX_RETRIES_ON_AUTHENTICATION_FAILURE = 2;

    /* Tracks if networks have been disabled during a connection */
    private boolean mNetworksDisabledDuringConnect = false;
@@ -155,8 +155,8 @@ class SupplicantStateTracker extends HierarchicalStateMachine {
        public boolean processMessage(Message message) {
            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
            switch (message.what) {
                case WifiStateMachine.PASSWORD_MAY_BE_INCORRECT_EVENT:
                    mPasswordFailuresCount++;
                case WifiStateMachine.AUTHENTICATION_FAILURE_EVENT:
                    mAuthenticationFailuresCount++;
                    mAuthFailureInSupplicantBroadcast = true;
                    break;
                case WifiStateMachine.SUPPLICANT_STATE_CHANGE_EVENT:
@@ -206,18 +206,17 @@ class SupplicantStateTracker extends HierarchicalStateMachine {
        @Override
         public void enter() {
             if (DBG) Log.d(TAG, getName() + "\n");
             /* If a disconnect event happens after password key failure
             /* If a disconnect event happens after authentication failure
              * exceeds maximum retries, disable the network
              */

             Message message = getCurrentMessage();
             StateChangeResult stateChangeResult = (StateChangeResult) message.obj;

             if (mPasswordFailuresCount >= MAX_RETRIES_ON_PASSWORD_FAILURE) {
             if (mAuthenticationFailuresCount >= MAX_RETRIES_ON_AUTHENTICATION_FAILURE) {
                 Log.d(TAG, "Failed to authenticate, disabling network " +
                         stateChangeResult.networkId);
                 handleNetworkConnectionFailure(stateChangeResult.networkId);
                 mPasswordFailuresCount = 0;
                 mAuthenticationFailuresCount = 0;
             }
         }
    }
@@ -282,8 +281,8 @@ class SupplicantStateTracker extends HierarchicalStateMachine {
        @Override
         public void enter() {
             if (DBG) Log.d(TAG, getName() + "\n");
             /* Reset password failure count */
             mPasswordFailuresCount = 0;
             /* Reset authentication failure count */
             mAuthenticationFailuresCount = 0;
             if (mNetworksDisabledDuringConnect) {
                 WifiConfigStore.enableAllNetworks();
                 mNetworksDisabledDuringConnect = false;
+22 −9
Original line number Diff line number Diff line
@@ -42,7 +42,8 @@ public class WifiMonitor {
    private static final int LINK_SPEED   = 5;
    private static final int TERMINATING  = 6;
    private static final int DRIVER_STATE = 7;
    private static final int UNKNOWN      = 8;
    private static final int EAP_FAILURE  = 8;
    private static final int UNKNOWN      = 9;

    /** All events coming from the supplicant start with this prefix */
    private static final String eventPrefix = "CTRL-EVENT-";
@@ -110,6 +111,17 @@ public class WifiMonitor {
     * <code>state</code> is either STARTED or STOPPED
     */
    private static final String driverStateEvent = "DRIVER-STATE";
    /**
     * <pre>
     * CTRL-EVENT-EAP-FAILURE EAP authentication failed
     * </pre>
     */
    private static final String eapFailureEvent = "EAP-FAILURE";

    /**
     * This indicates an authentication failure on EAP FAILURE event
     */
    private static final String eapAuthFailure = "EAP authentication failed";

    /**
     * Regex pattern for extracting an Ethernet-style MAC address from a string.
@@ -176,7 +188,7 @@ public class WifiMonitor {
                if (!eventStr.startsWith(eventPrefix)) {
                    if (eventStr.startsWith(wpaEventPrefix) &&
                            0 < eventStr.indexOf(passwordKeyMayBeIncorrectEvent)) {
                        handlePasswordKeyMayBeIncorrect();
                        mWifiStateMachine.notifyAuthenticationFailure();
                    } else if (eventStr.startsWith(wpsOverlapEvent)) {
                        mWifiStateMachine.notifyWpsOverlap();
                    }
@@ -207,16 +219,17 @@ public class WifiMonitor {
                    event = LINK_SPEED;
                else if (eventName.equals(terminatingEvent))
                    event = TERMINATING;
                else if (eventName.equals(driverStateEvent)) {
                else if (eventName.equals(driverStateEvent))
                    event = DRIVER_STATE;
                }
                else if (eventName.equals(eapFailureEvent))
                    event = EAP_FAILURE;
                else
                    event = UNKNOWN;

                String eventData = eventStr;
                if (event == DRIVER_STATE || event == LINK_SPEED)
                    eventData = eventData.split(" ")[1];
                else if (event == STATE_CHANGE) {
                else if (event == STATE_CHANGE || event == EAP_FAILURE) {
                    int ind = eventStr.indexOf(" ");
                    if (ind != -1) {
                        eventData = eventStr.substring(ind + 1);
@@ -261,6 +274,10 @@ public class WifiMonitor {
                    // notify and exit
                    mWifiStateMachine.notifySupplicantLost();
                    break;
                } else if (event == EAP_FAILURE) {
                    if (eventData.startsWith(eapAuthFailure)) {
                        mWifiStateMachine.notifyAuthenticationFailure();
                    }
                } else {
                    handleEvent(event, eventData);
                }
@@ -284,10 +301,6 @@ public class WifiMonitor {
            return false;
        }

        private void handlePasswordKeyMayBeIncorrect() {
            mWifiStateMachine.notifyPasswordKeyMayBeIncorrect();
        }

        private void handleDriverEvent(String state) {
            if (state == null) {
                return;
+11 −10
Original line number Diff line number Diff line
@@ -213,8 +213,8 @@ public class WifiStateMachine extends HierarchicalStateMachine {
    static final int SCAN_RESULTS_EVENT                   = 38;
    /* Supplicate state changed */
    static final int SUPPLICANT_STATE_CHANGE_EVENT        = 39;
    /* Password may be incorrect */
    static final int PASSWORD_MAY_BE_INCORRECT_EVENT      = 40;
    /* Password failure and EAP authentication failure */
    static final int AUTHENTICATION_FAILURE_EVENT         = 40;
    /* WPS overlap detected */
    static final int WPS_OVERLAP_EVENT                    = 41;

@@ -1384,11 +1384,12 @@ public class WifiStateMachine extends HierarchicalStateMachine {
    }

    /**
     * Send the tracker a notification that a user-entered password key
     * may be incorrect (i.e., caused authentication to fail).
     * Send the tracker a notification that a user provided
     * configuration caused authentication failure - this could
     * be a password failure or a EAP authentication failure
     */
    void notifyPasswordKeyMayBeIncorrect() {
        sendMessage(PASSWORD_MAY_BE_INCORRECT_EVENT);
    void notifyAuthenticationFailure() {
        sendMessage(AUTHENTICATION_FAILURE_EVENT);
    }

    /**
@@ -1516,7 +1517,7 @@ public class WifiStateMachine extends HierarchicalStateMachine {
                case NETWORK_DISCONNECTION_EVENT:
                case SCAN_RESULTS_EVENT:
                case SUPPLICANT_STATE_CHANGE_EVENT:
                case PASSWORD_MAY_BE_INCORRECT_EVENT:
                case AUTHENTICATION_FAILURE_EVENT:
                case WPS_OVERLAP_EVENT:
                case CMD_BLACKLIST_NETWORK:
                case CMD_CLEAR_BLACKLIST:
@@ -2060,7 +2061,7 @@ public class WifiStateMachine extends HierarchicalStateMachine {
                case SUPPLICANT_STATE_CHANGE_EVENT:
                case NETWORK_CONNECTION_EVENT:
                case NETWORK_DISCONNECTION_EVENT:
                case PASSWORD_MAY_BE_INCORRECT_EVENT:
                case AUTHENTICATION_FAILURE_EVENT:
                case WPS_OVERLAP_EVENT:
                case CMD_SET_SCAN_TYPE:
                case CMD_SET_HIGH_PERF_MODE:
@@ -2293,8 +2294,8 @@ public class WifiStateMachine extends HierarchicalStateMachine {
            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
            StateChangeResult stateChangeResult;
            switch(message.what) {
                case PASSWORD_MAY_BE_INCORRECT_EVENT:
                    mSupplicantStateTracker.sendMessage(PASSWORD_MAY_BE_INCORRECT_EVENT);
                case AUTHENTICATION_FAILURE_EVENT:
                    mSupplicantStateTracker.sendMessage(AUTHENTICATION_FAILURE_EVENT);
                    break;
                case WPS_OVERLAP_EVENT:
                    /* We just need to broadcast the error */