Merge changes I982543cd,I41c3bf6c,Id3e5f6e1

* changes:
  Add a provider to VPN
  Small VPN cleanup
  Migrate VPN to the public NetworkAgent API.
This commit is contained in:
Lorenzo Colitti
2020-11-30 13:48:26 +00:00
committed by Gerrit Code Review
4 changed files with 29 additions and 25 deletions

View File

@@ -50,13 +50,6 @@ public class NetworkProvider {
*/ */
public static final int ID_NONE = -1; public static final int ID_NONE = -1;
/**
* A hardcoded ID for NetworkAgents representing VPNs. These agents are not created by any
* provider, so they use this constant for clarity instead of NONE.
* @hide only used by ConnectivityService.
*/
public static final int ID_VPN = -2;
/** /**
* The first providerId value that will be allocated. * The first providerId value that will be allocated.
* @hide only used by ConnectivityService. * @hide only used by ConnectivityService.

View File

@@ -5140,7 +5140,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
} }
} }
private void onUserStart(int userId) { private void onUserStarted(int userId) {
synchronized (mVpns) { synchronized (mVpns) {
Vpn userVpn = mVpns.get(userId); Vpn userVpn = mVpns.get(userId);
if (userVpn != null) { if (userVpn != null) {
@@ -5155,7 +5155,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
} }
} }
private void onUserStop(int userId) { private void onUserStopped(int userId) {
synchronized (mVpns) { synchronized (mVpns) {
Vpn userVpn = mVpns.get(userId); Vpn userVpn = mVpns.get(userId);
if (userVpn == null) { if (userVpn == null) {
@@ -5272,9 +5272,9 @@ public class ConnectivityService extends IConnectivityManager.Stub
if (userId == UserHandle.USER_NULL) return; if (userId == UserHandle.USER_NULL) return;
if (Intent.ACTION_USER_STARTED.equals(action)) { if (Intent.ACTION_USER_STARTED.equals(action)) {
onUserStart(userId); onUserStarted(userId);
} else if (Intent.ACTION_USER_STOPPED.equals(action)) { } else if (Intent.ACTION_USER_STOPPED.equals(action)) {
onUserStop(userId); onUserStopped(userId);
} else if (Intent.ACTION_USER_ADDED.equals(action)) { } else if (Intent.ACTION_USER_ADDED.equals(action)) {
onUserAdded(userId); onUserAdded(userId);
} else if (Intent.ACTION_USER_REMOVED.equals(action)) { } else if (Intent.ACTION_USER_REMOVED.equals(action)) {

View File

@@ -1089,6 +1089,10 @@ public class ConnectivityServiceTest {
mMockNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_VPN, lp, mMockNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_VPN, lp,
mNetworkCapabilities); mNetworkCapabilities);
mMockNetworkAgent.waitForIdle(TIMEOUT_MS); mMockNetworkAgent.waitForIdle(TIMEOUT_MS);
verify(mNetworkManagementService, times(1))
.addVpnUidRanges(eq(mMockVpn.getNetId()), eq(uids.toArray(new UidRange[0])));
verify(mNetworkManagementService, never())
.removeVpnUidRanges(eq(mMockVpn.getNetId()), any());
mAgentRegistered = true; mAgentRegistered = true;
mNetworkCapabilities.set(mMockNetworkAgent.getNetworkCapabilities()); mNetworkCapabilities.set(mMockNetworkAgent.getNetworkCapabilities());
mNetworkAgent = mMockNetworkAgent.getNetworkAgent(); mNetworkAgent = mMockNetworkAgent.getNetworkAgent();
@@ -6922,8 +6926,8 @@ public class ConnectivityServiceTest {
final Set<UidRange> vpnRange = Collections.singleton(UidRange.createForUser(VPN_USER)); final Set<UidRange> vpnRange = Collections.singleton(UidRange.createForUser(VPN_USER));
mMockVpn.establish(lp, VPN_UID, vpnRange); mMockVpn.establish(lp, VPN_UID, vpnRange);
// Connected VPN should have interface rules set up. There are two expected invocations, // A connected VPN should have interface rules set up. There are two expected invocations,
// one during VPN uid update, one during VPN LinkProperties update // one during the VPN initial connection, one during the VPN LinkProperties update.
ArgumentCaptor<int[]> uidCaptor = ArgumentCaptor.forClass(int[].class); ArgumentCaptor<int[]> uidCaptor = ArgumentCaptor.forClass(int[].class);
verify(mMockNetd, times(2)).firewallAddUidInterfaceRules(eq("tun0"), uidCaptor.capture()); verify(mMockNetd, times(2)).firewallAddUidInterfaceRules(eq("tun0"), uidCaptor.capture());
assertContainsExactly(uidCaptor.getAllValues().get(0), APP1_UID, APP2_UID); assertContainsExactly(uidCaptor.getAllValues().get(0), APP1_UID, APP2_UID);

View File

@@ -41,6 +41,7 @@ import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.doAnswer;
@@ -86,10 +87,10 @@ import android.os.Build.VERSION_CODES;
import android.os.Bundle; import android.os.Bundle;
import android.os.ConditionVariable; import android.os.ConditionVariable;
import android.os.INetworkManagementService; import android.os.INetworkManagementService;
import android.os.Looper;
import android.os.Process; import android.os.Process;
import android.os.UserHandle; import android.os.UserHandle;
import android.os.UserManager; import android.os.UserManager;
import android.os.test.TestLooper;
import android.provider.Settings; import android.provider.Settings;
import android.security.Credentials; import android.security.Credentials;
import android.security.KeyStore; import android.security.KeyStore;
@@ -100,6 +101,7 @@ import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4; import androidx.test.runner.AndroidJUnit4;
import com.android.internal.R; import com.android.internal.R;
import com.android.internal.net.LegacyVpnInfo;
import com.android.internal.net.VpnConfig; import com.android.internal.net.VpnConfig;
import com.android.internal.net.VpnProfile; import com.android.internal.net.VpnProfile;
import com.android.server.IpSecService; import com.android.server.IpSecService;
@@ -223,6 +225,8 @@ public class VpnTest {
.thenReturn(mNotificationManager); .thenReturn(mNotificationManager);
when(mContext.getSystemService(eq(Context.CONNECTIVITY_SERVICE))) when(mContext.getSystemService(eq(Context.CONNECTIVITY_SERVICE)))
.thenReturn(mConnectivityManager); .thenReturn(mConnectivityManager);
when(mContext.getSystemServiceName(eq(ConnectivityManager.class)))
.thenReturn(Context.CONNECTIVITY_SERVICE);
when(mContext.getSystemService(eq(Context.IPSEC_SERVICE))).thenReturn(mIpSecManager); when(mContext.getSystemService(eq(Context.IPSEC_SERVICE))).thenReturn(mIpSecManager);
when(mContext.getString(R.string.config_customVpnAlwaysOnDisconnectedDialogComponent)) when(mContext.getString(R.string.config_customVpnAlwaysOnDisconnectedDialogComponent))
.thenReturn(Resources.getSystem().getString( .thenReturn(Resources.getSystem().getString(
@@ -589,7 +593,7 @@ public class VpnTest {
} }
@Test @Test
public void testNotificationShownForAlwaysOnApp() { public void testNotificationShownForAlwaysOnApp() throws Exception {
final UserHandle userHandle = UserHandle.of(primaryUser.id); final UserHandle userHandle = UserHandle.of(primaryUser.id);
final Vpn vpn = createVpn(primaryUser.id); final Vpn vpn = createVpn(primaryUser.id);
setMockedUsers(primaryUser); setMockedUsers(primaryUser);
@@ -619,7 +623,6 @@ public class VpnTest {
@Test @Test
public void testCapabilities() { public void testCapabilities() {
final Vpn vpn = createVpn(primaryUser.id);
setMockedUsers(primaryUser); setMockedUsers(primaryUser);
final Network mobile = new Network(1); final Network mobile = new Network(1);
@@ -1037,7 +1040,7 @@ public class VpnTest {
when(exception.getErrorType()) when(exception.getErrorType())
.thenReturn(IkeProtocolException.ERROR_TYPE_AUTHENTICATION_FAILED); .thenReturn(IkeProtocolException.ERROR_TYPE_AUTHENTICATION_FAILED);
final Vpn vpn = startLegacyVpn(mVpnProfile); final Vpn vpn = startLegacyVpn(createVpn(primaryUser.id), (mVpnProfile));
final NetworkCallback cb = triggerOnAvailableAndGetCallback(); final NetworkCallback cb = triggerOnAvailableAndGetCallback();
// Wait for createIkeSession() to be called before proceeding in order to ensure consistent // Wait for createIkeSession() to be called before proceeding in order to ensure consistent
@@ -1048,20 +1051,20 @@ public class VpnTest {
ikeCb.onClosedExceptionally(exception); ikeCb.onClosedExceptionally(exception);
verify(mConnectivityManager, timeout(TEST_TIMEOUT_MS)).unregisterNetworkCallback(eq(cb)); verify(mConnectivityManager, timeout(TEST_TIMEOUT_MS)).unregisterNetworkCallback(eq(cb));
assertEquals(DetailedState.FAILED, vpn.getNetworkInfo().getDetailedState()); assertEquals(LegacyVpnInfo.STATE_FAILED, vpn.getLegacyVpnInfo().state);
} }
@Test @Test
public void testStartPlatformVpnIllegalArgumentExceptionInSetup() throws Exception { public void testStartPlatformVpnIllegalArgumentExceptionInSetup() throws Exception {
when(mIkev2SessionCreator.createIkeSession(any(), any(), any(), any(), any(), any())) when(mIkev2SessionCreator.createIkeSession(any(), any(), any(), any(), any(), any()))
.thenThrow(new IllegalArgumentException()); .thenThrow(new IllegalArgumentException());
final Vpn vpn = startLegacyVpn(mVpnProfile); final Vpn vpn = startLegacyVpn(createVpn(primaryUser.id), mVpnProfile);
final NetworkCallback cb = triggerOnAvailableAndGetCallback(); final NetworkCallback cb = triggerOnAvailableAndGetCallback();
// Wait for createIkeSession() to be called before proceeding in order to ensure consistent // Wait for createIkeSession() to be called before proceeding in order to ensure consistent
// state // state
verify(mConnectivityManager, timeout(TEST_TIMEOUT_MS)).unregisterNetworkCallback(eq(cb)); verify(mConnectivityManager, timeout(TEST_TIMEOUT_MS)).unregisterNetworkCallback(eq(cb));
assertEquals(DetailedState.FAILED, vpn.getNetworkInfo().getDetailedState()); assertEquals(LegacyVpnInfo.STATE_FAILED, vpn.getLegacyVpnInfo().state);
} }
private void setAndVerifyAlwaysOnPackage(Vpn vpn, int uid, boolean lockdownEnabled) { private void setAndVerifyAlwaysOnPackage(Vpn vpn, int uid, boolean lockdownEnabled) {
@@ -1100,8 +1103,7 @@ public class VpnTest {
// a subsequent CL. // a subsequent CL.
} }
public Vpn startLegacyVpn(final VpnProfile vpnProfile) throws Exception { private Vpn startLegacyVpn(final Vpn vpn, final VpnProfile vpnProfile) throws Exception {
final Vpn vpn = createVpn(primaryUser.id);
setMockedUsers(primaryUser); setMockedUsers(primaryUser);
// Dummy egress interface // Dummy egress interface
@@ -1118,7 +1120,7 @@ public class VpnTest {
@Test @Test
public void testStartPlatformVpn() throws Exception { public void testStartPlatformVpn() throws Exception {
startLegacyVpn(mVpnProfile); startLegacyVpn(createVpn(primaryUser.id), mVpnProfile);
// TODO: Test the Ikev2VpnRunner started up properly. Relies on utility methods added in // TODO: Test the Ikev2VpnRunner started up properly. Relies on utility methods added in
// a subsequent patch. // a subsequent patch.
} }
@@ -1153,7 +1155,7 @@ public class VpnTest {
legacyRunnerReady.open(); legacyRunnerReady.open();
return new Network(102); return new Network(102);
}); });
final Vpn vpn = startLegacyVpn(profile); final Vpn vpn = startLegacyVpn(createVpn(primaryUser.id), profile);
final TestDeps deps = (TestDeps) vpn.mDeps; final TestDeps deps = (TestDeps) vpn.mDeps;
try { try {
// udppsk and 1701 are the values for TYPE_L2TP_IPSEC_PSK // udppsk and 1701 are the values for TYPE_L2TP_IPSEC_PSK
@@ -1287,8 +1289,13 @@ public class VpnTest {
doReturn(UserHandle.of(userId)).when(asUserContext).getUser(); doReturn(UserHandle.of(userId)).when(asUserContext).getUser();
when(mContext.createContextAsUser(eq(UserHandle.of(userId)), anyInt())) when(mContext.createContextAsUser(eq(UserHandle.of(userId)), anyInt()))
.thenReturn(asUserContext); .thenReturn(asUserContext);
return new Vpn(Looper.myLooper(), mContext, new TestDeps(), mNetService, final TestLooper testLooper = new TestLooper();
final Vpn vpn = new Vpn(testLooper.getLooper(), mContext, new TestDeps(), mNetService,
userId, mKeyStore, mSystemServices, mIkev2SessionCreator); userId, mKeyStore, mSystemServices, mIkev2SessionCreator);
verify(mConnectivityManager, times(1)).registerNetworkProvider(argThat(
provider -> provider.getName().contains("VpnNetworkProvider")
));
return vpn;
} }
private static void assertBlocked(Vpn vpn, int... uids) { private static void assertBlocked(Vpn vpn, int... uids) {