From 735a216da31d8440d23fed4355521013ead630f3 Mon Sep 17 00:00:00 2001 From: Pavel Grafov Date: Thu, 18 Mar 2021 22:46:08 +0000 Subject: [PATCH] Prevent disconnecting admin-configured VPN First, if the VPN is configured by an admin, the preference is disabled and tapping on it will results in a policy disclouser dialog. In addition restriction checks in the dialog also check if the VPN is admin-configured. Bug: 179975048 Test: Manual, setting VPN in profile and primary user and via DPM API. Test: make RunSettingsRoboTests -j Merged-In: Id59d2ac2782e83601bc3093d3a092faea36ff5d9 Change-Id: Id59d2ac2782e83601bc3093d3a092faea36ff5d9 --- .../settings/vpn2/AppDialogFragment.java | 12 ++++++++-- .../android/settings/vpn2/AppPreference.java | 23 +++++++++++++++++++ 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/src/com/android/settings/vpn2/AppDialogFragment.java b/src/com/android/settings/vpn2/AppDialogFragment.java index ea9e546a6e5..60c65965a00 100644 --- a/src/com/android/settings/vpn2/AppDialogFragment.java +++ b/src/com/android/settings/vpn2/AppDialogFragment.java @@ -17,6 +17,7 @@ package com.android.settings.vpn2; import android.app.Dialog; +import android.app.admin.DevicePolicyManager; import android.app.settings.SettingsEnums; import android.content.Context; import android.content.DialogInterface; @@ -55,6 +56,7 @@ public class AppDialogFragment extends InstrumentedDialogFragment implements App private UserManager mUserManager; private final IConnectivityManager mService = IConnectivityManager.Stub.asInterface( ServiceManager.getService(Context.CONNECTIVITY_SERVICE)); + private DevicePolicyManager mDevicePolicyManager; @Override public int getMetricsCategory() { @@ -97,7 +99,11 @@ public class AppDialogFragment extends InstrumentedDialogFragment implements App @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + mPackageInfo = getArguments().getParcelable(ARG_PACKAGE); mUserManager = UserManager.get(getContext()); + mDevicePolicyManager = getContext() + .createContextAsUser(UserHandle.of(getUserId()), /* flags= */ 0) + .getSystemService(DevicePolicyManager.class); } @Override @@ -106,7 +112,6 @@ public class AppDialogFragment extends InstrumentedDialogFragment implements App final String label = args.getString(ARG_LABEL); boolean managing = args.getBoolean(ARG_MANAGING); boolean connected = args.getBoolean(ARG_CONNECTED); - mPackageInfo = args.getParcelable(ARG_PACKAGE); if (managing) { return new AppDialog(getActivity(), this, mPackageInfo, label); @@ -178,7 +183,10 @@ public class AppDialogFragment extends InstrumentedDialogFragment implements App private boolean isUiRestricted() { final UserHandle userHandle = UserHandle.of(getUserId()); - return mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_VPN, userHandle); + if (mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_VPN, userHandle)) { + return true; + } + return mPackageInfo.packageName.equals(mDevicePolicyManager.getAlwaysOnVpnPackage()); } private int getUserId() { diff --git a/src/com/android/settings/vpn2/AppPreference.java b/src/com/android/settings/vpn2/AppPreference.java index 6b64250df32..8ee2f5f2d0c 100644 --- a/src/com/android/settings/vpn2/AppPreference.java +++ b/src/com/android/settings/vpn2/AppPreference.java @@ -16,6 +16,7 @@ package com.android.settings.vpn2; +import android.app.admin.DevicePolicyManager; import android.content.Context; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; @@ -26,6 +27,8 @@ import androidx.preference.Preference; import com.android.internal.net.LegacyVpnInfo; import com.android.internal.net.VpnConfig; +import com.android.settingslib.RestrictedLockUtils; +import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin; /** * {@link androidx.preference.Preference} containing information about a VPN @@ -43,6 +46,7 @@ public class AppPreference extends ManageablePreference { super.setUserId(userId); mPackageName = packageName; + disableIfConfiguredByAdmin(); // Fetch icon and VPN label String label = packageName; @@ -74,6 +78,25 @@ public class AppPreference extends ManageablePreference { setIcon(icon); } + /** + * Disable this preference if VPN is set as always on by a profile or device owner. + * NB: it should be called after super.setUserId() otherwise admin information can be lost. + */ + private void disableIfConfiguredByAdmin() { + if (isDisabledByAdmin()) { + // Already disabled due to user restriction. + return; + } + final DevicePolicyManager dpm = getContext() + .createContextAsUser(UserHandle.of(getUserId()), /* flags= */ 0) + .getSystemService(DevicePolicyManager.class); + if (mPackageName.equals(dpm.getAlwaysOnVpnPackage())) { + final EnforcedAdmin admin = RestrictedLockUtils.getProfileOrDeviceOwner( + getContext(), UserHandle.of(mUserId)); + setDisabledByAdmin(admin); + } + } + public PackageInfo getPackageInfo() { try { PackageManager pm = getUserContext().getPackageManager();