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 com.android.testutils.ParcelUtils.assertParcelSane; 20 21 import static org.junit.Assert.assertEquals; 22 import static org.junit.Assert.assertFalse; 23 import static org.junit.Assert.assertNotEquals; 24 import static org.junit.Assert.assertNull; 25 import static org.junit.Assert.assertTrue; 26 27 import android.net.IpSecAlgorithm; 28 import android.os.Build; 29 30 import androidx.test.filters.SmallTest; 31 32 import com.android.testutils.DevSdkIgnoreRule; 33 import com.android.testutils.DevSdkIgnoreRunner; 34 35 import org.junit.Test; 36 import org.junit.runner.RunWith; 37 38 import java.util.ArrayList; 39 import java.util.Arrays; 40 import java.util.List; 41 42 /** Unit tests for {@link VpnProfile}. */ 43 @SmallTest 44 @RunWith(DevSdkIgnoreRunner.class) 45 @DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.R) 46 public class VpnProfileTest { 47 private static final String DUMMY_PROFILE_KEY = "Test"; 48 49 private static final int ENCODED_INDEX_AUTH_PARAMS_INLINE = 23; 50 private static final int ENCODED_INDEX_RESTRICTED_TO_TEST_NETWORKS = 24; 51 52 @Test 53 public void testDefaults() throws Exception { 54 final VpnProfile p = new VpnProfile(DUMMY_PROFILE_KEY); 55 56 assertEquals(DUMMY_PROFILE_KEY, p.key); 57 assertEquals("", p.name); 58 assertEquals(VpnProfile.TYPE_PPTP, p.type); 59 assertEquals("", p.server); 60 assertEquals("", p.username); 61 assertEquals("", p.password); 62 assertEquals("", p.dnsServers); 63 assertEquals("", p.searchDomains); 64 assertEquals("", p.routes); 65 assertTrue(p.mppe); 66 assertEquals("", p.l2tpSecret); 67 assertEquals("", p.ipsecIdentifier); 68 assertEquals("", p.ipsecSecret); 69 assertEquals("", p.ipsecUserCert); 70 assertEquals("", p.ipsecCaCert); 71 assertEquals("", p.ipsecServerCert); 72 assertEquals(null, p.proxy); 73 assertTrue(p.getAllowedAlgorithms() != null && p.getAllowedAlgorithms().isEmpty()); 74 assertFalse(p.isBypassable); 75 assertFalse(p.isMetered); 76 assertEquals(1360, p.maxMtu); 77 assertFalse(p.areAuthParamsInline); 78 assertFalse(p.isRestrictedToTestNetworks); 79 } 80 81 private VpnProfile getSampleIkev2Profile(String key) { 82 final VpnProfile p = new VpnProfile(key, true /* isRestrictedToTestNetworks */); 83 84 p.name = "foo"; 85 p.type = VpnProfile.TYPE_IKEV2_IPSEC_USER_PASS; 86 p.server = "bar"; 87 p.username = "baz"; 88 p.password = "qux"; 89 p.dnsServers = "8.8.8.8"; 90 p.searchDomains = ""; 91 p.routes = "0.0.0.0/0"; 92 p.mppe = false; 93 p.l2tpSecret = ""; 94 p.ipsecIdentifier = "quux"; 95 p.ipsecSecret = "quuz"; 96 p.ipsecUserCert = "corge"; 97 p.ipsecCaCert = "grault"; 98 p.ipsecServerCert = "garply"; 99 p.proxy = null; 100 p.setAllowedAlgorithms( 101 Arrays.asList( 102 IpSecAlgorithm.AUTH_CRYPT_AES_GCM, 103 IpSecAlgorithm.AUTH_CRYPT_CHACHA20_POLY1305, 104 IpSecAlgorithm.AUTH_HMAC_SHA512, 105 IpSecAlgorithm.CRYPT_AES_CBC)); 106 p.isBypassable = true; 107 p.isMetered = true; 108 p.maxMtu = 1350; 109 p.areAuthParamsInline = true; 110 111 // Not saved, but also not compared. 112 p.saveLogin = true; 113 114 return p; 115 } 116 117 @Test 118 public void testEquals() { 119 assertEquals( 120 getSampleIkev2Profile(DUMMY_PROFILE_KEY), getSampleIkev2Profile(DUMMY_PROFILE_KEY)); 121 122 final VpnProfile modified = getSampleIkev2Profile(DUMMY_PROFILE_KEY); 123 modified.maxMtu--; 124 assertNotEquals(getSampleIkev2Profile(DUMMY_PROFILE_KEY), modified); 125 } 126 127 @Test 128 public void testParcelUnparcel() { 129 assertParcelSane(getSampleIkev2Profile(DUMMY_PROFILE_KEY), 23); 130 } 131 132 @Test 133 public void testEncodeDecode() { 134 final VpnProfile profile = getSampleIkev2Profile(DUMMY_PROFILE_KEY); 135 final VpnProfile decoded = VpnProfile.decode(DUMMY_PROFILE_KEY, profile.encode()); 136 assertEquals(profile, decoded); 137 } 138 139 @Test 140 public void testEncodeDecodeTooManyValues() { 141 final VpnProfile profile = getSampleIkev2Profile(DUMMY_PROFILE_KEY); 142 final byte[] tooManyValues = 143 (new String(profile.encode()) + VpnProfile.VALUE_DELIMITER + "invalid").getBytes(); 144 145 assertNull(VpnProfile.decode(DUMMY_PROFILE_KEY, tooManyValues)); 146 } 147 148 private String getEncodedDecodedIkev2ProfileMissingValues(int... missingIndices) { 149 // Sort to ensure when we remove, we can do it from greatest first. 150 Arrays.sort(missingIndices); 151 152 final String encoded = new String(getSampleIkev2Profile(DUMMY_PROFILE_KEY).encode()); 153 final List<String> parts = 154 new ArrayList<>(Arrays.asList(encoded.split(VpnProfile.VALUE_DELIMITER))); 155 156 // Remove from back first to ensure indexing is consistent. 157 for (int i = missingIndices.length - 1; i >= 0; i--) { 158 parts.remove(missingIndices[i]); 159 } 160 161 return String.join(VpnProfile.VALUE_DELIMITER, parts.toArray(new String[0])); 162 } 163 164 @Test 165 public void testEncodeDecodeInvalidNumberOfValues() { 166 final String tooFewValues = 167 getEncodedDecodedIkev2ProfileMissingValues( 168 ENCODED_INDEX_AUTH_PARAMS_INLINE, 169 ENCODED_INDEX_RESTRICTED_TO_TEST_NETWORKS /* missingIndices */); 170 171 assertNull(VpnProfile.decode(DUMMY_PROFILE_KEY, tooFewValues.getBytes())); 172 } 173 174 @Test 175 public void testEncodeDecodeMissingIsRestrictedToTestNetworks() { 176 final String tooFewValues = 177 getEncodedDecodedIkev2ProfileMissingValues( 178 ENCODED_INDEX_RESTRICTED_TO_TEST_NETWORKS /* missingIndices */); 179 180 // Verify decoding without isRestrictedToTestNetworks defaults to false 181 final VpnProfile decoded = VpnProfile.decode(DUMMY_PROFILE_KEY, tooFewValues.getBytes()); 182 assertFalse(decoded.isRestrictedToTestNetworks); 183 } 184 185 @Test 186 public void testEncodeDecodeLoginsNotSaved() { 187 final VpnProfile profile = getSampleIkev2Profile(DUMMY_PROFILE_KEY); 188 profile.saveLogin = false; 189 190 final VpnProfile decoded = VpnProfile.decode(DUMMY_PROFILE_KEY, profile.encode()); 191 assertNotEquals(profile, decoded); 192 193 // Add the username/password back, everything else must be equal. 194 decoded.username = profile.username; 195 decoded.password = profile.password; 196 assertEquals(profile, decoded); 197 } 198 } 199