• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2019 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;
18 
19 import static android.net.cts.util.IkeSessionTestUtils.CHILD_PARAMS;
20 import static android.net.cts.util.IkeSessionTestUtils.IKE_PARAMS_V4;
21 
22 import static com.android.modules.utils.build.SdkLevel.isAtLeastT;
23 import static com.android.modules.utils.build.SdkLevel.isAtLeastU;
24 import static com.android.testutils.ParcelUtils.assertParcelSane;
25 
26 import static org.junit.Assert.assertEquals;
27 import static org.junit.Assert.assertFalse;
28 import static org.junit.Assert.assertNotEquals;
29 import static org.junit.Assert.assertNull;
30 import static org.junit.Assert.assertTrue;
31 
32 import android.net.IpSecAlgorithm;
33 import android.net.ipsec.ike.IkeTunnelConnectionParams;
34 import android.os.Build;
35 
36 import androidx.test.filters.SmallTest;
37 
38 import com.android.testutils.DevSdkIgnoreRule;
39 import com.android.testutils.DevSdkIgnoreRunner;
40 
41 import org.junit.Test;
42 import org.junit.runner.RunWith;
43 
44 import java.util.ArrayList;
45 import java.util.Arrays;
46 import java.util.List;
47 
48 /** Unit tests for {@link VpnProfile}. */
49 @SmallTest
50 @RunWith(DevSdkIgnoreRunner.class)
51 @DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.R)
52 public class VpnProfileTest {
53     private static final String DUMMY_PROFILE_KEY = "Test";
54 
55     private static final int ENCODED_INDEX_AUTH_PARAMS_INLINE = 23;
56     private static final int ENCODED_INDEX_RESTRICTED_TO_TEST_NETWORKS = 24;
57     private static final int ENCODED_INDEX_EXCLUDE_LOCAL_ROUTE = 25;
58     private static final int ENCODED_INDEX_REQUIRE_PLATFORM_VALIDATION = 26;
59     private static final int ENCODED_INDEX_IKE_TUN_CONN_PARAMS = 27;
60     private static final int ENCODED_INDEX_AUTOMATIC_NATT_KEEPALIVE_TIMER_ENABLED = 28;
61     private static final int ENCODED_INDEX_AUTOMATIC_IP_VERSION_SELECTION_ENABLED = 29;
62 
63     @Test
testDefaults()64     public void testDefaults() throws Exception {
65         final VpnProfile p = new VpnProfile(DUMMY_PROFILE_KEY);
66 
67         assertEquals(DUMMY_PROFILE_KEY, p.key);
68         assertEquals("", p.name);
69         assertEquals(VpnProfile.TYPE_PPTP, p.type);
70         assertEquals("", p.server);
71         assertEquals("", p.username);
72         assertEquals("", p.password);
73         assertEquals("", p.dnsServers);
74         assertEquals("", p.searchDomains);
75         assertEquals("", p.routes);
76         assertTrue(p.mppe);
77         assertEquals("", p.l2tpSecret);
78         assertEquals("", p.ipsecIdentifier);
79         assertEquals("", p.ipsecSecret);
80         assertEquals("", p.ipsecUserCert);
81         assertEquals("", p.ipsecCaCert);
82         assertEquals("", p.ipsecServerCert);
83         assertEquals(null, p.proxy);
84         assertTrue(p.getAllowedAlgorithms() != null && p.getAllowedAlgorithms().isEmpty());
85         assertFalse(p.isBypassable);
86         assertFalse(p.isMetered);
87         assertEquals(1360, p.maxMtu);
88         assertFalse(p.areAuthParamsInline);
89         assertFalse(p.isRestrictedToTestNetworks);
90         assertFalse(p.excludeLocalRoutes);
91         assertFalse(p.requiresInternetValidation);
92         assertFalse(p.automaticNattKeepaliveTimerEnabled);
93         assertFalse(p.automaticIpVersionSelectionEnabled);
94     }
95 
getSampleIkev2Profile(String key)96     private VpnProfile getSampleIkev2Profile(String key) {
97         final VpnProfile p = new VpnProfile(key, true /* isRestrictedToTestNetworks */,
98                 false /* excludesLocalRoutes */, true /* requiresPlatformValidation */,
99                 null /* ikeTunConnParams */, true /* mAutomaticNattKeepaliveTimerEnabled */,
100                 true /* automaticIpVersionSelectionEnabled */);
101 
102         p.name = "foo";
103         p.type = VpnProfile.TYPE_IKEV2_IPSEC_USER_PASS;
104         p.server = "bar";
105         p.username = "baz";
106         p.password = "qux";
107         p.dnsServers = "8.8.8.8";
108         p.searchDomains = "";
109         p.routes = "0.0.0.0/0";
110         p.mppe = false;
111         p.l2tpSecret = "";
112         p.ipsecIdentifier = "quux";
113         p.ipsecSecret = "quuz";
114         p.ipsecUserCert = "corge";
115         p.ipsecCaCert = "grault";
116         p.ipsecServerCert = "garply";
117         p.proxy = null;
118         p.setAllowedAlgorithms(
119                 Arrays.asList(
120                         IpSecAlgorithm.AUTH_CRYPT_AES_GCM,
121                         IpSecAlgorithm.AUTH_CRYPT_CHACHA20_POLY1305,
122                         IpSecAlgorithm.AUTH_HMAC_SHA512,
123                         IpSecAlgorithm.CRYPT_AES_CBC));
124         p.isBypassable = true;
125         p.isMetered = true;
126         p.maxMtu = 1350;
127         p.areAuthParamsInline = true;
128 
129         // Not saved, but also not compared.
130         p.saveLogin = true;
131 
132         return p;
133     }
134 
getSampleIkev2ProfileWithIkeTunConnParams(String key)135     private VpnProfile getSampleIkev2ProfileWithIkeTunConnParams(String key) {
136         final VpnProfile p = new VpnProfile(key, true /* isRestrictedToTestNetworks */,
137                 false /* excludesLocalRoutes */, true /* requiresPlatformValidation */,
138                 new IkeTunnelConnectionParams(IKE_PARAMS_V4, CHILD_PARAMS),
139                 true /* mAutomaticNattKeepaliveTimerEnabled */,
140                 true /* automaticIpVersionSelectionEnabled */);
141 
142         p.name = "foo";
143         p.server = "bar";
144         p.dnsServers = "8.8.8.8";
145         p.searchDomains = "";
146         p.routes = "0.0.0.0/0";
147         p.mppe = false;
148         p.proxy = null;
149         p.setAllowedAlgorithms(
150                 Arrays.asList(
151                         IpSecAlgorithm.AUTH_CRYPT_AES_GCM,
152                         IpSecAlgorithm.AUTH_CRYPT_CHACHA20_POLY1305,
153                         IpSecAlgorithm.AUTH_HMAC_SHA512,
154                         IpSecAlgorithm.CRYPT_AES_CBC));
155         p.isBypassable = true;
156         p.isMetered = true;
157         p.maxMtu = 1350;
158         p.areAuthParamsInline = true;
159 
160         // Not saved, but also not compared.
161         p.saveLogin = true;
162 
163         return p;
164     }
165 
166     @Test
testEquals()167     public void testEquals() {
168         assertEquals(
169                 getSampleIkev2Profile(DUMMY_PROFILE_KEY), getSampleIkev2Profile(DUMMY_PROFILE_KEY));
170 
171         final VpnProfile modified = getSampleIkev2Profile(DUMMY_PROFILE_KEY);
172         modified.maxMtu--;
173         assertNotEquals(getSampleIkev2Profile(DUMMY_PROFILE_KEY), modified);
174     }
175 
176     @Test
testParcelUnparcel()177     public void testParcelUnparcel() {
178         if (isAtLeastU()) {
179             // automaticNattKeepaliveTimerEnabled, automaticIpVersionSelectionEnabled added in U.
180             assertParcelSane(getSampleIkev2Profile(DUMMY_PROFILE_KEY), 28);
181             assertParcelSane(getSampleIkev2ProfileWithIkeTunConnParams(DUMMY_PROFILE_KEY), 28);
182         } else if (isAtLeastT()) {
183             // excludeLocalRoutes, requiresPlatformValidation were added in T.
184             assertParcelSane(getSampleIkev2Profile(DUMMY_PROFILE_KEY), 26);
185             assertParcelSane(getSampleIkev2ProfileWithIkeTunConnParams(DUMMY_PROFILE_KEY), 26);
186         } else {
187             assertParcelSane(getSampleIkev2Profile(DUMMY_PROFILE_KEY), 23);
188         }
189     }
190 
191     @Test
testEncodeDecodeWithIkeTunConnParams()192     public void testEncodeDecodeWithIkeTunConnParams() {
193         final VpnProfile profile = getSampleIkev2ProfileWithIkeTunConnParams(DUMMY_PROFILE_KEY);
194         final VpnProfile decoded = VpnProfile.decode(DUMMY_PROFILE_KEY, profile.encode());
195         assertEquals(profile, decoded);
196     }
197 
198     @Test
testEncodeDecode()199     public void testEncodeDecode() {
200         final VpnProfile profile = getSampleIkev2Profile(DUMMY_PROFILE_KEY);
201         final VpnProfile decoded = VpnProfile.decode(DUMMY_PROFILE_KEY, profile.encode());
202         assertEquals(profile, decoded);
203     }
204 
205     @Test
testEncodeDecodeTooManyValues()206     public void testEncodeDecodeTooManyValues() {
207         final VpnProfile profile = getSampleIkev2Profile(DUMMY_PROFILE_KEY);
208         final byte[] tooManyValues =
209                 (new String(profile.encode()) + VpnProfile.VALUE_DELIMITER + "invalid").getBytes();
210 
211         assertNull(VpnProfile.decode(DUMMY_PROFILE_KEY, tooManyValues));
212     }
213 
getEncodedDecodedIkev2ProfileMissingValues(int... missingIndices)214     private String getEncodedDecodedIkev2ProfileMissingValues(int... missingIndices) {
215         // Sort to ensure when we remove, we can do it from greatest first.
216         Arrays.sort(missingIndices);
217 
218         final String encoded = new String(getSampleIkev2Profile(DUMMY_PROFILE_KEY).encode());
219         final List<String> parts =
220                 new ArrayList<>(Arrays.asList(encoded.split(VpnProfile.VALUE_DELIMITER)));
221 
222         // Remove from back first to ensure indexing is consistent.
223         for (int i = missingIndices.length - 1; i >= 0; i--) {
224             parts.remove(missingIndices[i]);
225         }
226 
227         return String.join(VpnProfile.VALUE_DELIMITER, parts.toArray(new String[0]));
228     }
229 
230     @Test
testEncodeDecodeInvalidNumberOfValues()231     public void testEncodeDecodeInvalidNumberOfValues() {
232         final String tooFewValues =
233                 getEncodedDecodedIkev2ProfileMissingValues(
234                         ENCODED_INDEX_AUTH_PARAMS_INLINE,
235                         ENCODED_INDEX_RESTRICTED_TO_TEST_NETWORKS,
236                         ENCODED_INDEX_EXCLUDE_LOCAL_ROUTE,
237                         ENCODED_INDEX_REQUIRE_PLATFORM_VALIDATION,
238                         ENCODED_INDEX_IKE_TUN_CONN_PARAMS,
239                         ENCODED_INDEX_AUTOMATIC_NATT_KEEPALIVE_TIMER_ENABLED,
240                         ENCODED_INDEX_AUTOMATIC_IP_VERSION_SELECTION_ENABLED
241                         /* missingIndices */);
242 
243         assertNull(VpnProfile.decode(DUMMY_PROFILE_KEY, tooFewValues.getBytes()));
244     }
245 
getEncodedDecodedIkev2ProfileWithtooFewValues()246     private String getEncodedDecodedIkev2ProfileWithtooFewValues() {
247         return getEncodedDecodedIkev2ProfileMissingValues(
248                 ENCODED_INDEX_RESTRICTED_TO_TEST_NETWORKS,
249                 ENCODED_INDEX_EXCLUDE_LOCAL_ROUTE,
250                 ENCODED_INDEX_REQUIRE_PLATFORM_VALIDATION,
251                 ENCODED_INDEX_IKE_TUN_CONN_PARAMS,
252                 ENCODED_INDEX_AUTOMATIC_NATT_KEEPALIVE_TIMER_ENABLED,
253                 ENCODED_INDEX_AUTOMATIC_IP_VERSION_SELECTION_ENABLED /* missingIndices */);
254     }
255 
256     @Test
testEncodeDecodeMissingIsRestrictedToTestNetworks()257     public void testEncodeDecodeMissingIsRestrictedToTestNetworks() {
258         final String tooFewValues = getEncodedDecodedIkev2ProfileWithtooFewValues();
259 
260         // Verify decoding without isRestrictedToTestNetworks defaults to false
261         final VpnProfile decoded = VpnProfile.decode(DUMMY_PROFILE_KEY, tooFewValues.getBytes());
262         assertFalse(decoded.isRestrictedToTestNetworks);
263     }
264 
265     @Test
testEncodeDecodeMissingExcludeLocalRoutes()266     public void testEncodeDecodeMissingExcludeLocalRoutes() {
267         final String tooFewValues = getEncodedDecodedIkev2ProfileWithtooFewValues();
268 
269         // Verify decoding without excludeLocalRoutes defaults to false
270         final VpnProfile decoded = VpnProfile.decode(DUMMY_PROFILE_KEY, tooFewValues.getBytes());
271         assertFalse(decoded.excludeLocalRoutes);
272     }
273 
274     @Test
testEncodeDecodeMissingRequiresValidation()275     public void testEncodeDecodeMissingRequiresValidation() {
276         final String tooFewValues = getEncodedDecodedIkev2ProfileWithtooFewValues();
277 
278         // Verify decoding without requiresValidation defaults to false
279         final VpnProfile decoded = VpnProfile.decode(DUMMY_PROFILE_KEY, tooFewValues.getBytes());
280         assertFalse(decoded.requiresInternetValidation);
281     }
282 
283     @Test
testEncodeDecodeMissingAutomaticNattKeepaliveTimerEnabled()284     public void testEncodeDecodeMissingAutomaticNattKeepaliveTimerEnabled() {
285         final String tooFewValues = getEncodedDecodedIkev2ProfileWithtooFewValues();
286 
287         // Verify decoding without automaticNattKeepaliveTimerEnabled defaults to false
288         final VpnProfile decoded = VpnProfile.decode(DUMMY_PROFILE_KEY, tooFewValues.getBytes());
289         assertFalse(decoded.automaticNattKeepaliveTimerEnabled);
290     }
291 
292     @Test
testEncodeDecodeMissingAutomaticIpVersionSelectionEnabled()293     public void testEncodeDecodeMissingAutomaticIpVersionSelectionEnabled() {
294         final String tooFewValues = getEncodedDecodedIkev2ProfileWithtooFewValues();
295 
296         // Verify decoding without automaticIpVersionSelectionEnabled defaults to false
297         final VpnProfile decoded = VpnProfile.decode(DUMMY_PROFILE_KEY, tooFewValues.getBytes());
298         assertFalse(decoded.automaticIpVersionSelectionEnabled);
299     }
300 
301     @Test
testEncodeDecodeLoginsNotSaved()302     public void testEncodeDecodeLoginsNotSaved() {
303         final VpnProfile profile = getSampleIkev2Profile(DUMMY_PROFILE_KEY);
304         profile.saveLogin = false;
305 
306         final VpnProfile decoded = VpnProfile.decode(DUMMY_PROFILE_KEY, profile.encode());
307         assertNotEquals(profile, decoded);
308 
309         // Add the username/password back, everything else must be equal.
310         decoded.username = profile.username;
311         decoded.password = profile.password;
312         assertEquals(profile, decoded);
313     }
314 }
315