Merge "Add new methods to redact NetworkCapabilities & LinkProperties"
This commit is contained in:
@@ -10,6 +10,8 @@ package android.net {
|
|||||||
method @NonNull @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK, android.Manifest.permission.NETWORK_SETTINGS}) public java.util.List<android.net.NetworkStateSnapshot> getAllNetworkStateSnapshots();
|
method @NonNull @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK, android.Manifest.permission.NETWORK_SETTINGS}) public java.util.List<android.net.NetworkStateSnapshot> getAllNetworkStateSnapshots();
|
||||||
method @Nullable public android.net.ProxyInfo getGlobalProxy();
|
method @Nullable public android.net.ProxyInfo getGlobalProxy();
|
||||||
method @NonNull public static android.util.Range<java.lang.Integer> getIpSecNetIdRange();
|
method @NonNull public static android.util.Range<java.lang.Integer> getIpSecNetIdRange();
|
||||||
|
method @Nullable @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK, android.Manifest.permission.NETWORK_SETTINGS}) public android.net.LinkProperties redactLinkPropertiesForPackage(@NonNull android.net.LinkProperties, int, @NonNull String);
|
||||||
|
method @Nullable @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK, android.Manifest.permission.NETWORK_SETTINGS}) public android.net.NetworkCapabilities redactNetworkCapabilitiesForPackage(@NonNull android.net.NetworkCapabilities, int, @NonNull String);
|
||||||
method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_SETTINGS}) public void registerDefaultNetworkCallbackForUid(int, @NonNull android.net.ConnectivityManager.NetworkCallback, @NonNull android.os.Handler);
|
method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_SETTINGS}) public void registerDefaultNetworkCallbackForUid(int, @NonNull android.net.ConnectivityManager.NetworkCallback, @NonNull android.os.Handler);
|
||||||
method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_SETTINGS}) public void registerSystemDefaultNetworkCallback(@NonNull android.net.ConnectivityManager.NetworkCallback, @NonNull android.os.Handler);
|
method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_SETTINGS}) public void registerSystemDefaultNetworkCallback(@NonNull android.net.ConnectivityManager.NetworkCallback, @NonNull android.os.Handler);
|
||||||
method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void replaceFirewallChain(int, @NonNull int[]);
|
method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void replaceFirewallChain(int, @NonNull int[]);
|
||||||
|
|||||||
@@ -1625,16 +1625,45 @@ public class ConnectivityManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the {@link NetworkCapabilities} for the given {@link Network}. This
|
* Redact {@link LinkProperties} for a given package
|
||||||
* will return {@code null} if the network is unknown or if the |network| argument is null.
|
|
||||||
*
|
*
|
||||||
* This will remove any location sensitive data in {@link TransportInfo} embedded in
|
* Returns an instance of the given {@link LinkProperties} appropriately redacted to send to the
|
||||||
* {@link NetworkCapabilities#getTransportInfo()}. Some transport info instances like
|
* given package, considering its permissions.
|
||||||
* {@link android.net.wifi.WifiInfo} contain location sensitive information. Retrieving
|
*
|
||||||
* this location sensitive information (subject to app's location permissions) will be
|
* @param lp A {@link LinkProperties} which will be redacted.
|
||||||
* noted by system. To include any location sensitive data in {@link TransportInfo},
|
* @param uid The target uid.
|
||||||
* use a {@link NetworkCallback} with
|
* @param packageName The name of the package, for appops logging.
|
||||||
* {@link NetworkCallback#FLAG_INCLUDE_LOCATION_INFO} flag.
|
* @return A redacted {@link LinkProperties} which is appropriate to send to the given uid,
|
||||||
|
* or null if the uid lacks the ACCESS_NETWORK_STATE permission.
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
@RequiresPermission(anyOf = {
|
||||||
|
NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
|
||||||
|
android.Manifest.permission.NETWORK_STACK,
|
||||||
|
android.Manifest.permission.NETWORK_SETTINGS})
|
||||||
|
@SystemApi(client = MODULE_LIBRARIES)
|
||||||
|
@Nullable
|
||||||
|
public LinkProperties redactLinkPropertiesForPackage(@NonNull LinkProperties lp, int uid,
|
||||||
|
@NonNull String packageName) {
|
||||||
|
try {
|
||||||
|
return mService.redactLinkPropertiesForPackage(
|
||||||
|
lp, uid, packageName, getAttributionTag());
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
throw e.rethrowFromSystemServer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the {@link NetworkCapabilities} for the given {@link Network}, or null.
|
||||||
|
*
|
||||||
|
* This will remove any location sensitive data in the returned {@link NetworkCapabilities}.
|
||||||
|
* Some {@link TransportInfo} instances like {@link android.net.wifi.WifiInfo} contain location
|
||||||
|
* sensitive information. To retrieve this location sensitive information (subject to
|
||||||
|
* the caller's location permissions), use a {@link NetworkCallback} with the
|
||||||
|
* {@link NetworkCallback#FLAG_INCLUDE_LOCATION_INFO} flag instead.
|
||||||
|
*
|
||||||
|
* This method returns {@code null} if the network is unknown or if the |network| argument
|
||||||
|
* is null.
|
||||||
*
|
*
|
||||||
* @param network The {@link Network} object identifying the network in question.
|
* @param network The {@link Network} object identifying the network in question.
|
||||||
* @return The {@link NetworkCapabilities} for the network, or {@code null}.
|
* @return The {@link NetworkCapabilities} for the network, or {@code null}.
|
||||||
@@ -1650,6 +1679,38 @@ public class ConnectivityManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Redact {@link NetworkCapabilities} for a given package.
|
||||||
|
*
|
||||||
|
* Returns an instance of {@link NetworkCapabilities} that is appropriately redacted to send
|
||||||
|
* to the given package, considering its permissions. Calling this method will blame the UID for
|
||||||
|
* retrieving the device location if the passed capabilities contain location-sensitive
|
||||||
|
* information.
|
||||||
|
*
|
||||||
|
* @param nc A {@link NetworkCapabilities} instance which will be redacted.
|
||||||
|
* @param uid The target uid.
|
||||||
|
* @param packageName The name of the package, for appops logging.
|
||||||
|
* @return A redacted {@link NetworkCapabilities} which is appropriate to send to the given uid,
|
||||||
|
* or null if the uid lacks the ACCESS_NETWORK_STATE permission.
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
@RequiresPermission(anyOf = {
|
||||||
|
NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
|
||||||
|
android.Manifest.permission.NETWORK_STACK,
|
||||||
|
android.Manifest.permission.NETWORK_SETTINGS})
|
||||||
|
@SystemApi(client = MODULE_LIBRARIES)
|
||||||
|
@Nullable
|
||||||
|
public NetworkCapabilities redactNetworkCapabilitiesForPackage(
|
||||||
|
@NonNull NetworkCapabilities nc,
|
||||||
|
int uid, @NonNull String packageName) {
|
||||||
|
try {
|
||||||
|
return mService.redactNetworkCapabilitiesForPackage(nc, uid, packageName,
|
||||||
|
getAttributionTag());
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
throw e.rethrowFromSystemServer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a URL that can be used for resolving whether a captive portal is present.
|
* Gets a URL that can be used for resolving whether a captive portal is present.
|
||||||
* 1. This URL should respond with a 204 response to a GET request to indicate no captive
|
* 1. This URL should respond with a 204 response to a GET request to indicate no captive
|
||||||
@@ -3547,7 +3608,20 @@ public class ConnectivityManager {
|
|||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
public static final int FLAG_NONE = 0;
|
public static final int FLAG_NONE = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Inclusion of this flag means location-sensitive redaction requests keeping location info.
|
||||||
|
*
|
||||||
|
* Some objects like {@link NetworkCapabilities} may contain location-sensitive information.
|
||||||
|
* Prior to Android 12, this information is always returned to apps holding the appropriate
|
||||||
|
* permission, possibly noting that the app has used location.
|
||||||
|
* <p>In Android 12 and above, by default the sent objects do not contain any location
|
||||||
|
* information, even if the app holds the necessary permissions, and the system does not
|
||||||
|
* take note of location usage by the app. Apps can request that location information is
|
||||||
|
* included, in which case the system will check location permission and the location
|
||||||
|
* toggle state, and take note of location usage by the app if any such information is
|
||||||
|
* returned.
|
||||||
|
*
|
||||||
* Use this flag to include any location sensitive data in {@link NetworkCapabilities} sent
|
* Use this flag to include any location sensitive data in {@link NetworkCapabilities} sent
|
||||||
* via {@link #onCapabilitiesChanged(Network, NetworkCapabilities)}.
|
* via {@link #onCapabilitiesChanged(Network, NetworkCapabilities)}.
|
||||||
* <p>
|
* <p>
|
||||||
@@ -3564,8 +3638,7 @@ public class ConnectivityManager {
|
|||||||
* <li> Retrieving this location sensitive information (subject to app's location
|
* <li> Retrieving this location sensitive information (subject to app's location
|
||||||
* permissions) will be noted by system. </li>
|
* permissions) will be noted by system. </li>
|
||||||
* <li> Without this flag any {@link NetworkCapabilities} provided via the callback does
|
* <li> Without this flag any {@link NetworkCapabilities} provided via the callback does
|
||||||
* not include location sensitive info.
|
* not include location sensitive information.
|
||||||
* </p>
|
|
||||||
*/
|
*/
|
||||||
// Note: Some existing fields which are location sensitive may still be included without
|
// Note: Some existing fields which are location sensitive may still be included without
|
||||||
// this flag if the app targets SDK < S (to maintain backwards compatibility).
|
// this flag if the app targets SDK < S (to maintain backwards compatibility).
|
||||||
|
|||||||
@@ -76,10 +76,15 @@ interface IConnectivityManager
|
|||||||
LinkProperties getActiveLinkProperties();
|
LinkProperties getActiveLinkProperties();
|
||||||
LinkProperties getLinkPropertiesForType(int networkType);
|
LinkProperties getLinkPropertiesForType(int networkType);
|
||||||
LinkProperties getLinkProperties(in Network network);
|
LinkProperties getLinkProperties(in Network network);
|
||||||
|
LinkProperties redactLinkPropertiesForPackage(in LinkProperties lp, int uid, String packageName,
|
||||||
|
String callingAttributionTag);
|
||||||
|
|
||||||
NetworkCapabilities getNetworkCapabilities(in Network network, String callingPackageName,
|
NetworkCapabilities getNetworkCapabilities(in Network network, String callingPackageName,
|
||||||
String callingAttributionTag);
|
String callingAttributionTag);
|
||||||
|
|
||||||
|
NetworkCapabilities redactNetworkCapabilitiesForPackage(in NetworkCapabilities nc, int uid,
|
||||||
|
String callingPackageName, String callingAttributionTag);
|
||||||
|
|
||||||
@UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
|
@UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
|
||||||
NetworkState[] getAllNetworkState();
|
NetworkState[] getAllNetworkState();
|
||||||
|
|
||||||
|
|||||||
@@ -2164,6 +2164,19 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Nullable
|
||||||
|
public LinkProperties redactLinkPropertiesForPackage(@NonNull LinkProperties lp, int uid,
|
||||||
|
@NonNull String packageName, @Nullable String callingAttributionTag) {
|
||||||
|
Objects.requireNonNull(packageName);
|
||||||
|
Objects.requireNonNull(lp);
|
||||||
|
enforceNetworkStackOrSettingsPermission();
|
||||||
|
if (!checkAccessPermission(-1 /* pid */, uid)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return linkPropertiesRestrictedForCallerPermissions(lp, -1 /* callerPid */, uid);
|
||||||
|
}
|
||||||
|
|
||||||
private NetworkCapabilities getNetworkCapabilitiesInternal(Network network) {
|
private NetworkCapabilities getNetworkCapabilitiesInternal(Network network) {
|
||||||
return getNetworkCapabilitiesInternal(getNetworkAgentInfoForNetwork(network));
|
return getNetworkCapabilitiesInternal(getNetworkAgentInfoForNetwork(network));
|
||||||
}
|
}
|
||||||
@@ -2187,13 +2200,34 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
getCallingPid(), mDeps.getCallingUid(), callingPackageName, callingAttributionTag);
|
getCallingPid(), mDeps.getCallingUid(), callingPackageName, callingAttributionTag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NetworkCapabilities redactNetworkCapabilitiesForPackage(@NonNull NetworkCapabilities nc,
|
||||||
|
int uid, @NonNull String packageName, @Nullable String callingAttributionTag) {
|
||||||
|
Objects.requireNonNull(nc);
|
||||||
|
Objects.requireNonNull(packageName);
|
||||||
|
enforceNetworkStackOrSettingsPermission();
|
||||||
|
if (!checkAccessPermission(-1 /* pid */, uid)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return createWithLocationInfoSanitizedIfNecessaryWhenParceled(
|
||||||
|
networkCapabilitiesRestrictedForCallerPermissions(nc, -1 /* callerPid */, uid),
|
||||||
|
true /* includeLocationSensitiveInfo */, -1 /* callingPid */, uid, packageName,
|
||||||
|
callingAttributionTag);
|
||||||
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
NetworkCapabilities networkCapabilitiesRestrictedForCallerPermissions(
|
NetworkCapabilities networkCapabilitiesRestrictedForCallerPermissions(
|
||||||
NetworkCapabilities nc, int callerPid, int callerUid) {
|
NetworkCapabilities nc, int callerPid, int callerUid) {
|
||||||
|
// Note : here it would be nice to check ACCESS_NETWORK_STATE and return null, but
|
||||||
|
// this would be expensive (one more permission check every time any NC callback is
|
||||||
|
// sent) and possibly dangerous : apps normally can't lose ACCESS_NETWORK_STATE, if
|
||||||
|
// it happens for some reason (e.g. the package is uninstalled while CS is trying to
|
||||||
|
// send the callback) it would crash the system server with NPE.
|
||||||
final NetworkCapabilities newNc = new NetworkCapabilities(nc);
|
final NetworkCapabilities newNc = new NetworkCapabilities(nc);
|
||||||
if (!checkSettingsPermission(callerPid, callerUid)) {
|
if (!checkSettingsPermission(callerPid, callerUid)) {
|
||||||
newNc.setUids(null);
|
newNc.setUids(null);
|
||||||
newNc.setSSID(null);
|
newNc.setSSID(null);
|
||||||
|
// TODO: Processes holding NETWORK_FACTORY should be able to see the underlying networks
|
||||||
newNc.setUnderlyingNetworks(null);
|
newNc.setUnderlyingNetworks(null);
|
||||||
}
|
}
|
||||||
if (newNc.getNetworkSpecifier() != null) {
|
if (newNc.getNetworkSpecifier() != null) {
|
||||||
@@ -2211,7 +2245,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Wrapper used to cache the permission check results performed for the corresponding
|
* Wrapper used to cache the permission check results performed for the corresponding
|
||||||
* app. This avoid performing multiple permission checks for different fields in
|
* app. This avoids performing multiple permission checks for different fields in
|
||||||
* NetworkCapabilities.
|
* NetworkCapabilities.
|
||||||
* Note: This wrapper does not support any sort of invalidation and thus must not be
|
* 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
|
* persistent or long-lived. It may only be used for the time necessary to
|
||||||
@@ -2339,6 +2373,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
includeLocationSensitiveInfo);
|
includeLocationSensitiveInfo);
|
||||||
final NetworkCapabilities newNc = new NetworkCapabilities(nc, redactions);
|
final NetworkCapabilities newNc = new NetworkCapabilities(nc, redactions);
|
||||||
// Reset owner uid if not destined for the owner app.
|
// Reset owner uid if not destined for the owner app.
|
||||||
|
// TODO : calling UID is redacted because apps should generally not know what UID is
|
||||||
|
// bringing up the VPN, but this should not apply to some very privileged apps like settings
|
||||||
if (callingUid != nc.getOwnerUid()) {
|
if (callingUid != nc.getOwnerUid()) {
|
||||||
newNc.setOwnerUid(INVALID_UID);
|
newNc.setOwnerUid(INVALID_UID);
|
||||||
return newNc;
|
return newNc;
|
||||||
@@ -2364,9 +2400,15 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
return newNc;
|
return newNc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
private LinkProperties linkPropertiesRestrictedForCallerPermissions(
|
private LinkProperties linkPropertiesRestrictedForCallerPermissions(
|
||||||
LinkProperties lp, int callerPid, int callerUid) {
|
LinkProperties lp, int callerPid, int callerUid) {
|
||||||
if (lp == null) return new LinkProperties();
|
if (lp == null) return new LinkProperties();
|
||||||
|
// Note : here it would be nice to check ACCESS_NETWORK_STATE and return null, but
|
||||||
|
// this would be expensive (one more permission check every time any LP callback is
|
||||||
|
// sent) and possibly dangerous : apps normally can't lose ACCESS_NETWORK_STATE, if
|
||||||
|
// it happens for some reason (e.g. the package is uninstalled while CS is trying to
|
||||||
|
// send the callback) it would crash the system server with NPE.
|
||||||
|
|
||||||
// Only do a permission check if sanitization is needed, to avoid unnecessary binder calls.
|
// Only do a permission check if sanitization is needed, to avoid unnecessary binder calls.
|
||||||
final boolean needsSanitization =
|
final boolean needsSanitization =
|
||||||
@@ -2737,6 +2779,11 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
"ConnectivityService");
|
"ConnectivityService");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean checkAccessPermission(int pid, int uid) {
|
||||||
|
return mContext.checkPermission(android.Manifest.permission.ACCESS_NETWORK_STATE, pid, uid)
|
||||||
|
== PERMISSION_GRANTED;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Performs a strict and comprehensive check of whether a calling package is allowed to
|
* Performs a strict and comprehensive check of whether a calling package is allowed to
|
||||||
* change the state of network, as the condition differs for pre-M, M+, and
|
* change the state of network, as the condition differs for pre-M, M+, and
|
||||||
|
|||||||
@@ -16,9 +16,15 @@
|
|||||||
|
|
||||||
package android.net.cts;
|
package android.net.cts;
|
||||||
|
|
||||||
|
import static android.Manifest.permission.ACCESS_COARSE_LOCATION;
|
||||||
|
import static android.Manifest.permission.ACCESS_FINE_LOCATION;
|
||||||
|
import static android.Manifest.permission.ACCESS_NETWORK_STATE;
|
||||||
import static android.Manifest.permission.CONNECTIVITY_INTERNAL;
|
import static android.Manifest.permission.CONNECTIVITY_INTERNAL;
|
||||||
import static android.Manifest.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS;
|
import static android.Manifest.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS;
|
||||||
|
import static android.Manifest.permission.NETWORK_FACTORY;
|
||||||
import static android.Manifest.permission.NETWORK_SETTINGS;
|
import static android.Manifest.permission.NETWORK_SETTINGS;
|
||||||
|
import static android.Manifest.permission.NETWORK_SETUP_WIZARD;
|
||||||
|
import static android.Manifest.permission.NETWORK_STACK;
|
||||||
import static android.Manifest.permission.READ_DEVICE_CONFIG;
|
import static android.Manifest.permission.READ_DEVICE_CONFIG;
|
||||||
import static android.content.pm.PackageManager.FEATURE_BLUETOOTH;
|
import static android.content.pm.PackageManager.FEATURE_BLUETOOTH;
|
||||||
import static android.content.pm.PackageManager.FEATURE_ETHERNET;
|
import static android.content.pm.PackageManager.FEATURE_ETHERNET;
|
||||||
@@ -54,7 +60,9 @@ import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED;
|
|||||||
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.TRANSPORT_TEST;
|
import static android.net.NetworkCapabilities.TRANSPORT_TEST;
|
||||||
|
import static android.net.NetworkCapabilities.TRANSPORT_VPN;
|
||||||
import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
|
import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
|
||||||
|
import static android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK;
|
||||||
import static android.net.cts.util.CtsNetUtils.ConnectivityActionReceiver;
|
import static android.net.cts.util.CtsNetUtils.ConnectivityActionReceiver;
|
||||||
import static android.net.cts.util.CtsNetUtils.HTTP_PORT;
|
import static android.net.cts.util.CtsNetUtils.HTTP_PORT;
|
||||||
import static android.net.cts.util.CtsNetUtils.NETWORK_CALLBACK_ACTION;
|
import static android.net.cts.util.CtsNetUtils.NETWORK_CALLBACK_ACTION;
|
||||||
@@ -64,6 +72,7 @@ import static android.net.cts.util.CtsTetheringUtils.TestTetheringEventCallback;
|
|||||||
import static android.net.util.NetworkStackUtils.TEST_CAPTIVE_PORTAL_HTTPS_URL;
|
import static android.net.util.NetworkStackUtils.TEST_CAPTIVE_PORTAL_HTTPS_URL;
|
||||||
import static android.net.util.NetworkStackUtils.TEST_CAPTIVE_PORTAL_HTTP_URL;
|
import static android.net.util.NetworkStackUtils.TEST_CAPTIVE_PORTAL_HTTP_URL;
|
||||||
import static android.os.MessageQueue.OnFileDescriptorEventListener.EVENT_INPUT;
|
import static android.os.MessageQueue.OnFileDescriptorEventListener.EVENT_INPUT;
|
||||||
|
import static android.os.Process.INVALID_UID;
|
||||||
import static android.provider.Settings.Global.NETWORK_METERED_MULTIPATH_PREFERENCE;
|
import static android.provider.Settings.Global.NETWORK_METERED_MULTIPATH_PREFERENCE;
|
||||||
import static android.system.OsConstants.AF_INET;
|
import static android.system.OsConstants.AF_INET;
|
||||||
import static android.system.OsConstants.AF_INET6;
|
import static android.system.OsConstants.AF_INET6;
|
||||||
@@ -76,6 +85,7 @@ import static com.android.modules.utils.build.SdkLevel.isAtLeastS;
|
|||||||
import static com.android.networkstack.apishim.ConstantsShim.BLOCKED_REASON_LOCKDOWN_VPN;
|
import static com.android.networkstack.apishim.ConstantsShim.BLOCKED_REASON_LOCKDOWN_VPN;
|
||||||
import static com.android.networkstack.apishim.ConstantsShim.BLOCKED_REASON_NONE;
|
import static com.android.networkstack.apishim.ConstantsShim.BLOCKED_REASON_NONE;
|
||||||
import static com.android.testutils.Cleanup.testAndCleanup;
|
import static com.android.testutils.Cleanup.testAndCleanup;
|
||||||
|
import static com.android.testutils.DevSdkIgnoreRuleKt.SC_V2;
|
||||||
import static com.android.testutils.MiscAsserts.assertThrows;
|
import static com.android.testutils.MiscAsserts.assertThrows;
|
||||||
import static com.android.testutils.TestNetworkTrackerKt.initTestNetwork;
|
import static com.android.testutils.TestNetworkTrackerKt.initTestNetwork;
|
||||||
import static com.android.testutils.TestPermissionUtil.runAsShell;
|
import static com.android.testutils.TestPermissionUtil.runAsShell;
|
||||||
@@ -103,6 +113,7 @@ import android.content.IntentFilter;
|
|||||||
import android.content.pm.PackageInfo;
|
import android.content.pm.PackageInfo;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
|
import android.net.CaptivePortalData;
|
||||||
import android.net.ConnectivityManager;
|
import android.net.ConnectivityManager;
|
||||||
import android.net.ConnectivityManager.NetworkCallback;
|
import android.net.ConnectivityManager.NetworkCallback;
|
||||||
import android.net.ConnectivitySettingsManager;
|
import android.net.ConnectivitySettingsManager;
|
||||||
@@ -132,6 +143,7 @@ import android.net.Uri;
|
|||||||
import android.net.cts.util.CtsNetUtils;
|
import android.net.cts.util.CtsNetUtils;
|
||||||
import android.net.cts.util.CtsTetheringUtils;
|
import android.net.cts.util.CtsTetheringUtils;
|
||||||
import android.net.util.KeepaliveUtils;
|
import android.net.util.KeepaliveUtils;
|
||||||
|
import android.net.wifi.WifiInfo;
|
||||||
import android.net.wifi.WifiManager;
|
import android.net.wifi.WifiManager;
|
||||||
import android.os.Binder;
|
import android.os.Binder;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
@@ -160,6 +172,7 @@ import androidx.test.runner.AndroidJUnit4;
|
|||||||
|
|
||||||
import com.android.internal.util.ArrayUtils;
|
import com.android.internal.util.ArrayUtils;
|
||||||
import com.android.modules.utils.build.SdkLevel;
|
import com.android.modules.utils.build.SdkLevel;
|
||||||
|
import com.android.net.module.util.CollectionUtils;
|
||||||
import com.android.networkstack.apishim.ConnectivityManagerShimImpl;
|
import com.android.networkstack.apishim.ConnectivityManagerShimImpl;
|
||||||
import com.android.networkstack.apishim.ConstantsShim;
|
import com.android.networkstack.apishim.ConstantsShim;
|
||||||
import com.android.networkstack.apishim.NetworkInformationShimImpl;
|
import com.android.networkstack.apishim.NetworkInformationShimImpl;
|
||||||
@@ -554,6 +567,223 @@ public class ConnectivityManagerTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean checkPermission(String perm, int uid) {
|
||||||
|
return mContext.checkPermission(perm, -1 /* pid */, uid) == PERMISSION_GRANTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String findPackageByPermissions(@NonNull List<String> requiredPermissions,
|
||||||
|
@NonNull List<String> forbiddenPermissions) throws Exception {
|
||||||
|
final List<PackageInfo> packageInfos =
|
||||||
|
mPackageManager.getInstalledPackages(GET_PERMISSIONS);
|
||||||
|
for (PackageInfo packageInfo : packageInfos) {
|
||||||
|
final int uid = mPackageManager.getPackageUid(packageInfo.packageName, 0 /* flags */);
|
||||||
|
if (!CollectionUtils.all(requiredPermissions, perm -> checkPermission(perm, uid))) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (CollectionUtils.any(forbiddenPermissions, perm -> checkPermission(perm, uid))) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return packageInfo.packageName;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@DevSdkIgnoreRule.IgnoreUpTo(SC_V2)
|
||||||
|
@Test
|
||||||
|
public void testRedactLinkPropertiesForPackage() throws Exception {
|
||||||
|
final String groundedPkg = findPackageByPermissions(
|
||||||
|
List.of(), /* requiredPermissions */
|
||||||
|
List.of(ACCESS_NETWORK_STATE) /* forbiddenPermissions */);
|
||||||
|
assertNotNull("Couldn't find any package without ACCESS_NETWORK_STATE", groundedPkg);
|
||||||
|
final int groundedUid = mPackageManager.getPackageUid(groundedPkg, 0 /* flags */);
|
||||||
|
|
||||||
|
final String normalPkg = findPackageByPermissions(
|
||||||
|
List.of(ACCESS_NETWORK_STATE) /* requiredPermissions */,
|
||||||
|
List.of(NETWORK_SETTINGS, NETWORK_STACK,
|
||||||
|
PERMISSION_MAINLINE_NETWORK_STACK) /* forbiddenPermissions */);
|
||||||
|
assertNotNull("Couldn't find any package with ACCESS_NETWORK_STATE but"
|
||||||
|
+ " without NETWORK_SETTINGS", normalPkg);
|
||||||
|
final int normalUid = mPackageManager.getPackageUid(normalPkg, 0 /* flags */);
|
||||||
|
|
||||||
|
// There are some privileged packages on the system, like the phone process, the network
|
||||||
|
// stack and the system server.
|
||||||
|
final String privilegedPkg = findPackageByPermissions(
|
||||||
|
List.of(ACCESS_NETWORK_STATE, NETWORK_SETTINGS), /* requiredPermissions */
|
||||||
|
List.of() /* forbiddenPermissions */);
|
||||||
|
assertNotNull("Couldn't find a package with sufficient permissions", privilegedPkg);
|
||||||
|
final int privilegedUid = mPackageManager.getPackageUid(privilegedPkg, 0);
|
||||||
|
|
||||||
|
// Set parcelSensitiveFields to true to preserve CaptivePortalApiUrl & CaptivePortalData
|
||||||
|
// when parceling.
|
||||||
|
final LinkProperties lp = new LinkProperties(new LinkProperties(),
|
||||||
|
true /* parcelSensitiveFields */);
|
||||||
|
final Uri capportUrl = Uri.parse("https://capport.example.com/api");
|
||||||
|
final CaptivePortalData capportData = new CaptivePortalData.Builder().build();
|
||||||
|
final int mtu = 12345;
|
||||||
|
lp.setMtu(mtu);
|
||||||
|
lp.setCaptivePortalApiUrl(capportUrl);
|
||||||
|
lp.setCaptivePortalData(capportData);
|
||||||
|
|
||||||
|
// No matter what the given uid is, a SecurityException will be thrown if the caller
|
||||||
|
// doesn't hold the NETWORK_SETTINGS permission.
|
||||||
|
assertThrows(SecurityException.class,
|
||||||
|
() -> mCm.redactLinkPropertiesForPackage(lp, groundedUid, groundedPkg));
|
||||||
|
assertThrows(SecurityException.class,
|
||||||
|
() -> mCm.redactLinkPropertiesForPackage(lp, normalUid, normalPkg));
|
||||||
|
assertThrows(SecurityException.class,
|
||||||
|
() -> mCm.redactLinkPropertiesForPackage(lp, privilegedUid, privilegedPkg));
|
||||||
|
|
||||||
|
runAsShell(NETWORK_SETTINGS, () -> {
|
||||||
|
// No matter what the given uid is, if the given LinkProperties is null, then
|
||||||
|
// NullPointerException will be thrown.
|
||||||
|
assertThrows(NullPointerException.class,
|
||||||
|
() -> mCm.redactLinkPropertiesForPackage(null, groundedUid, groundedPkg));
|
||||||
|
assertThrows(NullPointerException.class,
|
||||||
|
() -> mCm.redactLinkPropertiesForPackage(null, normalUid, normalPkg));
|
||||||
|
assertThrows(NullPointerException.class,
|
||||||
|
() -> mCm.redactLinkPropertiesForPackage(null, privilegedUid, privilegedPkg));
|
||||||
|
|
||||||
|
// Make sure null is returned for a UID without ACCESS_NETWORK_STATE.
|
||||||
|
assertNull(mCm.redactLinkPropertiesForPackage(lp, groundedUid, groundedPkg));
|
||||||
|
|
||||||
|
// CaptivePortalApiUrl & CaptivePortalData will be set to null if given uid doesn't hold
|
||||||
|
// the NETWORK_SETTINGS permission.
|
||||||
|
assertNull(mCm.redactLinkPropertiesForPackage(lp, normalUid, normalPkg)
|
||||||
|
.getCaptivePortalApiUrl());
|
||||||
|
assertNull(mCm.redactLinkPropertiesForPackage(lp, normalUid, normalPkg)
|
||||||
|
.getCaptivePortalData());
|
||||||
|
// MTU is not sensitive and is not redacted.
|
||||||
|
assertEquals(mtu, mCm.redactLinkPropertiesForPackage(lp, normalUid, normalPkg)
|
||||||
|
.getMtu());
|
||||||
|
|
||||||
|
// CaptivePortalApiUrl & CaptivePortalData will be preserved if the given uid holds the
|
||||||
|
// NETWORK_SETTINGS permission.
|
||||||
|
assertEquals(capportUrl,
|
||||||
|
mCm.redactLinkPropertiesForPackage(lp, privilegedUid, privilegedPkg)
|
||||||
|
.getCaptivePortalApiUrl());
|
||||||
|
assertEquals(capportData,
|
||||||
|
mCm.redactLinkPropertiesForPackage(lp, privilegedUid, privilegedPkg)
|
||||||
|
.getCaptivePortalData());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private NetworkCapabilities redactNc(@NonNull final NetworkCapabilities nc, int uid,
|
||||||
|
@NonNull String packageName) {
|
||||||
|
return mCm.redactNetworkCapabilitiesForPackage(nc, uid, packageName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@DevSdkIgnoreRule.IgnoreUpTo(SC_V2)
|
||||||
|
@Test
|
||||||
|
public void testRedactNetworkCapabilitiesForPackage() throws Exception {
|
||||||
|
final String groundedPkg = findPackageByPermissions(
|
||||||
|
List.of(), /* requiredPermissions */
|
||||||
|
List.of(ACCESS_NETWORK_STATE) /* forbiddenPermissions */);
|
||||||
|
assertNotNull("Couldn't find any package without ACCESS_NETWORK_STATE", groundedPkg);
|
||||||
|
final int groundedUid = mPackageManager.getPackageUid(groundedPkg, 0 /* flags */);
|
||||||
|
|
||||||
|
// A package which doesn't have any of the permissions below, but has NETWORK_STATE.
|
||||||
|
// There should be a number of packages like this on the device; AOSP has many,
|
||||||
|
// including contacts, webview, the keyboard, pacprocessor, messaging.
|
||||||
|
final String normalPkg = findPackageByPermissions(
|
||||||
|
List.of(ACCESS_NETWORK_STATE) /* requiredPermissions */,
|
||||||
|
List.of(NETWORK_SETTINGS, NETWORK_FACTORY, NETWORK_SETUP_WIZARD,
|
||||||
|
NETWORK_STACK, PERMISSION_MAINLINE_NETWORK_STACK,
|
||||||
|
ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION) /* forbiddenPermissions */);
|
||||||
|
assertNotNull("Can't find a package with ACCESS_NETWORK_STATE but without any of"
|
||||||
|
+ " the forbidden permissions", normalPkg);
|
||||||
|
final int normalUid = mPackageManager.getPackageUid(normalPkg, 0 /* flags */);
|
||||||
|
|
||||||
|
// There are some privileged packages on the system, like the phone process, the network
|
||||||
|
// stack and the system server.
|
||||||
|
final String privilegedPkg = findPackageByPermissions(
|
||||||
|
List.of(ACCESS_NETWORK_STATE, NETWORK_SETTINGS, NETWORK_FACTORY,
|
||||||
|
ACCESS_FINE_LOCATION), /* requiredPermissions */
|
||||||
|
List.of() /* forbiddenPermissions */);
|
||||||
|
assertNotNull("Couldn't find a package with sufficient permissions", privilegedPkg);
|
||||||
|
final int privilegedUid = mPackageManager.getPackageUid(privilegedPkg, 0);
|
||||||
|
|
||||||
|
final Set<Range<Integer>> uids = new ArraySet<>();
|
||||||
|
uids.add(new Range<>(10000, 10100));
|
||||||
|
uids.add(new Range<>(10200, 10300));
|
||||||
|
final String ssid = "My-WiFi";
|
||||||
|
// This test will set underlying networks in the capabilities to redact to see if they
|
||||||
|
// are appropriately redacted, so fetch the default network to put in there as an example.
|
||||||
|
final Network defaultNetwork = mCm.getActiveNetwork();
|
||||||
|
assertNotNull("CTS requires a working Internet connection", defaultNetwork);
|
||||||
|
final int subId1 = 1;
|
||||||
|
final int subId2 = 2;
|
||||||
|
final int[] administratorUids = {normalUid};
|
||||||
|
final String bssid = "location sensitive";
|
||||||
|
final int rssi = 43; // not location sensitive
|
||||||
|
final WifiInfo wifiInfo = new WifiInfo.Builder()
|
||||||
|
.setBssid(bssid)
|
||||||
|
.setRssi(rssi)
|
||||||
|
.build();
|
||||||
|
final NetworkCapabilities nc = new NetworkCapabilities.Builder()
|
||||||
|
.setUids(uids)
|
||||||
|
.setSsid(ssid)
|
||||||
|
.setUnderlyingNetworks(List.of(defaultNetwork))
|
||||||
|
.setSubscriptionIds(Set.of(subId1, subId2))
|
||||||
|
.setAdministratorUids(administratorUids)
|
||||||
|
.setOwnerUid(normalUid)
|
||||||
|
.setTransportInfo(wifiInfo)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// No matter what the given uid is, a SecurityException will be thrown if the caller
|
||||||
|
// doesn't hold the NETWORK_SETTINGS permission.
|
||||||
|
assertThrows(SecurityException.class, () -> redactNc(nc, groundedUid, groundedPkg));
|
||||||
|
assertThrows(SecurityException.class, () -> redactNc(nc, normalUid, normalPkg));
|
||||||
|
assertThrows(SecurityException.class, () -> redactNc(nc, privilegedUid, privilegedPkg));
|
||||||
|
|
||||||
|
runAsShell(NETWORK_SETTINGS, () -> {
|
||||||
|
// Make sure that the NC is null if the package doesn't hold ACCESS_NETWORK_STATE.
|
||||||
|
assertNull(redactNc(nc, groundedUid, groundedPkg));
|
||||||
|
|
||||||
|
// Uids, ssid, underlying networks & subscriptionIds will be redacted if the given uid
|
||||||
|
// doesn't hold the associated permissions. The wifi transport info is also suitably
|
||||||
|
// redacted.
|
||||||
|
final NetworkCapabilities redactedNormal = redactNc(nc, normalUid, normalPkg);
|
||||||
|
assertNull(redactedNormal.getUids());
|
||||||
|
assertNull(redactedNormal.getSsid());
|
||||||
|
assertNull(redactedNormal.getUnderlyingNetworks());
|
||||||
|
assertEquals(0, redactedNormal.getSubscriptionIds().size());
|
||||||
|
assertEquals(WifiInfo.DEFAULT_MAC_ADDRESS,
|
||||||
|
((WifiInfo) redactedNormal.getTransportInfo()).getBSSID());
|
||||||
|
assertEquals(rssi, ((WifiInfo) redactedNormal.getTransportInfo()).getRssi());
|
||||||
|
|
||||||
|
// Uids, ssid, underlying networks & subscriptionIds will be preserved if the given uid
|
||||||
|
// holds the associated permissions.
|
||||||
|
final NetworkCapabilities redactedPrivileged =
|
||||||
|
redactNc(nc, privilegedUid, privilegedPkg);
|
||||||
|
assertEquals(uids, redactedPrivileged.getUids());
|
||||||
|
assertEquals(ssid, redactedPrivileged.getSsid());
|
||||||
|
assertEquals(List.of(defaultNetwork), redactedPrivileged.getUnderlyingNetworks());
|
||||||
|
assertEquals(Set.of(subId1, subId2), redactedPrivileged.getSubscriptionIds());
|
||||||
|
assertEquals(bssid, ((WifiInfo) redactedPrivileged.getTransportInfo()).getBSSID());
|
||||||
|
assertEquals(rssi, ((WifiInfo) redactedPrivileged.getTransportInfo()).getRssi());
|
||||||
|
|
||||||
|
// The owner uid is only preserved when the network is a VPN and the uid is the
|
||||||
|
// same as the owner uid.
|
||||||
|
nc.addTransportType(TRANSPORT_VPN);
|
||||||
|
assertEquals(normalUid, redactNc(nc, normalUid, normalPkg).getOwnerUid());
|
||||||
|
assertEquals(INVALID_UID, redactNc(nc, privilegedUid, privilegedPkg).getOwnerUid());
|
||||||
|
nc.removeTransportType(TRANSPORT_VPN);
|
||||||
|
|
||||||
|
// If the given uid doesn't hold location permissions, the owner uid will be set to
|
||||||
|
// INVALID_UID even when sent to that UID (this avoids a wifi suggestor knowing where
|
||||||
|
// the device is by virtue of the device connecting to its own network).
|
||||||
|
assertEquals(INVALID_UID, redactNc(nc, normalUid, normalPkg).getOwnerUid());
|
||||||
|
|
||||||
|
// If the given uid holds location permissions, the owner uid is preserved. This works
|
||||||
|
// because the shell holds ACCESS_FINE_LOCATION.
|
||||||
|
final int[] administratorUids2 = { privilegedUid };
|
||||||
|
nc.setAdministratorUids(administratorUids2);
|
||||||
|
nc.setOwnerUid(privilegedUid);
|
||||||
|
assertEquals(privilegedUid, redactNc(nc, privilegedUid, privilegedPkg).getOwnerUid());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests that connections can be opened on WiFi and cellphone networks,
|
* Tests that connections can be opened on WiFi and cellphone networks,
|
||||||
* and that they are made from different IP addresses.
|
* and that they are made from different IP addresses.
|
||||||
|
|||||||
Reference in New Issue
Block a user