summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcyBerta <cyberta@riseup.net>2018-10-19 23:15:13 +0200
committercyBerta <cyberta@riseup.net>2018-10-19 23:15:13 +0200
commit74842cba92591aa9fbf64e8c6f39900a68b0c11c (patch)
tree3b81a830c7eff45b1dc04421201a4b675fc46c18
parent6c994f657ecf88bdbb2480141b9904cc2eeac6ce (diff)
#8919 update dependencies
-rw-r--r--app/build.gradle5
-rw-r--r--app/src/main/aidl/de/blinkt/openvpn/api/ExternalCertificateProvider.aidl39
-rw-r--r--app/src/main/aidl/de/blinkt/openvpn/api/IOpenVPNAPIService.aidl2
-rw-r--r--app/src/main/aidl/de/blinkt/openvpn/core/IOpenVPNServiceInternal.aidl1
-rw-r--r--app/src/main/java/de/blinkt/openvpn/LaunchVPN.java4
-rw-r--r--app/src/main/java/de/blinkt/openvpn/VpnProfile.java482
-rw-r--r--app/src/main/java/de/blinkt/openvpn/core/CIDRIP.java8
-rw-r--r--app/src/main/java/de/blinkt/openvpn/core/ConfigParser.java379
-rw-r--r--app/src/main/java/de/blinkt/openvpn/core/Connection.java33
-rw-r--r--app/src/main/java/de/blinkt/openvpn/core/ExtAuthHelper.java259
-rw-r--r--app/src/main/java/de/blinkt/openvpn/core/ICSOpenVPNApplication.java2
-rw-r--r--app/src/main/java/de/blinkt/openvpn/core/LogFileHandler.java4
-rw-r--r--app/src/main/java/de/blinkt/openvpn/core/NativeUtils.java22
-rw-r--r--app/src/main/java/de/blinkt/openvpn/core/NetworkSpace.java103
-rw-r--r--app/src/main/java/de/blinkt/openvpn/core/NetworkUtils.java75
-rw-r--r--app/src/main/java/de/blinkt/openvpn/core/OpenVPNService.java181
-rw-r--r--app/src/main/java/de/blinkt/openvpn/core/OpenVpnManagementThread.java239
-rw-r--r--app/src/main/java/de/blinkt/openvpn/core/OrbotHelper.java202
-rw-r--r--app/src/main/java/de/blinkt/openvpn/core/ProfileManager.java13
-rw-r--r--app/src/main/java/de/blinkt/openvpn/core/VPNLaunchHelper.java2
-rw-r--r--app/src/main/java/de/blinkt/openvpn/core/VpnStatus.java6
-rwxr-xr-xapp/src/main/res/values-be/plurals-icsopenvpn.xml3
-rwxr-xr-xapp/src/main/res/values-be/strings-icsopenvpn.xml464
-rwxr-xr-xapp/src/main/res/values-ca/strings-icsopenvpn.xml1
-rwxr-xr-xapp/src/main/res/values-cs/strings-icsopenvpn.xml5
-rwxr-xr-xapp/src/main/res/values-da/strings-icsopenvpn.xml88
-rwxr-xr-xapp/src/main/res/values-de/strings-icsopenvpn.xml15
-rwxr-xr-xapp/src/main/res/values-es/strings-icsopenvpn.xml22
-rwxr-xr-xapp/src/main/res/values-et/strings-icsopenvpn.xml1
-rwxr-xr-xapp/src/main/res/values-fr/strings-icsopenvpn.xml16
-rwxr-xr-xapp/src/main/res/values-hu/strings-icsopenvpn.xml5
-rwxr-xr-xapp/src/main/res/values-in/strings-icsopenvpn.xml21
-rwxr-xr-xapp/src/main/res/values-it/strings-icsopenvpn.xml24
-rwxr-xr-xapp/src/main/res/values-ja/strings-icsopenvpn.xml19
-rwxr-xr-xapp/src/main/res/values-ko/strings-icsopenvpn.xml13
-rwxr-xr-xapp/src/main/res/values-nl/strings-icsopenvpn.xml5
-rwxr-xr-xapp/src/main/res/values-no/strings-icsopenvpn.xml1
-rwxr-xr-xapp/src/main/res/values-pl/plurals-icsopenvpn.xml8
-rwxr-xr-xapp/src/main/res/values-pl/strings-icsopenvpn.xml26
-rwxr-xr-xapp/src/main/res/values-pt/strings-icsopenvpn.xml1
-rwxr-xr-xapp/src/main/res/values-ro/strings-icsopenvpn.xml1
-rwxr-xr-xapp/src/main/res/values-ru/plurals-icsopenvpn.xml12
-rwxr-xr-xapp/src/main/res/values-ru/strings-icsopenvpn.xml26
-rwxr-xr-xapp/src/main/res/values-sl/strings-icsopenvpn.xml1
-rwxr-xr-xapp/src/main/res/values-sv/strings-icsopenvpn.xml7
-rwxr-xr-xapp/src/main/res/values-tr/strings-icsopenvpn.xml5
-rwxr-xr-xapp/src/main/res/values-uk/plurals-icsopenvpn.xml23
-rwxr-xr-xapp/src/main/res/values-uk/strings-icsopenvpn.xml5
-rwxr-xr-xapp/src/main/res/values-vi/strings-icsopenvpn.xml30
-rwxr-xr-xapp/src/main/res/values-zh-rCN/strings-icsopenvpn.xml32
-rwxr-xr-xapp/src/main/res/values-zh-rTW/plurals-icsopenvpn.xml15
-rwxr-xr-xapp/src/main/res/values-zh-rTW/strings-icsopenvpn.xml181
-rwxr-xr-xapp/src/main/res/values/strings-icsopenvpn.xml23
-rw-r--r--app/src/ovpn3/java/de/blinkt/openvpn/core/OpenVPNThreadv3.java67
-rw-r--r--app/src/test/java/de/blinkt/openvpn/core/TestConfigGenerator.java69
-rw-r--r--app/src/test/java/de/blinkt/openvpn/core/TestConfigParser.java223
-rw-r--r--app/src/test/java/de/blinkt/openvpn/core/TestIpParser.java2
m---------ics-openvpn0
58 files changed, 2804 insertions, 717 deletions
diff --git a/app/build.gradle b/app/build.gradle
index 16d517b4..03d602e4 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -9,6 +9,11 @@ android {
compileSdkVersion 27
buildToolsVersion '27.0.3'
+ compileOptions {
+ targetCompatibility 1.8
+ sourceCompatibility 1.8
+ }
+
defaultConfig {
applicationId "se.leap.bitmaskclient"
versionCode 134
diff --git a/app/src/main/aidl/de/blinkt/openvpn/api/ExternalCertificateProvider.aidl b/app/src/main/aidl/de/blinkt/openvpn/api/ExternalCertificateProvider.aidl
new file mode 100644
index 00000000..c6db965b
--- /dev/null
+++ b/app/src/main/aidl/de/blinkt/openvpn/api/ExternalCertificateProvider.aidl
@@ -0,0 +1,39 @@
+// ExternalCertificateProvider.aidl
+package de.blinkt.openvpn.api;
+
+
+/*
+ * This is very simple interface that is specialised to have only the minimal set of crypto
+ * operation that are needed for OpenVPN to authenticate with an external certificate
+ */
+interface ExternalCertificateProvider {
+ /**
+ * Requests signing the data with RSA/ECB/PKCS1PADDING
+ * for RSA certficate and with NONEwithECDSA for EC certificates
+ * @parm alias the parameter that
+ */
+ byte[] getSignedData(in String alias, in byte[] data);
+
+ /**
+ * Requests the certificate chain for the selected alias
+ * The first certifcate returned is assumed to be
+ * the user certificate
+ */
+ byte[] getCertificateChain(in String alias);
+
+ /**
+ * This function is called for the app to get additional meta information from the
+ * external provider and will be called with the stored alias in the app
+ *
+ * For external app provider that do not provide an activity to configure them, this
+ * is used to get the alias that should be used.
+ * The format is the same as the activity should return, i.e.
+ *
+ * EXTRA_ALIAS = "de.blinkt.openvpn.api.KEY_ALIAS"
+ * EXTRA_DESCRIPTION = "de.blinkt.openvpn.api.KEY_DESCRIPTION"
+ *
+ * as the keys for the bundle.
+ *
+ */
+ Bundle getCertificateMetaData(in String alias);
+}
diff --git a/app/src/main/aidl/de/blinkt/openvpn/api/IOpenVPNAPIService.aidl b/app/src/main/aidl/de/blinkt/openvpn/api/IOpenVPNAPIService.aidl
index 75d0c329..e907bfd6 100644
--- a/app/src/main/aidl/de/blinkt/openvpn/api/IOpenVPNAPIService.aidl
+++ b/app/src/main/aidl/de/blinkt/openvpn/api/IOpenVPNAPIService.aidl
@@ -18,7 +18,7 @@ interface IOpenVPNAPIService {
boolean addVPNProfile (String name, String config);
/** start a profile using a config as inline string. Make sure that all needed data is inlined,
- * e.g., using <ca>...</ca> or <auth-user-data>...</auth-user-data>
+ * e.g., using <ca>...</ca> or <auth-user-pass>...</auth-user-pass>
* See the OpenVPN manual page for more on inlining files */
void startVPN (in String inlineconfig);
diff --git a/app/src/main/aidl/de/blinkt/openvpn/core/IOpenVPNServiceInternal.aidl b/app/src/main/aidl/de/blinkt/openvpn/core/IOpenVPNServiceInternal.aidl
index b19cf99e..293c2b6d 100644
--- a/app/src/main/aidl/de/blinkt/openvpn/core/IOpenVPNServiceInternal.aidl
+++ b/app/src/main/aidl/de/blinkt/openvpn/core/IOpenVPNServiceInternal.aidl
@@ -22,4 +22,5 @@ interface IOpenVPNServiceInternal {
boolean stopVPN(boolean replaceConnection);
boolean isVpnRunning();
+
}
diff --git a/app/src/main/java/de/blinkt/openvpn/LaunchVPN.java b/app/src/main/java/de/blinkt/openvpn/LaunchVPN.java
index e83cffa0..5bf178ae 100644
--- a/app/src/main/java/de/blinkt/openvpn/LaunchVPN.java
+++ b/app/src/main/java/de/blinkt/openvpn/LaunchVPN.java
@@ -7,6 +7,8 @@ package de.blinkt.openvpn;
import se.leap.bitmaskclient.R;
+import se.leap.bitmaskclient.R;
+
import android.annotation.TargetApi;
import android.app.Activity;
import android.app.AlertDialog;
@@ -231,4 +233,4 @@ public class LaunchVPN extends Activity {
VpnStatus.logException("SU command", e);
}
}
-}
+} \ No newline at end of file
diff --git a/app/src/main/java/de/blinkt/openvpn/VpnProfile.java b/app/src/main/java/de/blinkt/openvpn/VpnProfile.java
index 4becdc32..bd28ae16 100644
--- a/app/src/main/java/de/blinkt/openvpn/VpnProfile.java
+++ b/app/src/main/java/de/blinkt/openvpn/VpnProfile.java
@@ -6,7 +6,6 @@
package de.blinkt.openvpn;
import se.leap.bitmaskclient.R;
-
import se.leap.bitmaskclient.BuildConfig;
import android.annotation.SuppressLint;
@@ -16,10 +15,12 @@ import android.content.SharedPreferences;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Build;
+import android.os.RemoteException;
import android.preference.PreferenceManager;
import android.security.KeyChain;
import android.security.KeyChainException;
import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.util.Base64;
@@ -62,14 +63,9 @@ public class VpnProfile implements Serializable, Cloneable {
public static final String EXTRA_PROFILEUUID = "de.blinkt.openvpn.profileUUID";
public static final String INLINE_TAG = "[[INLINE]]";
public static final String DISPLAYNAME_TAG = "[[NAME]]";
-
- private static final long serialVersionUID = 7085688938959334563L;
public static final int MAXLOGLEVEL = 4;
- public static final int CURRENT_PROFILE_VERSION = 6;
+ public static final int CURRENT_PROFILE_VERSION = 7;
public static final int DEFAULT_MSSFIX_SIZE = 1280;
- public static String DEFAULT_DNS1 = "8.8.8.8";
- public static String DEFAULT_DNS2 = "8.8.4.4";
-
public static final int TYPE_CERTIFICATES = 0;
public static final int TYPE_PKCS12 = 1;
public static final int TYPE_KEYSTORE = 2;
@@ -78,17 +74,20 @@ public class VpnProfile implements Serializable, Cloneable {
public static final int TYPE_USERPASS_CERTIFICATES = 5;
public static final int TYPE_USERPASS_PKCS12 = 6;
public static final int TYPE_USERPASS_KEYSTORE = 7;
+ public static final int TYPE_EXTERNAL_APP = 8;
public static final int X509_VERIFY_TLSREMOTE = 0;
public static final int X509_VERIFY_TLSREMOTE_COMPAT_NOREMAPPING = 1;
public static final int X509_VERIFY_TLSREMOTE_DN = 2;
public static final int X509_VERIFY_TLSREMOTE_RDN = 3;
public static final int X509_VERIFY_TLSREMOTE_RDN_PREFIX = 4;
-
-
public static final int AUTH_RETRY_NONE_FORGET = 0;
- private static final int AUTH_RETRY_NONE_KEEP = 1;
public static final int AUTH_RETRY_NOINTERACT = 2;
+ public static final boolean mIsOpenVPN22 = false;
+ private static final long serialVersionUID = 7085688938959334563L;
+ private static final int AUTH_RETRY_NONE_KEEP = 1;
private static final int AUTH_RETRY_INTERACT = 3;
+ public static String DEFAULT_DNS1 = "8.8.8.8";
+ public static String DEFAULT_DNS2 = "8.8.4.4";
// variable named wrong and should haven beeen transient
// but needs to keep wrong name to guarante loading of old
// profiles
@@ -105,7 +104,6 @@ public class VpnProfile implements Serializable, Cloneable {
public String mPKCS12Filename;
public String mPKCS12Password;
public boolean mUseTLSAuth = false;
-
public String mDNS1 = DEFAULT_DNS1;
public String mDNS2 = DEFAULT_DNS2;
public String mIPv4Address;
@@ -127,7 +125,7 @@ public class VpnProfile implements Serializable, Cloneable {
public String mCustomConfigOptions = "";
public String mVerb = "1"; //ignored
public String mCipher = "";
- public boolean mNobind = false;
+ public boolean mNobind = true;
public boolean mUseDefaultRoutev6 = true;
public String mCustomRoutesv6 = "";
public String mKeyPassword = "";
@@ -139,13 +137,7 @@ public class VpnProfile implements Serializable, Cloneable {
public String mAuth = "";
public int mX509AuthType = X509_VERIFY_TLSREMOTE_RDN;
public String mx509UsernameField = null;
-
- private transient PrivateKey mPrivateKey;
- // Public attributes, since I got mad with getter/setter
- // set members to default values
- private UUID mUuid;
public boolean mAllowLocalLAN;
- private int mProfileVersion;
public String mExcludedRoutes;
public String mExcludedRoutesv6;
public int mMssFix = 0; // -1 is default,
@@ -153,26 +145,26 @@ public class VpnProfile implements Serializable, Cloneable {
public boolean mRemoteRandom = false;
public HashSet<String> mAllowedAppsVpn = new HashSet<>();
public boolean mAllowedAppsVpnAreDisallowed = true;
-
public String mCrlFilename;
public String mProfileCreator;
-
+ public String mExternalAuthenticator;
public int mAuthRetry = AUTH_RETRY_NONE_FORGET;
public int mTunMtu;
-
-
public boolean mPushPeerInfo = false;
- public static final boolean mIsOpenVPN22 = false;
-
public int mVersion = 0;
-
// timestamp when the profile was last used
public long mLastUsed;
-
+ public String importedProfileHash;
/* Options no longer used in new profiles */
public String mServerName = "openvpn.example.com";
public String mServerPort = "1194";
public boolean mUseUdp = true;
+ public boolean mTemporaryProfile = false;
+ private transient PrivateKey mPrivateKey;
+ // Public attributes, since I got mad with getter/setter
+ // set members to default values
+ private UUID mUuid;
+ private int mProfileVersion;
public VpnProfile(String name) {
@@ -200,6 +192,48 @@ public class VpnProfile implements Serializable, Cloneable {
return '"' + escapedString + '"';
}
+ public static boolean doUseOpenVPN3(Context c) {
+ SharedPreferences prefs = Preferences.getDefaultSharedPreferences(c);
+ boolean useOpenVPN3 = prefs.getBoolean("ovpn3", false);
+ if (!BuildConfig.openvpn3)
+ useOpenVPN3 = false;
+ return useOpenVPN3;
+ }
+
+ //! Put inline data inline and other data as normal escaped filename
+ public static String insertFileData(String cfgentry, String filedata) {
+ if (filedata == null) {
+ return String.format("%s %s\n", cfgentry, "file missing in config profile");
+ } else if (isEmbedded(filedata)) {
+ String dataWithOutHeader = getEmbeddedContent(filedata);
+ return String.format(Locale.ENGLISH, "<%s>\n%s\n</%s>\n", cfgentry, dataWithOutHeader, cfgentry);
+ } else {
+ return String.format(Locale.ENGLISH, "%s %s\n", cfgentry, openVpnEscape(filedata));
+ }
+ }
+
+ public static String getDisplayName(String embeddedFile) {
+ int start = DISPLAYNAME_TAG.length();
+ int end = embeddedFile.indexOf(INLINE_TAG);
+ return embeddedFile.substring(start, end);
+ }
+
+ public static String getEmbeddedContent(String data) {
+ if (!data.contains(INLINE_TAG))
+ return data;
+
+ int start = data.indexOf(INLINE_TAG) + INLINE_TAG.length();
+ return data.substring(start);
+ }
+
+ public static boolean isEmbedded(String data) {
+ if (data == null)
+ return false;
+ if (data.startsWith(INLINE_TAG) || data.startsWith(DISPLAYNAME_TAG))
+ return true;
+ else
+ return false;
+ }
@Override
public boolean equals(Object obj) {
@@ -223,6 +257,7 @@ public class VpnProfile implements Serializable, Cloneable {
mAllowLocalLAN = true;
mPushPeerInfo = false;
mMssFix = 0;
+ mNobind = false;
}
public UUID getUUID() {
@@ -230,6 +265,11 @@ public class VpnProfile implements Serializable, Cloneable {
}
+ // Only used for the special case of managed profiles
+ public void setUUID(UUID uuid) {
+ mUuid = uuid;
+ }
+
public String getName() {
if (TextUtils.isEmpty(mName))
return "No profile name";
@@ -248,6 +288,7 @@ public class VpnProfile implements Serializable, Cloneable {
}
if (mAllowedAppsVpn == null)
mAllowedAppsVpn = new HashSet<>();
+
if (mConnections == null)
mConnections = new Connection[0];
@@ -255,7 +296,11 @@ public class VpnProfile implements Serializable, Cloneable {
if (TextUtils.isEmpty(mProfileCreator))
mUserEditable = true;
}
-
+ if (mProfileVersion < 7) {
+ for (Connection c : mConnections)
+ if (c.mProxyType == null)
+ c.mProxyType = Connection.ProxyType.NONE;
+ }
mProfileVersion = CURRENT_PROFILE_VERSION;
@@ -274,68 +319,61 @@ public class VpnProfile implements Serializable, Cloneable {
}
-
- public static boolean doUseOpenVPN3(Context c) {
- SharedPreferences prefs = Preferences.getDefaultSharedPreferences(c);
- boolean useOpenVPN3 = prefs.getBoolean("ovpn3", false);
- if (!BuildConfig.openvpn3)
- useOpenVPN3 = false;
- return useOpenVPN3;
- }
-
public String getConfigFile(Context context, boolean configForOvpn3) {
File cacheDir = context.getCacheDir();
- String cfg = "";
+ StringBuilder cfg = new StringBuilder();
if (!configForOvpn3) {
// Enable management interface
- cfg += "# Config for OpenVPN 2.x\n";
- cfg += "# Enables connection to GUI\n";
- cfg += "management ";
+ cfg.append("# Config for OpenVPN 2.x\n");
+ cfg.append("# Enables connection to GUI\n");
+ cfg.append("management ");
- cfg += cacheDir.getAbsolutePath() + "/" + "mgmtsocket";
- cfg += " unix\n";
- cfg += "management-client\n";
+ cfg.append(cacheDir.getAbsolutePath()).append("/").append("mgmtsocket");
+ cfg.append(" unix\n");
+ cfg.append("management-client\n");
// Not needed, see updated man page in 2.3
//cfg += "management-signal\n";
- cfg += "management-query-passwords\n";
- cfg += "management-hold\n\n";
+ cfg.append("management-query-passwords\n");
+ cfg.append("management-hold\n\n");
- cfg += String.format("setenv IV_GUI_VER %s \n", openVpnEscape(getVersionEnvString(context)));
+ cfg.append(String.format("setenv IV_GUI_VER %s \n", openVpnEscape(getVersionEnvString(context))));
String versionString = getPlatformVersionEnvString();
- cfg += String.format("setenv IV_PLAT_VER %s\n", openVpnEscape(versionString));
+ cfg.append(String.format("setenv IV_PLAT_VER %s\n", openVpnEscape(versionString)));
} else {
- cfg += "# Config for OpeNVPN 3 C++\n";
+ cfg.append("# Config for OpenVPN 3 C++\n");
}
- cfg += "machine-readable-output\n";
- cfg += "allow-recursive-routing\n";
-
- // Users are confused by warnings that are misleading...
- cfg += "ifconfig-nowarn\n";
+ if (!configForOvpn3) {
+ cfg.append("machine-readable-output\n");
+ if (!mIsOpenVPN22)
+ cfg.append("allow-recursive-routing\n");
+ // Users are confused by warnings that are misleading...
+ cfg.append("ifconfig-nowarn\n");
+ }
boolean useTLSClient = (mAuthenticationType != TYPE_STATICKEYS);
if (useTLSClient && mUsePull)
- cfg += "client\n";
+ cfg.append("client\n");
else if (mUsePull)
- cfg += "pull\n";
+ cfg.append("pull\n");
else if (useTLSClient)
- cfg += "tls-client\n";
+ cfg.append("tls-client\n");
//cfg += "verb " + mVerb + "\n";
- cfg += "verb " + MAXLOGLEVEL + "\n";
+ cfg.append("verb " + MAXLOGLEVEL + "\n");
if (mConnectRetryMax == null) {
mConnectRetryMax = "-1";
}
if (!mConnectRetryMax.equals("-1"))
- cfg += "connect-retry-max " + mConnectRetryMax + "\n";
+ cfg.append("connect-retry-max ").append(mConnectRetryMax).append("\n");
if (TextUtils.isEmpty(mConnectRetry))
mConnectRetry = "2";
@@ -345,34 +383,34 @@ public class VpnProfile implements Serializable, Cloneable {
if (!mIsOpenVPN22)
- cfg += "connect-retry " + mConnectRetry + " " + mConnectRetryMaxTime + "\n";
- else if (mIsOpenVPN22 && mUseUdp)
- cfg += "connect-retry " + mConnectRetry + "\n";
+ cfg.append("connect-retry ").append(mConnectRetry).append(" ").append(mConnectRetryMaxTime).append("\n");
+ else if (mIsOpenVPN22 && !mUseUdp)
+ cfg.append("connect-retry ").append(mConnectRetry).append("\n");
- cfg += "resolv-retry 60\n";
+ cfg.append("resolv-retry 60\n");
// We cannot use anything else than tun
- cfg += "dev tun\n";
+ cfg.append("dev tun\n");
boolean canUsePlainRemotes = true;
if (mConnections.length == 1) {
- cfg += mConnections[0].getConnectionBlock();
+ cfg.append(mConnections[0].getConnectionBlock(configForOvpn3));
} else {
for (Connection conn : mConnections) {
canUsePlainRemotes = canUsePlainRemotes && conn.isOnlyRemote();
}
if (mRemoteRandom)
- cfg += "remote-random\n";
+ cfg.append("remote-random\n");
if (canUsePlainRemotes) {
for (Connection conn : mConnections) {
if (conn.mEnabled) {
- cfg += conn.getConnectionBlock();
+ cfg.append(conn.getConnectionBlock(configForOvpn3));
}
}
}
@@ -381,91 +419,101 @@ public class VpnProfile implements Serializable, Cloneable {
switch (mAuthenticationType) {
case VpnProfile.TYPE_USERPASS_CERTIFICATES:
- cfg += "auth-user-pass\n";
+ cfg.append("auth-user-pass\n");
case VpnProfile.TYPE_CERTIFICATES:
// Ca
- cfg += insertFileData("ca", mCaFilename);
+ cfg.append(insertFileData("ca", mCaFilename));
// Client Cert + Key
- cfg += insertFileData("key", mClientKeyFilename);
- cfg += insertFileData("cert", mClientCertFilename);
+ cfg.append(insertFileData("key", mClientKeyFilename));
+ cfg.append(insertFileData("cert", mClientCertFilename));
break;
case VpnProfile.TYPE_USERPASS_PKCS12:
- cfg += "auth-user-pass\n";
+ cfg.append("auth-user-pass\n");
case VpnProfile.TYPE_PKCS12:
- cfg += insertFileData("pkcs12", mPKCS12Filename);
+ cfg.append(insertFileData("pkcs12", mPKCS12Filename));
+
+ if (!TextUtils.isEmpty(mCaFilename))
+ {
+ cfg.append(insertFileData("ca", mCaFilename));
+ }
break;
case VpnProfile.TYPE_USERPASS_KEYSTORE:
- cfg += "auth-user-pass\n";
+ cfg.append("auth-user-pass\n");
case VpnProfile.TYPE_KEYSTORE:
+ case VpnProfile.TYPE_EXTERNAL_APP:
if (!configForOvpn3) {
- String[] ks = getKeyStoreCertificates(context);
- cfg += "### From Keystore ####\n";
+ String[] ks = getExternalCertificates(context);
+ cfg.append("### From Keystore/ext auth app ####\n");
if (ks != null) {
- cfg += "<ca>\n" + ks[0] + "\n</ca>\n";
- if (ks[1] != null)
- cfg += "<extra-certs>\n" + ks[1] + "\n</extra-certs>\n";
- cfg += "<cert>\n" + ks[2] + "\n</cert>\n";
- cfg += "management-external-key\n";
+ cfg.append("<ca>\n").append(ks[0]).append("\n</ca>\n");
+ if (!TextUtils.isEmpty(ks[1]))
+ cfg.append("<extra-certs>\n").append(ks[1]).append("\n</extra-certs>\n");
+ cfg.append("<cert>\n").append(ks[2]).append("\n</cert>\n");
+ cfg.append("management-external-key nopadding\n");
} else {
- cfg += context.getString(R.string.keychain_access) + "\n";
+ cfg.append(context.getString(R.string.keychain_access)).append("\n");
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.JELLY_BEAN)
if (!mAlias.matches("^[a-zA-Z0-9]$"))
- cfg += context.getString(R.string.jelly_keystore_alphanumeric_bug) + "\n";
+ cfg.append(context.getString(R.string.jelly_keystore_alphanumeric_bug)).append("\n");
}
}
break;
case VpnProfile.TYPE_USERPASS:
- cfg += "auth-user-pass\n";
- cfg += insertFileData("ca", mCaFilename);
+ cfg.append("auth-user-pass\n");
+ cfg.append(insertFileData("ca", mCaFilename));
+ if (configForOvpn3) {
+ // OpenVPN 3 needs to be told that a client certificate is not required
+ cfg.append("client-cert-not-required\n");
+ }
}
if (isUserPWAuth()) {
- if (mAuthenticationType == AUTH_RETRY_NOINTERACT)
- cfg += "auth-retry nointeract";
+ if (mAuthRetry == AUTH_RETRY_NOINTERACT)
+ cfg.append("auth-retry nointeract\n");
}
if (!TextUtils.isEmpty(mCrlFilename))
- cfg += insertFileData("crl-verify", mCrlFilename);
+ cfg.append(insertFileData("crl-verify", mCrlFilename));
if (mUseLzo) {
- cfg += "comp-lzo\n";
+ cfg.append("comp-lzo\n");
}
if (mUseTLSAuth) {
boolean useTlsCrypt = mTLSAuthDirection.equals("tls-crypt");
if (mAuthenticationType == TYPE_STATICKEYS)
- cfg += insertFileData("secret", mTLSAuthFilename);
+ cfg.append(insertFileData("secret", mTLSAuthFilename));
else if (useTlsCrypt)
- cfg += insertFileData("tls-crypt", mTLSAuthFilename);
+ cfg.append(insertFileData("tls-crypt", mTLSAuthFilename));
else
- cfg += insertFileData("tls-auth", mTLSAuthFilename);
+ cfg.append(insertFileData("tls-auth", mTLSAuthFilename));
if (!TextUtils.isEmpty(mTLSAuthDirection) && !useTlsCrypt) {
- cfg += "key-direction ";
- cfg += mTLSAuthDirection;
- cfg += "\n";
+ cfg.append("key-direction ");
+ cfg.append(mTLSAuthDirection);
+ cfg.append("\n");
}
}
if (!mUsePull) {
if (!TextUtils.isEmpty(mIPv4Address))
- cfg += "ifconfig " + cidrToIPAndNetmask(mIPv4Address) + "\n";
+ cfg.append("ifconfig ").append(cidrToIPAndNetmask(mIPv4Address)).append("\n");
if (!TextUtils.isEmpty(mIPv6Address)) {
// Use our own ip as gateway since we ignore it anyway
String fakegw = mIPv6Address.split("/", 2)[0];
- cfg += "ifconfig-ipv6 " + mIPv6Address + " " + fakegw + "\n";
+ cfg.append("ifconfig-ipv6 ").append(mIPv6Address).append(" ").append(fakegw).append("\n");
}
}
if (mUsePull && mRoutenopull)
- cfg += "route-nopull\n";
+ cfg.append("route-nopull\n");
String routes = "";
@@ -483,128 +531,129 @@ public class VpnProfile implements Serializable, Cloneable {
if (mUseDefaultRoutev6)
- cfg += "route-ipv6 ::/0\n";
+ cfg.append("route-ipv6 ::/0\n");
else
for (String route : getCustomRoutesv6(mCustomRoutesv6)) {
routes += "route-ipv6 " + route + "\n";
}
- cfg += routes;
+ cfg.append(routes);
if (mOverrideDNS || !mUsePull) {
if (!TextUtils.isEmpty(mDNS1)) {
- cfg += "dhcp-option DNS " + mDNS1 + "\n";
+ cfg.append("dhcp-option DNS ").append(mDNS1).append("\n");
}
if (!TextUtils.isEmpty(mDNS2)) {
- cfg += "dhcp-option DNS " + mDNS2 + "\n";
+ cfg.append("dhcp-option DNS ").append(mDNS2).append("\n");
}
if (!TextUtils.isEmpty(mSearchDomain))
- cfg += "dhcp-option DOMAIN " + mSearchDomain + "\n";
+ cfg.append("dhcp-option DOMAIN ").append(mSearchDomain).append("\n");
}
if (mMssFix != 0) {
if (mMssFix != 1450) {
- cfg += String.format(Locale.US, "mssfix %d\n", mMssFix);
+ cfg.append(String.format(Locale.US, "mssfix %d\n", mMssFix));
} else
- cfg += "mssfix\n";
+ cfg.append("mssfix\n");
}
if (mTunMtu >= 48 && mTunMtu != 1500) {
- cfg += String.format(Locale.US, "tun-mtu %d\n", mTunMtu);
+ cfg.append(String.format(Locale.US, "tun-mtu %d\n", mTunMtu));
}
if (mNobind)
- cfg += "nobind\n";
+ cfg.append("nobind\n");
// Authentication
if (mAuthenticationType != TYPE_STATICKEYS) {
if (mCheckRemoteCN) {
if (mRemoteCN == null || mRemoteCN.equals(""))
- cfg += "verify-x509-name " + openVpnEscape(mConnections[0].mServerName) + " name\n";
+ cfg.append("verify-x509-name ").append(openVpnEscape(mConnections[0].mServerName)).append(" name\n");
else
switch (mX509AuthType) {
// 2.2 style x509 checks
case X509_VERIFY_TLSREMOTE_COMPAT_NOREMAPPING:
- cfg += "compat-names no-remapping\n";
+ cfg.append("compat-names no-remapping\n");
case X509_VERIFY_TLSREMOTE:
- cfg += "tls-remote " + openVpnEscape(mRemoteCN) + "\n";
+ cfg.append("tls-remote ").append(openVpnEscape(mRemoteCN)).append("\n");
break;
case X509_VERIFY_TLSREMOTE_RDN:
- cfg += "verify-x509-name " + openVpnEscape(mRemoteCN) + " name\n";
+ cfg.append("verify-x509-name ").append(openVpnEscape(mRemoteCN)).append(" name\n");
break;
case X509_VERIFY_TLSREMOTE_RDN_PREFIX:
- cfg += "verify-x509-name " + openVpnEscape(mRemoteCN) + " name-prefix\n";
+ cfg.append("verify-x509-name ").append(openVpnEscape(mRemoteCN)).append(" name-prefix\n");
break;
case X509_VERIFY_TLSREMOTE_DN:
- cfg += "verify-x509-name " + openVpnEscape(mRemoteCN) + "\n";
+ cfg.append("verify-x509-name ").append(openVpnEscape(mRemoteCN)).append("\n");
break;
}
if (!TextUtils.isEmpty(mx509UsernameField))
- cfg += "x509-username-field " + openVpnEscape(mx509UsernameField) + "\n";
+ cfg.append("x509-username-field ").append(openVpnEscape(mx509UsernameField)).append("\n");
}
if (mExpectTLSCert)
- cfg += "remote-cert-tls server\n";
+ cfg.append("remote-cert-tls server\n");
}
if (!TextUtils.isEmpty(mCipher)) {
- cfg += "cipher " + mCipher + "\n";
+ cfg.append("cipher ").append(mCipher).append("\n");
}
if (!TextUtils.isEmpty(mAuth)) {
- cfg += "auth " + mAuth + "\n";
+ cfg.append("auth ").append(mAuth).append("\n");
}
// Obscure Settings dialog
if (mUseRandomHostname)
- cfg += "#my favorite options :)\nremote-random-hostname\n";
+ cfg.append("#my favorite options :)\nremote-random-hostname\n");
if (mUseFloat)
- cfg += "float\n";
+ cfg.append("float\n");
if (mPersistTun) {
- cfg += "persist-tun\n";
- cfg += "# persist-tun also enables pre resolving to avoid DNS resolve problem\n";
- cfg += "preresolve\n";
+ cfg.append("persist-tun\n");
+ cfg.append("# persist-tun also enables pre resolving to avoid DNS resolve problem\n");
+ if (!mIsOpenVPN22)
+ cfg.append("preresolve\n");
}
if (mPushPeerInfo)
- cfg += "push-peer-info\n";
+ cfg.append("push-peer-info\n");
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
boolean usesystemproxy = prefs.getBoolean("usesystemproxy", true);
- if (usesystemproxy && !mIsOpenVPN22 && !configForOvpn3) {
- cfg += "# Use system proxy setting\n";
- cfg += "management-query-proxy\n";
+ if (usesystemproxy && !mIsOpenVPN22 && !configForOvpn3 && !usesExtraProxyOptions()) {
+ cfg.append("# Use system proxy setting\n");
+ cfg.append("management-query-proxy\n");
}
if (mUseCustomConfig) {
- cfg += "# Custom configuration options\n";
- cfg += "# You are on your on own here :)\n";
- cfg += mCustomConfigOptions;
- cfg += "\n";
+ cfg.append("# Custom configuration options\n");
+ cfg.append("# You are on your on own here :)\n");
+ cfg.append(mCustomConfigOptions);
+ cfg.append("\n");
}
if (!canUsePlainRemotes) {
- cfg += "# Connection Options are at the end to allow global options (and global custom options) to influence connection blocks\n";
+ cfg.append("# Connection Options are at the end to allow global options (and global custom options) to influence connection blocks\n");
for (Connection conn : mConnections) {
if (conn.mEnabled) {
- cfg += "<connection>\n";
- cfg += conn.getConnectionBlock();
- cfg += "</connection>\n";
+ cfg.append("<connection>\n");
+ cfg.append(conn.getConnectionBlock(configForOvpn3));
+ cfg.append("</connection>\n");
}
}
}
- return cfg;
+ return cfg.toString();
}
public String getPlatformVersionEnvString() {
@@ -624,18 +673,6 @@ public class VpnProfile implements Serializable, Cloneable {
}
- //! Put inline data inline and other data as normal escaped filename
- public static String insertFileData(String cfgentry, String filedata) {
- if (filedata == null) {
- return String.format("%s %s\n", cfgentry, "file missing in config profile");
- } else if (isEmbedded(filedata)) {
- String dataWithOutHeader = getEmbeddedContent(filedata);
- return String.format(Locale.ENGLISH, "<%s>\n%s\n</%s>\n", cfgentry, dataWithOutHeader, cfgentry);
- } else {
- return String.format(Locale.ENGLISH, "%s %s\n", cfgentry, openVpnEscape(filedata));
- }
- }
-
@NonNull
private Collection<String> getCustomRoutes(String routes) {
Vector<String> cidrRoutes = new Vector<>();
@@ -697,7 +734,6 @@ public class VpnProfile implements Serializable, Cloneable {
return parts[0] + " " + netmask;
}
-
public Intent prepareStartService(Context context) {
Intent intent = getStartServiceIntent(context);
@@ -727,33 +763,6 @@ public class VpnProfile implements Serializable, Cloneable {
return intent;
}
- public String[] getKeyStoreCertificates(Context context) {
- return getKeyStoreCertificates(context, 5);
- }
-
- public static String getDisplayName(String embeddedFile) {
- int start = DISPLAYNAME_TAG.length();
- int end = embeddedFile.indexOf(INLINE_TAG);
- return embeddedFile.substring(start, end);
- }
-
- public static String getEmbeddedContent(String data) {
- if (!data.contains(INLINE_TAG))
- return data;
-
- int start = data.indexOf(INLINE_TAG) + INLINE_TAG.length();
- return data.substring(start);
- }
-
- public static boolean isEmbedded(String data) {
- if (data == null)
- return false;
- if (data.startsWith(INLINE_TAG) || data.startsWith(DISPLAYNAME_TAG))
- return true;
- else
- return false;
- }
-
public void checkForRestart(final Context context) {
/* This method is called when OpenVPNService is restarted */
@@ -762,7 +771,7 @@ public class VpnProfile implements Serializable, Cloneable {
new Thread(new Runnable() {
@Override
public void run() {
- getKeyStoreCertificates(context);
+ getExternalCertificates(context);
}
}).start();
@@ -798,26 +807,40 @@ public class VpnProfile implements Serializable, Cloneable {
}
+ private X509Certificate[] getKeyStoreCertificates(Context context) throws KeyChainException, InterruptedException {
+ PrivateKey privateKey = KeyChain.getPrivateKey(context, mAlias);
+ mPrivateKey = privateKey;
- class NoCertReturnedException extends Exception {
- public NoCertReturnedException(String msg) {
- super(msg);
- }
+
+ X509Certificate[] caChain = KeyChain.getCertificateChain(context, mAlias);
+ return caChain;
+ }
+
+ private X509Certificate[] getExtAppCertificates(Context context) throws KeyChainException {
+ if (mExternalAuthenticator == null || mAlias == null)
+ throw new KeyChainException("Alias or external auth provider name not set");
+ return ExtAuthHelper.getCertificateChain(context, mExternalAuthenticator, mAlias);
+ }
+
+ public String[] getExternalCertificates(Context context) {
+ return getExternalCertificates(context, 5);
}
- synchronized String[] getKeyStoreCertificates(Context context, int tries) {
+
+ synchronized String[] getExternalCertificates(Context context, int tries) {
// Force application context- KeyChain methods will block long enough that by the time they
// are finished and try to unbind, the original activity context might have been destroyed.
context = context.getApplicationContext();
try {
- PrivateKey privateKey = KeyChain.getPrivateKey(context, mAlias);
- mPrivateKey = privateKey;
-
String keystoreChain = null;
-
- X509Certificate[] caChain = KeyChain.getCertificateChain(context, mAlias);
+ X509Certificate caChain[];
+ if (mAuthenticationType == TYPE_EXTERNAL_APP) {
+ caChain = getExtAppCertificates(context);
+ } else {
+ caChain = getKeyStoreCertificates(context);
+ }
if (caChain == null)
throw new NoCertReturnedException("No certificate returned from Keystore");
@@ -900,14 +923,18 @@ public class VpnProfile implements Serializable, Cloneable {
} catch (InterruptedException e1) {
VpnStatus.logException(e1);
}
- return getKeyStoreCertificates(context, tries - 1);
+ return getExternalCertificates(context, tries - 1);
}
}
+ public int checkProfile(Context c) {
+ return checkProfile(c, doUseOpenVPN3(c));
+ }
+
//! Return an error if something is wrong
- public int checkProfile(Context context) {
- if (mAuthenticationType == TYPE_KEYSTORE || mAuthenticationType == TYPE_USERPASS_KEYSTORE) {
+ public int checkProfile(Context context, boolean useOpenVPN3) {
+ if (mAuthenticationType == TYPE_KEYSTORE || mAuthenticationType == TYPE_USERPASS_KEYSTORE || mAuthenticationType == TYPE_EXTERNAL_APP) {
if (mAlias == null)
return R.string.no_keystore_cert_selected;
} else if (mAuthenticationType == TYPE_CERTIFICATES || mAuthenticationType == TYPE_USERPASS_CERTIFICATES) {
@@ -944,21 +971,35 @@ public class VpnProfile implements Serializable, Cloneable {
boolean noRemoteEnabled = true;
- for (Connection c : mConnections)
+ for (Connection c : mConnections) {
if (c.mEnabled)
noRemoteEnabled = false;
+ }
if (noRemoteEnabled)
return R.string.remote_no_server_selected;
- if (doUseOpenVPN3(context)) {
+ if (useOpenVPN3) {
if (mAuthenticationType == TYPE_STATICKEYS) {
return R.string.openvpn3_nostatickeys;
}
if (mAuthenticationType == TYPE_PKCS12 || mAuthenticationType == TYPE_USERPASS_PKCS12) {
return R.string.openvpn3_pkcs12;
}
+ for (Connection conn : mConnections) {
+ if (conn.mProxyType == Connection.ProxyType.ORBOT || conn.mProxyType == Connection.ProxyType.SOCKS5)
+ return R.string.openvpn3_socksproxy;
+ }
}
+ for (Connection c : mConnections) {
+ if (c.mProxyType == Connection.ProxyType.ORBOT) {
+ if (usesExtraProxyOptions())
+ return R.string.error_orbot_and_proxy_options;
+ if (!OrbotHelper.checkTorReceier(context))
+ return R.string.no_orbotfound;
+ }
+ }
+
// Everything okay
return R.string.no_error_found;
@@ -1073,18 +1114,42 @@ public class VpnProfile implements Serializable, Cloneable {
}
public String getUUIDString() {
- return mUuid.toString();
+ return mUuid.toString().toLowerCase(Locale.ENGLISH);
}
public PrivateKey getKeystoreKey() {
return mPrivateKey;
}
- public String getSignedData(String b64data) {
- PrivateKey privkey = getKeystoreKey();
-
+ @Nullable
+ public String getSignedData(Context c, String b64data, boolean pkcs1padding) {
byte[] data = Base64.decode(b64data, Base64.DEFAULT);
+ byte[] signed_bytes;
+ if (mAuthenticationType == TYPE_EXTERNAL_APP)
+ signed_bytes = getExtAppSignedData(c, data);
+ else
+ signed_bytes = getKeyChainSignedData(data, pkcs1padding);
+ if (signed_bytes != null)
+ return Base64.encodeToString(signed_bytes, Base64.NO_WRAP);
+ else
+ return null;
+ }
+
+ private byte[] getExtAppSignedData(Context c, byte[] data) {
+ if (TextUtils.isEmpty(mExternalAuthenticator))
+ return null;
+ try {
+ return ExtAuthHelper.signData(c, mExternalAuthenticator, mAlias, data);
+ } catch (KeyChainException | InterruptedException e) {
+ VpnStatus.logError(R.string.error_extapp_sign, mExternalAuthenticator, e.getClass().toString(), e.getLocalizedMessage());
+ return null;
+ }
+ }
+
+ private byte[] getKeyChainSignedData(byte[] data, boolean pkcs1padding) {
+
+ PrivateKey privkey = getKeystoreKey();
// The Jelly Bean *evil* Hack
// 4.2 implements the RSA/ECB/PKCS1PADDING in the OpenSSLprovider
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.JELLY_BEAN) {
@@ -1109,15 +1174,17 @@ public class VpnProfile implements Serializable, Cloneable {
the public/private part in the TLS exchange
*/
Cipher signer;
- signer = Cipher.getInstance("RSA/ECB/PKCS1PADDING");
+ if (pkcs1padding)
+ signer = Cipher.getInstance("RSA/ECB/PKCS1PADDING");
+ else
+ signer = Cipher.getInstance("RSA/ECB/NoPadding");
signer.init(Cipher.ENCRYPT_MODE, privkey);
signed_bytes = signer.doFinal(data);
}
- return Base64.encodeToString(signed_bytes, Base64.NO_WRAP);
-
+ return signed_bytes;
} catch (NoSuchAlgorithmException | InvalidKeyException | IllegalBlockSizeException
| BadPaddingException | NoSuchPaddingException | SignatureException e) {
VpnStatus.logError(R.string.error_rsa_sign, e.getClass().toString(), e.getLocalizedMessage());
@@ -1125,7 +1192,7 @@ public class VpnProfile implements Serializable, Cloneable {
}
}
- private String processSignJellyBeans(PrivateKey privkey, byte[] data) {
+ private byte[] processSignJellyBeans(PrivateKey privkey, byte[] data) {
try {
Method getKey = privkey.getClass().getSuperclass().getDeclaredMethod("getOpenSSLKey");
getKey.setAccessible(true);
@@ -1143,8 +1210,7 @@ public class VpnProfile implements Serializable, Cloneable {
getPkeyContext.setAccessible(false);
// 112 with TLS 1.2 (172 back with 4.3), 36 with TLS 1.0
- byte[] signed_bytes = NativeUtils.rsasign(data, pkey);
- return Base64.encodeToString(signed_bytes, Base64.NO_WRAP);
+ return NativeUtils.rsasign(data, pkey);
} catch (NoSuchMethodException | InvalidKeyException | InvocationTargetException | IllegalAccessException | IllegalArgumentException e) {
VpnStatus.logError(R.string.error_rsa_sign, e.getClass().toString(), e.getLocalizedMessage());
@@ -1152,6 +1218,22 @@ public class VpnProfile implements Serializable, Cloneable {
}
}
+ private boolean usesExtraProxyOptions() {
+ if (mUseCustomConfig && mCustomConfigOptions != null && mCustomConfigOptions.contains("http-proxy-option "))
+ return true;
+ for (Connection c : mConnections)
+ if (c.usesExtraProxyOptions())
+ return true;
+
+ return false;
+ }
+
+ class NoCertReturnedException extends Exception {
+ public NoCertReturnedException(String msg) {
+ super(msg);
+ }
+ }
+
}
diff --git a/app/src/main/java/de/blinkt/openvpn/core/CIDRIP.java b/app/src/main/java/de/blinkt/openvpn/core/CIDRIP.java
index 799c68c9..ca3d1161 100644
--- a/app/src/main/java/de/blinkt/openvpn/core/CIDRIP.java
+++ b/app/src/main/java/de/blinkt/openvpn/core/CIDRIP.java
@@ -14,6 +14,11 @@ class CIDRIP {
public CIDRIP(String ip, String mask) {
mIp = ip;
+ len = calculateLenFromMask(mask);
+
+ }
+
+ public static int calculateLenFromMask(String mask) {
long netmask = getInt(mask);
// Add 33. bit to ensure the loop terminates
@@ -24,6 +29,7 @@ class CIDRIP {
lenZeros++;
netmask = netmask >> 1;
}
+ int len;
// Check if rest of netmask is only 1s
if (netmask != (0x1ffffffffl >> lenZeros)) {
// Asume no CIDR, set /32
@@ -31,7 +37,7 @@ class CIDRIP {
} else {
len = 32 - lenZeros;
}
-
+ return len;
}
public CIDRIP(String address, int prefix_length) {
diff --git a/app/src/main/java/de/blinkt/openvpn/core/ConfigParser.java b/app/src/main/java/de/blinkt/openvpn/core/ConfigParser.java
index 9889754d..0148bfb7 100644
--- a/app/src/main/java/de/blinkt/openvpn/core/ConfigParser.java
+++ b/app/src/main/java/de/blinkt/openvpn/core/ConfigParser.java
@@ -5,17 +5,15 @@
package de.blinkt.openvpn.core;
-import android.text.TextUtils;
+import android.os.Build;
import android.support.v4.util.Pair;
+import android.text.TextUtils;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Locale;
-import java.util.Vector;
+import java.util.*;
import de.blinkt.openvpn.VpnProfile;
@@ -29,10 +27,127 @@ public class ConfigParser {
public static final String CONVERTED_PROFILE = "converted Profile";
- private HashMap<String, Vector<Vector<String>>> options = new HashMap<String, Vector<Vector<String>>>();
+ final String[] unsupportedOptions = {"config",
+ "tls-server"
+
+ };
+ // Ignore all scripts
+ // in most cases these won't work and user who wish to execute scripts will
+ // figure out themselves
+ private final String[] ignoreOptions = {"tls-client",
+ "allow-recursive-routing",
+ "askpass",
+ "auth-nocache",
+ "up",
+ "down",
+ "route-up",
+ "ipchange",
+ "route-pre-down",
+ "auth-user-pass-verify",
+ "block-outside-dns",
+ "client-cert-not-required",
+ "dhcp-release",
+ "dhcp-renew",
+ "dh",
+ "group",
+ "ip-win32",
+ "ifconfig-nowarn",
+ "management-hold",
+ "management",
+ "management-client",
+ "management-query-remote",
+ "management-query-passwords",
+ "management-query-proxy",
+ "management-external-key",
+ "management-forget-disconnect",
+ "management-signal",
+ "management-log-cache",
+ "management-up-down",
+ "management-client-user",
+ "management-client-group",
+ "pause-exit",
+ "preresolve",
+ "plugin",
+ "machine-readable-output",
+ "persist-key",
+ "push",
+ "register-dns",
+ "route-delay",
+ "route-gateway",
+ "route-metric",
+ "route-method",
+ "status",
+ "script-security",
+ "show-net-up",
+ "suppress-timestamps",
+ "tap-sleep",
+ "tmp-dir",
+ "tun-ipv6",
+ "topology",
+ "user",
+ "win-sys",
+ };
+ private final String[][] ignoreOptionsWithArg =
+ {
+ {"setenv", "IV_GUI_VER"},
+ {"setenv", "IV_PLAT_VER"},
+ {"setenv", "IV_OPENVPN_GUI_VERSION"},
+ {"engine", "dynamic"},
+ {"setenv", "CLIENT_CERT"},
+ {"resolv-retry", "60"}
+ };
+ private final String[] connectionOptions = {
+ "local",
+ "remote",
+ "float",
+ "port",
+ "connect-retry",
+ "connect-timeout",
+ "connect-retry-max",
+ "link-mtu",
+ "tun-mtu",
+ "tun-mtu-extra",
+ "fragment",
+ "mtu-disc",
+ "local-port",
+ "remote-port",
+ "bind",
+ "nobind",
+ "proto",
+ "http-proxy",
+ "http-proxy-retry",
+ "http-proxy-timeout",
+ "http-proxy-option",
+ "socks-proxy",
+ "socks-proxy-retry",
+ "http-proxy-user-pass",
+ "explicit-exit-notify",
+ };
+ private HashSet<String> connectionOptionsSet = new HashSet<>(Arrays.asList(connectionOptions));
+
+ private HashMap<String, Vector<Vector<String>>> options = new HashMap<>();
private HashMap<String, Vector<String>> meta = new HashMap<String, Vector<String>>();
private String auth_user_pass_file;
+ static public void useEmbbedUserAuth(VpnProfile np, String inlinedata) {
+ String data = VpnProfile.getEmbeddedContent(inlinedata);
+ String[] parts = data.split("\n");
+ if (parts.length >= 2) {
+ np.mUsername = parts[0];
+ np.mPassword = parts[1];
+ }
+ }
+
+ static public void useEmbbedHttpAuth(Connection c, String inlinedata) {
+ String data = VpnProfile.getEmbeddedContent(inlinedata);
+ String[] parts = data.split("\n");
+ if (parts.length >= 2) {
+ c.mProxyAuthUser = parts[0];
+ c.mProxyAuthPassword = parts[1];
+ c.mUseProxyAuth = true;
+ }
+ }
+
public void parseConfig(Reader reader) throws IOException, ConfigParseError {
HashMap<String, String> optionAliases = new HashMap<>();
@@ -76,7 +191,7 @@ public class ConfigParser {
checkinlinefile(args, br);
String optionname = args.get(0);
- if (optionAliases.get(optionname)!=null)
+ if (optionAliases.get(optionname) != null)
optionname = optionAliases.get(optionname);
if (!options.containsKey(optionname)) {
@@ -119,8 +234,8 @@ public class ConfigParser {
}
} while (true);
- if(inlinefile.endsWith("\n"))
- inlinefile = inlinefile.substring(0, inlinefile.length()-1);
+ if (inlinefile.endsWith("\n"))
+ inlinefile = inlinefile.substring(0, inlinefile.length() - 1);
args.clear();
args.add(argname);
@@ -133,11 +248,6 @@ public class ConfigParser {
return auth_user_pass_file;
}
- enum linestate {
- initial,
- readin_single_quote, reading_quoted, reading_unquoted, done
- }
-
private boolean space(char c) {
// I really hope nobody is using zero bytes inside his/her config file
// to sperate parameter but here we go:
@@ -145,15 +255,6 @@ public class ConfigParser {
}
- public static class ConfigParseError extends Exception {
- private static final long serialVersionUID = -60L;
-
- public ConfigParseError(String msg) {
- super(msg);
- }
- }
-
-
// adapted openvpn's parse function to java
private Vector<String> parseline(String line) throws ConfigParseError {
Vector<String> parameters = new Vector<String>();
@@ -226,7 +327,7 @@ public class ConfigParser {
backslash = false;
}
- /* store parameter character */
+ /* store parameter character */
if (out != 0) {
currentarg += out;
}
@@ -235,105 +336,6 @@ public class ConfigParser {
return parameters;
}
-
- final String[] unsupportedOptions = {"config",
- "tls-server"
-
- };
-
- // Ignore all scripts
- // in most cases these won't work and user who wish to execute scripts will
- // figure out themselves
- final String[] ignoreOptions = {"tls-client",
- "askpass",
- "auth-nocache",
- "up",
- "down",
- "route-up",
- "ipchange",
- "route-up",
- "route-pre-down",
- "auth-user-pass-verify",
- "block-outside-dns",
- "dhcp-release",
- "dhcp-renew",
- "dh",
- "group",
- "allow-recursive-routing",
- "ip-win32",
- "ifconfig-nowarn",
- "management-hold",
- "management",
- "management-client",
- "management-query-remote",
- "management-query-passwords",
- "management-query-proxy",
- "management-external-key",
- "management-forget-disconnect",
- "management-signal",
- "management-log-cache",
- "management-up-down",
- "management-client-user",
- "management-client-group",
- "pause-exit",
- "preresolve",
- "plugin",
- "machine-readable-output",
- "persist-key",
- "push",
- "register-dns",
- "route-delay",
- "route-gateway",
- "route-metric",
- "route-method",
- "status",
- "script-security",
- "show-net-up",
- "suppress-timestamps",
- "tmp-dir",
- "tun-ipv6",
- "topology",
- "user",
- "win-sys",
- };
-
- final String[][] ignoreOptionsWithArg =
- {
- {"setenv", "IV_GUI_VER"},
- {"setenv", "IV_OPENVPN_GUI_VERSION"},
- {"engine", "dynamic"},
- {"setenv", "CLIENT_CERT"},
- {"resolve-retry","60"}
- };
-
- final String[] connectionOptions = {
- "local",
- "remote",
- "float",
- "port",
- "connect-retry",
- "connect-timeout",
- "connect-retry-max",
- "link-mtu",
- "tun-mtu",
- "tun-mtu-extra",
- "fragment",
- "mtu-disc",
- "local-port",
- "remote-port",
- "bind",
- "nobind",
- "proto",
- "http-proxy",
- "http-proxy-retry",
- "http-proxy-timeout",
- "http-proxy-option",
- "socks-proxy",
- "socks-proxy-retry",
- "explicit-exit-notify",
- };
-
-
// This method is far too long
@SuppressWarnings("ConstantConditions")
public VpnProfile convertProfile() throws ConfigParseError, IOException {
@@ -403,8 +405,8 @@ public class ConfigParser {
}
Vector<String> routeNoPull = getOption("route-nopull", 0, 0);
- if (routeNoPull!=null)
- np.mRoutenopull=true;
+ if (routeNoPull != null)
+ np.mRoutenopull = true;
// Also recognize tls-auth [inline] direction ...
Vector<Vector<String>> tlsauthoptions = getAllOption("tls-auth", 1, 2);
@@ -426,7 +428,7 @@ public class ConfigParser {
np.mTLSAuthDirection = direction.get(1);
Vector<String> tlscrypt = getOption("tls-crypt", 1, 1);
- if (tlscrypt!=null) {
+ if (tlscrypt != null) {
np.mUseTLSAuth = true;
np.mTLSAuthFilename = tlscrypt.get(1);
np.mTLSAuthDirection = "tls-crypt";
@@ -467,7 +469,7 @@ public class ConfigParser {
}
- Vector<String> tunmtu = getOption("mtu", 1, 1);
+ Vector<String> tunmtu = getOption("tun-mtu", 1, 1);
if (tunmtu != null) {
try {
@@ -478,7 +480,6 @@ public class ConfigParser {
}
-
Vector<String> mode = getOption("mode", 1, 1);
if (mode != null) {
if (!mode.get(1).equals("p2p"))
@@ -592,9 +593,9 @@ public class ConfigParser {
}
- Vector<String> x509usernamefield = getOption("x509-username-field", 1,1);
- if (x509usernamefield!=null) {
- np.mx509UsernameField = x509usernamefield.get(1);
+ Vector<String> x509usernamefield = getOption("x509-username-field", 1, 1);
+ if (x509usernamefield != null) {
+ np.mx509UsernameField = x509usernamefield.get(1);
}
@@ -666,7 +667,7 @@ public class ConfigParser {
if (crlfile != null) {
// If the 'dir' parameter is present just add it as custom option ..
if (crlfile.size() == 3 && crlfile.get(2).equals("dir"))
- np.mCustomConfigOptions += TextUtils.join(" ", crlfile) + "\n";
+ np.mCustomConfigOptions += join(" ", crlfile) + "\n";
else
// Save the filename for the config converter to add later
np.mCrlFilename = crlfile.get(1);
@@ -732,6 +733,13 @@ public class ConfigParser {
return np;
}
+ private String join(String s, Vector<String> str) {
+ if (Build.VERSION.SDK_INT > 26)
+ return String.join(s, str);
+ else
+ return TextUtils.join(s, str);
+ }
+
private Pair<Connection, Connection[]> parseConnection(String connection, Connection defaultValues) throws IOException, ConfigParseError {
// Parse a connection Block as a new configuration file
@@ -783,20 +791,48 @@ public class ConfigParser {
}
}
- // Parse remote config
- Vector<Vector<String>> remotes = getAllOption("remote", 1, 3);
+ Vector<String> proxy = getOption("socks-proxy", 1, 2);
+ if (proxy == null)
+ proxy = getOption("http-proxy", 2, 2);
+
+ if (proxy != null) {
+ if (proxy.get(0).equals("socks-proxy")) {
+ conn.mProxyType = Connection.ProxyType.SOCKS5;
+ // socks defaults to 1080, http always sets port
+ conn.mProxyPort = "1080";
+ } else {
+ conn.mProxyType = Connection.ProxyType.HTTP;
+ }
+
+ conn.mProxyName = proxy.get(1);
+ if (proxy.size() >= 3)
+ conn.mProxyPort = proxy.get(2);
+ }
+ Vector<String> httpproxyauthhttp = getOption("http-proxy-user-pass", 1, 1);
+ if (httpproxyauthhttp != null)
+ useEmbbedHttpAuth(conn, httpproxyauthhttp.get(1));
- // Assume that we need custom options if connectionDefault are set
- if (connDefault != null) {
- for (Vector<Vector<String>> option : options.values()) {
- conn.mCustomConfiguration += getOptionStrings(option);
+ // Parse remote config
+ Vector<Vector<String>> remotes = getAllOption("remote", 1, 3);
+
+
+ Vector <String> optionsToRemove = new Vector<>();
+ // Assume that we need custom options if connectionDefault are set or in the connection specific set
+ for (Map.Entry<String, Vector<Vector<String>>> option : options.entrySet()) {
+ if (connDefault != null || connectionOptionsSet.contains(option.getKey())) {
+ conn.mCustomConfiguration += getOptionStrings(option.getValue());
+ optionsToRemove.add(option.getKey());
}
- if (!TextUtils.isEmpty(conn.mCustomConfiguration))
- conn.mUseCustomConfig = true;
}
+ for (String o: optionsToRemove)
+ options.remove(o);
+
+ if (!(conn.mCustomConfiguration == null || "".equals(conn.mCustomConfiguration.trim())))
+ conn.mUseCustomConfig = true;
+
// Make remotes empty to simplify code
if (remotes == null)
remotes = new Vector<Vector<String>>();
@@ -821,6 +857,7 @@ public class ConfigParser {
}
i++;
}
+
return Pair.create(conn, connections);
}
@@ -830,19 +867,19 @@ public class ConfigParser {
boolean noIpv4 = false;
if (defaultRoute)
- for (Vector<String> redirect : defgw)
- for (int i = 1; i < redirect.size(); i++) {
- if (redirect.get(i).equals("block-local"))
- np.mAllowLocalLAN = false;
- else if (redirect.get(i).equals("unblock-local"))
- np.mAllowLocalLAN = true;
- else if (redirect.get(i).equals("!ipv4"))
- noIpv4=true;
- else if (redirect.get(i).equals("ipv6"))
- np.mUseDefaultRoutev6=true;
- }
+ for (Vector<String> redirect : defgw)
+ for (int i = 1; i < redirect.size(); i++) {
+ if (redirect.get(i).equals("block-local"))
+ np.mAllowLocalLAN = false;
+ else if (redirect.get(i).equals("unblock-local"))
+ np.mAllowLocalLAN = true;
+ else if (redirect.get(i).equals("!ipv4"))
+ noIpv4 = true;
+ else if (redirect.get(i).equals("ipv6"))
+ np.mUseDefaultRoutev6 = true;
+ }
if (defaultRoute && !noIpv4)
- np.mUseDefaultRoute=true;
+ np.mUseDefaultRoute = true;
}
private boolean isUdpProto(String proto) throws ConfigParseError {
@@ -861,15 +898,6 @@ public class ConfigParser {
return isudp;
}
- static public void useEmbbedUserAuth(VpnProfile np, String inlinedata) {
- String data = VpnProfile.getEmbeddedContent(inlinedata);
- String[] parts = data.split("\n");
- if (parts.length >= 2) {
- np.mUsername = parts[0];
- np.mPassword = parts[1];
- }
- }
-
private void checkIgnoreAndInvalidOptions(VpnProfile np) throws ConfigParseError {
for (String option : unsupportedOptions)
if (options.containsKey(option))
@@ -880,7 +908,16 @@ public class ConfigParser {
options.remove(option);
- if (options.size() > 0) {
+ boolean customOptions=false;
+ for (Vector<Vector<String>> option: options.values())
+ {
+ for (Vector<String> optionsline : option) {
+ if (!ignoreThisOption(optionsline)) {
+ customOptions = true;
+ }
+ }
+ }
+ if (customOptions) {
np.mCustomConfigOptions = "# These options found in the config file do not map to config settings:\n"
+ np.mCustomConfigOptions;
@@ -894,7 +931,6 @@ public class ConfigParser {
}
}
-
boolean ignoreThisOption(Vector<String> option) {
for (String[] ignoreOption : ignoreOptionsWithArg) {
@@ -920,7 +956,7 @@ public class ConfigParser {
if (!ignoreThisOption(optionsline)) {
// Check if option had been inlined and inline again
if (optionsline.size() == 2 &&
- ("extra-certs".equals(optionsline.get(0)) || "http-proxy-user-pass".equals(optionsline.get(0)))) {
+ "extra-certs".equals(optionsline.get(0))) {
custom += VpnProfile.insertFileData(optionsline.get(0), optionsline.get(1));
} else {
for (String arg : optionsline)
@@ -932,7 +968,6 @@ public class ConfigParser {
return custom;
}
-
private void fixup(VpnProfile np) {
if (np.mRemoteCN.equals(np.mServerName)) {
np.mRemoteCN = "";
@@ -947,7 +982,6 @@ public class ConfigParser {
return alloptions.lastElement();
}
-
private Vector<Vector<String>> getAllOption(String option, int minarg, int maxarg) throws ConfigParseError {
Vector<Vector<String>> args = options.get(option);
if (args == null)
@@ -964,6 +998,19 @@ public class ConfigParser {
return args;
}
+ enum linestate {
+ initial,
+ readin_single_quote, reading_quoted, reading_unquoted, done
+ }
+
+ public static class ConfigParseError extends Exception {
+ private static final long serialVersionUID = -60L;
+
+ public ConfigParseError(String msg) {
+ super(msg);
+ }
+ }
+
}
diff --git a/app/src/main/java/de/blinkt/openvpn/core/Connection.java b/app/src/main/java/de/blinkt/openvpn/core/Connection.java
index ff15daec..df071894 100644
--- a/app/src/main/java/de/blinkt/openvpn/core/Connection.java
+++ b/app/src/main/java/de/blinkt/openvpn/core/Connection.java
@@ -19,11 +19,25 @@ public class Connection implements Serializable, Cloneable {
public boolean mEnabled = true;
public int mConnectTimeout = 0;
public static final int CONNECTION_DEFAULT_TIMEOUT = 120;
+ public ProxyType mProxyType = ProxyType.NONE;
+ public String mProxyName = "proxy.example.com";
+ public String mProxyPort = "8080";
+
+ public boolean mUseProxyAuth;
+ public String mProxyAuthUser = null;
+ public String mProxyAuthPassword = null;
+
+ public enum ProxyType {
+ NONE,
+ HTTP,
+ SOCKS5,
+ ORBOT
+ }
private static final long serialVersionUID = 92031902903829089L;
- public String getConnectionBlock() {
+ public String getConnectionBlock(boolean isOpenVPN3) {
String cfg = "";
// Server Address
@@ -39,14 +53,31 @@ public class Connection implements Serializable, Cloneable {
if (mConnectTimeout != 0)
cfg += String.format(Locale.US, " connect-timeout %d\n", mConnectTimeout);
+ // OpenVPN 2.x manages proxy connection via management interface
+ if ((isOpenVPN3 || usesExtraProxyOptions()) && mProxyType == ProxyType.HTTP)
+ {
+ cfg+=String.format(Locale.US,"http-proxy %s %s\n", mProxyName, mProxyPort);
+ if (mUseProxyAuth)
+ cfg+=String.format(Locale.US, "<http-proxy-user-pass>\n%s\n%s\n</http-proxy-user-pass>\n", mProxyAuthUser, mProxyAuthPassword);
+ }
+ if (usesExtraProxyOptions() && mProxyType == ProxyType.SOCKS5) {
+ cfg+=String.format(Locale.US,"socks-proxy %s %s\n", mProxyName, mProxyPort);
+ }
if (!TextUtils.isEmpty(mCustomConfiguration) && mUseCustomConfig) {
cfg += mCustomConfiguration;
cfg += "\n";
}
+
+
return cfg;
}
+ public boolean usesExtraProxyOptions() {
+ return (mUseCustomConfig && mCustomConfiguration.contains("http-proxy-option "));
+ }
+
+
@Override
public Connection clone() throws CloneNotSupportedException {
return (Connection) super.clone();
diff --git a/app/src/main/java/de/blinkt/openvpn/core/ExtAuthHelper.java b/app/src/main/java/de/blinkt/openvpn/core/ExtAuthHelper.java
new file mode 100644
index 00000000..166bce12
--- /dev/null
+++ b/app/src/main/java/de/blinkt/openvpn/core/ExtAuthHelper.java
@@ -0,0 +1,259 @@
+/*
+ * Copyright (c) 2012-2018 Arne Schwabe
+ * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt
+ */
+
+package de.blinkt.openvpn.core;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.os.*;
+import android.security.KeyChainException;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.support.annotation.WorkerThread;
+import android.widget.ArrayAdapter;
+import android.widget.Spinner;
+import android.widget.SpinnerAdapter;
+import de.blinkt.openvpn.api.ExternalCertificateProvider;
+
+import java.io.ByteArrayInputStream;
+import java.io.Closeable;
+import java.io.UnsupportedEncodingException;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.util.*;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingQueue;
+
+public class ExtAuthHelper {
+
+ public static final String ACTION_CERT_CONFIGURATION = "de.blinkt.openvpn.api.ExternalCertificateConfiguration";
+ public static final String ACTION_CERT_PROVIDER = "de.blinkt.openvpn.api.ExternalCertificateProvider";
+
+ public static final String EXTRA_ALIAS = "de.blinkt.openvpn.api.KEY_ALIAS";
+ public static final String EXTRA_DESCRIPTION = "de.blinkt.openvpn.api.KEY_DESCRIPTION";
+
+
+ public static void setExternalAuthProviderSpinnerList(Spinner spinner, String selectedApp) {
+ Context c = spinner.getContext();
+ final PackageManager pm = c.getPackageManager();
+ ArrayList<ExternalAuthProvider> extProviders = getExternalAuthProviderList(c);
+
+ int selectedPos = -1;
+
+ if (extProviders.size() ==0)
+ {
+ selectedApp = "";
+ ExternalAuthProvider noauthprovider = new ExternalAuthProvider();
+ noauthprovider.label = "No external auth provider found";
+ noauthprovider.packageName = selectedApp;
+ noauthprovider.configurable = false;
+ extProviders.add(noauthprovider);
+ }
+
+
+ for (int i = 0; i < extProviders.size(); i++) {
+ if (extProviders.get(i).packageName.equals(selectedApp))
+ selectedPos = i;
+ }
+ SpinnerAdapter extAppAdapter = new ArrayAdapter<ExternalAuthProvider>(c, android.R.layout.simple_spinner_item, android.R.id.text1, extProviders);
+ spinner.setAdapter(extAppAdapter);
+ if (selectedPos != -1)
+ spinner.setSelection(selectedPos);
+ }
+
+ static ArrayList<ExternalAuthProvider> getExternalAuthProviderList(Context c) {
+ Intent configureExtAuth = new Intent(ACTION_CERT_CONFIGURATION);
+
+ final PackageManager packageManager = c.getPackageManager();
+ List<ResolveInfo> configureList =
+ packageManager.queryIntentActivities(configureExtAuth, 0);
+
+ Intent serviceExtAuth = new Intent(ACTION_CERT_PROVIDER);
+
+ List<ResolveInfo> serviceList =
+ packageManager.queryIntentServices(serviceExtAuth, 0);
+
+
+ // For now only list those who appear in both lists
+
+ ArrayList<ExternalAuthProvider> providers = new ArrayList<ExternalAuthProvider>();
+
+ for (ResolveInfo service : serviceList) {
+ ExternalAuthProvider ext = new ExternalAuthProvider();
+ ext.packageName = service.serviceInfo.packageName;
+
+ ext.label = (String) service.serviceInfo.applicationInfo.loadLabel(packageManager);
+
+ for (ResolveInfo activity : configureList) {
+ if (service.serviceInfo.packageName.equals(activity.activityInfo.packageName)) {
+ ext.configurable = true;
+ }
+ }
+ providers.add(ext);
+
+ }
+ return providers;
+
+ }
+
+ @Nullable
+ @WorkerThread
+ public static byte[] signData(@NonNull Context context,
+ @NonNull String extAuthPackageName,
+ @NonNull String alias,
+ @NonNull byte[] data
+ ) throws KeyChainException, InterruptedException
+
+ {
+
+
+ try (ExternalAuthProviderConnection authProviderConnection = bindToExtAuthProvider(context.getApplicationContext(), extAuthPackageName)) {
+ ExternalCertificateProvider externalAuthProvider = authProviderConnection.getService();
+ return externalAuthProvider.getSignedData(alias, data);
+
+ } catch (RemoteException e) {
+ throw new KeyChainException(e);
+ }
+ }
+
+ @Nullable
+ @WorkerThread
+ public static X509Certificate[] getCertificateChain(@NonNull Context context,
+ @NonNull String extAuthPackageName,
+ @NonNull String alias) throws KeyChainException {
+
+ final byte[] certificateBytes;
+ try (ExternalAuthProviderConnection authProviderConnection = bindToExtAuthProvider(context.getApplicationContext(), extAuthPackageName)) {
+ ExternalCertificateProvider externalAuthProvider = authProviderConnection.getService();
+ certificateBytes = externalAuthProvider.getCertificateChain(alias);
+ if (certificateBytes == null) {
+ return null;
+ }
+ Collection<X509Certificate> chain = toCertificates(certificateBytes);
+ return chain.toArray(new X509Certificate[chain.size()]);
+
+ } catch (RemoteException | RuntimeException | InterruptedException e) {
+ throw new KeyChainException(e);
+ }
+ }
+
+ public static Bundle getCertificateMetaData(@NonNull Context context,
+ @NonNull String extAuthPackageName,
+ String alias) throws KeyChainException
+ {
+ try (ExternalAuthProviderConnection authProviderConnection = bindToExtAuthProvider(context.getApplicationContext(), extAuthPackageName)) {
+ ExternalCertificateProvider externalAuthProvider = authProviderConnection.getService();
+ return externalAuthProvider.getCertificateMetaData(alias);
+
+ } catch (RemoteException | RuntimeException | InterruptedException e) {
+ throw new KeyChainException(e);
+ }
+ }
+
+ public static Collection<X509Certificate> toCertificates(@NonNull byte[] bytes) {
+ final String BEGINCERT = "-----BEGIN CERTIFICATE-----";
+ try {
+ Vector<X509Certificate> retCerts = new Vector<>();
+ // Java library is broken, although the javadoc says it will extract all certificates from a byte array
+ // it only extracts the first one
+ String allcerts = new String(bytes, "iso8859-1");
+ String[] certstrings = allcerts.split(BEGINCERT);
+ for (String certstring: certstrings) {
+ certstring = BEGINCERT + certstring;
+ CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
+ retCerts.addAll((Collection<? extends X509Certificate>) certFactory.generateCertificates(
+ new ByteArrayInputStream((certstring.getBytes("iso8859-1")))));
+
+ }
+ return retCerts;
+
+ } catch (CertificateException e) {
+ throw new AssertionError(e);
+ } catch (UnsupportedEncodingException e) {
+ throw new AssertionError(e);
+ }
+ }
+
+ // adapted form Keychain
+ @WorkerThread
+ public static ExternalAuthProviderConnection bindToExtAuthProvider(@NonNull Context context, String packagename) throws KeyChainException, InterruptedException {
+ ensureNotOnMainThread(context);
+ final BlockingQueue<ExternalCertificateProvider> q = new LinkedBlockingQueue<>(1);
+ ServiceConnection extAuthServiceConnection = new ServiceConnection() {
+ volatile boolean mConnectedAtLeastOnce = false;
+
+ @Override
+ public void onServiceConnected(ComponentName name, IBinder service) {
+ if (!mConnectedAtLeastOnce) {
+ mConnectedAtLeastOnce = true;
+ try {
+ q.put(ExternalCertificateProvider.Stub.asInterface(service));
+ } catch (InterruptedException e) {
+ // will never happen, since the queue starts with one available slot
+ }
+ }
+ }
+
+ @Override
+ public void onServiceDisconnected(ComponentName name) {
+ }
+ };
+ Intent intent = new Intent(ACTION_CERT_PROVIDER);
+ intent.setPackage(packagename);
+
+ if (!context.bindService(intent, extAuthServiceConnection, Context.BIND_AUTO_CREATE)) {
+ throw new KeyChainException("could not bind to external authticator app: " + packagename);
+ }
+ return new ExternalAuthProviderConnection(context, extAuthServiceConnection, q.take());
+ }
+
+ private static void ensureNotOnMainThread(@NonNull Context context) {
+ Looper looper = Looper.myLooper();
+ if (looper != null && looper == context.getMainLooper()) {
+ throw new IllegalStateException(
+ "calling this from your main thread can lead to deadlock");
+ }
+ }
+
+ public static class ExternalAuthProvider {
+
+ public String packageName;
+ public boolean configurable = false;
+ private String label;
+
+ @Override
+ public String toString() {
+ return label;
+ }
+ }
+
+ public static class ExternalAuthProviderConnection implements Closeable {
+ private final Context context;
+ private final ServiceConnection serviceConnection;
+ private final ExternalCertificateProvider service;
+
+ protected ExternalAuthProviderConnection(Context context,
+ ServiceConnection serviceConnection,
+ ExternalCertificateProvider service) {
+ this.context = context;
+ this.serviceConnection = serviceConnection;
+ this.service = service;
+ }
+
+ @Override
+ public void close() {
+ context.unbindService(serviceConnection);
+ }
+
+ public ExternalCertificateProvider getService() {
+ return service;
+ }
+ }
+}
diff --git a/app/src/main/java/de/blinkt/openvpn/core/ICSOpenVPNApplication.java b/app/src/main/java/de/blinkt/openvpn/core/ICSOpenVPNApplication.java
index 38f51807..5b1307b7 100644
--- a/app/src/main/java/de/blinkt/openvpn/core/ICSOpenVPNApplication.java
+++ b/app/src/main/java/de/blinkt/openvpn/core/ICSOpenVPNApplication.java
@@ -65,4 +65,4 @@ public class ICSOpenVPNApplication extends Application {
mChannel.setLightColor(Color.BLUE);
mNotificationManager.createNotificationChannel(mChannel);
}
-}
+} \ No newline at end of file
diff --git a/app/src/main/java/de/blinkt/openvpn/core/LogFileHandler.java b/app/src/main/java/de/blinkt/openvpn/core/LogFileHandler.java
index 57d1fb22..fca633b6 100644
--- a/app/src/main/java/de/blinkt/openvpn/core/LogFileHandler.java
+++ b/app/src/main/java/de/blinkt/openvpn/core/LogFileHandler.java
@@ -134,7 +134,9 @@ class LogFileHandler extends Handler {
if (!logfile.exists() || !logfile.canRead())
return;
- readCacheContents(new FileInputStream(logfile));
+ FileInputStream log = new FileInputStream(logfile);
+ readCacheContents(log);
+ log.close();
} catch (java.io.IOException | java.lang.RuntimeException e) {
VpnStatus.logError("Reading cached logfile failed");
diff --git a/app/src/main/java/de/blinkt/openvpn/core/NativeUtils.java b/app/src/main/java/de/blinkt/openvpn/core/NativeUtils.java
index 70c7455a..6b633c34 100644
--- a/app/src/main/java/de/blinkt/openvpn/core/NativeUtils.java
+++ b/app/src/main/java/de/blinkt/openvpn/core/NativeUtils.java
@@ -16,7 +16,15 @@ public class NativeUtils {
static native void jniclose(int fdint);
- public static native String getNativeAPI();
+ public static String getNativeAPI()
+ {
+ if (isRoboUnitTest())
+ return "ROBO";
+ else
+ return getJNIAPI();
+ }
+
+ private static native String getJNIAPI();
public final static int[] openSSLlengths = {
@@ -26,8 +34,14 @@ public class NativeUtils {
public static native double[] getOpenSSLSpeed(String algorithm, int testnum);
static {
- System.loadLibrary("opvpnutil");
- if (Build.VERSION.SDK_INT == Build.VERSION_CODES.JELLY_BEAN)
- System.loadLibrary("jbcrypto");
+ if (!isRoboUnitTest()) {
+ System.loadLibrary("opvpnutil");
+ if (Build.VERSION.SDK_INT == Build.VERSION_CODES.JELLY_BEAN)
+ System.loadLibrary("jbcrypto");
+ }
+ }
+
+ public static boolean isRoboUnitTest() {
+ return "robolectric".equals(Build.FINGERPRINT);
}
}
diff --git a/app/src/main/java/de/blinkt/openvpn/core/NetworkSpace.java b/app/src/main/java/de/blinkt/openvpn/core/NetworkSpace.java
index 37689b3f..0c54b050 100644
--- a/app/src/main/java/de/blinkt/openvpn/core/NetworkSpace.java
+++ b/app/src/main/java/de/blinkt/openvpn/core/NetworkSpace.java
@@ -7,9 +7,6 @@ package de.blinkt.openvpn.core;
import android.os.Build;
import android.support.annotation.NonNull;
-import android.text.TextUtils;
-
-import junit.framework.Assert;
import java.math.BigInteger;
import java.net.Inet6Address;
@@ -21,9 +18,17 @@ import java.util.Vector;
import se.leap.bitmaskclient.BuildConfig;
+
+
public class NetworkSpace {
- static class ipAddress implements Comparable<ipAddress> {
+ static void assertTrue(boolean f)
+ {
+ if (!f)
+ throw new IllegalStateException();
+ }
+
+ static class IpAddress implements Comparable<IpAddress> {
private BigInteger netAddress;
public int networkMask;
private boolean included;
@@ -38,7 +43,7 @@ public class NetworkSpace {
* 2. smaller networks are returned as smaller
*/
@Override
- public int compareTo(@NonNull ipAddress another) {
+ public int compareTo(@NonNull IpAddress another) {
int comp = getFirstAddress().compareTo(another.getFirstAddress());
if (comp != 0)
return comp;
@@ -59,22 +64,22 @@ public class NetworkSpace {
*/
@Override
public boolean equals(Object o) {
- if (!(o instanceof ipAddress))
+ if (!(o instanceof IpAddress))
return super.equals(o);
- ipAddress on = (ipAddress) o;
+ IpAddress on = (IpAddress) o;
return (networkMask == on.networkMask) && on.getFirstAddress().equals(getFirstAddress());
}
- public ipAddress(CIDRIP ip, boolean include) {
+ public IpAddress(CIDRIP ip, boolean include) {
included = include;
netAddress = BigInteger.valueOf(ip.getInt());
networkMask = ip.len;
isV4 = true;
}
- public ipAddress(Inet6Address address, int mask, boolean include) {
+ public IpAddress(Inet6Address address, int mask, boolean include) {
networkMask = mask;
included = include;
@@ -130,7 +135,7 @@ public class NetworkSpace {
return String.format(Locale.US, "%s/%d", getIPv6Address(), networkMask);
}
- ipAddress(BigInteger baseAddress, int mask, boolean included, boolean isV4) {
+ IpAddress(BigInteger baseAddress, int mask, boolean included, boolean isV4) {
this.netAddress = baseAddress;
this.networkMask = mask;
this.included = included;
@@ -138,26 +143,26 @@ public class NetworkSpace {
}
- public ipAddress[] split() {
- ipAddress firstHalf = new ipAddress(getFirstAddress(), networkMask + 1, included, isV4);
- ipAddress secondHalf = new ipAddress(firstHalf.getLastAddress().add(BigInteger.ONE), networkMask + 1, included, isV4);
+ public IpAddress[] split() {
+ IpAddress firstHalf = new IpAddress(getFirstAddress(), networkMask + 1, included, isV4);
+ IpAddress secondHalf = new IpAddress(firstHalf.getLastAddress().add(BigInteger.ONE), networkMask + 1, included, isV4);
if (BuildConfig.DEBUG)
- Assert.assertTrue(secondHalf.getLastAddress().equals(getLastAddress()));
- return new ipAddress[]{firstHalf, secondHalf};
+ assertTrue(secondHalf.getLastAddress().equals(getLastAddress()));
+ return new IpAddress[]{firstHalf, secondHalf};
}
String getIPv4Address() {
if (BuildConfig.DEBUG) {
- Assert.assertTrue(isV4);
- Assert.assertTrue(netAddress.longValue() <= 0xffffffffl);
- Assert.assertTrue(netAddress.longValue() >= 0);
+ assertTrue(isV4);
+ assertTrue(netAddress.longValue() <= 0xffffffffl);
+ assertTrue(netAddress.longValue() >= 0);
}
long ip = netAddress.longValue();
return String.format(Locale.US, "%d.%d.%d.%d", (ip >> 24) % 256, (ip >> 16) % 256, (ip >> 8) % 256, ip % 256);
}
String getIPv6Address() {
- if (BuildConfig.DEBUG) Assert.assertTrue(!isV4);
+ if (BuildConfig.DEBUG) assertTrue(!isV4);
BigInteger r = netAddress;
String ipv6str = null;
@@ -186,7 +191,7 @@ public class NetworkSpace {
return ipv6str;
}
- public boolean containsNet(ipAddress network) {
+ public boolean containsNet(IpAddress network) {
// this.first >= net.first && this.last <= net.last
BigInteger ourFirst = getFirstAddress();
BigInteger ourLast = getLastAddress();
@@ -201,12 +206,12 @@ public class NetworkSpace {
}
- TreeSet<ipAddress> mIpAddresses = new TreeSet<ipAddress>();
+ TreeSet<IpAddress> mIpAddresses = new TreeSet<IpAddress>();
- public Collection<ipAddress> getNetworks(boolean included) {
- Vector<ipAddress> ips = new Vector<ipAddress>();
- for (ipAddress ip : mIpAddresses) {
+ public Collection<IpAddress> getNetworks(boolean included) {
+ Vector<IpAddress> ips = new Vector<IpAddress>();
+ for (IpAddress ip : mIpAddresses) {
if (ip.included == included)
ips.add(ip);
}
@@ -220,35 +225,35 @@ public class NetworkSpace {
void addIP(CIDRIP cidrIp, boolean include) {
- mIpAddresses.add(new ipAddress(cidrIp, include));
+ mIpAddresses.add(new IpAddress(cidrIp, include));
}
public void addIPSplit(CIDRIP cidrIp, boolean include) {
- ipAddress newIP = new ipAddress(cidrIp, include);
- ipAddress[] splitIps = newIP.split();
- for (ipAddress split : splitIps)
+ IpAddress newIP = new IpAddress(cidrIp, include);
+ IpAddress[] splitIps = newIP.split();
+ for (IpAddress split : splitIps)
mIpAddresses.add(split);
}
void addIPv6(Inet6Address address, int mask, boolean included) {
- mIpAddresses.add(new ipAddress(address, mask, included));
+ mIpAddresses.add(new IpAddress(address, mask, included));
}
- TreeSet<ipAddress> generateIPList() {
+ TreeSet<IpAddress> generateIPList() {
- PriorityQueue<ipAddress> networks = new PriorityQueue<ipAddress>(mIpAddresses);
+ PriorityQueue<IpAddress> networks = new PriorityQueue<IpAddress>(mIpAddresses);
- TreeSet<ipAddress> ipsDone = new TreeSet<ipAddress>();
+ TreeSet<IpAddress> ipsDone = new TreeSet<IpAddress>();
- ipAddress currentNet = networks.poll();
+ IpAddress currentNet = networks.poll();
if (currentNet == null)
return ipsDone;
while (currentNet != null) {
// Check if it and the next of it are compatible
- ipAddress nextNet = networks.poll();
+ IpAddress nextNet = networks.poll();
- if (BuildConfig.DEBUG) Assert.assertNotNull(currentNet);
+ if (BuildConfig.DEBUG) assertTrue(currentNet!=null);
if (nextNet == null || currentNet.getLastAddress().compareTo(nextNet.getFirstAddress()) == -1) {
// Everything good, no overlapping nothing to do
ipsDone.add(currentNet);
@@ -263,7 +268,7 @@ public class NetworkSpace {
currentNet = nextNet;
} else {
// our currentNet is included in next and types differ. Need to split the next network
- ipAddress[] newNets = nextNet.split();
+ IpAddress[] newNets = nextNet.split();
// TODO: The contains method of the Priority is stupid linear search
@@ -274,7 +279,7 @@ public class NetworkSpace {
if (newNets[0].getLastAddress().equals(currentNet.getLastAddress())) {
if (BuildConfig.DEBUG)
- Assert.assertEquals(newNets[0].networkMask, currentNet.networkMask);
+ assertTrue(newNets[0].networkMask == currentNet.networkMask);
// Don't add the lower half that would conflict with currentNet
} else {
if (!networks.contains(newNets[0]))
@@ -284,9 +289,9 @@ public class NetworkSpace {
}
} else {
if (BuildConfig.DEBUG) {
- Assert.assertTrue(currentNet.networkMask < nextNet.networkMask);
- Assert.assertTrue(nextNet.getFirstAddress().compareTo(currentNet.getFirstAddress()) == 1);
- Assert.assertTrue(currentNet.getLastAddress().compareTo(nextNet.getLastAddress()) != -1);
+ assertTrue(currentNet.networkMask < nextNet.networkMask);
+ assertTrue(nextNet.getFirstAddress().compareTo(currentNet.getFirstAddress()) == 1);
+ assertTrue(currentNet.getLastAddress().compareTo(nextNet.getLastAddress()) != -1);
}
// This network is bigger than the next and last ip of current >= next
@@ -296,13 +301,13 @@ public class NetworkSpace {
// simply ignore the next and move on
} else {
// We need to split our network
- ipAddress[] newNets = currentNet.split();
+ IpAddress[] newNets = currentNet.split();
if (newNets[1].networkMask == nextNet.networkMask) {
if (BuildConfig.DEBUG) {
- Assert.assertTrue(newNets[1].getFirstAddress().equals(nextNet.getFirstAddress()));
- Assert.assertTrue(newNets[1].getLastAddress().equals(currentNet.getLastAddress()));
+ assertTrue(newNets[1].getFirstAddress().equals(nextNet.getFirstAddress()));
+ assertTrue(newNets[1].getLastAddress().equals(currentNet.getLastAddress()));
// split second equal the next network, do not add it
}
networks.add(nextNet);
@@ -322,11 +327,11 @@ public class NetworkSpace {
return ipsDone;
}
- Collection<ipAddress> getPositiveIPList() {
- TreeSet<ipAddress> ipsSorted = generateIPList();
+ Collection<IpAddress> getPositiveIPList() {
+ TreeSet<IpAddress> ipsSorted = generateIPList();
- Vector<ipAddress> ips = new Vector<ipAddress>();
- for (ipAddress ia : ipsSorted) {
+ Vector<IpAddress> ips = new Vector<IpAddress>();
+ for (IpAddress ia : ipsSorted) {
if (ia.included)
ips.add(ia);
}
@@ -334,7 +339,7 @@ public class NetworkSpace {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
// Include postive routes from the original set under < 4.4 since these might overrule the local
// network but only if no smaller negative route exists
- for (ipAddress origIp : mIpAddresses) {
+ for (IpAddress origIp : mIpAddresses) {
if (!origIp.included)
continue;
@@ -345,7 +350,7 @@ public class NetworkSpace {
boolean skipIp = false;
// If there is any smaller net that is excluded we may not add the positive route back
- for (ipAddress calculatedIp : ipsSorted) {
+ for (IpAddress calculatedIp : ipsSorted) {
if (!calculatedIp.included && origIp.containsNet(calculatedIp)) {
skipIp = true;
break;
diff --git a/app/src/main/java/de/blinkt/openvpn/core/NetworkUtils.java b/app/src/main/java/de/blinkt/openvpn/core/NetworkUtils.java
new file mode 100644
index 00000000..40449118
--- /dev/null
+++ b/app/src/main/java/de/blinkt/openvpn/core/NetworkUtils.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2012-2018 Arne Schwabe
+ * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt
+ */
+
+package de.blinkt.openvpn.core;
+
+import android.content.Context;
+import android.net.*;
+import android.os.Build;
+import android.text.TextUtils;
+
+import java.net.Inet4Address;
+import java.net.Inet6Address;
+import java.util.Vector;
+
+public class NetworkUtils {
+
+ public static Vector<String> getLocalNetworks(Context c, boolean ipv6) {
+ Vector<String> nets = new Vector<>();
+ ConnectivityManager conn = (ConnectivityManager) c.getSystemService(Context.CONNECTIVITY_SERVICE);
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+ Network[] networks = conn.getAllNetworks();
+ for (Network network : networks) {
+ NetworkInfo ni = conn.getNetworkInfo(network);
+ LinkProperties li = conn.getLinkProperties(network);
+
+ NetworkCapabilities nc = conn.getNetworkCapabilities(network);
+
+ // Skip VPN networks like ourselves
+ if (nc.hasTransport(NetworkCapabilities.TRANSPORT_VPN))
+ continue;
+
+ // Also skip mobile networks
+ if (nc.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR))
+ continue;
+
+
+ for (LinkAddress la : li.getLinkAddresses()) {
+ if ((la.getAddress() instanceof Inet4Address && !ipv6) ||
+ (la.getAddress() instanceof Inet6Address && ipv6))
+ nets.add(la.toString());
+ }
+ }
+ } else {
+ // Old Android Version, use native utils via ifconfig instead
+ // Add local network interfaces
+ if (ipv6)
+ return nets;
+
+ String[] localRoutes = NativeUtils.getIfconfig();
+
+ // The format of mLocalRoutes is kind of broken because I don't really like JNI
+ for (int i = 0; i < localRoutes.length; i += 3) {
+ String intf = localRoutes[i];
+ String ipAddr = localRoutes[i + 1];
+ String netMask = localRoutes[i + 2];
+
+ if (intf == null || intf.equals("lo") ||
+ intf.startsWith("tun") || intf.startsWith("rmnet"))
+ continue;
+
+ if (ipAddr == null || netMask == null) {
+ VpnStatus.logError("Local routes are broken?! (Report to author) " + TextUtils.join("|", localRoutes));
+ continue;
+ }
+ nets.add(ipAddr + "/" + CIDRIP.calculateLenFromMask(netMask));
+
+ }
+
+ }
+ return nets;
+ }
+
+} \ No newline at end of file
diff --git a/app/src/main/java/de/blinkt/openvpn/core/OpenVPNService.java b/app/src/main/java/de/blinkt/openvpn/core/OpenVPNService.java
index f701b7aa..11bc4da3 100644
--- a/app/src/main/java/de/blinkt/openvpn/core/OpenVPNService.java
+++ b/app/src/main/java/de/blinkt/openvpn/core/OpenVPNService.java
@@ -7,8 +7,12 @@ package de.blinkt.openvpn.core;
import android.Manifest.permission;
import android.annotation.TargetApi;
+import android.app.Activity;
import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
import android.app.UiModeManager;
+import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
@@ -16,14 +20,17 @@ import android.content.pm.ShortcutManager;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.net.ConnectivityManager;
+import android.net.Uri;
import android.net.VpnService;
import android.os.Build;
+import android.os.Bundle;
import android.os.Handler;
import android.os.Handler.Callback;
import android.os.IBinder;
import android.os.Message;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
+import android.support.annotation.NonNull;
import android.support.annotation.RequiresApi;
import android.system.OsConstants;
import android.text.TextUtils;
@@ -32,6 +39,7 @@ import android.widget.Toast;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.UnknownHostException;
@@ -39,6 +47,8 @@ import java.util.Collection;
import java.util.Locale;
import java.util.Vector;
+import de.blinkt.openvpn.LaunchVPN;
+import se.leap.bitmaskclient.R;
import de.blinkt.openvpn.VpnProfile;
import de.blinkt.openvpn.core.VpnStatus.ByteCountListener;
import de.blinkt.openvpn.core.VpnStatus.StateListener;
@@ -47,7 +57,7 @@ import se.leap.bitmaskclient.VpnNotificationManager;
import static de.blinkt.openvpn.core.ConnectionStatus.LEVEL_CONNECTED;
import static de.blinkt.openvpn.core.ConnectionStatus.LEVEL_WAITING_FOR_USER_INPUT;
-import static de.blinkt.openvpn.core.NetworkSpace.ipAddress;
+import static de.blinkt.openvpn.core.NetworkSpace.IpAddress;
public class OpenVPNService extends VpnService implements StateListener, Callback, ByteCountListener, IOpenVPNServiceInternal, VpnNotificationManager.VpnServiceCallback {
@@ -55,12 +65,12 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac
public static final String START_SERVICE_STICKY = "de.blinkt.openvpn.START_SERVICE_STICKY";
public static final String ALWAYS_SHOW_NOTIFICATION = "de.blinkt.openvpn.NOTIFICATION_ALWAYS_VISIBLE";
public static final String DISCONNECT_VPN = "de.blinkt.openvpn.DISCONNECT_VPN";
- private static final String PAUSE_VPN = "de.blinkt.openvpn.PAUSE_VPN";
- private static final String RESUME_VPN = "se.leap.bitmaskclient.RESUME_VPN";
public static final String NOTIFICATION_CHANNEL_BG_ID = "openvpn_bg";
public static final String NOTIFICATION_CHANNEL_NEWSTATUS_ID = "openvpn_newstat";
public static final String VPNSERVICE_TUN = "vpnservice-tun";
-
+ public final static String ORBOT_PACKAGE_NAME = "org.torproject.android";
+ private static final String PAUSE_VPN = "de.blinkt.openvpn.PAUSE_VPN";
+ private static final String RESUME_VPN = "se.leap.bitmaskclient.RESUME_VPN";
private static boolean mNotificationAlwaysVisible = false;
private final Vector<String> mDnslist = new Vector<>();
private final NetworkSpace mRoutes = new NetworkSpace();
@@ -407,8 +417,7 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac
}
Runnable processThread;
- if (useOpenVPN3)
- {
+ if (useOpenVPN3) {
OpenVPNManagement mOpenVPN3 = instantiateOpenVPN3Core();
processThread = (Runnable) mOpenVPN3;
mManagement = mOpenVPN3;
@@ -545,7 +554,9 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac
}
if (mLocalIP != null) {
- addLocalNetworksToRoutes();
+ // OpenVPN3 manages excluded local networks by callback
+ if (!VpnProfile.doUseOpenVPN3(this))
+ addLocalNetworksToRoutes();
try {
builder.addAddress(mLocalIP.mIp, mLocalIP.len);
} catch (IllegalArgumentException iae) {
@@ -584,15 +595,15 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac
builder.setMtu(mMtu);
}
- Collection<ipAddress> positiveIPv4Routes = mRoutes.getPositiveIPList();
- Collection<ipAddress> positiveIPv6Routes = mRoutesv6.getPositiveIPList();
+ Collection<IpAddress> positiveIPv4Routes = mRoutes.getPositiveIPList();
+ Collection<IpAddress> positiveIPv6Routes = mRoutesv6.getPositiveIPList();
if ("samsung".equals(Build.BRAND) && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && mDnslist.size() >= 1) {
// Check if the first DNS Server is in the VPN range
try {
- ipAddress dnsServer = new ipAddress(new CIDRIP(mDnslist.get(0), 32), true);
+ IpAddress dnsServer = new IpAddress(new CIDRIP(mDnslist.get(0), 32), true);
boolean dnsIncluded = false;
- for (ipAddress net : positiveIPv4Routes) {
+ for (IpAddress net : positiveIPv4Routes) {
if (net.containsNet(dnsServer)) {
dnsIncluded = true;
}
@@ -609,9 +620,9 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac
}
}
- ipAddress multicastRange = new ipAddress(new CIDRIP("224.0.0.0", 3), true);
+ IpAddress multicastRange = new IpAddress(new CIDRIP("224.0.0.0", 3), true);
- for (NetworkSpace.ipAddress route : positiveIPv4Routes) {
+ for (IpAddress route : positiveIPv4Routes) {
try {
if (multicastRange.containsNet(route))
@@ -623,7 +634,7 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac
}
}
- for (NetworkSpace.ipAddress route6 : positiveIPv6Routes) {
+ for (IpAddress route6 : positiveIPv6Routes) {
try {
builder.addRoute(route6.getIPv6Address(), route6.networkMask);
} catch (IllegalArgumentException ia) {
@@ -635,7 +646,16 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac
if (mDomain != null)
builder.addSearchDomain(mDomain);
- VpnStatus.logInfo(R.string.local_ip_info, mLocalIP.mIp, mLocalIP.len, mLocalIPv6, mMtu);
+ String ipv4info;
+ int ipv4len;
+ if (mLocalIP!=null) {
+ ipv4len=mLocalIP.len;
+ ipv4info=mLocalIP.mIp;
+ } else {
+ ipv4len = -1;
+ ipv4info="(not set)";
+ }
+ VpnStatus.logInfo(R.string.local_ip_info, ipv4info, ipv4len, mLocalIPv6, mMtu);
VpnStatus.logInfo(R.string.dns_server_info, TextUtils.join(", ", mDnslist), mDomain);
VpnStatus.logInfo(R.string.routes_info_incl, TextUtils.join(", ", mRoutes.getNetworks(true)), TextUtils.join(", ", mRoutesv6.getNetworks(true)));
VpnStatus.logInfo(R.string.routes_info_excl, TextUtils.join(", ", mRoutes.getNetworks(false)), TextUtils.join(", ", mRoutesv6.getNetworks(false)));
@@ -643,6 +663,10 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
setAllowedVpnPackages(builder);
}
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) {
+ // VPN always uses the default network
+ builder.setUnderlyingNetworks(null);
+ }
String session = mProfile.mName;
@@ -650,6 +674,8 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac
session = getString(R.string.session_ipv6string, session, mLocalIP, mLocalIPv6);
else if (mLocalIP != null)
session = getString(R.string.session_ipv4string, session, mLocalIP);
+ else
+ session = getString(R.string.session_ipv4string, session, mLocalIPv6);
builder.setSession(session);
@@ -691,25 +717,11 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac
}
private void addLocalNetworksToRoutes() {
-
- // Add local network interfaces
- String[] localRoutes = NativeUtils.getIfconfig();
-
- // The format of mLocalRoutes is kind of broken because I don't really like JNI
- for (int i = 0; i < localRoutes.length; i += 3) {
- String intf = localRoutes[i];
- String ipAddr = localRoutes[i + 1];
- String netMask = localRoutes[i + 2];
-
- if (intf == null || intf.equals("lo") ||
- intf.startsWith("tun") || intf.startsWith("rmnet"))
- continue;
-
- if (ipAddr == null || netMask == null) {
- VpnStatus.logError("Local routes are broken?! (Report to author) " + TextUtils.join("|", localRoutes));
- continue;
- }
-
+ for (String net: NetworkUtils.getLocalNetworks(this, false))
+ {
+ String[] netparts = net.split("/");
+ String ipAddr = netparts[0];
+ int netMask = Integer.parseInt(netparts[1]);
if (ipAddr.equals(mLocalIP.mIp))
continue;
@@ -719,19 +731,50 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && mProfile.mAllowLocalLAN)
mRoutes.addIP(new CIDRIP(ipAddr, netMask), false);
}
+
+ // IPv6 is Lollipop+ only so we can skip the lower than KITKAT case
+ if (mProfile.mAllowLocalLAN) {
+ for (String net : NetworkUtils.getLocalNetworks(this, true)) {
+ addRoutev6(net, false);;
+ }
+ }
+
+
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private void setAllowedVpnPackages(Builder builder) {
+ boolean profileUsesOrBot = false;
+
+ for (Connection c : mProfile.mConnections) {
+ if (c.mProxyType == Connection.ProxyType.ORBOT)
+ profileUsesOrBot = true;
+ }
+
+ if (profileUsesOrBot)
+ VpnStatus.logDebug("VPN Profile uses at least one server entry with Orbot. Setting up VPN so that OrBot is not redirected over VPN.");
+
+
boolean atLeastOneAllowedApp = false;
+
+ if (mProfile.mAllowedAppsVpnAreDisallowed && profileUsesOrBot) {
+ try {
+ builder.addDisallowedApplication(ORBOT_PACKAGE_NAME);
+ } catch (PackageManager.NameNotFoundException e) {
+ VpnStatus.logDebug("Orbot not installed?");
+ }
+ }
+
for (String pkg : mProfile.mAllowedAppsVpn) {
try {
if (mProfile.mAllowedAppsVpnAreDisallowed) {
builder.addDisallowedApplication(pkg);
} else {
- builder.addAllowedApplication(pkg);
- atLeastOneAllowedApp = true;
+ if (!(profileUsesOrBot && pkg.equals(ORBOT_PACKAGE_NAME))) {
+ builder.addAllowedApplication(pkg);
+ atLeastOneAllowedApp = true;
+ }
}
} catch (PackageManager.NameNotFoundException e) {
mProfile.mAllowedAppsVpn.remove(pkg);
@@ -776,13 +819,13 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac
CIDRIP route = new CIDRIP(dest, mask);
boolean include = isAndroidTunDevice(device);
- NetworkSpace.ipAddress gatewayIP = new NetworkSpace.ipAddress(new CIDRIP(gateway, 32), false);
+ IpAddress gatewayIP = new IpAddress(new CIDRIP(gateway, 32), false);
if (mLocalIP == null) {
VpnStatus.logError("Local IP address unset and received. Neither pushed server config nor local config specifies an IP addresses. Opening tun device is most likely going to fail.");
return;
}
- NetworkSpace.ipAddress localNet = new NetworkSpace.ipAddress(mLocalIP, true);
+ IpAddress localNet = new IpAddress(mLocalIP, true);
if (localNet.containsNet(gatewayIP))
include = true;
@@ -802,10 +845,13 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac
}
public void addRoutev6(String network, String device) {
- String[] v6parts = network.split("/");
+ // Tun is opened after ROUTE6, no device name may be present
boolean included = isAndroidTunDevice(device);
+ addRoutev6(network, included);
+ }
- // Tun is opened after ROUTE6, no device name may be present
+ public void addRoutev6(String network, boolean included) {
+ String[] v6parts = network.split("/");
try {
Inet6Address ip = (Inet6Address) InetAddress.getAllByName(v6parts[0])[0];
@@ -870,7 +916,7 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac
if (mLocalIP.len <= 31 && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
CIDRIP interfaceRoute = new CIDRIP(mLocalIP.mIp, mLocalIP.len);
interfaceRoute.normalise();
- addRoute(interfaceRoute ,true);
+ addRoute(interfaceRoute, true);
}
@@ -895,11 +941,7 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac
// Display byte count only after being connected
{
- if (level == LEVEL_WAITING_FOR_USER_INPUT) {
- // The user is presented a dialog of some kind, no need to inform the user
- // with a notifcation
- return;
- } else if (level == LEVEL_CONNECTED) {
+ if (level == LEVEL_CONNECTED) {
mDisplayBytecount = true;
mConnecttime = System.currentTimeMillis();
if (!runningOnAndroidTV())
@@ -1005,4 +1047,51 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac
public void onNotificationStop() {
stopForeground(true);
}
+
+ public void trigger_url_open(String info) {
+ /*
+ String channel = NOTIFICATION_CHANNEL_USERREQ_ID;
+
+
+ String url = info.split(":",2)[1];
+
+ NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
+
+ Notification.Builder nbuilder = new Notification.Builder(this);
+ nbuilder.setContentTitle(getString(R.string.openurl_requested));
+
+ nbuilder.setContentText(url);
+ nbuilder.setAutoCancel(true);
+
+ int icon = android.R.drawable.ic_dialog_info;
+
+ nbuilder.setSmallIcon(icon);
+
+ Intent openUrlIntent = new Intent(Intent.ACTION_VIEW);
+ openUrlIntent.setData(Uri.parse(url));
+ openUrlIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+
+ nbuilder.setContentIntent(PendingIntent.getActivity(this,0, openUrlIntent, 0));
+
+
+ // Try to set the priority available since API 16 (Jellybean)
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN)
+ jbNotificationExtras(PRIORITY_MAX, nbuilder);
+
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
+ lpNotificationExtras(nbuilder, Notification.CATEGORY_STATUS);
+
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ //noinspection NewApi
+ nbuilder.setChannelId(channel);
+ }
+
+ @SuppressWarnings("deprecation")
+ Notification notification = nbuilder.getNotification();
+
+ int notificationId = channel.hashCode();
+
+ mNotificationManager.notify(notificationId, notification);
+ */
+ }
} \ No newline at end of file
diff --git a/app/src/main/java/de/blinkt/openvpn/core/OpenVpnManagementThread.java b/app/src/main/java/de/blinkt/openvpn/core/OpenVpnManagementThread.java
index 2b6df9af..4f7a5bda 100644
--- a/app/src/main/java/de/blinkt/openvpn/core/OpenVpnManagementThread.java
+++ b/app/src/main/java/de/blinkt/openvpn/core/OpenVpnManagementThread.java
@@ -6,16 +6,20 @@
package de.blinkt.openvpn.core;
import android.content.Context;
+import android.content.Intent;
import android.net.LocalServerSocket;
import android.net.LocalSocket;
import android.net.LocalSocketAddress;
+import android.os.Build;
import android.os.Handler;
import android.os.ParcelFileDescriptor;
import android.support.annotation.NonNull;
-import android.text.TextUtils;
+import android.support.annotation.RequiresApi;
+import android.system.ErrnoException;
+import android.system.Os;
import android.util.Log;
-
-import junit.framework.Assert;
+import se.leap.bitmaskclient.R;
+import de.blinkt.openvpn.VpnProfile;
import java.io.FileDescriptor;
import java.io.IOException;
@@ -24,19 +28,13 @@ import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.LinkedList;
-import java.util.Locale;
-import java.util.Vector;
-
-import se.leap.bitmaskclient.BuildConfig;
-import se.leap.bitmaskclient.R;
-import de.blinkt.openvpn.VpnProfile;
+import java.util.*;
public class OpenVpnManagementThread implements Runnable, OpenVPNManagement {
+ public static final int ORBOT_TIMEOUT_MS = 20 * 1000;
private static final String TAG = "openvpn";
+ private static final Vector<OpenVpnManagementThread> active = new Vector<>();
private final Handler mResumeHandler;
private LocalSocket mSocket;
private VpnProfile mProfile;
@@ -45,13 +43,55 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement {
private LocalServerSocket mServerSocket;
private boolean mWaitingForRelease = false;
private long mLastHoldRelease = 0;
-
- private static final Vector<OpenVpnManagementThread> active = new Vector<>();
private LocalSocket mServerSocketLocal;
private pauseReason lastPauseReason = pauseReason.noNetwork;
private PausedStateCallback mPauseCallback;
private boolean mShuttingDown;
+ private Runnable mResumeHoldRunnable = () -> {
+ if (shouldBeRunning()) {
+ releaseHoldCmd();
+ }
+ };
+ private Runnable orbotStatusTimeOutRunnable = new Runnable() {
+ @Override
+ public void run() {
+ sendProxyCMD(Connection.ProxyType.SOCKS5, "127.0.0.1", Integer.toString(OrbotHelper.SOCKS_PROXY_PORT_DEFAULT), false);
+ OrbotHelper.get(mOpenVPNService).removeStatusCallback(statusCallback);
+
+ }
+ };
+ private OrbotHelper.StatusCallback statusCallback = new OrbotHelper.StatusCallback() {
+
+ @Override
+ public void onStatus(Intent statusIntent) {
+ StringBuilder extras = new StringBuilder();
+ for (String key : statusIntent.getExtras().keySet()) {
+ Object val = statusIntent.getExtras().get(key);
+
+ extras.append(String.format(Locale.ENGLISH, "%s - '%s'", key, val == null ? "null" : val.toString()));
+ }
+ VpnStatus.logDebug("Got Orbot status: " + extras);
+ }
+
+ @Override
+ public void onNotYetInstalled() {
+ VpnStatus.logDebug("Orbot not yet installed");
+ }
+
+ @Override
+ public void onOrbotReady(Intent intent, String socksHost, int socksPort) {
+ mResumeHandler.removeCallbacks(orbotStatusTimeOutRunnable);
+ sendProxyCMD(Connection.ProxyType.SOCKS5, socksHost, Integer.toString(socksPort), false);
+ OrbotHelper.get(mOpenVPNService).removeStatusCallback(this);
+ }
+
+ @Override
+ public void onDisabled(Intent intent) {
+ VpnStatus.logWarning("Orbot integration for external applications is disabled. Waiting %ds before connecting to the default port. Enable external app integration in Orbot or use Socks v5 config instead of Orbot to avoid this delay.");
+ }
+ };
+ private transient Connection mCurrentProxyConnection;
public OpenVpnManagementThread(VpnProfile profile, OpenVPNService openVpnService) {
mProfile = profile;
@@ -60,14 +100,21 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement {
}
- private Runnable mResumeHoldRunnable = new Runnable() {
- @Override
- public void run() {
- if (shouldBeRunning()) {
- releaseHoldCmd();
+ private static boolean stopOpenVPN() {
+ synchronized (active) {
+ boolean sendCMD = false;
+ for (OpenVpnManagementThread mt : active) {
+ sendCMD = mt.managmentCommand("signal SIGINT\n");
+ try {
+ if (mt.mSocket != null)
+ mt.mSocket.close();
+ } catch (IOException e) {
+ // Ignore close error on already closed socket
+ }
}
+ return sendCMD;
}
- };
+ }
public boolean openManagementInterface(@NonNull Context c) {
// Could take a while to open connection
@@ -122,7 +169,6 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement {
return false;
}
-
@Override
public void run() {
byte[] buffer = new byte[2048];
@@ -198,9 +244,13 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement {
//ParcelFileDescriptor pfd = ParcelFileDescriptor.fromFd(fdint);
//pfd.close();
- NativeUtils.jniclose(fdint);
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+ fdCloseLollipop(fd);
+ } else {
+ NativeUtils.jniclose(fdint);
+ }
return;
- } catch (NoSuchMethodException | IllegalArgumentException | InvocationTargetException | IllegalAccessException | NullPointerException e) {
+ } catch ( NoSuchMethodException | IllegalArgumentException | InvocationTargetException | IllegalAccessException | NullPointerException e) {
VpnStatus.logException("Failed to retrieve fd from socket (" + fd + ")", e);
}
@@ -208,6 +258,15 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement {
}
+ @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
+ private void fdCloseLollipop(FileDescriptor fd) {
+ try {
+ Os.close(fd);
+ } catch (Exception e) {
+ VpnStatus.logException("Failed to close fd (" + fd + ")", e);
+ }
+ }
+
private String processInput(String pendingInput) {
@@ -223,11 +282,9 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement {
return pendingInput;
}
-
private void processCommand(String command) {
//Log.i(TAG, "Line from managment" + command);
-
if (command.startsWith(">") && command.contains(":")) {
String[] parts = command.split(":", 2);
String cmd = parts[0].substring(1);
@@ -263,6 +320,9 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement {
case "PK_SIGN":
processSignCommand(argument);
break;
+ case "INFOMSG":
+ processInfoMessage(argument);
+ break;
default:
VpnStatus.logWarning("MGMT: Got unrecognized command" + command);
Log.i(TAG, "Got unrecognized command" + command);
@@ -281,6 +341,14 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement {
}
}
+ private void processInfoMessage(String info)
+ {
+ if (info.startsWith("OPEN_URL:"))
+ {
+ mOpenVPNService.trigger_url_open(info);
+ }
+ }
+
private void processLogMessage(String argument) {
String[] args = argument.split(",", 4);
// 0 unix time stamp
@@ -367,7 +435,6 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement {
//managmentCommand("log on all\n");
}
-
public void releaseHold() {
if (mWaitingForRelease)
releaseHoldCmd();
@@ -375,27 +442,81 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement {
private void processProxyCMD(String argument) {
String[] args = argument.split(",", 3);
- SocketAddress proxyaddr = ProxyDetection.detectProxy(mProfile);
+ Connection.ProxyType proxyType = Connection.ProxyType.NONE;
+
+ int connectionEntryNumber = Integer.parseInt(args[0]) - 1;
+ String proxyport = null;
+ String proxyname = null;
+ boolean proxyUseAuth = false;
+
+ if (mProfile.mConnections.length > connectionEntryNumber) {
+ Connection connection = mProfile.mConnections[connectionEntryNumber];
+ proxyType = connection.mProxyType;
+ proxyname = connection.mProxyName;
+ proxyport = connection.mProxyPort;
+ proxyUseAuth = connection.mUseProxyAuth;
+
+ // Use transient variable to remember http user/password
+ mCurrentProxyConnection = connection;
+
+ } else {
+ VpnStatus.logError(String.format(Locale.ENGLISH, "OpenVPN is asking for a proxy of an unknown connection entry (%d)", connectionEntryNumber));
+ }
- if (args.length >= 2) {
+ // atuo detection of proxy
+ if (proxyType == Connection.ProxyType.NONE) {
+ SocketAddress proxyaddr = ProxyDetection.detectProxy(mProfile);
+ if (proxyaddr instanceof InetSocketAddress) {
+ InetSocketAddress isa = (InetSocketAddress) proxyaddr;
+ proxyType = Connection.ProxyType.HTTP;
+ proxyname = isa.getHostName();
+ proxyport = String.valueOf(isa.getPort());
+ proxyUseAuth = false;
+
+ }
+ }
+
+
+ if (args.length >= 2 && proxyType == Connection.ProxyType.HTTP) {
String proto = args[1];
if (proto.equals("UDP")) {
- proxyaddr = null;
+ proxyname = null;
+ VpnStatus.logInfo("Not using an HTTP proxy since the connection uses UDP");
}
}
- if (proxyaddr instanceof InetSocketAddress) {
- InetSocketAddress isa = (InetSocketAddress) proxyaddr;
- VpnStatus.logInfo(R.string.using_proxy, isa.getHostName(), isa.getPort());
+ if (proxyType == Connection.ProxyType.ORBOT) {
+ VpnStatus.updateStateString("WAIT_ORBOT", "Waiting for Orbot to start", R.string.state_waitorbot, ConnectionStatus.LEVEL_CONNECTING_NO_SERVER_REPLY_YET);
+ OrbotHelper orbotHelper = OrbotHelper.get(mOpenVPNService);
+ if (!orbotHelper.checkTorReceier(mOpenVPNService))
+ VpnStatus.logError("Orbot does not seem to be installed!");
+
+ mResumeHandler.postDelayed(orbotStatusTimeOutRunnable, ORBOT_TIMEOUT_MS);
+ orbotHelper.addStatusCallback(mOpenVPNService, statusCallback);
+
+ orbotHelper.sendOrbotStartAndStatusBroadcast();
+
+ } else {
+ sendProxyCMD(proxyType, proxyname, proxyport, proxyUseAuth);
+ }
+ }
+
+ private void sendProxyCMD(Connection.ProxyType proxyType, String proxyname, String proxyport, boolean usePwAuth) {
+ if (proxyType != Connection.ProxyType.NONE && proxyname != null) {
+
+ VpnStatus.logInfo(R.string.using_proxy, proxyname, proxyname);
- String proxycmd = String.format(Locale.ENGLISH, "proxy HTTP %s %d\n", isa.getHostName(), isa.getPort());
+ String pwstr = usePwAuth ? " auto" : "";
+
+ String proxycmd = String.format(Locale.ENGLISH, "proxy %s %s %s%s\n",
+ proxyType == Connection.ProxyType.HTTP ? "HTTP" : "SOCKS",
+ proxyname, proxyport, pwstr);
managmentCommand(proxycmd);
} else {
managmentCommand("proxy NONE\n");
}
-
}
private void processState(String argument) {
@@ -408,7 +529,6 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement {
VpnStatus.updateStateString(currentstate, args[2]);
}
-
private void processByteCount(String argument) {
// >BYTECOUNT:{BYTES_IN},{BYTES_OUT}
int comma = argument.indexOf(',');
@@ -419,7 +539,6 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement {
}
-
private void processNeedCommand(String argument) {
int p1 = argument.indexOf('\'');
int p2 = argument.indexOf('\'', p1 + 1);
@@ -452,7 +571,8 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement {
*/
if (routeparts.length == 5) {
- if (BuildConfig.DEBUG) Assert.assertEquals("dev", routeparts[3]);
+ //if (BuildConfig.DEBUG)
+ // assertEquals("dev", routeparts[3]);
mOpenVPNService.addRoute(routeparts[0], routeparts[1], routeparts[2], routeparts[4]);
} else if (routeparts.length >= 3) {
mOpenVPNService.addRoute(routeparts[0], routeparts[1], routeparts[2], null);
@@ -473,8 +593,10 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement {
mOpenVPNService.setLocalIP(ifconfigparts[0], ifconfigparts[1], mtu, ifconfigparts[3]);
break;
case "IFCONFIG6":
- mOpenVPNService.setLocalIPv6(extra);
-
+ String[] ifconfig6parts = extra.split(" ");
+ mtu = Integer.parseInt(ifconfig6parts[1]);
+ mOpenVPNService.setMtu(mtu);
+ mOpenVPNService.setLocalIPv6(ifconfig6parts[0]);
break;
case "PERSIST_TUN_ACTION":
// check if tun cfg stayed the same
@@ -546,6 +668,10 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement {
try {
+ // Ignore Auth token message, already managed by openvpn itself
+ if (argument.startsWith("Auth-Token:")) {
+ return;
+ }
int p1 = argument.indexOf('\'');
int p2 = argument.indexOf('\'', p1 + 1);
@@ -560,17 +686,26 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement {
}
String pw = null;
+ String username = null;
if (needed.equals("Private Key")) {
pw = mProfile.getPasswordPrivateKey();
} else if (needed.equals("Auth")) {
pw = mProfile.getPasswordAuth();
+ username = mProfile.mUsername;
- String usercmd = String.format("username '%s' %s\n",
- needed, VpnProfile.openVpnEscape(mProfile.mUsername));
- managmentCommand(usercmd);
+ } else if (needed.equals("HTTP Proxy")) {
+ if( mCurrentProxyConnection != null) {
+ pw = mCurrentProxyConnection.mProxyAuthPassword;
+ username = mCurrentProxyConnection.mProxyAuthUser;
+ }
}
if (pw != null) {
+ if (username !=null) {
+ String usercmd = String.format("username '%s' %s\n",
+ needed, VpnProfile.openVpnEscape(username));
+ managmentCommand(usercmd);
+ }
String cmd = String.format("password '%s' %s\n", needed, VpnProfile.openVpnEscape(pw));
managmentCommand(cmd);
} else {
@@ -580,28 +715,10 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement {
}
-
private void proccessPWFailed(String needed, String args) {
VpnStatus.updateStateString("AUTH_FAILED", needed + args, R.string.state_auth_failed, ConnectionStatus.LEVEL_AUTH_FAILED);
}
-
- private static boolean stopOpenVPN() {
- synchronized (active) {
- boolean sendCMD = false;
- for (OpenVpnManagementThread mt : active) {
- sendCMD = mt.managmentCommand("signal SIGINT\n");
- try {
- if (mt.mSocket != null)
- mt.mSocket.close();
- } catch (IOException e) {
- // Ignore close error on already closed socket
- }
- }
- return sendCMD;
- }
- }
-
@Override
public void networkChange(boolean samenetwork) {
if (mWaitingForRelease)
@@ -634,7 +751,7 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement {
private void processSignCommand(String b64data) {
- String signed_string = mProfile.getSignedData(b64data);
+ String signed_string = mProfile.getSignedData(mOpenVPNService, b64data, false);
if (signed_string == null) {
managmentCommand("pk-sig\n");
diff --git a/app/src/main/java/de/blinkt/openvpn/core/OrbotHelper.java b/app/src/main/java/de/blinkt/openvpn/core/OrbotHelper.java
new file mode 100644
index 00000000..68f5835f
--- /dev/null
+++ b/app/src/main/java/de/blinkt/openvpn/core/OrbotHelper.java
@@ -0,0 +1,202 @@
+/*
+ * Copyright (c) 2012-2018 Arne Schwabe
+ * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt
+ */
+
+/*
+ * Portions Copyright 2014-2016 Hans-Christoph Steiner
+ * Portions Copyright 2012-2016 Nathan Freitas
+ * Portions Copyright (c) 2016 CommonsWare, LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package de.blinkt.openvpn.core;
+
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.text.TextUtils;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import static de.blinkt.openvpn.core.OpenVPNService.ORBOT_PACKAGE_NAME;
+
+public class OrbotHelper {
+ //! Based on the class from NetCipher but stripped down and modified for icsopenvpn
+
+ /**
+ * {@link Intent} send by Orbot with {@code ON/OFF/STARTING/STOPPING} status
+ * included as an {@link #EXTRA_STATUS} {@code String}. Your app should
+ * always receive {@code ACTION_STATUS Intent}s since any other app could
+ * start Orbot. Also, user-triggered starts and stops will also cause
+ * {@code ACTION_STATUS Intent}s to be broadcast.
+ */
+ public final static String ACTION_STATUS = "org.torproject.android.intent.action.STATUS";
+ public final static String STATUS_ON = "ON";
+ public final static String STATUS_STARTS_DISABLED = "STARTS_DISABLED";
+
+ public final static String STATUS_STARTING = "STARTING";
+ public final static String STATUS_STOPPING = "STOPPING";
+ public final static String EXTRA_STATUS = "org.torproject.android.intent.extra.STATUS";
+ /**
+ * A request to Orbot to transparently start Tor services
+ */
+ public final static String ACTION_START = "org.torproject.android.intent.action.START";
+ public final static String EXTRA_PACKAGE_NAME = "org.torproject.android.intent.extra.PACKAGE_NAME";
+ public static final int SOCKS_PROXY_PORT_DEFAULT = 9050;
+ private static OrbotHelper mInstance;
+
+ String EXTRA_SOCKS_PROXY_HOST = "org.torproject.android.intent.extra.SOCKS_PROXY_HOST";
+ String EXTRA_SOCKS_PROXY_PORT = "org.torproject.android.intent.extra.SOCKS_PROXY_PORT";
+ private Context mContext;
+ private Set<StatusCallback> statusCallbacks = new HashSet<>();
+ private BroadcastReceiver orbotStatusReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context c, Intent intent) {
+ if (TextUtils.equals(intent.getAction(),
+ OrbotHelper.ACTION_STATUS)) {
+ for (StatusCallback cb : statusCallbacks) {
+ cb.onStatus(intent);
+ }
+
+ String status = intent.getStringExtra(EXTRA_STATUS);
+ if (TextUtils.equals(status, STATUS_ON)) {
+ int socksPort = intent.getIntExtra(EXTRA_SOCKS_PROXY_PORT, SOCKS_PROXY_PORT_DEFAULT);
+ String socksHost = intent.getStringExtra(EXTRA_SOCKS_PROXY_HOST);
+ if (TextUtils.isEmpty(socksHost))
+ socksHost = "127.0.0.1";
+ for (StatusCallback cb : statusCallbacks) {
+ cb.onOrbotReady(intent, socksHost, socksPort);
+ }
+ } else if (TextUtils.equals(status, STATUS_STARTS_DISABLED)) {
+ for (StatusCallback cb : statusCallbacks)
+ cb.onDisabled(intent);
+ }
+
+ }
+ }
+ };
+
+ private OrbotHelper() {
+
+ }
+
+ public static OrbotHelper get(OpenVPNService mOpenVPNService) {
+ if (mInstance == null)
+ mInstance = new OrbotHelper();
+ return mInstance;
+ }
+
+ /**
+ * Gets an {@link Intent} for starting Orbot. Orbot will reply with the
+ * current status to the {@code packageName} of the app in the provided
+ * {@link Context} (i.e. {@link Context#getPackageName()}.
+ */
+ public static Intent getOrbotStartIntent(Context context) {
+ Intent intent = new Intent(ACTION_START);
+ intent.setPackage(ORBOT_PACKAGE_NAME);
+ intent.putExtra(EXTRA_PACKAGE_NAME, context.getPackageName());
+ return intent;
+ }
+
+ public static boolean checkTorReceier(Context c) {
+ Intent startOrbot = getOrbotStartIntent(c);
+ PackageManager pm = c.getPackageManager();
+ Intent result = null;
+ List<ResolveInfo> receivers =
+ pm.queryBroadcastReceivers(startOrbot, 0);
+
+ return receivers != null && receivers.size() > 0;
+ }
+
+ /**
+ * Adds a StatusCallback to be called when we find out that
+ * Orbot is ready. If Orbot is ready for use, your callback
+ * will be called with onEnabled() immediately, before this
+ * method returns.
+ *
+ * @param cb a callback
+ * @return the singleton, for chaining
+ */
+ public synchronized OrbotHelper addStatusCallback(Context c, StatusCallback cb) {
+ if (statusCallbacks.size() == 0) {
+ c.getApplicationContext().registerReceiver(orbotStatusReceiver,
+ new IntentFilter(OrbotHelper.ACTION_STATUS));
+ mContext = c.getApplicationContext();
+ }
+ if (!checkTorReceier(c))
+ cb.onNotYetInstalled();
+ statusCallbacks.add(cb);
+ return (this);
+ }
+
+ /**
+ * Removes an existing registered StatusCallback.
+ *
+ * @param cb the callback to remove
+ * @return the singleton, for chaining
+ */
+ public synchronized void removeStatusCallback(StatusCallback cb) {
+ statusCallbacks.remove(cb);
+ if (statusCallbacks.size() == 0)
+ mContext.unregisterReceiver(orbotStatusReceiver);
+ }
+
+ public void sendOrbotStartAndStatusBroadcast() {
+ mContext.sendBroadcast(getOrbotStartIntent(mContext));
+ }
+
+ private void startOrbotService(String action) {
+ Intent clearVPNMode = new Intent();
+ clearVPNMode.setComponent(new ComponentName(ORBOT_PACKAGE_NAME, ".service.TorService"));
+ clearVPNMode.setAction(action);
+ mContext.startService(clearVPNMode);
+ }
+
+ public interface StatusCallback {
+ /**
+ * Called when Orbot is operational
+ *
+ * @param statusIntent an Intent containing information about
+ * Orbot, including proxy ports
+ */
+ void onStatus(Intent statusIntent);
+
+
+ /**
+ * Called if Orbot is not yet installed. Usually, you handle
+ * this by checking the return value from init() on OrbotInitializer
+ * or calling isInstalled() on OrbotInitializer. However, if
+ * you have need for it, if a callback is registered before
+ * an init() call determines that Orbot is not installed, your
+ * callback will be called with onNotYetInstalled().
+ */
+ void onNotYetInstalled();
+
+ void onOrbotReady(Intent intent, String socksHost, int socksPort);
+
+ /**
+ * Called if Orbot background control is disabled.
+ * @param intent the intent delivered
+ */
+ void onDisabled(Intent intent);
+ }
+}
diff --git a/app/src/main/java/de/blinkt/openvpn/core/ProfileManager.java b/app/src/main/java/de/blinkt/openvpn/core/ProfileManager.java
index f776fc2e..b9edc4b2 100644
--- a/app/src/main/java/de/blinkt/openvpn/core/ProfileManager.java
+++ b/app/src/main/java/de/blinkt/openvpn/core/ProfileManager.java
@@ -128,6 +128,7 @@ public class ProfileManager {
}
public static void setTemporaryProfile(Context c, VpnProfile tmp) {
+ tmp.mTemporaryProfile = true;
ProfileManager.tmpprofile = tmp;
saveProfile(c, tmp, true, true);
}
@@ -174,8 +175,9 @@ public class ProfileManager {
vlist.add(TEMPORARY_PROFILE_FILENAME);
for (String vpnentry : vlist) {
+ ObjectInputStream vpnfile=null;
try {
- ObjectInputStream vpnfile = new ObjectInputStream(context.openFileInput(vpnentry + ".vp"));
+ vpnfile = new ObjectInputStream(context.openFileInput(vpnentry + ".vp"));
VpnProfile vp = ((VpnProfile) vpnfile.readObject());
// Sanity check
@@ -189,9 +191,18 @@ public class ProfileManager {
profiles.put(vp.getUUID().toString(), vp);
}
+
} catch (IOException | ClassNotFoundException e) {
if (!vpnentry.equals(TEMPORARY_PROFILE_FILENAME))
VpnStatus.logException("Loading VPN List", e);
+ } finally {
+ if (vpnfile!=null) {
+ try {
+ vpnfile.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
}
}
}
diff --git a/app/src/main/java/de/blinkt/openvpn/core/VPNLaunchHelper.java b/app/src/main/java/de/blinkt/openvpn/core/VPNLaunchHelper.java
index 97a73964..810974df 100644
--- a/app/src/main/java/de/blinkt/openvpn/core/VPNLaunchHelper.java
+++ b/app/src/main/java/de/blinkt/openvpn/core/VPNLaunchHelper.java
@@ -48,7 +48,7 @@ public class VPNLaunchHelper {
}
}
- return null;
+ throw new RuntimeException("Cannot find any execulte for this device's ABIs " + abis.toString());
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
diff --git a/app/src/main/java/de/blinkt/openvpn/core/VpnStatus.java b/app/src/main/java/de/blinkt/openvpn/core/VpnStatus.java
index a9cc4f18..5fbb440b 100644
--- a/app/src/main/java/de/blinkt/openvpn/core/VpnStatus.java
+++ b/app/src/main/java/de/blinkt/openvpn/core/VpnStatus.java
@@ -300,6 +300,8 @@ public class VpnStatus {
return R.string.state_resolve;
case "TCP_CONNECT":
return R.string.state_tcp_connect;
+ case "AUTH_PENDING":
+ return R.string.state_auth_pending;
default:
return R.string.unknown_state;
}
@@ -323,7 +325,7 @@ public class VpnStatus {
private static ConnectionStatus getLevel(String state) {
String[] noreplyet = {"CONNECTING", "WAIT", "RECONNECTING", "RESOLVE", "TCP_CONNECT"};
- String[] reply = {"AUTH", "GET_CONFIG", "ASSIGN_IP", "ADD_ROUTES"};
+ String[] reply = {"AUTH", "GET_CONFIG", "ASSIGN_IP", "ADD_ROUTES", "AUTH_PENDING"};
String[] connected = {"CONNECTED"};
String[] notconnected = {"DISCONNECTED", "EXITING"};
@@ -385,7 +387,7 @@ public class VpnStatus {
for (StateListener sl : stateListener) {
sl.updateState(state, msg, resid, level);
}
- newLogItem(new LogItem((LogLevel.DEBUG), String.format("New OpenVPN Status (%s->%s): %s",state,level.toString(),msg)));
+ //newLogItem(new LogItem((LogLevel.DEBUG), String.format("New OpenVPN Status (%s->%s): %s",state,level.toString(),msg)));
}
public static void logInfo(String message) {
diff --git a/app/src/main/res/values-be/plurals-icsopenvpn.xml b/app/src/main/res/values-be/plurals-icsopenvpn.xml
new file mode 100755
index 00000000..70489fbc
--- /dev/null
+++ b/app/src/main/res/values-be/plurals-icsopenvpn.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<resources></resources>
diff --git a/app/src/main/res/values-be/strings-icsopenvpn.xml b/app/src/main/res/values-be/strings-icsopenvpn.xml
new file mode 100755
index 00000000..45ec6c69
--- /dev/null
+++ b/app/src/main/res/values-be/strings-icsopenvpn.xml
@@ -0,0 +1,464 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!--
+ ~ Copyright (c) 2012-2016 Arne Schwabe
+ ~ Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt
+ -->
+<resources>
+
+ <string name="address">Адрас сервера:</string>
+ <string name="port">Порт сервера:</string>
+ <string name="location">Размяшчэнне</string>
+ <string name="cant_read_folder">Не атрымоўваецца прачытаць каталог</string>
+ <string name="select">Выбраць</string>
+ <string name="cancel">Адмена</string>
+ <string name="no_data">Няма дадзеных</string>
+ <string name="useLZO">Сціск LZO</string>
+ <string name="client_no_certificate">Няма сертыфіката</string>
+ <string name="client_certificate_title">Сертыфікат кліента</string>
+ <string name="client_key_title">Ключ сертыфіката кліента</string>
+ <string name="client_pkcs12_title">Файл PKCS12</string>
+ <string name="ca_title">Сертыфікат ЦС</string>
+ <string name="no_certificate">Трэба выбраць сертыфікат</string>
+ <string name="copyright_guicode">Зыходны код і адсочванне праблем даступныя на https://github.com/schwabe/ics-openvpn/</string>
+ <string name="copyright_others">Дадзеная праграма выкарыстоўвае наступныя кампаненты; гледзіце зыходны код для атрымання падрабязнай інфармацыі пра ліцэнзію</string>
+ <string name="about">Пра дадатак</string>
+ <string name="vpn_list_title">Профілі</string>
+ <string name="vpn_type">Тып</string>
+ <string name="pkcs12pwquery">Пароль для PKCS12</string>
+ <string name="file_select">Выбраць&#8230;</string>
+ <string name="file_nothing_selected">Вы павінны выбраць файл</string>
+ <string name="useTLSAuth">Скарыстаць аўтэнтыфікацыю TLS</string>
+ <string name="tls_direction">Кірунак праверкі TLS</string>
+ <string name="ipv6_dialog_tile">Увядзіце адрас/маску падсеткі IPv6 у фармаце CIDR (прыкладам, 2000:dd::23/64)</string>
+ <string name="ipv4_dialog_title">Увядзіце адрас/маску падсеткі IPv4 у фармаце CIDR (прыкладам, 1.2.3.4/24)</string>
+ <string name="ipv4_address">Адрас IPv4</string>
+ <string name="ipv6_address">Адрас IPv6</string>
+ <string name="custom_option_warning">Увядзіце дадатковыя параметры OpenVPN. Выкарыстоўвайце гэту магчымасць з вялікай асцярожнасцю. Калі вы лічыце, што адсутнічае важны параметр, звяжыцеся з аўтарам</string>
+ <string name="auth_username">Імя карыстача</string>
+ <string name="auth_pwquery">Пароль</string>
+ <string name="static_keys_info">Для канфігурацыі са статычнымі сертыфікатамі будуць выкарыстоўвацца ключы TLS</string>
+ <string name="configure_the_vpn">Налада VPN</string>
+ <string name="menu_add_profile">Дадаць канфігурацыю</string>
+ <string name="add_profile_name_prompt">Увядзіце назву новай канфігурацыі</string>
+ <string name="duplicate_profile_name">Калі ласка, увядзіце ўнікальную назву канфігурацыі</string>
+ <string name="profilename">Назва канфігурацыі</string>
+ <string name="no_keystore_cert_selected">Трэба выбраць сертыфікат карыстача</string>
+ <string name="no_ca_cert_selected">Трэба выбраць сертыфікат ЦС</string>
+ <string name="no_error_found">Памылак не знойдзена</string>
+ <string name="config_error_found">Ошибка в конфигурации</string>
+ <string name="ipv4_format_error">Немагчыма распазнаць IPv4 адрас</string>
+ <string name="custom_route_format_error">Немагчыма распазнаць карыстацкія маршруты</string>
+ <string name="pw_query_hint">(пакіньце пустым для запыту па вымозе)</string>
+ <string name="vpn_shortcut">Цэтлік OpenVPN</string>
+ <string name="vpn_launch_title">Падключэнне да VPN&#8230;</string>
+ <string name="shortcut_profile_notfound">Не знойдзены профіль, азначаны ў цэтліку</string>
+ <string name="random_host_prefix">Выпадковы прэфікс вузла</string>
+ <string name="random_host_summary">Дадае 6 выпадковых знакаў перад іменем хаста</string>
+ <string name="custom_config_title">Уключыць карыстацкія параметры</string>
+ <string name="custom_config_summary">Карыстацкія параметры. Скарыстайце з асцярожнасцю!</string>
+ <string name="route_rejected">Маршрут адхілены Android</string>
+ <string name="cancel_connection">Адключыць</string>
+ <string name="cancel_connection_long">Адключыць VPN</string>
+ <string name="clear_log">ачысціць журнал</string>
+ <string name="title_cancel">Пацверджанне скасавання</string>
+ <string name="cancel_connection_query">Адключыць актыўны VPN/скасаваць спробу падключэння?</string>
+ <string name="remove_vpn">Выдаліць VPN</string>
+ <string name="check_remote_tlscert">Правярае, ці выкарыстоўвае сервер сертыфікат з сервернымі пашырэннямі TLS (--remote-cert-tls server)</string>
+ <string name="check_remote_tlscert_title">Чакаць серверны сертыфікат TLS</string>
+ <string name="remote_tlscn_check_summary">Праверка DN аб\'екта падаленага сертыфіката</string>
+ <string name="remote_tlscn_check_title">Праверка імя хаста сертыфіката</string>
+ <string name="enter_tlscn_dialog">Увядзіце значэнне для праверкі DN выдаленага сертыфіката (прыкладам, C=DE, L=Paderborn, OU=Avian IP Carriers, CN=openvpn.blinkt.de)\n\n \Магчымыя значэнні: поўны DN ці RDN (у прыкладзе вышэй openvpn.blinkt.de) ці толькі прэфікс RDN для праверкі.\n\nПры выкарыстанні прэфікса RDN, «Server» падыдзе для «Server-1» і «Server-2»\n\nПры пустой тэкставай падлозе будзе правярацца, што RDN супадае з іменем вузла.\n\nПадрабязнасці гледзіце ў кіраўніцтве OpenVPN 2.3.1+, падзел --verify-x509-name</string>
+ <string name="enter_tlscn_title">Аб\'ект падаленага сертыфіката</string>
+ <string name="tls_key_auth">Уключыць аўтэнтыфікацыю па TLS ключу</string>
+ <string name="tls_auth_file">Файл аўтэнтыфікацыі TLS</string>
+ <string name="pull_on_summary">Запыт IP-адраса, маршрутаў і параметраў ад сервера.</string>
+ <string name="pull_off_summary">Ігнараваць усе параметры сервера. Параметры павінны быць азначаны ніжэй.</string>
+ <string name="use_pull">Запытваць параметры</string>
+ <string name="dns">DNS</string>
+ <string name="override_dns">Перавызначыць параметры DNS ад сервера</string>
+ <string name="dns_override_summary">Выкарыстоўваць вашы DNS</string>
+ <string name="searchdomain">Дамен пошуку</string>
+ <string name="dns1_summary">DNS-сервер для выкарыстання.</string>
+ <string name="dns_server">DNS-сервер</string>
+ <string name="secondary_dns_message">Другасны DNS-сервер выкарыстоўваецца, калі не атрыманы адказ ад першага сервера DNS.</string>
+ <string name="backup_dns">Рэзервовы сервер DNS</string>
+ <string name="ignored_pushed_routes">Ігнараваць пасыланыя маршруты</string>
+ <string name="ignore_routes_summary">Ігнараваць маршруты, пасыланыя серверам.</string>
+ <string name="default_route_summary">Перанакіроўвае ўвесь трафік праз VPN</string>
+ <string name="use_default_title">Выкарыстоўваць маршрут па змаўчанні</string>
+ <string name="custom_route_message">Увядзіце карыстальніцкія маршруты. Скарыстайце толькі адрас прызначэння ў фармаце CIDR. \"10.0.0.0/8 2002::/16\" скіруе сеткі 10.0.0.0/8 і 2002::/16 праз VPN.</string>
+ <string name="custom_route_message_excluded">Маршруты, якія НЕ павінны скіроўвацца праз VPN. Скарыстайце той жа сінтаксіс, што і для ўключаных маршрутаў.</string>
+ <string name="custom_routes_title">Карыстальніцкія маршруты</string>
+ <string name="custom_routes_title_excluded">Вынятыя сеткі</string>
+ <string name="log_verbosity_level">Ровень дэталізацыі журнала</string>
+ <string name="float_summary">Разрешить аутентифицированные пакеты с любого IP-адреса</string>
+ <string name="float_title">Дазволіць «плавальны» сервер</string>
+ <string name="custom_options_title">Карыстальніцкія параметры</string>
+ <string name="edit_vpn">Рэдагаванне параметраў VPN</string>
+ <string name="remove_vpn_query">Выдаліць профіль VPN «%s»?</string>
+ <string name="tun_error_helpful">На некаторых кастамных зборках права на /dev/tun могуць быць няправільнымі ці tun-модуль можа быць не ўключаны. Для прашыўкі CM9 можаце паспрабаваць выправіць уладальніка проста з налад праграмы</string>
+ <string name="tun_open_error">Не атрымоўваецца адкрыць tun інтэрфейс</string>
+ <string name="error">"Памылка: "</string>
+ <string name="clear">Ачысціць</string>
+ <string name="last_openvpn_tun_config">Адкрыццё tun-інтэрфейсу:</string>
+ <string name="local_ip_info">Адрас IPv4: %1$s/%2$d IPv6: %3$s MTU: %4$d</string>
+ <string name="dns_server_info">DNS-сервер: %1$s, Дамен: %2$s</string>
+ <string name="routes_info_incl">Маршруты: %1$s %2$s</string>
+ <string name="routes_info_excl">Вынятыя маршруты: %1$s %2$s</string>
+ <string name="routes_debug">Падлучаныя маршруты сэрвісу Vpn: %1$s %2$s</string>
+ <string name="ip_not_cidr">Атрымана інфармацыя інтэрфейсу %1$s і %2$s, другі адрас з\'яўляецца падаленым адрасам канала. Выкарыстоўваецца сеткавая маска /32 для лакальнага IP адраса. Рэжым, усталяваны OpenVPN: \"%3$s\".</string>
+ <string name="route_not_cidr">Немагчыма скарыстаць выразы %1$s і %2$s як маршрут па стандарце CIDR. выкарыстоўваецца /32 як маска падсеткі.</string>
+ <string name="route_not_netip">Маршрут выпраўлены з %1$s/%2$s на %3$s/%2$s</string>
+ <string name="keychain_access">Не атрымоўваецца атрымаць доступ да сховішча ключоў і сертыфікатаў Android. Гэта можа быць выклікана абнаўленнем прашыўкі ці аднаўлення старой копіі дадатку ці яго налад. Калі ласка, адрэдагуйце профіль VPN і наноў пакажыце ключы і сертыфікаты ў падзеле Асноўныя параметры.</string>
+ <string name="version_info">%1$s %2$s</string>
+ <string name="send_logfile">Адправіць файл журнала</string>
+ <string name="send">Адправіць</string>
+ <string name="ics_openvpn_log_file">ICS OpenVPN лог файл</string>
+ <string name="copied_entry">Запіс журнала скапіяваны ў буфер абмену</string>
+ <string name="tap_mode">Рэжым TAP</string>
+ <string name="faq_tap_mode">Рэжым TAP немагчымы на прыладах без root-а. Таму гэты дадатак не падтрымвае TAP</string>
+ <string name="tap_faq2">Ізноў? Вы здзекуецеся? Не падтрымваецца рэжым TAP і просьбы да аўтара пра гэта не дапамогуць яму рэалізавацца.</string>
+ <string name="tap_faq3">Трэці раз? Насамрэч можна было б пісаць эмулятар TAP, заснаваныя на tun, які б дадаваў інфармацыю 2 роўні пры адпраўленні і здабываў бы яе пры атрыманні. Але гэты эмулятар запатрабуе таксама ARP і, магчыма, кліента DHCP. Я не ведаю нікога, хто мог бы гэтым заняцца. Звяжыцеся са мной, калі вы хочаце заняцца гэтым.</string>
+ <string name="faq">Пытанні і адказы</string>
+ <string name="copying_log_entries">Капіяванне запісамі журнала</string>
+ <string name="faq_copying">Для капіявання аднаго запісу журнала трэба нажаць на яе і ўтрымваць. Каб скапіяваць/адправіць увесь файл журнала, скарыстайце опцыю «Адправіць файл журнала». Калі яна ўтоена, скарыстайце апаратную кнопку меню.</string>
+ <string name="faq_shortcut">Цэтлік для запуску</string>
+ <string name="faq_howto_shortcut">Вы можаце стварыць цэтлік для запуску OpenVPN на працоўным стале. У залежнасці ад вашага асяроддзя трэба дадаць цэтлік ці віджэт.</string>
+ <string name="no_vpn_support_image">Ваша прашыўка не падтрымвае VPNService API, прабачыце :(</string>
+ <string name="encryption">Шыфраванне</string>
+ <string name="cipher_dialog_title">Вызначце метад шыфравання</string>
+ <string name="chipher_dialog_message">Вызначце алгарытм шыфрацыі, які выкарыстоўваецца OpenVPN. Пакіньце пустым, каб скарыстаць шыфраванне па змаўчанні.</string>
+ <string name="auth_dialog_message">Увядзіце хэш-функцыю для аўтэнтыфікацыі ў OpenVPN. Пакіньце пустым для выкарыстання значэння па змаўчанні.</string>
+ <string name="settings_auth">Аўтэнтыфікацыя/шыфраванне</string>
+ <string name="file_explorer_tab">Агляд файлаў</string>
+ <string name="inline_file_tab">Убудаваны файл</string>
+ <string name="error_importing_file">Памылка імпарту файла</string>
+ <string name="import_error_message">Не атрымалася імпартаваць файл з файлавай сістэмы</string>
+ <string name="inline_file_data">[[Убудаваны файл дадзеных]]</string>
+ <string name="opentun_no_ipaddr">Адмова ў адкрыцці прылады tun без інфармацыі пра IP-адрас</string>
+ <string name="menu_import">Імпарт канфігурацыі з файла .ovpn</string>
+ <string name="menu_import_short">Імпарт</string>
+ <string name="import_content_resolve_error">Не атрымалася прачытаць канфігурацыю для імпарту</string>
+ <string name="error_reading_config_file">Памылка чытання файла канфігурацыі</string>
+ <string name="add_profile">Дадаць канфігурацыю</string>
+ <string name="import_could_not_open">Не атрымалася знайсці файл %1$s, азначаны ў файле канфігурацыі</string>
+ <string name="importing_config">Імпарт файла канфігурацыі з зыходнага %1$s</string>
+ <string name="import_warning_custom_options">Ваша канфігурацыя мела некалькі параметраў, якія не ўваходзяць у параметры стандартнай канфігурацыі. Гэтыя параметры былі вынесены ў карыстацкую канфігурацыю. Карыстацкая канфігурацыя адлюстроўваецца ніжэй:</string>
+ <string name="import_done">Файл канфігурацыі паспяхова прачытаны.</string>
+ <string name="nobind_summary">Не прывязвацца да лакальнага адраса і порта</string>
+ <string name="no_bind">Не выкарыстоўваць прывязкі</string>
+ <string name="import_configuration_file">Імпарт файла канфігурацыі</string>
+ <string name="faq_security_title">Меркаванні бяспекі</string>
+ <string name="faq_security">"Калі OpenVPN адчувальны да бяспекі, то дарэчныя будуць некалькі заўваг на яе рахунак. Усе дадзеныя на SD-карце ў існасці не абаронены. Кожны дадатак можа прачытаць іх (прыкладам, гэта праграма не патрабуе адмысловых прывілеяў на SD-карту). Дадзеныя гэтага дадатку могуць быць прачытаны толькі ім самім. Пры выкарыстанні опцыі імпарту сертыфікатаў і ключоў у дыялогавым акне дадзеныя захоўваюцца ў профілі VPN. Профілі VPN даступныя толькі гэтаму дадатку. (Не забудзьцеся потым выдаліць копіі на SD-карце). Нягледзячы на тое, што дадзеныя даступныя толькі гэтаму дадатку, яны ўсё яшчэ не зашыфраваны. Пры наяўнасці праў адміністратара (root) на тэлефоне ці праз нейкую ўразлівасць гэтыя дадзеныя можна выняць. Таксама захаваныя паролі захоўваюцца ў звычайным тэкставым выглядзе. Настойліва рэкамендуецца файлы pkcs12 імпартаваць у android keystore."</string>
+ <string name="import_vpn">Імпарт</string>
+ <string name="broken_image_cert_title">Памылка адлюстравання выбару сертыфіката</string>
+ <string name="broken_image_cert">Адбылася памылка пры спробе выкліку сістэмнага дыялогу выбару сертыфікатаў Android 4.0+. Гэтага не павінна было здарыцца на стандартнай прашыўцы. Можа быць у вашай прашыўцы сапсавана сховішча сертыфікатаў</string>
+ <string name="ipv4">IPv4</string>
+ <string name="ipv6">IPv6</string>
+ <string name="speed_waiting">Чаканне паведамлення пра стан&#8230;</string>
+ <string name="converted_profile">імпартаваны профіль</string>
+ <string name="converted_profile_i">імпартаваны профіль %d</string>
+ <string name="broken_images">Зламаныя прашыўкі</string>
+ <string name="broken_images_faq">&lt;p&gt; Вядома, што афіцыйныя прашыўкі HTC маюць дзіўныя праблемы з маршрутызацыяй, што прыводзіць да таго, што трафік не ідзе праз тунэль (гл. &lt;a href=\"https://github.com/schwabe/ics-openvpn/issues/18\"&gt;Issue 18&lt;/a&gt; у баг-трэкеры).&lt;/p&gt;&lt;p&gt;Таксама паведамлялася, што ў старых афіцыйных прашыўках SONY ад Xperia Arc S і Xperia Ray цалкам адсутнічае сэрвіс VPNService (гл. &lt;a href=\"https://github.com/schwabe/ics-openvpn/issues/29\"&gt;Issue 29&lt;/a&gt; у баг-трэкеры).&lt;/p&gt;&lt;p&gt;У некаторых неафіцыйных прашыўках модуль tun можа адсутнічаць, ці файл прылады /dev/tun можа мець няправільныя правы. Некаторыя прашыўкі CM9 могуць патрабаваць выпраўленні праў на /dev/tun у наладах «Хакі для дадзенай прылады».&lt;/p&gt;&lt;p&gt;І самае галоўнае: калі ў вас прашыўка з паказанымі праблемамі, паведаміце пра гэта вытворцу прылады. Чым больш за карыстачоў паведаміць пра праблему, тым больш за шанцы, што вытворца яе выправіць.&lt;/p&gt;</string>
+ <string name="pkcs12_file_encryption_key">Файл PKCS12-ключа</string>
+ <string name="private_key_password">Пароль закрытага ключа</string>
+ <string name="password">Пароль</string>
+ <string name="file_icon">файл значка</string>
+ <string name="tls_authentication">Аўтэнтыфікацыя/шыфраванне TLS</string>
+ <string name="generated_config">Згенераваная канфігурацыя</string>
+ <string name="generalsettings">Налады</string>
+ <string name="owner_fix_summary">Паспрабаваць змяніць уладальніка для /dev/tun. Некаторыя прашыўкі CM9 патрабуюць гэтага для карэктнай працы API OpenVPN. Патрабуецца root.</string>
+ <string name="owner_fix">Выправіць правы для /dev/tun</string>
+ <string name="generated_config_summary">Паказаць згенераваны файл канфігурацыі OpenVPN</string>
+ <string name="edit_profile_title">Праўка «%s»</string>
+ <string name="building_configration">Стварэнне канфігурацыі&#8230;</string>
+ <string name="netchange_summary">Перападлучацца, калі змяняецца стан сеткі (прыкладам, пры пераключэнні з Wi-Fi на мабільную і наадварот)</string>
+ <string name="netchange">Перападлучацца, калі змяняецца стан сеткі (прыкладам, пры пераключэнні з Wi-Fi на мабільную і наадварот)</string>
+ <string name="netstatus">Статус сеткі: %s</string>
+ <string name="extracahint">Сертыфікат ЦС звычайна захоўваецца ў Android Keystore. Вызначце асобны сертыфікат, калі ў вас паўсталі абмылы пры праверцы сертыфіката.</string>
+ <string name="select_file">Выбраць</string>
+ <string name="keychain_nocacert">Не атрымалася атрымаць сертыфікат ЦС са сховішча ключоў Android. Напэўна, аўтэнтыфікацыя завершыцца абмылай.</string>
+ <string name="show_log_summary">Паказвае акно журнала пры падлучэнні. Акно журнала заўсёды даступнае з панэлі апавяшчэнняў.</string>
+ <string name="show_log_window">Паказаць акно журнала</string>
+ <string name="mobile_info">%10$s %9$s працуе на %3$s %1$s (%2$s), Android %6$s (%7$s) API %4$d, ABI %5$s, (%8$s)</string>
+ <string name="error_rsa_sign">Памылка подпісу з выкарыстаннем ключа са сховішча Android %1$s: %2$s</string>
+ <string name="faq_system_dialogs">Папярэджанне VPN злучэння, што гаворыць, што гэты дадатак можа перахапляць увесь сеткавы трафік, паказваецца сістэмай для прадухілення злоўжывання API VPNService.\nАпавяшчэнне пра VPN злучэнні (знак ключа) таксама фармуецца сістэмай Android для сігналізацыі выходнага VPN злучэння. У некаторых прашыўках гэта апавяшчэнне суправаджаецца гукам.\nAndroid выкарыстоўвае гэтыя сістэмныя апавяшчэнні для вашай жа ўласнай бяспекі і іх няможна абысці. (На жаль, на некаторых прашыўках гэта ставіцца і да гуку апавяшчэння)</string>
+ <string name="faq_system_dialogs_title">Паведамленне пра падлучэнне і гук апавяшчэння</string>
+ <string name="translationby">Беларускі пераклад ад MikalaiB &lt;bregid69@gmail.com&gt;</string>
+ <string name="ipdns">IP-адрас і DNS</string>
+ <string name="basic">Асноўныя</string>
+ <string name="routing">Маршрутызацыя</string>
+ <string name="obscure">Утоеныя параметры OpenVPN. Звычайна не патрабуюцца.</string>
+ <string name="advanced">Пашыраныя</string>
+ <string name="export_config_title">ICS Openvpn канфігурацыя</string>
+ <string name="warn_no_dns">Серверы DNS не выкарыстоўваюцца. Дазвол імёнаў можа не працаваць. Разгледзіце магчымасць усталёўкі карыстацкіх DNS-сервераў. Таксама звернеце ўвагу, што Android будзе працягваць скарыстаць параметры, паказаныя для вашага мабільнага/Wi-Fi злучэння, калі не азначаны DNS-серверы.</string>
+ <string name="dns_add_error">Не атрымалася дадаць DNS-сервер «%1$s», адхілены сістэмай: %2$s</string>
+ <string name="ip_add_error">Не атрымалася наладзіць IP-адрас «%1$s», адхілены сістэмай: %2$s</string>
+ <string name="faq_howto">&lt;p&gt;Скарыстайце гатовую канфігурацыю (пратэставаную на вашым кампутары ці атрыманую ад вашага правайдара)&lt;/p&gt;&lt;p&gt;Калі гэта прастой файл без pem/pkcs12, вы можаце адправіць яго як укладанне па электроннай пошце на сваю прыладу. Калі ж файлаў некалькі, вы можаце скарыстаць іх са сваёй карты памяці.&lt;/p&gt;&lt;p&gt;Проста адкрыйце .conf файл ці выберыце яго ў дыялогу імпарту (значок тэчкі ў спісе профіляў)&lt;/p&gt;&lt;p&gt;Калі праграма выдасць памылку пра нястачу некаторых файлаў, проста змесціце гэтыя файлы на карту памяці.&lt;/p&gt;&lt;p&gt;Націсніце кнопку захавання для дадання імпартаванай канфігурацыі ў праграму&lt;/p&gt;&lt;p&gt;Запусціце ваш VPN-тунэль, нажаўшы на яго назву ў спісе&lt;/p&gt;&lt;p&gt;Калі пры запуску выніклі памылкі, паспрабуйце разабрацца і ўхіліць іх.&lt;/p&gt; </string>
+ <string name="faq_howto_title">Хуткі старт</string>
+ <string name="setting_loadtun_summary">Паспрабуйце загрузіць модуль ядра tun.ko, Перад тым як спрабаваць падлучыцца. Патрабуецца root-доступ на прыладзе.</string>
+ <string name="setting_loadtun">Загрузіць tun-модуль</string>
+ <string name="importpkcs12fromconfig">Імпарт PKCS12 са сховішча ключоў Android</string>
+ <string name="getproxy_error">Памылка пры атрыманні параметраў проксі-сервера: %s</string>
+ <string name="using_proxy">Выкарыстоўваецца проксі-сервер %1$s %2$s</string>
+ <string name="use_system_proxy">Выкарыстоўваць проксі-сервер сістэмы</string>
+ <string name="use_system_proxy_summary">Выкарыстоўваць сістэмную канфігурацыю проксі HTTP/HTTPS для злучэння.</string>
+ <string name="onbootrestartsummary">OpenVPN будзе падключацца да паказанага VPN, калі ён быў актыўны пры загрузцы сістэмы. Калі ласка, прачытайце FAQ пра папярэджанне пры падлучэнні перад тым, як скарыстаць гэту опцыю на Android &lt; 5.0.</string>
+ <string name="onbootrestart">Падключэнне пры загрузцы</string>
+ <string name="ignore">Ігнараваць</string>
+ <string name="restart">Перазапуск</string>
+ <string name="restart_vpn_after_change">Змены канфігурацыі ўжываюцца пасля перазапуску VPN. (Пера)запусціць VPN цяпер?</string>
+ <string name="configuration_changed">Канфігурацыя зменена</string>
+ <string name="log_no_last_vpn">Не атрымалася вызначыць апошні карыстаны профіль для рэдагавання</string>
+ <string name="faq_duplicate_notification_title">Апавяшчэнні што дублююцца</string>
+ <string name="faq_duplicate_notification">Калі ў Android узнікае нястача аператыўнай памяці (RAM), непатрэбныя службы і дадаткі спыняюцца. З-за гэтага перапыняецца ўсталяванае VPN-злучэнне. Каб пазбегнуць гэтага, дадатак трэба запускаць з падвышаным прыярытэтам. Для запуску з высокім прыярытэтам дадатак павінен вывесці апавяшчэнне. Значок ключа паказваецца наверсе панэлі апавяшчэнняў самай сістэмай, як апісана ў папярэднім пытанні. Ён не лічыцца тым апавяшчэннем, якое дадатку патрэбна для запуску з высокім прыярытэтам.</string>
+ <string name="no_vpn_profiles_defined">Профілі VPN не азначаны.</string>
+ <string name="add_new_vpn_hint">Выкарыстоўвайце значок &lt;img src=\"ic_menu_add\"/&gt; для дадання новага VPN</string>
+ <string name="vpn_import_hint">Скарыстайце кнопку &lt;img src=\"ic_menu_archive\"/&gt; для імпарту існавалых профіляў (.ovpn ці .conf) з карты памяці.</string>
+ <string name="faq_hint">Не забудзьцеся зазірнуць у FAQ. Там ёсць кароткае кіраўніцтва.</string>
+ <string name="faq_routing_title">Конфигурация маршрутизации/интерфейса</string>
+ <string name="faq_routing">Канфігурацыя маршрутызацыі і інтэрфейсу вырабляецца не праз традыцыйныя ifconfig/route каманды, а з дапамогай VPNService API. Гэта прыводзіць да стварэння іншай канфігурацыі маршрутызацыі, адрознай ад канфігурацый, што выкарыстоўваюцца на іншых АС. Канфігурацыя VPN-тунэля складаецца з IP-адрасоў і сетак, якія павінны скіроўвацца праз гэты інтэрфейс. Ніякіх адменных партнёрскіх адрасоў ці адрасоў шлюза не патрабуецца. Таксама не патрабуюцца і адмысловыя маршруты для злучэння з VPN-серверам (прыкладам, дададзеныя пры выкарыстанні redirect-gateway). Такім чынам, дадатак будзе ігнараваць гэтыя параметры пры імпарце канфігурацыі. Дадатак з дапамогай VPNService API гарантуе, што падлучэнне да сервера не скіроўваецца праз VPN-тунэль. Падтрымліваецца кірунак праз тунэль толькі пэўных сетак. Дадатак спрабуе вызначыць сеткі, якія не павінны быць скіраваны праз тунэль (прыкладам, маршрут x.x.x.x y.y.y.y net_gateway) і вылічае спіс маршрутаў, у які не ўлучаюцца гэтыя маршруты, каб эмуляваць паводзіны іншых платформаў. Вокны журналаў і логаваў паказваюць канфігурацыю сэрвісу VPN пасля ўсталявання злучэння.</string>
+ <string name="persisttun_summary">Не выкарыстоўваць звычайнае злучэнне без VPN пры перападлучэнні OpenVPN.</string>
+ <string name="persistent_tun_title">Заўсёдны tun</string>
+ <string name="openvpn_log">Журнал OpenVPN</string>
+ <string name="import_config">Імпарт канфігурацыі OpenVPN</string>
+ <string name="battery_consumption_title">Спажыванне батарэі</string>
+ <string name="baterry_consumption">У маіх тэстах галоўнай крыніцай высокага спажывання электраэнергіі батарэі былі пакеты keepalive. Большасць OpenVPN-сервераў утрымваюць дырэктыву накшталт «keepalive 10 60», якая прымушае кліент і сервер мяняцца keepalive-пакетамі кожныя 10 секундаў. &lt;p&gt; Хоць гэтыя пакеты і маленькія, і не расходуюць шмат трафіка, яны прымушаюць радыёмодуль увесь час працаваць, што павялічвае выдатак энергіі. (гл. &lt;a href=\"http://developer.android.com/training/efficient-downloads/efficient-network-access.html#RadioStateMachine\"&gt;The Radio State Machine | Android Developers&lt;/a&gt;) &lt;p&gt; Налады keepalive не могуць быць зменены на кліенту, гэта можа зрабіць толькі сістэмны адміністратар OpenVPN. &lt;p&gt; На жаль, выкарыстанне keepalive больш, чым 60 секундаў з UDP, можа прывесці да таго, што некаторыя шлюзы NAT будуць абрываць злучэнне з-за адсутнасці актыўнасці. Выкарыстанне TCP з вялікім keepalive-таймаўтам будзе працаваць, але прадукцыйнасць тунэлявання TCP праз TCP у сетках з высокімі стратамі пакетаў вельмі нізкая (гл. &lt;a href=\"http://sites.inka.de/bigred/devel/tcp-tcp.html\"&gt;Why TCP Over TCP Is A Bad Idea&lt;/a&gt;)</string>
+ <string name="faq_tethering">Функцыя тэтэрынгу Android (праз WiFi, USB ці Bluetooth) і VPNService API (карыстанае гэтай праграмай) не працуюць разам. Падрабязней у &lt;a href=\"https://github.com/schwabe/ics-openvpn/issues/34\"&gt;праблеме №34&lt;/a&gt;</string>
+ <string name="vpn_tethering_title">VPN и Tethering</string>
+ <string name="connection_retries">Спробы падлучэння</string>
+ <string name="reconnection_settings">Параметры перападлучэння</string>
+ <string name="connectretrymessage">Колькасць секундаў паміж спробамі падлучэння.</string>
+ <string name="connectretrywait">Секундаў паміж злучэннямі</string>
+ <string name="minidump_generated">OpenVPN завяршылася нечакана. Калі ласка, пагледзіце опцыю \"Адправіць Minidump\" у галоўным меню</string>
+ <string name="send_minidump">Адправіць Minidump распрацоўніку</string>
+ <string name="send_minidump_summary">Адпраўленне адладкавай інфармацыі распрацоўніку пра апошняе аварыйнае завяршэнне</string>
+ <string name="notifcation_title">OpenVPN - %s</string>
+ <string name="session_ipv4string">%1$s - %2$s</string>
+ <string name="session_ipv6string">%1$s - %3$s, %2$s</string>
+ <string name="state_connecting">Падключэнне</string>
+ <string name="state_wait">Чаканне адказу сервера</string>
+ <string name="state_auth">Праверка сапраўднасці</string>
+ <string name="state_get_config">Атрыманне канфігурацыі кліента</string>
+ <string name="state_assign_ip">Прызначэнне IP-адрасоў</string>
+ <string name="state_add_routes">Даданне маршрутаў</string>
+ <string name="state_connected">Падлучана</string>
+ <string name="state_disconnected">Адключыцца</string>
+ <string name="state_reconnecting">Паўторнае падлучэнне</string>
+ <string name="state_exiting">Выйсце</string>
+ <string name="state_noprocess">Не запушчана</string>
+ <string name="state_resolve">Дазвол імёнаў вузлоў</string>
+ <string name="state_tcp_connect">Падключэнне (TCP)</string>
+ <string name="state_auth_failed">Памылка аўтэнтыфікацыі</string>
+ <string name="state_nonetwork">Чаканне працы сеткі</string>
+ <string name="statusline_bytecount">↓%2$s %1$s - ↑%4$s %3$s</string>
+ <string name="notifcation_title_notconnect">Раз\'яднана</string>
+ <string name="start_vpn_title">Подключение к VPN %s</string>
+ <string name="start_vpn_ticker">Падключэнне да VPN %s</string>
+ <string name="jelly_keystore_alphanumeric_bug">У некаторых версіях Android 4.1 ёсць праблемы, калі імя сертыфіката ўтрымвае не літарна-лічбавыя знакі (прыкладам, прабелы, падкрэсленні ці працяжнік). Паспрабуйце пераўсталяваць сертыфікат без выкарыстання адмысловых знакаў.</string>
+ <string name="encryption_cipher">Алгарытм шыфравання</string>
+ <string name="packet_auth">Праверка сапраўднасці пакетаў</string>
+ <string name="auth_dialog_title">Вызначце метад праверкі сапраўднасці пакетаў</string>
+ <string name="built_by">создан %s</string>
+ <string name="debug_build">зборка для адладкі</string>
+ <string name="official_build">афіцыйная зборка</string>
+ <string name="make_selection_inline">Скапіяваць у профіль</string>
+ <string name="crashdump">Справаздача пра паданне</string>
+ <string name="add">Дадаць</string>
+ <string name="send_config">Адправіць канфігурацыйны файл</string>
+ <string name="complete_dn">Поўнае DN</string>
+ <string name="remotetlsnote">Імпартаваная канфігурацыя выкарыстоўвае САСТАРЭЛУЮ опцыю tls-remote, якая мае іншы фармат DN.</string>
+ <string name="rdn">RDN (поўнае імя)</string>
+ <string name="rdn_prefix">Прэфікс RDN</string>
+ <string name="tls_remote_deprecated">tls-remote (САСТАРЭЛАЕ)</string>
+ <string name="help_translate">Вы можаце палепшыць пераклад, наведаўшы http://crowdin.net/project/ics-openvpn/invite</string>
+ <string name="prompt">%1$s спрабуе кіраваць %2$s</string>
+ <string name="remote_warning">Працягваючы, вы даяце дадатку права на кіраванне \"OpenVPN для Android\" і перахоп усяго сеткавага трафіка. <b> Не працягвайце, калі не давяраеце цалкам гэтаму дадатку. </b> У адваротным выпадку вы рызыкуеце збегам і выкарыстаннем вашых дадзеных злачынцамі.</string>
+ <string name="remote_trust">Я давяраю гэтаму дадатку.</string>
+ <string name="no_external_app_allowed">Нет приложений, авторизованных для внешнего API</string>
+ <string name="allowed_apps">Дазволеныя дадаткі: %s</string>
+ <string name="clearappsdialog">Ачысціць спіс аўтарызаваных вонкавых дадаткаў?\nСпіс дазволеных дадаткаў:\n\n%s</string>
+ <string name="screenoff_summary">Приостанавливать VPN, если экран выключен и передано меньше 64kb данных за 60 сек. Когда включена опция \"Постоянный туннель\", приостановка VPN оставит ваше устройство без сетевого подключения. Без опции \"Постоянный туннель\" устройство не будет иметь VPN-соединения/защиты.</string>
+ <string name="screenoff_title">Прыпыніць VPN-злучэнне пры вымкнутым экране</string>
+ <string name="screenoff_pause">Прыпыненне злучэння пры вымкнутым экране: менш, чым %1$s за %2$sс</string>
+ <string name="screen_nopersistenttun">Увага: Заўсёдны тунэль не ўключаны для гэтага VPN. Трафік будзе скарыстаць звычайнае інтэрнэт злучэнне, калі экран вымкнуты.</string>
+ <string name="save_password">Захаваць пароль</string>
+ <string name="pauseVPN">Прыпыніць VPN</string>
+ <string name="resumevpn">Працягнуць VPN</string>
+ <string name="state_userpause">VPN прыпынены па запыце карыстача</string>
+ <string name="state_screenoff">VPN прыпынены - вымк. экран</string>
+ <string name="device_specific">Хакі для дадзенай прылады</string>
+ <string name="cannotparsecert">Не атрымоўваецца адлюстраваць звесткі пра сертыфікат</string>
+ <string name="appbehaviour">Паводзіны дадатку</string>
+ <string name="vpnbehaviour">Паводзіны VPN</string>
+ <string name="allow_vpn_changes">Дазволіць змену профіляў VPN</string>
+ <string name="hwkeychain">Апаратнае сховішча ключоў:</string>
+ <string name="permission_icon_app">Абразок дадатку спрабуе скарыстаць OpenVPN для Android</string>
+ <string name="faq_vpndialog43">"Пачынаючы з Android 4.3, дыялог пацверджання VPN-злучэння абаронены ад дадаткаў, «што накладаюцца паўзверх экрана». Гэта прыводзіць да таго, што дыялогавае акно пацверджання не рэагуе на сэнсорныя націскі. Калі вам трапіцца дадатак, што выкарыстоўвае накладанні і выклікае такія паводзіны, звяжыцеся з аўтарам гэтага дадаткі. Гэта праблема закранае ўсе VPN дадаткі на Android 4.3 і пазнейшых версіях. Гледзіце таксама &lt;a href=\"https://github.com/schwabe/ics-openvpn/issues/185\"&gt;Issue 185&lt;a&gt; для атрымання дадатковых звестак"</string>
+ <string name="faq_vpndialog43_title">Акно пацверджання VPN для Android 4.3 і пазней</string>
+ <string name="donatePlayStore">Таксама Вы можаце выказаць падзяку ў выглядзе ахвяравання на Краме Play:</string>
+ <string name="thanks_for_donation">Дзякуй за ахвяраванне %s!</string>
+ <string name="logCleared">Журнал вычышчаны.</string>
+ <string name="show_password">Паказаць пароль</string>
+ <string name="keyChainAccessError">памылка пры доступе да сховішча ключоў: %s</string>
+ <string name="timestamp_short">Коратка</string>
+ <string name="timestamp_iso">ISO</string>
+ <string name="timestamps">Час</string>
+ <string name="timestamps_none">Не</string>
+ <string name="uploaded_data">Выгружана</string>
+ <string name="downloaded_data">Загружана</string>
+ <string name="vpn_status">Статус VPN</string>
+ <string name="logview_options">Налады выгляду</string>
+ <string name="unhandled_exception">Неапазнаная памылка: %1$s\n\n%2$s</string>
+ <string name="unhandled_exception_context">%3$s: %1$s\n\n%2$s</string>
+ <string name="faq_system_dialog_xposed">Калі на вашай прыладзе ёсць root, можаце ўсталяваць &lt;a href=\"http://xposed.info/\"&gt;Xposed framework&lt;/a&gt; і &lt;a href=\"http://repo.xposed.info/module/de.blinkt.vpndialogxposed\"&gt;модуль аўтаматычнага пацверджання дыялогу падлучэння VPN&lt;/a&gt; на свой страх і рызык</string>
+ <string name="full_licenses">Поўныя тэксты ліцэнзій</string>
+ <string name="blocklocal_summary">Сеткі, даступныя наўпрост праз лакальны інтэрфейс, не будуць маршрутызаваны праз VPN. Адключыце гэту опцыю, каб скіраваць трафік праз VPN.</string>
+ <string name="blocklocal_title">Не выкарыстоўваць VPN для лакальных адрасоў</string>
+ <string name="userpw_file">Файл логіна і пароля</string>
+ <string name="imported_from_file">[Імпартавана з: %s]</string>
+ <string name="files_missing_hint">Некоторые файлы не найдены. Выберите файлы для импорта в профиль:</string>
+ <string name="openvpn_is_no_free_vpn">Для выкарыстання дадзенага дадатку патрэбен правайдар/шлюз VPN, што падтрымвае OpenVPN (часта падаецца працадаўцам). На http://community.openvpn.net/ можна знайсці інфармацыю пра OpenVPN і як наладзіць уласны сервер OpenVPN.</string>
+ <string name="import_log">Лог імпарту:</string>
+ <string name="ip_looks_like_subnet">Указана тапалогія VPN «%3$s», але ifconfig %1$s %2$s больш падобна на IP-адрас з маскай сеткі. Выкарыстоўваецца тапалогія «падсетка».</string>
+ <string name="mssfix_invalid_value">Значэнне, што перазапісвае MSS, павінна быць цэлым лікам ад 0 да 9000</string>
+ <string name="mtu_invalid_value">Значэнне, пяравызначальнае MTU, павінна быць цэлым лікам ад 64 да 9000</string>
+ <string name="mssfix_value_dialog">Абвясціць TCP сесіям, што працуюць праз тунэль, што яны павінны абмежаваць памер сваіх пакетаў так, каб пасля іх інкапсуляцыі OpenVPN выніковы памер UDP-пакета, які OpenVPN пасылае сваім балям, не перавышаў гэты лік байт. (1450 па змаўчанні)</string>
+ <string name="mssfix_checkbox">Перавызначыць MSS для нагрузкі TCP</string>
+ <string name="mssfix_dialogtitle">Задаць MSS для нагрузкі TCP</string>
+ <string name="client_behaviour">Паводзіны кліента</string>
+ <string name="clear_external_apps">Ачысціць дазволеныя знешнія дадаткі</string>
+ <string name="loading">Загружаецца&#8230;</string>
+ <string name="allowed_vpn_apps_info">Дазволеныя дадаткі VPN: %1$s</string>
+ <string name="disallowed_vpn_apps_info">Забароненыя дадаткі VPN: %1$s</string>
+ <string name="app_no_longer_exists">Пакет %s больш не ўсталяваны, ён падаляецца са спіса дазволеных/забароненых дадаткаў</string>
+ <string name="vpn_disallow_radio">Выкарыстоўваць VPN для ўсіх дадаткаў, апроч абраных</string>
+ <string name="vpn_allow_radio">Выкарыстоўваць VPN толькі для абраных дадаткаў</string>
+ <string name="query_delete_remote">Прыбраць запіс выдаленага сервера?</string>
+ <string name="keep">Захаваць</string>
+ <string name="delete">Выдаліць</string>
+ <string name="add_remote">Дадаць новую падаленку</string>
+ <string name="remote_random">Выкарыстоўваць спіс падлучэнняў у выпадковым парадку пры злучэнні</string>
+ <string name="remote_no_server_selected">Вы павінны вызначыць і ўключыць прынамсі адзін выдалены сервер.</string>
+ <string name="server_list">Спіс сервераў</string>
+ <string name="vpn_allowed_apps">Дазволеныя дадаткі</string>
+ <string name="advanced_settings">Пашыраныя налады</string>
+ <string name="payload_options">Налады карыснай нагрузкі</string>
+ <string name="tls_settings">Налады TLS</string>
+ <string name="no_remote_defined">Няма зададзенай падаленкі</string>
+ <string name="duplicate_vpn">Дубляваць профіль VPN</string>
+ <string name="duplicate_profile_title">Дубляванне профілю: %s</string>
+ <string name="show_log">Паказаць акно журнала</string>
+ <string name="faq_android_clients">Існуюць розныя кліенты OpenVPN для Android. Самыя пашыраныя — OpenVPN для Android (гэты кліент), OpenVPN Connect і OpenVPN Settings.&lt;p&gt;Кліенты можна падзяліць на дзве групы: OpenVPN для Android і OpenVPN Connect скарыстаюць афіцыйны VPNService API (Android 4.0+) і не патрабуюць root-доступ, і OpenVPN Settings, які патрабуе root.&lt;p&gt;OpenVPN для Android — кліент з адкрытым зыходным кодам, які распрацаваў Arne Schwabe. Ён прызначаны для больш за доследных карыстачоў і падае шмат налад, магчымасць імпарту профіляў з файлаў і наладжваць/змяняць профілі ўсярэдзіне дадатку. Гэты кліент заснаваны на грамадскай версіі OpenVPN. А менавіта на выточным кодзе OpenVPN 2.x. Гэты кліент можна ўявіць як напаўафіцыйны кліент супольнасці. &lt;p&gt;OpenVPN Connect — кліент з зачыненым зыходным кодам, які распрацоўваецца OpenVPN Technologies, Inc. Ён закліканы для звычайнага выкарыстання і прызначаны для простых карыстачоў, і дазваляе імпартаваць профілі з OpenVPN. Гэты кліент заснаваны на OpenVPN C++, іншай рэалізацыі пратакола OpenVPN (Гэта запатрабавалася OpenVPN Technologies, Inc, каб апублікаваць дадатак OpenVPN на iOS). Гэты кліент — афіцыйны кліент OpenVPN technologies &lt;p&gt; OpenVPN Settings — найстары з кліентаў, ён таксама UI для OpenVPN з адкрытым зыходным кодам. У адрозненне ад OpenVPN для Android, ён патрабуе root-правы і не выкарыстоўвае VPNService API. Ён не залежыць ад Android 4.0+</string>
+ <string name="faq_androids_clients_title">Адрозненні паміж кліентамі OpenVPN для Android</string>
+ <string name="ignore_multicast_route">Ігнаруецца мультыадрасны маршрут: %s</string>
+ <string name="ab_only_cidr">Android падтрымвае толькі CIDR маршруты да VPN. Бо не CIDR маршруты амаль ніколі не выкарыстоўваюцца, OpenVPN для Android будзе выкарыстоўваць /32 для не CIDR маршрутаў і выдаваць папярэджанне.</string>
+ <string name="ab_tethering_44">Тэтэрынг/раздача інтэрнэту працуе, калі актыўны VPN. Мадэмнае злучэнне (тэтэрынг) НЕ БУДЗЕ выкарыстоўваць VPN.</string>
+ <string name="ab_kitkat_mss">Раннія версіі KitKat усталёўваюць няслушнае значэнне MSS для TCP злучэнняў (#61948). Паспрабуйце ўключыць опцыю mssfix, каб абысці гэты баг.</string>
+ <string name="ab_proxy">Android будзе працягваць скарыстаць вашы налады проксі, паказаныя для мабільнага/Wi-Fi злучэння, калі не ўсталяваны DNS сервер. OpenVPN для Android папярэдзіць вас пра гэта ў журнале.<p>Калі VPN усталёўвае DNS сервер Android не выкарыстоўвае проксі. Для ўсталёўкі проксі для VPN злучэння няма API.</p></string>
+ <string name="ab_lollipop_reinstall">Приложения VPN могут перестать работать после удаления и повторной установки. Подробности см. #80074</string>
+ <string name="ab_not_route_to_vpn">Сканфігураваны IP-адрас кліента і IP-адраса ў яго падсеткі (паводле сеткавай маскі) не скіроўваюцца праз VPN. OpenVPN абыходзіць гэты баг, відавочна дадаючы маршрут, які адпавядае кліенцкаму IP і яго сеткавай масцы</string>
+ <string name="ab_persist_tun">Адкрыццё тунэля, калі тунэль ужо актыўны, для яго нязменнага ўтрымання, можа прывесці да памылкі і VPNServices зачыніцца на прыладзе. Для аднаўлення працы VPN патрабуецца перазагрузка. OpenVPN для Android спрабуе ўнікнуць усталёўкі другога тунэля, і калі сапраўды патрэбна - спачатку зачыняе бягучы тунэль, перад адкрыццём новага, каб пазбегнуць краху праграмы. Гэта можа прывесці да маленькага інтэрвалу, у якім перадача пакетаў адбываецца па звычайным (не VPN) злучэнню. Нават з гэтымі хітрыкамі VPNServices часам падае і патрабуе перазагрузкі прылады.</string>
+ <string name="ab_secondary_users">VPN зусім не працуе для другасных карыстачоў.</string>
+ <string name="ab_kitkat_reconnect">"Розныя карыстачы паведамляюць, што мабільная сувязь/мабільная перадача дадзеных часта абрываецца, калі выкарыстоўваецца VPN дадатак. Такія паводзіны, здаецца, закранае толькі некаторыя камбінацыі правайдараў/прылад, і пакуль што не выяўлена прычына/няма абыходу гэтага бага."</string>
+ <string name="ab_vpn_reachability_44">Адрасы могуць працаваць праз VPN толькі тыя, што даступныя без VPN. IPv6 VPN не працуюць зусім.</string>
+ <string name="ab_only_cidr_title">Не CIDR маршруты</string>
+ <string name="ab_proxy_title">Паводзіны проксі для VPN</string>
+ <string name="ab_lollipop_reinstall_title">Пераўсталяванне дадаткаў VPN</string>
+ <string name="version_upto">%s і раней</string>
+ <string name="copy_of_profile">Копія %s</string>
+ <string name="ab_not_route_to_vpn_title">Маршрут для ўсталяванага IP-адраса</string>
+ <string name="ab_kitkat_mss_title">Няслушнае значэнне MSS для VPN злучэння</string>
+ <string name="ab_secondary_users_title">Дадатковыя карыстачы прылады</string>
+ <string name="custom_connection_options_warng">Вызначце асаблівыя карыстальніцкія параметры падключэння. Выкарыстоўвайце з асцярожнасцю</string>
+ <string name="custom_connection_options">Карыстальніцкія параметры</string>
+ <string name="remove_connection_entry">Выдаліць запіс падключэння</string>
+ <string name="ab_kitkat_reconnect_title">Выпадковыя адключэнні ад мабільнай сеткі</string>
+ <string name="ab_vpn_reachability_44_title">Падаленыя сеткі недаступныя</string>
+ <string name="ab_persist_tun_title">Прымусовы рэжым tun</string>
+ <string name="version_and_later">%s і вышэй</string>
+ <string name="tls_cipher_alert_title">Няўдалае злучэнне з SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure</string>
+ <string name="tls_cipher_alert">Новыя версіі OpenVPN для Android (0.6.29/Сакавік 2015) скарыстаюць больш бяспечныя налады па змаўчанні для дазволеных набораў шыфраў (tls-cipher \"DEFAULT:!EXP:!PSK:!SRP:!kRSA\"). На жаль, спыненне выкарыстання менш за бяспечныя і экспартных набораў шыфраў, а асабліва тых набораў шыфраў, што не падтрымваюць Perfect Forward Secrecy (Diffie-Hellman), прыводзіць да некаторых праблем. Звычайна гэта адбываецца з-за добранамернай, але дрэнна рэалізаванай спробы ўзмацнення бяспекі TLS шляхам усталёўкі tls-cipher на серверы ці некаторых убудаваных АС з падрэзаным SSL (прыкладам, MikroTik).\nКаб вырашыць гэту праблему, усталюеце налады tls-cipher на серверы на разумныя па змаўчанні, такія як tls-cipher \"DEFAULT:!EXP:!PSK:!SRP:!kRSA\". Каб абысці праблему на кліенту, дадайце асобную наладу tls-cipher DEFAULT у Android-кліент.</string>
+ <string name="message_no_user_edit">Дадзены профіль быў дададзены з вонкавага дадатку (%s) і быў адзначаны як непрыдатны да рэдагавання карыстачамі.</string>
+ <string name="crl_file">Спіс адкліканых сертыфікатаў</string>
+ <string name="service_restarted">Перазапуск сэрвісу OpenVPN (Дадатак, напэўна, упаў ці быў зачынена з-за нястачы памяці)</string>
+ <string name="import_config_error">Імпартаванне канфігурацыі прывяло да памылкі, немагчыма захаваць змены</string>
+ <string name="Search">Пошук</string>
+ <string name="lastdumpdate">(Апошні дамп створаны %1$d г. і %2$d х. назад (%3$s))</string>
+ <string name="clear_log_on_connect">Чысціць журнал пры новым злучэнні</string>
+ <string name="connect_timeout">Час чакання злучэння</string>
+ <string name="no_allowed_app">Не дададзена дазволеных дадаткаў. Дадаём сябе (%s), каб у спісе дазволеных дадаткаў быў хоць бы адзін дадатак, інакш усе дадаткі дададуцца ў спіс дазволеных</string>
+ <string name="query_permissions_sdcard">OpenVPN для Android можа паспрабаваць знайсці адсутныя файлы на SD-карце аўтаматычна. Націсніце на гэта паведамленне, каб атрымаць запыт на дазвол.</string>
+ <string name="protocol">Пратакол</string>
+ <string name="enabled_connection_entry">Уключана</string>
+ <string name="abi_mismatch">Preferred native ABI precedence of this device (%1$s) and ABI reported by native libraries (%2$s) mismatch</string>
+ <string name="permission_revoked">Дазвол VPN адкліканы АС (прыкладам, запушчана іншая праграма VPN), спыняем VPN</string>
+ <string name="pushpeerinfo">Адправіць інфармацыю пра ўдзельніка</string>
+ <string name="pushpeerinfosummary">Адправіць дадатковую інфармацыю на сервер, прыкладам, версію SSL і версію Android</string>
+ <string name="pw_request_dialog_title">Патрабуецца %1$s</string>
+ <string name="pw_request_dialog_prompt">Калі ласка, увядзіце пароль для профілю %1$s</string>
+ <string name="menu_use_inline_data">Ужыць убудаваныя дадзеныя</string>
+ <string name="export_config_chooser_title">Экспарт файла канфігурацыі</string>
+ <string name="missing_tlsauth">файл tls-auth адсутнічае</string>
+ <string name="missing_certificates">Адсутнічае сертыфікат карыстача ці файл ключа сертыфіката карыстача</string>
+ <string name="missing_ca_certificate">Отсутствует сертификат ЦС</string>
+ <string name="crl_title">Спіс адкліканых сертыфікатаў (апцыянальна)</string>
+ <string name="reread_log">Перачытаць (%d) элементаў лога з файла кэша лога</string>
+ <string name="samsung_broken">Нават нягледзячы на тое, што тэлефоны Samsung з\'яўляюцца аднымі з найболей прадаваных тэлефонаў на Android, прашыўкі Samsung таксама з\'яўляюцца і найболей праблемнымі прашыўкамі на Android. Памылкі не абмяжоўваюцца толькі працай VPN на гэтых прыладах, але многія з іх можна абысці. Далей апісаны некаторыя з гэтых памылкаў.\n\nDNS не працуе, калі сервер DNS не ў дыяпазоне VPN.\n\nНа многіх прыладах Samsung 5.x функцыя дазволеных/забароненых дадаткаў не працуе.\nНа Samsung 6.x, як паведамляецца, VPN не працуе, пакуль дадатку VPN не дазволена не эканоміць зарад батарэі.</string>
+ <string name="samsung_broken_title">Тэлефоны Samsung</string>
+ <string name="novpn_selected">Не абрана VPN.</string>
+ <string name="defaultvpn">VPN па змаўчанні</string>
+ <string name="defaultvpnsummary">VPN, які будзе выкарыстоўвацца па змаўчанні, калі гэта патрэбна. А менавіта, пры загрузцы, для «Нязменнай VPN» і для перамыкача ў «Хуткіх наладах».</string>
+ <string name="vpnselected">У гэты час абраны VPN: \'%s\'</string>
+ <string name="reconnect">Перадалучыць</string>
+ <string name="qs_title">Пераключэнне VPN</string>
+ <string name="qs_connect">Падлучыцца да %s</string>
+ <string name="qs_disconnect">Адключыцца ад %s</string>
+ <string name="connectretrymaxmessage">Увядзіце максімальны час паміж спробамі злучэння. OpenVPN будзе павольна падымаць свой час чакання пасля няўдалай спробы падлучэння да гэтага значэння. Па змаўчанні 300 сек.</string>
+ <string name="connectretrymaxtitle">Максімальны час паміж спробамі злучэння</string>
+ <string name="state_waitconnectretry">Чаканне %ss секундаў паміж спробай падлучэння</string>
+ <string name="nought_alwayson_warning"><![CDATA[Калі дыялог пацверджання VPN не адкрыўся, то ў вас абраны іншы дадатак у «Нязменная VPN». Гэта значыць, што толькі дадзенаму дадатку дазволена падключацца да VPN. Праверце Налады -> (Сеткі) Яшчэ -> VPN]]></string>
+ <string name="management_socket_closed">Падключэнне да OpenVPN зачынена (%s)</string>
+ <string name="change_sorting">Змяніць сартаванне</string>
+ <string name="sort">Сартаваць</string>
+ <string name="sorted_lru">Профілі адсартаваны па парадку апошняга выкарыстання</string>
+ <string name="sorted_az">Профілі адсартаваны па назве</string>
+ <string name="deprecated_tls_remote">Файл налады выкарыстоўвае опцыю tls-remote, якая была абвешчана састарэлай у версіі 2.3 і канчаткова выдалена ў версіі 2.4</string>
+ <string name="auth_failed_behaviour">Паводзіны пры AUTH_FAILED</string>
+ <string name="graph">Графік</string>
+ <string name="use_logarithmic_scale">Выкарыстоўваць лагарыфмічную шкалу</string>
+ <string name="notenoughdata">Недастаткова дадзеных</string>
+ <string name="avghour">У сярэднім за гадзіну</string>
+ <string name="avgmin">У сярэднім за хвіліну</string>
+ <string name="last5minutes">Апошнія 5 хвілін</string>
+ <string name="data_in">Уваходны</string>
+ <string name="data_out">Выходны</string>
+ <string name="bits_per_second">%.0f біт/с</string>
+ <string name="kbits_per_second">%.1f Кбіт/с</string>
+ <string name="mbits_per_second">%.1f Мбіт/с</string>
+ <string name="gbits_per_second">%.1f Гбіт/с</string>
+ <string name="weakmd">&lt;p&gt; Пачынаючы з OpenSSL версіі 1.1, OpenSSL адхіляе слабыя подпісы ў такіх сертыфікатах, як MD5.&lt;/p&gt;&lt;p&gt;&lt;b&gt;MD5, подпісы цалкам небяспечныя і больш не павінны выкарыстоўвацца.&lt;/b&gt; Сутыкненні MD5 могуць быць створаны ў &lt;a
+ href=\"https://natmchugh.blogspot.de/2015/02/create-your-own-md5-collisions.html\"&gt; праз некалькі гадзін з мінімальнымі выдаткамі.&lt;/a&gt;. Вы павінны як мага хутчэй абнавіць сертыфікаты VPN. &lt;/p&gt;&lt;p&gt;На жаль, старыя дыстрыбутывы easy-rsa улучалі опцыю канфігурацыі «default_md md5». Калі вы скарыстаеце старую версію easy-rsa, абновіце яе да &lt;a href=\"https://github.com/OpenVPN/easy-rsa/releases\"&gt;latest версіі&lt;/a&gt;) ці зменіце md5 на sha256 і адновіце свае сертыфікаты.&lt;/p&gt;&lt;p&gt;Калі вы сапраўды хочаце скарыстаць старыя і пашкоджаныя сертыфікаты, скарыстайце наладжвальны параметр канфігурацыі tls-cipher «DEFAULT: @SECLEVEL = 0 \"у пашыранай канфігурацыі ці ў якасці дадатковага радка ў вашай імпартаванай канфігурацыі&lt;/p&gt;</string>
+ <string name="volume_byte">%.0f Б</string>
+ <string name="volume_kbyte">%.1f КБ</string>
+ <string name="volume_mbyte">%.1f МБ</string>
+ <string name="volume_gbyte">%.1f ГБ</string>
+ <string name="channel_name_background">Статыстыка падключэння</string>
+ <string name="channel_description_background">Бягучая статыстыка ўсталяванага злучэння OpenVPN</string>
+ <string name="channel_name_status">Изменение статуса соединения</string>
+ <string name="channel_description_status">Змены стану злучэння OpenVPN (падлучэнне, аўтэнтыфікацыя,...)</string>
+ <string name="weakmd_title">Слабыя (MD5) хэшы ў сігнатуры сертыфіката (SSL_CTX_use_certificate md занадта слабы)</string>
+ <string name="title_activity_open_sslspeed">Тэст хуткасці OpenSSL</string>
+ <string name="openssl_cipher_name">Імёны шыфраў OpenSSL</string>
+ <string name="osslspeedtest">Тэст хуткасці OpenSSL Crypto</string>
+ <string name="openssl_error">OpenSSL вярнуў памылку</string>
+ <string name="running_test">Запуск тэсту&#8230;</string>
+ <string name="test_algoirhtms">Тэставанне абраных алгарытмаў</string>
+ <string name="all_app_prompt">Вонкавы дадатак спрабуе кантраляваць %s. Дадатак, што запытвае доступ, не можа быць вызначаны. Дазвол гэтага дадатку падае доступ усім дадаткам.</string>
+ <string name="openvpn3_nostatickeys">Рэалізацыя OpenVPN 3 C ++ не падтрымвае статычныя ключы. Перайдзіце ў OpenVPN 2.x пад агульныя налады.</string>
+ <string name="openvpn3_pkcs12">Выкарыстанне файлаў PKCS12 наўпрост з дапамогай OpenVPN 3 C ++ не падтрымваецца. Імпартуйце файлы pkcs12 у сховішча ключоў Android ці заменіце OpenVPN 2.x на агульныя налады.</string>
+ <string name="proxy">Проксі</string>
+ <string name="Use_no_proxy">Нічога</string>
+ <string name="tor_orbot">Tor (Orbot)</string>
+</resources>
diff --git a/app/src/main/res/values-ca/strings-icsopenvpn.xml b/app/src/main/res/values-ca/strings-icsopenvpn.xml
index 48eca2d6..1bf7c91a 100755
--- a/app/src/main/res/values-ca/strings-icsopenvpn.xml
+++ b/app/src/main/res/values-ca/strings-icsopenvpn.xml
@@ -105,7 +105,6 @@
<string name="routing">Ruting</string>
<string name="advanced">Avançat</string>
<string name="faq_howto_title">Inici rapid</string>
- <string name="using_proxy">Utilitzant el proxy %1$s %2$d</string>
<string name="use_system_proxy">Utiliza el proxy del sistema</string>
<string name="ignore">Ignorar</string>
<string name="restart">Reinicia</string>
diff --git a/app/src/main/res/values-cs/strings-icsopenvpn.xml b/app/src/main/res/values-cs/strings-icsopenvpn.xml
index 40feea2c..dc33007c 100755
--- a/app/src/main/res/values-cs/strings-icsopenvpn.xml
+++ b/app/src/main/res/values-cs/strings-icsopenvpn.xml
@@ -201,7 +201,6 @@
<string name="setting_loadtun">Nahrát tun modul</string>
<string name="importpkcs12fromconfig">Importovat PKCS12 z konfigurace do Andoidího úložiště</string>
<string name="getproxy_error">Chyba při zjišťování nastavení proxy: %s</string>
- <string name="using_proxy">Používám proxy %1$s %2$d</string>
<string name="use_system_proxy">Použít systémovou proxy</string>
<string name="use_system_proxy_summary">K připojení použít systémové nastavení pro HTTP/HTTPS.</string>
<string name="onbootrestartsummary">OpenVPN se automaticky připojí k vybrané VPN po startu systému. Prosím věnujte pozornost upozornění ve FAQ pro verzi Android &lt; 5.0.</string>
@@ -357,6 +356,8 @@
<string name="ab_kitkat_mss">Dřívější KitKat verze nastavovaly špatnou hodnotu MSS na TCP spojení (#61948). OpenVPN automaticky zapne mssfix možnost pro obejití chyby.</string>
<string name="ab_lollipop_reinstall">Aplikace VPN mohou přestat fungovat po odinstalování a reinstalaci. Podrobnosti najdete v #80074</string>
<string name="ab_secondary_users">VPN vůbec nefunguje pro vedlejší uživatele.</string>
+ <string name="ab_kitkat_reconnect">"Více uživatelů hlasí, že mobilní připojení / mobilní datové připojení má časté výpadky během používání této VPN aplikace, Vypadá, že chování ovlivňuje jen nějaké kombinace mobilních dodavatelů / zařizení a zatím jsme přes žádnou přičinu nemohli identifikovat chybu."</string>
+ <string name="ab_vpn_reachability_44">Jediná destinace může být dosažena přes VPN které nejsou dosažitelné bez VPN. Sítě IPv6 nefungují vůbec.</string>
<string name="ab_only_cidr_title">Ne-CIDR trasy</string>
<string name="ab_proxy_title">Proxy chování pro VPN</string>
<string name="ab_lollipop_reinstall_title">Přeinstalování VPN aplikací</string>
@@ -381,6 +382,7 @@
<string name="lastdumpdate">(Poslední výpis je %1$d: %2$dh starý (%3$s))</string>
<string name="clear_log_on_connect">Vymazat log při novém připojení</string>
<string name="connect_timeout">Časový limit připojení</string>
+ <string name="query_permissions_sdcard">Aplikace OpenVPN pro systém Android se může pokusit automaticky zjistit chybějící soubor(y) na sdcard. Klepnutím na tuto zprávu spusťte žádost o povolení.</string>
<string name="protocol">Protokol</string>
<string name="enabled_connection_entry">Povoleno</string>
<string name="pushpeerinfo">Push Peer info</string>
@@ -427,4 +429,5 @@
<string name="volume_kbyte">%.1f kB</string>
<string name="volume_mbyte">%.1f MB</string>
<string name="volume_gbyte">%.1f GB</string>
+ <string name="tor_orbot">Tor (Orbot)</string>
</resources>
diff --git a/app/src/main/res/values-da/strings-icsopenvpn.xml b/app/src/main/res/values-da/strings-icsopenvpn.xml
index 2635c79e..e1012c0a 100755
--- a/app/src/main/res/values-da/strings-icsopenvpn.xml
+++ b/app/src/main/res/values-da/strings-icsopenvpn.xml
@@ -21,7 +21,7 @@
<string name="ca_title">CA Certifikat</string>
<string name="no_certificate">Du skal vælge et certifikat</string>
<string name="copyright_guicode">Kildekode og fejl tracker findes på http://code.google.com/p/ics-openvpn/</string>
- <string name="copyright_others">Dette program bruger følgende komponenter: se kildekoden for alle detaljer om licenserne</string>
+ <string name="copyright_others">Dette program bruger følgende komponenter (se kildekoden for detaljer om licenserne)</string>
<string name="about">Om</string>
<string name="vpn_list_title">Profiler</string>
<string name="vpn_type">Type</string>
@@ -83,7 +83,7 @@
<string name="dns_server">DNS-server</string>
<string name="secondary_dns_message">Sekundær DNS-Server som bruges, hvis den normale DNS-serveren ikke kan nås.</string>
<string name="backup_dns">Backup DNS-server</string>
- <string name="ignored_pushed_routes">Ignorer skubbet ruter</string>
+ <string name="ignored_pushed_routes">Ignorer modtagne routes</string>
<string name="ignore_routes_summary">Ignorer ruter modtaget fra serveren.</string>
<string name="default_route_summary">Omdiriger al trafik over VPN\'en</string>
<string name="use_default_title">Brug standard Rute</string>
@@ -121,7 +121,7 @@
<string name="tap_faq2">Igen? Laver du sjov? Nej, tap-tilstand er virkelig ikke understøttet og det hjælper ikke at sende mig mails og spørge om det bliver understøttet.</string>
<string name="tap_faq3">En tredje gang? Man kunne faktisk skrive en tap-emulator baseret på tun der kunne tilføje layer2 information når den sender og fjerne layer2 information når det modtages. Men en sådan tap-emulator skulle også implementere ARP og muligvis en DHCP-klient. JEg kender ikke nogen der arbejder i denne retning. Kontakt mig hvis du vil begynde at programmere det.</string>
<string name="faq">OFTE STILLEDE SPØRGSMÅL</string>
- <string name="copying_log_entries">Kopiere logposter</string>
+ <string name="copying_log_entries">Kopierer log poster</string>
<string name="faq_copying">For at kopiere en enkelt logpost skal du trykke og holde på logposten. For at kopiere/sende hele log\'en skal du bruge Send Log valgmuligheden. Brug hardware menu knappen hvis den ikke er vist i GUI\'en.</string>
<string name="faq_shortcut">Genvej til start</string>
<string name="faq_howto_shortcut">Du kan placere en genvej til at starte OpenVPN på dit skrivebord. Afhængigt af dit homescreen-program skal du enten tilføje en genvej eller et widget.</string>
@@ -201,7 +201,7 @@
<string name="setting_loadtun">Indlæs tun-modul</string>
<string name="importpkcs12fromconfig">Importer pkcs12 fra konfigurationen til Android Keystore</string>
<string name="getproxy_error">Fejl under indlæsning af proxy-indstillinger: %s</string>
- <string name="using_proxy">Anvender proxy %1$s %2$d</string>
+ <string name="using_proxy">Anvender proxy %1$s %2$s</string>
<string name="use_system_proxy">Anvend system-proxy</string>
<string name="use_system_proxy_summary">Anvend systemets globale konfiguration til forbindelse af HTTP/HTTPS proxy\'er.</string>
<string name="onbootrestartsummary">OpenVPN vil forbinde til den angivne VPN hvis den var aktiv under system opstart. Læs venligst forbindelses advarsel FAQ før du bruger demme valgmulighed på Android &lt; 5.0.</string>
@@ -279,15 +279,15 @@
<string name="no_external_app_allowed">Ingen app har lov til at anvende ekstern API</string>
<string name="allowed_apps">Tilladte apps: %s</string>
<string name="clearappsdialog">Ryd liste over tilladte eksterne apps?\nNuværende liste over tilladte apps:\n\n%s</string>
- <string name="screenoff_summary">Paus VPN når skærmen er slukket og mindre end 64 kB data er blevet overført de sidste 60 sekunder. Når \"Vedvarende Tun\" indstillingen er slået til, vil din enhed ikke have forbindelse til netværket når VPN\'en er pauset. Uden \"Vedvarende Tun\" indstillingen til enheden ikke have nogen VPN forbindelse/beskyttelse.</string>
- <string name="screenoff_title">Paus VPN-forbindelse efter skærmen slukkes</string>
- <string name="screenoff_pause">Pauser forbindelse i slukket-skræm tilstand: Mindre end %1$s på %2$ss</string>
+ <string name="screenoff_summary">Sæt VPN-forbindelsen på pause når skærmen er slukket og mindre end 64 kB data er blevet overført de sidste 60 sekunder. Når \"Vedvarende Tun\" indstillingen er slået til, vil din enhed ikke have forbindelse til netværket når VPN\'en er sat på pause. Uden \"Vedvarende Tun\" indstillingen til enheden ikke have nogen VPN forbindelse/beskyttelse.</string>
+ <string name="screenoff_title">Sæt VPN-forbindelsen på pause efter skærmen slukkes</string>
+ <string name="screenoff_pause">Sæt VPN-forbindelsen på pause i slukket-skræm tilstand: Mindre end %1$s på %2$ss</string>
<string name="screen_nopersistenttun">Advarsel: Vedvarende Tun er ikke slået til på denne VPN. Internettrafik vil anvende den normale internetforbindelse når skærmen er slukket.</string>
<string name="save_password">Gem adgangskode</string>
- <string name="pauseVPN">Paus VPN</string>
+ <string name="pauseVPN">Pause VPN</string>
<string name="resumevpn">Genoptag VPN</string>
- <string name="state_userpause">VPN pausning anmodet af bruger</string>
- <string name="state_screenoff">VPN pauset - Skærmen er slukket</string>
+ <string name="state_userpause">VPN pauset af bruger</string>
+ <string name="state_screenoff">VPN-forbindelsen på pause - Skærmen slukket</string>
<string name="device_specific">Enheds-specifikke hacks</string>
<string name="cannotparsecert">Kan ikke vise certifikatsinformation</string>
<string name="appbehaviour">Program opførsel</string>
@@ -315,7 +315,7 @@
<string name="faq_system_dialog_xposed">Hvis du har rootet din androidenhed kan du installere &lt;a href=\"http://xposed.info/\"&gt;Xposed framework&lt;/a&gt; og &lt;a href=\"http://repo.xposed.info/module/de.blinkt.vpndialogxposed\"&gt;VPN Dialog confirm module&lt;/a&gt; på din egen risiko</string>
<string name="full_licenses">Fulde licenser</string>
<string name="blocklocal_summary">Netværk forbundet direkte til det lokale interface vil ikke blive dirigeret gennem VPN\'en. Fravælges denne indstilling vil alt trafik til lokale netværk dirigeres gennem VPN\'en.</string>
- <string name="blocklocal_title">Forbipasser VPN for lokale netværk</string>
+ <string name="blocklocal_title">Undgå brug af VPN for lokale netværk</string>
<string name="userpw_file">Brugernavn/password fil</string>
<string name="imported_from_file">[Importeret fra: %s]</string>
<string name="files_missing_hint">Nogle filer kunne ikke findes. Vælg venligst filerne for at importere profilen:</string>
@@ -385,15 +385,81 @@
<string name="service_restarted">Genstarter OpenVPN Service (App\'en crashede, den crashede sandsynligvis eller blev stoppet på grund a RAM overbelastning)</string>
<string name="import_config_error">Import af konfigurationsfilen gav en fejl, kan ikke gemme</string>
<string name="Search">Søg</string>
+ <string name="lastdumpdate">(Sidste dump er %1$d:%2$dh gammel (%3$s))</string>
<string name="clear_log_on_connect">Ryd log ved ny forbindelse</string>
<string name="connect_timeout">Forbindelses-timeout</string>
<string name="no_allowed_app">Ingen tilladt app tilføjet. Tilføjer selve appen (%s) for at have mindst én tilladt app, ellers vil alle apps være tilladte</string>
<string name="query_permissions_sdcard">OpenVPN til Android kan forsøge at finde de(n) manglende fil(er) automatisk på SD-kortet. Klik på denne besked for at starte rettighedsanmodningen.</string>
<string name="protocol">Protokol</string>
<string name="enabled_connection_entry">Aktiveret</string>
+ <string name="abi_mismatch">Preferred native ABI precedence of this device (%1$s) and ABI reported by native libraries (%2$s) mismatch</string>
<string name="permission_revoked">VPN tilladelse tilbagekaldt af styresystemet (f.eks. kan et andet VPN program være startet), stopper VPN</string>
+ <string name="pushpeerinfo">Modtagne Peer info</string>
+ <string name="pushpeerinfosummary">Send ekstra information til serveren, f.eks. SSL-version og Android-version</string>
+ <string name="pw_request_dialog_title">Kræver %1$s</string>
+ <string name="pw_request_dialog_prompt">Angiv adgangskoden for profil %1$s</string>
+ <string name="menu_use_inline_data">Brug inline data</string>
+ <string name="export_config_chooser_title">Eksporter konfigurationsfil</string>
+ <string name="missing_tlsauth">tls-auth-filen mangler</string>
+ <string name="missing_certificates">Manglende brugercertifikat eller brugercertifikat nøglefil</string>
+ <string name="missing_ca_certificate">Manglende CA-certifikat</string>
+ <string name="crl_title">Certifcate Revoke List (valgfrit)</string>
+ <string name="reread_log">Genlæse (%d) log-linier fra cache</string>
+ <string name="samsung_broken">Selv om Samsung-telefoner er blandt de mest solgte Android-telefoner, er Samsungs firmware også blandt de mest fejlagtige Android-implementationer. Fejlene er ikke begrænset til VPN-operationer på disse enheder, men mange af dem kan løses. I det følgende beskrives nogle af disse fejl. \n\nDNS virker ikke, medmindre DNS-serveren er i samme VPN-område. \n\nMed mange Samsung 5.x-enheder virker funktionen for tilladte/afviste apps ikke. \nMed Samsung 6.x rapporteres at VPN ikke fungere, medmindre VPN-appen er undtaget fra Powersave-funktioner.</string>
+ <string name="samsung_broken_title">Samsung telefoner</string>
+ <string name="novpn_selected">Ingen VPN valgt.</string>
+ <string name="defaultvpn">Standard VPN</string>
+ <string name="defaultvpnsummary">VPN bruges i situationer, hvor en standard VPN er påkrævet. Disse er i øjeblikket ved opstart, til Always-On og Quick Settings Tile.</string>
+ <string name="vpnselected">Aktuelt valgt VPN: \'%s\'</string>
+ <string name="reconnect">Gentilslutter</string>
+ <string name="qs_title">Skift VPN</string>
+ <string name="qs_connect">Opret forbindelse til %s</string>
+ <string name="qs_disconnect">Afbryd %s</string>
+ <string name="connectretrymaxmessage">Indtast den maksimale tid mellem forbindelsesforsøg. OpenVPN vil langsomt øge ventetiden efter et mislykket forbindelsesforsøg op til denne værdi. Standard er 300 sekunder.</string>
+ <string name="connectretrymaxtitle">Maksimal tid mellem forbindelsesforsøg</string>
+ <string name="state_waitconnectretry">Venter %ssekunder mellem forbindelsesforsøg</string>
+ <string name="nought_alwayson_warning"><![CDATA[Hvis du ikke fik en VPN-bekræftelsesdialog, har du \"Always on VPN\" aktiveret af en anden app. I så fald må kun den app forbinde til en VPN. Se under Settings-> Networks more .. -> VPNs]]></string>
+ <string name="management_socket_closed">Forbindelse til OpenVPN lukket (%s)</string>
+ <string name="change_sorting">Skift sortering</string>
+ <string name="sort">Sorter</string>
+ <string name="sorted_lru">Profiler sorteret efter senest anvendelse</string>
+ <string name="sorted_az">Profiler sorteret efter navn</string>
+ <string name="deprecated_tls_remote">Konfigurationen bruger \"tls-remote\", understøttelsen af denne er fjernet i 2.4</string>
+ <string name="auth_failed_behaviour">Handling ved AUTH_FAILED</string>
+ <string name="graph">Graf</string>
+ <string name="use_logarithmic_scale">Brug logaritmisk skala</string>
+ <string name="notenoughdata">Ikke nok data</string>
+ <string name="avghour">Gennemsnit pr. time</string>
+ <string name="avgmin">Gennemsnit pr. minut</string>
+ <string name="last5minutes">Sidste 5 minutter</string>
+ <string name="data_in">Ind</string>
+ <string name="data_out">Ud</string>
+ <string name="bits_per_second">%.0f bit/s</string>
+ <string name="kbits_per_second">%.1f kbit/s</string>
+ <string name="mbits_per_second">%.1f Mbit / s</string>
+ <string name="gbits_per_second">%.1f Gbit / s</string>
+ <string name="weakmd">&lt;p&gt;Startende med OpenSSL version 1.1 vil OpenSSL afvise svage signaturer i certifikater som f.eks MD5.&lt;/p&gt;&lt;p&gt;&lt;b&gt;MD5 signaturer er usikre og bør ikke længere anvendes.&lt;/b&gt; MD5 sammenfald (collisions) kan fremstilles &lt;a
+ href=\"https://natmchugh.blogspot.de/2015/02/create-your-own-md5-collisions.html\"&gt; på kort tid uden de store ressourcer.&lt;/a&gt;. Du skal opdatere dine VPN-certifikaterne så hurtigt som muligt.&lt;/p&gt;&lt;p&gt;Desværre inkluderede ældre easy-rsa-distributioner config-opsætningen \"default_md md5\". Hvis du bruger en gammel easy-rsa-version, skal du opdatere til den &lt;a href=\"https://github.com/OpenVPN/easy-rsa/releases\"&gt;seneste version&lt;/a&gt;) eller skifte md5 til sha256 og regenerere dine certifikater.&lt;/p&gt;&lt;p&gt;Hvis du virkelig vil bruge gamle og usikre certifikater, skal du bruge den tilpassede konfigurationsindstilling tls-cipher \"DEFAULT: @ SECLEVEL = 0\" under avanceret konfiguration eller som ekstra linje i din importerede konfiguration&lt;/p&gt;
+ </string>
<string name="volume_byte">%.0f B</string>
<string name="volume_kbyte">%.1f kB</string>
<string name="volume_mbyte">%.1f MB</string>
<string name="volume_gbyte">%.1f GB</string>
+ <string name="channel_name_background">Forbindelsesstatistik</string>
+ <string name="channel_description_background">Løbende statistikker af den etablerede OpenVPN-forbindelse</string>
+ <string name="channel_name_status">Forbindelses status ændring</string>
+ <string name="channel_description_status">Status ændringer i OpenVPN-forbindelsen (Tilslutning, godkendelse, etc)</string>
+ <string name="weakmd_title">Svag (MD5) hashes i certifikat signatur (SSL_CTX_use_certificate md for svag)</string>
+ <string name="title_activity_open_sslspeed">OpenSSL Speed ​​Test</string>
+ <string name="openssl_cipher_name">OpenSSL cipher navne</string>
+ <string name="osslspeedtest">OpenSSL Crypto Speed ​​test</string>
+ <string name="openssl_error">OpenSSL returnerede en fejl</string>
+ <string name="running_test">Tester ...</string>
+ <string name="test_algoirhtms">Test valgte algoritmer</string>
+ <string name="all_app_prompt">En ekstern app forsøger at styre %s. Appen, der anmoder om adgang, kan ikke bestemmes. Tillad, at denne app giver ALLE apps adgang.</string>
+ <string name="openvpn3_nostatickeys">OpenVPN 3 C ++ implementeringen understøtter ikke statiske nøgler. Venligst skift til OpenVPN 2.x under generelle indstillinger.</string>
+ <string name="openvpn3_pkcs12">Brug af PKCS12 filer direkte med OpenVPN 3 C ++ implementering understøttes ikke. Indtast venligst pkcs12-filerne i Android-keystore eller skift til OpenVPN 2.x under generelle indstillinger.</string>
+ <string name="proxy">Proxy</string>
+ <string name="Use_no_proxy">Ingen</string>
+ <string name="tor_orbot">Tor (Orbot)</string>
</resources>
diff --git a/app/src/main/res/values-de/strings-icsopenvpn.xml b/app/src/main/res/values-de/strings-icsopenvpn.xml
index 04c50cd2..245a3e40 100755
--- a/app/src/main/res/values-de/strings-icsopenvpn.xml
+++ b/app/src/main/res/values-de/strings-icsopenvpn.xml
@@ -201,7 +201,7 @@
<string name="setting_loadtun">Tun-Modul laden</string>
<string name="importpkcs12fromconfig">In der Konfiguration angegebene PKCS12-Datei in den Android-Zertifikatsspeicher importieren</string>
<string name="getproxy_error">Fehler beim Ermitteln der Proxy-Einstellungen: %s</string>
- <string name="using_proxy">Verwende Proxy %1$s %2$d</string>
+ <string name="using_proxy">Verwende Proxy %1$s %2$s</string>
<string name="use_system_proxy">System-Proxys verwenden</string>
<string name="use_system_proxy_summary">Systemweite Einstellungen für HTTP- und HTTPS-Proxys beim Verbinden verwenden.</string>
<string name="onbootrestartsummary">Beim Systemstart das angegebene VPN verbinden. Auf Geräten mit Android 5.0 und höher bitte vor der Verwendung dieser Option die FAQ zum Bestätigungsdialog lesen.</string>
@@ -438,12 +438,18 @@
<string name="kbits_per_second">%.1f kbit/s</string>
<string name="mbits_per_second">%.1f Mbit/s</string>
<string name="gbits_per_second">%.1f Gbit/s</string>
+ <string name="weakmd">&lt;p&gt;Seit der OpenSSL Version 1.1, verweigert OpenSSL schwache Signaturen - wie MD5 - in Zertifikaten.&lt;/p&gt;
+&lt;p&gt;&lt;b&gt;MD5-Signaturen sind komplett unsicher und sollten nicht mehr verwendet werden.
+&lt;/b&gt;MD5-Kollisionen können in &lt;a href=\"https://natmchugh.blogspot.de/2015/02/create-your-own-md5-collisions.html\"&gt;wenigen Stunden mit minimalen Kosten&lt;/a&gt; erzeugt werden. Sie sollten die VPN-Zertifikate so schnell wie möglich aktualisieren.&lt;/p&gt;
+&lt;p&gt;Leider enthielten ältere easy-rsa Distributionen die config-Option \"default_md md5\". Falls Sie eine alte Version von easy-rsa verwenden, aktualisieren Sie auf die &lt;a href=\"https://github.com/OpenVPN/easy-rsa/releases\"&gt;neueste Version&lt;/a&gt; oder ändern Sie md5 auf sha256 und erzeugen Sie Ihre Zertifikate neu.&lt;/p&gt;
+&lt;p&gt;Falls Sie wirklich alte und unsichere Zertifikate verwenden wollen, benutzen Sie die benutzerdefinierte Konfigurationsoption tls-cipher \"DEFAULT:@SECLEVEL=0\" in der erweiterten Profil-Konfiguration oder als zusätzliche Zeile in Ihrer importierten Konfiguration.&lt;/p&gt;
+ </string>
<string name="volume_byte">%.0f B</string>
<string name="volume_kbyte">%.1f kB</string>
<string name="volume_mbyte">%.1f MB</string>
<string name="volume_gbyte">%.1f GB</string>
<string name="channel_name_background">Verbindungsstatistiken</string>
- <string name="channel_description_background">Laufende Statistiken der OpenVPN-Verbindung</string>
+ <string name="channel_description_background">Laufende Statistik der OpenVPN-Verbindung</string>
<string name="channel_name_status">Verbindungsstatus Änderungen</string>
<string name="channel_description_status">Statusänderungen der OpenVPN-Verbindung (Verbindung, Authentifizierung,...)</string>
<string name="weakmd_title">Schwache (MD5) Hashes in Zertifikatssignatur (SSL_CTX_use_certificate md too weak)</string>
@@ -455,5 +461,8 @@
<string name="test_algoirhtms">Ausgewählte Algorithmen testen</string>
<string name="all_app_prompt">Eine andere App versucht, %s zu steuern. Die anforderne App kann nicht bestimmt werden. Wenn Sie diesen Zugriff zulassen, erhalten ALLE Apps Zugriff.</string>
<string name="openvpn3_nostatickeys">Die OpenVPN 3 C ++ - Implementierung unterstützt keine statischen Schlüssel. Bitte wechseln Sie zu OpenVPN 2.x unter den allgemeinen Einstellungen.</string>
- <string name="openvpn3_pkcs12">Die Benutzung von PKCS12 Dateien mit der OpenVPN 3 C++ Implementierung wird nicht unterstützt. Bitte importieren Sie entweder die PKCS12 Datei in den Android Keystore oder nutzen Sie die Option OpenVPN 2.x in den allgemeinen Einstellungen auszuwählen.</string>
+ <string name="openvpn3_pkcs12">Die Benutzung von PKCS12 Dateien mit der OpenVPN 3 C++ Implementierung wird nicht unterstützt. Bitte importieren Sie entweder die PKCS12 Datei in den Android Keystore oder wählen Sie die Option OpenVPN 2.x in den allgemeinen Einstellungen aus.</string>
+ <string name="proxy">Proxy</string>
+ <string name="Use_no_proxy">Keinen</string>
+ <string name="tor_orbot">Tor (Orbot)</string>
</resources>
diff --git a/app/src/main/res/values-es/strings-icsopenvpn.xml b/app/src/main/res/values-es/strings-icsopenvpn.xml
index 42a15975..3f0ab495 100755
--- a/app/src/main/res/values-es/strings-icsopenvpn.xml
+++ b/app/src/main/res/values-es/strings-icsopenvpn.xml
@@ -202,7 +202,7 @@ hacia/de Móvil)</string>
<string name="setting_loadtun">Cargar modulo tun</string>
<string name="importpkcs12fromconfig">Importar PKCS12 de la configuración en el almacén de claves de Android</string>
<string name="getproxy_error">Error al obtener la configuración de proxy: %s</string>
- <string name="using_proxy">Usando proxy %1$s %2$d</string>
+ <string name="using_proxy">Using proxy %1$s %2$s</string>
<string name="use_system_proxy">Usar el proxy del sistema</string>
<string name="use_system_proxy_summary">Utilice la configuración del sistema para los proxies HTTP/HTTPS al conectar.</string>
<string name="onbootrestartsummary">OpenVPN se conectará la VPN se especifica si está activa en el arranque del sistema. Por favor, lea las preguntas frecuentes de aviso de conexión antes de utilizar esta opción en Android &lt; 5.0.</string>
@@ -440,8 +440,28 @@ hacia/de Móvil)</string>
<string name="kbits_per_second">%.1f kbit/s</string>
<string name="mbits_per_second">%.1f Mbit/s</string>
<string name="gbits_per_second">%.1f Gbit/s</string>
+ <string name="weakmd">&lt;p&gt;a partir de la versión 1.1 de OpenSSL, OpenSSL rechaza débiles firmas en certificados como el MD5.&lt;/p&gt;&lt;p&gt;&lt;b&gt;MD5 firmas son totalmente inseguras y no deberían utilizarse nunca más.&lt;/b&gt; las colisiones MD5 pueden crearse en &lt;a
+ href=\"https://natmchugh.blogspot.de/2015/02/create-your-own-md5-collisions.html\"&gt;pocas horas a un costo mínimo.&lt;/a&gt;. Debe actualizar los certificados VPN tan pronto como sea posible.&lt;p&gt;de&lt;/p&gt;Desafortunadamente, distribuciones antiguas de easy-rsa incluyeron la opción de configuración \"default_md md5\". Si está utilizando una versión antigua de easy-rsa, actualizar a la &lt;a href=\"https://github.com/OpenVPN/easy-rsa/releases\"&gt;última versión&lt;/a&gt;) o cambiar de md5 a sha256 y regenerar sus certificados.&lt;/p&gt;&lt;p&gt;si desea utilizar certificados viejos y rotos use el configuración personalizada opción tls-cipher \"DEFAULT:@SECLEVEL=0\" debajo de configuración avanzada o como línea adicional en su configuración importada&lt;/p&gt;
+ </string>
<string name="volume_byte">%.0f B</string>
<string name="volume_kbyte">%.1f kB</string>
<string name="volume_mbyte">%.1f MB</string>
<string name="volume_gbyte">%.1f GB</string>
+ <string name="channel_name_background">Estadísticas de conexión</string>
+ <string name="channel_description_background">Ongoing statistics of the established OpenVPN connection</string>
+ <string name="channel_name_status">Cambio de estado de conexión</string>
+ <string name="channel_description_status">Cambios de estado de la conexión OpenVPN (Conexión, autenticación, ...)</string>
+ <string name="weakmd_title">Hashes débiles (MD5) en la firma del certificado (SSL_CTX_use_certificate md too weak)</string>
+ <string name="title_activity_open_sslspeed">Prueba de velocidad OpenSSL</string>
+ <string name="openssl_cipher_name">Nombres de cifrado OpenSSL</string>
+ <string name="osslspeedtest">Prueba de velocidad de Crypto OpenSSL</string>
+ <string name="openssl_error">OpenSSL devolvió un error</string>
+ <string name="running_test">Ejecutando prueba...</string>
+ <string name="test_algoirhtms">Pruebe los algoritmos seleccionados</string>
+ <string name="all_app_prompt">Una aplicación externa intenta controlar %s. La aplicación que solicita acceso no puede determinarse. Permitir que esta aplicación otorgue acceso a TODAS las aplicaciones.</string>
+ <string name="openvpn3_nostatickeys">La implementación OpenVPN 3 C ++ no admite claves estáticas. Cambie a OpenVPN 2.x en la configuración general.</string>
+ <string name="openvpn3_pkcs12">Usar archivos PKCS12 directamente con la implementación OpenVPN 3 C++ no esta soportada. Por favor, importe los ficheros pkcs12 en el almacén de claves de Android o cambie a OpenVPN 2.x en configuración general.</string>
+ <string name="proxy">Proxy</string>
+ <string name="Use_no_proxy">Ninguno</string>
+ <string name="tor_orbot">Tor (Orbot)</string>
</resources>
diff --git a/app/src/main/res/values-et/strings-icsopenvpn.xml b/app/src/main/res/values-et/strings-icsopenvpn.xml
index 916e8db1..266b38fc 100755
--- a/app/src/main/res/values-et/strings-icsopenvpn.xml
+++ b/app/src/main/res/values-et/strings-icsopenvpn.xml
@@ -201,7 +201,6 @@
<string name="setting_loadtun">Laadi tun moodul</string>
<string name="importpkcs12fromconfig">Lae PKCS12 OpenVPN konfiguratsioonist Androidi võtmehoidlasse</string>
<string name="getproxy_error">Viga proxy seadistuste vastuvõtul: %s</string>
- <string name="using_proxy">Kasutusel proxy %1$s %2$d</string>
<string name="use_system_proxy">Kasuta süsteemset proxy\'t</string>
<string name="use_system_proxy_summary">Kasuta ühendumisel süsteemse HTTP/HTTPS proxy konfiguratsiooni.</string>
<string name="onbootrestartsummary">OpenVPN ühendab määratud VPN kui see oli süsteemi käivitumisel aktiivne. Palun tutvuge, enne Android &lt; 5.0 peal selle võimaluse kasutamist, KKK hoiatusega ühendumise kohta.</string>
diff --git a/app/src/main/res/values-fr/strings-icsopenvpn.xml b/app/src/main/res/values-fr/strings-icsopenvpn.xml
index a647bf40..7b37e6fd 100755
--- a/app/src/main/res/values-fr/strings-icsopenvpn.xml
+++ b/app/src/main/res/values-fr/strings-icsopenvpn.xml
@@ -85,7 +85,7 @@
<string name="backup_dns">Serveur DNS secondaire</string>
<string name="ignored_pushed_routes">Ignorer les routes envoyées</string>
<string name="ignore_routes_summary">Ignorer les règles de routage envoyées par le serveur.</string>
- <string name="default_route_summary">Redirige tout le trafic vers la connexion VPN</string>
+ <string name="default_route_summary">"Redirige tout le trafic sur la connexion VPN"</string>
<string name="use_default_title">Utiliser la route par défaut</string>
<string name="custom_route_message">Entrer les règles de routage. Saisissez seulement les destinations au format CIDR. Exemple: \"10.0.0.0/8 2002::/16\" devrait router les réseaux 10.0.0.0/8 et 2002::/16 via le VPN.</string>
<string name="custom_route_message_excluded">Routes qui ne devant pas être routées à travers le VPN. Utilisez la même syntaxe que pour les règles de routage.</string>
@@ -202,7 +202,7 @@ Sur certaines images, cette notification joue un son.\nAndroid à introduit ces
<string name="setting_loadtun">"Charger le module TUN"</string>
<string name="importpkcs12fromconfig">"Importer PKCS12 de la configuration dans le gestionnaire de clés Android"</string>
<string name="getproxy_error">Erreur d\'obtention des paramètres de proxy : %s</string>
- <string name="using_proxy">"Utilisation du proxy %1$s %2$d"</string>
+ <string name="using_proxy">"Utilisation du proxy %1$s %2$s"</string>
<string name="use_system_proxy">"Utiliser le proxy système"</string>
<string name="use_system_proxy_summary">"Utiliser la configuration générale du système pour que les proxy HTTP / HTTPS se connectent."</string>
<string name="onbootrestartsummary">OpenVPN connectera le VPN spécifié si elle était active au démarrage du système. Veuillez lire l\'avertissement de connexion FAQ avant d\'utiliser cette option sur Android &lt; 5.0.</string>
@@ -253,6 +253,7 @@ Sur certaines images, cette notification joue un son.\nAndroid à introduit ces
<string name="state_tcp_connect">Connexion (TCP)</string>
<string name="state_auth_failed">Authentification échouée</string>
<string name="state_nonetwork">En attente d\'un réseau utilisable</string>
+ <string name="statusline_bytecount">↓%2$s %1$s - ↑%4$s %3$s</string>
<string name="notifcation_title_notconnect">Non connecté</string>
<string name="start_vpn_title">Connexion au VPN %s</string>
<string name="start_vpn_ticker">Connexion au VPN %s</string>
@@ -359,8 +360,10 @@ Sur certaines images, cette notification joue un son.\nAndroid à introduit ces
<string name="ab_proxy">Android va continuer à utiliser vos paramètres de proxy spécifiés pour la connexion mobile / Wi-Fi lorsque aucun serveur DNS n\'est définis. OpenVPN pour Android vous avertira à ce sujet dans le log.<p>Quand un VPN définit un serveur de DNS, Android n\'utilisera pas de proxy. Il n\'y a pas d\'API pour définir un proxy pour un connection VPN.</p></string>
<string name="ab_lollipop_reinstall">Les applications VPN peuvent s\'arrêter de fonctionner lors d\'une désinstallation suivie d\'une réinstallation. Pour plus de détails, voir #80074</string>
<string name="ab_not_route_to_vpn">L\'adresse IP du client, et les adresses IP de ce réseau ne sont pas routées par le VPN. OpenVPN contourne ce problème en ajoutant une route qui corresponds à l’adresse IP et le Masque de sous réseau du client</string>
+ <string name="ab_persist_tun">Ouvrir un appareil en mode TUN pendant qu\'un autre appareil en mode TUN est actif, ce qui est requis pour la prise en charge de la persistance TUN, produit une panne de VPNServices sur l\'appareil. Un redémarrage est nécessaire pour faire fonctionner le VPN à nouveau. OpenVPN pour Android tente d\'éviter de ré-ouvrir l\'appareil en mode TUN , et si cela est indispensable il arrête d\'abord le TUN actuel avant d\'ouvrir le nouveau TUN pour éviter une panne. Cela peut conduire à une courte période pendant laquelle les paquets sont envoyés hors de la connexion VPN. Même avec cette solution de contournement, VPNServices se bloque parfois et nécessite un redémarrage de l\'appareil.</string>
<string name="ab_secondary_users">Le VPN ne fonctionnera pas du tout pour tous les utilisateurs secondaires.</string>
<string name="ab_kitkat_reconnect">"Plusieurs utilisateurs ont signalés des prêtes de paquets durant l\'utilisation d\'un VPN sur leur connexion mobile. Ce comportement semble lier à certains fournisseurs, il n\'y a pas de contournement connu ou de bug que l\'on puisse régler."</string>
+ <string name="ab_vpn_reachability_44">Seulement la destination accessible sans VPN peut etre etteinte via VPN. Les VPNs IPv6 me fonctionnent Pas su tour.</string>
<string name="ab_only_cidr_title">Routes non CIDR</string>
<string name="ab_proxy_title">Comportement proxy pour les VPN</string>
<string name="ab_lollipop_reinstall_title">Réinstallation des applications VPN</string>
@@ -377,6 +380,7 @@ Sur certaines images, cette notification joue un son.\nAndroid à introduit ces
<string name="ab_persist_tun_title">Mode tun persistant</string>
<string name="version_and_later">%s et ultérieur</string>
<string name="tls_cipher_alert_title">Échec de la connexion avec l\'erreur SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure</string>
+ <string name="tls_cipher_alert">Les nouvelles versions d\'OpenVPN pour Android (0.6.29 / Mars 2015) utilisent une valeur par défaut plus sécurisée pour les suites cryptographiques autorisées (tls-cipher \"DEFAULT:! EXP:! PSK:! SRP:! KRSA\"). Malheureusement, en omettant les suites cryptographiques moins sécurisées et les suites EXPORT, en particulier l\'omission de suites qui ne prennent pas en charge Perfect Forward Secrecy (Diffie-Hellman) pose certains problèmes. Cela est généralement dû à une tentative bien intentionnée mais mal exécutée de renforcer la sécurité TLS en configurant tls-cipher sur le serveur ou sur certains systèmes d\'exploitation embarqués avec un SSL dépouillé (par exemple MikroTik).\nPour résoudre ce problème, réglez le paramètre tls-cipher sur le serveur à une valeur par défaut raisonnable comme \"DEFAULT:! EXP:! PSK:! SRP:! kRSA\". Pour contourner le problème sur le client, ajoutez l\'option personnalisée tls-cipher DEFAULT sur le client Android.</string>
<string name="message_no_user_edit">Ce profil a été ajouté à partir d\'une application externe (%s) et a été marqué comme non modifiable par l\'utilisateur.</string>
<string name="crl_file">Liste des certificats révoqués</string>
<string name="service_restarted">Redémarrage du service OpenVPN (l\'Application a probablement plantée ou a été tué pour cause d\'utilisation excessive de la mémoire)</string>
@@ -389,6 +393,7 @@ Sur certaines images, cette notification joue un son.\nAndroid à introduit ces
<string name="query_permissions_sdcard">OpenVPN pour Android va essayer de chercher le(s) fichier(s) manquant(s) sur une sdcard. Tapoter cette fenêtre de dialogue va démarrer une demande d\'autorisation.</string>
<string name="protocol">Protocole</string>
<string name="enabled_connection_entry">Activé</string>
+ <string name="abi_mismatch">A precedencia da ABI nativa preferida deste dispositivo (%1$s) e a ABI referenciada por bibliotecas intrínsecas (%2$s) não combinam</string>
<string name="permission_revoked">Autorisation de VPN révoquée par le système d\'exploitation (ex : un autre programme VPN est lancé), arrêt du VPN</string>
<string name="pushpeerinfo">Envoyer plus d\'infos</string>
<string name="pushpeerinfosummary">Envoyer des informations supplémentaires sur le serveur, par exemple la version SSL et la version Android</string>
@@ -434,4 +439,11 @@ Sur certaines images, cette notification joue un son.\nAndroid à introduit ces
<string name="volume_kbyte">%.1f kB</string>
<string name="volume_mbyte">%.1f MB</string>
<string name="volume_gbyte">%.1f GB</string>
+ <string name="channel_name_background">Statistiques de connexion</string>
+ <string name="title_activity_open_sslspeed">Test de vitesse OpenSSL</string>
+ <string name="openssl_error">OpenSSL a retourné une erreur</string>
+ <string name="test_algoirhtms">Tester les algorithmes sélectionnés</string>
+ <string name="proxy">Proxy</string>
+ <string name="Use_no_proxy">Aucun</string>
+ <string name="tor_orbot">Tor (Orbot)</string>
</resources>
diff --git a/app/src/main/res/values-hu/strings-icsopenvpn.xml b/app/src/main/res/values-hu/strings-icsopenvpn.xml
index 4eafc9c1..dec919b5 100755
--- a/app/src/main/res/values-hu/strings-icsopenvpn.xml
+++ b/app/src/main/res/values-hu/strings-icsopenvpn.xml
@@ -201,7 +201,7 @@
<string name="setting_loadtun">Tun modul betöltése</string>
<string name="importpkcs12fromconfig">PKCS12 konfiguráció importálása az Android Keystore-ba</string>
<string name="getproxy_error">Hiba a proxy beállítások lekérésekor: %s</string>
- <string name="using_proxy">Proxy használatban: %1$s %2$d</string>
+ <string name="using_proxy">%1$s %2$s proxy használata</string>
<string name="use_system_proxy">Rendszerproxy használata</string>
<string name="use_system_proxy_summary">Rendszerszintű konfiguráció használata a HTTP/HTTPS proxy csatlakozáshoz.</string>
<string name="onbootrestartsummary">Az OpenVPN csatlakozni fog a VPN-hez, ha az a rendszer indulásakor aktív. Kérem, olvassa el a csatlakozás figyelmeztető GYIK-et mielőtt ezt az opciót Android &lt; 5.0-n használná.</string>
@@ -474,4 +474,7 @@
<string name="openvpn3_pkcs12">PKCS12-fájlok közvetlen használata nem támogatott az OpenVPN 3 C++ implementációval.
Kérem, importálja az Android kulcstárba a pkcs12 fájlokat, vagy váltson OpenVPN 2.x-re az általános beállításokban.
</string>
+ <string name="proxy">Proxy</string>
+ <string name="Use_no_proxy">Egyik sem</string>
+ <string name="tor_orbot">Tor (Orbot)</string>
</resources>
diff --git a/app/src/main/res/values-in/strings-icsopenvpn.xml b/app/src/main/res/values-in/strings-icsopenvpn.xml
index 784ee9bf..823e9d5f 100755
--- a/app/src/main/res/values-in/strings-icsopenvpn.xml
+++ b/app/src/main/res/values-in/strings-icsopenvpn.xml
@@ -14,17 +14,17 @@
<string name="cancel">Batal</string>
<string name="no_data">Tidak ada data</string>
<string name="useLZO">Kompresi LZO</string>
- <string name="client_no_certificate">Tidak ada Sertifikat</string>
+ <string name="client_no_certificate">Sertifikat CA</string>
<string name="client_certificate_title">Sertifikat Klien</string>
<string name="client_key_title">Kunci Sertifikat Klien</string>
<string name="client_pkcs12_title">Berkas PKCS12</string>
<string name="ca_title">Sertifikat CA</string>
<string name="no_certificate">Anda harus memilih sertifikat</string>
- <string name="copyright_guicode">Kode sumber dan masalah pelacak tersedia di http://code.google.com/p/ics-openvpn/</string>
- <string name="copyright_others">Program ini menggunakan komponen berikut ini; lihat kode sumber penjelasan lengkap mengenai lisensi</string>
+ <string name="copyright_guicode">Kode sumber dan pelacak masalah tersedia di https://github.com/schwabe/ics-openvpn/</string>
+ <string name="copyright_others">Program ini memakai komponen berikut ini. Lihat sumber untuk mengetahui rincian lisensi</string>
<string name="about">Tentang</string>
<string name="vpn_list_title">Profil</string>
- <string name="vpn_type">Tipe</string>
+ <string name="vpn_type">Mengetik</string>
<string name="pkcs12pwquery">Password PKCS12</string>
<string name="file_select">Pilih&#8230;</string>
<string name="file_nothing_selected">Anda harus memilih setidaknya satu berkas</string>
@@ -201,7 +201,7 @@
<string name="setting_loadtun">Pakai modul TUN</string>
<string name="importpkcs12fromconfig">Ambil PKCS12 dari konfigurasi ke Android Keystore</string>
<string name="getproxy_error">Gagal mendapatkan pengaturan proxy: %s</string>
- <string name="using_proxy">Menggunakan proxy %1$s %2$d</string>
+ <string name="using_proxy">Menggunakan proxy %1$s %2$s</string>
<string name="use_system_proxy">Gunakan sistem proxy</string>
<string name="use_system_proxy_summary">Gunakan konfigurasi lebih luas untuk menyambung system melalui proxy HTTP/HTTPS</string>
<string name="onbootrestartsummary">OpenVPN akan menghubungkan VPN ditentukan apakah itu aktif di sistem boot. Silakan baca koneksi peringatan FAQ sebelum menggunakan opsi ini pada Android &lt; 5.0.</string>
@@ -438,6 +438,17 @@
<string name="kbits_per_second">%.1f kbit/s</string>
<string name="mbits_per_second">%.1f Mbit/s</string>
<string name="gbits_per_second">%.1f Gbit/s</string>
+ <string name="weakmd">&lt;p&gt;Starting with OpenSSL version 1.1, OpenSSL rejects weak signatures in certificates like
+ MD5.&lt;/p&gt;&lt;p&gt;&lt;b&gt;MD5 signatures are completely insecure and should not be used anymore.&lt;/b&gt; MD5
+ collisions can be created in &lt;a
+ href=\"https://natmchugh.blogspot.de/2015/02/create-your-own-md5-collisions.html\"&gt;few hours at a minimal cost.&lt;/a&gt;.
+ You should update the VPN certificates as soon as possible.&lt;/p&gt;&lt;p&gt;Unfortunately, older easy-rsa
+ distributions included the config option \"default_md md5\". If you are using an old easy-rsa version, update to
+ the &lt;a href=\"https://github.com/OpenVPN/easy-rsa/releases\"&gt;latest version&lt;/a&gt;) or change md5 to sha256 and
+ regenerate your certificates.&lt;/p&gt;&lt;p&gt;If you really want to use old and broken certificates use the custom
+ configuration option tls-cipher \"DEFAULT:@SECLEVEL=0\" under advanced configuration or as additional line in your
+ imported configuration&lt;/p&gt;
+ </string>
<string name="volume_byte">%.0f B</string>
<string name="volume_kbyte">%.1f kB</string>
<string name="volume_mbyte">%.1f MB</string>
diff --git a/app/src/main/res/values-it/strings-icsopenvpn.xml b/app/src/main/res/values-it/strings-icsopenvpn.xml
index 77866ab8..d6f378b7 100755
--- a/app/src/main/res/values-it/strings-icsopenvpn.xml
+++ b/app/src/main/res/values-it/strings-icsopenvpn.xml
@@ -203,7 +203,7 @@ Effettuata la lettura del file di configurazione</string>
<string name="setting_loadtun">Carica il modulo tun</string>
<string name="importpkcs12fromconfig">Importa i PKCS12 dalla configurazione presente nel Keystore di Android</string>
<string name="getproxy_error">Errore nell\'ottenere le impostazioni del proxy: %s</string>
- <string name="using_proxy">Si sta utilizzando il proxy %1$s %2$d</string>
+ <string name="using_proxy">Utilizzo del proxy %1$s %2$s</string>
<string name="use_system_proxy">Utilizza il proxy di sistema</string>
<string name="use_system_proxy_summary">Utilizza la configurazione generale del sistema relativa ai proxy HTTP/HTTPS per connettersi.</string>
<string name="onbootrestartsummary">OpenVPN connetterà la VPN specificata se è attiva durante l\'avvio del sistema. Leggi le domande di avviso di connessione prima di utilizzare questa opzione in Android &lt; 5.0.</string>
@@ -420,7 +420,7 @@ Effettuata la lettura del file di configurazione</string>
<string name="connectretrymaxmessage">Inserire il tempo massimo tra i tentativi di connessione. OpenVPN aumenterà lentamente il tempo di attesa dopo un tentativo di connessione non riuscito fino a questo valore. Il valore predefinito è 300s.</string>
<string name="connectretrymaxtitle">Tempo massimo tra i tentativi di connessione</string>
<string name="state_waitconnectretry">Attendere %ss secondi tra i tentativi di connessione</string>
- <string name="nought_alwayson_warning"><![CDATA[Se non hai ottenuto una finestra di conferma VPN, hai abilitato \"Sempre in VPN \" per un'altra applicazione. In questo caso solo l'applicazione può connettersi a una VPN. Controlla in Impostazioni-> Altre reti .. -> VPNS]]></string>
+ <string name="nought_alwayson_warning"><![CDATA[Se non hai ottenuto una finestra di conferma VPN, hai abilitato \"Sempre in VPN \" per un\'altra applicazione. In questo caso solo l\'applicazione può connettersi a una VPN. Controlla in Impostazioni-> Altre reti .. -> VPNS]]></string>
<string name="management_socket_closed">Connessione a OpenVPN chiusa (%s)</string>
<string name="change_sorting">Cambia ordinamento</string>
<string name="sort">Ordina</string>
@@ -440,8 +440,28 @@ Effettuata la lettura del file di configurazione</string>
<string name="kbits_per_second">%.1f kbit/s</string>
<string name="mbits_per_second">%.1f Mbit/s</string>
<string name="gbits_per_second">%.1f Gbit/s</string>
+ <string name="weakmd">&lt;p&gt;A partire da OpenSSL versione 1.1, OpenSSL rifiuta le firme deboli in certificati come MD5.&lt;/p&gt;&lt;p&gt;&lt;b&gt;firme MD5 sono completamente insicure e non dovrebbero essere più utilizzate.&lt;/b&gt; collisioni MD5 possono essere create in &lt;a
+ href=\"https://natmchugh.blogspot.de/2015/02/create-your-own-md5-collisions.html\"&gt;ore a un costo minimo.&lt;/a&gt;. È necessario aggiornare i certificati VPN il prima possibile.&lt;/p&gt;&lt;p&gt;Sfortunatamente, le vecchie distribuzioni easy-rsa includevano l\'opzione di configurazione \"default_md md5\". Se si utilizza una vecchia versione easy-rsa, si aggiorna alla versione &lt;a href=\"https://github.com/OpenVPN/easy-rsa/releases\"&gt;più recente&lt;/a&gt;) o si modifica md5 in sha256 e si rigenerano i certificati.&lt;/p&gt;&lt;p&gt;Se si desidera utilizzare effettivamente certificati vecchi e guasti, utilizzare l\'opzione di configurazione personalizzata tls-cipher \"DEFAULT: @ SECLEVEL = 0\" in configurazione avanzata o come riga aggiuntiva nella configurazione importata&lt;/p&gt;
+ </string>
<string name="volume_byte">%.0f B</string>
<string name="volume_kbyte">%.1f kB</string>
<string name="volume_mbyte">%.1f MB</string>
<string name="volume_gbyte">%.1f GB</string>
+ <string name="channel_name_background">Statistiche di connessione</string>
+ <string name="channel_description_background">Statistiche in corso della connessione OpenVPN stabilita</string>
+ <string name="channel_name_status">Cambio dello stato della connessione</string>
+ <string name="channel_description_status">Cambiamenti di stato della connessione OpenVPN (Connessione, autenticazione, ...)</string>
+ <string name="weakmd_title">Hash (MD5) troppo deboli nella firma del certificato (SSL_CTX_use_certificate md too weak)</string>
+ <string name="title_activity_open_sslspeed">Test di velocità OpenSSL</string>
+ <string name="openssl_cipher_name">Nomi di cifratura OpenSSL</string>
+ <string name="osslspeedtest">OpenSSL Crypto Speed ​​test</string>
+ <string name="openssl_error">OpenSSL ha restituito un errore</string>
+ <string name="running_test">Esecuzione di test&#8230;</string>
+ <string name="test_algoirhtms">Testa gli algoritmi selezionati</string>
+ <string name="all_app_prompt">Un\'app esterna tenta di controllare %s. L\'app che richiede l\'accesso non può essere determinata. Consentendo questa app garantisce l\'accesso a TUTTE le app.</string>
+ <string name="openvpn3_nostatickeys">L\'implementazione di OpenVPN 3 C ++ non supporta le chiavi statiche. Passare a OpenVPN 2.x nelle impostazioni generali.</string>
+ <string name="openvpn3_pkcs12">L\'utilizzo di file PKCS12 direttamente con l\'implementazione di OpenVPN 3 C++ non è supportato. Importare i file pkcs12 nel keystore Android o passare a OpenVPN 2.x nelle impostazioni generali.</string>
+ <string name="proxy">Proxy</string>
+ <string name="Use_no_proxy">Nessuno</string>
+ <string name="tor_orbot">Tor (Orbot)</string>
</resources>
diff --git a/app/src/main/res/values-ja/strings-icsopenvpn.xml b/app/src/main/res/values-ja/strings-icsopenvpn.xml
index c491ce93..4f0a6359 100755
--- a/app/src/main/res/values-ja/strings-icsopenvpn.xml
+++ b/app/src/main/res/values-ja/strings-icsopenvpn.xml
@@ -216,7 +216,7 @@ Androidはあなた自身の安全性のために、これらを迂回できな
<string name="setting_loadtun">TUNモジュールをロード</string>
<string name="importpkcs12fromconfig">PKCS12の設定をAndroidのキーストアにインポートします</string>
<string name="getproxy_error">プロキシ設定でエラー: %s</string>
- <string name="using_proxy">プロキシを使用します %1$s %2$d</string>
+ <string name="using_proxy">プロキシを使用します %1$s %2$s</string>
<string name="use_system_proxy">システムのプロキシ設定を使用する</string>
<string name="use_system_proxy_summary">接続にシステム全体の構成の HTTP/HTTPS プロキシを使用します。</string>
<string name="onbootrestartsummary">有効にすると、OpenVPNはシステムの起動時に指定されたVPNに接続します。Android 5.0より前のバージョンでこのオプションを使用する場合は、接続時の警告に関する「よくある質問」を読んでください。</string>
@@ -477,12 +477,29 @@ Android 4.4以上はポリシールーティングを使用します。route/ifc
<string name="kbits_per_second">%.1f kbit/s</string>
<string name="mbits_per_second">%.1f Mbit/s</string>
<string name="gbits_per_second">%.1f Gbit/s</string>
+ <string name="weakmd">&lt;p&gt;OpenSSL version 1.1より、OpenSSLはMD5のような脆弱な署名による証明書を拒否するようになりました。&lt;/p&gt;&lt;p&gt;&lt;b&gt;MD5による署名は完全に脆弱でいかなる場面でも使われるべきではありません。&lt;/b&gt; 衝突するMD5の生成は&lt;a
+ href=\"https://natmchugh.blogspot.de/2015/02/create-your-own-md5-collisions.html\"&gt;最短で数時間&lt;/a&gt;で可能です。できるだけ早くVPNの証明書を更新すべきです。&lt;/p&gt;&lt;p&gt;残念なことに、古いeasy-rsaディストリビューションの中には設定として\"default_md md5\"が入っています。 もし古いeasy-rsaを使用しているようなら、&lt;a href=\"https://github.com/OpenVPN/easy-rsa/releases\"&gt;最新版&lt;/a&gt;)にアップデートするか、MD5からSHA256に変更して証明書を再生成してください。
+&lt;/p&gt;&lt;p&gt;もしどうしても古く劣化した証明書を使いたいのなら、高度な設定のカスタムオプションでtls-cipher \"DEFAULT:@SECLEVEL=0\"を追加してください。&lt;/p&gt;
+ </string>
<string name="volume_byte">%.0f B</string>
<string name="volume_kbyte">%.1f kB</string>
<string name="volume_mbyte">%.1f MB</string>
<string name="volume_gbyte">%.1f GB</string>
+ <string name="channel_name_background">Connection statistics</string>
+ <string name="channel_description_background">確立されたOpenVPN接続の継続的な統計</string>
+ <string name="channel_name_status">接続状態の変化</string>
+ <string name="channel_description_status">OpenVPN接続の状態変化(接続、認証等)</string>
+ <string name="weakmd_title">証明書の署名は弱いMD5です (SSL_CTX_use_certificate md は弱すぎます)</string>
<string name="title_activity_open_sslspeed">OpenSSLスピードテスト</string>
+ <string name="openssl_cipher_name">OpenSSLの暗号名</string>
+ <string name="osslspeedtest">OpenSSLの暗号化スピードテスト</string>
<string name="openssl_error">OpenSSLがエラーを返しました</string>
<string name="running_test">テストを実行中...</string>
+ <string name="test_algoirhtms">選択したアルゴリズムをテストする</string>
<string name="all_app_prompt">外部アプリが%sを制御しようとしています。アクセスをリクエストしているアプリは特定できません。このアプリを許可すると、すべてのアプリがアクセス許可されます。</string>
+ <string name="openvpn3_nostatickeys">OpenVPN 3 C ++実装は静的キーをサポートしていません。設定でOpenVPN 2.xに変更してください。</string>
+ <string name="openvpn3_pkcs12">OpenVPN 3 C++実装ではPKCS12ファイルを直接使用することはサポートされていません。 PKCS12ファイルをAndroidキーストアにインポートするか、設定でOpenVPN 2.xに変更してください。</string>
+ <string name="proxy">プロキシ</string>
+ <string name="Use_no_proxy">使用しない</string>
+ <string name="tor_orbot">Tor (Orbot)</string>
</resources>
diff --git a/app/src/main/res/values-ko/strings-icsopenvpn.xml b/app/src/main/res/values-ko/strings-icsopenvpn.xml
index e610bf79..02c8c364 100755
--- a/app/src/main/res/values-ko/strings-icsopenvpn.xml
+++ b/app/src/main/res/values-ko/strings-icsopenvpn.xml
@@ -98,10 +98,10 @@
<string name="edit_vpn">VPN 설정 편집</string>
<string name="remove_vpn_query">VPN 프로파일 \'%s\'을 삭제할까요?</string>
<string name="tun_error_helpful">일부 커스텀 ICS 이미지에서는 /dev/tun에 대한 권한이 잘못되어 있거나 tun 모듈 자체가 누락될 수 있습니다. CM9 이미지는 일반 설정에 있는 소유권 고치기 옵션을 사용해 보십시오.</string>
- <string name="tun_open_error">TUN 인터페이스를 열지 못했습니다</string>
+ <string name="tun_open_error">Tun 인터페이스를 열지 못했습니다</string>
<string name="error">"오류: "</string>
<string name="clear">지우기</string>
- <string name="last_openvpn_tun_config">TUN 인터페이스 열기:</string>
+ <string name="last_openvpn_tun_config">Tun 인터페이스 열기:</string>
<string name="local_ip_info">로컬 IPv4: %1$s/%2$d IPv6: %3$s MTU: %4$d</string>
<string name="dns_server_info">DNS 서버: %1$s, 도메인: %2$s</string>
<string name="routes_info_incl">경로: %1$s %2$s</string>
@@ -116,7 +116,7 @@
<string name="send">보내기</string>
<string name="ics_openvpn_log_file">ICS OpenVPN 로그 파일</string>
<string name="copied_entry">클립보드로 로그 복사</string>
- <string name="tap_mode">TAP 모드</string>
+ <string name="tap_mode">Tap 모드</string>
<string name="faq_tap_mode">TAP 모드는 루트가 아닌 VPN API에서는 불가능합니다. 따라서 본 앱은 TAP 지원을 제공할 수 없습니다</string>
<string name="tap_faq2">또? 농담인가요? 아니요. 정말로 TAP 모드는 지원이 불가능합니다. 계속해서 메일을 보내면서 요구하신다고 도움될 일이 아닙니다.</string>
<string name="tap_faq3">세 번째로? 실제로는 송신 때 레이어2 정보를 추가하고 수신 때 레이어2 정보를 떼내는 TUN을 이용한 TAP 에뮬레이터를 제작하는 것이 가능합니다. 하지만 이것만이 아닌 ARP 그리고 어쩌면 DHCP 클라이언트까지도 구현해야 합니다. 본인은 이 같은 작업을 하는 분을 알고 있지 않습니다. 코딩을 시작하려고 하시는 분이 계시면 제게 연락해 주십시오.</string>
@@ -201,7 +201,7 @@
<string name="setting_loadtun">TUN 모듈 로드하기</string>
<string name="importpkcs12fromconfig">구성에 있는 PKCS12를 안드로이드 키 저장소로 가져오기</string>
<string name="getproxy_error">프록시 설정 가져오기 오류: %s</string>
- <string name="using_proxy">프록시 %1$s %2$d를 사용</string>
+ <string name="using_proxy">%1$s</string>
<string name="use_system_proxy">시스템 프록시를 사용</string>
<string name="use_system_proxy_summary">연결할 HTTP/HTTPS 프록시로 시스템 범위의 설정을 사용합니다.</string>
<string name="onbootrestartsummary">OpenVPN이 시스템 부팅시에 활성화되면 지정된 VPN에 연결합니다. 안드로이드 5.0 이전 버전에 이 옵션을 사용하기 전에 연결 경고 FAQ를 읽어 보시기 바랍니다.</string>
@@ -215,7 +215,7 @@
<string name="faq_duplicate_notification">안드로이드는 시스템의 메모리(램)가 부족한 경우, 현재 필요하지 않는 앱들과 서비스들을 활성 메모리에서 삭제합니다. 이 과정에서 진행중인 VPN 연결이 끊어집니다. 이렇게 되지 않기 위해서 OpenVPN 서비스는 더 높은 우선 순위로 실행됩니다. 더 높은 우선 순위로 실행되기 위해서는 앱이 알림을 표시해야 합니다. 열쇠 알림 아이콘은 이전 FAQ에서 설명된 대로 시스템에서 강요하는 것입니다. 이것은 더 높은 우선 순위로 실행되기 위한 앱 알림이 아닙니다.</string>
<string name="no_vpn_profiles_defined">정의된 VPN 프로파일이 없습니다.</string>
<string name="add_new_vpn_hint">이 &lt;img src=\"ic_menu_add\"/&gt; 아이콘을 사용하여 VPN을 추가하세요</string>
- <string name="vpn_import_hint">이 &lt;img src=\"ic_menu_archive\"/&gt; 아이콘을 사용하여 귀하의 SD 카드에서 기존 (.ovpn 또는 .conf) 프로파일을 가져오세요.</string>
+ <string name="vpn_import_hint">이 &lt;img src=\"ic_menu_archive\"/&gt; 아이콘을 사용하여 귀하의 Sd 카드에서 기존 (.ovpn 또는 .conf) 프로파일을 가져오세요.</string>
<string name="faq_hint">꼭 FAQ를 확인하세요. 빠른 시작 가이드가 있습니다.</string>
<string name="faq_routing_title">라우팅/인터페이스 구성</string>
<string name="faq_routing">라우팅 및 인터페이스 구성은 기존 ifconfig/route 명령을 통하지 않고 VPNService API를 사용하여 수행됩니다. 그 결과 다른 OS와 다른 라우팅 구성이 생깁니다.\nVPN 터널의 구성은 IP 주소와 이 인터페이스를 통해 라우팅되어야 하는 네트워크들로 이루어져 있습니다. 특히 피어 파트너 주소 또는 게이트웨이 주소가 필요하거나 요구되지 않습니다. VPN 서버에 이르는 특수 경로들(예컨대 redirect-gateway 사용시 추가되는 것)도 필요하지 않습니다. 따라서 앱은 구성을 가져올 때 이러한 설정을 무시합니다. 이 앱은 VPNService API를 사용하여 서버에 대한 연결이 VPN 터널을 통해 라우팅되지 않도록 합니다.\nVPNService API는 VPN을 통해 라우트하지 않아야 할 네트워크들을 지정하는 걸 허용하지 않습니다. 우회 방법으로서 앱이 터널을 통해 라우팅해서는 안 되는 네트워크들(예: route x.x.x.x y.y.y.y net_gateway)을 감지하고 다른 플랫폼의 동작을 모방하기 위해 이 경로들을 제외한 일련의 경로들을 계산합니다. 로그 창은 연결을 수립할 때 VPNService의 설정을 보여줍니다.\n무대 뒤에서: Android 4.4 이상은 정책 라우팅을 사용합니다. route/ifconfig를 사용해선 설치된 경로를 볼 수 없을 것입니다. 대신 ip rule, iptables -t mangle -L을 사용하십시오.</string>
@@ -469,4 +469,7 @@
<string name="all_app_prompt">어떤 외부 앱이 %s를 제어하려고 합니다. 접근을 요청하는 앱을 정해 놓을 수 없습니다. 이 앱을 허용하면 모든 앱의 접근을 승인하게 됩니다.</string>
<string name="openvpn3_nostatickeys">OpenVPN 3 C++ 구현은 고정 키를 지원하지 않습니다. 일반 설정에서 OpenVPN 2.x로 변경해 주세요.</string>
<string name="openvpn3_pkcs12">OpenVPN 3 C++ 구현과 함께 PKCS12 파일을 직접 사용하는 것은 지원되지 않습니다. PKCS12 파일을 안드로이드 키 저장소로 가져 오거나 일반 설정에서 OpenVPN 2.x으로 변경하세요.</string>
+ <string name="proxy">대리</string>
+ <string name="Use_no_proxy">없음</string>
+ <string name="tor_orbot">Tor (Orbot)</string>
</resources>
diff --git a/app/src/main/res/values-nl/strings-icsopenvpn.xml b/app/src/main/res/values-nl/strings-icsopenvpn.xml
index 737cc2d3..e7a2b5a1 100755
--- a/app/src/main/res/values-nl/strings-icsopenvpn.xml
+++ b/app/src/main/res/values-nl/strings-icsopenvpn.xml
@@ -201,7 +201,7 @@
<string name="setting_loadtun">Laad tun module</string>
<string name="importpkcs12fromconfig">Importeer PKCS12 van configuratie naar Android Keystore</string>
<string name="getproxy_error">Fout bij het verkrijgen van proxy-instellingen: %s</string>
- <string name="using_proxy">Proxy %1$s %2$d is in gebruik</string>
+ <string name="using_proxy">Proxy %1$s %2$s is in gebruik</string>
<string name="use_system_proxy">Gebruik systeemproxy</string>
<string name="use_system_proxy_summary">Gebruik de systeemconfiguratie voor HTTP/HTTPS proxies om te verbinden.</string>
<string name="onbootrestartsummary">OpenVPN verbindt met de opgegeven VPN als deze actief was bij het opstarten van het systeem. Lees de FAQ over verbindingswaarschuwingen voordat u deze optie gebruikt op Android &lt; 5.0.</string>
@@ -464,4 +464,7 @@
<string name="all_app_prompt">Een externe app probeert %s te besturen. De app die om toegang vraagt, kan niet worden vastgesteld. Als u deze app toestaat, krijgen ALLE apps toegang.</string>
<string name="openvpn3_nostatickeys">De OpenVPN 3 C++ -implementatie ondersteunt geen statische sleutels. Verander naar OpenVPN 2.x onder algemene instellingen.</string>
<string name="openvpn3_pkcs12">PKCS12-bestanden rechtstreeks gebruiken met OpenVPN 3 C++ -implementatie wordt niet ondersteund. Importeer de pkcs12-bestanden in de Android keystore of verander naar OpenVPN 2.x onder algemene instellingen.</string>
+ <string name="proxy">Proxy</string>
+ <string name="Use_no_proxy">Geen</string>
+ <string name="tor_orbot">Tor (Orbot)</string>
</resources>
diff --git a/app/src/main/res/values-no/strings-icsopenvpn.xml b/app/src/main/res/values-no/strings-icsopenvpn.xml
index 5c29339d..68638149 100755
--- a/app/src/main/res/values-no/strings-icsopenvpn.xml
+++ b/app/src/main/res/values-no/strings-icsopenvpn.xml
@@ -172,7 +172,6 @@
<string name="setting_loadtun_summary">Prøv å laste tun.ko kjernemodul før tilkobling. Krever at enheten er rootet.</string>
<string name="setting_loadtun">Last tun modul</string>
<string name="getproxy_error">Feil ved henting av proxy-innstillinger: %s</string>
- <string name="using_proxy">Bruker proxy %1$s %2$d</string>
<string name="use_system_proxy">Bruk systemet proxy</string>
<string name="use_system_proxy_summary">Bruk global systemkonfigurasjon for HTTP/HTTPS proxy for å koble til.</string>
<string name="onbootrestart">Koble til ved oppstart</string>
diff --git a/app/src/main/res/values-pl/plurals-icsopenvpn.xml b/app/src/main/res/values-pl/plurals-icsopenvpn.xml
index 906e4395..70489fbc 100755
--- a/app/src/main/res/values-pl/plurals-icsopenvpn.xml
+++ b/app/src/main/res/values-pl/plurals-icsopenvpn.xml
@@ -1,9 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<!--Generated by crowdin.com-->
-<resources>
- <plurals name="months_left">
- <item quantity="one">Pozostał jeden miesiąc</item>
- <item quantity="few">Pozostało %d miesięcy</item>
- <item quantity="other">pozostało %d miesięcy</item>
- </plurals>
-</resources>
+<resources></resources>
diff --git a/app/src/main/res/values-pl/strings-icsopenvpn.xml b/app/src/main/res/values-pl/strings-icsopenvpn.xml
index 414a0f11..07017e6a 100755
--- a/app/src/main/res/values-pl/strings-icsopenvpn.xml
+++ b/app/src/main/res/values-pl/strings-icsopenvpn.xml
@@ -201,7 +201,7 @@
<string name="setting_loadtun">Załaduj moduł tun</string>
<string name="importpkcs12fromconfig">Importuj PKCS12 z konfiguracji do pęku kluczy Androida</string>
<string name="getproxy_error">Błąd pobierania ustawień proxy: %s</string>
- <string name="using_proxy">Używam proxy %1$s%2$d</string>
+ <string name="using_proxy">Korzystanie z serwera proxy %1$s %2$s</string>
<string name="use_system_proxy">Użyj proxy systemowego</string>
<string name="use_system_proxy_summary">Połącz używając systemowej konfiguracji proxy HTTP/HTTPS.</string>
<string name="onbootrestartsummary">OpenVPN połączy się z wybranym VPN jeżeli będzie aktywny podczas startu systemu. Przeczytaj FAQ dotyczący połączeń przed zastosowaniem tej opcji na Androidzie &lt; 5.0.</string>
@@ -393,6 +393,7 @@ OpenVPN dla Androida ostrzeże Cię o tym w logu.<p>Kiedy VPN ustawi serwer DNS
<string name="query_permissions_sdcard">OpenVPN dla Android spróbuje automatycznie wykryć brakujące pliki na karcie SD. Dotknij tego komunikatu, aby żądać uprawnień.</string>
<string name="protocol">Protokół</string>
<string name="enabled_connection_entry">Włączony</string>
+ <string name="abi_mismatch">Preferowane natywne pierwszeństwo ABI tego urządzenia (%1$s) i ABI zgłoszone przez niezgodność bibliotek (%2$s) natywnych</string>
<string name="permission_revoked">Pozwolenie VPN odwołane przez system (na przykład inny program VPN jest uruchomiony), zatrzymuję VPN</string>
<string name="pushpeerinfo">Naciśnij \"Peer info\"</string>
<string name="pushpeerinfosummary">Wyślij dodatkowe informację do serwera, na przykład wersję SSL oraz Androida</string>
@@ -409,6 +410,7 @@ OpenVPN dla Androida ostrzeże Cię o tym w logu.<p>Kiedy VPN ustawi serwer DNS
<string name="samsung_broken_title">Telefony Samsung</string>
<string name="novpn_selected">Nie wybrano VPN.</string>
<string name="defaultvpn">Domyślny VPN</string>
+ <string name="defaultvpnsummary">VPN używany w miejscach, gdzie trzeba domyślnego VPN. Obecnie przy uruchomieniu, dla Always-On i pliku Quick Settings.</string>
<string name="vpnselected">Obecnie wybrana sieć VPN: \'%s\'</string>
<string name="reconnect">Podłącz ponownie</string>
<string name="qs_title">Przełącz VPN</string>
@@ -417,6 +419,7 @@ OpenVPN dla Androida ostrzeże Cię o tym w logu.<p>Kiedy VPN ustawi serwer DNS
<string name="connectretrymaxmessage">Podaj maksymalny czas pomiędzy kolejnymi próbami połączenia. OpenVPN będzie powoli zwiększał czas oczekiwania po każdej nieudanej próbie połączenia aż do podanej wartości. Domyślna wartość to 300 sekund.</string>
<string name="connectretrymaxtitle">Maksymalny czas między próbami połączenia</string>
<string name="state_waitconnectretry">Oczekiwanie %s sekund pomiędzy kolejnymi próbami połączenia</string>
+ <string name="nought_alwayson_warning"><![CDATA[Jeśli nie dostałeś potwierdzenia VPN, masz włączony \"Always on VPN\" dla innej aplikacji. W tym przypadku tylko ona może łączyć się z VPN. Sprawdź Ustawienia-> Sieci więcej .. -> VPN]]></string>
<string name="management_socket_closed">Połączenie OpenVPN zamknięte (%s)</string>
<string name="change_sorting">Zmień sortowanie</string>
<string name="sort">Sortowanie</string>
@@ -436,8 +439,29 @@ OpenVPN dla Androida ostrzeże Cię o tym w logu.<p>Kiedy VPN ustawi serwer DNS
<string name="kbits_per_second">%.1f kbit/s</string>
<string name="mbits_per_second">%.1f Mbit / s</string>
<string name="gbits_per_second">%.1f Gbit/s</string>
+ <string name="weakmd">&lt;p&gt;Począwszy od wersji OpenSSL 1.1, OpenSSL odrzuca słabe sygnatury w certyfikatach takich jak MD5.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Podpisy MD5 są całkowicie niezabezpieczone i nie powinny być już używane.&lt;/b&gt; Zderzenia MD5 można utworzyć w ciągu &lt;a
+ href=\"https://natmchugh.blogspot.de/2015/02/create-your-own-md5-collisions.html\"&gt;godzin przy minimalnych kosztach.&lt;/a&gt;. Należy zaktualizować certyfikaty VPN tak szybko, jak to możliwe.&lt;/p&gt;&lt;p&gt;Niestety, starsze dystrybucje easy-rsa zawierały opcję konfiguracji \"default_md md5\". Jeśli używasz starej wersji easy-rsa, zaktualizuj do &lt;a href=\"https://github.com/OpenVPN/easy-rsa/releases\"&gt;najnowszej wersji&lt;/a&gt;) lub zmień md5 na sha256 i zrestartuj swoje certyfikaty.&lt;/p&gt;&lt;p&gt;Jeśli naprawdę chcesz używać starych i uszkodzonych certyfikatów, użyj niestandardowej opcji konfiguracji tls-cipher \"DEFAULT: @ SECLEVEL = 0\" w konfiguracji zaawansowanej lub jako dodatkowej linii w zaimportowanej konfiguracji&lt;/p&gt;
+ </string>
<string name="volume_byte">%.0f B</string>
<string name="volume_kbyte">%.1f kB</string>
<string name="volume_mbyte">%.1f MB</string>
<string name="volume_gbyte">%.1f GB</string>
+ <string name="channel_name_background">Statystyki połączenia</string>
+ <string name="channel_description_background">Statystyki obecnie nawiązanego połączenia OpenVPN</string>
+ <string name="channel_name_status">Zmiana statusu połączenia</string>
+ <string name="channel_description_status">Zmiana statusu połączenia OpenVPN (Łączenie, uwierzytelnianie,...)</string>
+ <string name="weakmd_title">Słabe hasze (MD5) w podpisie certyfikatu
+(SSL_CTX_use_certificate md za słabe)</string>
+ <string name="title_activity_open_sslspeed">OpenSSL Test Prędkości</string>
+ <string name="openssl_cipher_name">OpenSSL nazwy szyfrów</string>
+ <string name="osslspeedtest">OpenSSL Test Szybkości Crypto</string>
+ <string name="openssl_error">OpenSSL zwrócił błąd</string>
+ <string name="running_test">Testowanie&#8230;</string>
+ <string name="test_algoirhtms">Test wybranych algorytmów</string>
+ <string name="all_app_prompt">Zewnętrzna aplikacja próbuje przejąć kontrolę %s. Prośba o dostęp nie może być zweryfikowana. Zezwolenie da jej dostęp do WSZYSTKICH aplikacji.</string>
+ <string name="openvpn3_nostatickeys">Implementacja OpenVPN 3 C++ nie wspiera kluczy statycznych. Proszę zmienić na OpenVPN 2.x pod głównymi ustawieniami.</string>
+ <string name="openvpn3_pkcs12">Używanie plików PKCS22 bezpośrednio z implementacją OpenVPN 3 C++ nie jest wspierane. Proszę zaimportować pliki PKCS12 do magazynu kluczy Androida lub przejść na OpenVPN 2.x pod głównymi ustawieniami.</string>
+ <string name="proxy">Proxy</string>
+ <string name="Use_no_proxy">Żaden</string>
+ <string name="tor_orbot">Tor (Orbot)</string>
</resources>
diff --git a/app/src/main/res/values-pt/strings-icsopenvpn.xml b/app/src/main/res/values-pt/strings-icsopenvpn.xml
index 52772eba..7f1407f9 100755
--- a/app/src/main/res/values-pt/strings-icsopenvpn.xml
+++ b/app/src/main/res/values-pt/strings-icsopenvpn.xml
@@ -191,7 +191,6 @@
<string name="setting_loadtun_summary">Tente carregar o módulo tun.ko do kernel antes de ligar. Necessita de acesso root ao dispositivo.</string>
<string name="setting_loadtun">Carregar o módulo tun</string>
<string name="getproxy_error">Erro ao obter definições proxy %s</string>
- <string name="using_proxy">A utilizar proxy %1$s %2$d</string>
<string name="use_system_proxy">Usar a proxy do sistema</string>
<string name="onbootrestart">Ligar no arranque</string>
<string name="ignore">Ignorar</string>
diff --git a/app/src/main/res/values-ro/strings-icsopenvpn.xml b/app/src/main/res/values-ro/strings-icsopenvpn.xml
index 8ca5dce3..a784a190 100755
--- a/app/src/main/res/values-ro/strings-icsopenvpn.xml
+++ b/app/src/main/res/values-ro/strings-icsopenvpn.xml
@@ -201,7 +201,6 @@
<string name="setting_loadtun">Încarcă modulul tun</string>
<string name="importpkcs12fromconfig">Import PKCS12 configurare în Android Keystore</string>
<string name="getproxy_error">Eroare la obţinerea setărilor proxy: %s</string>
- <string name="using_proxy">Folosesc proxy %1$s %2$d</string>
<string name="use_system_proxy">Foloseşte proxy sistem</string>
<string name="use_system_proxy_summary">Foloseşte configurarea sistem pentru proxy HTTP/HTTPS folosit la conectare.</string>
<string name="onbootrestartsummary">OpenVPN va conecta VPN-ul specificat dacă vs fi activ la pornirea sistemului. Citiți întrebările frecvente privind avertizare de conexiune înainte de a utiliza această opțiune pe Android &lt; 5.0.</string>
diff --git a/app/src/main/res/values-ru/plurals-icsopenvpn.xml b/app/src/main/res/values-ru/plurals-icsopenvpn.xml
index 7cc8112c..66f65501 100755
--- a/app/src/main/res/values-ru/plurals-icsopenvpn.xml
+++ b/app/src/main/res/values-ru/plurals-icsopenvpn.xml
@@ -2,23 +2,27 @@
<!--Generated by crowdin.com-->
<resources>
<plurals name="months_left">
- <item quantity="one">Остался один месяц</item>
+ <item quantity="one">Остался %d месяц</item>
<item quantity="few">Осталось %d месяца</item>
+ <item quantity="many">Осталось %d месяцев</item>
<item quantity="other">Осталось %d месяцев</item>
</plurals>
<plurals name="days_left">
- <item quantity="one">Остался один день</item>
+ <item quantity="one">Остался %d день</item>
<item quantity="few">Осталось %d дня</item>
+ <item quantity="many">Осталось %d дней</item>
<item quantity="other">Осталось %d дней</item>
</plurals>
<plurals name="hours_left">
- <item quantity="one">Остался один час</item>
+ <item quantity="one">Остался %d час</item>
<item quantity="few">Осталось %d часа</item>
+ <item quantity="many">Осталось %d часов</item>
<item quantity="other">Осталось %d часов</item>
</plurals>
<plurals name="minutes_left">
- <item quantity="one">Осталась одна минута</item>
+ <item quantity="one">Осталась %d минута</item>
<item quantity="few">Осталось %d минуты</item>
+ <item quantity="many">Осталось %d минут</item>
<item quantity="other">Осталось %d минут</item>
</plurals>
</resources>
diff --git a/app/src/main/res/values-ru/strings-icsopenvpn.xml b/app/src/main/res/values-ru/strings-icsopenvpn.xml
index 73acc96a..9dda5191 100755
--- a/app/src/main/res/values-ru/strings-icsopenvpn.xml
+++ b/app/src/main/res/values-ru/strings-icsopenvpn.xml
@@ -201,10 +201,10 @@
<string name="setting_loadtun">Загрузить tun-модуль</string>
<string name="importpkcs12fromconfig">Импорт PKCS12 из хранилища ключей Android</string>
<string name="getproxy_error">Ошибка при получении параметров прокси-сервера: %s</string>
- <string name="using_proxy">Используется прокси-сервер %1$s %2$d</string>
+ <string name="using_proxy">Используется прокси-сервер %1$s %2$s</string>
<string name="use_system_proxy">Использовать прокси-сервер системы</string>
<string name="use_system_proxy_summary">Использовать системную конфигурацию прокси HTTP/HTTPS для соединения.</string>
- <string name="onbootrestartsummary">OpenVPN будет подключаться к указанному VPN, если он был активен при загрузке системы. Пожалуйста, прочитайте FAQ о предупреждении при подключении перед тем, как использовать эту опцию на Android &lt; 5.0.</string>
+ <string name="onbootrestartsummary">OpenVPN будет подключаться к указанному VPN, если он был активен при загрузке системы. Пожалуйста, прочитайте FAQ о предупреждении при подключении перед тем, как использовать эту функцию на Android &lt; 5.0.</string>
<string name="onbootrestart">Подключение при загрузке</string>
<string name="ignore">Игнорировать</string>
<string name="restart">Перезапуск</string>
@@ -268,7 +268,7 @@
<string name="add">Добавить</string>
<string name="send_config">Отправить конфигурационный файл</string>
<string name="complete_dn">Полное DN</string>
- <string name="remotetlsnote">Импортированная конфигурация использует УСТАРЕВШУЮ опцию tls-remote, которая имеет другой формат DN.</string>
+ <string name="remotetlsnote">Импортированная конфигурация использует УСТАРЕВШУЮ функцию tls-remote, которая имеет другой формат DN.</string>
<string name="rdn">RDN (полное имя)</string>
<string name="rdn_prefix">Префикс RDN</string>
<string name="tls_remote_deprecated">tls-remote (УСТАРЕВШЕЕ)</string>
@@ -279,7 +279,7 @@
<string name="no_external_app_allowed">Нет приложений, авторизованных для внешнего API</string>
<string name="allowed_apps">Разрешённые приложения: %s</string>
<string name="clearappsdialog">Очистить список авторизованных внешних приложений?\nСписок разрешенных приложений:\n\n%s</string>
- <string name="screenoff_summary">Приостанавливать VPN, если экран выключен и передано меньше 64kb данных за 60 сек. Когда включена опция \"Постоянный туннель\", приостановка VPN оставит ваше устройство без сетевого подключения. Без опции \"Постоянный туннель\" устройство не будет иметь VPN-соединения/защиты.</string>
+ <string name="screenoff_summary">Приостанавливать VPN, если экран выключен и передано меньше 64 КБ данных за 60 сек. Когда включена функция \"Постоянный туннель\", приостановка VPN оставит ваше устройство без сетевого подключения. Без функции \"Постоянный туннель\" устройство не будет иметь VPN-соединения/защиты.</string>
<string name="screenoff_title">Приостановить VPN-соединение при выключенном экране</string>
<string name="screenoff_pause">Приостановка соединения при выключенном экране: меньше, чем %1$s за %2$sс</string>
<string name="screen_nopersistenttun">Внимание: Постоянный туннель не включен для этого VPN. Трафик будет использовать обычное интернет соединение, когда экран выключен.</string>
@@ -314,7 +314,7 @@
<string name="unhandled_exception_context">%3$s: %1$s\n\n%2$s</string>
<string name="faq_system_dialog_xposed">Если на вашем устройстве есть root, можете установить &lt;a href=\"http://xposed.info/\"&gt;Xposed framework&lt;/a&gt; и &lt;a href=\"http://repo.xposed.info/module/de.blinkt.vpndialogxposed\"&gt;модуль автоматического подтверждения диалога подключения VPN&lt;/a&gt; на свой страх и риск</string>
<string name="full_licenses">Полные тексты лицензий</string>
- <string name="blocklocal_summary">Сети, доступные напрямую через локальный интерфейс, не будут маршрутизированы через VPN. Отключите эту опцию, чтобы направить трафик через VPN.</string>
+ <string name="blocklocal_summary">Сети, доступные напрямую через локальный интерфейс, не будут маршрутизированы через VPN. Отключите эту функцию, чтобы направить трафик через VPN.</string>
<string name="blocklocal_title">Не использовать VPN для локальных адресов</string>
<string name="userpw_file">Файл логина и пароля</string>
<string name="imported_from_file">[Импортировано из: %s]</string>
@@ -355,7 +355,7 @@
<string name="ignore_multicast_route">Игнорируется мультиадресный маршрут: %s</string>
<string name="ab_only_cidr">Android поддерживает только CIDR маршруты к VPN. Поскольку не CIDR маршруты почти никогда не используются, OpenVPN для Android будет использовать /32 для не CIDR маршрутов и выдавать предупреждение.</string>
<string name="ab_tethering_44">Тетеринг/раздача интернета работает, когда активен VPN. Модемное соединение (тетеринг) НЕ БУДЕТ использовать VPN.</string>
- <string name="ab_kitkat_mss">Ранние версии KitKat устанавливают неверное значение MSS для TCP соединений (#61948). Попробуйте включить опцию mssfix, чтобы обойти этот баг.</string>
+ <string name="ab_kitkat_mss">Ранние версии KitKat устанавливают неверное значение MSS для TCP-соединений (#61948). Попробуйте включить функцию mssfix, чтобы обойти эту ошибку.</string>
<string name="ab_proxy">Android будет продолжать использовать ваши настройки прокси, указанные для мобильного/Wi-Fi соединения, когда не установлен DNS сервер. OpenVPN for Android предупредит вас об этом в журнале.<p>Когда VPN устанавливает DNS сервер Android не использует прокси. Для установки прокси для VPN соединения нет API.</p></string>
<string name="ab_lollipop_reinstall">Приложения VPN могут перестать работать после удаления и повторной установки. Подробности см. #80074</string>
<string name="ab_not_route_to_vpn">Сконфигурированный IP-адрес клиента и IP-адреса в его подсети (согласно сетевой маске) не направляются через VPN. OpenVPN обходит этот баг, явно добавляя маршрут, который соответствует клиентскому IP и его сетевой маске</string>
@@ -424,7 +424,7 @@
<string name="sort">Сортировать</string>
<string name="sorted_lru">Профили отсортированы по порядку последнего использования</string>
<string name="sorted_az">Профили отсортированы по названию</string>
- <string name="deprecated_tls_remote">Файл настройки использует опцию tls-remote, которая была объявлена устаревшей в версии 2.3 и окончательно удалена в версии 2.4</string>
+ <string name="deprecated_tls_remote">Файл настройки использует функцию tls-remote, которая была объявлена устаревшей в версии 2.3 и окончательно удалена в версии 2.4</string>
<string name="auth_failed_behaviour">Поведение при AUTH_FAILED</string>
<string name="graph">График</string>
<string name="use_logarithmic_scale">Использовать логарифмическую шкалу</string>
@@ -438,8 +438,7 @@
<string name="kbits_per_second">%.1f Кбит/с</string>
<string name="mbits_per_second">%.1f Мбит/с</string>
<string name="gbits_per_second">%.1f Гбит/с</string>
- <string name="weakmd">&lt;p&gt; Начиная с OpenSSL версии 1.1, OpenSSL отклоняет слабые подписи в таких сертификатах, как MD5.&lt;/p&gt;&lt;p&gt;&lt;b&gt;MD5, подписи полностью небезопасны и больше не должны использоваться.&lt;/b&gt; Столкновения MD5 могут быть созданы в &lt;a
- href=\"https://natmchugh.blogspot.de/2015/02/create-your-own-md5-collisions.html\"&gt; через несколько часов с минимальными затратами.&lt;/a&gt;. Вы должны как можно скорее обновить сертификаты VPN. &lt;/p&gt;&lt;p&gt;К сожалению, старые дистрибутивы easy-rsa включали опцию конфигурации «default_md md5». Если вы используете старую версию easy-rsa, обновите ее до &lt;a href=\"https://github.com/OpenVPN/easy-rsa/releases\"&gt;latest версии&lt;/a&gt;) или измените md5 на sha256 и восстановите свои сертификаты.&lt;/p&gt;&lt;p&gt;Если вы действительно хотите использовать старые и поврежденные сертификаты, используйте настраиваемый параметр конфигурации tls-cipher «DEFAULT: @SECLEVEL = 0 \"в расширенной конфигурации или в качестве дополнительной строки в вашей импортированной конфигурации&lt;/p&gt;
+ <string name="weakmd">&lt;p&gt; Начиная с OpenSSL версии 1.1, OpenSSL отклоняет слабые подписи сертификатов, такие как MD5.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Подписи MD5 полностью небезопасны и больше не должны использоваться.&lt;/b&gt; Коллизии MD5 могут быть созданы &lt;a href=\"https://natmchugh.blogspot.de/2015/02/create-your-own-md5-collisions.html\"&gt; за несколько часов с минимальными затратами.&lt;/a&gt;Вы должны как можно скорее обновить сертификаты VPN. &lt;/p&gt;&lt;p&gt;К сожалению, старые версии easy-rsa включали опцию конфигурации «default_md md5». Если вы используете старую версию easy-rsa, обновите её до &lt;a href=\"https://github.com/OpenVPN/easy-rsa/releases\"&gt;последней версии&lt;/a&gt; или измените md5 на sha256 и обновите свои сертификаты.&lt;/p&gt;&lt;p&gt;Если вы действительно хотите использовать старые и проблемные сертификаты, используйте пользовательский параметр tls-cipher \"DEFAULT:@SECLEVEL=0\" на вкладке «Расширенные» или в качестве дополнительной строки в вашей импортированной конфигурации&lt;/p&gt;
</string>
<string name="volume_byte">%.0f Б</string>
<string name="volume_kbyte">%.1f КБ</string>
@@ -454,9 +453,12 @@
<string name="openssl_cipher_name">Имена шифров OpenSSL</string>
<string name="osslspeedtest">Тест скорости OpenSSL Crypto</string>
<string name="openssl_error">OpenSSL возвратил ошибку</string>
- <string name="running_test">Запуск теста&#8230;</string>
+ <string name="running_test">Тестирование&#8230;</string>
<string name="test_algoirhtms">Тестирование выбранных алгоритмов</string>
<string name="all_app_prompt">Внешнее приложение пытается контролировать %s. Приложение, запрашивающее доступ, не может быть определено. Разрешение этого приложения предоставляет доступ всем приложениям.</string>
- <string name="openvpn3_nostatickeys">Реализация OpenVPN 3 C ++ не поддерживает статические ключи. Перейдите в OpenVPN 2.x под общие настройки.</string>
- <string name="openvpn3_pkcs12">Использование файлов PKCS12 напрямую с помощью OpenVPN 3 C ++ не поддерживается. Импортируйте файлы pkcs12 в хранилище ключей Android или замените OpenVPN 2.x на общие настройки.</string>
+ <string name="openvpn3_nostatickeys">Реализация OpenVPN 3 C ++ не поддерживает статические ключи. Переключитесь на OpenVPN 2.x в общих настройках.</string>
+ <string name="openvpn3_pkcs12">Использование файлов PKCS12 напрямую с помощью OpenVPN 3 C ++ не поддерживается. Импортируйте файлы pkcs12 в хранилище ключей Android или переключитесь на OpenVPN 2.x в общих настройках.</string>
+ <string name="proxy">Прокси</string>
+ <string name="Use_no_proxy">Ничего</string>
+ <string name="tor_orbot">Тор (Орбот)</string>
</resources>
diff --git a/app/src/main/res/values-sl/strings-icsopenvpn.xml b/app/src/main/res/values-sl/strings-icsopenvpn.xml
index 019e27e4..d7ce31b9 100755
--- a/app/src/main/res/values-sl/strings-icsopenvpn.xml
+++ b/app/src/main/res/values-sl/strings-icsopenvpn.xml
@@ -201,7 +201,6 @@
<string name="setting_loadtun">Naloži modul TUN</string>
<string name="importpkcs12fromconfig">Uvozi PKCS12 iz nastavitev v Androidovo shrambo ključev</string>
<string name="getproxy_error">Napaka pri dobivanju nastavitev posredniškega strežnika: %s</string>
- <string name="using_proxy">Uporaba posredniškega strežnika %1$s %2$d</string>
<string name="use_system_proxy">Uporabi sis. pos. str.</string>
<string name="use_system_proxy_summary">Za povezavo uporabi nastavitve celega sistema za posredniške strežnike HTTP/HTTPS.</string>
<string name="onbootrestartsummary">OpenVPN bo povezal navedeni VPN, če je bil dejaven ob zagonu sistema. Preberite pogosta vprašanja o opozorilih glede povezav pred uporabo te možnosti na Androidu &lt; 5.0.</string>
diff --git a/app/src/main/res/values-sv/strings-icsopenvpn.xml b/app/src/main/res/values-sv/strings-icsopenvpn.xml
index c39906be..217de2aa 100755
--- a/app/src/main/res/values-sv/strings-icsopenvpn.xml
+++ b/app/src/main/res/values-sv/strings-icsopenvpn.xml
@@ -201,7 +201,7 @@
<string name="setting_loadtun">Ladda tun modul</string>
<string name="importpkcs12fromconfig">Importera PKCS12 från konfigurationen till Android Keystore</string>
<string name="getproxy_error">Fel vid hämtning av proxyinställningar: %s</string>
- <string name="using_proxy">Använder proxy %1$s %2$d</string>
+ <string name="using_proxy">Använder proxy %1$s %2$s</string>
<string name="use_system_proxy">Använd system proxy</string>
<string name="use_system_proxy_summary">Använda systemkonfigurationen för HTTP/HTTPS proxy för att ansluta.</string>
<string name="onbootrestartsummary">OpenVPN kommer att ansluta angiven VPN om den var aktivt vid systemets uppstart. Vänligen läs anslutningsvarnings FAQ innan du använder det här alternativet på Android &lt; 5.0.</string>
@@ -448,9 +448,14 @@
<string name="weakmd_title">Svag (MD5) hashes i certifikat signatur (SSL_CTX_use_certificate md för svag)</string>
<string name="title_activity_open_sslspeed">OpenSSL-hastighetstest</string>
<string name="openssl_cipher_name">OpenSSL-ciffernamn</string>
+ <string name="osslspeedtest">OpenSSL Crypto-hastighetstest</string>
<string name="openssl_error">OpenSSL returnerade ett fel</string>
<string name="running_test">Kör test&#8230;</string>
<string name="test_algoirhtms">Testa valda algoritmer</string>
<string name="all_app_prompt">En extern app försöker kontrollera %s. Appen som begär åtkomst kan inte bestämmas. Tillåtelse av den här appen ger åtkomst till ALLA program.</string>
<string name="openvpn3_nostatickeys">OpenVPN 3 C ++-implementeringen stöder inte statiska nycklar. Ändra till OpenVPN 2.x under allmänna inställningar.</string>
+ <string name="openvpn3_pkcs12">Användning av PKCS12-filer direkt med OpenVPN 3 C++-implementering stöds inte. Vänligen importera pkcs12-filerna till Android-nyckelbutiken eller ändra till OpenVPN 2.x under allmänna inställningar.</string>
+ <string name="proxy">Proxy</string>
+ <string name="Use_no_proxy">Ingen</string>
+ <string name="tor_orbot">Tor (Orbot)</string>
</resources>
diff --git a/app/src/main/res/values-tr/strings-icsopenvpn.xml b/app/src/main/res/values-tr/strings-icsopenvpn.xml
index 5f82c364..8b2fad33 100755
--- a/app/src/main/res/values-tr/strings-icsopenvpn.xml
+++ b/app/src/main/res/values-tr/strings-icsopenvpn.xml
@@ -201,7 +201,7 @@
<string name="setting_loadtun">Tun modülünü yükle</string>
<string name="importpkcs12fromconfig">PKCS12 yapılandırmasını Android anahtar deposuna alma</string>
<string name="getproxy_error">Vekil sunucu ayarları alınırken hata oluştu: %s</string>
- <string name="using_proxy">%1$s %2$d vekil sunucusu kullanarak</string>
+ <string name="using_proxy">%1$s %2$s Vekil Sunucusu kullanılıyor</string>
<string name="use_system_proxy">Sistem vekil sunucusunu kullan</string>
<string name="use_system_proxy_summary">Bağlanmak için sistem çapındaki HTTP/HTTPS vekil sunucularını kullan.</string>
<string name="onbootrestartsummary">Sistem önyüklemesi üzerinde etkinse, OpenVPN belirtilen VPN bağlantısına bağlanır. Lütfen bu seçeneği Android &lt; 5.0 üzerinde kullanmadan önce bağlantı uyarısı için SSS bölümünü okuyun.</string>
@@ -462,4 +462,7 @@
<string name="openvpn3_pkcs12">PKCS12 dosyalarını doğrudan OpenVPN 3 C++ uygulamasıyla kullanmak desteklenmiyor.
Lütfen, pkcs12 dosyalarını Android anahtar deposuna aktarın veya genel ayarlar altında OpenVPN 2.x\'e geçin.
</string>
+ <string name="proxy">Vekil Sunucu</string>
+ <string name="Use_no_proxy">Hiçbiri</string>
+ <string name="tor_orbot">Tor (Orbot)</string>
</resources>
diff --git a/app/src/main/res/values-uk/plurals-icsopenvpn.xml b/app/src/main/res/values-uk/plurals-icsopenvpn.xml
index 0fa0f62e..70489fbc 100755
--- a/app/src/main/res/values-uk/plurals-icsopenvpn.xml
+++ b/app/src/main/res/values-uk/plurals-icsopenvpn.xml
@@ -1,24 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<!--Generated by crowdin.com-->
-<resources>
- <plurals name="months_left">
- <item quantity="one">Залишився один місяць</item>
- <item quantity="few">Залишось %d місяці</item>
- <item quantity="other">Залишось %d місяці(-ів)</item>
- </plurals>
- <plurals name="days_left">
- <item quantity="one">Залишився один день</item>
- <item quantity="few">Залишилось %d дні</item>
- <item quantity="other">Залишилось %d днів</item>
- </plurals>
- <plurals name="hours_left">
- <item quantity="one">Залишилась одна година</item>
- <item quantity="few">Залишилось %d години</item>
- <item quantity="other">Залишилось %d годин</item>
- </plurals>
- <plurals name="minutes_left">
- <item quantity="one">Залишилася одна хвилина</item>
- <item quantity="few">Залишилось %d хвилини</item>
- <item quantity="other">Залишилось %d хвилин</item>
- </plurals>
-</resources>
+<resources></resources>
diff --git a/app/src/main/res/values-uk/strings-icsopenvpn.xml b/app/src/main/res/values-uk/strings-icsopenvpn.xml
index 61c350af..547ba025 100755
--- a/app/src/main/res/values-uk/strings-icsopenvpn.xml
+++ b/app/src/main/res/values-uk/strings-icsopenvpn.xml
@@ -201,7 +201,7 @@
<string name="setting_loadtun">Завантажити tun-модуль</string>
<string name="importpkcs12fromconfig">Імпорт PKCS12 з конфігурації у сховищі ключів Андроїд</string>
<string name="getproxy_error">Помилка отримання параметрів проксі: %s</string>
- <string name="using_proxy">Використовується проксі %1$s %2$d</string>
+ <string name="using_proxy">Використовується проксі-сервер %1$s %2$s</string>
<string name="use_system_proxy">Використовувати системний проксі</string>
<string name="use_system_proxy_summary">Використовувати системну конфігурацію HTTP/HTTPS проксі для з\'єднання.</string>
<string name="onbootrestartsummary">OpenVPN підключатиметься до вказаного VPN, якщо він був активний при завантаженні системи. Будь ласка, прочитайте FAQ про попередження при підключенні перед використанням цієї опції на Android &lt; 5.0.</string>
@@ -459,4 +459,7 @@
<string name="all_app_prompt">Зовнішній застосунок намагається контролювати %s. Застосунок, що запитує про доступ, не може бути визначений. Дозвіл цьому застосунку надає доступ всім додаткам.</string>
<string name="openvpn3_nostatickeys">Реалізація OpenVPN 3 C ++ не підтримує статичні ключи. Перейдіть в OpenVPN 2.x під загальними налаштуваннями.</string>
<string name="openvpn3_pkcs12">Використання файлів PKCS12 напряму за допомогою OpenVPN 3 C ++ не підтримується. Імпортуйте файли pkcs12 в сховище ключів Android або замініть OpenVPN 2.x на загальні налаштування.</string>
+ <string name="proxy">Проксі</string>
+ <string name="Use_no_proxy">Немає</string>
+ <string name="tor_orbot">Тор (Орбот)</string>
</resources>
diff --git a/app/src/main/res/values-vi/strings-icsopenvpn.xml b/app/src/main/res/values-vi/strings-icsopenvpn.xml
index f38aaf3e..c047ca54 100755
--- a/app/src/main/res/values-vi/strings-icsopenvpn.xml
+++ b/app/src/main/res/values-vi/strings-icsopenvpn.xml
@@ -201,7 +201,7 @@
<string name="setting_loadtun">Tải tun module</string>
<string name="importpkcs12fromconfig">Nhập PKCS12 từ cấu hình vào Khóa lưu trữ Android</string>
<string name="getproxy_error">Lỗi nhận cấu hình proxy: %s</string>
- <string name="using_proxy">Đang sử dụng proxy %1$s %2$d</string>
+ <string name="using_proxy">ใช้พร็อกซี% 1 $ s% 2 $ s</string>
<string name="use_system_proxy">Sử dụng proxy hệ thống</string>
<string name="use_system_proxy_summary">Sử dụng các cấu hình hệ thống rộng cho HTTP/HTTPS proxy để kết nối.</string>
<string name="onbootrestartsummary">OpenVPN sẽ kết nối VPN xác định nếu nó đã hoạt động trên hệ thống khởi động. Xin vui lòng đọc hướng dẫn cảnh báo kết nối trước khi sử dụng tùy chọn này trên Android &lt; 5.0.</string>
@@ -438,8 +438,36 @@
<string name="kbits_per_second">%.1f kbit/giây</string>
<string name="mbits_per_second">%.1f Mbit/giây</string>
<string name="gbits_per_second">%.1f Gbit/giây</string>
+ <string name="weakmd">&lt;p&gt;Bắt đầu với OpenSSL phiên bản 1.1, OpenSSL từ chối chữ ký yếu trong các chứng chỉ như
+ MD5.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Chữ ký MD5 hoàn toàn không an toàn và không nên sử dụng nữa.&lt;/b&gt; vụ va chạm MD5
+ có thể được tạo trong &lt;a
+ href=\"https://natmchugh.blogspot.de/2015/02/create-your-own-md5-collisions.html\"&gt;giờ với chi phí tối thiểu.&lt;/a&gt;.
+ Bạn nên cập nhật chứng chỉ VPN càng sớm càng tốt.&lt;/p&gt;&lt;p&gt;Thật không may, các bản phân phối
+ easy-rsa cũ hơn bao gồm tùy chọn cấu hình \"default_md md5\". Nếu bạn đang sử dụng phiên bản easy-rsa cũ, hãy cập nhật lên
+ phiên bản &lt;a href=\"https://github.com/OpenVPN/easy-rsa/releases\"&gt;mới nhất&lt;/a&gt;) hoặc thay đổi md5 thành sha256 và
+ tạo lại chứng chỉ của bạn.&lt;/p&gt;&lt;p&gt;Nếu bạn thực sự muốn sử dụng chứng chỉ cũ và bị hỏng, hãy sử dụng tùy chọn cấu hình tls-mật mã tùy chỉnh
+ \"DEFAULT: @ SECLEVEL = 0\" trong cấu hình nâng cao hoặc làm dòng bổ sung trong
+ cấu hình đã nhập của bạn&lt;/p&gt;
+ </string>
<string name="volume_byte">%.0f B</string>
<string name="volume_kbyte">%.1f kB</string>
<string name="volume_mbyte">%.1f MB</string>
<string name="volume_gbyte">%.1f GB</string>
+ <string name="channel_name_background">Connection statistics</string>
+ <string name="channel_description_background">Số liệu thống kê liên tục của kết nối OpenVPN đã được thiết lập</string>
+ <string name="channel_name_status">Thay đổi trạng thái kết nối</string>
+ <string name="channel_description_status">Thay đổi trạng thái của kết nối OpenVPN (Đang kết nối, xác thực,&#8230;)</string>
+ <string name="weakmd_title">Hàm băm yếu (MD5) trong chữ ký chứng chỉ (SSL_CTX_use_certificate md quá yếu)</string>
+ <string name="title_activity_open_sslspeed">Kiểm tra tốc độ OpenSSL</string>
+ <string name="openssl_cipher_name">Tên mã hóa OpenSSL</string>
+ <string name="osslspeedtest">Kiểm tra tốc độ OpenSSL Crypto</string>
+ <string name="openssl_error">OpenSSL trả về lỗi</string>
+ <string name="running_test">Đang chạy kiểm tra&#8230;</string>
+ <string name="test_algoirhtms">Kiểm tra các thuật toán đã chọn</string>
+ <string name="all_app_prompt">Một ứng dụng bên ngoài cố gắng kiểm soát %s. Không thể xác định ứng dụng yêu cầu quyền truy cập. Cho phép ứng dụng này cấp cho TẤT CẢ quyền truy cập ứng dụng.</string>
+ <string name="openvpn3_nostatickeys">Việc triển khai OpenVPN 3 C ++ không hỗ trợ các khóa tĩnh. Vui lòng thay đổi thành OpenVPN 2.x trong cài đặt chung.</string>
+ <string name="openvpn3_pkcs12">Việc sử dụng tệp PKCS12 trực tiếp với triển khai OpenVPN 3 C ++ không được hỗ trợ. Vui lòng nhập tệp pkcs12 vào kho khóa Android hoặc thay đổi thành OpenVPN 2.x trong cài đặt chung.</string>
+ <string name="proxy">Proxy</string>
+ <string name="Use_no_proxy">Không</string>
+ <string name="tor_orbot">Tor (Orbot)</string>
</resources>
diff --git a/app/src/main/res/values-zh-rCN/strings-icsopenvpn.xml b/app/src/main/res/values-zh-rCN/strings-icsopenvpn.xml
index 061a9827..4d6cc300 100755
--- a/app/src/main/res/values-zh-rCN/strings-icsopenvpn.xml
+++ b/app/src/main/res/values-zh-rCN/strings-icsopenvpn.xml
@@ -150,7 +150,7 @@
<string name="no_bind">无本地绑定</string>
<string name="import_configuration_file">导入配置文件</string>
<string name="faq_security_title">安全注意事项</string>
- <string name="faq_security">“OpenVPN 是非常注重安全的,所以在此提供一些安全方面的建议。所有保存在存储卡上的数据都是不安全的,任何应用都可以读取存储卡上的文件,即使这个应用没有‘写入存储卡’的权限也是如此。应用自身的数据只能被应用自己读取。在选择 CA 证书、证书文件或者密钥文件的时候请使用导入功能,这样这些数据就会保存在 OpenVPN 自身的数据文件中,保证不会被其他的应用恶意读取。当然导入证书之后记得要把证书从存储卡上删除掉。不过,虽然这些数据不能被其他应用读取,但是这些数据是明文保存的,如果你的系统是 rooted 的,那么这些数据将能够被任何拥有 root 权限的应用轻松地读取。保存在 OpenVPN 中的密码也是以明文保存的,如果设备被 rooted 了,这些密码也有可能被其他应用恶意读取。强烈建议使用 pkcs12 证书并将证书导入到 Android 自己的证书管理系统里。”</string>
+ <string name="faq_security">"As OpenVPN is security sensitive a few notes about security are sensible. All data on the sdcard is incoherently insecure. Every app can read it (for example this program requires no special sd card rights). The data of this application can only be read by the application itself. By using the import option for cacert/cert/key in the file dialog the data is stored in the VPN profile. The VPN profiles are only accessible by this application. (Do not forget to delete the copies on the sd card afterwards). Even though accessible only by this application the data is still unencrypted. By rooting the telephone or other exploits it may be possible to retrieve the data. Saved passwords are stored in plain text as well. For pkcs12 files it is highly recommended that you import them into the android keystore."</string>
<string name="import_vpn">导入</string>
<string name="broken_image_cert_title">显示证书选择错误</string>
<string name="broken_image_cert">尝试显示 Android 4.0 + 证书选择对话框时出现异常。Android 4.0 以上的系统不可能出现该问题,因为这是标准的系统功能。可能您当前 ROM 中的证书存储已经损坏。</string>
@@ -203,7 +203,7 @@
<string name="setting_loadtun">加载tun模块</string>
<string name="importpkcs12fromconfig">将PKCS12从配置导入到Android Keystore</string>
<string name="getproxy_error">获取代理设置时出错:%s</string>
- <string name="using_proxy">使用代理 %1$s %2$d</string>
+ <string name="using_proxy">Using proxy %1$s %2$s</string>
<string name="use_system_proxy">使用系统代理</string>
<string name="use_system_proxy_summary">使用系统设置连接 HTTP/HTTPS 代理服务器。</string>
<string name="onbootrestartsummary">如果在系统启动时OpenVPN处于活动状态,那么它会连接指定的VPN。在Android 5.0上使用这个选项前,请阅读连接警告的常见问题。</string>
@@ -442,8 +442,36 @@
<string name="kbits_per_second">%.1f kbit/s</string>
<string name="mbits_per_second">%.1f Mbit/s</string>
<string name="gbits_per_second">%.1f Gbit/s</string>
+ <string name="weakmd">&lt;p&gt;Starting with OpenSSL version 1.1, OpenSSL rejects weak signatures in certificates like
+ MD5.&lt;/p&gt;&lt;p&gt;&lt;b&gt;MD5 signatures are completely insecure and should not be used anymore.&lt;/b&gt; MD5
+ collisions can be created in &lt;a
+ href=\"https://natmchugh.blogspot.de/2015/02/create-your-own-md5-collisions.html\"&gt;few hours at a minimal cost.&lt;/a&gt;.
+ You should update the VPN certificates as soon as possible.&lt;/p&gt;&lt;p&gt;Unfortunately, older easy-rsa
+ distributions included the config option \"default_md md5\". If you are using an old easy-rsa version, update to
+ the &lt;a href=\"https://github.com/OpenVPN/easy-rsa/releases\"&gt;latest version&lt;/a&gt;) or change md5 to sha256 and
+ regenerate your certificates.&lt;/p&gt;&lt;p&gt;If you really want to use old and broken certificates use the custom
+ configuration option tls-cipher \"DEFAULT:@SECLEVEL=0\" under advanced configuration or as additional line in your
+ imported configuration&lt;/p&gt;
+ </string>
<string name="volume_byte">%.0f B</string>
<string name="volume_kbyte">%.1f kB</string>
<string name="volume_mbyte">%.1f MB</string>
<string name="volume_gbyte">%.1f GB</string>
+ <string name="channel_name_background">连接统计</string>
+ <string name="channel_description_background">正在建立的OpenVPN连接的统计数据</string>
+ <string name="channel_name_status">连接状态改变</string>
+ <string name="channel_description_status">OpenVPN连接的状态更改(连接,身份验证...)</string>
+ <string name="weakmd_title">证书签名中的弱 (MD5) 哈希 (SSL_CTX_use_certificate md 太弱)</string>
+ <string name="title_activity_open_sslspeed">OpenSSL 速度测试</string>
+ <string name="openssl_cipher_name">OpenSSL密码名称</string>
+ <string name="osslspeedtest">OpenSSL Crypto速度测试</string>
+ <string name="openssl_error">OpenSSL 返回错误</string>
+ <string name="running_test">正在运行测试&#8230;</string>
+ <string name="test_algoirhtms">测试选定的算法</string>
+ <string name="all_app_prompt">An external app tries to control %s. The app requesting access cannot be determined. Allowing this app grants ALL apps access.</string>
+ <string name="openvpn3_nostatickeys">OpenVPN 3 C ++实现不支持静态密钥。请在常规设置下更改为OpenVPN 2.x.</string>
+ <string name="openvpn3_pkcs12">不支持直接使用 OpenVPN 3 c++ 实现的 PKCS12 文件。请将 pkcs12 文件导入 Android 密钥库, 或在常规设置下更改为 OpenVPN 2.x。</string>
+ <string name="proxy">代理</string>
+ <string name="Use_no_proxy">无</string>
+ <string name="tor_orbot">Tor (Orbot)</string>
</resources>
diff --git a/app/src/main/res/values-zh-rTW/plurals-icsopenvpn.xml b/app/src/main/res/values-zh-rTW/plurals-icsopenvpn.xml
index 70489fbc..ba0d8399 100755
--- a/app/src/main/res/values-zh-rTW/plurals-icsopenvpn.xml
+++ b/app/src/main/res/values-zh-rTW/plurals-icsopenvpn.xml
@@ -1,3 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<!--Generated by crowdin.com-->
-<resources></resources>
+<resources>
+ <plurals name="months_left">
+ <item quantity="other">還剩 %d 個月</item>
+ </plurals>
+ <plurals name="days_left">
+ <item quantity="other">還剩 %d 天</item>
+ </plurals>
+ <plurals name="hours_left">
+ <item quantity="other">還剩 %d 小時</item>
+ </plurals>
+ <plurals name="minutes_left">
+ <item quantity="other">還剩 %d 分鐘</item>
+ </plurals>
+</resources>
diff --git a/app/src/main/res/values-zh-rTW/strings-icsopenvpn.xml b/app/src/main/res/values-zh-rTW/strings-icsopenvpn.xml
index ba2e7d8d..a754440e 100755
--- a/app/src/main/res/values-zh-rTW/strings-icsopenvpn.xml
+++ b/app/src/main/res/values-zh-rTW/strings-icsopenvpn.xml
@@ -7,7 +7,7 @@
<resources>
<string name="address">伺服器地址:</string>
- <string name="port">伺服器端口:</string>
+ <string name="port">伺服器連接埠:</string>
<string name="location">位置</string>
<string name="cant_read_folder">無法讀取檔案目錄</string>
<string name="select">選擇</string>
@@ -68,31 +68,31 @@
<string name="check_remote_tlscert_title">預期的 TLS 伺服器憑證</string>
<string name="remote_tlscn_check_summary">檢查遠端的伺服器憑證主旨 DN</string>
<string name="remote_tlscn_check_title">憑證主機名稱檢查</string>
- <string name="enter_tlscn_dialog">指定用於驗證遠程證書的DN(例如C = DE,L =帕德博恩,OU =禽流IP運營商,CN = openvpn.blinkt.de)\ñ\ n指定完整的DN或RDN檢查(openvpn.blinkt.de在這個例子中)或RDN前綴進行驗證。\ N使用RDN前綴“服務器”\ n當匹配“服務器1”和“服務器2”\ñ\ nLeaving文本字段為空將檢查RDN對服務器的主機名。 \ñ\ n有關詳細信息請參見下-verify-X509-名的OpenVPN 2.3.1+手冊頁</string>
+ <string name="enter_tlscn_dialog">指定這個檢查用於驗證遠端憑證 DN(例如:C=DE, L=Paderborn, OU=Avian IP Carriers, CN=openvpn.blinkt.de)\n\n指定完整的 DN 或 RDN(openvpn.blinkt.de 在範例中)或 RDN 前綴來驗證。\n\n當使用 RDN 前綴 \"Server\" 符合 \"Server-1\" 及 \"Server-2\"\n\n如文字欄位為空,將檢查 RDN 的主機名稱。\n\n更多詳情,請參閱 OpenVPN 2.3.1 + 在 manpage 的 —verify-x509-name</string>
<string name="enter_tlscn_title">遠端憑證主旨</string>
<string name="tls_key_auth">啟用 TLS 密鑰認證</string>
<string name="tls_auth_file">TLS 驗證檔</string>
- <string name="pull_on_summary">向伺服器請求 IP 地址,、路由和時間資訊</string>
+ <string name="pull_on_summary">向伺服器請求 IP 地址、路由和時間資訊</string>
<string name="pull_off_summary">沒有來自伺服器的資訊,需要在下面指定設定。</string>
- <string name="use_pull">拉設置</string>
+ <string name="use_pull">取得設定</string>
<string name="dns">DNS</string>
- <string name="override_dns">覆蓋的DNS設置服務器</string>
- <string name="dns_override_summary">使用您自己的DNS服務器</string>
+ <string name="override_dns">伺服器覆蓋 DNS 設定</string>
+ <string name="dns_override_summary">使用您自己的 DNS 伺服器</string>
<string name="searchdomain">sea​​rchDomain</string>
- <string name="dns1_summary">要使用的DNS服務器。</string>
- <string name="dns_server">DNS服務器</string>
- <string name="secondary_dns_message">備用DNS服務器使用,如果正常的DNS服務器無法到達。</string>
- <string name="backup_dns">備份DNS服務器</string>
+ <string name="dns1_summary">要使用的 DNS 伺服器。</string>
+ <string name="dns_server">DNS 伺服器</string>
+ <string name="secondary_dns_message">如果無法使用正常的 DNS 伺服器,會使用次要的 DNS 伺服器</string>
+ <string name="backup_dns">備用的 DNS 伺服器</string>
<string name="ignored_pushed_routes">忽略伺服器推送的路由</string>
- <string name="ignore_routes_summary">忽略路由推服務器。</string>
+ <string name="ignore_routes_summary">忽略由伺服器推送的路由</string>
<string name="default_route_summary">重新所有流量導到 VPN</string>
<string name="use_default_title">使用預設路由</string>
- <string name="custom_route_message">輸入自定義的路線。只有在CIDR格式輸入目的地。 “10.0.0.0/8 2002:: / 16”就直接網絡10.0.0.0/8和2002:: / 16通過VPN。</string>
- <string name="custom_route_message_excluded">路線不應該被路由通過VPN。使用相同的語法包括路線。</string>
- <string name="custom_routes_title">自定義路線</string>
- <string name="custom_routes_title_excluded">排除網絡</string>
+ <string name="custom_route_message">輸入自訂的路由。只有在以 CIDR 格式輸入目的,\"10.0.0.0/8 2002::/16\" 才會將 10.0.0.0/8 及 2002::/16 網路導向 VPN。</string>
+ <string name="custom_route_message_excluded">路由不應流經過 VPN,使用相同的語法來排除路由。</string>
+ <string name="custom_routes_title">自訂路由</string>
+ <string name="custom_routes_title_excluded">排除的網絡</string>
<string name="log_verbosity_level">日誌的詳細等級</string>
- <string name="float_summary">允許來自任何IP驗證的數據包</string>
+ <string name="float_summary">允許來自任何 IP 的驗證封包</string>
<string name="float_title">允許浮動伺服器</string>
<string name="custom_options_title">自訂選項</string>
<string name="edit_vpn">編輯 VPN 設定</string>
@@ -102,25 +102,25 @@
<string name="error">"錯誤: "</string>
<string name="clear">清除</string>
<string name="last_openvpn_tun_config">打開 tun 介面:</string>
- <string name="local_ip_info">本地 IPv4:%1$s / %2$d IPv6:%3$s MTU:%4$d</string>
+ <string name="local_ip_info">本機 IPv4:%1$s / %2$d IPv6:%3$s MTU:%4$d</string>
<string name="dns_server_info">DNS 伺服器器:%1$s,域名:%2$s</string>
<string name="routes_info_incl">路由:%1$s %2$s</string>
<string name="routes_info_excl">排除的路由:%1$s %2$s</string>
<string name="routes_debug">VpnService 路由安裝:%1$s %2$s</string>
- <string name="ip_not_cidr">GOT的接口信息%1$s和%2$s,假設第二個地址是遠程的對等地址。使用/ 32掩碼本地IP。通過OpenVPN的給定方式是“%3$s”。</string>
- <string name="route_not_cidr">不能使%1$s和%2$s如IP路由CIDR子網掩碼感,使用/ 32子網掩碼。</string>
+ <string name="ip_not_cidr">取得介面訊息 %1$s 及 %2$s,假設第二個位址是遠端對等的位址。使用 /32 子網路遮罩給本機 IP。OpenVPN 的模式是「%3$s」。</string>
+ <string name="route_not_cidr">無法將 %1$s 和 %2$s 作為具有 CIDR 子網路遮罩的 IP 路由,使用 /32 作為子網路遮罩。</string>
<string name="route_not_netip">修正路由 %1$s / %2$s 到 %3$s / %2$s</string>
- <string name="keychain_access">無法訪問Android鑰匙扣證書。這可以通過固件升級或通過恢復的應用程序/應用程序設置的備份引起。請編輯VPN和重新選擇下基本設置證書重新訪問證書的權限。</string>
+ <string name="keychain_access">無法存取 Android 鑰匙圈憑證。這可能是由韌體更新,或還原此應用程式/應用程式設定造成。請在基本設定下,編輯 VPN 及重新選擇憑證,以重新建立存取憑證的權限。</string>
<string name="version_info">%1$s %2$s</string>
<string name="send_logfile">送出日誌檔案</string>
<string name="send">傳送</string>
<string name="ics_openvpn_log_file">ICS OpenVPN 日誌檔案</string>
<string name="copied_entry">已將記錄複製到剪貼簿</string>
<string name="tap_mode">Tap 模式</string>
- <string name="faq_tap_mode">點擊模式是不可能的非根VPN API。因此,該應用程序不能提供自來水的支持</string>
+ <string name="faq_tap_mode">非 root 的 VPN API 無法使用 Tap 模式,因此,此應用程式無法提供 tap 支援。</string>
<string name="tap_faq2">再一次?你在開玩笑吧?這真的不支援 tap 模式,就算再寄電子郵件詢問能不能支援也是沒用的。</string>
<string name="tap_faq3">第三次嗎?實際上,一個可以寫基於屯,並添加 2 層資訊發送帶 2 層資訊上水龍頭模擬器接收。但這個水龍頭模擬器還必須實施 ARP 和可能 DHCP 用戶端。我不知道的任何人做任何工作在這個方向。與我聯繫,如果你想要開始對此編碼。</string>
- <string name="faq">FAQ</string>
+ <string name="faq">常問問題</string>
<string name="copying_log_entries">複製記錄項目</string>
<string name="faq_copying">若要複製單筆記錄,在此記錄項目上點選。若要複製/送出整筆記錄,使用送出記錄選項。如果這個按鈕在畫面中無法顯示,請使用實體的選單按鈕。</string>
<string name="faq_shortcut">以快捷方式啟動</string>
@@ -135,33 +135,33 @@
<string name="inline_file_tab">內嵌檔案</string>
<string name="error_importing_file">匯入過程中發生錯誤</string>
<string name="import_error_message">無法從檔案系統中匯入檔案</string>
- <string name="inline_file_data">&lt;內嵌於設定檔&gt;</string>
- <string name="opentun_no_ipaddr">拒絕開啟 tun 沒有 IP 資訊的裝置</string>
+ <string name="inline_file_data">[[內嵌於設定檔]]</string>
+ <string name="opentun_no_ipaddr">拒絕開啟沒有 IP 資訊的 tun 裝置</string>
<string name="menu_import">從 .ovpn 檔案匯入設定檔</string>
<string name="menu_import_short">匯入</string>
- <string name="import_content_resolve_error">匯入過程中無法讀取設定檔</string>
+ <string name="import_content_resolve_error">無法讀取設定檔來匯入</string>
<string name="error_reading_config_file">讀取設定檔時發生錯誤</string>
<string name="add_profile">新增設定檔</string>
<string name="import_could_not_open">找不到在導入配置文件中提到的文件%1$s</string>
<string name="importing_config">從源頭%1$s導入配置文件</string>
<string name="import_warning_custom_options">你的配置有沒有被映射到用戶界面配置一些配置選項。這些選項被添加為自定義配置選項。將顯示自定義配置如下:</string>
<string name="import_done">成功讀取設定檔</string>
- <string name="nobind_summary">不要綁定本地地址和端口</string>
- <string name="no_bind">沒有本地綁定</string>
+ <string name="nobind_summary">不要綁定本機位址與埠</string>
+ <string name="no_bind">沒有本機綁定</string>
<string name="import_configuration_file">匯入設定檔</string>
- <string name="faq_security_title">保安上的考慮</string>
+ <string name="faq_security_title">安全考量</string>
<string name="faq_security">“由於OpenVPN是安全敏感的有關安全性的幾個音符都是明智的。在​​SD卡的所有數據本質上是不安全的。每一個應用程序可以讀取它(比如這個方案並不需要特別的SD卡的權限)。此應用程序的數據只能讀由應用程序本身。通過使用CACERT /證書/密鑰的文件對話框中的數據導入選項存儲在VPN配置文件的VPN配置文件只能由該應用程序進行訪問。(不要忘了刪除在SD副本卡後)。即使只能由該應用程序中的數據仍然是未加密的,通過生根電話或其他攻擊有可能檢索數據。保存的密碼是明文存儲以及對於PKCS12文件,強烈建議你將它們導入到android的密鑰庫。“</string>
<string name="import_vpn">匯入</string>
- <string name="broken_image_cert_title">錯誤顯示證書選擇</string>
+ <string name="broken_image_cert_title">顯示憑證選擇錯誤</string>
<string name="broken_image_cert">有一個例外,試圖展示了Android 4.0+證書選擇對話框。這不應該發生,因為這款Android 4.0+的標準功能。也許對於證書存儲你的Andr​​oid ROM支持被打破</string>
<string name="ipv4">IPv4</string>
<string name="ipv6">IPv6</string>
- <string name="speed_waiting">等待狀態訊息&#8230;</string>
- <string name="converted_profile">匯入設定檔</string>
- <string name="converted_profile_i">匯入設定檔 %d</string>
+ <string name="speed_waiting">等待狀態訊息...</string>
+ <string name="converted_profile">已匯入設定檔</string>
+ <string name="converted_profile_i">已匯入設定檔 %d</string>
<string name="broken_images">損壞的映像</string>
<string name="broken_images_faq">&lt;p&gt;Official HTC圖像,已知有一種奇怪的路由問題造成交通不流過隧道(也&lt;a href=\"https://github.com/schwabe/ics-openvpn/issues/18\"&gt;Issue 18&lt;/a&gt;看到bug跟踪系統。)的的Xperia弧S和的Xperia雷&lt;/p&gt;&lt;p&gt;Older官方SONY圖像已被報導完全缺少VPNService從圖像。 (也&lt;a href=\"https://github.com/schwabe/ics-openvpn/issues/29\"&gt;Issue 29&lt;/a&gt;看到bug跟踪系統。)&lt;/p&gt;&lt;p&gt;On自定義生成的TUN模塊可能會丟失照片或為/ dev / TUN的權利可能是錯誤的。一些CM9圖像需要在“設備特定的黑客”enabled.&lt;/p&gt;&lt;p&gt;Most重要的是“修復所有權”選項:如果您的設備有一個破碎的機器人形象,報告給你的供應商。越多的人誰給供應商報告問題時,他們越有可能解決it.&lt;/p&gt;</string>
- <string name="pkcs12_file_encryption_key">PKCS12檔加密金鑰</string>
+ <string name="pkcs12_file_encryption_key">PKCS12 檔加密金鑰</string>
<string name="private_key_password">私密金鑰密碼</string>
<string name="password">密碼</string>
<string name="file_icon">檔案圖標</string>
@@ -186,7 +186,7 @@
<string name="faq_system_dialogs">系統的 VPN 連線警告說明這個應用程式可以攔截所有流量,這是防止 VPNService API 被濫用。\n為了提示正在進行的 VPN 連線, Android 系統會產生通知 (鑰匙符號) ,在一些系統中,會發出提示聲。\nAndroid 這麼做是為了確保你的安全。</string>
<string name="faq_system_dialogs_title">連線警告和通知時發出音效</string>
<string name="translationby">繁體中文</string>
- <string name="ipdns">IP和DNS</string>
+ <string name="ipdns">IP 和 DNS</string>
<string name="basic">基本</string>
<string name="routing">路由</string>
<string name="obscure">鮮為人知的OpenVPN設定,一般情況下不需要派上用場。</string>
@@ -195,19 +195,18 @@
<string name="warn_no_dns">不使用任何DNS服務器。名稱解析可能無法正常工作。考慮設置自定義DNS服務器。另請注意,Android將繼續使用您的手機/ Wi-Fi連接指定的代理服務器設置時沒有DNS服務器設置。</string>
<string name="dns_add_error">無法添加DNS服務器“%1$s”,系統拒絕:%2$s</string>
<string name="ip_add_error">無法配置IP地址“%1$s”,系統拒絕:%2$s</string>
- <string name="faq_howto">&lt;p&gt;Get工作的配置(從供應商/機構檢測您的電腦或下載)&lt;/p&gt;&lt;p&gt;If它沒有多餘的PEM / pks12文件,你可以自己通過電子郵件發送文件和打開附件的單個文件。如果您有多個文件,把它們放在你的SD card.&lt;/p&gt;&lt;p&gt;Click上的電子郵件附件/使用的文件夾圖標,在VPN列表導入配置file&lt;/p&gt;&lt;p&gt;If大約有丟失的文件將丟失的文件在你的SD card.&lt;/p&gt;&lt;p&gt;Click上保存錯誤標誌將導入的VPN添加到您的VPN list&lt;/p&gt;&lt;p&gt;Connect的VPN通過點擊VPN&lt;/p&gt;&lt;p&gt;If的名字有錯誤或警告日誌試著去了解警告/錯誤,並嘗試修復them&lt;/p&gt; </string>
+ <string name="faq_howto">&lt;p&gt;取得正在使用的設定(在電腦測試過的,或從供應商/組織下載的)&lt;/p&gt;&lt;p&gt;如果單一檔案且沒有沒有額外 pem/pks12 檔案,你可以發送這個檔案給自,打開附件。如果你有多個檔案,把他們放在你的 SD 卡。&lt;/p&gt;&lt;p&gt;點選 email 附件/使用在 VPN 清單的資料夾圖示,來匯入設定檔&lt;/p&gt;&lt;p&gt;如果有關在 SD 卡內,檔案遺失的錯誤。&lt;/p&gt;&lt;p&gt;點選儲存符號,來加入已匯入的 VPN 到你的 VPN 清單內&lt;/p&gt;&lt;p&gt;點選 VPN 的名稱來連線到此 VPN&lt;/p&gt;&lt;p&gt;如果在日誌中發現錯誤或警告,試著去了解警告/錯誤,並嘗試修復它&lt;/p&gt; </string>
<string name="faq_howto_title">快速入門</string>
<string name="setting_loadtun_summary">在連線前嘗試載入 Tun 模組,需要 Root。</string>
<string name="setting_loadtun">載入 tun 模組</string>
<string name="importpkcs12fromconfig">導入PKCS12從配置到Android的密鑰庫</string>
<string name="getproxy_error">取得代理伺服器資訊時發生錯誤: %s</string>
- <string name="using_proxy">使用代理伺服器 %1$s %2$d</string>
<string name="use_system_proxy">使用系統代理</string>
<string name="use_system_proxy_summary">使用系統配置的 HTTP/HTTPS 代理伺服器進行連線。</string>
<string name="onbootrestartsummary">OpenVPN 將會在系統啟動時連線到特定的 VPN。在 Android &lt; 5.0 上使用這個設定前,請閱讀連線警告 FAQ。</string>
<string name="onbootrestart">啟動時連線</string>
<string name="ignore">忽略</string>
- <string name="restart">重置</string>
+ <string name="restart">重新啟動</string>
<string name="restart_vpn_after_change">配置變更只會在重新啟動VPN時才生效,現在要(重新)啟動VPN嗎?</string>
<string name="configuration_changed">設定已變更</string>
<string name="log_no_last_vpn">無法判斷最後一次連線使用的設定檔,因此無法編輯設定檔。</string>
@@ -222,7 +221,7 @@
<string name="persisttun_summary">當 OpenVPN 重新連線時,持續使用 VPN 連線。</string>
<string name="persistent_tun_title">保持 tun 通道</string>
<string name="openvpn_log">OpenVPN 運作記錄</string>
- <string name="import_config">匯入 OpenVPN 配置</string>
+ <string name="import_config">匯入 OpenVPN 設定</string>
<string name="battery_consumption_title">電池消耗</string>
<string name="baterry_consumption">在我個人的測試中的 OpenVPN 高電池消耗的主要原因是保活資料包。大多數的 OpenVPN 伺服器有一個配置指令像 \' keepalive 10 60\',這會導致用戶端和伺服器交換保活資料包每十秒。&lt; P &gt; 雖然這些資料包是小和不使用太多的交通,它們保持移動無線電網路忙,增加了能源消耗。(請參見 &lt; href =\"HTTP://developer.android.com/training/efficient-downloads/efficient-network-access.html#RadioStateMachine\"&gt; 無線電狀態機 |Android 開發者 &lt; /a &gt;) &lt; p &gt; 此 keepalive 設置不能更改用戶端上。只有 OpenVPN 的系統管理員可以更改的設置。&lt; P &gt; 不幸的 udp 使用保活大於 60 秒可以導致一些 NAT 閘道來斷開連接由於不活動超時。用不了多久使用 TCP 保持活著超時工作,但隧道 TCP 通過 TCP 表現極為不佳與高資料包丟失連接上。(請參閱 &lt; href =\"HTTP://sites.inka.de/bigred/devel/tcp-tcp.html\"&gt; 為什麼 TCP 在 TCP 是一個壞點子 &lt; /a &gt;)</string>
<string name="faq_tethering">網路共用的功能 (透過 Wi-Fi、USB 或藍牙) 和 VPNService API (此程式使用) 不一起作用。更多細節請看 &lt;a href=\"https://github.com/schwabe/ics-openvpn/issues/34\"&gt;issue #34&lt;/a&gt;</string>
@@ -239,14 +238,14 @@
<string name="session_ipv6string">%1$s - %3$s, %2$s</string>
<string name="state_connecting">連線中</string>
<string name="state_wait">等待伺服器回覆</string>
- <string name="state_auth">身份驗證</string>
- <string name="state_get_config">取得客戶端配置</string>
+ <string name="state_auth">身份驗證中...</string>
+ <string name="state_get_config">正在取得客戶端設定</string>
<string name="state_assign_ip">分配 IP 位址</string>
- <string name="state_add_routes">添加路由</string>
+ <string name="state_add_routes">增加路由</string>
<string name="state_connected">已連線</string>
<string name="state_disconnected">中斷連線</string>
<string name="state_reconnecting">正在重新連線</string>
- <string name="state_exiting">退出</string>
+ <string name="state_exiting">離開</string>
<string name="state_noprocess">不在執行</string>
<string name="state_resolve">解析主機名稱</string>
<string name="state_tcp_connect">連線中 (TCP)</string>
@@ -254,8 +253,8 @@
<string name="state_nonetwork">等待可使用的網路</string>
<string name="statusline_bytecount">↓%2$s/秒 %1$s - ↑%4$s/秒 %3$s</string>
<string name="notifcation_title_notconnect">未連線</string>
- <string name="start_vpn_title">正在連接至 VPN %s</string>
- <string name="start_vpn_ticker">正在連接至 VPN %s</string>
+ <string name="start_vpn_title">正在連線至 VPN %s</string>
+ <string name="start_vpn_ticker">正在連線至 VPN %s</string>
<string name="jelly_keystore_alphanumeric_bug">如果,密鑰憑證的名稱包含非字母數字字元 (如空白、底線、破折號),在某些 Android 4.1 版本可能會出現問題。請嘗試重新匯入不含特殊字元的憑證。</string>
<string name="encryption_cipher">加密密鑰</string>
<string name="packet_auth">封包驗證</string>
@@ -265,28 +264,26 @@
<string name="official_build">正式版本</string>
<string name="make_selection_inline">複製到設定檔</string>
<string name="crashdump">異常傾印</string>
- <string name="add">添加</string>
- <string name="send_config">發送配置檔</string>
+ <string name="add">增加</string>
+ <string name="send_config">傳送設定檔案</string>
<string name="complete_dn">完整的 DN</string>
<string name="remotetlsnote">你匯入的設定使用了已經過舊且不建議的 tls-remote 選項使用了不同的 DN 格式。</string>
<string name="rdn">RDN (common name)</string>
<string name="rdn_prefix">RDN 前綴</string>
<string name="tls_remote_deprecated">tls-remote (不建議使用)</string>
- <string name="help_translate">您可以訪問
-http://crowdin.net/project/ics-openvpn/invite
-幫助我們翻譯本軟體</string>
+ <string name="help_translate">你可以拜訪 http://crowdin.net/project/ics-openvpn/invite 來協助翻譯</string>
<string name="prompt">%1$s 試圖控制 %2$s</string>
<string name="remote_warning">你正在提供這個應用程式完全控制 OpenVPN for Android 與攔截所有網路流量的權限,<b>不允許,除非信任此應用程式。</b>否則,你的資料會受到惡意軟體洩漏的風險。</string>
- <string name="remote_trust">信任此應用程式</string>
+ <string name="remote_trust">我信任此應用程式</string>
<string name="no_external_app_allowed">不允許應用程式使用外部 API </string>
<string name="allowed_apps">允許的應用程式:%s</string>
<string name="clearappsdialog">清除允許外部應用程式的清單?\n目前的允許應用程式的清單:\n\n%s</string>
<string name="screenoff_summary">當螢幕關閉和 60 秒內的傳輸資料,小於 60 KB 的時,暫停 VPN。當 「保持 Tun 通道」選項開啟時,暫停 VPN 會讓你的裝置沒有網路連線。如果不使用「保持 Tun 通道」選項,這個裝置會沒有 VPN 連線/保護。</string>
- <string name="screenoff_title">當螢幕關閉時暫停VPN連線</string>
+ <string name="screenoff_title">當螢幕關閉時暫停 VPN 連線</string>
<string name="screenoff_pause">螢幕在關閉狀態時暫停連線:少於 %1$s 在 %2$s 秒</string>
<string name="screen_nopersistenttun">警告:保持 tun 通道沒有在此 VPN 中開啟。當螢幕關閉時,將會使用一般的網際網路連線。</string>
<string name="save_password">記住密碼</string>
- <string name="pauseVPN">暫停VPN</string>
+ <string name="pauseVPN">暫停 VPN</string>
<string name="resumevpn">恢復 VPN</string>
<string name="state_userpause">使用者要求暫停 VPN</string>
<string name="state_screenoff">VPN 暫停 - 螢幕關閉</string>
@@ -315,12 +312,12 @@ http://crowdin.net/project/ics-openvpn/invite
<string name="unhandled_exception">未處理的異常:%1$s \n\n %2$s</string>
<string name="unhandled_exception_context">%3$s:%1$s \n\n %2$s</string>
<string name="faq_system_dialog_xposed">如果你的 Android 裝置已取得 root 權限,你可以自行承擔風險安裝 &lt;a href=\"http://xposed.info/\"&gt;Xposed framework&lt;/a&gt; 和 &lt;a href=\"http://repo.xposed.info/module/de.blinkt.vpndialogxposed\"&gt;VPN Dialog confirm module&lt;/a&gt;</string>
- <string name="full_licenses">證照齊全</string>
- <string name="blocklocal_summary">直接連接到本地接口的網絡將不被路由通過VPN。取消選擇此選項將縮進重定向本地網絡的VPN的所有流量。</string>
+ <string name="full_licenses">完整授權</string>
+ <string name="blocklocal_summary">直接連線到本機介面的網路將不會被送至 VPN。取消選擇這個選項,將會把所有畚箕網路的流量導向 VPN。</string>
<string name="blocklocal_title">對區域網路繞過 VPN</string>
<string name="userpw_file">用戶名稱/密碼</string>
<string name="imported_from_file">[從匯入:%s]</string>
- <string name="files_missing_hint">一些文件無法找到。請選擇要導入的文件的配置文件:</string>
+ <string name="files_missing_hint">無法找到一些文件。請選擇檔案來匯入設定:</string>
<string name="openvpn_is_no_free_vpn">要使用這個程序,你需要一個VPN供應商/ VPN支持OpenVPN的網關(通常由雇主提供)。查看http://community.openvpn.net/關於OpenVPN的更多信息,以及如何設置自己的OpenVPN服務器。</string>
<string name="import_log">匯入日誌:</string>
<string name="ip_looks_like_subnet">VPN拓撲“%3$s”規定,但使用ifconfig %1$s %2$s看起來更像是一個網絡掩碼的IP地址。假設“子網”的拓撲結構。</string>
@@ -330,24 +327,24 @@ http://crowdin.net/project/ics-openvpn/invite
<string name="mssfix_checkbox">覆寫TCP 裝載資料 (payload) 的最大分段大小 (MSS) 值</string>
<string name="mssfix_dialogtitle">設定 TCP 裝載資料 (payload) 的最大分段大小 (MSS)</string>
<string name="client_behaviour">客戶端行為</string>
- <string name="clear_external_apps">清除允許外部應用程序</string>
+ <string name="clear_external_apps">清除允許外部應用程式</string>
<string name="loading">載入中...</string>
- <string name="allowed_vpn_apps_info">允許上傳的VPN應用程序:%1$s</string>
+ <string name="allowed_vpn_apps_info">允許的 VPN 應用程式:%1$s</string>
<string name="disallowed_vpn_apps_info">不允許的 VPN 應用程式:%1$s</string>
<string name="app_no_longer_exists">包%s不再安裝,從應用程序刪除它允許/禁止列表</string>
- <string name="vpn_disallow_radio">VPN適用於所有的應用程序,但不包括所選</string>
- <string name="vpn_allow_radio">的VPN僅用於對選定的應用程序</string>
+ <string name="vpn_disallow_radio">VPN 用於全部的應用程式,但不包含選擇的</string>
+ <string name="vpn_allow_radio">VPN 僅用於選擇的應用程式</string>
<string name="query_delete_remote">刪除遠端伺服器項目?</string>
- <string name="keep">養</string>
- <string name="delete">刪</string>
- <string name="add_remote">添加新的遠程</string>
+ <string name="keep">保持</string>
+ <string name="delete">刪除</string>
+ <string name="add_remote">加入新的遠端伺服器</string>
<string name="remote_random">連線時,隨機選擇連線項目</string>
<string name="remote_no_server_selected">您需要定義和啟用至少一個遠端伺服器。</string>
<string name="server_list">伺服器列表</string>
<string name="vpn_allowed_apps">允許的應用程式</string>
<string name="advanced_settings">進階設定</string>
<string name="payload_options">資料 (payload) 選項</string>
- <string name="tls_settings">TLS設定</string>
+ <string name="tls_settings">TLS 設定</string>
<string name="no_remote_defined">遠端沒有定義</string>
<string name="duplicate_vpn">重複的 VPN 設定檔</string>
<string name="duplicate_profile_title">複製設定檔︰ %s</string>
@@ -360,8 +357,10 @@ http://crowdin.net/project/ics-openvpn/invite
<string name="ab_kitkat_mss">早期的 KitKat 版本在 TCP 連線中,設定錯誤的最大分段大小 (MSS) 值 (#61948)。試著開啟 mssfix 選項來繞開這個 bug。</string>
<string name="ab_proxy">Android 沒有 DNS 伺服器設定時,會繼續使用你指定的行動/Wi-Fi 連線代理設定。OpenVPN for Android 會在日誌中記錄警告訊息。<p>當 VPN 有設定 DNS 伺服器時,因為,Android API 中無法為 VPN 連線設定代理,所以,將不會使用代理設定。</p></string>
<string name="ab_lollipop_reinstall">當解除安裝或重新安裝,VPN 應用程式也會停止運作。詳細資訊起參閱 #80074</string>
- <string name="ab_not_route_to_vpn">台灣繁體中文</string>
+ <string name="ab_not_route_to_vpn">已設定的客戶端 IP 及在此網路遮罩的 IP 不會路由到 VPN。OpenVPN 以明確加入一條對應到客戶端 IP 與此子網路遮罩的路由,來嘗試解決這個問題。</string>
+ <string name="ab_persist_tun">Sdjddnnsmssjhfjdd</string>
<string name="ab_secondary_users">VPN 不會對次級使用者作用。</string>
+ <string name="ab_kitkat_reconnect">「許多使用者回報,在使用 VPN 應用程式時,行動連線/行動數據連線經常被斷線。這個行為似乎只影響一些行動供應商/裝置結合,目前為止,沒有原因/解決可辨別該錯誤。」</string>
<string name="ab_vpn_reachability_44">Vpn是幹嗎?</string>
<string name="ab_only_cidr_title">非無類別域間 (CIDR) 路由</string>
<string name="ab_proxy_title">VPN 的代理行為</string>
@@ -372,20 +371,21 @@ http://crowdin.net/project/ics-openvpn/invite
<string name="ab_kitkat_mss_title">VPN 連線錯誤的最大分段大小 (MSS) 值</string>
<string name="ab_secondary_users_title">二级平板电脑用户</string>
<string name="custom_connection_options_warng">指定自訂連線的特定選項,請小心使用</string>
- <string name="custom_connection_options">自定義選項</string>
+ <string name="custom_connection_options">自訂的選項</string>
<string name="remove_connection_entry">刪除連線項目</string>
- <string name="ab_kitkat_reconnect_title">了解!</string>
+ <string name="ab_kitkat_reconnect_title">從行動網路隨機斷線</string>
<string name="ab_vpn_reachability_44_title">遠端網路無法連線</string>
<string name="ab_persist_tun_title">保持 tun 模式</string>
<string name="version_and_later">%s 及更高版本</string>
- <string name="tls_cipher_alert_title">連接失敗,SSL23_GET_SERVER_HELLO:sslv3 握手失敗</string>
+ <string name="tls_cipher_alert_title">連線失敗,SSL23_GET_SERVER_HELLO:sslv3 警告交握失敗</string>
<string name="message_no_user_edit">這個設定檔已被從外部應用程式 (%s) 新增,並標記為使用者無法編輯。</string>
<string name="crl_file">憑證撤銷清單</string>
- <string name="import_config_error">導入配置產生錯誤,無法保存</string>
- <string name="Search">搜索</string>
+ <string name="service_restarted">正在重新啟動 OpenVPN 服務(應用程式當機可能因為記憶體壓力而當機或被終止)</string>
+ <string name="import_config_error">匯入設定發生錯誤,無法儲存</string>
+ <string name="Search">搜尋</string>
<string name="lastdumpdate">(最後傾印是 %1$d:%2$dh 久 (%3$s))</string>
<string name="clear_log_on_connect">清除新連線的記錄</string>
- <string name="connect_timeout">連線超時</string>
+ <string name="connect_timeout">連線逾時</string>
<string name="query_permissions_sdcard">添加新的遠程</string>
<string name="protocol">協定</string>
<string name="enabled_connection_entry">啟用</string>
@@ -404,6 +404,7 @@ http://crowdin.net/project/ics-openvpn/invite
<string name="novpn_selected">沒有 VPN 被選擇</string>
<string name="defaultvpn">預設 VPN</string>
<string name="defaultvpnsummary">VPN 在 VPN 需要預設使用在的地方。這些對於目前上啟動,總是在和快速設置平鋪。</string>
+ <string name="vpnselected">目前選擇的 VPN:「%s」</string>
<string name="reconnect">重新連線</string>
<string name="qs_title">切換 VPN</string>
<string name="qs_connect">連線到 %s</string>
@@ -412,4 +413,44 @@ http://crowdin.net/project/ics-openvpn/invite
<string name="state_waitconnectretry">連線重試間,等待 %s 秒。</string>
<string name="change_sorting">更改排序</string>
<string name="sort">排序</string>
+ <string name="sorted_lru">根據最近使用來排序設定檔</string>
+ <string name="sorted_az">根據名稱來排序設定檔</string>
+ <string name="graph">圖表</string>
+ <string name="use_logarithmic_scale">使用對數尺度</string>
+ <string name="notenoughdata">沒有足夠的資料</string>
+ <string name="avghour">每小時平均</string>
+ <string name="avgmin">每分鐘平均</string>
+ <string name="last5minutes">最後 5 分鐘</string>
+ <string name="data_in">進</string>
+ <string name="data_out">出</string>
+ <string name="bits_per_second">%.0f bit/s</string>
+ <string name="kbits_per_second">%.1f kbit/s</string>
+ <string name="mbits_per_second">%.1f Mbit/s</string>
+ <string name="gbits_per_second">%.1f Gbit/s</string>
+ <string name="weakmd">&lt;p&gt;從 OpenSSL 1.1 版本, OpenSSL 拒絕憑證中的弱簽章,如
+ MD5。&lt;/p&gt;&lt;p&gt;&lt;b&gt;MD5 簽章完全不安全,且不該再使用。&lt;/b&gt; MD5
+ 碰撞 &lt;a
+ href=\"https://natmchugh.blogspot.de/2015/02/create-your-own-md5-collisions.html\"&gt;在幾小時內以對成本產生&lt;/a&gt;。
+ 你應該盡快更新 VPN 憑證。&lt;/p&gt;&lt;p&gt;不幸的是,舊的 easy-rsa
+ 發行版包含了 \"\"default_md md5\" 的設定選項。如果您正使用舊版的 easy-rsa,更新到
+ &lt;a href=\"https://github.com/OpenVPN/easy-rsa/releases\"&gt;最新版本&lt;/a&gt;) 或將 md5 換至 sha256 及
+ 重新產生您的憑證。&lt;/p&gt;&lt;p&gt;如果你真的想使用破舊的憑證,使用自訂的
+ 設定選項 tls-cipher \"DEFAULT:@SECLEVEL=0\" 在進階設定中,或額外加一行在您的
+ 已匯入的設定內&lt;/p&gt;
+ </string>
+ <string name="volume_byte">%.0f B</string>
+ <string name="volume_kbyte">%.1f kB</string>
+ <string name="volume_mbyte">%.1f MB</string>
+ <string name="volume_gbyte">%.1f GB</string>
+ <string name="channel_name_background">連線統計</string>
+ <string name="channel_description_background">正在統計已建立的 OpenVPN 連線</string>
+ <string name="channel_name_status">連線狀態改變</string>
+ <string name="channel_description_status">OpenVPN 連線狀態改變(正在連線,正在驗證...)</string>
+ <string name="weakmd_title">在憑證簽章中的弱(MD5)雜湊(SSL_CTX_use_certificate md too weak)</string>
+ <string name="title_activity_open_sslspeed">OpenSSL 速度測試</string>
+ <string name="openssl_cipher_name">OpenSSL cipher 名稱</string>
+ <string name="osslspeedtest">OpenSSL 加密速度測試</string>
+ <string name="openssl_error">OpenSSL 回傳一個錯誤</string>
+ <string name="running_test">執行測試中...</string>
+ <string name="test_algoirhtms">測試已選擇的演算法</string>
</resources>
diff --git a/app/src/main/res/values/strings-icsopenvpn.xml b/app/src/main/res/values/strings-icsopenvpn.xml
index 5094b909..b390ecec 100755
--- a/app/src/main/res/values/strings-icsopenvpn.xml
+++ b/app/src/main/res/values/strings-icsopenvpn.xml
@@ -181,6 +181,7 @@
<string name="show_log_window">Show log window</string>
<string name="mobile_info">%10$s %9$s running on %3$s %1$s (%2$s), Android %6$s (%7$s) API %4$d, ABI %5$s, (%8$s)</string>
<string name="error_rsa_sign">Error signing with Android keystore key %1$s: %2$s</string>
+ <string name="error_extapp_sign">Error signing with external authenticator app (%3$s): %1$s: %2$s</string>
<string name="faq_system_dialogs">The VPN connection warning telling you that this app can intercept all traffic is imposed by the system to prevent abuse of the VPNService API.\nThe VPN connection notification (The key symbol) is also imposed by the Android system to signal an ongoing VPN connection. On some images this notification plays a sound.\nAndroid introduced these system dialogs for your own safety and made sure that they cannot be circumvented. (On some images this unfortunately includes a notification sound)</string>
<string name="faq_system_dialogs_title">Connection warning and notification sound</string>
<string name="translationby">English translation by Arne Schwabe&lt;arne@rfc2549.org&gt;</string>
@@ -199,7 +200,7 @@
<string name="setting_loadtun">Load tun module</string>
<string name="importpkcs12fromconfig">Import PKCS12 from configuration into Android Keystore</string>
<string name="getproxy_error">Error getting proxy settings: %s</string>
- <string name="using_proxy">Using proxy %1$s %2$d</string>
+ <string name="using_proxy">Using proxy %1$s %2$s</string>
<string name="use_system_proxy">Use system proxy</string>
<string name="use_system_proxy_summary">Use the system wide configuration for HTTP/HTTPS proxies to connect.</string>
<string name="onbootrestartsummary">OpenVPN will connect the specified VPN if it was active on system boot. Please read the connection warning FAQ before using this option on Android &lt; 5.0.</string>
@@ -250,6 +251,7 @@
<string name="state_tcp_connect">Connecting (TCP)</string>
<string name="state_auth_failed">Authentication failed</string>
<string name="state_nonetwork">Waiting for usable network</string>
+ <string name="state_waitorbot">Waiting for Orbot to start</string>
<string name="statusline_bytecount">↓%2$s %1$s - ↑%4$s %3$s</string>
<string name="notifcation_title_notconnect">Not connected</string>
<string name="start_vpn_title">Connecting to VPN %s</string>
@@ -465,5 +467,24 @@
<string name="all_app_prompt">An external app tries to control %s. The app requesting access cannot be determined. Allowing this app grants ALL apps access.</string>
<string name="openvpn3_nostatickeys">The OpenVPN 3 C++ implementation does not support static keys. Please change to OpenVPN 2.x under general settings.</string>
<string name="openvpn3_pkcs12">Using PKCS12 files directly with OpenVPN 3 C++ implementation is not supported. Please import the pkcs12 files into the Android keystore or change to OpenVPN 2.x under general settings.</string>
+ <string name="proxy">Proxy</string>
+ <string name="Use_no_proxy">None</string>
+ <string name="tor_orbot">Tor (Orbot)</string>
+ <string name="openvpn3_socksproxy">OpenVPN 3 C++ implementation does not support connecting via Socks proxy</string>
+ <string name="no_orbotfound">Orbot application cannot be found. Please install Orbot or use manual Socks v5 integration.</string>
+ <string name="faq_remote_api_title">Remote API</string>
+ <string name="faq_remote_api">OpenVPN for Android supports two remote APIs, a sophisticated API using AIDL (remoteEXample in the git repository) and a simple one using Intents. &lt;p>Examples using adb shell and the intents. Replace profilname with your profile name&lt;p>&lt;p> adb shell am start-activity -a android.intent.action.MAIN de.blinkt.openvpn/.api.DisconnectVPN&lt;p> adb shell am start-activity -a android.intent.action.MAIN -e de.blinkt.openvpn.api.profileName Blinkt de.blinkt.openvpn/.api.ConnectVPN</string>
+ <string name ="enableproxyauth">Enable Proxy Authentication</string>
+ <string name="error_orbot_and_proxy_options">Cannot use extra http-proxy-option statement and Orbot integration at the same timeO</string>
+ <string name="info_from_server">Info from server: \'%s\'</string>
+ <string name="channel_name_userreq">User interaction required</string>
+ <string name="channel_description_userreq">OpenVPN connection requires a user input, e.g. two factor
+ authentification
+ </string>
+ <string name="openurl_requested">Open URL to continue VPN authentication</string>
+ <string name="state_auth_pending">Authentication pending</string>
+ <string name="external_authenticator">External Authenticator</string>
+ <string name="configure">Configure</string>
+ <string name="extauth_not_configured">External Authneticator not configured</string>
</resources>
diff --git a/app/src/ovpn3/java/de/blinkt/openvpn/core/OpenVPNThreadv3.java b/app/src/ovpn3/java/de/blinkt/openvpn/core/OpenVPNThreadv3.java
index 54029628..ac49f988 100644
--- a/app/src/ovpn3/java/de/blinkt/openvpn/core/OpenVPNThreadv3.java
+++ b/app/src/ovpn3/java/de/blinkt/openvpn/core/OpenVPNThreadv3.java
@@ -1,21 +1,30 @@
package de.blinkt.openvpn.core;
-import net.openvpn.ovpn3.ClientAPI_Config;
-import net.openvpn.ovpn3.ClientAPI_EvalConfig;
-import net.openvpn.ovpn3.ClientAPI_Event;
-import net.openvpn.ovpn3.ClientAPI_ExternalPKICertRequest;
-import net.openvpn.ovpn3.ClientAPI_ExternalPKISignRequest;
-import net.openvpn.ovpn3.ClientAPI_LogInfo;
-import net.openvpn.ovpn3.ClientAPI_OpenVPNClient;
-import net.openvpn.ovpn3.ClientAPI_ProvideCreds;
-import net.openvpn.ovpn3.ClientAPI_Status;
-import net.openvpn.ovpn3.ClientAPI_TransportStats;
+import android.net.*;
+import android.os.Build;
+import se.leap.bitmaskclient.R;
+import net.openvpn.ovpn3.*;
import java.lang.Override;
+import java.net.Inet4Address;
+import java.net.Inet6Address;
+import java.util.Locale;
+import java.util.Vector;
import de.blinkt.openvpn.VpnProfile;
import android.content.Context;
+import net.openvpn.ovpn3.*;
+import net.openvpn.ovpn3.*;
+import net.openvpn.ovpn3.*;
+import net.openvpn.ovpn3.*;
+import net.openvpn.ovpn3.*;
+import net.openvpn.ovpn3.*;
+import net.openvpn.ovpn3.*;
+import net.openvpn.ovpn3.ClientAPI_Config;
+import net.openvpn.ovpn3.ClientAPI_EvalConfig;
+import net.openvpn.ovpn3.ClientAPI_Event;
+import net.openvpn.ovpn3.ClientAPI_ExternalPKICertRequest;
public class OpenVPNThreadv3 extends ClientAPI_OpenVPNClient implements Runnable, OpenVPNManagement {
@@ -164,8 +173,12 @@ public class OpenVPNThreadv3 extends ClientAPI_OpenVPNClient implements Runnable
}
- @Override
+ final static long EmulateExcludeRoutes = (1 << 16);
+
+ @Override
public boolean tun_builder_reroute_gw(boolean ipv4, boolean ipv6, long flags) {
+ if ((flags & EmulateExcludeRoutes) != 0)
+ return true;
if (ipv4)
mService.addRoute("0.0.0.0", "0.0.0.0", "127.0.0.1", OpenVPNService.VPNSERVICE_TUN);
@@ -188,6 +201,9 @@ public class OpenVPNThreadv3 extends ClientAPI_OpenVPNClient implements Runnable
config.setGuiVersion(mVp.getVersionEnvString(mService));
//config.setPlatformVersion(mVp.getPlatformVersionEnvString());
config.setExternalPkiAlias("extpki");
+ config.setCompressionMode("asym");
+ config.setInfo(true);
+ config.setAllowLocalLanAccess(mVp.mAllowLocalLAN);
ClientAPI_EvalConfig ec = eval_config(config);
if(ec.getExternalPki()) {
@@ -202,10 +218,11 @@ public class OpenVPNThreadv3 extends ClientAPI_OpenVPNClient implements Runnable
}
}
+
@Override
public void external_pki_cert_request(ClientAPI_ExternalPKICertRequest certreq) {
VpnStatus.logDebug("Got external PKI certificate request from OpenVPN core");
- String[] ks = mVp.getKeyStoreCertificates((Context) mService);
+ String[] ks = mVp.getExternalCertificates(mService);
if(ks==null) {
certreq.setError(true);
certreq.setErrorText("Error in pki cert request");
@@ -224,7 +241,7 @@ public class OpenVPNThreadv3 extends ClientAPI_OpenVPNClient implements Runnable
@Override
public void external_pki_sign_request(ClientAPI_ExternalPKISignRequest signreq) {
VpnStatus.logDebug("Got external PKI signing request from OpenVPN core");
- signreq.setSig(mVp.getSignedData(signreq.getData()));
+ signreq.setSig(mVp.getSignedData(mService, signreq.getData(),true));
}
void setUserPW() {
@@ -277,9 +294,29 @@ public class OpenVPNThreadv3 extends ClientAPI_OpenVPNClient implements Runnable
@Override
public void event(ClientAPI_Event event) {
- VpnStatus.updateStateString(event.getName(), event.getInfo());
+ String name = event.getName();
+ String info = event.getInfo();
+ if (name.equals("INFO")) {
+ VpnStatus.logInfo(R.string.info_from_server, info);
+ if (info.startsWith("OPEN_URL:"))
+ {
+ mService.trigger_url_open(info);
+ }
+ } else{
+ VpnStatus.updateStateString(name, info);
+ }
if(event.getError())
- VpnStatus.logError(String.format("EVENT(Error): %s: %s",event.getName(),event.getInfo()));
+ VpnStatus.logError(String.format("EVENT(Error): %s: %s", name, info));
+ }
+
+ @Override
+ public net.openvpn.ovpn3.ClientAPI_StringVec tun_builder_get_local_networks(boolean ipv6)
+ {
+
+ net.openvpn.ovpn3.ClientAPI_StringVec nets = new net.openvpn.ovpn3.ClientAPI_StringVec();
+ for (String net: NetworkUtils.getLocalNetworks(mService, ipv6))
+ nets.add(net);
+ return nets;
}
diff --git a/app/src/test/java/de/blinkt/openvpn/core/TestConfigGenerator.java b/app/src/test/java/de/blinkt/openvpn/core/TestConfigGenerator.java
new file mode 100644
index 00000000..892a5807
--- /dev/null
+++ b/app/src/test/java/de/blinkt/openvpn/core/TestConfigGenerator.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2012-2018 Arne Schwabe
+ * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt
+ */
+
+package de.blinkt.openvpn.core;
+
+import android.content.Context;
+import android.content.pm.PackageManager;
+
+import junit.framework.Assert;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+import de.blinkt.openvpn.VpnProfile;
+
+import static de.blinkt.openvpn.VpnProfile.AUTH_RETRY_NOINTERACT;
+import static de.blinkt.openvpn.VpnProfile.TYPE_USERPASS;
+
+/**
+ * Created by arne on 14.03.18.
+ */
+
+@Config(manifest= Config.NONE)
+@RunWith(RobolectricTestRunner.class)
+public class TestConfigGenerator {
+ @Test
+ public void testAuthRetryGen() throws PackageManager.NameNotFoundException {
+ /*Context mc = mock(Context.class);
+ PackageManager mpm = mock(PackageManager.class);
+
+ PackageInfo mpi = new PackageInfo();
+ mpi.versionCode = 177;
+ mpi.versionName = "foo";
+
+ when(mc.getCacheDir()).thenReturn(new File("/j/unit/test/"));
+ when(mc.getPackageName()).thenReturn("de.blinkt.openvpn");
+ when(mc.getPackageManager()).thenReturn(mpm);
+ when(mpm.getPackageInfo(eq("de.blinkt.openvpn"),eq(0))).thenReturn(mpi);*/
+
+
+
+ VpnProfile vp = new VpnProfile ("test") {
+ @Override
+ public String getVersionEnvString(Context c) {
+ return "no ver";
+ }
+
+ @Override
+ public String getPlatformVersionEnvString() {
+ return "test";
+ }
+ };
+
+ vp.mAuthenticationType = TYPE_USERPASS;
+ vp.mAuthRetry = AUTH_RETRY_NOINTERACT;
+ String config = vp.getConfigFile(RuntimeEnvironment.application, false);
+ Assert.assertTrue(config.contains("\nauth-retry nointeract\n"));
+ for (Connection connection: vp.mConnections)
+ Assert.assertTrue(connection.mProxyType == Connection.ProxyType.NONE);
+
+ }
+
+
+}
diff --git a/app/src/test/java/de/blinkt/openvpn/core/TestConfigParser.java b/app/src/test/java/de/blinkt/openvpn/core/TestConfigParser.java
index 560d4fc8..41ee2981 100644
--- a/app/src/test/java/de/blinkt/openvpn/core/TestConfigParser.java
+++ b/app/src/test/java/de/blinkt/openvpn/core/TestConfigParser.java
@@ -5,21 +5,51 @@
package de.blinkt.openvpn.core;
+import android.app.Application;
+import android.content.Context;
+import se.leap.bitmaskclient.R;
import org.junit.Assert;
import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
import java.io.IOException;
import java.io.StringReader;
+import java.util.Arrays;
import de.blinkt.openvpn.VpnProfile;
+import org.robolectric.annotation.Config;
/**
* Created by arne on 03.10.16.
*/
+@Config(manifest= "src/main/AndroidManifest.xml")
+@RunWith(RobolectricTestRunner.class)
public class TestConfigParser {
- String miniconfig = "client\nremote test.blinkt.de\n";
+ public static final String fakeCerts = "<ca>\n" +
+ "-----BEGIN CERTIFICATE-----\n" +
+ "\n" +
+ "-----END CERTIFICATE-----\n" +
+ "\n" +
+ "</ca>\n" +
+ "\n" +
+ "<cert>\n" +
+ "-----BEGIN CERTIFICATE-----\n" +
+ "\n" +
+ "-----END CERTIFICATE-----\n" +
+ "\n" +
+ "</cert>\n" +
+ "\n" +
+ "<key>\n" +
+ "-----BEGIN PRIVATE KEY-----\n" +
+ "\n" +
+ "-----END PRIVATE KEY-----\n" +
+ "\n" +
+ "</key>";
+ private final String miniconfig = "client\nremote test.blinkt.de\n";
@Test
public void testHttpProxyPass() throws IOException, ConfigParser.ConfigParseError {
@@ -31,7 +61,196 @@ public class TestConfigParser {
ConfigParser cp = new ConfigParser();
cp.parseConfig(new StringReader(miniconfig + httpproxypass));
VpnProfile p = cp.convertProfile();
- Assert.assertTrue(p.mCustomConfigOptions.contains(httpproxypass));
+ Assert.assertFalse(p.mCustomConfigOptions.contains(httpproxypass));
+
+ }
+
+ @Test
+ public void cleanReImport() throws IOException, ConfigParser.ConfigParseError {
+ ConfigParser cp = new ConfigParser();
+ cp.parseConfig(new StringReader(miniconfig + fakeCerts));
+ VpnProfile vp = cp.convertProfile();
+
+ String outConfig = vp.getConfigFile(RuntimeEnvironment.application, false);
+
+ cp = new ConfigParser();
+ cp.parseConfig(new StringReader(outConfig));
+ VpnProfile vp2 = cp.convertProfile();
+
+ String outConfig2 = vp2.getConfigFile(RuntimeEnvironment.application, false);
+
+ Assert.assertEquals(outConfig, outConfig2);
+ Assert.assertFalse(vp.mUseCustomConfig);
+ Assert.assertFalse(vp2.mUseCustomConfig);
+
+ }
+
+ @Test
+ public void testCommonOptionsImport() throws IOException, ConfigParser.ConfigParseError
+ {
+ String config = "client\n"
+ + "tun-mtu 1234\n" +
+ "<connection>\n" +
+ "remote foo.bar\n" +
+ "tun-mtu 1222\n"+
+ "</connection>\n";
+
+ ConfigParser cp = new ConfigParser();
+ cp.parseConfig(new StringReader(config));
+ VpnProfile vp = cp.convertProfile();
+
+ Assert.assertEquals(1234, vp.mTunMtu);
+ Assert.assertTrue(vp.mConnections[0].mCustomConfiguration.contains("tun-mtu 1222"));
+ Assert.assertTrue(vp.mConnections[0].mUseCustomConfig);
+ }
+
+ @Test
+ public void testSockProxyImport() throws IOException, ConfigParser.ConfigParseError {
+ String proxy =
+ "ca baz\n" +
+ "key foo\n" +
+ "cert bar\n" +
+ "client\n" +
+ "<connection>\n" +
+ "socks-proxy 13.23.3.2\n" +
+ "remote foo.bar\n" +
+ "</connection>\n" +
+ "\n" +
+ "<connection>\n" +
+ "socks-proxy 1.2.3.4 1234\n" +
+ "remote foo.bar\n" +
+ "</connection>\n" +
+ "\n" +
+ "<connection>\n" +
+ "http-proxy 1.2.3.7 8080\n" +
+ "remote foo.bar\n" +
+ "</connection>";
+
+ ConfigParser cp = new ConfigParser();
+ cp.parseConfig(new StringReader(proxy));
+ VpnProfile vp = cp.convertProfile();
+ Assert.assertEquals(3, vp.mConnections.length);
+
+ Assert.assertEquals("13.23.3.2", vp.mConnections[0].mProxyName);
+ Assert.assertEquals("1080", vp.mConnections[0].mProxyPort);
+ Assert.assertEquals(Connection.ProxyType.SOCKS5, vp.mConnections[0].mProxyType);
+
+ Assert.assertEquals("1.2.3.4", vp.mConnections[1].mProxyName);
+ Assert.assertEquals("1234", vp.mConnections[1].mProxyPort);
+ Assert.assertEquals(Connection.ProxyType.SOCKS5, vp.mConnections[0].mProxyType);
+
+ Assert.assertEquals("1.2.3.7", vp.mConnections[2].mProxyName);
+ Assert.assertEquals("8080", vp.mConnections[2].mProxyPort);
+ Assert.assertEquals(Connection.ProxyType.HTTP, vp.mConnections[2].mProxyType);
+
+ Context c = RuntimeEnvironment.application;
+ int err = vp.checkProfile(c, false);
+ Assert.assertTrue("Failed with " + c.getString(err), err == R.string.no_error_found);
}
+
+ @Test
+ public void testHttpUserPassAuth() throws IOException, ConfigParser.ConfigParseError {
+ String proxy ="client\n" +
+ "dev tun\n" +
+ "proto tcp\n" +
+ "remote 1.2.3.4 443\n" +
+ "resolv-retry infinite\n" +
+ "nobind\n" +
+ "persist-key\n" +
+ "persist-tun\n" +
+ "auth-user-pass\n" +
+ "verb 3\n" +
+ "cipher AES-128-CBC\n" +
+ "pull\n" +
+ "route-delay 2\n" +
+ "redirect-gateway\n" +
+ "remote-cert-tls server\n" +
+ "ns-cert-type server\n" +
+ "comp-lzo no\n" +
+ "http-proxy 1.2.3.4 1234\n" +
+ "<http-proxy-user-pass>\n" +
+ "username12\n" +
+ "password34\n" +
+ "</http-proxy-user-pass>\n" +
+ "<ca>\n" +
+ "foo\n" +
+ "</ca>\n" +
+ "<cert>\n" +
+ "bar\n" +
+ "</cert>\n" +
+ "<key>\n" +
+ "baz\n" +
+ "</key>\n";
+ ConfigParser cp = new ConfigParser();
+ cp.parseConfig(new StringReader(proxy));
+ VpnProfile vp = cp.convertProfile();
+ String config = vp.getConfigFile(RuntimeEnvironment.application, true);
+ Assert.assertTrue(config.contains("username12"));
+ Assert.assertTrue(config.contains("http-proxy 1.2.3.4"));
+
+ config = vp.getConfigFile(RuntimeEnvironment.application, false);
+
+ Assert.assertFalse(config.contains("username12"));
+ Assert.assertFalse(config.contains("http-proxy 1.2.3.4"));
+
+ Assert.assertTrue(vp.mConnections[0].mUseProxyAuth);
+ Assert.assertEquals(vp.mConnections[0].mProxyAuthUser, "username12");
+ Assert.assertEquals(vp.mConnections[0].mProxyAuthPassword, "password34");
+ }
+
+ @Test
+ public void testConfigWithHttpProxyOptions() throws IOException, ConfigParser.ConfigParseError {
+ String proxyconf = "pull\n" +
+ "dev tun\n" +
+ "proto tcp-client\n" +
+ "cipher AES-128-CBC\n" +
+ "auth SHA1\n" +
+ "reneg-sec 0\n" +
+ "remote-cert-tls server\n" +
+ "tls-version-min 1.2 or-highest\n" +
+ "persist-tun\n" +
+ "nobind\n" +
+ "connect-retry 2 2\n" +
+ "dhcp-option DNS 1.1.1.1\n" +
+ "dhcp-option DNS 84.200.69.80\n" +
+ "auth-user-pass\n" +
+ "\n" +
+ "remote xx.xx.xx.xx 1194\n" +
+ "http-proxy 1.2.3.4 8080\n" +
+ "http-proxy-option VERSION 1.1\n" +
+ "http-proxy-option CUSTOM-HEADER \"Connection: Upgrade\"\n" +
+ "http-proxy-option CUSTOM-HEADER \"X-Forwarded-Proto: https\"\n" +
+ "http-proxy-option CUSTOM-HEADER \"Upgrade-Insecure-Requests: 1\"\n" +
+ "http-proxy-option CUSTOM-HEADER \"DNT: 1\"\n" +
+ "http-proxy-option CUSTOM-HEADER \"Tk: N\"\n" +
+ "\n" +
+ fakeCerts;
+
+ ConfigParser cp = new ConfigParser();
+ cp.parseConfig(new StringReader(proxyconf));
+ VpnProfile vp = cp.convertProfile();
+ String config = vp.getConfigFile(RuntimeEnvironment.application, true);
+
+
+ Assert.assertEquals(vp.checkProfile(RuntimeEnvironment.application, true), R.string.no_error_found);
+ Assert.assertEquals(vp.checkProfile(RuntimeEnvironment.application, false), R.string.no_error_found);
+
+ config = vp.getConfigFile(RuntimeEnvironment.application, false);
+
+ Assert.assertTrue(config.contains("http-proxy 1.2.3.4"));
+ Assert.assertFalse(config.contains("management-query-proxy"));
+
+
+ Assert.assertTrue(config.contains("http-proxy-option CUSTOM-HEADER"));
+
+ vp.mConnections = Arrays.copyOf(vp.mConnections, vp.mConnections.length + 1);
+ vp.mConnections[vp.mConnections.length - 1] = new Connection();
+
+ vp.mConnections[vp.mConnections.length -1].mProxyType = Connection.ProxyType.ORBOT;
+
+ Assert.assertEquals(vp.checkProfile(RuntimeEnvironment.application, false), R.string.error_orbot_and_proxy_options);
+
+ }
+
}
diff --git a/app/src/test/java/de/blinkt/openvpn/core/TestIpParser.java b/app/src/test/java/de/blinkt/openvpn/core/TestIpParser.java
index 37f9fdcd..6b330b63 100644
--- a/app/src/test/java/de/blinkt/openvpn/core/TestIpParser.java
+++ b/app/src/test/java/de/blinkt/openvpn/core/TestIpParser.java
@@ -31,7 +31,7 @@ public class TestIpParser {
void testAddress(String input, int mask, String output) throws UnknownHostException {
Inet6Address ip = (Inet6Address) InetAddress.getByName(input);
- NetworkSpace.ipAddress netIp = new NetworkSpace.ipAddress(ip, mask, true);
+ NetworkSpace.IpAddress netIp = new NetworkSpace.IpAddress(ip, mask, true);
Assert.assertEquals(output, netIp.toString());
}
diff --git a/ics-openvpn b/ics-openvpn
-Subproject 18f82db3d78c801284d4818778042eaf4d44f69
+Subproject f310bd7a0120b770dbc29a67ea0d6ffba2e136c