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

Commit 44d474d7 authored by Lorenzo Colitti's avatar Lorenzo Colitti Committed by Android (Google) Code Review
Browse files

Merge "Add IPsec checks for IPSEC_TUNNEL feature" into qt-dev

parents 7339b6cf e265d5f9
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -19,11 +19,13 @@ import static com.android.internal.util.Preconditions.checkNotNull;

import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.RequiresFeature;
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.annotation.SystemService;
import android.annotation.TestApi;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Binder;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
@@ -749,6 +751,7 @@ public final class IpSecManager {
         * @hide
         */
        @SystemApi
        @RequiresFeature(PackageManager.FEATURE_IPSEC_TUNNELS)
        @RequiresPermission(android.Manifest.permission.MANAGE_IPSEC_TUNNELS)
        public void addAddress(@NonNull InetAddress address, int prefixLen) throws IOException {
            try {
@@ -771,6 +774,7 @@ public final class IpSecManager {
         * @hide
         */
        @SystemApi
        @RequiresFeature(PackageManager.FEATURE_IPSEC_TUNNELS)
        @RequiresPermission(android.Manifest.permission.MANAGE_IPSEC_TUNNELS)
        public void removeAddress(@NonNull InetAddress address, int prefixLen) throws IOException {
            try {
@@ -886,6 +890,7 @@ public final class IpSecManager {
     */
    @SystemApi
    @NonNull
    @RequiresFeature(PackageManager.FEATURE_IPSEC_TUNNELS)
    @RequiresPermission(android.Manifest.permission.MANAGE_IPSEC_TUNNELS)
    public IpSecTunnelInterface createIpSecTunnelInterface(@NonNull InetAddress localAddress,
            @NonNull InetAddress remoteAddress, @NonNull Network underlyingNetwork)
@@ -916,6 +921,7 @@ public final class IpSecManager {
     * @hide
     */
    @SystemApi
    @RequiresFeature(PackageManager.FEATURE_IPSEC_TUNNELS)
    @RequiresPermission(android.Manifest.permission.MANAGE_IPSEC_TUNNELS)
    public void applyTunnelModeTransform(@NonNull IpSecTunnelInterface tunnel,
            @PolicyDirection int direction, @NonNull IpSecTransform transform) throws IOException {
+3 −0
Original line number Diff line number Diff line
@@ -21,9 +21,11 @@ import static com.android.internal.util.Preconditions.checkNotNull;

import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.RequiresFeature;
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
@@ -483,6 +485,7 @@ public final class IpSecTransform implements AutoCloseable {
         */
        @SystemApi
        @NonNull
        @RequiresFeature(PackageManager.FEATURE_IPSEC_TUNNELS)
        @RequiresPermission(android.Manifest.permission.MANAGE_IPSEC_TUNNELS)
        public IpSecTransform buildTunnelModeTransform(
                @NonNull InetAddress sourceAddress,
+13 −7
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ import static com.android.internal.util.Preconditions.checkNotNull;
import android.annotation.NonNull;
import android.app.AppOpsManager;
import android.content.Context;
import android.content.pm.PackageManager;
import android.net.IIpSecService;
import android.net.INetd;
import android.net.IpSecAlgorithm;
@@ -1276,7 +1277,7 @@ public class IpSecService extends IIpSecService.Stub {
    public synchronized IpSecTunnelInterfaceResponse createTunnelInterface(
            String localAddr, String remoteAddr, Network underlyingNetwork, IBinder binder,
            String callingPackage) {
        enforceTunnelPermissions(callingPackage);
        enforceTunnelFeatureAndPermissions(callingPackage);
        checkNotNull(binder, "Null Binder passed to createTunnelInterface");
        checkNotNull(underlyingNetwork, "No underlying network was specified");
        checkInetAddress(localAddr);
@@ -1362,7 +1363,7 @@ public class IpSecService extends IIpSecService.Stub {
    @Override
    public synchronized void addAddressToTunnelInterface(
            int tunnelResourceId, LinkAddress localAddr, String callingPackage) {
        enforceTunnelPermissions(callingPackage);
        enforceTunnelFeatureAndPermissions(callingPackage);
        UserRecord userRecord = mUserResourceTracker.getUserRecord(Binder.getCallingUid());

        // Get tunnelInterface record; if no such interface is found, will throw
@@ -1391,7 +1392,7 @@ public class IpSecService extends IIpSecService.Stub {
    @Override
    public synchronized void removeAddressFromTunnelInterface(
            int tunnelResourceId, LinkAddress localAddr, String callingPackage) {
        enforceTunnelPermissions(callingPackage);
        enforceTunnelFeatureAndPermissions(callingPackage);

        UserRecord userRecord = mUserResourceTracker.getUserRecord(Binder.getCallingUid());
        // Get tunnelInterface record; if no such interface is found, will throw
@@ -1420,7 +1421,7 @@ public class IpSecService extends IIpSecService.Stub {
    @Override
    public synchronized void deleteTunnelInterface(
            int resourceId, String callingPackage) throws RemoteException {
        enforceTunnelPermissions(callingPackage);
        enforceTunnelFeatureAndPermissions(callingPackage);
        UserRecord userRecord = mUserResourceTracker.getUserRecord(Binder.getCallingUid());
        releaseResource(userRecord.mTunnelInterfaceRecords, resourceId);
    }
@@ -1549,7 +1550,12 @@ public class IpSecService extends IIpSecService.Stub {

    private static final String TUNNEL_OP = AppOpsManager.OPSTR_MANAGE_IPSEC_TUNNELS;

    private void enforceTunnelPermissions(String callingPackage) {
    private void enforceTunnelFeatureAndPermissions(String callingPackage) {
        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_IPSEC_TUNNELS)) {
            throw new UnsupportedOperationException(
                    "IPsec Tunnel Mode requires PackageManager.FEATURE_IPSEC_TUNNELS");
        }

        checkNotNull(callingPackage, "Null calling package cannot create IpSec tunnels");
        switch (getAppOpsManager().noteOp(TUNNEL_OP, Binder.getCallingUid(), callingPackage)) {
            case AppOpsManager.MODE_DEFAULT:
@@ -1621,7 +1627,7 @@ public class IpSecService extends IIpSecService.Stub {
            IpSecConfig c, IBinder binder, String callingPackage) throws RemoteException {
        checkNotNull(c);
        if (c.getMode() == IpSecTransform.MODE_TUNNEL) {
            enforceTunnelPermissions(callingPackage);
            enforceTunnelFeatureAndPermissions(callingPackage);
        }
        checkIpSecConfig(c);
        checkNotNull(binder, "Null Binder passed to createTransform");
@@ -1729,7 +1735,7 @@ public class IpSecService extends IIpSecService.Stub {
    public synchronized void applyTunnelModeTransform(
            int tunnelResourceId, int direction,
            int transformResourceId, String callingPackage) throws RemoteException {
        enforceTunnelPermissions(callingPackage);
        enforceTunnelFeatureAndPermissions(callingPackage);
        checkDirection(direction);

        int callingUid = Binder.getCallingUid();
+27 −0
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@ import static org.mockito.Mockito.when;

import android.app.AppOpsManager;
import android.content.Context;
import android.content.pm.PackageManager;
import android.net.INetd;
import android.net.IpSecAlgorithm;
import android.net.IpSecConfig;
@@ -57,6 +58,7 @@ 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;
@@ -118,6 +120,11 @@ public class IpSecServiceParameterizedTest {
            }
        }

        @Override
        public PackageManager getPackageManager() {
            return mMockPkgMgr;
        }

        @Override
        public void enforceCallingOrSelfPermission(String permission, String message) {
            if (permission == android.Manifest.permission.MANAGE_IPSEC_TUNNELS) {
@@ -128,6 +135,7 @@ public class IpSecServiceParameterizedTest {
    };

    INetd mMockNetd;
    PackageManager mMockPkgMgr;
    IpSecService.IpSecServiceConfiguration mMockIpSecSrvConfig;
    IpSecService mIpSecService;
    Network fakeNetwork = new Network(0xAB);
@@ -152,11 +160,16 @@ public class IpSecServiceParameterizedTest {
    @Before
    public void setUp() throws Exception {
        mMockNetd = mock(INetd.class);
        mMockPkgMgr = mock(PackageManager.class);
        mMockIpSecSrvConfig = mock(IpSecService.IpSecServiceConfiguration.class);
        mIpSecService = new IpSecService(mMockContext, 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("blessedPackage")))
            .thenReturn(AppOpsManager.MODE_ALLOWED);
@@ -709,4 +722,18 @@ public class IpSecServiceParameterizedTest {
        } 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(), "blessedPackage");
            fail("Expected UnsupportedOperationException for disabled feature");
        } catch (UnsupportedOperationException expected) {
        }
    }
}