Merge "LSS: pass secret to AuthSecret HAL when no credential" into pi-dev
This commit is contained in:
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
@@ -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() {
|
||||
|
||||
@@ -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;
|
||||
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user