From 74842cba92591aa9fbf64e8c6f39900a68b0c11c Mon Sep 17 00:00:00 2001 From: cyBerta Date: Fri, 19 Oct 2018 23:15:13 +0200 Subject: #8919 update dependencies --- .../openvpn/api/ExternalCertificateProvider.aidl | 39 ++ .../de/blinkt/openvpn/api/IOpenVPNAPIService.aidl | 2 +- .../openvpn/core/IOpenVPNServiceInternal.aidl | 1 + app/src/main/java/de/blinkt/openvpn/LaunchVPN.java | 4 +- .../main/java/de/blinkt/openvpn/VpnProfile.java | 482 ++++++++++++--------- .../main/java/de/blinkt/openvpn/core/CIDRIP.java | 8 +- .../java/de/blinkt/openvpn/core/ConfigParser.java | 379 +++++++++------- .../java/de/blinkt/openvpn/core/Connection.java | 33 +- .../java/de/blinkt/openvpn/core/ExtAuthHelper.java | 259 +++++++++++ .../blinkt/openvpn/core/ICSOpenVPNApplication.java | 2 +- .../de/blinkt/openvpn/core/LogFileHandler.java | 4 +- .../java/de/blinkt/openvpn/core/NativeUtils.java | 22 +- .../java/de/blinkt/openvpn/core/NetworkSpace.java | 103 ++--- .../java/de/blinkt/openvpn/core/NetworkUtils.java | 75 ++++ .../de/blinkt/openvpn/core/OpenVPNService.java | 181 ++++++-- .../openvpn/core/OpenVpnManagementThread.java | 239 +++++++--- .../java/de/blinkt/openvpn/core/OrbotHelper.java | 202 +++++++++ .../de/blinkt/openvpn/core/ProfileManager.java | 13 +- .../de/blinkt/openvpn/core/VPNLaunchHelper.java | 2 +- .../java/de/blinkt/openvpn/core/VpnStatus.java | 6 +- app/src/main/res/values-be/plurals-icsopenvpn.xml | 3 + app/src/main/res/values-be/strings-icsopenvpn.xml | 464 ++++++++++++++++++++ app/src/main/res/values-ca/strings-icsopenvpn.xml | 1 - app/src/main/res/values-cs/strings-icsopenvpn.xml | 5 +- app/src/main/res/values-da/strings-icsopenvpn.xml | 88 +++- app/src/main/res/values-de/strings-icsopenvpn.xml | 15 +- app/src/main/res/values-es/strings-icsopenvpn.xml | 22 +- app/src/main/res/values-et/strings-icsopenvpn.xml | 1 - app/src/main/res/values-fr/strings-icsopenvpn.xml | 16 +- app/src/main/res/values-hu/strings-icsopenvpn.xml | 5 +- app/src/main/res/values-in/strings-icsopenvpn.xml | 21 +- app/src/main/res/values-it/strings-icsopenvpn.xml | 24 +- app/src/main/res/values-ja/strings-icsopenvpn.xml | 19 +- app/src/main/res/values-ko/strings-icsopenvpn.xml | 13 +- app/src/main/res/values-nl/strings-icsopenvpn.xml | 5 +- app/src/main/res/values-no/strings-icsopenvpn.xml | 1 - app/src/main/res/values-pl/plurals-icsopenvpn.xml | 8 +- app/src/main/res/values-pl/strings-icsopenvpn.xml | 26 +- app/src/main/res/values-pt/strings-icsopenvpn.xml | 1 - app/src/main/res/values-ro/strings-icsopenvpn.xml | 1 - app/src/main/res/values-ru/plurals-icsopenvpn.xml | 12 +- app/src/main/res/values-ru/strings-icsopenvpn.xml | 26 +- app/src/main/res/values-sl/strings-icsopenvpn.xml | 1 - app/src/main/res/values-sv/strings-icsopenvpn.xml | 7 +- app/src/main/res/values-tr/strings-icsopenvpn.xml | 5 +- app/src/main/res/values-uk/plurals-icsopenvpn.xml | 23 +- app/src/main/res/values-uk/strings-icsopenvpn.xml | 5 +- app/src/main/res/values-vi/strings-icsopenvpn.xml | 30 +- .../main/res/values-zh-rCN/strings-icsopenvpn.xml | 32 +- .../main/res/values-zh-rTW/plurals-icsopenvpn.xml | 15 +- .../main/res/values-zh-rTW/strings-icsopenvpn.xml | 181 +++++--- app/src/main/res/values/strings-icsopenvpn.xml | 23 +- 52 files changed, 2456 insertions(+), 699 deletions(-) create mode 100644 app/src/main/aidl/de/blinkt/openvpn/api/ExternalCertificateProvider.aidl create mode 100644 app/src/main/java/de/blinkt/openvpn/core/ExtAuthHelper.java create mode 100644 app/src/main/java/de/blinkt/openvpn/core/NetworkUtils.java create mode 100644 app/src/main/java/de/blinkt/openvpn/core/OrbotHelper.java create mode 100755 app/src/main/res/values-be/plurals-icsopenvpn.xml create mode 100755 app/src/main/res/values-be/strings-icsopenvpn.xml (limited to 'app/src/main') 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 ... or ... + * e.g., using ... or ... * 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 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\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 += "\n" + ks[0] + "\n\n"; - if (ks[1] != null) - cfg += "\n" + ks[1] + "\n\n"; - cfg += "\n" + ks[2] + "\n\n"; - cfg += "management-external-key\n"; + cfg.append("\n").append(ks[0]).append("\n\n"); + if (!TextUtils.isEmpty(ks[1])) + cfg.append("\n").append(ks[1]).append("\n\n"); + cfg.append("\n").append(ks[2]).append("\n\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 += "\n"; - cfg += conn.getConnectionBlock(); - cfg += "\n"; + cfg.append("\n"); + cfg.append(conn.getConnectionBlock(configForOvpn3)); + cfg.append("\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\n", cfgentry, dataWithOutHeader, cfgentry); - } else { - return String.format(Locale.ENGLISH, "%s %s\n", cfgentry, openVpnEscape(filedata)); - } - } - @NonNull private Collection getCustomRoutes(String routes) { Vector 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>> options = new HashMap>>(); + 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 connectionOptionsSet = new HashSet<>(Arrays.asList(connectionOptions)); + + private HashMap>> options = new HashMap<>(); private HashMap> meta = new HashMap>(); 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 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 parseline(String line) throws ConfigParseError { Vector parameters = new Vector(); @@ -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 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> tlsauthoptions = getAllOption("tls-auth", 1, 2); @@ -426,7 +428,7 @@ public class ConfigParser { np.mTLSAuthDirection = direction.get(1); Vector 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 tunmtu = getOption("mtu", 1, 1); + Vector tunmtu = getOption("tun-mtu", 1, 1); if (tunmtu != null) { try { @@ -478,7 +480,6 @@ public class ConfigParser { } - Vector mode = getOption("mode", 1, 1); if (mode != null) { if (!mode.get(1).equals("p2p")) @@ -592,9 +593,9 @@ public class ConfigParser { } - Vector x509usernamefield = getOption("x509-username-field", 1,1); - if (x509usernamefield!=null) { - np.mx509UsernameField = x509usernamefield.get(1); + Vector 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 str) { + if (Build.VERSION.SDK_INT > 26) + return String.join(s, str); + else + return TextUtils.join(s, str); + } + private Pair 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> remotes = getAllOption("remote", 1, 3); + Vector 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 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> option : options.values()) { - conn.mCustomConfiguration += getOptionStrings(option); + // Parse remote config + Vector> remotes = getAllOption("remote", 1, 3); + + + Vector optionsToRemove = new Vector<>(); + // Assume that we need custom options if connectionDefault are set or in the connection specific set + for (Map.Entry>> 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>(); @@ -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 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 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> option: options.values()) + { + for (Vector 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 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> getAllOption(String option, int minarg, int maxarg) throws ConfigParseError { Vector> 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, "\n%s\n%s\n\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 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(c, android.R.layout.simple_spinner_item, android.R.id.text1, extProviders); + spinner.setAdapter(extAppAdapter); + if (selectedPos != -1) + spinner.setSelection(selectedPos); + } + + static ArrayList getExternalAuthProviderList(Context c) { + Intent configureExtAuth = new Intent(ACTION_CERT_CONFIGURATION); + + final PackageManager packageManager = c.getPackageManager(); + List configureList = + packageManager.queryIntentActivities(configureExtAuth, 0); + + Intent serviceExtAuth = new Intent(ACTION_CERT_PROVIDER); + + List serviceList = + packageManager.queryIntentServices(serviceExtAuth, 0); + + + // For now only list those who appear in both lists + + ArrayList providers = new ArrayList(); + + 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 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 toCertificates(@NonNull byte[] bytes) { + final String BEGINCERT = "-----BEGIN CERTIFICATE-----"; + try { + Vector 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) 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 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 { + static void assertTrue(boolean f) + { + if (!f) + throw new IllegalStateException(); + } + + static class IpAddress implements Comparable { 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 mIpAddresses = new TreeSet(); + TreeSet mIpAddresses = new TreeSet(); - public Collection getNetworks(boolean included) { - Vector ips = new Vector(); - for (ipAddress ip : mIpAddresses) { + public Collection getNetworks(boolean included) { + Vector ips = new Vector(); + 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 generateIPList() { + TreeSet generateIPList() { - PriorityQueue networks = new PriorityQueue(mIpAddresses); + PriorityQueue networks = new PriorityQueue(mIpAddresses); - TreeSet ipsDone = new TreeSet(); + TreeSet ipsDone = new TreeSet(); - 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 getPositiveIPList() { - TreeSet ipsSorted = generateIPList(); + Collection getPositiveIPList() { + TreeSet ipsSorted = generateIPList(); - Vector ips = new Vector(); - for (ipAddress ia : ipsSorted) { + Vector ips = new Vector(); + 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 getLocalNetworks(Context c, boolean ipv6) { + Vector 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 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 positiveIPv4Routes = mRoutes.getPositiveIPList(); - Collection positiveIPv6Routes = mRoutesv6.getPositiveIPList(); + Collection positiveIPv4Routes = mRoutes.getPositiveIPList(); + Collection 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 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 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 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 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 @@ + + + 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 @@ + + + + + + Адрас сервера: + Порт сервера: + Размяшчэнне + Не атрымоўваецца прачытаць каталог + Выбраць + Адмена + Няма дадзеных + Сціск LZO + Няма сертыфіката + Сертыфікат кліента + Ключ сертыфіката кліента + Файл PKCS12 + Сертыфікат ЦС + Трэба выбраць сертыфікат + Зыходны код і адсочванне праблем даступныя на https://github.com/schwabe/ics-openvpn/ + Дадзеная праграма выкарыстоўвае наступныя кампаненты; гледзіце зыходны код для атрымання падрабязнай інфармацыі пра ліцэнзію + Пра дадатак + Профілі + Тып + Пароль для PKCS12 + Выбраць… + Вы павінны выбраць файл + Скарыстаць аўтэнтыфікацыю TLS + Кірунак праверкі TLS + Увядзіце адрас/маску падсеткі IPv6 у фармаце CIDR (прыкладам, 2000:dd::23/64) + Увядзіце адрас/маску падсеткі IPv4 у фармаце CIDR (прыкладам, 1.2.3.4/24) + Адрас IPv4 + Адрас IPv6 + Увядзіце дадатковыя параметры OpenVPN. Выкарыстоўвайце гэту магчымасць з вялікай асцярожнасцю. Калі вы лічыце, што адсутнічае важны параметр, звяжыцеся з аўтарам + Імя карыстача + Пароль + Для канфігурацыі са статычнымі сертыфікатамі будуць выкарыстоўвацца ключы TLS + Налада VPN + Дадаць канфігурацыю + Увядзіце назву новай канфігурацыі + Калі ласка, увядзіце ўнікальную назву канфігурацыі + Назва канфігурацыі + Трэба выбраць сертыфікат карыстача + Трэба выбраць сертыфікат ЦС + Памылак не знойдзена + Ошибка в конфигурации + Немагчыма распазнаць IPv4 адрас + Немагчыма распазнаць карыстацкія маршруты + (пакіньце пустым для запыту па вымозе) + Цэтлік OpenVPN + Падключэнне да VPN… + Не знойдзены профіль, азначаны ў цэтліку + Выпадковы прэфікс вузла + Дадае 6 выпадковых знакаў перад іменем хаста + Уключыць карыстацкія параметры + Карыстацкія параметры. Скарыстайце з асцярожнасцю! + Маршрут адхілены Android + Адключыць + Адключыць VPN + ачысціць журнал + Пацверджанне скасавання + Адключыць актыўны VPN/скасаваць спробу падключэння? + Выдаліць VPN + Правярае, ці выкарыстоўвае сервер сертыфікат з сервернымі пашырэннямі TLS (--remote-cert-tls server) + Чакаць серверны сертыфікат TLS + Праверка DN аб\'екта падаленага сертыфіката + Праверка імя хаста сертыфіката + Увядзіце значэнне для праверкі 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 + Аб\'ект падаленага сертыфіката + Уключыць аўтэнтыфікацыю па TLS ключу + Файл аўтэнтыфікацыі TLS + Запыт IP-адраса, маршрутаў і параметраў ад сервера. + Ігнараваць усе параметры сервера. Параметры павінны быць азначаны ніжэй. + Запытваць параметры + DNS + Перавызначыць параметры DNS ад сервера + Выкарыстоўваць вашы DNS + Дамен пошуку + DNS-сервер для выкарыстання. + DNS-сервер + Другасны DNS-сервер выкарыстоўваецца, калі не атрыманы адказ ад першага сервера DNS. + Рэзервовы сервер DNS + Ігнараваць пасыланыя маршруты + Ігнараваць маршруты, пасыланыя серверам. + Перанакіроўвае ўвесь трафік праз VPN + Выкарыстоўваць маршрут па змаўчанні + Увядзіце карыстальніцкія маршруты. Скарыстайце толькі адрас прызначэння ў фармаце CIDR. \"10.0.0.0/8 2002::/16\" скіруе сеткі 10.0.0.0/8 і 2002::/16 праз VPN. + Маршруты, якія НЕ павінны скіроўвацца праз VPN. Скарыстайце той жа сінтаксіс, што і для ўключаных маршрутаў. + Карыстальніцкія маршруты + Вынятыя сеткі + Ровень дэталізацыі журнала + Разрешить аутентифицированные пакеты с любого IP-адреса + Дазволіць «плавальны» сервер + Карыстальніцкія параметры + Рэдагаванне параметраў VPN + Выдаліць профіль VPN «%s»? + На некаторых кастамных зборках права на /dev/tun могуць быць няправільнымі ці tun-модуль можа быць не ўключаны. Для прашыўкі CM9 можаце паспрабаваць выправіць уладальніка проста з налад праграмы + Не атрымоўваецца адкрыць tun інтэрфейс + "Памылка: " + Ачысціць + Адкрыццё tun-інтэрфейсу: + Адрас IPv4: %1$s/%2$d IPv6: %3$s MTU: %4$d + DNS-сервер: %1$s, Дамен: %2$s + Маршруты: %1$s %2$s + Вынятыя маршруты: %1$s %2$s + Падлучаныя маршруты сэрвісу Vpn: %1$s %2$s + Атрымана інфармацыя інтэрфейсу %1$s і %2$s, другі адрас з\'яўляецца падаленым адрасам канала. Выкарыстоўваецца сеткавая маска /32 для лакальнага IP адраса. Рэжым, усталяваны OpenVPN: \"%3$s\". + Немагчыма скарыстаць выразы %1$s і %2$s як маршрут па стандарце CIDR. выкарыстоўваецца /32 як маска падсеткі. + Маршрут выпраўлены з %1$s/%2$s на %3$s/%2$s + Не атрымоўваецца атрымаць доступ да сховішча ключоў і сертыфікатаў Android. Гэта можа быць выклікана абнаўленнем прашыўкі ці аднаўлення старой копіі дадатку ці яго налад. Калі ласка, адрэдагуйце профіль VPN і наноў пакажыце ключы і сертыфікаты ў падзеле Асноўныя параметры. + %1$s %2$s + Адправіць файл журнала + Адправіць + ICS OpenVPN лог файл + Запіс журнала скапіяваны ў буфер абмену + Рэжым TAP + Рэжым TAP немагчымы на прыладах без root-а. Таму гэты дадатак не падтрымвае TAP + Ізноў? Вы здзекуецеся? Не падтрымваецца рэжым TAP і просьбы да аўтара пра гэта не дапамогуць яму рэалізавацца. + Трэці раз? Насамрэч можна было б пісаць эмулятар TAP, заснаваныя на tun, які б дадаваў інфармацыю 2 роўні пры адпраўленні і здабываў бы яе пры атрыманні. Але гэты эмулятар запатрабуе таксама ARP і, магчыма, кліента DHCP. Я не ведаю нікога, хто мог бы гэтым заняцца. Звяжыцеся са мной, калі вы хочаце заняцца гэтым. + Пытанні і адказы + Капіяванне запісамі журнала + Для капіявання аднаго запісу журнала трэба нажаць на яе і ўтрымваць. Каб скапіяваць/адправіць увесь файл журнала, скарыстайце опцыю «Адправіць файл журнала». Калі яна ўтоена, скарыстайце апаратную кнопку меню. + Цэтлік для запуску + Вы можаце стварыць цэтлік для запуску OpenVPN на працоўным стале. У залежнасці ад вашага асяроддзя трэба дадаць цэтлік ці віджэт. + Ваша прашыўка не падтрымвае VPNService API, прабачыце :( + Шыфраванне + Вызначце метад шыфравання + Вызначце алгарытм шыфрацыі, які выкарыстоўваецца OpenVPN. Пакіньце пустым, каб скарыстаць шыфраванне па змаўчанні. + Увядзіце хэш-функцыю для аўтэнтыфікацыі ў OpenVPN. Пакіньце пустым для выкарыстання значэння па змаўчанні. + Аўтэнтыфікацыя/шыфраванне + Агляд файлаў + Убудаваны файл + Памылка імпарту файла + Не атрымалася імпартаваць файл з файлавай сістэмы + [[Убудаваны файл дадзеных]] + Адмова ў адкрыцці прылады tun без інфармацыі пра IP-адрас + Імпарт канфігурацыі з файла .ovpn + Імпарт + Не атрымалася прачытаць канфігурацыю для імпарту + Памылка чытання файла канфігурацыі + Дадаць канфігурацыю + Не атрымалася знайсці файл %1$s, азначаны ў файле канфігурацыі + Імпарт файла канфігурацыі з зыходнага %1$s + Ваша канфігурацыя мела некалькі параметраў, якія не ўваходзяць у параметры стандартнай канфігурацыі. Гэтыя параметры былі вынесены ў карыстацкую канфігурацыю. Карыстацкая канфігурацыя адлюстроўваецца ніжэй: + Файл канфігурацыі паспяхова прачытаны. + Не прывязвацца да лакальнага адраса і порта + Не выкарыстоўваць прывязкі + Імпарт файла канфігурацыі + Меркаванні бяспекі + "Калі OpenVPN адчувальны да бяспекі, то дарэчныя будуць некалькі заўваг на яе рахунак. Усе дадзеныя на SD-карце ў існасці не абаронены. Кожны дадатак можа прачытаць іх (прыкладам, гэта праграма не патрабуе адмысловых прывілеяў на SD-карту). Дадзеныя гэтага дадатку могуць быць прачытаны толькі ім самім. Пры выкарыстанні опцыі імпарту сертыфікатаў і ключоў у дыялогавым акне дадзеныя захоўваюцца ў профілі VPN. Профілі VPN даступныя толькі гэтаму дадатку. (Не забудзьцеся потым выдаліць копіі на SD-карце). Нягледзячы на тое, што дадзеныя даступныя толькі гэтаму дадатку, яны ўсё яшчэ не зашыфраваны. Пры наяўнасці праў адміністратара (root) на тэлефоне ці праз нейкую ўразлівасць гэтыя дадзеныя можна выняць. Таксама захаваныя паролі захоўваюцца ў звычайным тэкставым выглядзе. Настойліва рэкамендуецца файлы pkcs12 імпартаваць у android keystore." + Імпарт + Памылка адлюстравання выбару сертыфіката + Адбылася памылка пры спробе выкліку сістэмнага дыялогу выбару сертыфікатаў Android 4.0+. Гэтага не павінна было здарыцца на стандартнай прашыўцы. Можа быць у вашай прашыўцы сапсавана сховішча сертыфікатаў + IPv4 + IPv6 + Чаканне паведамлення пра стан… + імпартаваны профіль + імпартаваны профіль %d + Зламаныя прашыўкі + <p> Вядома, што афіцыйныя прашыўкі HTC маюць дзіўныя праблемы з маршрутызацыяй, што прыводзіць да таго, што трафік не ідзе праз тунэль (гл. <a href=\"https://github.com/schwabe/ics-openvpn/issues/18\">Issue 18</a> у баг-трэкеры).</p><p>Таксама паведамлялася, што ў старых афіцыйных прашыўках SONY ад Xperia Arc S і Xperia Ray цалкам адсутнічае сэрвіс VPNService (гл. <a href=\"https://github.com/schwabe/ics-openvpn/issues/29\">Issue 29</a> у баг-трэкеры).</p><p>У некаторых неафіцыйных прашыўках модуль tun можа адсутнічаць, ці файл прылады /dev/tun можа мець няправільныя правы. Некаторыя прашыўкі CM9 могуць патрабаваць выпраўленні праў на /dev/tun у наладах «Хакі для дадзенай прылады».</p><p>І самае галоўнае: калі ў вас прашыўка з паказанымі праблемамі, паведаміце пра гэта вытворцу прылады. Чым больш за карыстачоў паведаміць пра праблему, тым больш за шанцы, што вытворца яе выправіць.</p> + Файл PKCS12-ключа + Пароль закрытага ключа + Пароль + файл значка + Аўтэнтыфікацыя/шыфраванне TLS + Згенераваная канфігурацыя + Налады + Паспрабаваць змяніць уладальніка для /dev/tun. Некаторыя прашыўкі CM9 патрабуюць гэтага для карэктнай працы API OpenVPN. Патрабуецца root. + Выправіць правы для /dev/tun + Паказаць згенераваны файл канфігурацыі OpenVPN + Праўка «%s» + Стварэнне канфігурацыі… + Перападлучацца, калі змяняецца стан сеткі (прыкладам, пры пераключэнні з Wi-Fi на мабільную і наадварот) + Перападлучацца, калі змяняецца стан сеткі (прыкладам, пры пераключэнні з Wi-Fi на мабільную і наадварот) + Статус сеткі: %s + Сертыфікат ЦС звычайна захоўваецца ў Android Keystore. Вызначце асобны сертыфікат, калі ў вас паўсталі абмылы пры праверцы сертыфіката. + Выбраць + Не атрымалася атрымаць сертыфікат ЦС са сховішча ключоў Android. Напэўна, аўтэнтыфікацыя завершыцца абмылай. + Паказвае акно журнала пры падлучэнні. Акно журнала заўсёды даступнае з панэлі апавяшчэнняў. + Паказаць акно журнала + %10$s %9$s працуе на %3$s %1$s (%2$s), Android %6$s (%7$s) API %4$d, ABI %5$s, (%8$s) + Памылка подпісу з выкарыстаннем ключа са сховішча Android %1$s: %2$s + Папярэджанне VPN злучэння, што гаворыць, што гэты дадатак можа перахапляць увесь сеткавы трафік, паказваецца сістэмай для прадухілення злоўжывання API VPNService.\nАпавяшчэнне пра VPN злучэнні (знак ключа) таксама фармуецца сістэмай Android для сігналізацыі выходнага VPN злучэння. У некаторых прашыўках гэта апавяшчэнне суправаджаецца гукам.\nAndroid выкарыстоўвае гэтыя сістэмныя апавяшчэнні для вашай жа ўласнай бяспекі і іх няможна абысці. (На жаль, на некаторых прашыўках гэта ставіцца і да гуку апавяшчэння) + Паведамленне пра падлучэнне і гук апавяшчэння + Беларускі пераклад ад MikalaiB <bregid69@gmail.com> + IP-адрас і DNS + Асноўныя + Маршрутызацыя + Утоеныя параметры OpenVPN. Звычайна не патрабуюцца. + Пашыраныя + ICS Openvpn канфігурацыя + Серверы DNS не выкарыстоўваюцца. Дазвол імёнаў можа не працаваць. Разгледзіце магчымасць усталёўкі карыстацкіх DNS-сервераў. Таксама звернеце ўвагу, што Android будзе працягваць скарыстаць параметры, паказаныя для вашага мабільнага/Wi-Fi злучэння, калі не азначаны DNS-серверы. + Не атрымалася дадаць DNS-сервер «%1$s», адхілены сістэмай: %2$s + Не атрымалася наладзіць IP-адрас «%1$s», адхілены сістэмай: %2$s + <p>Скарыстайце гатовую канфігурацыю (пратэставаную на вашым кампутары ці атрыманую ад вашага правайдара)</p><p>Калі гэта прастой файл без pem/pkcs12, вы можаце адправіць яго як укладанне па электроннай пошце на сваю прыладу. Калі ж файлаў некалькі, вы можаце скарыстаць іх са сваёй карты памяці.</p><p>Проста адкрыйце .conf файл ці выберыце яго ў дыялогу імпарту (значок тэчкі ў спісе профіляў)</p><p>Калі праграма выдасць памылку пра нястачу некаторых файлаў, проста змесціце гэтыя файлы на карту памяці.</p><p>Націсніце кнопку захавання для дадання імпартаванай канфігурацыі ў праграму</p><p>Запусціце ваш VPN-тунэль, нажаўшы на яго назву ў спісе</p><p>Калі пры запуску выніклі памылкі, паспрабуйце разабрацца і ўхіліць іх.</p> + Хуткі старт + Паспрабуйце загрузіць модуль ядра tun.ko, Перад тым як спрабаваць падлучыцца. Патрабуецца root-доступ на прыладзе. + Загрузіць tun-модуль + Імпарт PKCS12 са сховішча ключоў Android + Памылка пры атрыманні параметраў проксі-сервера: %s + Выкарыстоўваецца проксі-сервер %1$s %2$s + Выкарыстоўваць проксі-сервер сістэмы + Выкарыстоўваць сістэмную канфігурацыю проксі HTTP/HTTPS для злучэння. + OpenVPN будзе падключацца да паказанага VPN, калі ён быў актыўны пры загрузцы сістэмы. Калі ласка, прачытайце FAQ пра папярэджанне пры падлучэнні перад тым, як скарыстаць гэту опцыю на Android < 5.0. + Падключэнне пры загрузцы + Ігнараваць + Перазапуск + Змены канфігурацыі ўжываюцца пасля перазапуску VPN. (Пера)запусціць VPN цяпер? + Канфігурацыя зменена + Не атрымалася вызначыць апошні карыстаны профіль для рэдагавання + Апавяшчэнні што дублююцца + Калі ў Android узнікае нястача аператыўнай памяці (RAM), непатрэбныя службы і дадаткі спыняюцца. З-за гэтага перапыняецца ўсталяванае VPN-злучэнне. Каб пазбегнуць гэтага, дадатак трэба запускаць з падвышаным прыярытэтам. Для запуску з высокім прыярытэтам дадатак павінен вывесці апавяшчэнне. Значок ключа паказваецца наверсе панэлі апавяшчэнняў самай сістэмай, як апісана ў папярэднім пытанні. Ён не лічыцца тым апавяшчэннем, якое дадатку патрэбна для запуску з высокім прыярытэтам. + Профілі VPN не азначаны. + Выкарыстоўвайце значок <img src=\"ic_menu_add\"/> для дадання новага VPN + Скарыстайце кнопку <img src=\"ic_menu_archive\"/> для імпарту існавалых профіляў (.ovpn ці .conf) з карты памяці. + Не забудзьцеся зазірнуць у FAQ. Там ёсць кароткае кіраўніцтва. + Конфигурация маршрутизации/интерфейса + Канфігурацыя маршрутызацыі і інтэрфейсу вырабляецца не праз традыцыйныя ifconfig/route каманды, а з дапамогай VPNService API. Гэта прыводзіць да стварэння іншай канфігурацыі маршрутызацыі, адрознай ад канфігурацый, што выкарыстоўваюцца на іншых АС. Канфігурацыя VPN-тунэля складаецца з IP-адрасоў і сетак, якія павінны скіроўвацца праз гэты інтэрфейс. Ніякіх адменных партнёрскіх адрасоў ці адрасоў шлюза не патрабуецца. Таксама не патрабуюцца і адмысловыя маршруты для злучэння з VPN-серверам (прыкладам, дададзеныя пры выкарыстанні redirect-gateway). Такім чынам, дадатак будзе ігнараваць гэтыя параметры пры імпарце канфігурацыі. Дадатак з дапамогай VPNService API гарантуе, што падлучэнне да сервера не скіроўваецца праз VPN-тунэль. Падтрымліваецца кірунак праз тунэль толькі пэўных сетак. Дадатак спрабуе вызначыць сеткі, якія не павінны быць скіраваны праз тунэль (прыкладам, маршрут x.x.x.x y.y.y.y net_gateway) і вылічае спіс маршрутаў, у які не ўлучаюцца гэтыя маршруты, каб эмуляваць паводзіны іншых платформаў. Вокны журналаў і логаваў паказваюць канфігурацыю сэрвісу VPN пасля ўсталявання злучэння. + Не выкарыстоўваць звычайнае злучэнне без VPN пры перападлучэнні OpenVPN. + Заўсёдны tun + Журнал OpenVPN + Імпарт канфігурацыі OpenVPN + Спажыванне батарэі + У маіх тэстах галоўнай крыніцай высокага спажывання электраэнергіі батарэі былі пакеты keepalive. Большасць OpenVPN-сервераў утрымваюць дырэктыву накшталт «keepalive 10 60», якая прымушае кліент і сервер мяняцца keepalive-пакетамі кожныя 10 секундаў. <p> Хоць гэтыя пакеты і маленькія, і не расходуюць шмат трафіка, яны прымушаюць радыёмодуль увесь час працаваць, што павялічвае выдатак энергіі. (гл. <a href=\"http://developer.android.com/training/efficient-downloads/efficient-network-access.html#RadioStateMachine\">The Radio State Machine | Android Developers</a>) <p> Налады keepalive не могуць быць зменены на кліенту, гэта можа зрабіць толькі сістэмны адміністратар OpenVPN. <p> На жаль, выкарыстанне keepalive больш, чым 60 секундаў з UDP, можа прывесці да таго, што некаторыя шлюзы NAT будуць абрываць злучэнне з-за адсутнасці актыўнасці. Выкарыстанне TCP з вялікім keepalive-таймаўтам будзе працаваць, але прадукцыйнасць тунэлявання TCP праз TCP у сетках з высокімі стратамі пакетаў вельмі нізкая (гл. <a href=\"http://sites.inka.de/bigred/devel/tcp-tcp.html\">Why TCP Over TCP Is A Bad Idea</a>) + Функцыя тэтэрынгу Android (праз WiFi, USB ці Bluetooth) і VPNService API (карыстанае гэтай праграмай) не працуюць разам. Падрабязней у <a href=\"https://github.com/schwabe/ics-openvpn/issues/34\">праблеме №34</a> + VPN и Tethering + Спробы падлучэння + Параметры перападлучэння + Колькасць секундаў паміж спробамі падлучэння. + Секундаў паміж злучэннямі + OpenVPN завяршылася нечакана. Калі ласка, пагледзіце опцыю \"Адправіць Minidump\" у галоўным меню + Адправіць Minidump распрацоўніку + Адпраўленне адладкавай інфармацыі распрацоўніку пра апошняе аварыйнае завяршэнне + OpenVPN - %s + %1$s - %2$s + %1$s - %3$s, %2$s + Падключэнне + Чаканне адказу сервера + Праверка сапраўднасці + Атрыманне канфігурацыі кліента + Прызначэнне IP-адрасоў + Даданне маршрутаў + Падлучана + Адключыцца + Паўторнае падлучэнне + Выйсце + Не запушчана + Дазвол імёнаў вузлоў + Падключэнне (TCP) + Памылка аўтэнтыфікацыі + Чаканне працы сеткі + ↓%2$s %1$s - ↑%4$s %3$s + Раз\'яднана + Подключение к VPN %s + Падключэнне да VPN %s + У некаторых версіях Android 4.1 ёсць праблемы, калі імя сертыфіката ўтрымвае не літарна-лічбавыя знакі (прыкладам, прабелы, падкрэсленні ці працяжнік). Паспрабуйце пераўсталяваць сертыфікат без выкарыстання адмысловых знакаў. + Алгарытм шыфравання + Праверка сапраўднасці пакетаў + Вызначце метад праверкі сапраўднасці пакетаў + создан %s + зборка для адладкі + афіцыйная зборка + Скапіяваць у профіль + Справаздача пра паданне + Дадаць + Адправіць канфігурацыйны файл + Поўнае DN + Імпартаваная канфігурацыя выкарыстоўвае САСТАРЭЛУЮ опцыю tls-remote, якая мае іншы фармат DN. + RDN (поўнае імя) + Прэфікс RDN + tls-remote (САСТАРЭЛАЕ) + Вы можаце палепшыць пераклад, наведаўшы http://crowdin.net/project/ics-openvpn/invite + %1$s спрабуе кіраваць %2$s + Працягваючы, вы даяце дадатку права на кіраванне \"OpenVPN для Android\" і перахоп усяго сеткавага трафіка. Не працягвайце, калі не давяраеце цалкам гэтаму дадатку. У адваротным выпадку вы рызыкуеце збегам і выкарыстаннем вашых дадзеных злачынцамі. + Я давяраю гэтаму дадатку. + Нет приложений, авторизованных для внешнего API + Дазволеныя дадаткі: %s + Ачысціць спіс аўтарызаваных вонкавых дадаткаў?\nСпіс дазволеных дадаткаў:\n\n%s + Приостанавливать VPN, если экран выключен и передано меньше 64kb данных за 60 сек. Когда включена опция \"Постоянный туннель\", приостановка VPN оставит ваше устройство без сетевого подключения. Без опции \"Постоянный туннель\" устройство не будет иметь VPN-соединения/защиты. + Прыпыніць VPN-злучэнне пры вымкнутым экране + Прыпыненне злучэння пры вымкнутым экране: менш, чым %1$s за %2$sс + Увага: Заўсёдны тунэль не ўключаны для гэтага VPN. Трафік будзе скарыстаць звычайнае інтэрнэт злучэнне, калі экран вымкнуты. + Захаваць пароль + Прыпыніць VPN + Працягнуць VPN + VPN прыпынены па запыце карыстача + VPN прыпынены - вымк. экран + Хакі для дадзенай прылады + Не атрымоўваецца адлюстраваць звесткі пра сертыфікат + Паводзіны дадатку + Паводзіны VPN + Дазволіць змену профіляў VPN + Апаратнае сховішча ключоў: + Абразок дадатку спрабуе скарыстаць OpenVPN для Android + "Пачынаючы з Android 4.3, дыялог пацверджання VPN-злучэння абаронены ад дадаткаў, «што накладаюцца паўзверх экрана». Гэта прыводзіць да таго, што дыялогавае акно пацверджання не рэагуе на сэнсорныя націскі. Калі вам трапіцца дадатак, што выкарыстоўвае накладанні і выклікае такія паводзіны, звяжыцеся з аўтарам гэтага дадаткі. Гэта праблема закранае ўсе VPN дадаткі на Android 4.3 і пазнейшых версіях. Гледзіце таксама <a href=\"https://github.com/schwabe/ics-openvpn/issues/185\">Issue 185<a> для атрымання дадатковых звестак" + Акно пацверджання VPN для Android 4.3 і пазней + Таксама Вы можаце выказаць падзяку ў выглядзе ахвяравання на Краме Play: + Дзякуй за ахвяраванне %s! + Журнал вычышчаны. + Паказаць пароль + памылка пры доступе да сховішча ключоў: %s + Коратка + ISO + Час + Не + Выгружана + Загружана + Статус VPN + Налады выгляду + Неапазнаная памылка: %1$s\n\n%2$s + %3$s: %1$s\n\n%2$s + Калі на вашай прыладзе ёсць root, можаце ўсталяваць <a href=\"http://xposed.info/\">Xposed framework</a> і <a href=\"http://repo.xposed.info/module/de.blinkt.vpndialogxposed\">модуль аўтаматычнага пацверджання дыялогу падлучэння VPN</a> на свой страх і рызык + Поўныя тэксты ліцэнзій + Сеткі, даступныя наўпрост праз лакальны інтэрфейс, не будуць маршрутызаваны праз VPN. Адключыце гэту опцыю, каб скіраваць трафік праз VPN. + Не выкарыстоўваць VPN для лакальных адрасоў + Файл логіна і пароля + [Імпартавана з: %s] + Некоторые файлы не найдены. Выберите файлы для импорта в профиль: + Для выкарыстання дадзенага дадатку патрэбен правайдар/шлюз VPN, што падтрымвае OpenVPN (часта падаецца працадаўцам). На http://community.openvpn.net/ можна знайсці інфармацыю пра OpenVPN і як наладзіць уласны сервер OpenVPN. + Лог імпарту: + Указана тапалогія VPN «%3$s», але ifconfig %1$s %2$s больш падобна на IP-адрас з маскай сеткі. Выкарыстоўваецца тапалогія «падсетка». + Значэнне, што перазапісвае MSS, павінна быць цэлым лікам ад 0 да 9000 + Значэнне, пяравызначальнае MTU, павінна быць цэлым лікам ад 64 да 9000 + Абвясціць TCP сесіям, што працуюць праз тунэль, што яны павінны абмежаваць памер сваіх пакетаў так, каб пасля іх інкапсуляцыі OpenVPN выніковы памер UDP-пакета, які OpenVPN пасылае сваім балям, не перавышаў гэты лік байт. (1450 па змаўчанні) + Перавызначыць MSS для нагрузкі TCP + Задаць MSS для нагрузкі TCP + Паводзіны кліента + Ачысціць дазволеныя знешнія дадаткі + Загружаецца… + Дазволеныя дадаткі VPN: %1$s + Забароненыя дадаткі VPN: %1$s + Пакет %s больш не ўсталяваны, ён падаляецца са спіса дазволеных/забароненых дадаткаў + Выкарыстоўваць VPN для ўсіх дадаткаў, апроч абраных + Выкарыстоўваць VPN толькі для абраных дадаткаў + Прыбраць запіс выдаленага сервера? + Захаваць + Выдаліць + Дадаць новую падаленку + Выкарыстоўваць спіс падлучэнняў у выпадковым парадку пры злучэнні + Вы павінны вызначыць і ўключыць прынамсі адзін выдалены сервер. + Спіс сервераў + Дазволеныя дадаткі + Пашыраныя налады + Налады карыснай нагрузкі + Налады TLS + Няма зададзенай падаленкі + Дубляваць профіль VPN + Дубляванне профілю: %s + Паказаць акно журнала + Існуюць розныя кліенты OpenVPN для Android. Самыя пашыраныя — OpenVPN для Android (гэты кліент), OpenVPN Connect і OpenVPN Settings.<p>Кліенты можна падзяліць на дзве групы: OpenVPN для Android і OpenVPN Connect скарыстаюць афіцыйны VPNService API (Android 4.0+) і не патрабуюць root-доступ, і OpenVPN Settings, які патрабуе root.<p>OpenVPN для Android — кліент з адкрытым зыходным кодам, які распрацаваў Arne Schwabe. Ён прызначаны для больш за доследных карыстачоў і падае шмат налад, магчымасць імпарту профіляў з файлаў і наладжваць/змяняць профілі ўсярэдзіне дадатку. Гэты кліент заснаваны на грамадскай версіі OpenVPN. А менавіта на выточным кодзе OpenVPN 2.x. Гэты кліент можна ўявіць як напаўафіцыйны кліент супольнасці. <p>OpenVPN Connect — кліент з зачыненым зыходным кодам, які распрацоўваецца OpenVPN Technologies, Inc. Ён закліканы для звычайнага выкарыстання і прызначаны для простых карыстачоў, і дазваляе імпартаваць профілі з OpenVPN. Гэты кліент заснаваны на OpenVPN C++, іншай рэалізацыі пратакола OpenVPN (Гэта запатрабавалася OpenVPN Technologies, Inc, каб апублікаваць дадатак OpenVPN на iOS). Гэты кліент — афіцыйны кліент OpenVPN technologies <p> OpenVPN Settings — найстары з кліентаў, ён таксама UI для OpenVPN з адкрытым зыходным кодам. У адрозненне ад OpenVPN для Android, ён патрабуе root-правы і не выкарыстоўвае VPNService API. Ён не залежыць ад Android 4.0+ + Адрозненні паміж кліентамі OpenVPN для Android + Ігнаруецца мультыадрасны маршрут: %s + Android падтрымвае толькі CIDR маршруты да VPN. Бо не CIDR маршруты амаль ніколі не выкарыстоўваюцца, OpenVPN для Android будзе выкарыстоўваць /32 для не CIDR маршрутаў і выдаваць папярэджанне. + Тэтэрынг/раздача інтэрнэту працуе, калі актыўны VPN. Мадэмнае злучэнне (тэтэрынг) НЕ БУДЗЕ выкарыстоўваць VPN. + Раннія версіі KitKat усталёўваюць няслушнае значэнне MSS для TCP злучэнняў (#61948). Паспрабуйце ўключыць опцыю mssfix, каб абысці гэты баг. + Android будзе працягваць скарыстаць вашы налады проксі, паказаныя для мабільнага/Wi-Fi злучэння, калі не ўсталяваны DNS сервер. OpenVPN для Android папярэдзіць вас пра гэта ў журнале.

