diff options
| author | 2025-01-14 17:23:38 -0800 | |
|---|---|---|
| committer | 2025-01-14 17:23:38 -0800 | |
| commit | a33667c43c3ae961f9f4710eed31b2202b4387df (patch) | |
| tree | de1c6f69e6e5e5e07d2ab67169bc728680959a8d | |
| parent | fffcf619d49ceb7179dcec0803c2723930cd409f (diff) | |
Add adb (Settings.Secure) CLI for disabling the adaptive auth auto lock.
To disable the lock (only on debuggable builds):
adb shell settings put secure disable_adaptive_auth_limit_lock 1
To re-enable the lock:
adb shell settings put secure disable_adaptive_auth_limit_lock 0
Bug: 371057865
Flag: android.security.disable_adaptive_auth_counter_lock
Test: atest AuthenticationPolicyServiceTest
Ignore-AOSP-First: Depends on other changes not in AOSP yet.
This reverts commit fffcf619d49ceb7179dcec0803c2723930cd409f.
Reason for revert: Restoring the original commit after the flag namespace issue in an unrelated test is resolved.
Change-Id: Id984761186d0daa1cddd2e97da4d55881896faf5
6 files changed, 88 insertions, 6 deletions
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index c57243d0bc73..735f96b47c26 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -12876,6 +12876,19 @@ public final class Settings { */ public static final String DISABLE_SECURE_WINDOWS = "disable_secure_windows"; + /** + * Controls if the adaptive authentication feature should be disabled, which + * will attempt to lock the device after a number of consecutive authentication + * attempts fail. + * + * This can only be disabled on debuggable builds. Set to 1 to disable or 0 for the + * normal behavior. + * + * @hide + */ + public static final String DISABLE_ADAPTIVE_AUTH_LIMIT_LOCK = + "disable_adaptive_auth_limit_lock"; + /** @hide */ public static final int PRIVATE_SPACE_AUTO_LOCK_ON_DEVICE_LOCK = 0; /** @hide */ diff --git a/core/java/android/security/flags.aconfig b/core/java/android/security/flags.aconfig index ebb6fb451699..d873ecdd1942 100644 --- a/core/java/android/security/flags.aconfig +++ b/core/java/android/security/flags.aconfig @@ -145,4 +145,11 @@ flag { description: "Feature flag to add the privileged flag to the SUBSCRIBE_TO_KEYGUARD_LOCKED_STATE permission" bug: "380120712" is_fixed_read_only: true -}
\ No newline at end of file +} + +flag { + name: "disable_adaptive_auth_counter_lock" + namespace: "biometrics" + description: "Flag to allow an adb secure setting to disable the adaptive auth lock" + bug: "371057865" +} diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java index 1d7608d7d4d0..f12ccd811674 100644 --- a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java +++ b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java @@ -454,5 +454,6 @@ public class SecureSettingsValidators { VALIDATORS.put(Secure.MANDATORY_BIOMETRICS_REQUIREMENTS_SATISFIED, new InclusiveIntegerRangeValidator(0, 1)); VALIDATORS.put(Secure.ADVANCED_PROTECTION_MODE, BOOLEAN_VALIDATOR); + VALIDATORS.put(Secure.DISABLE_ADAPTIVE_AUTH_LIMIT_LOCK, BOOLEAN_VALIDATOR); } } diff --git a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java index c88a7fd834d6..1a8e98e0ec38 100644 --- a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java +++ b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java @@ -690,6 +690,7 @@ public class SettingsBackupTest { Settings.Secure.DEFAULT_DEVICE_INPUT_METHOD, Settings.Secure.DEVICE_PAIRED, Settings.Secure.DIALER_DEFAULT_APPLICATION, + Settings.Secure.DISABLE_ADAPTIVE_AUTH_LIMIT_LOCK, Settings.Secure.DISABLED_PRINT_SERVICES, Settings.Secure.DISABLE_SECURE_WINDOWS, Settings.Secure.DISABLED_SYSTEM_INPUT_METHODS, diff --git a/services/core/java/com/android/server/security/authenticationpolicy/AuthenticationPolicyService.java b/services/core/java/com/android/server/security/authenticationpolicy/AuthenticationPolicyService.java index 6798a6146ae0..2452dc59bea5 100644 --- a/services/core/java/com/android/server/security/authenticationpolicy/AuthenticationPolicyService.java +++ b/services/core/java/com/android/server/security/authenticationpolicy/AuthenticationPolicyService.java @@ -17,6 +17,7 @@ package com.android.server.security.authenticationpolicy; import static android.Manifest.permission.MANAGE_SECURE_LOCK_DEVICE; +import static android.security.Flags.disableAdaptiveAuthCounterLock; import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_ADAPTIVE_AUTH_REQUEST; @@ -39,6 +40,7 @@ import android.os.IBinder; import android.os.Looper; import android.os.Message; import android.os.SystemClock; +import android.provider.Settings; import android.security.authenticationpolicy.AuthenticationPolicyManager; import android.security.authenticationpolicy.DisableSecureLockDeviceParams; import android.security.authenticationpolicy.EnableSecureLockDeviceParams; @@ -251,6 +253,17 @@ public class AuthenticationPolicyService extends SystemService { return; } + if (disableAdaptiveAuthCounterLock() && Build.IS_DEBUGGABLE) { + final boolean disabled = Settings.Secure.getIntForUser( + getContext().getContentResolver(), + Settings.Secure.DISABLE_ADAPTIVE_AUTH_LIMIT_LOCK, + 0 /* default */, userId) != 0; + if (disabled) { + Slog.d(TAG, "not locking (disabled by user)"); + return; + } + } + //TODO: additionally consider the trust signal before locking device lockDevice(userId); } diff --git a/services/tests/servicestests/src/com/android/server/security/authenticationpolicy/AuthenticationPolicyServiceTest.java b/services/tests/servicestests/src/com/android/server/security/authenticationpolicy/AuthenticationPolicyServiceTest.java index ee8eb9b35088..b76e0bc8cd14 100644 --- a/services/tests/servicestests/src/com/android/server/security/authenticationpolicy/AuthenticationPolicyServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/security/authenticationpolicy/AuthenticationPolicyServiceTest.java @@ -42,8 +42,10 @@ import android.hardware.biometrics.BiometricSourceType; import android.hardware.biometrics.events.AuthenticationFailedInfo; import android.hardware.biometrics.events.AuthenticationSucceededInfo; import android.os.RemoteException; +import android.platform.test.annotations.EnableFlags; import android.platform.test.annotations.Presubmit; import android.platform.test.flag.junit.SetFlagsRule; +import android.provider.Settings; import androidx.test.InstrumentationRegistry; import androidx.test.core.app.ApplicationProvider; @@ -151,6 +153,8 @@ public class AuthenticationPolicyServiceTest { when(mSecureLockDeviceService.disableSecureLockDevice(any())) .thenReturn(ERROR_UNSUPPORTED); } + + toggleAdaptiveAuthSettingsOverride(PRIMARY_USER_ID, false /* disable */); } @After @@ -252,8 +256,24 @@ public class AuthenticationPolicyServiceTest { } @Test - public void testReportAuthAttempt_biometricAuthFailed_multiple_deviceCurrentlyNotLocked() + @EnableFlags({android.security.Flags.FLAG_DISABLE_ADAPTIVE_AUTH_COUNTER_LOCK}) + public void testReportAuthAttempt_biometricAuthFailed_multiple_deviceCurrentlyNotLocked_deviceLockEnabled() + throws RemoteException { + testReportAuthAttempt_biometricAuthFailed_multiple_deviceCurrentlyNotLocked( + true /* enabled */); + } + + @Test + @EnableFlags({android.security.Flags.FLAG_DISABLE_ADAPTIVE_AUTH_COUNTER_LOCK}) + public void testReportAuthAttempt_biometricAuthFailed_multiple_deviceCurrentlyNotLocked_deviceLockDisabled() throws RemoteException { + toggleAdaptiveAuthSettingsOverride(PRIMARY_USER_ID, true /* disabled */); + testReportAuthAttempt_biometricAuthFailed_multiple_deviceCurrentlyNotLocked( + false /* enabled */); + } + + private void testReportAuthAttempt_biometricAuthFailed_multiple_deviceCurrentlyNotLocked( + boolean enabled) throws RemoteException { // Device is currently not locked and Keyguard is not showing when(mKeyguardManager.isDeviceLocked(PRIMARY_USER_ID)).thenReturn(false); when(mKeyguardManager.isKeyguardLocked()).thenReturn(false); @@ -264,7 +284,11 @@ public class AuthenticationPolicyServiceTest { } waitForAuthCompletion(); - verifyLockDevice(PRIMARY_USER_ID); + if (enabled) { + verifyLockDevice(PRIMARY_USER_ID); + } else { + verifyNotLockDevice(MAX_ALLOWED_FAILED_AUTH_ATTEMPTS, PRIMARY_USER_ID); + } } @Test @@ -300,8 +324,24 @@ public class AuthenticationPolicyServiceTest { } @Test - public void testReportAuthAttempt_primaryAuthAndBiometricAuthFailed_primaryUser() + @EnableFlags({android.security.Flags.FLAG_DISABLE_ADAPTIVE_AUTH_COUNTER_LOCK}) + public void testReportAuthAttempt_primaryAuthAndBiometricAuthFailed_primaryUser_deviceLockEnabled() throws RemoteException { + testReportAuthAttempt_primaryAuthAndBiometricAuthFailed_primaryUser( + true /* enabled */); + } + + @Test + @EnableFlags({android.security.Flags.FLAG_DISABLE_ADAPTIVE_AUTH_COUNTER_LOCK}) + public void testReportAuthAttempt_primaryAuthAndBiometricAuthFailed_primaryUser_deviceLockDisabled() + throws RemoteException { + toggleAdaptiveAuthSettingsOverride(PRIMARY_USER_ID, true /* disabled */); + testReportAuthAttempt_primaryAuthAndBiometricAuthFailed_primaryUser( + false /* enabled */); + } + + private void testReportAuthAttempt_primaryAuthAndBiometricAuthFailed_primaryUser( + boolean enabled) throws RemoteException { // Three failed primary auth attempts for (int i = 0; i < 3; i++) { mLockSettingsStateListenerCaptor.getValue().onAuthenticationFailed(PRIMARY_USER_ID); @@ -313,7 +353,11 @@ public class AuthenticationPolicyServiceTest { } waitForAuthCompletion(); - verifyLockDevice(PRIMARY_USER_ID); + if (enabled) { + verifyLockDevice(PRIMARY_USER_ID); + } else { + verifyNotLockDevice(MAX_ALLOWED_FAILED_AUTH_ATTEMPTS, PRIMARY_USER_ID); + } } @Test @@ -366,10 +410,13 @@ public class AuthenticationPolicyServiceTest { REASON_UNKNOWN, true, userId).build(); } - private AuthenticationFailedInfo authFailedInfo(int userId) { return new AuthenticationFailedInfo.Builder(BiometricSourceType.FINGERPRINT, REASON_UNKNOWN, userId).build(); } + private void toggleAdaptiveAuthSettingsOverride(int userId, boolean disable) { + Settings.Secure.putIntForUser(mContext.getContentResolver(), + Settings.Secure.DISABLE_ADAPTIVE_AUTH_LIMIT_LOCK, disable ? 1 : 0, userId); + } } |