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

Commit 9c70259e authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "[CS] Add an option to block sensitive network specifier" into pi-dev

parents c0ec138c 9b1d701a
Loading
Loading
Loading
Loading
+26 −1
Original line number Diff line number Diff line
@@ -17,7 +17,7 @@
package android.net;

/**
 * Describes specific properties of a network for use in a {@link NetworkRequest}.
 * Describes specific properties of a requested network for use in a {@link NetworkRequest}.
 *
 * Applications cannot instantiate this class by themselves, but can obtain instances of
 * subclasses of this class via other APIs.
@@ -49,4 +49,29 @@ public abstract class NetworkSpecifier {
    public void assertValidFromUid(int requestorUid) {
        // empty
    }

    /**
     * Optional method which can be overridden by concrete implementations of NetworkSpecifier to
     * perform any redaction of information from the NetworkSpecifier, e.g. if it contains
     * sensitive information. The default implementation simply returns the object itself - i.e.
     * no information is redacted. A concrete implementation may return a modified (copy) of the
     * NetworkSpecifier, or even return a null to fully remove all information.
     * <p>
     * This method is relevant to NetworkSpecifier objects used by agents - those are shared with
     * apps by default. Some agents may store sensitive matching information in the specifier,
     * e.g. a Wi-Fi SSID (which should not be shared since it may leak location). Those classes
     * can redact to a null. Other agents use the Network Specifier to share public information
     * with apps - those should not be redacted.
     * <p>
     * The default implementation redacts no information.
     *
     * @return A NetworkSpecifier object to be passed along to the requesting app.
     *
     * @hide
     */
    public NetworkSpecifier redact() {
        // TODO (b/122160111): convert default to null once all platform NetworkSpecifiers
        // implement this method.
        return this;
    }
}
+5 −1
Original line number Diff line number Diff line
@@ -1433,6 +1433,9 @@ public class ConnectivityService extends IConnectivityManager.Stub
            newNc.setUids(null);
            newNc.setSSID(null);
        }
        if (newNc.getNetworkSpecifier() != null) {
            newNc.setNetworkSpecifier(newNc.getNetworkSpecifier().redact());
        }
        return newNc;
    }