Калі VPN усталёўвае DNS сервер Android не выкарыстоўвае проксі. Для ўсталёўкі проксі для VPN злучэння няма API.

+ Приложения VPN могут перестать работать после удаления и повторной установки. Подробности см. #80074 + Сканфігураваны IP-адрас кліента і IP-адраса ў яго падсеткі (паводле сеткавай маскі) не скіроўваюцца праз VPN. OpenVPN абыходзіць гэты баг, відавочна дадаючы маршрут, які адпавядае кліенцкаму IP і яго сеткавай масцы + Адкрыццё тунэля, калі тунэль ужо актыўны, для яго нязменнага ўтрымання, можа прывесці да памылкі і VPNServices зачыніцца на прыладзе. Для аднаўлення працы VPN патрабуецца перазагрузка. OpenVPN для Android спрабуе ўнікнуць усталёўкі другога тунэля, і калі сапраўды патрэбна - спачатку зачыняе бягучы тунэль, перад адкрыццём новага, каб пазбегнуць краху праграмы. Гэта можа прывесці да маленькага інтэрвалу, у якім перадача пакетаў адбываецца па звычайным (не VPN) злучэнню. Нават з гэтымі хітрыкамі VPNServices часам падае і патрабуе перазагрузкі прылады. + VPN зусім не працуе для другасных карыстачоў. + "Розныя карыстачы паведамляюць, што мабільная сувязь/мабільная перадача дадзеных часта абрываецца, калі выкарыстоўваецца VPN дадатак. Такія паводзіны, здаецца, закранае толькі некаторыя камбінацыі правайдараў/прылад, і пакуль што не выяўлена прычына/няма абыходу гэтага бага." + Адрасы могуць працаваць праз VPN толькі тыя, што даступныя без VPN. IPv6 VPN не працуюць зусім. + Не CIDR маршруты + Паводзіны проксі для VPN + Пераўсталяванне дадаткаў VPN + %s і раней + Копія %s + Маршрут для ўсталяванага IP-адраса + Няслушнае значэнне MSS для VPN злучэння + Дадатковыя карыстачы прылады + Вызначце асаблівыя карыстальніцкія параметры падключэння. Выкарыстоўвайце з асцярожнасцю + Карыстальніцкія параметры + Выдаліць запіс падключэння + Выпадковыя адключэнні ад мабільнай сеткі + Падаленыя сеткі недаступныя + Прымусовы рэжым tun + %s і вышэй + Няўдалае злучэнне з SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure + Новыя версіі 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-кліент. + Дадзены профіль быў дададзены з вонкавага дадатку (%s) і быў адзначаны як непрыдатны да рэдагавання карыстачамі. + Спіс адкліканых сертыфікатаў + Перазапуск сэрвісу OpenVPN (Дадатак, напэўна, упаў ці быў зачынена з-за нястачы памяці) + Імпартаванне канфігурацыі прывяло да памылкі, немагчыма захаваць змены + Пошук + (Апошні дамп створаны %1$d г. і %2$d х. назад (%3$s)) + Чысціць журнал пры новым злучэнні + Час чакання злучэння + Не дададзена дазволеных дадаткаў. Дадаём сябе (%s), каб у спісе дазволеных дадаткаў быў хоць бы адзін дадатак, інакш усе дадаткі дададуцца ў спіс дазволеных + OpenVPN для Android можа паспрабаваць знайсці адсутныя файлы на SD-карце аўтаматычна. Націсніце на гэта паведамленне, каб атрымаць запыт на дазвол. + Пратакол + Уключана + Preferred native ABI precedence of this device (%1$s) and ABI reported by native libraries (%2$s) mismatch + Дазвол VPN адкліканы АС (прыкладам, запушчана іншая праграма VPN), спыняем VPN + Адправіць інфармацыю пра ўдзельніка + Адправіць дадатковую інфармацыю на сервер, прыкладам, версію SSL і версію Android + Патрабуецца %1$s + Калі ласка, увядзіце пароль для профілю %1$s + Ужыць убудаваныя дадзеныя + Экспарт файла канфігурацыі + файл tls-auth адсутнічае + Адсутнічае сертыфікат карыстача ці файл ключа сертыфіката карыстача + Отсутствует сертификат ЦС + Спіс адкліканых сертыфікатаў (апцыянальна) + Перачытаць (%d) элементаў лога з файла кэша лога + Нават нягледзячы на тое, што тэлефоны Samsung з\'яўляюцца аднымі з найболей прадаваных тэлефонаў на Android, прашыўкі Samsung таксама з\'яўляюцца і найболей праблемнымі прашыўкамі на Android. Памылкі не абмяжоўваюцца толькі працай VPN на гэтых прыладах, але многія з іх можна абысці. Далей апісаны некаторыя з гэтых памылкаў.\n\nDNS не працуе, калі сервер DNS не ў дыяпазоне VPN.\n\nНа многіх прыладах Samsung 5.x функцыя дазволеных/забароненых дадаткаў не працуе.\nНа Samsung 6.x, як паведамляецца, VPN не працуе, пакуль дадатку VPN не дазволена не эканоміць зарад батарэі. + Тэлефоны Samsung + Не абрана VPN. + VPN па змаўчанні + VPN, які будзе выкарыстоўвацца па змаўчанні, калі гэта патрэбна. А менавіта, пры загрузцы, для «Нязменнай VPN» і для перамыкача ў «Хуткіх наладах». + У гэты час абраны VPN: \'%s\' + Перадалучыць + Пераключэнне VPN + Падлучыцца да %s + Адключыцца ад %s + Увядзіце максімальны час паміж спробамі злучэння. OpenVPN будзе павольна падымаць свой час чакання пасля няўдалай спробы падлучэння да гэтага значэння. Па змаўчанні 300 сек. + Максімальны час паміж спробамі злучэння + Чаканне %ss секундаў паміж спробай падлучэння + (Сеткі) Яшчэ -> VPN]]> + Падключэнне да OpenVPN зачынена (%s) + Змяніць сартаванне + Сартаваць + Профілі адсартаваны па парадку апошняга выкарыстання + Профілі адсартаваны па назве + Файл налады выкарыстоўвае опцыю tls-remote, якая была абвешчана састарэлай у версіі 2.3 і канчаткова выдалена ў версіі 2.4 + Паводзіны пры AUTH_FAILED + Графік + Выкарыстоўваць лагарыфмічную шкалу + Недастаткова дадзеных + У сярэднім за гадзіну + У сярэднім за хвіліну + Апошнія 5 хвілін + Уваходны + Выходны + %.0f біт/с + %.1f Кбіт/с + %.1f Мбіт/с + %.1f Гбіт/с + <p> Пачынаючы з OpenSSL версіі 1.1, OpenSSL адхіляе слабыя подпісы ў такіх сертыфікатах, як MD5.</p><p><b>MD5, подпісы цалкам небяспечныя і больш не павінны выкарыстоўвацца.</b> Сутыкненні MD5 могуць быць створаны ў <a + href=\"https://natmchugh.blogspot.de/2015/02/create-your-own-md5-collisions.html\"> праз некалькі гадзін з мінімальнымі выдаткамі.</a>. Вы павінны як мага хутчэй абнавіць сертыфікаты VPN. </p><p>На жаль, старыя дыстрыбутывы easy-rsa улучалі опцыю канфігурацыі «default_md md5». Калі вы скарыстаеце старую версію easy-rsa, абновіце яе да <a href=\"https://github.com/OpenVPN/easy-rsa/releases\">latest версіі</a>) ці зменіце md5 на sha256 і адновіце свае сертыфікаты.</p><p>Калі вы сапраўды хочаце скарыстаць старыя і пашкоджаныя сертыфікаты, скарыстайце наладжвальны параметр канфігурацыі tls-cipher «DEFAULT: @SECLEVEL = 0 \"у пашыранай канфігурацыі ці ў якасці дадатковага радка ў вашай імпартаванай канфігурацыі</p> + %.0f Б + %.1f КБ + %.1f МБ + %.1f ГБ + Статыстыка падключэння + Бягучая статыстыка ўсталяванага злучэння OpenVPN + Изменение статуса соединения + Змены стану злучэння OpenVPN (падлучэнне, аўтэнтыфікацыя,...) + Слабыя (MD5) хэшы ў сігнатуры сертыфіката (SSL_CTX_use_certificate md занадта слабы) + Тэст хуткасці OpenSSL + Імёны шыфраў OpenSSL + Тэст хуткасці OpenSSL Crypto + OpenSSL вярнуў памылку + Запуск тэсту… + Тэставанне абраных алгарытмаў + Вонкавы дадатак спрабуе кантраляваць %s. Дадатак, што запытвае доступ, не можа быць вызначаны. Дазвол гэтага дадатку падае доступ усім дадаткам. + Рэалізацыя OpenVPN 3 C ++ не падтрымвае статычныя ключы. Перайдзіце ў OpenVPN 2.x пад агульныя налады. + Выкарыстанне файлаў PKCS12 наўпрост з дапамогай OpenVPN 3 C ++ не падтрымваецца. Імпартуйце файлы pkcs12 у сховішча ключоў Android ці заменіце OpenVPN 2.x на агульныя налады. + Проксі + Нічога + Tor (Orbot) +
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 @@ Ruting Avançat Inici rapid - Utilitzant el proxy %1$s %2$d Utiliza el proxy del sistema Ignorar Reinicia 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 @@ Nahrát tun modul Importovat PKCS12 z konfigurace do Andoidího úložiště Chyba při zjišťování nastavení proxy: %s - Používám proxy %1$s %2$d Použít systémovou proxy K připojení použít systémové nastavení pro HTTP/HTTPS. OpenVPN se automaticky připojí k vybrané VPN po startu systému. Prosím věnujte pozornost upozornění ve FAQ pro verzi Android < 5.0. @@ -357,6 +356,8 @@ Dřívější KitKat verze nastavovaly špatnou hodnotu MSS na TCP spojení (#61948). OpenVPN automaticky zapne mssfix možnost pro obejití chyby. Aplikace VPN mohou přestat fungovat po odinstalování a reinstalaci. Podrobnosti najdete v #80074 VPN vůbec nefunguje pro vedlejší uživatele. + "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." + Jediná destinace může být dosažena přes VPN které nejsou dosažitelné bez VPN. Sítě IPv6 nefungují vůbec. Ne-CIDR trasy Proxy chování pro VPN Přeinstalování VPN aplikací @@ -381,6 +382,7 @@ (Poslední výpis je %1$d: %2$dh starý (%3$s)) Vymazat log při novém připojení Časový limit připojení + 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í. Protokol Povoleno Push Peer info @@ -427,4 +429,5 @@ %.1f kB %.1f MB %.1f GB + Tor (Orbot) 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 @@ CA Certifikat Du skal vælge et certifikat Kildekode og fejl tracker findes på http://code.google.com/p/ics-openvpn/ - Dette program bruger følgende komponenter: se kildekoden for alle detaljer om licenserne + Dette program bruger følgende komponenter (se kildekoden for detaljer om licenserne) Om Profiler Type @@ -83,7 +83,7 @@ DNS-server Sekundær DNS-Server som bruges, hvis den normale DNS-serveren ikke kan nås. Backup DNS-server - Ignorer skubbet ruter + Ignorer modtagne routes Ignorer ruter modtaget fra serveren. Omdiriger al trafik over VPN\'en Brug standard Rute @@ -121,7 +121,7 @@ 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. 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. OFTE STILLEDE SPØRGSMÅL - Kopiere logposter + Kopierer log poster 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. Genvej til start 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. @@ -201,7 +201,7 @@ Indlæs tun-modul Importer pkcs12 fra konfigurationen til Android Keystore Fejl under indlæsning af proxy-indstillinger: %s - Anvender proxy %1$s %2$d + Anvender proxy %1$s %2$s Anvend system-proxy Anvend systemets globale konfiguration til forbindelse af HTTP/HTTPS proxy\'er. 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 < 5.0. @@ -279,15 +279,15 @@ Ingen app har lov til at anvende ekstern API Tilladte apps: %s Ryd liste over tilladte eksterne apps?\nNuværende liste over tilladte apps:\n\n%s - 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. - Paus VPN-forbindelse efter skærmen slukkes - Pauser forbindelse i slukket-skræm tilstand: Mindre end %1$s på %2$ss + 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. + Sæt VPN-forbindelsen på pause efter skærmen slukkes + Sæt VPN-forbindelsen på pause i slukket-skræm tilstand: Mindre end %1$s på %2$ss Advarsel: Vedvarende Tun er ikke slået til på denne VPN. Internettrafik vil anvende den normale internetforbindelse når skærmen er slukket. Gem adgangskode - Paus VPN + Pause VPN Genoptag VPN - VPN pausning anmodet af bruger - VPN pauset - Skærmen er slukket + VPN pauset af bruger + VPN-forbindelsen på pause - Skærmen slukket Enheds-specifikke hacks Kan ikke vise certifikatsinformation Program opførsel @@ -315,7 +315,7 @@ Hvis du har rootet din androidenhed kan du installere <a href=\"http://xposed.info/\">Xposed framework</a> og <a href=\"http://repo.xposed.info/module/de.blinkt.vpndialogxposed\">VPN Dialog confirm module</a> på din egen risiko Fulde licenser 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. - Forbipasser VPN for lokale netværk + Undgå brug af VPN for lokale netværk Brugernavn/password fil [Importeret fra: %s] Nogle filer kunne ikke findes. Vælg venligst filerne for at importere profilen: @@ -385,15 +385,81 @@ Genstarter OpenVPN Service (App\'en crashede, den crashede sandsynligvis eller blev stoppet på grund a RAM overbelastning) Import af konfigurationsfilen gav en fejl, kan ikke gemme Søg + (Sidste dump er %1$d:%2$dh gammel (%3$s)) Ryd log ved ny forbindelse Forbindelses-timeout Ingen tilladt app tilføjet. Tilføjer selve appen (%s) for at have mindst én tilladt app, ellers vil alle apps være tilladte 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. Protokol Aktiveret + Preferred native ABI precedence of this device (%1$s) and ABI reported by native libraries (%2$s) mismatch VPN tilladelse tilbagekaldt af styresystemet (f.eks. kan et andet VPN program være startet), stopper VPN + Modtagne Peer info + Send ekstra information til serveren, f.eks. SSL-version og Android-version + Kræver %1$s + Angiv adgangskoden for profil %1$s + Brug inline data + Eksporter konfigurationsfil + tls-auth-filen mangler + Manglende brugercertifikat eller brugercertifikat nøglefil + Manglende CA-certifikat + Certifcate Revoke List (valgfrit) + Genlæse (%d) log-linier fra cache + 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. + Samsung telefoner + Ingen VPN valgt. + Standard VPN + 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. + Aktuelt valgt VPN: \'%s\' + Gentilslutter + Skift VPN + Opret forbindelse til %s + Afbryd %s + 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. + Maksimal tid mellem forbindelsesforsøg + Venter %ssekunder mellem forbindelsesforsøg + Networks more .. -> VPNs]]> + Forbindelse til OpenVPN lukket (%s) + Skift sortering + Sorter + Profiler sorteret efter senest anvendelse + Profiler sorteret efter navn + Konfigurationen bruger \"tls-remote\", understøttelsen af denne er fjernet i 2.4 + Handling ved AUTH_FAILED + Graf + Brug logaritmisk skala + Ikke nok data + Gennemsnit pr. time + Gennemsnit pr. minut + Sidste 5 minutter + Ind + Ud + %.0f bit/s + %.1f kbit/s + %.1f Mbit / s + %.1f Gbit / s + <p>Startende med OpenSSL version 1.1 vil OpenSSL afvise svage signaturer i certifikater som f.eks MD5.</p><p><b>MD5 signaturer er usikre og bør ikke længere anvendes.</b> MD5 sammenfald (collisions) kan fremstilles <a + href=\"https://natmchugh.blogspot.de/2015/02/create-your-own-md5-collisions.html\"> på kort tid uden de store ressourcer.</a>. Du skal opdatere dine VPN-certifikaterne så hurtigt som muligt.</p><p>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 <a href=\"https://github.com/OpenVPN/easy-rsa/releases\">seneste version</a>) eller skifte md5 til sha256 og regenerere dine certifikater.</p><p>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</p> + %.0f B %.1f kB %.1f MB %.1f GB + Forbindelsesstatistik + Løbende statistikker af den etablerede OpenVPN-forbindelse + Forbindelses status ændring + Status ændringer i OpenVPN-forbindelsen (Tilslutning, godkendelse, etc) + Svag (MD5) hashes i certifikat signatur (SSL_CTX_use_certificate md for svag) + OpenSSL Speed ​​Test + OpenSSL cipher navne + OpenSSL Crypto Speed ​​test + OpenSSL returnerede en fejl + Tester ... + Test valgte algoritmer + En ekstern app forsøger at styre %s. Appen, der anmoder om adgang, kan ikke bestemmes. Tillad, at denne app giver ALLE apps adgang. + OpenVPN 3 C ++ implementeringen understøtter ikke statiske nøgler. Venligst skift til OpenVPN 2.x under generelle indstillinger. + 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. + Proxy + Ingen + Tor (Orbot) 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 @@ Tun-Modul laden In der Konfiguration angegebene PKCS12-Datei in den Android-Zertifikatsspeicher importieren Fehler beim Ermitteln der Proxy-Einstellungen: %s - Verwende Proxy %1$s %2$d + Verwende Proxy %1$s %2$s System-Proxys verwenden Systemweite Einstellungen für HTTP- und HTTPS-Proxys beim Verbinden verwenden. 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. @@ -438,12 +438,18 @@ %.1f kbit/s %.1f Mbit/s %.1f Gbit/s + <p>Seit der OpenSSL Version 1.1, verweigert OpenSSL schwache Signaturen - wie MD5 - in Zertifikaten.</p> +<p><b>MD5-Signaturen sind komplett unsicher und sollten nicht mehr verwendet werden. +</b>MD5-Kollisionen können in <a href=\"https://natmchugh.blogspot.de/2015/02/create-your-own-md5-collisions.html\">wenigen Stunden mit minimalen Kosten</a> erzeugt werden. Sie sollten die VPN-Zertifikate so schnell wie möglich aktualisieren.</p> +<p>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 <a href=\"https://github.com/OpenVPN/easy-rsa/releases\">neueste Version</a> oder ändern Sie md5 auf sha256 und erzeugen Sie Ihre Zertifikate neu.</p> +<p>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.</p> + %.0f B %.1f kB %.1f MB %.1f GB Verbindungsstatistiken - Laufende Statistiken der OpenVPN-Verbindung + Laufende Statistik der OpenVPN-Verbindung Verbindungsstatus Änderungen Statusänderungen der OpenVPN-Verbindung (Verbindung, Authentifizierung,...) Schwache (MD5) Hashes in Zertifikatssignatur (SSL_CTX_use_certificate md too weak) @@ -455,5 +461,8 @@ Ausgewählte Algorithmen testen Eine andere App versucht, %s zu steuern. Die anforderne App kann nicht bestimmt werden. Wenn Sie diesen Zugriff zulassen, erhalten ALLE Apps Zugriff. Die OpenVPN 3 C ++ - Implementierung unterstützt keine statischen Schlüssel. Bitte wechseln Sie zu OpenVPN 2.x unter den allgemeinen Einstellungen. - 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. + 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. + Proxy + Keinen + Tor (Orbot) 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)
Cargar modulo tun Importar PKCS12 de la configuración en el almacén de claves de Android Error al obtener la configuración de proxy: %s - Usando proxy %1$s %2$d + Using proxy %1$s %2$s Usar el proxy del sistema Utilice la configuración del sistema para los proxies HTTP/HTTPS al conectar. 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 < 5.0. @@ -440,8 +440,28 @@ hacia/de Móvil)
%.1f kbit/s %.1f Mbit/s %.1f Gbit/s + <p>a partir de la versión 1.1 de OpenSSL, OpenSSL rechaza débiles firmas en certificados como el MD5.</p><p><b>MD5 firmas son totalmente inseguras y no deberían utilizarse nunca más.</b> las colisiones MD5 pueden crearse en <a + href=\"https://natmchugh.blogspot.de/2015/02/create-your-own-md5-collisions.html\">pocas horas a un costo mínimo.</a>. Debe actualizar los certificados VPN tan pronto como sea posible.<p>de</p>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 <a href=\"https://github.com/OpenVPN/easy-rsa/releases\">última versión</a>) o cambiar de md5 a sha256 y regenerar sus certificados.</p><p>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</p> + %.0f B %.1f kB %.1f MB %.1f GB + Estadísticas de conexión + Ongoing statistics of the established OpenVPN connection + Cambio de estado de conexión + Cambios de estado de la conexión OpenVPN (Conexión, autenticación, ...) + Hashes débiles (MD5) en la firma del certificado (SSL_CTX_use_certificate md too weak) + Prueba de velocidad OpenSSL + Nombres de cifrado OpenSSL + Prueba de velocidad de Crypto OpenSSL + OpenSSL devolvió un error + Ejecutando prueba... + Pruebe los algoritmos seleccionados + 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. + La implementación OpenVPN 3 C ++ no admite claves estáticas. Cambie a OpenVPN 2.x en la configuración general. + 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. + Proxy + Ninguno + Tor (Orbot) 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 @@ Laadi tun moodul Lae PKCS12 OpenVPN konfiguratsioonist Androidi võtmehoidlasse Viga proxy seadistuste vastuvõtul: %s - Kasutusel proxy %1$s %2$d Kasuta süsteemset proxy\'t Kasuta ühendumisel süsteemse HTTP/HTTPS proxy konfiguratsiooni. OpenVPN ühendab määratud VPN kui see oli süsteemi käivitumisel aktiivne. Palun tutvuge, enne Android < 5.0 peal selle võimaluse kasutamist, KKK hoiatusega ühendumise kohta. 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 @@ Serveur DNS secondaire Ignorer les routes envoyées Ignorer les règles de routage envoyées par le serveur. - Redirige tout le trafic vers la connexion VPN + "Redirige tout le trafic sur la connexion VPN" Utiliser la route par défaut 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. Routes qui ne devant pas être routées à travers le VPN. Utilisez la même syntaxe que pour les règles de routage. @@ -202,7 +202,7 @@ Sur certaines images, cette notification joue un son.\nAndroid à introduit ces "Charger le module TUN" "Importer PKCS12 de la configuration dans le gestionnaire de clés Android" Erreur d\'obtention des paramètres de proxy : %s - "Utilisation du proxy %1$s %2$d" + "Utilisation du proxy %1$s %2$s" "Utiliser le proxy système" "Utiliser la configuration générale du système pour que les proxy HTTP / HTTPS se connectent." 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 < 5.0. @@ -253,6 +253,7 @@ Sur certaines images, cette notification joue un son.\nAndroid à introduit ces Connexion (TCP) Authentification échouée En attente d\'un réseau utilisable + ↓%2$s %1$s - ↑%4$s %3$s Non connecté Connexion au VPN %s Connexion au VPN %s @@ -359,8 +360,10 @@ Sur certaines images, cette notification joue un son.\nAndroid à introduit ces 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.

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.

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 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 + 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. Le VPN ne fonctionnera pas du tout pour tous les utilisateurs secondaires. "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." + Seulement la destination accessible sans VPN peut etre etteinte via VPN. Les VPNs IPv6 me fonctionnent Pas su tour. Routes non CIDR Comportement proxy pour les VPN Réinstallation des applications VPN @@ -377,6 +380,7 @@ Sur certaines images, cette notification joue un son.\nAndroid à introduit ces Mode tun persistant %s et ultérieur Échec de la connexion avec l\'erreur SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure + 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. Ce profil a été ajouté à partir d\'une application externe (%s) et a été marqué comme non modifiable par l\'utilisateur. Liste des certificats révoqués Redémarrage du service OpenVPN (l\'Application a probablement plantée ou a été tué pour cause d\'utilisation excessive de la mémoire) @@ -389,6 +393,7 @@ Sur certaines images, cette notification joue un son.\nAndroid à introduit ces 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. Protocole Activé + A precedencia da ABI nativa preferida deste dispositivo (%1$s) e a ABI referenciada por bibliotecas intrínsecas (%2$s) não combinam Autorisation de VPN révoquée par le système d\'exploitation (ex : un autre programme VPN est lancé), arrêt du VPN Envoyer plus d\'infos Envoyer des informations supplémentaires sur le serveur, par exemple la version SSL et la version Android @@ -434,4 +439,11 @@ Sur certaines images, cette notification joue un son.\nAndroid à introduit ces %.1f kB %.1f MB %.1f GB + Statistiques de connexion + Test de vitesse OpenSSL + OpenSSL a retourné une erreur + Tester les algorithmes sélectionnés + Proxy + Aucun + Tor (Orbot) 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 @@ Tun modul betöltése PKCS12 konfiguráció importálása az Android Keystore-ba Hiba a proxy beállítások lekérésekor: %s - Proxy használatban: %1$s %2$d + %1$s %2$s proxy használata Rendszerproxy használata Rendszerszintű konfiguráció használata a HTTP/HTTPS proxy csatlakozáshoz. 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 < 5.0-n használná. @@ -474,4 +474,7 @@ 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. + Proxy + Egyik sem + Tor (Orbot) 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 @@ Batal Tidak ada data Kompresi LZO - Tidak ada Sertifikat + Sertifikat CA Sertifikat Klien Kunci Sertifikat Klien Berkas PKCS12 Sertifikat CA Anda harus memilih sertifikat - Kode sumber dan masalah pelacak tersedia di http://code.google.com/p/ics-openvpn/ - Program ini menggunakan komponen berikut ini; lihat kode sumber penjelasan lengkap mengenai lisensi + Kode sumber dan pelacak masalah tersedia di https://github.com/schwabe/ics-openvpn/ + Program ini memakai komponen berikut ini. Lihat sumber untuk mengetahui rincian lisensi Tentang Profil - Tipe + Mengetik Password PKCS12 Pilih… Anda harus memilih setidaknya satu berkas @@ -201,7 +201,7 @@ Pakai modul TUN Ambil PKCS12 dari konfigurasi ke Android Keystore Gagal mendapatkan pengaturan proxy: %s - Menggunakan proxy %1$s %2$d + Menggunakan proxy %1$s %2$s Gunakan sistem proxy Gunakan konfigurasi lebih luas untuk menyambung system melalui proxy HTTP/HTTPS OpenVPN akan menghubungkan VPN ditentukan apakah itu aktif di sistem boot. Silakan baca koneksi peringatan FAQ sebelum menggunakan opsi ini pada Android < 5.0. @@ -438,6 +438,17 @@ %.1f kbit/s %.1f Mbit/s %.1f Gbit/s + <p>Starting with OpenSSL version 1.1, OpenSSL rejects weak signatures in certificates like + MD5.</p><p><b>MD5 signatures are completely insecure and should not be used anymore.</b> MD5 + collisions can be created in <a + href=\"https://natmchugh.blogspot.de/2015/02/create-your-own-md5-collisions.html\">few hours at a minimal cost.</a>. + You should update the VPN certificates as soon as possible.</p><p>Unfortunately, older easy-rsa + distributions included the config option \"default_md md5\". If you are using an old easy-rsa version, update to + the <a href=\"https://github.com/OpenVPN/easy-rsa/releases\">latest version</a>) or change md5 to sha256 and + regenerate your certificates.</p><p>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</p> + %.0f B %.1f kB %.1f MB 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
Carica il modulo tun Importa i PKCS12 dalla configurazione presente nel Keystore di Android Errore nell\'ottenere le impostazioni del proxy: %s - Si sta utilizzando il proxy %1$s %2$d + Utilizzo del proxy %1$s %2$s Utilizza il proxy di sistema Utilizza la configurazione generale del sistema relativa ai proxy HTTP/HTTPS per connettersi. 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 < 5.0. @@ -420,7 +420,7 @@ Effettuata la lettura del file di configurazione
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. Tempo massimo tra i tentativi di connessione Attendere %ss secondi tra i tentativi di connessione - Altre reti .. -> VPNS]]> + Altre reti .. -> VPNS]]> Connessione a OpenVPN chiusa (%s) Cambia ordinamento Ordina @@ -440,8 +440,28 @@ Effettuata la lettura del file di configurazione
%.1f kbit/s %.1f Mbit/s %.1f Gbit/s + <p>A partire da OpenSSL versione 1.1, OpenSSL rifiuta le firme deboli in certificati come MD5.</p><p><b>firme MD5 sono completamente insicure e non dovrebbero essere più utilizzate.</b> collisioni MD5 possono essere create in <a + href=\"https://natmchugh.blogspot.de/2015/02/create-your-own-md5-collisions.html\">ore a un costo minimo.</a>. È necessario aggiornare i certificati VPN il prima possibile.</p><p>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 <a href=\"https://github.com/OpenVPN/easy-rsa/releases\">più recente</a>) o si modifica md5 in sha256 e si rigenerano i certificati.</p><p>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</p> + %.0f B %.1f kB %.1f MB %.1f GB + Statistiche di connessione + Statistiche in corso della connessione OpenVPN stabilita + Cambio dello stato della connessione + Cambiamenti di stato della connessione OpenVPN (Connessione, autenticazione, ...) + Hash (MD5) troppo deboli nella firma del certificato (SSL_CTX_use_certificate md too weak) + Test di velocità OpenSSL + Nomi di cifratura OpenSSL + OpenSSL Crypto Speed ​​test + OpenSSL ha restituito un errore + Esecuzione di test… + Testa gli algoritmi selezionati + 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. + L\'implementazione di OpenVPN 3 C ++ non supporta le chiavi statiche. Passare a OpenVPN 2.x nelle impostazioni generali. + 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. + Proxy + Nessuno + Tor (Orbot) 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はあなた自身の安全性のために、これらを迂回できな TUNモジュールをロード PKCS12の設定をAndroidのキーストアにインポートします プロキシ設定でエラー: %s - プロキシを使用します %1$s %2$d + プロキシを使用します %1$s %2$s システムのプロキシ設定を使用する 接続にシステム全体の構成の HTTP/HTTPS プロキシを使用します。 有効にすると、OpenVPNはシステムの起動時に指定されたVPNに接続します。Android 5.0より前のバージョンでこのオプションを使用する場合は、接続時の警告に関する「よくある質問」を読んでください。 @@ -477,12 +477,29 @@ Android 4.4以上はポリシールーティングを使用します。route/ifc %.1f kbit/s %.1f Mbit/s %.1f Gbit/s + <p>OpenSSL version 1.1より、OpenSSLはMD5のような脆弱な署名による証明書を拒否するようになりました。</p><p><b>MD5による署名は完全に脆弱でいかなる場面でも使われるべきではありません。</b> 衝突するMD5の生成は<a + href=\"https://natmchugh.blogspot.de/2015/02/create-your-own-md5-collisions.html\">最短で数時間</a>で可能です。できるだけ早くVPNの証明書を更新すべきです。</p><p>残念なことに、古いeasy-rsaディストリビューションの中には設定として\"default_md md5\"が入っています。 もし古いeasy-rsaを使用しているようなら、<a href=\"https://github.com/OpenVPN/easy-rsa/releases\">最新版</a>)にアップデートするか、MD5からSHA256に変更して証明書を再生成してください。 +</p><p>もしどうしても古く劣化した証明書を使いたいのなら、高度な設定のカスタムオプションでtls-cipher \"DEFAULT:@SECLEVEL=0\"を追加してください。</p> + %.0f B %.1f kB %.1f MB %.1f GB + Connection statistics + 確立されたOpenVPN接続の継続的な統計 + 接続状態の変化 + OpenVPN接続の状態変化(接続、認証等) + 証明書の署名は弱いMD5です (SSL_CTX_use_certificate md は弱すぎます) OpenSSLスピードテスト + OpenSSLの暗号名 + OpenSSLの暗号化スピードテスト OpenSSLがエラーを返しました テストを実行中... + 選択したアルゴリズムをテストする 外部アプリが%sを制御しようとしています。アクセスをリクエストしているアプリは特定できません。このアプリを許可すると、すべてのアプリがアクセス許可されます。 + OpenVPN 3 C ++実装は静的キーをサポートしていません。設定でOpenVPN 2.xに変更してください。 + OpenVPN 3 C++実装ではPKCS12ファイルを直接使用することはサポートされていません。 PKCS12ファイルをAndroidキーストアにインポートするか、設定でOpenVPN 2.xに変更してください。 + プロキシ + 使用しない + Tor (Orbot) 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 @@ VPN 설정 편집 VPN 프로파일 \'%s\'을 삭제할까요? 일부 커스텀 ICS 이미지에서는 /dev/tun에 대한 권한이 잘못되어 있거나 tun 모듈 자체가 누락될 수 있습니다. CM9 이미지는 일반 설정에 있는 소유권 고치기 옵션을 사용해 보십시오. - TUN 인터페이스를 열지 못했습니다 + Tun 인터페이스를 열지 못했습니다 "오류: " 지우기 - TUN 인터페이스 열기: + Tun 인터페이스 열기: 로컬 IPv4: %1$s/%2$d IPv6: %3$s MTU: %4$d DNS 서버: %1$s, 도메인: %2$s 경로: %1$s %2$s @@ -116,7 +116,7 @@ 보내기 ICS OpenVPN 로그 파일 클립보드로 로그 복사 - TAP 모드 + Tap 모드 TAP 모드는 루트가 아닌 VPN API에서는 불가능합니다. 따라서 본 앱은 TAP 지원을 제공할 수 없습니다 또? 농담인가요? 아니요. 정말로 TAP 모드는 지원이 불가능합니다. 계속해서 메일을 보내면서 요구하신다고 도움될 일이 아닙니다. 세 번째로? 실제로는 송신 때 레이어2 정보를 추가하고 수신 때 레이어2 정보를 떼내는 TUN을 이용한 TAP 에뮬레이터를 제작하는 것이 가능합니다. 하지만 이것만이 아닌 ARP 그리고 어쩌면 DHCP 클라이언트까지도 구현해야 합니다. 본인은 이 같은 작업을 하는 분을 알고 있지 않습니다. 코딩을 시작하려고 하시는 분이 계시면 제게 연락해 주십시오. @@ -201,7 +201,7 @@ TUN 모듈 로드하기 구성에 있는 PKCS12를 안드로이드 키 저장소로 가져오기 프록시 설정 가져오기 오류: %s - 프록시 %1$s %2$d를 사용 + %1$s 시스템 프록시를 사용 연결할 HTTP/HTTPS 프록시로 시스템 범위의 설정을 사용합니다. OpenVPN이 시스템 부팅시에 활성화되면 지정된 VPN에 연결합니다. 안드로이드 5.0 이전 버전에 이 옵션을 사용하기 전에 연결 경고 FAQ를 읽어 보시기 바랍니다. @@ -215,7 +215,7 @@ 안드로이드는 시스템의 메모리(램)가 부족한 경우, 현재 필요하지 않는 앱들과 서비스들을 활성 메모리에서 삭제합니다. 이 과정에서 진행중인 VPN 연결이 끊어집니다. 이렇게 되지 않기 위해서 OpenVPN 서비스는 더 높은 우선 순위로 실행됩니다. 더 높은 우선 순위로 실행되기 위해서는 앱이 알림을 표시해야 합니다. 열쇠 알림 아이콘은 이전 FAQ에서 설명된 대로 시스템에서 강요하는 것입니다. 이것은 더 높은 우선 순위로 실행되기 위한 앱 알림이 아닙니다. 정의된 VPN 프로파일이 없습니다. 이 <img src=\"ic_menu_add\"/> 아이콘을 사용하여 VPN을 추가하세요 - 이 <img src=\"ic_menu_archive\"/> 아이콘을 사용하여 귀하의 SD 카드에서 기존 (.ovpn 또는 .conf) 프로파일을 가져오세요. + 이 <img src=\"ic_menu_archive\"/> 아이콘을 사용하여 귀하의 Sd 카드에서 기존 (.ovpn 또는 .conf) 프로파일을 가져오세요. 꼭 FAQ를 확인하세요. 빠른 시작 가이드가 있습니다. 라우팅/인터페이스 구성 라우팅 및 인터페이스 구성은 기존 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을 사용하십시오. @@ -469,4 +469,7 @@ 어떤 외부 앱이 %s를 제어하려고 합니다. 접근을 요청하는 앱을 정해 놓을 수 없습니다. 이 앱을 허용하면 모든 앱의 접근을 승인하게 됩니다. OpenVPN 3 C++ 구현은 고정 키를 지원하지 않습니다. 일반 설정에서 OpenVPN 2.x로 변경해 주세요. OpenVPN 3 C++ 구현과 함께 PKCS12 파일을 직접 사용하는 것은 지원되지 않습니다. PKCS12 파일을 안드로이드 키 저장소로 가져 오거나 일반 설정에서 OpenVPN 2.x으로 변경하세요. + 대리 + 없음 + Tor (Orbot) 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 @@ Laad tun module Importeer PKCS12 van configuratie naar Android Keystore Fout bij het verkrijgen van proxy-instellingen: %s - Proxy %1$s %2$d is in gebruik + Proxy %1$s %2$s is in gebruik Gebruik systeemproxy Gebruik de systeemconfiguratie voor HTTP/HTTPS proxies om te verbinden. 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 < 5.0. @@ -464,4 +464,7 @@ 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. De OpenVPN 3 C++ -implementatie ondersteunt geen statische sleutels. Verander naar OpenVPN 2.x onder algemene instellingen. 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. + Proxy + Geen + Tor (Orbot) 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 @@ Prøv å laste tun.ko kjernemodul før tilkobling. Krever at enheten er rootet. Last tun modul Feil ved henting av proxy-innstillinger: %s - Bruker proxy %1$s %2$d Bruk systemet proxy Bruk global systemkonfigurasjon for HTTP/HTTPS proxy for å koble til. Koble til ved oppstart 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 @@ - - - Pozostał jeden miesiąc - Pozostało %d miesięcy - pozostało %d miesięcy - - + 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 @@ Załaduj moduł tun Importuj PKCS12 z konfiguracji do pęku kluczy Androida Błąd pobierania ustawień proxy: %s - Używam proxy %1$s%2$d + Korzystanie z serwera proxy %1$s %2$s Użyj proxy systemowego Połącz używając systemowej konfiguracji proxy HTTP/HTTPS. 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 < 5.0. @@ -393,6 +393,7 @@ OpenVPN dla Androida ostrzeże Cię o tym w logu.

