Loading config/hiddenapi-greylist.txt +0 −1 Original line number Diff line number Diff line Loading @@ -1680,7 +1680,6 @@ Lcom/android/internal/widget/LockPatternUtils;->patternToHash(Ljava/util/List;)[ Lcom/android/internal/widget/LockPatternUtils;->patternToString(Ljava/util/List;)Ljava/lang/String; Lcom/android/internal/widget/LockPatternUtils;->reportFailedPasswordAttempt(I)V Lcom/android/internal/widget/LockPatternUtils;->reportSuccessfulPasswordAttempt(I)V Lcom/android/internal/widget/LockPatternUtils;->saveLockPassword(Ljava/lang/String;Ljava/lang/String;II)V Lcom/android/internal/widget/LockPatternUtils;->setLockoutAttemptDeadline(II)J Lcom/android/internal/widget/LockPatternUtils;->setLong(Ljava/lang/String;JI)V Lcom/android/internal/widget/LockPatternUtils;->setOwnerInfo(Ljava/lang/String;I)V Loading core/java/com/android/internal/widget/ILockSettings.aidl +1 −1 Original line number Diff line number Diff line Loading @@ -42,7 +42,7 @@ interface ILockSettings { long getLong(in String key, in long defaultValue, in int userId); @UnsupportedAppUsage String getString(in String key, in String defaultValue, in int userId); void setLockCredential(in byte[] credential, int type, in byte[] savedCredential, int requestedQuality, int userId); void setLockCredential(in byte[] credential, int type, in byte[] savedCredential, int requestedQuality, int userId, boolean allowUntrustedChange); void resetKeyStore(int userId); VerifyCredentialResponse checkCredential(in byte[] credential, int type, int userId, in ICheckCredentialProgressCallback progressCallback); Loading core/java/com/android/internal/widget/LockPatternUtils.java +62 −16 Original line number Diff line number Diff line Loading @@ -669,17 +669,25 @@ public class LockPatternUtils { /** * Clear any lock pattern or password. */ public void clearLock(byte[] savedCredential, int userHandle) { public boolean clearLock(byte[] savedCredential, int userHandle) { return clearLock(savedCredential, userHandle, false); } /** * Clear any lock pattern or password, with the option to ignore incorrect existing credential. */ public boolean clearLock(byte[] savedCredential, int userHandle, boolean allowUntrustedChange) { final int currentQuality = getKeyguardStoredPasswordQuality(userHandle); setKeyguardStoredPasswordQuality(PASSWORD_QUALITY_UNSPECIFIED, userHandle); try{ getLockSettings().setLockCredential(null, CREDENTIAL_TYPE_NONE, savedCredential, PASSWORD_QUALITY_UNSPECIFIED, userHandle); savedCredential, PASSWORD_QUALITY_UNSPECIFIED, userHandle, allowUntrustedChange); } catch (Exception e) { Log.e(TAG, "Failed to clear lock", e); setKeyguardStoredPasswordQuality(currentQuality, userHandle); return; return false; } if (userHandle == UserHandle.USER_SYSTEM) { Loading @@ -689,6 +697,7 @@ public class LockPatternUtils { } onAfterChangingPassword(userHandle); return true; } /** Loading Loading @@ -726,19 +735,28 @@ public class LockPatternUtils { /** * Save a lock pattern. * @param pattern The new pattern to save. * @param savedPattern The previously saved pattern, converted to byte[] format * @param userId the user whose pattern is to be saved. * * @return whether this was successful or not. */ public void saveLockPattern(List<LockPatternView.Cell> pattern, int userId) { this.saveLockPattern(pattern, null, userId); public boolean saveLockPattern(List<LockPatternView.Cell> pattern, byte[] savedPattern, int userId) { return saveLockPattern(pattern, savedPattern, userId, false); } /** * Save a lock pattern. * @param pattern The new pattern to save. * @param savedPattern The previously saved pattern, converted to byte[] format * @param userId the user whose pattern is to be saved. * @param allowUntrustedChange whether we want to allow saving a new password if the existing * password being provided is incorrect. * * @return whether this was successful or not. */ public void saveLockPattern(List<LockPatternView.Cell> pattern, byte[] savedPattern, int userId) { public boolean saveLockPattern(List<LockPatternView.Cell> pattern, byte[] savedPattern, int userId, boolean allowUntrustedChange) { if (!hasSecureLockScreen()) { throw new UnsupportedOperationException( "This operation requires the lock screen feature."); Loading @@ -753,11 +771,11 @@ public class LockPatternUtils { setKeyguardStoredPasswordQuality(PASSWORD_QUALITY_SOMETHING, userId); try { getLockSettings().setLockCredential(bytePattern, CREDENTIAL_TYPE_PATTERN, savedPattern, PASSWORD_QUALITY_SOMETHING, userId); PASSWORD_QUALITY_SOMETHING, userId, allowUntrustedChange); } catch (Exception e) { Log.e(TAG, "Couldn't save lock pattern", e); setKeyguardStoredPasswordQuality(currentQuality, userId); return; return false; } // Update the device encryption password. if (userId == UserHandle.USER_SYSTEM Loading @@ -771,6 +789,7 @@ public class LockPatternUtils { reportPatternWasChosen(userId); onAfterChangingPassword(userId); return true; } private void updateCryptoUserInfo(int userId) { Loading Loading @@ -873,17 +892,20 @@ public class LockPatternUtils { * password. * @param password The password to save * @param savedPassword The previously saved lock password, or null if none * @param requestedQuality {@see DevicePolicyManager#getPasswordQuality(android.content.ComponentName)} * @param requestedQuality {@see DevicePolicyManager#getPasswordQuality( * android.content.ComponentName)} * @param userHandle The userId of the user to change the password for * * @return whether this was successful or not. * * @deprecated Pass password as a byte array */ @Deprecated public void saveLockPassword(String password, String savedPassword, int requestedQuality, public boolean saveLockPassword(String password, String savedPassword, int requestedQuality, int userHandle) { byte[] passwordBytes = password != null ? password.getBytes() : null; byte[] savedPasswordBytes = savedPassword != null ? savedPassword.getBytes() : null; saveLockPassword(passwordBytes, savedPasswordBytes, requestedQuality, userHandle); return saveLockPassword(passwordBytes, savedPasswordBytes, requestedQuality, userHandle); } /** Loading @@ -895,9 +917,32 @@ public class LockPatternUtils { * @param requestedQuality {@see DevicePolicyManager#getPasswordQuality( * android.content.ComponentName)} * @param userHandle The userId of the user to change the password for * * @return whether this was successful or not. */ public void saveLockPassword(byte[] password, byte[] savedPassword, int requestedQuality, public boolean saveLockPassword(byte[] password, byte[] savedPassword, int requestedQuality, int userHandle) { return saveLockPassword(password, savedPassword, requestedQuality, userHandle, false); } /** * Save a lock password. Does not ensure that the password is as good * as the requested mode, but will adjust the mode to be as good as the * password. * @param password The password to save * @param savedPassword The previously saved lock password, or null if none * @param requestedQuality {@see DevicePolicyManager#getPasswordQuality( * android.content.ComponentName)} * @param userHandle The userId of the user to change the password for * @param allowUntrustedChange whether we want to allow saving a new password if the existing * password being provided is incorrect. * * @return whether this method saved the new password successfully or not. This flow will fail * and return false if the given credential is wrong and allowUntrustedChange is false. */ public boolean saveLockPassword(byte[] password, byte[] savedPassword, int requestedQuality, int userHandle, boolean allowUntrustedChange) { if (!hasSecureLockScreen()) { throw new UnsupportedOperationException( "This operation requires the lock screen feature."); Loading @@ -919,16 +964,17 @@ public class LockPatternUtils { setKeyguardStoredPasswordQuality(newKeyguardQuality, userHandle); try { getLockSettings().setLockCredential(password, CREDENTIAL_TYPE_PASSWORD, savedPassword, requestedQuality, userHandle); requestedQuality, userHandle, allowUntrustedChange); } catch (Exception e) { Log.e(TAG, "Unable to save lock password", e); setKeyguardStoredPasswordQuality(currentQuality, userHandle); return; return false; } updateEncryptionPasswordIfNeeded(password, passwordQuality, userHandle); updatePasswordHistory(password, userHandle); onAfterChangingPassword(userHandle); return true; } /** Loading services/core/java/com/android/server/locksettings/LockSettingsService.java +33 −24 Original line number Diff line number Diff line Loading @@ -323,8 +323,8 @@ public class LockSettingsService extends ILockSettings.Stub { } Arrays.fill(newPasswordChars, '\u0000'); final int quality = DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC; setLockCredentialInternal(newPassword, CREDENTIAL_TYPE_PASSWORD, managedUserPassword, quality, managedUserId); setLockCredentialInternal(newPassword, CREDENTIAL_TYPE_PASSWORD, managedUserPassword, quality, managedUserId, false); // We store a private credential for the managed user that's unlocked by the primary // account holder's credential. As such, the user will never be prompted to enter this // password directly, so we always store a password. Loading Loading @@ -1302,12 +1302,14 @@ public class LockSettingsService extends ILockSettings.Stub { if (profilePasswordMap != null && profilePasswordMap.containsKey(managedUserId)) { setLockCredentialInternal(null, CREDENTIAL_TYPE_NONE, profilePasswordMap.get(managedUserId), DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, managedUserId); DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, managedUserId, false); } else { Slog.wtf(TAG, "clear tied profile challenges, but no password supplied."); // Supplying null here would lead to untrusted credential change setLockCredentialInternal(null, CREDENTIAL_TYPE_NONE, null, DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, managedUserId); DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, managedUserId, true); } mStorage.removeChildProfileLock(managedUserId); removeKeystoreProfileKey(managedUserId); Loading @@ -1330,8 +1332,8 @@ public class LockSettingsService extends ILockSettings.Stub { // should call setLockCredentialInternal. @Override public void setLockCredential(byte[] credential, int type, byte[] savedCredential, int requestedQuality, int userId) throws RemoteException { byte[] savedCredential, int requestedQuality, int userId, boolean allowUntrustedChange) throws RemoteException { if (!mLockPatternUtils.hasSecureLockScreen()) { throw new UnsupportedOperationException( Loading @@ -1339,7 +1341,8 @@ public class LockSettingsService extends ILockSettings.Stub { } checkWritePermission(userId); synchronized (mSeparateChallengeLock) { setLockCredentialInternal(credential, type, savedCredential, requestedQuality, userId); setLockCredentialInternal(credential, type, savedCredential, requestedQuality, userId, allowUntrustedChange); setSeparateProfileChallengeEnabledLocked(userId, true, null); notifyPasswordChanged(userId); } Loading @@ -1347,7 +1350,8 @@ public class LockSettingsService extends ILockSettings.Stub { } private void setLockCredentialInternal(byte[] credential, @CredentialType int credentialType, byte[] savedCredential, int requestedQuality, int userId) throws RemoteException { byte[] savedCredential, int requestedQuality, int userId, boolean allowUntrustedChange) throws RemoteException { // Normalize savedCredential and credential such that empty string is always represented // as null. if (savedCredential == null || savedCredential.length == 0) { Loading @@ -1359,7 +1363,7 @@ public class LockSettingsService extends ILockSettings.Stub { synchronized (mSpManager) { if (isSyntheticPasswordBasedCredentialLocked(userId)) { spBasedSetLockCredentialInternalLocked(credential, credentialType, savedCredential, requestedQuality, userId); requestedQuality, userId, allowUntrustedChange); return; } } Loading Loading @@ -1410,7 +1414,7 @@ public class LockSettingsService extends ILockSettings.Stub { initializeSyntheticPasswordLocked(currentHandle.hash, savedCredential, currentHandle.type, requestedQuality, userId); spBasedSetLockCredentialInternalLocked(credential, credentialType, savedCredential, requestedQuality, userId); requestedQuality, userId, allowUntrustedChange); return; } } Loading Loading @@ -1705,7 +1709,7 @@ public class LockSettingsService extends ILockSettings.Stub { mStrongAuth.reportSuccessfulStrongAuthUnlock(userId); if (shouldReEnrollBaseZero) { setLockCredentialInternal(credential, storedHash.type, credentialToVerify, DevicePolicyManager.PASSWORD_QUALITY_SOMETHING, userId); DevicePolicyManager.PASSWORD_QUALITY_SOMETHING, userId, false); } } Loading Loading @@ -1796,7 +1800,7 @@ public class LockSettingsService extends ILockSettings.Stub { storedHash.type == CREDENTIAL_TYPE_PATTERN ? DevicePolicyManager.PASSWORD_QUALITY_SOMETHING : DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC /* TODO(roosa): keep the same password quality */, userId); /* TODO(roosa): keep the same password quality */, userId, false); if (!hasChallenge) { notifyActivePasswordMetricsAvailable(storedHash.type, credential, userId); // Use credentials to create recoverable keystore snapshot. Loading Loading @@ -1841,7 +1845,7 @@ public class LockSettingsService extends ILockSettings.Stub { /* TODO(roosa): keep the same password quality */; if (shouldReEnroll) { setLockCredentialInternal(credential, storedHash.type, credential, reEnrollQuality, userId); reEnrollQuality, userId, false); } else { // Now that we've cleared of all required GK migration, let's do the final // migration to synthetic password. Loading Loading @@ -2544,7 +2548,8 @@ public class LockSettingsService extends ILockSettings.Stub { @GuardedBy("mSpManager") private void spBasedSetLockCredentialInternalLocked(byte[] credential, int credentialType, byte[] savedCredential, int requestedQuality, int userId) throws RemoteException { byte[] savedCredential, int requestedQuality, int userId, boolean allowUntrustedChange) throws RemoteException { if (DEBUG) Slog.d(TAG, "spBasedSetLockCredentialInternalLocked: user=" + userId); if (isManagedProfileWithUnifiedLock(userId)) { // get credential from keystore when managed profile has unified lock Loading @@ -2565,27 +2570,31 @@ public class LockSettingsService extends ILockSettings.Stub { VerifyCredentialResponse response = authResult.gkResponse; AuthenticationToken auth = authResult.authToken; // If existing credential is provided, then it must match. // If existing credential is provided, the existing credential must match. if (savedCredential != null && auth == null) { throw new RemoteException("Failed to enroll " + (credentialType == CREDENTIAL_TYPE_PASSWORD ? "password" : "pattern")); throw new IllegalStateException("Failed to enroll " + (credentialType == CREDENTIAL_TYPE_PASSWORD ? "password" : "pattern")); } boolean untrustedReset = false; if (auth != null) { onAuthTokenKnownForUser(userId, auth); } else if (response != null && response.getResponseCode() == VerifyCredentialResponse.RESPONSE_ERROR) { } else if (response == null) { throw new IllegalStateException("Password change failed."); } else if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_ERROR) { // We are performing an untrusted credential change, by DevicePolicyManager or other // internal callers that don't provide the existing credential Slog.w(TAG, "Untrusted credential change invoked"); // Try to get a cached auth token, so we can keep SP unchanged. auth = mSpCache.get(userId); if (!allowUntrustedChange) { throw new IllegalStateException("Untrusted credential change was invoked but it was" + " not allowed. This is likely a bug. Auth token is null: " + Boolean.toString(auth == null)); } untrustedReset = true; } else /* response == null || responseCode == VerifyCredentialResponse.RESPONSE_RETRY */ { Slog.w(TAG, "spBasedSetLockCredentialInternalLocked: " + (response != null ? "rate limit exceeded" : "failed")); return; } else /* responseCode == VerifyCredentialResponse.RESPONSE_RETRY */ { throw new IllegalStateException("Rate limit exceeded, so password was not changed."); } if (auth != null) { Loading services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +5 −2 Original line number Diff line number Diff line Loading @@ -5133,11 +5133,14 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { final boolean result; try { if (token == null) { // This is the legacy reset password for DPM. Here we want to be able to override // the old device password without necessarily knowing it. if (!TextUtils.isEmpty(password)) { mLockPatternUtils.saveLockPassword(password.getBytes(), null, quality, userHandle); userHandle, /*allowUntrustedChange */true); } else { mLockPatternUtils.clearLock(null, userHandle); mLockPatternUtils.clearLock(null, userHandle, /*allowUntrustedChange */ true); } result = true; } else { Loading Loading
config/hiddenapi-greylist.txt +0 −1 Original line number Diff line number Diff line Loading @@ -1680,7 +1680,6 @@ Lcom/android/internal/widget/LockPatternUtils;->patternToHash(Ljava/util/List;)[ Lcom/android/internal/widget/LockPatternUtils;->patternToString(Ljava/util/List;)Ljava/lang/String; Lcom/android/internal/widget/LockPatternUtils;->reportFailedPasswordAttempt(I)V Lcom/android/internal/widget/LockPatternUtils;->reportSuccessfulPasswordAttempt(I)V Lcom/android/internal/widget/LockPatternUtils;->saveLockPassword(Ljava/lang/String;Ljava/lang/String;II)V Lcom/android/internal/widget/LockPatternUtils;->setLockoutAttemptDeadline(II)J Lcom/android/internal/widget/LockPatternUtils;->setLong(Ljava/lang/String;JI)V Lcom/android/internal/widget/LockPatternUtils;->setOwnerInfo(Ljava/lang/String;I)V Loading
core/java/com/android/internal/widget/ILockSettings.aidl +1 −1 Original line number Diff line number Diff line Loading @@ -42,7 +42,7 @@ interface ILockSettings { long getLong(in String key, in long defaultValue, in int userId); @UnsupportedAppUsage String getString(in String key, in String defaultValue, in int userId); void setLockCredential(in byte[] credential, int type, in byte[] savedCredential, int requestedQuality, int userId); void setLockCredential(in byte[] credential, int type, in byte[] savedCredential, int requestedQuality, int userId, boolean allowUntrustedChange); void resetKeyStore(int userId); VerifyCredentialResponse checkCredential(in byte[] credential, int type, int userId, in ICheckCredentialProgressCallback progressCallback); Loading
core/java/com/android/internal/widget/LockPatternUtils.java +62 −16 Original line number Diff line number Diff line Loading @@ -669,17 +669,25 @@ public class LockPatternUtils { /** * Clear any lock pattern or password. */ public void clearLock(byte[] savedCredential, int userHandle) { public boolean clearLock(byte[] savedCredential, int userHandle) { return clearLock(savedCredential, userHandle, false); } /** * Clear any lock pattern or password, with the option to ignore incorrect existing credential. */ public boolean clearLock(byte[] savedCredential, int userHandle, boolean allowUntrustedChange) { final int currentQuality = getKeyguardStoredPasswordQuality(userHandle); setKeyguardStoredPasswordQuality(PASSWORD_QUALITY_UNSPECIFIED, userHandle); try{ getLockSettings().setLockCredential(null, CREDENTIAL_TYPE_NONE, savedCredential, PASSWORD_QUALITY_UNSPECIFIED, userHandle); savedCredential, PASSWORD_QUALITY_UNSPECIFIED, userHandle, allowUntrustedChange); } catch (Exception e) { Log.e(TAG, "Failed to clear lock", e); setKeyguardStoredPasswordQuality(currentQuality, userHandle); return; return false; } if (userHandle == UserHandle.USER_SYSTEM) { Loading @@ -689,6 +697,7 @@ public class LockPatternUtils { } onAfterChangingPassword(userHandle); return true; } /** Loading Loading @@ -726,19 +735,28 @@ public class LockPatternUtils { /** * Save a lock pattern. * @param pattern The new pattern to save. * @param savedPattern The previously saved pattern, converted to byte[] format * @param userId the user whose pattern is to be saved. * * @return whether this was successful or not. */ public void saveLockPattern(List<LockPatternView.Cell> pattern, int userId) { this.saveLockPattern(pattern, null, userId); public boolean saveLockPattern(List<LockPatternView.Cell> pattern, byte[] savedPattern, int userId) { return saveLockPattern(pattern, savedPattern, userId, false); } /** * Save a lock pattern. * @param pattern The new pattern to save. * @param savedPattern The previously saved pattern, converted to byte[] format * @param userId the user whose pattern is to be saved. * @param allowUntrustedChange whether we want to allow saving a new password if the existing * password being provided is incorrect. * * @return whether this was successful or not. */ public void saveLockPattern(List<LockPatternView.Cell> pattern, byte[] savedPattern, int userId) { public boolean saveLockPattern(List<LockPatternView.Cell> pattern, byte[] savedPattern, int userId, boolean allowUntrustedChange) { if (!hasSecureLockScreen()) { throw new UnsupportedOperationException( "This operation requires the lock screen feature."); Loading @@ -753,11 +771,11 @@ public class LockPatternUtils { setKeyguardStoredPasswordQuality(PASSWORD_QUALITY_SOMETHING, userId); try { getLockSettings().setLockCredential(bytePattern, CREDENTIAL_TYPE_PATTERN, savedPattern, PASSWORD_QUALITY_SOMETHING, userId); PASSWORD_QUALITY_SOMETHING, userId, allowUntrustedChange); } catch (Exception e) { Log.e(TAG, "Couldn't save lock pattern", e); setKeyguardStoredPasswordQuality(currentQuality, userId); return; return false; } // Update the device encryption password. if (userId == UserHandle.USER_SYSTEM Loading @@ -771,6 +789,7 @@ public class LockPatternUtils { reportPatternWasChosen(userId); onAfterChangingPassword(userId); return true; } private void updateCryptoUserInfo(int userId) { Loading Loading @@ -873,17 +892,20 @@ public class LockPatternUtils { * password. * @param password The password to save * @param savedPassword The previously saved lock password, or null if none * @param requestedQuality {@see DevicePolicyManager#getPasswordQuality(android.content.ComponentName)} * @param requestedQuality {@see DevicePolicyManager#getPasswordQuality( * android.content.ComponentName)} * @param userHandle The userId of the user to change the password for * * @return whether this was successful or not. * * @deprecated Pass password as a byte array */ @Deprecated public void saveLockPassword(String password, String savedPassword, int requestedQuality, public boolean saveLockPassword(String password, String savedPassword, int requestedQuality, int userHandle) { byte[] passwordBytes = password != null ? password.getBytes() : null; byte[] savedPasswordBytes = savedPassword != null ? savedPassword.getBytes() : null; saveLockPassword(passwordBytes, savedPasswordBytes, requestedQuality, userHandle); return saveLockPassword(passwordBytes, savedPasswordBytes, requestedQuality, userHandle); } /** Loading @@ -895,9 +917,32 @@ public class LockPatternUtils { * @param requestedQuality {@see DevicePolicyManager#getPasswordQuality( * android.content.ComponentName)} * @param userHandle The userId of the user to change the password for * * @return whether this was successful or not. */ public void saveLockPassword(byte[] password, byte[] savedPassword, int requestedQuality, public boolean saveLockPassword(byte[] password, byte[] savedPassword, int requestedQuality, int userHandle) { return saveLockPassword(password, savedPassword, requestedQuality, userHandle, false); } /** * Save a lock password. Does not ensure that the password is as good * as the requested mode, but will adjust the mode to be as good as the * password. * @param password The password to save * @param savedPassword The previously saved lock password, or null if none * @param requestedQuality {@see DevicePolicyManager#getPasswordQuality( * android.content.ComponentName)} * @param userHandle The userId of the user to change the password for * @param allowUntrustedChange whether we want to allow saving a new password if the existing * password being provided is incorrect. * * @return whether this method saved the new password successfully or not. This flow will fail * and return false if the given credential is wrong and allowUntrustedChange is false. */ public boolean saveLockPassword(byte[] password, byte[] savedPassword, int requestedQuality, int userHandle, boolean allowUntrustedChange) { if (!hasSecureLockScreen()) { throw new UnsupportedOperationException( "This operation requires the lock screen feature."); Loading @@ -919,16 +964,17 @@ public class LockPatternUtils { setKeyguardStoredPasswordQuality(newKeyguardQuality, userHandle); try { getLockSettings().setLockCredential(password, CREDENTIAL_TYPE_PASSWORD, savedPassword, requestedQuality, userHandle); requestedQuality, userHandle, allowUntrustedChange); } catch (Exception e) { Log.e(TAG, "Unable to save lock password", e); setKeyguardStoredPasswordQuality(currentQuality, userHandle); return; return false; } updateEncryptionPasswordIfNeeded(password, passwordQuality, userHandle); updatePasswordHistory(password, userHandle); onAfterChangingPassword(userHandle); return true; } /** Loading
services/core/java/com/android/server/locksettings/LockSettingsService.java +33 −24 Original line number Diff line number Diff line Loading @@ -323,8 +323,8 @@ public class LockSettingsService extends ILockSettings.Stub { } Arrays.fill(newPasswordChars, '\u0000'); final int quality = DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC; setLockCredentialInternal(newPassword, CREDENTIAL_TYPE_PASSWORD, managedUserPassword, quality, managedUserId); setLockCredentialInternal(newPassword, CREDENTIAL_TYPE_PASSWORD, managedUserPassword, quality, managedUserId, false); // We store a private credential for the managed user that's unlocked by the primary // account holder's credential. As such, the user will never be prompted to enter this // password directly, so we always store a password. Loading Loading @@ -1302,12 +1302,14 @@ public class LockSettingsService extends ILockSettings.Stub { if (profilePasswordMap != null && profilePasswordMap.containsKey(managedUserId)) { setLockCredentialInternal(null, CREDENTIAL_TYPE_NONE, profilePasswordMap.get(managedUserId), DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, managedUserId); DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, managedUserId, false); } else { Slog.wtf(TAG, "clear tied profile challenges, but no password supplied."); // Supplying null here would lead to untrusted credential change setLockCredentialInternal(null, CREDENTIAL_TYPE_NONE, null, DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, managedUserId); DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, managedUserId, true); } mStorage.removeChildProfileLock(managedUserId); removeKeystoreProfileKey(managedUserId); Loading @@ -1330,8 +1332,8 @@ public class LockSettingsService extends ILockSettings.Stub { // should call setLockCredentialInternal. @Override public void setLockCredential(byte[] credential, int type, byte[] savedCredential, int requestedQuality, int userId) throws RemoteException { byte[] savedCredential, int requestedQuality, int userId, boolean allowUntrustedChange) throws RemoteException { if (!mLockPatternUtils.hasSecureLockScreen()) { throw new UnsupportedOperationException( Loading @@ -1339,7 +1341,8 @@ public class LockSettingsService extends ILockSettings.Stub { } checkWritePermission(userId); synchronized (mSeparateChallengeLock) { setLockCredentialInternal(credential, type, savedCredential, requestedQuality, userId); setLockCredentialInternal(credential, type, savedCredential, requestedQuality, userId, allowUntrustedChange); setSeparateProfileChallengeEnabledLocked(userId, true, null); notifyPasswordChanged(userId); } Loading @@ -1347,7 +1350,8 @@ public class LockSettingsService extends ILockSettings.Stub { } private void setLockCredentialInternal(byte[] credential, @CredentialType int credentialType, byte[] savedCredential, int requestedQuality, int userId) throws RemoteException { byte[] savedCredential, int requestedQuality, int userId, boolean allowUntrustedChange) throws RemoteException { // Normalize savedCredential and credential such that empty string is always represented // as null. if (savedCredential == null || savedCredential.length == 0) { Loading @@ -1359,7 +1363,7 @@ public class LockSettingsService extends ILockSettings.Stub { synchronized (mSpManager) { if (isSyntheticPasswordBasedCredentialLocked(userId)) { spBasedSetLockCredentialInternalLocked(credential, credentialType, savedCredential, requestedQuality, userId); requestedQuality, userId, allowUntrustedChange); return; } } Loading Loading @@ -1410,7 +1414,7 @@ public class LockSettingsService extends ILockSettings.Stub { initializeSyntheticPasswordLocked(currentHandle.hash, savedCredential, currentHandle.type, requestedQuality, userId); spBasedSetLockCredentialInternalLocked(credential, credentialType, savedCredential, requestedQuality, userId); requestedQuality, userId, allowUntrustedChange); return; } } Loading Loading @@ -1705,7 +1709,7 @@ public class LockSettingsService extends ILockSettings.Stub { mStrongAuth.reportSuccessfulStrongAuthUnlock(userId); if (shouldReEnrollBaseZero) { setLockCredentialInternal(credential, storedHash.type, credentialToVerify, DevicePolicyManager.PASSWORD_QUALITY_SOMETHING, userId); DevicePolicyManager.PASSWORD_QUALITY_SOMETHING, userId, false); } } Loading Loading @@ -1796,7 +1800,7 @@ public class LockSettingsService extends ILockSettings.Stub { storedHash.type == CREDENTIAL_TYPE_PATTERN ? DevicePolicyManager.PASSWORD_QUALITY_SOMETHING : DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC /* TODO(roosa): keep the same password quality */, userId); /* TODO(roosa): keep the same password quality */, userId, false); if (!hasChallenge) { notifyActivePasswordMetricsAvailable(storedHash.type, credential, userId); // Use credentials to create recoverable keystore snapshot. Loading Loading @@ -1841,7 +1845,7 @@ public class LockSettingsService extends ILockSettings.Stub { /* TODO(roosa): keep the same password quality */; if (shouldReEnroll) { setLockCredentialInternal(credential, storedHash.type, credential, reEnrollQuality, userId); reEnrollQuality, userId, false); } else { // Now that we've cleared of all required GK migration, let's do the final // migration to synthetic password. Loading Loading @@ -2544,7 +2548,8 @@ public class LockSettingsService extends ILockSettings.Stub { @GuardedBy("mSpManager") private void spBasedSetLockCredentialInternalLocked(byte[] credential, int credentialType, byte[] savedCredential, int requestedQuality, int userId) throws RemoteException { byte[] savedCredential, int requestedQuality, int userId, boolean allowUntrustedChange) throws RemoteException { if (DEBUG) Slog.d(TAG, "spBasedSetLockCredentialInternalLocked: user=" + userId); if (isManagedProfileWithUnifiedLock(userId)) { // get credential from keystore when managed profile has unified lock Loading @@ -2565,27 +2570,31 @@ public class LockSettingsService extends ILockSettings.Stub { VerifyCredentialResponse response = authResult.gkResponse; AuthenticationToken auth = authResult.authToken; // If existing credential is provided, then it must match. // If existing credential is provided, the existing credential must match. if (savedCredential != null && auth == null) { throw new RemoteException("Failed to enroll " + (credentialType == CREDENTIAL_TYPE_PASSWORD ? "password" : "pattern")); throw new IllegalStateException("Failed to enroll " + (credentialType == CREDENTIAL_TYPE_PASSWORD ? "password" : "pattern")); } boolean untrustedReset = false; if (auth != null) { onAuthTokenKnownForUser(userId, auth); } else if (response != null && response.getResponseCode() == VerifyCredentialResponse.RESPONSE_ERROR) { } else if (response == null) { throw new IllegalStateException("Password change failed."); } else if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_ERROR) { // We are performing an untrusted credential change, by DevicePolicyManager or other // internal callers that don't provide the existing credential Slog.w(TAG, "Untrusted credential change invoked"); // Try to get a cached auth token, so we can keep SP unchanged. auth = mSpCache.get(userId); if (!allowUntrustedChange) { throw new IllegalStateException("Untrusted credential change was invoked but it was" + " not allowed. This is likely a bug. Auth token is null: " + Boolean.toString(auth == null)); } untrustedReset = true; } else /* response == null || responseCode == VerifyCredentialResponse.RESPONSE_RETRY */ { Slog.w(TAG, "spBasedSetLockCredentialInternalLocked: " + (response != null ? "rate limit exceeded" : "failed")); return; } else /* responseCode == VerifyCredentialResponse.RESPONSE_RETRY */ { throw new IllegalStateException("Rate limit exceeded, so password was not changed."); } if (auth != null) { Loading
services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +5 −2 Original line number Diff line number Diff line Loading @@ -5133,11 +5133,14 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { final boolean result; try { if (token == null) { // This is the legacy reset password for DPM. Here we want to be able to override // the old device password without necessarily knowing it. if (!TextUtils.isEmpty(password)) { mLockPatternUtils.saveLockPassword(password.getBytes(), null, quality, userHandle); userHandle, /*allowUntrustedChange */true); } else { mLockPatternUtils.clearLock(null, userHandle); mLockPatternUtils.clearLock(null, userHandle, /*allowUntrustedChange */ true); } result = true; } else { Loading