Loading core/java/android/app/admin/PasswordMetrics.java +13 −0 Original line number Diff line number Diff line Loading @@ -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; Loading services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +9 −4 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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()) { Loading @@ -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, Loading services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java +40 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading
core/java/android/app/admin/PasswordMetrics.java +13 −0 Original line number Diff line number Diff line Loading @@ -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; Loading
services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +9 −4 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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()) { Loading @@ -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, Loading
services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java +40 −0 Original line number Diff line number Diff line Loading @@ -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; Loading