blob: ae4a396f648dd16b3f7887be0e49aedd437f2e4b [file] [log] [blame]
/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.server.wifi;
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
import android.app.test.MockAnswerUtil.AnswerWithArguments;
import android.net.IpConfiguration;
import android.net.wifi.WifiConfiguration;
import android.support.test.filters.SmallTest;
import android.text.TextUtils;
import android.util.SparseArray;
import com.android.server.wifi.WifiConfigStoreLegacy.IpConfigStoreWrapper;
import com.android.server.wifi.hotspot2.LegacyPasspointConfig;
import com.android.server.wifi.hotspot2.LegacyPasspointConfigParser;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Unit tests for {@link com.android.server.wifi.WifiConfigStoreLegacy}.
*/
@SmallTest
public class WifiConfigStoreLegacyTest {
private static final String MASKED_FIELD_VALUE = "*";
// Test mocks
@Mock private WifiNative mWifiNative;
@Mock private WifiNetworkHistory mWifiNetworkHistory;
@Mock private IpConfigStoreWrapper mIpconfigStoreWrapper;
@Mock private LegacyPasspointConfigParser mPasspointConfigParser;
/**
* Test instance of WifiConfigStore.
*/
private WifiConfigStoreLegacy mWifiConfigStore;
/**
* Setup the test environment.
*/
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
mWifiConfigStore = new WifiConfigStoreLegacy(mWifiNetworkHistory, mWifiNative,
mIpconfigStoreWrapper, mPasspointConfigParser);
}
/**
* Called after each test
*/
@After
public void cleanup() {
validateMockitoUsage();
}
/**
* Verify loading of network configurations from legacy stores. This is verifying the population
* of the masked wpa_supplicant fields using wpa_supplicant.conf file.
*/
@Test
public void testLoadFromStores() throws Exception {
WifiConfiguration pskNetwork = WifiConfigurationTestUtil.createPskNetwork();
WifiConfiguration wepNetwork = WifiConfigurationTestUtil.createWepNetwork();
WifiConfiguration eapNetwork = WifiConfigurationTestUtil.createEapNetwork();
WifiConfiguration passpointNetwork = WifiConfigurationTestUtil.createPasspointNetwork();
eapNetwork.enterpriseConfig.setPassword("EapPassword");
// Initialize Passpoint configuration data.
int passpointNetworkId = 1234;
String fqdn = passpointNetwork.FQDN;
String providerFriendlyName = passpointNetwork.providerFriendlyName;
long[] roamingConsortiumIds = new long[] {0x1234, 0x5678};
String realm = "test.com";
String imsi = "214321";
// Update Passpoint network.
// Network ID is used for lookup network extras, so use an unique ID for passpoint network.
passpointNetwork.networkId = passpointNetworkId;
passpointNetwork.enterpriseConfig.setPassword("PaspointPassword");
// Reset FQDN and provider friendly name so that the derived network from #read will
// obtained these information from networkExtras and {@link LegacyPasspointConfigParser}.
passpointNetwork.FQDN = null;
passpointNetwork.providerFriendlyName = null;
final List<WifiConfiguration> networks = new ArrayList<>();
networks.add(pskNetwork);
networks.add(wepNetwork);
networks.add(eapNetwork);
networks.add(passpointNetwork);
// Setup legacy Passpoint configuration data.
Map<String, LegacyPasspointConfig> passpointConfigs = new HashMap<>();
LegacyPasspointConfig passpointConfig = new LegacyPasspointConfig();
passpointConfig.mFqdn = fqdn;
passpointConfig.mFriendlyName = providerFriendlyName;
passpointConfig.mRoamingConsortiumOis = roamingConsortiumIds;
passpointConfig.mRealm = realm;
passpointConfig.mImsi = imsi;
passpointConfigs.put(fqdn, passpointConfig);
// Return the config data with passwords masked from wpa_supplicant control interface.
doAnswer(new AnswerWithArguments() {
public boolean answer(String ifaceName, Map<String, WifiConfiguration> configs,
SparseArray<Map<String, String>> networkExtras) {
for (Map.Entry<String, WifiConfiguration> entry:
createWpaSupplicantLoadData(networks).entrySet()) {
configs.put(entry.getKey(), entry.getValue());
}
// Setup networkExtras for Passpoint configuration.
networkExtras.put(passpointNetworkId, createNetworkExtrasForPasspointConfig(fqdn));
return true;
}
}).when(mWifiNative).migrateNetworksFromSupplicant(
any(), any(Map.class), any(SparseArray.class));
when(mPasspointConfigParser.parseConfig(anyString())).thenReturn(passpointConfigs);
when(mIpconfigStoreWrapper.readIpAndProxyConfigurations(anyString()))
.thenReturn(createIpConfigStoreLoadData(networks));
WifiConfigStoreLegacy.WifiConfigStoreDataLegacy storeData = mWifiConfigStore.read();
// Update the expected configuration for Passpoint network.
passpointNetwork.isLegacyPasspointConfig = true;
passpointNetwork.FQDN = fqdn;
passpointNetwork.providerFriendlyName = providerFriendlyName;
passpointNetwork.roamingConsortiumIds = roamingConsortiumIds;
passpointNetwork.enterpriseConfig.setRealm(realm);
passpointNetwork.enterpriseConfig.setPlmn(imsi);
WifiConfigurationTestUtil.assertConfigurationsEqualForConfigStore(
networks, storeData.getConfigurations());
}
/**
* Verify loading of network configurations from legacy stores with a null configKey.
* This happens if the 'ID_STR' field in wpa_supplicant.conf is not populated for some reason.
*/
@Test
public void testLoadFromStoresWithNullConfigKey() throws Exception {
WifiConfiguration pskNetwork = WifiConfigurationTestUtil.createPskNetwork();
WifiConfiguration wepNetwork = WifiConfigurationTestUtil.createWepNetwork();
WifiConfiguration eapNetwork = WifiConfigurationTestUtil.createEapNetwork();
eapNetwork.enterpriseConfig.setPassword("EapPassword");
final List<WifiConfiguration> networks = new ArrayList<>();
networks.add(pskNetwork);
networks.add(wepNetwork);
networks.add(eapNetwork);
// Return the config data with null configKey.
doAnswer(new AnswerWithArguments() {
public boolean answer(String ifaceName, Map<String, WifiConfiguration> configs,
SparseArray<Map<String, String>> networkExtras) {
for (Map.Entry<String, WifiConfiguration> entry:
createWpaSupplicantLoadData(networks).entrySet()) {
configs.put(null, entry.getValue());
}
return true;
}
}).when(mWifiNative).migrateNetworksFromSupplicant(
any(), any(Map.class), any(SparseArray.class));
when(mIpconfigStoreWrapper.readIpAndProxyConfigurations(anyString()))
.thenReturn(createIpConfigStoreLoadData(networks));
assertNotNull(mWifiConfigStore.read());
}
private SparseArray<IpConfiguration> createIpConfigStoreLoadData(
List<WifiConfiguration> configurations) {
SparseArray<IpConfiguration> newIpConfigurations = new SparseArray<>();
for (WifiConfiguration config : configurations) {
newIpConfigurations.put(
config.configKey().hashCode(),
new IpConfiguration(config.getIpConfiguration()));
}
return newIpConfigurations;
}
private Map<String, String> createPskMap(List<WifiConfiguration> configurations) {
Map<String, String> pskMap = new HashMap<>();
for (WifiConfiguration config : configurations) {
if (!TextUtils.isEmpty(config.preSharedKey)) {
pskMap.put(config.configKey(), config.preSharedKey);
}
}
return pskMap;
}
private Map<String, String> createWepKey0Map(List<WifiConfiguration> configurations) {
Map<String, String> wepKeyMap = new HashMap<>();
for (WifiConfiguration config : configurations) {
if (!TextUtils.isEmpty(config.wepKeys[0])) {
wepKeyMap.put(config.configKey(), config.wepKeys[0]);
}
}
return wepKeyMap;
}
private Map<String, String> createWepKey1Map(List<WifiConfiguration> configurations) {
Map<String, String> wepKeyMap = new HashMap<>();
for (WifiConfiguration config : configurations) {
if (!TextUtils.isEmpty(config.wepKeys[1])) {
wepKeyMap.put(config.configKey(), config.wepKeys[1]);
}
}
return wepKeyMap;
}
private Map<String, String> createWepKey2Map(List<WifiConfiguration> configurations) {
Map<String, String> wepKeyMap = new HashMap<>();
for (WifiConfiguration config : configurations) {
if (!TextUtils.isEmpty(config.wepKeys[2])) {
wepKeyMap.put(config.configKey(), config.wepKeys[2]);
}
}
return wepKeyMap;
}
private Map<String, String> createWepKey3Map(List<WifiConfiguration> configurations) {
Map<String, String> wepKeyMap = new HashMap<>();
for (WifiConfiguration config : configurations) {
if (!TextUtils.isEmpty(config.wepKeys[3])) {
wepKeyMap.put(config.configKey(), config.wepKeys[3]);
}
}
return wepKeyMap;
}
private Map<String, String> createEapPasswordMap(List<WifiConfiguration> configurations) {
Map<String, String> eapPasswordMap = new HashMap<>();
for (WifiConfiguration config : configurations) {
if (!TextUtils.isEmpty(config.enterpriseConfig.getPassword())) {
eapPasswordMap.put(config.configKey(), config.enterpriseConfig.getPassword());
}
}
return eapPasswordMap;
}
private Map<String, WifiConfiguration> createWpaSupplicantLoadData(
List<WifiConfiguration> configurations) {
Map<String, WifiConfiguration> configurationMap = new HashMap<>();
for (WifiConfiguration config : configurations) {
configurationMap.put(config.configKey(true), config);
}
return configurationMap;
}
private List<WifiConfiguration> createMaskedWifiConfigurations(
List<WifiConfiguration> configurations) {
List<WifiConfiguration> newConfigurations = new ArrayList<>();
for (WifiConfiguration config : configurations) {
newConfigurations.add(createMaskedWifiConfiguration(config));
}
return newConfigurations;
}
private WifiConfiguration createMaskedWifiConfiguration(WifiConfiguration configuration) {
WifiConfiguration newConfig = new WifiConfiguration(configuration);
if (!TextUtils.isEmpty(configuration.preSharedKey)) {
newConfig.preSharedKey = MASKED_FIELD_VALUE;
}
if (!TextUtils.isEmpty(configuration.wepKeys[0])) {
newConfig.wepKeys[0] = MASKED_FIELD_VALUE;
}
if (!TextUtils.isEmpty(configuration.wepKeys[1])) {
newConfig.wepKeys[1] = MASKED_FIELD_VALUE;
}
if (!TextUtils.isEmpty(configuration.wepKeys[2])) {
newConfig.wepKeys[2] = MASKED_FIELD_VALUE;
}
if (!TextUtils.isEmpty(configuration.wepKeys[3])) {
newConfig.wepKeys[3] = MASKED_FIELD_VALUE;
}
if (!TextUtils.isEmpty(configuration.enterpriseConfig.getPassword())) {
newConfig.enterpriseConfig.setPassword(MASKED_FIELD_VALUE);
}
return newConfig;
}
private Map<String, String> createNetworkExtrasForPasspointConfig(String fqdn) {
Map<String, String> extras = new HashMap<>();
extras.put(SupplicantStaNetworkHal.ID_STRING_KEY_FQDN, fqdn);
return extras;
}
}