From 991ccc26d86d027ed4edc9c512475043ad521453 Mon Sep 17 00:00:00 2001 From: Charles He Date: Wed, 19 Apr 2017 19:32:00 +0100 Subject: [PATCH] Prevent fingerprint from bypassing work challenge After too many incorrect attempts at entering the user credential (PIN, password, or pattern) for the work profile, a timeout will be triggered to limit the rate of retries. At the same time, fingerprint should no longer be allowed to unlock the work profile, until the user unlocks it with the correct user credential. Previously, fingerprint was not banned from unlocking the work profile during and after the said timeout. (Pattern lock screen only had a partial fix which removed the fingerprint UI, but still allowed fingerprint to unlock.) This CL fixes the issue. It also replaces the following fields with equivalent getter methods: - mIsStrongAuthRequired, - mAllowFpAuthentication. Otherwise, we would have to rely on these internal states being always up-to-date, which is less maintainable. Test: make SettingsGoogle and manually enter incorrect PINs/patterns Bug: 36912481 Change-Id: Id6ac6b5c78bdc19078ce8dd7acb4ec41329e57c3 --- .../ConfirmDeviceCredentialBaseFragment.java | 19 +++++++++---------- .../android/settings/ConfirmLockPassword.java | 4 +++- .../android/settings/ConfirmLockPattern.java | 5 +++-- 3 files changed, 15 insertions(+), 13 deletions(-) diff --git a/src/com/android/settings/ConfirmDeviceCredentialBaseFragment.java b/src/com/android/settings/ConfirmDeviceCredentialBaseFragment.java index a2e9fe96c49..2c97e1a78e3 100644 --- a/src/com/android/settings/ConfirmDeviceCredentialBaseFragment.java +++ b/src/com/android/settings/ConfirmDeviceCredentialBaseFragment.java @@ -68,8 +68,6 @@ public abstract class ConfirmDeviceCredentialBaseFragment extends OptionsMenuFra PACKAGE + ".ConfirmCredentials.showWhenLocked"; private FingerprintUiHelper mFingerprintHelper; - protected boolean mIsStrongAuthRequired; - private boolean mAllowFpAuthentication; protected boolean mReturnCredentials = false; protected Button mCancelButton; protected ImageView mFingerprintIcon; @@ -83,8 +81,6 @@ public abstract class ConfirmDeviceCredentialBaseFragment extends OptionsMenuFra @Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); - mAllowFpAuthentication = getActivity().getIntent().getBooleanExtra( - ALLOW_FP_AUTHENTICATION, false); mReturnCredentials = getActivity().getIntent().getBooleanExtra( ChooseLockSettingsHelper.EXTRA_KEY_RETURN_CREDENTIALS, false); // Only take this argument into account if it belongs to the current profile. @@ -133,23 +129,26 @@ public abstract class ConfirmDeviceCredentialBaseFragment extends OptionsMenuFra // credential. Otherwise, fingerprint can't unlock fbe/keystore through // verifyTiedProfileChallenge. In such case, we also wanna show the user message that // fingerprint is disabled due to device restart. - private boolean isFingerprintDisallowedByStrongAuth() { + protected boolean isFingerprintDisallowedByStrongAuth() { return !(mLockPatternUtils.isFingerprintAllowedForUser(mEffectiveUserId) && mUserManager.isUserUnlocked(mUserId)); } + private boolean isFingerprintAllowed() { + return !mReturnCredentials + && getActivity().getIntent().getBooleanExtra(ALLOW_FP_AUTHENTICATION, false) + && !isFingerprintDisallowedByStrongAuth() + && !isFingerprintDisabledByAdmin(); + } + @Override public void onResume() { super.onResume(); - mIsStrongAuthRequired = isFingerprintDisallowedByStrongAuth(); - mAllowFpAuthentication = getActivity().getIntent().getBooleanExtra( - ALLOW_FP_AUTHENTICATION, false) - && !isFingerprintDisabledByAdmin() && !mReturnCredentials && !mIsStrongAuthRequired; refreshLockScreen(); } protected void refreshLockScreen() { - if (mAllowFpAuthentication) { + if (isFingerprintAllowed()) { mFingerprintHelper.startListening(); } else { if (mFingerprintHelper.isListening()) { diff --git a/src/com/android/settings/ConfirmLockPassword.java b/src/com/android/settings/ConfirmLockPassword.java index 5c86dcd3d23..9a285f2a7bc 100644 --- a/src/com/android/settings/ConfirmLockPassword.java +++ b/src/com/android/settings/ConfirmLockPassword.java @@ -191,9 +191,10 @@ public class ConfirmLockPassword extends ConfirmDeviceCredentialBaseActivity { } private int getDefaultDetails() { + boolean isStrongAuthRequired = isFingerprintDisallowedByStrongAuth(); boolean isProfile = UserManager.get(getActivity()).isManagedProfile(mEffectiveUserId); // Map boolean flags to an index by isStrongAuth << 2 + isProfile << 1 + isAlpha. - int index = ((mIsStrongAuthRequired ? 1 : 0) << 2) + ((isProfile ? 1 : 0) << 1) + int index = ((isStrongAuthRequired ? 1 : 0) << 2) + ((isProfile ? 1 : 0) << 1) + (mIsAlpha ? 1 : 0); return DETAIL_TEXTS[index]; } @@ -443,6 +444,7 @@ public class ConfirmLockPassword extends ConfirmDeviceCredentialBaseActivity { checkForPendingIntent(); } else { if (timeoutMs > 0) { + refreshLockScreen(); long deadline = mLockPatternUtils.setLockoutAttemptDeadline( effectiveUserId, timeoutMs); handleAttemptLockout(deadline); diff --git a/src/com/android/settings/ConfirmLockPattern.java b/src/com/android/settings/ConfirmLockPattern.java index 4b65163ce29..56d92f1fcf6 100644 --- a/src/com/android/settings/ConfirmLockPattern.java +++ b/src/com/android/settings/ConfirmLockPattern.java @@ -236,12 +236,13 @@ public class ConfirmLockPattern extends ConfirmDeviceCredentialBaseActivity { } private int getDefaultDetails() { + boolean isStrongAuthRequired = isFingerprintDisallowedByStrongAuth(); if (UserManager.get(getActivity()).isManagedProfile(mEffectiveUserId)) { - return mIsStrongAuthRequired + return isStrongAuthRequired ? R.string.lockpassword_strong_auth_required_reason_restart_work_pattern : R.string.lockpassword_confirm_your_pattern_generic_profile; } else { - return mIsStrongAuthRequired + return isStrongAuthRequired ? R.string.lockpassword_strong_auth_required_reason_restart_device_pattern : R.string.lockpassword_confirm_your_pattern_generic; }