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 17 package com.android.server.wifi.util; 18 19 import static org.junit.Assert.assertFalse; 20 import static org.junit.Assert.assertTrue; 21 import static org.junit.Assert.fail; 22 import static org.mockito.Matchers.anyInt; 23 import static org.mockito.Matchers.anyString; 24 import static org.mockito.Mockito.doAnswer; 25 import static org.mockito.Mockito.doThrow; 26 import static org.mockito.Mockito.when; 27 28 import android.Manifest; 29 import android.app.AppOpsManager; 30 import android.content.ContentResolver; 31 import android.content.Context; 32 import android.content.pm.ApplicationInfo; 33 import android.content.pm.PackageManager; 34 import android.content.pm.UserInfo; 35 import android.os.Build; 36 import android.os.RemoteException; 37 import android.os.UserHandle; 38 import android.os.UserManager; 39 import android.provider.Settings; 40 import android.support.test.filters.SmallTest; 41 42 import com.android.server.wifi.BinderUtil; 43 import com.android.server.wifi.FakeWifiLog; 44 import com.android.server.wifi.WifiInjector; 45 import com.android.server.wifi.WifiSettingsStore; 46 47 import org.junit.Before; 48 import org.junit.Test; 49 import org.junit.runner.RunWith; 50 import org.junit.runners.JUnit4; 51 import org.mockito.Mock; 52 import org.mockito.MockitoAnnotations; 53 import org.mockito.Spy; 54 import org.mockito.invocation.InvocationOnMock; 55 import org.mockito.stubbing.Answer; 56 57 import java.util.Arrays; 58 import java.util.HashMap; 59 60 /** Unit tests for {@link WifiPermissionsUtil}. */ 61 @RunWith(JUnit4.class) 62 @SmallTest 63 public class WifiPermissionsUtilTest { 64 public static final String TAG = "WifiPermissionsUtilTest"; 65 66 // Mock objects for testing 67 @Mock private WifiPermissionsWrapper mMockPermissionsWrapper; 68 @Mock private Context mMockContext; 69 @Mock private PackageManager mMockPkgMgr; 70 @Mock private ApplicationInfo mMockApplInfo; 71 @Mock private AppOpsManager mMockAppOps; 72 @Mock private UserInfo mMockUserInfo; 73 @Mock private UserManager mMockUserManager; 74 @Mock private WifiSettingsStore mMockWifiSettingsStore; 75 @Mock private ContentResolver mMockContentResolver; 76 @Mock private WifiInjector mWifiInjector; 77 @Spy private FakeWifiLog mWifiLog; 78 79 private static final String TEST_PACKAGE_NAME = "com.google.somePackage"; 80 private static final String INVALID_PACKAGE = "BAD_PACKAGE"; 81 private static final int MANAGED_PROFILE_UID = 1100000; 82 private static final int OTHER_USER_UID = 1200000; 83 84 private final int mCallingUser = UserHandle.USER_CURRENT_OR_SELF; 85 private final String mMacAddressPermission = "android.permission.PEERS_MAC_ADDRESS"; 86 private final String mInteractAcrossUsersFullPermission = 87 "android.permission.INTERACT_ACROSS_USERS_FULL"; 88 private final String mManifestStringCoarse = 89 Manifest.permission.ACCESS_COARSE_LOCATION; 90 91 // Test variables 92 private int mWifiScanAllowApps; 93 private int mUid; 94 private int mCoarseLocationPermission; 95 private int mAllowCoarseLocationApps; 96 private String mPkgNameOfTopActivity; 97 private int mCurrentUser; 98 private int mLocationModeSetting; 99 private boolean mThrowSecurityException; 100 private Answer<Integer> mReturnPermission; 101 private HashMap<String, Integer> mPermissionsList = new HashMap<String, Integer>(); 102 103 /** 104 * Set up Mockito tests 105 */ 106 @Before 107 public void setUp() { 108 MockitoAnnotations.initMocks(this); 109 initTestVars(); 110 } 111 112 private void setupTestCase() throws Exception { 113 setupMocks(); 114 setupMockInterface(); 115 } 116 117 /** 118 * Verify we return true when the UID does have the override config permission 119 */ 120 @Test 121 public void testCheckConfigOverridePermissionApproved() throws Exception { 122 mUid = MANAGED_PROFILE_UID; // do not really care about this value 123 setupTestCase(); 124 WifiPermissionsUtil codeUnderTest = new WifiPermissionsUtil(mMockPermissionsWrapper, 125 mMockContext, mMockWifiSettingsStore, mMockUserManager, mWifiInjector); 126 when(mMockPermissionsWrapper.getOverrideWifiConfigPermission(anyInt())) 127 .thenReturn(PackageManager.PERMISSION_GRANTED); 128 assertTrue(codeUnderTest.checkConfigOverridePermission(mUid)); 129 } 130 131 /** 132 * Verify we return false when the UID does not have the override config permission. 133 */ 134 @Test 135 public void testCheckConfigOverridePermissionDenied() throws Exception { 136 mUid = OTHER_USER_UID; // do not really care about this value 137 setupTestCase(); 138 WifiPermissionsUtil codeUnderTest = new WifiPermissionsUtil(mMockPermissionsWrapper, 139 mMockContext, mMockWifiSettingsStore, mMockUserManager, mWifiInjector); 140 when(mMockPermissionsWrapper.getOverrideWifiConfigPermission(anyInt())) 141 .thenReturn(PackageManager.PERMISSION_DENIED); 142 assertFalse(codeUnderTest.checkConfigOverridePermission(mUid)); 143 } 144 145 /** 146 * Verify we return false when the override config permission check throws a RemoteException. 147 */ 148 @Test 149 public void testCheckConfigOverridePermissionWithException() throws Exception { 150 mUid = OTHER_USER_UID; // do not really care about this value 151 setupTestCase(); 152 WifiPermissionsUtil codeUnderTest = new WifiPermissionsUtil(mMockPermissionsWrapper, 153 mMockContext, mMockWifiSettingsStore, mMockUserManager, mWifiInjector); 154 doThrow(new RemoteException("Failed to check permissions for " + mUid)) 155 .when(mMockPermissionsWrapper).getOverrideWifiConfigPermission(mUid); 156 assertFalse(codeUnderTest.checkConfigOverridePermission(mUid)); 157 } 158 159 /** 160 * Test case setting: Package is valid 161 * Location mode is enabled 162 * Caller can read peers mac address 163 * This App has permission to request WIFI_SCAN 164 * User is current 165 * Validate no Exceptions are thrown 166 * - User has all the permissions 167 */ 168 @Test 169 public void testCanReadPeersMacAddressCurrentUserAndAllPermissions() throws Exception { 170 mThrowSecurityException = false; 171 mUid = MANAGED_PROFILE_UID; 172 mPermissionsList.put(mMacAddressPermission, mUid); 173 mWifiScanAllowApps = AppOpsManager.MODE_ALLOWED; 174 mCurrentUser = UserHandle.USER_CURRENT_OR_SELF; 175 mLocationModeSetting = Settings.Secure.LOCATION_MODE_HIGH_ACCURACY; 176 setupTestCase(); 177 WifiPermissionsUtil codeUnderTest = new WifiPermissionsUtil(mMockPermissionsWrapper, 178 mMockContext, mMockWifiSettingsStore, mMockUserManager, mWifiInjector); 179 codeUnderTest.enforceCanAccessScanResults(TEST_PACKAGE_NAME, mUid); 180 } 181 182 /** 183 * Test case setting: Package is valid 184 * Location mode is enabled 185 * Caller can read peers mac address 186 * This App has permission to request WIFI_SCAN 187 * User profile is current 188 * Validate no Exceptions are thrown 189 * - User has all the permissions 190 */ 191 @Test 192 public void testCanReadPeersMacAddressCurrentProfileAndAllPermissions() throws Exception { 193 mThrowSecurityException = false; 194 mUid = MANAGED_PROFILE_UID; 195 mPermissionsList.put(mMacAddressPermission, mUid); 196 mWifiScanAllowApps = AppOpsManager.MODE_ALLOWED; 197 mMockUserInfo.id = mCallingUser; 198 mLocationModeSetting = Settings.Secure.LOCATION_MODE_HIGH_ACCURACY; 199 setupTestCase(); 200 WifiPermissionsUtil codeUnderTest = new WifiPermissionsUtil(mMockPermissionsWrapper, 201 mMockContext, mMockWifiSettingsStore, mMockUserManager, mWifiInjector); 202 codeUnderTest.enforceCanAccessScanResults(TEST_PACKAGE_NAME, mUid); 203 } 204 205 /** 206 * Test case setting: Package is valid 207 * Caller can read peers mac address 208 * Validate that a SecurityException is thrown 209 * - This App doesn't have permission to request Wifi Scan 210 */ 211 @Test 212 public void testCannotAccessScanResult_AppNotAllowed() throws Exception { 213 mThrowSecurityException = false; 214 mPermissionsList.put(mMacAddressPermission, mUid); 215 setupTestCase(); 216 WifiPermissionsUtil codeUnderTest = new WifiPermissionsUtil(mMockPermissionsWrapper, 217 mMockContext, mMockWifiSettingsStore, mMockUserManager, mWifiInjector); 218 try { 219 codeUnderTest.enforceCanAccessScanResults(TEST_PACKAGE_NAME, mUid); 220 fail("Expected SecurityException is not thrown"); 221 } catch (SecurityException e) { 222 } 223 } 224 225 /** 226 * Test case setting: Package is valid 227 * Location mode is enabled 228 * Caller can read peers mac address 229 * This App has permission to request WIFI_SCAN 230 * User or profile is not current but the uid has 231 * permission to INTERACT_ACROSS_USERS_FULL 232 * Validate no Exceptions are thrown 233 * - User has all the permissions 234 */ 235 @Test 236 public void testenforceCanAccessScanResults_UserOrProfileNotCurrent() throws Exception { 237 mThrowSecurityException = false; 238 mUid = MANAGED_PROFILE_UID; 239 mPermissionsList.put(mMacAddressPermission, mUid); 240 mWifiScanAllowApps = AppOpsManager.MODE_ALLOWED; 241 mPermissionsList.put(mInteractAcrossUsersFullPermission, mUid); 242 mLocationModeSetting = Settings.Secure.LOCATION_MODE_HIGH_ACCURACY; 243 setupTestCase(); 244 WifiPermissionsUtil codeUnderTest = new WifiPermissionsUtil(mMockPermissionsWrapper, 245 mMockContext, mMockWifiSettingsStore, mMockUserManager, mWifiInjector); 246 codeUnderTest.enforceCanAccessScanResults(TEST_PACKAGE_NAME, mUid); 247 } 248 249 /** 250 * Test case setting: Package is valid 251 * Caller can read peers mac address 252 * This App has permission to request WIFI_SCAN 253 * User or profile is not Current 254 * Validate that a SecurityException is thrown 255 * - Calling uid doesn't have INTERACT_ACROSS_USERS_FULL permission 256 */ 257 @Test 258 public void testCannotAccessScanResults_NoInteractAcrossUsersFullPermission() throws Exception { 259 mThrowSecurityException = false; 260 mUid = MANAGED_PROFILE_UID; 261 mPermissionsList.put(mMacAddressPermission, mUid); 262 mWifiScanAllowApps = AppOpsManager.MODE_ALLOWED; 263 setupTestCase(); 264 WifiPermissionsUtil codeUnderTest = new WifiPermissionsUtil(mMockPermissionsWrapper, 265 mMockContext, mMockWifiSettingsStore, mMockUserManager, mWifiInjector); 266 try { 267 codeUnderTest.enforceCanAccessScanResults(TEST_PACKAGE_NAME, mUid); 268 fail("Expected SecurityException is not thrown"); 269 } catch (SecurityException e) { 270 } 271 } 272 273 /** 274 * Test case Setting: Package is valid 275 * Foreground 276 * This App has permission to request WIFI_SCAN 277 * User is current 278 * Validate that a SecurityException is thrown - app does not have location permission 279 */ 280 @Test 281 public void testLegacyForegroundAppWithOtherPermissionsDenied() throws Exception { 282 mThrowSecurityException = false; 283 mMockApplInfo.targetSdkVersion = Build.VERSION_CODES.GINGERBREAD; 284 mPkgNameOfTopActivity = TEST_PACKAGE_NAME; 285 mWifiScanAllowApps = AppOpsManager.MODE_ALLOWED; 286 mUid = MANAGED_PROFILE_UID; 287 mCurrentUser = UserHandle.USER_CURRENT_OR_SELF; 288 setupTestCase(); 289 WifiPermissionsUtil codeUnderTest = new WifiPermissionsUtil(mMockPermissionsWrapper, 290 mMockContext, mMockWifiSettingsStore, mMockUserManager, mWifiInjector); 291 try { 292 codeUnderTest.enforceCanAccessScanResults(TEST_PACKAGE_NAME, mUid); 293 fail("Expected SecurityException is not thrown"); 294 } catch (SecurityException e) { 295 } 296 } 297 298 /** 299 * Test case Setting: Package is valid 300 * Location Mode Enabled 301 * Coarse Location Access 302 * This App has permission to request WIFI_SCAN 303 * User profile is current 304 * Validate no Exceptions are thrown - has all permissions 305 */ 306 @Test 307 public void testLegacyAppHasLocationAndAllPermissions() throws Exception { 308 mThrowSecurityException = false; 309 mMockApplInfo.targetSdkVersion = Build.VERSION_CODES.GINGERBREAD; 310 mLocationModeSetting = Settings.Secure.LOCATION_MODE_HIGH_ACCURACY; 311 mCoarseLocationPermission = PackageManager.PERMISSION_GRANTED; 312 mAllowCoarseLocationApps = AppOpsManager.MODE_ALLOWED; 313 mWifiScanAllowApps = AppOpsManager.MODE_ALLOWED; 314 mUid = MANAGED_PROFILE_UID; 315 mMockUserInfo.id = mCallingUser; 316 setupTestCase(); 317 WifiPermissionsUtil codeUnderTest = new WifiPermissionsUtil(mMockPermissionsWrapper, 318 mMockContext, mMockWifiSettingsStore, mMockUserManager, mWifiInjector); 319 codeUnderTest.enforceCanAccessScanResults(TEST_PACKAGE_NAME, mUid); 320 } 321 322 /** 323 * Test case setting: Package is valid 324 * Location Mode Enabled 325 * Validate that a SecurityException is thrown 326 * - Doesn't have Peer Mac Address read permission 327 * - Uid is not an active network scorer 328 * - Location Mode is enabled but the uid 329 * - doesn't have Coarse Location Access 330 * - which implies No Location Permission 331 */ 332 @Test 333 public void testCannotAccessScanResults_NoCoarseLocationPermission() throws Exception { 334 mThrowSecurityException = false; 335 mLocationModeSetting = Settings.Secure.LOCATION_MODE_HIGH_ACCURACY; 336 setupTestCase(); 337 WifiPermissionsUtil codeUnderTest = new WifiPermissionsUtil(mMockPermissionsWrapper, 338 mMockContext, mMockWifiSettingsStore, mMockUserManager, mWifiInjector); 339 try { 340 codeUnderTest.enforceCanAccessScanResults(TEST_PACKAGE_NAME, mUid); 341 fail("Expected SecurityException is not thrown"); 342 } catch (SecurityException e) { 343 } 344 } 345 346 /** 347 * Test case setting: Package is valid 348 * Location Mode Disabled 349 * Caller has location permission 350 * Validate an Exception is thrown 351 * - Uid is not an active network scorer 352 * - Uid doesn't have Coarse Location Access 353 * - which implies No Location Permission 354 */ 355 @Test 356 public void testCannotAccessScanResults_LocationModeDisabled() throws Exception { 357 mThrowSecurityException = false; 358 mUid = MANAGED_PROFILE_UID; 359 mWifiScanAllowApps = AppOpsManager.MODE_ALLOWED; 360 mPermissionsList.put(mInteractAcrossUsersFullPermission, mUid); 361 mLocationModeSetting = Settings.Secure.LOCATION_MODE_OFF; 362 363 setupTestCase(); 364 when(mMockPermissionsWrapper.getChangeWifiConfigPermission(mUid)) 365 .thenReturn(PackageManager.PERMISSION_DENIED); 366 367 WifiPermissionsUtil codeUnderTest = new WifiPermissionsUtil(mMockPermissionsWrapper, 368 mMockContext, mMockWifiSettingsStore, mMockUserManager, mWifiInjector); 369 try { 370 codeUnderTest.enforceCanAccessScanResults(TEST_PACKAGE_NAME, mUid); 371 fail("Expected SecurityException is not thrown"); 372 } catch (SecurityException e) { 373 } 374 } 375 376 /** 377 * Test case setting: Package is valid 378 * Location Mode Disabled 379 * Caller has location permisson 380 * Caller has CHANGE_WIFI_STATE 381 * Validate SecurityException is thrown 382 * - Doesn't have Peer Mac Address read permission 383 * - Uid is not an active network scorer 384 * - Location Mode is disabled 385 * - which implies no scan result access 386 */ 387 @Test 388 public void testEnforceCannotAccessScanResults_LocationModeDisabledHasChangeWifiState() 389 throws Exception { 390 mThrowSecurityException = false; 391 mUid = MANAGED_PROFILE_UID; 392 mPermissionsList.put(mMacAddressPermission, mUid); 393 mWifiScanAllowApps = AppOpsManager.MODE_ALLOWED; 394 mPermissionsList.put(mInteractAcrossUsersFullPermission, mUid); 395 mLocationModeSetting = Settings.Secure.LOCATION_MODE_OFF; 396 397 setupTestCase(); 398 when(mMockPermissionsWrapper.getChangeWifiConfigPermission(mUid)) 399 .thenReturn(PackageManager.PERMISSION_GRANTED); 400 401 WifiPermissionsUtil codeUnderTest = new WifiPermissionsUtil(mMockPermissionsWrapper, 402 mMockContext, mMockWifiSettingsStore, mMockUserManager, mWifiInjector); 403 try { 404 codeUnderTest.enforceCanAccessScanResults(TEST_PACKAGE_NAME, mUid); 405 fail("Expected SecurityException is not thrown"); 406 } catch (SecurityException e) { 407 } 408 } 409 410 /** 411 * Test case setting: Package is valid 412 * Location Mode Disabled 413 * Caller has location permisson 414 * Caller has ACCESS_WIFI_STATE 415 * Validate Exception is thrown 416 * - Doesn't have Peer Mac Address read permission 417 * - Uid is not an active network scorer 418 * - Location Mode is disabled 419 * - doesn't have Coarse Location Access 420 * - which implies no scan result access 421 */ 422 @Test 423 public void testEnforceCannotAccessScanResults_LocationModeDisabledHasAccessWifiState() 424 throws Exception { 425 mThrowSecurityException = false; 426 mUid = MANAGED_PROFILE_UID; 427 mPermissionsList.put(mMacAddressPermission, mUid); 428 mWifiScanAllowApps = AppOpsManager.MODE_ALLOWED; 429 mPermissionsList.put(mInteractAcrossUsersFullPermission, mUid); 430 mLocationModeSetting = Settings.Secure.LOCATION_MODE_OFF; 431 432 setupTestCase(); 433 when(mMockPermissionsWrapper.getAccessWifiStatePermission(mUid)) 434 .thenReturn(PackageManager.PERMISSION_GRANTED); 435 436 WifiPermissionsUtil codeUnderTest = new WifiPermissionsUtil(mMockPermissionsWrapper, 437 mMockContext, mMockWifiSettingsStore, mMockUserManager, mWifiInjector); 438 try { 439 codeUnderTest.enforceCanAccessScanResults(TEST_PACKAGE_NAME, mUid); 440 fail("Expected SecurityException is not thrown"); 441 } catch (SecurityException e) { 442 } 443 } 444 445 /** 446 * Test case setting: Package is valid 447 * Location Mode Disabled 448 * Caller has location permisson 449 * Caller does not have NETWORK_SETTINGS 450 * Validate Exception is thrown 451 * - Doesn't have Peer Mac Address read permission 452 * - Uid is not an active network scorer 453 * - Location Mode is disabled 454 * - doesn't have Coarse Location Access 455 * - which implies no scan result access 456 */ 457 @Test 458 public void testEnforceCannotAccessScanResults_LocationModeDisabledHasNoNetworkSettings() 459 throws Exception { 460 mThrowSecurityException = false; 461 mUid = MANAGED_PROFILE_UID; 462 mPermissionsList.put(mMacAddressPermission, mUid); 463 mWifiScanAllowApps = AppOpsManager.MODE_ALLOWED; 464 mPermissionsList.put(mInteractAcrossUsersFullPermission, mUid); 465 mLocationModeSetting = Settings.Secure.LOCATION_MODE_OFF; 466 467 setupTestCase(); 468 when(mMockPermissionsWrapper.getUidPermission( 469 Manifest.permission.NETWORK_SETTINGS, MANAGED_PROFILE_UID)) 470 .thenReturn(PackageManager.PERMISSION_DENIED); 471 472 WifiPermissionsUtil codeUnderTest = new WifiPermissionsUtil(mMockPermissionsWrapper, 473 mMockContext, mMockWifiSettingsStore, mMockUserManager, mWifiInjector); 474 try { 475 codeUnderTest.enforceCanAccessScanResults(TEST_PACKAGE_NAME, mUid); 476 fail("Expected SecurityException is not thrown"); 477 } catch (SecurityException e) { 478 } 479 } 480 481 /** 482 * Test case setting: Package is valid 483 * Location Mode Disabled 484 * Caller has location permisson 485 * Caller has NETWORK_SETTINGS 486 * Validate Exception is thrown 487 * - Doesn't have Peer Mac Address read permission 488 * - Uid is not an active network scorer 489 * - Location Mode is disabled 490 * - doesn't have Coarse Location Access 491 * - which implies no scan result access 492 */ 493 @Test 494 public void testEnforceCanAccessScanResults_LocationModeDisabledHasNetworkSettings() 495 throws Exception { 496 mThrowSecurityException = false; 497 mUid = MANAGED_PROFILE_UID; 498 mPermissionsList.put(mMacAddressPermission, mUid); 499 mWifiScanAllowApps = AppOpsManager.MODE_ALLOWED; 500 mPermissionsList.put(mInteractAcrossUsersFullPermission, mUid); 501 mLocationModeSetting = Settings.Secure.LOCATION_MODE_OFF; 502 503 setupTestCase(); 504 when(mMockPermissionsWrapper.getUidPermission( 505 Manifest.permission.NETWORK_SETTINGS, MANAGED_PROFILE_UID)) 506 .thenReturn(PackageManager.PERMISSION_GRANTED); 507 508 WifiPermissionsUtil codeUnderTest = new WifiPermissionsUtil(mMockPermissionsWrapper, 509 mMockContext, mMockWifiSettingsStore, mMockUserManager, mWifiInjector); 510 codeUnderTest.enforceCanAccessScanResults(TEST_PACKAGE_NAME, mUid); 511 } 512 513 /** 514 * Test case setting: Package is valid 515 * Location Mode Disabled 516 * Caller has location permisson 517 * Caller does not have NETWORK_SETUP_WIZARD 518 * Validate Exception is thrown 519 * - Doesn't have Peer Mac Address read permission 520 * - Uid is not an active network scorer 521 * - Location Mode is disabled 522 * - doesn't have Coarse Location Access 523 * - which implies no scan result access 524 */ 525 @Test 526 public void testEnforceCannotAccessScanResults_LocationModeDisabledHasNoNetworkSetupWizard() 527 throws Exception { 528 mThrowSecurityException = false; 529 mUid = MANAGED_PROFILE_UID; 530 mPermissionsList.put(mMacAddressPermission, mUid); 531 mWifiScanAllowApps = AppOpsManager.MODE_ALLOWED; 532 mPermissionsList.put(mInteractAcrossUsersFullPermission, mUid); 533 mLocationModeSetting = Settings.Secure.LOCATION_MODE_OFF; 534 535 setupTestCase(); 536 when(mMockPermissionsWrapper.getUidPermission( 537 android.Manifest.permission.NETWORK_SETUP_WIZARD, MANAGED_PROFILE_UID)) 538 .thenReturn(PackageManager.PERMISSION_DENIED); 539 540 WifiPermissionsUtil codeUnderTest = new WifiPermissionsUtil(mMockPermissionsWrapper, 541 mMockContext, mMockWifiSettingsStore, mMockUserManager, mWifiInjector); 542 try { 543 codeUnderTest.enforceCanAccessScanResults(TEST_PACKAGE_NAME, mUid); 544 fail("Expected SecurityException is not thrown"); 545 } catch (SecurityException e) { 546 } 547 } 548 549 /** 550 * Test case setting: Package is valid 551 * Location Mode Disabled 552 * Caller has location permisson 553 * Caller has NETWORK_SETUP_WIZARD 554 * Validate Exception is thrown 555 * - Doesn't have Peer Mac Address read permission 556 * - Uid is not an active network scorer 557 * - Location Mode is disabled 558 * - doesn't have Coarse Location Access 559 * - which implies no scan result access 560 */ 561 @Test 562 public void testEnforceCanAccessScanResults_LocationModeDisabledHasNetworkSetupWizard() 563 throws Exception { 564 mThrowSecurityException = false; 565 mUid = MANAGED_PROFILE_UID; 566 mPermissionsList.put(mMacAddressPermission, mUid); 567 mWifiScanAllowApps = AppOpsManager.MODE_ALLOWED; 568 mPermissionsList.put(mInteractAcrossUsersFullPermission, mUid); 569 mLocationModeSetting = Settings.Secure.LOCATION_MODE_OFF; 570 571 setupTestCase(); 572 when(mMockPermissionsWrapper.getUidPermission( 573 android.Manifest.permission.NETWORK_SETUP_WIZARD, MANAGED_PROFILE_UID)) 574 .thenReturn(PackageManager.PERMISSION_GRANTED); 575 576 WifiPermissionsUtil codeUnderTest = new WifiPermissionsUtil(mMockPermissionsWrapper, 577 mMockContext, mMockWifiSettingsStore, mMockUserManager, mWifiInjector); 578 codeUnderTest.enforceCanAccessScanResults(TEST_PACKAGE_NAME, mUid); 579 } 580 581 /** 582 * Test case setting: Invalid Package 583 * Expect a securityException 584 */ 585 @Test 586 public void testInvalidPackage() throws Exception { 587 setupTestCase(); 588 WifiPermissionsUtil codeUnderTest = new WifiPermissionsUtil(mMockPermissionsWrapper, 589 mMockContext, mMockWifiSettingsStore, mMockUserManager, mWifiInjector); 590 try { 591 codeUnderTest.enforceCanAccessScanResults(TEST_PACKAGE_NAME, mUid); 592 fail("Expected SecurityException is not thrown"); 593 } catch (SecurityException e) { 594 } 595 } 596 597 /** 598 * Test case setting: caller does have Location permission. 599 * A SecurityException should not be thrown. 600 */ 601 @Test 602 public void testEnforceLocationPermission() throws Exception { 603 mThrowSecurityException = false; 604 mMockApplInfo.targetSdkVersion = Build.VERSION_CODES.GINGERBREAD; 605 mLocationModeSetting = Settings.Secure.LOCATION_MODE_HIGH_ACCURACY; 606 mCoarseLocationPermission = PackageManager.PERMISSION_GRANTED; 607 mAllowCoarseLocationApps = AppOpsManager.MODE_ALLOWED; 608 mWifiScanAllowApps = AppOpsManager.MODE_ALLOWED; 609 mUid = MANAGED_PROFILE_UID; 610 mMockUserInfo.id = mCallingUser; 611 setupTestCase(); 612 WifiPermissionsUtil codeUnderTest = new WifiPermissionsUtil(mMockPermissionsWrapper, 613 mMockContext, mMockWifiSettingsStore, mMockUserManager, mWifiInjector); 614 codeUnderTest.enforceLocationPermission(TEST_PACKAGE_NAME, mUid); 615 } 616 617 /** 618 * Verifies the helper method exposed for checking NETWORK_SETUP_WIZARD permission. 619 */ 620 @Test 621 public void testCheckNetworkSetupWizard() throws Exception { 622 setupMocks(); 623 WifiPermissionsUtil wifiPermissionsUtil = new WifiPermissionsUtil(mMockPermissionsWrapper, 624 mMockContext, mMockWifiSettingsStore, mMockUserManager, mWifiInjector); 625 626 when(mMockPermissionsWrapper.getUidPermission( 627 android.Manifest.permission.NETWORK_SETUP_WIZARD, MANAGED_PROFILE_UID)) 628 .thenReturn(PackageManager.PERMISSION_DENIED); 629 assertFalse(wifiPermissionsUtil.checkNetworkSetupWizardPermission(MANAGED_PROFILE_UID)); 630 631 when(mMockPermissionsWrapper.getUidPermission( 632 android.Manifest.permission.NETWORK_SETUP_WIZARD, MANAGED_PROFILE_UID)) 633 .thenReturn(PackageManager.PERMISSION_GRANTED); 634 assertTrue(wifiPermissionsUtil.checkNetworkSetupWizardPermission(MANAGED_PROFILE_UID)); 635 } 636 637 /** 638 * Test case setting: caller does not have Location permission. 639 * Expect a SecurityException 640 */ 641 @Test(expected = SecurityException.class) 642 public void testEnforceLocationPermissionExpectSecurityException() throws Exception { 643 setupTestCase(); 644 WifiPermissionsUtil codeUnderTest = new WifiPermissionsUtil(mMockPermissionsWrapper, 645 mMockContext, mMockWifiSettingsStore, mMockUserManager, mWifiInjector); 646 codeUnderTest.enforceLocationPermission(TEST_PACKAGE_NAME, mUid); 647 } 648 649 private Answer<Integer> createPermissionAnswer() { 650 return new Answer<Integer>() { 651 @Override 652 public Integer answer(InvocationOnMock invocation) { 653 int myUid = (int) invocation.getArguments()[1]; 654 String myPermission = (String) invocation.getArguments()[0]; 655 mPermissionsList.get(myPermission); 656 if (mPermissionsList.containsKey(myPermission)) { 657 int uid = mPermissionsList.get(myPermission); 658 if (myUid == uid) { 659 return PackageManager.PERMISSION_GRANTED; 660 } 661 } 662 return PackageManager.PERMISSION_DENIED; 663 } 664 }; 665 } 666 667 private void setupMocks() throws Exception { 668 when(mMockPkgMgr.getApplicationInfo(TEST_PACKAGE_NAME, 0)) 669 .thenReturn(mMockApplInfo); 670 when(mMockContext.getPackageManager()).thenReturn(mMockPkgMgr); 671 when(mMockAppOps.noteOp(AppOpsManager.OP_WIFI_SCAN, mUid, TEST_PACKAGE_NAME)) 672 .thenReturn(mWifiScanAllowApps); 673 when(mMockAppOps.noteOp(AppOpsManager.OP_COARSE_LOCATION, mUid, TEST_PACKAGE_NAME)) 674 .thenReturn(mAllowCoarseLocationApps); 675 if (mThrowSecurityException) { 676 doThrow(new SecurityException("Package " + TEST_PACKAGE_NAME + " doesn't belong" 677 + " to application bound to user " + mUid)) 678 .when(mMockAppOps).checkPackage(mUid, TEST_PACKAGE_NAME); 679 } 680 when(mMockContext.getSystemService(Context.APP_OPS_SERVICE)) 681 .thenReturn(mMockAppOps); 682 when(mMockUserManager.getProfiles(mCurrentUser)) 683 .thenReturn(Arrays.asList(mMockUserInfo)); 684 when(mMockContext.getContentResolver()).thenReturn(mMockContentResolver); 685 when(mMockContext.getSystemService(Context.USER_SERVICE)) 686 .thenReturn(mMockUserManager); 687 when(mWifiInjector.makeLog(anyString())).thenReturn(mWifiLog); 688 } 689 690 private void initTestVars() { 691 mPermissionsList.clear(); 692 mReturnPermission = createPermissionAnswer(); 693 mWifiScanAllowApps = AppOpsManager.MODE_ERRORED; 694 mUid = OTHER_USER_UID; 695 mThrowSecurityException = true; 696 mMockUserInfo.id = UserHandle.USER_NULL; 697 mMockApplInfo.targetSdkVersion = Build.VERSION_CODES.M; 698 mPkgNameOfTopActivity = INVALID_PACKAGE; 699 mLocationModeSetting = Settings.Secure.LOCATION_MODE_OFF; 700 mCurrentUser = UserHandle.USER_SYSTEM; 701 mCoarseLocationPermission = PackageManager.PERMISSION_DENIED; 702 mAllowCoarseLocationApps = AppOpsManager.MODE_ERRORED; 703 } 704 705 private void setupMockInterface() { 706 BinderUtil.setUid(mUid); 707 doAnswer(mReturnPermission).when(mMockPermissionsWrapper).getUidPermission( 708 anyString(), anyInt()); 709 doAnswer(mReturnPermission).when(mMockPermissionsWrapper).getUidPermission( 710 anyString(), anyInt()); 711 when(mMockPermissionsWrapper.getCallingUserId(mUid)).thenReturn(mCallingUser); 712 when(mMockPermissionsWrapper.getCurrentUser()).thenReturn(mCurrentUser); 713 when(mMockPermissionsWrapper.getUidPermission(mManifestStringCoarse, mUid)) 714 .thenReturn(mCoarseLocationPermission); 715 when(mMockWifiSettingsStore.getLocationModeSetting(mMockContext)) 716 .thenReturn(mLocationModeSetting); 717 when(mMockPermissionsWrapper.getTopPkgName()).thenReturn(mPkgNameOfTopActivity); 718 } 719 } 720