NetworkListStoreDataTest.java revision 0a0b5035ce8013ed327a0802357a1b7df3061912
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 17package com.android.server.wifi; 18 19import static org.junit.Assert.*; 20import static org.mockito.Mockito.*; 21 22import android.net.wifi.WifiConfiguration; 23import android.test.suitebuilder.annotation.SmallTest; 24import android.util.Xml; 25 26import com.android.internal.util.FastXmlSerializer; 27 28import org.junit.Before; 29import org.junit.Test; 30import org.xmlpull.v1.XmlPullParser; 31import org.xmlpull.v1.XmlPullParserException; 32import org.xmlpull.v1.XmlSerializer; 33 34import java.io.ByteArrayInputStream; 35import java.io.ByteArrayOutputStream; 36import java.nio.charset.StandardCharsets; 37import java.util.ArrayList; 38import java.util.Arrays; 39import java.util.List; 40 41/** 42 * Unit tests for {@link com.android.server.wifi.NetworksListStoreData}. 43 */ 44@SmallTest 45public class NetworkListStoreDataTest { 46 47 private static final String TEST_SSID = "WifiConfigStoreDataSSID_"; 48 private static final String TEST_CONNECT_CHOICE = "XmlUtilConnectChoice"; 49 private static final long TEST_CONNECT_CHOICE_TIMESTAMP = 0x4566; 50 private static final String SINGLE_OPEN_NETWORK_DATA_XML_STRING_FORMAT = 51 "<Network>\n" 52 + "<WifiConfiguration>\n" 53 + "<string name=\"ConfigKey\">%s</string>\n" 54 + "<string name=\"SSID\">%s</string>\n" 55 + "<null name=\"BSSID\" />\n" 56 + "<null name=\"PreSharedKey\" />\n" 57 + "<null name=\"WEPKeys\" />\n" 58 + "<int name=\"WEPTxKeyIndex\" value=\"0\" />\n" 59 + "<boolean name=\"HiddenSSID\" value=\"false\" />\n" 60 + "<boolean name=\"RequirePMF\" value=\"false\" />\n" 61 + "<byte-array name=\"AllowedKeyMgmt\" num=\"1\">01</byte-array>\n" 62 + "<byte-array name=\"AllowedProtocols\" num=\"0\"></byte-array>\n" 63 + "<byte-array name=\"AllowedAuthAlgos\" num=\"0\"></byte-array>\n" 64 + "<byte-array name=\"AllowedGroupCiphers\" num=\"0\"></byte-array>\n" 65 + "<byte-array name=\"AllowedPairwiseCiphers\" num=\"0\"></byte-array>\n" 66 + "<boolean name=\"Shared\" value=\"%s\" />\n" 67 + "<null name=\"FQDN\" />\n" 68 + "<null name=\"ProviderFriendlyName\" />\n" 69 + "<null name=\"LinkedNetworksList\" />\n" 70 + "<null name=\"DefaultGwMacAddress\" />\n" 71 + "<boolean name=\"ValidatedInternetAccess\" value=\"false\" />\n" 72 + "<boolean name=\"NoInternetAccessExpected\" value=\"false\" />\n" 73 + "<int name=\"UserApproved\" value=\"0\" />\n" 74 + "<boolean name=\"MeteredHint\" value=\"false\" />\n" 75 + "<boolean name=\"UseExternalScores\" value=\"false\" />\n" 76 + "<int name=\"NumAssociation\" value=\"0\" />\n" 77 + "<int name=\"CreatorUid\" value=\"%d\" />\n" 78 + "<null name=\"CreatorName\" />\n" 79 + "<null name=\"CreationTime\" />\n" 80 + "<int name=\"LastUpdateUid\" value=\"-1\" />\n" 81 + "<null name=\"LastUpdateName\" />\n" 82 + "<int name=\"LastConnectUid\" value=\"0\" />\n" 83 + "</WifiConfiguration>\n" 84 + "<NetworkStatus>\n" 85 + "<string name=\"SelectionStatus\">NETWORK_SELECTION_ENABLED</string>\n" 86 + "<string name=\"DisableReason\">NETWORK_SELECTION_ENABLE</string>\n" 87 + "<null name=\"ConnectChoice\" />\n" 88 + "<long name=\"ConnectChoiceTimeStamp\" value=\"-1\" />\n" 89 + "<boolean name=\"HasEverConnected\" value=\"false\" />\n" 90 + "</NetworkStatus>\n" 91 + "<IpConfiguration>\n" 92 + "<string name=\"IpAssignment\">DHCP</string>\n" 93 + "<string name=\"ProxySettings\">NONE</string>\n" 94 + "</IpConfiguration>\n" 95 + "</Network>\n"; 96 97 private static final String SINGLE_EAP_NETWORK_DATA_XML_STRING_FORMAT = 98 "<Network>\n" 99 + "<WifiConfiguration>\n" 100 + "<string name=\"ConfigKey\">%s</string>\n" 101 + "<string name=\"SSID\">%s</string>\n" 102 + "<null name=\"BSSID\" />\n" 103 + "<null name=\"PreSharedKey\" />\n" 104 + "<null name=\"WEPKeys\" />\n" 105 + "<int name=\"WEPTxKeyIndex\" value=\"0\" />\n" 106 + "<boolean name=\"HiddenSSID\" value=\"false\" />\n" 107 + "<boolean name=\"RequirePMF\" value=\"false\" />\n" 108 + "<byte-array name=\"AllowedKeyMgmt\" num=\"1\">0c</byte-array>\n" 109 + "<byte-array name=\"AllowedProtocols\" num=\"0\"></byte-array>\n" 110 + "<byte-array name=\"AllowedAuthAlgos\" num=\"0\"></byte-array>\n" 111 + "<byte-array name=\"AllowedGroupCiphers\" num=\"0\"></byte-array>\n" 112 + "<byte-array name=\"AllowedPairwiseCiphers\" num=\"0\"></byte-array>\n" 113 + "<boolean name=\"Shared\" value=\"%s\" />\n" 114 + "<null name=\"FQDN\" />\n" 115 + "<null name=\"ProviderFriendlyName\" />\n" 116 + "<null name=\"LinkedNetworksList\" />\n" 117 + "<null name=\"DefaultGwMacAddress\" />\n" 118 + "<boolean name=\"ValidatedInternetAccess\" value=\"false\" />\n" 119 + "<boolean name=\"NoInternetAccessExpected\" value=\"false\" />\n" 120 + "<int name=\"UserApproved\" value=\"0\" />\n" 121 + "<boolean name=\"MeteredHint\" value=\"false\" />\n" 122 + "<boolean name=\"UseExternalScores\" value=\"false\" />\n" 123 + "<int name=\"NumAssociation\" value=\"0\" />\n" 124 + "<int name=\"CreatorUid\" value=\"%d\" />\n" 125 + "<null name=\"CreatorName\" />\n" 126 + "<null name=\"CreationTime\" />\n" 127 + "<int name=\"LastUpdateUid\" value=\"-1\" />\n" 128 + "<null name=\"LastUpdateName\" />\n" 129 + "<int name=\"LastConnectUid\" value=\"0\" />\n" 130 + "</WifiConfiguration>\n" 131 + "<NetworkStatus>\n" 132 + "<string name=\"SelectionStatus\">NETWORK_SELECTION_ENABLED</string>\n" 133 + "<string name=\"DisableReason\">NETWORK_SELECTION_ENABLE</string>\n" 134 + "<null name=\"ConnectChoice\" />\n" 135 + "<long name=\"ConnectChoiceTimeStamp\" value=\"-1\" />\n" 136 + "<boolean name=\"HasEverConnected\" value=\"false\" />\n" 137 + "</NetworkStatus>\n" 138 + "<IpConfiguration>\n" 139 + "<string name=\"IpAssignment\">DHCP</string>\n" 140 + "<string name=\"ProxySettings\">NONE</string>\n" 141 + "</IpConfiguration>\n" 142 + "<WifiEnterpriseConfiguration>\n" 143 + "<string name=\"Identity\"></string>\n" 144 + "<string name=\"AnonIdentity\"></string>\n" 145 + "<string name=\"Password\"></string>\n" 146 + "<string name=\"ClientCert\"></string>\n" 147 + "<string name=\"CaCert\"></string>\n" 148 + "<string name=\"SubjectMatch\"></string>\n" 149 + "<string name=\"Engine\"></string>\n" 150 + "<string name=\"EngineId\"></string>\n" 151 + "<string name=\"PrivateKeyId\"></string>\n" 152 + "<string name=\"AltSubjectMatch\"></string>\n" 153 + "<string name=\"DomSuffixMatch\"></string>\n" 154 + "<string name=\"CaPath\"></string>\n" 155 + "<int name=\"EapMethod\" value=\"2\" />\n" 156 + "<int name=\"Phase2Method\" value=\"0\" />\n" 157 + "</WifiEnterpriseConfiguration>\n" 158 + "</Network>\n"; 159 160 private NetworkListStoreData mNetworkListStoreData; 161 162 @Before 163 public void setUp() throws Exception { 164 mNetworkListStoreData = new NetworkListStoreData(); 165 } 166 167 /** 168 * Helper function for serializing configuration data to a XML block. 169 * 170 * @param shared Flag indicating serializing shared or user configurations 171 * @return byte[] of the XML data 172 * @throws Exception 173 */ 174 private byte[] serializeData(boolean shared) throws Exception { 175 final XmlSerializer out = new FastXmlSerializer(); 176 final ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); 177 out.setOutput(outputStream, StandardCharsets.UTF_8.name()); 178 mNetworkListStoreData.serializeData(out, shared); 179 out.flush(); 180 return outputStream.toByteArray(); 181 } 182 183 /** 184 * Helper function for parsing configuration data from a XML block. 185 * 186 * @param data XML data to parse from 187 * @param shared Flag indicating parsing of shared or user configurations 188 * @return List of WifiConfiguration parsed 189 * @throws Exception 190 */ 191 private List<WifiConfiguration> deserializeData(byte[] data, boolean shared) throws Exception { 192 final XmlPullParser in = Xml.newPullParser(); 193 final ByteArrayInputStream inputStream = new ByteArrayInputStream(data); 194 in.setInput(inputStream, StandardCharsets.UTF_8.name()); 195 mNetworkListStoreData.deserializeData(in, in.getDepth(), shared); 196 if (shared) { 197 return mNetworkListStoreData.getSharedConfigurations(); 198 } else { 199 return mNetworkListStoreData.getUserConfigurations(); 200 } 201 } 202 203 /** 204 * Helper function for generating a network list for testing purpose. The network list 205 * will contained an open and an EAP network. 206 * 207 * @param shared Flag indicating shared network 208 * @return List of WifiConfiguration 209 */ 210 private List<WifiConfiguration> getTestNetworksConfig(boolean shared) { 211 WifiConfiguration openNetwork = WifiConfigurationTestUtil.createOpenNetwork(); 212 openNetwork.shared = shared; 213 openNetwork.setIpConfiguration( 214 WifiConfigurationTestUtil.createDHCPIpConfigurationWithNoProxy()); 215 WifiConfiguration eapNetwork = WifiConfigurationTestUtil.createEapNetwork(); 216 eapNetwork.shared = shared; 217 eapNetwork.setIpConfiguration( 218 WifiConfigurationTestUtil.createDHCPIpConfigurationWithNoProxy()); 219 List<WifiConfiguration> networkList = new ArrayList<>(); 220 networkList.add(openNetwork); 221 networkList.add(eapNetwork); 222 return networkList; 223 } 224 225 /** 226 * Helper function for generating XML block containing two networks, an open and an EAP 227 * network. 228 * 229 * @param openNetwork The WifiConfiguration for an open network 230 * @param eapNetwork The WifiConfiguration for an EAP network 231 * @return byte[] of the XML data 232 */ 233 private byte[] getTestNetworksXmlBytes(WifiConfiguration openNetwork, 234 WifiConfiguration eapNetwork) { 235 String openNetworkXml = String.format(SINGLE_OPEN_NETWORK_DATA_XML_STRING_FORMAT, 236 openNetwork.configKey().replaceAll("\"", """), 237 openNetwork.SSID.replaceAll("\"", """), 238 openNetwork.shared, openNetwork.creatorUid); 239 String eapNetworkXml = String.format(SINGLE_EAP_NETWORK_DATA_XML_STRING_FORMAT, 240 eapNetwork.configKey().replaceAll("\"", """), 241 eapNetwork.SSID.replaceAll("\"", """), 242 eapNetwork.shared, eapNetwork.creatorUid); 243 return (openNetworkXml + eapNetworkXml).getBytes(StandardCharsets.UTF_8); 244 } 245 246 /** 247 * Verify that serializing the store data without any configuration doesn't cause any crash 248 * and no data should be serialized. 249 * 250 * @throws Exception 251 */ 252 @Test 253 public void serializeEmptyConfigs() throws Exception { 254 assertEquals(0, serializeData(true /* shared */).length); 255 assertEquals(0, serializeData(false /* shared */).length); 256 } 257 258 /** 259 * Verify that parsing an empty data doesn't cause any crash and no configuration should 260 * be parsed. 261 * 262 * @throws Exception 263 */ 264 @Test 265 public void deserializeEmptyData() throws Exception { 266 assertTrue(deserializeData(new byte[0], true /* shared */).isEmpty()); 267 assertTrue(deserializeData(new byte[0], false /* shared */).isEmpty()); 268 } 269 270 /** 271 * Verify that NetworkListStoreData does support share data. 272 * 273 * @throws Exception 274 */ 275 @Test 276 public void supportShareData() throws Exception { 277 assertTrue(mNetworkListStoreData.supportShareData()); 278 } 279 280 /** 281 * Verify that the shared configurations (containing an open and an EAP network) are serialized 282 * correctly, matching the expected XML string. 283 * 284 * @throws Exception 285 */ 286 @Test 287 public void serializeSharedConfigurations() throws Exception { 288 List<WifiConfiguration> networkList = getTestNetworksConfig(true /* shared */); 289 mNetworkListStoreData.setSharedConfigurations(networkList); 290 byte[] expectedData = getTestNetworksXmlBytes(networkList.get(0), networkList.get(1)); 291 assertTrue(Arrays.equals(expectedData, serializeData(true /* shared */))); 292 } 293 294 /** 295 * Verify that the shared configurations are parsed correctly from a XML string containing 296 * test networks (an open and an EAP network). 297 * @throws Exception 298 */ 299 @Test 300 public void deserializeSharedConfigurations() throws Exception { 301 List<WifiConfiguration> networkList = getTestNetworksConfig(true /* shared */); 302 byte[] xmlData = getTestNetworksXmlBytes(networkList.get(0), networkList.get(1)); 303 WifiConfigurationTestUtil.assertConfigurationsEqualForConfigStore( 304 networkList, deserializeData(xmlData, true /* shared */)); 305 } 306 307 /** 308 * Verify that the user configurations (containing an open and an EAP network) are serialized 309 * correctly, matching the expected XML string. 310 * 311 * @throws Exception 312 */ 313 @Test 314 public void serializeUserConfigurations() throws Exception { 315 List<WifiConfiguration> networkList = getTestNetworksConfig(false /* shared */); 316 mNetworkListStoreData.setUserConfigurations(networkList); 317 byte[] expectedData = getTestNetworksXmlBytes(networkList.get(0), networkList.get(1)); 318 assertTrue(Arrays.equals(expectedData, serializeData(false /* shared */))); 319 } 320 321 /** 322 * Verify that the user configurations are parsed correctly from a XML string containing 323 * test networks (an open and an EAP network). 324 * @throws Exception 325 */ 326 @Test 327 public void deserializeUserConfigurations() throws Exception { 328 List<WifiConfiguration> networkList = getTestNetworksConfig(false /* shared */); 329 byte[] xmlData = getTestNetworksXmlBytes(networkList.get(0), networkList.get(1)); 330 WifiConfigurationTestUtil.assertConfigurationsEqualForConfigStore( 331 networkList, deserializeData(xmlData, false /* shared */)); 332 } 333 334 /** 335 * Verify that a XmlPullParserException will be thrown when parsing a <Network> block 336 * containing an unknown tag. 337 * 338 * @throws Exception 339 */ 340 @Test(expected = XmlPullParserException.class) 341 public void parseNetworkWithUnknownTag() throws Exception { 342 String configFormat = 343 "<Network>\n" 344 + "<WifiConfiguration>\n" 345 + "<string name=\"ConfigKey\">%s</string>\n" 346 + "<string name=\"SSID\">%s</string>\n" 347 + "<null name=\"BSSID\" />\n" 348 + "<null name=\"PreSharedKey\" />\n" 349 + "<null name=\"WEPKeys\" />\n" 350 + "<int name=\"WEPTxKeyIndex\" value=\"0\" />\n" 351 + "<boolean name=\"HiddenSSID\" value=\"false\" />\n" 352 + "<boolean name=\"RequirePMF\" value=\"false\" />\n" 353 + "<byte-array name=\"AllowedKeyMgmt\" num=\"1\">01</byte-array>\n" 354 + "<byte-array name=\"AllowedProtocols\" num=\"0\"></byte-array>\n" 355 + "<byte-array name=\"AllowedAuthAlgos\" num=\"0\"></byte-array>\n" 356 + "<byte-array name=\"AllowedGroupCiphers\" num=\"0\"></byte-array>\n" 357 + "<byte-array name=\"AllowedPairwiseCiphers\" num=\"0\"></byte-array>\n" 358 + "<boolean name=\"Shared\" value=\"%s\" />\n" 359 + "<null name=\"FQDN\" />\n" 360 + "<null name=\"ProviderFriendlyName\" />\n" 361 + "<null name=\"LinkedNetworksList\" />\n" 362 + "<null name=\"DefaultGwMacAddress\" />\n" 363 + "<boolean name=\"ValidatedInternetAccess\" value=\"false\" />\n" 364 + "<boolean name=\"NoInternetAccessExpected\" value=\"false\" />\n" 365 + "<int name=\"UserApproved\" value=\"0\" />\n" 366 + "<boolean name=\"MeteredHint\" value=\"false\" />\n" 367 + "<boolean name=\"UseExternalScores\" value=\"false\" />\n" 368 + "<int name=\"NumAssociation\" value=\"0\" />\n" 369 + "<int name=\"CreatorUid\" value=\"%d\" />\n" 370 + "<null name=\"CreatorName\" />\n" 371 + "<null name=\"CreationTime\" />\n" 372 + "<int name=\"LastUpdateUid\" value=\"-1\" />\n" 373 + "<null name=\"LastUpdateName\" />\n" 374 + "<int name=\"LastConnectUid\" value=\"0\" />\n" 375 + "</WifiConfiguration>\n" 376 + "<NetworkStatus>\n" 377 + "<string name=\"SelectionStatus\">NETWORK_SELECTION_ENABLED</string>\n" 378 + "<string name=\"DisableReason\">NETWORK_SELECTION_ENABLE</string>\n" 379 + "<null name=\"ConnectChoice\" />\n" 380 + "<long name=\"ConnectChoiceTimeStamp\" value=\"-1\" />\n" 381 + "<boolean name=\"HasEverConnected\" value=\"false\" />\n" 382 + "</NetworkStatus>\n" 383 + "<IpConfiguration>\n" 384 + "<string name=\"IpAssignment\">DHCP</string>\n" 385 + "<string name=\"ProxySettings\">NONE</string>\n" 386 + "</IpConfiguration>\n" 387 + "<Unknown>" // Unknown tag. 388 + "<int name=\"test\" value=\"0\" />\n" 389 + "</Unknown>" 390 + "</Network>\n"; 391 WifiConfiguration openNetwork = WifiConfigurationTestUtil.createOpenNetwork(); 392 byte[] xmlData = String.format(configFormat, 393 openNetwork.configKey().replaceAll("\"", """), 394 openNetwork.SSID.replaceAll("\"", """), 395 openNetwork.shared, openNetwork.creatorUid).getBytes(StandardCharsets.UTF_8); 396 deserializeData(xmlData, true); 397 } 398 399 /** 400 * Verify that a XmlPullParseException will be thrown when parsing a network configuration 401 * containing a mismatched config key. 402 * 403 * @throws Exception 404 */ 405 @Test(expected = XmlPullParserException.class) 406 public void parseNetworkWithMismatchConfigKey() throws Exception { 407 WifiConfiguration openNetwork = WifiConfigurationTestUtil.createOpenNetwork(); 408 byte[] xmlData = String.format(SINGLE_OPEN_NETWORK_DATA_XML_STRING_FORMAT, 409 "InvalidConfigKey", 410 openNetwork.SSID.replaceAll("\"", """), 411 openNetwork.shared, openNetwork.creatorUid).getBytes(StandardCharsets.UTF_8); 412 deserializeData(xmlData, true); 413 } 414} 415