Loading core/java/com/android/internal/widget/ILockSettings.aidl +0 −7 Original line number Diff line number Diff line Loading @@ -54,13 +54,6 @@ interface ILockSettings { void userPresent(int userId); int getStrongAuthForUser(int userId); long addEscrowToken(in byte[] token, int userId); boolean removeEscrowToken(long handle, int userId); boolean isEscrowTokenActive(long handle, int userId); boolean setLockCredentialWithToken(String credential, int type, long tokenHandle, in byte[] token, int requestedQuality, int userId); void unlockUserWithToken(long tokenHandle, in byte[] token, int userId); // Keystore RecoveryController methods. // {@code ServiceSpecificException} may be thrown to signal an error, which caller can // convert to {@code RecoveryManagerException}. Loading core/java/com/android/internal/widget/LockPatternUtils.java +63 −58 Original line number Diff line number Diff line Loading @@ -45,6 +45,7 @@ import android.util.SparseIntArray; import android.util.SparseLongArray; import com.android.internal.annotations.VisibleForTesting; import com.android.server.LocalServices; import com.google.android.collect.Lists; import libcore.util.HexEncoding; Loading Loading @@ -1473,6 +1474,13 @@ public class LockPatternUtils { } } private LockSettingsInternal getLockSettingsInternal() { LockSettingsInternal service = LocalServices.getService(LockSettingsInternal.class); if (service == null) { throw new SecurityException("Only available to system server itself"); } return service; } /** * Create an escrow token for the current user, which can later be used to unlock FBE * or change user password. Loading @@ -1481,44 +1489,41 @@ public class LockPatternUtils { * confirm credential operation in order to activate the token for future use. If the user * has no secure lockscreen, then the token is activated immediately. * * <p>This method is only available to code running in the system server process itself. * * @return a unique 64-bit token handle which is needed to refer to this token later. */ public long addEscrowToken(byte[] token, int userId) { try { return getLockSettings().addEscrowToken(token, userId); } catch (RemoteException re) { return 0L; } return getLockSettingsInternal().addEscrowToken(token, userId); } /** * Remove an escrow token. * * <p>This method is only available to code running in the system server process itself. * * @return true if the given handle refers to a valid token previously returned from * {@link #addEscrowToken}, whether it's active or not. return false otherwise. */ public boolean removeEscrowToken(long handle, int userId) { try { return getLockSettings().removeEscrowToken(handle, userId); } catch (RemoteException re) { return false; } return getLockSettingsInternal().removeEscrowToken(handle, userId); } /** * Check if the given escrow token is active or not. Only active token can be used to call * {@link #setLockCredentialWithToken} and {@link #unlockUserWithToken} * * <p>This method is only available to code running in the system server process itself. */ public boolean isEscrowTokenActive(long handle, int userId) { try { return getLockSettings().isEscrowTokenActive(handle, userId); } catch (RemoteException re) { return false; } return getLockSettingsInternal().isEscrowTokenActive(handle, userId); } /** * Change a user's lock credential with a pre-configured escrow token. * * <p>This method is only available to code running in the system server process itself. * * @param credential The new credential to be set * @param type Credential type: password / pattern / none. * @param requestedQuality the requested password quality by DevicePolicyManager. Loading @@ -1530,14 +1535,14 @@ public class LockPatternUtils { */ public boolean setLockCredentialWithToken(String credential, int type, int requestedQuality, long tokenHandle, byte[] token, int userId) { try { LockSettingsInternal localService = getLockSettingsInternal(); if (type != CREDENTIAL_TYPE_NONE) { if (TextUtils.isEmpty(credential) || credential.length() < MIN_LOCK_PASSWORD_SIZE) { throw new IllegalArgumentException("password must not be null and at least " + "of length " + MIN_LOCK_PASSWORD_SIZE); } final int quality = computePasswordQuality(type, credential, requestedQuality); if (!getLockSettings().setLockCredentialWithToken(credential, type, tokenHandle, if (!localService.setLockCredentialWithToken(credential, type, tokenHandle, token, quality, userId)) { return false; } Loading @@ -1549,7 +1554,7 @@ public class LockPatternUtils { if (!TextUtils.isEmpty(credential)) { throw new IllegalArgumentException("password must be emtpy for NONE type"); } if (!getLockSettings().setLockCredentialWithToken(null, CREDENTIAL_TYPE_NONE, if (!localService.setLockCredentialWithToken(null, CREDENTIAL_TYPE_NONE, tokenHandle, token, DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, userId)) { return false; Loading @@ -1565,20 +1570,20 @@ public class LockPatternUtils { } onAfterChangingPassword(userId); return true; } catch (RemoteException re) { Log.e(TAG, "Unable to save lock password ", re); re.rethrowFromSystemServer(); } return false; } public void unlockUserWithToken(long tokenHandle, byte[] token, int userId) { try { getLockSettings().unlockUserWithToken(tokenHandle, token, userId); } catch (RemoteException re) { Log.e(TAG, "Unable to unlock user with token", re); re.rethrowFromSystemServer(); } /** * Unlock the specified user by an pre-activated escrow token. This should have the same effect * on device encryption as the user entering his lockscreen credentials for the first time after * boot, this includes unlocking the user's credential-encrypted storage as well as the keystore * * <p>This method is only available to code running in the system server process itself. * * @return {@code true} if the supplied token is valid and unlock succeeds, * {@code false} otherwise. */ public boolean unlockUserWithToken(long tokenHandle, byte[] token, int userId) { return getLockSettingsInternal().unlockUserWithToken(tokenHandle, token, userId); } Loading core/java/com/android/internal/widget/LockSettingsInternal.java 0 → 100644 +56 −0 Original line number Diff line number Diff line /* * Copyright (C) 2018 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.internal.widget; /** * LockSettingsService local system service interface. * * @hide Only for use within the system server. */ public abstract class LockSettingsInternal { /** * Create an escrow token for the current user, which can later be used to unlock FBE * or change user password. * * After adding, if the user currently has lockscreen password, he will need to perform a * confirm credential operation in order to activate the token for future use. If the user * has no secure lockscreen, then the token is activated immediately. * * @return a unique 64-bit token handle which is needed to refer to this token later. */ public abstract long addEscrowToken(byte[] token, int userId); /** * Remove an escrow token. * @return true if the given handle refers to a valid token previously returned from * {@link #addEscrowToken}, whether it's active or not. return false otherwise. */ public abstract boolean removeEscrowToken(long handle, int userId); /** * Check if the given escrow token is active or not. Only active token can be used to call * {@link #setLockCredentialWithToken} and {@link #unlockUserWithToken} */ public abstract boolean isEscrowTokenActive(long handle, int userId); public abstract boolean setLockCredentialWithToken(String credential, int type, long tokenHandle, byte[] token, int requestedQuality, int userId); public abstract boolean unlockUserWithToken(long tokenHandle, byte[] token, int userId); } services/core/java/com/android/server/locksettings/LockSettingsService.java +60 −37 Original line number Diff line number Diff line Loading @@ -102,6 +102,7 @@ import com.android.internal.util.Preconditions; import com.android.internal.widget.ICheckCredentialProgressCallback; import com.android.internal.widget.ILockSettings; import com.android.internal.widget.LockPatternUtils; import com.android.internal.widget.LockSettingsInternal; import com.android.internal.widget.VerifyCredentialResponse; import com.android.server.LocalServices; import com.android.server.SystemService; Loading Loading @@ -436,6 +437,8 @@ public class LockSettingsService extends ILockSettings.Stub { mStrongAuthTracker.register(mStrongAuth); mSpManager = injector.getSyntheticPasswordManager(mStorage); LocalServices.addService(LockSettingsInternal.class, new LocalService()); } /** Loading Loading @@ -1041,15 +1044,11 @@ public class LockSettingsService extends ILockSettings.Stub { private boolean isUserSecure(int userId) { synchronized (mSpManager) { try { if (isSyntheticPasswordBasedCredentialLocked(userId)) { long handle = getSyntheticPasswordHandleLocked(userId); return mSpManager.getCredentialType(handle, userId) != LockPatternUtils.CREDENTIAL_TYPE_NONE; } } catch (RemoteException e) { // fall through } } return mStorage.hasCredential(userId); } Loading Loading @@ -2305,7 +2304,7 @@ public class LockSettingsService extends ILockSettings.Stub { SyntheticPasswordManager.DEFAULT_HANDLE, userId); } private boolean isSyntheticPasswordBasedCredentialLocked(int userId) throws RemoteException { private boolean isSyntheticPasswordBasedCredentialLocked(int userId) { if (userId == USER_FRP) { final int type = mStorage.readPersistentDataBlock().type; return type == PersistentData.TYPE_SP || type == PersistentData.TYPE_SP_WEAVER; Loading @@ -2318,7 +2317,7 @@ public class LockSettingsService extends ILockSettings.Stub { } @VisibleForTesting protected boolean shouldMigrateToSyntheticPasswordLocked(int userId) throws RemoteException { protected boolean shouldMigrateToSyntheticPasswordLocked(int userId) { long handle = getSyntheticPasswordHandleLocked(userId); // This is a global setting long enabled = getLong(SYNTHETIC_PASSWORD_ENABLED_KEY, Loading @@ -2326,7 +2325,7 @@ public class LockSettingsService extends ILockSettings.Stub { return enabled != 0 && handle == SyntheticPasswordManager.DEFAULT_HANDLE; } private void enableSyntheticPasswordLocked() throws RemoteException { private void enableSyntheticPasswordLocked() { setLong(SYNTHETIC_PASSWORD_ENABLED_KEY, 1, UserHandle.USER_SYSTEM); } Loading Loading @@ -2525,9 +2524,7 @@ public class LockSettingsService extends ILockSettings.Stub { mRecoverableKeyStoreManager.lockScreenSecretChanged(credentialType, credential, userId); } @Override public long addEscrowToken(byte[] token, int userId) throws RemoteException { ensureCallerSystemUid(); private long addEscrowToken(byte[] token, int userId) throws RemoteException { if (DEBUG) Slog.d(TAG, "addEscrowToken: user=" + userId); synchronized (mSpManager) { enableSyntheticPasswordLocked(); Loading Loading @@ -2559,7 +2556,7 @@ public class LockSettingsService extends ILockSettings.Stub { } } private void activateEscrowTokens(AuthenticationToken auth, int userId) throws RemoteException { private void activateEscrowTokens(AuthenticationToken auth, int userId) { if (DEBUG) Slog.d(TAG, "activateEscrowTokens: user=" + userId); synchronized (mSpManager) { disableEscrowTokenOnNonManagedDevicesIfNeeded(userId); Loading @@ -2570,17 +2567,13 @@ public class LockSettingsService extends ILockSettings.Stub { } } @Override public boolean isEscrowTokenActive(long handle, int userId) throws RemoteException { ensureCallerSystemUid(); private boolean isEscrowTokenActive(long handle, int userId) { synchronized (mSpManager) { return mSpManager.existsHandle(handle, userId); } } @Override public boolean removeEscrowToken(long handle, int userId) throws RemoteException { ensureCallerSystemUid(); private boolean removeEscrowToken(long handle, int userId) { synchronized (mSpManager) { if (handle == getSyntheticPasswordHandleLocked(userId)) { Slog.w(TAG, "Cannot remove password handle"); Loading @@ -2598,10 +2591,8 @@ public class LockSettingsService extends ILockSettings.Stub { } } @Override public boolean setLockCredentialWithToken(String credential, int type, long tokenHandle, private boolean setLockCredentialWithToken(String credential, int type, long tokenHandle, byte[] token, int requestedQuality, int userId) throws RemoteException { ensureCallerSystemUid(); boolean result; synchronized (mSpManager) { if (!mSpManager.hasEscrowData(userId)) { Loading Loading @@ -2650,10 +2641,8 @@ public class LockSettingsService extends ILockSettings.Stub { return true; } @Override public void unlockUserWithToken(long tokenHandle, byte[] token, int userId) private boolean unlockUserWithToken(long tokenHandle, byte[] token, int userId) throws RemoteException { ensureCallerSystemUid(); AuthenticationResult authResult; synchronized (mSpManager) { if (!mSpManager.hasEscrowData(userId)) { Loading @@ -2663,11 +2652,12 @@ public class LockSettingsService extends ILockSettings.Stub { tokenHandle, token, userId); if (authResult.authToken == null) { Slog.w(TAG, "Invalid escrow token supplied"); return; return false; } } unlockUser(userId, null, authResult.authToken.deriveDiskEncryptionKey()); onAuthTokenKnownForUser(userId, authResult.authToken); return true; } @Override Loading Loading @@ -2732,20 +2722,11 @@ public class LockSettingsService extends ILockSettings.Stub { if (isSyntheticPasswordBasedCredentialLocked(userId)) { mSpManager.destroyEscrowData(userId); } } catch (RemoteException e) { Slog.e(TAG, "disableEscrowTokenOnNonManagedDevices", e); } finally { Binder.restoreCallingIdentity(ident); } } private void ensureCallerSystemUid() throws SecurityException { final int callingUid = mInjector.binderGetCallingUid(); if (callingUid != Process.SYSTEM_UID) { throw new SecurityException("Only system can call this API."); } } private class DeviceProvisionedObserver extends ContentObserver { private final Uri mDeviceProvisionedUri = Settings.Global.getUriFor( Settings.Global.DEVICE_PROVISIONED); Loading Loading @@ -2834,4 +2815,46 @@ public class LockSettingsService extends ILockSettings.Stub { Settings.Global.DEVICE_PROVISIONED, 0) != 0; } } private final class LocalService extends LockSettingsInternal { @Override public long addEscrowToken(byte[] token, int userId) { try { return LockSettingsService.this.addEscrowToken(token, userId); } catch (RemoteException re) { throw re.rethrowFromSystemServer(); } } @Override public boolean removeEscrowToken(long handle, int userId) { return LockSettingsService.this.removeEscrowToken(handle, userId); } @Override public boolean isEscrowTokenActive(long handle, int userId) { return LockSettingsService.this.isEscrowTokenActive(handle, userId); } @Override public boolean setLockCredentialWithToken(String credential, int type, long tokenHandle, byte[] token, int requestedQuality, int userId) { try { return LockSettingsService.this.setLockCredentialWithToken(credential, type, tokenHandle, token, requestedQuality, userId); } catch (RemoteException re) { throw re.rethrowFromSystemServer(); } } @Override public boolean unlockUserWithToken(long tokenHandle, byte[] token, int userId) { try { return LockSettingsService.this.unlockUserWithToken(tokenHandle, token, userId); } catch (RemoteException re) { throw re.rethrowFromSystemServer(); } } } } services/tests/servicestests/src/com/android/server/locksettings/BaseLockSettingsServiceTests.java +4 −0 Original line number Diff line number Diff line Loading @@ -43,6 +43,7 @@ import android.test.AndroidTestCase; import com.android.internal.widget.ILockSettings; import com.android.internal.widget.LockPatternUtils; import com.android.internal.widget.LockSettingsInternal; import com.android.server.LocalServices; import org.mockito.invocation.InvocationOnMock; Loading @@ -67,6 +68,7 @@ public class BaseLockSettingsServiceTests extends AndroidTestCase { private ArrayList<UserInfo> mPrimaryUserProfiles = new ArrayList<>(); LockSettingsService mService; LockSettingsInternal mLocalService; MockLockSettingsContext mContext; LockSettingsStorageTestable mStorage; Loading Loading @@ -95,6 +97,7 @@ public class BaseLockSettingsServiceTests extends AndroidTestCase { mDevicePolicyManager = mock(DevicePolicyManager.class); mDevicePolicyManagerInternal = mock(DevicePolicyManagerInternal.class); LocalServices.removeServiceForTest(LockSettingsInternal.class); LocalServices.removeServiceForTest(DevicePolicyManagerInternal.class); LocalServices.addService(DevicePolicyManagerInternal.class, mDevicePolicyManagerInternal); Loading Loading @@ -146,6 +149,7 @@ public class BaseLockSettingsServiceTests extends AndroidTestCase { // Adding a fake Device Owner app which will enable escrow token support in LSS. when(mDevicePolicyManager.getDeviceOwnerComponentOnAnyUser()).thenReturn( new ComponentName("com.dummy.package", ".FakeDeviceOwner")); mLocalService = LocalServices.getService(LockSettingsInternal.class); } private UserInfo installChildProfile(int profileId) { Loading Loading
core/java/com/android/internal/widget/ILockSettings.aidl +0 −7 Original line number Diff line number Diff line Loading @@ -54,13 +54,6 @@ interface ILockSettings { void userPresent(int userId); int getStrongAuthForUser(int userId); long addEscrowToken(in byte[] token, int userId); boolean removeEscrowToken(long handle, int userId); boolean isEscrowTokenActive(long handle, int userId); boolean setLockCredentialWithToken(String credential, int type, long tokenHandle, in byte[] token, int requestedQuality, int userId); void unlockUserWithToken(long tokenHandle, in byte[] token, int userId); // Keystore RecoveryController methods. // {@code ServiceSpecificException} may be thrown to signal an error, which caller can // convert to {@code RecoveryManagerException}. Loading
core/java/com/android/internal/widget/LockPatternUtils.java +63 −58 Original line number Diff line number Diff line Loading @@ -45,6 +45,7 @@ import android.util.SparseIntArray; import android.util.SparseLongArray; import com.android.internal.annotations.VisibleForTesting; import com.android.server.LocalServices; import com.google.android.collect.Lists; import libcore.util.HexEncoding; Loading Loading @@ -1473,6 +1474,13 @@ public class LockPatternUtils { } } private LockSettingsInternal getLockSettingsInternal() { LockSettingsInternal service = LocalServices.getService(LockSettingsInternal.class); if (service == null) { throw new SecurityException("Only available to system server itself"); } return service; } /** * Create an escrow token for the current user, which can later be used to unlock FBE * or change user password. Loading @@ -1481,44 +1489,41 @@ public class LockPatternUtils { * confirm credential operation in order to activate the token for future use. If the user * has no secure lockscreen, then the token is activated immediately. * * <p>This method is only available to code running in the system server process itself. * * @return a unique 64-bit token handle which is needed to refer to this token later. */ public long addEscrowToken(byte[] token, int userId) { try { return getLockSettings().addEscrowToken(token, userId); } catch (RemoteException re) { return 0L; } return getLockSettingsInternal().addEscrowToken(token, userId); } /** * Remove an escrow token. * * <p>This method is only available to code running in the system server process itself. * * @return true if the given handle refers to a valid token previously returned from * {@link #addEscrowToken}, whether it's active or not. return false otherwise. */ public boolean removeEscrowToken(long handle, int userId) { try { return getLockSettings().removeEscrowToken(handle, userId); } catch (RemoteException re) { return false; } return getLockSettingsInternal().removeEscrowToken(handle, userId); } /** * Check if the given escrow token is active or not. Only active token can be used to call * {@link #setLockCredentialWithToken} and {@link #unlockUserWithToken} * * <p>This method is only available to code running in the system server process itself. */ public boolean isEscrowTokenActive(long handle, int userId) { try { return getLockSettings().isEscrowTokenActive(handle, userId); } catch (RemoteException re) { return false; } return getLockSettingsInternal().isEscrowTokenActive(handle, userId); } /** * Change a user's lock credential with a pre-configured escrow token. * * <p>This method is only available to code running in the system server process itself. * * @param credential The new credential to be set * @param type Credential type: password / pattern / none. * @param requestedQuality the requested password quality by DevicePolicyManager. Loading @@ -1530,14 +1535,14 @@ public class LockPatternUtils { */ public boolean setLockCredentialWithToken(String credential, int type, int requestedQuality, long tokenHandle, byte[] token, int userId) { try { LockSettingsInternal localService = getLockSettingsInternal(); if (type != CREDENTIAL_TYPE_NONE) { if (TextUtils.isEmpty(credential) || credential.length() < MIN_LOCK_PASSWORD_SIZE) { throw new IllegalArgumentException("password must not be null and at least " + "of length " + MIN_LOCK_PASSWORD_SIZE); } final int quality = computePasswordQuality(type, credential, requestedQuality); if (!getLockSettings().setLockCredentialWithToken(credential, type, tokenHandle, if (!localService.setLockCredentialWithToken(credential, type, tokenHandle, token, quality, userId)) { return false; } Loading @@ -1549,7 +1554,7 @@ public class LockPatternUtils { if (!TextUtils.isEmpty(credential)) { throw new IllegalArgumentException("password must be emtpy for NONE type"); } if (!getLockSettings().setLockCredentialWithToken(null, CREDENTIAL_TYPE_NONE, if (!localService.setLockCredentialWithToken(null, CREDENTIAL_TYPE_NONE, tokenHandle, token, DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, userId)) { return false; Loading @@ -1565,20 +1570,20 @@ public class LockPatternUtils { } onAfterChangingPassword(userId); return true; } catch (RemoteException re) { Log.e(TAG, "Unable to save lock password ", re); re.rethrowFromSystemServer(); } return false; } public void unlockUserWithToken(long tokenHandle, byte[] token, int userId) { try { getLockSettings().unlockUserWithToken(tokenHandle, token, userId); } catch (RemoteException re) { Log.e(TAG, "Unable to unlock user with token", re); re.rethrowFromSystemServer(); } /** * Unlock the specified user by an pre-activated escrow token. This should have the same effect * on device encryption as the user entering his lockscreen credentials for the first time after * boot, this includes unlocking the user's credential-encrypted storage as well as the keystore * * <p>This method is only available to code running in the system server process itself. * * @return {@code true} if the supplied token is valid and unlock succeeds, * {@code false} otherwise. */ public boolean unlockUserWithToken(long tokenHandle, byte[] token, int userId) { return getLockSettingsInternal().unlockUserWithToken(tokenHandle, token, userId); } Loading
core/java/com/android/internal/widget/LockSettingsInternal.java 0 → 100644 +56 −0 Original line number Diff line number Diff line /* * Copyright (C) 2018 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.internal.widget; /** * LockSettingsService local system service interface. * * @hide Only for use within the system server. */ public abstract class LockSettingsInternal { /** * Create an escrow token for the current user, which can later be used to unlock FBE * or change user password. * * After adding, if the user currently has lockscreen password, he will need to perform a * confirm credential operation in order to activate the token for future use. If the user * has no secure lockscreen, then the token is activated immediately. * * @return a unique 64-bit token handle which is needed to refer to this token later. */ public abstract long addEscrowToken(byte[] token, int userId); /** * Remove an escrow token. * @return true if the given handle refers to a valid token previously returned from * {@link #addEscrowToken}, whether it's active or not. return false otherwise. */ public abstract boolean removeEscrowToken(long handle, int userId); /** * Check if the given escrow token is active or not. Only active token can be used to call * {@link #setLockCredentialWithToken} and {@link #unlockUserWithToken} */ public abstract boolean isEscrowTokenActive(long handle, int userId); public abstract boolean setLockCredentialWithToken(String credential, int type, long tokenHandle, byte[] token, int requestedQuality, int userId); public abstract boolean unlockUserWithToken(long tokenHandle, byte[] token, int userId); }
services/core/java/com/android/server/locksettings/LockSettingsService.java +60 −37 Original line number Diff line number Diff line Loading @@ -102,6 +102,7 @@ import com.android.internal.util.Preconditions; import com.android.internal.widget.ICheckCredentialProgressCallback; import com.android.internal.widget.ILockSettings; import com.android.internal.widget.LockPatternUtils; import com.android.internal.widget.LockSettingsInternal; import com.android.internal.widget.VerifyCredentialResponse; import com.android.server.LocalServices; import com.android.server.SystemService; Loading Loading @@ -436,6 +437,8 @@ public class LockSettingsService extends ILockSettings.Stub { mStrongAuthTracker.register(mStrongAuth); mSpManager = injector.getSyntheticPasswordManager(mStorage); LocalServices.addService(LockSettingsInternal.class, new LocalService()); } /** Loading Loading @@ -1041,15 +1044,11 @@ public class LockSettingsService extends ILockSettings.Stub { private boolean isUserSecure(int userId) { synchronized (mSpManager) { try { if (isSyntheticPasswordBasedCredentialLocked(userId)) { long handle = getSyntheticPasswordHandleLocked(userId); return mSpManager.getCredentialType(handle, userId) != LockPatternUtils.CREDENTIAL_TYPE_NONE; } } catch (RemoteException e) { // fall through } } return mStorage.hasCredential(userId); } Loading Loading @@ -2305,7 +2304,7 @@ public class LockSettingsService extends ILockSettings.Stub { SyntheticPasswordManager.DEFAULT_HANDLE, userId); } private boolean isSyntheticPasswordBasedCredentialLocked(int userId) throws RemoteException { private boolean isSyntheticPasswordBasedCredentialLocked(int userId) { if (userId == USER_FRP) { final int type = mStorage.readPersistentDataBlock().type; return type == PersistentData.TYPE_SP || type == PersistentData.TYPE_SP_WEAVER; Loading @@ -2318,7 +2317,7 @@ public class LockSettingsService extends ILockSettings.Stub { } @VisibleForTesting protected boolean shouldMigrateToSyntheticPasswordLocked(int userId) throws RemoteException { protected boolean shouldMigrateToSyntheticPasswordLocked(int userId) { long handle = getSyntheticPasswordHandleLocked(userId); // This is a global setting long enabled = getLong(SYNTHETIC_PASSWORD_ENABLED_KEY, Loading @@ -2326,7 +2325,7 @@ public class LockSettingsService extends ILockSettings.Stub { return enabled != 0 && handle == SyntheticPasswordManager.DEFAULT_HANDLE; } private void enableSyntheticPasswordLocked() throws RemoteException { private void enableSyntheticPasswordLocked() { setLong(SYNTHETIC_PASSWORD_ENABLED_KEY, 1, UserHandle.USER_SYSTEM); } Loading Loading @@ -2525,9 +2524,7 @@ public class LockSettingsService extends ILockSettings.Stub { mRecoverableKeyStoreManager.lockScreenSecretChanged(credentialType, credential, userId); } @Override public long addEscrowToken(byte[] token, int userId) throws RemoteException { ensureCallerSystemUid(); private long addEscrowToken(byte[] token, int userId) throws RemoteException { if (DEBUG) Slog.d(TAG, "addEscrowToken: user=" + userId); synchronized (mSpManager) { enableSyntheticPasswordLocked(); Loading Loading @@ -2559,7 +2556,7 @@ public class LockSettingsService extends ILockSettings.Stub { } } private void activateEscrowTokens(AuthenticationToken auth, int userId) throws RemoteException { private void activateEscrowTokens(AuthenticationToken auth, int userId) { if (DEBUG) Slog.d(TAG, "activateEscrowTokens: user=" + userId); synchronized (mSpManager) { disableEscrowTokenOnNonManagedDevicesIfNeeded(userId); Loading @@ -2570,17 +2567,13 @@ public class LockSettingsService extends ILockSettings.Stub { } } @Override public boolean isEscrowTokenActive(long handle, int userId) throws RemoteException { ensureCallerSystemUid(); private boolean isEscrowTokenActive(long handle, int userId) { synchronized (mSpManager) { return mSpManager.existsHandle(handle, userId); } } @Override public boolean removeEscrowToken(long handle, int userId) throws RemoteException { ensureCallerSystemUid(); private boolean removeEscrowToken(long handle, int userId) { synchronized (mSpManager) { if (handle == getSyntheticPasswordHandleLocked(userId)) { Slog.w(TAG, "Cannot remove password handle"); Loading @@ -2598,10 +2591,8 @@ public class LockSettingsService extends ILockSettings.Stub { } } @Override public boolean setLockCredentialWithToken(String credential, int type, long tokenHandle, private boolean setLockCredentialWithToken(String credential, int type, long tokenHandle, byte[] token, int requestedQuality, int userId) throws RemoteException { ensureCallerSystemUid(); boolean result; synchronized (mSpManager) { if (!mSpManager.hasEscrowData(userId)) { Loading Loading @@ -2650,10 +2641,8 @@ public class LockSettingsService extends ILockSettings.Stub { return true; } @Override public void unlockUserWithToken(long tokenHandle, byte[] token, int userId) private boolean unlockUserWithToken(long tokenHandle, byte[] token, int userId) throws RemoteException { ensureCallerSystemUid(); AuthenticationResult authResult; synchronized (mSpManager) { if (!mSpManager.hasEscrowData(userId)) { Loading @@ -2663,11 +2652,12 @@ public class LockSettingsService extends ILockSettings.Stub { tokenHandle, token, userId); if (authResult.authToken == null) { Slog.w(TAG, "Invalid escrow token supplied"); return; return false; } } unlockUser(userId, null, authResult.authToken.deriveDiskEncryptionKey()); onAuthTokenKnownForUser(userId, authResult.authToken); return true; } @Override Loading Loading @@ -2732,20 +2722,11 @@ public class LockSettingsService extends ILockSettings.Stub { if (isSyntheticPasswordBasedCredentialLocked(userId)) { mSpManager.destroyEscrowData(userId); } } catch (RemoteException e) { Slog.e(TAG, "disableEscrowTokenOnNonManagedDevices", e); } finally { Binder.restoreCallingIdentity(ident); } } private void ensureCallerSystemUid() throws SecurityException { final int callingUid = mInjector.binderGetCallingUid(); if (callingUid != Process.SYSTEM_UID) { throw new SecurityException("Only system can call this API."); } } private class DeviceProvisionedObserver extends ContentObserver { private final Uri mDeviceProvisionedUri = Settings.Global.getUriFor( Settings.Global.DEVICE_PROVISIONED); Loading Loading @@ -2834,4 +2815,46 @@ public class LockSettingsService extends ILockSettings.Stub { Settings.Global.DEVICE_PROVISIONED, 0) != 0; } } private final class LocalService extends LockSettingsInternal { @Override public long addEscrowToken(byte[] token, int userId) { try { return LockSettingsService.this.addEscrowToken(token, userId); } catch (RemoteException re) { throw re.rethrowFromSystemServer(); } } @Override public boolean removeEscrowToken(long handle, int userId) { return LockSettingsService.this.removeEscrowToken(handle, userId); } @Override public boolean isEscrowTokenActive(long handle, int userId) { return LockSettingsService.this.isEscrowTokenActive(handle, userId); } @Override public boolean setLockCredentialWithToken(String credential, int type, long tokenHandle, byte[] token, int requestedQuality, int userId) { try { return LockSettingsService.this.setLockCredentialWithToken(credential, type, tokenHandle, token, requestedQuality, userId); } catch (RemoteException re) { throw re.rethrowFromSystemServer(); } } @Override public boolean unlockUserWithToken(long tokenHandle, byte[] token, int userId) { try { return LockSettingsService.this.unlockUserWithToken(tokenHandle, token, userId); } catch (RemoteException re) { throw re.rethrowFromSystemServer(); } } } }
services/tests/servicestests/src/com/android/server/locksettings/BaseLockSettingsServiceTests.java +4 −0 Original line number Diff line number Diff line Loading @@ -43,6 +43,7 @@ import android.test.AndroidTestCase; import com.android.internal.widget.ILockSettings; import com.android.internal.widget.LockPatternUtils; import com.android.internal.widget.LockSettingsInternal; import com.android.server.LocalServices; import org.mockito.invocation.InvocationOnMock; Loading @@ -67,6 +68,7 @@ public class BaseLockSettingsServiceTests extends AndroidTestCase { private ArrayList<UserInfo> mPrimaryUserProfiles = new ArrayList<>(); LockSettingsService mService; LockSettingsInternal mLocalService; MockLockSettingsContext mContext; LockSettingsStorageTestable mStorage; Loading Loading @@ -95,6 +97,7 @@ public class BaseLockSettingsServiceTests extends AndroidTestCase { mDevicePolicyManager = mock(DevicePolicyManager.class); mDevicePolicyManagerInternal = mock(DevicePolicyManagerInternal.class); LocalServices.removeServiceForTest(LockSettingsInternal.class); LocalServices.removeServiceForTest(DevicePolicyManagerInternal.class); LocalServices.addService(DevicePolicyManagerInternal.class, mDevicePolicyManagerInternal); Loading Loading @@ -146,6 +149,7 @@ public class BaseLockSettingsServiceTests extends AndroidTestCase { // Adding a fake Device Owner app which will enable escrow token support in LSS. when(mDevicePolicyManager.getDeviceOwnerComponentOnAnyUser()).thenReturn( new ComponentName("com.dummy.package", ".FakeDeviceOwner")); mLocalService = LocalServices.getService(LockSettingsInternal.class); } private UserInfo installChildProfile(int profileId) { Loading