Merge changes from topic "VPN_APPOPS" am: 357179542a am: 1d6536fda4
Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/1854374 Change-Id: I1b8dc8856e8f103cd931b5993320b07f2ee767ca
This commit is contained in:
@@ -126,6 +126,7 @@ import com.android.server.net.BaseNetworkObserver;
|
||||
import libcore.io.IoUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
@@ -195,6 +196,7 @@ public class Vpn {
|
||||
|
||||
private final Context mContext;
|
||||
private final ConnectivityManager mConnectivityManager;
|
||||
private final AppOpsManager mAppOpsManager;
|
||||
// The context is for specific user which is created from mUserId
|
||||
private final Context mUserIdContext;
|
||||
@VisibleForTesting final Dependencies mDeps;
|
||||
@@ -407,6 +409,46 @@ public class Vpn {
|
||||
public boolean isInterfacePresent(final Vpn vpn, final String iface) {
|
||||
return vpn.jniCheck(iface) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ParcelFileDescriptor#adoptFd(int)
|
||||
*/
|
||||
public ParcelFileDescriptor adoptFd(Vpn vpn, int mtu) {
|
||||
return ParcelFileDescriptor.adoptFd(jniCreate(vpn, mtu));
|
||||
}
|
||||
|
||||
/**
|
||||
* Call native method to create the VPN interface and return the FileDescriptor of /dev/tun.
|
||||
*/
|
||||
public int jniCreate(Vpn vpn, int mtu) {
|
||||
return vpn.jniCreate(mtu);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call native method to get the interface name of VPN.
|
||||
*/
|
||||
public String jniGetName(Vpn vpn, int fd) {
|
||||
return vpn.jniGetName(fd);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call native method to set the VPN addresses and return the number of addresses.
|
||||
*/
|
||||
public int jniSetAddresses(Vpn vpn, String interfaze, String addresses) {
|
||||
return vpn.jniSetAddresses(interfaze, addresses);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see IoUtils#setBlocking(FileDescriptor, boolean)
|
||||
*/
|
||||
public void setBlocking(FileDescriptor fd, boolean blocking) {
|
||||
try {
|
||||
IoUtils.setBlocking(fd, blocking);
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException(
|
||||
"Cannot set tunnel's fd as blocking=" + blocking, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Vpn(Looper looper, Context context, INetworkManagementService netService, INetd netd,
|
||||
@@ -431,6 +473,7 @@ public class Vpn {
|
||||
mVpnProfileStore = vpnProfileStore;
|
||||
mContext = context;
|
||||
mConnectivityManager = mContext.getSystemService(ConnectivityManager.class);
|
||||
mAppOpsManager = mContext.getSystemService(AppOpsManager.class);
|
||||
mUserIdContext = context.createContextAsUser(UserHandle.of(userId), 0 /* flags */);
|
||||
mDeps = deps;
|
||||
mNms = netService;
|
||||
@@ -826,7 +869,6 @@ public class Vpn {
|
||||
VpnProfile profile = getVpnProfilePrivileged(alwaysOnPackage);
|
||||
if (profile != null) {
|
||||
startVpnProfilePrivileged(profile, alwaysOnPackage);
|
||||
|
||||
// If the above startVpnProfilePrivileged() call returns, the Ikev2VpnProfile was
|
||||
// correctly parsed, and the VPN has started running in a different thread. The only
|
||||
// other possibility is that the above call threw an exception, which will be
|
||||
@@ -974,9 +1016,15 @@ public class Vpn {
|
||||
} catch (Exception e) {
|
||||
// ignore
|
||||
}
|
||||
mAppOpsManager.finishOp(
|
||||
AppOpsManager.OPSTR_ESTABLISH_VPN_SERVICE, mOwnerUID, mPackage, null);
|
||||
mContext.unbindService(mConnection);
|
||||
cleanupVpnStateLocked();
|
||||
} else if (mVpnRunner != null) {
|
||||
if (!VpnConfig.LEGACY_VPN.equals(mPackage)) {
|
||||
mAppOpsManager.finishOp(
|
||||
AppOpsManager.OPSTR_ESTABLISH_VPN_MANAGER, mOwnerUID, mPackage, null);
|
||||
}
|
||||
// cleanupVpnStateLocked() is called from mVpnRunner.exit()
|
||||
mVpnRunner.exit();
|
||||
}
|
||||
@@ -1041,10 +1089,8 @@ public class Vpn {
|
||||
return false;
|
||||
}
|
||||
|
||||
final AppOpsManager appOpMgr =
|
||||
(AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);
|
||||
for (final String appOpStr : toChange) {
|
||||
appOpMgr.setMode(
|
||||
mAppOpsManager.setMode(
|
||||
appOpStr,
|
||||
uid,
|
||||
packageName,
|
||||
@@ -1366,9 +1412,9 @@ public class Vpn {
|
||||
Set<Range<Integer>> oldUsers = mNetworkCapabilities.getUids();
|
||||
|
||||
// Configure the interface. Abort if any of these steps fails.
|
||||
ParcelFileDescriptor tun = ParcelFileDescriptor.adoptFd(jniCreate(config.mtu));
|
||||
final ParcelFileDescriptor tun = mDeps.adoptFd(this, config.mtu);
|
||||
try {
|
||||
String interfaze = jniGetName(tun.getFd());
|
||||
final String interfaze = mDeps.jniGetName(this, tun.getFd());
|
||||
|
||||
// TEMP use the old jni calls until there is support for netd address setting
|
||||
StringBuilder builder = new StringBuilder();
|
||||
@@ -1376,7 +1422,7 @@ public class Vpn {
|
||||
builder.append(" ");
|
||||
builder.append(address);
|
||||
}
|
||||
if (jniSetAddresses(interfaze, builder.toString()) < 1) {
|
||||
if (mDeps.jniSetAddresses(this, interfaze, builder.toString()) < 1) {
|
||||
throw new IllegalArgumentException("At least one address must be specified");
|
||||
}
|
||||
Connection connection = new Connection();
|
||||
@@ -1422,11 +1468,11 @@ public class Vpn {
|
||||
jniReset(oldInterface);
|
||||
}
|
||||
|
||||
try {
|
||||
IoUtils.setBlocking(tun.getFileDescriptor(), config.blocking);
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException(
|
||||
"Cannot set tunnel's fd as blocking=" + config.blocking, e);
|
||||
mDeps.setBlocking(tun.getFileDescriptor(), config.blocking);
|
||||
// Record that the VPN connection is established by an app which uses VpnService API.
|
||||
if (oldNetworkAgent != mNetworkAgent) {
|
||||
mAppOpsManager.startOp(
|
||||
AppOpsManager.OPSTR_ESTABLISH_VPN_SERVICE, mOwnerUID, mPackage, null, null);
|
||||
}
|
||||
} catch (RuntimeException e) {
|
||||
IoUtils.closeQuietly(tun);
|
||||
@@ -1781,9 +1827,17 @@ public class Vpn {
|
||||
synchronized (Vpn.this) {
|
||||
if (interfaze.equals(mInterface) && jniCheck(interfaze) == 0) {
|
||||
if (mConnection != null) {
|
||||
mAppOpsManager.finishOp(
|
||||
AppOpsManager.OPSTR_ESTABLISH_VPN_SERVICE, mOwnerUID, mPackage,
|
||||
null);
|
||||
mContext.unbindService(mConnection);
|
||||
cleanupVpnStateLocked();
|
||||
} else if (mVpnRunner != null) {
|
||||
if (!VpnConfig.LEGACY_VPN.equals(mPackage)) {
|
||||
mAppOpsManager.finishOp(
|
||||
AppOpsManager.OPSTR_ESTABLISH_VPN_MANAGER, mOwnerUID, mPackage,
|
||||
null);
|
||||
}
|
||||
// cleanupVpnStateLocked() is called from mVpnRunner.exit()
|
||||
mVpnRunner.exit();
|
||||
}
|
||||
@@ -3254,8 +3308,7 @@ public class Vpn {
|
||||
*
|
||||
* @param packageName the package name of the app provisioning this profile
|
||||
*/
|
||||
public synchronized void startVpnProfile(
|
||||
@NonNull String packageName) {
|
||||
public synchronized void startVpnProfile(@NonNull String packageName) {
|
||||
requireNonNull(packageName, "No package name provided");
|
||||
|
||||
enforceNotRestrictedUser();
|
||||
@@ -3318,6 +3371,13 @@ public class Vpn {
|
||||
Log.d(TAG, "Unknown VPN profile type: " + profile.type);
|
||||
break;
|
||||
}
|
||||
|
||||
// Record that the VPN connection is established by an app which uses VpnManager API.
|
||||
if (!VpnConfig.LEGACY_VPN.equals(packageName)) {
|
||||
mAppOpsManager.startOp(
|
||||
AppOpsManager.OPSTR_ESTABLISH_VPN_MANAGER, mOwnerUID, mPackage, null,
|
||||
null);
|
||||
}
|
||||
} catch (GeneralSecurityException e) {
|
||||
// Reset mConfig
|
||||
mConfig = null;
|
||||
|
||||
Reference in New Issue
Block a user