1 /*
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 
17 package android.net;
18 
19 import static org.junit.Assert.assertEquals;
20 import static org.junit.Assert.assertNotEquals;
21 import static org.junit.Assert.fail;
22 import static org.mockito.ArgumentMatchers.any;
23 import static org.mockito.ArgumentMatchers.anyInt;
24 import static org.mockito.ArgumentMatchers.eq;
25 import static org.mockito.Mockito.mock;
26 import static org.mockito.Mockito.verify;
27 import static org.mockito.Mockito.when;
28 
29 import android.content.Context;
30 import android.os.Build;
31 import android.test.mock.MockContext;
32 
33 import androidx.test.filters.SmallTest;
34 
35 import com.android.server.IpSecService;
36 import com.android.testutils.DevSdkIgnoreRule;
37 import com.android.testutils.DevSdkIgnoreRunner;
38 
39 import org.junit.Before;
40 import org.junit.Rule;
41 import org.junit.Test;
42 import org.junit.runner.RunWith;
43 
44 import java.net.InetAddress;
45 
46 /** Unit tests for {@link IpSecTransform}. */
47 @SmallTest
48 @RunWith(DevSdkIgnoreRunner.class)
49 @DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.S_V2)
50 public class IpSecTransformTest {
51     @Rule public final DevSdkIgnoreRule ignoreRule = new DevSdkIgnoreRule();
52 
53     private static final int DROID_SPI = 0xD1201D;
54     private static final int TEST_RESOURCE_ID = 0x1234;
55 
56     private static final InetAddress SRC_ADDRESS = InetAddresses.parseNumericAddress("192.0.2.200");
57     private static final InetAddress DST_ADDRESS = InetAddresses.parseNumericAddress("192.0.2.201");
58     private static final InetAddress SRC_ADDRESS_V6 =
59             InetAddresses.parseNumericAddress("2001:db8::200");
60     private static final InetAddress DST_ADDRESS_V6 =
61             InetAddresses.parseNumericAddress("2001:db8::201");
62 
63     private MockContext mMockContext;
64     private IpSecService mMockIpSecService;
65     private IpSecManager mIpSecManager;
66 
67     @Before
setUp()68     public void setUp() throws Exception {
69         mMockIpSecService = mock(IpSecService.class);
70         mIpSecManager = new IpSecManager(mock(Context.class) /* unused */, mMockIpSecService);
71 
72         // Set up mMockContext since IpSecTransform needs an IpSecManager instance and a non-null
73         // package name to create transform
74         mMockContext =
75                 new MockContext() {
76                     @Override
77                     public String getSystemServiceName(Class<?> serviceClass) {
78                         if (serviceClass.equals(IpSecManager.class)) {
79                             return Context.IPSEC_SERVICE;
80                         }
81                         throw new UnsupportedOperationException();
82                     }
83 
84                     @Override
85                     public Object getSystemService(String name) {
86                         if (name.equals(Context.IPSEC_SERVICE)) {
87                             return mIpSecManager;
88                         }
89                         throw new UnsupportedOperationException();
90                     }
91 
92                     @Override
93                     public String getOpPackageName() {
94                         return "fooPackage";
95                     }
96                 };
97 
98         final IpSecSpiResponse spiResp =
99                 new IpSecSpiResponse(IpSecManager.Status.OK, TEST_RESOURCE_ID, DROID_SPI);
100         when(mMockIpSecService.allocateSecurityParameterIndex(any(), anyInt(), any()))
101                 .thenReturn(spiResp);
102 
103         final IpSecTransformResponse transformResp =
104                 new IpSecTransformResponse(IpSecManager.Status.OK, TEST_RESOURCE_ID);
105         when(mMockIpSecService.createTransform(any(), any(), any())).thenReturn(transformResp);
106     }
107 
108     @Test
testCreateTransformCopiesConfig()109     public void testCreateTransformCopiesConfig() {
110         // Create a config with a few parameters to make sure it's not empty
111         IpSecConfig config = new IpSecConfig();
112         config.setSourceAddress("0.0.0.0");
113         config.setDestinationAddress("1.2.3.4");
114         config.setSpiResourceId(1984);
115 
116         IpSecTransform preModification = new IpSecTransform(null, config);
117 
118         config.setSpiResourceId(1985);
119         IpSecTransform postModification = new IpSecTransform(null, config);
120 
121         assertNotEquals(preModification, postModification);
122     }
123 
124     @Test
testCreateTransformsWithSameConfigEqual()125     public void testCreateTransformsWithSameConfigEqual() {
126         // Create a config with a few parameters to make sure it's not empty
127         IpSecConfig config = new IpSecConfig();
128         config.setSourceAddress("0.0.0.0");
129         config.setDestinationAddress("1.2.3.4");
130         config.setSpiResourceId(1984);
131 
132         IpSecTransform config1 = new IpSecTransform(null, config);
133         IpSecTransform config2 = new IpSecTransform(null, config);
134 
135         assertEquals(config1, config2);
136     }
137 
buildTestTransform()138     private IpSecTransform buildTestTransform() throws Exception {
139         final IpSecManager.SecurityParameterIndex spi =
140                 mIpSecManager.allocateSecurityParameterIndex(DST_ADDRESS);
141         return new IpSecTransform.Builder(mMockContext).buildTunnelModeTransform(SRC_ADDRESS, spi);
142     }
143 
144     @Test
145     @DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.TIRAMISU)
testStartTransformMigration()146     public void testStartTransformMigration() throws Exception {
147         mIpSecManager.startTunnelModeTransformMigration(
148                 buildTestTransform(), SRC_ADDRESS_V6, DST_ADDRESS_V6);
149         verify(mMockIpSecService)
150                 .migrateTransform(
151                         anyInt(),
152                         eq(SRC_ADDRESS_V6.getHostAddress()),
153                         eq(DST_ADDRESS_V6.getHostAddress()),
154                         any());
155     }
156 
157     @Test
158     @DevSdkIgnoreRule.IgnoreAfter(Build.VERSION_CODES.TIRAMISU)
testStartTransformMigrationOnSdkBeforeU()159     public void testStartTransformMigrationOnSdkBeforeU() throws Exception {
160         try {
161             mIpSecManager.startTunnelModeTransformMigration(
162                     buildTestTransform(), SRC_ADDRESS_V6, DST_ADDRESS_V6);
163             fail("Expect to fail since migration is not supported before U");
164         } catch (UnsupportedOperationException expected) {
165         }
166     }
167 }
168