diff options
| author | 2018-04-13 08:59:23 +0000 | |
|---|---|---|
| committer | 2018-04-13 08:59:23 +0000 | |
| commit | 878d0e90b5cca05658b7f6b0bcc00dc3f5be838f (patch) | |
| tree | 6988d512c330faa343eef24794a7c401290c9f36 | |
| parent | df88614db2c408a45518bd51a28705b542525c73 (diff) | |
| parent | b03a6229b82ba16520468ddda79ac1ee395aa983 (diff) | |
Merge "Add a new ssid field in NetworkCapabilities." into pi-dev
3 files changed, 137 insertions, 10 deletions
diff --git a/core/java/android/net/NetworkCapabilities.java b/core/java/android/net/NetworkCapabilities.java index a8e81791fe30..65dfb132378f 100644 --- a/core/java/android/net/NetworkCapabilities.java +++ b/core/java/android/net/NetworkCapabilities.java @@ -71,6 +71,7 @@ public final class NetworkCapabilities implements Parcelable { mUids = nc.mUids; mEstablishingVpnAppUid = nc.mEstablishingVpnAppUid; mUnwantedNetworkCapabilities = nc.mUnwantedNetworkCapabilities; + mSSID = nc.mSSID; } } @@ -86,6 +87,7 @@ public final class NetworkCapabilities implements Parcelable { mSignalStrength = SIGNAL_STRENGTH_UNSPECIFIED; mUids = null; mEstablishingVpnAppUid = INVALID_UID; + mSSID = null; } /** @@ -921,7 +923,7 @@ public final class NetworkCapabilities implements Parcelable { /** * Sets the signal strength. This is a signed integer, with higher values indicating a stronger * signal. The exact units are bearer-dependent. For example, Wi-Fi uses the same RSSI units - * reported by WifiManager. + * reported by wifi code. * <p> * Note that when used to register a network callback, this specifies the minimum acceptable * signal strength. When received as the state of an existing network it specifies the current @@ -1053,7 +1055,7 @@ public final class NetworkCapabilities implements Parcelable { } /** - * Tests if the set of UIDs that this network applies to is the same of the passed set of UIDs. + * Tests if the set of UIDs that this network applies to is the same as the passed network. * <p> * This test only checks whether equal range objects are in both sets. It will * return false if the ranges are not exactly the same, even if the covered UIDs @@ -1143,6 +1145,62 @@ public final class NetworkCapabilities implements Parcelable { mUids.addAll(nc.mUids); } + + /** + * The SSID of the network, or null if not applicable or unknown. + * <p> + * This is filled in by wifi code. + * @hide + */ + private String mSSID; + + /** + * Sets the SSID of this network. + * @hide + */ + public NetworkCapabilities setSSID(String ssid) { + mSSID = ssid; + return this; + } + + /** + * Gets the SSID of this network, or null if none or unknown. + * @hide + */ + public String getSSID() { + return mSSID; + } + + /** + * Tests if the SSID of this network is the same as the SSID of the passed network. + * @hide + */ + public boolean equalsSSID(NetworkCapabilities nc) { + return Objects.equals(mSSID, nc.mSSID); + } + + /** + * Check if the SSID requirements of this object are matched by the passed object. + * @hide + */ + public boolean satisfiedBySSID(NetworkCapabilities nc) { + return mSSID == null || mSSID.equals(nc.mSSID); + } + + /** + * Combine SSIDs of the capabilities. + * <p> + * This is only legal if either the SSID of this object is null, or both SSIDs are + * equal. + * @hide + */ + private void combineSSIDs(NetworkCapabilities nc) { + if (mSSID != null && !mSSID.equals(nc.mSSID)) { + throw new IllegalStateException("Can't combine two SSIDs"); + } + setSSID(nc.mSSID); + } + /** * Combine a set of Capabilities to this one. Useful for coming up with the complete set * @hide @@ -1154,6 +1212,7 @@ public final class NetworkCapabilities implements Parcelable { combineSpecifiers(nc); combineSignalStrength(nc); combineUids(nc); + combineSSIDs(nc); } /** @@ -1172,7 +1231,8 @@ public final class NetworkCapabilities implements Parcelable { && (onlyImmutable || satisfiedByLinkBandwidths(nc)) && satisfiedBySpecifier(nc) && (onlyImmutable || satisfiedBySignalStrength(nc)) - && (onlyImmutable || satisfiedByUids(nc))); + && (onlyImmutable || satisfiedByUids(nc)) + && (onlyImmutable || satisfiedBySSID(nc))); } /** @@ -1259,7 +1319,8 @@ public final class NetworkCapabilities implements Parcelable { && equalsLinkBandwidths(that) && equalsSignalStrength(that) && equalsSpecifier(that) - && equalsUids(that)); + && equalsUids(that) + && equalsSSID(that)); } @Override @@ -1274,7 +1335,8 @@ public final class NetworkCapabilities implements Parcelable { + (mLinkDownBandwidthKbps * 19) + Objects.hashCode(mNetworkSpecifier) * 23 + (mSignalStrength * 29) - + Objects.hashCode(mUids) * 31; + + Objects.hashCode(mUids) * 31 + + Objects.hashCode(mSSID) * 37; } @Override @@ -1291,6 +1353,7 @@ public final class NetworkCapabilities implements Parcelable { dest.writeParcelable((Parcelable) mNetworkSpecifier, flags); dest.writeInt(mSignalStrength); dest.writeArraySet(mUids); + dest.writeString(mSSID); } public static final Creator<NetworkCapabilities> CREATOR = @@ -1308,6 +1371,7 @@ public final class NetworkCapabilities implements Parcelable { netCap.mSignalStrength = in.readInt(); netCap.mUids = (ArraySet<UidRange>) in.readArraySet( null /* ClassLoader, null for default */); + netCap.mSSID = in.readString(); return netCap; } @Override @@ -1358,6 +1422,10 @@ public final class NetworkCapabilities implements Parcelable { sb.append(" EstablishingAppUid: ").append(mEstablishingVpnAppUid); } + if (null != mSSID) { + sb.append(" SSID: ").append(mSSID); + } + sb.append("]"); return sb.toString(); } diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index 6463bed639a9..079d81559983 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -1383,7 +1383,8 @@ public class ConnectivityService extends IConnectivityManager.Stub if (nai != null) { synchronized (nai) { if (nai.networkCapabilities != null) { - return networkCapabilitiesWithoutUidsUnlessAllowed(nai.networkCapabilities, + return networkCapabilitiesRestrictedForCallerPermissions( + nai.networkCapabilities, Binder.getCallingPid(), Binder.getCallingUid()); } } @@ -1397,10 +1398,12 @@ public class ConnectivityService extends IConnectivityManager.Stub return getNetworkCapabilitiesInternal(getNetworkAgentInfoForNetwork(network)); } - private NetworkCapabilities networkCapabilitiesWithoutUidsUnlessAllowed( + private NetworkCapabilities networkCapabilitiesRestrictedForCallerPermissions( NetworkCapabilities nc, int callerPid, int callerUid) { - if (checkSettingsPermission(callerPid, callerUid)) return new NetworkCapabilities(nc); - return new NetworkCapabilities(nc).setUids(null); + final NetworkCapabilities newNc = new NetworkCapabilities(nc); + if (!checkSettingsPermission(callerPid, callerUid)) newNc.setUids(null); + if (!checkNetworkStackPermission(callerPid, callerUid)) newNc.setSSID(null); + return newNc; } private void restrictRequestUidsForCaller(NetworkCapabilities nc) { @@ -1659,6 +1662,11 @@ public class ConnectivityService extends IConnectivityManager.Stub android.Manifest.permission.NETWORK_SETTINGS, pid, uid); } + private boolean checkNetworkStackPermission(int pid, int uid) { + return PERMISSION_GRANTED == mContext.checkPermission( + android.Manifest.permission.NETWORK_STACK, pid, uid); + } + private void enforceTetherAccessPermission() { mContext.enforceCallingOrSelfPermission( android.Manifest.permission.ACCESS_NETWORK_STATE, @@ -4235,6 +4243,15 @@ public class ConnectivityService extends IConnectivityManager.Stub } } + // This checks that the passed capabilities either do not request a specific SSID, or the + // calling app has permission to do so. + private void ensureSufficientPermissionsForRequest(NetworkCapabilities nc, + int callerPid, int callerUid) { + if (null != nc.getSSID() && !checkNetworkStackPermission(callerPid, callerUid)) { + throw new SecurityException("Insufficient permissions to request a specific SSID"); + } + } + private ArrayList<Integer> getSignalStrengthThresholds(NetworkAgentInfo nai) { final SortedSet<Integer> thresholds = new TreeSet(); synchronized (nai) { @@ -4304,6 +4321,8 @@ public class ConnectivityService extends IConnectivityManager.Stub enforceMeteredApnPolicy(networkCapabilities); } ensureRequestableCapabilities(networkCapabilities); + ensureSufficientPermissionsForRequest(networkCapabilities, + Binder.getCallingPid(), Binder.getCallingUid()); // Set the UID range for this request to the single UID of the requester, or to an empty // set of UIDs if the caller has the appropriate permission and UIDs have not been set. // This will overwrite any allowed UIDs in the requested capabilities. Though there @@ -4382,6 +4401,8 @@ public class ConnectivityService extends IConnectivityManager.Stub enforceNetworkRequestPermissions(networkCapabilities); enforceMeteredApnPolicy(networkCapabilities); ensureRequestableCapabilities(networkCapabilities); + ensureSufficientPermissionsForRequest(networkCapabilities, + Binder.getCallingPid(), Binder.getCallingUid()); ensureValidNetworkSpecifier(networkCapabilities); restrictRequestUidsForCaller(networkCapabilities); @@ -4437,6 +4458,8 @@ public class ConnectivityService extends IConnectivityManager.Stub } NetworkCapabilities nc = new NetworkCapabilities(networkCapabilities); + ensureSufficientPermissionsForRequest(networkCapabilities, + Binder.getCallingPid(), Binder.getCallingUid()); restrictRequestUidsForCaller(nc); // Apps without the CHANGE_NETWORK_STATE permission can't use background networks, so // make all their listens include NET_CAPABILITY_FOREGROUND. That way, they will get @@ -4463,6 +4486,8 @@ public class ConnectivityService extends IConnectivityManager.Stub enforceAccessPermission(); } ensureValidNetworkSpecifier(networkCapabilities); + ensureSufficientPermissionsForRequest(networkCapabilities, + Binder.getCallingPid(), Binder.getCallingUid()); final NetworkCapabilities nc = new NetworkCapabilities(networkCapabilities); restrictRequestUidsForCaller(nc); @@ -5034,7 +5059,7 @@ public class ConnectivityService extends IConnectivityManager.Stub } case ConnectivityManager.CALLBACK_CAP_CHANGED: { // networkAgent can't be null as it has been accessed a few lines above. - final NetworkCapabilities nc = networkCapabilitiesWithoutUidsUnlessAllowed( + final NetworkCapabilities nc = networkCapabilitiesRestrictedForCallerPermissions( networkAgent.networkCapabilities, nri.mPid, nri.mUid); putParcelable(bundle, nc); break; diff --git a/tests/net/java/android/net/NetworkCapabilitiesTest.java b/tests/net/java/android/net/NetworkCapabilitiesTest.java index cdb4307d70e8..da897ae9ea0b 100644 --- a/tests/net/java/android/net/NetworkCapabilitiesTest.java +++ b/tests/net/java/android/net/NetworkCapabilitiesTest.java @@ -39,12 +39,14 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; import android.os.Parcel; import android.support.test.runner.AndroidJUnit4; import android.test.suitebuilder.annotation.SmallTest; import android.util.ArraySet; + import org.junit.Test; import org.junit.runner.RunWith; @@ -53,6 +55,8 @@ import java.util.Set; @RunWith(AndroidJUnit4.class) @SmallTest public class NetworkCapabilitiesTest { + private static final String TEST_SSID = "TEST_SSID"; + @Test public void testMaybeMarkCapabilitiesRestricted() { // verify EIMS is restricted @@ -259,6 +263,8 @@ public class NetworkCapabilitiesTest { .addCapability(NET_CAPABILITY_EIMS) .addCapability(NET_CAPABILITY_NOT_METERED); assertEqualsThroughMarshalling(netCap); + netCap.setSSID(TEST_SSID); + assertEqualsThroughMarshalling(netCap); } @Test @@ -354,6 +360,21 @@ public class NetworkCapabilitiesTest { } @Test + public void testSSID() { + NetworkCapabilities nc1 = new NetworkCapabilities(); + NetworkCapabilities nc2 = new NetworkCapabilities(); + assertTrue(nc2.satisfiedBySSID(nc1)); + + nc1.setSSID(TEST_SSID); + assertTrue(nc2.satisfiedBySSID(nc1)); + nc2.setSSID("different " + TEST_SSID); + assertFalse(nc2.satisfiedBySSID(nc1)); + + assertTrue(nc1.satisfiedByImmutableNetworkCapabilities(nc2)); + assertFalse(nc1.satisfiedByNetworkCapabilities(nc2)); + } + + @Test public void testCombineCapabilities() { NetworkCapabilities nc1 = new NetworkCapabilities(); NetworkCapabilities nc2 = new NetworkCapabilities(); @@ -374,6 +395,19 @@ public class NetworkCapabilitiesTest { // will never be satisfied. assertTrue(nc2.hasCapability(NET_CAPABILITY_NOT_ROAMING)); assertTrue(nc2.hasUnwantedCapability(NET_CAPABILITY_NOT_ROAMING)); + + nc1.setSSID(TEST_SSID); + nc2.combineCapabilities(nc1); + assertTrue(TEST_SSID.equals(nc2.getSSID())); + + // Because they now have the same SSID, the folllowing call should not throw + nc2.combineCapabilities(nc1); + + nc1.setSSID("different " + TEST_SSID); + try { + nc2.combineCapabilities(nc1); + fail("Expected IllegalStateException: can't combine different SSIDs"); + } catch (IllegalStateException expected) {} } @Test |