Reset idenitities for EAP-SIM networks when SIM is pulled

This change resets identity and anonymous_identity for all
networks that use SIM based auth. This ensures that all cached
data is destroyed when SIM is removed; and newly added SIM
must be authorized on the network to connect again.

Bug: 23703716

Change-Id: I83d80336b2089c73d99214651b64b79443faf7f7
diff --git a/service/java/com/android/server/wifi/WifiConfigStore.java b/service/java/com/android/server/wifi/WifiConfigStore.java
index d40b875..25d8ece 100644
--- a/service/java/com/android/server/wifi/WifiConfigStore.java
+++ b/service/java/com/android/server/wifi/WifiConfigStore.java
@@ -3991,6 +3991,31 @@
         return false;
     }
 
+    static boolean isSimConfig(WifiConfiguration config) {
+        if (config == null) {
+            return false;
+        }
+
+        if (config.enterpriseConfig == null) {
+            return false;
+        }
+
+        int method = config.enterpriseConfig.getEapMethod();
+        return (method == WifiEnterpriseConfig.Eap.SIM
+                || method == WifiEnterpriseConfig.Eap.AKA
+                || method == WifiEnterpriseConfig.Eap.AKA_PRIME);
+    }
+
+    void resetSimNetworks() {
+        for(WifiConfiguration config : mConfiguredNetworks.values()) {
+            if (isSimConfig(config)) {
+                /* This configuration may have cached Pseudonym IDs; lets remove them */
+                mWifiNative.setNetworkVariable(config.networkId, "identity", "NULL");
+                mWifiNative.setNetworkVariable(config.networkId, "anonymous_identity", "NULL");
+            }
+        }
+    }
+
     boolean isNetworkConfigured(WifiConfiguration config) {
         // Check if either we have a network Id or a WifiConfiguration
         // matching the one we are trying to add.
diff --git a/service/java/com/android/server/wifi/WifiServiceImpl.java b/service/java/com/android/server/wifi/WifiServiceImpl.java
index 33ce852..5ab035c 100644
--- a/service/java/com/android/server/wifi/WifiServiceImpl.java
+++ b/service/java/com/android/server/wifi/WifiServiceImpl.java
@@ -373,6 +373,8 @@
                     public void onReceive(Context context, Intent intent) {
                         String state = intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE);
                         if (state.equals(IccCardConstants.INTENT_VALUE_ICC_ABSENT)) {
+                            Log.d(TAG, "resetting networks because SIM was removed");
+                            mWifiStateMachine.resetSimAuthNetworks();
                             Log.d(TAG, "resetting country code because SIM is removed");
                             mWifiStateMachine.resetCountryCode();
                         }
diff --git a/service/java/com/android/server/wifi/WifiStateMachine.java b/service/java/com/android/server/wifi/WifiStateMachine.java
index ced5bab..7773cb9 100644
--- a/service/java/com/android/server/wifi/WifiStateMachine.java
+++ b/service/java/com/android/server/wifi/WifiStateMachine.java
@@ -743,6 +743,9 @@
     /* alert from firmware */
     static final int CMD_FIRMWARE_ALERT                                 = BASE + 100;
 
+    /* SIM is removed; reset any cached data for it */
+    static final int CMD_RESET_SIM_NETWORKS                             = BASE + 101;
+
     /**
      * Make this timer 40 seconds, which is about the normal DHCP timeout.
      * In no valid case, the WiFiStateMachine should remain stuck in ObtainingIpAddress
@@ -2472,6 +2475,14 @@
     }
 
     /**
+     * reset cached SIM credential data
+     */
+    public synchronized void resetSimAuthNetworks() {
+        sendMessage(CMD_RESET_SIM_NETWORKS);
+    }
+
+
+    /**
      * Get Network object of current wifi network
      * @return Network object of current wifi network
      */
@@ -6095,6 +6106,10 @@
 
                     mWifiP2pChannel.sendMessage(WifiP2pServiceImpl.SET_COUNTRY_CODE, country);
                     break;
+                case CMD_RESET_SIM_NETWORKS:
+                    log("resetting EAP-SIM/AKA/AKA' networks since SIM was removed");
+                    mWifiConfigStore.resetSimNetworks();
+                    break;
                 default:
                     return NOT_HANDLED;
             }
@@ -8569,6 +8584,17 @@
                 case CMD_STOP_RSSI_MONITORING_OFFLOAD:
                     stopRssiMonitoringOffload();
                     break;
+                case CMD_RESET_SIM_NETWORKS:
+                    if (mLastNetworkId != WifiConfiguration.INVALID_NETWORK_ID) {
+                        WifiConfiguration config =
+                                mWifiConfigStore.getWifiConfiguration(mLastNetworkId);
+                        if (mWifiConfigStore.isSimConfig(config)) {
+                            mWifiNative.disconnect();
+                            transitionTo(mDisconnectingState);
+                        }
+                    }
+                    /* allow parent state to reset data for other networks */
+                    return NOT_HANDLED;
                 default:
                     return NOT_HANDLED;
             }