Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 01b46f8f authored by Yan Yan's avatar Yan Yan Committed by android-build-merger
Browse files

Merge changes I10c01f2b,Ie05bc535 am: 277d42a0 am: 47a589c9

am: 73d9c32a

Change-Id: I074056f861332835adaed32ad7d43ed36667ffa3
parents b8027a44 73d9c32a
Loading
Loading
Loading
Loading
+35 −0
Original line number Diff line number Diff line
@@ -19,6 +19,8 @@ package com.android.server;
import static android.Manifest.permission.DUMP;
import static android.net.IpSecManager.INVALID_RESOURCE_ID;
import static android.system.OsConstants.AF_INET;
import static android.system.OsConstants.AF_INET6;
import static android.system.OsConstants.AF_UNSPEC;
import static android.system.OsConstants.EINVAL;
import static android.system.OsConstants.IPPROTO_UDP;
import static android.system.OsConstants.SOCK_DGRAM;
@@ -63,6 +65,8 @@ import com.android.internal.util.Preconditions;
import java.io.FileDescriptor;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;
@@ -1426,6 +1430,17 @@ public class IpSecService extends IIpSecService.Stub {
                        + "or Encryption algorithms");
    }

    private int getFamily(String inetAddress) {
        int family = AF_UNSPEC;
        InetAddress checkAddress = NetworkUtils.numericToInetAddress(inetAddress);
        if (checkAddress instanceof Inet4Address) {
            family = AF_INET;
        } else if (checkAddress instanceof Inet6Address) {
            family = AF_INET6;
        }
        return family;
    }

    /**
     * Checks an IpSecConfig parcel to ensure that the contents are sane and throws an
     * IllegalArgumentException if they are not.
@@ -1479,6 +1494,26 @@ public class IpSecService extends IIpSecService.Stub {
        // Require a valid source address for all transforms.
        checkInetAddress(config.getSourceAddress());

        // Check to ensure source and destination have the same address family.
        String sourceAddress = config.getSourceAddress();
        String destinationAddress = config.getDestinationAddress();
        int sourceFamily = getFamily(sourceAddress);
        int destinationFamily = getFamily(destinationAddress);
        if (sourceFamily != destinationFamily) {
            throw new IllegalArgumentException(
                    "Source address ("
                            + sourceAddress
                            + ") and destination address ("
                            + destinationAddress
                            + ") have different address families.");
        }

        // Throw an error if UDP Encapsulation is not used in IPv4.
        if (config.getEncapType() != IpSecTransform.ENCAP_NONE && sourceFamily != AF_INET) {
            throw new IllegalArgumentException(
                    "UDP Encapsulation is not supported for this address family");
        }

        switch (config.getMode()) {
            case IpSecTransform.MODE_TRANSPORT:
                break;
+108 −48
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package com.android.server;

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;
@@ -34,8 +36,10 @@ 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.Network;
import android.net.NetworkUtils;
@@ -62,16 +66,17 @@ public class IpSecServiceParameterizedTest {

    private static final int TEST_SPI = 0xD1201D;

    private final String mDestinationAddr;
    private final String mSourceAddr;
    private final String mDestinationAddr;
    private final LinkAddress mLocalInnerAddress;
    private final int mFamily;

    @Parameterized.Parameters
    public static Collection ipSecConfigs() {
        return Arrays.asList(
                new Object[][] {
                {"1.2.3.4", "8.8.4.4", "10.0.1.1/24"},
                {"2601::2", "2601::10", "2001:db8::1/64"}
                {"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}
        });
    }

@@ -129,12 +134,14 @@ public class IpSecServiceParameterizedTest {
            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;

    public IpSecServiceParameterizedTest(
            String sourceAddr, String destAddr, String localInnerAddr) {
            String sourceAddr, String destAddr, String localInnerAddr, int family) {
        mSourceAddr = sourceAddr;
        mDestinationAddr = destAddr;
        mLocalInnerAddress = new LinkAddress(localInnerAddr);
        mFamily = family;
    }

    @Before
@@ -157,6 +164,8 @@ public class IpSecServiceParameterizedTest {
            .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)))
@@ -257,6 +266,47 @@ public class IpSecServiceParameterizedTest {
        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()));
    }

    @Test
    public void testCreateTransform() throws Exception {
        IpSecConfig ipSecConfig = new IpSecConfig();
@@ -267,28 +317,7 @@ public class IpSecServiceParameterizedTest {
                mIpSecService.createTransform(ipSecConfig, new Binder(), "blessedPackage");
        assertEquals(IpSecManager.Status.OK, createTransformResp.status);

        verify(mMockNetd)
                .ipSecAddSecurityAssociation(
                        eq(mUid),
                        anyInt(),
                        anyString(),
                        anyString(),
                        anyInt(),
                        eq(TEST_SPI),
                        anyInt(),
                        anyInt(),
                        eq(IpSecAlgorithm.AUTH_HMAC_SHA256),
                        eq(AUTH_KEY),
                        anyInt(),
                        eq(IpSecAlgorithm.CRYPT_AES_CBC),
                        eq(CRYPT_KEY),
                        anyInt(),
                        eq(""),
                        eq(new byte[] {}),
                        eq(0),
                        anyInt(),
                        anyInt(),
                        anyInt());
        verifyTransformNetdCalledForCreatingSA(ipSecConfig, createTransformResp);
    }

    @Test
@@ -302,28 +331,59 @@ public class IpSecServiceParameterizedTest {
                mIpSecService.createTransform(ipSecConfig, new Binder(), "blessedPackage");
        assertEquals(IpSecManager.Status.OK, createTransformResp.status);

        verify(mMockNetd)
                .ipSecAddSecurityAssociation(
                        eq(mUid),
                        anyInt(),
                        anyString(),
                        anyString(),
                        anyInt(),
                        eq(TEST_SPI),
                        anyInt(),
                        anyInt(),
                        eq(""),
                        eq(new byte[] {}),
                        eq(0),
                        eq(""),
                        eq(new byte[] {}),
                        eq(0),
                        eq(IpSecAlgorithm.AUTH_CRYPT_AES_GCM),
                        eq(AEAD_KEY),
                        anyInt(),
                        anyInt(),
                        anyInt(),
                        anyInt());
        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(), "blessedPackage");
            assertEquals(IpSecManager.Status.OK, createTransformResp.status);

            verifyTransformNetdCalledForCreatingSA(ipSecConfig, createTransformResp, udpSock.port);
        } else {
            try {
                IpSecTransformResponse createTransformResp =
                        mIpSecService.createTransform(ipSecConfig, new Binder(), "blessedPackage");
                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(), "blessedPackage");
            assertEquals(IpSecManager.Status.OK, createTransformResp.status);

            verifyTransformNetdCalledForCreatingSA(ipSecConfig, createTransformResp, udpSock.port);
        } else {
            try {
                IpSecTransformResponse createTransformResp =
                        mIpSecService.createTransform(ipSecConfig, new Binder(), "blessedPackage");
                fail("Expected IllegalArgumentException on attempt to use UDP Encap in IPv6");
            } catch (IllegalArgumentException expected) {
            }
        }
    }

    @Test