Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d4f9d26e authored by Rubin Xu's avatar Rubin Xu Committed by Android (Google) Code Review
Browse files

Merge "Do not suppress severe exception when password change fails"

parents c6fb01ce 6a7303d0
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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, boolean allowUntrustedChange);
    boolean 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);
+60 −21
Original line number Diff line number Diff line
@@ -680,6 +680,15 @@ public class LockPatternUtils {

    /**
     * Clear any lock pattern or password.

     * <p> This method will fail (returning {@code false}) if the previously
     * saved password provided is incorrect, or if the lockscreen verification
     * is still being throttled.
     *
     * @param savedCredential The previously saved credential
     * @param userHandle the user whose pattern is to be saved.
     * @return whether this was successful or not.
     * @throws RuntimeException if password change encountered an unrecoverable error.
     */
    public boolean clearLock(byte[] savedCredential, int userHandle) {
        return clearLock(savedCredential, userHandle, false);
@@ -687,20 +696,28 @@ public class LockPatternUtils {

    /**
     * Clear any lock pattern or password, with the option to ignore incorrect existing credential.
     * <p> This method will fail (returning {@code false}) if the previously
     * saved password provided is incorrect, or if the lockscreen verification
     * is still being throttled.
     *
     * @param savedCredential The previously saved credential
     * @param userHandle the user whose pattern is to be saved.
     * @return whether this was successful or not.
     * @throws RuntimeException if password change encountered an unrecoverable error.
     */
    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,
                    allowUntrustedChange);
        } catch (Exception e) {
            Log.e(TAG, "Failed to clear lock", e);
            setKeyguardStoredPasswordQuality(currentQuality, userHandle);
            if (!getLockSettings().setLockCredential(null, CREDENTIAL_TYPE_NONE, savedCredential,
                    PASSWORD_QUALITY_UNSPECIFIED, userHandle, allowUntrustedChange)) {
                return false;
            }
        } catch (RemoteException | RuntimeException e) {
            setKeyguardStoredPasswordQuality(currentQuality, userHandle);
            throw new RuntimeException("Failed to clear lock", e);
        }

        if (userHandle == UserHandle.USER_SYSTEM) {
            // Set the encryption password to default.
@@ -747,11 +764,15 @@ public class LockPatternUtils {

    /**
     * Save a lock pattern.
     *
     * <p> This method will fail (returning {@code false}) if the previously saved pattern provided
     * is incorrect, or if the lockscreen verification is still being throttled.
     *
     * @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.
     * @throws RuntimeException if password change encountered an unrecoverable error.
     */
    public boolean saveLockPattern(List<LockPatternView.Cell> pattern, byte[] savedPattern,
            int userId) {
@@ -760,13 +781,17 @@ public class LockPatternUtils {

    /**
     * Save a lock pattern.
     *
     * <p> This method will fail (returning {@code false}) if the previously saved pattern provided
     * is incorrect, or if the lockscreen verification is still being throttled.
     *
     * @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.
     * @throws RuntimeException if password change encountered an unrecoverable error.
     */
    public boolean saveLockPattern(List<LockPatternView.Cell> pattern, byte[] savedPattern,
            int userId, boolean allowUntrustedChange) {
@@ -783,13 +808,14 @@ public class LockPatternUtils {
        final int currentQuality = getKeyguardStoredPasswordQuality(userId);
        setKeyguardStoredPasswordQuality(PASSWORD_QUALITY_SOMETHING, userId);
        try {
            getLockSettings().setLockCredential(bytePattern, CREDENTIAL_TYPE_PATTERN, savedPattern,
                    PASSWORD_QUALITY_SOMETHING, userId, allowUntrustedChange);
        } catch (Exception e) {
            Log.e(TAG, "Couldn't save lock pattern", e);
            setKeyguardStoredPasswordQuality(currentQuality, userId);
            if (!getLockSettings().setLockCredential(bytePattern, CREDENTIAL_TYPE_PATTERN,
                    savedPattern, PASSWORD_QUALITY_SOMETHING, userId, allowUntrustedChange)) {
                return false;
            }
        } catch (RemoteException | RuntimeException e) {
            setKeyguardStoredPasswordQuality(currentQuality, userId);
            throw new RuntimeException("Couldn't save lock pattern", e);
        }
        // Update the device encryption password.
        if (userId == UserHandle.USER_SYSTEM
                && LockPatternUtils.isDeviceEncryptionEnabled()) {
@@ -906,14 +932,18 @@ public class LockPatternUtils {
     * 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.
     *
     * <p> This method will fail (returning {@code false}) if the previously
     * saved password provided is incorrect, or if the lockscreen verification
     * is still being throttled.
     *
     * @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
     *
     * @return whether this was successful or not.
     *
     * @throws RuntimeException if password change encountered an unrecoverable error.
     * @deprecated Pass password as a byte array
     */
    @Deprecated
@@ -928,13 +958,18 @@ public class LockPatternUtils {
     * 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.
     *
     * <p> This method will fail (returning {@code false}) if the previously
     * saved password provided is incorrect, or if the lockscreen verification
     * is still being throttled.
     *
     * @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
     *
     * @return whether this was successful or not.
     * @throws RuntimeException if password change encountered an unrecoverable error.
     */
    public boolean saveLockPassword(byte[] password, byte[] savedPassword, int requestedQuality,
            int userHandle) {
@@ -946,6 +981,11 @@ public class LockPatternUtils {
     * 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.
     *
     * <p> This method will fail (returning {@code false}) if the previously
     * saved password provided is incorrect, or if the lockscreen verification
     * is still being throttled.
     *
     * @param password The password to save
     * @param savedPassword The previously saved lock password, or null if none
     * @param requestedQuality {@see DevicePolicyManager#getPasswordQuality(
@@ -953,9 +993,9 @@ public class LockPatternUtils {
     * @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.
     * @throws RuntimeException if password change encountered an unrecoverable error.
     */
    public boolean saveLockPassword(byte[] password, byte[] savedPassword,
            int requestedQuality, int userHandle, boolean allowUntrustedChange) {
@@ -981,10 +1021,9 @@ public class LockPatternUtils {
        try {
            getLockSettings().setLockCredential(password, CREDENTIAL_TYPE_PASSWORD, savedPassword,
                    requestedQuality, userHandle, allowUntrustedChange);
        } catch (Exception e) {
            Log.e(TAG, "Unable to save lock password", e);
        } catch (RemoteException | RuntimeException e) {
            setKeyguardStoredPasswordQuality(currentQuality, userHandle);
            return false;
            throw new RuntimeException("Unable to save lock password", e);
        }

        updateEncryptionPasswordIfNeeded(password, passwordQuality, userHandle);
+42 −35
Original line number Diff line number Diff line
@@ -1461,7 +1461,7 @@ public class LockSettingsService extends ILockSettings.Stub {
    // This method should be called by LockPatternUtil only, all internal methods in this class
    // should call setLockCredentialInternal.
    @Override
    public void setLockCredential(byte[] credential, int type,
    public boolean setLockCredential(byte[] credential, int type,
            byte[] savedCredential, int requestedQuality, int userId,
            boolean allowUntrustedChange) {

@@ -1471,8 +1471,10 @@ public class LockSettingsService extends ILockSettings.Stub {
        }
        checkWritePermission(userId);
        synchronized (mSeparateChallengeLock) {
            setLockCredentialInternal(credential, type, savedCredential, requestedQuality, userId,
                    allowUntrustedChange, /* isLockTiedToParent= */ false);
            if (!setLockCredentialInternal(credential, type, savedCredential, requestedQuality,
                    userId, allowUntrustedChange, /* isLockTiedToParent= */ false)) {
                return false;
            }
            setSeparateProfileChallengeEnabledLocked(userId, true, null);
            notifyPasswordChanged(userId);
        }
@@ -1481,13 +1483,14 @@ public class LockSettingsService extends ILockSettings.Stub {
            setDeviceUnlockedForUser(userId);
        }
        notifySeparateProfileChallengeChanged(userId);
        return true;
    }

    /**
     * @param isLockTiedToParent is {@code true} if {@code userId} is a profile and its new
     *     credentials are being tied to its parent's credentials.
     */
    private void setLockCredentialInternal(byte[] credential, @CredentialType int credentialType,
    private boolean setLockCredentialInternal(byte[] credential, @CredentialType int credentialType,
            byte[] savedCredential, int requestedQuality, int userId, boolean allowUntrustedChange,
            boolean isLockTiedToParent) {
        // Normalize savedCredential and credential such that empty string is always represented
@@ -1500,9 +1503,9 @@ public class LockSettingsService extends ILockSettings.Stub {
        }
        synchronized (mSpManager) {
            if (isSyntheticPasswordBasedCredentialLocked(userId)) {
                spBasedSetLockCredentialInternalLocked(credential, credentialType, savedCredential,
                        requestedQuality, userId, allowUntrustedChange, isLockTiedToParent);
                return;
                return spBasedSetLockCredentialInternalLocked(credential, credentialType,
                        savedCredential, requestedQuality, userId, allowUntrustedChange,
                        isLockTiedToParent);
            }
        }

@@ -1519,7 +1522,7 @@ public class LockSettingsService extends ILockSettings.Stub {
            setUserPasswordMetrics(CREDENTIAL_TYPE_NONE, null, userId);
            sendCredentialsOnChangeIfRequired(
                    credentialType, credential, userId, isLockTiedToParent);
            return;
            return true;
        }
        if (credential == null) {
            throw new IllegalArgumentException("Null credential with mismatched credential type");
@@ -1552,15 +1555,19 @@ public class LockSettingsService extends ILockSettings.Stub {
            if (shouldMigrateToSyntheticPasswordLocked(userId)) {
                initializeSyntheticPasswordLocked(currentHandle.hash, savedCredential,
                        currentHandle.type, requestedQuality, userId);
                spBasedSetLockCredentialInternalLocked(credential, credentialType, savedCredential,
                        requestedQuality, userId, allowUntrustedChange, isLockTiedToParent);
                return;
                return spBasedSetLockCredentialInternalLocked(credential, credentialType,
                        savedCredential, requestedQuality, userId, allowUntrustedChange,
                        isLockTiedToParent);
            }
        }
        if (DEBUG) Slog.d(TAG, "setLockCredentialInternal: user=" + userId);
        byte[] enrolledHandle = enrollCredential(currentHandle.hash, savedCredential, credential,
                userId);
        if (enrolledHandle != null) {
        if (enrolledHandle == null) {
            Slog.w(TAG, String.format("Failed to enroll %s: incorrect credential",
                    credentialType == CREDENTIAL_TYPE_PASSWORD ? "password" : "pattern"));
            return false;
        }
        CredentialHash willStore = CredentialHash.create(enrolledHandle, credentialType);
        mStorage.writeCredentialHash(willStore, userId);
        // push new secret and auth token to vold
@@ -1579,10 +1586,7 @@ public class LockSettingsService extends ILockSettings.Stub {
        synchronizeUnifiedWorkChallengeForProfiles(userId, null);
        sendCredentialsOnChangeIfRequired(
                credentialType, credential, userId, isLockTiedToParent);
        } else {
            throw new IllegalStateException(String.format("Failed to enroll %s",
                    credentialType == CREDENTIAL_TYPE_PASSWORD ? "password" : "pattern"));
        }
        return true;
    }

    private VerifyCredentialResponse convertResponse(GateKeeperResponse gateKeeperResponse) {
@@ -2711,7 +2715,7 @@ public class LockSettingsService extends ILockSettings.Stub {
    }

    @GuardedBy("mSpManager")
    private void spBasedSetLockCredentialInternalLocked(byte[] credential, int credentialType,
    private boolean spBasedSetLockCredentialInternalLocked(byte[] credential, int credentialType,
            byte[] savedCredential, int requestedQuality, int userId,
            boolean allowUntrustedChange, boolean isLockTiedToParent) {
        if (DEBUG) Slog.d(TAG, "spBasedSetLockCredentialInternalLocked: user=" + userId);
@@ -2736,8 +2740,9 @@ public class LockSettingsService extends ILockSettings.Stub {

        // If existing credential is provided, the existing credential must match.
        if (savedCredential != null && auth == null) {
            throw new IllegalStateException(String.format("Failed to enroll %s",
            Slog.w(TAG, String.format("Failed to enroll %s: incorrect credential",
                    credentialType == CREDENTIAL_TYPE_PASSWORD ? "password" : "pattern"));
            return false;
        }
        boolean untrustedReset = false;
        if (auth != null) {
@@ -2757,7 +2762,8 @@ public class LockSettingsService extends ILockSettings.Stub {
            }
            untrustedReset = true;
        } else /* responseCode == VerifyCredentialResponse.RESPONSE_RETRY */ {
            throw new IllegalStateException("Rate limit exceeded, so password was not changed.");
            Slog.w(TAG, "Rate limit exceeded, so password was not changed.");
            return false;
        }

        if (auth != null) {
@@ -2779,6 +2785,7 @@ public class LockSettingsService extends ILockSettings.Stub {
            // synthetic password. That would invalidate existing escrow tokens though.
        }
        sendCredentialsOnChangeIfRequired(credentialType, credential, userId, isLockTiedToParent);
        return true;
    }

    /**
+37 −42

File changed.

Preview size limit exceeded, changes collapsed.