Kiedy VPN ustawi serwer DNS OpenVPN dla Android spróbuje automatycznie wykryć brakujące pliki na karcie SD. Dotknij tego komunikatu, aby żądać uprawnień. Protokół Włączony + Preferowane natywne pierwszeństwo ABI tego urządzenia (%1$s) i ABI zgłoszone przez niezgodność bibliotek (%2$s) natywnych Pozwolenie VPN odwołane przez system (na przykład inny program VPN jest uruchomiony), zatrzymuję VPN Naciśnij \"Peer info\" Wyślij dodatkowe informację do serwera, na przykład wersję SSL oraz Androida @@ -409,6 +410,7 @@ OpenVPN dla Androida ostrzeże Cię o tym w logu.

Kiedy VPN ustawi serwer DNS Telefony Samsung Nie wybrano VPN. Domyślny VPN + VPN używany w miejscach, gdzie trzeba domyślnego VPN. Obecnie przy uruchomieniu, dla Always-On i pliku Quick Settings. Obecnie wybrana sieć VPN: \'%s\' Podłącz ponownie Przełącz VPN @@ -417,6 +419,7 @@ OpenVPN dla Androida ostrzeże Cię o tym w logu.

Kiedy VPN ustawi serwer DNS 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. Maksymalny czas między próbami połączenia Oczekiwanie %s sekund pomiędzy kolejnymi próbami połączenia + Sieci więcej .. -> VPN]]> Połączenie OpenVPN zamknięte (%s) Zmień sortowanie Sortowanie @@ -436,8 +439,29 @@ OpenVPN dla Androida ostrzeże Cię o tym w logu.

