1 /*
2  * Copyright (C) 2017 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.mockito.Mockito.mock;
20 
21 import android.app.IActivityManager;
22 import android.app.admin.DeviceStateCache;
23 import android.content.Context;
24 import android.content.Intent;
25 import android.content.pm.UserInfo;
26 import android.hardware.authsecret.IAuthSecret;
27 import android.os.Handler;
28 import android.os.Parcel;
29 import android.os.Process;
30 import android.os.RemoteException;
31 import android.os.UserHandle;
32 import android.os.storage.IStorageManager;
33 import android.security.keystore.KeyPermanentlyInvalidatedException;
34 import android.service.gatekeeper.IGateKeeperService;
35 
36 import com.android.internal.widget.LockscreenCredential;
37 import com.android.server.ServiceThread;
38 import com.android.server.locksettings.SyntheticPasswordManager.SyntheticPassword;
39 import com.android.server.locksettings.recoverablekeystore.RecoverableKeyStoreManager;
40 import com.android.server.pm.UserManagerInternal;
41 
42 import java.io.FileNotFoundException;
43 import java.security.KeyStore;
44 
45 public class LockSettingsServiceTestable extends LockSettingsService {
46     private Intent mSavedFrpNotificationIntent = null;
47     private UserHandle mSavedFrpNotificationUserHandle = null;
48     private String mSavedFrpNotificationPermission = null;
49 
50     public static class MockInjector extends LockSettingsService.Injector {
51 
52         private LockSettingsStorage mLockSettingsStorage;
53         private IActivityManager mActivityManager;
54         private IStorageManager mStorageManager;
55         private SyntheticPasswordManager mSpManager;
56         private FakeGsiService mGsiService;
57         private RecoverableKeyStoreManager mRecoverableKeyStoreManager;
58         private UserManagerInternal mUserManagerInternal;
59         private DeviceStateCache mDeviceStateCache;
60 
61         public boolean mIsHeadlessSystemUserMode = false;
62         public boolean mIsMainUserPermanentAdmin = false;
63 
MockInjector(Context context, LockSettingsStorage storage, IActivityManager activityManager, IStorageManager storageManager, SyntheticPasswordManager spManager, FakeGsiService gsiService, RecoverableKeyStoreManager recoverableKeyStoreManager, UserManagerInternal userManagerInternal, DeviceStateCache deviceStateCache)64         public MockInjector(Context context, LockSettingsStorage storage,
65                 IActivityManager activityManager, IStorageManager storageManager,
66                 SyntheticPasswordManager spManager, FakeGsiService gsiService,
67                 RecoverableKeyStoreManager recoverableKeyStoreManager,
68                 UserManagerInternal userManagerInternal, DeviceStateCache deviceStateCache) {
69             super(context);
70             mLockSettingsStorage = storage;
71             mActivityManager = activityManager;
72             mStorageManager = storageManager;
73             mSpManager = spManager;
74             mGsiService = gsiService;
75             mRecoverableKeyStoreManager = recoverableKeyStoreManager;
76             mUserManagerInternal = userManagerInternal;
77             mDeviceStateCache = deviceStateCache;
78         }
79 
80         @Override
getHandler(ServiceThread handlerThread)81         public Handler getHandler(ServiceThread handlerThread) {
82             return new Handler(handlerThread.getLooper());
83         }
84 
85         @Override
getStorage()86         public LockSettingsStorage getStorage() {
87             return mLockSettingsStorage;
88         }
89 
90         @Override
getStrongAuth()91         public LockSettingsStrongAuth getStrongAuth() {
92             return mock(LockSettingsStrongAuth.class);
93         }
94 
95         @Override
getStrongAuthTracker()96         public SynchronizedStrongAuthTracker getStrongAuthTracker() {
97             return mock(SynchronizedStrongAuthTracker.class);
98         }
99 
100         @Override
getActivityManager()101         public IActivityManager getActivityManager() {
102             return mActivityManager;
103         }
104 
105         @Override
getDeviceStateCache()106         public DeviceStateCache getDeviceStateCache() {
107             return mDeviceStateCache;
108         }
109 
110         @Override
getStorageManager()111         public IStorageManager getStorageManager() {
112             return mStorageManager;
113         }
114 
115         @Override
getSyntheticPasswordManager(LockSettingsStorage storage)116         public SyntheticPasswordManager getSyntheticPasswordManager(LockSettingsStorage storage) {
117             return mSpManager;
118         }
119 
120         @Override
getUserManagerInternal()121         public UserManagerInternal getUserManagerInternal() {
122             return mUserManagerInternal;
123         }
124 
125         @Override
binderGetCallingUid()126         public int binderGetCallingUid() {
127             return Process.SYSTEM_UID;
128         }
129 
130         @Override
isGsiRunning()131         public boolean isGsiRunning() {
132             return mGsiService.isGsiRunning();
133         }
134 
135         @Override
getRecoverableKeyStoreManager()136         public RecoverableKeyStoreManager getRecoverableKeyStoreManager() {
137             return mRecoverableKeyStoreManager;
138         }
139 
140         @Override
getUnifiedProfilePasswordCache(KeyStore ks)141         public UnifiedProfilePasswordCache getUnifiedProfilePasswordCache(KeyStore ks) {
142             return mock(UnifiedProfilePasswordCache.class);
143         }
144 
145         @Override
isHeadlessSystemUserMode()146         public boolean isHeadlessSystemUserMode() {
147             return mIsHeadlessSystemUserMode;
148         }
149 
150         @Override
isMainUserPermanentAdmin()151         public boolean isMainUserPermanentAdmin() {
152             return mIsMainUserPermanentAdmin;
153         }
154     }
155 
LockSettingsServiceTestable( LockSettingsService.Injector injector, IGateKeeperService gatekeeper, IAuthSecret authSecretService)156     protected LockSettingsServiceTestable(
157             LockSettingsService.Injector injector,
158             IGateKeeperService gatekeeper,
159             IAuthSecret authSecretService) {
160         super(injector);
161         mGateKeeperService = gatekeeper;
162         mAuthSecretService = authSecretService;
163     }
164 
165     @Override
tieProfileLockToParent(int profileUserId, int parentUserId, LockscreenCredential password)166     protected void tieProfileLockToParent(int profileUserId, int parentUserId,
167             LockscreenCredential password) {
168         Parcel parcel = Parcel.obtain();
169         parcel.writeParcelable(password, 0);
170         mStorage.writeChildProfileLock(profileUserId, parcel.marshall());
171         parcel.recycle();
172     }
173 
174     @Override
getDecryptedPasswordForTiedProfile(int userId)175     protected LockscreenCredential getDecryptedPasswordForTiedProfile(int userId)
176             throws FileNotFoundException, KeyPermanentlyInvalidatedException {
177         byte[] storedData = mStorage.readChildProfileLock(userId);
178         if (storedData == null) {
179             throw new FileNotFoundException("Child profile lock file not found");
180         }
181         try {
182             if (mGateKeeperService.getSecureUserId(userId) == 0) {
183                 throw new KeyPermanentlyInvalidatedException();
184             }
185         } catch (RemoteException e) {
186             // shouldn't happen.
187         }
188         Parcel parcel = Parcel.obtain();
189         try {
190             parcel.unmarshall(storedData, 0, storedData.length);
191             parcel.setDataPosition(0);
192             return (LockscreenCredential) parcel.readParcelable(null);
193         } finally {
194             parcel.recycle();
195         }
196     }
197 
198     @Override
setKeystorePassword(byte[] password, int userHandle)199     void setKeystorePassword(byte[] password, int userHandle) {
200 
201     }
202 
203     @Override
initKeystoreSuperKeys(int userId, SyntheticPassword sp, boolean allowExisting)204     void initKeystoreSuperKeys(int userId, SyntheticPassword sp, boolean allowExisting) {
205     }
206 
207     @Override
isCredentialSharableWithParent(int userId)208     protected boolean isCredentialSharableWithParent(int userId) {
209         UserInfo userInfo = mUserManager.getUserInfo(userId);
210         return userInfo.isCloneProfile() || userInfo.isManagedProfile();
211     }
212 
clearAuthSecret()213     void clearAuthSecret() {
214         synchronized (mHeadlessAuthSecretLock) {
215             mAuthSecret = null;
216         }
217     }
218 
219     @Override
sendBroadcast(Intent intent, UserHandle userHandle, String permission)220     void sendBroadcast(Intent intent, UserHandle userHandle, String permission) {
221         mSavedFrpNotificationIntent = intent;
222         mSavedFrpNotificationUserHandle = userHandle;
223         mSavedFrpNotificationPermission = permission;
224     }
225 
getSavedFrpNotificationPermission()226     String getSavedFrpNotificationPermission() {
227         return mSavedFrpNotificationPermission;
228     }
229 
getSavedFrpNotificationUserHandle()230     UserHandle getSavedFrpNotificationUserHandle() {
231         return mSavedFrpNotificationUserHandle;
232     }
233 
getSavedFrpNotificationIntent()234     Intent getSavedFrpNotificationIntent() {
235         return mSavedFrpNotificationIntent;
236     }
237 
clearRecordedFrpNotificationData()238     void clearRecordedFrpNotificationData() {
239         mSavedFrpNotificationIntent = null;
240         mSavedFrpNotificationPermission = null;
241         mSavedFrpNotificationUserHandle = null;
242     }
243 }
244