Loading services/core/java/com/android/server/LockSettingsService.java +20 −9 Original line number Diff line number Diff line Loading @@ -146,6 +146,7 @@ public class LockSettingsService extends ILockSettings.Stub { private final LockPatternUtils mLockPatternUtils; private final NotificationManager mNotificationManager; private final UserManager mUserManager; private final DevicePolicyManager mDevicePolicyManager; private final IActivityManager mActivityManager; private final KeyStore mKeyStore; Loading Loading @@ -333,6 +334,10 @@ public class LockSettingsService extends ILockSettings.Stub { return (UserManager) mContext.getSystemService(Context.USER_SERVICE); } public DevicePolicyManager getDevicePolicyManager() { return (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); } public KeyStore getKeyStore() { return KeyStore.getInstance(); } Loading Loading @@ -380,6 +385,7 @@ public class LockSettingsService extends ILockSettings.Stub { mStorage = injector.getStorage(); mNotificationManager = injector.getNotificationManager(); mUserManager = injector.getUserManager(); mDevicePolicyManager = injector.getDevicePolicyManager(); mStrongAuthTracker = injector.getStrongAuthTracker(); mStrongAuthTracker.register(mStrongAuth); Loading Loading @@ -2015,14 +2021,17 @@ public class LockSettingsService extends ILockSettings.Stub { } } long handle = getSyntheticPasswordHandleLocked(userId); AuthenticationToken auth = mSpManager.unwrapPasswordBasedSyntheticPassword( getGateKeeperService(), handle, savedCredential, userId).authToken; AuthenticationResult authResult = mSpManager.unwrapPasswordBasedSyntheticPassword( getGateKeeperService(), handle, savedCredential, userId); VerifyCredentialResponse response = authResult.gkResponse; AuthenticationToken auth = authResult.authToken; if (auth != null) { // We are performing a trusted credential change i.e. a correct existing credential // is provided setLockCredentialWithAuthTokenLocked(credential, credentialType, auth, userId); mSpManager.destroyPasswordBasedSyntheticPassword(handle, userId); } else { } else if (response != null && response.getResponseCode() == VerifyCredentialResponse.RESPONSE_ERROR){ // We are performing an untrusted credential change i.e. by DevicePolicyManager. // So provision a new SP and SID. This would invalidate existing escrow tokens. // Still support this for now but this flow will be removed in the next release. Loading @@ -2031,6 +2040,10 @@ public class LockSettingsService extends ILockSettings.Stub { initializeSyntheticPasswordLocked(null, credential, credentialType, userId); synchronizeUnifiedWorkChallengeForProfiles(userId, null); mSpManager.destroyPasswordBasedSyntheticPassword(handle, userId); } else /* response == null || responseCode == VerifyCredentialResponse.RESPONSE_RETRY */ { Slog.w(TAG, "spBasedSetLockCredentialInternalLocked: " + (response != null ? "rate limit exceeded" : "failed")); return; } notifyActivePasswordMetricsAvailable(credential, userId); Loading @@ -2042,7 +2055,7 @@ public class LockSettingsService extends ILockSettings.Stub { if (DEBUG) Slog.d(TAG, "addEscrowToken: user=" + userId); synchronized (mSpManager) { enableSyntheticPasswordLocked(); // Migrate to synthetic password based credentials if ther user has no password, // Migrate to synthetic password based credentials if the user has no password, // the token can then be activated immediately. AuthenticationToken auth = null; if (!isUserSecure(userId)) { Loading Loading @@ -2201,22 +2214,20 @@ public class LockSettingsService extends ILockSettings.Stub { Slog.i(TAG, "Managed profile can have escrow token"); return; } DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); // Devices with Device Owner should have escrow enabled on all users. if (dpm.getDeviceOwnerComponentOnAnyUser() != null) { if (mDevicePolicyManager.getDeviceOwnerComponentOnAnyUser() != null) { Slog.i(TAG, "Corp-owned device can have escrow token"); return; } // We could also have a profile owner on the given (non-managed) user for unicorn cases if (dpm.getProfileOwnerAsUser(userId) != null) { if (mDevicePolicyManager.getProfileOwnerAsUser(userId) != null) { Slog.i(TAG, "User with profile owner can have escrow token"); return; } // If the device is yet to be provisioned (still in SUW), there is still // a chance that Device Owner will be set on the device later, so postpone // disabling escrow token for now. if (!dpm.isDeviceProvisioned()) { if (!mDevicePolicyManager.isDeviceProvisioned()) { Slog.i(TAG, "Postpone disabling escrow tokens until device is provisioned"); return; } Loading services/core/java/com/android/server/SyntheticPasswordManager.java +1 −1 Original line number Diff line number Diff line Loading @@ -526,7 +526,7 @@ public class SyntheticPasswordManager { * RESPONSE_OK, since user authentication failures are detected earlier when trying to * decrypt SP. */ public VerifyCredentialResponse verifyChallenge(IGateKeeperService gatekeeper, public @Nullable VerifyCredentialResponse verifyChallenge(IGateKeeperService gatekeeper, @NonNull AuthenticationToken auth, long challenge, int userId) throws RemoteException { byte[] spHandle = loadSyntheticPasswordHandle(userId); if (spHandle == null) { Loading services/tests/servicestests/src/com/android/server/BaseLockSettingsServiceTests.java +10 −2 Original line number Diff line number Diff line Loading @@ -25,6 +25,8 @@ import static org.mockito.Mockito.when; import android.app.IActivityManager; import android.app.NotificationManager; import android.app.admin.DevicePolicyManager; import android.content.ComponentName; import android.content.Context; import android.content.pm.UserInfo; import android.database.sqlite.SQLiteDatabase; Loading Loading @@ -76,7 +78,7 @@ public class BaseLockSettingsServiceTests extends AndroidTestCase { UserManager mUserManager; MockStorageManager mStorageManager; IActivityManager mActivityManager; DevicePolicyManager mDevicePolicyManager; KeyStore mKeyStore; @Override Loading @@ -89,7 +91,9 @@ public class BaseLockSettingsServiceTests extends AndroidTestCase { mUserManager = mock(UserManager.class); mStorageManager = new MockStorageManager(); mActivityManager = mock(IActivityManager.class); mContext = new MockLockSettingsContext(getContext(), mUserManager, mNotificationManager); mDevicePolicyManager = mock(DevicePolicyManager.class); mContext = new MockLockSettingsContext(getContext(), mUserManager, mNotificationManager, mDevicePolicyManager); mStorage = new LockSettingsStorageTestable(mContext, new File(getContext().getFilesDir(), "locksettings")); File storageDir = mStorage.mStorageDir; Loading Loading @@ -122,6 +126,10 @@ public class BaseLockSettingsServiceTests extends AndroidTestCase { }); when(mLockPatternUtils.getLockSettings()).thenReturn(mService); // Adding a fake Device Owner app which will enable escrow token support in LSS. when(mDevicePolicyManager.getDeviceOwnerComponentOnAnyUser()).thenReturn( new ComponentName("com.dummy.package", ".FakeDeviceOwner")); } @Override Loading services/tests/servicestests/src/com/android/server/LockSettingsStorageTests.java +2 −1 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import android.app.NotificationManager; import android.app.admin.DevicePolicyManager; import android.content.Context; import android.content.ContextWrapper; import android.content.pm.UserInfo; Loading Loading @@ -68,7 +69,7 @@ public class LockSettingsStorageTests extends AndroidTestCase { when(mockUserManager.getProfileParent(eq(3))).thenReturn(new UserInfo(0, "name", 0)); MockLockSettingsContext context = new MockLockSettingsContext(getContext(), mockUserManager, mock(NotificationManager.class)); mock(NotificationManager.class), mock(DevicePolicyManager.class)); mStorage = new LockSettingsStorageTestable(context, new File(getContext().getFilesDir(), "locksettings")); mStorage.setDatabaseOnCreateCallback(new LockSettingsStorage.Callback() { Loading services/tests/servicestests/src/com/android/server/MockLockSettingsContext.java +6 −1 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.server; import android.app.NotificationManager; import android.app.admin.DevicePolicyManager; import android.content.Context; import android.content.ContextWrapper; import android.os.UserManager; Loading @@ -25,12 +26,14 @@ public class MockLockSettingsContext extends ContextWrapper { private UserManager mUserManager; private NotificationManager mNotificationManager; private DevicePolicyManager mDevicePolicyManager; public MockLockSettingsContext(Context base, UserManager userManager, NotificationManager notificationManager) { NotificationManager notificationManager, DevicePolicyManager devicePolicyManager) { super(base); mUserManager = userManager; mNotificationManager = notificationManager; mDevicePolicyManager = devicePolicyManager; } @Override Loading @@ -39,6 +42,8 @@ public class MockLockSettingsContext extends ContextWrapper { return mUserManager; } else if (NOTIFICATION_SERVICE.equals(name)) { return mNotificationManager; } else if (DEVICE_POLICY_SERVICE.equals(name)) { return mDevicePolicyManager; } else { throw new RuntimeException("System service not mocked: " + name); } Loading Loading
services/core/java/com/android/server/LockSettingsService.java +20 −9 Original line number Diff line number Diff line Loading @@ -146,6 +146,7 @@ public class LockSettingsService extends ILockSettings.Stub { private final LockPatternUtils mLockPatternUtils; private final NotificationManager mNotificationManager; private final UserManager mUserManager; private final DevicePolicyManager mDevicePolicyManager; private final IActivityManager mActivityManager; private final KeyStore mKeyStore; Loading Loading @@ -333,6 +334,10 @@ public class LockSettingsService extends ILockSettings.Stub { return (UserManager) mContext.getSystemService(Context.USER_SERVICE); } public DevicePolicyManager getDevicePolicyManager() { return (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); } public KeyStore getKeyStore() { return KeyStore.getInstance(); } Loading Loading @@ -380,6 +385,7 @@ public class LockSettingsService extends ILockSettings.Stub { mStorage = injector.getStorage(); mNotificationManager = injector.getNotificationManager(); mUserManager = injector.getUserManager(); mDevicePolicyManager = injector.getDevicePolicyManager(); mStrongAuthTracker = injector.getStrongAuthTracker(); mStrongAuthTracker.register(mStrongAuth); Loading Loading @@ -2015,14 +2021,17 @@ public class LockSettingsService extends ILockSettings.Stub { } } long handle = getSyntheticPasswordHandleLocked(userId); AuthenticationToken auth = mSpManager.unwrapPasswordBasedSyntheticPassword( getGateKeeperService(), handle, savedCredential, userId).authToken; AuthenticationResult authResult = mSpManager.unwrapPasswordBasedSyntheticPassword( getGateKeeperService(), handle, savedCredential, userId); VerifyCredentialResponse response = authResult.gkResponse; AuthenticationToken auth = authResult.authToken; if (auth != null) { // We are performing a trusted credential change i.e. a correct existing credential // is provided setLockCredentialWithAuthTokenLocked(credential, credentialType, auth, userId); mSpManager.destroyPasswordBasedSyntheticPassword(handle, userId); } else { } else if (response != null && response.getResponseCode() == VerifyCredentialResponse.RESPONSE_ERROR){ // We are performing an untrusted credential change i.e. by DevicePolicyManager. // So provision a new SP and SID. This would invalidate existing escrow tokens. // Still support this for now but this flow will be removed in the next release. Loading @@ -2031,6 +2040,10 @@ public class LockSettingsService extends ILockSettings.Stub { initializeSyntheticPasswordLocked(null, credential, credentialType, userId); synchronizeUnifiedWorkChallengeForProfiles(userId, null); mSpManager.destroyPasswordBasedSyntheticPassword(handle, userId); } else /* response == null || responseCode == VerifyCredentialResponse.RESPONSE_RETRY */ { Slog.w(TAG, "spBasedSetLockCredentialInternalLocked: " + (response != null ? "rate limit exceeded" : "failed")); return; } notifyActivePasswordMetricsAvailable(credential, userId); Loading @@ -2042,7 +2055,7 @@ public class LockSettingsService extends ILockSettings.Stub { if (DEBUG) Slog.d(TAG, "addEscrowToken: user=" + userId); synchronized (mSpManager) { enableSyntheticPasswordLocked(); // Migrate to synthetic password based credentials if ther user has no password, // Migrate to synthetic password based credentials if the user has no password, // the token can then be activated immediately. AuthenticationToken auth = null; if (!isUserSecure(userId)) { Loading Loading @@ -2201,22 +2214,20 @@ public class LockSettingsService extends ILockSettings.Stub { Slog.i(TAG, "Managed profile can have escrow token"); return; } DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); // Devices with Device Owner should have escrow enabled on all users. if (dpm.getDeviceOwnerComponentOnAnyUser() != null) { if (mDevicePolicyManager.getDeviceOwnerComponentOnAnyUser() != null) { Slog.i(TAG, "Corp-owned device can have escrow token"); return; } // We could also have a profile owner on the given (non-managed) user for unicorn cases if (dpm.getProfileOwnerAsUser(userId) != null) { if (mDevicePolicyManager.getProfileOwnerAsUser(userId) != null) { Slog.i(TAG, "User with profile owner can have escrow token"); return; } // If the device is yet to be provisioned (still in SUW), there is still // a chance that Device Owner will be set on the device later, so postpone // disabling escrow token for now. if (!dpm.isDeviceProvisioned()) { if (!mDevicePolicyManager.isDeviceProvisioned()) { Slog.i(TAG, "Postpone disabling escrow tokens until device is provisioned"); return; } Loading
services/core/java/com/android/server/SyntheticPasswordManager.java +1 −1 Original line number Diff line number Diff line Loading @@ -526,7 +526,7 @@ public class SyntheticPasswordManager { * RESPONSE_OK, since user authentication failures are detected earlier when trying to * decrypt SP. */ public VerifyCredentialResponse verifyChallenge(IGateKeeperService gatekeeper, public @Nullable VerifyCredentialResponse verifyChallenge(IGateKeeperService gatekeeper, @NonNull AuthenticationToken auth, long challenge, int userId) throws RemoteException { byte[] spHandle = loadSyntheticPasswordHandle(userId); if (spHandle == null) { Loading
services/tests/servicestests/src/com/android/server/BaseLockSettingsServiceTests.java +10 −2 Original line number Diff line number Diff line Loading @@ -25,6 +25,8 @@ import static org.mockito.Mockito.when; import android.app.IActivityManager; import android.app.NotificationManager; import android.app.admin.DevicePolicyManager; import android.content.ComponentName; import android.content.Context; import android.content.pm.UserInfo; import android.database.sqlite.SQLiteDatabase; Loading Loading @@ -76,7 +78,7 @@ public class BaseLockSettingsServiceTests extends AndroidTestCase { UserManager mUserManager; MockStorageManager mStorageManager; IActivityManager mActivityManager; DevicePolicyManager mDevicePolicyManager; KeyStore mKeyStore; @Override Loading @@ -89,7 +91,9 @@ public class BaseLockSettingsServiceTests extends AndroidTestCase { mUserManager = mock(UserManager.class); mStorageManager = new MockStorageManager(); mActivityManager = mock(IActivityManager.class); mContext = new MockLockSettingsContext(getContext(), mUserManager, mNotificationManager); mDevicePolicyManager = mock(DevicePolicyManager.class); mContext = new MockLockSettingsContext(getContext(), mUserManager, mNotificationManager, mDevicePolicyManager); mStorage = new LockSettingsStorageTestable(mContext, new File(getContext().getFilesDir(), "locksettings")); File storageDir = mStorage.mStorageDir; Loading Loading @@ -122,6 +126,10 @@ public class BaseLockSettingsServiceTests extends AndroidTestCase { }); when(mLockPatternUtils.getLockSettings()).thenReturn(mService); // Adding a fake Device Owner app which will enable escrow token support in LSS. when(mDevicePolicyManager.getDeviceOwnerComponentOnAnyUser()).thenReturn( new ComponentName("com.dummy.package", ".FakeDeviceOwner")); } @Override Loading
services/tests/servicestests/src/com/android/server/LockSettingsStorageTests.java +2 −1 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import android.app.NotificationManager; import android.app.admin.DevicePolicyManager; import android.content.Context; import android.content.ContextWrapper; import android.content.pm.UserInfo; Loading Loading @@ -68,7 +69,7 @@ public class LockSettingsStorageTests extends AndroidTestCase { when(mockUserManager.getProfileParent(eq(3))).thenReturn(new UserInfo(0, "name", 0)); MockLockSettingsContext context = new MockLockSettingsContext(getContext(), mockUserManager, mock(NotificationManager.class)); mock(NotificationManager.class), mock(DevicePolicyManager.class)); mStorage = new LockSettingsStorageTestable(context, new File(getContext().getFilesDir(), "locksettings")); mStorage.setDatabaseOnCreateCallback(new LockSettingsStorage.Callback() { Loading
services/tests/servicestests/src/com/android/server/MockLockSettingsContext.java +6 −1 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.server; import android.app.NotificationManager; import android.app.admin.DevicePolicyManager; import android.content.Context; import android.content.ContextWrapper; import android.os.UserManager; Loading @@ -25,12 +26,14 @@ public class MockLockSettingsContext extends ContextWrapper { private UserManager mUserManager; private NotificationManager mNotificationManager; private DevicePolicyManager mDevicePolicyManager; public MockLockSettingsContext(Context base, UserManager userManager, NotificationManager notificationManager) { NotificationManager notificationManager, DevicePolicyManager devicePolicyManager) { super(base); mUserManager = userManager; mNotificationManager = notificationManager; mDevicePolicyManager = devicePolicyManager; } @Override Loading @@ -39,6 +42,8 @@ public class MockLockSettingsContext extends ContextWrapper { return mUserManager; } else if (NOTIFICATION_SERVICE.equals(name)) { return mNotificationManager; } else if (DEVICE_POLICY_SERVICE.equals(name)) { return mDevicePolicyManager; } else { throw new RuntimeException("System service not mocked: " + name); } Loading