Kiedy VPN ustawi serwer DNS %.1f kbit/s %.1f Mbit / s %.1f Gbit/s + <p>Począwszy od wersji OpenSSL 1.1, OpenSSL odrzuca słabe sygnatury w certyfikatach takich jak MD5.</p><p><b>Podpisy MD5 są całkowicie niezabezpieczone i nie powinny być już używane.</b> Zderzenia MD5 można utworzyć w ciągu <a + href=\"https://natmchugh.blogspot.de/2015/02/create-your-own-md5-collisions.html\">godzin przy minimalnych kosztach.</a>. Należy zaktualizować certyfikaty VPN tak szybko, jak to możliwe.</p><p>Niestety, starsze dystrybucje easy-rsa zawierały opcję konfiguracji \"default_md md5\". Jeśli używasz starej wersji easy-rsa, zaktualizuj do <a href=\"https://github.com/OpenVPN/easy-rsa/releases\">najnowszej wersji</a>) lub zmień md5 na sha256 i zrestartuj swoje certyfikaty.</p><p>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</p> + %.0f B %.1f kB %.1f MB %.1f GB + Statystyki połączenia + Statystyki obecnie nawiązanego połączenia OpenVPN + Zmiana statusu połączenia + Zmiana statusu połączenia OpenVPN (Łączenie, uwierzytelnianie,...) + Słabe hasze (MD5) w podpisie certyfikatu +(SSL_CTX_use_certificate md za słabe) + OpenSSL Test Prędkości + OpenSSL nazwy szyfrów + OpenSSL Test Szybkości Crypto + OpenSSL zwrócił błąd + Testowanie… + Test wybranych algorytmów + 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. + Implementacja OpenVPN 3 C++ nie wspiera kluczy statycznych. Proszę zmienić na OpenVPN 2.x pod głównymi ustawieniami. + 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. + Proxy + Żaden + Tor (Orbot) 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 @@ Tente carregar o módulo tun.ko do kernel antes de ligar. Necessita de acesso root ao dispositivo. Carregar o módulo tun Erro ao obter definições proxy %s - A utilizar proxy %1$s %2$d Usar a proxy do sistema Ligar no arranque Ignorar 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 @@ Încarcă modulul tun Import PKCS12 configurare în Android Keystore Eroare la obţinerea setărilor proxy: %s - Folosesc proxy %1$s %2$d Foloseşte proxy sistem Foloseşte configurarea sistem pentru proxy HTTP/HTTPS folosit la conectare. 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 < 5.0. 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 @@ - Остался один месяц + Остался %d месяц Осталось %d месяца + Осталось %d месяцев Осталось %d месяцев - Остался один день + Остался %d день Осталось %d дня + Осталось %d дней Осталось %d дней - Остался один час + Остался %d час Осталось %d часа + Осталось %d часов Осталось %d часов - Осталась одна минута + Осталась %d минута Осталось %d минуты + Осталось %d минут Осталось %d минут 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 @@ Загрузить tun-модуль Импорт PKCS12 из хранилища ключей Android Ошибка при получении параметров прокси-сервера: %s - Используется прокси-сервер %1$s %2$d + Используется прокси-сервер %1$s %2$s Использовать прокси-сервер системы Использовать системную конфигурацию прокси HTTP/HTTPS для соединения. - OpenVPN будет подключаться к указанному VPN, если он был активен при загрузке системы. Пожалуйста, прочитайте FAQ о предупреждении при подключении перед тем, как использовать эту опцию на Android < 5.0. + OpenVPN будет подключаться к указанному VPN, если он был активен при загрузке системы. Пожалуйста, прочитайте FAQ о предупреждении при подключении перед тем, как использовать эту функцию на Android < 5.0. Подключение при загрузке Игнорировать Перезапуск @@ -268,7 +268,7 @@ Добавить Отправить конфигурационный файл Полное DN - Импортированная конфигурация использует УСТАРЕВШУЮ опцию tls-remote, которая имеет другой формат DN. + Импортированная конфигурация использует УСТАРЕВШУЮ функцию tls-remote, которая имеет другой формат DN. RDN (полное имя) Префикс RDN tls-remote (УСТАРЕВШЕЕ) @@ -279,7 +279,7 @@ Нет приложений, авторизованных для внешнего API Разрешённые приложения: %s Очистить список авторизованных внешних приложений?\nСписок разрешенных приложений:\n\n%s - Приостанавливать VPN, если экран выключен и передано меньше 64kb данных за 60 сек. Когда включена опция \"Постоянный туннель\", приостановка VPN оставит ваше устройство без сетевого подключения. Без опции \"Постоянный туннель\" устройство не будет иметь VPN-соединения/защиты. + Приостанавливать VPN, если экран выключен и передано меньше 64 КБ данных за 60 сек. Когда включена функция \"Постоянный туннель\", приостановка VPN оставит ваше устройство без сетевого подключения. Без функции \"Постоянный туннель\" устройство не будет иметь VPN-соединения/защиты. Приостановить VPN-соединение при выключенном экране Приостановка соединения при выключенном экране: меньше, чем %1$s за %2$sс Внимание: Постоянный туннель не включен для этого VPN. Трафик будет использовать обычное интернет соединение, когда экран выключен. @@ -314,7 +314,7 @@ %3$s: %1$s\n\n%2$s Если на вашем устройстве есть root, можете установить <a href=\"http://xposed.info/\">Xposed framework</a> и <a href=\"http://repo.xposed.info/module/de.blinkt.vpndialogxposed\">модуль автоматического подтверждения диалога подключения VPN</a> на свой страх и риск Полные тексты лицензий - Сети, доступные напрямую через локальный интерфейс, не будут маршрутизированы через VPN. Отключите эту опцию, чтобы направить трафик через VPN. + Сети, доступные напрямую через локальный интерфейс, не будут маршрутизированы через VPN. Отключите эту функцию, чтобы направить трафик через VPN. Не использовать VPN для локальных адресов Файл логина и пароля [Импортировано из: %s] @@ -355,7 +355,7 @@ Игнорируется мультиадресный маршрут: %s Android поддерживает только CIDR маршруты к VPN. Поскольку не CIDR маршруты почти никогда не используются, OpenVPN для Android будет использовать /32 для не CIDR маршрутов и выдавать предупреждение. Тетеринг/раздача интернета работает, когда активен VPN. Модемное соединение (тетеринг) НЕ БУДЕТ использовать VPN. - Ранние версии KitKat устанавливают неверное значение MSS для TCP соединений (#61948). Попробуйте включить опцию mssfix, чтобы обойти этот баг. + Ранние версии KitKat устанавливают неверное значение MSS для TCP-соединений (#61948). Попробуйте включить функцию mssfix, чтобы обойти эту ошибку. Android будет продолжать использовать ваши настройки прокси, указанные для мобильного/Wi-Fi соединения, когда не установлен DNS сервер. OpenVPN for Android предупредит вас об этом в журнале.

