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