VPN: move VpnDialogs away from system uid.

Bug: 6632536
Change-Id: Iece647c077caf5298ccfe7d7aba5f0911a4ed0d1
diff --git a/services/java/com/android/server/connectivity/Vpn.java b/services/java/com/android/server/connectivity/Vpn.java
index c4f9ce1..4b82037 100644
--- a/services/java/com/android/server/connectivity/Vpn.java
+++ b/services/java/com/android/server/connectivity/Vpn.java
@@ -106,16 +106,16 @@
             return true;
         }
 
-        // Only system user can revoke a package.
-        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
-            throw new SecurityException("Unauthorized Caller");
-        }
+        // Check if the caller is authorized.
+        enforceControlPermission();
 
         // Reset the interface and hide the notification.
         if (mInterface != null) {
             jniReset(mInterface);
+            long identity = Binder.clearCallingIdentity();
             mCallback.restore();
             hideNotification();
+            Binder.restoreCallingIdentity(identity);
             mInterface = null;
         }
 
@@ -291,6 +291,26 @@
     public void limitReached(String limit, String interfaze) {
     }
 
+    private void enforceControlPermission() {
+        // System user is allowed to control VPN.
+        if (Binder.getCallingUid() == Process.SYSTEM_UID) {
+            return;
+        }
+
+        try {
+            // System dialogs are also allowed to control VPN.
+            PackageManager pm = mContext.getPackageManager();
+            ApplicationInfo app = pm.getApplicationInfo(VpnConfig.DIALOGS_PACKAGE, 0);
+            if (Binder.getCallingUid() == app.uid) {
+                return;
+            }
+        } catch (Exception e) {
+            // ignore
+        }
+
+        throw new SecurityException("Unauthorized Caller");
+    }
+
     private class Connection implements ServiceConnection {
         private IBinder mService;
 
@@ -368,10 +388,8 @@
      * Return the information of the current ongoing legacy VPN.
      */
     public synchronized LegacyVpnInfo getLegacyVpnInfo() {
-        // Only system user can call this method.
-        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
-            throw new SecurityException("Unauthorized Caller");
-        }
+        // Check if the caller is authorized.
+        enforceControlPermission();
         return (mLegacyVpnRunner == null) ? null : mLegacyVpnRunner.getInfo();
     }