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

Commit 29823649 authored by Lorenzo Colitti's avatar Lorenzo Colitti Committed by Gerrit Code Review
Browse files

Merge "Remove Vpn#isBlockingUid."

parents 158e8ae1 2d3e8c7a
Loading
Loading
Loading
Loading
+0 −28
Original line number Diff line number Diff line
@@ -1850,34 +1850,6 @@ public class Vpn {
        }
    }

    /**
     * @param uid The target uid.
     *
     * @return {@code true} if {@code uid} is included in one of the mBlockedUidsAsToldToNetd
     * ranges and the VPN is not connected, or if the VPN is connected but does not apply to
     * the {@code uid}.
     *
     * @apiNote This method don't check VPN lockdown status.
     * @see #mBlockedUidsAsToldToConnectivity
     */
    public synchronized boolean isBlockingUid(int uid) {
        if (mNetworkInfo.isConnected()) {
            return !appliesToUid(uid);
        } else {
            return containsUid(mBlockedUidsAsToldToConnectivity, uid);
        }
    }

    private boolean containsUid(Collection<UidRangeParcel> ranges, int uid) {
        if (ranges == null) return false;
        for (UidRangeParcel range : ranges) {
            if (range.start <= uid && uid <= range.stop) {
                return true;
            }
        }
        return false;
    }

    private void updateAlwaysOnNotification(DetailedState networkState) {
        final boolean visible = (mAlwaysOn && networkState != DetailedState.CONNECTED);

+54 −0
Original line number Diff line number Diff line
@@ -1199,6 +1199,8 @@ public class ConnectivityServiceTest {
                updateState(NetworkInfo.DetailedState.DISCONNECTED, "disconnect");
            }
            mAgentRegistered = false;
            setUids(null);
            mInterface = null;
        }

        @Override
@@ -6180,11 +6182,15 @@ public class ConnectivityServiceTest {

        // Create a fake restricted profile whose parent is our user ID.
        final int userId = UserHandle.getUserId(uid);
        when(mUserManager.canHaveRestrictedProfile(userId)).thenReturn(true);
        final int restrictedUserId = userId + 1;
        final UserInfo info = new UserInfo(restrictedUserId, "user", UserInfo.FLAG_RESTRICTED);
        info.restrictedProfileParentId = userId;
        assertTrue(info.isRestricted());
        when(mUserManager.getUserInfo(restrictedUserId)).thenReturn(info);
        when(mPackageManager.getPackageUidAsUser(ALWAYS_ON_PACKAGE, restrictedUserId))
                .thenReturn(UserHandle.getUid(restrictedUserId, VPN_UID));

        final Intent addedIntent = new Intent(ACTION_USER_ADDED);
        addedIntent.putExtra(Intent.EXTRA_USER_HANDLE, restrictedUserId);

@@ -6224,6 +6230,54 @@ public class ConnectivityServiceTest {
                && caps.getUids().contains(new UidRange(uid, uid))
                && caps.hasTransport(TRANSPORT_VPN)
                && !caps.hasTransport(TRANSPORT_WIFI));

        // Test lockdown with restricted profiles.
        mServiceContext.setPermission(
                Manifest.permission.CONTROL_ALWAYS_ON_VPN, PERMISSION_GRANTED);
        mServiceContext.setPermission(
                Manifest.permission.CONTROL_VPN, PERMISSION_GRANTED);
        mServiceContext.setPermission(
                Manifest.permission.NETWORK_SETTINGS, PERMISSION_GRANTED);

        // Connect wifi and check that UIDs in the main and restricted profiles have network access.
        mMockVpn.disconnect();
        mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
        mWiFiNetworkAgent.connect(true /* validated */);
        final int restrictedUid = UserHandle.getUid(restrictedUserId, 42 /* appId */);
        assertNotNull(mCm.getActiveNetworkForUid(uid));
        assertNotNull(mCm.getActiveNetworkForUid(restrictedUid));

        // Enable always-on VPN lockdown. The main user loses network access because no VPN is up.
        final ArrayList<String> allowList = new ArrayList<>();
        mService.setAlwaysOnVpnPackage(userId, ALWAYS_ON_PACKAGE, true /* lockdown */, allowList);
        waitForIdle();
        assertNull(mCm.getActiveNetworkForUid(uid));
        assertNotNull(mCm.getActiveNetworkForUid(restrictedUid));

        // Start the restricted profile, and check that the UID within it loses network access.
        when(mUserManager.getAliveUsers()).thenReturn(
                Arrays.asList(new UserInfo[] {
                        new UserInfo(userId, "", 0),
                        info
                }));
        // TODO: check that VPN app within restricted profile still has access, etc.
        handler.post(() -> mServiceContext.sendBroadcast(addedIntent));
        waitForIdle();
        assertNull(mCm.getActiveNetworkForUid(uid));
        assertNull(mCm.getActiveNetworkForUid(restrictedUid));

        // Stop the restricted profile, and check that the UID within it has network access again.
        when(mUserManager.getAliveUsers()).thenReturn(
                Arrays.asList(new UserInfo[] {
                        new UserInfo(userId, "", 0),
                }));
        handler.post(() -> mServiceContext.sendBroadcast(removedIntent));
        waitForIdle();
        assertNull(mCm.getActiveNetworkForUid(uid));
        assertNotNull(mCm.getActiveNetworkForUid(restrictedUid));

        mService.setAlwaysOnVpnPackage(userId, null, false /* lockdown */, allowList);
        waitForIdle();
    }

    @Test