Когда VPN устанавливает DNS сервер Android не использует прокси. Для установки прокси для VPN соединения нет API.

Приложения VPN могут перестать работать после удаления и повторной установки. Подробности см. #80074 Сконфигурированный IP-адрес клиента и IP-адреса в его подсети (согласно сетевой маске) не направляются через VPN. OpenVPN обходит этот баг, явно добавляя маршрут, который соответствует клиентскому IP и его сетевой маске @@ -424,7 +424,7 @@ Сортировать Профили отсортированы по порядку последнего использования Профили отсортированы по названию - Файл настройки использует опцию tls-remote, которая была объявлена устаревшей в версии 2.3 и окончательно удалена в версии 2.4 + Файл настройки использует функцию tls-remote, которая была объявлена устаревшей в версии 2.3 и окончательно удалена в версии 2.4 Поведение при AUTH_FAILED График Использовать логарифмическую шкалу @@ -438,8 +438,7 @@ %.1f Кбит/с %.1f Мбит/с %.1f Гбит/с - <p> Начиная с OpenSSL версии 1.1, OpenSSL отклоняет слабые подписи в таких сертификатах, как MD5.</p><p><b>MD5, подписи полностью небезопасны и больше не должны использоваться.</b> Столкновения MD5 могут быть созданы в <a - href=\"https://natmchugh.blogspot.de/2015/02/create-your-own-md5-collisions.html\"> через несколько часов с минимальными затратами.</a>. Вы должны как можно скорее обновить сертификаты VPN. </p><p>К сожалению, старые дистрибутивы easy-rsa включали опцию конфигурации «default_md md5». Если вы используете старую версию easy-rsa, обновите ее до <a href=\"https://github.com/OpenVPN/easy-rsa/releases\">latest версии</a>) или измените md5 на sha256 и восстановите свои сертификаты.</p><p>Если вы действительно хотите использовать старые и поврежденные сертификаты, используйте настраиваемый параметр конфигурации tls-cipher «DEFAULT: @SECLEVEL = 0 \"в расширенной конфигурации или в качестве дополнительной строки в вашей импортированной конфигурации</p> + <p> Начиная с OpenSSL версии 1.1, OpenSSL отклоняет слабые подписи сертификатов, такие как MD5.</p><p><b>Подписи MD5 полностью небезопасны и больше не должны использоваться.</b> Коллизии MD5 могут быть созданы <a href=\"https://natmchugh.blogspot.de/2015/02/create-your-own-md5-collisions.html\"> за несколько часов с минимальными затратами.</a>Вы должны как можно скорее обновить сертификаты VPN. </p><p>К сожалению, старые версии easy-rsa включали опцию конфигурации «default_md md5». Если вы используете старую версию easy-rsa, обновите её до <a href=\"https://github.com/OpenVPN/easy-rsa/releases\">последней версии</a> или измените md5 на sha256 и обновите свои сертификаты.</p><p>Если вы действительно хотите использовать старые и проблемные сертификаты, используйте пользовательский параметр tls-cipher \"DEFAULT:@SECLEVEL=0\" на вкладке «Расширенные» или в качестве дополнительной строки в вашей импортированной конфигурации</p> %.0f Б %.1f КБ @@ -454,9 +453,12 @@ Имена шифров OpenSSL Тест скорости OpenSSL Crypto OpenSSL возвратил ошибку - Запуск теста… + Тестирование… Тестирование выбранных алгоритмов Внешнее приложение пытается контролировать %s. Приложение, запрашивающее доступ, не может быть определено. Разрешение этого приложения предоставляет доступ всем приложениям. - Реализация OpenVPN 3 C ++ не поддерживает статические ключи. Перейдите в OpenVPN 2.x под общие настройки. - Использование файлов PKCS12 напрямую с помощью OpenVPN 3 C ++ не поддерживается. Импортируйте файлы pkcs12 в хранилище ключей Android или замените OpenVPN 2.x на общие настройки. + Реализация OpenVPN 3 C ++ не поддерживает статические ключи. Переключитесь на OpenVPN 2.x в общих настройках. + Использование файлов PKCS12 напрямую с помощью OpenVPN 3 C ++ не поддерживается. Импортируйте файлы pkcs12 в хранилище ключей Android или переключитесь на OpenVPN 2.x в общих настройках. + Прокси + Ничего + Тор (Орбот) 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 @@ Naloži modul TUN Uvozi PKCS12 iz nastavitev v Androidovo shrambo ključev Napaka pri dobivanju nastavitev posredniškega strežnika: %s - Uporaba posredniškega strežnika %1$s %2$d Uporabi sis. pos. str. Za povezavo uporabi nastavitve celega sistema za posredniške strežnike HTTP/HTTPS. 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 < 5.0. 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 @@ Ladda tun modul Importera PKCS12 från konfigurationen till Android Keystore Fel vid hämtning av proxyinställningar: %s - Använder proxy %1$s %2$d + Använder proxy %1$s %2$s Använd system proxy Använda systemkonfigurationen för HTTP/HTTPS proxy för att ansluta. 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 < 5.0. @@ -448,9 +448,14 @@ Svag (MD5) hashes i certifikat signatur (SSL_CTX_use_certificate md för svag) OpenSSL-hastighetstest OpenSSL-ciffernamn + OpenSSL Crypto-hastighetstest OpenSSL returnerade ett fel Kör test… Testa valda algoritmer 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. OpenVPN 3 C ++-implementeringen stöder inte statiska nycklar. Ändra till OpenVPN 2.x under allmänna inställningar. + 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. + Proxy + Ingen + Tor (Orbot) 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 @@ Tun modülünü yükle PKCS12 yapılandırmasını Android anahtar deposuna alma Vekil sunucu ayarları alınırken hata oluştu: %s - %1$s %2$d vekil sunucusu kullanarak + %1$s %2$s Vekil Sunucusu kullanılıyor Sistem vekil sunucusunu kullan Bağlanmak için sistem çapındaki HTTP/HTTPS vekil sunucularını kullan. Sistem önyüklemesi üzerinde etkinse, OpenVPN belirtilen VPN bağlantısına bağlanır. Lütfen bu seçeneği Android < 5.0 üzerinde kullanmadan önce bağlantı uyarısı için SSS bölümünü okuyun. @@ -462,4 +462,7 @@ 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. + Vekil Sunucu + Hiçbiri + Tor (Orbot) 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 @@ - - - Залишився один місяць - Залишось %d місяці - Залишось %d місяці(-ів) - - - Залишився один день - Залишилось %d дні - Залишилось %d днів - - - Залишилась одна година - Залишилось %d години - Залишилось %d годин - - - Залишилася одна хвилина - Залишилось %d хвилини - Залишилось %d хвилин - - + 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 @@ Завантажити tun-модуль Імпорт PKCS12 з конфігурації у сховищі ключів Андроїд Помилка отримання параметрів проксі: %s - Використовується проксі %1$s %2$d + Використовується проксі-сервер %1$s %2$s Використовувати системний проксі Використовувати системну конфігурацію HTTP/HTTPS проксі для з\'єднання. OpenVPN підключатиметься до вказаного VPN, якщо він був активний при завантаженні системи. Будь ласка, прочитайте FAQ про попередження при підключенні перед використанням цієї опції на Android < 5.0. @@ -459,4 +459,7 @@ Зовнішній застосунок намагається контролювати %s. Застосунок, що запитує про доступ, не може бути визначений. Дозвіл цьому застосунку надає доступ всім додаткам. Реалізація OpenVPN 3 C ++ не підтримує статичні ключи. Перейдіть в OpenVPN 2.x під загальними налаштуваннями. Використання файлів PKCS12 напряму за допомогою OpenVPN 3 C ++ не підтримується. Імпортуйте файли pkcs12 в сховище ключів Android або замініть OpenVPN 2.x на загальні налаштування. + Проксі + Немає + Тор (Орбот) 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 @@ Tải tun module Nhập PKCS12 từ cấu hình vào Khóa lưu trữ Android Lỗi nhận cấu hình proxy: %s - Đang sử dụng proxy %1$s %2$d + ใช้พร็อกซี% 1 $ s% 2 $ s Sử dụng proxy hệ thống Sử dụng các cấu hình hệ thống rộng cho HTTP/HTTPS proxy để kết nối. 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 < 5.0. @@ -438,8 +438,36 @@ %.1f kbit/giây %.1f Mbit/giây %.1f Gbit/giây + <p>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.</p><p><b>Chữ ký MD5 hoàn toàn không an toàn và không nên sử dụng nữa.</b> vụ va chạm MD5 + có thể được tạo trong <a + href=\"https://natmchugh.blogspot.de/2015/02/create-your-own-md5-collisions.html\">giờ với chi phí tối thiểu.</a>. + Bạn nên cập nhật chứng chỉ VPN càng sớm càng tốt.</p><p>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 <a href=\"https://github.com/OpenVPN/easy-rsa/releases\">mới nhất</a>) hoặc thay đổi md5 thành sha256 và + tạo lại chứng chỉ của bạn.</p><p>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</p> + %.0f B %.1f kB %.1f MB %.1f GB + Connection statistics + Số liệu thống kê liên tục của kết nối OpenVPN đã được thiết lập + Thay đổi trạng thái kết nối + Thay đổi trạng thái của kết nối OpenVPN (Đang kết nối, xác thực,…) + Hàm băm yếu (MD5) trong chữ ký chứng chỉ (SSL_CTX_use_certificate md quá yếu) + Kiểm tra tốc độ OpenSSL + Tên mã hóa OpenSSL + Kiểm tra tốc độ OpenSSL Crypto + OpenSSL trả về lỗi + Đang chạy kiểm tra… + Kiểm tra các thuật toán đã chọn + 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. + 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. + 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. + Proxy + Không + Tor (Orbot) 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 @@ 无本地绑定 导入配置文件 安全注意事项 - “OpenVPN 是非常注重安全的,所以在此提供一些安全方面的建议。所有保存在存储卡上的数据都是不安全的,任何应用都可以读取存储卡上的文件,即使这个应用没有‘写入存储卡’的权限也是如此。应用自身的数据只能被应用自己读取。在选择 CA 证书、证书文件或者密钥文件的时候请使用导入功能,这样这些数据就会保存在 OpenVPN 自身的数据文件中,保证不会被其他的应用恶意读取。当然导入证书之后记得要把证书从存储卡上删除掉。不过,虽然这些数据不能被其他应用读取,但是这些数据是明文保存的,如果你的系统是 rooted 的,那么这些数据将能够被任何拥有 root 权限的应用轻松地读取。保存在 OpenVPN 中的密码也是以明文保存的,如果设备被 rooted 了,这些密码也有可能被其他应用恶意读取。强烈建议使用 pkcs12 证书并将证书导入到 Android 自己的证书管理系统里。” + "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." 导入 显示证书选择错误 尝试显示 Android 4.0 + 证书选择对话框时出现异常。Android 4.0 以上的系统不可能出现该问题,因为这是标准的系统功能。可能您当前 ROM 中的证书存储已经损坏。 @@ -203,7 +203,7 @@ 加载tun模块 将PKCS12从配置导入到Android Keystore 获取代理设置时出错:%s - 使用代理 %1$s %2$d + Using proxy %1$s %2$s 使用系统代理 使用系统设置连接 HTTP/HTTPS 代理服务器。 如果在系统启动时OpenVPN处于活动状态,那么它会连接指定的VPN。在Android 5.0上使用这个选项前,请阅读连接警告的常见问题。 @@ -442,8 +442,36 @@ %.1f kbit/s %.1f Mbit/s %.1f Gbit/s + <p>Starting with OpenSSL version 1.1, OpenSSL rejects weak signatures in certificates like + MD5.</p><p><b>MD5 signatures are completely insecure and should not be used anymore.</b> MD5 + collisions can be created in <a + href=\"https://natmchugh.blogspot.de/2015/02/create-your-own-md5-collisions.html\">few hours at a minimal cost.</a>. + You should update the VPN certificates as soon as possible.</p><p>Unfortunately, older easy-rsa + distributions included the config option \"default_md md5\". If you are using an old easy-rsa version, update to + the <a href=\"https://github.com/OpenVPN/easy-rsa/releases\">latest version</a>) or change md5 to sha256 and + regenerate your certificates.</p><p>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</p> + %.0f B %.1f kB %.1f MB %.1f GB + 连接统计 + 正在建立的OpenVPN连接的统计数据 + 连接状态改变 + OpenVPN连接的状态更改(连接,身份验证...) + 证书签名中的弱 (MD5) 哈希 (SSL_CTX_use_certificate md 太弱) + OpenSSL 速度测试 + OpenSSL密码名称 + OpenSSL Crypto速度测试 + OpenSSL 返回错误 + 正在运行测试… + 测试选定的算法 + An external app tries to control %s. The app requesting access cannot be determined. Allowing this app grants ALL apps access. + OpenVPN 3 C ++实现不支持静态密钥。请在常规设置下更改为OpenVPN 2.x. + 不支持直接使用 OpenVPN 3 c++ 实现的 PKCS12 文件。请将 pkcs12 文件导入 Android 密钥库, 或在常规设置下更改为 OpenVPN 2.x。 + 代理 + + Tor (Orbot) 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 @@ - + + + 還剩 %d 個月 + + + 還剩 %d 天 + + + 還剩 %d 小時 + + + 還剩 %d 分鐘 + + 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 @@ 伺服器地址: - 伺服器端口: + 伺服器連接埠: 位置 無法讀取檔案目錄 選擇 @@ -68,31 +68,31 @@ 預期的 TLS 伺服器憑證 檢查遠端的伺服器憑證主旨 DN 憑證主機名稱檢查 - 指定用於驗證遠程證書的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+手冊頁 + 指定這個檢查用於驗證遠端憑證 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 遠端憑證主旨 啟用 TLS 密鑰認證 TLS 驗證檔 - 向伺服器請求 IP 地址,、路由和時間資訊 + 向伺服器請求 IP 地址、路由和時間資訊 沒有來自伺服器的資訊,需要在下面指定設定。 - 拉設置 + 取得設定 DNS - 覆蓋的DNS設置服務器 - 使用您自己的DNS服務器 + 伺服器覆蓋 DNS 設定 + 使用您自己的 DNS 伺服器 sea​​rchDomain - 要使用的DNS服務器。 - DNS服務器 - 備用DNS服務器使用,如果正常的DNS服務器無法到達。 - 備份DNS服務器 + 要使用的 DNS 伺服器。 + DNS 伺服器 + 如果無法使用正常的 DNS 伺服器,會使用次要的 DNS 伺服器 + 備用的 DNS 伺服器 忽略伺服器推送的路由 - 忽略路由推服務器。 + 忽略由伺服器推送的路由 重新所有流量導到 VPN 使用預設路由 - 輸入自定義的路線。只有在CIDR格式輸入目的地。 “10.0.0.0/8 2002:: / 16”就直接網絡10.0.0.0/8和2002:: / 16通過VPN。 - 路線不應該被路由通過VPN。使用相同的語法包括路線。 - 自定義路線 - 排除網絡 + 輸入自訂的路由。只有在以 CIDR 格式輸入目的,\"10.0.0.0/8 2002::/16\" 才會將 10.0.0.0/8 及 2002::/16 網路導向 VPN。 + 路由不應流經過 VPN,使用相同的語法來排除路由。 + 自訂路由 + 排除的網絡 日誌的詳細等級 - 允許來自任何IP驗證的數據包 + 允許來自任何 IP 的驗證封包 允許浮動伺服器 自訂選項 編輯 VPN 設定 @@ -102,25 +102,25 @@ "錯誤: " 清除 打開 tun 介面: - 本地 IPv4:%1$s / %2$d IPv6:%3$s MTU:%4$d + 本機 IPv4:%1$s / %2$d IPv6:%3$s MTU:%4$d DNS 伺服器器:%1$s,域名:%2$s 路由:%1$s %2$s 排除的路由:%1$s %2$s VpnService 路由安裝:%1$s %2$s - GOT的接口信息%1$s和%2$s,假設第二個地址是遠程的對等地址。使用/ 32掩碼本地IP。通過OpenVPN的給定方式是“%3$s”。 - 不能使%1$s和%2$s如IP路由CIDR子網掩碼感,使用/ 32子網掩碼。 + 取得介面訊息 %1$s 及 %2$s,假設第二個位址是遠端對等的位址。使用 /32 子網路遮罩給本機 IP。OpenVPN 的模式是「%3$s」。 + 無法將 %1$s 和 %2$s 作為具有 CIDR 子網路遮罩的 IP 路由,使用 /32 作為子網路遮罩。 修正路由 %1$s / %2$s 到 %3$s / %2$s - 無法訪問Android鑰匙扣證書。這可以通過固件升級或通過恢復的應用程序/應用程序設置的備份引起。請編輯VPN和重新選擇下基本設置證書重新訪問證書的權限。 + 無法存取 Android 鑰匙圈憑證。這可能是由韌體更新,或還原此應用程式/應用程式設定造成。請在基本設定下,編輯 VPN 及重新選擇憑證,以重新建立存取憑證的權限。 %1$s %2$s 送出日誌檔案 傳送 ICS OpenVPN 日誌檔案 已將記錄複製到剪貼簿 Tap 模式 - 點擊模式是不可能的非根VPN API。因此,該應用程序不能提供自來水的支持 + 非 root 的 VPN API 無法使用 Tap 模式,因此,此應用程式無法提供 tap 支援。 再一次?你在開玩笑吧?這真的不支援 tap 模式,就算再寄電子郵件詢問能不能支援也是沒用的。 第三次嗎?實際上,一個可以寫基於屯,並添加 2 層資訊發送帶 2 層資訊上水龍頭模擬器接收。但這個水龍頭模擬器還必須實施 ARP 和可能 DHCP 用戶端。我不知道的任何人做任何工作在這個方向。與我聯繫,如果你想要開始對此編碼。 - FAQ + 常問問題 複製記錄項目 若要複製單筆記錄,在此記錄項目上點選。若要複製/送出整筆記錄,使用送出記錄選項。如果這個按鈕在畫面中無法顯示,請使用實體的選單按鈕。 以快捷方式啟動 @@ -135,33 +135,33 @@ 內嵌檔案 匯入過程中發生錯誤 無法從檔案系統中匯入檔案 - <內嵌於設定檔> - 拒絕開啟 tun 沒有 IP 資訊的裝置 + [[內嵌於設定檔]] + 拒絕開啟沒有 IP 資訊的 tun 裝置 從 .ovpn 檔案匯入設定檔 匯入 - 匯入過程中無法讀取設定檔 + 無法讀取設定檔來匯入 讀取設定檔時發生錯誤 新增設定檔 找不到在導入配置文件中提到的文件%1$s 從源頭%1$s導入配置文件 你的配置有沒有被映射到用戶界面配置一些配置選項。這些選項被添加為自定義配置選項。將顯示自定義配置如下: 成功讀取設定檔 - 不要綁定本地地址和端口 - 沒有本地綁定 + 不要綁定本機位址與埠 + 沒有本機綁定 匯入設定檔 - 保安上的考慮 + 安全考量 “由於OpenVPN是安全敏感的有關安全性的幾個音符都是明智的。在​​SD卡的所有數據本質上是不安全的。每一個應用程序可以讀取它(比如這個方案並不需要特別的SD卡的權限)。此應用程序的數據只能讀由應用程序本身。通過使用CACERT /證書/密鑰的文件對話框中的數據導入選項存儲在VPN配置文件的VPN配置文件只能由該應用程序進行訪問。(不要忘了刪除在SD副本卡後)。即使只能由該應用程序中的數據仍然是未加密的,通過生根電話或其他攻擊有可能檢索數據。保存的密碼是明文存儲以及對於PKCS12文件,強烈建議你將它們導入到android的密鑰庫。“ 匯入 - 錯誤顯示證書選擇 + 顯示憑證選擇錯誤 有一個例外,試圖展示了Android 4.0+證書選擇對話框。這不應該發生,因為這款Android 4.0+的標準功能。也許對於證書存儲你的Andr​​oid ROM支持被打破 IPv4 IPv6 - 等待狀態訊息… - 匯入設定檔 - 匯入設定檔 %d + 等待狀態訊息... + 已匯入設定檔 + 已匯入設定檔 %d 損壞的映像 <p>Official HTC圖像,已知有一種奇怪的路由問題造成交通不流過隧道(也<a href=\"https://github.com/schwabe/ics-openvpn/issues/18\">Issue 18</a>看到bug跟踪系統。)的的Xperia弧S和的Xperia雷</p><p>Older官方SONY圖像已被報導完全缺少VPNService從圖像。 (也<a href=\"https://github.com/schwabe/ics-openvpn/issues/29\">Issue 29</a>看到bug跟踪系統。)</p><p>On自定義生成的TUN模塊可能會丟失照片或為/ dev / TUN的權利可能是錯誤的。一些CM9圖像需要在“設備特定的黑客”enabled.</p><p>Most重要的是“修復所有權”選項:如果您的設備有一個破碎的機器人形象,報告給你的供應商。越多的人誰給供應商報告問題時,他們越有可能解決it.</p> - PKCS12檔加密金鑰 + PKCS12 檔加密金鑰 私密金鑰密碼 密碼 檔案圖標 @@ -186,7 +186,7 @@ 系統的 VPN 連線警告說明這個應用程式可以攔截所有流量,這是防止 VPNService API 被濫用。\n為了提示正在進行的 VPN 連線, Android 系統會產生通知 (鑰匙符號) ,在一些系統中,會發出提示聲。\nAndroid 這麼做是為了確保你的安全。 連線警告和通知時發出音效 繁體中文 - IP和DNS + IP 和 DNS 基本 路由 鮮為人知的OpenVPN設定,一般情況下不需要派上用場。 @@ -195,19 +195,18 @@ 不使用任何DNS服務器。名稱解析可能無法正常工作。考慮設置自定義DNS服務器。另請注意,Android將繼續使用您的手機/ Wi-Fi連接指定的代理服務器設置時沒有DNS服務器設置。 無法添加DNS服務器“%1$s”,系統拒絕:%2$s 無法配置IP地址“%1$s”,系統拒絕:%2$s - <p>Get工作的配置(從供應商/機構檢測您的電腦或下載)</p><p>If它沒有多餘的PEM / pks12文件,你可以自己通過電子郵件發送文件和打開附件的單個文件。如果您有多個文件,把它們放在你的SD card.</p><p>Click上的電子郵件附件/使用的文件夾圖標,在VPN列表導入配置file</p><p>If大約有丟失的文件將丟失的文件在你的SD card.</p><p>Click上保存錯誤標誌將導入的VPN添加到您的VPN list</p><p>Connect的VPN通過點擊VPN</p><p>If的名字有錯誤或警告日誌試著去了解警告/錯誤,並嘗試修復them</p> + <p>取得正在使用的設定(在電腦測試過的,或從供應商/組織下載的)</p><p>如果單一檔案且沒有沒有額外 pem/pks12 檔案,你可以發送這個檔案給自,打開附件。如果你有多個檔案,把他們放在你的 SD 卡。</p><p>點選 email 附件/使用在 VPN 清單的資料夾圖示,來匯入設定檔</p><p>如果有關在 SD 卡內,檔案遺失的錯誤。</p><p>點選儲存符號,來加入已匯入的 VPN 到你的 VPN 清單內</p><p>點選 VPN 的名稱來連線到此 VPN</p><p>如果在日誌中發現錯誤或警告,試著去了解警告/錯誤,並嘗試修復它</p> 快速入門 在連線前嘗試載入 Tun 模組,需要 Root。 載入 tun 模組 導入PKCS12從配置到Android的密鑰庫 取得代理伺服器資訊時發生錯誤: %s - 使用代理伺服器 %1$s %2$d 使用系統代理 使用系統配置的 HTTP/HTTPS 代理伺服器進行連線。 OpenVPN 將會在系統啟動時連線到特定的 VPN。在 Android < 5.0 上使用這個設定前,請閱讀連線警告 FAQ。 啟動時連線 忽略 - 重置 + 重新啟動 配置變更只會在重新啟動VPN時才生效,現在要(重新)啟動VPN嗎? 設定已變更 無法判斷最後一次連線使用的設定檔,因此無法編輯設定檔。 @@ -222,7 +221,7 @@ 當 OpenVPN 重新連線時,持續使用 VPN 連線。 保持 tun 通道 OpenVPN 運作記錄 - 匯入 OpenVPN 配置 + 匯入 OpenVPN 設定 電池消耗 在我個人的測試中的 OpenVPN 高電池消耗的主要原因是保活資料包。大多數的 OpenVPN 伺服器有一個配置指令像 \' keepalive 10 60\',這會導致用戶端和伺服器交換保活資料包每十秒。< P > 雖然這些資料包是小和不使用太多的交通,它們保持移動無線電網路忙,增加了能源消耗。(請參見 < href =\"HTTP://developer.android.com/training/efficient-downloads/efficient-network-access.html#RadioStateMachine\"> 無線電狀態機 |Android 開發者 < /a >) < p > 此 keepalive 設置不能更改用戶端上。只有 OpenVPN 的系統管理員可以更改的設置。< P > 不幸的 udp 使用保活大於 60 秒可以導致一些 NAT 閘道來斷開連接由於不活動超時。用不了多久使用 TCP 保持活著超時工作,但隧道 TCP 通過 TCP 表現極為不佳與高資料包丟失連接上。(請參閱 < href =\"HTTP://sites.inka.de/bigred/devel/tcp-tcp.html\"> 為什麼 TCP 在 TCP 是一個壞點子 < /a >) 網路共用的功能 (透過 Wi-Fi、USB 或藍牙) 和 VPNService API (此程式使用) 不一起作用。更多細節請看 <a href=\"https://github.com/schwabe/ics-openvpn/issues/34\">issue #34</a> @@ -239,14 +238,14 @@ %1$s - %3$s, %2$s 連線中 等待伺服器回覆 - 身份驗證 - 取得客戶端配置 + 身份驗證中... + 正在取得客戶端設定 分配 IP 位址 - 添加路由 + 增加路由 已連線 中斷連線 正在重新連線 - 退出 + 離開 不在執行 解析主機名稱 連線中 (TCP) @@ -254,8 +253,8 @@ 等待可使用的網路 ↓%2$s/秒 %1$s - ↑%4$s/秒 %3$s 未連線 - 正在連接至 VPN %s - 正在連接至 VPN %s + 正在連線至 VPN %s + 正在連線至 VPN %s 如果,密鑰憑證的名稱包含非字母數字字元 (如空白、底線、破折號),在某些 Android 4.1 版本可能會出現問題。請嘗試重新匯入不含特殊字元的憑證。 加密密鑰 封包驗證 @@ -265,28 +264,26 @@ 正式版本 複製到設定檔 異常傾印 - 添加 - 發送配置檔 + 增加 + 傳送設定檔案 完整的 DN 你匯入的設定使用了已經過舊且不建議的 tls-remote 選項使用了不同的 DN 格式。 RDN (common name) RDN 前綴 tls-remote (不建議使用) - 您可以訪問 -http://crowdin.net/project/ics-openvpn/invite -幫助我們翻譯本軟體 + 你可以拜訪 http://crowdin.net/project/ics-openvpn/invite 來協助翻譯 %1$s 試圖控制 %2$s 你正在提供這個應用程式完全控制 OpenVPN for Android 與攔截所有網路流量的權限,不允許,除非信任此應用程式。否則,你的資料會受到惡意軟體洩漏的風險。 - 信任此應用程式 + 我信任此應用程式 不允許應用程式使用外部 API 允許的應用程式:%s 清除允許外部應用程式的清單?\n目前的允許應用程式的清單:\n\n%s 當螢幕關閉和 60 秒內的傳輸資料,小於 60 KB 的時,暫停 VPN。當 「保持 Tun 通道」選項開啟時,暫停 VPN 會讓你的裝置沒有網路連線。如果不使用「保持 Tun 通道」選項,這個裝置會沒有 VPN 連線/保護。 - 當螢幕關閉時暫停VPN連線 + 當螢幕關閉時暫停 VPN 連線 螢幕在關閉狀態時暫停連線:少於 %1$s 在 %2$s 秒 警告:保持 tun 通道沒有在此 VPN 中開啟。當螢幕關閉時,將會使用一般的網際網路連線。 記住密碼 - 暫停VPN + 暫停 VPN 恢復 VPN 使用者要求暫停 VPN VPN 暫停 - 螢幕關閉 @@ -315,12 +312,12 @@ http://crowdin.net/project/ics-openvpn/invite 未處理的異常:%1$s \n\n %2$s %3$s:%1$s \n\n %2$s 如果你的 Android 裝置已取得 root 權限,你可以自行承擔風險安裝 <a href=\"http://xposed.info/\">Xposed framework</a> 和 <a href=\"http://repo.xposed.info/module/de.blinkt.vpndialogxposed\">VPN Dialog confirm module</a> - 證照齊全 - 直接連接到本地接口的網絡將不被路由通過VPN。取消選擇此選項將縮進重定向本地網絡的VPN的所有流量。 + 完整授權 + 直接連線到本機介面的網路將不會被送至 VPN。取消選擇這個選項,將會把所有畚箕網路的流量導向 VPN。 對區域網路繞過 VPN 用戶名稱/密碼 [從匯入:%s] - 一些文件無法找到。請選擇要導入的文件的配置文件: + 無法找到一些文件。請選擇檔案來匯入設定: 要使用這個程序,你需要一個VPN供應商/ VPN支持OpenVPN的網關(通常由雇主提供)。查看http://community.openvpn.net/關於OpenVPN的更多信息,以及如何設置自己的OpenVPN服務器。 匯入日誌: VPN拓撲“%3$s”規定,但使用ifconfig %1$s %2$s看起來更像是一個網絡掩碼的IP地址。假設“子網”的拓撲結構。 @@ -330,24 +327,24 @@ http://crowdin.net/project/ics-openvpn/invite 覆寫TCP 裝載資料 (payload) 的最大分段大小 (MSS) 值 設定 TCP 裝載資料 (payload) 的最大分段大小 (MSS) 客戶端行為 - 清除允許外部應用程序 + 清除允許外部應用程式 載入中... - 允許上傳的VPN應用程序:%1$s + 允許的 VPN 應用程式:%1$s 不允許的 VPN 應用程式:%1$s 包%s不再安裝,從應用程序刪除它允許/禁止列表 - VPN適用於所有的應用程序,但不包括所選 - 的VPN僅用於對選定的應用程序 + VPN 用於全部的應用程式,但不包含選擇的 + VPN 僅用於選擇的應用程式 刪除遠端伺服器項目? - - - 添加新的遠程 + 保持 + 刪除 + 加入新的遠端伺服器 連線時,隨機選擇連線項目 您需要定義和啟用至少一個遠端伺服器。 伺服器列表 允許的應用程式 進階設定 資料 (payload) 選項 - TLS設定 + TLS 設定 遠端沒有定義 重複的 VPN 設定檔 複製設定檔︰ %s @@ -360,8 +357,10 @@ http://crowdin.net/project/ics-openvpn/invite 早期的 KitKat 版本在 TCP 連線中,設定錯誤的最大分段大小 (MSS) 值 (#61948)。試著開啟 mssfix 選項來繞開這個 bug。 Android 沒有 DNS 伺服器設定時,會繼續使用你指定的行動/Wi-Fi 連線代理設定。OpenVPN for Android 會在日誌中記錄警告訊息。

