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

Commit 78f88d62 authored by Eric Biggers's avatar Eric Biggers Committed by Automerger Merge Worker
Browse files

Merge "Unlock non-secure users automatically (1/2)" into main am: 985c8dcf

parents 41d5e400 985c8dcf
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -108,4 +108,5 @@ interface ILockSettings {
    boolean removeWeakEscrowToken(long handle, int userId);
    boolean removeWeakEscrowToken(long handle, int userId);
    boolean isWeakEscrowTokenActive(long handle, int userId);
    boolean isWeakEscrowTokenActive(long handle, int userId);
    boolean isWeakEscrowTokenValid(long handle, in byte[] token, int userId);
    boolean isWeakEscrowTokenValid(long handle, in byte[] token, int userId);
    void unlockUserKeyIfUnsecured(int userId);
}
}
+16 −1
Original line number Original line Diff line number Diff line
@@ -1933,8 +1933,23 @@ public class LockPatternUtils {
        }
        }
    }
    }


    /**
     * Unlocks the credential-encrypted storage for the given user if the user is not secured, i.e.
     * doesn't have an LSKF.
     * <p>
     * Whether the storage has been unlocked can be determined by
     * {@link StorageManager#isUserKeyUnlocked()}.
     *
     * Requires the {@link android.Manifest.permission#ACCESS_KEYGUARD_SECURE_STORAGE} permission.
     *
     * @param userId the ID of the user whose storage to unlock
     */
    public void unlockUserKeyIfUnsecured(@UserIdInt int userId) {
    public void unlockUserKeyIfUnsecured(@UserIdInt int userId) {
        getLockSettingsInternal().unlockUserKeyIfUnsecured(userId);
        try {
            getLockSettings().unlockUserKeyIfUnsecured(userId);
        } catch (RemoteException re) {
            re.rethrowFromSystemServer();
        }
    }
    }


    public void createNewUser(@UserIdInt int userId, int userSerialNumber) {
    public void createNewUser(@UserIdInt int userId, int userSerialNumber) {
+0 −11
Original line number Original line Diff line number Diff line
@@ -59,17 +59,6 @@ public abstract class LockSettingsInternal {
     */
     */
    public abstract void onThirdPartyAppsStarted();
    public abstract void onThirdPartyAppsStarted();


    /**
     * Unlocks the credential-encrypted storage for the given user if the user is not secured, i.e.
     * doesn't have an LSKF.
     * <p>
     * This doesn't throw an exception on failure; whether the storage has been unlocked can be
     * determined by {@link StorageManager#isUserKeyUnlocked()}.
     *
     * @param userId the ID of the user whose storage to unlock
     */
    public abstract void unlockUserKeyIfUnsecured(@UserIdInt int userId);

    /**
    /**
     * Creates the locksettings state for a new user.
     * Creates the locksettings state for a new user.
     * <p>
     * <p>
+3 −6
Original line number Original line Diff line number Diff line
@@ -2047,7 +2047,9 @@ public class LockSettingsService extends ILockSettings.Stub {
        }
        }
    }
    }


    private void unlockUserKeyIfUnsecured(@UserIdInt int userId) {
    @Override
    public void unlockUserKeyIfUnsecured(@UserIdInt int userId) {
        checkPasswordReadPermission();
        synchronized (mSpManager) {
        synchronized (mSpManager) {
            if (isUserKeyUnlocked(userId)) {
            if (isUserKeyUnlocked(userId)) {
                Slogf.d(TAG, "CE storage for user %d is already unlocked", userId);
                Slogf.d(TAG, "CE storage for user %d is already unlocked", userId);
@@ -3455,11 +3457,6 @@ public class LockSettingsService extends ILockSettings.Stub {
            LockSettingsService.this.onThirdPartyAppsStarted();
            LockSettingsService.this.onThirdPartyAppsStarted();
        }
        }


        @Override
        public void unlockUserKeyIfUnsecured(@UserIdInt int userId) {
            LockSettingsService.this.unlockUserKeyIfUnsecured(userId);
        }

        @Override
        @Override
        public void createNewUser(@UserIdInt int userId, int userSerialNumber) {
        public void createNewUser(@UserIdInt int userId, int userSerialNumber) {
            LockSettingsService.this.createNewUser(userId, userSerialNumber);
            LockSettingsService.this.createNewUser(userId, userSerialNumber);
+8 −8
Original line number Original line Diff line number Diff line
@@ -255,7 +255,7 @@ public class SyntheticPasswordTests extends BaseLockSettingsServiceTests {
    public void testUnlockUserKeyIfUnsecuredPassesPrimaryUserAuthSecret() throws RemoteException {
    public void testUnlockUserKeyIfUnsecuredPassesPrimaryUserAuthSecret() throws RemoteException {
        initSpAndSetCredential(PRIMARY_USER_ID, newPassword(null));
        initSpAndSetCredential(PRIMARY_USER_ID, newPassword(null));
        reset(mAuthSecretService);
        reset(mAuthSecretService);
        mLocalService.unlockUserKeyIfUnsecured(PRIMARY_USER_ID);
        mService.unlockUserKeyIfUnsecured(PRIMARY_USER_ID);
        verify(mAuthSecretService).setPrimaryUserCredential(any(byte[].class));
        verify(mAuthSecretService).setPrimaryUserCredential(any(byte[].class));
    }
    }


@@ -267,7 +267,7 @@ public class SyntheticPasswordTests extends BaseLockSettingsServiceTests {
        mService.setLockCredential(nonePassword(), password, PRIMARY_USER_ID);
        mService.setLockCredential(nonePassword(), password, PRIMARY_USER_ID);


        reset(mAuthSecretService);
        reset(mAuthSecretService);
        mLocalService.unlockUserKeyIfUnsecured(PRIMARY_USER_ID);
        mService.unlockUserKeyIfUnsecured(PRIMARY_USER_ID);
        verify(mAuthSecretService).setPrimaryUserCredential(any(byte[].class));
        verify(mAuthSecretService).setPrimaryUserCredential(any(byte[].class));
    }
    }


@@ -285,39 +285,39 @@ public class SyntheticPasswordTests extends BaseLockSettingsServiceTests {
    @Test
    @Test
    public void testHeadlessSystemUserDoesNotPassAuthSecret() throws RemoteException {
    public void testHeadlessSystemUserDoesNotPassAuthSecret() throws RemoteException {
        setupHeadlessTest();
        setupHeadlessTest();
        mLocalService.unlockUserKeyIfUnsecured(PRIMARY_USER_ID);
        mService.unlockUserKeyIfUnsecured(PRIMARY_USER_ID);
        verify(mAuthSecretService, never()).setPrimaryUserCredential(any(byte[].class));
        verify(mAuthSecretService, never()).setPrimaryUserCredential(any(byte[].class));
    }
    }


    @Test
    @Test
    public void testHeadlessSecondaryUserPassesAuthSecret() throws RemoteException {
    public void testHeadlessSecondaryUserPassesAuthSecret() throws RemoteException {
        setupHeadlessTest();
        setupHeadlessTest();
        mLocalService.unlockUserKeyIfUnsecured(SECONDARY_USER_ID);
        mService.unlockUserKeyIfUnsecured(SECONDARY_USER_ID);
        verify(mAuthSecretService).setPrimaryUserCredential(any(byte[].class));
        verify(mAuthSecretService).setPrimaryUserCredential(any(byte[].class));
    }
    }


    @Test
    @Test
    public void testHeadlessTertiaryUserPassesSameAuthSecret() throws RemoteException {
    public void testHeadlessTertiaryUserPassesSameAuthSecret() throws RemoteException {
        setupHeadlessTest();
        setupHeadlessTest();
        mLocalService.unlockUserKeyIfUnsecured(SECONDARY_USER_ID);
        mService.unlockUserKeyIfUnsecured(SECONDARY_USER_ID);
        var captor = ArgumentCaptor.forClass(byte[].class);
        var captor = ArgumentCaptor.forClass(byte[].class);
        verify(mAuthSecretService).setPrimaryUserCredential(captor.capture());
        verify(mAuthSecretService).setPrimaryUserCredential(captor.capture());
        var value = captor.getValue();
        var value = captor.getValue();
        reset(mAuthSecretService);
        reset(mAuthSecretService);
        mLocalService.unlockUserKeyIfUnsecured(TERTIARY_USER_ID);
        mService.unlockUserKeyIfUnsecured(TERTIARY_USER_ID);
        verify(mAuthSecretService).setPrimaryUserCredential(eq(value));
        verify(mAuthSecretService).setPrimaryUserCredential(eq(value));
    }
    }


    @Test
    @Test
    public void testHeadlessTertiaryUserPassesSameAuthSecretAfterReset() throws RemoteException {
    public void testHeadlessTertiaryUserPassesSameAuthSecretAfterReset() throws RemoteException {
        setupHeadlessTest();
        setupHeadlessTest();
        mLocalService.unlockUserKeyIfUnsecured(SECONDARY_USER_ID);
        mService.unlockUserKeyIfUnsecured(SECONDARY_USER_ID);
        var captor = ArgumentCaptor.forClass(byte[].class);
        var captor = ArgumentCaptor.forClass(byte[].class);
        verify(mAuthSecretService).setPrimaryUserCredential(captor.capture());
        verify(mAuthSecretService).setPrimaryUserCredential(captor.capture());
        var value = captor.getValue();
        var value = captor.getValue();
        mService.clearAuthSecret();
        mService.clearAuthSecret();
        reset(mAuthSecretService);
        reset(mAuthSecretService);
        mLocalService.unlockUserKeyIfUnsecured(TERTIARY_USER_ID);
        mService.unlockUserKeyIfUnsecured(TERTIARY_USER_ID);
        verify(mAuthSecretService).setPrimaryUserCredential(eq(value));
        verify(mAuthSecretService).setPrimaryUserCredential(eq(value));
    }
    }