diff --git a/tests/unit/java/com/android/server/ConnectivityServiceTest.java b/tests/unit/java/com/android/server/ConnectivityServiceTest.java index 5e276fac04..e84df162e1 100644 --- a/tests/unit/java/com/android/server/ConnectivityServiceTest.java +++ b/tests/unit/java/com/android/server/ConnectivityServiceTest.java @@ -1477,7 +1477,7 @@ public class ConnectivityServiceTest { !mMockNetworkAgent.isBypassableVpn(), mVpnType)); updateState(NetworkInfo.DetailedState.CONNECTED, "registerAgent"); mNetworkCapabilities.set(mMockNetworkAgent.getNetworkCapabilities()); - mNetworkAgent = new Vpn.VpnNetworkAgentWrapper(mMockNetworkAgent.getNetworkAgent()); + mNetworkAgent = mMockNetworkAgent.getNetworkAgent(); } private void registerAgent(Set uids) throws Exception { diff --git a/tests/unit/java/com/android/server/connectivity/VpnTest.java b/tests/unit/java/com/android/server/connectivity/VpnTest.java index 615e434809..cdfa1904de 100644 --- a/tests/unit/java/com/android/server/connectivity/VpnTest.java +++ b/tests/unit/java/com/android/server/connectivity/VpnTest.java @@ -27,14 +27,11 @@ import static android.content.pm.UserInfo.FLAG_RESTRICTED; import static android.net.ConnectivityManager.NetworkCallback; import static android.net.INetd.IF_STATE_DOWN; import static android.net.INetd.IF_STATE_UP; -import static android.net.RouteInfo.RTN_UNREACHABLE; import static android.net.VpnManager.TYPE_VPN_PLATFORM; -import static android.net.ipsec.ike.IkeSessionConfiguration.EXTENSION_TYPE_MOBIKE; import static android.os.Build.VERSION_CODES.S_V2; import static android.os.UserHandle.PER_USER_RANGE; import static com.android.modules.utils.build.SdkLevel.isAtLeastT; -import static com.android.server.connectivity.Vpn.VpnNetworkAgentWrapper; import static com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo; import static com.android.testutils.MiscAsserts.assertThrows; @@ -62,7 +59,6 @@ import static org.mockito.Mockito.inOrder; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.reset; -import static org.mockito.Mockito.spy; import static org.mockito.Mockito.timeout; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -87,9 +83,7 @@ import android.net.Ikev2VpnProfile; import android.net.InetAddresses; import android.net.InterfaceConfigurationParcel; import android.net.IpPrefix; -import android.net.IpSecConfig; import android.net.IpSecManager; -import android.net.IpSecTransform; import android.net.IpSecTunnelInterfaceResponse; import android.net.LinkAddress; import android.net.LinkProperties; @@ -106,12 +100,7 @@ import android.net.VpnManager; import android.net.VpnProfileState; import android.net.VpnService; import android.net.VpnTransportInfo; -import android.net.ipsec.ike.ChildSessionCallback; -import android.net.ipsec.ike.ChildSessionConfiguration; import android.net.ipsec.ike.IkeSessionCallback; -import android.net.ipsec.ike.IkeSessionConfiguration; -import android.net.ipsec.ike.IkeSessionConnectionInfo; -import android.net.ipsec.ike.IkeTrafficSelector; import android.net.ipsec.ike.exceptions.IkeException; import android.net.ipsec.ike.exceptions.IkeNetworkLostException; import android.net.ipsec.ike.exceptions.IkeNonProtocolException; @@ -132,7 +121,6 @@ import android.provider.Settings; import android.security.Credentials; import android.util.ArrayMap; import android.util.ArraySet; -import android.util.Pair; import android.util.Range; import androidx.test.filters.SmallTest; @@ -167,7 +155,6 @@ import java.io.FileDescriptor; import java.io.FileWriter; import java.io.IOException; import java.net.Inet4Address; -import java.net.Inet6Address; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.ArrayList; @@ -178,7 +165,6 @@ import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.TimeUnit; import java.util.stream.Stream; @@ -212,37 +198,11 @@ public class VpnTest { static final Network EGRESS_NETWORK = new Network(101); static final String EGRESS_IFACE = "wlan0"; static final String TEST_VPN_PKG = "com.testvpn.vpn"; - private static final String TEST_VPN_CLIENT = "2.4.6.8"; private static final String TEST_VPN_SERVER = "1.2.3.4"; private static final String TEST_VPN_IDENTITY = "identity"; private static final byte[] TEST_VPN_PSK = "psk".getBytes(); - private static final int IP4_PREFIX_LEN = 32; - private static final int MIN_PORT = 0; - private static final int MAX_PORT = 65535; - - private static final InetAddress TEST_VPN_CLIENT_IP = - InetAddresses.parseNumericAddress(TEST_VPN_CLIENT); - private static final InetAddress TEST_VPN_SERVER_IP = - InetAddresses.parseNumericAddress(TEST_VPN_SERVER); - private static final InetAddress TEST_VPN_CLIENT_IP_2 = - InetAddresses.parseNumericAddress("192.0.2.200"); - private static final InetAddress TEST_VPN_SERVER_IP_2 = - InetAddresses.parseNumericAddress("192.0.2.201"); - private static final InetAddress TEST_VPN_INTERNAL_IP = - InetAddresses.parseNumericAddress("198.51.100.10"); - private static final InetAddress TEST_VPN_INTERNAL_DNS = - InetAddresses.parseNumericAddress("8.8.8.8"); - - private static final IkeTrafficSelector IN_TS = - new IkeTrafficSelector(MIN_PORT, MAX_PORT, TEST_VPN_INTERNAL_IP, TEST_VPN_INTERNAL_IP); - private static final IkeTrafficSelector OUT_TS = - new IkeTrafficSelector(MIN_PORT, MAX_PORT, - InetAddresses.parseNumericAddress("0.0.0.0"), - InetAddresses.parseNumericAddress("255.255.255.255")); - private static final Network TEST_NETWORK = new Network(Integer.MAX_VALUE); - private static final Network TEST_NETWORK_2 = new Network(Integer.MAX_VALUE - 1); private static final String TEST_IFACE_NAME = "TEST_IFACE"; private static final int TEST_TUNNEL_RESOURCE_ID = 0x2345; private static final long TEST_TIMEOUT_MS = 500L; @@ -274,9 +234,7 @@ public class VpnTest { @Mock private AppOpsManager mAppOps; @Mock private NotificationManager mNotificationManager; @Mock private Vpn.SystemServices mSystemServices; - @Mock private Vpn.IkeSessionWrapper mIkeSessionWrapper; @Mock private Vpn.Ikev2SessionCreator mIkev2SessionCreator; - @Mock private Vpn.VpnNetworkAgentWrapper mVpnNetworkAgentWrapper; @Mock private ConnectivityManager mConnectivityManager; @Mock private IpSecService mIpSecService; @Mock private VpnProfileStore mVpnProfileStore; @@ -285,8 +243,6 @@ public class VpnTest { private IpSecManager mIpSecManager; - private TestDeps mTestDeps; - public VpnTest() throws Exception { // Build an actual VPN profile that is capable of being converted to and from an // Ikev2VpnProfile @@ -301,7 +257,6 @@ public class VpnTest { MockitoAnnotations.initMocks(this); mIpSecManager = new IpSecManager(mContext, mIpSecService); - mTestDeps = spy(new TestDeps()); when(mContext.getPackageManager()).thenReturn(mPackageManager); setMockedPackages(mPackages); @@ -342,14 +297,6 @@ public class VpnTest { // itself, so set the default value of Context#checkCallingOrSelfPermission to // PERMISSION_DENIED. doReturn(PERMISSION_DENIED).when(mContext).checkCallingOrSelfPermission(any()); - - resetIkev2SessionCreator(mIkeSessionWrapper); - } - - private void resetIkev2SessionCreator(Vpn.IkeSessionWrapper ikeSession) { - reset(mIkev2SessionCreator); - when(mIkev2SessionCreator.createIkeSession(any(), any(), any(), any(), any(), any())) - .thenReturn(ikeSession); } @After @@ -861,11 +808,10 @@ public class VpnTest { vpn.startVpnProfile(TEST_VPN_PKG); verify(mVpnProfileStore).get(eq(vpn.getProfileNameForPackage(TEST_VPN_PKG))); - vpn.mNetworkAgent = new VpnNetworkAgentWrapper( - new NetworkAgent(mContext, Looper.getMainLooper(), TAG, - new NetworkCapabilities.Builder().build(), new LinkProperties(), - 10 /* score */, new NetworkAgentConfig.Builder().build(), - new NetworkProvider(mContext, Looper.getMainLooper(), TAG)) {}); + vpn.mNetworkAgent = new NetworkAgent(mContext, Looper.getMainLooper(), TAG, + new NetworkCapabilities.Builder().build(), new LinkProperties(), 10 /* score */, + new NetworkAgentConfig.Builder().build(), + new NetworkProvider(mContext, Looper.getMainLooper(), TAG)) {}; return vpn; } @@ -1374,10 +1320,6 @@ public class VpnTest { final ArgumentCaptor captor = ArgumentCaptor.forClass(IkeSessionCallback.class); - // This test depends on a real ScheduledThreadPoolExecutor - doReturn(new ScheduledThreadPoolExecutor(1)).when(mTestDeps) - .getScheduledThreadPoolExecutor(); - final Vpn vpn = createVpnAndSetupUidChecks(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN); when(mVpnProfileStore.get(vpn.getProfileNameForPackage(TEST_VPN_PKG))) .thenReturn(mVpnProfile.encode()); @@ -1549,216 +1491,13 @@ public class VpnTest { return vpn; } - private IkeSessionConnectionInfo createIkeConnectInfo() { - return new IkeSessionConnectionInfo(TEST_VPN_CLIENT_IP, TEST_VPN_SERVER_IP, TEST_NETWORK); - } - - private IkeSessionConnectionInfo createNewIkeConnectInfo() { - return new IkeSessionConnectionInfo( - TEST_VPN_CLIENT_IP_2, TEST_VPN_SERVER_IP_2, TEST_NETWORK_2); - } - - private IkeSessionConfiguration createIkeConfig( - IkeSessionConnectionInfo ikeConnectInfo, boolean isMobikeEnabled) { - final IkeSessionConfiguration.Builder builder = - new IkeSessionConfiguration.Builder(ikeConnectInfo); - - if (isMobikeEnabled) { - builder.addIkeExtension(EXTENSION_TYPE_MOBIKE); - } - - return builder.build(); - } - - private ChildSessionConfiguration createChildConfig() { - return new ChildSessionConfiguration.Builder(Arrays.asList(IN_TS), Arrays.asList(OUT_TS)) - .addInternalAddress(new LinkAddress(TEST_VPN_INTERNAL_IP, IP4_PREFIX_LEN)) - .addInternalDnsServer(TEST_VPN_INTERNAL_DNS) - .build(); - } - - private IpSecTransform createIpSecTransform() { - return new IpSecTransform(mContext, new IpSecConfig()); - } - - private void verifyApplyTunnelModeTransforms(int expectedTimes) throws Exception { - verify(mIpSecService, times(expectedTimes)).applyTunnelModeTransform( - eq(TEST_TUNNEL_RESOURCE_ID), eq(IpSecManager.DIRECTION_IN), - anyInt(), anyString()); - verify(mIpSecService, times(expectedTimes)).applyTunnelModeTransform( - eq(TEST_TUNNEL_RESOURCE_ID), eq(IpSecManager.DIRECTION_OUT), - anyInt(), anyString()); - } - - private Pair verifyCreateIkeAndCaptureCbs() - throws Exception { - final ArgumentCaptor ikeCbCaptor = - ArgumentCaptor.forClass(IkeSessionCallback.class); - final ArgumentCaptor childCbCaptor = - ArgumentCaptor.forClass(ChildSessionCallback.class); - - verify(mIkev2SessionCreator, timeout(TEST_TIMEOUT_MS)).createIkeSession( - any(), any(), any(), any(), ikeCbCaptor.capture(), childCbCaptor.capture()); - final IkeSessionCallback ikeCb = ikeCbCaptor.getValue(); - final ChildSessionCallback childCb = childCbCaptor.getValue(); - - return new Pair<>(ikeCbCaptor.getValue(), childCbCaptor.getValue()); - } - - private static class PlatformVpnSnapshot { - public final Vpn vpn; - public final NetworkCallback nwCb; - public final IkeSessionCallback ikeCb; - public final ChildSessionCallback childCb; - - PlatformVpnSnapshot(Vpn vpn, NetworkCallback nwCb, - IkeSessionCallback ikeCb, ChildSessionCallback childCb) { - this.vpn = vpn; - this.nwCb = nwCb; - this.ikeCb = ikeCb; - this.childCb = childCb; - } - } - - private PlatformVpnSnapshot verifySetupPlatformVpn(IkeSessionConfiguration ikeConfig) - throws Exception { - doReturn(mVpnNetworkAgentWrapper).when(mTestDeps) - .getVpnNetworkAgentWrapper( - any(), any(), anyString(), any(), any(), any(), any(), any()); - - final Vpn vpn = createVpnAndSetupUidChecks(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN); - when(mVpnProfileStore.get(vpn.getProfileNameForPackage(TEST_VPN_PKG))) - .thenReturn(mVpnProfile.encode()); - - vpn.startVpnProfile(TEST_VPN_PKG); - final NetworkCallback nwCb = triggerOnAvailableAndGetCallback(); - - // Mock the setup procedure by firing callbacks - final Pair cbPair = - verifyCreateIkeAndCaptureCbs(); - final IkeSessionCallback ikeCb = cbPair.first; - final ChildSessionCallback childCb = cbPair.second; - - ikeCb.onOpened(ikeConfig); - childCb.onIpSecTransformCreated(createIpSecTransform(), IpSecManager.DIRECTION_IN); - childCb.onIpSecTransformCreated(createIpSecTransform(), IpSecManager.DIRECTION_OUT); - childCb.onOpened(createChildConfig()); - - // Verification VPN setup - verifyApplyTunnelModeTransforms(1); - - ArgumentCaptor lpCaptor = ArgumentCaptor.forClass(LinkProperties.class); - ArgumentCaptor ncCaptor = - ArgumentCaptor.forClass(NetworkCapabilities.class); - verify(mTestDeps).getVpnNetworkAgentWrapper( - any(), any(), anyString(), ncCaptor.capture(), lpCaptor.capture(), - any(), any(), any()); - - // Check LinkProperties - final LinkProperties lp = lpCaptor.getValue(); - final List expectedRoutes = Arrays.asList( - new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), null /*gateway*/, - TEST_IFACE_NAME, RouteInfo.RTN_UNICAST), - new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), null /*gateway*/, - TEST_IFACE_NAME, RTN_UNREACHABLE)); - assertEquals(expectedRoutes, lp.getRoutes()); - - // Check internal addresses - final List expectedAddresses = - Arrays.asList(new LinkAddress(TEST_VPN_INTERNAL_IP, IP4_PREFIX_LEN)); - assertEquals(expectedAddresses, lp.getLinkAddresses()); - - // Check internal DNS - assertEquals(Arrays.asList(TEST_VPN_INTERNAL_DNS), lp.getDnsServers()); - - // Check NetworkCapabilities - assertEquals(Arrays.asList(TEST_NETWORK), ncCaptor.getValue().getUnderlyingNetworks()); - - return new PlatformVpnSnapshot(vpn, nwCb, ikeCb, childCb); - } - @Test public void testStartPlatformVpn() throws Exception { - final PlatformVpnSnapshot vpnSnapShot = verifySetupPlatformVpn( - createIkeConfig(createIkeConnectInfo(), true /* isMobikeEnabled */)); - vpnSnapShot.vpn.mVpnRunner.exitVpnRunner(); + startLegacyVpn(createVpn(primaryUser.id), mVpnProfile); + // TODO: Test the Ikev2VpnRunner started up properly. Relies on utility methods added in + // a subsequent patch. } - @Test - public void testStartPlatformVpnMobility_mobikeEnabled() throws Exception { - final PlatformVpnSnapshot vpnSnapShot = verifySetupPlatformVpn( - createIkeConfig(createIkeConnectInfo(), true /* isMobikeEnabled */)); - - // Mock network switch - vpnSnapShot.nwCb.onLost(TEST_NETWORK); - vpnSnapShot.nwCb.onAvailable(TEST_NETWORK_2); - - // Verify MOBIKE is triggered - verify(mIkeSessionWrapper).setNetwork(TEST_NETWORK_2); - - // Mock the MOBIKE procedure - vpnSnapShot.ikeCb.onIkeSessionConnectionInfoChanged(createNewIkeConnectInfo()); - vpnSnapShot.childCb.onIpSecTransformsMigrated( - createIpSecTransform(), createIpSecTransform()); - - verify(mIpSecService).setNetworkForTunnelInterface( - eq(TEST_TUNNEL_RESOURCE_ID), eq(TEST_NETWORK_2), anyString()); - - // Expect 2 times: one for initial setup and one for MOBIKE - verifyApplyTunnelModeTransforms(2); - - // Verify mNetworkCapabilities and mNetworkAgent are updated - assertEquals( - Collections.singletonList(TEST_NETWORK_2), - vpnSnapShot.vpn.mNetworkCapabilities.getUnderlyingNetworks()); - verify(mVpnNetworkAgentWrapper) - .setUnderlyingNetworks(Collections.singletonList(TEST_NETWORK_2)); - - vpnSnapShot.vpn.mVpnRunner.exitVpnRunner(); - } - - @Test - public void testStartPlatformVpnReestablishes_mobikeDisabled() throws Exception { - final PlatformVpnSnapshot vpnSnapShot = verifySetupPlatformVpn( - createIkeConfig(createIkeConnectInfo(), false /* isMobikeEnabled */)); - - // Forget the first IKE creation - resetIkev2SessionCreator(mock(Vpn.IkeSessionWrapper.class)); - - // Mock network switch - vpnSnapShot.nwCb.onLost(TEST_NETWORK); - vpnSnapShot.nwCb.onAvailable(TEST_NETWORK_2); - - // Verify the old IKE Session is killed - verify(mIkeSessionWrapper).kill(); - - final Pair cbPair = - verifyCreateIkeAndCaptureCbs(); - final IkeSessionCallback ikeCbNew = cbPair.first; - final ChildSessionCallback childCbNew = cbPair.second; - - // Mock the IKE Session setup - ikeCbNew.onOpened(createIkeConfig(createNewIkeConnectInfo(), false /* isMobikeEnabled */)); - - childCbNew.onIpSecTransformCreated(createIpSecTransform(), IpSecManager.DIRECTION_IN); - childCbNew.onIpSecTransformCreated(createIpSecTransform(), IpSecManager.DIRECTION_OUT); - childCbNew.onOpened(createChildConfig()); - - // Expect 2 times since there have been two Session setups - verifyApplyTunnelModeTransforms(2); - - // Verify mNetworkCapabilities and mNetworkAgent are updated - assertEquals( - Collections.singletonList(TEST_NETWORK_2), - vpnSnapShot.vpn.mNetworkCapabilities.getUnderlyingNetworks()); - verify(mVpnNetworkAgentWrapper) - .setUnderlyingNetworks(Collections.singletonList(TEST_NETWORK_2)); - - vpnSnapShot.vpn.mVpnRunner.exitVpnRunner(); - } - - // TODO: Add a test for network loss without mobility - @Test public void testStartRacoonNumericAddress() throws Exception { startRacoon("1.2.3.4", "1.2.3.4"); @@ -1839,8 +1578,7 @@ public class VpnTest { } } - // Make it public and un-final so as to spy it - public class TestDeps extends Vpn.Dependencies { + private final class TestDeps extends Vpn.Dependencies { public final CompletableFuture racoonArgs = new CompletableFuture(); public final CompletableFuture mtpdArgs = new CompletableFuture(); public final File mStateFile; @@ -1975,25 +1713,10 @@ public class VpnTest { return mDeviceIdleInternal; } - @Override public long getNextRetryDelaySeconds(int retryCount) { // Simply return retryCount as the delay seconds for retrying. return retryCount; } - - @Override - public ScheduledThreadPoolExecutor getScheduledThreadPoolExecutor() { - final ScheduledThreadPoolExecutor mockExecutor = - mock(ScheduledThreadPoolExecutor.class); - doAnswer( - (invocation) -> { - ((Runnable) invocation.getArgument(0)).run(); - return null; - }) - .when(mockExecutor) - .execute(any()); - return mockExecutor; - } } /** @@ -2005,7 +1728,7 @@ public class VpnTest { when(mContext.createContextAsUser(eq(UserHandle.of(userId)), anyInt())) .thenReturn(asUserContext); final TestLooper testLooper = new TestLooper(); - final Vpn vpn = new Vpn(testLooper.getLooper(), mContext, mTestDeps, mNetService, + final Vpn vpn = new Vpn(testLooper.getLooper(), mContext, new TestDeps(), mNetService, mNetd, userId, mVpnProfileStore, mSystemServices, mIkev2SessionCreator); verify(mConnectivityManager, times(1)).registerNetworkProvider(argThat( provider -> provider.getName().contains("VpnNetworkProvider")