diff --git a/src/frontends/android/app/build.gradle b/src/frontends/android/app/build.gradle index 01eb5a189..9b59f448a 100644 --- a/src/frontends/android/app/build.gradle +++ b/src/frontends/android/app/build.gradle @@ -9,8 +9,8 @@ android { minSdkVersion 21 targetSdkVersion 34 - versionCode 89 - versionName "2.5.5" + versionCode 91 + versionName "2.5.6" externalNativeBuild { ndkBuild { @@ -45,8 +45,8 @@ android { } dependencies { - implementation 'androidx.appcompat:appcompat:1.7.0' - implementation 'androidx.lifecycle:lifecycle-process:2.8.3' + implementation 'androidx.appcompat:appcompat:1.7.1' + implementation 'androidx.lifecycle:lifecycle-process:2.9.1' implementation 'androidx.preference:preference:1.2.1' implementation 'com.google.android.material:material:1.12.0' testImplementation 'junit:junit:4.13.2' diff --git a/src/frontends/android/app/src/main/java/org/strongswan/android/data/DatabaseHelper.java b/src/frontends/android/app/src/main/java/org/strongswan/android/data/DatabaseHelper.java index 1a6b7e174..7feccbdfe 100644 --- a/src/frontends/android/app/src/main/java/org/strongswan/android/data/DatabaseHelper.java +++ b/src/frontends/android/app/src/main/java/org/strongswan/android/data/DatabaseHelper.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2023 Relution GmbH - * Copyright (C) 2012-2024 Tobias Brunner + * Copyright (C) 2012-2025 Tobias Brunner * Copyright (C) 2012 Giuliano Grassi * Copyright (C) 2012 Ralf Sager * @@ -67,6 +67,9 @@ public class DatabaseHelper extends SQLiteOpenHelper new DbColumn(VpnProfileDataSource.KEY_IKE_PROPOSAL, "TEXT", 15), new DbColumn(VpnProfileDataSource.KEY_ESP_PROPOSAL, "TEXT", 15), new DbColumn(VpnProfileDataSource.KEY_DNS_SERVERS, "TEXT", 17), + new DbColumn(VpnProfileDataSource.KEY_PROXY_HOST, "TEXT", 19), + new DbColumn(VpnProfileDataSource.KEY_PROXY_PORT, "INTEGER", 19), + new DbColumn(VpnProfileDataSource.KEY_PROXY_EXCLUSIONS, "TEXT", 19), }); public static final DbTable TABLE_TRUSTED_CERTIFICATE = new DbTable(TABLE_NAME_TRUSTED_CERTIFICATE, 18, new DbColumn[]{ @@ -84,7 +87,7 @@ public class DatabaseHelper extends SQLiteOpenHelper new DbColumn(ManagedUserCertificate.KEY_PASSWORD, "TEXT", 18), }); - private static final int DATABASE_VERSION = 18; + private static final int DATABASE_VERSION = 19; private static final Set TABLES; diff --git a/src/frontends/android/app/src/main/java/org/strongswan/android/data/ManagedVpnProfile.java b/src/frontends/android/app/src/main/java/org/strongswan/android/data/ManagedVpnProfile.java index 30943aa6b..47e85a5ca 100644 --- a/src/frontends/android/app/src/main/java/org/strongswan/android/data/ManagedVpnProfile.java +++ b/src/frontends/android/app/src/main/java/org/strongswan/android/data/ManagedVpnProfile.java @@ -83,6 +83,14 @@ public class ManagedVpnProfile extends VpnProfile setIncludedSubnets(getString(splitTunneling, VpnProfileDataSource.KEY_INCLUDED_SUBNETS)); } + final Bundle proxyServer = bundle.getBundle(VpnProfileDataSource.KEY_PROXY_SERVER); + if (proxyServer != null) + { + setProxyHost(getString(proxyServer, VpnProfileDataSource.KEY_PROXY_HOST)); + setProxyPort(getInt(proxyServer, VpnProfileDataSource.KEY_PROXY_PORT, 1, 65_535)); + setProxyExclusions(getString(proxyServer, VpnProfileDataSource.KEY_PROXY_EXCLUSIONS)); + } + setSplitTunneling(splitFlags); setFlags(flags); } diff --git a/src/frontends/android/app/src/main/java/org/strongswan/android/data/VpnProfile.java b/src/frontends/android/app/src/main/java/org/strongswan/android/data/VpnProfile.java index e3ce9d4b8..52464eb12 100644 --- a/src/frontends/android/app/src/main/java/org/strongswan/android/data/VpnProfile.java +++ b/src/frontends/android/app/src/main/java/org/strongswan/android/data/VpnProfile.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012-2019 Tobias Brunner + * Copyright (C) 2012-2025 Tobias Brunner * Copyright (C) 2012 Giuliano Grassi * Copyright (C) 2012 Ralf Sager * @@ -42,8 +42,8 @@ public class VpnProfile implements Cloneable private String mName, mGateway, mUsername, mPassword, mCertificate, mUserCertificate; private String mRemoteId, mLocalId, mExcludedSubnets, mIncludedSubnets, mSelectedApps; - private String mIkeProposal, mEspProposal, mDnsServers; - private Integer mMTU, mPort, mSplitTunneling, mNATKeepAlive, mFlags; + private String mIkeProposal, mEspProposal, mDnsServers, mProxyHost, mProxyExclusions; + private Integer mMTU, mPort, mProxyPort, mSplitTunneling, mNATKeepAlive, mFlags; private SelectedAppsHandling mSelectedAppsHandling = SelectedAppsHandling.SELECTED_APPS_DISABLE; private VpnType mVpnType; private UUID mUUID; @@ -313,6 +313,36 @@ public class VpnProfile implements Cloneable return mSelectedAppsHandling; } + public String getProxyHost() + { + return mProxyHost; + } + + public void setProxyHost(String proxy) + { + this.mProxyHost = proxy; + } + + public Integer getProxyPort() + { + return mProxyPort; + } + + public void setProxyPort(Integer port) + { + this.mProxyPort = port; + } + + public String getProxyExclusions() + { + return mProxyExclusions; + } + + public void setProxyExclusions(String exclusions) + { + this.mProxyExclusions = exclusions; + } + public Integer getSplitTunneling() { return mSplitTunneling; diff --git a/src/frontends/android/app/src/main/java/org/strongswan/android/data/VpnProfileDataSource.java b/src/frontends/android/app/src/main/java/org/strongswan/android/data/VpnProfileDataSource.java index f95ce4734..b5289337c 100644 --- a/src/frontends/android/app/src/main/java/org/strongswan/android/data/VpnProfileDataSource.java +++ b/src/frontends/android/app/src/main/java/org/strongswan/android/data/VpnProfileDataSource.java @@ -50,6 +50,10 @@ public interface VpnProfileDataSource String KEY_IKE_PROPOSAL = "ike_proposal"; String KEY_ESP_PROPOSAL = "esp_proposal"; String KEY_DNS_SERVERS = "dns_servers"; + String KEY_PROXY_SERVER = "proxy_server"; + String KEY_PROXY_HOST = "proxy_host"; + String KEY_PROXY_PORT = "proxy_port"; + String KEY_PROXY_EXCLUSIONS = "proxy_exclusions"; String KEY_READ_ONLY = "read_only"; /** diff --git a/src/frontends/android/app/src/main/java/org/strongswan/android/data/VpnProfileSqlDataSource.java b/src/frontends/android/app/src/main/java/org/strongswan/android/data/VpnProfileSqlDataSource.java index 50ffc6297..cee26a457 100644 --- a/src/frontends/android/app/src/main/java/org/strongswan/android/data/VpnProfileSqlDataSource.java +++ b/src/frontends/android/app/src/main/java/org/strongswan/android/data/VpnProfileSqlDataSource.java @@ -151,6 +151,9 @@ public class VpnProfileSqlDataSource implements VpnProfileDataSource profile.setIkeProposal(cursor.getString(cursor.getColumnIndexOrThrow(KEY_IKE_PROPOSAL))); profile.setEspProposal(cursor.getString(cursor.getColumnIndexOrThrow(KEY_ESP_PROPOSAL))); profile.setDnsServers(cursor.getString(cursor.getColumnIndexOrThrow(KEY_DNS_SERVERS))); + profile.setProxyHost(cursor.getString(cursor.getColumnIndexOrThrow(KEY_PROXY_HOST))); + profile.setProxyPort(getInt(cursor, cursor.getColumnIndexOrThrow(KEY_PROXY_PORT))); + profile.setProxyExclusions(cursor.getString(cursor.getColumnIndexOrThrow(KEY_PROXY_EXCLUSIONS))); return profile; } @@ -179,6 +182,9 @@ public class VpnProfileSqlDataSource implements VpnProfileDataSource values.put(KEY_IKE_PROPOSAL, profile.getIkeProposal()); values.put(KEY_ESP_PROPOSAL, profile.getEspProposal()); values.put(KEY_DNS_SERVERS, profile.getDnsServers()); + values.put(KEY_PROXY_HOST, profile.getProxyHost()); + values.put(KEY_PROXY_PORT, profile.getProxyPort()); + values.put(KEY_PROXY_EXCLUSIONS, profile.getProxyExclusions()); return values; } diff --git a/src/frontends/android/app/src/main/java/org/strongswan/android/logic/CharonVpnService.java b/src/frontends/android/app/src/main/java/org/strongswan/android/logic/CharonVpnService.java index 314678ede..69b217a2e 100644 --- a/src/frontends/android/app/src/main/java/org/strongswan/android/logic/CharonVpnService.java +++ b/src/frontends/android/app/src/main/java/org/strongswan/android/logic/CharonVpnService.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012-2018 Tobias Brunner + * Copyright (C) 2012-2025 Tobias Brunner * Copyright (C) 2012 Giuliano Grassi * Copyright (C) 2012 Ralf Sager * @@ -30,6 +30,7 @@ import android.content.Intent; import android.content.ServiceConnection; import android.content.SharedPreferences; import android.content.pm.PackageManager; +import android.net.ProxyInfo; import android.net.VpnService; import android.os.Build; import android.os.Bundle; @@ -72,6 +73,8 @@ import java.security.PrivateKey; import java.security.cert.CertificateEncodingException; import java.security.cert.X509Certificate; import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; import java.util.List; import java.util.Locale; import java.util.SortedSet; @@ -1116,6 +1119,7 @@ public class CharonVpnService extends VpnService implements Runnable, VpnStateSe private final List mDnsServers = new ArrayList<>(); private int mMtu; private boolean mIPv4Seen, mIPv6Seen, mDnsServersConfigured; + private ProxyInfo mProxyServer; public BuilderCache(VpnProfile profile) { @@ -1169,6 +1173,17 @@ public class CharonVpnService extends VpnService implements Runnable, VpnStateSe } } + if (profile.getProxyHost() != null) + { + int port = profile.getProxyPort() != null ? profile.getProxyPort() : Constants.PROXY_PORT_DEFAULT; + List exclusions = new ArrayList<>(); + if (profile.getProxyExclusions() != null) + { + Collections.addAll(exclusions, profile.getProxyExclusions().split("\\s+")); + } + mProxyServer = ProxyInfo.buildDirectProxy(profile.getProxyHost(), port, exclusions); + } + /* set a default MTU, will be set by the daemon for regular interfaces */ Integer mtu = profile.getMTU(); mMtu = mtu == null ? Constants.MTU_MAX : mtu; @@ -1249,7 +1264,7 @@ public class CharonVpnService extends VpnService implements Runnable, VpnStateSe } } - public void applyData(VpnService.Builder builder) + public void applyData(Builder builder) { for (IPRange address : mAddresses) { @@ -1375,6 +1390,10 @@ public class CharonVpnService extends VpnService implements Runnable, VpnStateSe break; } } + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q && mProxyServer != null) + { + builder.setHttpProxy(mProxyServer); + } builder.setMtu(mMtu); } diff --git a/src/frontends/android/app/src/main/java/org/strongswan/android/logic/SimpleFetcher.java b/src/frontends/android/app/src/main/java/org/strongswan/android/logic/SimpleFetcher.java index 7679cd457..93ccfdb07 100644 --- a/src/frontends/android/app/src/main/java/org/strongswan/android/logic/SimpleFetcher.java +++ b/src/frontends/android/app/src/main/java/org/strongswan/android/logic/SimpleFetcher.java @@ -22,6 +22,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.HttpURLConnection; +import java.net.Proxy; import java.net.SocketTimeoutException; import java.net.URL; import java.util.ArrayList; @@ -55,7 +56,7 @@ public class SimpleFetcher } future = mExecutor.submit(() -> { URL url = new URL(uri); - HttpURLConnection conn = (HttpURLConnection) url.openConnection(); + HttpURLConnection conn = (HttpURLConnection) url.openConnection(Proxy.NO_PROXY); conn.setConnectTimeout(10000); conn.setReadTimeout(10000); conn.setRequestProperty("Connection", "close"); diff --git a/src/frontends/android/app/src/main/java/org/strongswan/android/ui/VpnProfileDetailActivity.java b/src/frontends/android/app/src/main/java/org/strongswan/android/ui/VpnProfileDetailActivity.java index d33a16d07..cf1789d4b 100644 --- a/src/frontends/android/app/src/main/java/org/strongswan/android/ui/VpnProfileDetailActivity.java +++ b/src/frontends/android/app/src/main/java/org/strongswan/android/ui/VpnProfileDetailActivity.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2023 Relution GmbH - * Copyright (C) 2012-2020 Tobias Brunner + * Copyright (C) 2012-2025 Tobias Brunner * Copyright (C) 2012 Giuliano Grassi * Copyright (C) 2012 Ralf Sager * @@ -147,6 +147,10 @@ public class VpnProfileDetailActivity extends AppCompatActivity private TextView mProfileId; private EditText mDnsServers; private TextInputLayoutHelper mDnsServersWrap; + private EditText mProxyHost; + private EditText mProxyPort; + private TextInputLayoutHelper mProxyPortWrap; + private EditText mProxyExclusions; private final ActivityResultLauncher mInstallPKCS12 = registerForActivityResult( new ActivityResultContracts.StartActivityForResult(), @@ -254,6 +258,11 @@ public class VpnProfileDetailActivity extends AppCompatActivity /* make the link clickable */ ((TextView)findViewById(R.id.proposal_intro)).setMovementMethod(LinkMovementMethod.getInstance()); + mProxyHost = findViewById(R.id.proxy_host); + mProxyPort = findViewById(R.id.proxy_port); + mProxyPortWrap = findViewById(R.id.proxy_port_wrap); + mProxyExclusions = findViewById(R.id.proxy_exclusions); + mProfileIdLabel = findViewById(R.id.profile_id_label); mProfileId = findViewById(R.id.profile_id); @@ -584,7 +593,9 @@ public class VpnProfileDetailActivity extends AppCompatActivity mProfile.getIncludedSubnets() != null || mProfile.getExcludedSubnets() != null || mProfile.getSelectedAppsHandling() != SelectedAppsHandling.SELECTED_APPS_DISABLE || mProfile.getIkeProposal() != null || mProfile.getEspProposal() != null || - mProfile.getDnsServers() != null || mProfile.getLocalId() != null; + mProfile.getDnsServers() != null || mProfile.getLocalId() != null || + mProfile.getProxyHost() != null || mProfile.getProxyPort() != null || + mProfile.getProxyExclusions() != null; } mShowAdvanced.setVisibility(!show ? View.VISIBLE : View.GONE); mAdvancedSettings.setVisibility(show ? View.VISIBLE : View.GONE); @@ -700,6 +711,11 @@ public class VpnProfileDetailActivity extends AppCompatActivity mDnsServersWrap.setError(getString(R.string.alert_text_no_ips)); valid = false; } + if (!validateInteger(mProxyPort, 1, 65535)) + { + mProxyPortWrap.setError(String.format(getString(R.string.alert_text_out_of_range), 1, 65535)); + valid = false; + } return valid; } @@ -749,6 +765,9 @@ public class VpnProfileDetailActivity extends AppCompatActivity mProfile.setIkeProposal(getString(mIkeProposal)); mProfile.setEspProposal(getString(mEspProposal)); mProfile.setDnsServers(getString(mDnsServers)); + mProfile.setProxyHost(getString(mProxyHost)); + mProfile.setProxyPort(getInteger(mProxyPort)); + mProfile.setProxyExclusions(getString(mProxyExclusions)); } /** @@ -786,6 +805,9 @@ public class VpnProfileDetailActivity extends AppCompatActivity mIkeProposal.setText(mProfile.getIkeProposal()); mEspProposal.setText(mProfile.getEspProposal()); mDnsServers.setText(mProfile.getDnsServers()); + mProxyHost.setText(mProfile.getProxyHost()); + mProxyPort.setText(mProfile.getProxyPort() != null ? mProfile.getProxyPort().toString() : null); + mProxyExclusions.setText(mProfile.getProxyExclusions()); mProfileId.setText(mProfile.getUUID().toString()); flags = mProfile.getFlags(); useralias = mProfile.getUserCertificateAlias(); @@ -877,6 +899,9 @@ public class VpnProfileDetailActivity extends AppCompatActivity mIkeProposal.setEnabled(!readOnly); mEspProposal.setEnabled(!readOnly); mDnsServers.setEnabled(!readOnly); + mProxyHost.setEnabled(!readOnly); + mProxyPort.setEnabled(!readOnly); + mProxyExclusions.setEnabled(!readOnly); mSelectVpnType.setEnabled(!readOnly); mCertReq.setEnabled(!readOnly); diff --git a/src/frontends/android/app/src/main/java/org/strongswan/android/ui/VpnProfileImportActivity.java b/src/frontends/android/app/src/main/java/org/strongswan/android/ui/VpnProfileImportActivity.java index 08565d67b..ee56c1e53 100644 --- a/src/frontends/android/app/src/main/java/org/strongswan/android/ui/VpnProfileImportActivity.java +++ b/src/frontends/android/app/src/main/java/org/strongswan/android/ui/VpnProfileImportActivity.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016-2020 Tobias Brunner + * Copyright (C) 2016-2025 Tobias Brunner * * Copyright (C) secunet Security Networks AG * @@ -556,6 +556,14 @@ public class VpnProfileImportActivity extends AppCompatActivity flags |= VpnProfile.FLAGS_IPv6_TRANSPORT; } + JSONObject proxy = obj.optJSONObject("proxy"); + if (proxy != null) + { + profile.setProxyHost(proxy.optString("host")); + profile.setProxyPort(getInteger(proxy, "port", 1, 65535)); + profile.setProxyExclusions(getFlatStringList(proxy, "exclusions")); + } + JSONObject split = obj.optJSONObject("split-tunneling"); if (split != null) { @@ -569,8 +577,8 @@ public class VpnProfileImportActivity extends AppCompatActivity profile.setSplitTunneling(st == 0 ? null : st); } /* only one of these can be set, prefer specific apps */ - String selectedApps = getApps(obj.optJSONArray("apps")); - String excludedApps = getApps(obj.optJSONArray("excluded-apps")); + String selectedApps = getFlatStringList(obj, "apps"); + String excludedApps = getFlatStringList(obj, "excluded-apps"); if (!TextUtils.isEmpty(selectedApps)) { profile.setSelectedApps(selectedApps); @@ -606,24 +614,8 @@ public class VpnProfileImportActivity extends AppCompatActivity private String getSubnets(JSONObject split, String key) throws JSONException { - ArrayList subnets = new ArrayList<>(); - JSONArray arr = split.optJSONArray(key); - if (arr != null) - { - for (int i = 0; i < arr.length(); i++) - { /* replace all spaces, e.g. in "192.168.1.1 - 192.168.1.10" */ - subnets.add(arr.getString(i).replace(" ", "")); - } - } - else - { - String value = split.optString(key, null); - if (!TextUtils.isEmpty(value)) - { - subnets.add(value); - } - } - if (subnets.size() > 0) + ArrayList subnets = getStringList(split, key); + if (!subnets.isEmpty()) { String joined = TextUtils.join(" ", subnets); IPRangeSet ranges = IPRangeSet.fromString(joined); @@ -639,25 +631,8 @@ public class VpnProfileImportActivity extends AppCompatActivity private String getAddressList(JSONObject obj, String key) throws JSONException { - ArrayList addrs = new ArrayList<>(); - JSONArray arr = obj.optJSONArray(key); - if (arr != null) - { - for (int i = 0; i < arr.length(); i++) - { - String addr = arr.getString(i).replace(" ", ""); - addrs.add(addr); - } - } - else - { - String value = obj.optString(key, null); - if (!TextUtils.isEmpty(value)) - { - Collections.addAll(addrs, value.split("\\s+")); - } - } - if (addrs.size() > 0) + ArrayList addrs = getStringList(obj, key); + if (!addrs.isEmpty()) { for (String addr : addrs) { @@ -675,17 +650,39 @@ public class VpnProfileImportActivity extends AppCompatActivity return null; } - private String getApps(JSONArray arr) throws JSONException + private String getFlatStringList(JSONObject obj, String key) throws JSONException { - ArrayList apps = new ArrayList<>(); + ArrayList list = getStringList(obj, key); + if (!list.isEmpty()) + { + return TextUtils.join(" ", list); + } + return null; + } + + /** + * Return a list of strings, either retrieved from an array or from a space-separated string. + */ + private ArrayList getStringList(JSONObject obj, String key) throws JSONException + { + ArrayList list = new ArrayList<>(); + JSONArray arr = obj.optJSONArray(key); if (arr != null) { for (int i = 0; i < arr.length(); i++) - { - apps.add(arr.getString(i)); + { /* replace all spaces, including e.g. in "192.168.1.1 - 192.168.1.10" */ + list.add(arr.getString(i).replace(" ", "")); } } - return TextUtils.join(" ", apps); + else + { + String value = obj.optString(key, null); + if (!TextUtils.isEmpty(value)) + { + Collections.addAll(list, value.split("\\s+")); + } + } + return list; } /** diff --git a/src/frontends/android/app/src/main/java/org/strongswan/android/utils/Constants.java b/src/frontends/android/app/src/main/java/org/strongswan/android/utils/Constants.java index 7f5220fbf..59c6e6ad8 100644 --- a/src/frontends/android/app/src/main/java/org/strongswan/android/utils/Constants.java +++ b/src/frontends/android/app/src/main/java/org/strongswan/android/utils/Constants.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016-2020 Tobias Brunner + * Copyright (C) 2016-2025 Tobias Brunner * * Copyright (C) secunet Security Networks AG * @@ -45,6 +45,11 @@ public final class Constants public static final int NAT_KEEPALIVE_MAX = 120; public static final int NAT_KEEPALIVE_MIN = 10; + /** + * Default port for proxy servers + */ + public static final int PROXY_PORT_DEFAULT = 8080; + /** * Preference key for default VPN profile */ diff --git a/src/frontends/android/app/src/main/play/listings/de-DE/full-description.txt b/src/frontends/android/app/src/main/play/listings/de-DE/full-description.txt index a24347690..101357702 100644 --- a/src/frontends/android/app/src/main/play/listings/de-DE/full-description.txt +++ b/src/frontends/android/app/src/main/play/listings/de-DE/full-description.txt @@ -4,8 +4,8 @@ Dies ist die offizielle Android-Portierung der populären strongSwan VPN-Lösung
  • Verwendet die VpnService API von Android 4+. Geräte von einigen Herstellern scheinen diese nicht zu unterstützen - strongSwan wird auf diesen Geräten nicht funktionieren!
  • -
  • Verwendet das IKEv2 Schlüsselaustausch-Protokoll (IKEv1 wird nicht unterstützt)
  • -
  • Verwendet IPsec für den Datenkanal (L2TP wird nicht unterstützt)
  • +
  • Verwendet das IKEv2 Schlüsselaustausch-Protokoll
  • +
  • Verwendet IPsec für den Datenkanal
  • Volle Unterstützung für Konnektivitätsänderungen und Mobilität via MOBIKE (oder Re-Authentisierung)
  • Zur Authentisierung der Nutzer wird sowohl einfache auf Benutzername und Passwort basierende EAP-Authentisierung (namentlich EAP-MSCHAPv2, EAP-MD5 und EAP-GTC), sowie zertifikatsbasierte RSA/ECSA-Authentisierung unterstützt, EAP-TLS mit Benutzer-Zertifikaten wird ebenfalls unterstützt
  • Kombinierte Authentisierung mit RSA/ECDSA und EAP wird über zwei Authentisierungsrunden nach RFC 4739 unterstützt
  • diff --git a/src/frontends/android/app/src/main/play/listings/en-US/full-description.txt b/src/frontends/android/app/src/main/play/listings/en-US/full-description.txt index 72114f983..1a73b5c40 100644 --- a/src/frontends/android/app/src/main/play/listings/en-US/full-description.txt +++ b/src/frontends/android/app/src/main/play/listings/en-US/full-description.txt @@ -4,8 +4,8 @@ Official Android port of the popular strongSwan VPN solution.
    • Uses the VpnService API featured by Android 4+. Devices by some manufacturers seem to lack support for this - strongSwan VPN Client won't work on these devices!
    • -
    • Uses the IKEv2 key exchange protocol (IKEv1 is not supported)
    • -
    • Uses IPsec for data traffic (L2TP is not supported)
    • +
    • Uses the IKEv2 key exchange protocol
    • +
    • Uses IPsec for data traffic
    • Full support for changed connectivity and mobility through MOBIKE (or reauthentication)
    • Supports username/password EAP authentication (namely EAP-MSCHAPv2, EAP-MD5 and EAP-GTC) as well as RSA/ECDSA private key/certificate authentication to authenticate users, EAP-TLS with client certificates is also supported
    • Combined RSA/ECDSA and EAP authentication is supported by using two authentication rounds as defined in RFC 4739
    • diff --git a/src/frontends/android/app/src/main/play/release-notes/de-DE/default.txt b/src/frontends/android/app/src/main/play/release-notes/de-DE/default.txt index 7cfb62d6d..9409e3a19 100644 --- a/src/frontends/android/app/src/main/play/release-notes/de-DE/default.txt +++ b/src/frontends/android/app/src/main/play/release-notes/de-DE/default.txt @@ -1,3 +1,7 @@ +# 2.5.6 # + +- Unterstützt benutzerdefinierte HTTP Proxy-Server (Android 10+) + # 2.5.5 # - Fixt den Start von verwalteten Profilen als Always-on VPN diff --git a/src/frontends/android/app/src/main/play/release-notes/en-US/default.txt b/src/frontends/android/app/src/main/play/release-notes/en-US/default.txt index 4b8b02ed0..2ae778052 100644 --- a/src/frontends/android/app/src/main/play/release-notes/en-US/default.txt +++ b/src/frontends/android/app/src/main/play/release-notes/en-US/default.txt @@ -1,3 +1,7 @@ +# 2.5.6 # + +- Add support for custom HTTP proxy server (Android 10+) + # 2.5.5 # - Fix initiating managed profiles as Always-on VPN diff --git a/src/frontends/android/app/src/main/res/layout/profile_detail_view.xml b/src/frontends/android/app/src/main/res/layout/profile_detail_view.xml index eb67583bb..04696058b 100644 --- a/src/frontends/android/app/src/main/res/layout/profile_detail_view.xml +++ b/src/frontends/android/app/src/main/res/layout/profile_detail_view.xml @@ -1,6 +1,6 @@ + @string/profile_proxy_server_label + @string/profile_proxy_server_intro + @string/profile_proxy_host_label + @string/profile_proxy_host_hint + @string/profile_proxy_port_label + @string/profile_proxy_port_hint + @string/profile_proxy_exclusions_label + @string/profile_proxy_exclusions_hint diff --git a/src/frontends/android/app/src/main/res/values-pl/strings.xml b/src/frontends/android/app/src/main/res/values-pl/strings.xml index 7d4fe1357..8d98fe36b 100644 --- a/src/frontends/android/app/src/main/res/values-pl/strings.xml +++ b/src/frontends/android/app/src/main/res/values-pl/strings.xml @@ -130,6 +130,14 @@ For non-AEAD/classic encryption algorithms, an integrity algorithm, a pseudo random function (optional, defaults to one based on the integrity algorithm) and a Diffie-Hellman group are required (e.g. aes256-sha256-ecp256). For combined-mode/AEAD algorithms, the integrity algorithm is omitted but a PRF is required (e.g. aes256gcm16-prfsha256-ecp256). IPsec/ESP Algorithms For non-AEAD/classic encryption algorithms, an integrity algorithm is required, a Diffie-Hellman group is optional (e.g. aes256-sha256 or aes256-sha256-ecp256). For combined-mode/AEAD algorithms, the integrity algorithm is omitted (e.g. aes256gcm16 or aes256gcm16-ecp256). If a DH group is specified IPsec SA rekeying will use a DH key exchange. However, DH groups specified here are not used when the connection is established initially because the keys there are derived from the IKE SA key material. Therefore, any configuration mismatch with the server will only cause errors later during rekeying. + HTTP proxy server + Optional HTTP proxy server to use when connected to the VPN. This is only a recommendation and may be ignored by apps. Note that apps using the proxy will access all HTTP resources through it regardless of the destination, so split-tunneling settings might not have any effect. To avoid using the proxy server for specific hosts, use the exclusion list below. + Proxy host + IP address or hostname of the HTTP proxy server to use when connected to the VPN + Proxy port + Port to access the HTTP proxy server, defaults to 8080 + Proxy exclusion list + Optional list of hosts for which the HTTP proxy server is not used (separated by spaces, and wildcards are possible, e.g. \"direct.example.net *.example.com\") Import VPN profile Failed to import VPN profile Failed to import VPN profile: %1$s diff --git a/src/frontends/android/app/src/main/res/values-pl/strings_managed_configuration.xml b/src/frontends/android/app/src/main/res/values-pl/strings_managed_configuration.xml index 74e59cfe7..c7d516011 100644 --- a/src/frontends/android/app/src/main/res/values-pl/strings_managed_configuration.xml +++ b/src/frontends/android/app/src/main/res/values-pl/strings_managed_configuration.xml @@ -108,4 +108,13 @@ @string/profile_split_tunnelingv6_title Specifies whether to block IPv6 traffic that\'s not destined for the VPN. Forces all IPv6 traffic via VPN (traffic that does not match the negotiated traffic selector is then just dropped). Thus this is basically equivalent to including ::/0 in subnets + + @string/profile_proxy_server_label + @string/profile_proxy_server_intro + @string/profile_proxy_host_label + @string/profile_proxy_host_hint + @string/profile_proxy_port_label + @string/profile_proxy_port_hint + @string/profile_proxy_exclusions_label + @string/profile_proxy_exclusions_hint diff --git a/src/frontends/android/app/src/main/res/values-ru/strings.xml b/src/frontends/android/app/src/main/res/values-ru/strings.xml index d289ca111..0f8c724ad 100644 --- a/src/frontends/android/app/src/main/res/values-ru/strings.xml +++ b/src/frontends/android/app/src/main/res/values-ru/strings.xml @@ -124,6 +124,14 @@ For non-AEAD/classic encryption algorithms, an integrity algorithm, a pseudo random function (optional, defaults to one based on the integrity algorithm) and a Diffie-Hellman group are required (e.g. aes256-sha256-ecp256). For combined-mode/AEAD algorithms, the integrity algorithm is omitted but a PRF is required (e.g. aes256gcm16-prfsha256-ecp256). IPsec/ESP Algorithms For non-AEAD/classic encryption algorithms, an integrity algorithm is required, a Diffie-Hellman group is optional (e.g. aes256-sha256 or aes256-sha256-ecp256). For combined-mode/AEAD algorithms, the integrity algorithm is omitted (e.g. aes256gcm16 or aes256gcm16-ecp256). If a DH group is specified IPsec SA rekeying will use a DH key exchange. However, DH groups specified here are not used when the connection is established initially because the keys there are derived from the IKE SA key material. Therefore, any configuration mismatch with the server will only cause errors later during rekeying. + HTTP proxy server + Optional HTTP proxy server to use when connected to the VPN. This is only a recommendation and may be ignored by apps. Note that apps using the proxy will access all HTTP resources through it regardless of the destination, so split-tunneling settings might not have any effect. To avoid using the proxy server for specific hosts, use the exclusion list below. + Proxy host + IP address or hostname of the HTTP proxy server to use when connected to the VPN + Proxy port + Port to access the HTTP proxy server, defaults to 8080 + Proxy exclusion list + Optional list of hosts for which the HTTP proxy server is not used (separated by spaces, and wildcards are possible, e.g. \"direct.example.net *.example.com\") Import VPN profile Failed to import VPN profile Failed to import VPN profile: %1$s diff --git a/src/frontends/android/app/src/main/res/values-ru/strings_managed_configuration.xml b/src/frontends/android/app/src/main/res/values-ru/strings_managed_configuration.xml index 74e59cfe7..c7d516011 100644 --- a/src/frontends/android/app/src/main/res/values-ru/strings_managed_configuration.xml +++ b/src/frontends/android/app/src/main/res/values-ru/strings_managed_configuration.xml @@ -108,4 +108,13 @@ @string/profile_split_tunnelingv6_title Specifies whether to block IPv6 traffic that\'s not destined for the VPN. Forces all IPv6 traffic via VPN (traffic that does not match the negotiated traffic selector is then just dropped). Thus this is basically equivalent to including ::/0 in subnets + + @string/profile_proxy_server_label + @string/profile_proxy_server_intro + @string/profile_proxy_host_label + @string/profile_proxy_host_hint + @string/profile_proxy_port_label + @string/profile_proxy_port_hint + @string/profile_proxy_exclusions_label + @string/profile_proxy_exclusions_hint diff --git a/src/frontends/android/app/src/main/res/values-uk/strings.xml b/src/frontends/android/app/src/main/res/values-uk/strings.xml index e3c78c45d..2b552b606 100644 --- a/src/frontends/android/app/src/main/res/values-uk/strings.xml +++ b/src/frontends/android/app/src/main/res/values-uk/strings.xml @@ -125,6 +125,14 @@ For non-AEAD/classic encryption algorithms, an integrity algorithm, a pseudo random function (optional, defaults to one based on the integrity algorithm) and a Diffie-Hellman group are required (e.g. aes256-sha256-ecp256). For combined-mode/AEAD algorithms, the integrity algorithm is omitted but a PRF is required (e.g. aes256gcm16-prfsha256-ecp256). IPsec/ESP Algorithms For non-AEAD/classic encryption algorithms, an integrity algorithm is required, a Diffie-Hellman group is optional (e.g. aes256-sha256 or aes256-sha256-ecp256). For combined-mode/AEAD algorithms, the integrity algorithm is omitted (e.g. aes256gcm16 or aes256gcm16-ecp256). If a DH group is specified IPsec SA rekeying will use a DH key exchange. However, DH groups specified here are not used when the connection is established initially because the keys there are derived from the IKE SA key material. Therefore, any configuration mismatch with the server will only cause errors later during rekeying. + HTTP proxy server + Optional HTTP proxy server to use when connected to the VPN. This is only a recommendation and may be ignored by apps. Note that apps using the proxy will access all HTTP resources through it regardless of the destination, so split-tunneling settings might not have any effect. To avoid using the proxy server for specific hosts, use the exclusion list below. + Proxy host + IP address or hostname of the HTTP proxy server to use when connected to the VPN + Proxy port + Port to access the HTTP proxy server, defaults to 8080 + Proxy exclusion list + Optional list of hosts for which the HTTP proxy server is not used (separated by spaces, and wildcards are possible, e.g. \"direct.example.net *.example.com\") Import VPN profile Failed to import VPN profile Failed to import VPN profile: %1$s diff --git a/src/frontends/android/app/src/main/res/values-uk/strings_managed_configuration.xml b/src/frontends/android/app/src/main/res/values-uk/strings_managed_configuration.xml index 74e59cfe7..c7d516011 100644 --- a/src/frontends/android/app/src/main/res/values-uk/strings_managed_configuration.xml +++ b/src/frontends/android/app/src/main/res/values-uk/strings_managed_configuration.xml @@ -108,4 +108,13 @@ @string/profile_split_tunnelingv6_title Specifies whether to block IPv6 traffic that\'s not destined for the VPN. Forces all IPv6 traffic via VPN (traffic that does not match the negotiated traffic selector is then just dropped). Thus this is basically equivalent to including ::/0 in subnets + + @string/profile_proxy_server_label + @string/profile_proxy_server_intro + @string/profile_proxy_host_label + @string/profile_proxy_host_hint + @string/profile_proxy_port_label + @string/profile_proxy_port_hint + @string/profile_proxy_exclusions_label + @string/profile_proxy_exclusions_hint diff --git a/src/frontends/android/app/src/main/res/values-zh-rCN/strings.xml b/src/frontends/android/app/src/main/res/values-zh-rCN/strings.xml index 4dd71912d..fe9602836 100644 --- a/src/frontends/android/app/src/main/res/values-zh-rCN/strings.xml +++ b/src/frontends/android/app/src/main/res/values-zh-rCN/strings.xml @@ -124,6 +124,14 @@ 对于非AEAD/经典加密算法,需要完整性算法、伪随机函数(可选,默认为基于完整性算法的函数)和Diffie-Hellman组(例如aes256-sha256-ecp256)。对于组合模式/AEAD算法,省略完整性算法,但需要PRF(例如aes256gcm16-prfsha256-ecp256)。 IPsec/ESP 算法 对于非AEAD/经典加密算法,需要完整性算法,Diffie-Hellman组是可选的(例如aes256-sha256或aes256-sha256-ecp256)。对于组合模式/AEAD算法,省略完整性算法(例如aes256gcm16或aes256gcm16-ecp256)。如果指定了DH组,IPsec SA密钥更新将使用DH密钥交换。但是,在最初建立连接时,不使用此处指定的DH组,因为其中的密钥来自IKE SA密钥材料。因此,与服务器的任何配置不匹配只会在稍后重新设置密钥时导致错误。 + HTTP proxy server + Optional HTTP proxy server to use when connected to the VPN. This is only a recommendation and may be ignored by apps. Note that apps using the proxy will access all HTTP resources through it regardless of the destination, so split-tunneling settings might not have any effect. To avoid using the proxy server for specific hosts, use the exclusion list below. + Proxy host + IP address or hostname of the HTTP proxy server to use when connected to the VPN + Proxy port + Port to access the HTTP proxy server, defaults to 8080 + Proxy exclusion list + Optional list of hosts for which the HTTP proxy server is not used (separated by spaces, and wildcards are possible, e.g. \"direct.example.net *.example.com\") 导入VPN配置 导入VPN配置失败 导入VPN配置失败: %1$s diff --git a/src/frontends/android/app/src/main/res/values-zh-rCN/strings_managed_configuration.xml b/src/frontends/android/app/src/main/res/values-zh-rCN/strings_managed_configuration.xml index 74e59cfe7..c7d516011 100644 --- a/src/frontends/android/app/src/main/res/values-zh-rCN/strings_managed_configuration.xml +++ b/src/frontends/android/app/src/main/res/values-zh-rCN/strings_managed_configuration.xml @@ -108,4 +108,13 @@ @string/profile_split_tunnelingv6_title Specifies whether to block IPv6 traffic that\'s not destined for the VPN. Forces all IPv6 traffic via VPN (traffic that does not match the negotiated traffic selector is then just dropped). Thus this is basically equivalent to including ::/0 in subnets + + @string/profile_proxy_server_label + @string/profile_proxy_server_intro + @string/profile_proxy_host_label + @string/profile_proxy_host_hint + @string/profile_proxy_port_label + @string/profile_proxy_port_hint + @string/profile_proxy_exclusions_label + @string/profile_proxy_exclusions_hint diff --git a/src/frontends/android/app/src/main/res/values-zh-rTW/strings.xml b/src/frontends/android/app/src/main/res/values-zh-rTW/strings.xml index f97f35885..26f3e80a1 100644 --- a/src/frontends/android/app/src/main/res/values-zh-rTW/strings.xml +++ b/src/frontends/android/app/src/main/res/values-zh-rTW/strings.xml @@ -124,6 +124,14 @@ For non-AEAD/classic encryption algorithms, an integrity algorithm, a pseudo random function (optional, defaults to one based on the integrity algorithm) and a Diffie-Hellman group are required (e.g. aes256-sha256-ecp256). For combined-mode/AEAD algorithms, the integrity algorithm is omitted but a PRF is required (e.g. aes256gcm16-prfsha256-ecp256). IPsec/ESP Algorithms For non-AEAD/classic encryption algorithms, an integrity algorithm is required, a Diffie-Hellman group is optional (e.g. aes256-sha256 or aes256-sha256-ecp256). For combined-mode/AEAD algorithms, the integrity algorithm is omitted (e.g. aes256gcm16 or aes256gcm16-ecp256). If a DH group is specified IPsec SA rekeying will use a DH key exchange. However, DH groups specified here are not used when the connection is established initially because the keys there are derived from the IKE SA key material. Therefore, any configuration mismatch with the server will only cause errors later during rekeying. + HTTP proxy server + Optional HTTP proxy server to use when connected to the VPN. This is only a recommendation and may be ignored by apps. Note that apps using the proxy will access all HTTP resources through it regardless of the destination, so split-tunneling settings might not have any effect. To avoid using the proxy server for specific hosts, use the exclusion list below. + Proxy host + IP address or hostname of the HTTP proxy server to use when connected to the VPN + Proxy port + Port to access the HTTP proxy server, defaults to 8080 + Proxy exclusion list + Optional list of hosts for which the HTTP proxy server is not used (separated by spaces, and wildcards are possible, e.g. \"direct.example.net *.example.com\") 匯入VPN設定檔 匯入VPN設定檔失敗 匯入VPN設定檔失敗: %1$s diff --git a/src/frontends/android/app/src/main/res/values-zh-rTW/strings_managed_configuration.xml b/src/frontends/android/app/src/main/res/values-zh-rTW/strings_managed_configuration.xml index 74e59cfe7..c7d516011 100644 --- a/src/frontends/android/app/src/main/res/values-zh-rTW/strings_managed_configuration.xml +++ b/src/frontends/android/app/src/main/res/values-zh-rTW/strings_managed_configuration.xml @@ -108,4 +108,13 @@ @string/profile_split_tunnelingv6_title Specifies whether to block IPv6 traffic that\'s not destined for the VPN. Forces all IPv6 traffic via VPN (traffic that does not match the negotiated traffic selector is then just dropped). Thus this is basically equivalent to including ::/0 in subnets + + @string/profile_proxy_server_label + @string/profile_proxy_server_intro + @string/profile_proxy_host_label + @string/profile_proxy_host_hint + @string/profile_proxy_port_label + @string/profile_proxy_port_hint + @string/profile_proxy_exclusions_label + @string/profile_proxy_exclusions_hint diff --git a/src/frontends/android/app/src/main/res/values/strings.xml b/src/frontends/android/app/src/main/res/values/strings.xml index e80be46b5..7f031bec8 100644 --- a/src/frontends/android/app/src/main/res/values/strings.xml +++ b/src/frontends/android/app/src/main/res/values/strings.xml @@ -128,6 +128,14 @@ For non-AEAD/classic encryption algorithms, an integrity algorithm, a pseudo random function (optional, defaults to one based on the integrity algorithm) and a Diffie-Hellman group are required (e.g. aes256-sha256-ecp256). For combined-mode/AEAD algorithms, the integrity algorithm is omitted but a PRF is required (e.g. aes256gcm16-prfsha256-ecp256). IPsec/ESP Algorithms For non-AEAD/classic encryption algorithms, an integrity algorithm is required, a Diffie-Hellman group is optional (e.g. aes256-sha256 or aes256-sha256-ecp256). For combined-mode/AEAD algorithms, the integrity algorithm is omitted (e.g. aes256gcm16 or aes256gcm16-ecp256). If a DH group is specified IPsec SA rekeying will use a DH key exchange. However, DH groups specified here are not used when the connection is established initially because the keys there are derived from the IKE SA key material. Therefore, any configuration mismatch with the server will only cause errors later during rekeying. + HTTP proxy server + Optional HTTP proxy server to use when connected to the VPN. This is only a recommendation and may be ignored by apps. Note that apps using the proxy will access all HTTP resources through it regardless of the destination, so split-tunneling settings might not have any effect. To avoid using the proxy server for specific hosts, use the exclusion list below. + Proxy host + IP address or hostname of the HTTP proxy server to use when connected to the VPN + Proxy port + Port to access the HTTP proxy server, defaults to 8080 + Proxy exclusion list + Optional list of hosts for which the HTTP proxy server is not used (separated by spaces, and wildcards are possible, e.g. \"direct.example.net *.example.com\") Import VPN profile Failed to import VPN profile Failed to import VPN profile: %1$s diff --git a/src/frontends/android/app/src/main/res/values/strings_managed_configuration.xml b/src/frontends/android/app/src/main/res/values/strings_managed_configuration.xml index 74e59cfe7..04922033d 100644 --- a/src/frontends/android/app/src/main/res/values/strings_managed_configuration.xml +++ b/src/frontends/android/app/src/main/res/values/strings_managed_configuration.xml @@ -1,5 +1,6 @@ + @string/profile_proxy_server_label + @string/profile_proxy_server_intro + @string/profile_proxy_host_label + @string/profile_proxy_host_hint + @string/profile_proxy_port_label + @string/profile_proxy_port_hint + @string/profile_proxy_exclusions_label + @string/profile_proxy_exclusions_hint diff --git a/src/frontends/android/app/src/main/res/xml/managed_configuration.xml b/src/frontends/android/app/src/main/res/xml/managed_configuration.xml index e86ad721e..8c2a70eb8 100644 --- a/src/frontends/android/app/src/main/res/xml/managed_configuration.xml +++ b/src/frontends/android/app/src/main/res/xml/managed_configuration.xml @@ -1,5 +1,6 @@