blob: 99a5a69213fa5e7ce474e6533e586d9be5c97ba2 [file] [log] [blame]
Nathan Harold2e9a5202017-09-26 11:44:23 -07001/*
2 * Copyright (C) 2017 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
17package com.android.server;
18
19import static org.junit.Assert.assertEquals;
Benedict Wongecc9f7c2018-03-01 18:53:07 -080020import static org.junit.Assert.assertNotNull;
Benedict Wong0febe5e2017-08-22 21:42:33 -070021import static org.junit.Assert.fail;
Nathan Harold2e9a5202017-09-26 11:44:23 -070022import static org.mockito.Matchers.anyInt;
Nathan Harold2e9a5202017-09-26 11:44:23 -070023import static org.mockito.Matchers.anyString;
24import static org.mockito.Matchers.eq;
25import static org.mockito.Mockito.mock;
Nathan Harold22795302018-02-27 19:19:40 -080026import static org.mockito.Mockito.times;
Nathan Harold2e9a5202017-09-26 11:44:23 -070027import static org.mockito.Mockito.verify;
28import static org.mockito.Mockito.when;
29
Nathan Harold21208ee2018-03-15 18:06:06 -070030import android.app.AppOpsManager;
Nathan Harold2e9a5202017-09-26 11:44:23 -070031import android.content.Context;
32import android.net.INetd;
33import android.net.IpSecAlgorithm;
34import android.net.IpSecConfig;
35import android.net.IpSecManager;
36import android.net.IpSecSpiResponse;
Nathan Harold2e9a5202017-09-26 11:44:23 -070037import android.net.IpSecTransformResponse;
Benedict Wongecc9f7c2018-03-01 18:53:07 -080038import android.net.IpSecTunnelInterfaceResponse;
39import android.net.LinkAddress;
40import android.net.Network;
Nathan Harold2e9a5202017-09-26 11:44:23 -070041import android.net.NetworkUtils;
42import android.os.Binder;
43import android.os.ParcelFileDescriptor;
44import android.support.test.filters.SmallTest;
Benedict Wong344bd622017-11-16 15:27:22 -080045import android.system.Os;
Benedict Wonga0989622018-07-25 13:06:29 -070046import android.test.mock.MockContext;
Nathan Harold2e9a5202017-09-26 11:44:23 -070047
48import java.net.Socket;
49import java.util.Arrays;
50import java.util.Collection;
51
52import org.junit.Before;
Nathan Harold8c69bcb2018-05-15 19:18:38 -070053import org.junit.Ignore;
Nathan Harold2e9a5202017-09-26 11:44:23 -070054import org.junit.Test;
55import org.junit.runner.RunWith;
56import org.junit.runners.Parameterized;
57
58/** Unit tests for {@link IpSecService}. */
59@SmallTest
60@RunWith(Parameterized.class)
61public class IpSecServiceParameterizedTest {
62
Nathan Harolda2523312018-01-05 19:25:13 -080063 private static final int TEST_SPI = 0xD1201D;
Nathan Harold2e9a5202017-09-26 11:44:23 -070064
Nathan Harolda2523312018-01-05 19:25:13 -080065 private final String mDestinationAddr;
Nathan Harold5676f5f2018-01-16 19:34:01 -080066 private final String mSourceAddr;
Benedict Wongecc9f7c2018-03-01 18:53:07 -080067 private final LinkAddress mLocalInnerAddress;
Nathan Harold2e9a5202017-09-26 11:44:23 -070068
69 @Parameterized.Parameters
70 public static Collection ipSecConfigs() {
Benedict Wongecc9f7c2018-03-01 18:53:07 -080071 return Arrays.asList(
72 new Object[][] {
73 {"1.2.3.4", "8.8.4.4", "10.0.1.1/24"},
74 {"2601::2", "2601::10", "2001:db8::1/64"}
75 });
Nathan Harold2e9a5202017-09-26 11:44:23 -070076 }
77
Benedict Wong4ebc2c52017-11-01 17:14:25 -070078 private static final byte[] AEAD_KEY = {
79 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
80 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
81 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
82 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
83 0x73, 0x61, 0x6C, 0x74
84 };
Nathan Harold2e9a5202017-09-26 11:44:23 -070085 private static final byte[] CRYPT_KEY = {
86 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
87 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
88 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
89 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F
90 };
91 private static final byte[] AUTH_KEY = {
92 0x7A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
93 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F,
94 0x7A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
95 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F
96 };
97
Nathan Harold21208ee2018-03-15 18:06:06 -070098 AppOpsManager mMockAppOps = mock(AppOpsManager.class);
99
100 MockContext mMockContext = new MockContext() {
101 @Override
102 public Object getSystemService(String name) {
103 switch(name) {
104 case Context.APP_OPS_SERVICE:
105 return mMockAppOps;
106 default:
107 return null;
108 }
109 }
110
111 @Override
112 public void enforceCallingOrSelfPermission(String permission, String message) {
113 if (permission == android.Manifest.permission.MANAGE_IPSEC_TUNNELS) {
114 return;
115 }
116 throw new SecurityException("Unavailable permission requested");
117 }
118 };
119
Nathan Harold2e9a5202017-09-26 11:44:23 -0700120 INetd mMockNetd;
121 IpSecService.IpSecServiceConfiguration mMockIpSecSrvConfig;
122 IpSecService mIpSecService;
Benedict Wongecc9f7c2018-03-01 18:53:07 -0800123 Network fakeNetwork = new Network(0xAB);
Benedict Wonga0989622018-07-25 13:06:29 -0700124 int mUid = Os.getuid();
Nathan Harold2e9a5202017-09-26 11:44:23 -0700125
Benedict Wong0febe5e2017-08-22 21:42:33 -0700126 private static final IpSecAlgorithm AUTH_ALGO =
127 new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, AUTH_KEY, AUTH_KEY.length * 4);
128 private static final IpSecAlgorithm CRYPT_ALGO =
129 new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
130 private static final IpSecAlgorithm AEAD_ALGO =
Benedict Wong4ebc2c52017-11-01 17:14:25 -0700131 new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 128);
Benedict Wong0febe5e2017-08-22 21:42:33 -0700132
Benedict Wongecc9f7c2018-03-01 18:53:07 -0800133 public IpSecServiceParameterizedTest(
134 String sourceAddr, String destAddr, String localInnerAddr) {
Nathan Harold5676f5f2018-01-16 19:34:01 -0800135 mSourceAddr = sourceAddr;
136 mDestinationAddr = destAddr;
Benedict Wongecc9f7c2018-03-01 18:53:07 -0800137 mLocalInnerAddress = new LinkAddress(localInnerAddr);
Nathan Harold2e9a5202017-09-26 11:44:23 -0700138 }
139
140 @Before
141 public void setUp() throws Exception {
Nathan Harold2e9a5202017-09-26 11:44:23 -0700142 mMockNetd = mock(INetd.class);
143 mMockIpSecSrvConfig = mock(IpSecService.IpSecServiceConfiguration.class);
144 mIpSecService = new IpSecService(mMockContext, mMockIpSecSrvConfig);
145
146 // Injecting mock netd
147 when(mMockIpSecSrvConfig.getNetdInstance()).thenReturn(mMockNetd);
Nathan Harold21208ee2018-03-15 18:06:06 -0700148 // A package granted the AppOp for MANAGE_IPSEC_TUNNELS will be MODE_ALLOWED.
149 when(mMockAppOps.noteOp(anyInt(), anyInt(), eq("blessedPackage")))
150 .thenReturn(AppOpsManager.MODE_ALLOWED);
151 // A system package will not be granted the app op, so this should fall back to
152 // a permissions check, which should pass.
153 when(mMockAppOps.noteOp(anyInt(), anyInt(), eq("systemPackage")))
154 .thenReturn(AppOpsManager.MODE_DEFAULT);
155 // A mismatch between the package name and the UID will return MODE_IGNORED.
156 when(mMockAppOps.noteOp(anyInt(), anyInt(), eq("badPackage")))
157 .thenReturn(AppOpsManager.MODE_IGNORED);
Nathan Harold2e9a5202017-09-26 11:44:23 -0700158 }
159
160 @Test
161 public void testIpSecServiceReserveSpi() throws Exception {
Nathan Harolda2523312018-01-05 19:25:13 -0800162 when(mMockNetd.ipSecAllocateSpi(anyInt(), anyString(), eq(mDestinationAddr), eq(TEST_SPI)))
163 .thenReturn(TEST_SPI);
Nathan Harold2e9a5202017-09-26 11:44:23 -0700164
165 IpSecSpiResponse spiResp =
Jonathan Basseri5fb92902017-11-16 10:58:01 -0800166 mIpSecService.allocateSecurityParameterIndex(
Nathan Harolda2523312018-01-05 19:25:13 -0800167 mDestinationAddr, TEST_SPI, new Binder());
Nathan Harold2e9a5202017-09-26 11:44:23 -0700168 assertEquals(IpSecManager.Status.OK, spiResp.status);
Nathan Harolda2523312018-01-05 19:25:13 -0800169 assertEquals(TEST_SPI, spiResp.spi);
Nathan Harold2e9a5202017-09-26 11:44:23 -0700170 }
171
172 @Test
173 public void testReleaseSecurityParameterIndex() throws Exception {
Nathan Harolda2523312018-01-05 19:25:13 -0800174 when(mMockNetd.ipSecAllocateSpi(anyInt(), anyString(), eq(mDestinationAddr), eq(TEST_SPI)))
175 .thenReturn(TEST_SPI);
Nathan Harold2e9a5202017-09-26 11:44:23 -0700176
177 IpSecSpiResponse spiResp =
Jonathan Basseri5fb92902017-11-16 10:58:01 -0800178 mIpSecService.allocateSecurityParameterIndex(
Nathan Harolda2523312018-01-05 19:25:13 -0800179 mDestinationAddr, TEST_SPI, new Binder());
Nathan Harold2e9a5202017-09-26 11:44:23 -0700180
181 mIpSecService.releaseSecurityParameterIndex(spiResp.resourceId);
182
183 verify(mMockNetd)
184 .ipSecDeleteSecurityAssociation(
Benedict Wonga0989622018-07-25 13:06:29 -0700185 eq(mUid),
Di Lu0b611f42018-01-11 11:35:25 -0800186 anyString(),
187 anyString(),
188 eq(TEST_SPI),
189 anyInt(),
190 anyInt());
Benedict Wong344bd622017-11-16 15:27:22 -0800191
192 // Verify quota and RefcountedResource objects cleaned up
Benedict Wonga0989622018-07-25 13:06:29 -0700193 IpSecService.UserRecord userRecord = mIpSecService.mUserResourceTracker.getUserRecord(mUid);
Benedict Wong344bd622017-11-16 15:27:22 -0800194 assertEquals(0, userRecord.mSpiQuotaTracker.mCurrent);
195 try {
196 userRecord.mSpiRecords.getRefcountedResourceOrThrow(spiResp.resourceId);
197 fail("Expected IllegalArgumentException on attempt to access deleted resource");
198 } catch (IllegalArgumentException expected) {
199
200 }
201 }
202
203 @Test
204 public void testSecurityParameterIndexBinderDeath() throws Exception {
Nathan Harolda2523312018-01-05 19:25:13 -0800205 when(mMockNetd.ipSecAllocateSpi(anyInt(), anyString(), eq(mDestinationAddr), eq(TEST_SPI)))
206 .thenReturn(TEST_SPI);
Benedict Wong344bd622017-11-16 15:27:22 -0800207
208 IpSecSpiResponse spiResp =
Nathan Harold660a3352017-12-14 14:46:46 -0800209 mIpSecService.allocateSecurityParameterIndex(
Nathan Harolda2523312018-01-05 19:25:13 -0800210 mDestinationAddr, TEST_SPI, new Binder());
Benedict Wong344bd622017-11-16 15:27:22 -0800211
Benedict Wonga0989622018-07-25 13:06:29 -0700212 IpSecService.UserRecord userRecord = mIpSecService.mUserResourceTracker.getUserRecord(mUid);
Benedict Wong344bd622017-11-16 15:27:22 -0800213 IpSecService.RefcountedResource refcountedRecord =
214 userRecord.mSpiRecords.getRefcountedResourceOrThrow(spiResp.resourceId);
215
216 refcountedRecord.binderDied();
217
218 verify(mMockNetd)
219 .ipSecDeleteSecurityAssociation(
Benedict Wonga0989622018-07-25 13:06:29 -0700220 eq(mUid),
Di Lu0b611f42018-01-11 11:35:25 -0800221 anyString(),
222 anyString(),
223 eq(TEST_SPI),
224 anyInt(),
225 anyInt());
Benedict Wong344bd622017-11-16 15:27:22 -0800226
227 // Verify quota and RefcountedResource objects cleaned up
228 assertEquals(0, userRecord.mSpiQuotaTracker.mCurrent);
229 try {
230 userRecord.mSpiRecords.getRefcountedResourceOrThrow(spiResp.resourceId);
231 fail("Expected IllegalArgumentException on attempt to access deleted resource");
232 } catch (IllegalArgumentException expected) {
233
234 }
Nathan Harold2e9a5202017-09-26 11:44:23 -0700235 }
236
Nathan Harolda2523312018-01-05 19:25:13 -0800237 private int getNewSpiResourceId(String remoteAddress, int returnSpi) throws Exception {
238 when(mMockNetd.ipSecAllocateSpi(anyInt(), anyString(), anyString(), anyInt()))
Benedict Wong0febe5e2017-08-22 21:42:33 -0700239 .thenReturn(returnSpi);
Nathan Harold2e9a5202017-09-26 11:44:23 -0700240
Benedict Wong0febe5e2017-08-22 21:42:33 -0700241 IpSecSpiResponse spi =
Jonathan Basseri5fb92902017-11-16 10:58:01 -0800242 mIpSecService.allocateSecurityParameterIndex(
Benedict Wong0febe5e2017-08-22 21:42:33 -0700243 NetworkUtils.numericToInetAddress(remoteAddress).getHostAddress(),
244 IpSecManager.INVALID_SECURITY_PARAMETER_INDEX,
245 new Binder());
246 return spi.resourceId;
247 }
Nathan Harold2e9a5202017-09-26 11:44:23 -0700248
Benedict Wong0febe5e2017-08-22 21:42:33 -0700249 private void addDefaultSpisAndRemoteAddrToIpSecConfig(IpSecConfig config) throws Exception {
Nathan Harolda2523312018-01-05 19:25:13 -0800250 config.setSpiResourceId(getNewSpiResourceId(mDestinationAddr, TEST_SPI));
Nathan Harold5676f5f2018-01-16 19:34:01 -0800251 config.setSourceAddress(mSourceAddr);
Nathan Harolda2523312018-01-05 19:25:13 -0800252 config.setDestinationAddress(mDestinationAddr);
Benedict Wong0febe5e2017-08-22 21:42:33 -0700253 }
254
255 private void addAuthAndCryptToIpSecConfig(IpSecConfig config) throws Exception {
Nathan Harolda2523312018-01-05 19:25:13 -0800256 config.setEncryption(CRYPT_ALGO);
257 config.setAuthentication(AUTH_ALGO);
Nathan Harold2e9a5202017-09-26 11:44:23 -0700258 }
259
260 @Test
Benedict Wongf33f03132018-01-18 14:38:16 -0800261 public void testCreateTransform() throws Exception {
Benedict Wong0febe5e2017-08-22 21:42:33 -0700262 IpSecConfig ipSecConfig = new IpSecConfig();
263 addDefaultSpisAndRemoteAddrToIpSecConfig(ipSecConfig);
264 addAuthAndCryptToIpSecConfig(ipSecConfig);
Nathan Harold2e9a5202017-09-26 11:44:23 -0700265
266 IpSecTransformResponse createTransformResp =
Nathan Harold21208ee2018-03-15 18:06:06 -0700267 mIpSecService.createTransform(ipSecConfig, new Binder(), "blessedPackage");
Nathan Harold2e9a5202017-09-26 11:44:23 -0700268 assertEquals(IpSecManager.Status.OK, createTransformResp.status);
269
270 verify(mMockNetd)
271 .ipSecAddSecurityAssociation(
Benedict Wonga0989622018-07-25 13:06:29 -0700272 eq(mUid),
Nathan Harold2e9a5202017-09-26 11:44:23 -0700273 anyInt(),
Nathan Harold2e9a5202017-09-26 11:44:23 -0700274 anyString(),
275 anyString(),
Benedict Wong0fe58a92018-01-19 17:36:02 -0800276 anyInt(),
Nathan Harolda2523312018-01-05 19:25:13 -0800277 eq(TEST_SPI),
Di Lu0b611f42018-01-11 11:35:25 -0800278 anyInt(),
279 anyInt(),
Benedict Wong0febe5e2017-08-22 21:42:33 -0700280 eq(IpSecAlgorithm.AUTH_HMAC_SHA256),
281 eq(AUTH_KEY),
282 anyInt(),
283 eq(IpSecAlgorithm.CRYPT_AES_CBC),
284 eq(CRYPT_KEY),
285 anyInt(),
286 eq(""),
Manoj Boopathi Rajfffa8112017-10-26 11:49:02 -0700287 eq(new byte[] {}),
Benedict Wong0febe5e2017-08-22 21:42:33 -0700288 eq(0),
289 anyInt(),
290 anyInt(),
291 anyInt());
292 }
293
294 @Test
Benedict Wongf33f03132018-01-18 14:38:16 -0800295 public void testCreateTransformAead() throws Exception {
Benedict Wong0febe5e2017-08-22 21:42:33 -0700296 IpSecConfig ipSecConfig = new IpSecConfig();
297 addDefaultSpisAndRemoteAddrToIpSecConfig(ipSecConfig);
298
Nathan Harolda2523312018-01-05 19:25:13 -0800299 ipSecConfig.setAuthenticatedEncryption(AEAD_ALGO);
Benedict Wong0febe5e2017-08-22 21:42:33 -0700300
301 IpSecTransformResponse createTransformResp =
Nathan Harold21208ee2018-03-15 18:06:06 -0700302 mIpSecService.createTransform(ipSecConfig, new Binder(), "blessedPackage");
Benedict Wong0febe5e2017-08-22 21:42:33 -0700303 assertEquals(IpSecManager.Status.OK, createTransformResp.status);
304
305 verify(mMockNetd)
306 .ipSecAddSecurityAssociation(
Benedict Wonga0989622018-07-25 13:06:29 -0700307 eq(mUid),
Benedict Wong0febe5e2017-08-22 21:42:33 -0700308 anyInt(),
Benedict Wong0febe5e2017-08-22 21:42:33 -0700309 anyString(),
310 anyString(),
Benedict Wong0fe58a92018-01-19 17:36:02 -0800311 anyInt(),
Nathan Harolda2523312018-01-05 19:25:13 -0800312 eq(TEST_SPI),
Di Lu0b611f42018-01-11 11:35:25 -0800313 anyInt(),
314 anyInt(),
Benedict Wong0febe5e2017-08-22 21:42:33 -0700315 eq(""),
Manoj Boopathi Rajfffa8112017-10-26 11:49:02 -0700316 eq(new byte[] {}),
Benedict Wong0febe5e2017-08-22 21:42:33 -0700317 eq(0),
318 eq(""),
Manoj Boopathi Rajfffa8112017-10-26 11:49:02 -0700319 eq(new byte[] {}),
Benedict Wong0febe5e2017-08-22 21:42:33 -0700320 eq(0),
321 eq(IpSecAlgorithm.AUTH_CRYPT_AES_GCM),
Benedict Wong4ebc2c52017-11-01 17:14:25 -0700322 eq(AEAD_KEY),
Nathan Harold2e9a5202017-09-26 11:44:23 -0700323 anyInt(),
324 anyInt(),
325 anyInt(),
326 anyInt());
327 }
328
Andreas Gampea7b26b52018-02-26 08:06:30 -0800329 @Test
Benedict Wonge6b42772017-12-13 18:26:40 -0800330 public void testCreateTwoTransformsWithSameSpis() throws Exception {
331 IpSecConfig ipSecConfig = new IpSecConfig();
332 addDefaultSpisAndRemoteAddrToIpSecConfig(ipSecConfig);
333 addAuthAndCryptToIpSecConfig(ipSecConfig);
334
335 IpSecTransformResponse createTransformResp =
Nathan Harold21208ee2018-03-15 18:06:06 -0700336 mIpSecService.createTransform(ipSecConfig, new Binder(), "blessedPackage");
Benedict Wonge6b42772017-12-13 18:26:40 -0800337 assertEquals(IpSecManager.Status.OK, createTransformResp.status);
338
339 // Attempting to create transform a second time with the same SPIs should throw an error...
340 try {
Nathan Harold21208ee2018-03-15 18:06:06 -0700341 mIpSecService.createTransform(ipSecConfig, new Binder(), "blessedPackage");
Benedict Wonge6b42772017-12-13 18:26:40 -0800342 fail("IpSecService should have thrown an error for reuse of SPI");
343 } catch (IllegalStateException expected) {
344 }
345
346 // ... even if the transform is deleted
347 mIpSecService.deleteTransform(createTransformResp.resourceId);
348 try {
Nathan Harold21208ee2018-03-15 18:06:06 -0700349 mIpSecService.createTransform(ipSecConfig, new Binder(), "blessedPackage");
Benedict Wonge6b42772017-12-13 18:26:40 -0800350 fail("IpSecService should have thrown an error for reuse of SPI");
351 } catch (IllegalStateException expected) {
352 }
353 }
354
Nathan Harold2e9a5202017-09-26 11:44:23 -0700355 @Test
Nathan Harold22795302018-02-27 19:19:40 -0800356 public void testReleaseOwnedSpi() throws Exception {
357 IpSecConfig ipSecConfig = new IpSecConfig();
358 addDefaultSpisAndRemoteAddrToIpSecConfig(ipSecConfig);
359 addAuthAndCryptToIpSecConfig(ipSecConfig);
360
361 IpSecTransformResponse createTransformResp =
Nathan Harold21208ee2018-03-15 18:06:06 -0700362 mIpSecService.createTransform(ipSecConfig, new Binder(), "blessedPackage");
Benedict Wonga0989622018-07-25 13:06:29 -0700363 IpSecService.UserRecord userRecord = mIpSecService.mUserResourceTracker.getUserRecord(mUid);
Nathan Harold22795302018-02-27 19:19:40 -0800364 assertEquals(1, userRecord.mSpiQuotaTracker.mCurrent);
365 mIpSecService.releaseSecurityParameterIndex(ipSecConfig.getSpiResourceId());
366 verify(mMockNetd, times(0))
367 .ipSecDeleteSecurityAssociation(
Benedict Wonga0989622018-07-25 13:06:29 -0700368 eq(mUid),
Nathan Harold22795302018-02-27 19:19:40 -0800369 anyString(),
370 anyString(),
371 eq(TEST_SPI),
372 anyInt(),
373 anyInt());
374 // quota is not released until the SPI is released by the Transform
375 assertEquals(1, userRecord.mSpiQuotaTracker.mCurrent);
376 }
377
378 @Test
Benedict Wongf33f03132018-01-18 14:38:16 -0800379 public void testDeleteTransform() throws Exception {
Benedict Wong0febe5e2017-08-22 21:42:33 -0700380 IpSecConfig ipSecConfig = new IpSecConfig();
381 addDefaultSpisAndRemoteAddrToIpSecConfig(ipSecConfig);
382 addAuthAndCryptToIpSecConfig(ipSecConfig);
Nathan Harold2e9a5202017-09-26 11:44:23 -0700383
384 IpSecTransformResponse createTransformResp =
Nathan Harold21208ee2018-03-15 18:06:06 -0700385 mIpSecService.createTransform(ipSecConfig, new Binder(), "blessedPackage");
Benedict Wongf33f03132018-01-18 14:38:16 -0800386 mIpSecService.deleteTransform(createTransformResp.resourceId);
Nathan Harold2e9a5202017-09-26 11:44:23 -0700387
Nathan Harold22795302018-02-27 19:19:40 -0800388 verify(mMockNetd, times(1))
Nathan Harold2e9a5202017-09-26 11:44:23 -0700389 .ipSecDeleteSecurityAssociation(
Benedict Wonga0989622018-07-25 13:06:29 -0700390 eq(mUid),
Di Lu0b611f42018-01-11 11:35:25 -0800391 anyString(),
392 anyString(),
393 eq(TEST_SPI),
394 anyInt(),
395 anyInt());
Benedict Wong344bd622017-11-16 15:27:22 -0800396
397 // Verify quota and RefcountedResource objects cleaned up
Benedict Wonga0989622018-07-25 13:06:29 -0700398 IpSecService.UserRecord userRecord = mIpSecService.mUserResourceTracker.getUserRecord(mUid);
Benedict Wong344bd622017-11-16 15:27:22 -0800399 assertEquals(0, userRecord.mTransformQuotaTracker.mCurrent);
Nathan Harold22795302018-02-27 19:19:40 -0800400 assertEquals(1, userRecord.mSpiQuotaTracker.mCurrent);
401
402 mIpSecService.releaseSecurityParameterIndex(ipSecConfig.getSpiResourceId());
403 // Verify that ipSecDeleteSa was not called when the SPI was released because the
404 // ownedByTransform property should prevent it; (note, the called count is cumulative).
405 verify(mMockNetd, times(1))
406 .ipSecDeleteSecurityAssociation(
407 anyInt(),
408 anyString(),
409 anyString(),
410 anyInt(),
411 anyInt(),
412 anyInt());
413 assertEquals(0, userRecord.mSpiQuotaTracker.mCurrent);
414
Benedict Wong344bd622017-11-16 15:27:22 -0800415 try {
416 userRecord.mTransformRecords.getRefcountedResourceOrThrow(
417 createTransformResp.resourceId);
418 fail("Expected IllegalArgumentException on attempt to access deleted resource");
419 } catch (IllegalArgumentException expected) {
420
421 }
422 }
423
424 @Test
425 public void testTransportModeTransformBinderDeath() throws Exception {
426 IpSecConfig ipSecConfig = new IpSecConfig();
427 addDefaultSpisAndRemoteAddrToIpSecConfig(ipSecConfig);
428 addAuthAndCryptToIpSecConfig(ipSecConfig);
429
430 IpSecTransformResponse createTransformResp =
Nathan Harold21208ee2018-03-15 18:06:06 -0700431 mIpSecService.createTransform(ipSecConfig, new Binder(), "blessedPackage");
Benedict Wong344bd622017-11-16 15:27:22 -0800432
Benedict Wonga0989622018-07-25 13:06:29 -0700433 IpSecService.UserRecord userRecord = mIpSecService.mUserResourceTracker.getUserRecord(mUid);
Benedict Wong344bd622017-11-16 15:27:22 -0800434 IpSecService.RefcountedResource refcountedRecord =
435 userRecord.mTransformRecords.getRefcountedResourceOrThrow(
436 createTransformResp.resourceId);
437
438 refcountedRecord.binderDied();
439
440 verify(mMockNetd)
441 .ipSecDeleteSecurityAssociation(
Benedict Wonga0989622018-07-25 13:06:29 -0700442 eq(mUid),
Di Lu0b611f42018-01-11 11:35:25 -0800443 anyString(),
444 anyString(),
445 eq(TEST_SPI),
446 anyInt(),
447 anyInt());
Benedict Wong344bd622017-11-16 15:27:22 -0800448
449 // Verify quota and RefcountedResource objects cleaned up
450 assertEquals(0, userRecord.mTransformQuotaTracker.mCurrent);
451 try {
452 userRecord.mTransformRecords.getRefcountedResourceOrThrow(
453 createTransformResp.resourceId);
454 fail("Expected IllegalArgumentException on attempt to access deleted resource");
455 } catch (IllegalArgumentException expected) {
456
457 }
Nathan Harold2e9a5202017-09-26 11:44:23 -0700458 }
459
460 @Test
461 public void testApplyTransportModeTransform() throws Exception {
Benedict Wong0febe5e2017-08-22 21:42:33 -0700462 IpSecConfig ipSecConfig = new IpSecConfig();
463 addDefaultSpisAndRemoteAddrToIpSecConfig(ipSecConfig);
464 addAuthAndCryptToIpSecConfig(ipSecConfig);
Nathan Harold2e9a5202017-09-26 11:44:23 -0700465
466 IpSecTransformResponse createTransformResp =
Nathan Harold21208ee2018-03-15 18:06:06 -0700467 mIpSecService.createTransform(ipSecConfig, new Binder(), "blessedPackage");
Nathan Harold2e9a5202017-09-26 11:44:23 -0700468 ParcelFileDescriptor pfd = ParcelFileDescriptor.fromSocket(new Socket());
469
470 int resourceId = createTransformResp.resourceId;
Nathan Harolda2523312018-01-05 19:25:13 -0800471 mIpSecService.applyTransportModeTransform(pfd, IpSecManager.DIRECTION_OUT, resourceId);
Nathan Harold2e9a5202017-09-26 11:44:23 -0700472
473 verify(mMockNetd)
474 .ipSecApplyTransportModeTransform(
475 eq(pfd.getFileDescriptor()),
Benedict Wonga0989622018-07-25 13:06:29 -0700476 eq(mUid),
Nathan Harolda2523312018-01-05 19:25:13 -0800477 eq(IpSecManager.DIRECTION_OUT),
Nathan Harold2e9a5202017-09-26 11:44:23 -0700478 anyString(),
479 anyString(),
Nathan Harolda2523312018-01-05 19:25:13 -0800480 eq(TEST_SPI));
Nathan Harold2e9a5202017-09-26 11:44:23 -0700481 }
482
483 @Test
484 public void testRemoveTransportModeTransform() throws Exception {
485 ParcelFileDescriptor pfd = ParcelFileDescriptor.fromSocket(new Socket());
Nathan Haroldf73d2522018-01-17 01:00:20 -0800486 mIpSecService.removeTransportModeTransforms(pfd);
Nathan Harold2e9a5202017-09-26 11:44:23 -0700487
488 verify(mMockNetd).ipSecRemoveTransportModeTransform(pfd.getFileDescriptor());
489 }
Benedict Wongecc9f7c2018-03-01 18:53:07 -0800490
491 private IpSecTunnelInterfaceResponse createAndValidateTunnel(
Nathan Harold21208ee2018-03-15 18:06:06 -0700492 String localAddr, String remoteAddr, String pkgName) {
Benedict Wongecc9f7c2018-03-01 18:53:07 -0800493 IpSecTunnelInterfaceResponse createTunnelResp =
494 mIpSecService.createTunnelInterface(
Nathan Harold21208ee2018-03-15 18:06:06 -0700495 mSourceAddr, mDestinationAddr, fakeNetwork, new Binder(), pkgName);
Benedict Wongecc9f7c2018-03-01 18:53:07 -0800496
497 assertNotNull(createTunnelResp);
498 assertEquals(IpSecManager.Status.OK, createTunnelResp.status);
499 return createTunnelResp;
500 }
501
502 @Test
503 public void testCreateTunnelInterface() throws Exception {
504 IpSecTunnelInterfaceResponse createTunnelResp =
Nathan Harold21208ee2018-03-15 18:06:06 -0700505 createAndValidateTunnel(mSourceAddr, mDestinationAddr, "blessedPackage");
Benedict Wongecc9f7c2018-03-01 18:53:07 -0800506
507 // Check that we have stored the tracking object, and retrieve it
Benedict Wonga0989622018-07-25 13:06:29 -0700508 IpSecService.UserRecord userRecord = mIpSecService.mUserResourceTracker.getUserRecord(mUid);
Benedict Wongecc9f7c2018-03-01 18:53:07 -0800509 IpSecService.RefcountedResource refcountedRecord =
510 userRecord.mTunnelInterfaceRecords.getRefcountedResourceOrThrow(
511 createTunnelResp.resourceId);
512
513 assertEquals(1, userRecord.mTunnelQuotaTracker.mCurrent);
514 verify(mMockNetd)
515 .addVirtualTunnelInterface(
516 eq(createTunnelResp.interfaceName),
517 eq(mSourceAddr),
518 eq(mDestinationAddr),
519 anyInt(),
520 anyInt());
521 }
522
523 @Test
524 public void testDeleteTunnelInterface() throws Exception {
525 IpSecTunnelInterfaceResponse createTunnelResp =
Nathan Harold21208ee2018-03-15 18:06:06 -0700526 createAndValidateTunnel(mSourceAddr, mDestinationAddr, "blessedPackage");
Benedict Wongecc9f7c2018-03-01 18:53:07 -0800527
Benedict Wonga0989622018-07-25 13:06:29 -0700528 IpSecService.UserRecord userRecord = mIpSecService.mUserResourceTracker.getUserRecord(mUid);
Benedict Wongecc9f7c2018-03-01 18:53:07 -0800529
Nathan Harold21208ee2018-03-15 18:06:06 -0700530 mIpSecService.deleteTunnelInterface(createTunnelResp.resourceId, "blessedPackage");
Benedict Wongecc9f7c2018-03-01 18:53:07 -0800531
532 // Verify quota and RefcountedResource objects cleaned up
533 assertEquals(0, userRecord.mTunnelQuotaTracker.mCurrent);
534 verify(mMockNetd).removeVirtualTunnelInterface(eq(createTunnelResp.interfaceName));
535 try {
536 userRecord.mTunnelInterfaceRecords.getRefcountedResourceOrThrow(
537 createTunnelResp.resourceId);
538 fail("Expected IllegalArgumentException on attempt to access deleted resource");
539 } catch (IllegalArgumentException expected) {
540 }
541 }
542
543 @Test
544 public void testTunnelInterfaceBinderDeath() throws Exception {
545 IpSecTunnelInterfaceResponse createTunnelResp =
Nathan Harold21208ee2018-03-15 18:06:06 -0700546 createAndValidateTunnel(mSourceAddr, mDestinationAddr, "blessedPackage");
Benedict Wongecc9f7c2018-03-01 18:53:07 -0800547
Benedict Wonga0989622018-07-25 13:06:29 -0700548 IpSecService.UserRecord userRecord = mIpSecService.mUserResourceTracker.getUserRecord(mUid);
Benedict Wongecc9f7c2018-03-01 18:53:07 -0800549 IpSecService.RefcountedResource refcountedRecord =
550 userRecord.mTunnelInterfaceRecords.getRefcountedResourceOrThrow(
551 createTunnelResp.resourceId);
552
553 refcountedRecord.binderDied();
554
555 // Verify quota and RefcountedResource objects cleaned up
556 assertEquals(0, userRecord.mTunnelQuotaTracker.mCurrent);
557 verify(mMockNetd).removeVirtualTunnelInterface(eq(createTunnelResp.interfaceName));
558 try {
559 userRecord.mTunnelInterfaceRecords.getRefcountedResourceOrThrow(
560 createTunnelResp.resourceId);
561 fail("Expected IllegalArgumentException on attempt to access deleted resource");
562 } catch (IllegalArgumentException expected) {
563 }
564 }
565
566 @Test
567 public void testAddRemoveAddressFromTunnelInterface() throws Exception {
Nathan Harold21208ee2018-03-15 18:06:06 -0700568 for (String pkgName : new String[]{"blessedPackage", "systemPackage"}) {
569 IpSecTunnelInterfaceResponse createTunnelResp =
570 createAndValidateTunnel(mSourceAddr, mDestinationAddr, pkgName);
571 mIpSecService.addAddressToTunnelInterface(
572 createTunnelResp.resourceId, mLocalInnerAddress, pkgName);
573 verify(mMockNetd, times(1))
574 .interfaceAddAddress(
575 eq(createTunnelResp.interfaceName),
576 eq(mLocalInnerAddress.getAddress().getHostAddress()),
577 eq(mLocalInnerAddress.getPrefixLength()));
578 mIpSecService.removeAddressFromTunnelInterface(
579 createTunnelResp.resourceId, mLocalInnerAddress, pkgName);
580 verify(mMockNetd, times(1))
581 .interfaceDelAddress(
582 eq(createTunnelResp.interfaceName),
583 eq(mLocalInnerAddress.getAddress().getHostAddress()),
584 eq(mLocalInnerAddress.getPrefixLength()));
585 mIpSecService.deleteTunnelInterface(createTunnelResp.resourceId, pkgName);
586 }
587 }
Benedict Wongecc9f7c2018-03-01 18:53:07 -0800588
Nathan Harold8c69bcb2018-05-15 19:18:38 -0700589 @Ignore
Nathan Harold21208ee2018-03-15 18:06:06 -0700590 @Test
591 public void testAddTunnelFailsForBadPackageName() throws Exception {
592 try {
593 IpSecTunnelInterfaceResponse createTunnelResp =
594 createAndValidateTunnel(mSourceAddr, mDestinationAddr, "badPackage");
595 fail("Expected a SecurityException for badPackage.");
596 } catch (SecurityException expected) {
597 }
Benedict Wongecc9f7c2018-03-01 18:53:07 -0800598 }
Nathan Harold2e9a5202017-09-26 11:44:23 -0700599}