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