summaryrefslogtreecommitdiff
path: root/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java
diff options
context:
space:
mode:
Diffstat (limited to 'tests/net/java/com/android/server/IpSecServiceParameterizedTest.java')
-rw-r--r--tests/net/java/com/android/server/IpSecServiceParameterizedTest.java1004
1 files changed, 0 insertions, 1004 deletions
diff --git a/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java b/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java
deleted file mode 100644
index cf2c9c783ac7..000000000000
--- a/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java
+++ /dev/null
@@ -1,1004 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server;
-
-import static android.content.pm.PackageManager.PERMISSION_DENIED;
-import static android.content.pm.PackageManager.PERMISSION_GRANTED;
-import static android.net.INetd.IF_STATE_DOWN;
-import static android.net.INetd.IF_STATE_UP;
-import static android.net.IpSecManager.DIRECTION_FWD;
-import static android.net.IpSecManager.DIRECTION_IN;
-import static android.net.IpSecManager.DIRECTION_OUT;
-import static android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK;
-import static android.system.OsConstants.AF_INET;
-import static android.system.OsConstants.AF_INET6;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.fail;
-import static org.mockito.ArgumentMatchers.argThat;
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.app.AppOpsManager;
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.net.ConnectivityManager;
-import android.net.INetd;
-import android.net.InetAddresses;
-import android.net.InterfaceConfigurationParcel;
-import android.net.IpSecAlgorithm;
-import android.net.IpSecConfig;
-import android.net.IpSecManager;
-import android.net.IpSecSpiResponse;
-import android.net.IpSecTransform;
-import android.net.IpSecTransformResponse;
-import android.net.IpSecTunnelInterfaceResponse;
-import android.net.IpSecUdpEncapResponse;
-import android.net.LinkAddress;
-import android.net.LinkProperties;
-import android.net.Network;
-import android.os.Binder;
-import android.os.ParcelFileDescriptor;
-import android.system.Os;
-import android.test.mock.MockContext;
-import android.util.ArraySet;
-
-import androidx.test.filters.SmallTest;
-
-import com.android.server.IpSecService.TunnelInterfaceRecord;
-
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-
-import java.net.Inet4Address;
-import java.net.Socket;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Set;
-
-/** Unit tests for {@link IpSecService}. */
-@SmallTest
-@RunWith(Parameterized.class)
-public class IpSecServiceParameterizedTest {
-
- private static final int TEST_SPI = 0xD1201D;
-
- private final String mSourceAddr;
- private final String mDestinationAddr;
- private final LinkAddress mLocalInnerAddress;
- private final int mFamily;
-
- private static final int[] ADDRESS_FAMILIES =
- new int[] {AF_INET, AF_INET6};
-
- @Parameterized.Parameters
- public static Collection ipSecConfigs() {
- return Arrays.asList(
- new Object[][] {
- {"1.2.3.4", "8.8.4.4", "10.0.1.1/24", AF_INET},
- {"2601::2", "2601::10", "2001:db8::1/64", AF_INET6}
- });
- }
-
- private static final byte[] AEAD_KEY = {
- 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
- 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
- 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
- 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
- 0x73, 0x61, 0x6C, 0x74
- };
- private static final byte[] CRYPT_KEY = {
- 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
- 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
- 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
- 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F
- };
- private static final byte[] AUTH_KEY = {
- 0x7A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F,
- 0x7A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F
- };
-
- AppOpsManager mMockAppOps = mock(AppOpsManager.class);
- ConnectivityManager mMockConnectivityMgr = mock(ConnectivityManager.class);
-
- TestContext mTestContext = new TestContext();
-
- private class TestContext extends MockContext {
- private Set<String> mAllowedPermissions = new ArraySet<>(Arrays.asList(
- android.Manifest.permission.MANAGE_IPSEC_TUNNELS,
- android.Manifest.permission.NETWORK_STACK,
- PERMISSION_MAINLINE_NETWORK_STACK));
-
- private void setAllowedPermissions(String... permissions) {
- mAllowedPermissions = new ArraySet<>(permissions);
- }
-
- @Override
- public Object getSystemService(String name) {
- switch(name) {
- case Context.APP_OPS_SERVICE:
- return mMockAppOps;
- case Context.CONNECTIVITY_SERVICE:
- return mMockConnectivityMgr;
- default:
- return null;
- }
- }
-
- @Override
- public String getSystemServiceName(Class<?> serviceClass) {
- if (ConnectivityManager.class == serviceClass) {
- return Context.CONNECTIVITY_SERVICE;
- }
- return null;
- }
-
- @Override
- public PackageManager getPackageManager() {
- return mMockPkgMgr;
- }
-
- @Override
- public void enforceCallingOrSelfPermission(String permission, String message) {
- if (mAllowedPermissions.contains(permission)) {
- return;
- } else {
- throw new SecurityException("Unavailable permission requested");
- }
- }
-
- @Override
- public int checkCallingOrSelfPermission(String permission) {
- if (mAllowedPermissions.contains(permission)) {
- return PERMISSION_GRANTED;
- } else {
- return PERMISSION_DENIED;
- }
- }
- }
-
- INetd mMockNetd;
- PackageManager mMockPkgMgr;
- IpSecService.IpSecServiceConfiguration mMockIpSecSrvConfig;
- IpSecService mIpSecService;
- Network fakeNetwork = new Network(0xAB);
- int mUid = Os.getuid();
-
- private static final IpSecAlgorithm AUTH_ALGO =
- new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, AUTH_KEY, AUTH_KEY.length * 4);
- private static final IpSecAlgorithm CRYPT_ALGO =
- new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
- private static final IpSecAlgorithm AEAD_ALGO =
- new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 128);
- private static final int REMOTE_ENCAP_PORT = 4500;
-
- private static final String BLESSED_PACKAGE = "blessedPackage";
- private static final String SYSTEM_PACKAGE = "systemPackage";
- private static final String BAD_PACKAGE = "badPackage";
-
- public IpSecServiceParameterizedTest(
- String sourceAddr, String destAddr, String localInnerAddr, int family) {
- mSourceAddr = sourceAddr;
- mDestinationAddr = destAddr;
- mLocalInnerAddress = new LinkAddress(localInnerAddr);
- mFamily = family;
- }
-
- @Before
- public void setUp() throws Exception {
- mMockNetd = mock(INetd.class);
- mMockPkgMgr = mock(PackageManager.class);
- mMockIpSecSrvConfig = mock(IpSecService.IpSecServiceConfiguration.class);
- mIpSecService = new IpSecService(mTestContext, mMockIpSecSrvConfig);
-
- // Injecting mock netd
- when(mMockIpSecSrvConfig.getNetdInstance()).thenReturn(mMockNetd);
-
- // PackageManager should always return true (feature flag tests in IpSecServiceTest)
- when(mMockPkgMgr.hasSystemFeature(anyString())).thenReturn(true);
-
- // A package granted the AppOp for MANAGE_IPSEC_TUNNELS will be MODE_ALLOWED.
- when(mMockAppOps.noteOp(anyInt(), anyInt(), eq(BLESSED_PACKAGE)))
- .thenReturn(AppOpsManager.MODE_ALLOWED);
- // A system package will not be granted the app op, so this should fall back to
- // a permissions check, which should pass.
- when(mMockAppOps.noteOp(anyInt(), anyInt(), eq(SYSTEM_PACKAGE)))
- .thenReturn(AppOpsManager.MODE_DEFAULT);
- // A mismatch between the package name and the UID will return MODE_IGNORED.
- when(mMockAppOps.noteOp(anyInt(), anyInt(), eq(BAD_PACKAGE)))
- .thenReturn(AppOpsManager.MODE_IGNORED);
- }
-
- //TODO: Add a test to verify SPI.
-
- @Test
- public void testIpSecServiceReserveSpi() throws Exception {
- when(mMockNetd.ipSecAllocateSpi(anyInt(), anyString(), eq(mDestinationAddr), eq(TEST_SPI)))
- .thenReturn(TEST_SPI);
-
- IpSecSpiResponse spiResp =
- mIpSecService.allocateSecurityParameterIndex(
- mDestinationAddr, TEST_SPI, new Binder());
- assertEquals(IpSecManager.Status.OK, spiResp.status);
- assertEquals(TEST_SPI, spiResp.spi);
- }
-
- @Test
- public void testReleaseSecurityParameterIndex() throws Exception {
- when(mMockNetd.ipSecAllocateSpi(anyInt(), anyString(), eq(mDestinationAddr), eq(TEST_SPI)))
- .thenReturn(TEST_SPI);
-
- IpSecSpiResponse spiResp =
- mIpSecService.allocateSecurityParameterIndex(
- mDestinationAddr, TEST_SPI, new Binder());
-
- mIpSecService.releaseSecurityParameterIndex(spiResp.resourceId);
-
- verify(mMockNetd)
- .ipSecDeleteSecurityAssociation(
- eq(mUid),
- anyString(),
- anyString(),
- eq(TEST_SPI),
- anyInt(),
- anyInt(),
- anyInt());
-
- // Verify quota and RefcountedResource objects cleaned up
- IpSecService.UserRecord userRecord = mIpSecService.mUserResourceTracker.getUserRecord(mUid);
- assertEquals(0, userRecord.mSpiQuotaTracker.mCurrent);
- try {
- userRecord.mSpiRecords.getRefcountedResourceOrThrow(spiResp.resourceId);
- fail("Expected IllegalArgumentException on attempt to access deleted resource");
- } catch (IllegalArgumentException expected) {
-
- }
- }
-
- @Test
- public void testSecurityParameterIndexBinderDeath() throws Exception {
- when(mMockNetd.ipSecAllocateSpi(anyInt(), anyString(), eq(mDestinationAddr), eq(TEST_SPI)))
- .thenReturn(TEST_SPI);
-
- IpSecSpiResponse spiResp =
- mIpSecService.allocateSecurityParameterIndex(
- mDestinationAddr, TEST_SPI, new Binder());
-
- IpSecService.UserRecord userRecord = mIpSecService.mUserResourceTracker.getUserRecord(mUid);
- IpSecService.RefcountedResource refcountedRecord =
- userRecord.mSpiRecords.getRefcountedResourceOrThrow(spiResp.resourceId);
-
- refcountedRecord.binderDied();
-
- verify(mMockNetd)
- .ipSecDeleteSecurityAssociation(
- eq(mUid),
- anyString(),
- anyString(),
- eq(TEST_SPI),
- anyInt(),
- anyInt(),
- anyInt());
-
- // Verify quota and RefcountedResource objects cleaned up
- assertEquals(0, userRecord.mSpiQuotaTracker.mCurrent);
- try {
- userRecord.mSpiRecords.getRefcountedResourceOrThrow(spiResp.resourceId);
- fail("Expected IllegalArgumentException on attempt to access deleted resource");
- } catch (IllegalArgumentException expected) {
-
- }
- }
-
- private int getNewSpiResourceId(String remoteAddress, int returnSpi) throws Exception {
- when(mMockNetd.ipSecAllocateSpi(anyInt(), anyString(), anyString(), anyInt()))
- .thenReturn(returnSpi);
-
- IpSecSpiResponse spi =
- mIpSecService.allocateSecurityParameterIndex(
- InetAddresses.parseNumericAddress(remoteAddress).getHostAddress(),
- IpSecManager.INVALID_SECURITY_PARAMETER_INDEX,
- new Binder());
- return spi.resourceId;
- }
-
- private void addDefaultSpisAndRemoteAddrToIpSecConfig(IpSecConfig config) throws Exception {
- config.setSpiResourceId(getNewSpiResourceId(mDestinationAddr, TEST_SPI));
- config.setSourceAddress(mSourceAddr);
- config.setDestinationAddress(mDestinationAddr);
- }
-
- private void addAuthAndCryptToIpSecConfig(IpSecConfig config) throws Exception {
- config.setEncryption(CRYPT_ALGO);
- config.setAuthentication(AUTH_ALGO);
- }
-
- private void addEncapSocketToIpSecConfig(int resourceId, IpSecConfig config) throws Exception {
- config.setEncapType(IpSecTransform.ENCAP_ESPINUDP);
- config.setEncapSocketResourceId(resourceId);
- config.setEncapRemotePort(REMOTE_ENCAP_PORT);
- }
-
- private void verifyTransformNetdCalledForCreatingSA(
- IpSecConfig config, IpSecTransformResponse resp) throws Exception {
- verifyTransformNetdCalledForCreatingSA(config, resp, 0);
- }
-
- private void verifyTransformNetdCalledForCreatingSA(
- IpSecConfig config, IpSecTransformResponse resp, int encapSocketPort) throws Exception {
- IpSecAlgorithm auth = config.getAuthentication();
- IpSecAlgorithm crypt = config.getEncryption();
- IpSecAlgorithm authCrypt = config.getAuthenticatedEncryption();
-
- verify(mMockNetd, times(1))
- .ipSecAddSecurityAssociation(
- eq(mUid),
- eq(config.getMode()),
- eq(config.getSourceAddress()),
- eq(config.getDestinationAddress()),
- eq((config.getNetwork() != null) ? config.getNetwork().netId : 0),
- eq(TEST_SPI),
- eq(0),
- eq(0),
- eq((auth != null) ? auth.getName() : ""),
- eq((auth != null) ? auth.getKey() : new byte[] {}),
- eq((auth != null) ? auth.getTruncationLengthBits() : 0),
- eq((crypt != null) ? crypt.getName() : ""),
- eq((crypt != null) ? crypt.getKey() : new byte[] {}),
- eq((crypt != null) ? crypt.getTruncationLengthBits() : 0),
- eq((authCrypt != null) ? authCrypt.getName() : ""),
- eq((authCrypt != null) ? authCrypt.getKey() : new byte[] {}),
- eq((authCrypt != null) ? authCrypt.getTruncationLengthBits() : 0),
- eq(config.getEncapType()),
- eq(encapSocketPort),
- eq(config.getEncapRemotePort()),
- eq(config.getXfrmInterfaceId()));
- }
-
- @Test
- public void testCreateTransform() throws Exception {
- IpSecConfig ipSecConfig = new IpSecConfig();
- addDefaultSpisAndRemoteAddrToIpSecConfig(ipSecConfig);
- addAuthAndCryptToIpSecConfig(ipSecConfig);
-
- IpSecTransformResponse createTransformResp =
- mIpSecService.createTransform(ipSecConfig, new Binder(), BLESSED_PACKAGE);
- assertEquals(IpSecManager.Status.OK, createTransformResp.status);
-
- verifyTransformNetdCalledForCreatingSA(ipSecConfig, createTransformResp);
- }
-
- @Test
- public void testCreateTransformAead() throws Exception {
- IpSecConfig ipSecConfig = new IpSecConfig();
- addDefaultSpisAndRemoteAddrToIpSecConfig(ipSecConfig);
-
- ipSecConfig.setAuthenticatedEncryption(AEAD_ALGO);
-
- IpSecTransformResponse createTransformResp =
- mIpSecService.createTransform(ipSecConfig, new Binder(), BLESSED_PACKAGE);
- assertEquals(IpSecManager.Status.OK, createTransformResp.status);
-
- verifyTransformNetdCalledForCreatingSA(ipSecConfig, createTransformResp);
- }
-
- @Test
- public void testCreateTransportModeTransformWithEncap() throws Exception {
- IpSecUdpEncapResponse udpSock = mIpSecService.openUdpEncapsulationSocket(0, new Binder());
-
- IpSecConfig ipSecConfig = new IpSecConfig();
- ipSecConfig.setMode(IpSecTransform.MODE_TRANSPORT);
- addDefaultSpisAndRemoteAddrToIpSecConfig(ipSecConfig);
- addAuthAndCryptToIpSecConfig(ipSecConfig);
- addEncapSocketToIpSecConfig(udpSock.resourceId, ipSecConfig);
-
- if (mFamily == AF_INET) {
- IpSecTransformResponse createTransformResp =
- mIpSecService.createTransform(ipSecConfig, new Binder(), BLESSED_PACKAGE);
- assertEquals(IpSecManager.Status.OK, createTransformResp.status);
-
- verifyTransformNetdCalledForCreatingSA(ipSecConfig, createTransformResp, udpSock.port);
- } else {
- try {
- IpSecTransformResponse createTransformResp =
- mIpSecService.createTransform(ipSecConfig, new Binder(), BLESSED_PACKAGE);
- fail("Expected IllegalArgumentException on attempt to use UDP Encap in IPv6");
- } catch (IllegalArgumentException expected) {
- }
- }
- }
-
- @Test
- public void testCreateTunnelModeTransformWithEncap() throws Exception {
- IpSecUdpEncapResponse udpSock = mIpSecService.openUdpEncapsulationSocket(0, new Binder());
-
- IpSecConfig ipSecConfig = new IpSecConfig();
- ipSecConfig.setMode(IpSecTransform.MODE_TUNNEL);
- addDefaultSpisAndRemoteAddrToIpSecConfig(ipSecConfig);
- addAuthAndCryptToIpSecConfig(ipSecConfig);
- addEncapSocketToIpSecConfig(udpSock.resourceId, ipSecConfig);
-
- if (mFamily == AF_INET) {
- IpSecTransformResponse createTransformResp =
- mIpSecService.createTransform(ipSecConfig, new Binder(), BLESSED_PACKAGE);
- assertEquals(IpSecManager.Status.OK, createTransformResp.status);
-
- verifyTransformNetdCalledForCreatingSA(ipSecConfig, createTransformResp, udpSock.port);
- } else {
- try {
- IpSecTransformResponse createTransformResp =
- mIpSecService.createTransform(ipSecConfig, new Binder(), BLESSED_PACKAGE);
- fail("Expected IllegalArgumentException on attempt to use UDP Encap in IPv6");
- } catch (IllegalArgumentException expected) {
- }
- }
- }
-
- @Test
- public void testCreateTwoTransformsWithSameSpis() throws Exception {
- IpSecConfig ipSecConfig = new IpSecConfig();
- addDefaultSpisAndRemoteAddrToIpSecConfig(ipSecConfig);
- addAuthAndCryptToIpSecConfig(ipSecConfig);
-
- IpSecTransformResponse createTransformResp =
- mIpSecService.createTransform(ipSecConfig, new Binder(), BLESSED_PACKAGE);
- assertEquals(IpSecManager.Status.OK, createTransformResp.status);
-
- // Attempting to create transform a second time with the same SPIs should throw an error...
- try {
- mIpSecService.createTransform(ipSecConfig, new Binder(), BLESSED_PACKAGE);
- fail("IpSecService should have thrown an error for reuse of SPI");
- } catch (IllegalStateException expected) {
- }
-
- // ... even if the transform is deleted
- mIpSecService.deleteTransform(createTransformResp.resourceId);
- try {
- mIpSecService.createTransform(ipSecConfig, new Binder(), BLESSED_PACKAGE);
- fail("IpSecService should have thrown an error for reuse of SPI");
- } catch (IllegalStateException expected) {
- }
- }
-
- @Test
- public void testReleaseOwnedSpi() throws Exception {
- IpSecConfig ipSecConfig = new IpSecConfig();
- addDefaultSpisAndRemoteAddrToIpSecConfig(ipSecConfig);
- addAuthAndCryptToIpSecConfig(ipSecConfig);
-
- IpSecTransformResponse createTransformResp =
- mIpSecService.createTransform(ipSecConfig, new Binder(), BLESSED_PACKAGE);
- IpSecService.UserRecord userRecord = mIpSecService.mUserResourceTracker.getUserRecord(mUid);
- assertEquals(1, userRecord.mSpiQuotaTracker.mCurrent);
- mIpSecService.releaseSecurityParameterIndex(ipSecConfig.getSpiResourceId());
- verify(mMockNetd, times(0))
- .ipSecDeleteSecurityAssociation(
- eq(mUid),
- anyString(),
- anyString(),
- eq(TEST_SPI),
- anyInt(),
- anyInt(),
- anyInt());
- // quota is not released until the SPI is released by the Transform
- assertEquals(1, userRecord.mSpiQuotaTracker.mCurrent);
- }
-
- @Test
- public void testDeleteTransform() throws Exception {
- IpSecConfig ipSecConfig = new IpSecConfig();
- addDefaultSpisAndRemoteAddrToIpSecConfig(ipSecConfig);
- addAuthAndCryptToIpSecConfig(ipSecConfig);
-
- IpSecTransformResponse createTransformResp =
- mIpSecService.createTransform(ipSecConfig, new Binder(), BLESSED_PACKAGE);
- mIpSecService.deleteTransform(createTransformResp.resourceId);
-
- verify(mMockNetd, times(1))
- .ipSecDeleteSecurityAssociation(
- eq(mUid),
- anyString(),
- anyString(),
- eq(TEST_SPI),
- anyInt(),
- anyInt(),
- anyInt());
-
- // Verify quota and RefcountedResource objects cleaned up
- IpSecService.UserRecord userRecord = mIpSecService.mUserResourceTracker.getUserRecord(mUid);
- assertEquals(0, userRecord.mTransformQuotaTracker.mCurrent);
- assertEquals(1, userRecord.mSpiQuotaTracker.mCurrent);
-
- mIpSecService.releaseSecurityParameterIndex(ipSecConfig.getSpiResourceId());
- // Verify that ipSecDeleteSa was not called when the SPI was released because the
- // ownedByTransform property should prevent it; (note, the called count is cumulative).
- verify(mMockNetd, times(1))
- .ipSecDeleteSecurityAssociation(
- anyInt(),
- anyString(),
- anyString(),
- anyInt(),
- anyInt(),
- anyInt(),
- anyInt());
- assertEquals(0, userRecord.mSpiQuotaTracker.mCurrent);
-
- try {
- userRecord.mTransformRecords.getRefcountedResourceOrThrow(
- createTransformResp.resourceId);
- fail("Expected IllegalArgumentException on attempt to access deleted resource");
- } catch (IllegalArgumentException expected) {
-
- }
- }
-
- @Test
- public void testTransportModeTransformBinderDeath() throws Exception {
- IpSecConfig ipSecConfig = new IpSecConfig();
- addDefaultSpisAndRemoteAddrToIpSecConfig(ipSecConfig);
- addAuthAndCryptToIpSecConfig(ipSecConfig);
-
- IpSecTransformResponse createTransformResp =
- mIpSecService.createTransform(ipSecConfig, new Binder(), BLESSED_PACKAGE);
-
- IpSecService.UserRecord userRecord = mIpSecService.mUserResourceTracker.getUserRecord(mUid);
- IpSecService.RefcountedResource refcountedRecord =
- userRecord.mTransformRecords.getRefcountedResourceOrThrow(
- createTransformResp.resourceId);
-
- refcountedRecord.binderDied();
-
- verify(mMockNetd)
- .ipSecDeleteSecurityAssociation(
- eq(mUid),
- anyString(),
- anyString(),
- eq(TEST_SPI),
- anyInt(),
- anyInt(),
- anyInt());
-
- // Verify quota and RefcountedResource objects cleaned up
- assertEquals(0, userRecord.mTransformQuotaTracker.mCurrent);
- try {
- userRecord.mTransformRecords.getRefcountedResourceOrThrow(
- createTransformResp.resourceId);
- fail("Expected IllegalArgumentException on attempt to access deleted resource");
- } catch (IllegalArgumentException expected) {
-
- }
- }
-
- @Test
- public void testApplyTransportModeTransform() throws Exception {
- verifyApplyTransportModeTransformCommon(false);
- }
-
- @Test
- public void testApplyTransportModeTransformReleasedSpi() throws Exception {
- verifyApplyTransportModeTransformCommon(true);
- }
-
- public void verifyApplyTransportModeTransformCommon(
- boolean closeSpiBeforeApply) throws Exception {
- IpSecConfig ipSecConfig = new IpSecConfig();
- addDefaultSpisAndRemoteAddrToIpSecConfig(ipSecConfig);
- addAuthAndCryptToIpSecConfig(ipSecConfig);
-
- IpSecTransformResponse createTransformResp =
- mIpSecService.createTransform(ipSecConfig, new Binder(), BLESSED_PACKAGE);
-
- if (closeSpiBeforeApply) {
- mIpSecService.releaseSecurityParameterIndex(ipSecConfig.getSpiResourceId());
- }
-
- Socket socket = new Socket();
- socket.bind(null);
- ParcelFileDescriptor pfd = ParcelFileDescriptor.fromSocket(socket);
-
- int resourceId = createTransformResp.resourceId;
- mIpSecService.applyTransportModeTransform(pfd, IpSecManager.DIRECTION_OUT, resourceId);
-
- verify(mMockNetd)
- .ipSecApplyTransportModeTransform(
- eq(pfd),
- eq(mUid),
- eq(IpSecManager.DIRECTION_OUT),
- anyString(),
- anyString(),
- eq(TEST_SPI));
- }
-
- @Test
- public void testApplyTransportModeTransformWithClosedSpi() throws Exception {
- IpSecConfig ipSecConfig = new IpSecConfig();
- addDefaultSpisAndRemoteAddrToIpSecConfig(ipSecConfig);
- addAuthAndCryptToIpSecConfig(ipSecConfig);
-
- IpSecTransformResponse createTransformResp =
- mIpSecService.createTransform(ipSecConfig, new Binder(), BLESSED_PACKAGE);
-
- // Close SPI record
- mIpSecService.releaseSecurityParameterIndex(ipSecConfig.getSpiResourceId());
-
- Socket socket = new Socket();
- socket.bind(null);
- ParcelFileDescriptor pfd = ParcelFileDescriptor.fromSocket(socket);
-
- int resourceId = createTransformResp.resourceId;
- mIpSecService.applyTransportModeTransform(pfd, IpSecManager.DIRECTION_OUT, resourceId);
-
- verify(mMockNetd)
- .ipSecApplyTransportModeTransform(
- eq(pfd),
- eq(mUid),
- eq(IpSecManager.DIRECTION_OUT),
- anyString(),
- anyString(),
- eq(TEST_SPI));
- }
-
- @Test
- public void testRemoveTransportModeTransform() throws Exception {
- Socket socket = new Socket();
- socket.bind(null);
- ParcelFileDescriptor pfd = ParcelFileDescriptor.fromSocket(socket);
- mIpSecService.removeTransportModeTransforms(pfd);
-
- verify(mMockNetd).ipSecRemoveTransportModeTransform(pfd);
- }
-
- private IpSecTunnelInterfaceResponse createAndValidateTunnel(
- String localAddr, String remoteAddr, String pkgName) throws Exception {
- final InterfaceConfigurationParcel config = new InterfaceConfigurationParcel();
- config.flags = new String[] {IF_STATE_DOWN};
- when(mMockNetd.interfaceGetCfg(anyString())).thenReturn(config);
- IpSecTunnelInterfaceResponse createTunnelResp =
- mIpSecService.createTunnelInterface(
- mSourceAddr, mDestinationAddr, fakeNetwork, new Binder(), pkgName);
-
- assertNotNull(createTunnelResp);
- assertEquals(IpSecManager.Status.OK, createTunnelResp.status);
- for (int direction : new int[] {DIRECTION_IN, DIRECTION_OUT, DIRECTION_FWD}) {
- for (int selAddrFamily : ADDRESS_FAMILIES) {
- verify(mMockNetd).ipSecAddSecurityPolicy(
- eq(mUid),
- eq(selAddrFamily),
- eq(direction),
- anyString(),
- anyString(),
- eq(0),
- anyInt(), // iKey/oKey
- anyInt(), // mask
- eq(createTunnelResp.resourceId));
- }
- }
-
- return createTunnelResp;
- }
-
- @Test
- public void testCreateTunnelInterface() throws Exception {
- IpSecTunnelInterfaceResponse createTunnelResp =
- createAndValidateTunnel(mSourceAddr, mDestinationAddr, BLESSED_PACKAGE);
-
- // Check that we have stored the tracking object, and retrieve it
- IpSecService.UserRecord userRecord = mIpSecService.mUserResourceTracker.getUserRecord(mUid);
- IpSecService.RefcountedResource refcountedRecord =
- userRecord.mTunnelInterfaceRecords.getRefcountedResourceOrThrow(
- createTunnelResp.resourceId);
-
- assertEquals(1, userRecord.mTunnelQuotaTracker.mCurrent);
- verify(mMockNetd)
- .ipSecAddTunnelInterface(
- eq(createTunnelResp.interfaceName),
- eq(mSourceAddr),
- eq(mDestinationAddr),
- anyInt(),
- anyInt(),
- anyInt());
- verify(mMockNetd).interfaceSetCfg(argThat(
- config -> Arrays.asList(config.flags).contains(IF_STATE_UP)));
- }
-
- @Test
- public void testDeleteTunnelInterface() throws Exception {
- IpSecTunnelInterfaceResponse createTunnelResp =
- createAndValidateTunnel(mSourceAddr, mDestinationAddr, BLESSED_PACKAGE);
-
- IpSecService.UserRecord userRecord = mIpSecService.mUserResourceTracker.getUserRecord(mUid);
-
- mIpSecService.deleteTunnelInterface(createTunnelResp.resourceId, BLESSED_PACKAGE);
-
- // Verify quota and RefcountedResource objects cleaned up
- assertEquals(0, userRecord.mTunnelQuotaTracker.mCurrent);
- verify(mMockNetd).ipSecRemoveTunnelInterface(eq(createTunnelResp.interfaceName));
- try {
- userRecord.mTunnelInterfaceRecords.getRefcountedResourceOrThrow(
- createTunnelResp.resourceId);
- fail("Expected IllegalArgumentException on attempt to access deleted resource");
- } catch (IllegalArgumentException expected) {
- }
- }
-
- private Network createFakeUnderlyingNetwork(String interfaceName) {
- final Network fakeNetwork = new Network(1000);
- final LinkProperties fakeLp = new LinkProperties();
- fakeLp.setInterfaceName(interfaceName);
- when(mMockConnectivityMgr.getLinkProperties(eq(fakeNetwork))).thenReturn(fakeLp);
- return fakeNetwork;
- }
-
- @Test
- public void testSetNetworkForTunnelInterface() throws Exception {
- final IpSecTunnelInterfaceResponse createTunnelResp =
- createAndValidateTunnel(mSourceAddr, mDestinationAddr, BLESSED_PACKAGE);
- final Network newFakeNetwork = createFakeUnderlyingNetwork("newFakeNetworkInterface");
- final int tunnelIfaceResourceId = createTunnelResp.resourceId;
- mIpSecService.setNetworkForTunnelInterface(
- tunnelIfaceResourceId, newFakeNetwork, BLESSED_PACKAGE);
-
- final IpSecService.UserRecord userRecord =
- mIpSecService.mUserResourceTracker.getUserRecord(mUid);
- assertEquals(1, userRecord.mTunnelQuotaTracker.mCurrent);
-
- final TunnelInterfaceRecord tunnelInterfaceInfo =
- userRecord.mTunnelInterfaceRecords.getResourceOrThrow(tunnelIfaceResourceId);
- assertEquals(newFakeNetwork, tunnelInterfaceInfo.getUnderlyingNetwork());
- }
-
- @Test
- public void testSetNetworkForTunnelInterfaceFailsForInvalidResourceId() throws Exception {
- final IpSecTunnelInterfaceResponse createTunnelResp =
- createAndValidateTunnel(mSourceAddr, mDestinationAddr, BLESSED_PACKAGE);
- final Network newFakeNetwork = new Network(1000);
-
- try {
- mIpSecService.setNetworkForTunnelInterface(
- IpSecManager.INVALID_RESOURCE_ID, newFakeNetwork, BLESSED_PACKAGE);
- fail("Expected an IllegalArgumentException for invalid resource ID.");
- } catch (IllegalArgumentException expected) {
- }
- }
-
- @Test
- public void testSetNetworkForTunnelInterfaceFailsWhenSettingTunnelNetwork() throws Exception {
- final IpSecTunnelInterfaceResponse createTunnelResp =
- createAndValidateTunnel(mSourceAddr, mDestinationAddr, BLESSED_PACKAGE);
- final int tunnelIfaceResourceId = createTunnelResp.resourceId;
- final IpSecService.UserRecord userRecord =
- mIpSecService.mUserResourceTracker.getUserRecord(mUid);
- final TunnelInterfaceRecord tunnelInterfaceInfo =
- userRecord.mTunnelInterfaceRecords.getResourceOrThrow(tunnelIfaceResourceId);
-
- final Network newFakeNetwork =
- createFakeUnderlyingNetwork(tunnelInterfaceInfo.getInterfaceName());
-
- try {
- mIpSecService.setNetworkForTunnelInterface(
- tunnelIfaceResourceId, newFakeNetwork, BLESSED_PACKAGE);
- fail(
- "Expected an IllegalArgumentException because the underlying network is the"
- + " network being exposed by this tunnel.");
- } catch (IllegalArgumentException expected) {
- }
- }
-
- @Test
- public void testTunnelInterfaceBinderDeath() throws Exception {
- IpSecTunnelInterfaceResponse createTunnelResp =
- createAndValidateTunnel(mSourceAddr, mDestinationAddr, BLESSED_PACKAGE);
-
- IpSecService.UserRecord userRecord = mIpSecService.mUserResourceTracker.getUserRecord(mUid);
- IpSecService.RefcountedResource refcountedRecord =
- userRecord.mTunnelInterfaceRecords.getRefcountedResourceOrThrow(
- createTunnelResp.resourceId);
-
- refcountedRecord.binderDied();
-
- // Verify quota and RefcountedResource objects cleaned up
- assertEquals(0, userRecord.mTunnelQuotaTracker.mCurrent);
- verify(mMockNetd).ipSecRemoveTunnelInterface(eq(createTunnelResp.interfaceName));
- try {
- userRecord.mTunnelInterfaceRecords.getRefcountedResourceOrThrow(
- createTunnelResp.resourceId);
- fail("Expected IllegalArgumentException on attempt to access deleted resource");
- } catch (IllegalArgumentException expected) {
- }
- }
-
- @Test
- public void testApplyTunnelModeTransformOutbound() throws Exception {
- verifyApplyTunnelModeTransformCommon(false /* closeSpiBeforeApply */, DIRECTION_OUT);
- }
-
- @Test
- public void testApplyTunnelModeTransformOutboundNonNetworkStack() throws Exception {
- mTestContext.setAllowedPermissions(android.Manifest.permission.MANAGE_IPSEC_TUNNELS);
- verifyApplyTunnelModeTransformCommon(false /* closeSpiBeforeApply */, DIRECTION_OUT);
- }
-
- @Test
- public void testApplyTunnelModeTransformOutboundReleasedSpi() throws Exception {
- verifyApplyTunnelModeTransformCommon(true /* closeSpiBeforeApply */, DIRECTION_OUT);
- }
-
- @Test
- public void testApplyTunnelModeTransformInbound() throws Exception {
- verifyApplyTunnelModeTransformCommon(true /* closeSpiBeforeApply */, DIRECTION_IN);
- }
-
- @Test
- public void testApplyTunnelModeTransformInboundNonNetworkStack() throws Exception {
- mTestContext.setAllowedPermissions(android.Manifest.permission.MANAGE_IPSEC_TUNNELS);
- verifyApplyTunnelModeTransformCommon(true /* closeSpiBeforeApply */, DIRECTION_IN);
- }
-
- @Test
- public void testApplyTunnelModeTransformForward() throws Exception {
- verifyApplyTunnelModeTransformCommon(true /* closeSpiBeforeApply */, DIRECTION_FWD);
- }
-
- @Test
- public void testApplyTunnelModeTransformForwardNonNetworkStack() throws Exception {
- mTestContext.setAllowedPermissions(android.Manifest.permission.MANAGE_IPSEC_TUNNELS);
-
- try {
- verifyApplyTunnelModeTransformCommon(true /* closeSpiBeforeApply */, DIRECTION_FWD);
- fail("Expected security exception due to use of forward policies without NETWORK_STACK"
- + " or MAINLINE_NETWORK_STACK permission");
- } catch (SecurityException expected) {
- }
- }
-
- public void verifyApplyTunnelModeTransformCommon(boolean closeSpiBeforeApply, int direction)
- throws Exception {
- IpSecConfig ipSecConfig = new IpSecConfig();
- ipSecConfig.setMode(IpSecTransform.MODE_TUNNEL);
- addDefaultSpisAndRemoteAddrToIpSecConfig(ipSecConfig);
- addAuthAndCryptToIpSecConfig(ipSecConfig);
-
- IpSecTransformResponse createTransformResp =
- mIpSecService.createTransform(ipSecConfig, new Binder(), BLESSED_PACKAGE);
- IpSecTunnelInterfaceResponse createTunnelResp =
- createAndValidateTunnel(mSourceAddr, mDestinationAddr, BLESSED_PACKAGE);
-
- if (closeSpiBeforeApply) {
- mIpSecService.releaseSecurityParameterIndex(ipSecConfig.getSpiResourceId());
- }
-
- int transformResourceId = createTransformResp.resourceId;
- int tunnelResourceId = createTunnelResp.resourceId;
- mIpSecService.applyTunnelModeTransform(
- tunnelResourceId, direction, transformResourceId, BLESSED_PACKAGE);
-
- for (int selAddrFamily : ADDRESS_FAMILIES) {
- verify(mMockNetd)
- .ipSecUpdateSecurityPolicy(
- eq(mUid),
- eq(selAddrFamily),
- eq(direction),
- anyString(),
- anyString(),
- eq(direction == DIRECTION_OUT ? TEST_SPI : 0),
- anyInt(), // iKey/oKey
- anyInt(), // mask
- eq(tunnelResourceId));
- }
-
- ipSecConfig.setXfrmInterfaceId(tunnelResourceId);
- verifyTransformNetdCalledForCreatingSA(ipSecConfig, createTransformResp);
- }
-
-
- @Test
- public void testApplyTunnelModeTransformWithClosedSpi() throws Exception {
- IpSecConfig ipSecConfig = new IpSecConfig();
- ipSecConfig.setMode(IpSecTransform.MODE_TUNNEL);
- addDefaultSpisAndRemoteAddrToIpSecConfig(ipSecConfig);
- addAuthAndCryptToIpSecConfig(ipSecConfig);
-
- IpSecTransformResponse createTransformResp =
- mIpSecService.createTransform(ipSecConfig, new Binder(), BLESSED_PACKAGE);
- IpSecTunnelInterfaceResponse createTunnelResp =
- createAndValidateTunnel(mSourceAddr, mDestinationAddr, BLESSED_PACKAGE);
-
- // Close SPI record
- mIpSecService.releaseSecurityParameterIndex(ipSecConfig.getSpiResourceId());
-
- int transformResourceId = createTransformResp.resourceId;
- int tunnelResourceId = createTunnelResp.resourceId;
- mIpSecService.applyTunnelModeTransform(
- tunnelResourceId, IpSecManager.DIRECTION_OUT, transformResourceId, BLESSED_PACKAGE);
-
- for (int selAddrFamily : ADDRESS_FAMILIES) {
- verify(mMockNetd)
- .ipSecUpdateSecurityPolicy(
- eq(mUid),
- eq(selAddrFamily),
- eq(IpSecManager.DIRECTION_OUT),
- anyString(),
- anyString(),
- eq(TEST_SPI),
- anyInt(), // iKey/oKey
- anyInt(), // mask
- eq(tunnelResourceId));
- }
-
- ipSecConfig.setXfrmInterfaceId(tunnelResourceId);
- verifyTransformNetdCalledForCreatingSA(ipSecConfig, createTransformResp);
- }
-
- @Test
- public void testAddRemoveAddressFromTunnelInterface() throws Exception {
- for (String pkgName : new String[] {BLESSED_PACKAGE, SYSTEM_PACKAGE}) {
- IpSecTunnelInterfaceResponse createTunnelResp =
- createAndValidateTunnel(mSourceAddr, mDestinationAddr, pkgName);
- mIpSecService.addAddressToTunnelInterface(
- createTunnelResp.resourceId, mLocalInnerAddress, pkgName);
- verify(mMockNetd, times(1))
- .interfaceAddAddress(
- eq(createTunnelResp.interfaceName),
- eq(mLocalInnerAddress.getAddress().getHostAddress()),
- eq(mLocalInnerAddress.getPrefixLength()));
- mIpSecService.removeAddressFromTunnelInterface(
- createTunnelResp.resourceId, mLocalInnerAddress, pkgName);
- verify(mMockNetd, times(1))
- .interfaceDelAddress(
- eq(createTunnelResp.interfaceName),
- eq(mLocalInnerAddress.getAddress().getHostAddress()),
- eq(mLocalInnerAddress.getPrefixLength()));
- mIpSecService.deleteTunnelInterface(createTunnelResp.resourceId, pkgName);
- }
- }
-
- @Ignore
- @Test
- public void testAddTunnelFailsForBadPackageName() throws Exception {
- try {
- IpSecTunnelInterfaceResponse createTunnelResp =
- createAndValidateTunnel(mSourceAddr, mDestinationAddr, BAD_PACKAGE);
- fail("Expected a SecurityException for badPackage.");
- } catch (SecurityException expected) {
- }
- }
-
- @Test
- public void testFeatureFlagVerification() throws Exception {
- when(mMockPkgMgr.hasSystemFeature(eq(PackageManager.FEATURE_IPSEC_TUNNELS)))
- .thenReturn(false);
-
- try {
- String addr = Inet4Address.getLoopbackAddress().getHostAddress();
- mIpSecService.createTunnelInterface(
- addr, addr, new Network(0), new Binder(), BLESSED_PACKAGE);
- fail("Expected UnsupportedOperationException for disabled feature");
- } catch (UnsupportedOperationException expected) {
- }
- }
-}