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
This commit is contained in:
Charles He
2017-04-19 19:32:00 +01:00
parent eb62407114
commit 991ccc26d8
3 changed files with 15 additions and 13 deletions

View File

@@ -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()) {

View File

@@ -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);

View File

@@ -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;
}