1/* 2 * Copyright (C) 2016 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.app.test.MockAnswerUtil.AnswerWithArguments; 23import android.net.IpConfiguration; 24import android.net.wifi.WifiConfiguration; 25import android.test.suitebuilder.annotation.SmallTest; 26import android.text.TextUtils; 27import android.util.SparseArray; 28 29import com.android.server.net.IpConfigStore; 30import com.android.server.wifi.hotspot2.LegacyPasspointConfig; 31import com.android.server.wifi.hotspot2.LegacyPasspointConfigParser; 32 33import org.junit.After; 34import org.junit.Before; 35import org.junit.Test; 36import org.mockito.Mock; 37import org.mockito.MockitoAnnotations; 38 39import java.util.ArrayList; 40import java.util.HashMap; 41import java.util.List; 42import java.util.Map; 43 44/** 45 * Unit tests for {@link com.android.server.wifi.WifiConfigStoreLegacy}. 46 */ 47@SmallTest 48public class WifiConfigStoreLegacyTest { 49 private static final String MASKED_FIELD_VALUE = "*"; 50 51 // Test mocks 52 @Mock private WifiNative mWifiNative; 53 @Mock private WifiNetworkHistory mWifiNetworkHistory; 54 @Mock private IpConfigStore mIpconfigStore; 55 @Mock private LegacyPasspointConfigParser mPasspointConfigParser; 56 57 /** 58 * Test instance of WifiConfigStore. 59 */ 60 private WifiConfigStoreLegacy mWifiConfigStore; 61 62 63 /** 64 * Setup the test environment. 65 */ 66 @Before 67 public void setUp() throws Exception { 68 MockitoAnnotations.initMocks(this); 69 70 mWifiConfigStore = new WifiConfigStoreLegacy(mWifiNetworkHistory, mWifiNative, 71 mIpconfigStore, mPasspointConfigParser); 72 } 73 74 /** 75 * Called after each test 76 */ 77 @After 78 public void cleanup() { 79 validateMockitoUsage(); 80 } 81 82 /** 83 * Verify loading of network configurations from legacy stores. This is verifying the population 84 * of the masked wpa_supplicant fields using wpa_supplicant.conf file. 85 */ 86 @Test 87 public void testLoadFromStores() throws Exception { 88 WifiConfiguration pskNetwork = WifiConfigurationTestUtil.createPskNetwork(); 89 WifiConfiguration wepNetwork = WifiConfigurationTestUtil.createWepNetwork(); 90 WifiConfiguration eapNetwork = WifiConfigurationTestUtil.createEapNetwork(); 91 WifiConfiguration passpointNetwork = WifiConfigurationTestUtil.createPasspointNetwork(); 92 eapNetwork.enterpriseConfig.setPassword("EapPassword"); 93 94 // Initialize Passpoint configuration data. 95 int passpointNetworkId = 1234; 96 String fqdn = passpointNetwork.FQDN; 97 String providerFriendlyName = passpointNetwork.providerFriendlyName; 98 long[] roamingConsortiumIds = new long[] {0x1234, 0x5678}; 99 String realm = "test.com"; 100 String imsi = "214321"; 101 102 // Update Passpoint network. 103 // Network ID is used for lookup network extras, so use an unique ID for passpoint network. 104 passpointNetwork.networkId = passpointNetworkId; 105 passpointNetwork.enterpriseConfig.setPassword("PaspointPassword"); 106 // Reset FQDN and provider friendly name so that the derived network from #read will 107 // obtained these information from networkExtras and {@link LegacyPasspointConfigParser}. 108 passpointNetwork.FQDN = null; 109 passpointNetwork.providerFriendlyName = null; 110 111 final List<WifiConfiguration> networks = new ArrayList<>(); 112 networks.add(pskNetwork); 113 networks.add(wepNetwork); 114 networks.add(eapNetwork); 115 networks.add(passpointNetwork); 116 117 // Setup legacy Passpoint configuration data. 118 Map<String, LegacyPasspointConfig> passpointConfigs = new HashMap<>(); 119 LegacyPasspointConfig passpointConfig = new LegacyPasspointConfig(); 120 passpointConfig.mFqdn = fqdn; 121 passpointConfig.mFriendlyName = providerFriendlyName; 122 passpointConfig.mRoamingConsortiumOis = roamingConsortiumIds; 123 passpointConfig.mRealm = realm; 124 passpointConfig.mImsi = imsi; 125 passpointConfigs.put(fqdn, passpointConfig); 126 127 // Return the config data with passwords masked from wpa_supplicant control interface. 128 doAnswer(new AnswerWithArguments() { 129 public boolean answer(Map<String, WifiConfiguration> configs, 130 SparseArray<Map<String, String>> networkExtras) { 131 for (Map.Entry<String, WifiConfiguration> entry: 132 createWpaSupplicantLoadData(networks).entrySet()) { 133 configs.put(entry.getKey(), entry.getValue()); 134 } 135 // Setup networkExtras for Passpoint configuration. 136 networkExtras.put(passpointNetworkId, createNetworkExtrasForPasspointConfig(fqdn)); 137 return true; 138 } 139 }).when(mWifiNative).migrateNetworksFromSupplicant(any(Map.class), any(SparseArray.class)); 140 141 when(mPasspointConfigParser.parseConfig(anyString())).thenReturn(passpointConfigs); 142 WifiConfigStoreLegacy.WifiConfigStoreDataLegacy storeData = mWifiConfigStore.read(); 143 144 // Update the expected configuration for Passpoint network. 145 passpointNetwork.isLegacyPasspointConfig = true; 146 passpointNetwork.FQDN = fqdn; 147 passpointNetwork.providerFriendlyName = providerFriendlyName; 148 passpointNetwork.roamingConsortiumIds = roamingConsortiumIds; 149 passpointNetwork.enterpriseConfig.setRealm(realm); 150 passpointNetwork.enterpriseConfig.setPlmn(imsi); 151 152 WifiConfigurationTestUtil.assertConfigurationsEqualForConfigStore( 153 networks, storeData.getConfigurations()); 154 } 155 156 private SparseArray<IpConfiguration> createIpConfigStoreLoadData( 157 List<WifiConfiguration> configurations) { 158 SparseArray<IpConfiguration> newIpConfigurations = new SparseArray<>(); 159 for (WifiConfiguration config : configurations) { 160 newIpConfigurations.put( 161 config.configKey().hashCode(), 162 new IpConfiguration(config.getIpConfiguration())); 163 } 164 return newIpConfigurations; 165 } 166 167 private Map<String, String> createPskMap(List<WifiConfiguration> configurations) { 168 Map<String, String> pskMap = new HashMap<>(); 169 for (WifiConfiguration config : configurations) { 170 if (!TextUtils.isEmpty(config.preSharedKey)) { 171 pskMap.put(config.configKey(), config.preSharedKey); 172 } 173 } 174 return pskMap; 175 } 176 177 private Map<String, String> createWepKey0Map(List<WifiConfiguration> configurations) { 178 Map<String, String> wepKeyMap = new HashMap<>(); 179 for (WifiConfiguration config : configurations) { 180 if (!TextUtils.isEmpty(config.wepKeys[0])) { 181 wepKeyMap.put(config.configKey(), config.wepKeys[0]); 182 } 183 } 184 return wepKeyMap; 185 } 186 187 private Map<String, String> createWepKey1Map(List<WifiConfiguration> configurations) { 188 Map<String, String> wepKeyMap = new HashMap<>(); 189 for (WifiConfiguration config : configurations) { 190 if (!TextUtils.isEmpty(config.wepKeys[1])) { 191 wepKeyMap.put(config.configKey(), config.wepKeys[1]); 192 } 193 } 194 return wepKeyMap; 195 } 196 197 private Map<String, String> createWepKey2Map(List<WifiConfiguration> configurations) { 198 Map<String, String> wepKeyMap = new HashMap<>(); 199 for (WifiConfiguration config : configurations) { 200 if (!TextUtils.isEmpty(config.wepKeys[2])) { 201 wepKeyMap.put(config.configKey(), config.wepKeys[2]); 202 } 203 } 204 return wepKeyMap; 205 } 206 207 private Map<String, String> createWepKey3Map(List<WifiConfiguration> configurations) { 208 Map<String, String> wepKeyMap = new HashMap<>(); 209 for (WifiConfiguration config : configurations) { 210 if (!TextUtils.isEmpty(config.wepKeys[3])) { 211 wepKeyMap.put(config.configKey(), config.wepKeys[3]); 212 } 213 } 214 return wepKeyMap; 215 } 216 217 private Map<String, String> createEapPasswordMap(List<WifiConfiguration> configurations) { 218 Map<String, String> eapPasswordMap = new HashMap<>(); 219 for (WifiConfiguration config : configurations) { 220 if (!TextUtils.isEmpty(config.enterpriseConfig.getPassword())) { 221 eapPasswordMap.put(config.configKey(), config.enterpriseConfig.getPassword()); 222 } 223 } 224 return eapPasswordMap; 225 } 226 227 private Map<String, WifiConfiguration> createWpaSupplicantLoadData( 228 List<WifiConfiguration> configurations) { 229 Map<String, WifiConfiguration> configurationMap = new HashMap<>(); 230 for (WifiConfiguration config : configurations) { 231 configurationMap.put(config.configKey(true), config); 232 } 233 return configurationMap; 234 } 235 236 private List<WifiConfiguration> createMaskedWifiConfigurations( 237 List<WifiConfiguration> configurations) { 238 List<WifiConfiguration> newConfigurations = new ArrayList<>(); 239 for (WifiConfiguration config : configurations) { 240 newConfigurations.add(createMaskedWifiConfiguration(config)); 241 } 242 return newConfigurations; 243 } 244 245 private WifiConfiguration createMaskedWifiConfiguration(WifiConfiguration configuration) { 246 WifiConfiguration newConfig = new WifiConfiguration(configuration); 247 if (!TextUtils.isEmpty(configuration.preSharedKey)) { 248 newConfig.preSharedKey = MASKED_FIELD_VALUE; 249 } 250 if (!TextUtils.isEmpty(configuration.wepKeys[0])) { 251 newConfig.wepKeys[0] = MASKED_FIELD_VALUE; 252 } 253 if (!TextUtils.isEmpty(configuration.wepKeys[1])) { 254 newConfig.wepKeys[1] = MASKED_FIELD_VALUE; 255 } 256 if (!TextUtils.isEmpty(configuration.wepKeys[2])) { 257 newConfig.wepKeys[2] = MASKED_FIELD_VALUE; 258 } 259 if (!TextUtils.isEmpty(configuration.wepKeys[3])) { 260 newConfig.wepKeys[3] = MASKED_FIELD_VALUE; 261 } 262 if (!TextUtils.isEmpty(configuration.enterpriseConfig.getPassword())) { 263 newConfig.enterpriseConfig.setPassword(MASKED_FIELD_VALUE); 264 } 265 return newConfig; 266 } 267 268 private Map<String, String> createNetworkExtrasForPasspointConfig(String fqdn) { 269 Map<String, String> extras = new HashMap<>(); 270 extras.put(SupplicantStaNetworkHal.ID_STRING_KEY_FQDN, fqdn); 271 return extras; 272 } 273} 274