Add a new ssid field in NetworkCapabilities.

Bug: 77891227
Test: frameworks-net
Change-Id: Ifba33ecd48ccecce7e8f8d05ff70bb85653f6163
This commit is contained in:
Chalard Jean
2018-04-11 21:09:10 +09:00
parent d5b916a0a8
commit 3ec2c0fc84
3 changed files with 137 additions and 10 deletions

View File

@@ -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;
}
/**
@@ -922,7 +924,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
@@ -1054,7 +1056,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
@@ -1144,6 +1146,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
@@ -1155,6 +1213,7 @@ public final class NetworkCapabilities implements Parcelable {
combineSpecifiers(nc);
combineSignalStrength(nc);
combineUids(nc);
combineSSIDs(nc);
}
/**
@@ -1173,7 +1232,8 @@ public final class NetworkCapabilities implements Parcelable {
&& (onlyImmutable || satisfiedByLinkBandwidths(nc))
&& satisfiedBySpecifier(nc)
&& (onlyImmutable || satisfiedBySignalStrength(nc))
&& (onlyImmutable || satisfiedByUids(nc)));
&& (onlyImmutable || satisfiedByUids(nc))
&& (onlyImmutable || satisfiedBySSID(nc)));
}
/**
@@ -1260,7 +1320,8 @@ public final class NetworkCapabilities implements Parcelable {
&& equalsLinkBandwidths(that)
&& equalsSignalStrength(that)
&& equalsSpecifier(that)
&& equalsUids(that));
&& equalsUids(that)
&& equalsSSID(that));
}
@Override
@@ -1275,7 +1336,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
@@ -1292,6 +1354,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 =
@@ -1309,6 +1372,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
@@ -1359,6 +1423,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();
}

View File

@@ -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;

View File

@@ -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
@@ -353,6 +359,21 @@ public class NetworkCapabilitiesTest {
assertTrue(nc1.equalsNetCapabilities(nc2));
}
@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();
@@ -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