當 VPN 有設定 DNS 伺服器時,因為,Android API 中無法為 VPN 連線設定代理,所以,將不會使用代理設定。

當解除安裝或重新安裝,VPN 應用程式也會停止運作。詳細資訊起參閱 #80074 - 台灣繁體中文 + 已設定的客戶端 IP 及在此網路遮罩的 IP 不會路由到 VPN。OpenVPN 以明確加入一條對應到客戶端 IP 與此子網路遮罩的路由,來嘗試解決這個問題。 + Sdjddnnsmssjhfjdd VPN 不會對次級使用者作用。 + 「許多使用者回報,在使用 VPN 應用程式時,行動連線/行動數據連線經常被斷線。這個行為似乎只影響一些行動供應商/裝置結合,目前為止,沒有原因/解決可辨別該錯誤。」 Vpn是幹嗎? 非無類別域間 (CIDR) 路由 VPN 的代理行為 @@ -372,20 +371,21 @@ http://crowdin.net/project/ics-openvpn/invite VPN 連線錯誤的最大分段大小 (MSS) 值 二级平板电脑用户 指定自訂連線的特定選項,請小心使用 - 自定義選項 + 自訂的選項 刪除連線項目 - 了解! + 從行動網路隨機斷線 遠端網路無法連線 保持 tun 模式 %s 及更高版本 - 連接失敗,SSL23_GET_SERVER_HELLO:sslv3 握手失敗 + 連線失敗,SSL23_GET_SERVER_HELLO:sslv3 警告交握失敗 這個設定檔已被從外部應用程式 (%s) 新增,並標記為使用者無法編輯。 憑證撤銷清單 - 導入配置產生錯誤,無法保存 - 搜索 + 正在重新啟動 OpenVPN 服務(應用程式當機可能因為記憶體壓力而當機或被終止) + 匯入設定發生錯誤,無法儲存 + 搜尋 (最後傾印是 %1$d:%2$dh 久 (%3$s)) 清除新連線的記錄 - 連線超時 + 連線逾時 添加新的遠程 協定 啟用 @@ -404,6 +404,7 @@ http://crowdin.net/project/ics-openvpn/invite 沒有 VPN 被選擇 預設 VPN VPN 在 VPN 需要預設使用在的地方。這些對於目前上啟動,總是在和快速設置平鋪。 + 目前選擇的 VPN:「%s」 重新連線 切換 VPN 連線到 %s @@ -412,4 +413,44 @@ http://crowdin.net/project/ics-openvpn/invite 連線重試間,等待 %s 秒。 更改排序 排序 + 根據最近使用來排序設定檔 + 根據名稱來排序設定檔 + 圖表 + 使用對數尺度 + 沒有足夠的資料 + 每小時平均 + 每分鐘平均 + 最後 5 分鐘 + + + %.0f bit/s + %.1f kbit/s + %.1f Mbit/s + %.1f Gbit/s + <p>從 OpenSSL 1.1 版本, OpenSSL 拒絕憑證中的弱簽章,如 + MD5。</p><p><b>MD5 簽章完全不安全,且不該再使用。</b> MD5 + 碰撞 <a + href=\"https://natmchugh.blogspot.de/2015/02/create-your-own-md5-collisions.html\">在幾小時內以對成本產生</a>。 + 你應該盡快更新 VPN 憑證。</p><p>不幸的是,舊的 easy-rsa + 發行版包含了 \"\"default_md md5\" 的設定選項。如果您正使用舊版的 easy-rsa,更新到 + <a href=\"https://github.com/OpenVPN/easy-rsa/releases\">最新版本</a>) 或將 md5 換至 sha256 及 + 重新產生您的憑證。</p><p>如果你真的想使用破舊的憑證,使用自訂的 + 設定選項 tls-cipher \"DEFAULT:@SECLEVEL=0\" 在進階設定中,或額外加一行在您的 + 已匯入的設定內</p> + + %.0f B + %.1f kB + %.1f MB + %.1f GB + 連線統計 + 正在統計已建立的 OpenVPN 連線 + 連線狀態改變 + OpenVPN 連線狀態改變(正在連線,正在驗證...) + 在憑證簽章中的弱(MD5)雜湊(SSL_CTX_use_certificate md too weak) + OpenSSL 速度測試 + OpenSSL cipher 名稱 + OpenSSL 加密速度測試 + OpenSSL 回傳一個錯誤 + 執行測試中... + 測試已選擇的演算法
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 @@ Show log window %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) Error signing with Android keystore key %1$s: %2$s + Error signing with external authenticator app (%3$s): %1$s: %2$s 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) Connection warning and notification sound English translation by Arne Schwabe<arne@rfc2549.org> @@ -199,7 +200,7 @@ Load tun module Import PKCS12 from configuration into Android Keystore Error getting proxy settings: %s - Using proxy %1$s %2$d + Using proxy %1$s %2$s Use system proxy Use the system wide configuration for HTTP/HTTPS proxies to connect. 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 < 5.0. @@ -250,6 +251,7 @@ Connecting (TCP) Authentication failed Waiting for usable network + Waiting for Orbot to start ↓%2$s %1$s - ↑%4$s %3$s Not connected Connecting to VPN %s @@ -465,5 +467,24 @@ An external app tries to control %s. The app requesting access cannot be determined. Allowing this app grants ALL apps access. The OpenVPN 3 C++ implementation does not support static keys. Please change to OpenVPN 2.x under general settings. 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. + Proxy + None + Tor (Orbot) + OpenVPN 3 C++ implementation does not support connecting via Socks proxy + Orbot application cannot be found. Please install Orbot or use manual Socks v5 integration. + 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. <p>Examples using adb shell and the intents. Replace profilname with your profile name<p><p> adb shell am start-activity -a android.intent.action.MAIN de.blinkt.openvpn/.api.DisconnectVPN<p> adb shell am start-activity -a android.intent.action.MAIN -e de.blinkt.openvpn.api.profileName Blinkt de.blinkt.openvpn/.api.ConnectVPN + Enable Proxy Authentication + Cannot use extra http-proxy-option statement and Orbot integration at the same timeO + Info from server: \'%s\' + User interaction required + OpenVPN connection requires a user input, e.g. two factor + authentification + + Open URL to continue VPN authentication + Authentication pending + External Authenticator + Configure + External Authneticator not configured -- cgit v1.2.3