If the proider model is enabled, the User cannot create insecure VPNs
Additionally, existing secure vpns cannot have their type changed to an
insecure type.
Existing insecure VPNs can be edited, but once the type is changed to a
secure type, it cannot be set to an insecure type again.
Note that devices without FEATURE_IPSEC_TUNNELS still have the ability
to make insecure VPNs at the moment. What to do about these devices will
be addressed in a future change.
Recall video with this Change: https://recall.googleplex.com/projects/a801b0cf-91a5-414e-973b-3c1c8fb5e7be/sessions/bc54e4f2-0205-4822-a51a-382e54f3a956
Test: atest -c SettingsUnitTests
Bug: 176821216
Change-Id: Icf87419650c934a783b01f4d2907b7f704d139b8
diff --git a/src/com/android/settings/vpn2/ConfigDialog.java b/src/com/android/settings/vpn2/ConfigDialog.java
index a88be03..cd6b4ff 100644
--- a/src/com/android/settings/vpn2/ConfigDialog.java
+++ b/src/com/android/settings/vpn2/ConfigDialog.java
@@ -26,6 +26,7 @@
import android.os.SystemProperties;
import android.text.Editable;
import android.text.TextWatcher;
+import android.util.Log;
import android.view.View;
import android.view.WindowManager;
import android.widget.AdapterView;
@@ -40,6 +41,7 @@
import com.android.internal.net.VpnProfile;
import com.android.net.module.util.ProxyUtils;
import com.android.settings.R;
+import com.android.settings.Utils;
import com.android.settings.utils.AndroidKeystoreAliasLoader;
import java.net.InetAddress;
@@ -64,6 +66,8 @@
private boolean mEditing;
private boolean mExists;
+ private List<String> mTotalTypes;
+ private List<String> mAllowedTypes;
private View mView;
@@ -134,7 +138,13 @@
// Second, copy values from the profile.
mName.setText(mProfile.name);
setTypesByFeature(mType);
- mType.setSelection(mProfile.type);
+ // Not all types will be available to the user. Find the index corresponding to the
+ // string of the profile's type.
+ if (mAllowedTypes != null && mTotalTypes != null) {
+ mType.setSelection(mAllowedTypes.indexOf(mTotalTypes.get(mProfile.type)));
+ } else {
+ Log.w(TAG, "Allowed or Total vpn types not initialized when setting initial selection");
+ }
mServer.setText(mProfile.server);
if (mProfile.saveLogin) {
mUsername.setText(mProfile.username);
@@ -276,7 +286,10 @@
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
if (parent == mType) {
- changeType(position);
+ // Because the spinner may not display all available types,
+ // convert the selected position into the actual vpn profile type integer.
+ final int profileType = convertAllowedIndexToProfileType(position);
+ changeType(profileType);
} else if (parent == mProxySettings) {
updateProxyFieldsVisibility(position);
}
@@ -371,7 +384,7 @@
// Configure networking option visibility
// TODO(b/149070123): Add ability for platform VPNs to support DNS & routes
final int visibility =
- isLegacyType(mType.getSelectedItemPosition()) ? View.VISIBLE : View.GONE;
+ isLegacyType(getSelectedVpnType()) ? View.VISIBLE : View.GONE;
mView.findViewById(R.id.network_options).setVisibility(visibility);
} else {
mView.findViewById(R.id.options).setVisibility(View.GONE);
@@ -431,7 +444,7 @@
return false;
}
- final int type = mType.getSelectedItemPosition();
+ final int type = getSelectedVpnType();
if (!editing && requiresUsernamePassword(type)) {
return mUsername.getText().length() != 0 && mPassword.getText().length() != 0;
}
@@ -503,6 +516,8 @@
private void setTypesByFeature(Spinner typeSpinner) {
String[] types = getContext().getResources().getStringArray(R.array.vpn_types);
+ mTotalTypes = new ArrayList<>(Arrays.asList(types));
+ mAllowedTypes = new ArrayList<>(Arrays.asList(types));
if (!getContext().getPackageManager().hasSystemFeature(
PackageManager.FEATURE_IPSEC_TUNNELS)) {
final List<String> typesList = new ArrayList<>(Arrays.asList(types));
@@ -513,6 +528,26 @@
typesList.remove(VpnProfile.TYPE_IKEV2_IPSEC_USER_PASS);
types = typesList.toArray(new String[0]);
+ } else if (Utils.isProviderModelEnabled(getContext())) {
+ // If the provider mode is enabled and the vpn is new or is not already a legacy type,
+ // don't allow the user to set the type to a legacy option.
+
+ // Set the mProfile.type to TYPE_IKEV2_IPSEC_USER_PASS if the VPN not exist
+ if (!mExists) {
+ mProfile.type = VpnProfile.TYPE_IKEV2_IPSEC_USER_PASS;
+ }
+
+ // Remove all types which are legacy types from the typesList
+ if (!VpnProfile.isLegacyType(mProfile.type)) {
+ for (int i = mAllowedTypes.size() - 1; i >= 0; i--) {
+ // This must be removed from back to front in order to ensure index consistency
+ if (VpnProfile.isLegacyType(i)) {
+ mAllowedTypes.remove(i);
+ }
+ }
+
+ types = mAllowedTypes.toArray(new String[0]);
+ }
}
final ArrayAdapter<String> adapter = new ArrayAdapter<String>(
getContext(), android.R.layout.simple_spinner_item, types);
@@ -577,7 +612,7 @@
// First, save common fields.
VpnProfile profile = new VpnProfile(mProfile.key);
profile.name = mName.getText().toString();
- profile.type = mType.getSelectedItemPosition();
+ profile.type = getSelectedVpnType();
profile.server = mServer.getText().toString().trim();
profile.username = mUsername.getText().toString();
profile.password = mPassword.getText().toString();
@@ -652,4 +687,19 @@
return ProxyUtils.validate(host, port, "") == ProxyUtils.PROXY_VALID;
}
+ private int getSelectedVpnType() {
+ return convertAllowedIndexToProfileType(mType.getSelectedItemPosition());
+ }
+
+ private int convertAllowedIndexToProfileType(int allowedSelectedPosition) {
+ if (mAllowedTypes != null && mTotalTypes != null) {
+ final String typeString = mAllowedTypes.get(allowedSelectedPosition);
+ final int profileType = mTotalTypes.indexOf(typeString);
+ return profileType;
+ } else {
+ Log.w(TAG, "Allowed or Total vpn types not initialized when converting protileType");
+ return allowedSelectedPosition;
+ }
+ }
+
}