1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.server.connectivity; 18 19 import static android.Manifest.permission.BIND_VPN_SERVICE; 20 import static android.Manifest.permission.CONTROL_VPN; 21 import static android.content.pm.PackageManager.PERMISSION_DENIED; 22 import static android.content.pm.PackageManager.PERMISSION_GRANTED; 23 import static android.net.ConnectivityDiagnosticsManager.ConnectivityDiagnosticsCallback; 24 import static android.net.ConnectivityDiagnosticsManager.DataStallReport; 25 import static android.net.ConnectivityManager.NetworkCallback; 26 import static android.net.INetd.IF_STATE_DOWN; 27 import static android.net.INetd.IF_STATE_UP; 28 import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET; 29 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED; 30 import static android.net.NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED; 31 import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; 32 import static android.net.NetworkCapabilities.TRANSPORT_WIFI; 33 import static android.net.RouteInfo.RTN_UNREACHABLE; 34 import static android.net.VpnManager.TYPE_VPN_PLATFORM; 35 import static android.net.cts.util.IkeSessionTestUtils.CHILD_PARAMS; 36 import static android.net.cts.util.IkeSessionTestUtils.TEST_IDENTITY; 37 import static android.net.cts.util.IkeSessionTestUtils.TEST_KEEPALIVE_TIMEOUT_UNSET; 38 import static android.net.cts.util.IkeSessionTestUtils.getTestIkeSessionParams; 39 import static android.net.ipsec.ike.IkeSessionConfiguration.EXTENSION_TYPE_MOBIKE; 40 import static android.net.ipsec.ike.IkeSessionParams.ESP_ENCAP_TYPE_AUTO; 41 import static android.net.ipsec.ike.IkeSessionParams.ESP_ENCAP_TYPE_NONE; 42 import static android.net.ipsec.ike.IkeSessionParams.ESP_ENCAP_TYPE_UDP; 43 import static android.net.ipsec.ike.IkeSessionParams.ESP_IP_VERSION_AUTO; 44 import static android.net.ipsec.ike.IkeSessionParams.ESP_IP_VERSION_IPV4; 45 import static android.net.ipsec.ike.IkeSessionParams.ESP_IP_VERSION_IPV6; 46 import static android.os.UserHandle.PER_USER_RANGE; 47 import static android.telephony.CarrierConfigManager.KEY_CARRIER_CONFIG_APPLIED_BOOL; 48 import static android.telephony.CarrierConfigManager.KEY_MIN_UDP_PORT_4500_NAT_TIMEOUT_SEC_INT; 49 import static android.telephony.CarrierConfigManager.KEY_PREFERRED_IKE_PROTOCOL_INT; 50 51 import static com.android.net.module.util.NetworkStackConstants.IPV6_MIN_MTU; 52 import static com.android.server.connectivity.Vpn.AUTOMATIC_KEEPALIVE_DELAY_SECONDS; 53 import static com.android.server.connectivity.Vpn.DEFAULT_LONG_LIVED_TCP_CONNS_EXPENSIVE_TIMEOUT_SEC; 54 import static com.android.server.connectivity.Vpn.DEFAULT_UDP_PORT_4500_NAT_TIMEOUT_SEC_INT; 55 import static com.android.server.connectivity.Vpn.PREFERRED_IKE_PROTOCOL_AUTO; 56 import static com.android.server.connectivity.Vpn.PREFERRED_IKE_PROTOCOL_IPV4_UDP; 57 import static com.android.server.connectivity.Vpn.PREFERRED_IKE_PROTOCOL_IPV6_ESP; 58 import static com.android.server.connectivity.Vpn.PREFERRED_IKE_PROTOCOL_IPV6_UDP; 59 import static com.android.testutils.HandlerUtils.waitForIdleSerialExecutor; 60 import static com.android.testutils.MiscAsserts.assertThrows; 61 62 import static org.junit.Assert.assertEquals; 63 import static org.junit.Assert.assertFalse; 64 import static org.junit.Assert.assertNotNull; 65 import static org.junit.Assert.assertNull; 66 import static org.junit.Assert.assertTrue; 67 import static org.junit.Assert.fail; 68 import static org.mockito.ArgumentMatchers.any; 69 import static org.mockito.ArgumentMatchers.anyBoolean; 70 import static org.mockito.ArgumentMatchers.anyInt; 71 import static org.mockito.ArgumentMatchers.anyLong; 72 import static org.mockito.ArgumentMatchers.anyString; 73 import static org.mockito.ArgumentMatchers.argThat; 74 import static org.mockito.ArgumentMatchers.eq; 75 import static org.mockito.ArgumentMatchers.longThat; 76 import static org.mockito.Mockito.after; 77 import static org.mockito.Mockito.atLeast; 78 import static org.mockito.Mockito.atLeastOnce; 79 import static org.mockito.Mockito.clearInvocations; 80 import static org.mockito.Mockito.doAnswer; 81 import static org.mockito.Mockito.doCallRealMethod; 82 import static org.mockito.Mockito.doNothing; 83 import static org.mockito.Mockito.doReturn; 84 import static org.mockito.Mockito.doThrow; 85 import static org.mockito.Mockito.inOrder; 86 import static org.mockito.Mockito.mock; 87 import static org.mockito.Mockito.never; 88 import static org.mockito.Mockito.reset; 89 import static org.mockito.Mockito.spy; 90 import static org.mockito.Mockito.timeout; 91 import static org.mockito.Mockito.times; 92 import static org.mockito.Mockito.verify; 93 import static org.mockito.Mockito.when; 94 95 import android.annotation.NonNull; 96 import android.annotation.UserIdInt; 97 import android.app.AppOpsManager; 98 import android.app.NotificationManager; 99 import android.app.PendingIntent; 100 import android.content.Context; 101 import android.content.Intent; 102 import android.content.pm.ApplicationInfo; 103 import android.content.pm.PackageManager; 104 import android.content.pm.ResolveInfo; 105 import android.content.pm.ServiceInfo; 106 import android.content.pm.UserInfo; 107 import android.content.res.Resources; 108 import android.net.ConnectivityDiagnosticsManager; 109 import android.net.ConnectivityManager; 110 import android.net.INetd; 111 import android.net.Ikev2VpnProfile; 112 import android.net.InetAddresses; 113 import android.net.InterfaceConfigurationParcel; 114 import android.net.IpPrefix; 115 import android.net.IpSecConfig; 116 import android.net.IpSecManager; 117 import android.net.IpSecTransform; 118 import android.net.IpSecTunnelInterfaceResponse; 119 import android.net.LinkAddress; 120 import android.net.LinkProperties; 121 import android.net.Network; 122 import android.net.NetworkAgent; 123 import android.net.NetworkAgentConfig; 124 import android.net.NetworkCapabilities; 125 import android.net.NetworkInfo.DetailedState; 126 import android.net.RouteInfo; 127 import android.net.TelephonyNetworkSpecifier; 128 import android.net.UidRangeParcel; 129 import android.net.VpnManager; 130 import android.net.VpnProfileState; 131 import android.net.VpnService; 132 import android.net.VpnTransportInfo; 133 import android.net.ipsec.ike.ChildSessionCallback; 134 import android.net.ipsec.ike.ChildSessionConfiguration; 135 import android.net.ipsec.ike.IkeFqdnIdentification; 136 import android.net.ipsec.ike.IkeSessionCallback; 137 import android.net.ipsec.ike.IkeSessionConfiguration; 138 import android.net.ipsec.ike.IkeSessionConnectionInfo; 139 import android.net.ipsec.ike.IkeSessionParams; 140 import android.net.ipsec.ike.IkeTrafficSelector; 141 import android.net.ipsec.ike.IkeTunnelConnectionParams; 142 import android.net.ipsec.ike.exceptions.IkeException; 143 import android.net.ipsec.ike.exceptions.IkeNetworkLostException; 144 import android.net.ipsec.ike.exceptions.IkeNonProtocolException; 145 import android.net.ipsec.ike.exceptions.IkeProtocolException; 146 import android.net.ipsec.ike.exceptions.IkeTimeoutException; 147 import android.net.vcn.VcnTransportInfo; 148 import android.net.wifi.WifiInfo; 149 import android.os.Build.VERSION_CODES; 150 import android.os.Bundle; 151 import android.os.INetworkManagementService; 152 import android.os.ParcelFileDescriptor; 153 import android.os.PersistableBundle; 154 import android.os.PowerWhitelistManager; 155 import android.os.Process; 156 import android.os.UserHandle; 157 import android.os.UserManager; 158 import android.os.test.TestLooper; 159 import android.provider.Settings; 160 import android.security.Credentials; 161 import android.telephony.CarrierConfigManager; 162 import android.telephony.SubscriptionInfo; 163 import android.telephony.SubscriptionManager; 164 import android.telephony.TelephonyManager; 165 import android.util.ArrayMap; 166 import android.util.ArraySet; 167 import android.util.Pair; 168 import android.util.Range; 169 170 import androidx.test.ext.junit.runners.AndroidJUnit4; 171 import androidx.test.filters.SmallTest; 172 173 import com.android.internal.R; 174 import com.android.internal.net.LegacyVpnInfo; 175 import com.android.internal.net.VpnConfig; 176 import com.android.internal.net.VpnProfile; 177 import com.android.internal.util.HexDump; 178 import com.android.internal.util.IndentingPrintWriter; 179 import com.android.server.DeviceIdleInternal; 180 import com.android.server.IpSecService; 181 import com.android.server.VpnTestBase; 182 import com.android.server.vcn.util.PersistableBundleUtils; 183 184 import org.junit.Before; 185 import org.junit.Test; 186 import org.junit.runner.RunWith; 187 import org.mockito.AdditionalAnswers; 188 import org.mockito.Answers; 189 import org.mockito.ArgumentCaptor; 190 import org.mockito.Captor; 191 import org.mockito.InOrder; 192 import org.mockito.Mock; 193 import org.mockito.MockitoAnnotations; 194 195 import java.io.FileDescriptor; 196 import java.io.IOException; 197 import java.io.StringWriter; 198 import java.net.Inet4Address; 199 import java.net.Inet6Address; 200 import java.net.InetAddress; 201 import java.net.UnknownHostException; 202 import java.util.ArrayList; 203 import java.util.Arrays; 204 import java.util.Collection; 205 import java.util.Collections; 206 import java.util.List; 207 import java.util.Map; 208 import java.util.Set; 209 import java.util.SortedSet; 210 import java.util.TreeSet; 211 import java.util.concurrent.ScheduledFuture; 212 import java.util.concurrent.ScheduledThreadPoolExecutor; 213 import java.util.concurrent.TimeUnit; 214 import java.util.regex.Matcher; 215 import java.util.regex.Pattern; 216 217 /** 218 * Tests for {@link Vpn}. 219 * 220 * Build, install and run with: 221 * runtest frameworks-net -c com.android.server.connectivity.VpnTest 222 */ 223 @RunWith(AndroidJUnit4.class) 224 @SmallTest 225 public class VpnTest extends VpnTestBase { 226 private static final String TAG = "VpnTest"; 227 228 static final Network EGRESS_NETWORK = new Network(101); 229 static final String EGRESS_IFACE = "wlan0"; 230 private static final String TEST_VPN_CLIENT = "2.4.6.8"; 231 private static final String TEST_VPN_SERVER = "1.2.3.4"; 232 private static final String TEST_VPN_IDENTITY = "identity"; 233 private static final byte[] TEST_VPN_PSK = "psk".getBytes(); 234 235 private static final int IP4_PREFIX_LEN = 32; 236 private static final int IP6_PREFIX_LEN = 64; 237 private static final int MIN_PORT = 0; 238 private static final int MAX_PORT = 65535; 239 240 private static final InetAddress TEST_VPN_CLIENT_IP = 241 InetAddresses.parseNumericAddress(TEST_VPN_CLIENT); 242 private static final InetAddress TEST_VPN_SERVER_IP = 243 InetAddresses.parseNumericAddress(TEST_VPN_SERVER); 244 private static final InetAddress TEST_VPN_CLIENT_IP_2 = 245 InetAddresses.parseNumericAddress("192.0.2.200"); 246 private static final InetAddress TEST_VPN_SERVER_IP_2 = 247 InetAddresses.parseNumericAddress("192.0.2.201"); 248 private static final InetAddress TEST_VPN_INTERNAL_IP = 249 InetAddresses.parseNumericAddress("198.51.100.10"); 250 private static final InetAddress TEST_VPN_INTERNAL_IP6 = 251 InetAddresses.parseNumericAddress("2001:db8::1"); 252 private static final InetAddress TEST_VPN_INTERNAL_DNS = 253 InetAddresses.parseNumericAddress("8.8.8.8"); 254 private static final InetAddress TEST_VPN_INTERNAL_DNS6 = 255 InetAddresses.parseNumericAddress("2001:4860:4860::8888"); 256 257 private static final IkeTrafficSelector IN_TS = 258 new IkeTrafficSelector(MIN_PORT, MAX_PORT, TEST_VPN_INTERNAL_IP, TEST_VPN_INTERNAL_IP); 259 private static final IkeTrafficSelector IN_TS6 = 260 new IkeTrafficSelector( 261 MIN_PORT, MAX_PORT, TEST_VPN_INTERNAL_IP6, TEST_VPN_INTERNAL_IP6); 262 private static final IkeTrafficSelector OUT_TS = 263 new IkeTrafficSelector(MIN_PORT, MAX_PORT, 264 InetAddresses.parseNumericAddress("0.0.0.0"), 265 InetAddresses.parseNumericAddress("255.255.255.255")); 266 private static final IkeTrafficSelector OUT_TS6 = 267 new IkeTrafficSelector( 268 MIN_PORT, 269 MAX_PORT, 270 InetAddresses.parseNumericAddress("::"), 271 InetAddresses.parseNumericAddress("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")); 272 273 private static final Network TEST_NETWORK = new Network(Integer.MAX_VALUE); 274 private static final Network TEST_NETWORK_2 = new Network(Integer.MAX_VALUE - 1); 275 private static final String TEST_IFACE_NAME = "TEST_IFACE"; 276 private static final int TEST_TUNNEL_RESOURCE_ID = 0x2345; 277 private static final long TEST_TIMEOUT_MS = 500L; 278 private static final long TIMEOUT_CROSSTHREAD_MS = 20_000L; 279 private static final String PRIMARY_USER_APP_EXCLUDE_KEY = 280 "VPNAPPEXCLUDED_27_com.testvpn.vpn"; 281 static final String PKGS_BYTES = getPackageByteString(List.of(PKGS)); 282 private static final Range<Integer> PRIMARY_USER_RANGE = uidRangeForUser(PRIMARY_USER.id); 283 private static final int TEST_KEEPALIVE_TIMER = 800; 284 private static final int TEST_SUB_ID = 1234; 285 private static final String TEST_MCCMNC = "12345"; 286 287 @Mock(answer = Answers.RETURNS_DEEP_STUBS) private Context mContext; 288 @Mock private UserManager mUserManager; 289 @Mock private PackageManager mPackageManager; 290 @Mock private INetworkManagementService mNetService; 291 @Mock private INetd mNetd; 292 @Mock private AppOpsManager mAppOps; 293 @Mock private NotificationManager mNotificationManager; 294 @Mock private Vpn.SystemServices mSystemServices; 295 @Mock private Vpn.IkeSessionWrapper mIkeSessionWrapper; 296 @Mock private Vpn.Ikev2SessionCreator mIkev2SessionCreator; 297 @Mock private Vpn.VpnNetworkAgentWrapper mMockNetworkAgent; 298 @Mock private ConnectivityManager mConnectivityManager; 299 @Mock private ConnectivityDiagnosticsManager mCdm; 300 @Mock private TelephonyManager mTelephonyManager; 301 @Mock private TelephonyManager mTmPerSub; 302 @Mock private CarrierConfigManager mConfigManager; 303 @Mock private SubscriptionManager mSubscriptionManager; 304 @Mock private IpSecService mIpSecService; 305 @Mock private VpnProfileStore mVpnProfileStore; 306 private final TestExecutor mExecutor; 307 @Mock DeviceIdleInternal mDeviceIdleInternal; 308 private final VpnProfile mVpnProfile; 309 310 @Captor private ArgumentCaptor<Collection<Range<Integer>>> mUidRangesCaptor; 311 312 private IpSecManager mIpSecManager; 313 private TestDeps mTestDeps; 314 315 public static class TestExecutor extends ScheduledThreadPoolExecutor { 316 public static final long REAL_DELAY = -1; 317 318 // For the purposes of the test, run all scheduled tasks after 10ms to save 319 // execution time, unless overridden by the specific test. Set to REAL_DELAY 320 // to actually wait for the delay specified by the real call to schedule(). 321 public long delayMs = 10; 322 // If this is true, execute() will call the runnable inline. This is useful because 323 // super.execute() calls schedule(), which messes with checks that scheduled() is 324 // called a given number of times. 325 public boolean executeDirect = false; 326 TestExecutor()327 public TestExecutor() { 328 super(1); 329 } 330 331 @Override execute(final Runnable command)332 public void execute(final Runnable command) { 333 // See |executeDirect| for why this is necessary. 334 if (executeDirect) { 335 command.run(); 336 } else { 337 super.execute(command); 338 } 339 } 340 341 @Override schedule(final Runnable command, final long delay, TimeUnit unit)342 public ScheduledFuture<?> schedule(final Runnable command, final long delay, 343 TimeUnit unit) { 344 if (0 == delay || delayMs == REAL_DELAY) { 345 // super.execute() calls schedule() with 0, so use the real delay if it's 0. 346 return super.schedule(command, delay, unit); 347 } else { 348 return super.schedule(command, delayMs, TimeUnit.MILLISECONDS); 349 } 350 } 351 } 352 VpnTest()353 public VpnTest() throws Exception { 354 // Build an actual VPN profile that is capable of being converted to and from an 355 // Ikev2VpnProfile 356 final Ikev2VpnProfile.Builder builder = 357 new Ikev2VpnProfile.Builder(TEST_VPN_SERVER, TEST_VPN_IDENTITY); 358 builder.setAuthPsk(TEST_VPN_PSK); 359 builder.setBypassable(true /* isBypassable */); 360 mExecutor = spy(new TestExecutor()); 361 mVpnProfile = builder.build().toVpnProfile(); 362 } 363 364 @Before setUp()365 public void setUp() throws Exception { 366 MockitoAnnotations.initMocks(this); 367 368 mIpSecManager = new IpSecManager(mContext, mIpSecService); 369 mTestDeps = spy(new TestDeps()); 370 doReturn(IPV6_MIN_MTU) 371 .when(mTestDeps) 372 .calculateVpnMtu(any(), anyInt(), anyInt(), anyBoolean()); 373 doReturn(1500).when(mTestDeps).getJavaNetworkInterfaceMtu(any(), anyInt()); 374 375 when(mContext.getPackageManager()).thenReturn(mPackageManager); 376 setMockedPackages(sPackages); 377 378 when(mContext.getPackageName()).thenReturn(TEST_VPN_PKG); 379 when(mContext.getOpPackageName()).thenReturn(TEST_VPN_PKG); 380 mockService(UserManager.class, Context.USER_SERVICE, mUserManager); 381 mockService(AppOpsManager.class, Context.APP_OPS_SERVICE, mAppOps); 382 mockService(NotificationManager.class, Context.NOTIFICATION_SERVICE, mNotificationManager); 383 mockService(ConnectivityManager.class, Context.CONNECTIVITY_SERVICE, mConnectivityManager); 384 mockService(IpSecManager.class, Context.IPSEC_SERVICE, mIpSecManager); 385 mockService(ConnectivityDiagnosticsManager.class, Context.CONNECTIVITY_DIAGNOSTICS_SERVICE, 386 mCdm); 387 mockService(TelephonyManager.class, Context.TELEPHONY_SERVICE, mTelephonyManager); 388 mockService(CarrierConfigManager.class, Context.CARRIER_CONFIG_SERVICE, mConfigManager); 389 mockService(SubscriptionManager.class, Context.TELEPHONY_SUBSCRIPTION_SERVICE, 390 mSubscriptionManager); 391 doReturn(mTmPerSub).when(mTelephonyManager).createForSubscriptionId(anyInt()); 392 when(mContext.getString(R.string.config_customVpnAlwaysOnDisconnectedDialogComponent)) 393 .thenReturn(Resources.getSystem().getString( 394 R.string.config_customVpnAlwaysOnDisconnectedDialogComponent)); 395 when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_IPSEC_TUNNELS)) 396 .thenReturn(true); 397 398 // Used by {@link Notification.Builder} 399 ApplicationInfo applicationInfo = new ApplicationInfo(); 400 applicationInfo.targetSdkVersion = VERSION_CODES.CUR_DEVELOPMENT; 401 when(mContext.getApplicationInfo()).thenReturn(applicationInfo); 402 when(mPackageManager.getApplicationInfoAsUser(anyString(), anyInt(), anyInt())) 403 .thenReturn(applicationInfo); 404 405 doNothing().when(mNetService).registerObserver(any()); 406 407 // Deny all appops by default. 408 when(mAppOps.noteOpNoThrow(anyString(), anyInt(), anyString(), any(), any())) 409 .thenReturn(AppOpsManager.MODE_IGNORED); 410 411 // Setup IpSecService 412 final IpSecTunnelInterfaceResponse tunnelResp = 413 new IpSecTunnelInterfaceResponse( 414 IpSecManager.Status.OK, TEST_TUNNEL_RESOURCE_ID, TEST_IFACE_NAME); 415 when(mIpSecService.createTunnelInterface(any(), any(), any(), any(), any())) 416 .thenReturn(tunnelResp); 417 doReturn(new LinkProperties()).when(mConnectivityManager).getLinkProperties(any()); 418 419 // The unit test should know what kind of permission it needs and set the permission by 420 // itself, so set the default value of Context#checkCallingOrSelfPermission to 421 // PERMISSION_DENIED. 422 doReturn(PERMISSION_DENIED).when(mContext).checkCallingOrSelfPermission(any()); 423 424 // Set up mIkev2SessionCreator and mExecutor 425 resetIkev2SessionCreator(mIkeSessionWrapper); 426 } 427 resetIkev2SessionCreator(Vpn.IkeSessionWrapper ikeSession)428 private void resetIkev2SessionCreator(Vpn.IkeSessionWrapper ikeSession) { 429 reset(mIkev2SessionCreator); 430 when(mIkev2SessionCreator.createIkeSession(any(), any(), any(), any(), any(), any())) 431 .thenReturn(ikeSession); 432 } 433 mockService(Class<T> clazz, String name, T service)434 private <T> void mockService(Class<T> clazz, String name, T service) { 435 doReturn(service).when(mContext).getSystemService(name); 436 doReturn(name).when(mContext).getSystemServiceName(clazz); 437 if (mContext.getSystemService(clazz).getClass().equals(Object.class)) { 438 // Test is using mockito-extended (mContext uses Answers.RETURNS_DEEP_STUBS and returned 439 // a mock object on a final method) 440 doCallRealMethod().when(mContext).getSystemService(clazz); 441 } 442 } 443 rangeSet(Range<Integer> .... ranges)444 private Set<Range<Integer>> rangeSet(Range<Integer> ... ranges) { 445 final Set<Range<Integer>> range = new ArraySet<>(); 446 for (Range<Integer> r : ranges) range.add(r); 447 448 return range; 449 } 450 uidRangeForUser(int userId)451 private static Range<Integer> uidRangeForUser(int userId) { 452 return new Range<Integer>(userId * PER_USER_RANGE, (userId + 1) * PER_USER_RANGE - 1); 453 } 454 uidRange(int start, int stop)455 private Range<Integer> uidRange(int start, int stop) { 456 return new Range<Integer>(start, stop); 457 } 458 getPackageByteString(List<String> packages)459 private static String getPackageByteString(List<String> packages) { 460 try { 461 return HexDump.toHexString( 462 PersistableBundleUtils.toDiskStableBytes(PersistableBundleUtils.fromList( 463 packages, PersistableBundleUtils.STRING_SERIALIZER)), 464 true /* upperCase */); 465 } catch (IOException e) { 466 return null; 467 } 468 } 469 470 @Test testRestrictedProfilesAreAddedToVpn()471 public void testRestrictedProfilesAreAddedToVpn() { 472 setMockedUsers(PRIMARY_USER, SECONDARY_USER, RESTRICTED_PROFILE_A, RESTRICTED_PROFILE_B); 473 474 final Vpn vpn = createVpn(PRIMARY_USER.id); 475 476 // Assume the user can have restricted profiles. 477 doReturn(true).when(mUserManager).canHaveRestrictedProfile(); 478 final Set<Range<Integer>> ranges = 479 vpn.createUserAndRestrictedProfilesRanges(PRIMARY_USER.id, null, null); 480 481 assertEquals(rangeSet(PRIMARY_USER_RANGE, uidRangeForUser(RESTRICTED_PROFILE_A.id)), 482 ranges); 483 } 484 485 @Test testManagedProfilesAreNotAddedToVpn()486 public void testManagedProfilesAreNotAddedToVpn() { 487 setMockedUsers(PRIMARY_USER, MANAGED_PROFILE_A); 488 489 final Vpn vpn = createVpn(PRIMARY_USER.id); 490 final Set<Range<Integer>> ranges = vpn.createUserAndRestrictedProfilesRanges( 491 PRIMARY_USER.id, null, null); 492 493 assertEquals(rangeSet(PRIMARY_USER_RANGE), ranges); 494 } 495 496 @Test testAddUserToVpnOnlyAddsOneUser()497 public void testAddUserToVpnOnlyAddsOneUser() { 498 setMockedUsers(PRIMARY_USER, RESTRICTED_PROFILE_A, MANAGED_PROFILE_A); 499 500 final Vpn vpn = createVpn(PRIMARY_USER.id); 501 final Set<Range<Integer>> ranges = new ArraySet<>(); 502 vpn.addUserToRanges(ranges, PRIMARY_USER.id, null, null); 503 504 assertEquals(rangeSet(PRIMARY_USER_RANGE), ranges); 505 } 506 507 @Test testUidAllowAndDenylist()508 public void testUidAllowAndDenylist() throws Exception { 509 final Vpn vpn = createVpn(PRIMARY_USER.id); 510 final Range<Integer> user = PRIMARY_USER_RANGE; 511 final int userStart = user.getLower(); 512 final int userStop = user.getUpper(); 513 final String[] packages = {PKGS[0], PKGS[1], PKGS[2]}; 514 515 // Allowed list 516 final Set<Range<Integer>> allow = vpn.createUserAndRestrictedProfilesRanges(PRIMARY_USER.id, 517 Arrays.asList(packages), null /* disallowedApplications */); 518 assertEquals(rangeSet( 519 uidRange(userStart + PKG_UIDS[0], userStart + PKG_UIDS[0]), 520 uidRange(userStart + PKG_UIDS[1], userStart + PKG_UIDS[2]), 521 uidRange(Process.toSdkSandboxUid(userStart + PKG_UIDS[0]), 522 Process.toSdkSandboxUid(userStart + PKG_UIDS[0])), 523 uidRange(Process.toSdkSandboxUid(userStart + PKG_UIDS[1]), 524 Process.toSdkSandboxUid(userStart + PKG_UIDS[2]))), 525 allow); 526 527 // Denied list 528 final Set<Range<Integer>> disallow = 529 vpn.createUserAndRestrictedProfilesRanges(PRIMARY_USER.id, 530 null /* allowedApplications */, Arrays.asList(packages)); 531 assertEquals(rangeSet( 532 uidRange(userStart, userStart + PKG_UIDS[0] - 1), 533 uidRange(userStart + PKG_UIDS[0] + 1, userStart + PKG_UIDS[1] - 1), 534 /* Empty range between UIDS[1] and UIDS[2], should be excluded, */ 535 uidRange(userStart + PKG_UIDS[2] + 1, 536 Process.toSdkSandboxUid(userStart + PKG_UIDS[0] - 1)), 537 uidRange(Process.toSdkSandboxUid(userStart + PKG_UIDS[0] + 1), 538 Process.toSdkSandboxUid(userStart + PKG_UIDS[1] - 1)), 539 uidRange(Process.toSdkSandboxUid(userStart + PKG_UIDS[2] + 1), userStop)), 540 disallow); 541 } 542 verifyPowerSaveTempWhitelistApp(String packageName)543 private void verifyPowerSaveTempWhitelistApp(String packageName) { 544 verify(mDeviceIdleInternal, timeout(TEST_TIMEOUT_MS)).addPowerSaveTempWhitelistApp( 545 anyInt(), eq(packageName), anyLong(), anyInt(), eq(false), 546 eq(PowerWhitelistManager.REASON_VPN), eq("VpnManager event")); 547 } 548 549 @Test testGetAlwaysAndOnGetLockDown()550 public void testGetAlwaysAndOnGetLockDown() throws Exception { 551 final Vpn vpn = createVpn(PRIMARY_USER.id); 552 553 // Default state. 554 assertFalse(vpn.getAlwaysOn()); 555 assertFalse(vpn.getLockdown()); 556 557 // Set always-on without lockdown. 558 assertTrue(vpn.setAlwaysOnPackage(PKGS[1], false, Collections.emptyList())); 559 assertTrue(vpn.getAlwaysOn()); 560 assertFalse(vpn.getLockdown()); 561 562 // Set always-on with lockdown. 563 assertTrue(vpn.setAlwaysOnPackage(PKGS[1], true, Collections.emptyList())); 564 assertTrue(vpn.getAlwaysOn()); 565 assertTrue(vpn.getLockdown()); 566 567 // Remove always-on configuration. 568 assertTrue(vpn.setAlwaysOnPackage(null, false, Collections.emptyList())); 569 assertFalse(vpn.getAlwaysOn()); 570 assertFalse(vpn.getLockdown()); 571 } 572 573 @Test testAlwaysOnWithoutLockdown()574 public void testAlwaysOnWithoutLockdown() throws Exception { 575 final Vpn vpn = createVpn(PRIMARY_USER.id); 576 assertTrue(vpn.setAlwaysOnPackage( 577 PKGS[1], false /* lockdown */, null /* lockdownAllowlist */)); 578 verify(mConnectivityManager, never()).setRequireVpnForUids(anyBoolean(), any()); 579 580 assertTrue(vpn.setAlwaysOnPackage( 581 null /* packageName */, false /* lockdown */, null /* lockdownAllowlist */)); 582 verify(mConnectivityManager, never()).setRequireVpnForUids(anyBoolean(), any()); 583 } 584 585 @Test testLockdownChangingPackage()586 public void testLockdownChangingPackage() throws Exception { 587 final Vpn vpn = createVpn(PRIMARY_USER.id); 588 final Range<Integer> user = PRIMARY_USER_RANGE; 589 final int userStart = user.getLower(); 590 final int userStop = user.getUpper(); 591 // Set always-on without lockdown. 592 assertTrue(vpn.setAlwaysOnPackage(PKGS[1], false, null)); 593 594 // Set always-on with lockdown. 595 assertTrue(vpn.setAlwaysOnPackage(PKGS[1], true, null)); 596 verify(mConnectivityManager).setRequireVpnForUids(true, toRanges(new UidRangeParcel[] { 597 new UidRangeParcel(userStart, userStart + PKG_UIDS[1] - 1), 598 new UidRangeParcel(userStart + PKG_UIDS[1] + 1, 599 Process.toSdkSandboxUid(userStart + PKG_UIDS[1] - 1)), 600 new UidRangeParcel(Process.toSdkSandboxUid(userStart + PKG_UIDS[1] + 1), userStop) 601 })); 602 603 // Switch to another app. 604 assertTrue(vpn.setAlwaysOnPackage(PKGS[3], true, null)); 605 verify(mConnectivityManager).setRequireVpnForUids(false, toRanges(new UidRangeParcel[] { 606 new UidRangeParcel(userStart, userStart + PKG_UIDS[1] - 1), 607 new UidRangeParcel(userStart + PKG_UIDS[1] + 1, 608 Process.toSdkSandboxUid(userStart + PKG_UIDS[1] - 1)), 609 new UidRangeParcel(Process.toSdkSandboxUid(userStart + PKG_UIDS[1] + 1), userStop) 610 })); 611 verify(mConnectivityManager).setRequireVpnForUids(true, toRanges(new UidRangeParcel[] { 612 new UidRangeParcel(userStart, userStart + PKG_UIDS[3] - 1), 613 new UidRangeParcel(userStart + PKG_UIDS[3] + 1, 614 Process.toSdkSandboxUid(userStart + PKG_UIDS[3] - 1)), 615 new UidRangeParcel(Process.toSdkSandboxUid(userStart + PKG_UIDS[3] + 1), userStop) 616 })); 617 } 618 619 @Test testLockdownAllowlist()620 public void testLockdownAllowlist() throws Exception { 621 final Vpn vpn = createVpn(PRIMARY_USER.id); 622 final Range<Integer> user = PRIMARY_USER_RANGE; 623 final int userStart = user.getLower(); 624 final int userStop = user.getUpper(); 625 // Set always-on with lockdown and allow app PKGS[2] from lockdown. 626 assertTrue(vpn.setAlwaysOnPackage( 627 PKGS[1], true, Collections.singletonList(PKGS[2]))); 628 verify(mConnectivityManager).setRequireVpnForUids(true, toRanges(new UidRangeParcel[] { 629 new UidRangeParcel(userStart, userStart + PKG_UIDS[1] - 1), 630 new UidRangeParcel(userStart + PKG_UIDS[2] + 1, 631 Process.toSdkSandboxUid(userStart + PKG_UIDS[1]) - 1), 632 new UidRangeParcel(Process.toSdkSandboxUid(userStart + PKG_UIDS[2] + 1), userStop) 633 })); 634 // Change allowed app list to PKGS[3]. 635 assertTrue(vpn.setAlwaysOnPackage( 636 PKGS[1], true, Collections.singletonList(PKGS[3]))); 637 verify(mConnectivityManager).setRequireVpnForUids(false, toRanges(new UidRangeParcel[] { 638 new UidRangeParcel(userStart + PKG_UIDS[2] + 1, 639 Process.toSdkSandboxUid(userStart + PKG_UIDS[1] - 1)), 640 new UidRangeParcel(Process.toSdkSandboxUid(userStart + PKG_UIDS[2] + 1), userStop) 641 })); 642 verify(mConnectivityManager).setRequireVpnForUids(true, toRanges(new UidRangeParcel[] { 643 new UidRangeParcel(userStart + PKG_UIDS[1] + 1, userStart + PKG_UIDS[3] - 1), 644 new UidRangeParcel(userStart + PKG_UIDS[3] + 1, 645 Process.toSdkSandboxUid(userStart + PKG_UIDS[1] - 1)), 646 new UidRangeParcel(Process.toSdkSandboxUid(userStart + PKG_UIDS[1] + 1), 647 Process.toSdkSandboxUid(userStart + PKG_UIDS[3] - 1)), 648 new UidRangeParcel(Process.toSdkSandboxUid(userStart + PKG_UIDS[3] + 1), userStop) 649 })); 650 651 // Change the VPN app. 652 assertTrue(vpn.setAlwaysOnPackage( 653 PKGS[0], true, Collections.singletonList(PKGS[3]))); 654 verify(mConnectivityManager).setRequireVpnForUids(false, toRanges(new UidRangeParcel[] { 655 new UidRangeParcel(userStart, userStart + PKG_UIDS[1] - 1), 656 new UidRangeParcel(userStart + PKG_UIDS[1] + 1, userStart + PKG_UIDS[3] - 1), 657 new UidRangeParcel(userStart + PKG_UIDS[3] + 1, 658 Process.toSdkSandboxUid(userStart + PKG_UIDS[1] - 1)), 659 new UidRangeParcel(Process.toSdkSandboxUid(userStart + PKG_UIDS[1] + 1), 660 Process.toSdkSandboxUid(userStart + PKG_UIDS[3] - 1)) 661 })); 662 verify(mConnectivityManager).setRequireVpnForUids(true, toRanges(new UidRangeParcel[] { 663 new UidRangeParcel(userStart, userStart + PKG_UIDS[0] - 1), 664 new UidRangeParcel(userStart + PKG_UIDS[0] + 1, userStart + PKG_UIDS[3] - 1), 665 new UidRangeParcel(userStart + PKG_UIDS[3] + 1, 666 Process.toSdkSandboxUid(userStart + PKG_UIDS[0] - 1)), 667 new UidRangeParcel(Process.toSdkSandboxUid(userStart + PKG_UIDS[0] + 1), 668 Process.toSdkSandboxUid(userStart + PKG_UIDS[3] - 1)) 669 })); 670 671 // Remove the list of allowed packages. 672 assertTrue(vpn.setAlwaysOnPackage(PKGS[0], true, null)); 673 verify(mConnectivityManager).setRequireVpnForUids(false, toRanges(new UidRangeParcel[] { 674 new UidRangeParcel(userStart + PKG_UIDS[0] + 1, userStart + PKG_UIDS[3] - 1), 675 new UidRangeParcel(userStart + PKG_UIDS[3] + 1, 676 Process.toSdkSandboxUid(userStart + PKG_UIDS[0] - 1)), 677 new UidRangeParcel(Process.toSdkSandboxUid(userStart + PKG_UIDS[0] + 1), 678 Process.toSdkSandboxUid(userStart + PKG_UIDS[3] - 1)), 679 new UidRangeParcel(Process.toSdkSandboxUid(userStart + PKG_UIDS[3] + 1), userStop) 680 })); 681 verify(mConnectivityManager).setRequireVpnForUids(true, toRanges(new UidRangeParcel[] { 682 new UidRangeParcel(userStart + PKG_UIDS[0] + 1, 683 Process.toSdkSandboxUid(userStart + PKG_UIDS[0] - 1)), 684 new UidRangeParcel(Process.toSdkSandboxUid(userStart + PKG_UIDS[0] + 1), userStop), 685 })); 686 687 // Add the list of allowed packages. 688 assertTrue(vpn.setAlwaysOnPackage( 689 PKGS[0], true, Collections.singletonList(PKGS[1]))); 690 verify(mConnectivityManager).setRequireVpnForUids(false, toRanges(new UidRangeParcel[] { 691 new UidRangeParcel(userStart + PKG_UIDS[0] + 1, 692 Process.toSdkSandboxUid(userStart + PKG_UIDS[0] - 1)), 693 new UidRangeParcel(Process.toSdkSandboxUid(userStart + PKG_UIDS[0] + 1), userStop), 694 })); 695 verify(mConnectivityManager).setRequireVpnForUids(true, toRanges(new UidRangeParcel[] { 696 new UidRangeParcel(userStart + PKG_UIDS[0] + 1, userStart + PKG_UIDS[1] - 1), 697 new UidRangeParcel(userStart + PKG_UIDS[1] + 1, 698 Process.toSdkSandboxUid(userStart + PKG_UIDS[0] - 1)), 699 new UidRangeParcel(Process.toSdkSandboxUid(userStart + PKG_UIDS[0] + 1), 700 Process.toSdkSandboxUid(userStart + PKG_UIDS[1] - 1)), 701 new UidRangeParcel(Process.toSdkSandboxUid(userStart + PKG_UIDS[1] + 1), userStop) 702 })); 703 704 // Try allowing a package with a comma, should be rejected. 705 assertFalse(vpn.setAlwaysOnPackage( 706 PKGS[0], true, Collections.singletonList("a.b,c.d"))); 707 708 // Pass a non-existent packages in the allowlist, they (and only they) should be ignored. 709 // allowed package should change from PGKS[1] to PKGS[2]. 710 assertTrue(vpn.setAlwaysOnPackage( 711 PKGS[0], true, Arrays.asList("com.foo.app", PKGS[2], "com.bar.app"))); 712 verify(mConnectivityManager).setRequireVpnForUids(false, toRanges(new UidRangeParcel[] { 713 new UidRangeParcel(userStart + PKG_UIDS[0] + 1, userStart + PKG_UIDS[1] - 1), 714 new UidRangeParcel(userStart + PKG_UIDS[1] + 1, 715 Process.toSdkSandboxUid(userStart + PKG_UIDS[0] - 1)), 716 new UidRangeParcel(Process.toSdkSandboxUid(userStart + PKG_UIDS[0] + 1), 717 Process.toSdkSandboxUid(userStart + PKG_UIDS[1] - 1)), 718 new UidRangeParcel(Process.toSdkSandboxUid(userStart + PKG_UIDS[1] + 1), userStop) 719 })); 720 verify(mConnectivityManager).setRequireVpnForUids(true, toRanges(new UidRangeParcel[] { 721 new UidRangeParcel(userStart + PKG_UIDS[0] + 1, userStart + PKG_UIDS[2] - 1), 722 new UidRangeParcel(userStart + PKG_UIDS[2] + 1, 723 Process.toSdkSandboxUid(userStart + PKG_UIDS[0] - 1)), 724 new UidRangeParcel(Process.toSdkSandboxUid(userStart + PKG_UIDS[0] + 1), 725 Process.toSdkSandboxUid(userStart + PKG_UIDS[2] - 1)), 726 new UidRangeParcel(Process.toSdkSandboxUid(userStart + PKG_UIDS[2] + 1), userStop) 727 })); 728 } 729 730 @Test testLockdownSystemUser()731 public void testLockdownSystemUser() throws Exception { 732 final Vpn vpn = createVpn(SYSTEM_USER_ID); 733 734 // Uid 0 is always excluded and PKG_UIDS[1] is the uid of the VPN. 735 final List<Integer> excludedUids = new ArrayList<>(List.of(0, PKG_UIDS[1])); 736 final List<Range<Integer>> ranges = makeVpnUidRange(SYSTEM_USER_ID, excludedUids); 737 738 // Set always-on with lockdown. 739 assertTrue(vpn.setAlwaysOnPackage( 740 PKGS[1], true /* lockdown */, null /* lockdownAllowlist */)); 741 verify(mConnectivityManager).setRequireVpnForUids(true, ranges); 742 743 // Disable always-on with lockdown. 744 assertTrue(vpn.setAlwaysOnPackage( 745 null /* packageName */, false /* lockdown */, null /* lockdownAllowlist */)); 746 verify(mConnectivityManager).setRequireVpnForUids(false, ranges); 747 748 // Set always-on with lockdown and allow the app PKGS[2]. 749 excludedUids.add(PKG_UIDS[2]); 750 final List<Range<Integer>> ranges2 = makeVpnUidRange(SYSTEM_USER_ID, excludedUids); 751 assertTrue(vpn.setAlwaysOnPackage( 752 PKGS[1], true /* lockdown */, Collections.singletonList(PKGS[2]))); 753 verify(mConnectivityManager).setRequireVpnForUids(true, ranges2); 754 755 // Disable always-on with lockdown. 756 assertTrue(vpn.setAlwaysOnPackage( 757 null /* packageName */, false /* lockdown */, null /* lockdownAllowlist */)); 758 verify(mConnectivityManager).setRequireVpnForUids(false, ranges2); 759 } 760 761 @Test testLockdownRuleRepeatability()762 public void testLockdownRuleRepeatability() throws Exception { 763 final Vpn vpn = createVpn(PRIMARY_USER.id); 764 final UidRangeParcel[] primaryUserRangeParcel = new UidRangeParcel[] { 765 new UidRangeParcel(PRIMARY_USER_RANGE.getLower(), PRIMARY_USER_RANGE.getUpper())}; 766 // Given legacy lockdown is already enabled, 767 vpn.setLockdown(true); 768 verify(mConnectivityManager, times(1)).setRequireVpnForUids(true, 769 toRanges(primaryUserRangeParcel)); 770 771 // Enabling legacy lockdown twice should do nothing. 772 vpn.setLockdown(true); 773 verify(mConnectivityManager, times(1)).setRequireVpnForUids(anyBoolean(), any()); 774 775 // And disabling should remove the rules exactly once. 776 vpn.setLockdown(false); 777 verify(mConnectivityManager, times(1)).setRequireVpnForUids(false, 778 toRanges(primaryUserRangeParcel)); 779 780 // Removing the lockdown again should have no effect. 781 vpn.setLockdown(false); 782 verify(mConnectivityManager, times(2)).setRequireVpnForUids(anyBoolean(), any()); 783 } 784 toRanges(UidRangeParcel[] ranges)785 private ArrayList<Range<Integer>> toRanges(UidRangeParcel[] ranges) { 786 ArrayList<Range<Integer>> rangesArray = new ArrayList<>(ranges.length); 787 for (int i = 0; i < ranges.length; i++) { 788 rangesArray.add(new Range<>(ranges[i].start, ranges[i].stop)); 789 } 790 return rangesArray; 791 } 792 793 @Test testLockdownRuleReversibility()794 public void testLockdownRuleReversibility() throws Exception { 795 doReturn(PERMISSION_GRANTED).when(mContext).checkCallingOrSelfPermission(CONTROL_VPN); 796 final Vpn vpn = createVpn(PRIMARY_USER.id); 797 final UidRangeParcel[] entireUser = { 798 new UidRangeParcel(PRIMARY_USER_RANGE.getLower(), PRIMARY_USER_RANGE.getUpper()) 799 }; 800 final UidRangeParcel[] exceptPkg0 = { 801 new UidRangeParcel(entireUser[0].start, entireUser[0].start + PKG_UIDS[0] - 1), 802 new UidRangeParcel(entireUser[0].start + PKG_UIDS[0] + 1, 803 Process.toSdkSandboxUid(entireUser[0].start + PKG_UIDS[0] - 1)), 804 new UidRangeParcel(Process.toSdkSandboxUid(entireUser[0].start + PKG_UIDS[0] + 1), 805 entireUser[0].stop), 806 }; 807 808 final InOrder order = inOrder(mConnectivityManager); 809 810 // Given lockdown is enabled with no package (legacy VPN), 811 vpn.setLockdown(true); 812 order.verify(mConnectivityManager).setRequireVpnForUids(true, toRanges(entireUser)); 813 814 // When a new VPN package is set the rules should change to cover that package. 815 vpn.prepare(null, PKGS[0], VpnManager.TYPE_VPN_SERVICE); 816 order.verify(mConnectivityManager).setRequireVpnForUids(false, toRanges(entireUser)); 817 order.verify(mConnectivityManager).setRequireVpnForUids(true, toRanges(exceptPkg0)); 818 819 // When that VPN package is unset, everything should be undone again in reverse. 820 vpn.prepare(null, VpnConfig.LEGACY_VPN, VpnManager.TYPE_VPN_SERVICE); 821 order.verify(mConnectivityManager).setRequireVpnForUids(false, toRanges(exceptPkg0)); 822 order.verify(mConnectivityManager).setRequireVpnForUids(true, toRanges(entireUser)); 823 } 824 825 @Test testOnUserAddedAndRemoved_restrictedUser()826 public void testOnUserAddedAndRemoved_restrictedUser() throws Exception { 827 final InOrder order = inOrder(mMockNetworkAgent); 828 final Vpn vpn = createVpn(PRIMARY_USER.id); 829 final Set<Range<Integer>> initialRange = rangeSet(PRIMARY_USER_RANGE); 830 // Note since mVpnProfile is a Ikev2VpnProfile, this starts an IkeV2VpnRunner. 831 startLegacyVpn(vpn, mVpnProfile); 832 // Set an initial Uid range and mock the network agent 833 vpn.mNetworkCapabilities.setUids(initialRange); 834 vpn.mNetworkAgent = mMockNetworkAgent; 835 836 // Add the restricted user 837 setMockedUsers(PRIMARY_USER, RESTRICTED_PROFILE_A); 838 vpn.onUserAdded(RESTRICTED_PROFILE_A.id); 839 // Expect restricted user range to be added to the NetworkCapabilities. 840 final Set<Range<Integer>> expectRestrictedRange = 841 rangeSet(PRIMARY_USER_RANGE, uidRangeForUser(RESTRICTED_PROFILE_A.id)); 842 assertEquals(expectRestrictedRange, vpn.mNetworkCapabilities.getUids()); 843 order.verify(mMockNetworkAgent).doSendNetworkCapabilities( 844 argThat(nc -> expectRestrictedRange.equals(nc.getUids()))); 845 846 // Remove the restricted user 847 vpn.onUserRemoved(RESTRICTED_PROFILE_A.id); 848 // Expect restricted user range to be removed from the NetworkCapabilities. 849 assertEquals(initialRange, vpn.mNetworkCapabilities.getUids()); 850 order.verify(mMockNetworkAgent).doSendNetworkCapabilities( 851 argThat(nc -> initialRange.equals(nc.getUids()))); 852 } 853 854 @Test testOnUserAddedAndRemoved_restrictedUserLockdown()855 public void testOnUserAddedAndRemoved_restrictedUserLockdown() throws Exception { 856 final UidRangeParcel[] primaryUserRangeParcel = new UidRangeParcel[] { 857 new UidRangeParcel(PRIMARY_USER_RANGE.getLower(), PRIMARY_USER_RANGE.getUpper())}; 858 final Range<Integer> restrictedUserRange = uidRangeForUser(RESTRICTED_PROFILE_A.id); 859 final UidRangeParcel[] restrictedUserRangeParcel = new UidRangeParcel[] { 860 new UidRangeParcel(restrictedUserRange.getLower(), restrictedUserRange.getUpper())}; 861 final Vpn vpn = createVpn(PRIMARY_USER.id); 862 863 // Set lockdown calls setRequireVpnForUids 864 vpn.setLockdown(true); 865 verify(mConnectivityManager).setRequireVpnForUids(true, toRanges(primaryUserRangeParcel)); 866 867 // Add the restricted user 868 doReturn(true).when(mUserManager).canHaveRestrictedProfile(); 869 setMockedUsers(PRIMARY_USER, RESTRICTED_PROFILE_A); 870 vpn.onUserAdded(RESTRICTED_PROFILE_A.id); 871 872 // Expect restricted user range to be added. 873 verify(mConnectivityManager).setRequireVpnForUids(true, 874 toRanges(restrictedUserRangeParcel)); 875 876 // Mark as partial indicates that the user is removed, mUserManager.getAliveUsers() does not 877 // return the restricted user but it is still returned in mUserManager.getUserInfo(). 878 RESTRICTED_PROFILE_A.partial = true; 879 // Remove the restricted user 880 vpn.onUserRemoved(RESTRICTED_PROFILE_A.id); 881 verify(mConnectivityManager).setRequireVpnForUids(false, 882 toRanges(restrictedUserRangeParcel)); 883 // reset to avoid affecting other tests since RESTRICTED_PROFILE_A is static. 884 RESTRICTED_PROFILE_A.partial = false; 885 } 886 887 @Test testOnUserAddedAndRemoved_restrictedUserAlwaysOn()888 public void testOnUserAddedAndRemoved_restrictedUserAlwaysOn() throws Exception { 889 final Vpn vpn = createVpn(PRIMARY_USER.id); 890 891 // setAlwaysOnPackage() calls setRequireVpnForUids() 892 assertTrue(vpn.setAlwaysOnPackage( 893 PKGS[0], true /* lockdown */, null /* lockdownAllowlist */)); 894 final List<Integer> excludedUids = List.of(PKG_UIDS[0]); 895 final List<Range<Integer>> primaryRanges = 896 makeVpnUidRange(PRIMARY_USER.id, excludedUids); 897 verify(mConnectivityManager).setRequireVpnForUids(true, primaryRanges); 898 899 // Add the restricted user 900 doReturn(true).when(mUserManager).canHaveRestrictedProfile(); 901 setMockedUsers(PRIMARY_USER, RESTRICTED_PROFILE_A); 902 vpn.onUserAdded(RESTRICTED_PROFILE_A.id); 903 904 final List<Range<Integer>> restrictedRanges = 905 makeVpnUidRange(RESTRICTED_PROFILE_A.id, excludedUids); 906 // Expect restricted user range to be added. 907 verify(mConnectivityManager).setRequireVpnForUids(true, restrictedRanges); 908 909 // Mark as partial indicates that the user is removed, mUserManager.getAliveUsers() does not 910 // return the restricted user but it is still returned in mUserManager.getUserInfo(). 911 RESTRICTED_PROFILE_A.partial = true; 912 // Remove the restricted user 913 vpn.onUserRemoved(RESTRICTED_PROFILE_A.id); 914 verify(mConnectivityManager).setRequireVpnForUids(false, restrictedRanges); 915 916 // reset to avoid affecting other tests since RESTRICTED_PROFILE_A is static. 917 RESTRICTED_PROFILE_A.partial = false; 918 } 919 920 @Test testPrepare_throwSecurityExceptionWhenGivenPackageDoesNotBelongToTheCaller()921 public void testPrepare_throwSecurityExceptionWhenGivenPackageDoesNotBelongToTheCaller() 922 throws Exception { 923 mTestDeps.mIgnoreCallingUidChecks = false; 924 final Vpn vpn = createVpn(); 925 assertThrows(SecurityException.class, 926 () -> vpn.prepare("com.not.vpn.owner", null, VpnManager.TYPE_VPN_SERVICE)); 927 assertThrows(SecurityException.class, 928 () -> vpn.prepare(null, "com.not.vpn.owner", VpnManager.TYPE_VPN_SERVICE)); 929 assertThrows(SecurityException.class, 930 () -> vpn.prepare("com.not.vpn.owner1", "com.not.vpn.owner2", 931 VpnManager.TYPE_VPN_SERVICE)); 932 } 933 934 @Test testPrepare_bothOldPackageAndNewPackageAreNull()935 public void testPrepare_bothOldPackageAndNewPackageAreNull() throws Exception { 936 final Vpn vpn = createVpn(); 937 assertTrue(vpn.prepare(null, null, VpnManager.TYPE_VPN_SERVICE)); 938 939 } 940 941 @Test testPrepare_legacyVpnWithoutControlVpn()942 public void testPrepare_legacyVpnWithoutControlVpn() 943 throws Exception { 944 doThrow(new SecurityException("no CONTROL_VPN")).when(mContext) 945 .enforceCallingOrSelfPermission(eq(CONTROL_VPN), any()); 946 final Vpn vpn = createVpn(); 947 assertThrows(SecurityException.class, 948 () -> vpn.prepare(null, VpnConfig.LEGACY_VPN, VpnManager.TYPE_VPN_SERVICE)); 949 950 // CONTROL_VPN can be held by the caller or another system server process - both are 951 // allowed. Just checking for `enforceCallingPermission` may not be sufficient. 952 verify(mContext, never()).enforceCallingPermission(eq(CONTROL_VPN), any()); 953 } 954 955 @Test testPrepare_legacyVpnWithControlVpn()956 public void testPrepare_legacyVpnWithControlVpn() 957 throws Exception { 958 doNothing().when(mContext).enforceCallingOrSelfPermission(eq(CONTROL_VPN), any()); 959 final Vpn vpn = createVpn(); 960 assertTrue(vpn.prepare(null, VpnConfig.LEGACY_VPN, VpnManager.TYPE_VPN_SERVICE)); 961 962 // CONTROL_VPN can be held by the caller or another system server process - both are 963 // allowed. Just checking for `enforceCallingPermission` may not be sufficient. 964 verify(mContext, never()).enforceCallingPermission(eq(CONTROL_VPN), any()); 965 } 966 967 @Test testIsAlwaysOnPackageSupported()968 public void testIsAlwaysOnPackageSupported() throws Exception { 969 final Vpn vpn = createVpn(PRIMARY_USER.id); 970 971 ApplicationInfo appInfo = new ApplicationInfo(); 972 when(mPackageManager.getApplicationInfoAsUser(eq(PKGS[0]), anyInt(), eq(PRIMARY_USER.id))) 973 .thenReturn(appInfo); 974 975 ServiceInfo svcInfo = new ServiceInfo(); 976 ResolveInfo resInfo = new ResolveInfo(); 977 resInfo.serviceInfo = svcInfo; 978 when(mPackageManager.queryIntentServicesAsUser(any(), eq(PackageManager.GET_META_DATA), 979 eq(PRIMARY_USER.id))) 980 .thenReturn(Collections.singletonList(resInfo)); 981 982 // null package name should return false 983 assertFalse(vpn.isAlwaysOnPackageSupported(null)); 984 985 // Pre-N apps are not supported 986 appInfo.targetSdkVersion = VERSION_CODES.M; 987 assertFalse(vpn.isAlwaysOnPackageSupported(PKGS[0])); 988 989 // N+ apps are supported by default 990 appInfo.targetSdkVersion = VERSION_CODES.N; 991 assertTrue(vpn.isAlwaysOnPackageSupported(PKGS[0])); 992 993 // Apps that opt out explicitly are not supported 994 appInfo.targetSdkVersion = VERSION_CODES.CUR_DEVELOPMENT; 995 Bundle metaData = new Bundle(); 996 metaData.putBoolean(VpnService.SERVICE_META_DATA_SUPPORTS_ALWAYS_ON, false); 997 svcInfo.metaData = metaData; 998 assertFalse(vpn.isAlwaysOnPackageSupported(PKGS[0])); 999 } 1000 1001 @Test testNotificationShownForAlwaysOnApp()1002 public void testNotificationShownForAlwaysOnApp() throws Exception { 1003 final UserHandle userHandle = UserHandle.of(PRIMARY_USER.id); 1004 final Vpn vpn = createVpn(PRIMARY_USER.id); 1005 setMockedUsers(PRIMARY_USER); 1006 1007 final InOrder order = inOrder(mNotificationManager); 1008 1009 // Don't show a notification for regular disconnected states. 1010 vpn.updateState(DetailedState.DISCONNECTED, TAG); 1011 order.verify(mNotificationManager, atLeastOnce()).cancel(anyString(), anyInt()); 1012 1013 // Start showing a notification for disconnected once always-on. 1014 vpn.setAlwaysOnPackage(PKGS[0], false, null); 1015 order.verify(mNotificationManager).notify(anyString(), anyInt(), any()); 1016 1017 // Stop showing the notification once connected. 1018 vpn.updateState(DetailedState.CONNECTED, TAG); 1019 order.verify(mNotificationManager).cancel(anyString(), anyInt()); 1020 1021 // Show the notification if we disconnect again. 1022 vpn.updateState(DetailedState.DISCONNECTED, TAG); 1023 order.verify(mNotificationManager).notify(anyString(), anyInt(), any()); 1024 1025 // Notification should be cleared after unsetting always-on package. 1026 vpn.setAlwaysOnPackage(null, false, null); 1027 order.verify(mNotificationManager).cancel(anyString(), anyInt()); 1028 } 1029 1030 /** 1031 * The profile name should NOT change between releases for backwards compatibility 1032 * 1033 * <p>If this is changed between releases, the {@link Vpn#getVpnProfilePrivileged()} method MUST 1034 * be updated to ensure backward compatibility. 1035 */ 1036 @Test testGetProfileNameForPackage()1037 public void testGetProfileNameForPackage() throws Exception { 1038 final Vpn vpn = createVpn(PRIMARY_USER.id); 1039 setMockedUsers(PRIMARY_USER); 1040 1041 final String expected = Credentials.PLATFORM_VPN + PRIMARY_USER.id + "_" + TEST_VPN_PKG; 1042 assertEquals(expected, vpn.getProfileNameForPackage(TEST_VPN_PKG)); 1043 } 1044 createVpn(String... grantedOps)1045 private Vpn createVpn(String... grantedOps) throws Exception { 1046 return createVpn(PRIMARY_USER, grantedOps); 1047 } 1048 createVpn(UserInfo user, String... grantedOps)1049 private Vpn createVpn(UserInfo user, String... grantedOps) throws Exception { 1050 final Vpn vpn = createVpn(user.id); 1051 setMockedUsers(user); 1052 1053 for (final String opStr : grantedOps) { 1054 when(mAppOps.noteOpNoThrow(opStr, Process.myUid(), TEST_VPN_PKG, 1055 null /* attributionTag */, null /* message */)) 1056 .thenReturn(AppOpsManager.MODE_ALLOWED); 1057 } 1058 1059 return vpn; 1060 } 1061 checkProvisionVpnProfile(Vpn vpn, boolean expectedResult, String... checkedOps)1062 private void checkProvisionVpnProfile(Vpn vpn, boolean expectedResult, String... checkedOps) { 1063 assertEquals(expectedResult, vpn.provisionVpnProfile(TEST_VPN_PKG, mVpnProfile)); 1064 1065 // The profile should always be stored, whether or not consent has been previously granted. 1066 verify(mVpnProfileStore) 1067 .put( 1068 eq(vpn.getProfileNameForPackage(TEST_VPN_PKG)), 1069 eq(mVpnProfile.encode())); 1070 1071 for (final String checkedOpStr : checkedOps) { 1072 verify(mAppOps).noteOpNoThrow(checkedOpStr, Process.myUid(), TEST_VPN_PKG, 1073 null /* attributionTag */, null /* message */); 1074 } 1075 } 1076 1077 @Test testProvisionVpnProfileNoIpsecTunnels()1078 public void testProvisionVpnProfileNoIpsecTunnels() throws Exception { 1079 when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_IPSEC_TUNNELS)) 1080 .thenReturn(false); 1081 final Vpn vpn = createVpn(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN); 1082 1083 try { 1084 checkProvisionVpnProfile( 1085 vpn, true /* expectedResult */, AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN); 1086 fail("Expected exception due to missing feature"); 1087 } catch (UnsupportedOperationException expected) { 1088 } 1089 } 1090 startVpnForVerifyAppExclusionList(Vpn vpn)1091 private String startVpnForVerifyAppExclusionList(Vpn vpn) throws Exception { 1092 when(mVpnProfileStore.get(vpn.getProfileNameForPackage(TEST_VPN_PKG))) 1093 .thenReturn(mVpnProfile.encode()); 1094 when(mVpnProfileStore.get(PRIMARY_USER_APP_EXCLUDE_KEY)) 1095 .thenReturn(HexDump.hexStringToByteArray(PKGS_BYTES)); 1096 final String sessionKey = vpn.startVpnProfile(TEST_VPN_PKG); 1097 final Set<Range<Integer>> uidRanges = vpn.createUserAndRestrictedProfilesRanges( 1098 PRIMARY_USER.id, null /* allowedApplications */, Arrays.asList(PKGS)); 1099 verify(mConnectivityManager).setVpnDefaultForUids(eq(sessionKey), eq(uidRanges)); 1100 clearInvocations(mConnectivityManager); 1101 verify(mVpnProfileStore).get(eq(vpn.getProfileNameForPackage(TEST_VPN_PKG))); 1102 vpn.mNetworkAgent = mMockNetworkAgent; 1103 1104 return sessionKey; 1105 } 1106 prepareVpnForVerifyAppExclusionList()1107 private Vpn prepareVpnForVerifyAppExclusionList() throws Exception { 1108 final Vpn vpn = createVpn(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN); 1109 startVpnForVerifyAppExclusionList(vpn); 1110 1111 return vpn; 1112 } 1113 1114 @Test testSetAndGetAppExclusionList()1115 public void testSetAndGetAppExclusionList() throws Exception { 1116 final Vpn vpn = createVpn(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN); 1117 final String sessionKey = startVpnForVerifyAppExclusionList(vpn); 1118 verify(mVpnProfileStore, never()).put(eq(PRIMARY_USER_APP_EXCLUDE_KEY), any()); 1119 vpn.setAppExclusionList(TEST_VPN_PKG, Arrays.asList(PKGS)); 1120 verify(mVpnProfileStore) 1121 .put(eq(PRIMARY_USER_APP_EXCLUDE_KEY), 1122 eq(HexDump.hexStringToByteArray(PKGS_BYTES))); 1123 final Set<Range<Integer>> uidRanges = vpn.createUserAndRestrictedProfilesRanges( 1124 PRIMARY_USER.id, null /* allowedApplications */, Arrays.asList(PKGS)); 1125 verify(mConnectivityManager).setVpnDefaultForUids(eq(sessionKey), eq(uidRanges)); 1126 assertEquals(uidRanges, vpn.mNetworkCapabilities.getUids()); 1127 assertEquals(Arrays.asList(PKGS), vpn.getAppExclusionList(TEST_VPN_PKG)); 1128 } 1129 1130 @Test testRefreshPlatformVpnAppExclusionList_updatesExcludedUids()1131 public void testRefreshPlatformVpnAppExclusionList_updatesExcludedUids() throws Exception { 1132 final Vpn vpn = createVpn(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN); 1133 final String sessionKey = startVpnForVerifyAppExclusionList(vpn); 1134 vpn.setAppExclusionList(TEST_VPN_PKG, Arrays.asList(PKGS)); 1135 final Set<Range<Integer>> uidRanges = vpn.createUserAndRestrictedProfilesRanges( 1136 PRIMARY_USER.id, null /* allowedApplications */, Arrays.asList(PKGS)); 1137 verify(mConnectivityManager).setVpnDefaultForUids(eq(sessionKey), eq(uidRanges)); 1138 verify(mMockNetworkAgent).doSendNetworkCapabilities(any()); 1139 assertEquals(Arrays.asList(PKGS), vpn.getAppExclusionList(TEST_VPN_PKG)); 1140 1141 reset(mMockNetworkAgent); 1142 1143 // Remove one of the package 1144 List<Integer> newExcludedUids = toList(PKG_UIDS); 1145 newExcludedUids.remove((Integer) PKG_UIDS[0]); 1146 Set<Range<Integer>> newUidRanges = makeVpnUidRangeSet(PRIMARY_USER.id, newExcludedUids); 1147 sPackages.remove(PKGS[0]); 1148 vpn.refreshPlatformVpnAppExclusionList(); 1149 1150 // List in keystore is not changed, but UID for the removed packages is no longer exempted. 1151 assertEquals(Arrays.asList(PKGS), vpn.getAppExclusionList(TEST_VPN_PKG)); 1152 assertEquals(newUidRanges, vpn.mNetworkCapabilities.getUids()); 1153 ArgumentCaptor<NetworkCapabilities> ncCaptor = 1154 ArgumentCaptor.forClass(NetworkCapabilities.class); 1155 verify(mMockNetworkAgent).doSendNetworkCapabilities(ncCaptor.capture()); 1156 assertEquals(newUidRanges, ncCaptor.getValue().getUids()); 1157 verify(mConnectivityManager).setVpnDefaultForUids(eq(sessionKey), eq(newUidRanges)); 1158 1159 reset(mMockNetworkAgent); 1160 1161 // Add the package back 1162 newExcludedUids.add(PKG_UIDS[0]); 1163 newUidRanges = makeVpnUidRangeSet(PRIMARY_USER.id, newExcludedUids); 1164 sPackages.put(PKGS[0], PKG_UIDS[0]); 1165 vpn.refreshPlatformVpnAppExclusionList(); 1166 1167 // List in keystore is not changed and the uid list should be updated in the net cap. 1168 assertEquals(Arrays.asList(PKGS), vpn.getAppExclusionList(TEST_VPN_PKG)); 1169 assertEquals(newUidRanges, vpn.mNetworkCapabilities.getUids()); 1170 verify(mMockNetworkAgent).doSendNetworkCapabilities(ncCaptor.capture()); 1171 assertEquals(newUidRanges, ncCaptor.getValue().getUids()); 1172 1173 // The uidRange is the same as the original setAppExclusionList so this is the second call 1174 verify(mConnectivityManager, times(2)) 1175 .setVpnDefaultForUids(eq(sessionKey), eq(newUidRanges)); 1176 } 1177 makeVpnUidRange(int userId, List<Integer> excludedAppIdList)1178 private List<Range<Integer>> makeVpnUidRange(int userId, List<Integer> excludedAppIdList) { 1179 final SortedSet<Integer> list = new TreeSet<>(); 1180 1181 final int userBase = userId * UserHandle.PER_USER_RANGE; 1182 for (int appId : excludedAppIdList) { 1183 final int uid = UserHandle.getUid(userId, appId); 1184 list.add(uid); 1185 if (Process.isApplicationUid(uid)) { 1186 list.add(Process.toSdkSandboxUid(uid)); // Add Sdk Sandbox UID 1187 } 1188 } 1189 1190 final int minUid = userBase; 1191 final int maxUid = userBase + UserHandle.PER_USER_RANGE - 1; 1192 final List<Range<Integer>> ranges = new ArrayList<>(); 1193 1194 // Iterate the list to create the ranges between each uid. 1195 int start = minUid; 1196 for (int uid : list) { 1197 if (uid == start) { 1198 start++; 1199 } else { 1200 ranges.add(new Range<>(start, uid - 1)); 1201 start = uid + 1; 1202 } 1203 } 1204 1205 // Create the range between last uid and max uid. 1206 if (start <= maxUid) { 1207 ranges.add(new Range<>(start, maxUid)); 1208 } 1209 1210 return ranges; 1211 } 1212 makeVpnUidRangeSet(int userId, List<Integer> excludedAppIdList)1213 private Set<Range<Integer>> makeVpnUidRangeSet(int userId, List<Integer> excludedAppIdList) { 1214 return new ArraySet<>(makeVpnUidRange(userId, excludedAppIdList)); 1215 } 1216 1217 @Test testSetAndGetAppExclusionListRestrictedUser()1218 public void testSetAndGetAppExclusionListRestrictedUser() throws Exception { 1219 final Vpn vpn = prepareVpnForVerifyAppExclusionList(); 1220 1221 // Mock it to restricted profile 1222 when(mUserManager.getUserInfo(anyInt())).thenReturn(RESTRICTED_PROFILE_A); 1223 1224 // Restricted users cannot configure VPNs 1225 assertThrows(SecurityException.class, 1226 () -> vpn.setAppExclusionList(TEST_VPN_PKG, new ArrayList<>())); 1227 1228 assertEquals(Arrays.asList(PKGS), vpn.getAppExclusionList(TEST_VPN_PKG)); 1229 } 1230 1231 @Test testProvisionVpnProfilePreconsented()1232 public void testProvisionVpnProfilePreconsented() throws Exception { 1233 final Vpn vpn = createVpn(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN); 1234 1235 checkProvisionVpnProfile( 1236 vpn, true /* expectedResult */, AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN); 1237 } 1238 1239 @Test testProvisionVpnProfileNotPreconsented()1240 public void testProvisionVpnProfileNotPreconsented() throws Exception { 1241 final Vpn vpn = createVpn(); 1242 1243 // Expect that both the ACTIVATE_VPN and ACTIVATE_PLATFORM_VPN were tried, but the caller 1244 // had neither. 1245 checkProvisionVpnProfile(vpn, false /* expectedResult */, 1246 AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN, AppOpsManager.OPSTR_ACTIVATE_VPN); 1247 } 1248 1249 @Test testProvisionVpnProfileVpnServicePreconsented()1250 public void testProvisionVpnProfileVpnServicePreconsented() throws Exception { 1251 final Vpn vpn = createVpn(AppOpsManager.OPSTR_ACTIVATE_VPN); 1252 1253 checkProvisionVpnProfile(vpn, true /* expectedResult */, AppOpsManager.OPSTR_ACTIVATE_VPN); 1254 } 1255 1256 @Test testProvisionVpnProfileTooLarge()1257 public void testProvisionVpnProfileTooLarge() throws Exception { 1258 final Vpn vpn = createVpn(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN); 1259 1260 final VpnProfile bigProfile = new VpnProfile(""); 1261 bigProfile.name = new String(new byte[Vpn.MAX_VPN_PROFILE_SIZE_BYTES + 1]); 1262 1263 try { 1264 vpn.provisionVpnProfile(TEST_VPN_PKG, bigProfile); 1265 fail("Expected IAE due to profile size"); 1266 } catch (IllegalArgumentException expected) { 1267 } 1268 } 1269 1270 @Test testProvisionVpnProfileRestrictedUser()1271 public void testProvisionVpnProfileRestrictedUser() throws Exception { 1272 final Vpn vpn = 1273 createVpn( 1274 RESTRICTED_PROFILE_A, AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN); 1275 1276 try { 1277 vpn.provisionVpnProfile(TEST_VPN_PKG, mVpnProfile); 1278 fail("Expected SecurityException due to restricted user"); 1279 } catch (SecurityException expected) { 1280 } 1281 } 1282 1283 @Test testDeleteVpnProfile()1284 public void testDeleteVpnProfile() throws Exception { 1285 final Vpn vpn = createVpn(); 1286 1287 vpn.deleteVpnProfile(TEST_VPN_PKG); 1288 1289 verify(mVpnProfileStore) 1290 .remove(eq(vpn.getProfileNameForPackage(TEST_VPN_PKG))); 1291 } 1292 1293 @Test testDeleteVpnProfileRestrictedUser()1294 public void testDeleteVpnProfileRestrictedUser() throws Exception { 1295 final Vpn vpn = 1296 createVpn( 1297 RESTRICTED_PROFILE_A, AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN); 1298 1299 try { 1300 vpn.deleteVpnProfile(TEST_VPN_PKG); 1301 fail("Expected SecurityException due to restricted user"); 1302 } catch (SecurityException expected) { 1303 } 1304 } 1305 1306 @Test testGetVpnProfilePrivileged()1307 public void testGetVpnProfilePrivileged() throws Exception { 1308 final Vpn vpn = createVpn(); 1309 1310 when(mVpnProfileStore.get(vpn.getProfileNameForPackage(TEST_VPN_PKG))) 1311 .thenReturn(new VpnProfile("").encode()); 1312 1313 vpn.getVpnProfilePrivileged(TEST_VPN_PKG); 1314 1315 verify(mVpnProfileStore).get(eq(vpn.getProfileNameForPackage(TEST_VPN_PKG))); 1316 } 1317 verifyPlatformVpnIsActivated(String packageName)1318 private void verifyPlatformVpnIsActivated(String packageName) { 1319 verify(mAppOps).noteOpNoThrow( 1320 eq(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN), 1321 eq(Process.myUid()), 1322 eq(packageName), 1323 eq(null) /* attributionTag */, 1324 eq(null) /* message */); 1325 verify(mAppOps).startOp( 1326 eq(AppOpsManager.OPSTR_ESTABLISH_VPN_MANAGER), 1327 eq(UserHandle.getUid(PRIMARY_USER.id, Process.myUid())), 1328 eq(packageName), 1329 eq(null) /* attributionTag */, 1330 eq(null) /* message */); 1331 } 1332 verifyPlatformVpnIsDeactivated(String packageName)1333 private void verifyPlatformVpnIsDeactivated(String packageName) { 1334 // Add a small delay to double confirm that finishOp is only called once. 1335 verify(mAppOps, after(100)).finishOp( 1336 eq(AppOpsManager.OPSTR_ESTABLISH_VPN_MANAGER), 1337 eq(UserHandle.getUid(PRIMARY_USER.id, Process.myUid())), 1338 eq(packageName), 1339 eq(null) /* attributionTag */); 1340 } 1341 1342 @Test testStartVpnProfile()1343 public void testStartVpnProfile() throws Exception { 1344 final Vpn vpn = createVpn(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN); 1345 1346 when(mVpnProfileStore.get(vpn.getProfileNameForPackage(TEST_VPN_PKG))) 1347 .thenReturn(mVpnProfile.encode()); 1348 1349 vpn.startVpnProfile(TEST_VPN_PKG); 1350 1351 verify(mVpnProfileStore).get(eq(vpn.getProfileNameForPackage(TEST_VPN_PKG))); 1352 verifyPlatformVpnIsActivated(TEST_VPN_PKG); 1353 } 1354 1355 @Test testStartVpnProfileVpnServicePreconsented()1356 public void testStartVpnProfileVpnServicePreconsented() throws Exception { 1357 final Vpn vpn = createVpn(AppOpsManager.OPSTR_ACTIVATE_VPN); 1358 1359 when(mVpnProfileStore.get(vpn.getProfileNameForPackage(TEST_VPN_PKG))) 1360 .thenReturn(mVpnProfile.encode()); 1361 1362 vpn.startVpnProfile(TEST_VPN_PKG); 1363 1364 // Verify that the ACTIVATE_VPN appop was checked, but no error was thrown. 1365 verify(mAppOps).noteOpNoThrow(AppOpsManager.OPSTR_ACTIVATE_VPN, Process.myUid(), 1366 TEST_VPN_PKG, null /* attributionTag */, null /* message */); 1367 } 1368 1369 @Test testStartVpnProfileNotConsented()1370 public void testStartVpnProfileNotConsented() throws Exception { 1371 final Vpn vpn = createVpn(); 1372 1373 try { 1374 vpn.startVpnProfile(TEST_VPN_PKG); 1375 fail("Expected failure due to no user consent"); 1376 } catch (SecurityException expected) { 1377 } 1378 1379 // Verify both appops were checked. 1380 verify(mAppOps) 1381 .noteOpNoThrow( 1382 eq(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN), 1383 eq(Process.myUid()), 1384 eq(TEST_VPN_PKG), 1385 eq(null) /* attributionTag */, 1386 eq(null) /* message */); 1387 verify(mAppOps).noteOpNoThrow(AppOpsManager.OPSTR_ACTIVATE_VPN, Process.myUid(), 1388 TEST_VPN_PKG, null /* attributionTag */, null /* message */); 1389 1390 // Keystore should never have been accessed. 1391 verify(mVpnProfileStore, never()).get(any()); 1392 } 1393 1394 @Test testStartVpnProfileMissingProfile()1395 public void testStartVpnProfileMissingProfile() throws Exception { 1396 final Vpn vpn = createVpn(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN); 1397 1398 when(mVpnProfileStore.get(vpn.getProfileNameForPackage(TEST_VPN_PKG))).thenReturn(null); 1399 1400 try { 1401 vpn.startVpnProfile(TEST_VPN_PKG); 1402 fail("Expected failure due to missing profile"); 1403 } catch (IllegalArgumentException expected) { 1404 } 1405 1406 verify(mVpnProfileStore).get(vpn.getProfileNameForPackage(TEST_VPN_PKG)); 1407 verify(mAppOps) 1408 .noteOpNoThrow( 1409 eq(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN), 1410 eq(Process.myUid()), 1411 eq(TEST_VPN_PKG), 1412 eq(null) /* attributionTag */, 1413 eq(null) /* message */); 1414 } 1415 1416 @Test testStartVpnProfileRestrictedUser()1417 public void testStartVpnProfileRestrictedUser() throws Exception { 1418 final Vpn vpn = createVpn(RESTRICTED_PROFILE_A, AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN); 1419 1420 try { 1421 vpn.startVpnProfile(TEST_VPN_PKG); 1422 fail("Expected SecurityException due to restricted user"); 1423 } catch (SecurityException expected) { 1424 } 1425 } 1426 1427 @Test testStopVpnProfileRestrictedUser()1428 public void testStopVpnProfileRestrictedUser() throws Exception { 1429 final Vpn vpn = createVpn(RESTRICTED_PROFILE_A, AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN); 1430 1431 try { 1432 vpn.stopVpnProfile(TEST_VPN_PKG); 1433 fail("Expected SecurityException due to restricted user"); 1434 } catch (SecurityException expected) { 1435 } 1436 } 1437 1438 @Test testStartOpAndFinishOpWillBeCalledWhenPlatformVpnIsOnAndOff()1439 public void testStartOpAndFinishOpWillBeCalledWhenPlatformVpnIsOnAndOff() throws Exception { 1440 final Vpn vpn = createVpn(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN); 1441 when(mVpnProfileStore.get(vpn.getProfileNameForPackage(TEST_VPN_PKG))) 1442 .thenReturn(mVpnProfile.encode()); 1443 vpn.startVpnProfile(TEST_VPN_PKG); 1444 verifyPlatformVpnIsActivated(TEST_VPN_PKG); 1445 // Add a small delay to make sure that startOp is only called once. 1446 verify(mAppOps, after(100).times(1)).startOp( 1447 eq(AppOpsManager.OPSTR_ESTABLISH_VPN_MANAGER), 1448 eq(UserHandle.getUid(PRIMARY_USER.id, Process.myUid())), 1449 eq(TEST_VPN_PKG), 1450 eq(null) /* attributionTag */, 1451 eq(null) /* message */); 1452 // Check that the startOp is not called with OPSTR_ESTABLISH_VPN_SERVICE. 1453 verify(mAppOps, never()).startOp( 1454 eq(AppOpsManager.OPSTR_ESTABLISH_VPN_SERVICE), 1455 eq(UserHandle.getUid(PRIMARY_USER.id, Process.myUid())), 1456 eq(TEST_VPN_PKG), 1457 eq(null) /* attributionTag */, 1458 eq(null) /* message */); 1459 vpn.stopVpnProfile(TEST_VPN_PKG); 1460 verifyPlatformVpnIsDeactivated(TEST_VPN_PKG); 1461 } 1462 1463 @Test testStartOpWithSeamlessHandover()1464 public void testStartOpWithSeamlessHandover() throws Exception { 1465 // Create with SYSTEM_USER so that establish() will match the user ID when checking 1466 // against Binder.getCallerUid 1467 final Vpn vpn = createVpn(SYSTEM_USER, AppOpsManager.OPSTR_ACTIVATE_VPN); 1468 assertTrue(vpn.prepare(TEST_VPN_PKG, null, VpnManager.TYPE_VPN_SERVICE)); 1469 final VpnConfig config = new VpnConfig(); 1470 config.user = "VpnTest"; 1471 config.addresses.add(new LinkAddress("192.0.2.2/32")); 1472 config.mtu = 1450; 1473 final ResolveInfo resolveInfo = new ResolveInfo(); 1474 final ServiceInfo serviceInfo = new ServiceInfo(); 1475 serviceInfo.permission = BIND_VPN_SERVICE; 1476 resolveInfo.serviceInfo = serviceInfo; 1477 when(mPackageManager.resolveService(any(), anyInt())).thenReturn(resolveInfo); 1478 when(mContext.bindServiceAsUser(any(), any(), anyInt(), any())).thenReturn(true); 1479 vpn.establish(config); 1480 verify(mAppOps, times(1)).startOp( 1481 eq(AppOpsManager.OPSTR_ESTABLISH_VPN_SERVICE), 1482 eq(Process.myUid()), 1483 eq(TEST_VPN_PKG), 1484 eq(null) /* attributionTag */, 1485 eq(null) /* message */); 1486 // Call establish() twice with the same config, it should match seamless handover case and 1487 // startOp() shouldn't be called again. 1488 vpn.establish(config); 1489 verify(mAppOps, times(1)).startOp( 1490 eq(AppOpsManager.OPSTR_ESTABLISH_VPN_SERVICE), 1491 eq(Process.myUid()), 1492 eq(TEST_VPN_PKG), 1493 eq(null) /* attributionTag */, 1494 eq(null) /* message */); 1495 } 1496 verifyVpnManagerEvent(String sessionKey, String category, int errorClass, int errorCode, String[] packageName, @NonNull VpnProfileState... profileState)1497 private void verifyVpnManagerEvent(String sessionKey, String category, int errorClass, 1498 int errorCode, String[] packageName, @NonNull VpnProfileState... profileState) { 1499 final Context userContext = 1500 mContext.createContextAsUser(UserHandle.of(PRIMARY_USER.id), 0 /* flags */); 1501 final ArgumentCaptor<Intent> intentArgumentCaptor = ArgumentCaptor.forClass(Intent.class); 1502 1503 final int verifyTimes = profileState.length; 1504 verify(userContext, timeout(TEST_TIMEOUT_MS).times(verifyTimes)) 1505 .startService(intentArgumentCaptor.capture()); 1506 1507 for (int i = 0; i < verifyTimes; i++) { 1508 final Intent intent = intentArgumentCaptor.getAllValues().get(i); 1509 assertEquals(packageName[i], intent.getPackage()); 1510 assertEquals(sessionKey, intent.getStringExtra(VpnManager.EXTRA_SESSION_KEY)); 1511 final Set<String> categories = intent.getCategories(); 1512 assertTrue(categories.contains(category)); 1513 assertEquals(1, categories.size()); 1514 assertEquals(errorClass, 1515 intent.getIntExtra(VpnManager.EXTRA_ERROR_CLASS, -1 /* defaultValue */)); 1516 assertEquals(errorCode, 1517 intent.getIntExtra(VpnManager.EXTRA_ERROR_CODE, -1 /* defaultValue */)); 1518 // CATEGORY_EVENT_DEACTIVATED_BY_USER & CATEGORY_EVENT_ALWAYS_ON_STATE_CHANGED won't 1519 // send NetworkCapabilities & LinkProperties to VPN app. 1520 // For ERROR_CODE_NETWORK_LOST, the NetworkCapabilities & LinkProperties of underlying 1521 // network will be cleared. So the VPN app will receive null for those 2 extra values. 1522 if (category.equals(VpnManager.CATEGORY_EVENT_DEACTIVATED_BY_USER) 1523 || category.equals(VpnManager.CATEGORY_EVENT_ALWAYS_ON_STATE_CHANGED) 1524 || errorCode == VpnManager.ERROR_CODE_NETWORK_LOST) { 1525 assertNull(intent.getParcelableExtra( 1526 VpnManager.EXTRA_UNDERLYING_NETWORK_CAPABILITIES)); 1527 assertNull(intent.getParcelableExtra(VpnManager.EXTRA_UNDERLYING_LINK_PROPERTIES)); 1528 } else { 1529 assertNotNull(intent.getParcelableExtra( 1530 VpnManager.EXTRA_UNDERLYING_NETWORK_CAPABILITIES)); 1531 assertNotNull(intent.getParcelableExtra( 1532 VpnManager.EXTRA_UNDERLYING_LINK_PROPERTIES)); 1533 } 1534 1535 assertEquals(profileState[i], intent.getParcelableExtra( 1536 VpnManager.EXTRA_VPN_PROFILE_STATE, VpnProfileState.class)); 1537 } 1538 reset(userContext); 1539 } 1540 verifyDeactivatedByUser(String sessionKey, String[] packageName)1541 private void verifyDeactivatedByUser(String sessionKey, String[] packageName) { 1542 // CATEGORY_EVENT_DEACTIVATED_BY_USER is not an error event, so both of errorClass and 1543 // errorCode won't be set. 1544 verifyVpnManagerEvent(sessionKey, VpnManager.CATEGORY_EVENT_DEACTIVATED_BY_USER, 1545 -1 /* errorClass */, -1 /* errorCode */, packageName, 1546 // VPN NetworkAgnet does not switch to CONNECTED in the test, and the state is not 1547 // important here. Verify that the state as it is, i.e. CONNECTING state. 1548 new VpnProfileState(VpnProfileState.STATE_CONNECTING, 1549 sessionKey, false /* alwaysOn */, false /* lockdown */)); 1550 } 1551 verifyAlwaysOnStateChanged(String[] packageName, VpnProfileState... profileState)1552 private void verifyAlwaysOnStateChanged(String[] packageName, VpnProfileState... profileState) { 1553 verifyVpnManagerEvent(null /* sessionKey */, 1554 VpnManager.CATEGORY_EVENT_ALWAYS_ON_STATE_CHANGED, -1 /* errorClass */, 1555 -1 /* errorCode */, packageName, profileState); 1556 } 1557 1558 @Test testVpnManagerEventForUserDeactivated()1559 public void testVpnManagerEventForUserDeactivated() throws Exception { 1560 // For security reasons, Vpn#prepare() will check that oldPackage and newPackage are either 1561 // null or the package of the caller. This test will call Vpn#prepare() to pretend the old 1562 // VPN is replaced by a new one. But only Settings can change to some other packages, and 1563 // this is checked with CONTROL_VPN so simulate holding CONTROL_VPN in order to pass the 1564 // security checks. 1565 doReturn(PERMISSION_GRANTED).when(mContext).checkCallingOrSelfPermission(CONTROL_VPN); 1566 final Vpn vpn = createVpn(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN); 1567 when(mVpnProfileStore.get(vpn.getProfileNameForPackage(TEST_VPN_PKG))) 1568 .thenReturn(mVpnProfile.encode()); 1569 1570 // Test the case that the user deactivates the vpn in vpn app. 1571 final String sessionKey1 = vpn.startVpnProfile(TEST_VPN_PKG); 1572 verifyPlatformVpnIsActivated(TEST_VPN_PKG); 1573 vpn.stopVpnProfile(TEST_VPN_PKG); 1574 verifyPlatformVpnIsDeactivated(TEST_VPN_PKG); 1575 verifyPowerSaveTempWhitelistApp(TEST_VPN_PKG); 1576 reset(mDeviceIdleInternal); 1577 verifyDeactivatedByUser(sessionKey1, new String[] {TEST_VPN_PKG}); 1578 reset(mAppOps); 1579 1580 // Test the case that the user chooses another vpn and the original one is replaced. 1581 final String sessionKey2 = vpn.startVpnProfile(TEST_VPN_PKG); 1582 verifyPlatformVpnIsActivated(TEST_VPN_PKG); 1583 vpn.prepare(TEST_VPN_PKG, "com.new.vpn" /* newPackage */, TYPE_VPN_PLATFORM); 1584 verifyPlatformVpnIsDeactivated(TEST_VPN_PKG); 1585 verifyPowerSaveTempWhitelistApp(TEST_VPN_PKG); 1586 reset(mDeviceIdleInternal); 1587 verifyDeactivatedByUser(sessionKey2, new String[] {TEST_VPN_PKG}); 1588 } 1589 1590 @Test testVpnManagerEventForAlwaysOnChanged()1591 public void testVpnManagerEventForAlwaysOnChanged() throws Exception { 1592 // Calling setAlwaysOnPackage() needs to hold CONTROL_VPN. 1593 doReturn(PERMISSION_GRANTED).when(mContext).checkCallingOrSelfPermission(CONTROL_VPN); 1594 final Vpn vpn = createVpn(PRIMARY_USER.id); 1595 // Enable VPN always-on for PKGS[1]. 1596 assertTrue(vpn.setAlwaysOnPackage(PKGS[1], false /* lockdown */, 1597 null /* lockdownAllowlist */)); 1598 verifyPowerSaveTempWhitelistApp(PKGS[1]); 1599 reset(mDeviceIdleInternal); 1600 verifyAlwaysOnStateChanged(new String[] {PKGS[1]}, 1601 new VpnProfileState(VpnProfileState.STATE_DISCONNECTED, 1602 null /* sessionKey */, true /* alwaysOn */, false /* lockdown */)); 1603 1604 // Enable VPN lockdown for PKGS[1]. 1605 assertTrue(vpn.setAlwaysOnPackage(PKGS[1], true /* lockdown */, 1606 null /* lockdownAllowlist */)); 1607 verifyPowerSaveTempWhitelistApp(PKGS[1]); 1608 reset(mDeviceIdleInternal); 1609 verifyAlwaysOnStateChanged(new String[] {PKGS[1]}, 1610 new VpnProfileState(VpnProfileState.STATE_DISCONNECTED, 1611 null /* sessionKey */, true /* alwaysOn */, true /* lockdown */)); 1612 1613 // Disable VPN lockdown for PKGS[1]. 1614 assertTrue(vpn.setAlwaysOnPackage(PKGS[1], false /* lockdown */, 1615 null /* lockdownAllowlist */)); 1616 verifyPowerSaveTempWhitelistApp(PKGS[1]); 1617 reset(mDeviceIdleInternal); 1618 verifyAlwaysOnStateChanged(new String[] {PKGS[1]}, 1619 new VpnProfileState(VpnProfileState.STATE_DISCONNECTED, 1620 null /* sessionKey */, true /* alwaysOn */, false /* lockdown */)); 1621 1622 // Disable VPN always-on. 1623 assertTrue(vpn.setAlwaysOnPackage(null, false /* lockdown */, 1624 null /* lockdownAllowlist */)); 1625 verifyPowerSaveTempWhitelistApp(PKGS[1]); 1626 reset(mDeviceIdleInternal); 1627 verifyAlwaysOnStateChanged(new String[] {PKGS[1]}, 1628 new VpnProfileState(VpnProfileState.STATE_DISCONNECTED, 1629 null /* sessionKey */, false /* alwaysOn */, false /* lockdown */)); 1630 1631 // Enable VPN always-on for PKGS[1] again. 1632 assertTrue(vpn.setAlwaysOnPackage(PKGS[1], false /* lockdown */, 1633 null /* lockdownAllowlist */)); 1634 verifyPowerSaveTempWhitelistApp(PKGS[1]); 1635 reset(mDeviceIdleInternal); 1636 verifyAlwaysOnStateChanged(new String[] {PKGS[1]}, 1637 new VpnProfileState(VpnProfileState.STATE_DISCONNECTED, 1638 null /* sessionKey */, true /* alwaysOn */, false /* lockdown */)); 1639 1640 // Enable VPN always-on for PKGS[2]. 1641 assertTrue(vpn.setAlwaysOnPackage(PKGS[2], false /* lockdown */, 1642 null /* lockdownAllowlist */)); 1643 verifyPowerSaveTempWhitelistApp(PKGS[2]); 1644 reset(mDeviceIdleInternal); 1645 // PKGS[1] is replaced with PKGS[2]. 1646 // Pass 2 VpnProfileState objects to verifyVpnManagerEvent(), the first one is sent to 1647 // PKGS[1] to notify PKGS[1] that the VPN always-on is disabled, the second one is sent to 1648 // PKGS[2] to notify PKGS[2] that the VPN always-on is enabled. 1649 verifyAlwaysOnStateChanged(new String[] {PKGS[1], PKGS[2]}, 1650 new VpnProfileState(VpnProfileState.STATE_DISCONNECTED, 1651 null /* sessionKey */, false /* alwaysOn */, false /* lockdown */), 1652 new VpnProfileState(VpnProfileState.STATE_DISCONNECTED, 1653 null /* sessionKey */, true /* alwaysOn */, false /* lockdown */)); 1654 } 1655 1656 @Test testReconnectVpnManagerVpnWithAlwaysOnEnabled()1657 public void testReconnectVpnManagerVpnWithAlwaysOnEnabled() throws Exception { 1658 final Vpn vpn = createVpn(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN); 1659 when(mVpnProfileStore.get(vpn.getProfileNameForPackage(TEST_VPN_PKG))) 1660 .thenReturn(mVpnProfile.encode()); 1661 vpn.startVpnProfile(TEST_VPN_PKG); 1662 verifyPlatformVpnIsActivated(TEST_VPN_PKG); 1663 1664 // Enable VPN always-on for TEST_VPN_PKG. 1665 assertTrue(vpn.setAlwaysOnPackage(TEST_VPN_PKG, false /* lockdown */, 1666 null /* lockdownAllowlist */)); 1667 1668 // Reset to verify next startVpnProfile. 1669 reset(mAppOps); 1670 1671 vpn.stopVpnProfile(TEST_VPN_PKG); 1672 1673 // Reconnect the vpn with different package will cause exception. 1674 assertThrows(SecurityException.class, () -> vpn.startVpnProfile(PKGS[0])); 1675 1676 // Reconnect the vpn again with the vpn always on package w/o exception. 1677 vpn.startVpnProfile(TEST_VPN_PKG); 1678 verifyPlatformVpnIsActivated(TEST_VPN_PKG); 1679 } 1680 1681 @Test testLockdown_enableDisableWhileConnected()1682 public void testLockdown_enableDisableWhileConnected() throws Exception { 1683 final PlatformVpnSnapshot vpnSnapShot = verifySetupPlatformVpn( 1684 createIkeConfig(createIkeConnectInfo(), true /* isMobikeEnabled */)); 1685 1686 final InOrder order = inOrder(mTestDeps); 1687 order.verify(mTestDeps, timeout(TIMEOUT_CROSSTHREAD_MS)) 1688 .newNetworkAgent(any(), any(), any(), any(), any(), any(), 1689 argThat(config -> config.allowBypass), any(), any()); 1690 1691 // Make VPN lockdown. 1692 assertTrue(vpnSnapShot.vpn.setAlwaysOnPackage(TEST_VPN_PKG, true /* lockdown */, 1693 null /* lockdownAllowlist */)); 1694 1695 order.verify(mTestDeps, timeout(TIMEOUT_CROSSTHREAD_MS)) 1696 .newNetworkAgent(any(), any(), any(), any(), any(), any(), 1697 argThat(config -> !config.allowBypass), any(), any()); 1698 1699 // Disable lockdown. 1700 assertTrue(vpnSnapShot.vpn.setAlwaysOnPackage(TEST_VPN_PKG, false /* lockdown */, 1701 null /* lockdownAllowlist */)); 1702 1703 order.verify(mTestDeps, timeout(TIMEOUT_CROSSTHREAD_MS)) 1704 .newNetworkAgent(any(), any(), any(), any(), any(), any(), 1705 argThat(config -> config.allowBypass), any(), any()); 1706 } 1707 1708 @Test testSetPackageAuthorizationVpnService()1709 public void testSetPackageAuthorizationVpnService() throws Exception { 1710 final Vpn vpn = createVpn(); 1711 1712 assertTrue(vpn.setPackageAuthorization(TEST_VPN_PKG, VpnManager.TYPE_VPN_SERVICE)); 1713 verify(mAppOps) 1714 .setMode( 1715 eq(AppOpsManager.OPSTR_ACTIVATE_VPN), 1716 eq(UserHandle.getUid(PRIMARY_USER.id, Process.myUid())), 1717 eq(TEST_VPN_PKG), 1718 eq(AppOpsManager.MODE_ALLOWED)); 1719 } 1720 1721 @Test testSetPackageAuthorizationPlatformVpn()1722 public void testSetPackageAuthorizationPlatformVpn() throws Exception { 1723 final Vpn vpn = createVpn(); 1724 1725 assertTrue(vpn.setPackageAuthorization(TEST_VPN_PKG, TYPE_VPN_PLATFORM)); 1726 verify(mAppOps) 1727 .setMode( 1728 eq(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN), 1729 eq(UserHandle.getUid(PRIMARY_USER.id, Process.myUid())), 1730 eq(TEST_VPN_PKG), 1731 eq(AppOpsManager.MODE_ALLOWED)); 1732 } 1733 1734 @Test testSetPackageAuthorizationRevokeAuthorization()1735 public void testSetPackageAuthorizationRevokeAuthorization() throws Exception { 1736 final Vpn vpn = createVpn(); 1737 1738 assertTrue(vpn.setPackageAuthorization(TEST_VPN_PKG, VpnManager.TYPE_VPN_NONE)); 1739 verify(mAppOps) 1740 .setMode( 1741 eq(AppOpsManager.OPSTR_ACTIVATE_VPN), 1742 eq(UserHandle.getUid(PRIMARY_USER.id, Process.myUid())), 1743 eq(TEST_VPN_PKG), 1744 eq(AppOpsManager.MODE_IGNORED)); 1745 verify(mAppOps) 1746 .setMode( 1747 eq(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN), 1748 eq(UserHandle.getUid(PRIMARY_USER.id, Process.myUid())), 1749 eq(TEST_VPN_PKG), 1750 eq(AppOpsManager.MODE_IGNORED)); 1751 } 1752 triggerOnAvailableAndGetCallback()1753 private NetworkCallback triggerOnAvailableAndGetCallback() throws Exception { 1754 return triggerOnAvailableAndGetCallback(new NetworkCapabilities.Builder().build()); 1755 } 1756 triggerOnAvailableAndGetCallback( @onNull final NetworkCapabilities caps)1757 private NetworkCallback triggerOnAvailableAndGetCallback( 1758 @NonNull final NetworkCapabilities caps) throws Exception { 1759 final ArgumentCaptor<NetworkCallback> networkCallbackCaptor = 1760 ArgumentCaptor.forClass(NetworkCallback.class); 1761 verify(mConnectivityManager, timeout(TEST_TIMEOUT_MS)) 1762 .registerSystemDefaultNetworkCallback(networkCallbackCaptor.capture(), any()); 1763 1764 // onAvailable() will trigger onDefaultNetworkChanged(), so NetdUtils#setInterfaceUp will be 1765 // invoked. Set the return value of INetd#interfaceGetCfg to prevent NullPointerException. 1766 final InterfaceConfigurationParcel config = new InterfaceConfigurationParcel(); 1767 config.flags = new String[] {IF_STATE_DOWN}; 1768 when(mNetd.interfaceGetCfg(anyString())).thenReturn(config); 1769 final NetworkCallback cb = networkCallbackCaptor.getValue(); 1770 cb.onAvailable(TEST_NETWORK); 1771 // Trigger onCapabilitiesChanged() and onLinkPropertiesChanged() so the test can verify that 1772 // if NetworkCapabilities and LinkProperties of underlying network will be sent/cleared or 1773 // not. 1774 // See verifyVpnManagerEvent(). 1775 cb.onCapabilitiesChanged(TEST_NETWORK, caps); 1776 cb.onLinkPropertiesChanged(TEST_NETWORK, new LinkProperties()); 1777 return cb; 1778 } 1779 verifyInterfaceSetCfgWithFlags(String flag)1780 private void verifyInterfaceSetCfgWithFlags(String flag) throws Exception { 1781 // Add a timeout for waiting for interfaceSetCfg to be called. 1782 verify(mNetd, timeout(TEST_TIMEOUT_MS)).interfaceSetCfg(argThat( 1783 config -> Arrays.asList(config.flags).contains(flag))); 1784 } 1785 doTestPlatformVpnWithException(IkeException exception, String category, int errorType, int errorCode)1786 private void doTestPlatformVpnWithException(IkeException exception, 1787 String category, int errorType, int errorCode) throws Exception { 1788 final ArgumentCaptor<IkeSessionCallback> captor = 1789 ArgumentCaptor.forClass(IkeSessionCallback.class); 1790 1791 final Vpn vpn = createVpn(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN); 1792 when(mVpnProfileStore.get(vpn.getProfileNameForPackage(TEST_VPN_PKG))) 1793 .thenReturn(mVpnProfile.encode()); 1794 1795 doReturn(new NetworkCapabilities()).when(mConnectivityManager) 1796 .getRedactedNetworkCapabilitiesForPackage(any(), anyInt(), anyString()); 1797 doReturn(new LinkProperties()).when(mConnectivityManager) 1798 .getRedactedLinkPropertiesForPackage(any(), anyInt(), anyString()); 1799 1800 final String sessionKey = vpn.startVpnProfile(TEST_VPN_PKG); 1801 final Set<Range<Integer>> uidRanges = rangeSet(PRIMARY_USER_RANGE); 1802 // This is triggered by Ikev2VpnRunner constructor. 1803 verify(mConnectivityManager, times(1)).setVpnDefaultForUids(eq(sessionKey), eq(uidRanges)); 1804 final NetworkCallback cb = triggerOnAvailableAndGetCallback(); 1805 1806 verifyInterfaceSetCfgWithFlags(IF_STATE_UP); 1807 1808 // Wait for createIkeSession() to be called before proceeding in order to ensure consistent 1809 // state 1810 verify(mIkev2SessionCreator, timeout(TEST_TIMEOUT_MS)) 1811 .createIkeSession(any(), any(), any(), any(), captor.capture(), any()); 1812 // This is triggered by Vpn#startOrMigrateIkeSession(). 1813 verify(mConnectivityManager, times(2)).setVpnDefaultForUids(eq(sessionKey), eq(uidRanges)); 1814 reset(mIkev2SessionCreator); 1815 // For network lost case, the process should be triggered by calling onLost(), which is the 1816 // same process with the real case. 1817 if (errorCode == VpnManager.ERROR_CODE_NETWORK_LOST) { 1818 cb.onLost(TEST_NETWORK); 1819 verify(mExecutor, atLeastOnce()).schedule(any(Runnable.class), anyLong(), any()); 1820 } else { 1821 final IkeSessionCallback ikeCb = captor.getValue(); 1822 mExecutor.execute(() -> ikeCb.onClosedWithException(exception)); 1823 } 1824 1825 verifyPowerSaveTempWhitelistApp(TEST_VPN_PKG); 1826 reset(mDeviceIdleInternal); 1827 verifyVpnManagerEvent(sessionKey, category, errorType, errorCode, 1828 // VPN NetworkAgnet does not switch to CONNECTED in the test, and the state is not 1829 // important here. Verify that the state as it is, i.e. CONNECTING state. 1830 new String[] {TEST_VPN_PKG}, new VpnProfileState(VpnProfileState.STATE_CONNECTING, 1831 sessionKey, false /* alwaysOn */, false /* lockdown */)); 1832 if (errorType == VpnManager.ERROR_CLASS_NOT_RECOVERABLE) { 1833 verify(mConnectivityManager).setVpnDefaultForUids(eq(sessionKey), 1834 eq(Collections.EMPTY_LIST)); 1835 verify(mConnectivityManager, timeout(TEST_TIMEOUT_MS)) 1836 .unregisterNetworkCallback(eq(cb)); 1837 } else if (errorType == VpnManager.ERROR_CLASS_RECOVERABLE 1838 // Vpn won't retry when there is no usable underlying network. 1839 && errorCode != VpnManager.ERROR_CODE_NETWORK_LOST) { 1840 int retryIndex = 0; 1841 // First failure occurred above. 1842 final IkeSessionCallback retryCb = verifyRetryAndGetNewIkeCb(retryIndex++); 1843 // Trigger 2 more failures to let the retry delay increase to 5s. 1844 mExecutor.execute(() -> retryCb.onClosedWithException(exception)); 1845 final IkeSessionCallback retryCb2 = verifyRetryAndGetNewIkeCb(retryIndex++); 1846 mExecutor.execute(() -> retryCb2.onClosedWithException(exception)); 1847 final IkeSessionCallback retryCb3 = verifyRetryAndGetNewIkeCb(retryIndex++); 1848 1849 // setVpnDefaultForUids may be called again but the uidRanges should not change. 1850 verify(mConnectivityManager, atLeast(2)).setVpnDefaultForUids(eq(sessionKey), 1851 mUidRangesCaptor.capture()); 1852 final List<Collection<Range<Integer>>> capturedUidRanges = 1853 mUidRangesCaptor.getAllValues(); 1854 for (int i = 2; i < capturedUidRanges.size(); i++) { 1855 // Assert equals no order. 1856 assertTrue( 1857 "uid ranges should not be modified. Expected: " + uidRanges 1858 + ", actual: " + capturedUidRanges.get(i), 1859 capturedUidRanges.get(i).containsAll(uidRanges) 1860 && capturedUidRanges.get(i).size() == uidRanges.size()); 1861 } 1862 1863 // A fourth failure will cause the retry delay to be greater than 5s. 1864 mExecutor.execute(() -> retryCb3.onClosedWithException(exception)); 1865 verifyRetryAndGetNewIkeCb(retryIndex++); 1866 1867 // The VPN network preference will be cleared when the retry delay is greater than 5s. 1868 verify(mConnectivityManager).setVpnDefaultForUids(eq(sessionKey), 1869 eq(Collections.EMPTY_LIST)); 1870 } 1871 } 1872 verifyRetryAndGetNewIkeCb(int retryIndex)1873 private IkeSessionCallback verifyRetryAndGetNewIkeCb(int retryIndex) { 1874 final ArgumentCaptor<IkeSessionCallback> ikeCbCaptor = 1875 ArgumentCaptor.forClass(IkeSessionCallback.class); 1876 1877 // Verify retry is scheduled 1878 final long expectedDelayMs = mTestDeps.getNextRetryDelayMs(retryIndex); 1879 verify(mExecutor, timeout(TEST_TIMEOUT_MS)).schedule(any(Runnable.class), 1880 eq(expectedDelayMs), eq(TimeUnit.MILLISECONDS)); 1881 1882 verify(mIkev2SessionCreator, timeout(TEST_TIMEOUT_MS + expectedDelayMs)) 1883 .createIkeSession(any(), any(), any(), any(), ikeCbCaptor.capture(), any()); 1884 1885 // Forget the mIkev2SessionCreator#createIkeSession call and mExecutor#schedule call 1886 // for the next retry verification 1887 resetIkev2SessionCreator(mIkeSessionWrapper); 1888 1889 return ikeCbCaptor.getValue(); 1890 } 1891 1892 @Test testStartPlatformVpnAuthenticationFailed()1893 public void testStartPlatformVpnAuthenticationFailed() throws Exception { 1894 final IkeProtocolException exception = mock(IkeProtocolException.class); 1895 final int errorCode = IkeProtocolException.ERROR_TYPE_AUTHENTICATION_FAILED; 1896 when(exception.getErrorType()).thenReturn(errorCode); 1897 doTestPlatformVpnWithException(exception, 1898 VpnManager.CATEGORY_EVENT_IKE_ERROR, VpnManager.ERROR_CLASS_NOT_RECOVERABLE, 1899 errorCode); 1900 } 1901 1902 @Test testStartPlatformVpnFailedWithRecoverableError()1903 public void testStartPlatformVpnFailedWithRecoverableError() throws Exception { 1904 final IkeProtocolException exception = mock(IkeProtocolException.class); 1905 final int errorCode = IkeProtocolException.ERROR_TYPE_TEMPORARY_FAILURE; 1906 when(exception.getErrorType()).thenReturn(errorCode); 1907 doTestPlatformVpnWithException(exception, 1908 VpnManager.CATEGORY_EVENT_IKE_ERROR, VpnManager.ERROR_CLASS_RECOVERABLE, errorCode); 1909 } 1910 1911 @Test testStartPlatformVpnFailedWithUnknownHostException()1912 public void testStartPlatformVpnFailedWithUnknownHostException() throws Exception { 1913 final IkeNonProtocolException exception = mock(IkeNonProtocolException.class); 1914 final UnknownHostException unknownHostException = new UnknownHostException(); 1915 final int errorCode = VpnManager.ERROR_CODE_NETWORK_UNKNOWN_HOST; 1916 when(exception.getCause()).thenReturn(unknownHostException); 1917 doTestPlatformVpnWithException(exception, 1918 VpnManager.CATEGORY_EVENT_NETWORK_ERROR, VpnManager.ERROR_CLASS_RECOVERABLE, 1919 errorCode); 1920 } 1921 1922 @Test testStartPlatformVpnFailedWithIkeTimeoutException()1923 public void testStartPlatformVpnFailedWithIkeTimeoutException() throws Exception { 1924 final IkeNonProtocolException exception = mock(IkeNonProtocolException.class); 1925 final IkeTimeoutException ikeTimeoutException = 1926 new IkeTimeoutException("IkeTimeoutException"); 1927 final int errorCode = VpnManager.ERROR_CODE_NETWORK_PROTOCOL_TIMEOUT; 1928 when(exception.getCause()).thenReturn(ikeTimeoutException); 1929 doTestPlatformVpnWithException(exception, 1930 VpnManager.CATEGORY_EVENT_NETWORK_ERROR, VpnManager.ERROR_CLASS_RECOVERABLE, 1931 errorCode); 1932 } 1933 1934 @Test testStartPlatformVpnFailedWithIkeNetworkLostException()1935 public void testStartPlatformVpnFailedWithIkeNetworkLostException() throws Exception { 1936 final IkeNetworkLostException exception = new IkeNetworkLostException( 1937 new Network(100)); 1938 doTestPlatformVpnWithException(exception, 1939 VpnManager.CATEGORY_EVENT_NETWORK_ERROR, VpnManager.ERROR_CLASS_RECOVERABLE, 1940 VpnManager.ERROR_CODE_NETWORK_LOST); 1941 } 1942 1943 @Test testStartPlatformVpnFailedWithIOException()1944 public void testStartPlatformVpnFailedWithIOException() throws Exception { 1945 final IkeNonProtocolException exception = mock(IkeNonProtocolException.class); 1946 final IOException ioException = new IOException(); 1947 final int errorCode = VpnManager.ERROR_CODE_NETWORK_IO; 1948 when(exception.getCause()).thenReturn(ioException); 1949 doTestPlatformVpnWithException(exception, 1950 VpnManager.CATEGORY_EVENT_NETWORK_ERROR, VpnManager.ERROR_CLASS_RECOVERABLE, 1951 errorCode); 1952 } 1953 1954 @Test testStartPlatformVpnIllegalArgumentExceptionInSetup()1955 public void testStartPlatformVpnIllegalArgumentExceptionInSetup() throws Exception { 1956 when(mIkev2SessionCreator.createIkeSession(any(), any(), any(), any(), any(), any())) 1957 .thenThrow(new IllegalArgumentException()); 1958 final Vpn vpn = startLegacyVpn(createVpn(PRIMARY_USER.id), mVpnProfile); 1959 final NetworkCallback cb = triggerOnAvailableAndGetCallback(); 1960 1961 verifyInterfaceSetCfgWithFlags(IF_STATE_UP); 1962 1963 // Wait for createIkeSession() to be called before proceeding in order to ensure consistent 1964 // state 1965 verify(mConnectivityManager, timeout(TEST_TIMEOUT_MS)).unregisterNetworkCallback(eq(cb)); 1966 assertEquals(LegacyVpnInfo.STATE_FAILED, vpn.getLegacyVpnInfo().state); 1967 } 1968 1969 @Test testVpnManagerEventWillNotBeSentToSettingsVpn()1970 public void testVpnManagerEventWillNotBeSentToSettingsVpn() throws Exception { 1971 startLegacyVpn(createVpn(PRIMARY_USER.id), mVpnProfile); 1972 triggerOnAvailableAndGetCallback(); 1973 1974 verifyInterfaceSetCfgWithFlags(IF_STATE_UP); 1975 1976 final IkeNonProtocolException exception = mock(IkeNonProtocolException.class); 1977 final IkeTimeoutException ikeTimeoutException = 1978 new IkeTimeoutException("IkeTimeoutException"); 1979 when(exception.getCause()).thenReturn(ikeTimeoutException); 1980 1981 final ArgumentCaptor<IkeSessionCallback> captor = 1982 ArgumentCaptor.forClass(IkeSessionCallback.class); 1983 verify(mIkev2SessionCreator, timeout(TEST_TIMEOUT_MS)) 1984 .createIkeSession(any(), any(), any(), any(), captor.capture(), any()); 1985 final IkeSessionCallback ikeCb = captor.getValue(); 1986 ikeCb.onClosedWithException(exception); 1987 1988 final Context userContext = 1989 mContext.createContextAsUser(UserHandle.of(PRIMARY_USER.id), 0 /* flags */); 1990 verify(userContext, never()).startService(any()); 1991 } 1992 setAndVerifyAlwaysOnPackage(Vpn vpn, int uid, boolean lockdownEnabled)1993 private void setAndVerifyAlwaysOnPackage(Vpn vpn, int uid, boolean lockdownEnabled) { 1994 assertTrue(vpn.setAlwaysOnPackage(TEST_VPN_PKG, lockdownEnabled, null)); 1995 1996 verify(mVpnProfileStore).get(eq(vpn.getProfileNameForPackage(TEST_VPN_PKG))); 1997 verify(mAppOps).setMode( 1998 eq(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN), eq(uid), eq(TEST_VPN_PKG), 1999 eq(AppOpsManager.MODE_ALLOWED)); 2000 2001 verify(mSystemServices).settingsSecurePutStringForUser( 2002 eq(Settings.Secure.ALWAYS_ON_VPN_APP), eq(TEST_VPN_PKG), eq(PRIMARY_USER.id)); 2003 verify(mSystemServices).settingsSecurePutIntForUser( 2004 eq(Settings.Secure.ALWAYS_ON_VPN_LOCKDOWN), eq(lockdownEnabled ? 1 : 0), 2005 eq(PRIMARY_USER.id)); 2006 verify(mSystemServices).settingsSecurePutStringForUser( 2007 eq(Settings.Secure.ALWAYS_ON_VPN_LOCKDOWN_WHITELIST), eq(""), eq(PRIMARY_USER.id)); 2008 } 2009 2010 @Test testSetAndStartAlwaysOnVpn()2011 public void testSetAndStartAlwaysOnVpn() throws Exception { 2012 final Vpn vpn = createVpn(PRIMARY_USER.id); 2013 setMockedUsers(PRIMARY_USER); 2014 2015 // UID checks must return a different UID; otherwise it'll be treated as already prepared. 2016 final int uid = Process.myUid() + 1; 2017 when(mPackageManager.getPackageUidAsUser(eq(TEST_VPN_PKG), anyInt())) 2018 .thenReturn(uid); 2019 when(mVpnProfileStore.get(vpn.getProfileNameForPackage(TEST_VPN_PKG))) 2020 .thenReturn(mVpnProfile.encode()); 2021 2022 setAndVerifyAlwaysOnPackage(vpn, uid, false); 2023 assertTrue(vpn.startAlwaysOnVpn()); 2024 2025 // TODO: Test the Ikev2VpnRunner started up properly. Relies on utility methods added in 2026 // a subsequent CL. 2027 } 2028 startLegacyVpn(final Vpn vpn, final VpnProfile vpnProfile)2029 private Vpn startLegacyVpn(final Vpn vpn, final VpnProfile vpnProfile) throws Exception { 2030 setMockedUsers(PRIMARY_USER); 2031 vpn.startLegacyVpn(vpnProfile); 2032 return vpn; 2033 } 2034 createIkeConnectInfo()2035 private IkeSessionConnectionInfo createIkeConnectInfo() { 2036 return new IkeSessionConnectionInfo(TEST_VPN_CLIENT_IP, TEST_VPN_SERVER_IP, TEST_NETWORK); 2037 } 2038 createIkeConnectInfo_2()2039 private IkeSessionConnectionInfo createIkeConnectInfo_2() { 2040 return new IkeSessionConnectionInfo( 2041 TEST_VPN_CLIENT_IP_2, TEST_VPN_SERVER_IP_2, TEST_NETWORK_2); 2042 } 2043 createIkeConfig( IkeSessionConnectionInfo ikeConnectInfo, boolean isMobikeEnabled)2044 private IkeSessionConfiguration createIkeConfig( 2045 IkeSessionConnectionInfo ikeConnectInfo, boolean isMobikeEnabled) { 2046 final IkeSessionConfiguration.Builder builder = 2047 new IkeSessionConfiguration.Builder(ikeConnectInfo); 2048 2049 if (isMobikeEnabled) { 2050 builder.addIkeExtension(EXTENSION_TYPE_MOBIKE); 2051 } 2052 2053 return builder.build(); 2054 } 2055 createChildConfig()2056 private ChildSessionConfiguration createChildConfig() { 2057 return new ChildSessionConfiguration.Builder( 2058 Arrays.asList(IN_TS, IN_TS6), Arrays.asList(OUT_TS, OUT_TS6)) 2059 .addInternalAddress(new LinkAddress(TEST_VPN_INTERNAL_IP, IP4_PREFIX_LEN)) 2060 .addInternalAddress(new LinkAddress(TEST_VPN_INTERNAL_IP6, IP6_PREFIX_LEN)) 2061 .addInternalDnsServer(TEST_VPN_INTERNAL_DNS) 2062 .addInternalDnsServer(TEST_VPN_INTERNAL_DNS6) 2063 .build(); 2064 } 2065 createIpSecTransform()2066 private IpSecTransform createIpSecTransform() { 2067 return new IpSecTransform(mContext, new IpSecConfig()); 2068 } 2069 verifyApplyTunnelModeTransforms(int expectedTimes)2070 private void verifyApplyTunnelModeTransforms(int expectedTimes) throws Exception { 2071 verify(mIpSecService, times(expectedTimes)).applyTunnelModeTransform( 2072 eq(TEST_TUNNEL_RESOURCE_ID), eq(IpSecManager.DIRECTION_IN), 2073 anyInt(), anyString()); 2074 verify(mIpSecService, times(expectedTimes)).applyTunnelModeTransform( 2075 eq(TEST_TUNNEL_RESOURCE_ID), eq(IpSecManager.DIRECTION_OUT), 2076 anyInt(), anyString()); 2077 } 2078 verifyCreateIkeAndCaptureCbs()2079 private Pair<IkeSessionCallback, ChildSessionCallback> verifyCreateIkeAndCaptureCbs() 2080 throws Exception { 2081 final ArgumentCaptor<IkeSessionCallback> ikeCbCaptor = 2082 ArgumentCaptor.forClass(IkeSessionCallback.class); 2083 final ArgumentCaptor<ChildSessionCallback> childCbCaptor = 2084 ArgumentCaptor.forClass(ChildSessionCallback.class); 2085 2086 verify(mIkev2SessionCreator, timeout(TEST_TIMEOUT_MS)).createIkeSession( 2087 any(), any(), any(), any(), ikeCbCaptor.capture(), childCbCaptor.capture()); 2088 2089 return new Pair<>(ikeCbCaptor.getValue(), childCbCaptor.getValue()); 2090 } 2091 2092 private static class PlatformVpnSnapshot { 2093 public final Vpn vpn; 2094 public final NetworkCallback nwCb; 2095 public final IkeSessionCallback ikeCb; 2096 public final ChildSessionCallback childCb; 2097 PlatformVpnSnapshot(Vpn vpn, NetworkCallback nwCb, IkeSessionCallback ikeCb, ChildSessionCallback childCb)2098 PlatformVpnSnapshot(Vpn vpn, NetworkCallback nwCb, 2099 IkeSessionCallback ikeCb, ChildSessionCallback childCb) { 2100 this.vpn = vpn; 2101 this.nwCb = nwCb; 2102 this.ikeCb = ikeCb; 2103 this.childCb = childCb; 2104 } 2105 } 2106 verifySetupPlatformVpn(IkeSessionConfiguration ikeConfig)2107 private PlatformVpnSnapshot verifySetupPlatformVpn(IkeSessionConfiguration ikeConfig) 2108 throws Exception { 2109 return verifySetupPlatformVpn(ikeConfig, true); 2110 } 2111 verifySetupPlatformVpn( IkeSessionConfiguration ikeConfig, boolean mtuSupportsIpv6)2112 private PlatformVpnSnapshot verifySetupPlatformVpn( 2113 IkeSessionConfiguration ikeConfig, boolean mtuSupportsIpv6) throws Exception { 2114 return verifySetupPlatformVpn(mVpnProfile, ikeConfig, mtuSupportsIpv6); 2115 } 2116 verifySetupPlatformVpn(VpnProfile vpnProfile, IkeSessionConfiguration ikeConfig, boolean mtuSupportsIpv6)2117 private PlatformVpnSnapshot verifySetupPlatformVpn(VpnProfile vpnProfile, 2118 IkeSessionConfiguration ikeConfig, boolean mtuSupportsIpv6) throws Exception { 2119 return verifySetupPlatformVpn(vpnProfile, ikeConfig, 2120 new NetworkCapabilities.Builder().build() /* underlying network caps */, 2121 mtuSupportsIpv6, false /* areLongLivedTcpConnectionsExpensive */); 2122 } 2123 verifySetupPlatformVpn(VpnProfile vpnProfile, IkeSessionConfiguration ikeConfig, @NonNull final NetworkCapabilities underlyingNetworkCaps, boolean mtuSupportsIpv6, boolean areLongLivedTcpConnectionsExpensive)2124 private PlatformVpnSnapshot verifySetupPlatformVpn(VpnProfile vpnProfile, 2125 IkeSessionConfiguration ikeConfig, 2126 @NonNull final NetworkCapabilities underlyingNetworkCaps, 2127 boolean mtuSupportsIpv6, 2128 boolean areLongLivedTcpConnectionsExpensive) throws Exception { 2129 if (!mtuSupportsIpv6) { 2130 doReturn(IPV6_MIN_MTU - 1).when(mTestDeps).calculateVpnMtu(any(), anyInt(), anyInt(), 2131 anyBoolean()); 2132 } 2133 2134 doReturn(mMockNetworkAgent).when(mTestDeps) 2135 .newNetworkAgent( 2136 any(), any(), anyString(), any(), any(), any(), any(), any(), any()); 2137 doReturn(TEST_NETWORK).when(mMockNetworkAgent).getNetwork(); 2138 2139 final Vpn vpn = createVpn(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN); 2140 when(mVpnProfileStore.get(vpn.getProfileNameForPackage(TEST_VPN_PKG))) 2141 .thenReturn(vpnProfile.encode()); 2142 2143 final String sessionKey = vpn.startVpnProfile(TEST_VPN_PKG); 2144 final Set<Range<Integer>> uidRanges = Collections.singleton(PRIMARY_USER_RANGE); 2145 verify(mConnectivityManager).setVpnDefaultForUids(eq(sessionKey), eq(uidRanges)); 2146 final NetworkCallback nwCb = triggerOnAvailableAndGetCallback(underlyingNetworkCaps); 2147 // There are 4 interactions with the executor. 2148 // - Network available 2149 // - LP change 2150 // - NC change 2151 // - schedule() calls in scheduleStartIkeSession() 2152 // The first 3 calls are triggered from Executor.execute(). The execute() will also call to 2153 // schedule() with 0 delay. Verify the exact interaction here so that it won't cause flakes 2154 // in the follow-up flow. 2155 verify(mExecutor, timeout(TEST_TIMEOUT_MS).times(4)) 2156 .schedule(any(Runnable.class), anyLong(), any()); 2157 reset(mExecutor); 2158 2159 // Mock the setup procedure by firing callbacks 2160 final Pair<IkeSessionCallback, ChildSessionCallback> cbPair = 2161 verifyCreateIkeAndCaptureCbs(); 2162 final IkeSessionCallback ikeCb = cbPair.first; 2163 final ChildSessionCallback childCb = cbPair.second; 2164 2165 ikeCb.onOpened(ikeConfig); 2166 childCb.onIpSecTransformCreated(createIpSecTransform(), IpSecManager.DIRECTION_IN); 2167 childCb.onIpSecTransformCreated(createIpSecTransform(), IpSecManager.DIRECTION_OUT); 2168 childCb.onOpened(createChildConfig()); 2169 2170 // Verification VPN setup 2171 verifyApplyTunnelModeTransforms(1); 2172 2173 ArgumentCaptor<LinkProperties> lpCaptor = ArgumentCaptor.forClass(LinkProperties.class); 2174 ArgumentCaptor<NetworkCapabilities> ncCaptor = 2175 ArgumentCaptor.forClass(NetworkCapabilities.class); 2176 ArgumentCaptor<NetworkAgentConfig> nacCaptor = 2177 ArgumentCaptor.forClass(NetworkAgentConfig.class); 2178 verify(mTestDeps).newNetworkAgent( 2179 any(), any(), anyString(), ncCaptor.capture(), lpCaptor.capture(), 2180 any(), nacCaptor.capture(), any(), any()); 2181 verify(mIkeSessionWrapper).setUnderpinnedNetwork(TEST_NETWORK); 2182 // Check LinkProperties 2183 final LinkProperties lp = lpCaptor.getValue(); 2184 final List<RouteInfo> expectedRoutes = 2185 new ArrayList<>( 2186 Arrays.asList( 2187 new RouteInfo( 2188 new IpPrefix(Inet4Address.ANY, 0), 2189 null /* gateway */, 2190 TEST_IFACE_NAME, 2191 RouteInfo.RTN_UNICAST))); 2192 final List<LinkAddress> expectedAddresses = 2193 new ArrayList<>( 2194 Arrays.asList(new LinkAddress(TEST_VPN_INTERNAL_IP, IP4_PREFIX_LEN))); 2195 final List<InetAddress> expectedDns = new ArrayList<>(Arrays.asList(TEST_VPN_INTERNAL_DNS)); 2196 2197 if (mtuSupportsIpv6) { 2198 expectedRoutes.add( 2199 new RouteInfo( 2200 new IpPrefix(Inet6Address.ANY, 0), 2201 null /* gateway */, 2202 TEST_IFACE_NAME, 2203 RouteInfo.RTN_UNICAST)); 2204 expectedAddresses.add(new LinkAddress(TEST_VPN_INTERNAL_IP6, IP6_PREFIX_LEN)); 2205 expectedDns.add(TEST_VPN_INTERNAL_DNS6); 2206 } else { 2207 expectedRoutes.add( 2208 new RouteInfo( 2209 new IpPrefix(Inet6Address.ANY, 0), 2210 null /* gateway */, 2211 TEST_IFACE_NAME, 2212 RTN_UNREACHABLE)); 2213 } 2214 2215 assertEquals(expectedRoutes, lp.getRoutes()); 2216 assertEquals(expectedAddresses, lp.getLinkAddresses()); 2217 assertEquals(expectedDns, lp.getDnsServers()); 2218 2219 // Check NetworkCapabilities 2220 assertEquals(Arrays.asList(TEST_NETWORK), ncCaptor.getValue().getUnderlyingNetworks()); 2221 2222 // Check if allowBypass is set or not. 2223 assertTrue(nacCaptor.getValue().isBypassableVpn()); 2224 // Check if extra info for VPN is set. 2225 assertTrue(nacCaptor.getValue().getLegacyExtraInfo().contains(TEST_VPN_PKG)); 2226 final VpnTransportInfo info = (VpnTransportInfo) ncCaptor.getValue().getTransportInfo(); 2227 assertTrue(info.isBypassable()); 2228 assertEquals(areLongLivedTcpConnectionsExpensive, 2229 info.areLongLivedTcpConnectionsExpensive()); 2230 return new PlatformVpnSnapshot(vpn, nwCb, ikeCb, childCb); 2231 } 2232 2233 @Test testStartPlatformVpn()2234 public void testStartPlatformVpn() throws Exception { 2235 final PlatformVpnSnapshot vpnSnapShot = verifySetupPlatformVpn( 2236 createIkeConfig(createIkeConnectInfo(), true /* isMobikeEnabled */)); 2237 vpnSnapShot.vpn.mVpnRunner.exitVpnRunner(); 2238 verify(mConnectivityManager).setVpnDefaultForUids(anyString(), eq(Collections.EMPTY_LIST)); 2239 } 2240 2241 @Test testMigrateIkeSession_FromIkeTunnConnParams_AutoTimerNoTimer()2242 public void testMigrateIkeSession_FromIkeTunnConnParams_AutoTimerNoTimer() throws Exception { 2243 doTestMigrateIkeSession_FromIkeTunnConnParams( 2244 false /* isAutomaticIpVersionSelectionEnabled */, 2245 true /* isAutomaticNattKeepaliveTimerEnabled */, 2246 TEST_KEEPALIVE_TIMEOUT_UNSET /* keepaliveInProfile */, 2247 ESP_IP_VERSION_AUTO /* ipVersionInProfile */, 2248 ESP_ENCAP_TYPE_AUTO /* encapTypeInProfile */); 2249 } 2250 2251 @Test testMigrateIkeSession_FromIkeTunnConnParams_AutoTimerTimerSet()2252 public void testMigrateIkeSession_FromIkeTunnConnParams_AutoTimerTimerSet() throws Exception { 2253 doTestMigrateIkeSession_FromIkeTunnConnParams( 2254 false /* isAutomaticIpVersionSelectionEnabled */, 2255 true /* isAutomaticNattKeepaliveTimerEnabled */, 2256 TEST_KEEPALIVE_TIMER /* keepaliveInProfile */, 2257 ESP_IP_VERSION_AUTO /* ipVersionInProfile */, 2258 ESP_ENCAP_TYPE_AUTO /* encapTypeInProfile */); 2259 } 2260 2261 @Test testMigrateIkeSession_FromIkeTunnConnParams_AutoIp()2262 public void testMigrateIkeSession_FromIkeTunnConnParams_AutoIp() throws Exception { 2263 doTestMigrateIkeSession_FromIkeTunnConnParams( 2264 true /* isAutomaticIpVersionSelectionEnabled */, 2265 false /* isAutomaticNattKeepaliveTimerEnabled */, 2266 TEST_KEEPALIVE_TIMEOUT_UNSET /* keepaliveInProfile */, 2267 ESP_IP_VERSION_AUTO /* ipVersionInProfile */, 2268 ESP_ENCAP_TYPE_AUTO /* encapTypeInProfile */); 2269 } 2270 2271 @Test testMigrateIkeSession_FromIkeTunnConnParams_AssignedIpProtocol()2272 public void testMigrateIkeSession_FromIkeTunnConnParams_AssignedIpProtocol() throws Exception { 2273 doTestMigrateIkeSession_FromIkeTunnConnParams( 2274 false /* isAutomaticIpVersionSelectionEnabled */, 2275 false /* isAutomaticNattKeepaliveTimerEnabled */, 2276 TEST_KEEPALIVE_TIMEOUT_UNSET /* keepaliveInProfile */, 2277 ESP_IP_VERSION_IPV4 /* ipVersionInProfile */, 2278 ESP_ENCAP_TYPE_UDP /* encapTypeInProfile */); 2279 } 2280 2281 @Test testMigrateIkeSession_FromNotIkeTunnConnParams_AutoTimer()2282 public void testMigrateIkeSession_FromNotIkeTunnConnParams_AutoTimer() throws Exception { 2283 doTestMigrateIkeSession_FromNotIkeTunnConnParams( 2284 false /* isAutomaticIpVersionSelectionEnabled */, 2285 true /* isAutomaticNattKeepaliveTimerEnabled */); 2286 } 2287 2288 @Test testMigrateIkeSession_FromNotIkeTunnConnParams_AutoIp()2289 public void testMigrateIkeSession_FromNotIkeTunnConnParams_AutoIp() throws Exception { 2290 doTestMigrateIkeSession_FromNotIkeTunnConnParams( 2291 true /* isAutomaticIpVersionSelectionEnabled */, 2292 false /* isAutomaticNattKeepaliveTimerEnabled */); 2293 } 2294 doTestMigrateIkeSession_FromNotIkeTunnConnParams( boolean isAutomaticIpVersionSelectionEnabled, boolean isAutomaticNattKeepaliveTimerEnabled)2295 private void doTestMigrateIkeSession_FromNotIkeTunnConnParams( 2296 boolean isAutomaticIpVersionSelectionEnabled, 2297 boolean isAutomaticNattKeepaliveTimerEnabled) throws Exception { 2298 final Ikev2VpnProfile ikeProfile = 2299 new Ikev2VpnProfile.Builder(TEST_VPN_SERVER, TEST_VPN_IDENTITY) 2300 .setAuthPsk(TEST_VPN_PSK) 2301 .setBypassable(true /* isBypassable */) 2302 .setAutomaticNattKeepaliveTimerEnabled(isAutomaticNattKeepaliveTimerEnabled) 2303 .setAutomaticIpVersionSelectionEnabled(isAutomaticIpVersionSelectionEnabled) 2304 .build(); 2305 2306 final int expectedKeepalive = isAutomaticNattKeepaliveTimerEnabled 2307 ? AUTOMATIC_KEEPALIVE_DELAY_SECONDS 2308 : DEFAULT_UDP_PORT_4500_NAT_TIMEOUT_SEC_INT; 2309 doTestMigrateIkeSession(ikeProfile.toVpnProfile(), 2310 expectedKeepalive, 2311 ESP_IP_VERSION_AUTO /* expectedIpVersion */, 2312 ESP_ENCAP_TYPE_AUTO /* expectedEncapType */, 2313 new NetworkCapabilities.Builder().build()); 2314 } 2315 makeIkeV2VpnProfile( boolean isAutomaticIpVersionSelectionEnabled, boolean isAutomaticNattKeepaliveTimerEnabled, int keepaliveInProfile, int ipVersionInProfile, int encapTypeInProfile)2316 private Ikev2VpnProfile makeIkeV2VpnProfile( 2317 boolean isAutomaticIpVersionSelectionEnabled, 2318 boolean isAutomaticNattKeepaliveTimerEnabled, 2319 int keepaliveInProfile, 2320 int ipVersionInProfile, 2321 int encapTypeInProfile) { 2322 // TODO: Update helper function in IkeSessionTestUtils to support building IkeSessionParams 2323 // with IP version and encap type when mainline-prod branch support these two APIs. 2324 final IkeSessionParams params = getTestIkeSessionParams(true /* testIpv6 */, 2325 new IkeFqdnIdentification(TEST_IDENTITY), keepaliveInProfile); 2326 final IkeSessionParams ikeSessionParams = new IkeSessionParams.Builder(params) 2327 .setIpVersion(ipVersionInProfile) 2328 .setEncapType(encapTypeInProfile) 2329 .build(); 2330 2331 final IkeTunnelConnectionParams tunnelParams = 2332 new IkeTunnelConnectionParams(ikeSessionParams, CHILD_PARAMS); 2333 return new Ikev2VpnProfile.Builder(tunnelParams) 2334 .setBypassable(true) 2335 .setAutomaticNattKeepaliveTimerEnabled(isAutomaticNattKeepaliveTimerEnabled) 2336 .setAutomaticIpVersionSelectionEnabled(isAutomaticIpVersionSelectionEnabled) 2337 .build(); 2338 } 2339 doTestMigrateIkeSession_FromIkeTunnConnParams( boolean isAutomaticIpVersionSelectionEnabled, boolean isAutomaticNattKeepaliveTimerEnabled, int keepaliveInProfile, int ipVersionInProfile, int encapTypeInProfile)2340 private void doTestMigrateIkeSession_FromIkeTunnConnParams( 2341 boolean isAutomaticIpVersionSelectionEnabled, 2342 boolean isAutomaticNattKeepaliveTimerEnabled, 2343 int keepaliveInProfile, 2344 int ipVersionInProfile, 2345 int encapTypeInProfile) throws Exception { 2346 doTestMigrateIkeSession_FromIkeTunnConnParams(isAutomaticIpVersionSelectionEnabled, 2347 isAutomaticNattKeepaliveTimerEnabled, keepaliveInProfile, ipVersionInProfile, 2348 encapTypeInProfile, new NetworkCapabilities.Builder().build()); 2349 } 2350 doTestMigrateIkeSession_FromIkeTunnConnParams( boolean isAutomaticIpVersionSelectionEnabled, boolean isAutomaticNattKeepaliveTimerEnabled, int keepaliveInProfile, int ipVersionInProfile, int encapTypeInProfile, @NonNull final NetworkCapabilities nc)2351 private void doTestMigrateIkeSession_FromIkeTunnConnParams( 2352 boolean isAutomaticIpVersionSelectionEnabled, 2353 boolean isAutomaticNattKeepaliveTimerEnabled, 2354 int keepaliveInProfile, 2355 int ipVersionInProfile, 2356 int encapTypeInProfile, 2357 @NonNull final NetworkCapabilities nc) throws Exception { 2358 final Ikev2VpnProfile ikeProfile = makeIkeV2VpnProfile( 2359 isAutomaticIpVersionSelectionEnabled, 2360 isAutomaticNattKeepaliveTimerEnabled, 2361 keepaliveInProfile, 2362 ipVersionInProfile, 2363 encapTypeInProfile); 2364 2365 final IkeSessionParams ikeSessionParams = 2366 ikeProfile.getIkeTunnelConnectionParams().getIkeSessionParams(); 2367 final int expectedKeepalive = isAutomaticNattKeepaliveTimerEnabled 2368 ? AUTOMATIC_KEEPALIVE_DELAY_SECONDS 2369 : ikeSessionParams.getNattKeepAliveDelaySeconds(); 2370 final int expectedIpVersion = isAutomaticIpVersionSelectionEnabled 2371 ? ESP_IP_VERSION_AUTO 2372 : ikeSessionParams.getIpVersion(); 2373 final int expectedEncapType = isAutomaticIpVersionSelectionEnabled 2374 ? ESP_ENCAP_TYPE_AUTO 2375 : ikeSessionParams.getEncapType(); 2376 doTestMigrateIkeSession(ikeProfile.toVpnProfile(), expectedKeepalive, 2377 expectedIpVersion, expectedEncapType, nc); 2378 } 2379 2380 @Test doTestMigrateIkeSession_Vcn()2381 public void doTestMigrateIkeSession_Vcn() throws Exception { 2382 final int expectedKeepalive = 2097; // Any unlikely number will do 2383 final NetworkCapabilities vcnNc = new NetworkCapabilities.Builder() 2384 .addTransportType(TRANSPORT_CELLULAR) 2385 .setTransportInfo(new VcnTransportInfo(TEST_SUB_ID, expectedKeepalive)) 2386 .build(); 2387 final Ikev2VpnProfile ikev2VpnProfile = makeIkeV2VpnProfile( 2388 true /* isAutomaticIpVersionSelectionEnabled */, 2389 true /* isAutomaticNattKeepaliveTimerEnabled */, 2390 234 /* keepaliveInProfile */, // Should be ignored, any value will do 2391 ESP_IP_VERSION_IPV4, // Should be ignored 2392 ESP_ENCAP_TYPE_UDP // Should be ignored 2393 ); 2394 doTestMigrateIkeSession( 2395 ikev2VpnProfile.toVpnProfile(), 2396 expectedKeepalive, 2397 ESP_IP_VERSION_AUTO /* expectedIpVersion */, 2398 ESP_ENCAP_TYPE_AUTO /* expectedEncapType */, 2399 vcnNc); 2400 } 2401 doTestMigrateIkeSession( @onNull final VpnProfile profile, final int expectedKeepalive, final int expectedIpVersion, final int expectedEncapType, @NonNull final NetworkCapabilities caps)2402 private void doTestMigrateIkeSession( 2403 @NonNull final VpnProfile profile, 2404 final int expectedKeepalive, 2405 final int expectedIpVersion, 2406 final int expectedEncapType, 2407 @NonNull final NetworkCapabilities caps) throws Exception { 2408 final PlatformVpnSnapshot vpnSnapShot = 2409 verifySetupPlatformVpn(profile, 2410 createIkeConfig(createIkeConnectInfo(), true /* isMobikeEnabled */), 2411 caps /* underlying network capabilities */, 2412 false /* mtuSupportsIpv6 */, 2413 expectedKeepalive < DEFAULT_LONG_LIVED_TCP_CONNS_EXPENSIVE_TIMEOUT_SEC); 2414 // Simulate a new network coming up 2415 vpnSnapShot.nwCb.onAvailable(TEST_NETWORK_2); 2416 verify(mIkeSessionWrapper, never()).setNetwork(any(), anyInt(), anyInt(), anyInt()); 2417 2418 vpnSnapShot.nwCb.onCapabilitiesChanged(TEST_NETWORK_2, caps); 2419 // Verify MOBIKE is triggered 2420 verify(mIkeSessionWrapper, timeout(TEST_TIMEOUT_MS)).setNetwork(TEST_NETWORK_2, 2421 expectedIpVersion, expectedEncapType, expectedKeepalive); 2422 2423 vpnSnapShot.vpn.mVpnRunner.exitVpnRunner(); 2424 } 2425 2426 @Test testLinkPropertiesUpdateTriggerReevaluation()2427 public void testLinkPropertiesUpdateTriggerReevaluation() throws Exception { 2428 final boolean hasV6 = true; 2429 2430 mockCarrierConfig(TEST_SUB_ID, TelephonyManager.SIM_STATE_LOADED, TEST_KEEPALIVE_TIMER, 2431 PREFERRED_IKE_PROTOCOL_IPV6_ESP); 2432 final IkeSessionParams params = getTestIkeSessionParams(hasV6, 2433 new IkeFqdnIdentification(TEST_IDENTITY), TEST_KEEPALIVE_TIMER); 2434 final IkeTunnelConnectionParams tunnelParams = 2435 new IkeTunnelConnectionParams(params, CHILD_PARAMS); 2436 final Ikev2VpnProfile ikeProfile = new Ikev2VpnProfile.Builder(tunnelParams) 2437 .setBypassable(true) 2438 .setAutomaticNattKeepaliveTimerEnabled(false) 2439 .setAutomaticIpVersionSelectionEnabled(true) 2440 .build(); 2441 final PlatformVpnSnapshot vpnSnapShot = 2442 verifySetupPlatformVpn(ikeProfile.toVpnProfile(), 2443 createIkeConfig(createIkeConnectInfo(), true /* isMobikeEnabled */), 2444 new NetworkCapabilities.Builder().build() /* underlying network caps */, 2445 hasV6 /* mtuSupportsIpv6 */, 2446 false /* areLongLivedTcpConnectionsExpensive */); 2447 reset(mExecutor); 2448 2449 // Simulate a new network coming up 2450 final LinkProperties lp = new LinkProperties(); 2451 lp.addLinkAddress(new LinkAddress("192.0.2.2/32")); 2452 2453 // Have the executor use the real delay to make sure schedule() was called only 2454 // once for all calls. Also, arrange for execute() not to call schedule() to avoid 2455 // messing with the checks for schedule(). 2456 mExecutor.delayMs = TestExecutor.REAL_DELAY; 2457 mExecutor.executeDirect = true; 2458 vpnSnapShot.nwCb.onAvailable(TEST_NETWORK_2); 2459 vpnSnapShot.nwCb.onCapabilitiesChanged( 2460 TEST_NETWORK_2, new NetworkCapabilities.Builder().build()); 2461 vpnSnapShot.nwCb.onLinkPropertiesChanged(TEST_NETWORK_2, new LinkProperties(lp)); 2462 verify(mExecutor).schedule(any(Runnable.class), longThat(it -> it > 0), any()); 2463 reset(mExecutor); 2464 2465 final InOrder order = inOrder(mIkeSessionWrapper); 2466 2467 // Verify the network is started 2468 order.verify(mIkeSessionWrapper, timeout(TIMEOUT_CROSSTHREAD_MS)).setNetwork(TEST_NETWORK_2, 2469 ESP_IP_VERSION_AUTO, ESP_ENCAP_TYPE_AUTO, TEST_KEEPALIVE_TIMER); 2470 2471 // Send the same properties, check that no migration is scheduled 2472 vpnSnapShot.nwCb.onLinkPropertiesChanged(TEST_NETWORK_2, new LinkProperties(lp)); 2473 verify(mExecutor, never()).schedule(any(Runnable.class), anyLong(), any()); 2474 2475 // Add v6 address, verify MOBIKE is triggered 2476 lp.addLinkAddress(new LinkAddress("2001:db8::1/64")); 2477 vpnSnapShot.nwCb.onLinkPropertiesChanged(TEST_NETWORK_2, new LinkProperties(lp)); 2478 order.verify(mIkeSessionWrapper, timeout(TIMEOUT_CROSSTHREAD_MS)).setNetwork(TEST_NETWORK_2, 2479 ESP_IP_VERSION_AUTO, ESP_ENCAP_TYPE_AUTO, TEST_KEEPALIVE_TIMER); 2480 2481 // Add another v4 address, verify MOBIKE is triggered 2482 final LinkProperties stacked = new LinkProperties(); 2483 stacked.setInterfaceName("v4-" + lp.getInterfaceName()); 2484 stacked.addLinkAddress(new LinkAddress("192.168.0.1/32")); 2485 lp.addStackedLink(stacked); 2486 vpnSnapShot.nwCb.onLinkPropertiesChanged(TEST_NETWORK_2, new LinkProperties(lp)); 2487 order.verify(mIkeSessionWrapper, timeout(TIMEOUT_CROSSTHREAD_MS)).setNetwork(TEST_NETWORK_2, 2488 ESP_IP_VERSION_AUTO, ESP_ENCAP_TYPE_AUTO, TEST_KEEPALIVE_TIMER); 2489 2490 vpnSnapShot.vpn.mVpnRunner.exitVpnRunner(); 2491 } 2492 mockCarrierConfig(int subId, int simStatus, int keepaliveTimer, int ikeProtocol)2493 private void mockCarrierConfig(int subId, int simStatus, int keepaliveTimer, int ikeProtocol) { 2494 final SubscriptionInfo subscriptionInfo = mock(SubscriptionInfo.class); 2495 doReturn(subId).when(subscriptionInfo).getSubscriptionId(); 2496 doReturn(List.of(subscriptionInfo)).when(mSubscriptionManager) 2497 .getActiveSubscriptionInfoList(); 2498 2499 doReturn(simStatus).when(mTmPerSub).getSimApplicationState(); 2500 doReturn(TEST_MCCMNC).when(mTmPerSub).getSimOperator(subId); 2501 2502 final PersistableBundle persistableBundle = new PersistableBundle(); 2503 persistableBundle.putInt(KEY_MIN_UDP_PORT_4500_NAT_TIMEOUT_SEC_INT, keepaliveTimer); 2504 persistableBundle.putInt(KEY_PREFERRED_IKE_PROTOCOL_INT, ikeProtocol); 2505 // For CarrierConfigManager.isConfigForIdentifiedCarrier check 2506 persistableBundle.putBoolean(KEY_CARRIER_CONFIG_APPLIED_BOOL, true); 2507 doReturn(persistableBundle).when(mConfigManager).getConfigForSubId(subId); 2508 } 2509 getCarrierConfigListener()2510 private CarrierConfigManager.CarrierConfigChangeListener getCarrierConfigListener() { 2511 final ArgumentCaptor<CarrierConfigManager.CarrierConfigChangeListener> listenerCaptor = 2512 ArgumentCaptor.forClass(CarrierConfigManager.CarrierConfigChangeListener.class); 2513 2514 verify(mConfigManager).registerCarrierConfigChangeListener(any(), listenerCaptor.capture()); 2515 2516 return listenerCaptor.getValue(); 2517 } 2518 2519 @Test testNattKeepaliveTimerFromCarrierConfig_noSubId()2520 public void testNattKeepaliveTimerFromCarrierConfig_noSubId() throws Exception { 2521 doTestReadCarrierConfig(new NetworkCapabilities(), 2522 TelephonyManager.SIM_STATE_LOADED, 2523 PREFERRED_IKE_PROTOCOL_IPV4_UDP, 2524 AUTOMATIC_KEEPALIVE_DELAY_SECONDS /* expectedKeepaliveTimer */, 2525 ESP_IP_VERSION_AUTO /* expectedIpVersion */, 2526 ESP_ENCAP_TYPE_AUTO /* expectedEncapType */, 2527 false /* expectedReadFromCarrierConfig*/, 2528 true /* areLongLivedTcpConnectionsExpensive */); 2529 } 2530 2531 @Test testNattKeepaliveTimerFromCarrierConfig_simAbsent()2532 public void testNattKeepaliveTimerFromCarrierConfig_simAbsent() throws Exception { 2533 doTestReadCarrierConfig(new NetworkCapabilities.Builder().build(), 2534 TelephonyManager.SIM_STATE_ABSENT, 2535 PREFERRED_IKE_PROTOCOL_IPV4_UDP, 2536 AUTOMATIC_KEEPALIVE_DELAY_SECONDS /* expectedKeepaliveTimer */, 2537 ESP_IP_VERSION_AUTO /* expectedIpVersion */, 2538 ESP_ENCAP_TYPE_AUTO /* expectedEncapType */, 2539 false /* expectedReadFromCarrierConfig*/, 2540 true /* areLongLivedTcpConnectionsExpensive */); 2541 } 2542 2543 @Test testNattKeepaliveTimerFromCarrierConfig()2544 public void testNattKeepaliveTimerFromCarrierConfig() throws Exception { 2545 doTestReadCarrierConfig(createTestCellNc(), 2546 TelephonyManager.SIM_STATE_LOADED, 2547 PREFERRED_IKE_PROTOCOL_AUTO, 2548 TEST_KEEPALIVE_TIMER /* expectedKeepaliveTimer */, 2549 ESP_IP_VERSION_AUTO /* expectedIpVersion */, 2550 ESP_ENCAP_TYPE_AUTO /* expectedEncapType */, 2551 true /* expectedReadFromCarrierConfig*/, 2552 false /* areLongLivedTcpConnectionsExpensive */); 2553 } 2554 2555 @Test testNattKeepaliveTimerFromCarrierConfig_NotCell()2556 public void testNattKeepaliveTimerFromCarrierConfig_NotCell() throws Exception { 2557 final NetworkCapabilities nc = new NetworkCapabilities.Builder() 2558 .addTransportType(TRANSPORT_WIFI) 2559 .setTransportInfo(new WifiInfo.Builder().build()) 2560 .build(); 2561 doTestReadCarrierConfig(nc, 2562 TelephonyManager.SIM_STATE_LOADED, 2563 PREFERRED_IKE_PROTOCOL_IPV4_UDP, 2564 AUTOMATIC_KEEPALIVE_DELAY_SECONDS /* expectedKeepaliveTimer */, 2565 ESP_IP_VERSION_AUTO /* expectedIpVersion */, 2566 ESP_ENCAP_TYPE_AUTO /* expectedEncapType */, 2567 false /* expectedReadFromCarrierConfig*/, 2568 true /* areLongLivedTcpConnectionsExpensive */); 2569 } 2570 2571 @Test testPreferredIpProtocolFromCarrierConfig_v4UDP()2572 public void testPreferredIpProtocolFromCarrierConfig_v4UDP() throws Exception { 2573 doTestReadCarrierConfig(createTestCellNc(), 2574 TelephonyManager.SIM_STATE_LOADED, 2575 PREFERRED_IKE_PROTOCOL_IPV4_UDP, 2576 TEST_KEEPALIVE_TIMER /* expectedKeepaliveTimer */, 2577 ESP_IP_VERSION_IPV4 /* expectedIpVersion */, 2578 ESP_ENCAP_TYPE_UDP /* expectedEncapType */, 2579 true /* expectedReadFromCarrierConfig*/, 2580 false /* areLongLivedTcpConnectionsExpensive */); 2581 } 2582 2583 @Test testPreferredIpProtocolFromCarrierConfig_v6ESP()2584 public void testPreferredIpProtocolFromCarrierConfig_v6ESP() throws Exception { 2585 doTestReadCarrierConfig(createTestCellNc(), 2586 TelephonyManager.SIM_STATE_LOADED, 2587 PREFERRED_IKE_PROTOCOL_IPV6_ESP, 2588 TEST_KEEPALIVE_TIMER /* expectedKeepaliveTimer */, 2589 ESP_IP_VERSION_IPV6 /* expectedIpVersion */, 2590 ESP_ENCAP_TYPE_NONE /* expectedEncapType */, 2591 true /* expectedReadFromCarrierConfig*/, 2592 false /* areLongLivedTcpConnectionsExpensive */); 2593 } 2594 2595 @Test testPreferredIpProtocolFromCarrierConfig_v6UDP()2596 public void testPreferredIpProtocolFromCarrierConfig_v6UDP() throws Exception { 2597 doTestReadCarrierConfig(createTestCellNc(), 2598 TelephonyManager.SIM_STATE_LOADED, 2599 PREFERRED_IKE_PROTOCOL_IPV6_UDP, 2600 TEST_KEEPALIVE_TIMER /* expectedKeepaliveTimer */, 2601 ESP_IP_VERSION_IPV6 /* expectedIpVersion */, 2602 ESP_ENCAP_TYPE_UDP /* expectedEncapType */, 2603 true /* expectedReadFromCarrierConfig*/, 2604 false /* areLongLivedTcpConnectionsExpensive */); 2605 } 2606 createTestCellNc()2607 private NetworkCapabilities createTestCellNc() { 2608 return new NetworkCapabilities.Builder() 2609 .addTransportType(TRANSPORT_CELLULAR) 2610 .setNetworkSpecifier(new TelephonyNetworkSpecifier.Builder() 2611 .setSubscriptionId(TEST_SUB_ID) 2612 .build()) 2613 .build(); 2614 } 2615 doTestReadCarrierConfig(NetworkCapabilities nc, int simState, int preferredIpProto, int expectedKeepaliveTimer, int expectedIpVersion, int expectedEncapType, boolean expectedReadFromCarrierConfig, boolean areLongLivedTcpConnectionsExpensive)2616 private void doTestReadCarrierConfig(NetworkCapabilities nc, int simState, int preferredIpProto, 2617 int expectedKeepaliveTimer, int expectedIpVersion, int expectedEncapType, 2618 boolean expectedReadFromCarrierConfig, 2619 boolean areLongLivedTcpConnectionsExpensive) 2620 throws Exception { 2621 final Ikev2VpnProfile ikeProfile = 2622 new Ikev2VpnProfile.Builder(TEST_VPN_SERVER, TEST_VPN_IDENTITY) 2623 .setAuthPsk(TEST_VPN_PSK) 2624 .setBypassable(true /* isBypassable */) 2625 .setAutomaticNattKeepaliveTimerEnabled(true) 2626 .setAutomaticIpVersionSelectionEnabled(true) 2627 .build(); 2628 2629 final PlatformVpnSnapshot vpnSnapShot = 2630 verifySetupPlatformVpn(ikeProfile.toVpnProfile(), 2631 createIkeConfig(createIkeConnectInfo(), true /* isMobikeEnabled */), 2632 new NetworkCapabilities.Builder().build() /* underlying network caps */, 2633 false /* mtuSupportsIpv6 */, 2634 true /* areLongLivedTcpConnectionsExpensive */); 2635 2636 final CarrierConfigManager.CarrierConfigChangeListener listener = 2637 getCarrierConfigListener(); 2638 2639 // Simulate a new network coming up 2640 vpnSnapShot.nwCb.onAvailable(TEST_NETWORK_2); 2641 // Migration will not be started until receiving network capabilities change. 2642 verify(mIkeSessionWrapper, never()).setNetwork(any(), anyInt(), anyInt(), anyInt()); 2643 2644 reset(mIkeSessionWrapper); 2645 mockCarrierConfig(TEST_SUB_ID, simState, TEST_KEEPALIVE_TIMER, preferredIpProto); 2646 vpnSnapShot.nwCb.onCapabilitiesChanged(TEST_NETWORK_2, nc); 2647 verify(mIkeSessionWrapper, timeout(TEST_TIMEOUT_MS)).setNetwork(TEST_NETWORK_2, 2648 expectedIpVersion, expectedEncapType, expectedKeepaliveTimer); 2649 if (expectedReadFromCarrierConfig) { 2650 final ArgumentCaptor<NetworkCapabilities> ncCaptor = 2651 ArgumentCaptor.forClass(NetworkCapabilities.class); 2652 verify(mMockNetworkAgent, timeout(TEST_TIMEOUT_MS)) 2653 .doSendNetworkCapabilities(ncCaptor.capture()); 2654 2655 final VpnTransportInfo info = 2656 (VpnTransportInfo) ncCaptor.getValue().getTransportInfo(); 2657 assertEquals(areLongLivedTcpConnectionsExpensive, 2658 info.areLongLivedTcpConnectionsExpensive()); 2659 } else { 2660 verify(mMockNetworkAgent, never()).doSendNetworkCapabilities(any()); 2661 } 2662 2663 reset(mExecutor); 2664 reset(mIkeSessionWrapper); 2665 reset(mMockNetworkAgent); 2666 2667 // Trigger carrier config change 2668 listener.onCarrierConfigChanged(1 /* logicalSlotIndex */, TEST_SUB_ID, 2669 -1 /* carrierId */, -1 /* specificCarrierId */); 2670 verify(mIkeSessionWrapper).setNetwork(TEST_NETWORK_2, 2671 expectedIpVersion, expectedEncapType, expectedKeepaliveTimer); 2672 // Expect no NetworkCapabilities change. 2673 // Call to doSendNetworkCapabilities() will not be triggered. 2674 verify(mMockNetworkAgent, never()).doSendNetworkCapabilities(any()); 2675 } 2676 2677 @Test testStartPlatformVpn_mtuDoesNotSupportIpv6()2678 public void testStartPlatformVpn_mtuDoesNotSupportIpv6() throws Exception { 2679 final PlatformVpnSnapshot vpnSnapShot = 2680 verifySetupPlatformVpn( 2681 createIkeConfig(createIkeConnectInfo(), true /* isMobikeEnabled */), 2682 false /* mtuSupportsIpv6 */); 2683 vpnSnapShot.vpn.mVpnRunner.exitVpnRunner(); 2684 } 2685 2686 @Test testStartPlatformVpn_underlyingNetworkNotChange()2687 public void testStartPlatformVpn_underlyingNetworkNotChange() throws Exception { 2688 final PlatformVpnSnapshot vpnSnapShot = verifySetupPlatformVpn( 2689 createIkeConfig(createIkeConnectInfo(), true /* isMobikeEnabled */)); 2690 // Trigger update on the same network should not cause underlying network change in NC of 2691 // the VPN network 2692 vpnSnapShot.nwCb.onAvailable(TEST_NETWORK); 2693 vpnSnapShot.nwCb.onCapabilitiesChanged(TEST_NETWORK, 2694 new NetworkCapabilities.Builder() 2695 .setSubscriptionIds(Set.of(TEST_SUB_ID)) 2696 .build()); 2697 // Verify setNetwork() called but no underlying network update 2698 verify(mIkeSessionWrapper, timeout(TEST_TIMEOUT_MS)).setNetwork(eq(TEST_NETWORK), 2699 eq(ESP_IP_VERSION_AUTO) /* ipVersion */, 2700 eq(ESP_ENCAP_TYPE_AUTO) /* encapType */, 2701 eq(DEFAULT_UDP_PORT_4500_NAT_TIMEOUT_SEC_INT) /* keepaliveDelay */); 2702 verify(mMockNetworkAgent, never()) 2703 .doSetUnderlyingNetworks(any()); 2704 2705 vpnSnapShot.nwCb.onAvailable(TEST_NETWORK_2); 2706 vpnSnapShot.nwCb.onCapabilitiesChanged(TEST_NETWORK_2, 2707 new NetworkCapabilities.Builder().build()); 2708 2709 // A new network should trigger both setNetwork() and a underlying network update. 2710 verify(mIkeSessionWrapper, timeout(TEST_TIMEOUT_MS)).setNetwork(eq(TEST_NETWORK_2), 2711 eq(ESP_IP_VERSION_AUTO) /* ipVersion */, 2712 eq(ESP_ENCAP_TYPE_AUTO) /* encapType */, 2713 eq(DEFAULT_UDP_PORT_4500_NAT_TIMEOUT_SEC_INT) /* keepaliveDelay */); 2714 verify(mMockNetworkAgent).doSetUnderlyingNetworks( 2715 Collections.singletonList(TEST_NETWORK_2)); 2716 2717 vpnSnapShot.vpn.mVpnRunner.exitVpnRunner(); 2718 } 2719 2720 @Test testStartPlatformVpnMobility_mobikeEnabled()2721 public void testStartPlatformVpnMobility_mobikeEnabled() throws Exception { 2722 final PlatformVpnSnapshot vpnSnapShot = verifySetupPlatformVpn( 2723 createIkeConfig(createIkeConnectInfo(), true /* isMobikeEnabled */)); 2724 2725 // Set new MTU on a different network 2726 final int newMtu = IPV6_MIN_MTU + 1; 2727 doReturn(newMtu).when(mTestDeps).calculateVpnMtu(any(), anyInt(), anyInt(), anyBoolean()); 2728 2729 // Mock network loss and verify a cleanup task is scheduled 2730 vpnSnapShot.nwCb.onLost(TEST_NETWORK); 2731 verify(mExecutor, atLeastOnce()).schedule(any(Runnable.class), anyLong(), any()); 2732 2733 // Mock new network comes up and the cleanup task is cancelled 2734 vpnSnapShot.nwCb.onAvailable(TEST_NETWORK_2); 2735 verify(mIkeSessionWrapper, never()).setNetwork(any(), anyInt(), anyInt(), anyInt()); 2736 2737 vpnSnapShot.nwCb.onCapabilitiesChanged(TEST_NETWORK_2, 2738 new NetworkCapabilities.Builder().build()); 2739 // Verify MOBIKE is triggered 2740 verify(mIkeSessionWrapper, timeout(TEST_TIMEOUT_MS)).setNetwork(eq(TEST_NETWORK_2), 2741 eq(ESP_IP_VERSION_AUTO) /* ipVersion */, 2742 eq(ESP_ENCAP_TYPE_AUTO) /* encapType */, 2743 eq(DEFAULT_UDP_PORT_4500_NAT_TIMEOUT_SEC_INT) /* keepaliveDelay */); 2744 // Verify mNetworkCapabilities is updated 2745 assertEquals( 2746 Collections.singletonList(TEST_NETWORK_2), 2747 vpnSnapShot.vpn.mNetworkCapabilities.getUnderlyingNetworks()); 2748 verify(mMockNetworkAgent) 2749 .doSetUnderlyingNetworks(Collections.singletonList(TEST_NETWORK_2)); 2750 2751 // Mock the MOBIKE procedure 2752 vpnSnapShot.ikeCb.onIkeSessionConnectionInfoChanged(createIkeConnectInfo_2()); 2753 vpnSnapShot.childCb.onIpSecTransformsMigrated( 2754 createIpSecTransform(), createIpSecTransform()); 2755 2756 verify(mIpSecService).setNetworkForTunnelInterface( 2757 eq(TEST_TUNNEL_RESOURCE_ID), eq(TEST_NETWORK_2), anyString()); 2758 2759 // Expect 2 times: one for initial setup and one for MOBIKE 2760 verifyApplyTunnelModeTransforms(2); 2761 2762 // Verify mNetworkAgent is updated 2763 verify(mMockNetworkAgent).doSendLinkProperties(argThat(lp -> lp.getMtu() == newMtu)); 2764 verify(mMockNetworkAgent, never()).unregister(); 2765 // No further doSetUnderlyingNetworks interaction. The interaction count should stay one. 2766 verify(mMockNetworkAgent, times(1)).doSetUnderlyingNetworks(any()); 2767 vpnSnapShot.vpn.mVpnRunner.exitVpnRunner(); 2768 } 2769 2770 @Test testStartPlatformVpnMobility_mobikeEnabledMtuDoesNotSupportIpv6()2771 public void testStartPlatformVpnMobility_mobikeEnabledMtuDoesNotSupportIpv6() throws Exception { 2772 final PlatformVpnSnapshot vpnSnapShot = 2773 verifySetupPlatformVpn( 2774 createIkeConfig(createIkeConnectInfo(), true /* isMobikeEnabled */)); 2775 2776 // Set MTU below 1280 2777 final int newMtu = IPV6_MIN_MTU - 1; 2778 doReturn(newMtu).when(mTestDeps).calculateVpnMtu(any(), anyInt(), anyInt(), anyBoolean()); 2779 2780 // Mock new network available & MOBIKE procedures 2781 vpnSnapShot.nwCb.onAvailable(TEST_NETWORK_2); 2782 vpnSnapShot.nwCb.onCapabilitiesChanged(TEST_NETWORK_2, 2783 new NetworkCapabilities.Builder().build()); 2784 // Verify mNetworkCapabilities is updated 2785 verify(mMockNetworkAgent, timeout(TEST_TIMEOUT_MS)) 2786 .doSetUnderlyingNetworks(Collections.singletonList(TEST_NETWORK_2)); 2787 assertEquals( 2788 Collections.singletonList(TEST_NETWORK_2), 2789 vpnSnapShot.vpn.mNetworkCapabilities.getUnderlyingNetworks()); 2790 2791 vpnSnapShot.ikeCb.onIkeSessionConnectionInfoChanged(createIkeConnectInfo_2()); 2792 vpnSnapShot.childCb.onIpSecTransformsMigrated( 2793 createIpSecTransform(), createIpSecTransform()); 2794 2795 // Verify removal of IPv6 addresses and routes triggers a network agent restart 2796 final ArgumentCaptor<LinkProperties> lpCaptor = 2797 ArgumentCaptor.forClass(LinkProperties.class); 2798 verify(mTestDeps, times(2)) 2799 .newNetworkAgent(any(), any(), anyString(), any(), lpCaptor.capture(), any(), any(), 2800 any(), any()); 2801 verify(mMockNetworkAgent).unregister(); 2802 // mMockNetworkAgent is an old NetworkAgent, so it won't update LinkProperties after 2803 // unregistering. 2804 verify(mMockNetworkAgent, never()).doSendLinkProperties(any()); 2805 2806 final LinkProperties lp = lpCaptor.getValue(); 2807 2808 for (LinkAddress addr : lp.getLinkAddresses()) { 2809 if (addr.isIpv6()) { 2810 fail("IPv6 address found on VPN with MTU < IPv6 minimum MTU"); 2811 } 2812 } 2813 2814 for (InetAddress dnsAddr : lp.getDnsServers()) { 2815 if (dnsAddr instanceof Inet6Address) { 2816 fail("IPv6 DNS server found on VPN with MTU < IPv6 minimum MTU"); 2817 } 2818 } 2819 2820 for (RouteInfo routeInfo : lp.getRoutes()) { 2821 if (routeInfo.getDestinationLinkAddress().isIpv6() 2822 && !routeInfo.isIPv6UnreachableDefault()) { 2823 fail("IPv6 route found on VPN with MTU < IPv6 minimum MTU"); 2824 } 2825 } 2826 2827 assertEquals(newMtu, lp.getMtu()); 2828 2829 vpnSnapShot.vpn.mVpnRunner.exitVpnRunner(); 2830 } 2831 2832 @Test testStartPlatformVpnReestablishes_mobikeDisabled()2833 public void testStartPlatformVpnReestablishes_mobikeDisabled() throws Exception { 2834 final PlatformVpnSnapshot vpnSnapShot = verifySetupPlatformVpn( 2835 createIkeConfig(createIkeConnectInfo(), false /* isMobikeEnabled */)); 2836 2837 // Forget the first IKE creation to be prepared to capture callbacks of the second 2838 // IKE session 2839 resetIkev2SessionCreator(mock(Vpn.IkeSessionWrapper.class)); 2840 2841 // Mock network switch 2842 vpnSnapShot.nwCb.onLost(TEST_NETWORK); 2843 vpnSnapShot.nwCb.onAvailable(TEST_NETWORK_2); 2844 // The old IKE Session will not be killed until receiving network capabilities change. 2845 verify(mIkeSessionWrapper, never()).kill(); 2846 2847 vpnSnapShot.nwCb.onCapabilitiesChanged( 2848 TEST_NETWORK_2, new NetworkCapabilities.Builder().build()); 2849 // Verify the old IKE Session is killed 2850 verify(mIkeSessionWrapper, timeout(TEST_TIMEOUT_MS)).kill(); 2851 2852 // Capture callbacks of the new IKE Session 2853 final Pair<IkeSessionCallback, ChildSessionCallback> cbPair = 2854 verifyCreateIkeAndCaptureCbs(); 2855 final IkeSessionCallback ikeCb = cbPair.first; 2856 final ChildSessionCallback childCb = cbPair.second; 2857 2858 // Mock the IKE Session setup 2859 ikeCb.onOpened(createIkeConfig(createIkeConnectInfo_2(), false /* isMobikeEnabled */)); 2860 2861 childCb.onIpSecTransformCreated(createIpSecTransform(), IpSecManager.DIRECTION_IN); 2862 childCb.onIpSecTransformCreated(createIpSecTransform(), IpSecManager.DIRECTION_OUT); 2863 childCb.onOpened(createChildConfig()); 2864 2865 // Expect 2 times since there have been two Session setups 2866 verifyApplyTunnelModeTransforms(2); 2867 2868 // Verify mNetworkCapabilities and mNetworkAgent are updated 2869 assertEquals( 2870 Collections.singletonList(TEST_NETWORK_2), 2871 vpnSnapShot.vpn.mNetworkCapabilities.getUnderlyingNetworks()); 2872 verify(mMockNetworkAgent) 2873 .doSetUnderlyingNetworks(Collections.singletonList(TEST_NETWORK_2)); 2874 2875 vpnSnapShot.vpn.mVpnRunner.exitVpnRunner(); 2876 } 2877 getDump(@onNull final Vpn vpn)2878 private String getDump(@NonNull final Vpn vpn) { 2879 final StringWriter sw = new StringWriter(); 2880 final IndentingPrintWriter writer = new IndentingPrintWriter(sw, ""); 2881 vpn.dump(writer); 2882 writer.flush(); 2883 return sw.toString(); 2884 } 2885 countMatches(@onNull final Pattern regexp, @NonNull final String string)2886 private int countMatches(@NonNull final Pattern regexp, @NonNull final String string) { 2887 final Matcher m = regexp.matcher(string); 2888 int i = 0; 2889 while (m.find()) ++i; 2890 return i; 2891 } 2892 2893 @Test testNCEventChanges()2894 public void testNCEventChanges() throws Exception { 2895 final NetworkCapabilities.Builder ncBuilder = new NetworkCapabilities.Builder() 2896 .addTransportType(TRANSPORT_CELLULAR) 2897 .addCapability(NET_CAPABILITY_INTERNET) 2898 .addCapability(NET_CAPABILITY_NOT_RESTRICTED) 2899 .setLinkDownstreamBandwidthKbps(1000) 2900 .setLinkUpstreamBandwidthKbps(500); 2901 2902 final Ikev2VpnProfile ikeProfile = 2903 new Ikev2VpnProfile.Builder(TEST_VPN_SERVER, TEST_VPN_IDENTITY) 2904 .setAuthPsk(TEST_VPN_PSK) 2905 .setBypassable(true /* isBypassable */) 2906 .setAutomaticNattKeepaliveTimerEnabled(true) 2907 .setAutomaticIpVersionSelectionEnabled(true) 2908 .build(); 2909 2910 final PlatformVpnSnapshot vpnSnapShot = 2911 verifySetupPlatformVpn(ikeProfile.toVpnProfile(), 2912 createIkeConfig(createIkeConnectInfo(), true /* isMobikeEnabled */), 2913 ncBuilder.build(), false /* mtuSupportsIpv6 */, 2914 true /* areLongLivedTcpConnectionsExpensive */); 2915 2916 // Calls to onCapabilitiesChanged will be thrown to the executor for execution ; by 2917 // default this will incur a 10ms delay before it's executed, messing with the timing 2918 // of the log and having the checks for counts in equals() below flake. 2919 mExecutor.executeDirect = true; 2920 2921 // First nc changed triggered by verifySetupPlatformVpn 2922 final Pattern pattern = Pattern.compile("Cap changed from", Pattern.MULTILINE); 2923 final String stage1 = getDump(vpnSnapShot.vpn); 2924 assertEquals(1, countMatches(pattern, stage1)); 2925 2926 vpnSnapShot.nwCb.onCapabilitiesChanged(TEST_NETWORK, ncBuilder.build()); 2927 final String stage2 = getDump(vpnSnapShot.vpn); 2928 // Was the same caps, there should still be only 1 match 2929 assertEquals(1, countMatches(pattern, stage2)); 2930 2931 ncBuilder.setLinkDownstreamBandwidthKbps(1200) 2932 .setLinkUpstreamBandwidthKbps(300); 2933 vpnSnapShot.nwCb.onCapabilitiesChanged(TEST_NETWORK, ncBuilder.build()); 2934 final String stage3 = getDump(vpnSnapShot.vpn); 2935 // Was not an important change, should not be logged, still only 1 match 2936 assertEquals(1, countMatches(pattern, stage3)); 2937 2938 ncBuilder.addCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED); 2939 vpnSnapShot.nwCb.onCapabilitiesChanged(TEST_NETWORK, ncBuilder.build()); 2940 final String stage4 = getDump(vpnSnapShot.vpn); 2941 // Change to caps is important, should cause a new match 2942 assertEquals(2, countMatches(pattern, stage4)); 2943 2944 ncBuilder.removeCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED); 2945 ncBuilder.setLinkDownstreamBandwidthKbps(600); 2946 vpnSnapShot.nwCb.onCapabilitiesChanged(TEST_NETWORK, ncBuilder.build()); 2947 final String stage5 = getDump(vpnSnapShot.vpn); 2948 // Change to caps is important, should cause a new match even with the unimportant change 2949 assertEquals(3, countMatches(pattern, stage5)); 2950 } 2951 // TODO : beef up event logs tests 2952 verifyHandlingNetworkLoss(PlatformVpnSnapshot vpnSnapShot)2953 private void verifyHandlingNetworkLoss(PlatformVpnSnapshot vpnSnapShot) throws Exception { 2954 // Forget the #sendLinkProperties during first setup. 2955 reset(mMockNetworkAgent); 2956 2957 // Mock network loss 2958 vpnSnapShot.nwCb.onLost(TEST_NETWORK); 2959 2960 // Mock the grace period expires 2961 verify(mExecutor, atLeastOnce()).schedule(any(Runnable.class), anyLong(), any()); 2962 2963 final ArgumentCaptor<LinkProperties> lpCaptor = 2964 ArgumentCaptor.forClass(LinkProperties.class); 2965 verify(mMockNetworkAgent, timeout(TEST_TIMEOUT_MS)) 2966 .doSendLinkProperties(lpCaptor.capture()); 2967 final LinkProperties lp = lpCaptor.getValue(); 2968 2969 assertNull(lp.getInterfaceName()); 2970 final List<RouteInfo> expectedRoutes = Arrays.asList( 2971 new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), null /* gateway */, 2972 null /* iface */, RTN_UNREACHABLE), 2973 new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), null /* gateway */, 2974 null /* iface */, RTN_UNREACHABLE)); 2975 assertEquals(expectedRoutes, lp.getRoutes()); 2976 2977 verify(mMockNetworkAgent, timeout(TEST_TIMEOUT_MS)).unregister(); 2978 } 2979 2980 @Test testStartPlatformVpnHandlesNetworkLoss_mobikeEnabled()2981 public void testStartPlatformVpnHandlesNetworkLoss_mobikeEnabled() throws Exception { 2982 final PlatformVpnSnapshot vpnSnapShot = verifySetupPlatformVpn( 2983 createIkeConfig(createIkeConnectInfo(), true /* isMobikeEnabled */)); 2984 verifyHandlingNetworkLoss(vpnSnapShot); 2985 } 2986 2987 @Test testStartPlatformVpnHandlesNetworkLoss_mobikeDisabled()2988 public void testStartPlatformVpnHandlesNetworkLoss_mobikeDisabled() throws Exception { 2989 final PlatformVpnSnapshot vpnSnapShot = verifySetupPlatformVpn( 2990 createIkeConfig(createIkeConnectInfo(), false /* isMobikeEnabled */)); 2991 verifyHandlingNetworkLoss(vpnSnapShot); 2992 } 2993 getConnectivityDiagCallback()2994 private ConnectivityDiagnosticsCallback getConnectivityDiagCallback() { 2995 final ArgumentCaptor<ConnectivityDiagnosticsCallback> cdcCaptor = 2996 ArgumentCaptor.forClass(ConnectivityDiagnosticsCallback.class); 2997 verify(mCdm).registerConnectivityDiagnosticsCallback( 2998 any(), any(), cdcCaptor.capture()); 2999 return cdcCaptor.getValue(); 3000 } 3001 createDataStallReport()3002 private DataStallReport createDataStallReport() { 3003 return new DataStallReport(TEST_NETWORK, 1234 /* reportTimestamp */, 3004 1 /* detectionMethod */, new LinkProperties(), new NetworkCapabilities(), 3005 new PersistableBundle()); 3006 } 3007 verifyMobikeTriggered(List<Network> expected, int retryIndex)3008 private void verifyMobikeTriggered(List<Network> expected, int retryIndex) { 3009 // Verify retry is scheduled 3010 final long expectedDelayMs = mTestDeps.getValidationFailRecoveryMs(retryIndex); 3011 final ArgumentCaptor<Long> delayCaptor = ArgumentCaptor.forClass(Long.class); 3012 verify(mExecutor, times(retryIndex + 1)).schedule( 3013 any(Runnable.class), delayCaptor.capture(), eq(TimeUnit.MILLISECONDS)); 3014 final List<Long> delays = delayCaptor.getAllValues(); 3015 assertEquals(expectedDelayMs, (long) delays.get(delays.size() - 1)); 3016 3017 final ArgumentCaptor<Network> networkCaptor = ArgumentCaptor.forClass(Network.class); 3018 verify(mIkeSessionWrapper, timeout(TEST_TIMEOUT_MS + expectedDelayMs)) 3019 .setNetwork(networkCaptor.capture(), anyInt() /* ipVersion */, 3020 anyInt() /* encapType */, anyInt() /* keepaliveDelay */); 3021 assertEquals(expected, Collections.singletonList(networkCaptor.getValue())); 3022 } 3023 3024 @Test testDataStallInIkev2VpnMobikeDisabled()3025 public void testDataStallInIkev2VpnMobikeDisabled() throws Exception { 3026 final PlatformVpnSnapshot vpnSnapShot = verifySetupPlatformVpn( 3027 createIkeConfig(createIkeConnectInfo(), false /* isMobikeEnabled */)); 3028 3029 doReturn(TEST_NETWORK).when(mMockNetworkAgent).getNetwork(); 3030 ((Vpn.IkeV2VpnRunner) vpnSnapShot.vpn.mVpnRunner).onValidationStatus( 3031 NetworkAgent.VALIDATION_STATUS_NOT_VALID); 3032 3033 // Should not trigger MOBIKE if MOBIKE is not enabled 3034 verify(mIkeSessionWrapper, never()).setNetwork(any() /* network */, 3035 anyInt() /* ipVersion */, anyInt() /* encapType */, anyInt() /* keepaliveDelay */); 3036 } 3037 3038 @Test testDataStallInIkev2VpnRecoveredByMobike()3039 public void testDataStallInIkev2VpnRecoveredByMobike() throws Exception { 3040 final PlatformVpnSnapshot vpnSnapShot = verifySetupPlatformVpn( 3041 createIkeConfig(createIkeConnectInfo(), true /* isMobikeEnabled */)); 3042 3043 doReturn(TEST_NETWORK).when(mMockNetworkAgent).getNetwork(); 3044 ((Vpn.IkeV2VpnRunner) vpnSnapShot.vpn.mVpnRunner).onValidationStatus( 3045 NetworkAgent.VALIDATION_STATUS_NOT_VALID); 3046 // Verify MOBIKE is triggered 3047 verifyMobikeTriggered(vpnSnapShot.vpn.mNetworkCapabilities.getUnderlyingNetworks(), 3048 0 /* retryIndex */); 3049 // Validation failure on VPN network should trigger a re-evaluation request for the 3050 // underlying network. 3051 verify(mConnectivityManager).reportNetworkConnectivity(TEST_NETWORK, false); 3052 3053 reset(mIkev2SessionCreator); 3054 reset(mExecutor); 3055 3056 // Send validation status update. 3057 // Recovered and get network validated. It should not trigger the ike session reset. 3058 ((Vpn.IkeV2VpnRunner) vpnSnapShot.vpn.mVpnRunner).onValidationStatus( 3059 NetworkAgent.VALIDATION_STATUS_VALID); 3060 // Verify that the retry count is reset. The mValidationFailRetryCount will not be reset 3061 // until the executor finishes the execute() call, so wait until the all tasks are executed. 3062 waitForIdleSerialExecutor(mExecutor, TEST_TIMEOUT_MS); 3063 assertEquals(0, 3064 ((Vpn.IkeV2VpnRunner) vpnSnapShot.vpn.mVpnRunner).mValidationFailRetryCount); 3065 verify(mIkev2SessionCreator, never()).createIkeSession( 3066 any(), any(), any(), any(), any(), any()); 3067 3068 reset(mIkeSessionWrapper); 3069 reset(mExecutor); 3070 3071 // Another validation fail should trigger another reportNetworkConnectivity 3072 ((Vpn.IkeV2VpnRunner) vpnSnapShot.vpn.mVpnRunner).onValidationStatus( 3073 NetworkAgent.VALIDATION_STATUS_NOT_VALID); 3074 verifyMobikeTriggered(vpnSnapShot.vpn.mNetworkCapabilities.getUnderlyingNetworks(), 3075 0 /* retryIndex */); 3076 verify(mConnectivityManager, times(2)).reportNetworkConnectivity(TEST_NETWORK, false); 3077 } 3078 3079 @Test testDataStallInIkev2VpnNotRecoveredByMobike()3080 public void testDataStallInIkev2VpnNotRecoveredByMobike() throws Exception { 3081 final PlatformVpnSnapshot vpnSnapShot = verifySetupPlatformVpn( 3082 createIkeConfig(createIkeConnectInfo(), true /* isMobikeEnabled */)); 3083 3084 int retry = 0; 3085 doReturn(TEST_NETWORK).when(mMockNetworkAgent).getNetwork(); 3086 ((Vpn.IkeV2VpnRunner) vpnSnapShot.vpn.mVpnRunner).onValidationStatus( 3087 NetworkAgent.VALIDATION_STATUS_NOT_VALID); 3088 verifyMobikeTriggered(vpnSnapShot.vpn.mNetworkCapabilities.getUnderlyingNetworks(), 3089 retry++); 3090 // Validation failure on VPN network should trigger a re-evaluation request for the 3091 // underlying network. 3092 verify(mConnectivityManager).reportNetworkConnectivity(TEST_NETWORK, false); 3093 reset(mIkev2SessionCreator); 3094 3095 // Second validation status update. 3096 ((Vpn.IkeV2VpnRunner) vpnSnapShot.vpn.mVpnRunner).onValidationStatus( 3097 NetworkAgent.VALIDATION_STATUS_NOT_VALID); 3098 verifyMobikeTriggered(vpnSnapShot.vpn.mNetworkCapabilities.getUnderlyingNetworks(), 3099 retry++); 3100 // Call to reportNetworkConnectivity should only happen once. No further interaction. 3101 verify(mConnectivityManager, times(1)).reportNetworkConnectivity(TEST_NETWORK, false); 3102 3103 // Use real delay to verify reset session will not be performed if there is an existing 3104 // recovery for resetting the session. 3105 mExecutor.delayMs = TestExecutor.REAL_DELAY; 3106 mExecutor.executeDirect = true; 3107 // Send validation status update should result in ike session reset. 3108 ((Vpn.IkeV2VpnRunner) vpnSnapShot.vpn.mVpnRunner).onValidationStatus( 3109 NetworkAgent.VALIDATION_STATUS_NOT_VALID); 3110 3111 // Verify session reset is scheduled 3112 long expectedDelay = mTestDeps.getValidationFailRecoveryMs(retry++); 3113 final ArgumentCaptor<Long> delayCaptor = ArgumentCaptor.forClass(Long.class); 3114 verify(mExecutor, times(retry)).schedule(any(Runnable.class), delayCaptor.capture(), 3115 eq(TimeUnit.MILLISECONDS)); 3116 final List<Long> delays = delayCaptor.getAllValues(); 3117 assertEquals(expectedDelay, (long) delays.get(delays.size() - 1)); 3118 // Call to reportNetworkConnectivity should only happen once. No further interaction. 3119 verify(mConnectivityManager, times(1)).reportNetworkConnectivity(TEST_NETWORK, false); 3120 3121 // Another invalid status reported should not trigger other scheduled recovery. 3122 expectedDelay = mTestDeps.getValidationFailRecoveryMs(retry++); 3123 ((Vpn.IkeV2VpnRunner) vpnSnapShot.vpn.mVpnRunner).onValidationStatus( 3124 NetworkAgent.VALIDATION_STATUS_NOT_VALID); 3125 verify(mExecutor, never()).schedule( 3126 any(Runnable.class), eq(expectedDelay), eq(TimeUnit.MILLISECONDS)); 3127 3128 // Verify that session being reset 3129 verify(mIkev2SessionCreator, timeout(TEST_TIMEOUT_MS + expectedDelay)) 3130 .createIkeSession(any(), any(), any(), any(), any(), any()); 3131 // Call to reportNetworkConnectivity should only happen once. No further interaction. 3132 verify(mConnectivityManager, times(1)).reportNetworkConnectivity(TEST_NETWORK, false); 3133 } 3134 3135 @Test testStartLegacyVpnType()3136 public void testStartLegacyVpnType() throws Exception { 3137 setMockedUsers(PRIMARY_USER); 3138 final Vpn vpn = createVpn(PRIMARY_USER.id); 3139 final VpnProfile profile = new VpnProfile("testProfile" /* key */); 3140 3141 profile.type = VpnProfile.TYPE_PPTP; 3142 assertThrows(UnsupportedOperationException.class, () -> startLegacyVpn(vpn, profile)); 3143 profile.type = VpnProfile.TYPE_L2TP_IPSEC_PSK; 3144 assertThrows(UnsupportedOperationException.class, () -> startLegacyVpn(vpn, profile)); 3145 } 3146 3147 @Test testStartLegacyVpnModifyProfile_TypePSK()3148 public void testStartLegacyVpnModifyProfile_TypePSK() throws Exception { 3149 setMockedUsers(PRIMARY_USER); 3150 final Vpn vpn = createVpn(PRIMARY_USER.id); 3151 final Ikev2VpnProfile ikev2VpnProfile = 3152 new Ikev2VpnProfile.Builder(TEST_VPN_SERVER, TEST_VPN_IDENTITY) 3153 .setAuthPsk(TEST_VPN_PSK) 3154 .build(); 3155 final VpnProfile profile = ikev2VpnProfile.toVpnProfile(); 3156 3157 startLegacyVpn(vpn, profile); 3158 assertEquals(profile, ikev2VpnProfile.toVpnProfile()); 3159 } 3160 3161 // Make it public and un-final so as to spy it 3162 public class TestDeps extends Vpn.Dependencies { TestDeps()3163 TestDeps() {} 3164 3165 @Override isCallerSystem()3166 public boolean isCallerSystem() { 3167 return true; 3168 } 3169 3170 @Override getIntentForStatusPanel(Context context)3171 public PendingIntent getIntentForStatusPanel(Context context) { 3172 return null; 3173 } 3174 3175 @Override adoptFd(Vpn vpn, int mtu)3176 public ParcelFileDescriptor adoptFd(Vpn vpn, int mtu) { 3177 return new ParcelFileDescriptor(new FileDescriptor()); 3178 } 3179 3180 @Override jniCreate(Vpn vpn, int mtu)3181 public int jniCreate(Vpn vpn, int mtu) { 3182 // Pick a random positive number as fd to return. 3183 return 345; 3184 } 3185 3186 @Override jniGetName(Vpn vpn, int fd)3187 public String jniGetName(Vpn vpn, int fd) { 3188 return TEST_IFACE_NAME; 3189 } 3190 3191 @Override jniSetAddresses(Vpn vpn, String interfaze, String addresses)3192 public int jniSetAddresses(Vpn vpn, String interfaze, String addresses) { 3193 if (addresses == null) return 0; 3194 // Return the number of addresses. 3195 return addresses.split(" ").length; 3196 } 3197 3198 @Override setBlocking(FileDescriptor fd, boolean blocking)3199 public void setBlocking(FileDescriptor fd, boolean blocking) {} 3200 3201 @Override getDeviceIdleInternal()3202 public DeviceIdleInternal getDeviceIdleInternal() { 3203 return mDeviceIdleInternal; 3204 } 3205 3206 @Override getValidationFailRecoveryMs(int retryCount)3207 public long getValidationFailRecoveryMs(int retryCount) { 3208 // Simply return retryCount as the delay seconds for retrying. 3209 return retryCount * 100L; 3210 } 3211 3212 @Override newScheduledThreadPoolExecutor()3213 public ScheduledThreadPoolExecutor newScheduledThreadPoolExecutor() { 3214 return mExecutor; 3215 } 3216 3217 public boolean mIgnoreCallingUidChecks = true; 3218 @Override verifyCallingUidAndPackage(Context context, String packageName, int userId)3219 public void verifyCallingUidAndPackage(Context context, String packageName, int userId) { 3220 if (!mIgnoreCallingUidChecks) { 3221 super.verifyCallingUidAndPackage(context, packageName, userId); 3222 } 3223 } 3224 } 3225 3226 /** 3227 * Mock some methods of vpn object. 3228 */ createVpn(@serIdInt int userId)3229 private Vpn createVpn(@UserIdInt int userId) { 3230 final Context asUserContext = mock(Context.class, AdditionalAnswers.delegatesTo(mContext)); 3231 doReturn(UserHandle.of(userId)).when(asUserContext).getUser(); 3232 when(mContext.createContextAsUser(eq(UserHandle.of(userId)), anyInt())) 3233 .thenReturn(asUserContext); 3234 final TestLooper testLooper = new TestLooper(); 3235 final Vpn vpn = new Vpn(testLooper.getLooper(), mContext, mTestDeps, mNetService, 3236 mNetd, userId, mVpnProfileStore, mSystemServices, mIkev2SessionCreator); 3237 verify(mConnectivityManager, times(1)).registerNetworkProvider(argThat( 3238 provider -> provider.getName().contains("VpnNetworkProvider") 3239 )); 3240 return vpn; 3241 } 3242 3243 /** 3244 * Populate {@link #mUserManager} with a list of fake users. 3245 */ setMockedUsers(UserInfo... users)3246 private void setMockedUsers(UserInfo... users) { 3247 final Map<Integer, UserInfo> userMap = new ArrayMap<>(); 3248 for (UserInfo user : users) { 3249 userMap.put(user.id, user); 3250 } 3251 3252 /** 3253 * @see UserManagerService#getUsers(boolean) 3254 */ 3255 doAnswer(invocation -> { 3256 final ArrayList<UserInfo> result = new ArrayList<>(users.length); 3257 for (UserInfo ui : users) { 3258 if (ui.isEnabled() && !ui.partial) { 3259 result.add(ui); 3260 } 3261 } 3262 return result; 3263 }).when(mUserManager).getAliveUsers(); 3264 3265 doAnswer(invocation -> { 3266 final int id = (int) invocation.getArguments()[0]; 3267 return userMap.get(id); 3268 }).when(mUserManager).getUserInfo(anyInt()); 3269 } 3270 3271 /** 3272 * Populate {@link #mPackageManager} with a fake packageName-to-UID mapping. 3273 */ setMockedPackages(final Map<String, Integer> packages)3274 private void setMockedPackages(final Map<String, Integer> packages) { 3275 try { 3276 doAnswer(invocation -> { 3277 final String appName = (String) invocation.getArguments()[0]; 3278 final int userId = (int) invocation.getArguments()[1]; 3279 Integer appId = packages.get(appName); 3280 if (appId == null) throw new PackageManager.NameNotFoundException(appName); 3281 return UserHandle.getUid(userId, appId); 3282 }).when(mPackageManager).getPackageUidAsUser(anyString(), anyInt()); 3283 } catch (Exception e) { 3284 } 3285 } 3286 } 3287