+0 −77
Original line number Diff line number Diff line
@@ -339,14 +339,8 @@ public class VpnTest {
        final Vpn vpn = createVpn(primaryUser.id);
        final UidRange user = PRI_USER_RANGE;

        // Default state.
        assertUnblocked(vpn, user.start + PKG_UIDS[0], user.start + PKG_UIDS[1],
                user.start + PKG_UIDS[2], user.start + PKG_UIDS[3]);

        // Set always-on without lockdown.
        assertTrue(vpn.setAlwaysOnPackage(PKGS[1], false, null, mKeyStore));
        assertUnblocked(vpn, user.start + PKG_UIDS[0], user.start + PKG_UIDS[1],
                user.start + PKG_UIDS[2], user.start + PKG_UIDS[3]);

        // Set always-on with lockdown.
        assertTrue(vpn.setAlwaysOnPackage(PKGS[1], true, null, mKeyStore));
@@ -355,10 +349,6 @@ public class VpnTest {
                new UidRangeParcel(user.start + PKG_UIDS[1] + 1, user.stop)
        }));

        assertBlocked(vpn, user.start + PKG_UIDS[0], user.start + PKG_UIDS[2],
                user.start + PKG_UIDS[3]);
        assertUnblocked(vpn, user.start + PKG_UIDS[1]);

        // Switch to another app.
        assertTrue(vpn.setAlwaysOnPackage(PKGS[3], true, null, mKeyStore));
        verify(mConnectivityManager).setRequireVpnForUids(false, toRanges(new UidRangeParcel[] {
@@ -369,9 +359,6 @@ public class VpnTest {
                new UidRangeParcel(user.start, user.start + PKG_UIDS[3] - 1),
                new UidRangeParcel(user.start + PKG_UIDS[3] + 1, user.stop)
        }));
        assertBlocked(vpn, user.start + PKG_UIDS[0], user.start + PKG_UIDS[1],
                user.start + PKG_UIDS[2]);
        assertUnblocked(vpn, user.start + PKG_UIDS[3]);
    }

    @Test
@@ -386,8 +373,6 @@ public class VpnTest {
                new UidRangeParcel(user.start, user.start + PKG_UIDS[1] - 1),
                new UidRangeParcel(user.start + PKG_UIDS[2] + 1, user.stop)
        }));
        assertBlocked(vpn, user.start + PKG_UIDS[0], user.start + PKG_UIDS[3]);
        assertUnblocked(vpn, user.start + PKG_UIDS[1], user.start + PKG_UIDS[2]);
        // Change allowed app list to PKGS[3].
        assertTrue(vpn.setAlwaysOnPackage(
                PKGS[1], true, Collections.singletonList(PKGS[3]), mKeyStore));
@@ -398,8 +383,6 @@ public class VpnTest {
                new UidRangeParcel(user.start + PKG_UIDS[1] + 1, user.start + PKG_UIDS[3] - 1),
                new UidRangeParcel(user.start + PKG_UIDS[3] + 1, user.stop)
        }));
        assertBlocked(vpn, user.start + PKG_UIDS[0], user.start + PKG_UIDS[2]);
        assertUnblocked(vpn, user.start + PKG_UIDS[1], user.start + PKG_UIDS[3]);

        // Change the VPN app.
        assertTrue(vpn.setAlwaysOnPackage(
@@ -412,8 +395,6 @@ public class VpnTest {
                new UidRangeParcel(user.start, user.start + PKG_UIDS[0] - 1),
                new UidRangeParcel(user.start + PKG_UIDS[0] + 1, user.start + PKG_UIDS[3] - 1)
        }));
        assertBlocked(vpn, user.start + PKG_UIDS[1], user.start + PKG_UIDS[2]);
        assertUnblocked(vpn, user.start + PKG_UIDS[0], user.start + PKG_UIDS[3]);

        // Remove the list of allowed packages.
        assertTrue(vpn.setAlwaysOnPackage(PKGS[0], true, null, mKeyStore));
