From 682d16758010e311910133fb40868133c05b3fe6 Mon Sep 17 00:00:00 2001 From: Rubin Xu Date: Wed, 21 Mar 2018 09:13:44 +0000 Subject: [PATCH] Restore state if password change fails Bug: 73299306 Fixes: 73299306 Test: Call LockPatternUtils.clearLock() with wrong password, make sure device still unlocks after reboot Change-Id: I640fc62cbe0c0c57e980455d4f499df02dee0832 --- .../internal/widget/LockPatternUtils.java | 152 ++++++++++-------- 1 file changed, 83 insertions(+), 69 deletions(-) diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java index fde7e961b843b..d4ab4265b3fb9 100644 --- a/core/java/com/android/internal/widget/LockPatternUtils.java +++ b/core/java/com/android/internal/widget/LockPatternUtils.java @@ -16,6 +16,15 @@ package com.android.internal.widget; +import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC; +import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC; +import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_COMPLEX; +import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_MANAGED; +import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_NUMERIC; +import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX; +import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_SOMETHING; +import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED; + import android.annotation.IntDef; import android.annotation.Nullable; import android.app.admin.DevicePolicyManager; @@ -59,7 +68,6 @@ import java.security.SecureRandom; import java.util.ArrayList; import java.util.Collection; import java.util.List; - /** * Utilities for the lock pattern and its settings. */ @@ -585,7 +593,7 @@ public class LockPatternUtils { return quality; } - return DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED; + return PASSWORD_QUALITY_UNSPECIFIED; } /** @@ -604,13 +612,16 @@ public class LockPatternUtils { * Clear any lock pattern or password. */ public void clearLock(String savedCredential, int userHandle) { - setLong(PASSWORD_TYPE_KEY, DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, userHandle); + final int currentQuality = getKeyguardStoredPasswordQuality(userHandle); + setKeyguardStoredPasswordQuality(PASSWORD_QUALITY_UNSPECIFIED, userHandle); try{ getLockSettings().setLockCredential(null, CREDENTIAL_TYPE_NONE, savedCredential, - DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, userHandle); - } catch (RemoteException e) { - // well, we tried... + PASSWORD_QUALITY_UNSPECIFIED, userHandle); + } catch (Exception e) { + Log.e(TAG, "Failed to clear lock", e); + setKeyguardStoredPasswordQuality(currentQuality, userHandle); + return; } if (userHandle == UserHandle.USER_SYSTEM) { @@ -669,32 +680,34 @@ public class LockPatternUtils { * @param userId the user whose pattern is to be saved. */ public void saveLockPattern(List pattern, String savedPattern, int userId) { - try { - if (pattern == null || pattern.size() < MIN_LOCK_PATTERN_SIZE) { - throw new IllegalArgumentException("pattern must not be null and at least " - + MIN_LOCK_PATTERN_SIZE + " dots long."); - } - - setLong(PASSWORD_TYPE_KEY, DevicePolicyManager.PASSWORD_QUALITY_SOMETHING, userId); - getLockSettings().setLockCredential(patternToString(pattern), CREDENTIAL_TYPE_PATTERN, - savedPattern, DevicePolicyManager.PASSWORD_QUALITY_SOMETHING, userId); - - // Update the device encryption password. - if (userId == UserHandle.USER_SYSTEM - && LockPatternUtils.isDeviceEncryptionEnabled()) { - if (!shouldEncryptWithCredentials(true)) { - clearEncryptionPassword(); - } else { - String stringPattern = patternToString(pattern); - updateEncryptionPassword(StorageManager.CRYPT_TYPE_PATTERN, stringPattern); - } - } - - reportPatternWasChosen(userId); - onAfterChangingPassword(userId); - } catch (RemoteException re) { - Log.e(TAG, "Couldn't save lock pattern " + re); + if (pattern == null || pattern.size() < MIN_LOCK_PATTERN_SIZE) { + throw new IllegalArgumentException("pattern must not be null and at least " + + MIN_LOCK_PATTERN_SIZE + " dots long."); } + + final String stringPattern = patternToString(pattern); + final int currentQuality = getKeyguardStoredPasswordQuality(userId); + setKeyguardStoredPasswordQuality(PASSWORD_QUALITY_SOMETHING, userId); + try { + getLockSettings().setLockCredential(stringPattern, CREDENTIAL_TYPE_PATTERN, + savedPattern, PASSWORD_QUALITY_SOMETHING, userId); + } catch (Exception e) { + Log.e(TAG, "Couldn't save lock pattern", e); + setKeyguardStoredPasswordQuality(currentQuality, userId); + return; + } + // Update the device encryption password. + if (userId == UserHandle.USER_SYSTEM + && LockPatternUtils.isDeviceEncryptionEnabled()) { + if (!shouldEncryptWithCredentials(true)) { + clearEncryptionPassword(); + } else { + updateEncryptionPassword(StorageManager.CRYPT_TYPE_PATTERN, stringPattern); + } + } + + reportPatternWasChosen(userId); + onAfterChangingPassword(userId); } private void updateCryptoUserInfo(int userId) { @@ -796,25 +809,27 @@ public class LockPatternUtils { */ public void saveLockPassword(String password, String savedPassword, int requestedQuality, int userHandle) { - try { - if (password == null || password.length() < MIN_LOCK_PASSWORD_SIZE) { - throw new IllegalArgumentException("password must not be null and at least " - + "of length " + MIN_LOCK_PASSWORD_SIZE); - } - - setLong(PASSWORD_TYPE_KEY, - computePasswordQuality(CREDENTIAL_TYPE_PASSWORD, password, requestedQuality), - userHandle); - getLockSettings().setLockCredential(password, CREDENTIAL_TYPE_PASSWORD, savedPassword, - requestedQuality, userHandle); - - updateEncryptionPasswordIfNeeded(password, - PasswordMetrics.computeForPassword(password).quality, userHandle); - updatePasswordHistory(password, userHandle); - } catch (RemoteException re) { - // Cant do much - Log.e(TAG, "Unable to save lock password " + re); + if (password == null || password.length() < MIN_LOCK_PASSWORD_SIZE) { + throw new IllegalArgumentException("password must not be null and at least " + + "of length " + MIN_LOCK_PASSWORD_SIZE); } + + final int currentQuality = getKeyguardStoredPasswordQuality(userHandle); + setKeyguardStoredPasswordQuality( + computePasswordQuality(CREDENTIAL_TYPE_PASSWORD, password, requestedQuality), + userHandle); + try { + getLockSettings().setLockCredential(password, CREDENTIAL_TYPE_PASSWORD, + savedPassword, requestedQuality, userHandle); + } catch (Exception e) { + Log.e(TAG, "Unable to save lock password", e); + setKeyguardStoredPasswordQuality(currentQuality, userHandle); + return; + } + + updateEncryptionPasswordIfNeeded(password, + PasswordMetrics.computeForPassword(password).quality, userHandle); + updatePasswordHistory(password, userHandle); } /** @@ -828,9 +843,8 @@ public class LockPatternUtils { if (!shouldEncryptWithCredentials(true)) { clearEncryptionPassword(); } else { - boolean numeric = quality == DevicePolicyManager.PASSWORD_QUALITY_NUMERIC; - boolean numericComplex = quality - == DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX; + boolean numeric = quality == PASSWORD_QUALITY_NUMERIC; + boolean numericComplex = quality == PASSWORD_QUALITY_NUMERIC_COMPLEX; int type = numeric || numericComplex ? StorageManager.CRYPT_TYPE_PIN : StorageManager.CRYPT_TYPE_PASSWORD; updateEncryptionPassword(type, password); @@ -894,8 +908,11 @@ public class LockPatternUtils { * @return stored password quality */ public int getKeyguardStoredPasswordQuality(int userHandle) { - return (int) getLong(PASSWORD_TYPE_KEY, - DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, userHandle); + return (int) getLong(PASSWORD_TYPE_KEY, PASSWORD_QUALITY_UNSPECIFIED, userHandle); + } + + private void setKeyguardStoredPasswordQuality(int quality, int userHandle) { + setLong(PASSWORD_TYPE_KEY, quality, userHandle); } /** @@ -909,9 +926,9 @@ public class LockPatternUtils { int computedQuality = PasswordMetrics.computeForPassword(credential).quality; quality = Math.max(requestedQuality, computedQuality); } else if (type == CREDENTIAL_TYPE_PATTERN) { - quality = DevicePolicyManager.PASSWORD_QUALITY_SOMETHING; + quality = PASSWORD_QUALITY_SOMETHING; } else /* if (type == CREDENTIAL_TYPE_NONE) */ { - quality = DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED; + quality = PASSWORD_QUALITY_UNSPECIFIED; } return quality; } @@ -1125,12 +1142,12 @@ public class LockPatternUtils { } private boolean isLockPasswordEnabled(int mode, int userId) { - final boolean passwordEnabled = mode == DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC - || mode == DevicePolicyManager.PASSWORD_QUALITY_NUMERIC - || mode == DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX - || mode == DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC - || mode == DevicePolicyManager.PASSWORD_QUALITY_COMPLEX - || mode == DevicePolicyManager.PASSWORD_QUALITY_MANAGED; + final boolean passwordEnabled = mode == PASSWORD_QUALITY_ALPHABETIC + || mode == PASSWORD_QUALITY_NUMERIC + || mode == PASSWORD_QUALITY_NUMERIC_COMPLEX + || mode == PASSWORD_QUALITY_ALPHANUMERIC + || mode == PASSWORD_QUALITY_COMPLEX + || mode == PASSWORD_QUALITY_MANAGED; return passwordEnabled && savedPasswordExists(userId); } @@ -1155,8 +1172,7 @@ public class LockPatternUtils { } private boolean isLockPatternEnabled(int mode, int userId) { - return mode == DevicePolicyManager.PASSWORD_QUALITY_SOMETHING - && savedPatternExists(userId); + return mode == PASSWORD_QUALITY_SOMETHING && savedPatternExists(userId); } /** @@ -1551,7 +1567,7 @@ public class LockPatternUtils { token, quality, userId)) { return false; } - setLong(PASSWORD_TYPE_KEY, quality, userId); + setKeyguardStoredPasswordQuality(quality, userId); updateEncryptionPasswordIfNeeded(credential, quality, userId); updatePasswordHistory(credential, userId); @@ -1560,12 +1576,10 @@ public class LockPatternUtils { throw new IllegalArgumentException("password must be emtpy for NONE type"); } if (!localService.setLockCredentialWithToken(null, CREDENTIAL_TYPE_NONE, - tokenHandle, token, DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, - userId)) { + tokenHandle, token, PASSWORD_QUALITY_UNSPECIFIED, userId)) { return false; } - setLong(PASSWORD_TYPE_KEY, DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, - userId); + setKeyguardStoredPasswordQuality(PASSWORD_QUALITY_UNSPECIFIED, userId); if (userId == UserHandle.USER_SYSTEM) { // Set the encryption password to default.