Skip to content
Snippets Groups Projects
Commit 4b66d4e2 authored by Jean Chalard's avatar Jean Chalard Committed by Gerrit Code Review
Browse files

Merge "Add and implement API for VpnManagers to request validation"

parents 07621512 865511a8
No related branches found
No related tags found
No related merge requests found
......@@ -124,6 +124,7 @@ package android.net {
public final class NetworkAgentConfig implements android.os.Parcelable {
method @Nullable public String getSubscriberId();
method public boolean getVpnRequiresValidation();
method public boolean isBypassableVpn();
}
......@@ -131,6 +132,7 @@ package android.net {
method @NonNull public android.net.NetworkAgentConfig.Builder setBypassableVpn(boolean);
method @NonNull public android.net.NetworkAgentConfig.Builder setExcludeLocalRoutesVpn(boolean);
method @NonNull public android.net.NetworkAgentConfig.Builder setSubscriberId(@Nullable String);
method @NonNull public android.net.NetworkAgentConfig.Builder setVpnRequiresValidation(boolean);
}
public final class NetworkCapabilities implements android.os.Parcelable {
......
......@@ -34,6 +34,8 @@ import java.util.Objects;
*/
@SystemApi
public final class NetworkAgentConfig implements Parcelable {
// TODO : make this object immutable. The fields that should stay mutable should likely
// migrate to NetworkAgentInfo.
/**
* If the {@link Network} is a VPN, whether apps are allowed to bypass the
......@@ -246,6 +248,27 @@ public final class NetworkAgentConfig implements Parcelable {
return excludeLocalRouteVpn;
}
/**
* Whether network validation should be performed for this VPN network.
* {@see #getVpnRequiresValidation}
* @hide
*/
private boolean mVpnRequiresValidation = false;
/**
* Whether network validation should be performed for this VPN network.
*
* If this network isn't a VPN this should always be {@code false}, and will be ignored
* if set.
* If this network is a VPN, false means this network should always be considered validated;
* true means it follows the same validation semantics as general internet networks.
* @hide
*/
@SystemApi(client = MODULE_LIBRARIES)
public boolean getVpnRequiresValidation() {
return mVpnRequiresValidation;
}
/** @hide */
public NetworkAgentConfig() {
}
......@@ -266,6 +289,7 @@ public final class NetworkAgentConfig implements Parcelable {
legacySubTypeName = nac.legacySubTypeName;
mLegacyExtraInfo = nac.mLegacyExtraInfo;
excludeLocalRouteVpn = nac.excludeLocalRouteVpn;
mVpnRequiresValidation = nac.mVpnRequiresValidation;
}
}
......@@ -408,6 +432,25 @@ public final class NetworkAgentConfig implements Parcelable {
return this;
}
/**
* Sets whether network validation should be performed for this VPN network.
*
* Only agents registering a VPN network should use this setter. On other network
* types it will be ignored.
* False means this network should always be considered validated;
* true means it follows the same validation semantics as general internet.
*
* @param vpnRequiresValidation whether this VPN requires validation.
* Default is {@code false}.
* @hide
*/
@NonNull
@SystemApi(client = MODULE_LIBRARIES)
public Builder setVpnRequiresValidation(boolean vpnRequiresValidation) {
mConfig.mVpnRequiresValidation = vpnRequiresValidation;
return this;
}
/**
* Sets whether the apps can bypass the VPN connection.
*
......@@ -458,14 +501,16 @@ public final class NetworkAgentConfig implements Parcelable {
&& Objects.equals(subscriberId, that.subscriberId)
&& Objects.equals(legacyTypeName, that.legacyTypeName)
&& Objects.equals(mLegacyExtraInfo, that.mLegacyExtraInfo)
&& excludeLocalRouteVpn == that.excludeLocalRouteVpn;
&& excludeLocalRouteVpn == that.excludeLocalRouteVpn
&& mVpnRequiresValidation == that.mVpnRequiresValidation;
}
@Override
public int hashCode() {
return Objects.hash(allowBypass, explicitlySelected, acceptUnvalidated,
acceptPartialConnectivity, provisioningNotificationDisabled, subscriberId,
skip464xlat, legacyType, legacyTypeName, mLegacyExtraInfo, excludeLocalRouteVpn);
skip464xlat, legacyType, legacyTypeName, mLegacyExtraInfo, excludeLocalRouteVpn,
mVpnRequiresValidation);
}
@Override
......@@ -483,6 +528,7 @@ public final class NetworkAgentConfig implements Parcelable {
+ ", legacyTypeName = '" + legacyTypeName + '\''
+ ", legacyExtraInfo = '" + mLegacyExtraInfo + '\''
+ ", excludeLocalRouteVpn = '" + excludeLocalRouteVpn + '\''
+ ", vpnRequiresValidation = '" + mVpnRequiresValidation + '\''
+ "}";
}
......@@ -506,6 +552,7 @@ public final class NetworkAgentConfig implements Parcelable {
out.writeString(legacySubTypeName);
out.writeString(mLegacyExtraInfo);
out.writeInt(excludeLocalRouteVpn ? 1 : 0);
out.writeInt(mVpnRequiresValidation ? 1 : 0);
}
public static final @NonNull Creator<NetworkAgentConfig> CREATOR =
......@@ -526,6 +573,7 @@ public final class NetworkAgentConfig implements Parcelable {
networkAgentConfig.legacySubTypeName = in.readString();
networkAgentConfig.mLegacyExtraInfo = in.readString();
networkAgentConfig.excludeLocalRouteVpn = in.readInt() != 0;
networkAgentConfig.mVpnRequiresValidation = in.readInt() != 0;
return networkAgentConfig;
}
......
......@@ -20,6 +20,7 @@ import android.os.Build
import androidx.test.filters.SmallTest
import androidx.test.runner.AndroidJUnit4
import com.android.modules.utils.build.SdkLevel.isAtLeastS
import com.android.modules.utils.build.SdkLevel.isAtLeastT
import com.android.testutils.ConnectivityModuleTest
import com.android.testutils.DevSdkIgnoreRule
import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo
......@@ -49,6 +50,10 @@ class NetworkAgentConfigTest {
if (isAtLeastS()) {
setBypassableVpn(true)
}
if (isAtLeastT()) {
setExcludeLocalRoutesVpn(true)
setVpnRequiresValidation(true)
}
}.build()
assertParcelingIsLossless(config)
}
......@@ -69,6 +74,10 @@ class NetworkAgentConfigTest {
setProvisioningNotificationEnabled(false)
setBypassableVpn(true)
}
if (isAtLeastT()) {
setExcludeLocalRoutesVpn(true)
setVpnRequiresValidation(true)
}
}.build()
assertTrue(config.isExplicitlySelected())
......@@ -77,6 +86,10 @@ class NetworkAgentConfigTest {
assertFalse(config.isPartialConnectivityAcceptable())
assertTrue(config.isUnvalidatedConnectivityAcceptable())
assertEquals("TEST_NETWORK", config.getLegacyTypeName())
if (isAtLeastT()) {
assertTrue(config.getExcludeLocalRouteVpn())
assertTrue(config.getVpnRequiresValidation())
}
if (isAtLeastS()) {
assertEquals(testExtraInfo, config.getLegacyExtraInfo())
assertFalse(config.isNat64DetectionEnabled())
......
......@@ -50,6 +50,7 @@ public class VpnProfileTest {
private static final int ENCODED_INDEX_AUTH_PARAMS_INLINE = 23;
private static final int ENCODED_INDEX_RESTRICTED_TO_TEST_NETWORKS = 24;
private static final int ENCODED_INDEX_EXCLUDE_LOCAL_ROUTE = 25;
private static final int ENCODED_INDEX_REQUIRE_PLATFORM_VALIDATION = 26;
@Test
public void testDefaults() throws Exception {
......@@ -78,10 +79,13 @@ public class VpnProfileTest {
assertEquals(1360, p.maxMtu);
assertFalse(p.areAuthParamsInline);
assertFalse(p.isRestrictedToTestNetworks);
assertFalse(p.excludeLocalRoutes);
assertFalse(p.requiresInternetValidation);
}
private VpnProfile getSampleIkev2Profile(String key) {
final VpnProfile p = new VpnProfile(key, true /* isRestrictedToTestNetworks */);
final VpnProfile p = new VpnProfile(key, true /* isRestrictedToTestNetworks */,
false /* excludesLocalRoutes */, true /* requiresPlatformValidation */);
p.name = "foo";
p.type = VpnProfile.TYPE_IKEV2_IPSEC_USER_PASS;
......@@ -129,8 +133,8 @@ public class VpnProfileTest {
@Test
public void testParcelUnparcel() {
if (isAtLeastT()) {
// excludeLocalRoutes is added in T.
assertParcelSane(getSampleIkev2Profile(DUMMY_PROFILE_KEY), 24);
// excludeLocalRoutes, requiresPlatformValidation were added in T.
assertParcelSane(getSampleIkev2Profile(DUMMY_PROFILE_KEY), 25);
} else {
assertParcelSane(getSampleIkev2Profile(DUMMY_PROFILE_KEY), 23);
}
......@@ -174,7 +178,8 @@ public class VpnProfileTest {
getEncodedDecodedIkev2ProfileMissingValues(
ENCODED_INDEX_AUTH_PARAMS_INLINE,
ENCODED_INDEX_RESTRICTED_TO_TEST_NETWORKS,
ENCODED_INDEX_EXCLUDE_LOCAL_ROUTE /* missingIndices */);
ENCODED_INDEX_EXCLUDE_LOCAL_ROUTE,
ENCODED_INDEX_REQUIRE_PLATFORM_VALIDATION /* missingIndices */);
assertNull(VpnProfile.decode(DUMMY_PROFILE_KEY, tooFewValues.getBytes()));
}
......@@ -194,13 +199,25 @@ public class VpnProfileTest {
public void testEncodeDecodeMissingExcludeLocalRoutes() {
final String tooFewValues =
getEncodedDecodedIkev2ProfileMissingValues(
ENCODED_INDEX_EXCLUDE_LOCAL_ROUTE /* missingIndices */);
ENCODED_INDEX_EXCLUDE_LOCAL_ROUTE,
ENCODED_INDEX_REQUIRE_PLATFORM_VALIDATION /* missingIndices */);
// Verify decoding without isRestrictedToTestNetworks defaults to false
// Verify decoding without excludeLocalRoutes defaults to false
final VpnProfile decoded = VpnProfile.decode(DUMMY_PROFILE_KEY, tooFewValues.getBytes());
assertFalse(decoded.excludeLocalRoutes);
}
@Test
public void testEncodeDecodeMissingRequiresValidation() {
final String tooFewValues =
getEncodedDecodedIkev2ProfileMissingValues(
ENCODED_INDEX_REQUIRE_PLATFORM_VALIDATION /* missingIndices */);
// Verify decoding without requiresValidation defaults to false
final VpnProfile decoded = VpnProfile.decode(DUMMY_PROFILE_KEY, tooFewValues.getBytes());
assertFalse(decoded.requiresInternetValidation);
}
@Test
public void testEncodeDecodeLoginsNotSaved() {
final VpnProfile profile = getSampleIkev2Profile(DUMMY_PROFILE_KEY);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment