Restrict access to protected networks.

Some networks should only be brought up and controlled by system apps.

bug: 4585677
Change-Id: I61b1ee3dcfca0ee54387cecffe5198a0b010d98b
diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java
index a8ddc15..e11190f 100644
--- a/services/java/com/android/server/ConnectivityService.java
+++ b/services/java/com/android/server/ConnectivityService.java
@@ -250,6 +250,9 @@
     }
     RadioAttributes[] mRadioAttributes;
 
+    // the set of network types that can only be enabled by system/sig apps
+    List mProtectedNetworks;
+
     public static synchronized ConnectivityService getInstance(Context context) {
         if (sServiceInstance == null) {
             sServiceInstance = new ConnectivityService(context);
@@ -349,6 +352,17 @@
             }
         }
 
+        mProtectedNetworks = new ArrayList<Integer>();
+        int[] protectedNetworks = context.getResources().getIntArray(
+                com.android.internal.R.array.config_protectedNetworks);
+        for (int p : protectedNetworks) {
+            if ((mNetConfigs[p] != null) && (mProtectedNetworks.contains(p) == false)) {
+                mProtectedNetworks.add(p);
+            } else {
+                if (DBG) loge("Ignoring protectedNetwork " + p);
+            }
+        }
+
         // high priority first
         mPriorityList = new int[mNetworksDefined];
         {
@@ -678,6 +692,11 @@
                 usedNetworkType = networkType;
             }
         }
+
+        if (mProtectedNetworks.contains(usedNetworkType)) {
+            enforceConnectivityInternalPermission();
+        }
+
         NetworkStateTracker network = mNetTrackers[usedNetworkType];
         if (network != null) {
             Integer currentPid = new Integer(getCallingPid());
@@ -888,6 +907,10 @@
      */
     public boolean requestRouteToHostAddress(int networkType, byte[] hostAddress) {
         enforceChangePermission();
+        if (mProtectedNetworks.contains(networkType)) {
+            enforceConnectivityInternalPermission();
+        }
+
         if (!ConnectivityManager.isNetworkTypeValid(networkType)) {
             return false;
         }
@@ -1005,7 +1028,8 @@
     }
 
     public void setDataDependency(int networkType, boolean met) {
-        enforceChangePermission();
+        enforceConnectivityInternalPermission();
+
         if (DBG) {
             log("setDataDependency(" + networkType + ", " + met + ")");
         }