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

Commit 499a786e authored by Billy Huang's avatar Billy Huang Committed by Gerrit Code Review
Browse files

Merge "Add flag to subscribe trust manager to primary auth events" into main

parents b54b9b52 ba344cc5
Loading
Loading
Loading
Loading
+7 −0
Original line number Original line Diff line number Diff line
@@ -83,3 +83,10 @@ flag {
    description: "Add a dump capability for attestation_verification service"
    description: "Add a dump capability for attestation_verification service"
    bug: "335498868"
    bug: "335498868"
}
}

flag {
  name: "should_trust_manager_listen_for_primary_auth"
  namespace: "biometrics"
  description: "Causes TrustManagerService to listen for credential attempts and ignore reports from upstream"
  bug: "323086607"
}
+8 −2
Original line number Original line Diff line number Diff line
@@ -22,6 +22,8 @@ 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_NUMERIC_COMPLEX;
import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_SOMETHING;
import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_SOMETHING;
import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
import static android.security.Flags.reportPrimaryAuthAttempts;
import static android.security.Flags.shouldTrustManagerListenForPrimaryAuth;


import android.annotation.IntDef;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.NonNull;
@@ -414,7 +416,9 @@ public class LockPatternUtils {
            return;
            return;
        }
        }
        getDevicePolicyManager().reportFailedPasswordAttempt(userId);
        getDevicePolicyManager().reportFailedPasswordAttempt(userId);
        getTrustManager().reportUnlockAttempt(false /* authenticated */, userId);
        if (!reportPrimaryAuthAttempts() || !shouldTrustManagerListenForPrimaryAuth()) {
            getTrustManager().reportUnlockAttempt(/* authenticated= */ false, userId);
        }
    }
    }


    @UnsupportedAppUsage
    @UnsupportedAppUsage
