Merge changes from topics "revert-1645768-revert-1626206-replaceUidRange-MSYTKFNGUE-HIUTVTIGIR", "ti_redaction"
* changes: TransportInfo: Add a generic redaction mechanism Revert "Revert "Expose uids related APIs in NetworkRequest and N..." Revert^2 "Replace the usage of UidRange"
This commit is contained in:
@@ -37,9 +37,24 @@ package android.net {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public final class NetworkCapabilities implements android.os.Parcelable {
|
public final class NetworkCapabilities implements android.os.Parcelable {
|
||||||
|
ctor public NetworkCapabilities(@Nullable android.net.NetworkCapabilities, long);
|
||||||
|
method @Nullable public java.util.Set<android.util.Range<java.lang.Integer>> getUids();
|
||||||
|
field public static final long REDACT_ALL = -1L; // 0xffffffffffffffffL
|
||||||
|
field public static final long REDACT_FOR_ACCESS_FINE_LOCATION = 1L; // 0x1L
|
||||||
|
field public static final long REDACT_FOR_LOCAL_MAC_ADDRESS = 2L; // 0x2L
|
||||||
|
field public static final long REDACT_FOR_NETWORK_SETTINGS = 4L; // 0x4L
|
||||||
|
field public static final long REDACT_NONE = 0L; // 0x0L
|
||||||
field public static final int TRANSPORT_TEST = 7; // 0x7
|
field public static final int TRANSPORT_TEST = 7; // 0x7
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static final class NetworkCapabilities.Builder {
|
||||||
|
method @NonNull public android.net.NetworkCapabilities.Builder setUids(@Nullable java.util.Set<android.util.Range<java.lang.Integer>>);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class NetworkRequest.Builder {
|
||||||
|
method @NonNull public android.net.NetworkRequest.Builder setUids(@Nullable java.util.Set<android.util.Range<java.lang.Integer>>);
|
||||||
|
}
|
||||||
|
|
||||||
public class ParseException extends java.lang.RuntimeException {
|
public class ParseException extends java.lang.RuntimeException {
|
||||||
ctor public ParseException(@NonNull String);
|
ctor public ParseException(@NonNull String);
|
||||||
ctor public ParseException(@NonNull String, @NonNull Throwable);
|
ctor public ParseException(@NonNull String, @NonNull Throwable);
|
||||||
@@ -80,6 +95,11 @@ package android.net {
|
|||||||
field @NonNull public static final android.os.Parcelable.Creator<android.net.TestNetworkSpecifier> CREATOR;
|
field @NonNull public static final android.os.Parcelable.Creator<android.net.TestNetworkSpecifier> CREATOR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public interface TransportInfo {
|
||||||
|
method public default long getApplicableRedactions();
|
||||||
|
method @NonNull public default android.net.TransportInfo makeCopy(long);
|
||||||
|
}
|
||||||
|
|
||||||
public final class VpnTransportInfo implements android.os.Parcelable android.net.TransportInfo {
|
public final class VpnTransportInfo implements android.os.Parcelable android.net.TransportInfo {
|
||||||
ctor public VpnTransportInfo(int);
|
ctor public VpnTransportInfo(int);
|
||||||
method public int describeContents();
|
method public int describeContents();
|
||||||
|
|||||||
@@ -261,7 +261,6 @@ package android.net {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public final class NetworkCapabilities implements android.os.Parcelable {
|
public final class NetworkCapabilities implements android.os.Parcelable {
|
||||||
ctor public NetworkCapabilities(@Nullable android.net.NetworkCapabilities, boolean);
|
|
||||||
method @NonNull public int[] getAdministratorUids();
|
method @NonNull public int[] getAdministratorUids();
|
||||||
method @Nullable public String getSsid();
|
method @Nullable public String getSsid();
|
||||||
method @NonNull public int[] getTransportTypes();
|
method @NonNull public int[] getTransportTypes();
|
||||||
@@ -435,11 +434,6 @@ package android.net {
|
|||||||
field public final int tcpWindowScale;
|
field public final int tcpWindowScale;
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface TransportInfo {
|
|
||||||
method public default boolean hasLocationSensitiveFields();
|
|
||||||
method @NonNull public default android.net.TransportInfo makeCopy(boolean);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
package android.net.apf {
|
package android.net.apf {
|
||||||
|
|||||||
@@ -434,7 +434,7 @@ public abstract class NetworkAgent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mInitialConfiguration = new InitialConfiguration(context,
|
mInitialConfiguration = new InitialConfiguration(context,
|
||||||
new NetworkCapabilities(nc, /* parcelLocationSensitiveFields */ true),
|
new NetworkCapabilities(nc, NetworkCapabilities.REDACT_NONE),
|
||||||
new LinkProperties(lp), score, config, ni);
|
new LinkProperties(lp), score, config, ni);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -878,8 +878,7 @@ public abstract class NetworkAgent {
|
|||||||
mBandwidthUpdatePending.set(false);
|
mBandwidthUpdatePending.set(false);
|
||||||
mLastBwRefreshTime = System.currentTimeMillis();
|
mLastBwRefreshTime = System.currentTimeMillis();
|
||||||
final NetworkCapabilities nc =
|
final NetworkCapabilities nc =
|
||||||
new NetworkCapabilities(networkCapabilities,
|
new NetworkCapabilities(networkCapabilities, NetworkCapabilities.REDACT_NONE);
|
||||||
/* parcelLocationSensitiveFields */ true);
|
|
||||||
queueOrSendMessage(reg -> reg.sendNetworkCapabilities(nc));
|
queueOrSendMessage(reg -> reg.sendNetworkCapabilities(nc));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,9 +19,11 @@ package android.net;
|
|||||||
import static com.android.internal.annotations.VisibleForTesting.Visibility.PRIVATE;
|
import static com.android.internal.annotations.VisibleForTesting.Visibility.PRIVATE;
|
||||||
|
|
||||||
import android.annotation.IntDef;
|
import android.annotation.IntDef;
|
||||||
|
import android.annotation.LongDef;
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
import android.annotation.Nullable;
|
import android.annotation.Nullable;
|
||||||
import android.annotation.RequiresPermission;
|
import android.annotation.RequiresPermission;
|
||||||
|
import android.annotation.SuppressLint;
|
||||||
import android.annotation.SystemApi;
|
import android.annotation.SystemApi;
|
||||||
import android.compat.annotation.UnsupportedAppUsage;
|
import android.compat.annotation.UnsupportedAppUsage;
|
||||||
import android.net.ConnectivityManager.NetworkCallback;
|
import android.net.ConnectivityManager.NetworkCallback;
|
||||||
@@ -32,6 +34,7 @@ import android.os.Parcelable;
|
|||||||
import android.os.Process;
|
import android.os.Process;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.ArraySet;
|
import android.util.ArraySet;
|
||||||
|
import android.util.Range;
|
||||||
import android.util.proto.ProtoOutputStream;
|
import android.util.proto.ProtoOutputStream;
|
||||||
|
|
||||||
import com.android.internal.annotations.VisibleForTesting;
|
import com.android.internal.annotations.VisibleForTesting;
|
||||||
@@ -63,6 +66,68 @@ import java.util.StringJoiner;
|
|||||||
public final class NetworkCapabilities implements Parcelable {
|
public final class NetworkCapabilities implements Parcelable {
|
||||||
private static final String TAG = "NetworkCapabilities";
|
private static final String TAG = "NetworkCapabilities";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mechanism to support redaction of fields in NetworkCapabilities that are guarded by specific
|
||||||
|
* app permissions.
|
||||||
|
**/
|
||||||
|
/**
|
||||||
|
* Don't redact any fields since the receiving app holds all the necessary permissions.
|
||||||
|
*
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
|
||||||
|
public static final long REDACT_NONE = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Redact any fields that need {@link android.Manifest.permission#ACCESS_FINE_LOCATION}
|
||||||
|
* permission since the receiving app does not hold this permission or the location toggle
|
||||||
|
* is off.
|
||||||
|
*
|
||||||
|
* @see android.Manifest.permission#ACCESS_FINE_LOCATION
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
|
||||||
|
public static final long REDACT_FOR_ACCESS_FINE_LOCATION = 1 << 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Redact any fields that need {@link android.Manifest.permission#LOCAL_MAC_ADDRESS}
|
||||||
|
* permission since the receiving app does not hold this permission.
|
||||||
|
*
|
||||||
|
* @see android.Manifest.permission#LOCAL_MAC_ADDRESS
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
|
||||||
|
public static final long REDACT_FOR_LOCAL_MAC_ADDRESS = 1 << 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Redact any fields that need {@link android.Manifest.permission#NETWORK_SETTINGS}
|
||||||
|
* permission since the receiving app does not hold this permission.
|
||||||
|
*
|
||||||
|
* @see android.Manifest.permission#NETWORK_SETTINGS
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
|
||||||
|
public static final long REDACT_FOR_NETWORK_SETTINGS = 1 << 2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Redact all fields in this object that require any relevant permission.
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
|
||||||
|
public static final long REDACT_ALL = -1L;
|
||||||
|
|
||||||
|
/** @hide */
|
||||||
|
@LongDef(flag = true, prefix = { "REDACT_" }, value = {
|
||||||
|
REDACT_NONE,
|
||||||
|
REDACT_FOR_ACCESS_FINE_LOCATION,
|
||||||
|
REDACT_FOR_LOCAL_MAC_ADDRESS,
|
||||||
|
REDACT_FOR_NETWORK_SETTINGS,
|
||||||
|
REDACT_ALL
|
||||||
|
})
|
||||||
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
|
public @interface RedactionType {}
|
||||||
|
|
||||||
// Set to true when private DNS is broken.
|
// Set to true when private DNS is broken.
|
||||||
private boolean mPrivateDnsBroken;
|
private boolean mPrivateDnsBroken;
|
||||||
|
|
||||||
@@ -77,32 +142,31 @@ public final class NetworkCapabilities implements Parcelable {
|
|||||||
private String mRequestorPackageName;
|
private String mRequestorPackageName;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates whether parceling should preserve fields that are set based on permissions of
|
* Indicates what fields should be redacted from this instance.
|
||||||
* the process receiving the {@link NetworkCapabilities}.
|
|
||||||
*/
|
*/
|
||||||
private final boolean mParcelLocationSensitiveFields;
|
private final @RedactionType long mRedactions;
|
||||||
|
|
||||||
public NetworkCapabilities() {
|
public NetworkCapabilities() {
|
||||||
mParcelLocationSensitiveFields = false;
|
mRedactions = REDACT_ALL;
|
||||||
clearAll();
|
clearAll();
|
||||||
mNetworkCapabilities = DEFAULT_CAPABILITIES;
|
mNetworkCapabilities = DEFAULT_CAPABILITIES;
|
||||||
}
|
}
|
||||||
|
|
||||||
public NetworkCapabilities(NetworkCapabilities nc) {
|
public NetworkCapabilities(NetworkCapabilities nc) {
|
||||||
this(nc, false /* parcelLocationSensitiveFields */);
|
this(nc, REDACT_ALL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Make a copy of NetworkCapabilities.
|
* Make a copy of NetworkCapabilities.
|
||||||
*
|
*
|
||||||
* @param nc Original NetworkCapabilities
|
* @param nc Original NetworkCapabilities
|
||||||
* @param parcelLocationSensitiveFields Whether to parcel location sensitive data or not.
|
* @param redactions bitmask of redactions that needs to be performed on this new instance of
|
||||||
|
* {@link NetworkCapabilities}.
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
@SystemApi
|
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
|
||||||
public NetworkCapabilities(
|
public NetworkCapabilities(@Nullable NetworkCapabilities nc, @RedactionType long redactions) {
|
||||||
@Nullable NetworkCapabilities nc, boolean parcelLocationSensitiveFields) {
|
mRedactions = redactions;
|
||||||
mParcelLocationSensitiveFields = parcelLocationSensitiveFields;
|
|
||||||
if (nc != null) {
|
if (nc != null) {
|
||||||
set(nc);
|
set(nc);
|
||||||
}
|
}
|
||||||
@@ -114,11 +178,13 @@ public final class NetworkCapabilities implements Parcelable {
|
|||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
public void clearAll() {
|
public void clearAll() {
|
||||||
// Ensures that the internal copies maintained by the connectivity stack does not set
|
// Ensures that the internal copies maintained by the connectivity stack does not set it to
|
||||||
// this bit.
|
// anything other than |REDACT_ALL|.
|
||||||
if (mParcelLocationSensitiveFields) {
|
if (mRedactions != REDACT_ALL) {
|
||||||
|
// This is needed because the current redaction mechanism relies on redaction while
|
||||||
|
// parceling.
|
||||||
throw new UnsupportedOperationException(
|
throw new UnsupportedOperationException(
|
||||||
"Cannot clear NetworkCapabilities when parcelLocationSensitiveFields is set");
|
"Cannot clear NetworkCapabilities when mRedactions is set");
|
||||||
}
|
}
|
||||||
mNetworkCapabilities = mTransportTypes = mUnwantedNetworkCapabilities = 0;
|
mNetworkCapabilities = mTransportTypes = mUnwantedNetworkCapabilities = 0;
|
||||||
mLinkUpBandwidthKbps = mLinkDownBandwidthKbps = LINK_BANDWIDTH_UNSPECIFIED;
|
mLinkUpBandwidthKbps = mLinkDownBandwidthKbps = LINK_BANDWIDTH_UNSPECIFIED;
|
||||||
@@ -148,12 +214,12 @@ public final class NetworkCapabilities implements Parcelable {
|
|||||||
mLinkDownBandwidthKbps = nc.mLinkDownBandwidthKbps;
|
mLinkDownBandwidthKbps = nc.mLinkDownBandwidthKbps;
|
||||||
mNetworkSpecifier = nc.mNetworkSpecifier;
|
mNetworkSpecifier = nc.mNetworkSpecifier;
|
||||||
if (nc.getTransportInfo() != null) {
|
if (nc.getTransportInfo() != null) {
|
||||||
setTransportInfo(nc.getTransportInfo().makeCopy(mParcelLocationSensitiveFields));
|
setTransportInfo(nc.getTransportInfo().makeCopy(mRedactions));
|
||||||
} else {
|
} else {
|
||||||
setTransportInfo(null);
|
setTransportInfo(null);
|
||||||
}
|
}
|
||||||
mSignalStrength = nc.mSignalStrength;
|
mSignalStrength = nc.mSignalStrength;
|
||||||
setUids(nc.mUids); // Will make the defensive copy
|
mUids = (nc.mUids == null) ? null : new ArraySet<>(nc.mUids);
|
||||||
setAdministratorUids(nc.getAdministratorUids());
|
setAdministratorUids(nc.getAdministratorUids());
|
||||||
mOwnerUid = nc.mOwnerUid;
|
mOwnerUid = nc.mOwnerUid;
|
||||||
mUnwantedNetworkCapabilities = nc.mUnwantedNetworkCapabilities;
|
mUnwantedNetworkCapabilities = nc.mUnwantedNetworkCapabilities;
|
||||||
@@ -1456,9 +1522,8 @@ public final class NetworkCapabilities implements Parcelable {
|
|||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
public @NonNull NetworkCapabilities setSingleUid(int uid) {
|
public @NonNull NetworkCapabilities setSingleUid(int uid) {
|
||||||
final ArraySet<UidRange> identity = new ArraySet<>(1);
|
mUids = new ArraySet<>(1);
|
||||||
identity.add(new UidRange(uid, uid));
|
mUids.add(new UidRange(uid, uid));
|
||||||
setUids(identity);
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1467,22 +1532,34 @@ public final class NetworkCapabilities implements Parcelable {
|
|||||||
* This makes a copy of the set so that callers can't modify it after the call.
|
* This makes a copy of the set so that callers can't modify it after the call.
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
public @NonNull NetworkCapabilities setUids(Set<UidRange> uids) {
|
public @NonNull NetworkCapabilities setUids(@Nullable Set<Range<Integer>> uids) {
|
||||||
if (null == uids) {
|
mUids = UidRange.fromIntRanges(uids);
|
||||||
mUids = null;
|
|
||||||
} else {
|
|
||||||
mUids = new ArraySet<>(uids);
|
|
||||||
}
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the list of UIDs this network applies to.
|
||||||
|
* This returns a copy of the set so that callers can't modify the original object.
|
||||||
|
*
|
||||||
|
* @return the list of UIDs this network applies to. If {@code null}, then the network applies
|
||||||
|
* to all UIDs.
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
|
||||||
|
@SuppressLint("NullableCollection")
|
||||||
|
public @Nullable Set<Range<Integer>> getUids() {
|
||||||
|
return UidRange.toIntRanges(mUids);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the list of UIDs this network applies to.
|
* Get the list of UIDs this network applies to.
|
||||||
* This returns a copy of the set so that callers can't modify the original object.
|
* This returns a copy of the set so that callers can't modify the original object.
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
public @Nullable Set<UidRange> getUids() {
|
public @Nullable Set<UidRange> getUidRanges() {
|
||||||
return null == mUids ? null : new ArraySet<>(mUids);
|
if (mUids == null) return null;
|
||||||
|
|
||||||
|
return new ArraySet<>(mUids);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -2335,6 +2412,23 @@ public final class NetworkCapabilities implements Parcelable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a bitmask of all the applicable redactions (based on the permissions held by the
|
||||||
|
* receiving app) to be performed on this object.
|
||||||
|
*
|
||||||
|
* @return bitmask of redactions applicable on this instance.
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public @RedactionType long getApplicableRedactions() {
|
||||||
|
// Currently, there are no fields redacted in NetworkCapabilities itself, so we just
|
||||||
|
// passthrough the redactions required by the embedded TransportInfo. If this changes
|
||||||
|
// in the future, modify this method.
|
||||||
|
if (mTransportInfo == null) {
|
||||||
|
return NetworkCapabilities.REDACT_NONE;
|
||||||
|
}
|
||||||
|
return mTransportInfo.getApplicableRedactions();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Builder class for NetworkCapabilities.
|
* Builder class for NetworkCapabilities.
|
||||||
*
|
*
|
||||||
@@ -2652,6 +2746,21 @@ public final class NetworkCapabilities implements Parcelable {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the list of UIDs this network applies to.
|
||||||
|
*
|
||||||
|
* @param uids the list of UIDs this network applies to, or {@code null} if this network
|
||||||
|
* applies to all UIDs.
|
||||||
|
* @return this builder
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
|
||||||
|
public Builder setUids(@Nullable Set<Range<Integer>> uids) {
|
||||||
|
mCaps.setUids(uids);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Builds the instance of the capabilities.
|
* Builds the instance of the capabilities.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ import static android.net.NetworkCapabilities.TRANSPORT_TEST;
|
|||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
import android.annotation.Nullable;
|
import android.annotation.Nullable;
|
||||||
import android.annotation.RequiresPermission;
|
import android.annotation.RequiresPermission;
|
||||||
|
import android.annotation.SuppressLint;
|
||||||
import android.annotation.SystemApi;
|
import android.annotation.SystemApi;
|
||||||
import android.compat.annotation.UnsupportedAppUsage;
|
import android.compat.annotation.UnsupportedAppUsage;
|
||||||
import android.net.NetworkCapabilities.NetCapability;
|
import android.net.NetworkCapabilities.NetCapability;
|
||||||
@@ -45,6 +46,7 @@ import android.os.Parcel;
|
|||||||
import android.os.Parcelable;
|
import android.os.Parcelable;
|
||||||
import android.os.Process;
|
import android.os.Process;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
|
import android.util.Range;
|
||||||
import android.util.proto.ProtoOutputStream;
|
import android.util.proto.ProtoOutputStream;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
@@ -277,11 +279,14 @@ public class NetworkRequest implements Parcelable {
|
|||||||
* Set the watched UIDs for this request. This will be reset and wiped out unless
|
* Set the watched UIDs for this request. This will be reset and wiped out unless
|
||||||
* the calling app holds the CHANGE_NETWORK_STATE permission.
|
* the calling app holds the CHANGE_NETWORK_STATE permission.
|
||||||
*
|
*
|
||||||
* @param uids The watched UIDs as a set of UidRanges, or null for everything.
|
* @param uids The watched UIDs as a set of {@code Range<Integer>}, or null for everything.
|
||||||
* @return The builder to facilitate chaining.
|
* @return The builder to facilitate chaining.
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
public Builder setUids(Set<UidRange> uids) {
|
@NonNull
|
||||||
|
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
|
||||||
|
@SuppressLint("MissingGetterMatchingBuilder")
|
||||||
|
public Builder setUids(@Nullable Set<Range<Integer>> uids) {
|
||||||
mNetworkCapabilities.setUids(uids);
|
mNetworkCapabilities.setUids(uids);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,35 +29,47 @@ import android.annotation.SystemApi;
|
|||||||
public interface TransportInfo {
|
public interface TransportInfo {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a copy of a {@link TransportInfo} that will preserve location sensitive fields that
|
* Create a copy of a {@link TransportInfo} with some fields redacted based on the permissions
|
||||||
* were set based on the permissions of the process that originally received it.
|
* held by the receiving app.
|
||||||
*
|
*
|
||||||
* <p>By default {@link TransportInfo} does not preserve such fields during parceling, as
|
* <p>
|
||||||
* they should not be shared outside of the process that receives them without appropriate
|
* Usage by connectivity stack:
|
||||||
* checks.
|
* <ul>
|
||||||
|
* <li> Connectivity stack will invoke {@link #getApplicableRedactions()} to find the list
|
||||||
|
* of redactions that are required by this {@link TransportInfo} instance.</li>
|
||||||
|
* <li> Connectivity stack then loops through each bit in the bitmask returned and checks if the
|
||||||
|
* receiving app holds the corresponding permission.
|
||||||
|
* <ul>
|
||||||
|
* <li> If the app holds the corresponding permission, the bit is cleared from the
|
||||||
|
* |redactions| bitmask. </li>
|
||||||
|
* <li> If the app does not hold the corresponding permission, the bit is retained in the
|
||||||
|
* |redactions| bitmask. </li>
|
||||||
|
* </ul>
|
||||||
|
* <li> Connectivity stack then invokes {@link #makeCopy(long)} with the necessary |redactions|
|
||||||
|
* to create a copy to send to the corresponding app. </li>
|
||||||
|
* </ul>
|
||||||
|
* </p>
|
||||||
*
|
*
|
||||||
* @param parcelLocationSensitiveFields Whether the location sensitive fields should be kept
|
* @param redactions bitmask of redactions that needs to be performed on this instance.
|
||||||
* when parceling
|
* @return Copy of this instance with the necessary redactions.
|
||||||
* @return Copy of this instance.
|
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
@SystemApi
|
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
|
||||||
@NonNull
|
@NonNull
|
||||||
default TransportInfo makeCopy(boolean parcelLocationSensitiveFields) {
|
default TransportInfo makeCopy(@NetworkCapabilities.RedactionType long redactions) {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether this TransportInfo type has location sensitive fields or not (helps
|
* Returns a bitmask of all the applicable redactions (based on the permissions held by the
|
||||||
* to determine whether to perform a location permission check or not before sending to
|
* receiving app) to be performed on this TransportInfo.
|
||||||
* apps).
|
|
||||||
*
|
*
|
||||||
* @return {@code true} if this instance contains location sensitive info, {@code false}
|
* @return bitmask of redactions applicable on this instance.
|
||||||
* otherwise.
|
* @see #makeCopy(long)
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
@SystemApi
|
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
|
||||||
default boolean hasLocationSensitiveFields() {
|
default @NetworkCapabilities.RedactionType long getApplicableRedactions() {
|
||||||
return false;
|
return NetworkCapabilities.REDACT_NONE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,8 +20,11 @@ import android.annotation.Nullable;
|
|||||||
import android.os.Parcel;
|
import android.os.Parcel;
|
||||||
import android.os.Parcelable;
|
import android.os.Parcelable;
|
||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
|
import android.util.ArraySet;
|
||||||
|
import android.util.Range;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An inclusive range of UIDs.
|
* An inclusive range of UIDs.
|
||||||
@@ -149,4 +152,32 @@ public final class UidRange implements Parcelable {
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert a set of {@code Range<Integer>} to a set of {@link UidRange}.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
public static ArraySet<UidRange> fromIntRanges(@Nullable Set<Range<Integer>> ranges) {
|
||||||
|
if (null == ranges) return null;
|
||||||
|
|
||||||
|
final ArraySet<UidRange> uids = new ArraySet<>();
|
||||||
|
for (Range<Integer> range : ranges) {
|
||||||
|
uids.add(new UidRange(range.getLower(), range.getUpper()));
|
||||||
|
}
|
||||||
|
return uids;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert a set of {@link UidRange} to a set of {@code Range<Integer>}.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
public static ArraySet<Range<Integer>> toIntRanges(@Nullable Set<UidRange> ranges) {
|
||||||
|
if (null == ranges) return null;
|
||||||
|
|
||||||
|
final ArraySet<Range<Integer>> uids = new ArraySet<>();
|
||||||
|
for (UidRange range : ranges) {
|
||||||
|
uids.add(new Range<Integer>(range.start, range.stop));
|
||||||
|
}
|
||||||
|
return uids;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -69,6 +69,9 @@ import static android.net.NetworkCapabilities.NET_CAPABILITY_OEM_PAID;
|
|||||||
import static android.net.NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE;
|
import static android.net.NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE;
|
||||||
import static android.net.NetworkCapabilities.NET_CAPABILITY_PARTIAL_CONNECTIVITY;
|
import static android.net.NetworkCapabilities.NET_CAPABILITY_PARTIAL_CONNECTIVITY;
|
||||||
import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
|
import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
|
||||||
|
import static android.net.NetworkCapabilities.REDACT_FOR_ACCESS_FINE_LOCATION;
|
||||||
|
import static android.net.NetworkCapabilities.REDACT_FOR_LOCAL_MAC_ADDRESS;
|
||||||
|
import static android.net.NetworkCapabilities.REDACT_FOR_NETWORK_SETTINGS;
|
||||||
import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
|
import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
|
||||||
import static android.net.NetworkCapabilities.TRANSPORT_TEST;
|
import static android.net.NetworkCapabilities.TRANSPORT_TEST;
|
||||||
import static android.net.NetworkCapabilities.TRANSPORT_VPN;
|
import static android.net.NetworkCapabilities.TRANSPORT_VPN;
|
||||||
@@ -1335,7 +1338,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
netCap.addCapability(NET_CAPABILITY_INTERNET);
|
netCap.addCapability(NET_CAPABILITY_INTERNET);
|
||||||
netCap.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED);
|
netCap.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED);
|
||||||
netCap.removeCapability(NET_CAPABILITY_NOT_VPN);
|
netCap.removeCapability(NET_CAPABILITY_NOT_VPN);
|
||||||
netCap.setUids(Collections.singleton(uids));
|
netCap.setUids(UidRange.toIntRanges(Collections.singleton(uids)));
|
||||||
return netCap;
|
return netCap;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1771,7 +1774,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
nai.network,
|
nai.network,
|
||||||
createWithLocationInfoSanitizedIfNecessaryWhenParceled(
|
createWithLocationInfoSanitizedIfNecessaryWhenParceled(
|
||||||
nc, false /* includeLocationSensitiveInfo */,
|
nc, false /* includeLocationSensitiveInfo */,
|
||||||
mDeps.getCallingUid(), callingPackageName, callingAttributionTag));
|
getCallingPid(), mDeps.getCallingUid(), callingPackageName,
|
||||||
|
callingAttributionTag));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1786,7 +1790,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
createWithLocationInfoSanitizedIfNecessaryWhenParceled(
|
createWithLocationInfoSanitizedIfNecessaryWhenParceled(
|
||||||
nc,
|
nc,
|
||||||
false /* includeLocationSensitiveInfo */,
|
false /* includeLocationSensitiveInfo */,
|
||||||
mDeps.getCallingUid(), callingPackageName,
|
getCallingPid(), mDeps.getCallingUid(), callingPackageName,
|
||||||
callingAttributionTag));
|
callingAttributionTag));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1869,7 +1873,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
return createWithLocationInfoSanitizedIfNecessaryWhenParceled(
|
return createWithLocationInfoSanitizedIfNecessaryWhenParceled(
|
||||||
getNetworkCapabilitiesInternal(network),
|
getNetworkCapabilitiesInternal(network),
|
||||||
false /* includeLocationSensitiveInfo */,
|
false /* includeLocationSensitiveInfo */,
|
||||||
mDeps.getCallingUid(), callingPackageName, callingAttributionTag);
|
getCallingPid(), mDeps.getCallingUid(), callingPackageName, callingAttributionTag);
|
||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
@@ -1888,40 +1892,137 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
return newNc;
|
return newNc;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean hasLocationPermission(int callerUid, @NonNull String callerPkgName,
|
/**
|
||||||
@Nullable String callingAttributionTag) {
|
* Wrapper used to cache the permission check results performed for the corresponding
|
||||||
|
* app. This avoid performing multiple permission checks for different fields in
|
||||||
|
* NetworkCapabilities.
|
||||||
|
* Note: This wrapper does not support any sort of invalidation and thus must not be
|
||||||
|
* persistent or long-lived. It may only be used for the time necessary to
|
||||||
|
* compute the redactions required by one particular NetworkCallback or
|
||||||
|
* synchronous call.
|
||||||
|
*/
|
||||||
|
private class RedactionPermissionChecker {
|
||||||
|
private final int mCallingPid;
|
||||||
|
private final int mCallingUid;
|
||||||
|
@NonNull private final String mCallingPackageName;
|
||||||
|
@Nullable private final String mCallingAttributionTag;
|
||||||
|
|
||||||
|
private Boolean mHasLocationPermission = null;
|
||||||
|
private Boolean mHasLocalMacAddressPermission = null;
|
||||||
|
private Boolean mHasSettingsPermission = null;
|
||||||
|
|
||||||
|
RedactionPermissionChecker(int callingPid, int callingUid,
|
||||||
|
@NonNull String callingPackageName, @Nullable String callingAttributionTag) {
|
||||||
|
mCallingPid = callingPid;
|
||||||
|
mCallingUid = callingUid;
|
||||||
|
mCallingPackageName = callingPackageName;
|
||||||
|
mCallingAttributionTag = callingAttributionTag;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean hasLocationPermissionInternal() {
|
||||||
final long token = Binder.clearCallingIdentity();
|
final long token = Binder.clearCallingIdentity();
|
||||||
try {
|
try {
|
||||||
return mLocationPermissionChecker.checkLocationPermission(
|
return mLocationPermissionChecker.checkLocationPermission(
|
||||||
callerPkgName, callingAttributionTag, callerUid, null /* message */);
|
mCallingPackageName, mCallingAttributionTag, mCallingUid,
|
||||||
|
null /* message */);
|
||||||
} finally {
|
} finally {
|
||||||
Binder.restoreCallingIdentity(token);
|
Binder.restoreCallingIdentity(token);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether the app holds location permission or not (might return cached result
|
||||||
|
* if the permission was already checked before).
|
||||||
|
*/
|
||||||
|
public boolean hasLocationPermission() {
|
||||||
|
if (mHasLocationPermission == null) {
|
||||||
|
// If there is no cached result, perform the check now.
|
||||||
|
mHasLocationPermission = hasLocationPermissionInternal();
|
||||||
|
}
|
||||||
|
return mHasLocationPermission;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether the app holds local mac address permission or not (might return cached
|
||||||
|
* result if the permission was already checked before).
|
||||||
|
*/
|
||||||
|
public boolean hasLocalMacAddressPermission() {
|
||||||
|
if (mHasLocalMacAddressPermission == null) {
|
||||||
|
// If there is no cached result, perform the check now.
|
||||||
|
mHasLocalMacAddressPermission =
|
||||||
|
checkLocalMacAddressPermission(mCallingPid, mCallingUid);
|
||||||
|
}
|
||||||
|
return mHasLocalMacAddressPermission;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether the app holds settings permission or not (might return cached
|
||||||
|
* result if the permission was already checked before).
|
||||||
|
*/
|
||||||
|
public boolean hasSettingsPermission() {
|
||||||
|
if (mHasSettingsPermission == null) {
|
||||||
|
// If there is no cached result, perform the check now.
|
||||||
|
mHasSettingsPermission = checkSettingsPermission(mCallingPid, mCallingUid);
|
||||||
|
}
|
||||||
|
return mHasSettingsPermission;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean shouldRedact(@NetworkCapabilities.RedactionType long redactions,
|
||||||
|
@NetworkCapabilities.NetCapability long redaction) {
|
||||||
|
return (redactions & redaction) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use the provided |applicableRedactions| to check the receiving app's
|
||||||
|
* permissions and clear/set the corresponding bit in the returned bitmask. The bitmask
|
||||||
|
* returned will be used to ensure the necessary redactions are performed by NetworkCapabilities
|
||||||
|
* before being sent to the corresponding app.
|
||||||
|
*/
|
||||||
|
private @NetworkCapabilities.RedactionType long retrieveRequiredRedactions(
|
||||||
|
@NetworkCapabilities.RedactionType long applicableRedactions,
|
||||||
|
@NonNull RedactionPermissionChecker redactionPermissionChecker,
|
||||||
|
boolean includeLocationSensitiveInfo) {
|
||||||
|
long redactions = applicableRedactions;
|
||||||
|
if (shouldRedact(redactions, REDACT_FOR_ACCESS_FINE_LOCATION)) {
|
||||||
|
if (includeLocationSensitiveInfo
|
||||||
|
&& redactionPermissionChecker.hasLocationPermission()) {
|
||||||
|
redactions &= ~REDACT_FOR_ACCESS_FINE_LOCATION;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (shouldRedact(redactions, REDACT_FOR_LOCAL_MAC_ADDRESS)) {
|
||||||
|
if (redactionPermissionChecker.hasLocalMacAddressPermission()) {
|
||||||
|
redactions &= ~REDACT_FOR_LOCAL_MAC_ADDRESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (shouldRedact(redactions, REDACT_FOR_NETWORK_SETTINGS)) {
|
||||||
|
if (redactionPermissionChecker.hasSettingsPermission()) {
|
||||||
|
redactions &= ~REDACT_FOR_NETWORK_SETTINGS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return redactions;
|
||||||
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
@Nullable
|
@Nullable
|
||||||
NetworkCapabilities createWithLocationInfoSanitizedIfNecessaryWhenParceled(
|
NetworkCapabilities createWithLocationInfoSanitizedIfNecessaryWhenParceled(
|
||||||
@Nullable NetworkCapabilities nc, boolean includeLocationSensitiveInfo,
|
@Nullable NetworkCapabilities nc, boolean includeLocationSensitiveInfo,
|
||||||
int callerUid, @NonNull String callerPkgName, @Nullable String callingAttributionTag) {
|
int callingPid, int callingUid, @NonNull String callingPkgName,
|
||||||
|
@Nullable String callingAttributionTag) {
|
||||||
if (nc == null) {
|
if (nc == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
Boolean hasLocationPermission = null;
|
|
||||||
final NetworkCapabilities newNc;
|
|
||||||
// Avoid doing location permission check if the transport info has no location sensitive
|
// Avoid doing location permission check if the transport info has no location sensitive
|
||||||
// data.
|
// data.
|
||||||
if (includeLocationSensitiveInfo
|
final RedactionPermissionChecker redactionPermissionChecker =
|
||||||
&& nc.getTransportInfo() != null
|
new RedactionPermissionChecker(callingPid, callingUid, callingPkgName,
|
||||||
&& nc.getTransportInfo().hasLocationSensitiveFields()) {
|
callingAttributionTag);
|
||||||
hasLocationPermission =
|
final long redactions = retrieveRequiredRedactions(
|
||||||
hasLocationPermission(callerUid, callerPkgName, callingAttributionTag);
|
nc.getApplicableRedactions(), redactionPermissionChecker,
|
||||||
newNc = new NetworkCapabilities(nc, hasLocationPermission);
|
includeLocationSensitiveInfo);
|
||||||
} else {
|
final NetworkCapabilities newNc = new NetworkCapabilities(nc, redactions);
|
||||||
newNc = new NetworkCapabilities(nc, false /* parcelLocationSensitiveFields */);
|
|
||||||
}
|
|
||||||
// Reset owner uid if not destined for the owner app.
|
// Reset owner uid if not destined for the owner app.
|
||||||
if (callerUid != nc.getOwnerUid()) {
|
if (callingUid != nc.getOwnerUid()) {
|
||||||
newNc.setOwnerUid(INVALID_UID);
|
newNc.setOwnerUid(INVALID_UID);
|
||||||
return newNc;
|
return newNc;
|
||||||
}
|
}
|
||||||
@@ -1930,23 +2031,17 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
// Owner UIDs already checked above. No need to re-check.
|
// Owner UIDs already checked above. No need to re-check.
|
||||||
return newNc;
|
return newNc;
|
||||||
}
|
}
|
||||||
// If the caller does not want location sensitive data & target SDK >= S, then mask info.
|
// If the calling does not want location sensitive data & target SDK >= S, then mask info.
|
||||||
// Else include the owner UID iff the caller has location permission to provide backwards
|
// Else include the owner UID iff the calling has location permission to provide backwards
|
||||||
// compatibility for older apps.
|
// compatibility for older apps.
|
||||||
if (!includeLocationSensitiveInfo
|
if (!includeLocationSensitiveInfo
|
||||||
&& isTargetSdkAtleast(
|
&& isTargetSdkAtleast(
|
||||||
Build.VERSION_CODES.S, callerUid, callerPkgName)) {
|
Build.VERSION_CODES.S, callingUid, callingPkgName)) {
|
||||||
newNc.setOwnerUid(INVALID_UID);
|
newNc.setOwnerUid(INVALID_UID);
|
||||||
return newNc;
|
return newNc;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasLocationPermission == null) {
|
|
||||||
// Location permission not checked yet, check now for masking owner UID.
|
|
||||||
hasLocationPermission =
|
|
||||||
hasLocationPermission(callerUid, callerPkgName, callingAttributionTag);
|
|
||||||
}
|
|
||||||
// Reset owner uid if the app has no location permission.
|
// Reset owner uid if the app has no location permission.
|
||||||
if (!hasLocationPermission) {
|
if (!redactionPermissionChecker.hasLocationPermission()) {
|
||||||
newNc.setOwnerUid(INVALID_UID);
|
newNc.setOwnerUid(INVALID_UID);
|
||||||
}
|
}
|
||||||
return newNc;
|
return newNc;
|
||||||
@@ -2437,6 +2532,11 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
mContext.enforceCallingOrSelfPermission(KeepaliveTracker.PERMISSION, "ConnectivityService");
|
mContext.enforceCallingOrSelfPermission(KeepaliveTracker.PERMISSION, "ConnectivityService");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean checkLocalMacAddressPermission(int pid, int uid) {
|
||||||
|
return PERMISSION_GRANTED == mContext.checkPermission(
|
||||||
|
Manifest.permission.LOCAL_MAC_ADDRESS, pid, uid);
|
||||||
|
}
|
||||||
|
|
||||||
private void sendConnectedBroadcast(NetworkInfo info) {
|
private void sendConnectedBroadcast(NetworkInfo info) {
|
||||||
sendGeneralBroadcast(info, CONNECTIVITY_ACTION);
|
sendGeneralBroadcast(info, CONNECTIVITY_ACTION);
|
||||||
}
|
}
|
||||||
@@ -2868,7 +2968,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
if (0 == defaultRequest.mRequests.size()) {
|
if (0 == defaultRequest.mRequests.size()) {
|
||||||
pw.println("none, this should never occur.");
|
pw.println("none, this should never occur.");
|
||||||
} else {
|
} else {
|
||||||
pw.println(defaultRequest.mRequests.get(0).networkCapabilities.getUids());
|
pw.println(defaultRequest.mRequests.get(0).networkCapabilities.getUidRanges());
|
||||||
}
|
}
|
||||||
pw.decreaseIndent();
|
pw.decreaseIndent();
|
||||||
pw.decreaseIndent();
|
pw.decreaseIndent();
|
||||||
@@ -5293,9 +5393,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
private Set<UidRange> getUids() {
|
private Set<UidRange> getUids() {
|
||||||
// networkCapabilities.getUids() returns a defensive copy.
|
// networkCapabilities.getUids() returns a defensive copy.
|
||||||
// multilayer requests will all have the same uids so return the first one.
|
// multilayer requests will all have the same uids so return the first one.
|
||||||
final Set<UidRange> uids = null == mRequests.get(0).networkCapabilities.getUids()
|
final Set<UidRange> uids = mRequests.get(0).networkCapabilities.getUidRanges();
|
||||||
? new ArraySet<>() : mRequests.get(0).networkCapabilities.getUids();
|
return (null == uids) ? new ArraySet<>() : uids;
|
||||||
return uids;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NetworkRequestInfo(@NonNull final NetworkRequest r, @Nullable final PendingIntent pi,
|
NetworkRequestInfo(@NonNull final NetworkRequest r, @Nullable final PendingIntent pi,
|
||||||
@@ -6101,7 +6200,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
for (final NetworkRequestInfo nri : mDefaultNetworkRequests) {
|
for (final NetworkRequestInfo nri : mDefaultNetworkRequests) {
|
||||||
// Currently, all network requests will have the same uids therefore checking the first
|
// Currently, all network requests will have the same uids therefore checking the first
|
||||||
// one is sufficient. If/when uids are tracked at the nri level, this can change.
|
// one is sufficient. If/when uids are tracked at the nri level, this can change.
|
||||||
final Set<UidRange> uids = nri.mRequests.get(0).networkCapabilities.getUids();
|
final Set<UidRange> uids = nri.mRequests.get(0).networkCapabilities.getUidRanges();
|
||||||
if (null == uids) {
|
if (null == uids) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -6542,7 +6641,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final Set<UidRange> ranges = nai.networkCapabilities.getUids();
|
final Set<UidRange> ranges = nai.networkCapabilities.getUidRanges();
|
||||||
final int vpnAppUid = nai.networkCapabilities.getOwnerUid();
|
final int vpnAppUid = nai.networkCapabilities.getOwnerUid();
|
||||||
// TODO: this create a window of opportunity for apps to receive traffic between the time
|
// TODO: this create a window of opportunity for apps to receive traffic between the time
|
||||||
// when the old rules are removed and the time when new rules are added. To fix this,
|
// when the old rules are removed and the time when new rules are added. To fix this,
|
||||||
@@ -6907,8 +7006,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
|
|
||||||
private void updateUids(NetworkAgentInfo nai, NetworkCapabilities prevNc,
|
private void updateUids(NetworkAgentInfo nai, NetworkCapabilities prevNc,
|
||||||
NetworkCapabilities newNc) {
|
NetworkCapabilities newNc) {
|
||||||
Set<UidRange> prevRanges = null == prevNc ? null : prevNc.getUids();
|
Set<UidRange> prevRanges = null == prevNc ? null : prevNc.getUidRanges();
|
||||||
Set<UidRange> newRanges = null == newNc ? null : newNc.getUids();
|
Set<UidRange> newRanges = null == newNc ? null : newNc.getUidRanges();
|
||||||
if (null == prevRanges) prevRanges = new ArraySet<>();
|
if (null == prevRanges) prevRanges = new ArraySet<>();
|
||||||
if (null == newRanges) newRanges = new ArraySet<>();
|
if (null == newRanges) newRanges = new ArraySet<>();
|
||||||
final Set<UidRange> prevRangesCopy = new ArraySet<>(prevRanges);
|
final Set<UidRange> prevRangesCopy = new ArraySet<>(prevRanges);
|
||||||
@@ -7144,7 +7243,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
putParcelable(
|
putParcelable(
|
||||||
bundle,
|
bundle,
|
||||||
createWithLocationInfoSanitizedIfNecessaryWhenParceled(
|
createWithLocationInfoSanitizedIfNecessaryWhenParceled(
|
||||||
nc, includeLocationSensitiveInfo, nri.mUid,
|
nc, includeLocationSensitiveInfo, nri.mPid, nri.mUid,
|
||||||
nrForCallback.getRequestorPackageName(),
|
nrForCallback.getRequestorPackageName(),
|
||||||
nri.mCallingAttributionTag));
|
nri.mCallingAttributionTag));
|
||||||
putParcelable(bundle, linkPropertiesRestrictedForCallerPermissions(
|
putParcelable(bundle, linkPropertiesRestrictedForCallerPermissions(
|
||||||
@@ -7165,7 +7264,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
putParcelable(
|
putParcelable(
|
||||||
bundle,
|
bundle,
|
||||||
createWithLocationInfoSanitizedIfNecessaryWhenParceled(
|
createWithLocationInfoSanitizedIfNecessaryWhenParceled(
|
||||||
netCap, includeLocationSensitiveInfo, nri.mUid,
|
netCap, includeLocationSensitiveInfo, nri.mPid, nri.mUid,
|
||||||
nrForCallback.getRequestorPackageName(),
|
nrForCallback.getRequestorPackageName(),
|
||||||
nri.mCallingAttributionTag));
|
nri.mCallingAttributionTag));
|
||||||
break;
|
break;
|
||||||
@@ -9239,7 +9338,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
final ArrayList<NetworkRequest> nrs = new ArrayList<>();
|
final ArrayList<NetworkRequest> nrs = new ArrayList<>();
|
||||||
nrs.add(createNetworkRequest(NetworkRequest.Type.REQUEST, pref.capabilities));
|
nrs.add(createNetworkRequest(NetworkRequest.Type.REQUEST, pref.capabilities));
|
||||||
nrs.add(createDefaultRequest());
|
nrs.add(createDefaultRequest());
|
||||||
setNetworkRequestUids(nrs, pref.capabilities.getUids());
|
setNetworkRequestUids(nrs, UidRange.fromIntRanges(pref.capabilities.getUids()));
|
||||||
final NetworkRequestInfo nri = new NetworkRequestInfo(nrs);
|
final NetworkRequestInfo nri = new NetworkRequestInfo(nrs);
|
||||||
result.add(nri);
|
result.add(nri);
|
||||||
}
|
}
|
||||||
@@ -9455,9 +9554,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
|
|
||||||
private static void setNetworkRequestUids(@NonNull final List<NetworkRequest> requests,
|
private static void setNetworkRequestUids(@NonNull final List<NetworkRequest> requests,
|
||||||
@NonNull final Set<UidRange> uids) {
|
@NonNull final Set<UidRange> uids) {
|
||||||
final Set<UidRange> ranges = new ArraySet<>(uids);
|
|
||||||
for (final NetworkRequest req : requests) {
|
for (final NetworkRequest req : requests) {
|
||||||
req.networkCapabilities.setUids(ranges);
|
req.networkCapabilities.setUids(UidRange.toIntRanges(uids));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -35,6 +35,9 @@ import static android.net.NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE;
|
|||||||
import static android.net.NetworkCapabilities.NET_CAPABILITY_PARTIAL_CONNECTIVITY;
|
import static android.net.NetworkCapabilities.NET_CAPABILITY_PARTIAL_CONNECTIVITY;
|
||||||
import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
|
import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
|
||||||
import static android.net.NetworkCapabilities.NET_CAPABILITY_WIFI_P2P;
|
import static android.net.NetworkCapabilities.NET_CAPABILITY_WIFI_P2P;
|
||||||
|
import static android.net.NetworkCapabilities.REDACT_FOR_ACCESS_FINE_LOCATION;
|
||||||
|
import static android.net.NetworkCapabilities.REDACT_FOR_LOCAL_MAC_ADDRESS;
|
||||||
|
import static android.net.NetworkCapabilities.REDACT_FOR_NETWORK_SETTINGS;
|
||||||
import static android.net.NetworkCapabilities.RESTRICTED_CAPABILITIES;
|
import static android.net.NetworkCapabilities.RESTRICTED_CAPABILITIES;
|
||||||
import static android.net.NetworkCapabilities.SIGNAL_STRENGTH_UNSPECIFIED;
|
import static android.net.NetworkCapabilities.SIGNAL_STRENGTH_UNSPECIFIED;
|
||||||
import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
|
import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
|
||||||
@@ -51,7 +54,6 @@ import static com.android.testutils.MiscAsserts.assertEmpty;
|
|||||||
import static com.android.testutils.MiscAsserts.assertThrows;
|
import static com.android.testutils.MiscAsserts.assertThrows;
|
||||||
import static com.android.testutils.ParcelUtils.assertParcelSane;
|
import static com.android.testutils.ParcelUtils.assertParcelSane;
|
||||||
import static com.android.testutils.ParcelUtils.assertParcelingIsLossless;
|
import static com.android.testutils.ParcelUtils.assertParcelingIsLossless;
|
||||||
import static com.android.testutils.ParcelUtils.parcelingRoundTrip;
|
|
||||||
|
|
||||||
import static org.junit.Assert.assertArrayEquals;
|
import static org.junit.Assert.assertArrayEquals;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
@@ -62,13 +64,13 @@ import static org.junit.Assert.assertTrue;
|
|||||||
import static org.junit.Assert.fail;
|
import static org.junit.Assert.fail;
|
||||||
import static org.junit.Assume.assumeTrue;
|
import static org.junit.Assume.assumeTrue;
|
||||||
|
|
||||||
import android.net.wifi.WifiInfo;
|
|
||||||
import android.net.wifi.aware.DiscoverySession;
|
import android.net.wifi.aware.DiscoverySession;
|
||||||
import android.net.wifi.aware.PeerHandle;
|
import android.net.wifi.aware.PeerHandle;
|
||||||
import android.net.wifi.aware.WifiAwareNetworkSpecifier;
|
import android.net.wifi.aware.WifiAwareNetworkSpecifier;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.test.suitebuilder.annotation.SmallTest;
|
import android.test.suitebuilder.annotation.SmallTest;
|
||||||
import android.util.ArraySet;
|
import android.util.ArraySet;
|
||||||
|
import android.util.Range;
|
||||||
|
|
||||||
import androidx.test.runner.AndroidJUnit4;
|
import androidx.test.runner.AndroidJUnit4;
|
||||||
|
|
||||||
@@ -240,9 +242,21 @@ public class NetworkCapabilitiesTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testSetUids() {
|
public void testSetUids() {
|
||||||
final NetworkCapabilities netCap = new NetworkCapabilities();
|
final NetworkCapabilities netCap = new NetworkCapabilities();
|
||||||
final Set<UidRange> uids = new ArraySet<>();
|
// Null uids match all UIDs
|
||||||
uids.add(new UidRange(50, 100));
|
netCap.setUids(null);
|
||||||
uids.add(new UidRange(3000, 4000));
|
assertTrue(netCap.appliesToUid(10));
|
||||||
|
assertTrue(netCap.appliesToUid(200));
|
||||||
|
assertTrue(netCap.appliesToUid(3000));
|
||||||
|
assertTrue(netCap.appliesToUid(10010));
|
||||||
|
assertTrue(netCap.appliesToUidRange(new UidRange(50, 100)));
|
||||||
|
assertTrue(netCap.appliesToUidRange(new UidRange(70, 72)));
|
||||||
|
assertTrue(netCap.appliesToUidRange(new UidRange(3500, 3912)));
|
||||||
|
assertTrue(netCap.appliesToUidRange(new UidRange(1, 100000)));
|
||||||
|
|
||||||
|
if (isAtLeastS()) {
|
||||||
|
final Set<Range<Integer>> uids = new ArraySet<>();
|
||||||
|
uids.add(uidRange(50, 100));
|
||||||
|
uids.add(uidRange(3000, 4000));
|
||||||
netCap.setUids(uids);
|
netCap.setUids(uids);
|
||||||
assertTrue(netCap.appliesToUid(50));
|
assertTrue(netCap.appliesToUid(50));
|
||||||
assertTrue(netCap.appliesToUid(80));
|
assertTrue(netCap.appliesToUid(80));
|
||||||
@@ -275,7 +289,7 @@ public class NetworkCapabilitiesTest {
|
|||||||
assertTrue(netCap.equalsUids(netCap2));
|
assertTrue(netCap.equalsUids(netCap2));
|
||||||
assertTrue(netCap2.equalsUids(netCap));
|
assertTrue(netCap2.equalsUids(netCap));
|
||||||
|
|
||||||
uids.add(new UidRange(600, 700));
|
uids.add(uidRange(600, 700));
|
||||||
netCap2.setUids(uids);
|
netCap2.setUids(uids);
|
||||||
assertFalse(netCap2.satisfiedByUids(netCap));
|
assertFalse(netCap2.satisfiedByUids(netCap));
|
||||||
assertFalse(netCap.appliesToUid(650));
|
assertFalse(netCap.appliesToUid(650));
|
||||||
@@ -292,20 +306,29 @@ public class NetworkCapabilitiesTest {
|
|||||||
assertFalse(netCap2.appliesToUid(500));
|
assertFalse(netCap2.appliesToUid(500));
|
||||||
assertFalse(netCap2.appliesToUidRange(new UidRange(1, 100000)));
|
assertFalse(netCap2.appliesToUidRange(new UidRange(1, 100000)));
|
||||||
assertTrue(new NetworkCapabilities().satisfiedByUids(netCap));
|
assertTrue(new NetworkCapabilities().satisfiedByUids(netCap));
|
||||||
|
|
||||||
|
// Null uids satisfies everything.
|
||||||
|
netCap.setUids(null);
|
||||||
|
assertTrue(netCap2.satisfiedByUids(netCap));
|
||||||
|
assertTrue(netCap.satisfiedByUids(netCap2));
|
||||||
|
netCap2.setUids(null);
|
||||||
|
assertTrue(netCap2.satisfiedByUids(netCap));
|
||||||
|
assertTrue(netCap.satisfiedByUids(netCap2));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testParcelNetworkCapabilities() {
|
public void testParcelNetworkCapabilities() {
|
||||||
final Set<UidRange> uids = new ArraySet<>();
|
final Set<Range<Integer>> uids = new ArraySet<>();
|
||||||
uids.add(new UidRange(50, 100));
|
uids.add(uidRange(50, 100));
|
||||||
uids.add(new UidRange(3000, 4000));
|
uids.add(uidRange(3000, 4000));
|
||||||
final NetworkCapabilities netCap = new NetworkCapabilities()
|
final NetworkCapabilities netCap = new NetworkCapabilities()
|
||||||
.addCapability(NET_CAPABILITY_INTERNET)
|
.addCapability(NET_CAPABILITY_INTERNET)
|
||||||
.setUids(uids)
|
|
||||||
.addCapability(NET_CAPABILITY_EIMS)
|
.addCapability(NET_CAPABILITY_EIMS)
|
||||||
.addCapability(NET_CAPABILITY_NOT_METERED);
|
.addCapability(NET_CAPABILITY_NOT_METERED);
|
||||||
if (isAtLeastS()) {
|
if (isAtLeastS()) {
|
||||||
netCap.setSubIds(Set.of(TEST_SUBID1, TEST_SUBID2));
|
netCap.setSubIds(Set.of(TEST_SUBID1, TEST_SUBID2));
|
||||||
|
netCap.setUids(uids);
|
||||||
} else if (isAtLeastR()) {
|
} else if (isAtLeastR()) {
|
||||||
netCap.setOwnerUid(123);
|
netCap.setOwnerUid(123);
|
||||||
netCap.setAdministratorUids(new int[] {5, 11});
|
netCap.setAdministratorUids(new int[] {5, 11});
|
||||||
@@ -330,55 +353,6 @@ public class NetworkCapabilitiesTest {
|
|||||||
testParcelSane(netCap);
|
testParcelSane(netCap);
|
||||||
}
|
}
|
||||||
|
|
||||||
private NetworkCapabilities createNetworkCapabilitiesWithWifiInfo() {
|
|
||||||
// uses a real WifiInfo to test parceling of sensitive data.
|
|
||||||
final WifiInfo wifiInfo = new WifiInfo.Builder()
|
|
||||||
.setSsid("sssid1234".getBytes())
|
|
||||||
.setBssid("00:11:22:33:44:55")
|
|
||||||
.build();
|
|
||||||
return new NetworkCapabilities()
|
|
||||||
.addCapability(NET_CAPABILITY_INTERNET)
|
|
||||||
.addCapability(NET_CAPABILITY_EIMS)
|
|
||||||
.addCapability(NET_CAPABILITY_NOT_METERED)
|
|
||||||
.setSSID(TEST_SSID)
|
|
||||||
.setTransportInfo(wifiInfo)
|
|
||||||
.setRequestorPackageName("com.android.test")
|
|
||||||
.setRequestorUid(9304);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testParcelNetworkCapabilitiesWithLocationSensitiveFields() {
|
|
||||||
assumeTrue(isAtLeastS());
|
|
||||||
|
|
||||||
final NetworkCapabilities netCap = createNetworkCapabilitiesWithWifiInfo();
|
|
||||||
final NetworkCapabilities netCapWithLocationSensitiveFields =
|
|
||||||
new NetworkCapabilities(netCap, true);
|
|
||||||
|
|
||||||
assertParcelingIsLossless(netCapWithLocationSensitiveFields);
|
|
||||||
testParcelSane(netCapWithLocationSensitiveFields);
|
|
||||||
|
|
||||||
assertEquals(netCapWithLocationSensitiveFields,
|
|
||||||
parcelingRoundTrip(netCapWithLocationSensitiveFields));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testParcelNetworkCapabilitiesWithoutLocationSensitiveFields() {
|
|
||||||
assumeTrue(isAtLeastS());
|
|
||||||
|
|
||||||
final NetworkCapabilities netCap = createNetworkCapabilitiesWithWifiInfo();
|
|
||||||
final NetworkCapabilities netCapWithoutLocationSensitiveFields =
|
|
||||||
new NetworkCapabilities(netCap, false);
|
|
||||||
|
|
||||||
final NetworkCapabilities sanitizedNetCap =
|
|
||||||
new NetworkCapabilities(netCapWithoutLocationSensitiveFields);
|
|
||||||
final WifiInfo sanitizedWifiInfo = new WifiInfo.Builder()
|
|
||||||
.setSsid(new byte[0])
|
|
||||||
.setBssid(WifiInfo.DEFAULT_MAC_ADDRESS)
|
|
||||||
.build();
|
|
||||||
sanitizedNetCap.setTransportInfo(sanitizedWifiInfo);
|
|
||||||
assertEquals(sanitizedNetCap, parcelingRoundTrip(netCapWithoutLocationSensitiveFields));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void testParcelSane(NetworkCapabilities cap) {
|
private void testParcelSane(NetworkCapabilities cap) {
|
||||||
if (isAtLeastS()) {
|
if (isAtLeastS()) {
|
||||||
assertParcelSane(cap, 17);
|
assertParcelSane(cap, 17);
|
||||||
@@ -389,6 +363,45 @@ public class NetworkCapabilitiesTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static NetworkCapabilities createNetworkCapabilitiesWithTransportInfo() {
|
||||||
|
return new NetworkCapabilities()
|
||||||
|
.addCapability(NET_CAPABILITY_INTERNET)
|
||||||
|
.addCapability(NET_CAPABILITY_EIMS)
|
||||||
|
.addCapability(NET_CAPABILITY_NOT_METERED)
|
||||||
|
.setSSID(TEST_SSID)
|
||||||
|
.setTransportInfo(new TestTransportInfo())
|
||||||
|
.setRequestorPackageName("com.android.test")
|
||||||
|
.setRequestorUid(9304);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testNetworkCapabilitiesCopyWithNoRedactions() {
|
||||||
|
assumeTrue(isAtLeastS());
|
||||||
|
|
||||||
|
final NetworkCapabilities netCap = createNetworkCapabilitiesWithTransportInfo();
|
||||||
|
final NetworkCapabilities netCapWithNoRedactions =
|
||||||
|
new NetworkCapabilities(netCap, NetworkCapabilities.REDACT_NONE);
|
||||||
|
TestTransportInfo testTransportInfo =
|
||||||
|
(TestTransportInfo) netCapWithNoRedactions.getTransportInfo();
|
||||||
|
assertFalse(testTransportInfo.locationRedacted);
|
||||||
|
assertFalse(testTransportInfo.localMacAddressRedacted);
|
||||||
|
assertFalse(testTransportInfo.settingsRedacted);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testNetworkCapabilitiesCopyWithoutLocationSensitiveFields() {
|
||||||
|
assumeTrue(isAtLeastS());
|
||||||
|
|
||||||
|
final NetworkCapabilities netCap = createNetworkCapabilitiesWithTransportInfo();
|
||||||
|
final NetworkCapabilities netCapWithNoRedactions =
|
||||||
|
new NetworkCapabilities(netCap, REDACT_FOR_ACCESS_FINE_LOCATION);
|
||||||
|
TestTransportInfo testTransportInfo =
|
||||||
|
(TestTransportInfo) netCapWithNoRedactions.getTransportInfo();
|
||||||
|
assertTrue(testTransportInfo.locationRedacted);
|
||||||
|
assertFalse(testTransportInfo.localMacAddressRedacted);
|
||||||
|
assertFalse(testTransportInfo.settingsRedacted);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testOemPaid() {
|
public void testOemPaid() {
|
||||||
NetworkCapabilities nc = new NetworkCapabilities();
|
NetworkCapabilities nc = new NetworkCapabilities();
|
||||||
@@ -540,12 +553,16 @@ public class NetworkCapabilitiesTest {
|
|||||||
assertFalse(nc1.satisfiedByNetworkCapabilities(nc2));
|
assertFalse(nc1.satisfiedByNetworkCapabilities(nc2));
|
||||||
}
|
}
|
||||||
|
|
||||||
private ArraySet<UidRange> uidRange(int from, int to) {
|
private ArraySet<Range<Integer>> uidRanges(int from, int to) {
|
||||||
final ArraySet<UidRange> range = new ArraySet<>(1);
|
final ArraySet<Range<Integer>> range = new ArraySet<>(1);
|
||||||
range.add(new UidRange(from, to));
|
range.add(uidRange(from, to));
|
||||||
return range;
|
return range;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Range<Integer> uidRange(int from, int to) {
|
||||||
|
return new Range<Integer>(from, to);
|
||||||
|
}
|
||||||
|
|
||||||
@Test @IgnoreUpTo(Build.VERSION_CODES.Q)
|
@Test @IgnoreUpTo(Build.VERSION_CODES.Q)
|
||||||
public void testSetAdministratorUids() {
|
public void testSetAdministratorUids() {
|
||||||
NetworkCapabilities nc =
|
NetworkCapabilities nc =
|
||||||
@@ -601,14 +618,15 @@ public class NetworkCapabilitiesTest {
|
|||||||
} catch (IllegalStateException expected) {}
|
} catch (IllegalStateException expected) {}
|
||||||
nc1.setSSID(TEST_SSID);
|
nc1.setSSID(TEST_SSID);
|
||||||
|
|
||||||
nc1.setUids(uidRange(10, 13));
|
if (isAtLeastS()) {
|
||||||
|
nc1.setUids(uidRanges(10, 13));
|
||||||
assertNotEquals(nc1, nc2);
|
assertNotEquals(nc1, nc2);
|
||||||
nc2.combineCapabilities(nc1); // Everything + 10~13 is still everything.
|
nc2.combineCapabilities(nc1); // Everything + 10~13 is still everything.
|
||||||
assertNotEquals(nc1, nc2);
|
assertNotEquals(nc1, nc2);
|
||||||
nc1.combineCapabilities(nc2); // 10~13 + everything is everything.
|
nc1.combineCapabilities(nc2); // 10~13 + everything is everything.
|
||||||
assertEquals(nc1, nc2);
|
assertEquals(nc1, nc2);
|
||||||
nc1.setUids(uidRange(10, 13));
|
nc1.setUids(uidRanges(10, 13));
|
||||||
nc2.setUids(uidRange(20, 23));
|
nc2.setUids(uidRanges(20, 23));
|
||||||
assertNotEquals(nc1, nc2);
|
assertNotEquals(nc1, nc2);
|
||||||
nc1.combineCapabilities(nc2);
|
nc1.combineCapabilities(nc2);
|
||||||
assertTrue(nc1.appliesToUid(12));
|
assertTrue(nc1.appliesToUid(12));
|
||||||
@@ -617,7 +635,6 @@ public class NetworkCapabilitiesTest {
|
|||||||
assertTrue(nc2.appliesToUid(22));
|
assertTrue(nc2.appliesToUid(22));
|
||||||
|
|
||||||
// Verify the subscription id list can be combined only when they are equal.
|
// Verify the subscription id list can be combined only when they are equal.
|
||||||
if (isAtLeastS()) {
|
|
||||||
nc1.setSubIds(Set.of(TEST_SUBID1, TEST_SUBID2));
|
nc1.setSubIds(Set.of(TEST_SUBID1, TEST_SUBID2));
|
||||||
nc2.setSubIds(Set.of(TEST_SUBID2));
|
nc2.setSubIds(Set.of(TEST_SUBID2));
|
||||||
assertThrows(IllegalStateException.class, () -> nc2.combineCapabilities(nc1));
|
assertThrows(IllegalStateException.class, () -> nc2.combineCapabilities(nc1));
|
||||||
@@ -773,8 +790,11 @@ public class NetworkCapabilitiesTest {
|
|||||||
if (isAtLeastR()) {
|
if (isAtLeastR()) {
|
||||||
assertTrue(DIFFERENT_TEST_SSID.equals(nc2.getSsid()));
|
assertTrue(DIFFERENT_TEST_SSID.equals(nc2.getSsid()));
|
||||||
}
|
}
|
||||||
|
if (isAtLeastS()) {
|
||||||
nc1.setUids(uidRange(10, 13));
|
nc1.setUids(uidRanges(10, 13));
|
||||||
|
} else {
|
||||||
|
nc1.setUids(null);
|
||||||
|
}
|
||||||
nc2.set(nc1); // Overwrites, as opposed to combineCapabilities
|
nc2.set(nc1); // Overwrites, as opposed to combineCapabilities
|
||||||
assertEquals(nc1, nc2);
|
assertEquals(nc1, nc2);
|
||||||
|
|
||||||
@@ -1033,18 +1053,42 @@ public class NetworkCapabilitiesTest {
|
|||||||
} catch (IllegalArgumentException e) { }
|
} catch (IllegalArgumentException e) { }
|
||||||
}
|
}
|
||||||
|
|
||||||
private class TestTransportInfo implements TransportInfo {
|
/**
|
||||||
|
* Test TransportInfo to verify redaction mechanism.
|
||||||
|
*/
|
||||||
|
private static class TestTransportInfo implements TransportInfo {
|
||||||
|
public final boolean locationRedacted;
|
||||||
|
public final boolean localMacAddressRedacted;
|
||||||
|
public final boolean settingsRedacted;
|
||||||
|
|
||||||
TestTransportInfo() {
|
TestTransportInfo() {
|
||||||
|
locationRedacted = false;
|
||||||
|
localMacAddressRedacted = false;
|
||||||
|
settingsRedacted = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
TestTransportInfo(boolean locationRedacted,
|
||||||
|
boolean localMacAddressRedacted,
|
||||||
|
boolean settingsRedacted) {
|
||||||
|
this.locationRedacted = locationRedacted;
|
||||||
|
this.localMacAddressRedacted =
|
||||||
|
localMacAddressRedacted;
|
||||||
|
this.settingsRedacted = settingsRedacted;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TransportInfo makeCopy(boolean parcelLocationSensitiveFields) {
|
public TransportInfo makeCopy(@NetworkCapabilities.RedactionType long redactions) {
|
||||||
return this;
|
return new TestTransportInfo(
|
||||||
|
(redactions & NetworkCapabilities.REDACT_FOR_ACCESS_FINE_LOCATION) != 0,
|
||||||
|
(redactions & REDACT_FOR_LOCAL_MAC_ADDRESS) != 0,
|
||||||
|
(redactions & REDACT_FOR_NETWORK_SETTINGS) != 0
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasLocationSensitiveFields() {
|
public @NetworkCapabilities.RedactionType long getApplicableRedactions() {
|
||||||
return false;
|
return REDACT_FOR_ACCESS_FINE_LOCATION | REDACT_FOR_LOCAL_MAC_ADDRESS
|
||||||
|
| REDACT_FOR_NETWORK_SETTINGS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1055,7 +1099,7 @@ public class NetworkCapabilitiesTest {
|
|||||||
final int requestUid = 10100;
|
final int requestUid = 10100;
|
||||||
final int[] administratorUids = {ownerUid, 10001};
|
final int[] administratorUids = {ownerUid, 10001};
|
||||||
final TelephonyNetworkSpecifier specifier = new TelephonyNetworkSpecifier(1);
|
final TelephonyNetworkSpecifier specifier = new TelephonyNetworkSpecifier(1);
|
||||||
final TestTransportInfo transportInfo = new TestTransportInfo();
|
final TransportInfo transportInfo = new TransportInfo() {};
|
||||||
final String ssid = "TEST_SSID";
|
final String ssid = "TEST_SSID";
|
||||||
final String packageName = "com.google.test.networkcapabilities";
|
final String packageName = "com.google.test.networkcapabilities";
|
||||||
final NetworkCapabilities nc = new NetworkCapabilities.Builder()
|
final NetworkCapabilities nc = new NetworkCapabilities.Builder()
|
||||||
|
|||||||
@@ -44,11 +44,11 @@ import android.net.NetworkProvider;
|
|||||||
import android.net.NetworkSpecifier;
|
import android.net.NetworkSpecifier;
|
||||||
import android.net.QosFilter;
|
import android.net.QosFilter;
|
||||||
import android.net.SocketKeepalive;
|
import android.net.SocketKeepalive;
|
||||||
import android.net.UidRange;
|
|
||||||
import android.os.ConditionVariable;
|
import android.os.ConditionVariable;
|
||||||
import android.os.HandlerThread;
|
import android.os.HandlerThread;
|
||||||
import android.os.Message;
|
import android.os.Message;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
import android.util.Range;
|
||||||
|
|
||||||
import com.android.net.module.util.ArrayTrackRecord;
|
import com.android.net.module.util.ArrayTrackRecord;
|
||||||
import com.android.server.connectivity.ConnectivityConstants;
|
import com.android.server.connectivity.ConnectivityConstants;
|
||||||
@@ -222,7 +222,7 @@ public class NetworkAgentWrapper implements TestableNetworkCallback.HasNetwork {
|
|||||||
mNetworkAgent.sendNetworkCapabilities(mNetworkCapabilities);
|
mNetworkAgent.sendNetworkCapabilities(mNetworkCapabilities);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setUids(Set<UidRange> uids) {
|
public void setUids(Set<Range<Integer>> uids) {
|
||||||
mNetworkCapabilities.setUids(uids);
|
mNetworkCapabilities.setUids(uids);
|
||||||
mNetworkAgent.sendNetworkCapabilities(mNetworkCapabilities);
|
mNetworkAgent.sendNetworkCapabilities(mNetworkCapabilities);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -82,6 +82,10 @@ import static android.net.NetworkCapabilities.NET_CAPABILITY_TRUSTED;
|
|||||||
import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
|
import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
|
||||||
import static android.net.NetworkCapabilities.NET_CAPABILITY_WIFI_P2P;
|
import static android.net.NetworkCapabilities.NET_CAPABILITY_WIFI_P2P;
|
||||||
import static android.net.NetworkCapabilities.NET_CAPABILITY_XCAP;
|
import static android.net.NetworkCapabilities.NET_CAPABILITY_XCAP;
|
||||||
|
import static android.net.NetworkCapabilities.REDACT_FOR_ACCESS_FINE_LOCATION;
|
||||||
|
import static android.net.NetworkCapabilities.REDACT_FOR_LOCAL_MAC_ADDRESS;
|
||||||
|
import static android.net.NetworkCapabilities.REDACT_FOR_NETWORK_SETTINGS;
|
||||||
|
import static android.net.NetworkCapabilities.REDACT_NONE;
|
||||||
import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
|
import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
|
||||||
import static android.net.NetworkCapabilities.TRANSPORT_ETHERNET;
|
import static android.net.NetworkCapabilities.TRANSPORT_ETHERNET;
|
||||||
import static android.net.NetworkCapabilities.TRANSPORT_VPN;
|
import static android.net.NetworkCapabilities.TRANSPORT_VPN;
|
||||||
@@ -237,7 +241,6 @@ import android.net.resolv.aidl.PrivateDnsValidationEventParcel;
|
|||||||
import android.net.shared.NetworkMonitorUtils;
|
import android.net.shared.NetworkMonitorUtils;
|
||||||
import android.net.shared.PrivateDnsConfig;
|
import android.net.shared.PrivateDnsConfig;
|
||||||
import android.net.util.MultinetworkPolicyTracker;
|
import android.net.util.MultinetworkPolicyTracker;
|
||||||
import android.net.wifi.WifiInfo;
|
|
||||||
import android.os.BadParcelableException;
|
import android.os.BadParcelableException;
|
||||||
import android.os.Binder;
|
import android.os.Binder;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
@@ -268,6 +271,7 @@ import android.text.TextUtils;
|
|||||||
import android.util.ArraySet;
|
import android.util.ArraySet;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.util.Pair;
|
import android.util.Pair;
|
||||||
|
import android.util.Range;
|
||||||
import android.util.SparseArray;
|
import android.util.SparseArray;
|
||||||
|
|
||||||
import androidx.test.InstrumentationRegistry;
|
import androidx.test.InstrumentationRegistry;
|
||||||
@@ -1158,7 +1162,7 @@ public class ConnectivityServiceTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void setUids(Set<UidRange> uids) {
|
public void setUids(Set<UidRange> uids) {
|
||||||
mNetworkCapabilities.setUids(uids);
|
mNetworkCapabilities.setUids(UidRange.toIntRanges(uids));
|
||||||
if (mAgentRegistered) {
|
if (mAgentRegistered) {
|
||||||
mMockNetworkAgent.setNetworkCapabilities(mNetworkCapabilities, true);
|
mMockNetworkAgent.setNetworkCapabilities(mNetworkCapabilities, true);
|
||||||
}
|
}
|
||||||
@@ -1448,6 +1452,8 @@ public class ConnectivityServiceTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static final int PRIMARY_USER = 0;
|
private static final int PRIMARY_USER = 0;
|
||||||
|
private static final UidRange PRIMARY_UIDRANGE =
|
||||||
|
UidRange.createForUser(UserHandle.of(PRIMARY_USER));
|
||||||
private static final int APP1_UID = UserHandle.getUid(PRIMARY_USER, 10100);
|
private static final int APP1_UID = UserHandle.getUid(PRIMARY_USER, 10100);
|
||||||
private static final int APP2_UID = UserHandle.getUid(PRIMARY_USER, 10101);
|
private static final int APP2_UID = UserHandle.getUid(PRIMARY_USER, 10101);
|
||||||
private static final int VPN_UID = UserHandle.getUid(PRIMARY_USER, 10043);
|
private static final int VPN_UID = UserHandle.getUid(PRIMARY_USER, 10043);
|
||||||
@@ -6946,7 +6952,7 @@ public class ConnectivityServiceTest {
|
|||||||
final int uid = Process.myUid();
|
final int uid = Process.myUid();
|
||||||
NetworkCapabilities nc = mCm.getNetworkCapabilities(mMockVpn.getNetwork());
|
NetworkCapabilities nc = mCm.getNetworkCapabilities(mMockVpn.getNetwork());
|
||||||
assertNotNull("nc=" + nc, nc.getUids());
|
assertNotNull("nc=" + nc, nc.getUids());
|
||||||
assertEquals(nc.getUids(), uidRangesForUids(uid));
|
assertEquals(nc.getUids(), UidRange.toIntRanges(uidRangesForUids(uid)));
|
||||||
assertVpnTransportInfo(nc, VpnManager.TYPE_VPN_SERVICE);
|
assertVpnTransportInfo(nc, VpnManager.TYPE_VPN_SERVICE);
|
||||||
|
|
||||||
// Set an underlying network and expect to see the VPN transports change.
|
// Set an underlying network and expect to see the VPN transports change.
|
||||||
@@ -6971,10 +6977,13 @@ public class ConnectivityServiceTest {
|
|||||||
|
|
||||||
// Expect that the VPN UID ranges contain both |uid| and the UID range for the newly-added
|
// Expect that the VPN UID ranges contain both |uid| and the UID range for the newly-added
|
||||||
// restricted user.
|
// restricted user.
|
||||||
|
final UidRange rRange = UidRange.createForUser(UserHandle.of(RESTRICTED_USER));
|
||||||
|
final Range<Integer> restrictUidRange = new Range<Integer>(rRange.start, rRange.stop);
|
||||||
|
final Range<Integer> singleUidRange = new Range<Integer>(uid, uid);
|
||||||
callback.expectCapabilitiesThat(mMockVpn, (caps)
|
callback.expectCapabilitiesThat(mMockVpn, (caps)
|
||||||
-> caps.getUids().size() == 2
|
-> caps.getUids().size() == 2
|
||||||
&& caps.getUids().contains(new UidRange(uid, uid))
|
&& caps.getUids().contains(singleUidRange)
|
||||||
&& caps.getUids().contains(createUidRange(RESTRICTED_USER))
|
&& caps.getUids().contains(restrictUidRange)
|
||||||
&& caps.hasTransport(TRANSPORT_VPN)
|
&& caps.hasTransport(TRANSPORT_VPN)
|
||||||
&& caps.hasTransport(TRANSPORT_WIFI));
|
&& caps.hasTransport(TRANSPORT_WIFI));
|
||||||
|
|
||||||
@@ -6983,8 +6992,8 @@ public class ConnectivityServiceTest {
|
|||||||
callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
|
callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
|
||||||
callback.expectCapabilitiesThat(mMockVpn, (caps)
|
callback.expectCapabilitiesThat(mMockVpn, (caps)
|
||||||
-> caps.getUids().size() == 2
|
-> caps.getUids().size() == 2
|
||||||
&& caps.getUids().contains(new UidRange(uid, uid))
|
&& caps.getUids().contains(singleUidRange)
|
||||||
&& caps.getUids().contains(createUidRange(RESTRICTED_USER))
|
&& caps.getUids().contains(restrictUidRange)
|
||||||
&& caps.hasTransport(TRANSPORT_VPN)
|
&& caps.hasTransport(TRANSPORT_VPN)
|
||||||
&& !caps.hasTransport(TRANSPORT_WIFI));
|
&& !caps.hasTransport(TRANSPORT_WIFI));
|
||||||
|
|
||||||
@@ -6998,7 +7007,7 @@ public class ConnectivityServiceTest {
|
|||||||
// change made just before that (i.e., loss of TRANSPORT_WIFI) is preserved.
|
// change made just before that (i.e., loss of TRANSPORT_WIFI) is preserved.
|
||||||
callback.expectCapabilitiesThat(mMockVpn, (caps)
|
callback.expectCapabilitiesThat(mMockVpn, (caps)
|
||||||
-> caps.getUids().size() == 1
|
-> caps.getUids().size() == 1
|
||||||
&& caps.getUids().contains(new UidRange(uid, uid))
|
&& caps.getUids().contains(singleUidRange)
|
||||||
&& caps.hasTransport(TRANSPORT_VPN)
|
&& caps.hasTransport(TRANSPORT_VPN)
|
||||||
&& !caps.hasTransport(TRANSPORT_WIFI));
|
&& !caps.hasTransport(TRANSPORT_WIFI));
|
||||||
}
|
}
|
||||||
@@ -7656,7 +7665,7 @@ public class ConnectivityServiceTest {
|
|||||||
assertNotNull(underlying);
|
assertNotNull(underlying);
|
||||||
mMockVpn.setVpnType(VpnManager.TYPE_VPN_LEGACY);
|
mMockVpn.setVpnType(VpnManager.TYPE_VPN_LEGACY);
|
||||||
// The legacy lockdown VPN only supports userId 0.
|
// The legacy lockdown VPN only supports userId 0.
|
||||||
final Set<UidRange> ranges = Collections.singleton(createUidRange(PRIMARY_USER));
|
final Set<UidRange> ranges = Collections.singleton(PRIMARY_UIDRANGE);
|
||||||
mMockVpn.registerAgent(ranges);
|
mMockVpn.registerAgent(ranges);
|
||||||
mMockVpn.setUnderlyingNetworks(new Network[]{underlying});
|
mMockVpn.setUnderlyingNetworks(new Network[]{underlying});
|
||||||
mMockVpn.connect(true);
|
mMockVpn.connect(true);
|
||||||
@@ -8618,7 +8627,7 @@ public class ConnectivityServiceTest {
|
|||||||
lp.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), null));
|
lp.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), null));
|
||||||
lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), RTN_UNREACHABLE));
|
lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), RTN_UNREACHABLE));
|
||||||
// The uid range needs to cover the test app so the network is visible to it.
|
// The uid range needs to cover the test app so the network is visible to it.
|
||||||
final Set<UidRange> vpnRange = Collections.singleton(createUidRange(PRIMARY_USER));
|
final Set<UidRange> vpnRange = Collections.singleton(PRIMARY_UIDRANGE);
|
||||||
mMockVpn.establish(lp, VPN_UID, vpnRange);
|
mMockVpn.establish(lp, VPN_UID, vpnRange);
|
||||||
assertVpnUidRangesUpdated(true, vpnRange, VPN_UID);
|
assertVpnUidRangesUpdated(true, vpnRange, VPN_UID);
|
||||||
|
|
||||||
@@ -8646,7 +8655,7 @@ public class ConnectivityServiceTest {
|
|||||||
lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), null));
|
lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), null));
|
||||||
lp.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), null));
|
lp.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), null));
|
||||||
// The uid range needs to cover the test app so the network is visible to it.
|
// The uid range needs to cover the test app so the network is visible to it.
|
||||||
final Set<UidRange> vpnRange = Collections.singleton(createUidRange(PRIMARY_USER));
|
final Set<UidRange> vpnRange = Collections.singleton(PRIMARY_UIDRANGE);
|
||||||
mMockVpn.establish(lp, Process.SYSTEM_UID, vpnRange);
|
mMockVpn.establish(lp, Process.SYSTEM_UID, vpnRange);
|
||||||
assertVpnUidRangesUpdated(true, vpnRange, Process.SYSTEM_UID);
|
assertVpnUidRangesUpdated(true, vpnRange, Process.SYSTEM_UID);
|
||||||
|
|
||||||
@@ -8662,7 +8671,7 @@ public class ConnectivityServiceTest {
|
|||||||
lp.addRoute(new RouteInfo(new IpPrefix("192.0.2.0/24"), null, "tun0"));
|
lp.addRoute(new RouteInfo(new IpPrefix("192.0.2.0/24"), null, "tun0"));
|
||||||
lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), RTN_UNREACHABLE));
|
lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), RTN_UNREACHABLE));
|
||||||
// The uid range needs to cover the test app so the network is visible to it.
|
// The uid range needs to cover the test app so the network is visible to it.
|
||||||
final Set<UidRange> vpnRange = Collections.singleton(createUidRange(PRIMARY_USER));
|
final Set<UidRange> vpnRange = Collections.singleton(PRIMARY_UIDRANGE);
|
||||||
mMockVpn.establish(lp, Process.SYSTEM_UID, vpnRange);
|
mMockVpn.establish(lp, Process.SYSTEM_UID, vpnRange);
|
||||||
assertVpnUidRangesUpdated(true, vpnRange, Process.SYSTEM_UID);
|
assertVpnUidRangesUpdated(true, vpnRange, Process.SYSTEM_UID);
|
||||||
|
|
||||||
@@ -8677,7 +8686,7 @@ public class ConnectivityServiceTest {
|
|||||||
lp.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), null));
|
lp.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), null));
|
||||||
lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), null));
|
lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), null));
|
||||||
// The uid range needs to cover the test app so the network is visible to it.
|
// The uid range needs to cover the test app so the network is visible to it.
|
||||||
final Set<UidRange> vpnRange = Collections.singleton(createUidRange(PRIMARY_USER));
|
final Set<UidRange> vpnRange = Collections.singleton(PRIMARY_UIDRANGE);
|
||||||
mMockVpn.establish(lp, VPN_UID, vpnRange);
|
mMockVpn.establish(lp, VPN_UID, vpnRange);
|
||||||
assertVpnUidRangesUpdated(true, vpnRange, VPN_UID);
|
assertVpnUidRangesUpdated(true, vpnRange, VPN_UID);
|
||||||
|
|
||||||
@@ -8729,7 +8738,7 @@ public class ConnectivityServiceTest {
|
|||||||
lp.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), RTN_UNREACHABLE));
|
lp.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), RTN_UNREACHABLE));
|
||||||
lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), null));
|
lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), null));
|
||||||
// The uid range needs to cover the test app so the network is visible to it.
|
// The uid range needs to cover the test app so the network is visible to it.
|
||||||
final UidRange vpnRange = createUidRange(PRIMARY_USER);
|
final UidRange vpnRange = PRIMARY_UIDRANGE;
|
||||||
final Set<UidRange> vpnRanges = Collections.singleton(vpnRange);
|
final Set<UidRange> vpnRanges = Collections.singleton(vpnRange);
|
||||||
mMockVpn.establish(lp, VPN_UID, vpnRanges);
|
mMockVpn.establish(lp, VPN_UID, vpnRanges);
|
||||||
assertVpnUidRangesUpdated(true, vpnRanges, VPN_UID);
|
assertVpnUidRangesUpdated(true, vpnRanges, VPN_UID);
|
||||||
@@ -8834,29 +8843,34 @@ public class ConnectivityServiceTest {
|
|||||||
final NetworkCapabilities netCap = new NetworkCapabilities().setOwnerUid(ownerUid);
|
final NetworkCapabilities netCap = new NetworkCapabilities().setOwnerUid(ownerUid);
|
||||||
|
|
||||||
return mService.createWithLocationInfoSanitizedIfNecessaryWhenParceled(
|
return mService.createWithLocationInfoSanitizedIfNecessaryWhenParceled(
|
||||||
netCap, includeLocationSensitiveInfo, callerUid,
|
netCap, includeLocationSensitiveInfo, Process.myUid(), callerUid,
|
||||||
mContext.getPackageName(), getAttributionTag())
|
mContext.getPackageName(), getAttributionTag())
|
||||||
.getOwnerUid();
|
.getOwnerUid();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void verifyWifiInfoCopyNetCapsPermission(
|
private void verifyTransportInfoCopyNetCapsPermission(
|
||||||
int callerUid, boolean includeLocationSensitiveInfo,
|
int callerUid, boolean includeLocationSensitiveInfo,
|
||||||
boolean shouldMakeCopyWithLocationSensitiveFieldsParcelable) {
|
boolean shouldMakeCopyWithLocationSensitiveFieldsParcelable) {
|
||||||
final WifiInfo wifiInfo = mock(WifiInfo.class);
|
final TransportInfo transportInfo = mock(TransportInfo.class);
|
||||||
when(wifiInfo.hasLocationSensitiveFields()).thenReturn(true);
|
when(transportInfo.getApplicableRedactions()).thenReturn(REDACT_FOR_ACCESS_FINE_LOCATION);
|
||||||
final NetworkCapabilities netCap = new NetworkCapabilities().setTransportInfo(wifiInfo);
|
final NetworkCapabilities netCap =
|
||||||
|
new NetworkCapabilities().setTransportInfo(transportInfo);
|
||||||
|
|
||||||
mService.createWithLocationInfoSanitizedIfNecessaryWhenParceled(
|
mService.createWithLocationInfoSanitizedIfNecessaryWhenParceled(
|
||||||
netCap, includeLocationSensitiveInfo, callerUid,
|
netCap, includeLocationSensitiveInfo, Process.myPid(), callerUid,
|
||||||
mContext.getPackageName(), getAttributionTag());
|
mContext.getPackageName(), getAttributionTag());
|
||||||
verify(wifiInfo).makeCopy(eq(shouldMakeCopyWithLocationSensitiveFieldsParcelable));
|
if (shouldMakeCopyWithLocationSensitiveFieldsParcelable) {
|
||||||
|
verify(transportInfo).makeCopy(REDACT_NONE);
|
||||||
|
} else {
|
||||||
|
verify(transportInfo).makeCopy(REDACT_FOR_ACCESS_FINE_LOCATION);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void verifyOwnerUidAndWifiInfoNetCapsPermission(
|
private void verifyOwnerUidAndTransportInfoNetCapsPermission(
|
||||||
boolean shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag,
|
boolean shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag,
|
||||||
boolean shouldInclLocationSensitiveOwnerUidWithIncludeFlag,
|
boolean shouldInclLocationSensitiveOwnerUidWithIncludeFlag,
|
||||||
boolean shouldInclLocationSensitiveWifiInfoWithoutIncludeFlag,
|
boolean shouldInclLocationSensitiveTransportInfoWithoutIncludeFlag,
|
||||||
boolean shouldInclLocationSensitiveWifiInfoWithIncludeFlag) {
|
boolean shouldInclLocationSensitiveTransportInfoWithIncludeFlag) {
|
||||||
final int myUid = Process.myUid();
|
final int myUid = Process.myUid();
|
||||||
|
|
||||||
final int expectedOwnerUidWithoutIncludeFlag =
|
final int expectedOwnerUidWithoutIncludeFlag =
|
||||||
@@ -8870,13 +8884,13 @@ public class ConnectivityServiceTest {
|
|||||||
assertEquals(expectedOwnerUidWithIncludeFlag, getOwnerUidNetCapsPermission(
|
assertEquals(expectedOwnerUidWithIncludeFlag, getOwnerUidNetCapsPermission(
|
||||||
myUid, myUid, true /* includeLocationSensitiveInfo */));
|
myUid, myUid, true /* includeLocationSensitiveInfo */));
|
||||||
|
|
||||||
verifyWifiInfoCopyNetCapsPermission(myUid,
|
verifyTransportInfoCopyNetCapsPermission(myUid,
|
||||||
false, /* includeLocationSensitiveInfo */
|
false, /* includeLocationSensitiveInfo */
|
||||||
shouldInclLocationSensitiveWifiInfoWithoutIncludeFlag);
|
shouldInclLocationSensitiveTransportInfoWithoutIncludeFlag);
|
||||||
|
|
||||||
verifyWifiInfoCopyNetCapsPermission(myUid,
|
verifyTransportInfoCopyNetCapsPermission(myUid,
|
||||||
true, /* includeLocationSensitiveInfo */
|
true, /* includeLocationSensitiveInfo */
|
||||||
shouldInclLocationSensitiveWifiInfoWithIncludeFlag);
|
shouldInclLocationSensitiveTransportInfoWithIncludeFlag);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -8886,15 +8900,15 @@ public class ConnectivityServiceTest {
|
|||||||
setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_FINE_LOCATION,
|
setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_FINE_LOCATION,
|
||||||
Manifest.permission.ACCESS_FINE_LOCATION);
|
Manifest.permission.ACCESS_FINE_LOCATION);
|
||||||
|
|
||||||
verifyOwnerUidAndWifiInfoNetCapsPermission(
|
verifyOwnerUidAndTransportInfoNetCapsPermission(
|
||||||
// Ensure that we include owner uid even if the request asks to remove it since the
|
// Ensure that we include owner uid even if the request asks to remove it since the
|
||||||
// app has necessary permissions and targetSdk < S.
|
// app has necessary permissions and targetSdk < S.
|
||||||
true, /* shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag */
|
true, /* shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag */
|
||||||
true, /* shouldInclLocationSensitiveOwnerUidWithIncludeFlag */
|
true, /* shouldInclLocationSensitiveOwnerUidWithIncludeFlag */
|
||||||
false, /* shouldInclLocationSensitiveWifiInfoWithoutIncludeFlag */
|
false, /* shouldInclLocationSensitiveTransportInfoWithoutIncludeFlag */
|
||||||
// Ensure that we remove location info if the request asks to remove it even if the
|
// Ensure that we remove location info if the request asks to remove it even if the
|
||||||
// app has necessary permissions.
|
// app has necessary permissions.
|
||||||
true /* shouldInclLocationSensitiveWifiInfoWithIncludeFlag */
|
true /* shouldInclLocationSensitiveTransportInfoWithIncludeFlag */
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -8904,15 +8918,15 @@ public class ConnectivityServiceTest {
|
|||||||
setupLocationPermissions(Build.VERSION_CODES.R, true, AppOpsManager.OPSTR_FINE_LOCATION,
|
setupLocationPermissions(Build.VERSION_CODES.R, true, AppOpsManager.OPSTR_FINE_LOCATION,
|
||||||
Manifest.permission.ACCESS_FINE_LOCATION);
|
Manifest.permission.ACCESS_FINE_LOCATION);
|
||||||
|
|
||||||
verifyOwnerUidAndWifiInfoNetCapsPermission(
|
verifyOwnerUidAndTransportInfoNetCapsPermission(
|
||||||
// Ensure that we include owner uid even if the request asks to remove it since the
|
// Ensure that we include owner uid even if the request asks to remove it since the
|
||||||
// app has necessary permissions and targetSdk < S.
|
// app has necessary permissions and targetSdk < S.
|
||||||
true, /* shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag */
|
true, /* shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag */
|
||||||
true, /* shouldInclLocationSensitiveOwnerUidWithIncludeFlag */
|
true, /* shouldInclLocationSensitiveOwnerUidWithIncludeFlag */
|
||||||
false, /* shouldInclLocationSensitiveWifiInfoWithoutIncludeFlag */
|
false, /* shouldInclLocationSensitiveTransportInfoWithoutIncludeFlag */
|
||||||
// Ensure that we remove location info if the request asks to remove it even if the
|
// Ensure that we remove location info if the request asks to remove it even if the
|
||||||
// app has necessary permissions.
|
// app has necessary permissions.
|
||||||
true /* shouldInclLocationSensitiveWifiInfoWithIncludeFlag */
|
true /* shouldInclLocationSensitiveTransportInfoWithIncludeFlag */
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -8923,15 +8937,15 @@ public class ConnectivityServiceTest {
|
|||||||
setupLocationPermissions(Build.VERSION_CODES.S, true, AppOpsManager.OPSTR_FINE_LOCATION,
|
setupLocationPermissions(Build.VERSION_CODES.S, true, AppOpsManager.OPSTR_FINE_LOCATION,
|
||||||
Manifest.permission.ACCESS_FINE_LOCATION);
|
Manifest.permission.ACCESS_FINE_LOCATION);
|
||||||
|
|
||||||
verifyOwnerUidAndWifiInfoNetCapsPermission(
|
verifyOwnerUidAndTransportInfoNetCapsPermission(
|
||||||
// Ensure that we owner UID if the request asks us to remove it even if the app
|
// Ensure that we owner UID if the request asks us to remove it even if the app
|
||||||
// has necessary permissions since targetSdk >= S.
|
// has necessary permissions since targetSdk >= S.
|
||||||
false, /* shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag */
|
false, /* shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag */
|
||||||
true, /* shouldInclLocationSensitiveOwnerUidWithIncludeFlag */
|
true, /* shouldInclLocationSensitiveOwnerUidWithIncludeFlag */
|
||||||
false, /* shouldInclLocationSensitiveWifiInfoWithoutIncludeFlag */
|
false, /* shouldInclLocationSensitiveTransportInfoWithoutIncludeFlag */
|
||||||
// Ensure that we remove location info if the request asks to remove it even if the
|
// Ensure that we remove location info if the request asks to remove it even if the
|
||||||
// app has necessary permissions.
|
// app has necessary permissions.
|
||||||
true /* shouldInclLocationSensitiveWifiInfoWithIncludeFlag */
|
true /* shouldInclLocationSensitiveTransportInfoWithIncludeFlag */
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -8941,15 +8955,15 @@ public class ConnectivityServiceTest {
|
|||||||
setupLocationPermissions(Build.VERSION_CODES.P, true, AppOpsManager.OPSTR_COARSE_LOCATION,
|
setupLocationPermissions(Build.VERSION_CODES.P, true, AppOpsManager.OPSTR_COARSE_LOCATION,
|
||||||
Manifest.permission.ACCESS_COARSE_LOCATION);
|
Manifest.permission.ACCESS_COARSE_LOCATION);
|
||||||
|
|
||||||
verifyOwnerUidAndWifiInfoNetCapsPermission(
|
verifyOwnerUidAndTransportInfoNetCapsPermission(
|
||||||
// Ensure that we owner UID if the request asks us to remove it even if the app
|
// Ensure that we owner UID if the request asks us to remove it even if the app
|
||||||
// has necessary permissions since targetSdk >= S.
|
// has necessary permissions since targetSdk >= S.
|
||||||
true, /* shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag */
|
true, /* shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag */
|
||||||
true, /* shouldInclLocationSensitiveOwnerUidWithIncludeFlag */
|
true, /* shouldInclLocationSensitiveOwnerUidWithIncludeFlag */
|
||||||
false, /* shouldInclLocationSensitiveWifiInfoWithoutIncludeFlag */
|
false, /* shouldInclLocationSensitiveTransportInfoWithoutIncludeFlag */
|
||||||
// Ensure that we remove location info if the request asks to remove it even if the
|
// Ensure that we remove location info if the request asks to remove it even if the
|
||||||
// app has necessary permissions.
|
// app has necessary permissions.
|
||||||
true /* shouldInclLocationSensitiveWifiInfoWithIncludeFlag */
|
true /* shouldInclLocationSensitiveTransportInfoWithIncludeFlag */
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -8959,11 +8973,11 @@ public class ConnectivityServiceTest {
|
|||||||
setupLocationPermissions(Build.VERSION_CODES.Q, false, AppOpsManager.OPSTR_FINE_LOCATION,
|
setupLocationPermissions(Build.VERSION_CODES.Q, false, AppOpsManager.OPSTR_FINE_LOCATION,
|
||||||
Manifest.permission.ACCESS_FINE_LOCATION);
|
Manifest.permission.ACCESS_FINE_LOCATION);
|
||||||
|
|
||||||
verifyOwnerUidAndWifiInfoNetCapsPermission(
|
verifyOwnerUidAndTransportInfoNetCapsPermission(
|
||||||
false, /* shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag */
|
false, /* shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag */
|
||||||
false, /* shouldInclLocationSensitiveOwnerUidWithIncludeFlag */
|
false, /* shouldInclLocationSensitiveOwnerUidWithIncludeFlag */
|
||||||
false, /* shouldInclLocationSensitiveWifiInfoWithoutIncludeFlag */
|
false, /* shouldInclLocationSensitiveTransportInfoWithoutIncludeFlag */
|
||||||
false /* shouldInclLocationSensitiveWifiInfoWithIncludeFlag */
|
false /* shouldInclLocationSensitiveTransportInfoWithIncludeFlag */
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -8986,11 +9000,11 @@ public class ConnectivityServiceTest {
|
|||||||
setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_COARSE_LOCATION,
|
setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_COARSE_LOCATION,
|
||||||
Manifest.permission.ACCESS_COARSE_LOCATION);
|
Manifest.permission.ACCESS_COARSE_LOCATION);
|
||||||
|
|
||||||
verifyOwnerUidAndWifiInfoNetCapsPermission(
|
verifyOwnerUidAndTransportInfoNetCapsPermission(
|
||||||
false, /* shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag */
|
false, /* shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag */
|
||||||
false, /* shouldInclLocationSensitiveOwnerUidWithIncludeFlag */
|
false, /* shouldInclLocationSensitiveOwnerUidWithIncludeFlag */
|
||||||
false, /* shouldInclLocationSensitiveWifiInfoWithoutIncludeFlag */
|
false, /* shouldInclLocationSensitiveTransportInfoWithoutIncludeFlag */
|
||||||
false /* shouldInclLocationSensitiveWifiInfoWithIncludeFlag */
|
false /* shouldInclLocationSensitiveTransportInfoWithIncludeFlag */
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -9000,17 +9014,196 @@ public class ConnectivityServiceTest {
|
|||||||
// Test that not having fine location permission leads to sanitization.
|
// Test that not having fine location permission leads to sanitization.
|
||||||
setupLocationPermissions(Build.VERSION_CODES.Q, true, null /* op */, null /* perm */);
|
setupLocationPermissions(Build.VERSION_CODES.Q, true, null /* op */, null /* perm */);
|
||||||
|
|
||||||
verifyOwnerUidAndWifiInfoNetCapsPermission(
|
verifyOwnerUidAndTransportInfoNetCapsPermission(
|
||||||
false, /* shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag */
|
false, /* shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag */
|
||||||
false, /* shouldInclLocationSensitiveOwnerUidWithIncludeFlag */
|
false, /* shouldInclLocationSensitiveOwnerUidWithIncludeFlag */
|
||||||
false, /* shouldInclLocationSensitiveWifiInfoWithoutIncludeFlag */
|
false, /* shouldInclLocationSensitiveTransportInfoWithoutIncludeFlag */
|
||||||
false /* shouldInclLocationSensitiveWifiInfoWithIncludeFlag */
|
false /* shouldInclLocationSensitiveTransportInfoWithIncludeFlag */
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCreateForCallerWithLocalMacAddressSanitizedWithLocalMacAddressPermission()
|
||||||
|
throws Exception {
|
||||||
|
mServiceContext.setPermission(Manifest.permission.LOCAL_MAC_ADDRESS, PERMISSION_GRANTED);
|
||||||
|
|
||||||
|
final TransportInfo transportInfo = mock(TransportInfo.class);
|
||||||
|
when(transportInfo.getApplicableRedactions())
|
||||||
|
.thenReturn(REDACT_FOR_ACCESS_FINE_LOCATION | REDACT_FOR_LOCAL_MAC_ADDRESS);
|
||||||
|
final NetworkCapabilities netCap =
|
||||||
|
new NetworkCapabilities().setTransportInfo(transportInfo);
|
||||||
|
|
||||||
|
mService.createWithLocationInfoSanitizedIfNecessaryWhenParceled(
|
||||||
|
netCap, false /* includeLocationSensitiveInfoInTransportInfo */,
|
||||||
|
Process.myPid(), Process.myUid(),
|
||||||
|
mContext.getPackageName(), getAttributionTag());
|
||||||
|
// don't redact MAC_ADDRESS fields, only location sensitive fields.
|
||||||
|
verify(transportInfo).makeCopy(REDACT_FOR_ACCESS_FINE_LOCATION);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCreateForCallerWithLocalMacAddressSanitizedWithoutLocalMacAddressPermission()
|
||||||
|
throws Exception {
|
||||||
|
mServiceContext.setPermission(Manifest.permission.LOCAL_MAC_ADDRESS, PERMISSION_DENIED);
|
||||||
|
|
||||||
|
final TransportInfo transportInfo = mock(TransportInfo.class);
|
||||||
|
when(transportInfo.getApplicableRedactions())
|
||||||
|
.thenReturn(REDACT_FOR_ACCESS_FINE_LOCATION | REDACT_FOR_LOCAL_MAC_ADDRESS);
|
||||||
|
final NetworkCapabilities netCap =
|
||||||
|
new NetworkCapabilities().setTransportInfo(transportInfo);
|
||||||
|
|
||||||
|
mService.createWithLocationInfoSanitizedIfNecessaryWhenParceled(
|
||||||
|
netCap, false /* includeLocationSensitiveInfoInTransportInfo */,
|
||||||
|
Process.myPid(), Process.myUid(),
|
||||||
|
mContext.getPackageName(), getAttributionTag());
|
||||||
|
// redact both MAC_ADDRESS & location sensitive fields.
|
||||||
|
verify(transportInfo).makeCopy(REDACT_FOR_ACCESS_FINE_LOCATION
|
||||||
|
| REDACT_FOR_LOCAL_MAC_ADDRESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCreateForCallerWithLocalMacAddressSanitizedWithSettingsPermission()
|
||||||
|
throws Exception {
|
||||||
|
mServiceContext.setPermission(Manifest.permission.NETWORK_SETTINGS, PERMISSION_GRANTED);
|
||||||
|
|
||||||
|
final TransportInfo transportInfo = mock(TransportInfo.class);
|
||||||
|
when(transportInfo.getApplicableRedactions())
|
||||||
|
.thenReturn(REDACT_FOR_ACCESS_FINE_LOCATION | REDACT_FOR_NETWORK_SETTINGS);
|
||||||
|
final NetworkCapabilities netCap =
|
||||||
|
new NetworkCapabilities().setTransportInfo(transportInfo);
|
||||||
|
|
||||||
|
mService.createWithLocationInfoSanitizedIfNecessaryWhenParceled(
|
||||||
|
netCap, false /* includeLocationSensitiveInfoInTransportInfo */,
|
||||||
|
Process.myPid(), Process.myUid(),
|
||||||
|
mContext.getPackageName(), getAttributionTag());
|
||||||
|
// don't redact NETWORK_SETTINGS fields, only location sensitive fields.
|
||||||
|
verify(transportInfo).makeCopy(REDACT_FOR_ACCESS_FINE_LOCATION);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCreateForCallerWithLocalMacAddressSanitizedWithoutSettingsPermission()
|
||||||
|
throws Exception {
|
||||||
|
mServiceContext.setPermission(Manifest.permission.LOCAL_MAC_ADDRESS, PERMISSION_DENIED);
|
||||||
|
|
||||||
|
final TransportInfo transportInfo = mock(TransportInfo.class);
|
||||||
|
when(transportInfo.getApplicableRedactions())
|
||||||
|
.thenReturn(REDACT_FOR_ACCESS_FINE_LOCATION | REDACT_FOR_NETWORK_SETTINGS);
|
||||||
|
final NetworkCapabilities netCap =
|
||||||
|
new NetworkCapabilities().setTransportInfo(transportInfo);
|
||||||
|
|
||||||
|
mService.createWithLocationInfoSanitizedIfNecessaryWhenParceled(
|
||||||
|
netCap, false /* includeLocationSensitiveInfoInTransportInfo */,
|
||||||
|
Process.myPid(), Process.myUid(),
|
||||||
|
mContext.getPackageName(), getAttributionTag());
|
||||||
|
// redact both NETWORK_SETTINGS & location sensitive fields.
|
||||||
|
verify(transportInfo).makeCopy(
|
||||||
|
REDACT_FOR_ACCESS_FINE_LOCATION | REDACT_FOR_NETWORK_SETTINGS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test TransportInfo to verify redaction mechanism.
|
||||||
|
*/
|
||||||
|
private static class TestTransportInfo implements TransportInfo {
|
||||||
|
public final boolean locationRedacted;
|
||||||
|
public final boolean localMacAddressRedacted;
|
||||||
|
public final boolean settingsRedacted;
|
||||||
|
|
||||||
|
TestTransportInfo() {
|
||||||
|
locationRedacted = false;
|
||||||
|
localMacAddressRedacted = false;
|
||||||
|
settingsRedacted = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
TestTransportInfo(boolean locationRedacted, boolean localMacAddressRedacted,
|
||||||
|
boolean settingsRedacted) {
|
||||||
|
this.locationRedacted = locationRedacted;
|
||||||
|
this.localMacAddressRedacted =
|
||||||
|
localMacAddressRedacted;
|
||||||
|
this.settingsRedacted = settingsRedacted;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TransportInfo makeCopy(@NetworkCapabilities.RedactionType long redactions) {
|
||||||
|
return new TestTransportInfo(
|
||||||
|
(redactions & REDACT_FOR_ACCESS_FINE_LOCATION) != 0,
|
||||||
|
(redactions & REDACT_FOR_LOCAL_MAC_ADDRESS) != 0,
|
||||||
|
(redactions & REDACT_FOR_NETWORK_SETTINGS) != 0
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NetworkCapabilities.RedactionType long getApplicableRedactions() {
|
||||||
|
return REDACT_FOR_ACCESS_FINE_LOCATION | REDACT_FOR_LOCAL_MAC_ADDRESS
|
||||||
|
| REDACT_FOR_NETWORK_SETTINGS;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object other) {
|
||||||
|
if (!(other instanceof TestTransportInfo)) return false;
|
||||||
|
TestTransportInfo that = (TestTransportInfo) other;
|
||||||
|
return that.locationRedacted == this.locationRedacted
|
||||||
|
&& that.localMacAddressRedacted == this.localMacAddressRedacted
|
||||||
|
&& that.settingsRedacted == this.settingsRedacted;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(locationRedacted, localMacAddressRedacted, settingsRedacted);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void verifyNetworkCallbackLocationDataInclusionUsingTransportInfoAndOwnerUidInNetCaps(
|
||||||
|
@NonNull TestNetworkCallback wifiNetworkCallback, int actualOwnerUid,
|
||||||
|
@NonNull TransportInfo actualTransportInfo, int expectedOwnerUid,
|
||||||
|
@NonNull TransportInfo expectedTransportInfo) throws Exception {
|
||||||
|
when(mPackageManager.getTargetSdkVersion(anyString())).thenReturn(Build.VERSION_CODES.S);
|
||||||
|
final NetworkCapabilities ncTemplate =
|
||||||
|
new NetworkCapabilities()
|
||||||
|
.addTransportType(TRANSPORT_WIFI)
|
||||||
|
.setOwnerUid(actualOwnerUid);
|
||||||
|
|
||||||
|
final NetworkRequest wifiRequest = new NetworkRequest.Builder()
|
||||||
|
.addTransportType(TRANSPORT_WIFI).build();
|
||||||
|
mCm.registerNetworkCallback(wifiRequest, wifiNetworkCallback);
|
||||||
|
|
||||||
|
mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, new LinkProperties(),
|
||||||
|
ncTemplate);
|
||||||
|
mWiFiNetworkAgent.connect(false);
|
||||||
|
|
||||||
|
wifiNetworkCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
|
||||||
|
|
||||||
|
// Send network capabilities update with TransportInfo to trigger capabilities changed
|
||||||
|
// callback.
|
||||||
|
mWiFiNetworkAgent.setNetworkCapabilities(
|
||||||
|
ncTemplate.setTransportInfo(actualTransportInfo), true);
|
||||||
|
|
||||||
|
wifiNetworkCallback.expectCapabilitiesThat(mWiFiNetworkAgent,
|
||||||
|
nc -> Objects.equals(expectedOwnerUid, nc.getOwnerUid())
|
||||||
|
&& Objects.equals(expectedTransportInfo, nc.getTransportInfo()));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testVerifyLocationDataIsNotIncludedWhenInclFlagNotSet() throws Exception {
|
||||||
|
final TestNetworkCallback wifiNetworkCallack = new TestNetworkCallback();
|
||||||
|
final int ownerUid = Process.myUid();
|
||||||
|
final TransportInfo transportInfo = new TestTransportInfo();
|
||||||
|
// Even though the test uid holds privileged permissions, mask location fields since
|
||||||
|
// the callback did not explicitly opt-in to get location data.
|
||||||
|
final TransportInfo sanitizedTransportInfo = new TestTransportInfo(
|
||||||
|
true, /* locationRedacted */
|
||||||
|
true, /* localMacAddressRedacted */
|
||||||
|
true /* settingsRedacted */
|
||||||
|
);
|
||||||
|
// Should not expect location data since the callback does not set the flag for including
|
||||||
|
// location data.
|
||||||
|
verifyNetworkCallbackLocationDataInclusionUsingTransportInfoAndOwnerUidInNetCaps(
|
||||||
|
wifiNetworkCallack, ownerUid, transportInfo, INVALID_UID, sanitizedTransportInfo);
|
||||||
|
}
|
||||||
|
|
||||||
private void setupConnectionOwnerUid(int vpnOwnerUid, @VpnManager.VpnType int vpnType)
|
private void setupConnectionOwnerUid(int vpnOwnerUid, @VpnManager.VpnType int vpnType)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
final Set<UidRange> vpnRange = Collections.singleton(createUidRange(PRIMARY_USER));
|
final Set<UidRange> vpnRange = Collections.singleton(PRIMARY_UIDRANGE);
|
||||||
mMockVpn.setVpnType(vpnType);
|
mMockVpn.setVpnType(vpnType);
|
||||||
mMockVpn.establish(new LinkProperties(), vpnOwnerUid, vpnRange);
|
mMockVpn.establish(new LinkProperties(), vpnOwnerUid, vpnRange);
|
||||||
assertVpnUidRangesUpdated(true, vpnRange, vpnOwnerUid);
|
assertVpnUidRangesUpdated(true, vpnRange, vpnOwnerUid);
|
||||||
@@ -9570,7 +9763,7 @@ public class ConnectivityServiceTest {
|
|||||||
lp.setInterfaceName("tun0");
|
lp.setInterfaceName("tun0");
|
||||||
lp.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), null));
|
lp.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), null));
|
||||||
lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), null));
|
lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), null));
|
||||||
final UidRange vpnRange = createUidRange(PRIMARY_USER);
|
final UidRange vpnRange = PRIMARY_UIDRANGE;
|
||||||
Set<UidRange> vpnRanges = Collections.singleton(vpnRange);
|
Set<UidRange> vpnRanges = Collections.singleton(vpnRange);
|
||||||
mMockVpn.establish(lp, VPN_UID, vpnRanges);
|
mMockVpn.establish(lp, VPN_UID, vpnRanges);
|
||||||
assertVpnUidRangesUpdated(true, vpnRanges, VPN_UID);
|
assertVpnUidRangesUpdated(true, vpnRanges, VPN_UID);
|
||||||
@@ -9768,7 +9961,7 @@ public class ConnectivityServiceTest {
|
|||||||
.thenReturn(hasFeature);
|
.thenReturn(hasFeature);
|
||||||
}
|
}
|
||||||
|
|
||||||
private UidRange getNriFirstUidRange(
|
private Range<Integer> getNriFirstUidRange(
|
||||||
@NonNull final ConnectivityService.NetworkRequestInfo nri) {
|
@NonNull final ConnectivityService.NetworkRequestInfo nri) {
|
||||||
return nri.mRequests.get(0).networkCapabilities.getUids().iterator().next();
|
return nri.mRequests.get(0).networkCapabilities.getUids().iterator().next();
|
||||||
}
|
}
|
||||||
@@ -9951,11 +10144,11 @@ public class ConnectivityServiceTest {
|
|||||||
pref));
|
pref));
|
||||||
|
|
||||||
// Sort by uid to access nris by index
|
// Sort by uid to access nris by index
|
||||||
nris.sort(Comparator.comparingInt(nri -> getNriFirstUidRange(nri).start));
|
nris.sort(Comparator.comparingInt(nri -> getNriFirstUidRange(nri).getLower()));
|
||||||
assertEquals(TEST_PACKAGE_UID, getNriFirstUidRange(nris.get(0)).start);
|
assertEquals(TEST_PACKAGE_UID, (int) getNriFirstUidRange(nris.get(0)).getLower());
|
||||||
assertEquals(TEST_PACKAGE_UID, getNriFirstUidRange(nris.get(0)).stop);
|
assertEquals(TEST_PACKAGE_UID, (int) getNriFirstUidRange(nris.get(0)).getUpper());
|
||||||
assertEquals(testPackageNameUid2, getNriFirstUidRange(nris.get(1)).start);
|
assertEquals(testPackageNameUid2, (int) getNriFirstUidRange(nris.get(1)).getLower());
|
||||||
assertEquals(testPackageNameUid2, getNriFirstUidRange(nris.get(1)).stop);
|
assertEquals(testPackageNameUid2, (int) getNriFirstUidRange(nris.get(1)).getUpper());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -9985,17 +10178,17 @@ public class ConnectivityServiceTest {
|
|||||||
// UIDs for all users and all managed packages should be present.
|
// UIDs for all users and all managed packages should be present.
|
||||||
// Two users each with two packages.
|
// Two users each with two packages.
|
||||||
final int expectedUidSize = 2;
|
final int expectedUidSize = 2;
|
||||||
final List<UidRange> uids =
|
final List<Range<Integer>> uids =
|
||||||
new ArrayList<>(nris.get(0).mRequests.get(0).networkCapabilities.getUids());
|
new ArrayList<>(nris.get(0).mRequests.get(0).networkCapabilities.getUids());
|
||||||
assertEquals(expectedUidSize, uids.size());
|
assertEquals(expectedUidSize, uids.size());
|
||||||
|
|
||||||
// Sort by uid to access nris by index
|
// Sort by uid to access nris by index
|
||||||
uids.sort(Comparator.comparingInt(uid -> uid.start));
|
uids.sort(Comparator.comparingInt(uid -> uid.getLower()));
|
||||||
final int secondUserTestPackageUid = UserHandle.getUid(secondUser, TEST_PACKAGE_UID);
|
final int secondUserTestPackageUid = UserHandle.getUid(secondUser, TEST_PACKAGE_UID);
|
||||||
assertEquals(TEST_PACKAGE_UID, uids.get(0).start);
|
assertEquals(TEST_PACKAGE_UID, (int) uids.get(0).getLower());
|
||||||
assertEquals(TEST_PACKAGE_UID, uids.get(0).stop);
|
assertEquals(TEST_PACKAGE_UID, (int) uids.get(0).getUpper());
|
||||||
assertEquals(secondUserTestPackageUid, uids.get(1).start);
|
assertEquals(secondUserTestPackageUid, (int) uids.get(1).getLower());
|
||||||
assertEquals(secondUserTestPackageUid, uids.get(1).stop);
|
assertEquals(secondUserTestPackageUid, (int) uids.get(1).getUpper());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import static android.content.pm.UserInfo.FLAG_RESTRICTED;
|
|||||||
import static android.net.ConnectivityManager.NetworkCallback;
|
import static android.net.ConnectivityManager.NetworkCallback;
|
||||||
import static android.net.INetd.IF_STATE_DOWN;
|
import static android.net.INetd.IF_STATE_DOWN;
|
||||||
import static android.net.INetd.IF_STATE_UP;
|
import static android.net.INetd.IF_STATE_UP;
|
||||||
|
import static android.os.UserHandle.PER_USER_RANGE;
|
||||||
|
|
||||||
import static org.junit.Assert.assertArrayEquals;
|
import static org.junit.Assert.assertArrayEquals;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
@@ -74,7 +75,6 @@ import android.net.Network;
|
|||||||
import android.net.NetworkCapabilities;
|
import android.net.NetworkCapabilities;
|
||||||
import android.net.NetworkInfo.DetailedState;
|
import android.net.NetworkInfo.DetailedState;
|
||||||
import android.net.RouteInfo;
|
import android.net.RouteInfo;
|
||||||
import android.net.UidRange;
|
|
||||||
import android.net.UidRangeParcel;
|
import android.net.UidRangeParcel;
|
||||||
import android.net.VpnManager;
|
import android.net.VpnManager;
|
||||||
import android.net.VpnService;
|
import android.net.VpnService;
|
||||||
@@ -181,8 +181,7 @@ public class VpnTest {
|
|||||||
mPackages.put(PKGS[i], PKG_UIDS[i]);
|
mPackages.put(PKGS[i], PKG_UIDS[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private static final UidRange PRI_USER_RANGE =
|
private static final Range<Integer> PRI_USER_RANGE = uidRangeForUser(primaryUser.id);
|
||||||
UidRange.createForUser(UserHandle.of(primaryUser.id));
|
|
||||||
|
|
||||||
@Mock(answer = Answers.RETURNS_DEEP_STUBS) private Context mContext;
|
@Mock(answer = Answers.RETURNS_DEEP_STUBS) private Context mContext;
|
||||||
@Mock private UserManager mUserManager;
|
@Mock private UserManager mUserManager;
|
||||||
@@ -260,6 +259,21 @@ public class VpnTest {
|
|||||||
.thenReturn(tunnelResp);
|
.thenReturn(tunnelResp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Set<Range<Integer>> rangeSet(Range<Integer> ... ranges) {
|
||||||
|
final Set<Range<Integer>> range = new ArraySet<>();
|
||||||
|
for (Range<Integer> r : ranges) range.add(r);
|
||||||
|
|
||||||
|
return range;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Range<Integer> uidRangeForUser(int userId) {
|
||||||
|
return new Range<Integer>(userId * PER_USER_RANGE, (userId + 1) * PER_USER_RANGE - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Range<Integer> uidRange(int start, int stop) {
|
||||||
|
return new Range<Integer>(start, stop);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRestrictedProfilesAreAddedToVpn() {
|
public void testRestrictedProfilesAreAddedToVpn() {
|
||||||
setMockedUsers(primaryUser, secondaryUser, restrictedProfileA, restrictedProfileB);
|
setMockedUsers(primaryUser, secondaryUser, restrictedProfileA, restrictedProfileB);
|
||||||
@@ -268,12 +282,10 @@ public class VpnTest {
|
|||||||
|
|
||||||
// Assume the user can have restricted profiles.
|
// Assume the user can have restricted profiles.
|
||||||
doReturn(true).when(mUserManager).canHaveRestrictedProfile();
|
doReturn(true).when(mUserManager).canHaveRestrictedProfile();
|
||||||
final Set<UidRange> ranges =
|
final Set<Range<Integer>> ranges =
|
||||||
vpn.createUserAndRestrictedProfilesRanges(primaryUser.id, null, null);
|
vpn.createUserAndRestrictedProfilesRanges(primaryUser.id, null, null);
|
||||||
|
|
||||||
assertEquals(new ArraySet<>(Arrays.asList(new UidRange[] {
|
assertEquals(rangeSet(PRI_USER_RANGE, uidRangeForUser(restrictedProfileA.id)), ranges);
|
||||||
PRI_USER_RANGE, UidRange.createForUser(UserHandle.of(restrictedProfileA.id))
|
|
||||||
})), ranges);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -281,10 +293,10 @@ public class VpnTest {
|
|||||||
setMockedUsers(primaryUser, managedProfileA);
|
setMockedUsers(primaryUser, managedProfileA);
|
||||||
|
|
||||||
final Vpn vpn = createVpn(primaryUser.id);
|
final Vpn vpn = createVpn(primaryUser.id);
|
||||||
final Set<UidRange> ranges = vpn.createUserAndRestrictedProfilesRanges(primaryUser.id,
|
final Set<Range<Integer>> ranges = vpn.createUserAndRestrictedProfilesRanges(primaryUser.id,
|
||||||
null, null);
|
null, null);
|
||||||
|
|
||||||
assertEquals(new ArraySet<>(Arrays.asList(new UidRange[] { PRI_USER_RANGE })), ranges);
|
assertEquals(rangeSet(PRI_USER_RANGE), ranges);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -292,35 +304,38 @@ public class VpnTest {
|
|||||||
setMockedUsers(primaryUser, restrictedProfileA, managedProfileA);
|
setMockedUsers(primaryUser, restrictedProfileA, managedProfileA);
|
||||||
|
|
||||||
final Vpn vpn = createVpn(primaryUser.id);
|
final Vpn vpn = createVpn(primaryUser.id);
|
||||||
final Set<UidRange> ranges = new ArraySet<>();
|
final Set<Range<Integer>> ranges = new ArraySet<>();
|
||||||
vpn.addUserToRanges(ranges, primaryUser.id, null, null);
|
vpn.addUserToRanges(ranges, primaryUser.id, null, null);
|
||||||
|
|
||||||
assertEquals(new ArraySet<>(Arrays.asList(new UidRange[] { PRI_USER_RANGE })), ranges);
|
assertEquals(rangeSet(PRI_USER_RANGE), ranges);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testUidAllowAndDenylist() throws Exception {
|
public void testUidAllowAndDenylist() throws Exception {
|
||||||
final Vpn vpn = createVpn(primaryUser.id);
|
final Vpn vpn = createVpn(primaryUser.id);
|
||||||
final UidRange user = PRI_USER_RANGE;
|
final Range<Integer> user = PRI_USER_RANGE;
|
||||||
|
final int userStart = user.getLower();
|
||||||
|
final int userStop = user.getUpper();
|
||||||
final String[] packages = {PKGS[0], PKGS[1], PKGS[2]};
|
final String[] packages = {PKGS[0], PKGS[1], PKGS[2]};
|
||||||
|
|
||||||
// Allowed list
|
// Allowed list
|
||||||
final Set<UidRange> allow = vpn.createUserAndRestrictedProfilesRanges(primaryUser.id,
|
final Set<Range<Integer>> allow = vpn.createUserAndRestrictedProfilesRanges(primaryUser.id,
|
||||||
Arrays.asList(packages), null);
|
Arrays.asList(packages), null /* disallowedApplications */);
|
||||||
assertEquals(new ArraySet<>(Arrays.asList(new UidRange[] {
|
assertEquals(rangeSet(
|
||||||
new UidRange(user.start + PKG_UIDS[0], user.start + PKG_UIDS[0]),
|
uidRange(userStart + PKG_UIDS[0], userStart + PKG_UIDS[0]),
|
||||||
new UidRange(user.start + PKG_UIDS[1], user.start + PKG_UIDS[2])
|
uidRange(userStart + PKG_UIDS[1], userStart + PKG_UIDS[2])),
|
||||||
})), allow);
|
allow);
|
||||||
|
|
||||||
// Denied list
|
// Denied list
|
||||||
final Set<UidRange> disallow = vpn.createUserAndRestrictedProfilesRanges(primaryUser.id,
|
final Set<Range<Integer>> disallow =
|
||||||
null, Arrays.asList(packages));
|
vpn.createUserAndRestrictedProfilesRanges(primaryUser.id,
|
||||||
assertEquals(new ArraySet<>(Arrays.asList(new UidRange[] {
|
null /* allowedApplications */, Arrays.asList(packages));
|
||||||
new UidRange(user.start, user.start + PKG_UIDS[0] - 1),
|
assertEquals(rangeSet(
|
||||||
new UidRange(user.start + PKG_UIDS[0] + 1, user.start + PKG_UIDS[1] - 1),
|
uidRange(userStart, userStart + PKG_UIDS[0] - 1),
|
||||||
|
uidRange(userStart + PKG_UIDS[0] + 1, userStart + PKG_UIDS[1] - 1),
|
||||||
/* Empty range between UIDS[1] and UIDS[2], should be excluded, */
|
/* Empty range between UIDS[1] and UIDS[2], should be excluded, */
|
||||||
new UidRange(user.start + PKG_UIDS[2] + 1, user.stop)
|
uidRange(userStart + PKG_UIDS[2] + 1, userStop)),
|
||||||
})), disallow);
|
disallow);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -350,84 +365,86 @@ public class VpnTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testLockdownChangingPackage() throws Exception {
|
public void testLockdownChangingPackage() throws Exception {
|
||||||
final Vpn vpn = createVpn(primaryUser.id);
|
final Vpn vpn = createVpn(primaryUser.id);
|
||||||
final UidRange user = PRI_USER_RANGE;
|
final Range<Integer> user = PRI_USER_RANGE;
|
||||||
|
final int userStart = user.getLower();
|
||||||
|
final int userStop = user.getUpper();
|
||||||
// Set always-on without lockdown.
|
// Set always-on without lockdown.
|
||||||
assertTrue(vpn.setAlwaysOnPackage(PKGS[1], false, null));
|
assertTrue(vpn.setAlwaysOnPackage(PKGS[1], false, null));
|
||||||
|
|
||||||
// Set always-on with lockdown.
|
// Set always-on with lockdown.
|
||||||
assertTrue(vpn.setAlwaysOnPackage(PKGS[1], true, null));
|
assertTrue(vpn.setAlwaysOnPackage(PKGS[1], true, null));
|
||||||
verify(mConnectivityManager).setRequireVpnForUids(true, toRanges(new UidRangeParcel[] {
|
verify(mConnectivityManager).setRequireVpnForUids(true, toRanges(new UidRangeParcel[] {
|
||||||
new UidRangeParcel(user.start, user.start + PKG_UIDS[1] - 1),
|
new UidRangeParcel(userStart, userStart + PKG_UIDS[1] - 1),
|
||||||
new UidRangeParcel(user.start + PKG_UIDS[1] + 1, user.stop)
|
new UidRangeParcel(userStart + PKG_UIDS[1] + 1, userStop)
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// Switch to another app.
|
// Switch to another app.
|
||||||
assertTrue(vpn.setAlwaysOnPackage(PKGS[3], true, null));
|
assertTrue(vpn.setAlwaysOnPackage(PKGS[3], true, null));
|
||||||
verify(mConnectivityManager).setRequireVpnForUids(false, toRanges(new UidRangeParcel[] {
|
verify(mConnectivityManager).setRequireVpnForUids(false, toRanges(new UidRangeParcel[] {
|
||||||
new UidRangeParcel(user.start, user.start + PKG_UIDS[1] - 1),
|
new UidRangeParcel(userStart, userStart + PKG_UIDS[1] - 1),
|
||||||
new UidRangeParcel(user.start + PKG_UIDS[1] + 1, user.stop)
|
new UidRangeParcel(userStart + PKG_UIDS[1] + 1, userStop)
|
||||||
}));
|
}));
|
||||||
verify(mConnectivityManager).setRequireVpnForUids(true, toRanges(new UidRangeParcel[] {
|
verify(mConnectivityManager).setRequireVpnForUids(true, toRanges(new UidRangeParcel[] {
|
||||||
new UidRangeParcel(user.start, user.start + PKG_UIDS[3] - 1),
|
new UidRangeParcel(userStart, userStart + PKG_UIDS[3] - 1),
|
||||||
new UidRangeParcel(user.start + PKG_UIDS[3] + 1, user.stop)
|
new UidRangeParcel(userStart + PKG_UIDS[3] + 1, userStop)
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testLockdownAllowlist() throws Exception {
|
public void testLockdownAllowlist() throws Exception {
|
||||||
final Vpn vpn = createVpn(primaryUser.id);
|
final Vpn vpn = createVpn(primaryUser.id);
|
||||||
final UidRange user = PRI_USER_RANGE;
|
final Range<Integer> user = PRI_USER_RANGE;
|
||||||
|
final int userStart = user.getLower();
|
||||||
|
final int userStop = user.getUpper();
|
||||||
// Set always-on with lockdown and allow app PKGS[2] from lockdown.
|
// Set always-on with lockdown and allow app PKGS[2] from lockdown.
|
||||||
assertTrue(vpn.setAlwaysOnPackage(
|
assertTrue(vpn.setAlwaysOnPackage(
|
||||||
PKGS[1], true, Collections.singletonList(PKGS[2])));
|
PKGS[1], true, Collections.singletonList(PKGS[2])));
|
||||||
verify(mConnectivityManager).setRequireVpnForUids(true, toRanges(new UidRangeParcel[] {
|
verify(mConnectivityManager).setRequireVpnForUids(true, toRanges(new UidRangeParcel[] {
|
||||||
new UidRangeParcel(user.start, user.start + PKG_UIDS[1] - 1),
|
new UidRangeParcel(userStart, userStart + PKG_UIDS[1] - 1),
|
||||||
new UidRangeParcel(user.start + PKG_UIDS[2] + 1, user.stop)
|
new UidRangeParcel(userStart + PKG_UIDS[2] + 1, userStop)
|
||||||
}));
|
}));
|
||||||
// Change allowed app list to PKGS[3].
|
// Change allowed app list to PKGS[3].
|
||||||
assertTrue(vpn.setAlwaysOnPackage(
|
assertTrue(vpn.setAlwaysOnPackage(
|
||||||
PKGS[1], true, Collections.singletonList(PKGS[3])));
|
PKGS[1], true, Collections.singletonList(PKGS[3])));
|
||||||
verify(mConnectivityManager).setRequireVpnForUids(false, toRanges(new UidRangeParcel[] {
|
verify(mConnectivityManager).setRequireVpnForUids(false, toRanges(new UidRangeParcel[] {
|
||||||
new UidRangeParcel(user.start + PKG_UIDS[2] + 1, user.stop)
|
new UidRangeParcel(userStart + PKG_UIDS[2] + 1, userStop)
|
||||||
}));
|
}));
|
||||||
verify(mConnectivityManager).setRequireVpnForUids(true, toRanges(new UidRangeParcel[] {
|
verify(mConnectivityManager).setRequireVpnForUids(true, toRanges(new UidRangeParcel[] {
|
||||||
new UidRangeParcel(user.start + PKG_UIDS[1] + 1, user.start + PKG_UIDS[3] - 1),
|
new UidRangeParcel(userStart + PKG_UIDS[1] + 1, userStart + PKG_UIDS[3] - 1),
|
||||||
new UidRangeParcel(user.start + PKG_UIDS[3] + 1, user.stop)
|
new UidRangeParcel(userStart + PKG_UIDS[3] + 1, userStop)
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// Change the VPN app.
|
// Change the VPN app.
|
||||||
assertTrue(vpn.setAlwaysOnPackage(
|
assertTrue(vpn.setAlwaysOnPackage(
|
||||||
PKGS[0], true, Collections.singletonList(PKGS[3])));
|
PKGS[0], true, Collections.singletonList(PKGS[3])));
|
||||||
verify(mConnectivityManager).setRequireVpnForUids(false, toRanges(new UidRangeParcel[] {
|
verify(mConnectivityManager).setRequireVpnForUids(false, toRanges(new UidRangeParcel[] {
|
||||||
new UidRangeParcel(user.start, user.start + PKG_UIDS[1] - 1),
|
new UidRangeParcel(userStart, userStart + PKG_UIDS[1] - 1),
|
||||||
new UidRangeParcel(user.start + PKG_UIDS[1] + 1, user.start + PKG_UIDS[3] - 1)
|
new UidRangeParcel(userStart + PKG_UIDS[1] + 1, userStart + PKG_UIDS[3] - 1)
|
||||||
}));
|
}));
|
||||||
verify(mConnectivityManager).setRequireVpnForUids(true, toRanges(new UidRangeParcel[] {
|
verify(mConnectivityManager).setRequireVpnForUids(true, toRanges(new UidRangeParcel[] {
|
||||||
new UidRangeParcel(user.start, user.start + PKG_UIDS[0] - 1),
|
new UidRangeParcel(userStart, userStart + PKG_UIDS[0] - 1),
|
||||||
new UidRangeParcel(user.start + PKG_UIDS[0] + 1, user.start + PKG_UIDS[3] - 1)
|
new UidRangeParcel(userStart + PKG_UIDS[0] + 1, userStart + PKG_UIDS[3] - 1)
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// Remove the list of allowed packages.
|
// Remove the list of allowed packages.
|
||||||
assertTrue(vpn.setAlwaysOnPackage(PKGS[0], true, null));
|
assertTrue(vpn.setAlwaysOnPackage(PKGS[0], true, null));
|
||||||
verify(mConnectivityManager).setRequireVpnForUids(false, toRanges(new UidRangeParcel[] {
|
verify(mConnectivityManager).setRequireVpnForUids(false, toRanges(new UidRangeParcel[] {
|
||||||
new UidRangeParcel(user.start + PKG_UIDS[0] + 1, user.start + PKG_UIDS[3] - 1),
|
new UidRangeParcel(userStart + PKG_UIDS[0] + 1, userStart + PKG_UIDS[3] - 1),
|
||||||
new UidRangeParcel(user.start + PKG_UIDS[3] + 1, user.stop)
|
new UidRangeParcel(userStart + PKG_UIDS[3] + 1, userStop)
|
||||||
}));
|
}));
|
||||||
verify(mConnectivityManager).setRequireVpnForUids(true, toRanges(new UidRangeParcel[] {
|
verify(mConnectivityManager).setRequireVpnForUids(true, toRanges(new UidRangeParcel[] {
|
||||||
new UidRangeParcel(user.start + PKG_UIDS[0] + 1, user.stop),
|
new UidRangeParcel(userStart + PKG_UIDS[0] + 1, userStop),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// Add the list of allowed packages.
|
// Add the list of allowed packages.
|
||||||
assertTrue(vpn.setAlwaysOnPackage(
|
assertTrue(vpn.setAlwaysOnPackage(
|
||||||
PKGS[0], true, Collections.singletonList(PKGS[1])));
|
PKGS[0], true, Collections.singletonList(PKGS[1])));
|
||||||
verify(mConnectivityManager).setRequireVpnForUids(false, toRanges(new UidRangeParcel[] {
|
verify(mConnectivityManager).setRequireVpnForUids(false, toRanges(new UidRangeParcel[] {
|
||||||
new UidRangeParcel(user.start + PKG_UIDS[0] + 1, user.stop)
|
new UidRangeParcel(userStart + PKG_UIDS[0] + 1, userStop)
|
||||||
}));
|
}));
|
||||||
verify(mConnectivityManager).setRequireVpnForUids(true, toRanges(new UidRangeParcel[] {
|
verify(mConnectivityManager).setRequireVpnForUids(true, toRanges(new UidRangeParcel[] {
|
||||||
new UidRangeParcel(user.start + PKG_UIDS[0] + 1, user.start + PKG_UIDS[1] - 1),
|
new UidRangeParcel(userStart + PKG_UIDS[0] + 1, userStart + PKG_UIDS[1] - 1),
|
||||||
new UidRangeParcel(user.start + PKG_UIDS[1] + 1, user.stop)
|
new UidRangeParcel(userStart + PKG_UIDS[1] + 1, userStop)
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// Try allowing a package with a comma, should be rejected.
|
// Try allowing a package with a comma, should be rejected.
|
||||||
@@ -439,12 +456,12 @@ public class VpnTest {
|
|||||||
assertTrue(vpn.setAlwaysOnPackage(
|
assertTrue(vpn.setAlwaysOnPackage(
|
||||||
PKGS[0], true, Arrays.asList("com.foo.app", PKGS[2], "com.bar.app")));
|
PKGS[0], true, Arrays.asList("com.foo.app", PKGS[2], "com.bar.app")));
|
||||||
verify(mConnectivityManager).setRequireVpnForUids(false, toRanges(new UidRangeParcel[] {
|
verify(mConnectivityManager).setRequireVpnForUids(false, toRanges(new UidRangeParcel[] {
|
||||||
new UidRangeParcel(user.start + PKG_UIDS[0] + 1, user.start + PKG_UIDS[1] - 1),
|
new UidRangeParcel(userStart + PKG_UIDS[0] + 1, userStart + PKG_UIDS[1] - 1),
|
||||||
new UidRangeParcel(user.start + PKG_UIDS[1] + 1, user.stop)
|
new UidRangeParcel(userStart + PKG_UIDS[1] + 1, userStop)
|
||||||
}));
|
}));
|
||||||
verify(mConnectivityManager).setRequireVpnForUids(true, toRanges(new UidRangeParcel[] {
|
verify(mConnectivityManager).setRequireVpnForUids(true, toRanges(new UidRangeParcel[] {
|
||||||
new UidRangeParcel(user.start + PKG_UIDS[0] + 1, user.start + PKG_UIDS[2] - 1),
|
new UidRangeParcel(userStart + PKG_UIDS[0] + 1, userStart + PKG_UIDS[2] - 1),
|
||||||
new UidRangeParcel(user.start + PKG_UIDS[2] + 1, user.stop)
|
new UidRangeParcel(userStart + PKG_UIDS[2] + 1, userStop)
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -452,7 +469,7 @@ public class VpnTest {
|
|||||||
public void testLockdownRuleRepeatability() throws Exception {
|
public void testLockdownRuleRepeatability() throws Exception {
|
||||||
final Vpn vpn = createVpn(primaryUser.id);
|
final Vpn vpn = createVpn(primaryUser.id);
|
||||||
final UidRangeParcel[] primaryUserRangeParcel = new UidRangeParcel[] {
|
final UidRangeParcel[] primaryUserRangeParcel = new UidRangeParcel[] {
|
||||||
new UidRangeParcel(PRI_USER_RANGE.start, PRI_USER_RANGE.stop)};
|
new UidRangeParcel(PRI_USER_RANGE.getLower(), PRI_USER_RANGE.getUpper())};
|
||||||
// Given legacy lockdown is already enabled,
|
// Given legacy lockdown is already enabled,
|
||||||
vpn.setLockdown(true);
|
vpn.setLockdown(true);
|
||||||
verify(mConnectivityManager, times(1)).setRequireVpnForUids(true,
|
verify(mConnectivityManager, times(1)).setRequireVpnForUids(true,
|
||||||
@@ -484,7 +501,7 @@ public class VpnTest {
|
|||||||
public void testLockdownRuleReversibility() throws Exception {
|
public void testLockdownRuleReversibility() throws Exception {
|
||||||
final Vpn vpn = createVpn(primaryUser.id);
|
final Vpn vpn = createVpn(primaryUser.id);
|
||||||
final UidRangeParcel[] entireUser = {
|
final UidRangeParcel[] entireUser = {
|
||||||
new UidRangeParcel(PRI_USER_RANGE.start, PRI_USER_RANGE.stop)
|
new UidRangeParcel(PRI_USER_RANGE.getLower(), PRI_USER_RANGE.getUpper())
|
||||||
};
|
};
|
||||||
final UidRangeParcel[] exceptPkg0 = {
|
final UidRangeParcel[] exceptPkg0 = {
|
||||||
new UidRangeParcel(entireUser[0].start, entireUser[0].start + PKG_UIDS[0] - 1),
|
new UidRangeParcel(entireUser[0].start, entireUser[0].start + PKG_UIDS[0] - 1),
|
||||||
|
|||||||
Reference in New Issue
Block a user