• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 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 com.android.internal.net.ipsec.test.ike;
18 
19 import static com.android.internal.net.ipsec.test.ike.IkeLocalRequestScheduler.LOCAL_REQUEST_WAKE_LOCK_TAG;
20 import static com.android.internal.net.ipsec.test.ike.IkeSessionStateMachine.BUSY_WAKE_LOCK_TAG;
21 import static com.android.internal.net.ipsec.test.ike.IkeSocket.SERVER_PORT_NON_UDP_ENCAPSULATED;
22 import static com.android.internal.net.ipsec.test.ike.IkeSocket.SERVER_PORT_UDP_ENCAPSULATED;
23 
24 import static org.mockito.ArgumentMatchers.argThat;
25 import static org.mockito.ArgumentMatchers.any;
26 import static org.mockito.ArgumentMatchers.anyInt;
27 import static org.mockito.ArgumentMatchers.eq;
28 import static org.mockito.Mockito.any;
29 import static org.mockito.Mockito.anyInt;
30 import static org.mockito.Mockito.doAnswer;
31 import static org.mockito.Mockito.doNothing;
32 import static org.mockito.Mockito.doReturn;
33 import static org.mockito.Mockito.eq;
34 import static org.mockito.Mockito.mock;
35 import static org.mockito.Mockito.reset;
36 import static org.mockito.Mockito.spy;
37 import static org.mockito.Mockito.times;
38 import static org.mockito.Mockito.verify;
39 import static org.mockito.Mockito.when;
40 
41 import android.content.Context;
42 import android.content.IntentFilter;
43 import android.net.ConnectivityManager;
44 import android.net.InetAddresses;
45 import android.net.IpSecManager;
46 import android.net.LinkAddress;
47 import android.net.LinkProperties;
48 import android.net.Network;
49 import android.net.NetworkCapabilities;
50 import android.net.SocketKeepalive;
51 import android.net.ipsec.test.ike.IkeManager;
52 import android.net.ipsec.test.ike.IkeSession;
53 import android.os.Handler;
54 import android.os.PowerManager;
55 
56 import com.android.internal.net.ipsec.test.ike.net.IkeLocalAddressGenerator;
57 import com.android.internal.net.ipsec.test.ike.testutils.MockIpSecTestUtils;
58 import com.android.internal.net.ipsec.test.ike.utils.IState;
59 import com.android.internal.net.ipsec.test.ike.utils.IkeAlarmReceiver;
60 import com.android.internal.net.ipsec.test.ike.utils.IkeMetrics;
61 import com.android.internal.net.ipsec.test.ike.utils.RandomnessFactory;
62 
63 import org.junit.Before;
64 import org.mockito.invocation.InvocationOnMock;
65 import org.mockito.stubbing.Answer;
66 
67 import java.io.IOException;
68 import java.net.Inet4Address;
69 import java.net.Inet6Address;
70 import java.net.InetAddress;
71 import java.util.concurrent.Executor;
72 
73 public abstract class IkeSessionTestBase {
74     protected static final Inet4Address LOCAL_ADDRESS =
75             (Inet4Address) InetAddresses.parseNumericAddress("192.0.2.200");
76     protected static final Inet4Address UPDATED_LOCAL_ADDRESS =
77             (Inet4Address) InetAddresses.parseNumericAddress("192.0.2.201");
78     protected static final Inet4Address REMOTE_ADDRESS =
79             (Inet4Address) InetAddresses.parseNumericAddress("127.0.0.1");
80     protected static final Inet6Address LOCAL_ADDRESS_V6 =
81             (Inet6Address) InetAddresses.parseNumericAddress("2001:db8::200");
82     protected static final Inet6Address UPDATED_LOCAL_ADDRESS_V6 =
83             (Inet6Address) InetAddresses.parseNumericAddress("2001:db8::201");
84     protected static final Inet6Address REMOTE_ADDRESS_V6 =
85             (Inet6Address) InetAddresses.parseNumericAddress("::1");
86     protected static final String REMOTE_HOSTNAME = "ike.test.android.com";
87 
88     protected PowerManager.WakeLock mMockBusyWakelock;
89     protected PowerManager.WakeLock mMockLocalRequestWakelock;
90 
91     protected MockIpSecTestUtils mMockIpSecTestUtils;
92     protected Context mSpyContext;
93     protected IpSecManager mIpSecManager;
94     protected PowerManager mPowerManager;
95     protected IkeMetrics mIkeMetrics;
96 
97     protected ConnectivityManager mMockConnectManager;
98     protected Network mMockDefaultNetwork;
99     protected SocketKeepalive mMockSocketKeepalive;
100     protected NetworkCapabilities mMockNetworkCapabilities;
101     protected IkeLocalAddressGenerator mMockIkeLocalAddressGenerator;
102 
103     @Before
setUp()104     public void setUp() throws Exception {
105         mMockIpSecTestUtils = MockIpSecTestUtils.setUpMockIpSec();
106         mIpSecManager = mMockIpSecTestUtils.getIpSecManager();
107 
108         mSpyContext = spy(mMockIpSecTestUtils.getContext());
109         doReturn(null)
110                 .when(mSpyContext)
111                 .registerReceiver(
112                         any(IkeAlarmReceiver.class),
113                         any(IntentFilter.class),
114                         any(),
115                         any(Handler.class),
116                         anyInt());
117         doNothing().when(mSpyContext).unregisterReceiver(any(IkeAlarmReceiver.class));
118 
119         mPowerManager = mock(PowerManager.class);
120         mMockBusyWakelock = mock(PowerManager.WakeLock.class);
121         mMockLocalRequestWakelock = mock(PowerManager.WakeLock.class);
122         doReturn(mPowerManager).when(mSpyContext).getSystemService(eq(PowerManager.class));
123         doReturn(mMockBusyWakelock)
124                 .when(mPowerManager)
125                 .newWakeLock(anyInt(), argThat(tag -> tag.contains(BUSY_WAKE_LOCK_TAG)));
126         // Only in test that all local requests will get the same WakeLock instance but in function
127         // code each local request will have a separate WakeLock.
128         doReturn(mMockLocalRequestWakelock)
129                 .when(mPowerManager)
130                 .newWakeLock(anyInt(), argThat(tag -> tag.contains(LOCAL_REQUEST_WAKE_LOCK_TAG)));
131 
132         mMockDefaultNetwork = mock(Network.class);
133         resetDefaultNetwork();
134 
135         mMockSocketKeepalive = mock(SocketKeepalive.class);
136 
137         mMockNetworkCapabilities = mock(NetworkCapabilities.class);
138         doReturn(false)
139                 .when(mMockNetworkCapabilities)
140                 .hasTransport(RandomnessFactory.TRANSPORT_TEST);
141 
142         mMockConnectManager = mock(ConnectivityManager.class);
143         doReturn(mMockConnectManager)
144                 .when(mSpyContext)
145                 .getSystemService(Context.CONNECTIVITY_SERVICE);
146 
147         mMockIkeLocalAddressGenerator = mock(IkeLocalAddressGenerator.class);
148         resetMockConnectManager();
149 
150         // Setup metrics parameters
151         mIkeMetrics = mock(IkeMetrics.class);
152         IkeManager.setIkeMetrics(mIkeMetrics);
153         doReturn(IkeSession.CONTEXT_ATTRIBUTION_TAG_VCN).when(mSpyContext).getAttributionTag();
154     }
155 
resetMockConnectManager()156     protected void resetMockConnectManager() throws Exception {
157         reset(mMockConnectManager);
158         doReturn(mMockDefaultNetwork).when(mMockConnectManager).getActiveNetwork();
159         doReturn(mMockSocketKeepalive)
160                 .when(mMockConnectManager)
161                 .createSocketKeepalive(
162                         any(Network.class),
163                         any(),
164                         any(Inet4Address.class),
165                         any(Inet4Address.class),
166                         any(Executor.class),
167                         any(SocketKeepalive.Callback.class));
168         doReturn(mMockNetworkCapabilities)
169                 .when(mMockConnectManager)
170                 .getNetworkCapabilities(any(Network.class));
171         setupLocalAddressForNetwork(mMockDefaultNetwork, LOCAL_ADDRESS);
172         setupRemoteAddressForNetwork(mMockDefaultNetwork, REMOTE_ADDRESS);
173     }
174 
resetDefaultNetwork()175     protected void resetDefaultNetwork() throws Exception {
176         reset(mMockDefaultNetwork);
177         doReturn(new InetAddress[] {REMOTE_ADDRESS})
178                 .when(mMockDefaultNetwork)
179                 .getAllByName(REMOTE_HOSTNAME);
180         doReturn(new InetAddress[] {REMOTE_ADDRESS})
181                 .when(mMockDefaultNetwork)
182                 .getAllByName(REMOTE_ADDRESS.getHostAddress());
183     }
184 
resetMockIkeSocket(IkeSocket mockSocket)185     protected void resetMockIkeSocket(IkeSocket mockSocket) {
186         reset(mockSocket);
187         if (mockSocket instanceof IkeUdp4Socket || mockSocket instanceof IkeUdp6Socket) {
188             when(mockSocket.getIkeServerPort()).thenReturn(SERVER_PORT_NON_UDP_ENCAPSULATED);
189         } else {
190             when(mockSocket.getIkeServerPort()).thenReturn(SERVER_PORT_UDP_ENCAPSULATED);
191         }
192     }
193 
newMockIkeSocket(Class<T> socketClass)194     protected <T extends IkeSocket> T newMockIkeSocket(Class<T> socketClass) {
195         T mockSocket = mock(socketClass);
196         resetMockIkeSocket(mockSocket);
197 
198         return mockSocket;
199     }
200 
setupLocalAddressAndGetLinkAddress(Network network, InetAddress address)201     private LinkAddress setupLocalAddressAndGetLinkAddress(Network network, InetAddress address)
202             throws Exception {
203         boolean isIpv4 = address instanceof Inet4Address;
204         when(mMockIkeLocalAddressGenerator.generateLocalAddress(
205                         eq(network), eq(isIpv4), any(), anyInt()))
206                 .thenReturn(address);
207 
208         LinkAddress mockLinkAddress = mock(LinkAddress.class);
209         when(mockLinkAddress.getAddress()).thenReturn(address);
210         if (!isIpv4) {
211             when(mockLinkAddress.isGlobalPreferred()).thenReturn(true);
212         }
213 
214         return mockLinkAddress;
215     }
216 
setupLocalAddressForNetwork( Network network, Inet4Address addressV4, Inet6Address addressV6)217     protected void setupLocalAddressForNetwork(
218             Network network, Inet4Address addressV4, Inet6Address addressV6) throws Exception {
219         LinkProperties linkProperties = new LinkProperties();
220         if (addressV4 != null) {
221             linkProperties.addLinkAddress(setupLocalAddressAndGetLinkAddress(network, addressV4));
222         }
223         if (addressV6 != null) {
224             linkProperties.addLinkAddress(setupLocalAddressAndGetLinkAddress(network, addressV6));
225         }
226         when(mMockConnectManager.getLinkProperties(eq(network))).thenReturn(linkProperties);
227     }
228 
setupLocalAddressForNetwork(Network network, InetAddress address)229     protected void setupLocalAddressForNetwork(Network network, InetAddress address)
230             throws Exception {
231         if (address instanceof Inet4Address) {
232             setupLocalAddressForNetwork(network, (Inet4Address) address, null);
233         } else {
234             setupLocalAddressForNetwork(network, null, (Inet6Address) address);
235         }
236     }
237 
setupRemoteAddressForNetwork(Network network, InetAddress... addresses)238     protected void setupRemoteAddressForNetwork(Network network, InetAddress... addresses)
239             throws Exception {
240         doAnswer(
241                 new Answer() {
242                         public Object answer(InvocationOnMock invocation) throws IOException {
243                             return addresses;
244                         }
245                 })
246                 .when(network)
247                 .getAllByName(REMOTE_HOSTNAME);
248     }
249 
verifyMetricsLogged(int sessionType, int stateCode, int exceptionCode)250     protected void verifyMetricsLogged(int sessionType, int stateCode, int exceptionCode) {
251         verify(mIkeMetrics)
252                 .logSessionTerminated(
253                         IkeMetrics.IKE_CALLER_UNKNOWN, sessionType, stateCode, exceptionCode);
254     }
255 
verifyIkeSaMetricsLogged( int count, int ikeCaller, int ikeSessionType, int sessionState, int dhGroup, int encryptionAlgorithm, int keyLength, int integrityAlgorithm, int prfAlgorithm, int exceptionCode)256     protected void verifyIkeSaMetricsLogged(
257             int count,
258             int ikeCaller,
259             int ikeSessionType,
260             int sessionState,
261             int dhGroup,
262             int encryptionAlgorithm,
263             int keyLength,
264             int integrityAlgorithm,
265             int prfAlgorithm,
266             int exceptionCode) {
267         verify(mIkeMetrics, times(count))
268                 .logSaNegotiation(
269                         eq(ikeCaller),
270                         eq(ikeSessionType),
271                         eq(sessionState),
272                         eq(dhGroup),
273                         eq(encryptionAlgorithm),
274                         eq(keyLength),
275                         eq(integrityAlgorithm),
276                         eq(prfAlgorithm),
277                         eq(exceptionCode));
278     }
279 
getStateCode(IState state)280     protected int getStateCode(IState state) {
281         return state instanceof AbstractSessionStateMachine.ExceptionHandlerBase
282                 ? ((AbstractSessionStateMachine.ExceptionHandlerBase) state).getMetricsStateCode()
283                 : IkeMetrics.IKE_STATE_UNKNOWN;
284     }
285 }
286