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

Commit 682d1675 authored by Rubin Xu's avatar Rubin Xu
Browse files

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
parent 01cee8e6
Loading
Loading
Loading
Loading
+80 −66
Original line number Diff line number Diff line
@@ -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<LockPatternView.Cell> 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);

        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 {
                    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);
        }
    }

    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,
        final int currentQuality = getKeyguardStoredPasswordQuality(userHandle);
        setKeyguardStoredPasswordQuality(
                computePasswordQuality(CREDENTIAL_TYPE_PASSWORD, password, requestedQuality),
                userHandle);
            getLockSettings().setLockCredential(password, CREDENTIAL_TYPE_PASSWORD, savedPassword,
                    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);
        } catch (RemoteException re) {
            // Cant do much
            Log.e(TAG, "Unable to save lock password " + re);
        }
    }

    /**
@@ -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.