Allow VPN apps to ask for running the validation checks
Expose an API to allow VPNs app to ask for running the validation check on the VPN network built from Ikev2VpnProfile. Bug: 184750836 Test: New test in Ikev2VpnTest Also FrameworksNetTests Change-Id: I385bb887b6c697d8f5d87af750dbd2aab44afca6 CTS-Coverage-Bug: 184750836 (but CTS is in the same topic, just not detected by the tool)
This commit is contained in:
parent
1962b10531
commit
3fc98d5ebd
@ -25227,6 +25227,7 @@ package android.net {
|
||||
method @NonNull public android.net.Ikev2VpnProfile.Builder setMaxMtu(int);
|
||||
method @NonNull public android.net.Ikev2VpnProfile.Builder setMetered(boolean);
|
||||
method @NonNull public android.net.Ikev2VpnProfile.Builder setProxy(@Nullable android.net.ProxyInfo);
|
||||
method @NonNull public android.net.Ikev2VpnProfile.Builder setRequiresInternetValidation(boolean);
|
||||
}
|
||||
|
||||
public final class IpSecAlgorithm implements android.os.Parcelable {
|
||||
@ -25370,6 +25371,7 @@ package android.net {
|
||||
|
||||
public abstract class PlatformVpnProfile {
|
||||
method public final boolean getExcludeLocalRoutes();
|
||||
method public final boolean getRequiresInternetValidation();
|
||||
method public final int getType();
|
||||
method @NonNull public final String getTypeString();
|
||||
field public static final int TYPE_IKEV2_IPSEC_PSK = 7; // 0x7
|
||||
|
@ -159,8 +159,9 @@ public final class Ikev2VpnProfile extends PlatformVpnProfile {
|
||||
boolean isMetered,
|
||||
int maxMtu,
|
||||
boolean restrictToTestNetworks,
|
||||
boolean excludeLocalRoutes) {
|
||||
super(type, excludeLocalRoutes);
|
||||
boolean excludeLocalRoutes,
|
||||
boolean requiresInternetValidation) {
|
||||
super(type, excludeLocalRoutes, requiresInternetValidation);
|
||||
|
||||
checkNotNull(serverAddr, MISSING_PARAM_MSG_TMPL, "Server address");
|
||||
checkNotNull(userIdentity, MISSING_PARAM_MSG_TMPL, "User Identity");
|
||||
@ -181,7 +182,7 @@ public final class Ikev2VpnProfile extends PlatformVpnProfile {
|
||||
mAllowedAlgorithms = Collections.unmodifiableList(new ArrayList<>(allowedAlgorithms));
|
||||
if (excludeLocalRoutes && !isBypassable) {
|
||||
throw new IllegalArgumentException(
|
||||
"Vpn should be byassable if excludeLocalRoutes is set");
|
||||
"Vpn must be bypassable if excludeLocalRoutes is set");
|
||||
}
|
||||
|
||||
mIsBypassable = isBypassable;
|
||||
@ -238,7 +239,7 @@ public final class Ikev2VpnProfile extends PlatformVpnProfile {
|
||||
* that provides Authentication, and one that provides Encryption. Authenticated Encryption with
|
||||
* Associated Data (AEAD) algorithms are counted as providing Authentication and Encryption.
|
||||
*
|
||||
* @param allowedAlgorithms The list to be validated
|
||||
* @param algorithmNames The list to be validated
|
||||
*/
|
||||
private static void validateAllowedAlgorithms(@NonNull List<String> algorithmNames) {
|
||||
// First, make sure no insecure algorithms were proposed.
|
||||
@ -400,7 +401,9 @@ public final class Ikev2VpnProfile extends PlatformVpnProfile {
|
||||
mIsBypassable,
|
||||
mIsMetered,
|
||||
mMaxMtu,
|
||||
mIsRestrictedToTestNetworks);
|
||||
mIsRestrictedToTestNetworks,
|
||||
mExcludeLocalRoutes,
|
||||
mRequiresInternetValidation);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -425,7 +428,8 @@ public final class Ikev2VpnProfile extends PlatformVpnProfile {
|
||||
&& mIsMetered == other.mIsMetered
|
||||
&& mMaxMtu == other.mMaxMtu
|
||||
&& mIsRestrictedToTestNetworks == other.mIsRestrictedToTestNetworks
|
||||
&& mExcludeLocalRoutes == other.mExcludeLocalRoutes;
|
||||
&& mExcludeLocalRoutes == other.mExcludeLocalRoutes
|
||||
&& mRequiresInternetValidation == other.mRequiresInternetValidation;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -439,7 +443,7 @@ public final class Ikev2VpnProfile extends PlatformVpnProfile {
|
||||
@NonNull
|
||||
public VpnProfile toVpnProfile() throws IOException, GeneralSecurityException {
|
||||
final VpnProfile profile = new VpnProfile("" /* Key; value unused by IKEv2VpnProfile(s) */,
|
||||
mIsRestrictedToTestNetworks, mExcludeLocalRoutes);
|
||||
mIsRestrictedToTestNetworks, mExcludeLocalRoutes, mRequiresInternetValidation);
|
||||
profile.type = mType;
|
||||
profile.server = mServerAddr;
|
||||
profile.ipsecIdentifier = mUserIdentity;
|
||||
@ -544,6 +548,7 @@ public final class Ikev2VpnProfile extends PlatformVpnProfile {
|
||||
Log.w(TAG, "ExcludeLocalRoutes should only be set in the bypassable VPN");
|
||||
}
|
||||
builder.setExcludeLocalRoutes(profile.excludeLocalRoutes && profile.isBypassable);
|
||||
builder.setRequiresInternetValidation(profile.requiresInternetValidation);
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
@ -776,6 +781,7 @@ public final class Ikev2VpnProfile extends PlatformVpnProfile {
|
||||
|
||||
@Nullable private ProxyInfo mProxyInfo;
|
||||
@NonNull private List<String> mAllowedAlgorithms = DEFAULT_ALGORITHMS;
|
||||
private boolean mRequiresInternetValidation = false;
|
||||
private boolean mIsBypassable = false;
|
||||
private boolean mIsMetered = true;
|
||||
private int mMaxMtu = PlatformVpnProfile.MAX_MTU_DEFAULT;
|
||||
@ -987,6 +993,30 @@ public final class Ikev2VpnProfile extends PlatformVpnProfile {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Request that this VPN undergoes Internet validation.
|
||||
*
|
||||
* If this is true, the platform will perform basic validation checks for Internet
|
||||
* connectivity over this VPN. If and when they succeed, the VPN network capabilities will
|
||||
* reflect this by gaining the {@link NetworkCapabilities#NET_CAPABILITY_VALIDATED}
|
||||
* capability.
|
||||
*
|
||||
* If this is false, the platform assumes the VPN either is always capable of reaching the
|
||||
* Internet or intends not to. In this case, the VPN network capabilities will
|
||||
* always gain the {@link NetworkCapabilities#NET_CAPABILITY_VALIDATED} capability
|
||||
* immediately after it connects, whether it can reach public Internet destinations or not.
|
||||
*
|
||||
* @param requiresInternetValidation {@code true} if the framework should attempt to
|
||||
* validate this VPN for Internet connectivity. Defaults
|
||||
* to {@code false}.
|
||||
*/
|
||||
@NonNull
|
||||
@RequiresFeature(PackageManager.FEATURE_IPSEC_TUNNELS)
|
||||
public Builder setRequiresInternetValidation(boolean requiresInternetValidation) {
|
||||
mRequiresInternetValidation = requiresInternetValidation;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks the VPN network as metered.
|
||||
*
|
||||
@ -1103,7 +1133,8 @@ public final class Ikev2VpnProfile extends PlatformVpnProfile {
|
||||
mIsMetered,
|
||||
mMaxMtu,
|
||||
mIsRestrictedToTestNetworks,
|
||||
mExcludeLocalRoutes);
|
||||
mExcludeLocalRoutes,
|
||||
mRequiresInternetValidation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -16,10 +16,6 @@
|
||||
|
||||
package android.net;
|
||||
|
||||
import static android.net.PlatformVpnProfile.TYPE_IKEV2_IPSEC_PSK;
|
||||
import static android.net.PlatformVpnProfile.TYPE_IKEV2_IPSEC_RSA;
|
||||
import static android.net.PlatformVpnProfile.TYPE_IKEV2_IPSEC_USER_PASS;
|
||||
|
||||
import android.annotation.IntDef;
|
||||
import android.annotation.NonNull;
|
||||
|
||||
@ -67,11 +63,15 @@ public abstract class PlatformVpnProfile {
|
||||
|
||||
/** @hide */
|
||||
protected final boolean mExcludeLocalRoutes;
|
||||
/** @hide */
|
||||
protected final boolean mRequiresInternetValidation;
|
||||
|
||||
/** @hide */
|
||||
PlatformVpnProfile(@PlatformVpnType int type, boolean excludeLocalRoutes) {
|
||||
PlatformVpnProfile(@PlatformVpnType int type, boolean excludeLocalRoutes,
|
||||
boolean requiresValidation) {
|
||||
mType = type;
|
||||
mExcludeLocalRoutes = excludeLocalRoutes;
|
||||
mRequiresInternetValidation = requiresValidation;
|
||||
}
|
||||
|
||||
/** Returns the profile integer type. */
|
||||
@ -80,14 +80,30 @@ public abstract class PlatformVpnProfile {
|
||||
return mType;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns if the local traffic is exempted from the VPN.
|
||||
* Returns whether the local traffic is exempted from the VPN.
|
||||
*/
|
||||
public final boolean getExcludeLocalRoutes() {
|
||||
return mExcludeLocalRoutes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether this VPN should undergo Internet validation.
|
||||
*
|
||||
* If this is true, the platform will perform basic validation checks for Internet
|
||||
* connectivity over this VPN. If and when they succeed, the VPN network capabilities will
|
||||
* reflect this by gaining the {@link NetworkCapabilities#NET_CAPABILITY_VALIDATED}
|
||||
* capability.
|
||||
*
|
||||
* If this is false, the platform assumes the VPN either is always capable of reaching the
|
||||
* Internet or intends not to. In this case, the VPN network capabilities will
|
||||
* always gain the {@link NetworkCapabilities#NET_CAPABILITY_VALIDATED} capability
|
||||
* immediately after it connects, whether it can reach public Internet destinations or not.
|
||||
*/
|
||||
public final boolean getRequiresInternetValidation() {
|
||||
return mRequiresInternetValidation;
|
||||
}
|
||||
|
||||
/** Returns a type string describing the VPN profile type */
|
||||
@NonNull
|
||||
public final String getTypeString() {
|
||||
|
@ -105,6 +105,7 @@ public class VpnConfig implements Parcelable {
|
||||
public boolean allowIPv4;
|
||||
public boolean allowIPv6;
|
||||
public boolean isMetered = true;
|
||||
public boolean requiresInternetValidation = false;
|
||||
public Network[] underlyingNetworks;
|
||||
public ProxyInfo proxyInfo;
|
||||
|
||||
@ -131,6 +132,7 @@ public class VpnConfig implements Parcelable {
|
||||
allowIPv4 = other.allowIPv4;
|
||||
allowIPv6 = other.allowIPv6;
|
||||
isMetered = other.isMetered;
|
||||
requiresInternetValidation = other.requiresInternetValidation;
|
||||
underlyingNetworks = other.underlyingNetworks != null ? Arrays.copyOf(
|
||||
other.underlyingNetworks, other.underlyingNetworks.length) : null;
|
||||
proxyInfo = other.proxyInfo;
|
||||
@ -189,6 +191,7 @@ public class VpnConfig implements Parcelable {
|
||||
out.writeInt(allowIPv4 ? 1 : 0);
|
||||
out.writeInt(allowIPv6 ? 1 : 0);
|
||||
out.writeInt(isMetered ? 1 : 0);
|
||||
out.writeInt(requiresInternetValidation ? 1 : 0);
|
||||
out.writeTypedArray(underlyingNetworks, flags);
|
||||
out.writeParcelable(proxyInfo, flags);
|
||||
}
|
||||
@ -216,6 +219,7 @@ public class VpnConfig implements Parcelable {
|
||||
config.allowIPv4 = in.readInt() != 0;
|
||||
config.allowIPv6 = in.readInt() != 0;
|
||||
config.isMetered = in.readInt() != 0;
|
||||
config.requiresInternetValidation = in.readInt() != 0;
|
||||
config.underlyingNetworks = in.createTypedArray(Network.CREATOR);
|
||||
config.proxyInfo = in.readParcelable(null);
|
||||
return config;
|
||||
@ -248,6 +252,8 @@ public class VpnConfig implements Parcelable {
|
||||
.append(", allowBypass=").append(allowBypass)
|
||||
.append(", allowIPv4=").append(allowIPv4)
|
||||
.append(", allowIPv6=").append(allowIPv6)
|
||||
.append(", isMetered=").append(isMetered)
|
||||
.append(", requiresInternetValidation").append(requiresInternetValidation)
|
||||
.append(", underlyingNetworks=").append(Arrays.toString(underlyingNetworks))
|
||||
.append(", proxyInfo=").append(proxyInfo)
|
||||
.append("}")
|
||||
|
@ -144,23 +144,26 @@ public final class VpnProfile implements Cloneable, Parcelable {
|
||||
public final boolean isRestrictedToTestNetworks; // 24
|
||||
|
||||
public final boolean excludeLocalRoutes; // 25
|
||||
public final boolean requiresInternetValidation; // 26
|
||||
|
||||
// Helper fields.
|
||||
@UnsupportedAppUsage
|
||||
public transient boolean saveLogin = false;
|
||||
|
||||
public VpnProfile(String key) {
|
||||
this(key, false, false);
|
||||
this(key, false, false, false);
|
||||
}
|
||||
|
||||
public VpnProfile(String key, boolean isRestrictedToTestNetworks) {
|
||||
this(key, isRestrictedToTestNetworks, false);
|
||||
this(key, isRestrictedToTestNetworks, false, false);
|
||||
}
|
||||
|
||||
public VpnProfile(String key, boolean isRestrictedToTestNetworks, boolean excludeLocalRoutes) {
|
||||
public VpnProfile(String key, boolean isRestrictedToTestNetworks, boolean excludeLocalRoutes,
|
||||
boolean requiresInternetValidation) {
|
||||
this.key = key;
|
||||
this.isRestrictedToTestNetworks = isRestrictedToTestNetworks;
|
||||
this.excludeLocalRoutes = excludeLocalRoutes;
|
||||
this.requiresInternetValidation = requiresInternetValidation;
|
||||
}
|
||||
|
||||
@UnsupportedAppUsage
|
||||
@ -191,6 +194,7 @@ public final class VpnProfile implements Cloneable, Parcelable {
|
||||
areAuthParamsInline = in.readBoolean();
|
||||
isRestrictedToTestNetworks = in.readBoolean();
|
||||
excludeLocalRoutes = in.readBoolean();
|
||||
requiresInternetValidation = in.readBoolean();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -239,6 +243,7 @@ public final class VpnProfile implements Cloneable, Parcelable {
|
||||
out.writeBoolean(areAuthParamsInline);
|
||||
out.writeBoolean(isRestrictedToTestNetworks);
|
||||
out.writeBoolean(excludeLocalRoutes);
|
||||
out.writeBoolean(requiresInternetValidation);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -258,9 +263,11 @@ public final class VpnProfile implements Cloneable, Parcelable {
|
||||
// 14-19: Standard profile, with option for serverCert, proxy
|
||||
// 24: Standard profile with serverCert, proxy and platform-VPN parameters
|
||||
// 25: Standard profile with platform-VPN parameters and isRestrictedToTestNetworks
|
||||
// 26: Standard profile with platform-VPN parameters and excludeLocalRoutes
|
||||
if ((values.length < 14 || values.length > 19)
|
||||
&& values.length != 24 && values.length != 25 && values.length != 26) {
|
||||
// 26: ...and excludeLocalRoutes
|
||||
// (26 can only be found on dogfood devices)
|
||||
// 27: ...and requiresInternetValidation
|
||||
if ((values.length < 14 || (values.length > 19 && values.length < 24)
|
||||
|| values.length > 27)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -278,8 +285,15 @@ public final class VpnProfile implements Cloneable, Parcelable {
|
||||
excludeLocalRoutes = false;
|
||||
}
|
||||
|
||||
final boolean requiresInternetValidation;
|
||||
if (values.length >= 27) {
|
||||
requiresInternetValidation = Boolean.parseBoolean(values[26]);
|
||||
} else {
|
||||
requiresInternetValidation = false;
|
||||
}
|
||||
|
||||
VpnProfile profile = new VpnProfile(key, isRestrictedToTestNetworks,
|
||||
excludeLocalRoutes);
|
||||
excludeLocalRoutes, requiresInternetValidation);
|
||||
profile.name = values[0];
|
||||
profile.type = Integer.parseInt(values[1]);
|
||||
if (profile.type < 0 || profile.type > TYPE_MAX) {
|
||||
@ -390,6 +404,7 @@ public final class VpnProfile implements Cloneable, Parcelable {
|
||||
builder.append(VALUE_DELIMITER).append(isRestrictedToTestNetworks);
|
||||
|
||||
builder.append(VALUE_DELIMITER).append(excludeLocalRoutes);
|
||||
builder.append(VALUE_DELIMITER).append(requiresInternetValidation);
|
||||
|
||||
return builder.toString().getBytes(StandardCharsets.UTF_8);
|
||||
}
|
||||
@ -471,7 +486,7 @@ public final class VpnProfile implements Cloneable, Parcelable {
|
||||
key, type, server, username, password, dnsServers, searchDomains, routes, mppe,
|
||||
l2tpSecret, ipsecIdentifier, ipsecSecret, ipsecUserCert, ipsecCaCert, ipsecServerCert,
|
||||
proxy, mAllowedAlgorithms, isBypassable, isMetered, maxMtu, areAuthParamsInline,
|
||||
isRestrictedToTestNetworks, excludeLocalRoutes);
|
||||
isRestrictedToTestNetworks, excludeLocalRoutes, requiresInternetValidation);
|
||||
}
|
||||
|
||||
/** Checks VPN profiles for interior equality. */
|
||||
@ -505,11 +520,12 @@ public final class VpnProfile implements Cloneable, Parcelable {
|
||||
&& maxMtu == other.maxMtu
|
||||
&& areAuthParamsInline == other.areAuthParamsInline
|
||||
&& isRestrictedToTestNetworks == other.isRestrictedToTestNetworks
|
||||
&& excludeLocalRoutes == other.excludeLocalRoutes;
|
||||
&& excludeLocalRoutes == other.excludeLocalRoutes
|
||||
&& requiresInternetValidation == other.requiresInternetValidation;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static final Creator<VpnProfile> CREATOR = new Creator<VpnProfile>() {
|
||||
public static final Creator<VpnProfile> CREATOR = new Creator<>() {
|
||||
@Override
|
||||
public VpnProfile createFromParcel(Parcel in) {
|
||||
return new VpnProfile(in);
|
||||
|
@ -1302,6 +1302,7 @@ public class Vpn {
|
||||
.setLegacyType(ConnectivityManager.TYPE_VPN)
|
||||
.setLegacyTypeName("VPN")
|
||||
.setBypassableVpn(mConfig.allowBypass && !mLockdown)
|
||||
.setVpnRequiresValidation(mConfig.requiresInternetValidation)
|
||||
.build();
|
||||
|
||||
capsBuilder.setOwnerUid(mOwnerUID);
|
||||
@ -3363,6 +3364,7 @@ public class Vpn {
|
||||
}
|
||||
mConfig.startTime = SystemClock.elapsedRealtime();
|
||||
mConfig.proxyInfo = profile.proxy;
|
||||
mConfig.requiresInternetValidation = profile.requiresInternetValidation;
|
||||
|
||||
switch (profile.type) {
|
||||
case VpnProfile.TYPE_IKEV2_IPSEC_USER_PASS:
|
||||
|
Loading…
x
Reference in New Issue
Block a user