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.anyBoolean;
23 import static org.mockito.ArgumentMatchers.anyInt;
24 import static org.mockito.ArgumentMatchers.eq;
25 import static org.mockito.Mockito.doAnswer;
26 import static org.mockito.Mockito.mock;
27 import static org.mockito.Mockito.when;
28 
29 import android.app.IActivityManager;
30 import android.app.KeyguardManager;
31 import android.app.NotificationManager;
32 import android.app.admin.DevicePolicyManager;
33 import android.app.admin.DevicePolicyManagerInternal;
34 import android.app.admin.DeviceStateCache;
35 import android.app.trust.TrustManager;
36 import android.content.ComponentName;
37 import android.content.pm.PackageManager;
38 import android.content.pm.UserInfo;
39 import android.hardware.authsecret.V1_0.IAuthSecret;
40 import android.hardware.face.Face;
41 import android.hardware.face.FaceManager;
42 import android.hardware.fingerprint.Fingerprint;
43 import android.hardware.fingerprint.FingerprintManager;
44 import android.os.FileUtils;
45 import android.os.IProgressListener;
46 import android.os.RemoteException;
47 import android.os.UserManager;
48 import android.os.UserManagerInternal;
49 import android.os.storage.IStorageManager;
50 import android.os.storage.StorageManager;
51 import android.security.KeyStore;
52 
53 import androidx.test.InstrumentationRegistry;
54 import androidx.test.runner.AndroidJUnit4;
55 
56 import com.android.internal.widget.LockPatternUtils;
57 import com.android.internal.widget.LockSettingsInternal;
58 import com.android.internal.widget.LockscreenCredential;
59 import com.android.server.LocalServices;
60 import com.android.server.locksettings.recoverablekeystore.RecoverableKeyStoreManager;
61 import com.android.server.wm.WindowManagerInternal;
62 
63 import org.junit.After;
64 import org.junit.Before;
65 import org.junit.runner.RunWith;
66 import org.mockito.invocation.InvocationOnMock;
67 import org.mockito.stubbing.Answer;
68 
69 import java.io.File;
70 import java.util.ArrayList;
71 import java.util.Arrays;
72 
73 @RunWith(AndroidJUnit4.class)
74 public abstract class BaseLockSettingsServiceTests {
75     protected static final int PRIMARY_USER_ID = 0;
76     protected static final int MANAGED_PROFILE_USER_ID = 12;
77     protected static final int TURNED_OFF_PROFILE_USER_ID = 17;
78     protected static final int SECONDARY_USER_ID = 20;
79 
80     private static final UserInfo PRIMARY_USER_INFO = new UserInfo(PRIMARY_USER_ID, null, null,
81             UserInfo.FLAG_INITIALIZED | UserInfo.FLAG_ADMIN | UserInfo.FLAG_PRIMARY);
82     private static final UserInfo SECONDARY_USER_INFO = new UserInfo(SECONDARY_USER_ID, null, null,
83             UserInfo.FLAG_INITIALIZED);
84 
85     private ArrayList<UserInfo> mPrimaryUserProfiles = new ArrayList<>();
86 
87     LockSettingsService mService;
88     LockSettingsInternal mLocalService;
89 
90     MockLockSettingsContext mContext;
91     LockSettingsStorageTestable mStorage;
92 
93     FakeGateKeeperService mGateKeeperService;
94     NotificationManager mNotificationManager;
95     UserManager mUserManager;
96     FakeStorageManager mStorageManager;
97     IActivityManager mActivityManager;
98     DevicePolicyManager mDevicePolicyManager;
99     DevicePolicyManagerInternal mDevicePolicyManagerInternal;
100     KeyStore mKeyStore;
101     MockSyntheticPasswordManager mSpManager;
102     IAuthSecret mAuthSecretService;
103     WindowManagerInternal mMockWindowManager;
104     FakeGsiService mGsiService;
105     PasswordSlotManagerTestable mPasswordSlotManager;
106     RecoverableKeyStoreManager mRecoverableKeyStoreManager;
107     UserManagerInternal mUserManagerInternal;
108     DeviceStateCache mDeviceStateCache;
109     FingerprintManager mFingerprintManager;
110     FaceManager mFaceManager;
111     PackageManager mPackageManager;
112     FakeSettings mSettings;
113 
114     @Before
setUp_baseServices()115     public void setUp_baseServices() throws Exception {
116         mGateKeeperService = new FakeGateKeeperService();
117         mNotificationManager = mock(NotificationManager.class);
118         mUserManager = mock(UserManager.class);
119         mStorageManager = new FakeStorageManager();
120         mActivityManager = mock(IActivityManager.class);
121         mDevicePolicyManager = mock(DevicePolicyManager.class);
122         mDevicePolicyManagerInternal = mock(DevicePolicyManagerInternal.class);
123         mMockWindowManager = mock(WindowManagerInternal.class);
124         mGsiService = new FakeGsiService();
125         mPasswordSlotManager = new PasswordSlotManagerTestable();
126         mRecoverableKeyStoreManager = mock(RecoverableKeyStoreManager.class);
127         mUserManagerInternal = mock(UserManagerInternal.class);
128         mDeviceStateCache = mock(DeviceStateCache.class);
129         mFingerprintManager = mock(FingerprintManager.class);
130         mFaceManager = mock(FaceManager.class);
131         mPackageManager = mock(PackageManager.class);
132         mSettings = new FakeSettings();
133 
134         LocalServices.removeServiceForTest(LockSettingsInternal.class);
135         LocalServices.removeServiceForTest(DevicePolicyManagerInternal.class);
136         LocalServices.removeServiceForTest(WindowManagerInternal.class);
137         LocalServices.addService(DevicePolicyManagerInternal.class, mDevicePolicyManagerInternal);
138         LocalServices.addService(WindowManagerInternal.class, mMockWindowManager);
139 
140         mContext = new MockLockSettingsContext(InstrumentationRegistry.getContext(), mUserManager,
141                 mNotificationManager, mDevicePolicyManager, mock(StorageManager.class),
142                 mock(TrustManager.class), mock(KeyguardManager.class), mFingerprintManager,
143                 mFaceManager, mPackageManager);
144         mStorage = new LockSettingsStorageTestable(mContext,
145                 new File(InstrumentationRegistry.getContext().getFilesDir(), "locksettings"));
146         File storageDir = mStorage.mStorageDir;
147         if (storageDir.exists()) {
148             FileUtils.deleteContents(storageDir);
149         } else {
150             storageDir.mkdirs();
151         }
152 
153         mSpManager = new MockSyntheticPasswordManager(mContext, mStorage, mGateKeeperService,
154                 mUserManager, mPasswordSlotManager);
155         mAuthSecretService = mock(IAuthSecret.class);
156         mService = new LockSettingsServiceTestable(mContext, mStorage,
157                 mGateKeeperService, mKeyStore, setUpStorageManagerMock(), mActivityManager,
158                 mSpManager, mAuthSecretService, mGsiService, mRecoverableKeyStoreManager,
159                 mUserManagerInternal, mDeviceStateCache, mSettings);
160         mService.mHasSecureLockScreen = true;
161         when(mUserManager.getUserInfo(eq(PRIMARY_USER_ID))).thenReturn(PRIMARY_USER_INFO);
162         mPrimaryUserProfiles.add(PRIMARY_USER_INFO);
163         installChildProfile(MANAGED_PROFILE_USER_ID);
164         installAndTurnOffChildProfile(TURNED_OFF_PROFILE_USER_ID);
165         for (UserInfo profile : mPrimaryUserProfiles) {
166             when(mUserManager.getProfiles(eq(profile.id))).thenReturn(mPrimaryUserProfiles);
167         }
168         when(mUserManager.getUserInfo(eq(SECONDARY_USER_ID))).thenReturn(SECONDARY_USER_INFO);
169 
170         final ArrayList<UserInfo> allUsers = new ArrayList<>(mPrimaryUserProfiles);
171         allUsers.add(SECONDARY_USER_INFO);
172         when(mUserManager.getUsers(anyBoolean())).thenReturn(allUsers);
173 
174         when(mActivityManager.unlockUser(anyInt(), any(), any(), any())).thenAnswer(
175                 new Answer<Boolean>() {
176             @Override
177             public Boolean answer(InvocationOnMock invocation) throws Throwable {
178                 Object[] args = invocation.getArguments();
179                 mStorageManager.unlockUser((int)args[0], (byte[])args[2],
180                         (IProgressListener) args[3]);
181                 return true;
182             }
183         });
184 
185         // Adding a fake Device Owner app which will enable escrow token support in LSS.
186         when(mDevicePolicyManager.getDeviceOwnerComponentOnAnyUser()).thenReturn(
187                 new ComponentName("com.dummy.package", ".FakeDeviceOwner"));
188         when(mUserManagerInternal.isDeviceManaged()).thenReturn(true);
189         when(mDeviceStateCache.isDeviceProvisioned()).thenReturn(true);
190         mockBiometricsHardwareFingerprintsAndTemplates(PRIMARY_USER_ID);
191         mockBiometricsHardwareFingerprintsAndTemplates(MANAGED_PROFILE_USER_ID);
192 
193         mSettings.setDeviceProvisioned(true);
194         mLocalService = LocalServices.getService(LockSettingsInternal.class);
195     }
196 
installChildProfile(int profileId)197     private UserInfo installChildProfile(int profileId) {
198         final UserInfo userInfo = new UserInfo(
199             profileId, null, null, UserInfo.FLAG_INITIALIZED | UserInfo.FLAG_MANAGED_PROFILE);
200         userInfo.profileGroupId = PRIMARY_USER_ID;
201         mPrimaryUserProfiles.add(userInfo);
202         when(mUserManager.getUserInfo(eq(profileId))).thenReturn(userInfo);
203         when(mUserManager.getProfileParent(eq(profileId))).thenReturn(PRIMARY_USER_INFO);
204         when(mUserManager.isUserRunning(eq(profileId))).thenReturn(true);
205         when(mUserManager.isUserUnlocked(eq(profileId))).thenReturn(true);
206         when(mUserManagerInternal.isUserManaged(eq(profileId))).thenReturn(true);
207         return userInfo;
208     }
209 
installAndTurnOffChildProfile(int profileId)210     private UserInfo installAndTurnOffChildProfile(int profileId) {
211         final UserInfo userInfo = installChildProfile(profileId);
212         userInfo.flags |= UserInfo.FLAG_QUIET_MODE;
213         when(mUserManager.isUserRunning(eq(profileId))).thenReturn(false);
214         when(mUserManager.isUserUnlocked(eq(profileId))).thenReturn(false);
215         return userInfo;
216     }
217 
setUpStorageManagerMock()218     private IStorageManager setUpStorageManagerMock() throws RemoteException {
219         final IStorageManager sm = mock(IStorageManager.class);
220 
221         doAnswer(new Answer<Void>() {
222             @Override
223             public Void answer(InvocationOnMock invocation) throws Throwable {
224                 Object[] args = invocation.getArguments();
225                 mStorageManager.addUserKeyAuth((int) args[0] /* userId */,
226                         (int) args[1] /* serialNumber */,
227                         (byte[]) args[2] /* token */,
228                         (byte[]) args[3] /* secret */);
229                 return null;
230             }
231         }).when(sm).addUserKeyAuth(anyInt(), anyInt(), any(), any());
232 
233         doAnswer(new Answer<Void>() {
234             @Override
235             public Void answer(InvocationOnMock invocation) throws Throwable {
236                 Object[] args = invocation.getArguments();
237                 mStorageManager.clearUserKeyAuth((int) args[0] /* userId */,
238                         (int) args[1] /* serialNumber */,
239                         (byte[]) args[2] /* token */,
240                         (byte[]) args[3] /* secret */);
241                 return null;
242             }
243         }).when(sm).clearUserKeyAuth(anyInt(), anyInt(), any(), any());
244 
245         doAnswer(
246                 new Answer<Void>() {
247             @Override
248             public Void answer(InvocationOnMock invocation) throws Throwable {
249                 Object[] args = invocation.getArguments();
250                 mStorageManager.fixateNewestUserKeyAuth((int) args[0] /* userId */);
251                 return null;
252             }
253         }).when(sm).fixateNewestUserKeyAuth(anyInt());
254         return sm;
255     }
256 
mockBiometricsHardwareFingerprintsAndTemplates(int userId)257     private void mockBiometricsHardwareFingerprintsAndTemplates(int userId) {
258         // Hardware must be detected and fingerprints must be enrolled
259         when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)).thenReturn(true);
260         when(mFingerprintManager.isHardwareDetected()).thenReturn(true);
261         when(mFingerprintManager.hasEnrolledFingerprints(userId)).thenReturn(true);
262         doAnswer(new Answer<Void>() {
263             @Override
264             public Void answer(InvocationOnMock invocation) throws Throwable {
265                 Fingerprint fp = (Fingerprint) invocation.getArguments()[0];
266                 FingerprintManager.RemovalCallback callback =
267                         (FingerprintManager.RemovalCallback) invocation.getArguments()[2];
268                 callback.onRemovalSucceeded(fp, 0);
269                 return null;
270             }
271         }).when(mFingerprintManager).remove(any(), eq(userId), any());
272 
273 
274         // Hardware must be detected and templates must be enrolled
275         when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_FACE)).thenReturn(true);
276         when(mFaceManager.isHardwareDetected()).thenReturn(true);
277         when(mFaceManager.hasEnrolledTemplates(userId)).thenReturn(true);
278         doAnswer(new Answer<Void>() {
279             @Override
280             public Void answer(InvocationOnMock invocation) throws Throwable {
281                 Face face = (Face) invocation.getArguments()[0];
282                 FaceManager.RemovalCallback callback =
283                         (FaceManager.RemovalCallback) invocation.getArguments()[2];
284                 callback.onRemovalSucceeded(face, 0);
285                 return null;
286             }
287         }).when(mFaceManager).remove(any(), eq(userId), any());
288     }
289 
290     @After
tearDown_baseServices()291     public void tearDown_baseServices() throws Exception {
292         mStorage.closeDatabase();
293         File db = InstrumentationRegistry.getContext().getDatabasePath("locksettings.db");
294         assertTrue(!db.exists() || db.delete());
295 
296         File storageDir = mStorage.mStorageDir;
297         assertTrue(FileUtils.deleteContents(storageDir));
298 
299         mPasswordSlotManager.cleanup();
300     }
301 
flushHandlerTasks()302     protected void flushHandlerTasks() {
303         mService.mHandler.runWithScissors(() -> { }, 0 /*now*/); // Flush runnables on handler
304     }
305 
assertNotEquals(long expected, long actual)306     protected void assertNotEquals(long expected, long actual) {
307         assertTrue(expected != actual);
308     }
309 
assertArrayEquals(byte[] expected, byte[] actual)310     protected static void assertArrayEquals(byte[] expected, byte[] actual) {
311         assertTrue(Arrays.equals(expected, actual));
312     }
313 
assertArrayNotEquals(byte[] expected, byte[] actual)314     protected static void assertArrayNotEquals(byte[] expected, byte[] actual) {
315         assertFalse(Arrays.equals(expected, actual));
316     }
317 
newPassword(String password)318     protected LockscreenCredential newPassword(String password) {
319         return LockscreenCredential.createPasswordOrNone(password);
320     }
321 
newPin(String pin)322     protected LockscreenCredential newPin(String pin) {
323         return LockscreenCredential.createPinOrNone(pin);
324     }
325 
newPattern(String pattern)326     protected LockscreenCredential newPattern(String pattern) {
327         return LockscreenCredential.createPattern(LockPatternUtils.byteArrayToPattern(
328                 pattern.getBytes()));
329     }
330 
nonePassword()331     protected LockscreenCredential nonePassword() {
332         return LockscreenCredential.createNone();
333     }
334 
335 }
336