forked from PeterGSI/patches
202 lines
8.6 KiB
Diff
202 lines
8.6 KiB
Diff
From af0cbe50e889694dc72ab84c4e1af816bdd199b9 Mon Sep 17 00:00:00 2001
|
|
From: Oliver Scott <olivercscott@gmail.com>
|
|
Date: Thu, 8 Jul 2021 10:41:43 -0400
|
|
Subject: [PATCH 4/6] Global VPN feature [1/2]
|
|
|
|
* Modify existing VPN user range functions to conditionally have traffic
|
|
from all users pass through the global VPN.
|
|
These functions are called when:
|
|
1. Starting a VPN
|
|
2. Adding a user
|
|
3. Removing a user
|
|
* Disallow starting VPNs in secondary users when a global VPN is set
|
|
|
|
Also includes:
|
|
Author: Oliver Scott <olivercscott@gmail.com>
|
|
Date: 2021-08-27 16:30:22 -0400
|
|
|
|
Show Global VPN icon on all users
|
|
|
|
Change-Id: I496c0abbdf92b8f823bc57b297473aa14bd968c8
|
|
|
|
Change-Id: I42616cc1f4e39e1dad739d81f6d5c55e218be995
|
|
Signed-off-by: Mohammad Hasan Keramat J <ikeramat@protonmail.com>
|
|
---
|
|
core/java/android/provider/Settings.java | 6 +++
|
|
.../policy/SecurityControllerImpl.java | 8 +++-
|
|
.../com/android/server/connectivity/Vpn.java | 37 +++++++++++++++++--
|
|
3 files changed, 46 insertions(+), 5 deletions(-)
|
|
|
|
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
|
|
index 8d8379831e87..bd6cc1d4d7bf 100644
|
|
--- a/core/java/android/provider/Settings.java
|
|
+++ b/core/java/android/provider/Settings.java
|
|
@@ -16060,6 +16060,12 @@ public final class Settings {
|
|
CLOCKWORK_HOME_READY,
|
|
};
|
|
|
|
+ /**
|
|
+ * Package designated as global VPN provider.
|
|
+ * @hide
|
|
+ */
|
|
+ public static final String GLOBAL_VPN_APP = "global_vpn_app";
|
|
+
|
|
/**
|
|
* Keys we no longer back up under the current schema, but want to continue to
|
|
* process when restoring historical backup datasets.
|
|
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java
|
|
index ba947149d287..e5eb04c7818d 100644
|
|
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java
|
|
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java
|
|
@@ -39,6 +39,7 @@ import android.os.Handler;
|
|
import android.os.RemoteException;
|
|
import android.os.UserHandle;
|
|
import android.os.UserManager;
|
|
+import android.provider.Settings;
|
|
import android.security.KeyChain;
|
|
import android.util.ArrayMap;
|
|
import android.util.Log;
|
|
@@ -332,8 +333,13 @@ public class SecurityControllerImpl implements SecurityController {
|
|
@Override
|
|
public void onUserSwitched(int newUserId) {
|
|
mCurrentUserId = newUserId;
|
|
+ final String globalVpnApp = Settings.Global.getString(mContext.getContentResolver(),
|
|
+ Settings.Global.GLOBAL_VPN_APP);
|
|
final UserInfo newUserInfo = mUserManager.getUserInfo(newUserId);
|
|
- if (newUserInfo.isRestricted()) {
|
|
+ if (mCurrentVpns.get(UserHandle.USER_SYSTEM) != null &&
|
|
+ mCurrentVpns.get(UserHandle.USER_SYSTEM).user.equals(globalVpnApp)) {
|
|
+ mVpnUserId = UserHandle.USER_SYSTEM;
|
|
+ } else if (newUserInfo.isRestricted()) {
|
|
// VPN for a restricted profile is routed through its owner user
|
|
mVpnUserId = newUserInfo.restrictedProfileParentId;
|
|
} else {
|
|
diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java
|
|
index 8510de4ef201..7c02924a711d 100644
|
|
--- a/services/core/java/com/android/server/connectivity/Vpn.java
|
|
+++ b/services/core/java/com/android/server/connectivity/Vpn.java
|
|
@@ -691,6 +691,15 @@ public class Vpn {
|
|
return mAlwaysOn;
|
|
}
|
|
|
|
+ /**
|
|
+ * Returns whether currently prepared VPN package is set as the global VPN.
|
|
+ */
|
|
+ private synchronized boolean isGlobalVpn() {
|
|
+ final String globalVpnPkg = Settings.Global.getString(mContext.getContentResolver(),
|
|
+ Settings.Global.GLOBAL_VPN_APP);
|
|
+ return mUserId == UserHandle.USER_SYSTEM && mPackage.equals(globalVpnPkg);
|
|
+ }
|
|
+
|
|
/**
|
|
* Checks if a VPN app supports always-on mode.
|
|
*
|
|
@@ -1559,6 +1568,7 @@ public class Vpn {
|
|
try {
|
|
// Restricted users are not allowed to create VPNs, they are tied to Owner
|
|
enforceNotRestrictedUser();
|
|
+ enforceNotGlobalVpn();
|
|
|
|
final PackageManager packageManager = mUserIdContext.getPackageManager();
|
|
if (packageManager == null) {
|
|
@@ -1720,7 +1730,7 @@ public class Vpn {
|
|
addUserToRanges(ranges, userId, allowedApplications, disallowedApplications);
|
|
|
|
// If the user can have restricted profiles, assign all its restricted profiles too
|
|
- if (canHaveRestrictedProfile(userId)) {
|
|
+ if (canHaveRestrictedProfile(userId) || isGlobalVpn()) {
|
|
final long token = Binder.clearCallingIdentity();
|
|
List<UserInfo> users;
|
|
try {
|
|
@@ -1729,7 +1739,8 @@ public class Vpn {
|
|
Binder.restoreCallingIdentity(token);
|
|
}
|
|
for (UserInfo user : users) {
|
|
- if (user.isRestricted() && (user.restrictedProfileParentId == userId)) {
|
|
+ if ((user.isRestricted() && (user.restrictedProfileParentId == userId))
|
|
+ || isGlobalVpn()) {
|
|
addUserToRanges(ranges, user.id, allowedApplications, disallowedApplications);
|
|
}
|
|
}
|
|
@@ -1810,7 +1821,8 @@ public class Vpn {
|
|
public void onUserAdded(int userId) {
|
|
// If the user is restricted tie them to the parent user's VPN
|
|
UserInfo user = mUserManager.getUserInfo(userId);
|
|
- if (user.isRestricted() && user.restrictedProfileParentId == mUserId) {
|
|
+ if ((user.isRestricted() && user.restrictedProfileParentId == mUserId) ||
|
|
+ isGlobalVpn()) {
|
|
synchronized(Vpn.this) {
|
|
final Set<Range<Integer>> existingRanges = mNetworkCapabilities.getUids();
|
|
if (existingRanges != null) {
|
|
@@ -1839,7 +1851,8 @@ public class Vpn {
|
|
public void onUserRemoved(int userId) {
|
|
// clean up if restricted
|
|
UserInfo user = mUserManager.getUserInfo(userId);
|
|
- if (user.isRestricted() && user.restrictedProfileParentId == mUserId) {
|
|
+ if ((user.isRestricted() && user.restrictedProfileParentId == mUserId) ||
|
|
+ isGlobalVpn()) {
|
|
synchronized(Vpn.this) {
|
|
final Set<Range<Integer>> existingRanges = mNetworkCapabilities.getUids();
|
|
if (existingRanges != null) {
|
|
@@ -2278,6 +2291,17 @@ public class Vpn {
|
|
}
|
|
}
|
|
|
|
+ private void enforceNotGlobalVpn() {
|
|
+ Binder.withCleanCallingIdentity(() -> {
|
|
+ if (mUserId != UserHandle.USER_SYSTEM && !TextUtils.isEmpty(
|
|
+ Settings.Global.getString(mContext.getContentResolver(),
|
|
+ Settings.Global.GLOBAL_VPN_APP))) {
|
|
+ throw new SecurityException("Secondary users cannot configure VPNs when" +
|
|
+ " global vpn is set");
|
|
+ }
|
|
+ });
|
|
+ }
|
|
+
|
|
/**
|
|
* Start legacy VPN, controlling native daemons as needed. Creates a
|
|
* secondary thread to perform connection work, returning quickly.
|
|
@@ -2362,6 +2386,7 @@ public class Vpn {
|
|
new UserHandle(mUserId))) {
|
|
throw new SecurityException("Restricted users cannot establish VPNs");
|
|
}
|
|
+ enforceNotGlobalVpn();
|
|
|
|
final RouteInfo ipv4DefaultRoute = findIPv4DefaultRoute(egress);
|
|
final String gateway = ipv4DefaultRoute.getGateway().getHostAddress();
|
|
@@ -3859,6 +3884,7 @@ public class Vpn {
|
|
|
|
verifyCallingUidAndPackage(packageName);
|
|
enforceNotRestrictedUser();
|
|
+ enforceNotGlobalVpn();
|
|
validateRequiredFeatures(profile);
|
|
|
|
if (profile.isRestrictedToTestNetworks) {
|
|
@@ -3901,6 +3927,7 @@ public class Vpn {
|
|
|
|
verifyCallingUidAndPackage(packageName);
|
|
enforceNotRestrictedUser();
|
|
+ enforceNotGlobalVpn();
|
|
|
|
final long token = Binder.clearCallingIdentity();
|
|
try {
|
|
@@ -3964,6 +3991,7 @@ public class Vpn {
|
|
requireNonNull(packageName, "No package name provided");
|
|
|
|
enforceNotRestrictedUser();
|
|
+ enforceNotGlobalVpn();
|
|
|
|
// Prepare VPN for startup
|
|
if (!prepare(packageName, null /* newPackage */, VpnManager.TYPE_VPN_PLATFORM)) {
|
|
@@ -4085,6 +4113,7 @@ public class Vpn {
|
|
requireNonNull(packageName, "No package name provided");
|
|
|
|
enforceNotRestrictedUser();
|
|
+ enforceNotGlobalVpn();
|
|
|
|
// To stop the VPN profile, the caller must be the current prepared package and must be
|
|
// running an Ikev2VpnProfile.
|
|
--
|
|
2.41.0
|
|
|