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 
52 import androidx.test.InstrumentationRegistry;
53 import androidx.test.runner.AndroidJUnit4;
54 
55 import com.android.internal.util.test.FakeSettingsProvider;
56 import com.android.internal.util.test.FakeSettingsProviderRule;
57 import com.android.internal.widget.LockPatternUtils;
58 import com.android.internal.widget.LockSettingsInternal;
59 import com.android.internal.widget.LockscreenCredential;
60 import com.android.server.LocalServices;
61 import com.android.server.locksettings.recoverablekeystore.RecoverableKeyStoreManager;
62 import com.android.server.pm.UserManagerInternal;
63 import com.android.server.wm.WindowManagerInternal;
64 
65 import org.junit.After;
66 import org.junit.Before;
67 import org.junit.Rule;
68 import org.junit.runner.RunWith;
69 import org.mockito.invocation.InvocationOnMock;
70 import org.mockito.stubbing.Answer;
71 
72 import java.io.File;
73 import java.util.ArrayList;
74 import java.util.Arrays;
75 
76 @RunWith(AndroidJUnit4.class)
77 public abstract class BaseLockSettingsServiceTests {
78     protected static final int PRIMARY_USER_ID = 0;
79     protected static final int MANAGED_PROFILE_USER_ID = 12;
80     protected static final int TURNED_OFF_PROFILE_USER_ID = 17;
81     protected static final int SECONDARY_USER_ID = 20;
82     protected static final int TERTIARY_USER_ID = 21;
83 
84     protected UserInfo mPrimaryUserInfo;
85     protected UserInfo mSecondaryUserInfo;
86     protected UserInfo mTertiaryUserInfo;
87 
88     private ArrayList<UserInfo> mPrimaryUserProfiles = new ArrayList<>();
89 
90     LockSettingsServiceTestable mService;
91     LockSettingsInternal mLocalService;
92 
93     MockLockSettingsContext mContext;
94     LockSettingsStorageTestable mStorage;
95 
96     Resources mResources;
97     FakeGateKeeperService mGateKeeperService;
98     NotificationManager mNotificationManager;
99     UserManager mUserManager;
100     FakeStorageManager mStorageManager;
101     IActivityManager mActivityManager;
102     DevicePolicyManager mDevicePolicyManager;
103     DevicePolicyManagerInternal mDevicePolicyManagerInternal;
104     MockSyntheticPasswordManager mSpManager;
105     IAuthSecret mAuthSecretService;
106     WindowManagerInternal mMockWindowManager;
107     FakeGsiService mGsiService;
108     PasswordSlotManagerTestable mPasswordSlotManager;
109     RecoverableKeyStoreManager mRecoverableKeyStoreManager;
110     UserManagerInternal mUserManagerInternal;
111     DeviceStateCache mDeviceStateCache;
112     FingerprintManager mFingerprintManager;
113     FaceManager mFaceManager;
114     PackageManager mPackageManager;
115     LockSettingsServiceTestable.MockInjector mInjector;
116     @Rule
117     public FakeSettingsProviderRule mSettingsRule = FakeSettingsProvider.rule();
118 
119     @Before
setUp_baseServices()120     public void setUp_baseServices() throws Exception {
121         mResources = createMockResources();
122         mGateKeeperService = new FakeGateKeeperService();
123         mNotificationManager = mock(NotificationManager.class);
124         mUserManager = mock(UserManager.class);
125         mStorageManager = new FakeStorageManager();
126         mActivityManager = mock(IActivityManager.class);
127         mDevicePolicyManager = mock(DevicePolicyManager.class);
128         mDevicePolicyManagerInternal = mock(DevicePolicyManagerInternal.class);
129         mMockWindowManager = mock(WindowManagerInternal.class);
130         mGsiService = new FakeGsiService();
131         mPasswordSlotManager = new PasswordSlotManagerTestable();
132         mRecoverableKeyStoreManager = mock(RecoverableKeyStoreManager.class);
133         mUserManagerInternal = mock(UserManagerInternal.class);
134         mDeviceStateCache = mock(DeviceStateCache.class);
135         mFingerprintManager = mock(FingerprintManager.class);
136         mFaceManager = mock(FaceManager.class);
137         mPackageManager = mock(PackageManager.class);
138 
139         LocalServices.removeServiceForTest(LockSettingsInternal.class);
140         LocalServices.removeServiceForTest(DevicePolicyManagerInternal.class);
141         LocalServices.removeServiceForTest(WindowManagerInternal.class);
142         LocalServices.addService(DevicePolicyManagerInternal.class, mDevicePolicyManagerInternal);
143         LocalServices.addService(WindowManagerInternal.class, mMockWindowManager);
144 
145         final Context origContext = InstrumentationRegistry.getContext();
146         mContext = new MockLockSettingsContext(origContext, mResources,
147                 mSettingsRule.mockContentResolver(origContext), mUserManager, mNotificationManager,
148                 mDevicePolicyManager, mock(StorageManager.class), mock(TrustManager.class),
149                 mock(KeyguardManager.class), mFingerprintManager, mFaceManager, mPackageManager);
150         mStorage = new LockSettingsStorageTestable(mContext,
151                 new File(origContext.getFilesDir(), "locksettings"));
152         File storageDir = mStorage.mStorageDir;
153         if (storageDir.exists()) {
154             FileUtils.deleteContents(storageDir);
155         } else {
156             storageDir.mkdirs();
157         }
158 
159         mSpManager = new MockSyntheticPasswordManager(mContext, mStorage, mGateKeeperService,
160                 mUserManager, mPasswordSlotManager);
161         mAuthSecretService = mock(IAuthSecret.class);
162         mInjector =
163                 new LockSettingsServiceTestable.MockInjector(
164                         mContext,
165                         mStorage,
166                         mActivityManager,
167                         setUpStorageManagerMock(),
168                         mSpManager,
169                         mGsiService,
170                         mRecoverableKeyStoreManager,
171                         mUserManagerInternal,
172                         mDeviceStateCache);
173         mService =
174                 new LockSettingsServiceTestable(mInjector, mGateKeeperService, mAuthSecretService);
175         mService.mHasSecureLockScreen = true;
176         mPrimaryUserInfo =
177                 new UserInfo(
178                         PRIMARY_USER_ID,
179                         null,
180                         null,
181                         UserInfo.FLAG_INITIALIZED
182                                 | UserInfo.FLAG_ADMIN
183                                 | UserInfo.FLAG_PRIMARY
184                                 | UserInfo.FLAG_MAIN
185                                 | UserInfo.FLAG_FULL);
186         mSecondaryUserInfo =
187                 new UserInfo(
188                         SECONDARY_USER_ID,
189                         null,
190                         null,
191                         UserInfo.FLAG_INITIALIZED | UserInfo.FLAG_FULL);
192         mTertiaryUserInfo =
193                 new UserInfo(
194                         TERTIARY_USER_ID,
195                         null,
196                         null,
197                         UserInfo.FLAG_INITIALIZED | UserInfo.FLAG_FULL);
198 
199         when(mUserManager.getUserInfo(eq(PRIMARY_USER_ID))).thenReturn(mPrimaryUserInfo);
200         when(mUserManagerInternal.getUserInfo(eq(PRIMARY_USER_ID))).thenReturn(mPrimaryUserInfo);
201         mPrimaryUserProfiles.add(mPrimaryUserInfo);
202         installChildProfile(MANAGED_PROFILE_USER_ID);
203         installAndTurnOffChildProfile(TURNED_OFF_PROFILE_USER_ID);
204         for (UserInfo profile : mPrimaryUserProfiles) {
205             when(mUserManager.getProfiles(eq(profile.id))).thenReturn(mPrimaryUserProfiles);
206         }
207         when(mUserManager.getUserInfo(eq(SECONDARY_USER_ID))).thenReturn(mSecondaryUserInfo);
208         when(mUserManagerInternal.getUserInfo(eq(SECONDARY_USER_ID)))
209                 .thenReturn(mSecondaryUserInfo);
210         when(mUserManager.getUserInfo(eq(TERTIARY_USER_ID))).thenReturn(mTertiaryUserInfo);
211         when(mUserManagerInternal.getUserInfo(eq(TERTIARY_USER_ID))).thenReturn(mTertiaryUserInfo);
212 
213         final ArrayList<UserInfo> allUsers = new ArrayList<>(mPrimaryUserProfiles);
214         allUsers.add(mSecondaryUserInfo);
215         allUsers.add(mTertiaryUserInfo);
216         when(mUserManager.getUsers()).thenReturn(allUsers);
217 
218         when(mActivityManager.unlockUser2(anyInt(), any())).thenAnswer(
219             invocation -> {
220                 Object[] args = invocation.getArguments();
221                 int userId = (int) args[0];
222                 IProgressListener listener = (IProgressListener) args[1];
223                 listener.onStarted(userId, null);
224                 listener.onFinished(userId, null);
225                 return true;
226             });
227 
228         // Adding a fake Device Owner app which will enable escrow token support in LSS.
229         when(mDevicePolicyManager.getDeviceOwnerComponentOnAnyUser()).thenReturn(
230                 new ComponentName("com.dummy.package", ".FakeDeviceOwner"));
231         when(mUserManagerInternal.isDeviceManaged()).thenReturn(true);
232         when(mDeviceStateCache.isUserOrganizationManaged(anyInt())).thenReturn(true);
233         when(mDeviceStateCache.isDeviceProvisioned()).thenReturn(true);
234         mockBiometricsHardwareFingerprintsAndTemplates(PRIMARY_USER_ID);
235         mockBiometricsHardwareFingerprintsAndTemplates(MANAGED_PROFILE_USER_ID);
236 
237         setDeviceProvisioned(true);
238         mLocalService = LocalServices.getService(LockSettingsInternal.class);
239     }
240 
createMockResources()241     private Resources createMockResources() {
242         Resources res = mock(Resources.class);
243 
244         // Set up some default configs, copied from core/res/res/values/config.xml
245         when(res.getBoolean(eq(com.android.internal.R.bool.config_disableLockscreenByDefault)))
246                 .thenReturn(false);
247         when(res.getBoolean(
248                 eq(com.android.internal.R.bool.config_enableCredentialFactoryResetProtection)))
249                 .thenReturn(true);
250         when(res.getBoolean(eq(com.android.internal.R.bool.config_isMainUserPermanentAdmin)))
251                 .thenReturn(true);
252         when(res.getBoolean(eq(com.android.internal.R.bool.config_strongAuthRequiredOnBoot)))
253                 .thenReturn(true);
254         when(res.getBoolean(eq(com.android.internal.R.bool.config_repairModeSupported)))
255                 .thenReturn(true);
256         return res;
257     }
258 
setDeviceProvisioned(boolean provisioned)259     protected void setDeviceProvisioned(boolean provisioned) {
260         Settings.Global.putInt(mContext.getContentResolver(),
261                 Settings.Global.DEVICE_PROVISIONED, provisioned ? 1 : 0);
262     }
263 
setUserSetupComplete(boolean complete)264     protected void setUserSetupComplete(boolean complete) {
265         Settings.Secure.putIntForUser(mContext.getContentResolver(),
266                 Settings.Secure.USER_SETUP_COMPLETE, complete ? 1 : 0, UserHandle.USER_SYSTEM);
267     }
268 
setSecureFrpMode(boolean secure)269     protected void setSecureFrpMode(boolean secure) {
270         if (android.security.Flags.frpEnforcement()) {
271             mStorage.setTestFactoryResetProtectionState(secure);
272         }
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.unlockCeStorage(/* userId= */ (int) args[0],
308                     /* secret= */ (byte[]) args[1]);
309             return null;
310         }).when(sm).unlockCeStorage(anyInt(), any());
311 
312         doAnswer(invocation -> {
313             Object[] args = invocation.getArguments();
314             mStorageManager.setCeStorageProtection(/* userId= */ (int) args[0],
315                     /* secret= */ (byte[]) args[1]);
316             return null;
317         }).when(sm).setCeStorageProtection(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