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 Original line Diff line number Diff line
@@ -31,7 +31,7 @@ import android.util.Log;
 * Tracks the state changes in supplicant and provides functionality
 * Tracks the state changes in supplicant and provides functionality
 * that is based on these state changes:
 * that is based on these state changes:
 * - detect a failed WPA handshake that loops indefinitely
 * - detect a failed WPA handshake that loops indefinitely
 * - password failure handling
 * - authentication failure handling
 */
 */
class SupplicantStateTracker extends HierarchicalStateMachine {
class SupplicantStateTracker extends HierarchicalStateMachine {


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


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


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


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

             Message message = getCurrentMessage();
             Message message = getCurrentMessage();
             StateChangeResult stateChangeResult = (StateChangeResult) message.obj;
             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 " +
                 Log.d(TAG, "Failed to authenticate, disabling network " +
                         stateChangeResult.networkId);
                         stateChangeResult.networkId);
                 handleNetworkConnectionFailure(stateChangeResult.networkId);
                 handleNetworkConnectionFailure(stateChangeResult.networkId);
                 mPasswordFailuresCount = 0;
                 mAuthenticationFailuresCount = 0;
             }
             }
         }
         }
    }
    }
@@ -282,8 +281,8 @@ class SupplicantStateTracker extends HierarchicalStateMachine {
        @Override
        @Override
         public void enter() {
         public void enter() {
             if (DBG) Log.d(TAG, getName() + "\n");
             if (DBG) Log.d(TAG, getName() + "\n");
             /* Reset password failure count */
             /* Reset authentication failure count */
             mPasswordFailuresCount = 0;
             mAuthenticationFailuresCount = 0;
             if (mNetworksDisabledDuringConnect) {
             if (mNetworksDisabledDuringConnect) {
                 WifiConfigStore.enableAllNetworks();
                 WifiConfigStore.enableAllNetworks();
                 mNetworksDisabledDuringConnect = false;
                 mNetworksDisabledDuringConnect = false;
+22 −9
Original line number Original line Diff line number Diff line
@@ -42,7 +42,8 @@ public class WifiMonitor {
    private static final int LINK_SPEED   = 5;
    private static final int LINK_SPEED   = 5;
    private static final int TERMINATING  = 6;
    private static final int TERMINATING  = 6;
    private static final int DRIVER_STATE = 7;
    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 */
    /** All events coming from the supplicant start with this prefix */
    private static final String eventPrefix = "CTRL-EVENT-";
    private static final String eventPrefix = "CTRL-EVENT-";
@@ -110,6 +111,17 @@ public class WifiMonitor {
     * <code>state</code> is either STARTED or STOPPED
     * <code>state</code> is either STARTED or STOPPED
     */
     */
    private static final String driverStateEvent = "DRIVER-STATE";
    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.
     * 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(eventPrefix)) {
                    if (eventStr.startsWith(wpaEventPrefix) &&
                    if (eventStr.startsWith(wpaEventPrefix) &&
                            0 < eventStr.indexOf(passwordKeyMayBeIncorrectEvent)) {
                            0 < eventStr.indexOf(passwordKeyMayBeIncorrectEvent)) {
                        handlePasswordKeyMayBeIncorrect();
                        mWifiStateMachine.notifyAuthenticationFailure();
                    } else if (eventStr.startsWith(wpsOverlapEvent)) {
                    } else if (eventStr.startsWith(wpsOverlapEvent)) {
                        mWifiStateMachine.notifyWpsOverlap();
                        mWifiStateMachine.notifyWpsOverlap();
                    }
                    }
@@ -207,16 +219,17 @@ public class WifiMonitor {
                    event = LINK_SPEED;
                    event = LINK_SPEED;
                else if (eventName.equals(terminatingEvent))
                else if (eventName.equals(terminatingEvent))
                    event = TERMINATING;
                    event = TERMINATING;
                else if (eventName.equals(driverStateEvent)) {
                else if (eventName.equals(driverStateEvent))
                    event = DRIVER_STATE;
                    event = DRIVER_STATE;
                }
                else if (eventName.equals(eapFailureEvent))
                    event = EAP_FAILURE;
                else
                else
                    event = UNKNOWN;
                    event = UNKNOWN;


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


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

        private void handleDriverEvent(String state) {
        private void handleDriverEvent(String state) {
            if (state == null) {
            if (state == null) {
                return;
                return;
+11 −10
Original line number Original line Diff line number Diff line
@@ -213,8 +213,8 @@ public class WifiStateMachine extends HierarchicalStateMachine {
    static final int SCAN_RESULTS_EVENT                   = 38;
    static final int SCAN_RESULTS_EVENT                   = 38;
    /* Supplicate state changed */
    /* Supplicate state changed */
    static final int SUPPLICANT_STATE_CHANGE_EVENT        = 39;
    static final int SUPPLICANT_STATE_CHANGE_EVENT        = 39;
    /* Password may be incorrect */
    /* Password failure and EAP authentication failure */
    static final int PASSWORD_MAY_BE_INCORRECT_EVENT      = 40;
    static final int AUTHENTICATION_FAILURE_EVENT         = 40;
    /* WPS overlap detected */
    /* WPS overlap detected */
    static final int WPS_OVERLAP_EVENT                    = 41;
    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
     * Send the tracker a notification that a user provided
     * may be incorrect (i.e., caused authentication to fail).
     * configuration caused authentication failure - this could
     * be a password failure or a EAP authentication failure
     */
     */
    void notifyPasswordKeyMayBeIncorrect() {
    void notifyAuthenticationFailure() {
        sendMessage(PASSWORD_MAY_BE_INCORRECT_EVENT);
        sendMessage(AUTHENTICATION_FAILURE_EVENT);
    }
    }


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