@@ -424,9 +405,6 @@ public class VpnTest {
        verify(mConnectivityManager).setRequireVpnForUids(true, toRanges(new UidRangeParcel[] {
                new UidRangeParcel(user.start + PKG_UIDS[0] + 1, user.stop),
        }));
        assertBlocked(vpn, user.start + PKG_UIDS[1], user.start + PKG_UIDS[2],
                user.start + PKG_UIDS[3]);
        assertUnblocked(vpn, user.start + PKG_UIDS[0]);

        // Add the list of allowed packages.
        assertTrue(vpn.setAlwaysOnPackage(
@@ -438,8 +416,6 @@ public class VpnTest {
                new UidRangeParcel(user.start + PKG_UIDS[0] + 1, user.start + PKG_UIDS[1] - 1),
                new UidRangeParcel(user.start + PKG_UIDS[1] + 1, user.stop)
        }));
        assertBlocked(vpn, user.start + PKG_UIDS[2], user.start + PKG_UIDS[3]);
        assertUnblocked(vpn, user.start + PKG_UIDS[0], user.start + PKG_UIDS[1]);

        // Try allowing a package with a comma, should be rejected.
        assertFalse(vpn.setAlwaysOnPackage(
@@ -459,45 +435,6 @@ public class VpnTest {
        }));
    }

    @Test
    public void testLockdownAddingAProfile() throws Exception {
        final Vpn vpn = createVpn(primaryUser.id);
        setMockedUsers(primaryUser);

        // Make a copy of the restricted profile, as we're going to mark it deleted halfway through.
        final UserInfo tempProfile = new UserInfo(restrictedProfileA.id, restrictedProfileA.name,
                restrictedProfileA.flags);
        tempProfile.restrictedProfileParentId = primaryUser.id;

        final UidRange user = PRI_USER_RANGE;
        final UidRange profile = UidRange.createForUser(tempProfile.id);

        // Set lockdown.
        assertTrue(vpn.setAlwaysOnPackage(PKGS[3], true, null, mKeyStore));
        verify(mConnectivityManager).setRequireVpnForUids(true, toRanges(new UidRangeParcel[] {
                new UidRangeParcel(user.start, user.start + PKG_UIDS[3] - 1),
                new UidRangeParcel(user.start + PKG_UIDS[3] + 1, user.stop)
        }));
        // Verify restricted user isn't affected at first.
        assertUnblocked(vpn, profile.start + PKG_UIDS[0]);

        // Add the restricted user.
        setMockedUsers(primaryUser, tempProfile);
        vpn.onUserAdded(tempProfile.id);
        verify(mConnectivityManager).setRequireVpnForUids(true, toRanges(new UidRangeParcel[] {
                new UidRangeParcel(profile.start, profile.start + PKG_UIDS[3] - 1),
                new UidRangeParcel(profile.start + PKG_UIDS[3] + 1, profile.stop)
        }));

        // Remove the restricted user.
        tempProfile.partial = true;
        vpn.onUserRemoved(tempProfile.id);
        verify(mConnectivityManager).setRequireVpnForUids(false, toRanges(new UidRangeParcel[] {
                new UidRangeParcel(profile.start, profile.start + PKG_UIDS[3] - 1),
                new UidRangeParcel(profile.start + PKG_UIDS[3] + 1, profile.stop)
        }));
    }

    @Test
    public void testLockdownRuleRepeatability() throws Exception {
        final Vpn vpn = createVpn(primaryUser.id);
@@ -1207,20 +1144,6 @@ public class VpnTest {
        return vpn;
    }

    private static void assertBlocked(Vpn vpn, int... uids) {
        for (int uid : uids) {
            final boolean blocked = vpn.getLockdown() && vpn.isBlockingUid(uid);
            assertTrue("Uid " + uid + " should be blocked", blocked);
        }
    }

    private static void assertUnblocked(Vpn vpn, int... uids) {
        for (int uid : uids) {
            final boolean blocked = vpn.getLockdown() && vpn.isBlockingUid(uid);
            assertFalse("Uid " + uid + " should not be blocked", blocked);
        }
    }

    /**
     * Populate {@link #mUserManager} with a list of fake users.
     */