@@ -423,7 +427,9 @@ public class LockPatternUtils {
            return;
            return;
        }
        }
        getDevicePolicyManager().reportSuccessfulPasswordAttempt(userId);
        getDevicePolicyManager().reportSuccessfulPasswordAttempt(userId);
        getTrustManager().reportUnlockAttempt(true /* authenticated */, userId);
        if (!reportPrimaryAuthAttempts() || !shouldTrustManagerListenForPrimaryAuth()) {
            getTrustManager().reportUnlockAttempt(/* authenticated= */ true, userId);
        }
    }
    }


    public void reportPasswordLockout(int timeoutMs, int userId) {
    public void reportPasswordLockout(int timeoutMs, int userId) {
+23 −0
Original line number Original line Diff line number Diff line
@@ -16,6 +16,7 @@


package com.android.server.trust;
package com.android.server.trust;


import static android.security.Flags.shouldTrustManagerListenForPrimaryAuth;
import static android.service.trust.GrantTrustResult.STATUS_UNLOCKED_BY_GRANT;
import static android.service.trust.GrantTrustResult.STATUS_UNLOCKED_BY_GRANT;
import static android.service.trust.TrustAgentService.FLAG_GRANT_TRUST_TEMPORARY_AND_RENEWABLE;
import static android.service.trust.TrustAgentService.FLAG_GRANT_TRUST_TEMPORARY_AND_RENEWABLE;


@@ -82,6 +83,9 @@ import com.android.internal.content.PackageMonitor;
import com.android.internal.infra.AndroidFuture;
import com.android.internal.infra.AndroidFuture;
import com.android.internal.util.DumpUtils;
import com.android.internal.util.DumpUtils;
import com.android.internal.widget.LockPatternUtils;
import com.android.internal.widget.LockPatternUtils;
import com.android.internal.widget.LockSettingsInternal;
import com.android.internal.widget.LockSettingsStateListener;
import com.android.server.LocalServices;
import com.android.server.SystemService;
import com.android.server.SystemService;


import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParser;
@@ -154,6 +158,7 @@ public class TrustManagerService extends SystemService {


    /* package */ final TrustArchive mArchive = new TrustArchive();
    /* package */ final TrustArchive mArchive = new TrustArchive();
    private final Context mContext;
    private final Context mContext;
    private final LockSettingsInternal mLockSettings;
    private final LockPatternUtils mLockPatternUtils;
    private final LockPatternUtils mLockPatternUtils;
    private final KeyStoreAuthorization mKeyStoreAuthorization;
    private final KeyStoreAuthorization mKeyStoreAuthorization;
    private final UserManager mUserManager;
    private final UserManager mUserManager;
@@ -245,6 +250,20 @@ public class TrustManagerService extends SystemService {


    private final StrongAuthTracker mStrongAuthTracker;
    private final StrongAuthTracker mStrongAuthTracker;


    // Used to subscribe to device credential auth attempts.
    private final LockSettingsStateListener mLockSettingsStateListener =
            new LockSettingsStateListener() {
                @Override
                public void onAuthenticationSucceeded(int userId) {
                    mHandler.obtainMessage(MSG_DISPATCH_UNLOCK_ATTEMPT, 1, userId).sendToTarget();
                }

                @Override
                public void onAuthenticationFailed(int userId) {
                    mHandler.obtainMessage(MSG_DISPATCH_UNLOCK_ATTEMPT, 0, userId).sendToTarget();
                }
            };

    private boolean mTrustAgentsCanRun = false;
    private boolean mTrustAgentsCanRun = false;
    private int mCurrentUser = UserHandle.USER_SYSTEM;
    private int mCurrentUser = UserHandle.USER_SYSTEM;


@@ -286,6 +305,7 @@ public class TrustManagerService extends SystemService {
        mHandler = createHandler(injector.getLooper());
        mHandler = createHandler(injector.getLooper());
        mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
        mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
        mActivityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
        mActivityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
        mLockSettings = LocalServices.getService(LockSettingsInternal.class);
        mLockPatternUtils = injector.getLockPatternUtils();
        mLockPatternUtils = injector.getLockPatternUtils();
        mKeyStoreAuthorization = injector.getKeyStoreAuthorization();
        mKeyStoreAuthorization = injector.getKeyStoreAuthorization();
        mStrongAuthTracker = new StrongAuthTracker(context, injector.getLooper());
        mStrongAuthTracker = new StrongAuthTracker(context, injector.getLooper());
@@ -307,6 +327,9 @@ public class TrustManagerService extends SystemService {
            checkNewAgents();
            checkNewAgents();
            mPackageMonitor.register(mContext, mHandler.getLooper(), UserHandle.ALL, true);
            mPackageMonitor.register(mContext, mHandler.getLooper(), UserHandle.ALL, true);
            mReceiver.register(mContext);
            mReceiver.register(mContext);
            if (shouldTrustManagerListenForPrimaryAuth()) {
                mLockSettings.registerLockSettingsStateListener(mLockSettingsStateListener);
            }
            mLockPatternUtils.registerStrongAuthTracker(mStrongAuthTracker);
            mLockPatternUtils.registerStrongAuthTracker(mStrongAuthTracker);
            mFingerprintManager = mContext.getSystemService(FingerprintManager.class);
            mFingerprintManager = mContext.getSystemService(FingerprintManager.class);
            mFaceManager = mContext.getSystemService(FaceManager.class);
            mFaceManager = mContext.getSystemService(FaceManager.class);
+1 −0
Original line number Original line Diff line number Diff line
@@ -53,6 +53,7 @@ android_test {
        "mockingservicestests-utils-mockito",
        "mockingservicestests-utils-mockito",
        "mockito-target-extended-minus-junit4",
        "mockito-target-extended-minus-junit4",
        "platform-compat-test-rules",
        "platform-compat-test-rules",
        "platform-parametric-runner-lib",
        "platform-test-annotations",
        "platform-test-annotations",
        "PlatformProperties",
        "PlatformProperties",
        "service-blobstore",
        "service-blobstore",
+40 −2
Original line number Original line Diff line number Diff line
@@ -16,6 +16,8 @@


package com.android.server.trust;
package com.android.server.trust;


import static android.security.Flags.FLAG_SHOULD_TRUST_MANAGER_LISTEN_FOR_PRIMARY_AUTH;
import static android.security.Flags.shouldTrustManagerListenForPrimaryAuth;
import static android.service.trust.TrustAgentService.FLAG_GRANT_TRUST_TEMPORARY_AND_RENEWABLE;
import static android.service.trust.TrustAgentService.FLAG_GRANT_TRUST_TEMPORARY_AND_RENEWABLE;


import static com.android.dx.mockito.inline.extended.ExtendedMockito.any;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.any;
@@ -73,6 +75,8 @@ import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.ServiceManager;
import android.os.UserHandle;
import android.os.UserHandle;
import android.os.UserManager;
import android.os.UserManager;
import android.platform.test.flag.junit.FlagsParameterization;
import android.platform.test.flag.junit.SetFlagsRule;
import android.provider.Settings;
import android.provider.Settings;
import android.security.KeyStoreAuthorization;
import android.security.KeyStoreAuthorization;
import android.service.trust.GrantTrustResult;
import android.service.trust.GrantTrustResult;
@@ -91,6 +95,7 @@ import com.android.internal.widget.LockPatternUtils;
import com.android.internal.widget.LockPatternUtils.StrongAuthTracker;
import com.android.internal.widget.LockPatternUtils.StrongAuthTracker;
import com.android.internal.widget.LockPatternUtils.StrongAuthTracker.StrongAuthFlags;
import com.android.internal.widget.LockPatternUtils.StrongAuthTracker.StrongAuthFlags;
import com.android.internal.widget.LockSettingsInternal;
import com.android.internal.widget.LockSettingsInternal;
import com.android.internal.widget.LockSettingsStateListener;
import com.android.modules.utils.testing.ExtendedMockitoRule;
import com.android.modules.utils.testing.ExtendedMockitoRule;
import com.android.server.LocalServices;
import com.android.server.LocalServices;
import com.android.server.SystemService;
import com.android.server.SystemService;
@@ -101,6 +106,7 @@ import org.junit.Before;
import org.junit.Ignore;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Rule;
import org.junit.Test;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.ArgumentCaptor;
import org.mockito.ArgumentMatcher;
import org.mockito.ArgumentMatcher;
import org.mockito.Mock;
import org.mockito.Mock;
@@ -112,7 +118,16 @@ import java.util.HashMap;
import java.util.List;
import java.util.List;
import java.util.Map;
import java.util.Map;


import platform.test.runner.parameterized.ParameterizedAndroidJunit4;
import platform.test.runner.parameterized.Parameters;

@RunWith(ParameterizedAndroidJunit4.class)
public class TrustManagerServiceTest {
public class TrustManagerServiceTest {
    @Parameters(name = "{0}")
    public static List<FlagsParameterization> getParams() {
        return FlagsParameterization.allCombinationsOf(
                FLAG_SHOULD_TRUST_MANAGER_LISTEN_FOR_PRIMARY_AUTH);
    }


    @Rule
    @Rule
    public final ExtendedMockitoRule mExtendedMockitoRule = new ExtendedMockitoRule.Builder(this)
    public final ExtendedMockitoRule mExtendedMockitoRule = new ExtendedMockitoRule.Builder(this)
@@ -121,6 +136,9 @@ public class TrustManagerServiceTest {
            .mockStatic(WindowManagerGlobal.class)
            .mockStatic(WindowManagerGlobal.class)
            .build();
            .build();


    @Rule
    public final SetFlagsRule mSetFlagsRule;

    @Rule
    @Rule
    public final MockContext mMockContext = new MockContext(
    public final MockContext mMockContext = new MockContext(
            ApplicationProvider.getApplicationContext());
            ApplicationProvider.getApplicationContext());
@@ -162,6 +180,10 @@ public class TrustManagerServiceTest {
    private ITrustManager mTrustManager;
    private ITrustManager mTrustManager;
    private ActivityManagerInternal mPreviousActivityManagerInternal;
    private ActivityManagerInternal mPreviousActivityManagerInternal;


    public TrustManagerServiceTest(FlagsParameterization flags) {
        mSetFlagsRule = new SetFlagsRule(SetFlagsRule.DefaultInitValueType.DEVICE_DEFAULT, flags);
    }

    @Before
    @Before
    public void setUp() throws Exception {
    public void setUp() throws Exception {
        when(mActivityManager.isUserRunning(TEST_USER_ID)).thenReturn(true);
        when(mActivityManager.isUserRunning(TEST_USER_ID)).thenReturn(true);
@@ -594,12 +616,28 @@ public class TrustManagerServiceTest {
    }
    }


    private void attemptSuccessfulUnlock(int userId) throws RemoteException {
    private void attemptSuccessfulUnlock(int userId) throws RemoteException {
        if (shouldTrustManagerListenForPrimaryAuth()) {
            ArgumentCaptor<LockSettingsStateListener> captor =
                    ArgumentCaptor.forClass(LockSettingsStateListener.class);
            verify(mLockSettingsInternal).registerLockSettingsStateListener(captor.capture());
            LockSettingsStateListener listener = captor.getValue();
            listener.onAuthenticationSucceeded(userId);
        } else {
            mTrustManager.reportUnlockAttempt(/* successful= */ true, userId);
            mTrustManager.reportUnlockAttempt(/* successful= */ true, userId);
        }
        }
    }


    private void attemptFailedUnlock(int userId) throws RemoteException {
    private void attemptFailedUnlock(int userId) throws RemoteException {
        if (shouldTrustManagerListenForPrimaryAuth()) {
            ArgumentCaptor<LockSettingsStateListener> captor =
                    ArgumentCaptor.forClass(LockSettingsStateListener.class);
            verify(mLockSettingsInternal).registerLockSettingsStateListener(captor.capture());
            LockSettingsStateListener listener = captor.getValue();
            listener.onAuthenticationFailed(userId);
        } else {
            mTrustManager.reportUnlockAttempt(/* successful= */ false, userId);
            mTrustManager.reportUnlockAttempt(/* successful= */ false, userId);
        }
        }
    }


    private void grantRenewableTrust(ITrustAgentServiceCallback callback) throws RemoteException {
    private void grantRenewableTrust(ITrustAgentServiceCallback callback) throws RemoteException {
        Log.i(TAG, "Granting trust");
        Log.i(TAG, "Granting trust");
Loading