Merge "LSS: pass secret to AuthSecret HAL when no credential" into pi-dev

This commit is contained in:
Andrew Scull
2018-04-17 11:04:52 +00:00
committed by Android (Google) Code Review
5 changed files with 77 additions and 3 deletions

View File

@@ -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) {

View File

@@ -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;

View File

@@ -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() {

View File

@@ -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);
}

View File

@@ -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();