diff options
-rw-r--r-- | core/java/com/android/internal/net/VpnConfig.java | 6 | ||||
-rw-r--r-- | packages/VpnDialogs/AndroidManifest.xml | 3 | ||||
-rw-r--r-- | services/java/com/android/server/connectivity/Vpn.java | 34 |
3 files changed, 31 insertions, 12 deletions
diff --git a/core/java/com/android/internal/net/VpnConfig.java b/core/java/com/android/internal/net/VpnConfig.java index d61a579..d6f9e07 100644 --- a/core/java/com/android/internal/net/VpnConfig.java +++ b/core/java/com/android/internal/net/VpnConfig.java @@ -34,17 +34,19 @@ public class VpnConfig implements Parcelable { public static final String SERVICE_INTERFACE = "android.net.VpnService"; + public static final String DIALOGS_PACKAGE = "com.android.vpndialogs"; + public static final String LEGACY_VPN = "[Legacy VPN]"; public static Intent getIntentForConfirmation() { Intent intent = new Intent(); - intent.setClassName("com.android.vpndialogs", "com.android.vpndialogs.ConfirmDialog"); + intent.setClassName(DIALOGS_PACKAGE, DIALOGS_PACKAGE + ".ConfirmDialog"); return intent; } public static PendingIntent getIntentForStatusPanel(Context context, VpnConfig config) { Intent intent = new Intent(); - intent.setClassName("com.android.vpndialogs", "com.android.vpndialogs.ManageDialog"); + intent.setClassName(DIALOGS_PACKAGE, DIALOGS_PACKAGE + ".ManageDialog"); intent.putExtra("config", config); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_NO_HISTORY | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); diff --git a/packages/VpnDialogs/AndroidManifest.xml b/packages/VpnDialogs/AndroidManifest.xml index 46c0f83..ef640d5 100644 --- a/packages/VpnDialogs/AndroidManifest.xml +++ b/packages/VpnDialogs/AndroidManifest.xml @@ -1,6 +1,5 @@ <manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="com.android.vpndialogs" - android:sharedUserId="android.uid.system"> + package="com.android.vpndialogs"> <application android:label="VpnDialogs" android:allowBackup="false" > 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 @@ public class Vpn extends INetworkManagementEventObserver.Stub { 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 class Vpn extends INetworkManagementEventObserver.Stub { 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 @@ public class Vpn extends INetworkManagementEventObserver.Stub { * 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(); } |