Merge "Recognize numeric PIN in resetPasswordWithToken()" into sc-dev

This commit is contained in:
Rubin Xu
2021-04-09 23:21:18 +00:00
committed by Android (Google) Code Review
3 changed files with 62 additions and 4 deletions

View File

@@ -691,6 +691,19 @@ public final class PasswordMetrics implements Parcelable {
return minMetrics;
}
/**
* Returns true if password is non-empty and contains digits only.
* @param password
* @return
*/
public static boolean isNumericOnly(@NonNull String password) {
if (password.length() == 0) return false;
for (int i = 0; i < password.length(); i++) {
if (categoryChar(password.charAt(i)) != CHAR_DIGIT) return false;
}
return true;
}
@Override
public boolean equals(@Nullable Object o) {
if (this == o) return true;

View File

@@ -4954,6 +4954,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
int flags, CallerIdentity caller) {
final int callingUid = caller.getUid();
final int userHandle = UserHandle.getUserId(callingUid);
final boolean isPin = PasswordMetrics.isNumericOnly(password);
synchronized (getLockObject()) {
final PasswordMetrics minMetrics = getPasswordMinimumMetricsUnchecked(userHandle);
final List<PasswordValidationError> validationErrors;
@@ -4961,12 +4962,12 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
// TODO: Consider changing validation API to take LockscreenCredential.
if (password.isEmpty()) {
validationErrors = PasswordMetrics.validatePasswordMetrics(
minMetrics, complexity, false /* isPin */,
minMetrics, complexity, isPin,
new PasswordMetrics(CREDENTIAL_TYPE_NONE));
} else {
// TODO(b/120484642): remove getBytes() below
validationErrors = PasswordMetrics.validatePassword(
minMetrics, complexity, false, password.getBytes());
minMetrics, complexity, isPin, password.getBytes());
}
if (!validationErrors.isEmpty()) {
@@ -4992,8 +4993,12 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
// Don't do this with the lock held, because it is going to call
// back in to the service.
final long ident = mInjector.binderClearCallingIdentity();
final LockscreenCredential newCredential =
LockscreenCredential.createPasswordOrNone(password);
final LockscreenCredential newCredential;
if (isPin) {
newCredential = LockscreenCredential.createPin(password);
} else {
newCredential = LockscreenCredential.createPasswordOrNone(password);
}
try {
if (tokenHandle == 0 || token == null) {
if (!mLockPatternUtils.setLockCredential(newCredential,

View File

@@ -5089,6 +5089,46 @@ public class DevicePolicyManagerTest extends DpmTestBase {
assertThat(dpm.clearResetPasswordToken(admin1)).isTrue();
}
@Test
public void resetPasswordWithToken_NumericPin() throws Exception {
mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
setupDeviceOwner();
// adding a token
final byte[] token = new byte[32];
final long handle = 123456;
when(getServices().lockPatternUtils.addEscrowToken(eq(token), eq(UserHandle.USER_SYSTEM),
nullable(EscrowTokenStateChangeCallback.class)))
.thenReturn(handle);
assertThat(dpm.setResetPasswordToken(admin1, token)).isTrue();
// Test resetting with a numeric pin
final String pin = "123456";
when(getServices().lockPatternUtils.setLockCredentialWithToken(
LockscreenCredential.createPin(pin), handle, token,
UserHandle.USER_SYSTEM)).thenReturn(true);
assertThat(dpm.resetPasswordWithToken(admin1, pin, token, 0)).isTrue();
}
@Test
public void resetPasswordWithToken_EmptyPassword() throws Exception {
mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
setupDeviceOwner();
// adding a token
final byte[] token = new byte[32];
final long handle = 123456;
when(getServices().lockPatternUtils.addEscrowToken(eq(token), eq(UserHandle.USER_SYSTEM),
nullable(EscrowTokenStateChangeCallback.class)))
.thenReturn(handle);
assertThat(dpm.setResetPasswordToken(admin1, token)).isTrue();
// Test resetting with an empty password
final String password = "";
when(getServices().lockPatternUtils.setLockCredentialWithToken(
LockscreenCredential.createNone(), handle, token,
UserHandle.USER_SYSTEM)).thenReturn(true);
assertThat(dpm.resetPasswordWithToken(admin1, password, token, 0)).isTrue();
}
@Test
public void testIsActivePasswordSufficient() throws Exception {
mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;