@@ -5145,7 +5148,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
        }
        switch (notificationType) {
            case ConnectivityManager.CALLBACK_AVAILABLE: {
                putParcelable(bundle, new NetworkCapabilities(networkAgent.networkCapabilities));
                putParcelable(bundle, networkCapabilitiesRestrictedForCallerPermissions(
                        networkAgent.networkCapabilities, nri.mPid, nri.mUid));
                putParcelable(bundle, new LinkProperties(networkAgent.linkProperties));
                break;
            }
+98 −11
Original line number Diff line number Diff line
@@ -113,7 +113,6 @@ import android.net.NetworkSpecifier;
import android.net.NetworkState;
import android.net.NetworkUtils;
import android.net.RouteInfo;
import android.net.StringNetworkSpecifier;
import android.net.UidRange;
import android.net.VpnService;
import android.net.captiveportal.CaptivePortalProbeResult;
@@ -135,6 +134,7 @@ import android.support.test.InstrumentationRegistry;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
import android.test.mock.MockContentResolver;
import android.text.TextUtils;
import android.util.ArraySet;
import android.util.Log;

@@ -2495,16 +2495,76 @@ public class ConnectivityServiceTest {
        return new NetworkRequest.Builder().addTransportType(TRANSPORT_WIFI);
    }

    /**
     * Verify request matching behavior with network specifiers.
     *
     * Note: this test is somewhat problematic since it involves removing capabilities from
     * agents - i.e. agents rejecting requests which they previously accepted. This is flagged
     * as a WTF bug in
     * {@link ConnectivityService#mixInCapabilities(NetworkAgentInfo, NetworkCapabilities)} but
     * does work.
     */
    @Test
    public void testNetworkSpecifier() {
        // A NetworkSpecifier subclass that matches all networks but must not be visible to apps.
        class ConfidentialMatchAllNetworkSpecifier extends NetworkSpecifier implements
                Parcelable {
            @Override
            public boolean satisfiedBy(NetworkSpecifier other) {
                return true;
            }

            @Override
            public int describeContents() {
                return 0;
            }

            @Override
            public void writeToParcel(Parcel dest, int flags) {}

            @Override
            public NetworkSpecifier redact() {
                return null;
            }
        }

        // A network specifier that matches either another LocalNetworkSpecifier with the same
        // string or a ConfidentialMatchAllNetworkSpecifier, and can be passed to apps as is.
        class LocalStringNetworkSpecifier extends NetworkSpecifier implements Parcelable {
            private String mString;

            LocalStringNetworkSpecifier(String string) {
                mString = string;
            }

            @Override
            public boolean satisfiedBy(NetworkSpecifier other) {
                if (other instanceof LocalStringNetworkSpecifier) {
                    return TextUtils.equals(mString,
                            ((LocalStringNetworkSpecifier) other).mString);
                }
                if (other instanceof ConfidentialMatchAllNetworkSpecifier) return true;
                return false;
            }

            @Override
            public int describeContents() {
                return 0;
            }
            @Override
            public void writeToParcel(Parcel dest, int flags) {}
        }


        NetworkRequest rEmpty1 = newWifiRequestBuilder().build();
        NetworkRequest rEmpty2 = newWifiRequestBuilder().setNetworkSpecifier((String) null).build();
        NetworkRequest rEmpty3 = newWifiRequestBuilder().setNetworkSpecifier("").build();
        NetworkRequest rEmpty4 = newWifiRequestBuilder().setNetworkSpecifier(
            (NetworkSpecifier) null).build();
        NetworkRequest rFoo = newWifiRequestBuilder().setNetworkSpecifier("foo").build();
        NetworkRequest rFoo = newWifiRequestBuilder().setNetworkSpecifier(
                new LocalStringNetworkSpecifier("foo")).build();
        NetworkRequest rBar = newWifiRequestBuilder().setNetworkSpecifier(
                new StringNetworkSpecifier("bar")).build();
                new LocalStringNetworkSpecifier("bar")).build();

        TestNetworkCallback cEmpty1 = new TestNetworkCallback();
        TestNetworkCallback cEmpty2 = new TestNetworkCallback();
@@ -2513,7 +2573,7 @@ public class ConnectivityServiceTest {
        TestNetworkCallback cFoo = new TestNetworkCallback();
        TestNetworkCallback cBar = new TestNetworkCallback();
        TestNetworkCallback[] emptyCallbacks = new TestNetworkCallback[] {
                cEmpty1, cEmpty2, cEmpty3 };
                cEmpty1, cEmpty2, cEmpty3, cEmpty4 };

        mCm.registerNetworkCallback(rEmpty1, cEmpty1);
        mCm.registerNetworkCallback(rEmpty2, cEmpty2);
@@ -2522,6 +2582,9 @@ public class ConnectivityServiceTest {
        mCm.registerNetworkCallback(rFoo, cFoo);
        mCm.registerNetworkCallback(rBar, cBar);

        LocalStringNetworkSpecifier nsFoo = new LocalStringNetworkSpecifier("foo");
        LocalStringNetworkSpecifier nsBar = new LocalStringNetworkSpecifier("bar");

        mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
        mWiFiNetworkAgent.connect(false);
        cEmpty1.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
@@ -2530,30 +2593,54 @@ public class ConnectivityServiceTest {
        cEmpty4.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
        assertNoCallbacks(cFoo, cBar);

        mWiFiNetworkAgent.setNetworkSpecifier(new StringNetworkSpecifier("foo"));
        mWiFiNetworkAgent.setNetworkSpecifier(nsFoo);
        cFoo.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
        for (TestNetworkCallback c: emptyCallbacks) {
            c.expectCallback(CallbackState.NETWORK_CAPABILITIES, mWiFiNetworkAgent);
            c.expectCapabilitiesLike((caps) -> caps.getNetworkSpecifier().equals(nsFoo),
                    mWiFiNetworkAgent);
        }
        cFoo.expectCallback(CallbackState.NETWORK_CAPABILITIES, mWiFiNetworkAgent);
        cFoo.expectCapabilitiesLike((caps) -> caps.getNetworkSpecifier().equals(nsFoo),
                mWiFiNetworkAgent);
        assertEquals(nsFoo,
                mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).getNetworkSpecifier());
        cFoo.assertNoCallback();

        mWiFiNetworkAgent.setNetworkSpecifier(new StringNetworkSpecifier("bar"));
        mWiFiNetworkAgent.setNetworkSpecifier(nsBar);
        cFoo.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
        cBar.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
        for (TestNetworkCallback c: emptyCallbacks) {
            c.expectCallback(CallbackState.NETWORK_CAPABILITIES, mWiFiNetworkAgent);
            c.expectCapabilitiesLike((caps) -> caps.getNetworkSpecifier().equals(nsBar),
                    mWiFiNetworkAgent);
        }
        cBar.expectCallback(CallbackState.NETWORK_CAPABILITIES, mWiFiNetworkAgent);
        cBar.expectCapabilitiesLike((caps) -> caps.getNetworkSpecifier().equals(nsBar),
                mWiFiNetworkAgent);
        assertEquals(nsBar,
                mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).getNetworkSpecifier());
        cBar.assertNoCallback();

        mWiFiNetworkAgent.setNetworkSpecifier(new ConfidentialMatchAllNetworkSpecifier());
        cFoo.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
        for (TestNetworkCallback c : emptyCallbacks) {
            c.expectCapabilitiesLike((caps) -> caps.getNetworkSpecifier() == null,
                    mWiFiNetworkAgent);
        }
        cFoo.expectCapabilitiesLike((caps) -> caps.getNetworkSpecifier() == null,
                mWiFiNetworkAgent);
        cBar.expectCapabilitiesLike((caps) -> caps.getNetworkSpecifier() == null,
                mWiFiNetworkAgent);
        assertNull(
                mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).getNetworkSpecifier());
        cFoo.assertNoCallback();
        cBar.assertNoCallback();

        mWiFiNetworkAgent.setNetworkSpecifier(null);
        cFoo.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
        cBar.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
        for (TestNetworkCallback c: emptyCallbacks) {
            c.expectCallback(CallbackState.NETWORK_CAPABILITIES, mWiFiNetworkAgent);
        }

        assertNoCallbacks(cEmpty1, cEmpty2, cEmpty3, cFoo, cBar);
        assertNoCallbacks(cEmpty1, cEmpty2, cEmpty3, cEmpty4, cFoo, cBar);
    }

    @Test