Merge "Automatically set IPsec tunnel interface as up"

This commit is contained in:
Benedict Wong
2020-03-25 04:18:50 +00:00
committed by Gerrit Code Review
5 changed files with 36 additions and 14 deletions

View File

@@ -48,6 +48,7 @@ import android.net.TrafficStats;
import android.net.util.NetdService; import android.net.util.NetdService;
import android.os.Binder; import android.os.Binder;
import android.os.IBinder; import android.os.IBinder;
import android.os.INetworkManagementService;
import android.os.ParcelFileDescriptor; import android.os.ParcelFileDescriptor;
import android.os.RemoteException; import android.os.RemoteException;
import android.os.ServiceSpecificException; import android.os.ServiceSpecificException;
@@ -76,6 +77,7 @@ import java.net.InetSocketAddress;
import java.net.UnknownHostException; import java.net.UnknownHostException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Objects;
/** /**
* A service to manage multiple clients that want to access the IpSec API. The service is * A service to manage multiple clients that want to access the IpSec API. The service is
@@ -115,6 +117,9 @@ public class IpSecService extends IIpSecService.Stub {
/* Binder context for this service */ /* Binder context for this service */
private final Context mContext; private final Context mContext;
/* NetworkManager instance */
private final INetworkManagementService mNetworkManager;
/** /**
* The next non-repeating global ID for tracking resources between users, this service, and * The next non-repeating global ID for tracking resources between users, this service, and
* kernel data structures. Accessing this variable is not thread safe, so it is only read or * kernel data structures. Accessing this variable is not thread safe, so it is only read or
@@ -993,12 +998,13 @@ public class IpSecService extends IIpSecService.Stub {
* *
* @param context Binder context for this service * @param context Binder context for this service
*/ */
private IpSecService(Context context) { private IpSecService(Context context, INetworkManagementService networkManager) {
this(context, IpSecServiceConfiguration.GETSRVINSTANCE); this(context, networkManager, IpSecServiceConfiguration.GETSRVINSTANCE);
} }
static IpSecService create(Context context) throws InterruptedException { static IpSecService create(Context context, INetworkManagementService networkManager)
final IpSecService service = new IpSecService(context); throws InterruptedException {
final IpSecService service = new IpSecService(context, networkManager);
service.connectNativeNetdService(); service.connectNativeNetdService();
return service; return service;
} }
@@ -1012,9 +1018,11 @@ public class IpSecService extends IIpSecService.Stub {
/** @hide */ /** @hide */
@VisibleForTesting @VisibleForTesting
public IpSecService(Context context, IpSecServiceConfiguration config) { public IpSecService(Context context, INetworkManagementService networkManager,
IpSecServiceConfiguration config) {
this( this(
context, context,
networkManager,
config, config,
(fd, uid) -> { (fd, uid) -> {
try { try {
@@ -1028,9 +1036,10 @@ public class IpSecService extends IIpSecService.Stub {
/** @hide */ /** @hide */
@VisibleForTesting @VisibleForTesting
public IpSecService( public IpSecService(Context context, INetworkManagementService networkManager,
Context context, IpSecServiceConfiguration config, UidFdTagger uidFdTagger) { IpSecServiceConfiguration config, UidFdTagger uidFdTagger) {
mContext = context; mContext = context;
mNetworkManager = Objects.requireNonNull(networkManager);
mSrvConfig = config; mSrvConfig = config;
mUidFdTagger = uidFdTagger; mUidFdTagger = uidFdTagger;
} }
@@ -1309,6 +1318,10 @@ public class IpSecService extends IIpSecService.Stub {
final INetd netd = mSrvConfig.getNetdInstance(); final INetd netd = mSrvConfig.getNetdInstance();
netd.ipSecAddTunnelInterface(intfName, localAddr, remoteAddr, ikey, okey, resourceId); netd.ipSecAddTunnelInterface(intfName, localAddr, remoteAddr, ikey, okey, resourceId);
Binder.withCleanCallingIdentity(() -> {
mNetworkManager.setInterfaceUp(intfName);
});
for (int selAddrFamily : ADDRESS_FAMILIES) { for (int selAddrFamily : ADDRESS_FAMILIES) {
// Always send down correct local/remote addresses for template. // Always send down correct local/remote addresses for template.
netd.ipSecAddSecurityPolicy( netd.ipSecAddSecurityPolicy(

View File

@@ -1328,7 +1328,7 @@ public final class SystemServer {
traceBeginAndSlog("StartIpSecService"); traceBeginAndSlog("StartIpSecService");
try { try {
ipSecService = IpSecService.create(context); ipSecService = IpSecService.create(context, networkManagement);
ServiceManager.addService(Context.IPSEC_SERVICE, ipSecService); ServiceManager.addService(Context.IPSEC_SERVICE, ipSecService);
} catch (Throwable e) { } catch (Throwable e) {
reportWtf("starting IpSec Service", e); reportWtf("starting IpSec Service", e);

View File

@@ -46,6 +46,7 @@ import android.net.LinkAddress;
import android.net.Network; import android.net.Network;
import android.net.NetworkUtils; import android.net.NetworkUtils;
import android.os.Binder; import android.os.Binder;
import android.os.INetworkManagementService;
import android.os.ParcelFileDescriptor; import android.os.ParcelFileDescriptor;
import android.system.Os; import android.system.Os;
import android.test.mock.MockContext; import android.test.mock.MockContext;
@@ -135,6 +136,7 @@ public class IpSecServiceParameterizedTest {
}; };
INetd mMockNetd; INetd mMockNetd;
INetworkManagementService mNetworkManager;
PackageManager mMockPkgMgr; PackageManager mMockPkgMgr;
IpSecService.IpSecServiceConfiguration mMockIpSecSrvConfig; IpSecService.IpSecServiceConfiguration mMockIpSecSrvConfig;
IpSecService mIpSecService; IpSecService mIpSecService;
@@ -160,9 +162,10 @@ public class IpSecServiceParameterizedTest {
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
mMockNetd = mock(INetd.class); mMockNetd = mock(INetd.class);
mNetworkManager = mock(INetworkManagementService.class);
mMockPkgMgr = mock(PackageManager.class); mMockPkgMgr = mock(PackageManager.class);
mMockIpSecSrvConfig = mock(IpSecService.IpSecServiceConfiguration.class); mMockIpSecSrvConfig = mock(IpSecService.IpSecServiceConfiguration.class);
mIpSecService = new IpSecService(mMockContext, mMockIpSecSrvConfig); mIpSecService = new IpSecService(mMockContext, mNetworkManager, mMockIpSecSrvConfig);
// Injecting mock netd // Injecting mock netd
when(mMockIpSecSrvConfig.getNetdInstance()).thenReturn(mMockNetd); when(mMockIpSecSrvConfig.getNetdInstance()).thenReturn(mMockNetd);
@@ -609,6 +612,7 @@ public class IpSecServiceParameterizedTest {
anyInt(), anyInt(),
anyInt(), anyInt(),
anyInt()); anyInt());
verify(mNetworkManager).setInterfaceUp(createTunnelResp.interfaceName);
} }
@Test @Test

View File

@@ -31,6 +31,7 @@ import static org.mockito.Mockito.verify;
import android.content.Context; import android.content.Context;
import android.os.Binder; import android.os.Binder;
import android.os.IBinder; import android.os.IBinder;
import android.os.INetworkManagementService;
import android.os.RemoteException; import android.os.RemoteException;
import androidx.test.filters.SmallTest; import androidx.test.filters.SmallTest;
@@ -61,7 +62,8 @@ public class IpSecServiceRefcountedResourceTest {
public void setUp() throws Exception { public void setUp() throws Exception {
mMockContext = mock(Context.class); mMockContext = mock(Context.class);
mMockIpSecSrvConfig = mock(IpSecService.IpSecServiceConfiguration.class); mMockIpSecSrvConfig = mock(IpSecService.IpSecServiceConfiguration.class);
mIpSecService = new IpSecService(mMockContext, mMockIpSecSrvConfig); mIpSecService = new IpSecService(
mMockContext, mock(INetworkManagementService.class), mMockIpSecSrvConfig);
} }
private void assertResourceState( private void assertResourceState(

View File

@@ -42,6 +42,7 @@ import android.net.IpSecManager;
import android.net.IpSecSpiResponse; import android.net.IpSecSpiResponse;
import android.net.IpSecUdpEncapResponse; import android.net.IpSecUdpEncapResponse;
import android.os.Binder; import android.os.Binder;
import android.os.INetworkManagementService;
import android.os.ParcelFileDescriptor; import android.os.ParcelFileDescriptor;
import android.os.Process; import android.os.Process;
import android.system.ErrnoException; import android.system.ErrnoException;
@@ -115,6 +116,7 @@ public class IpSecServiceTest {
} }
Context mMockContext; Context mMockContext;
INetworkManagementService mMockNetworkManager;
INetd mMockNetd; INetd mMockNetd;
IpSecService.IpSecServiceConfiguration mMockIpSecSrvConfig; IpSecService.IpSecServiceConfiguration mMockIpSecSrvConfig;
IpSecService mIpSecService; IpSecService mIpSecService;
@@ -122,9 +124,10 @@ public class IpSecServiceTest {
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
mMockContext = mock(Context.class); mMockContext = mock(Context.class);
mMockNetworkManager = mock(INetworkManagementService.class);
mMockNetd = mock(INetd.class); mMockNetd = mock(INetd.class);
mMockIpSecSrvConfig = mock(IpSecService.IpSecServiceConfiguration.class); mMockIpSecSrvConfig = mock(IpSecService.IpSecServiceConfiguration.class);
mIpSecService = new IpSecService(mMockContext, mMockIpSecSrvConfig); mIpSecService = new IpSecService(mMockContext, mMockNetworkManager, mMockIpSecSrvConfig);
// Injecting mock netd // Injecting mock netd
when(mMockIpSecSrvConfig.getNetdInstance()).thenReturn(mMockNetd); when(mMockIpSecSrvConfig.getNetdInstance()).thenReturn(mMockNetd);
@@ -132,7 +135,7 @@ public class IpSecServiceTest {
@Test @Test
public void testIpSecServiceCreate() throws InterruptedException { public void testIpSecServiceCreate() throws InterruptedException {
IpSecService ipSecSrv = IpSecService.create(mMockContext); IpSecService ipSecSrv = IpSecService.create(mMockContext, mMockNetworkManager);
assertNotNull(ipSecSrv); assertNotNull(ipSecSrv);
} }
@@ -604,8 +607,8 @@ public class IpSecServiceTest {
@Test @Test
public void testOpenUdpEncapSocketTagsSocket() throws Exception { public void testOpenUdpEncapSocketTagsSocket() throws Exception {
IpSecService.UidFdTagger mockTagger = mock(IpSecService.UidFdTagger.class); IpSecService.UidFdTagger mockTagger = mock(IpSecService.UidFdTagger.class);
IpSecService testIpSecService = IpSecService testIpSecService = new IpSecService(
new IpSecService(mMockContext, mMockIpSecSrvConfig, mockTagger); mMockContext, mMockNetworkManager, mMockIpSecSrvConfig, mockTagger);
IpSecUdpEncapResponse udpEncapResp = IpSecUdpEncapResponse udpEncapResp =
testIpSecService.openUdpEncapsulationSocket(0, new Binder()); testIpSecService.openUdpEncapsulationSocket(0, new Binder());