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.locksettings;
18 
19 import static org.junit.Assert.assertFalse;
20 import static org.junit.Assert.assertTrue;
21 import static org.mockito.ArgumentMatchers.any;
22 import static org.mockito.ArgumentMatchers.anyInt;
23 import static org.mockito.ArgumentMatchers.eq;
24 import static org.mockito.Mockito.doAnswer;
25 import static org.mockito.Mockito.mock;
26 import static org.mockito.Mockito.when;
27 
28 import android.app.IActivityManager;
29 import android.app.KeyguardManager;
30 import android.app.NotificationManager;
31 import android.app.admin.DevicePolicyManager;
32 import android.app.admin.DevicePolicyManagerInternal;
33 import android.app.admin.DeviceStateCache;
34 import android.app.trust.TrustManager;
35 import android.content.ComponentName;
36 import android.content.Context;
37 import android.content.pm.PackageManager;
38 import android.content.pm.UserInfo;
39 import android.content.res.Resources;
40 import android.hardware.authsecret.IAuthSecret;
41 import android.hardware.face.FaceManager;
42 import android.hardware.fingerprint.FingerprintManager;
43 import android.os.FileUtils;
44 import android.os.IProgressListener;
45 import android.os.RemoteException;
46 import android.os.UserHandle;
47 import android.os.UserManager;
48 import android.os.storage.IStorageManager;
49 import android.os.storage.StorageManager;
50 import android.provider.Settings;
51 import android.security.KeyStore;
52 
53 import androidx.test.InstrumentationRegistry;
54 import androidx.test.runner.AndroidJUnit4;
55 
56 import com.android.internal.util.test.FakeSettingsProvider;
57 import com.android.internal.util.test.FakeSettingsProviderRule;
58 import com.android.internal.widget.LockPatternUtils;
59 import com.android.internal.widget.LockSettingsInternal;
60 import com.android.internal.widget.LockscreenCredential;
61 import com.android.server.LocalServices;
62 import com.android.server.locksettings.recoverablekeystore.RecoverableKeyStoreManager;
63 import com.android.server.pm.UserManagerInternal;
64 import com.android.server.wm.WindowManagerInternal;
65 
66 import org.junit.After;
67 import org.junit.Before;
68 import org.junit.Rule;
69 import org.junit.runner.RunWith;
70 import org.mockito.invocation.InvocationOnMock;
71 import org.mockito.stubbing.Answer;
72 
73 import java.io.File;
74 import java.util.ArrayList;
75 import java.util.Arrays;
76 
77 @RunWith(AndroidJUnit4.class)
78 public abstract class BaseLockSettingsServiceTests {
79     protected static final int PRIMARY_USER_ID = 0;
80     protected static final int MANAGED_PROFILE_USER_ID = 12;
81     protected static final int TURNED_OFF_PROFILE_USER_ID = 17;
82     protected static final int SECONDARY_USER_ID = 20;
83     protected static final int TERTIARY_USER_ID = 21;
84 
85     protected UserInfo mPrimaryUserInfo;
86     protected UserInfo mSecondaryUserInfo;
87     protected UserInfo mTertiaryUserInfo;
88 
89     private ArrayList<UserInfo> mPrimaryUserProfiles = new ArrayList<>();
90 
91     LockSettingsServiceTestable mService;
92     LockSettingsInternal mLocalService;
93 
94     MockLockSettingsContext mContext;
95     LockSettingsStorageTestable mStorage;
96 
97     Resources mResources;
98     FakeGateKeeperService mGateKeeperService;
99     NotificationManager mNotificationManager;
100     UserManager mUserManager;
101     FakeStorageManager mStorageManager;
102     IActivityManager mActivityManager;
103     DevicePolicyManager mDevicePolicyManager;
104     DevicePolicyManagerInternal mDevicePolicyManagerInternal;
105     KeyStore mKeyStore;
106     MockSyntheticPasswordManager mSpManager;
107     IAuthSecret mAuthSecretService;
108     WindowManagerInternal mMockWindowManager;
109     FakeGsiService mGsiService;
110     PasswordSlotManagerTestable mPasswordSlotManager;
111     RecoverableKeyStoreManager mRecoverableKeyStoreManager;
112     UserManagerInternal mUserManagerInternal;
113     DeviceStateCache mDeviceStateCache;
114     FingerprintManager mFingerprintManager;
115     FaceManager mFaceManager;
116     PackageManager mPackageManager;
117     LockSettingsServiceTestable.MockInjector mInjector;
118     @Rule
119     public FakeSettingsProviderRule mSettingsRule = FakeSettingsProvider.rule();
120 
121     @Before
setUp_baseServices()122     public void setUp_baseServices() throws Exception {
123         mResources = createMockResources();
124         mGateKeeperService = new FakeGateKeeperService();
125         mNotificationManager = mock(NotificationManager.class);
126         mUserManager = mock(UserManager.class);
127         mStorageManager = new FakeStorageManager();
128         mActivityManager = mock(IActivityManager.class);
129         mDevicePolicyManager = mock(DevicePolicyManager.class);
130         mDevicePolicyManagerInternal = mock(DevicePolicyManagerInternal.class);
131         mMockWindowManager = mock(WindowManagerInternal.class);
132         mGsiService = new FakeGsiService();
133         mPasswordSlotManager = new PasswordSlotManagerTestable();
134         mRecoverableKeyStoreManager = mock(RecoverableKeyStoreManager.class);
135         mUserManagerInternal = mock(UserManagerInternal.class);
136         mDeviceStateCache = mock(DeviceStateCache.class);
137         mFingerprintManager = mock(FingerprintManager.class);
138         mFaceManager = mock(FaceManager.class);
139         mPackageManager = mock(PackageManager.class);
140 
141         LocalServices.removeServiceForTest(LockSettingsInternal.class);
142         LocalServices.removeServiceForTest(DevicePolicyManagerInternal.class);
143         LocalServices.removeServiceForTest(WindowManagerInternal.class);
144         LocalServices.addService(DevicePolicyManagerInternal.class, mDevicePolicyManagerInternal);
145         LocalServices.addService(WindowManagerInternal.class, mMockWindowManager);
146 
147         final Context origContext = InstrumentationRegistry.getContext();
148         mContext = new MockLockSettingsContext(origContext, mResources,
149                 mSettingsRule.mockContentResolver(origContext), mUserManager, mNotificationManager,
150                 mDevicePolicyManager, mock(StorageManager.class), mock(TrustManager.class),
151                 mock(KeyguardManager.class), mFingerprintManager, mFaceManager, mPackageManager);
152         mStorage = new LockSettingsStorageTestable(mContext,
153                 new File(origContext.getFilesDir(), "locksettings"));
154         File storageDir = mStorage.mStorageDir;
155         if (storageDir.exists()) {
156             FileUtils.deleteContents(storageDir);
157         } else {
158             storageDir.mkdirs();
159         }
160 
161         mSpManager = new MockSyntheticPasswordManager(mContext, mStorage, mGateKeeperService,
162                 mUserManager, mPasswordSlotManager);
163         mAuthSecretService = mock(IAuthSecret.class);
164         mInjector =
165                 new LockSettingsServiceTestable.MockInjector(
166                         mContext,
167                         mStorage,
168                         mKeyStore,
169                         mActivityManager,
170                         setUpStorageManagerMock(),
171                         mSpManager,
172                         mGsiService,
173                         mRecoverableKeyStoreManager,
174                         mUserManagerInternal,
175                         mDeviceStateCache);
176         mService =
177                 new LockSettingsServiceTestable(mInjector, mGateKeeperService, mAuthSecretService);
178         mService.mHasSecureLockScreen = true;
179         mPrimaryUserInfo =
180                 new UserInfo(
181                         PRIMARY_USER_ID,
182                         null,
183                         null,
184                         UserInfo.FLAG_INITIALIZED
185                                 | UserInfo.FLAG_ADMIN
186                                 | UserInfo.FLAG_PRIMARY
187                                 | UserInfo.FLAG_MAIN
188                                 | UserInfo.FLAG_FULL);
189         mSecondaryUserInfo =
190                 new UserInfo(
191                         SECONDARY_USER_ID,
192                         null,
193                         null,
194                         UserInfo.FLAG_INITIALIZED | UserInfo.FLAG_FULL);
195         mTertiaryUserInfo =
196                 new UserInfo(
197                         TERTIARY_USER_ID,
198                         null,
199                         null,
200                         UserInfo.FLAG_INITIALIZED | UserInfo.FLAG_FULL);
201 
202         when(mUserManager.getUserInfo(eq(PRIMARY_USER_ID))).thenReturn(mPrimaryUserInfo);
203         when(mUserManagerInternal.getUserInfo(eq(PRIMARY_USER_ID))).thenReturn(mPrimaryUserInfo);
204         mPrimaryUserProfiles.add(mPrimaryUserInfo);
205         installChildProfile(MANAGED_PROFILE_USER_ID);
206         installAndTurnOffChildProfile(TURNED_OFF_PROFILE_USER_ID);
207         for (UserInfo profile : mPrimaryUserProfiles) {
208             when(mUserManager.getProfiles(eq(profile.id))).thenReturn(mPrimaryUserProfiles);
209         }
210         when(mUserManager.getUserInfo(eq(SECONDARY_USER_ID))).thenReturn(mSecondaryUserInfo);
211         when(mUserManagerInternal.getUserInfo(eq(SECONDARY_USER_ID)))
212                 .thenReturn(mSecondaryUserInfo);
213         when(mUserManager.getUserInfo(eq(TERTIARY_USER_ID))).thenReturn(mTertiaryUserInfo);
214         when(mUserManagerInternal.getUserInfo(eq(TERTIARY_USER_ID))).thenReturn(mTertiaryUserInfo);
215 
216         final ArrayList<UserInfo> allUsers = new ArrayList<>(mPrimaryUserProfiles);
217         allUsers.add(mSecondaryUserInfo);
218         allUsers.add(mTertiaryUserInfo);
219         when(mUserManager.getUsers()).thenReturn(allUsers);
220 
221         when(mActivityManager.unlockUser2(anyInt(), any())).thenAnswer(
222             invocation -> {
223                 Object[] args = invocation.getArguments();
224                 int userId = (int) args[0];
225                 IProgressListener listener = (IProgressListener) args[1];
226                 listener.onStarted(userId, null);
227                 listener.onFinished(userId, null);
228                 return true;
229             });
230 
231         // Adding a fake Device Owner app which will enable escrow token support in LSS.
232         when(mDevicePolicyManager.getDeviceOwnerComponentOnAnyUser()).thenReturn(
233                 new ComponentName("com.dummy.package", ".FakeDeviceOwner"));
234         when(mUserManagerInternal.isDeviceManaged()).thenReturn(true);
235         when(mDeviceStateCache.isUserOrganizationManaged(anyInt())).thenReturn(true);
236         when(mDeviceStateCache.isDeviceProvisioned()).thenReturn(true);
237         mockBiometricsHardwareFingerprintsAndTemplates(PRIMARY_USER_ID);
238         mockBiometricsHardwareFingerprintsAndTemplates(MANAGED_PROFILE_USER_ID);
239 
240         setDeviceProvisioned(true);
241         mLocalService = LocalServices.getService(LockSettingsInternal.class);
242     }
243 
createMockResources()244     private Resources createMockResources() {
245         Resources res = mock(Resources.class);
246 
247         // Set up some default configs, copied from core/res/res/values/config.xml
248         when(res.getBoolean(eq(com.android.internal.R.bool.config_disableLockscreenByDefault)))
249                 .thenReturn(false);
250         when(res.getBoolean(
251                 eq(com.android.internal.R.bool.config_enableCredentialFactoryResetProtection)))
252                 .thenReturn(true);
253         when(res.getBoolean(eq(com.android.internal.R.bool.config_isMainUserPermanentAdmin)))
254                 .thenReturn(true);
255         when(res.getBoolean(eq(com.android.internal.R.bool.config_strongAuthRequiredOnBoot)))
256                 .thenReturn(true);
257         when(res.getBoolean(eq(com.android.internal.R.bool.config_repairModeSupported)))
258                 .thenReturn(true);
259         return res;
260     }
261 
setDeviceProvisioned(boolean provisioned)262     protected void setDeviceProvisioned(boolean provisioned) {
263         Settings.Global.putInt(mContext.getContentResolver(),
264                 Settings.Global.DEVICE_PROVISIONED, provisioned ? 1 : 0);
265     }
266 
setUserSetupComplete(boolean complete)267     protected void setUserSetupComplete(boolean complete) {
268         Settings.Secure.putIntForUser(mContext.getContentResolver(),
269                 Settings.Secure.USER_SETUP_COMPLETE, complete ? 1 : 0, UserHandle.USER_SYSTEM);
270     }
271 
setSecureFrpMode(boolean secure)272     protected void setSecureFrpMode(boolean secure) {
273         Settings.Secure.putIntForUser(mContext.getContentResolver(),
274                 Settings.Secure.SECURE_FRP_MODE, secure ? 1 : 0, UserHandle.USER_SYSTEM);
275     }
276 
installChildProfile(int profileId)277     private UserInfo installChildProfile(int profileId) {
278         final UserInfo userInfo = new UserInfo(
279             profileId, null, null, UserInfo.FLAG_INITIALIZED | UserInfo.FLAG_MANAGED_PROFILE);
280         userInfo.profileGroupId = PRIMARY_USER_ID;
281         mPrimaryUserProfiles.add(userInfo);
282         when(mUserManager.getUserInfo(eq(profileId))).thenReturn(userInfo);
283         when(mUserManager.getProfileParent(eq(profileId))).thenReturn(mPrimaryUserInfo);
284         when(mUserManager.isUserRunning(eq(profileId))).thenReturn(true);
285         when(mUserManager.isUserUnlocked(eq(profileId))).thenReturn(true);
286         when(mUserManagerInternal.getUserInfo(eq(profileId))).thenReturn(userInfo);
287         // TODO(b/258213147): Remove
288         when(mUserManagerInternal.isUserManaged(eq(profileId))).thenReturn(true);
289         when(mDeviceStateCache.isUserOrganizationManaged(eq(profileId)))
290                 .thenReturn(true);
291         return userInfo;
292     }
293 
installAndTurnOffChildProfile(int profileId)294     private UserInfo installAndTurnOffChildProfile(int profileId) {
295         final UserInfo userInfo = installChildProfile(profileId);
296         userInfo.flags |= UserInfo.FLAG_QUIET_MODE;
297         when(mUserManager.isUserRunning(eq(profileId))).thenReturn(false);
298         when(mUserManager.isUserUnlocked(eq(profileId))).thenReturn(false);
299         return userInfo;
300     }
301 
setUpStorageManagerMock()302     private IStorageManager setUpStorageManagerMock() throws RemoteException {
303         final IStorageManager sm = mock(IStorageManager.class);
304 
305         doAnswer(invocation -> {
306             Object[] args = invocation.getArguments();
307             mStorageManager.unlockUserKey(/* userId= */ (int) args[0],
308                     /* secret= */ (byte[]) args[2]);
309             return null;
310         }).when(sm).unlockUserKey(anyInt(), anyInt(), any());
311 
312         doAnswer(invocation -> {
313             Object[] args = invocation.getArguments();
314             mStorageManager.setUserKeyProtection(/* userId= */ (int) args[0],
315                     /* secret= */ (byte[]) args[1]);
316             return null;
317         }).when(sm).setUserKeyProtection(anyInt(), any());
318 
319         return sm;
320     }
321 
mockBiometricsHardwareFingerprintsAndTemplates(int userId)322     private void mockBiometricsHardwareFingerprintsAndTemplates(int userId) {
323         // Hardware must be detected and fingerprints must be enrolled
324         when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)).thenReturn(true);
325         when(mFingerprintManager.isHardwareDetected()).thenReturn(true);
326         when(mFingerprintManager.hasEnrolledFingerprints(userId)).thenReturn(true);
327         doAnswer(new Answer<Void>() {
328             @Override
329             public Void answer(InvocationOnMock invocation) throws Throwable {
330                 FingerprintManager.RemovalCallback callback =
331                         (FingerprintManager.RemovalCallback) invocation.getArguments()[1];
332                 callback.onRemovalSucceeded(null, 0);
333                 return null;
334             }
335         }).when(mFingerprintManager).removeAll(eq(userId), any());
336 
337 
338         // Hardware must be detected and templates must be enrolled
339         when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_FACE)).thenReturn(true);
340         when(mFaceManager.isHardwareDetected()).thenReturn(true);
341         when(mFaceManager.hasEnrolledTemplates(userId)).thenReturn(true);
342         doAnswer(new Answer<Void>() {
343             @Override
344             public Void answer(InvocationOnMock invocation) throws Throwable {
345                 FaceManager.RemovalCallback callback =
346                         (FaceManager.RemovalCallback) invocation.getArguments()[1];
347                 callback.onRemovalSucceeded(null, 0);
348                 return null;
349             }
350         }).when(mFaceManager).removeAll(eq(userId), any());
351     }
352 
353     @After
tearDown_baseServices()354     public void tearDown_baseServices() throws Exception {
355         mStorage.closeDatabase();
356         File db = InstrumentationRegistry.getContext().getDatabasePath("locksettings.db");
357         assertTrue(!db.exists() || db.delete());
358 
359         File storageDir = mStorage.mStorageDir;
360         assertTrue(FileUtils.deleteContents(storageDir));
361 
362         mPasswordSlotManager.cleanup();
363     }
364 
flushHandlerTasks()365     protected void flushHandlerTasks() {
366         mService.mHandler.runWithScissors(() -> { }, 0 /*now*/); // Flush runnables on handler
367     }
368 
assertNotEquals(long expected, long actual)369     protected void assertNotEquals(long expected, long actual) {
370         assertTrue(expected != actual);
371     }
372 
assertArrayEquals(byte[] expected, byte[] actual)373     protected static void assertArrayEquals(byte[] expected, byte[] actual) {
374         assertTrue(Arrays.equals(expected, actual));
375     }
376 
assertArrayNotEquals(byte[] expected, byte[] actual)377     protected static void assertArrayNotEquals(byte[] expected, byte[] actual) {
378         assertFalse(Arrays.equals(expected, actual));
379     }
380 
newPassword(String password)381     protected LockscreenCredential newPassword(String password) {
382         return LockscreenCredential.createPasswordOrNone(password);
383     }
384 
newPin(String pin)385     protected LockscreenCredential newPin(String pin) {
386         return LockscreenCredential.createPinOrNone(pin);
387     }
388 
newPattern(String pattern)389     protected LockscreenCredential newPattern(String pattern) {
390         return LockscreenCredential.createPattern(LockPatternUtils.byteArrayToPattern(
391                 pattern.getBytes()));
392     }
393 
nonePassword()394     protected LockscreenCredential nonePassword() {
395         return LockscreenCredential.createNone();
396     }
397 
398 }
399