Loading services/core/java/com/android/server/locksettings/LockSettingsService.java +33 −0 Original line number Diff line number Diff line Loading @@ -584,10 +584,43 @@ public class LockSettingsService extends ILockSettings.Stub { if (mUserManager.getUserInfo(userId).isManagedProfile()) { tieManagedProfileLockIfNecessary(userId, null); } // If the user doesn't have a credential, try and derive their secret for the // AuthSecret HAL. The secret will have been enrolled if the user previously set a // credential and still needs to be passed to the HAL once that credential is // removed. if (mUserManager.getUserInfo(userId).isPrimary() && !isUserSecure(userId)) { tryDeriveAuthTokenForUnsecuredPrimaryUser(userId); } } }); } private void tryDeriveAuthTokenForUnsecuredPrimaryUser(@UserIdInt int userId) { synchronized (mSpManager) { // Make sure the user has a synthetic password to derive if (!isSyntheticPasswordBasedCredentialLocked(userId)) { return; } try { final long handle = getSyntheticPasswordHandleLocked(userId); final String noCredential = null; AuthenticationResult result = mSpManager.unwrapPasswordBasedSyntheticPassword( getGateKeeperService(), handle, noCredential, userId, null); if (result.authToken != null) { Slog.i(TAG, "Retrieved auth token for user " + userId); onAuthTokenKnownForUser(userId, result.authToken); } else { Slog.e(TAG, "Auth token not available for user " + userId); } } catch (RemoteException e) { Slog.e(TAG, "Failure retrieving auth token", e); } } } private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { Loading services/tests/servicestests/src/com/android/server/locksettings/BaseLockSettingsServiceTests.java +3 −1 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import android.app.IActivityManager; import android.app.KeyguardManager; import android.app.NotificationManager; import android.app.admin.DevicePolicyManager; import android.app.admin.DevicePolicyManagerInternal; Loading Loading @@ -102,7 +103,8 @@ public class BaseLockSettingsServiceTests extends AndroidTestCase { LocalServices.addService(DevicePolicyManagerInternal.class, mDevicePolicyManagerInternal); mContext = new MockLockSettingsContext(getContext(), mUserManager, mNotificationManager, mDevicePolicyManager, mock(StorageManager.class), mock(TrustManager.class)); mDevicePolicyManager, mock(StorageManager.class), mock(TrustManager.class), mock(KeyguardManager.class)); mStorage = new LockSettingsStorageTestable(mContext, new File(getContext().getFilesDir(), "locksettings")); File storageDir = mStorage.mStorageDir; Loading services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStorageTests.java +2 −1 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import static org.mockito.Matchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import android.app.KeyguardManager; import android.app.NotificationManager; import android.app.admin.DevicePolicyManager; import android.app.trust.TrustManager; Loading Loading @@ -79,7 +80,7 @@ public class LockSettingsStorageTests extends AndroidTestCase { MockLockSettingsContext context = new MockLockSettingsContext(getContext(), mockUserManager, mock(NotificationManager.class), mock(DevicePolicyManager.class), mock(StorageManager.class), mock(TrustManager.class)); mock(StorageManager.class), mock(TrustManager.class), mock(KeyguardManager.class)); mStorage = new LockSettingsStorageTestable(context, new File(getContext().getFilesDir(), "locksettings")); mStorage.setDatabaseOnCreateCallback(new LockSettingsStorage.Callback() { Loading services/tests/servicestests/src/com/android/server/locksettings/MockLockSettingsContext.java +7 −1 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.server.locksettings; import android.app.KeyguardManager; import android.app.NotificationManager; import android.app.admin.DevicePolicyManager; import android.app.trust.TrustManager; Loading @@ -32,16 +33,19 @@ public class MockLockSettingsContext extends ContextWrapper { private DevicePolicyManager mDevicePolicyManager; private StorageManager mStorageManager; private TrustManager mTrustManager; private KeyguardManager mKeyguardManager; public MockLockSettingsContext(Context base, UserManager userManager, NotificationManager notificationManager, DevicePolicyManager devicePolicyManager, StorageManager storageManager, TrustManager trustManager) { StorageManager storageManager, TrustManager trustManager, KeyguardManager keyguardManager) { super(base); mUserManager = userManager; mNotificationManager = notificationManager; mDevicePolicyManager = devicePolicyManager; mStorageManager = storageManager; mTrustManager = trustManager; mKeyguardManager = keyguardManager; } @Override Loading @@ -56,6 +60,8 @@ public class MockLockSettingsContext extends ContextWrapper { return mStorageManager; } else if (TRUST_SERVICE.equals(name)) { return mTrustManager; } else if (KEYGUARD_SERVICE.equals(name)) { return mKeyguardManager; } else { throw new RuntimeException("System service not mocked: " + name); } Loading services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java +32 −0 Original line number Diff line number Diff line Loading @@ -217,6 +217,38 @@ public class SyntheticPasswordTests extends BaseLockSettingsServiceTests { verify(mAuthSecretService, never()).primaryUserCredential(any(ArrayList.class)); } public void testNoSyntheticPasswordOrCredentialDoesNotPassAuthSecret() throws RemoteException { // Setting null doesn't create a synthetic password initializeCredentialUnderSP(null, PRIMARY_USER_ID); reset(mAuthSecretService); mService.onUnlockUser(PRIMARY_USER_ID); mService.mHandler.runWithScissors(() -> {}, 0 /*now*/); // Flush runnables on handler verify(mAuthSecretService, never()).primaryUserCredential(any(ArrayList.class)); } public void testSyntheticPasswordAndCredentialDoesNotPassAuthSecret() throws RemoteException { final String PASSWORD = "passwordForASyntheticPassword"; initializeCredentialUnderSP(PASSWORD, PRIMARY_USER_ID); reset(mAuthSecretService); mService.onUnlockUser(PRIMARY_USER_ID); mService.mHandler.runWithScissors(() -> {}, 0 /*now*/); // Flush runnables on handler verify(mAuthSecretService, never()).primaryUserCredential(any(ArrayList.class)); } public void testSyntheticPasswordButNoCredentialPassesAuthSecret() throws RemoteException { final String PASSWORD = "getASyntheticPassword"; initializeCredentialUnderSP(PASSWORD, PRIMARY_USER_ID); mService.setLockCredential(null, LockPatternUtils.CREDENTIAL_TYPE_NONE, PASSWORD, PASSWORD_QUALITY_UNSPECIFIED, PRIMARY_USER_ID); reset(mAuthSecretService); mService.onUnlockUser(PRIMARY_USER_ID); mService.mHandler.runWithScissors(() -> {}, 0 /*now*/); // Flush runnables on handler verify(mAuthSecretService).primaryUserCredential(any(ArrayList.class)); } public void testManagedProfileUnifiedChallengeMigration() throws RemoteException { final String UnifiedPassword = "testManagedProfileUnifiedChallengeMigration-pwd"; disableSyntheticPassword(); Loading Loading
services/core/java/com/android/server/locksettings/LockSettingsService.java +33 −0 Original line number Diff line number Diff line Loading @@ -584,10 +584,43 @@ public class LockSettingsService extends ILockSettings.Stub { if (mUserManager.getUserInfo(userId).isManagedProfile()) { tieManagedProfileLockIfNecessary(userId, null); } // If the user doesn't have a credential, try and derive their secret for the // AuthSecret HAL. The secret will have been enrolled if the user previously set a // credential and still needs to be passed to the HAL once that credential is // removed. if (mUserManager.getUserInfo(userId).isPrimary() && !isUserSecure(userId)) { tryDeriveAuthTokenForUnsecuredPrimaryUser(userId); } } }); } private void tryDeriveAuthTokenForUnsecuredPrimaryUser(@UserIdInt int userId) { synchronized (mSpManager) { // Make sure the user has a synthetic password to derive if (!isSyntheticPasswordBasedCredentialLocked(userId)) { return; } try { final long handle = getSyntheticPasswordHandleLocked(userId); final String noCredential = null; AuthenticationResult result = mSpManager.unwrapPasswordBasedSyntheticPassword( getGateKeeperService(), handle, noCredential, userId, null); if (result.authToken != null) { Slog.i(TAG, "Retrieved auth token for user " + userId); onAuthTokenKnownForUser(userId, result.authToken); } else { Slog.e(TAG, "Auth token not available for user " + userId); } } catch (RemoteException e) { Slog.e(TAG, "Failure retrieving auth token", e); } } } private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { Loading
services/tests/servicestests/src/com/android/server/locksettings/BaseLockSettingsServiceTests.java +3 −1 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import android.app.IActivityManager; import android.app.KeyguardManager; import android.app.NotificationManager; import android.app.admin.DevicePolicyManager; import android.app.admin.DevicePolicyManagerInternal; Loading Loading @@ -102,7 +103,8 @@ public class BaseLockSettingsServiceTests extends AndroidTestCase { LocalServices.addService(DevicePolicyManagerInternal.class, mDevicePolicyManagerInternal); mContext = new MockLockSettingsContext(getContext(), mUserManager, mNotificationManager, mDevicePolicyManager, mock(StorageManager.class), mock(TrustManager.class)); mDevicePolicyManager, mock(StorageManager.class), mock(TrustManager.class), mock(KeyguardManager.class)); mStorage = new LockSettingsStorageTestable(mContext, new File(getContext().getFilesDir(), "locksettings")); File storageDir = mStorage.mStorageDir; Loading
services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStorageTests.java +2 −1 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import static org.mockito.Matchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import android.app.KeyguardManager; import android.app.NotificationManager; import android.app.admin.DevicePolicyManager; import android.app.trust.TrustManager; Loading Loading @@ -79,7 +80,7 @@ public class LockSettingsStorageTests extends AndroidTestCase { MockLockSettingsContext context = new MockLockSettingsContext(getContext(), mockUserManager, mock(NotificationManager.class), mock(DevicePolicyManager.class), mock(StorageManager.class), mock(TrustManager.class)); mock(StorageManager.class), mock(TrustManager.class), mock(KeyguardManager.class)); mStorage = new LockSettingsStorageTestable(context, new File(getContext().getFilesDir(), "locksettings")); mStorage.setDatabaseOnCreateCallback(new LockSettingsStorage.Callback() { Loading
services/tests/servicestests/src/com/android/server/locksettings/MockLockSettingsContext.java +7 −1 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.server.locksettings; import android.app.KeyguardManager; import android.app.NotificationManager; import android.app.admin.DevicePolicyManager; import android.app.trust.TrustManager; Loading @@ -32,16 +33,19 @@ public class MockLockSettingsContext extends ContextWrapper { private DevicePolicyManager mDevicePolicyManager; private StorageManager mStorageManager; private TrustManager mTrustManager; private KeyguardManager mKeyguardManager; public MockLockSettingsContext(Context base, UserManager userManager, NotificationManager notificationManager, DevicePolicyManager devicePolicyManager, StorageManager storageManager, TrustManager trustManager) { StorageManager storageManager, TrustManager trustManager, KeyguardManager keyguardManager) { super(base); mUserManager = userManager; mNotificationManager = notificationManager; mDevicePolicyManager = devicePolicyManager; mStorageManager = storageManager; mTrustManager = trustManager; mKeyguardManager = keyguardManager; } @Override Loading @@ -56,6 +60,8 @@ public class MockLockSettingsContext extends ContextWrapper { return mStorageManager; } else if (TRUST_SERVICE.equals(name)) { return mTrustManager; } else if (KEYGUARD_SERVICE.equals(name)) { return mKeyguardManager; } else { throw new RuntimeException("System service not mocked: " + name); } Loading
services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java +32 −0 Original line number Diff line number Diff line Loading @@ -217,6 +217,38 @@ public class SyntheticPasswordTests extends BaseLockSettingsServiceTests { verify(mAuthSecretService, never()).primaryUserCredential(any(ArrayList.class)); } public void testNoSyntheticPasswordOrCredentialDoesNotPassAuthSecret() throws RemoteException { // Setting null doesn't create a synthetic password initializeCredentialUnderSP(null, PRIMARY_USER_ID); reset(mAuthSecretService); mService.onUnlockUser(PRIMARY_USER_ID); mService.mHandler.runWithScissors(() -> {}, 0 /*now*/); // Flush runnables on handler verify(mAuthSecretService, never()).primaryUserCredential(any(ArrayList.class)); } public void testSyntheticPasswordAndCredentialDoesNotPassAuthSecret() throws RemoteException { final String PASSWORD = "passwordForASyntheticPassword"; initializeCredentialUnderSP(PASSWORD, PRIMARY_USER_ID); reset(mAuthSecretService); mService.onUnlockUser(PRIMARY_USER_ID); mService.mHandler.runWithScissors(() -> {}, 0 /*now*/); // Flush runnables on handler verify(mAuthSecretService, never()).primaryUserCredential(any(ArrayList.class)); } public void testSyntheticPasswordButNoCredentialPassesAuthSecret() throws RemoteException { final String PASSWORD = "getASyntheticPassword"; initializeCredentialUnderSP(PASSWORD, PRIMARY_USER_ID); mService.setLockCredential(null, LockPatternUtils.CREDENTIAL_TYPE_NONE, PASSWORD, PASSWORD_QUALITY_UNSPECIFIED, PRIMARY_USER_ID); reset(mAuthSecretService); mService.onUnlockUser(PRIMARY_USER_ID); mService.mHandler.runWithScissors(() -> {}, 0 /*now*/); // Flush runnables on handler verify(mAuthSecretService).primaryUserCredential(any(ArrayList.class)); } public void testManagedProfileUnifiedChallengeMigration() throws RemoteException { final String UnifiedPassword = "testManagedProfileUnifiedChallengeMigration-pwd"; disableSyntheticPassword(); Loading