PasspointManagerTest.java revision 4781e9e2904824ef1fbf8a0cf75e89fa957d6a92
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.hotspot2; 18 19import static android.net.wifi.WifiManager.EXTRA_PASSPOINT_ICON_BSSID; 20import static android.net.wifi.WifiManager.EXTRA_PASSPOINT_ICON_DATA; 21import static android.net.wifi.WifiManager.EXTRA_PASSPOINT_ICON_FILE; 22import static android.net.wifi.WifiManager.PASSPOINT_ICON_RECEIVED_ACTION; 23 24import static org.junit.Assert.assertEquals; 25import static org.junit.Assert.assertFalse; 26import static org.junit.Assert.assertTrue; 27import static org.mockito.Mockito.eq; 28import static org.mockito.Mockito.verify; 29import static org.mockito.Mockito.when; 30import static org.mockito.MockitoAnnotations.initMocks; 31 32import android.content.Context; 33import android.content.Intent; 34import android.net.wifi.EAPConstants; 35import android.net.wifi.hotspot2.PasspointConfiguration; 36import android.net.wifi.hotspot2.pps.Credential; 37import android.net.wifi.hotspot2.pps.HomeSP; 38import android.os.UserHandle; 39import android.test.suitebuilder.annotation.SmallTest; 40 41import com.android.server.wifi.FakeKeys; 42import com.android.server.wifi.IMSIParameter; 43import com.android.server.wifi.SIMAccessor; 44import com.android.server.wifi.WifiInjector; 45 46import org.junit.Before; 47import org.junit.Test; 48import org.mockito.ArgumentCaptor; 49import org.mockito.Mock; 50 51import java.util.ArrayList; 52import java.util.List; 53 54/** 55 * Unit tests for {@link com.android.server.wifi.hotspot2.PasspointManager}. 56 */ 57@SmallTest 58public class PasspointManagerTest { 59 private static final long BSSID = 0x112233445566L; 60 private static final String ICON_FILENAME = "test"; 61 private static final String TEST_FQDN = "test1.test.com"; 62 private static final String TEST_FQDN1 = "test.com"; 63 private static final String TEST_FRIENDLY_NAME = "friendly name"; 64 private static final String TEST_REALM = "realm.test.com"; 65 private static final String TEST_IMSI = "1234*"; 66 67 @Mock Context mContext; 68 @Mock WifiInjector mWifiInjector; 69 @Mock PasspointEventHandler.Callbacks mCallbacks; 70 @Mock SIMAccessor mSimAccessor; 71 PasspointManager mManager; 72 73 /** Sets up test. */ 74 @Before 75 public void setUp() throws Exception { 76 initMocks(this); 77 mManager = new PasspointManager(mContext, mWifiInjector, mSimAccessor); 78 ArgumentCaptor<PasspointEventHandler.Callbacks> callbacks = 79 ArgumentCaptor.forClass(PasspointEventHandler.Callbacks.class); 80 verify(mWifiInjector).makePasspointEventHandler(callbacks.capture()); 81 mCallbacks = callbacks.getValue(); 82 } 83 84 /** 85 * Verify PASSPOINT_ICON_RECEIVED_ACTION broadcast intent. 86 * @param bssid BSSID of the AP 87 * @param fileName Name of the icon file 88 * @param data icon data byte array 89 */ 90 private void verifyIconIntent(long bssid, String fileName, byte[] data) { 91 ArgumentCaptor<Intent> intent = ArgumentCaptor.forClass(Intent.class); 92 verify(mContext).sendBroadcastAsUser(intent.capture(), eq(UserHandle.ALL)); 93 assertEquals(PASSPOINT_ICON_RECEIVED_ACTION, intent.getValue().getAction()); 94 assertTrue(intent.getValue().getExtras().containsKey(EXTRA_PASSPOINT_ICON_BSSID)); 95 assertEquals(bssid, intent.getValue().getExtras().getLong(EXTRA_PASSPOINT_ICON_BSSID)); 96 assertTrue(intent.getValue().getExtras().containsKey(EXTRA_PASSPOINT_ICON_FILE)); 97 assertEquals(fileName, intent.getValue().getExtras().getString(EXTRA_PASSPOINT_ICON_FILE)); 98 if (data != null) { 99 assertTrue(intent.getValue().getExtras().containsKey(EXTRA_PASSPOINT_ICON_DATA)); 100 assertEquals(data, 101 intent.getValue().getExtras().getByteArray(EXTRA_PASSPOINT_ICON_DATA)); 102 } 103 } 104 105 /** 106 * Verify that the given Passpoint configuration matches the one that's added to 107 * the PasspointManager. 108 * 109 * @param expectedConfig The expected installed Passpoint configuration 110 */ 111 private void verifyInstalledConfig(PasspointConfiguration expectedConfig) { 112 List<PasspointConfiguration> installedConfigs = mManager.getProviderConfigs(); 113 assertEquals(1, installedConfigs.size()); 114 assertEquals(expectedConfig, installedConfigs.get(0)); 115 } 116 117 /** 118 * Validate the broadcast intent when icon file retrieval succeeded. 119 * 120 * @throws Exception 121 */ 122 @Test 123 public void iconResponseSuccess() throws Exception { 124 byte[] iconData = new byte[] {0x00, 0x11}; 125 mCallbacks.onIconResponse(BSSID, ICON_FILENAME, iconData); 126 verifyIconIntent(BSSID, ICON_FILENAME, iconData); 127 } 128 129 /** 130 * Validate the broadcast intent when icon file retrieval failed. 131 * 132 * @throws Exception 133 */ 134 @Test 135 public void iconResponseFailure() throws Exception { 136 mCallbacks.onIconResponse(BSSID, ICON_FILENAME, null); 137 verifyIconIntent(BSSID, ICON_FILENAME, null); 138 } 139 140 /** 141 * Verify that adding a provider with a null configuration will fail. 142 * 143 * @throws Exception 144 */ 145 @Test 146 public void addProviderWithNullConfig() throws Exception { 147 assertFalse(mManager.addProvider(null)); 148 } 149 150 /** 151 * Verify that adding a provider with a empty configuration will fail. 152 * 153 * @throws Exception 154 */ 155 @Test 156 public void addProviderWithEmptyConfig() throws Exception { 157 assertFalse(mManager.addProvider(new PasspointConfiguration())); 158 } 159 160 /** 161 * Verify taht adding a provider with an invalid credential will fail (using EAP-TLS 162 * for user credential). 163 * 164 * @throws Exception 165 */ 166 @Test 167 public void addProviderWithInvalidCredential() throws Exception { 168 PasspointConfiguration config = new PasspointConfiguration(); 169 config.homeSp = new HomeSP(); 170 config.homeSp.fqdn = TEST_FQDN; 171 config.homeSp.friendlyName = TEST_FRIENDLY_NAME; 172 config.credential = new Credential(); 173 config.credential.realm = TEST_REALM; 174 config.credential.caCertificate = FakeKeys.CA_CERT0; 175 config.credential.userCredential = new Credential.UserCredential(); 176 config.credential.userCredential.username = "username"; 177 config.credential.userCredential.password = "password"; 178 // EAP-TLS not allowed for user credential. 179 config.credential.userCredential.eapType = EAPConstants.EAP_TLS; 180 config.credential.userCredential.nonEapInnerMethod = "MS-CHAP"; 181 assertFalse(mManager.addProvider(config)); 182 } 183 184 /** 185 * Verify that adding a provider with a valid configuration and user credential will succeed. 186 * 187 * @throws Exception 188 */ 189 @Test 190 public void addRemoveProviderWithValidUserCredential() throws Exception { 191 PasspointConfiguration config = new PasspointConfiguration(); 192 config.homeSp = new HomeSP(); 193 config.homeSp.fqdn = TEST_FQDN; 194 config.homeSp.friendlyName = TEST_FRIENDLY_NAME; 195 config.credential = new Credential(); 196 config.credential.realm = TEST_REALM; 197 config.credential.caCertificate = FakeKeys.CA_CERT0; 198 config.credential.userCredential = new Credential.UserCredential(); 199 config.credential.userCredential.username = "username"; 200 config.credential.userCredential.password = "password"; 201 config.credential.userCredential.eapType = EAPConstants.EAP_TTLS; 202 config.credential.userCredential.nonEapInnerMethod = "MS-CHAP"; 203 assertTrue(mManager.addProvider(config)); 204 verifyInstalledConfig(config); 205 206 // Remove the provider. 207 assertTrue(mManager.removeProvider(TEST_FQDN)); 208 assertEquals(null, mManager.getProviderConfigs()); 209 } 210 211 /** 212 * Verify that adding a provider with a valid configuration and SIM credential will succeed. 213 * 214 * @throws Exception 215 */ 216 @Test 217 public void addRemoveProviderWithValidSimCredential() throws Exception { 218 PasspointConfiguration config = new PasspointConfiguration(); 219 config.homeSp = new HomeSP(); 220 config.homeSp.fqdn = TEST_FQDN; 221 config.homeSp.friendlyName = TEST_FRIENDLY_NAME; 222 config.credential = new Credential(); 223 config.credential.realm = TEST_REALM; 224 config.credential.simCredential = new Credential.SimCredential(); 225 config.credential.simCredential.imsi = TEST_IMSI; 226 config.credential.simCredential.eapType = EAPConstants.EAP_SIM; 227 when(mSimAccessor.getMatchingImsis(new IMSIParameter(TEST_IMSI))) 228 .thenReturn(new ArrayList<String>()); 229 assertTrue(mManager.addProvider(config)); 230 verifyInstalledConfig(config); 231 232 // Remove the provider. 233 assertTrue(mManager.removeProvider(TEST_FQDN)); 234 assertEquals(null, mManager.getProviderConfigs()); 235 } 236 237 /** 238 * Verify that adding a provider with an invalid SIM credential (configured IMSI doesn't 239 * match the IMSI of the installed SIM cards) will fail. 240 * 241 * @throws Exception 242 */ 243 @Test 244 public void addProviderWithValidSimCredentialWithInvalidIMSI() throws Exception { 245 PasspointConfiguration config = new PasspointConfiguration(); 246 config.homeSp = new HomeSP(); 247 config.homeSp.fqdn = TEST_FQDN; 248 config.homeSp.friendlyName = TEST_FRIENDLY_NAME; 249 config.credential = new Credential(); 250 config.credential.realm = TEST_REALM; 251 config.credential.simCredential = new Credential.SimCredential(); 252 config.credential.simCredential.imsi = TEST_IMSI; 253 config.credential.simCredential.eapType = EAPConstants.EAP_SIM; 254 when(mSimAccessor.getMatchingImsis(new IMSIParameter(TEST_IMSI))).thenReturn(null); 255 assertFalse(mManager.addProvider(config)); 256 } 257 258 /** 259 * Verify that adding a provider with the same base domain as the existing provider will 260 * succeed, and verify that the existing provider is replaced by the new provider with 261 * the new configuration. 262 * 263 * @throws Exception 264 */ 265 @Test 266 public void addProviderWithExistingConfig() throws Exception { 267 // Add a provider with the original configuration. 268 PasspointConfiguration origConfig = new PasspointConfiguration(); 269 origConfig.homeSp = new HomeSP(); 270 origConfig.homeSp.fqdn = TEST_FQDN; 271 origConfig.homeSp.friendlyName = TEST_FRIENDLY_NAME; 272 origConfig.credential = new Credential(); 273 origConfig.credential.realm = TEST_REALM; 274 origConfig.credential.simCredential = new Credential.SimCredential(); 275 origConfig.credential.simCredential.imsi = TEST_IMSI; 276 origConfig.credential.simCredential.eapType = EAPConstants.EAP_SIM; 277 when(mSimAccessor.getMatchingImsis(new IMSIParameter(TEST_IMSI))) 278 .thenReturn(new ArrayList<String>()); 279 assertTrue(mManager.addProvider(origConfig)); 280 verifyInstalledConfig(origConfig); 281 282 // Add another provider with the same base domain as the existing provider. 283 // This should replace the existing provider with the new configuration. 284 PasspointConfiguration newConfig = new PasspointConfiguration(); 285 newConfig.homeSp = new HomeSP(); 286 newConfig.homeSp.fqdn = TEST_FQDN1; 287 newConfig.homeSp.friendlyName = TEST_FRIENDLY_NAME; 288 newConfig.credential = new Credential(); 289 newConfig.credential.realm = TEST_REALM; 290 newConfig.credential.caCertificate = FakeKeys.CA_CERT0; 291 newConfig.credential.userCredential = new Credential.UserCredential(); 292 newConfig.credential.userCredential.username = "username"; 293 newConfig.credential.userCredential.password = "password"; 294 newConfig.credential.userCredential.eapType = EAPConstants.EAP_TTLS; 295 newConfig.credential.userCredential.nonEapInnerMethod = "MS-CHAP"; 296 assertTrue(mManager.addProvider(newConfig)); 297 verifyInstalledConfig(newConfig); 298 } 299} 300