Merge changes I5a01d709,I1b7da86d am: 95d9c6164b am: 3e07b3a7f3
Change-Id: If6905874c40756157d5c6aa33db38964c6dd5a6d
This commit is contained in:
@@ -52,6 +52,7 @@ public class VpnConfig implements Parcelable {
|
|||||||
|
|
||||||
public static final String DIALOGS_PACKAGE = "com.android.vpndialogs";
|
public static final String DIALOGS_PACKAGE = "com.android.vpndialogs";
|
||||||
|
|
||||||
|
// TODO: Rename this to something that encompasses Settings-based Platform VPNs as well.
|
||||||
public static final String LEGACY_VPN = "[Legacy VPN]";
|
public static final String LEGACY_VPN = "[Legacy VPN]";
|
||||||
|
|
||||||
public static Intent getIntentForConfirmation() {
|
public static Intent getIntentForConfirmation() {
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ import android.content.pm.UserInfo;
|
|||||||
import android.net.ConnectivityManager;
|
import android.net.ConnectivityManager;
|
||||||
import android.net.INetworkManagementEventObserver;
|
import android.net.INetworkManagementEventObserver;
|
||||||
import android.net.IpPrefix;
|
import android.net.IpPrefix;
|
||||||
|
import android.net.IpSecManager;
|
||||||
import android.net.LinkAddress;
|
import android.net.LinkAddress;
|
||||||
import android.net.LinkProperties;
|
import android.net.LinkProperties;
|
||||||
import android.net.LocalSocket;
|
import android.net.LocalSocket;
|
||||||
@@ -180,7 +181,10 @@ public class Vpn {
|
|||||||
private boolean mIsPackageTargetingAtLeastQ;
|
private boolean mIsPackageTargetingAtLeastQ;
|
||||||
private String mInterface;
|
private String mInterface;
|
||||||
private Connection mConnection;
|
private Connection mConnection;
|
||||||
private LegacyVpnRunner mLegacyVpnRunner;
|
|
||||||
|
/** Tracks the runners for all VPN types managed by the platform (eg. LegacyVpn, PlatformVpn) */
|
||||||
|
private VpnRunner mVpnRunner;
|
||||||
|
|
||||||
private PendingIntent mStatusIntent;
|
private PendingIntent mStatusIntent;
|
||||||
private volatile boolean mEnableTeardown = true;
|
private volatile boolean mEnableTeardown = true;
|
||||||
private final INetworkManagementService mNetd;
|
private final INetworkManagementService mNetd;
|
||||||
@@ -762,7 +766,7 @@ public class Vpn {
|
|||||||
mNetworkCapabilities.setUids(null);
|
mNetworkCapabilities.setUids(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Revoke the connection or stop LegacyVpnRunner.
|
// Revoke the connection or stop the VpnRunner.
|
||||||
if (mConnection != null) {
|
if (mConnection != null) {
|
||||||
try {
|
try {
|
||||||
mConnection.mService.transact(IBinder.LAST_CALL_TRANSACTION,
|
mConnection.mService.transact(IBinder.LAST_CALL_TRANSACTION,
|
||||||
@@ -772,9 +776,9 @@ public class Vpn {
|
|||||||
}
|
}
|
||||||
mContext.unbindService(mConnection);
|
mContext.unbindService(mConnection);
|
||||||
mConnection = null;
|
mConnection = null;
|
||||||
} else if (mLegacyVpnRunner != null) {
|
} else if (mVpnRunner != null) {
|
||||||
mLegacyVpnRunner.exit();
|
mVpnRunner.exit();
|
||||||
mLegacyVpnRunner = null;
|
mVpnRunner = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -1506,8 +1510,8 @@ public class Vpn {
|
|||||||
@Override
|
@Override
|
||||||
public void interfaceStatusChanged(String interfaze, boolean up) {
|
public void interfaceStatusChanged(String interfaze, boolean up) {
|
||||||
synchronized (Vpn.this) {
|
synchronized (Vpn.this) {
|
||||||
if (!up && mLegacyVpnRunner != null) {
|
if (!up && mVpnRunner != null && mVpnRunner instanceof LegacyVpnRunner) {
|
||||||
mLegacyVpnRunner.check(interfaze);
|
((LegacyVpnRunner) mVpnRunner).exitIfOuterInterfaceIs(interfaze);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1524,9 +1528,10 @@ public class Vpn {
|
|||||||
mContext.unbindService(mConnection);
|
mContext.unbindService(mConnection);
|
||||||
mConnection = null;
|
mConnection = null;
|
||||||
agentDisconnect();
|
agentDisconnect();
|
||||||
} else if (mLegacyVpnRunner != null) {
|
} else if (mVpnRunner != null) {
|
||||||
mLegacyVpnRunner.exit();
|
// agentDisconnect must be called from mVpnRunner.exit()
|
||||||
mLegacyVpnRunner = null;
|
mVpnRunner.exit();
|
||||||
|
mVpnRunner = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1909,23 +1914,40 @@ public class Vpn {
|
|||||||
|
|
||||||
private synchronized void startLegacyVpn(VpnConfig config, String[] racoon, String[] mtpd,
|
private synchronized void startLegacyVpn(VpnConfig config, String[] racoon, String[] mtpd,
|
||||||
VpnProfile profile) {
|
VpnProfile profile) {
|
||||||
stopLegacyVpnPrivileged();
|
stopVpnRunnerPrivileged();
|
||||||
|
|
||||||
// Prepare for the new request.
|
// Prepare for the new request.
|
||||||
prepareInternal(VpnConfig.LEGACY_VPN);
|
prepareInternal(VpnConfig.LEGACY_VPN);
|
||||||
updateState(DetailedState.CONNECTING, "startLegacyVpn");
|
updateState(DetailedState.CONNECTING, "startLegacyVpn");
|
||||||
|
|
||||||
// Start a new LegacyVpnRunner and we are done!
|
// Start a new LegacyVpnRunner and we are done!
|
||||||
mLegacyVpnRunner = new LegacyVpnRunner(config, racoon, mtpd, profile);
|
mVpnRunner = new LegacyVpnRunner(config, racoon, mtpd, profile);
|
||||||
mLegacyVpnRunner.start();
|
mVpnRunner.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Stop legacy VPN. Permissions must be checked by callers. */
|
/**
|
||||||
public synchronized void stopLegacyVpnPrivileged() {
|
* Checks if this the currently running VPN (if any) was started by the Settings app
|
||||||
if (mLegacyVpnRunner != null) {
|
*
|
||||||
mLegacyVpnRunner.exit();
|
* <p>This includes both Legacy VPNs and Platform VPNs.
|
||||||
mLegacyVpnRunner = null;
|
*/
|
||||||
|
private boolean isSettingsVpnLocked() {
|
||||||
|
return mVpnRunner != null && VpnConfig.LEGACY_VPN.equals(mPackage);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Stop VPN runner. Permissions must be checked by callers. */
|
||||||
|
public synchronized void stopVpnRunnerPrivileged() {
|
||||||
|
if (!isSettingsVpnLocked()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final boolean isLegacyVpn = mVpnRunner instanceof LegacyVpnRunner;
|
||||||
|
|
||||||
|
mVpnRunner.exit();
|
||||||
|
mVpnRunner = null;
|
||||||
|
|
||||||
|
// LegacyVpn uses daemons that must be shut down before new ones are brought up.
|
||||||
|
// The same limitation does not apply to Platform VPNs.
|
||||||
|
if (isLegacyVpn) {
|
||||||
synchronized (LegacyVpnRunner.TAG) {
|
synchronized (LegacyVpnRunner.TAG) {
|
||||||
// wait for old thread to completely finish before spinning up
|
// wait for old thread to completely finish before spinning up
|
||||||
// new instance, otherwise state updates can be out of order.
|
// new instance, otherwise state updates can be out of order.
|
||||||
@@ -1947,7 +1969,7 @@ public class Vpn {
|
|||||||
* Callers are responsible for checking permissions if needed.
|
* Callers are responsible for checking permissions if needed.
|
||||||
*/
|
*/
|
||||||
private synchronized LegacyVpnInfo getLegacyVpnInfoPrivileged() {
|
private synchronized LegacyVpnInfo getLegacyVpnInfoPrivileged() {
|
||||||
if (mLegacyVpnRunner == null) return null;
|
if (!isSettingsVpnLocked()) return null;
|
||||||
|
|
||||||
final LegacyVpnInfo info = new LegacyVpnInfo();
|
final LegacyVpnInfo info = new LegacyVpnInfo();
|
||||||
info.key = mConfig.user;
|
info.key = mConfig.user;
|
||||||
@@ -1958,14 +1980,53 @@ public class Vpn {
|
|||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
public VpnConfig getLegacyVpnConfig() {
|
public synchronized VpnConfig getLegacyVpnConfig() {
|
||||||
if (mLegacyVpnRunner != null) {
|
if (isSettingsVpnLocked()) {
|
||||||
return mConfig;
|
return mConfig;
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** This class represents the common interface for all VPN runners. */
|
||||||
|
private abstract class VpnRunner extends Thread {
|
||||||
|
|
||||||
|
protected VpnRunner(String name) {
|
||||||
|
super(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract void run();
|
||||||
|
|
||||||
|
protected abstract void exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
private class IkeV2VpnRunner extends VpnRunner {
|
||||||
|
private static final String TAG = "IkeV2VpnRunner";
|
||||||
|
|
||||||
|
private final IpSecManager mIpSecManager;
|
||||||
|
private final VpnProfile mProfile;
|
||||||
|
|
||||||
|
IkeV2VpnRunner(VpnProfile profile) {
|
||||||
|
super(TAG);
|
||||||
|
mProfile = profile;
|
||||||
|
|
||||||
|
// TODO: move this to startVpnRunnerPrivileged()
|
||||||
|
mConfig = new VpnConfig();
|
||||||
|
mIpSecManager = mContext.getSystemService(IpSecManager.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
// TODO: Build IKE config, start IKE session
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void exit() {
|
||||||
|
// TODO: Teardown IKE session & any resources.
|
||||||
|
agentDisconnect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Bringing up a VPN connection takes time, and that is all this thread
|
* Bringing up a VPN connection takes time, and that is all this thread
|
||||||
* does. Here we have plenty of time. The only thing we need to take
|
* does. Here we have plenty of time. The only thing we need to take
|
||||||
@@ -1973,7 +2034,7 @@ public class Vpn {
|
|||||||
* requests will pile up. This could be done in a Handler as a state
|
* requests will pile up. This could be done in a Handler as a state
|
||||||
* machine, but it is much easier to read in the current form.
|
* machine, but it is much easier to read in the current form.
|
||||||
*/
|
*/
|
||||||
private class LegacyVpnRunner extends Thread {
|
private class LegacyVpnRunner extends VpnRunner {
|
||||||
private static final String TAG = "LegacyVpnRunner";
|
private static final String TAG = "LegacyVpnRunner";
|
||||||
|
|
||||||
private final String[] mDaemons;
|
private final String[] mDaemons;
|
||||||
@@ -2043,13 +2104,21 @@ public class Vpn {
|
|||||||
mContext.registerReceiver(mBroadcastReceiver, filter);
|
mContext.registerReceiver(mBroadcastReceiver, filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void check(String interfaze) {
|
/**
|
||||||
|
* Checks if the parameter matches the underlying interface
|
||||||
|
*
|
||||||
|
* <p>If the underlying interface is torn down, the LegacyVpnRunner also should be. It has
|
||||||
|
* no ability to migrate between interfaces (or Networks).
|
||||||
|
*/
|
||||||
|
public void exitIfOuterInterfaceIs(String interfaze) {
|
||||||
if (interfaze.equals(mOuterInterface)) {
|
if (interfaze.equals(mOuterInterface)) {
|
||||||
Log.i(TAG, "Legacy VPN is going down with " + interfaze);
|
Log.i(TAG, "Legacy VPN is going down with " + interfaze);
|
||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Tears down this LegacyVpn connection */
|
||||||
|
@Override
|
||||||
public void exit() {
|
public void exit() {
|
||||||
// We assume that everything is reset after stopping the daemons.
|
// We assume that everything is reset after stopping the daemons.
|
||||||
interrupt();
|
interrupt();
|
||||||
|
|||||||
@@ -138,7 +138,7 @@ public class LockdownVpnTracker {
|
|||||||
|
|
||||||
if (egressDisconnected || egressChanged) {
|
if (egressDisconnected || egressChanged) {
|
||||||
mAcceptedEgressIface = null;
|
mAcceptedEgressIface = null;
|
||||||
mVpn.stopLegacyVpnPrivileged();
|
mVpn.stopVpnRunnerPrivileged();
|
||||||
}
|
}
|
||||||
if (egressDisconnected) {
|
if (egressDisconnected) {
|
||||||
hideNotification();
|
hideNotification();
|
||||||
@@ -218,7 +218,7 @@ public class LockdownVpnTracker {
|
|||||||
mAcceptedEgressIface = null;
|
mAcceptedEgressIface = null;
|
||||||
mErrorCount = 0;
|
mErrorCount = 0;
|
||||||
|
|
||||||
mVpn.stopLegacyVpnPrivileged();
|
mVpn.stopVpnRunnerPrivileged();
|
||||||
mVpn.setLockdown(false);
|
mVpn.setLockdown(false);
|
||||||
hideNotification();
|
hideNotification();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user