From d6190becb1c48ee912b11a4206116d0fd4c90772 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Sat, 20 Dec 2014 20:14:23 +0100 Subject: Update ics-openvpn to 1006 --- .../src/main/java/de/blinkt/openvpn/LaunchVPN.java | 2 +- .../main/java/de/blinkt/openvpn/VpnProfile.java | 127 ++++++++-- .../blinkt/openvpn/activities/DisconnectVPN.java | 2 +- .../de/blinkt/openvpn/activities/LogWindow.java | 2 +- .../main/java/de/blinkt/openvpn/core/CIDRIP.java | 2 +- .../java/de/blinkt/openvpn/core/ConfigParser.java | 280 +++++++++++++-------- .../blinkt/openvpn/core/DeviceStateReceiver.java | 12 +- .../blinkt/openvpn/core/ICSOpenVPNApplication.java | 2 +- .../java/de/blinkt/openvpn/core/NativeUtils.java | 3 +- .../java/de/blinkt/openvpn/core/NetworkSpace.java | 11 +- .../de/blinkt/openvpn/core/OpenVPNManagement.java | 2 +- .../de/blinkt/openvpn/core/OpenVPNService.java | 153 +++++++++-- .../java/de/blinkt/openvpn/core/OpenVPNThread.java | 2 +- .../openvpn/core/OpenVpnManagementThread.java | 4 +- .../java/de/blinkt/openvpn/core/PRNGFixes.java | 2 +- .../de/blinkt/openvpn/core/ProfileManager.java | 2 +- .../de/blinkt/openvpn/core/ProxyDetection.java | 2 +- .../de/blinkt/openvpn/core/VPNLaunchHelper.java | 3 +- .../java/de/blinkt/openvpn/core/VpnStatus.java | 8 +- .../java/de/blinkt/openvpn/core/X509Utils.java | 2 +- .../de/blinkt/openvpn/fragments/LogFragment.java | 2 +- .../java/de/blinkt/openvpn/views/SeekBarTicks.java | 2 +- .../main/res/layout-sw600dp-port/log_fragment.xml | 8 +- .../src/main/res/layout-sw600dp/log_fragment.xml | 9 +- .../main/src/main/res/layout/log_fragment.xml | 8 +- .../main/src/main/res/layout/log_silders.xml | 2 +- .../main/src/main/res/layout/log_window.xml | 2 +- .../main/src/main/res/layout/vpnstatus.xml | 2 +- .../main/src/main/res/menu/logmenu.xml | 2 +- .../main/src/main/res/values-ca/strings.xml | 5 +- .../main/src/main/res/values-cs/strings.xml | 24 +- .../main/src/main/res/values-de/strings.xml | 27 +- .../main/src/main/res/values-es/strings.xml | 39 ++- .../main/src/main/res/values-et/strings.xml | 27 +- .../main/src/main/res/values-fr/strings.xml | 5 +- .../main/src/main/res/values-hu/strings.xml | 5 +- .../main/src/main/res/values-in/strings.xml | 5 +- .../main/src/main/res/values-it/strings.xml | 17 +- .../main/src/main/res/values-ja/strings.xml | 5 +- .../main/src/main/res/values-ko/strings.xml | 5 +- .../main/src/main/res/values-nl/strings.xml | 5 +- .../main/src/main/res/values-no/strings.xml | 5 +- .../main/src/main/res/values-pl/strings.xml | 5 +- .../main/src/main/res/values-pt/strings.xml | 5 +- .../main/src/main/res/values-ro/strings.xml | 5 +- .../main/src/main/res/values-ru/strings.xml | 5 +- .../main/src/main/res/values-sv/strings.xml | 5 +- .../main/src/main/res/values-sw600dp/dimens.xml | 5 + .../main/src/main/res/values-sw600dp/styles.xml | 5 + .../main/src/main/res/values-tr/strings.xml | 23 +- .../main/src/main/res/values-uk/strings.xml | 5 +- .../main/src/main/res/values-v21/styles.xml | 6 +- .../main/src/main/res/values-zh-rCN/strings.xml | 10 +- .../main/src/main/res/values-zh-rTW/strings.xml | 5 +- .../main/src/main/res/values/dimens.xml | 10 +- .../main/src/main/res/values/strings.xml | 38 ++- .../main/src/main/res/values/styles.xml | 14 +- .../main/src/main/res/values/untranslatable.xml | 2 +- 58 files changed, 729 insertions(+), 253 deletions(-) (limited to 'ics-openvpn-stripped') diff --git a/ics-openvpn-stripped/main/src/main/java/de/blinkt/openvpn/LaunchVPN.java b/ics-openvpn-stripped/main/src/main/java/de/blinkt/openvpn/LaunchVPN.java index 5c2f0783..706a932f 100644 --- a/ics-openvpn-stripped/main/src/main/java/de/blinkt/openvpn/LaunchVPN.java +++ b/ics-openvpn-stripped/main/src/main/java/de/blinkt/openvpn/LaunchVPN.java @@ -1,6 +1,6 @@ /* * Copyright (c) 2012-2014 Arne Schwabe - * Distributed under the GNU GPL v2. For full terms see the file doc/LICENSE.txt + * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt */ package de.blinkt.openvpn; diff --git a/ics-openvpn-stripped/main/src/main/java/de/blinkt/openvpn/VpnProfile.java b/ics-openvpn-stripped/main/src/main/java/de/blinkt/openvpn/VpnProfile.java index 8e98aaf4..165bef33 100644 --- a/ics-openvpn-stripped/main/src/main/java/de/blinkt/openvpn/VpnProfile.java +++ b/ics-openvpn-stripped/main/src/main/java/de/blinkt/openvpn/VpnProfile.java @@ -1,6 +1,6 @@ /* * Copyright (c) 2012-2014 Arne Schwabe - * Distributed under the GNU GPL v2. For full terms see the file doc/LICENSE.txt + * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt */ package de.blinkt.openvpn; @@ -40,6 +40,7 @@ import java.security.cert.Certificate; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import java.util.Collection; +import java.util.HashSet; import java.util.Locale; import java.util.UUID; import java.util.Vector; @@ -49,13 +50,14 @@ import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; +import de.blinkt.openvpn.core.Connection; import de.blinkt.openvpn.core.NativeUtils; import de.blinkt.openvpn.core.OpenVPNService; import de.blinkt.openvpn.core.VPNLaunchHelper; import de.blinkt.openvpn.core.VpnStatus; import de.blinkt.openvpn.core.X509Utils; -public class VpnProfile implements Serializable { +public class VpnProfile implements Serializable, Cloneable { // Note that this class cannot be moved to core where it belongs since // the profile loading depends on it being here // The Serializable documentation mentions that class name change are possible @@ -69,7 +71,7 @@ public class VpnProfile implements Serializable { private static final long serialVersionUID = 7085688938959334563L; public static final int MAXLOGLEVEL = 4; - public static final int CURRENT_PROFILE_VERSION = 2; + public static final int CURRENT_PROFILE_VERSION = 5; public static final int DEFAULT_MSSFIX_SIZE = 1450; public static String DEFAULT_DNS1 = "8.8.8.8"; public static String DEFAULT_DNS2 = "8.8.4.4"; @@ -104,12 +106,10 @@ public class VpnProfile implements Serializable { public String mClientKeyFilename; public String mCaFilename; public boolean mUseLzo = true; - public String mServerPort = "1194"; - public boolean mUseUdp = true; public String mPKCS12Filename; public String mPKCS12Password; public boolean mUseTLSAuth = false; - public String mServerName = "openvpn.blinkt.de"; + public String mDNS1 = DEFAULT_DNS1; public String mDNS2 = DEFAULT_DNS2; public String mIPv4Address; @@ -150,6 +150,16 @@ public class VpnProfile implements Serializable { public String mExcludedRoutes; public String mExcludedRoutesv6; public int mMssFix =0; // -1 is default, + public Connection[] mConnections = new Connection[0]; + public boolean mRemoteRandom=false; + public HashSet mAllowedAppsVpn = new HashSet(); + public boolean mAllowedAppsVpnAreDisallowed = true; + + + /* Options no long used in new profiles */ + public String mServerName = "openvpn.blinkt.de"; + public String mServerPort = "1194"; + public boolean mUseUdp = true; @@ -157,6 +167,9 @@ public class VpnProfile implements Serializable { mUuid = UUID.randomUUID(); mName = name; mProfileVersion = CURRENT_PROFILE_VERSION; + + mConnections = new Connection[1]; + mConnections[0] = new Connection(); } public static String openVpnEscape(String unescaped) { @@ -204,7 +217,30 @@ public class VpnProfile implements Serializable { mAllowLocalLAN = Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT; } + if (mProfileVersion < 4) { + moveOptionsToConnection(); + mAllowedAppsVpnAreDisallowed=true; + } + if (mAllowedAppsVpn==null) + mAllowedAppsVpn = new HashSet(); + if (mConnections ==null) + mConnections = new Connection[0]; + mProfileVersion= CURRENT_PROFILE_VERSION; + + } + + private void moveOptionsToConnection() { + mConnections = new Connection[1]; + Connection conn = new Connection(); + + conn.mServerName = mServerName; + conn.mServerPort = mServerPort; + conn.mUseUdp = mUseUdp; + conn.mCustomConfiguration = ""; + + mConnections[0] = conn; + } public String getConfigFile(Context context, boolean configForOvpn3) { @@ -265,15 +301,27 @@ public class VpnProfile implements Serializable { // We cannot use anything else than tun cfg += "dev tun\n"; - // Server Address - cfg += "remote "; - cfg += mServerName; - cfg += " "; - cfg += mServerPort; - if (mUseUdp) - cfg += " udp\n"; - else - cfg += " tcp-client\n"; + + boolean canUsePlainRemotes = true; + + if (mConnections.length==1) { + cfg += mConnections[0].getConnectionBlock(); + } else { + for (Connection conn : mConnections) { + canUsePlainRemotes = canUsePlainRemotes && conn.isOnlyRemote(); + } + + if (mRemoteRandom) + cfg+="remote-random\n"; + + if (canUsePlainRemotes) { + for (Connection conn : mConnections) { + if (conn.mEnabled) { + cfg += conn.getConnectionBlock(); + } + } + } + } switch (mAuthenticationType) { @@ -363,11 +411,6 @@ public class VpnProfile implements Serializable { } } - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT && !mAllowLocalLAN) - cfg+="redirect-private block-local\n"; - else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && mAllowLocalLAN) - cfg+="redirect-private unblock-local\n"; - if (mUseDefaultRoutev6) cfg += "route-ipv6 ::/0\n"; @@ -403,7 +446,7 @@ public class VpnProfile implements Serializable { if (mAuthenticationType != TYPE_STATICKEYS) { if (mCheckRemoteCN) { if (mRemoteCN == null || mRemoteCN.equals("")) - cfg += "verify-x509-name " + mServerName + " name\n"; + cfg += "verify-x509-name " + mConnections[0].mServerName + " name\n"; else switch (mX509AuthType) { @@ -468,6 +511,19 @@ public class VpnProfile implements Serializable { } + if (!canUsePlainRemotes) { + cfg += "# 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"; + } + } + } + + + return cfg; } @@ -637,6 +693,27 @@ public class VpnProfile implements Serializable { } } + @Override + protected VpnProfile clone() throws CloneNotSupportedException { + VpnProfile copy = (VpnProfile) super.clone(); + copy.mUuid = UUID.randomUUID(); + copy.mConnections = mConnections.clone(); + copy.mAllowedAppsVpn = (HashSet) mAllowedAppsVpn.clone(); + return copy; + } + + public VpnProfile copy(String name) { + try { + VpnProfile copy = (VpnProfile) clone(); + copy.mName = name; + return copy; + + } catch (CloneNotSupportedException e) { + e.printStackTrace(); + return null; + } + } + class NoCertReturnedException extends Exception { public NoCertReturnedException (String msg) { @@ -767,6 +844,14 @@ public class VpnProfile implements Serializable { if (!mUseDefaultRoute && (getCustomRoutes(mCustomRoutes) == null || getCustomRoutes(mExcludedRoutes) ==null)) return R.string.custom_route_format_error; + boolean noRemoteEnabled = true; + for (Connection c : mConnections) + if (c.mEnabled) + noRemoteEnabled = false; + + if(noRemoteEnabled) + return R.string.remote_no_server_selected; + // Everything okay return R.string.no_error_found; diff --git a/ics-openvpn-stripped/main/src/main/java/de/blinkt/openvpn/activities/DisconnectVPN.java b/ics-openvpn-stripped/main/src/main/java/de/blinkt/openvpn/activities/DisconnectVPN.java index 4940d5d6..dfd815e4 100644 --- a/ics-openvpn-stripped/main/src/main/java/de/blinkt/openvpn/activities/DisconnectVPN.java +++ b/ics-openvpn-stripped/main/src/main/java/de/blinkt/openvpn/activities/DisconnectVPN.java @@ -1,6 +1,6 @@ /* * Copyright (c) 2012-2014 Arne Schwabe - * Distributed under the GNU GPL v2. For full terms see the file doc/LICENSE.txt + * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt */ package de.blinkt.openvpn.activities; diff --git a/ics-openvpn-stripped/main/src/main/java/de/blinkt/openvpn/activities/LogWindow.java b/ics-openvpn-stripped/main/src/main/java/de/blinkt/openvpn/activities/LogWindow.java index 5e4f9517..45f09c8e 100644 --- a/ics-openvpn-stripped/main/src/main/java/de/blinkt/openvpn/activities/LogWindow.java +++ b/ics-openvpn-stripped/main/src/main/java/de/blinkt/openvpn/activities/LogWindow.java @@ -1,6 +1,6 @@ /* * Copyright (c) 2012-2014 Arne Schwabe - * Distributed under the GNU GPL v2. For full terms see the file doc/LICENSE.txt + * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt */ package de.blinkt.openvpn.activities; diff --git a/ics-openvpn-stripped/main/src/main/java/de/blinkt/openvpn/core/CIDRIP.java b/ics-openvpn-stripped/main/src/main/java/de/blinkt/openvpn/core/CIDRIP.java index ac9a8ccb..e525abd5 100644 --- a/ics-openvpn-stripped/main/src/main/java/de/blinkt/openvpn/core/CIDRIP.java +++ b/ics-openvpn-stripped/main/src/main/java/de/blinkt/openvpn/core/CIDRIP.java @@ -1,6 +1,6 @@ /* * Copyright (c) 2012-2014 Arne Schwabe - * Distributed under the GNU GPL v2. For full terms see the file doc/LICENSE.txt + * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt */ package de.blinkt.openvpn.core; diff --git a/ics-openvpn-stripped/main/src/main/java/de/blinkt/openvpn/core/ConfigParser.java b/ics-openvpn-stripped/main/src/main/java/de/blinkt/openvpn/core/ConfigParser.java index 0d8230b7..5dc96bbc 100644 --- a/ics-openvpn-stripped/main/src/main/java/de/blinkt/openvpn/core/ConfigParser.java +++ b/ics-openvpn-stripped/main/src/main/java/de/blinkt/openvpn/core/ConfigParser.java @@ -1,13 +1,17 @@ /* * Copyright (c) 2012-2014 Arne Schwabe - * Distributed under the GNU GPL v2. For full terms see the file doc/LICENSE.txt + * 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.text.TextUtils; +import android.util.Pair; + 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; @@ -28,48 +32,49 @@ public class ConfigParser { private HashMap>> options = new HashMap>>(); private HashMap> meta = new HashMap>(); - - private boolean extraRemotesAsCustom=false; - public void parseConfig(Reader reader) throws IOException, ConfigParseError { - BufferedReader br =new BufferedReader(reader); + BufferedReader br = new BufferedReader(reader); - int lineno=0; - while (true){ - String line = br.readLine(); - lineno++; - if(line==null) - break; + int lineno = 0; + try { + while (true) { + String line = br.readLine(); + lineno++; + if (line == null) + break; - if (lineno==1 && (line.startsWith("PK\003\004") - || (line.startsWith("PK\007\008")))) + if (lineno == 1 && (line.startsWith("PK\003\004") + || (line.startsWith("PK\007\008")))) throw new ConfigParseError("Input looks like a ZIP Archive. Import is only possible for OpenVPN config files (.ovpn/.conf)"); - // Check for OpenVPN Access Server Meta information - if (line.startsWith("# OVPN_ACCESS_SERVER_")) { - Vector metaarg = parsemeta(line); - meta.put(metaarg.get(0),metaarg); - continue; - } - Vector args = parseline(line); + // Check for OpenVPN Access Server Meta information + if (line.startsWith("# OVPN_ACCESS_SERVER_")) { + Vector metaarg = parsemeta(line); + meta.put(metaarg.get(0), metaarg); + continue; + } + Vector args = parseline(line); - if(args.size() ==0) - continue; + if (args.size() == 0) + continue; - if(args.get(0).startsWith("--")) - args.set(0, args.get(0).substring(2)); + if (args.get(0).startsWith("--")) + args.set(0, args.get(0).substring(2)); - checkinlinefile(args,br); + checkinlinefile(args, br); - String optionname = args.get(0); - if(!options.containsKey(optionname)) { - options.put(optionname, new Vector>()); - } - options.get(optionname).add(args); - } + String optionname = args.get(0); + if (!options.containsKey(optionname)) { + options.put(optionname, new Vector>()); + } + options.get(optionname).add(args); + } + } catch (java.lang.OutOfMemoryError memoryError) { + throw new ConfigParseError("File too large to parse: " + memoryError.getLocalizedMessage()); + } } private Vector parsemeta(String line) { @@ -98,7 +103,7 @@ public class ConfigParser { break; else { inlinefile+=line; - inlinefile+= "\n"; + inlinefile+= "\n"; } } while(true); @@ -132,7 +137,7 @@ public class ConfigParser { // adapted openvpn's parse function to java private Vector parseline(String line) throws ConfigParseError { - Vector parameters = new Vector(); + Vector parameters = new Vector(); if (line.length()==0) return parameters; @@ -145,12 +150,12 @@ public class ConfigParser { int pos=0; String currentarg=""; - do { + do { // Emulate the c parsing ... char in; if(pos < line.length()) in = line.charAt(pos); - else + else in = '\0'; if (!backslash && in == '\\' && state != linestate.readin_single_quote) @@ -228,10 +233,7 @@ public class ConfigParser { } - final String[] unsupportedOptions = { "config", - "connection", - "proto-force", - "remote-random", + final String[] unsupportedOptions = { "config", "tls-server" }; @@ -299,7 +301,7 @@ public class ConfigParser { "remote", "float", "port", -// "connect-retry", + "connect-retry", "connect-timeout", "connect-retry-max", "link-mtu", @@ -325,7 +327,7 @@ public class ConfigParser { // This method is far too long @SuppressWarnings("ConstantConditions") - public VpnProfile convertProfile() throws ConfigParseError{ + public VpnProfile convertProfile() throws ConfigParseError, IOException { boolean noauthtypeset=true; VpnProfile np = new VpnProfile(CONVERTED_PROFILE); // Pull, client, tls-client @@ -338,7 +340,7 @@ public class ConfigParser { } Vector secret = getOption("secret", 1, 2); - if(secret!=null) + if(secret!=null) { np.mAuthenticationType=VpnProfile.TYPE_STATICKEYS; noauthtypeset=false; @@ -362,7 +364,7 @@ public class ConfigParser { if (route.size() >= 4) gateway = route.get(3); - String net = route.get(1); + String net = route.get(1); try { CIDRIP cidr = new CIDRIP(net, netmask); if (gateway.equals("net_gateway")) @@ -398,7 +400,7 @@ public class ConfigParser { Vector> tlsauthoptions = getAllOption("tls-auth", 1, 2); if(tlsauthoptions!=null) { for(Vector tlsauth:tlsauthoptions) { - if(tlsauth!=null) + if(tlsauth!=null) { if(!tlsauth.get(1).equals("[inline]")) { np.mTLSAuthFilename=tlsauth.get(1); @@ -458,36 +460,6 @@ public class ConfigParser { throw new ConfigParseError("Invalid mode for --mode specified, need p2p"); } - Vector port = getOption("port", 1,1); - if(port!=null){ - np.mServerPort = port.get(1); - } - - Vector rport = getOption("rport", 1,1); - if(rport!=null){ - np.mServerPort = rport.get(1); - } - - Vector proto = getOption("proto", 1,1); - if(proto!=null){ - np.mUseUdp=isUdpProto(proto.get(1)); - } - - // Parse remote config - Vector> remotes = getAllOption("remote",1,3); - - if(remotes!=null && remotes.size()>=1 ) { - Vector remote = remotes.get(0); - switch (remote.size()) { - case 4: - np.mUseUdp=isUdpProto(remote.get(3)); - case 3: - np.mServerPort = remote.get(2); - case 2: - np.mServerName = remote.get(1); - } - } - Vector> dhcpoptions = getAllOption("dhcp-option", 2, 2); @@ -581,18 +553,18 @@ public class ConfigParser { if(verifyx509name!=null){ np.mRemoteCN = verifyx509name.get(1); np.mCheckRemoteCN=true; - if(verifyx509name.size()>2) { + if(verifyx509name.size()>2) { if (verifyx509name.get(2).equals("name")) np.mX509AuthType=VpnProfile.X509_VERIFY_TLSREMOTE_RDN; else if (verifyx509name.get(2).equals("name-prefix")) np.mX509AuthType=VpnProfile.X509_VERIFY_TLSREMOTE_RDN_PREFIX; - else + else throw new ConfigParseError("Unknown parameter to x509-verify-name: " + verifyx509name.get(2) ); } else { np.mX509AuthType = VpnProfile.X509_VERIFY_TLSREMOTE_DN; } - } + } Vector verb = getOption("verb",1,1); @@ -615,7 +587,7 @@ public class ConfigParser { if(connectretrymax!=null) np.mConnectRetryMax =connectretrymax.get(1); - Vector> remotetls = getAllOption("remote-cert-tls", 1, 1); + Vector> remotetls = getAllOption("remote-cert-tls", 1, 1); if(remotetls!=null) if(remotetls.get(0).get(1).equals("server")) np.mExpectTLSCert=true; @@ -632,14 +604,55 @@ public class ConfigParser { np.mAuthenticationType=VpnProfile.TYPE_USERPASS_KEYSTORE; } if(authuser.size()>1) { - // Set option value to password get to get cance to embed later. + // Set option value to password get to embed later. np.mUsername=null; - np.mPassword=authuser.get(1); - useEmbbedUserAuth(np,authuser.get(1)); + useEmbbedUserAuth(np, authuser.get(1)); } } - // Parse OpenVPN Access Server extra + Pair conns = parseConnectionOptions(null); + np.mConnections =conns.second; + + Vector> connectionBlocks = getAllOption("connection", 1, 1); + + if (np.mConnections.length > 0 && connectionBlocks !=null ) { + throw new ConfigParseError("Using a block and --remote is not allowed."); + } + + if (connectionBlocks!=null) { + np.mConnections = new Connection[connectionBlocks.size()]; + + int connIndex = 0; + for (Vector conn : connectionBlocks) { + Pair connectionBlockConnection = + parseConnection(conn.get(1), conns.first); + + if (connectionBlockConnection.second.length != 1) + throw new ConfigParseError("A block must have exactly one remote"); + np.mConnections[connIndex] = connectionBlockConnection.second[0]; + connIndex++; + } + } + if(getOption("remote-random", 0, 0) != null) + np.mRemoteRandom=true; + + Vector protoforce = getOption("proto-force", 1, 1); + if(protoforce!=null) { + boolean disableUDP; + String protoToDisable = protoforce.get(1); + if (protoToDisable.equals("udp")) + disableUDP=true; + else if (protoToDisable.equals("tcp")) + disableUDP=false; + else + throw new ConfigParseError(String.format("Unknown protocol %s in proto-force", protoToDisable)); + + for (Connection conn:np.mConnections) + if(conn.mUseUdp==disableUDP) + conn.mEnabled=false; + } + + // Parse OpenVPN Access Server extra Vector friendlyname = meta.get("FRIENDLY_NAME"); if(friendlyname !=null && friendlyname.size() > 1) np.mName=friendlyname.get(1); @@ -649,20 +662,95 @@ public class ConfigParser { if(ocusername !=null && ocusername.size() > 1) np.mUsername=ocusername.get(1); - // Check the other options - if(remotes !=null && remotes.size()>1 && extraRemotesAsCustom) { - // first is already added - remotes.remove(0); - np.mCustomConfigOptions += getOptionStrings(remotes); - np.mUseCustomConfig=true; - - } - checkIgnoreAndInvalidOptions(np); + checkIgnoreAndInvalidOptions(np); fixup(np); return np; } + private Pair parseConnection(String connection, Connection defaultValues) throws IOException, ConfigParseError { + // Parse a connection Block as a new configuration file + + + ConfigParser connectionParser = new ConfigParser(); + StringReader reader = new StringReader(connection.substring(VpnProfile.INLINE_TAG.length())); + connectionParser.parseConfig(reader); + + Pair conn = connectionParser.parseConnectionOptions(defaultValues); + + return conn; + } + + private Pair parseConnectionOptions(Connection connDefault) throws ConfigParseError { + Connection conn; + if (connDefault!=null) + try { + conn = connDefault.clone(); + } catch (CloneNotSupportedException e) { + e.printStackTrace(); + return null; + } + else + conn = new Connection(); + + Vector port = getOption("port", 1,1); + if(port!=null){ + conn.mServerPort = port.get(1); + } + + Vector rport = getOption("rport", 1,1); + if(rport!=null){ + conn.mServerPort = rport.get(1); + } + + Vector proto = getOption("proto", 1,1); + if(proto!=null){ + conn.mUseUdp=isUdpProto(proto.get(1)); + } + + + // Parse remote config + Vector> remotes = getAllOption("remote",1,3); + + + // Assume that we need custom options if connectionDefault are set + if(connDefault!=null) { + for (Vector> option : options.values()) { + + conn.mCustomConfiguration += getOptionStrings(option); + + } + if (!TextUtils.isEmpty(conn.mCustomConfiguration)) + conn.mUseCustomConfig = true; + } + // Make remotes empty to simplify code + if (remotes==null) + remotes = new Vector>(); + + Connection[] connections = new Connection[remotes.size()]; + + + int i=0; + for (Vector remote: remotes) { + try { + connections[i] = conn.clone(); + } catch (CloneNotSupportedException e) { + e.printStackTrace(); + } + switch (remote.size()) { + case 4: + connections[i].mUseUdp=isUdpProto(remote.get(3)); + case 3: + connections[i].mServerPort = remote.get(2); + case 2: + connections[i].mServerName = remote.get(1); + } + i++; + } + return Pair.create(conn, connections); + + } + private void checkRedirectParameters(VpnProfile np, Vector> defgw) { for (Vector redirect: defgw) for (int i=1;i { private BigInteger netAddress; public int networkMask; @@ -198,6 +200,13 @@ public class NetworkSpace { 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) + mIpAddresses.add(split); + } + void addIPv6(Inet6Address address, int mask, boolean included) { mIpAddresses.add(new ipAddress(address, mask, included)); } diff --git a/ics-openvpn-stripped/main/src/main/java/de/blinkt/openvpn/core/OpenVPNManagement.java b/ics-openvpn-stripped/main/src/main/java/de/blinkt/openvpn/core/OpenVPNManagement.java index e90c16d1..1f28c77d 100644 --- a/ics-openvpn-stripped/main/src/main/java/de/blinkt/openvpn/core/OpenVPNManagement.java +++ b/ics-openvpn-stripped/main/src/main/java/de/blinkt/openvpn/core/OpenVPNManagement.java @@ -1,6 +1,6 @@ /* * Copyright (c) 2012-2014 Arne Schwabe - * Distributed under the GNU GPL v2. For full terms see the file doc/LICENSE.txt + * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt */ package de.blinkt.openvpn.core; diff --git a/ics-openvpn-stripped/main/src/main/java/de/blinkt/openvpn/core/OpenVPNService.java b/ics-openvpn-stripped/main/src/main/java/de/blinkt/openvpn/core/OpenVPNService.java index d9830955..578d95e7 100644 --- a/ics-openvpn-stripped/main/src/main/java/de/blinkt/openvpn/core/OpenVPNService.java +++ b/ics-openvpn-stripped/main/src/main/java/de/blinkt/openvpn/core/OpenVPNService.java @@ -1,6 +1,6 @@ /* * Copyright (c) 2012-2014 Arne Schwabe - * Distributed under the GNU GPL v2. For full terms see the file doc/LICENSE.txt + * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt */ package de.blinkt.openvpn.core; @@ -14,7 +14,9 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.SharedPreferences; +import android.content.pm.PackageManager; import android.net.ConnectivityManager; +import android.net.NetworkRequest; import android.net.VpnService; import android.os.Binder; import android.os.Build; @@ -23,6 +25,7 @@ import android.os.IBinder; import android.os.Message; import android.os.ParcelFileDescriptor; import android.preference.PreferenceManager; +import android.system.OsConstants; import android.text.TextUtils; import android.util.Log; @@ -81,6 +84,7 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac private String mLastTunCfg; private String mRemoteGW; private final Object mProcessLock = new Object(); + private LollipopDeviceStateListener mLollipopDeviceStateListener; // From: http://stackoverflow.com/questions/3758606/how-to-convert-byte-size-into-human-readable-format-in-java public static String humanReadableByteCount(long bytes, boolean mbit) { @@ -266,6 +270,9 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac mDeviceStateReceiver = new DeviceStateReceiver(magnagement); registerReceiver(mDeviceStateReceiver, filter); VpnStatus.addByteCountListener(mDeviceStateReceiver); + + /*if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) + addLollipopCMListener(); */ } synchronized void unregisterDeviceStateReceiver() { @@ -280,6 +287,10 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac iae.printStackTrace(); } mDeviceStateReceiver = null; + + /*if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) + removeLollipopCMListener();*/ + } public void userPause(boolean shouldBePaused) { @@ -320,7 +331,7 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac mProfile = ProfileManager.getLastConnectedProfile(this, false); /* Got no profile, just stop */ - if (mProfile==null) { + if (mProfile == null) { Log.d("OpenVPN", "Got no last connected profile on null intent. Stopping"); stopSelf(startId); return START_NOT_STICKY; @@ -431,7 +442,7 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac private OpenVPNManagement instantiateOpenVPN3Core() { try { Class cl = Class.forName("de.blinkt.openvpn.core.OpenVPNThreadv3"); - return (OpenVPNManagement) cl.getConstructor(OpenVPNService.class,VpnProfile.class).newInstance(this,mProfile); + return (OpenVPNManagement) cl.getConstructor(OpenVPNService.class, VpnProfile.class).newInstance(this, mProfile); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (InstantiationException e) { @@ -474,6 +485,7 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac if (mLocalIPv6 != null) cfg += mLocalIPv6; + cfg += "routes: " + TextUtils.join("|", mRoutes.getNetworks(true)) + TextUtils.join("|", mRoutesv6.getNetworks(true)); cfg += "excl. routes:" + TextUtils.join("|", mRoutes.getNetworks(false)) + TextUtils.join("|", mRoutesv6.getNetworks(false)); cfg += "dns: " + TextUtils.join("|", mDnslist); @@ -490,6 +502,10 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac VpnStatus.logInfo(R.string.last_openvpn_tun_config); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && mProfile.mAllowLocalLAN) + { + allowAllAFFamilies(builder); + } if (mLocalIP == null && mLocalIPv6 == null) { VpnStatus.logError(getString(R.string.opentun_no_ipaddr)); @@ -497,6 +513,7 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac } if (mLocalIP != null) { + addLocalNetworksToRoutes(); try { builder.addAddress(mLocalIP.mIp, mLocalIP.len); } catch (IllegalArgumentException iae) { @@ -527,7 +544,7 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac String release = Build.VERSION.RELEASE; if ((Build.VERSION.SDK_INT == Build.VERSION_CODES.KITKAT && !release.startsWith("4.4.3") - && !release.startsWith("4.4.4") && !release.startsWith("4.4.5") && !release.startsWith("4.4.6")) + && !release.startsWith("4.4.4") && !release.startsWith("4.4.5") && !release.startsWith("4.4.6")) && mMtu < 1280) { VpnStatus.logInfo(String.format(Locale.US, "Forcing MTU to 1280 instead of %d to workaround Android Bug #70916", mMtu)); builder.setMtu(1280); @@ -560,8 +577,12 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac VpnStatus.logInfo(R.string.local_ip_info, mLocalIP.mIp, mLocalIP.len, 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))); + VpnStatus.logInfo(R.string.routes_info_excl, TextUtils.join(", ", mRoutes.getNetworks(false)), TextUtils.join(", ", mRoutesv6.getNetworks(false))); VpnStatus.logDebug(R.string.routes_debug, TextUtils.join(", ", positiveIPv4Routes), TextUtils.join(", ", positiveIPv6Routes)); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + setAllowedVpnPackages(builder); + } + String session = mProfile.mName; if (mLocalIP != null && mLocalIPv6 != null) @@ -601,6 +622,82 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac } + @TargetApi(Build.VERSION_CODES.LOLLIPOP) + private void allowAllAFFamilies(Builder builder) { + builder.allowFamily(OsConstants.AF_INET); + builder.allowFamily(OsConstants.AF_INET6); + } + + @TargetApi(Build.VERSION_CODES.LOLLIPOP) + void removeLollipopCMListener() { + ConnectivityManager cm = (ConnectivityManager) getBaseContext().getSystemService(CONNECTIVITY_SERVICE); + cm.unregisterNetworkCallback(mLollipopDeviceStateListener); + mLollipopDeviceStateListener = null; + } + + @TargetApi(Build.VERSION_CODES.LOLLIPOP) + void addLollipopCMListener() { + ConnectivityManager cm = (ConnectivityManager) getBaseContext().getSystemService(CONNECTIVITY_SERVICE); + NetworkRequest.Builder nrb = new NetworkRequest.Builder(); + + mLollipopDeviceStateListener = new LollipopDeviceStateListener(); + cm.registerNetworkCallback(nrb.build(), mLollipopDeviceStateListener); + } + + 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; + } + + if (ipAddr.equals(mLocalIP.mIp)) + continue; + + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT && !mProfile.mAllowLocalLAN) { + mRoutes.addIPSplit(new CIDRIP(ipAddr, netMask), true); + + } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && mProfile.mAllowLocalLAN) + mRoutes.addIP(new CIDRIP(ipAddr, netMask), false); + } + } + + + @TargetApi(Build.VERSION_CODES.LOLLIPOP) + private void setAllowedVpnPackages(Builder builder) { + for (String pkg : mProfile.mAllowedAppsVpn) { + try { + if (mProfile.mAllowedAppsVpnAreDisallowed) { + builder.addDisallowedApplication(pkg); + } else { + builder.addAllowedApplication(pkg); + } + } catch (PackageManager.NameNotFoundException e) { + mProfile.mAllowedAppsVpn.remove(pkg); + VpnStatus.logInfo(R.string.app_no_longer_exists, pkg); + } + } + + if (mProfile.mAllowedAppsVpnAreDisallowed) { + VpnStatus.logDebug(R.string.disallowed_vpn_apps_info, TextUtils.join(", ", mProfile.mAllowedAppsVpn)); + } else { + VpnStatus.logDebug(R.string.allowed_vpn_apps_info, TextUtils.join(", ", mProfile.mAllowedAppsVpn)); + } + } + public void addDNS(String dns) { mDnslist.add(dns); } @@ -611,28 +708,30 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac } } - /** Route that is always included, used by the v3 core */ - public void addRoute (CIDRIP route) { + /** + * Route that is always included, used by the v3 core + */ + public void addRoute(CIDRIP route) { mRoutes.addIP(route, true); } - public void addRoute (String dest, String mask, String gateway, String device) { + public void addRoute(String dest, String mask, String gateway, String device) { CIDRIP route = new CIDRIP(dest, mask); boolean include = isAndroidTunDevice(device); - NetworkSpace.ipAddress gatewayIP = new NetworkSpace.ipAddress(new CIDRIP(gateway, 32),false); + NetworkSpace.ipAddress gatewayIP = new NetworkSpace.ipAddress(new CIDRIP(gateway, 32), false); - if (mLocalIP==null) { + if (mLocalIP == null) { VpnStatus.logError("Local IP address unset but adding route?! This is broken! Please contact author with log"); return; } - NetworkSpace.ipAddress localNet = new NetworkSpace.ipAddress(mLocalIP,true); + NetworkSpace.ipAddress localNet = new NetworkSpace.ipAddress(mLocalIP, true); if (localNet.containsNet(gatewayIP)) - include=true; + include = true; - if (gateway!= null && + if (gateway != null && (gateway.equals("255.255.255.255") || gateway.equals(mRemoteGW))) - include=true; + include = true; if (route.len == 32 && !mask.equals("255.255.255.255")) { @@ -664,7 +763,7 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac } private boolean isAndroidTunDevice(String device) { - return device!=null && + return device != null && (device.startsWith("tun") || "(null)".equals(device) || "vpnservice-tun".equals(device)); } @@ -679,7 +778,7 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac public void setLocalIP(String local, String netmask, int mtu, String mode) { mLocalIP = new CIDRIP(local, netmask); mMtu = mtu; - mRemoteGW=null; + mRemoteGW = null; long netMaskAsInt = CIDRIP.getInt(netmask); @@ -687,14 +786,17 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac // get the netmask as IP int masklen; - if ("net30".equals(mode)) + long mask; + if ("net30".equals(mode)) { masklen = 30; - else + mask = 0xfffffffc; + } else { masklen = 31; + mask = 0xfffffffe; + } - int mask = ~( 1 << (32 - (mLocalIP.len +1))); // Netmask is Ip address +/-1, assume net30/p2p with small net - if ((netMaskAsInt & mask) == (mLocalIP.getInt() & mask )) { + if ((netMaskAsInt & mask) == (mLocalIP.getInt() & mask)) { mLocalIP.len = masklen; } else { mLocalIP.len = 32; @@ -702,13 +804,18 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac VpnStatus.logWarning(R.string.ip_not_cidr, local, netmask, mode); } } - if (("p2p".equals(mode) && mLocalIP.len < 32) || ("net30".equals(mode) && mLocalIP.len < 30)) { + if (("p2p".equals(mode) && mLocalIP.len < 32) || ("net30".equals(mode) && mLocalIP.len < 30)) { VpnStatus.logWarning(R.string.ip_looks_like_subnet, local, netmask, mode); } + /* Workaround for Lollipop, it does not route traffic to the VPNs own network mask */ + if (mLocalIP.len <= 31 && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) + addRoute(mLocalIP); + + // Configurations are sometimes really broken... - mRemoteGW=netmask; + mRemoteGW = netmask; } public void setLocalIPv6(String ipv6addr) { @@ -810,7 +917,7 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac } else { String release = Build.VERSION.RELEASE; if (Build.VERSION.SDK_INT == Build.VERSION_CODES.KITKAT && !release.startsWith("4.4.3") - && !release.startsWith("4.4.4") && !release.startsWith("4.4.5") && !release.startsWith("4.4.6")) + && !release.startsWith("4.4.4") && !release.startsWith("4.4.5") && !release.startsWith("4.4.6")) // There will be probably no 4.4.4 or 4.4.5 version, so don't waste effort to do parsing here return "OPEN_AFTER_CLOSE"; else diff --git a/ics-openvpn-stripped/main/src/main/java/de/blinkt/openvpn/core/OpenVPNThread.java b/ics-openvpn-stripped/main/src/main/java/de/blinkt/openvpn/core/OpenVPNThread.java index e36a5b8a..298a6c40 100644 --- a/ics-openvpn-stripped/main/src/main/java/de/blinkt/openvpn/core/OpenVPNThread.java +++ b/ics-openvpn-stripped/main/src/main/java/de/blinkt/openvpn/core/OpenVPNThread.java @@ -1,6 +1,6 @@ /* * Copyright (c) 2012-2014 Arne Schwabe - * Distributed under the GNU GPL v2. For full terms see the file doc/LICENSE.txt + * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt */ package de.blinkt.openvpn.core; diff --git a/ics-openvpn-stripped/main/src/main/java/de/blinkt/openvpn/core/OpenVpnManagementThread.java b/ics-openvpn-stripped/main/src/main/java/de/blinkt/openvpn/core/OpenVpnManagementThread.java index 37094a1b..1c3b3362 100644 --- a/ics-openvpn-stripped/main/src/main/java/de/blinkt/openvpn/core/OpenVpnManagementThread.java +++ b/ics-openvpn-stripped/main/src/main/java/de/blinkt/openvpn/core/OpenVpnManagementThread.java @@ -1,6 +1,6 @@ /* * Copyright (c) 2012-2014 Arne Schwabe - * Distributed under the GNU GPL v2. For full terms see the file doc/LICENSE.txt + * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt */ package de.blinkt.openvpn.core; @@ -157,7 +157,7 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement { } } catch (IOException e) { - if (!e.getMessage().equals("socket closed")) + if (!e.getMessage().equals("socket closed") && !e.getMessage().equals("Connection reset by peer")) VpnStatus.logException(e); } synchronized (active) { diff --git a/ics-openvpn-stripped/main/src/main/java/de/blinkt/openvpn/core/PRNGFixes.java b/ics-openvpn-stripped/main/src/main/java/de/blinkt/openvpn/core/PRNGFixes.java index bca0a4ab..a788426a 100644 --- a/ics-openvpn-stripped/main/src/main/java/de/blinkt/openvpn/core/PRNGFixes.java +++ b/ics-openvpn-stripped/main/src/main/java/de/blinkt/openvpn/core/PRNGFixes.java @@ -1,6 +1,6 @@ /* * Copyright (c) 2012-2014 Arne Schwabe - * Distributed under the GNU GPL v2. For full terms see the file doc/LICENSE.txt + * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt */ package de.blinkt.openvpn.core;/* diff --git a/ics-openvpn-stripped/main/src/main/java/de/blinkt/openvpn/core/ProfileManager.java b/ics-openvpn-stripped/main/src/main/java/de/blinkt/openvpn/core/ProfileManager.java index 2a26152e..1ebc0a57 100644 --- a/ics-openvpn-stripped/main/src/main/java/de/blinkt/openvpn/core/ProfileManager.java +++ b/ics-openvpn-stripped/main/src/main/java/de/blinkt/openvpn/core/ProfileManager.java @@ -1,6 +1,6 @@ /* * Copyright (c) 2012-2014 Arne Schwabe - * Distributed under the GNU GPL v2. For full terms see the file doc/LICENSE.txt + * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt */ package de.blinkt.openvpn.core; diff --git a/ics-openvpn-stripped/main/src/main/java/de/blinkt/openvpn/core/ProxyDetection.java b/ics-openvpn-stripped/main/src/main/java/de/blinkt/openvpn/core/ProxyDetection.java index cf953863..6e2abb13 100644 --- a/ics-openvpn-stripped/main/src/main/java/de/blinkt/openvpn/core/ProxyDetection.java +++ b/ics-openvpn-stripped/main/src/main/java/de/blinkt/openvpn/core/ProxyDetection.java @@ -1,6 +1,6 @@ /* * Copyright (c) 2012-2014 Arne Schwabe - * Distributed under the GNU GPL v2. For full terms see the file doc/LICENSE.txt + * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt */ package de.blinkt.openvpn.core; diff --git a/ics-openvpn-stripped/main/src/main/java/de/blinkt/openvpn/core/VPNLaunchHelper.java b/ics-openvpn-stripped/main/src/main/java/de/blinkt/openvpn/core/VPNLaunchHelper.java index 208aa359..73ed05bc 100644 --- a/ics-openvpn-stripped/main/src/main/java/de/blinkt/openvpn/core/VPNLaunchHelper.java +++ b/ics-openvpn-stripped/main/src/main/java/de/blinkt/openvpn/core/VPNLaunchHelper.java @@ -1,6 +1,6 @@ /* * Copyright (c) 2012-2014 Arne Schwabe - * Distributed under the GNU GPL v2. For full terms see the file doc/LICENSE.txt + * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt */ package de.blinkt.openvpn.core; @@ -76,7 +76,6 @@ public class VPNLaunchHelper { args.add("--config"); args.add(c.getCacheDir().getAbsolutePath() + "/" + OVPNCONFIGFILE); - return args.toArray(new String[args.size()]); } diff --git a/ics-openvpn-stripped/main/src/main/java/de/blinkt/openvpn/core/VpnStatus.java b/ics-openvpn-stripped/main/src/main/java/de/blinkt/openvpn/core/VpnStatus.java index 25558f13..ffc8097d 100644 --- a/ics-openvpn-stripped/main/src/main/java/de/blinkt/openvpn/core/VpnStatus.java +++ b/ics-openvpn-stripped/main/src/main/java/de/blinkt/openvpn/core/VpnStatus.java @@ -1,6 +1,6 @@ /* * Copyright (c) 2012-2014 Arne Schwabe - * Distributed under the GNU GPL v2. For full terms see the file doc/LICENSE.txt + * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt */ package de.blinkt.openvpn.core; @@ -480,7 +480,11 @@ public class VpnStatus { newLogItem(new LogItem(LogLevel.INFO, message)); } - public static void logInfo(int resourceId, Object... args) { + public static void logDebug(String message) { + newLogItem(new LogItem(LogLevel.DEBUG, message)); + } + + public static void logInfo(int resourceId, Object... args) { newLogItem(new LogItem(LogLevel.INFO, resourceId, args)); } diff --git a/ics-openvpn-stripped/main/src/main/java/de/blinkt/openvpn/core/X509Utils.java b/ics-openvpn-stripped/main/src/main/java/de/blinkt/openvpn/core/X509Utils.java index ff383e0f..0786967b 100644 --- a/ics-openvpn-stripped/main/src/main/java/de/blinkt/openvpn/core/X509Utils.java +++ b/ics-openvpn-stripped/main/src/main/java/de/blinkt/openvpn/core/X509Utils.java @@ -1,6 +1,6 @@ /* * Copyright (c) 2012-2014 Arne Schwabe - * Distributed under the GNU GPL v2. For full terms see the file doc/LICENSE.txt + * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt */ package de.blinkt.openvpn.core; diff --git a/ics-openvpn-stripped/main/src/main/java/de/blinkt/openvpn/fragments/LogFragment.java b/ics-openvpn-stripped/main/src/main/java/de/blinkt/openvpn/fragments/LogFragment.java index 82e51ba3..92bf9ad3 100644 --- a/ics-openvpn-stripped/main/src/main/java/de/blinkt/openvpn/fragments/LogFragment.java +++ b/ics-openvpn-stripped/main/src/main/java/de/blinkt/openvpn/fragments/LogFragment.java @@ -1,6 +1,6 @@ /* * Copyright (c) 2012-2014 Arne Schwabe - * Distributed under the GNU GPL v2. For full terms see the file doc/LICENSE.txt + * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt */ package de.blinkt.openvpn.fragments; diff --git a/ics-openvpn-stripped/main/src/main/java/de/blinkt/openvpn/views/SeekBarTicks.java b/ics-openvpn-stripped/main/src/main/java/de/blinkt/openvpn/views/SeekBarTicks.java index e25c2859..82378b00 100644 --- a/ics-openvpn-stripped/main/src/main/java/de/blinkt/openvpn/views/SeekBarTicks.java +++ b/ics-openvpn-stripped/main/src/main/java/de/blinkt/openvpn/views/SeekBarTicks.java @@ -1,6 +1,6 @@ /* * Copyright (c) 2012-2014 Arne Schwabe - * Distributed under the GNU GPL v2. For full terms see the file doc/LICENSE.txt + * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt */ package de.blinkt.openvpn.views; diff --git a/ics-openvpn-stripped/main/src/main/res/layout-sw600dp-port/log_fragment.xml b/ics-openvpn-stripped/main/src/main/res/layout-sw600dp-port/log_fragment.xml index 2f5c774d..1fb9fa54 100644 --- a/ics-openvpn-stripped/main/src/main/res/layout-sw600dp-port/log_fragment.xml +++ b/ics-openvpn-stripped/main/src/main/res/layout-sw600dp-port/log_fragment.xml @@ -1,7 +1,7 @@ @@ -33,10 +35,6 @@ android:layout_weight="1"/> - - - - - + diff --git a/ics-openvpn-stripped/main/src/main/res/values-ca/strings.xml b/ics-openvpn-stripped/main/src/main/res/values-ca/strings.xml index 6aac659d..3da268e4 100755 --- a/ics-openvpn-stripped/main/src/main/res/values-ca/strings.xml +++ b/ics-openvpn-stripped/main/src/main/res/values-ca/strings.xml @@ -1,9 +1,10 @@ - + + OpenVPN per Android diff --git a/ics-openvpn-stripped/main/src/main/res/values-cs/strings.xml b/ics-openvpn-stripped/main/src/main/res/values-cs/strings.xml index 26093fce..b81397e1 100755 --- a/ics-openvpn-stripped/main/src/main/res/values-cs/strings.xml +++ b/ics-openvpn-stripped/main/src/main/res/values-cs/strings.xml @@ -1,9 +1,10 @@ - + + OpenVPN pro Android @@ -328,4 +329,23 @@ Oznámit TCP sezením běžícím skrze tunel, že mají limitovat velikost odesílaných paketů tak, aby poté, co je OpenVPN zabalí, byla výsledná velikost UDP paketu, které OpenVPN posílá menší než tento počet bytů. (výchozí je 1450) Přepsat hodnotu MSS pro TCP obsah Nastavit MSS pro TCP obsah + Chování klienta + Zrušit povolené externí aplikace + Načítání… + Povolené VPN aplikace: %1$s + Zakázané VPN aplikace: %1$s + Balíček %s již není nainstalován, odstraňuji ho ze seznamu povolených/zakázaných aplikací + VPN je používaná pro všechny aplikace, kromě + VPN je používaná je pro vybrané aplikace + Odstranit položku vzdáleného serveru? + Zachovat + Smazat + Přidat nové vzdálené místo + Použít položky k připojení v náhodném pořadí + Je potřeba definovat a povolit alespoň jeden vzdálený server. + Seznam serverů + Povolené aplikace + Pokročilé nastavení + Možnosti dat + Nastevení TLS diff --git a/ics-openvpn-stripped/main/src/main/res/values-de/strings.xml b/ics-openvpn-stripped/main/src/main/res/values-de/strings.xml index a800951e..b15f6b20 100755 --- a/ics-openvpn-stripped/main/src/main/res/values-de/strings.xml +++ b/ics-openvpn-stripped/main/src/main/res/values-de/strings.xml @@ -1,9 +1,10 @@ - + + OpenVPN für Android @@ -328,4 +329,26 @@ Ändere TCP-Verbindungen, die über den Tunnel laufen, so dass die resultierende UDP-Paketgröße nach der Enkapsulierung durch OpenVPN auf diesen Wert beschränkt bleibt. (Standardwert ist 1450) Überschreiben des MSS-Wert von TCP-Nutzlast Setze MSS von TCP-Nutzlast + Client-Verhalten + Widerrufe Berechtigungen OpenVPN zu steuern + Wird geladen… + Apps erlaubt für das VPN: %1$s + Apps, die nicht das VPN nutzen: %1$s + Anwendung mit Paketnamen \'%s\' ist nicht mehr installiert, wird von der Liste der erlaubten/nicht erlaubten VPN Anwendungen gelöscht. + VPN für alle Anwendung ausgenommen den ausgewählten + VPN nur für die ausgewählten Anwendungen + Servereintrag entfernen? + Behalten + Entfernen + Neuen Server hinzufügen + Beim Verbinden Servereinträge in zufälliger Reihenfolge verwenden + Sie müssen mindestens einen Server definieren und aktivieren. + Serverliste + Erlaubte Anwendungen + Erweiterte Einstellungen + Nutzlast-Optionen + TLS-Einstellungen + Keine Server definiert + VPN Profil duplizieren + VPN Profil duplizieren: %s diff --git a/ics-openvpn-stripped/main/src/main/res/values-es/strings.xml b/ics-openvpn-stripped/main/src/main/res/values-es/strings.xml index 1eb501d6..b9e10fd2 100755 --- a/ics-openvpn-stripped/main/src/main/res/values-es/strings.xml +++ b/ics-openvpn-stripped/main/src/main/res/values-es/strings.xml @@ -1,9 +1,10 @@ - + + OpenVPN para Android @@ -147,7 +148,7 @@ Su configuración tiene algunas opciones de configuración que no están establecidas en la interfaz de usuario . Estas opciones fueron agregadas como opciones de configuración personalizadas. A continuación se muestra la configuración personalizada: Se termino de leer el archivo de configuración. No enlazar con el puerto y la dirección local - Ningún enlace local + No enlazar localmente Importar archivo de configuracion Consideraciones de seguridad "Como OpenVPN es sensible a la seguridad, son razonables algunas notas acerca de seguridad. Todos los datos en la tarjeta SD son inherentemente inseguros. Cualquier aplicación puede leerla (por ejemplo, esta aplicación no requiere ningún permiso especial sobre la tarjeta SD). Los datos de esta aplicación sólo pueden ser leidos por la misma aplicación. Al utilizar la opción importar para el certificado de la CA/certificado/llave, en la ventana de diálogo para selección de archivos, los datos se almacenan en el perfil de la VPN. Los perfiles de VPN sólo son accesibles por esta aplicación. (No olvide después borrar las copias de la tarjeta SD). Aunque sólo sea accesible por esta aplicación, los datos aún están sin encriptar. Al acceder el dispositivo portátil como root u otro medio, es posible recuperar estos datos. Las contraseñas guardadas son almacenadas también en texto plano. Para archivos pkcs12 es muy recomendable que los importe al repositorio de llaves de Android." @@ -173,7 +174,8 @@ Muestra el archivo de configuración OpenVPN generado Editando \"%s\" Construyendo configuracion… - Turning this option on will force a reconnect if the network state is changed (e.g. WiFi to/from mobile) + Activando esta opción forzara una reconexión si el estado de la red es cambiado (Ej. De/hacia WIFi +hacia/de Móvil) Reconectar en cambio de red Estado de la red: %s El certificado de la CA usualmente es recuperado del almacén de claves de Android. Especifique un certificado diferente si obtiene errores de verificación de certificado. @@ -185,7 +187,7 @@ Error al firmar con la llave del almacén de llaves de Android %1$s: %2$s El aviso de conectividad VPN que esta aplicación puede interceptar todo el trafico esta impuesta por el sistema para evitar abusos de la API VPNService.\nLa notificación de conectividad (El símbolo de llave) también esta impuesta por el sistema Android para notificar una conexión VPN en curso. En algunas imágenes, esta notificación también emite un sonido.\nAndroid ha introducido estos diálogos de sistema para su seguridad e se ha asegurado que no pueden ser evitados. (En algunas imágenes, esto incluye la notificación sonora) Advertencia de conexión y sonido de notificación - Traducción al español por José Luis Bandala Perez<luis.449bp@gmail.com> + Traducción al español por José Luis Bandala Pérez<luis.449bp@gmail.com> IP y DNS Básico Enrutamiento @@ -274,7 +276,7 @@ RDN (nombre comun) Prefijo RDN tls-remote (OBSOLETO) - Tu puedes ayudar traduciendo visitando http://crowdin.net/project/ics-openvpn/invite + Tu puedes ayudar a traducir visitando http://crowdin.net/project/ics-openvpn/invite %1$s intentos de controlar %2$s Al proceder, le estás proporcionando permiso a la aplicación para controlar completamente OpenVPN for Android e interceptar todo el tráfico de la red.NO aceptar a menos que confíes en la aplicación. De otro modo, corres el riesgo de que tus datos se vean comprometidos por software malicioso.\" Confío en esta aplicación. @@ -317,7 +319,7 @@ Si ha rooteado su dispositivo Android, puede instalar el <a href=\"http://xposed.info/\">framework Xposed</a> y añadir el <a href=\"http://repo.xposed.info/module/de.blinkt.vpndialogxposed\">módulo de confirmación de Diálogo VPN</a> bajo su propio riesgo\" Licencias completas Las redes conectadas directamente a los interfaces locales no serán enrutadas a través de la VPN. Al desmarcar esta opción, todo el tráfico previsto para las redes locales será redirigido a la VPN. - Evitar la VPN para las redes locales + Saltarse la VPN en redes locales Archivo de Usuario/Contraseña [Importado de:%s] Algunos archivos no se pudo encontrar. Por favor, seleccione los archivos que desea importar el perfil: @@ -325,6 +327,29 @@ Importar registros: Topología de VPN \"%3$s\" especificado pero ifconfig %1$s %2$s se parece más a una dirección IP con una máscara de red. Asumiendo una topología de \"subred\". El valor de mssfix debe ser un número entero entre 0 y 9000 + Anunciar a las sesiones TCP ejecutandose sobre el túnel que deben limitar su tamaño de paquetes enviados de tal manera que después de que OpenVPN los hay encapsulado, el tamaño del paquete UDP resultante enviado a su par no exceda este numero de bytes. (Por defecto es 1450) Reemplazar el valor MSS de la carga TCP Establecer MSS de la carga TCP + Comportamiento del cliente + Borrar aplicaciones externas permitidas + Cargando… + Aplicaciones VPN permitidas: %1$s + Aplicaciones VPN no permitidas: %1$s + El paquete %s ya no está instalado, sacándolo de la lista de apps permitidas/no permitidas + La VPN es usada por todas las aplicaciones, excepto por las seleccionadas + La VPN es utilizada únicamente por las aplicaciones seleccionadas + ¿Eliminar entrada del servidor remoto? + Mantener + Eliminar + Añadir nuevo acceso remoto + Utiliza las entradas de conexión en orden aleatorio en la conexión + Es necesario definir y habilitar al menos un servidor remoto. + Lista de servidores + Aplicaciones permitidas + Opciones Avanzadas + Opciones de carga útil + Configuración TLS + Servidor remoto no definido + Duplicar perfil VPN + Duplicando Perfil: %s diff --git a/ics-openvpn-stripped/main/src/main/res/values-et/strings.xml b/ics-openvpn-stripped/main/src/main/res/values-et/strings.xml index 3dc5a354..9e6e0c7e 100755 --- a/ics-openvpn-stripped/main/src/main/res/values-et/strings.xml +++ b/ics-openvpn-stripped/main/src/main/res/values-et/strings.xml @@ -1,9 +1,10 @@ - + + OpenVPN Androidile @@ -328,4 +329,26 @@ Informeeri tunneldatud TCP sessioone et nad piiraksid saadetavate pakettide suuruse nii, et peale OpenVPN kapseldatud paketi partnerile saatmist ei oleks saadud UDP pakett suurem kui ette antud baitide arv. (vaikeväärtus on 1450) Ignoreeri TCP lasti MSS väärtust Sea TCP lasti MSS väärtus + Kliendi toimimine + Nulli lubatud välised programmid + Laadimine… + Lubatud VPN programmid: %1$s + Keelatud VPN programmid: %1$s + Programm %s on seadmest eemaldatud, see kustutatakse ka lubatud/keelatud programmide nimistust + VPN on kõigi, välja arvatud märgitud, programmide puhul kasutuses + VPN on kasutuses ainult märgitud programmide puhul + Kas eemaldada kaugserveri kirje? + Säilita + Eemalda + Uue kaugserveri lisamine + Ühendumisel kasuta ühenduskirjeid juhuslikus järjekorras + Peate määrama vähemalt ühe kaugserveri. + Serverite Nimistu + Lubatud Programmid + Täpsemad seaded + Nimikoormuse valikud + TLS Seaded + Kaugserverid määramata + Dubleeritud VPN profiil + Duplitseeritakse profiili: %s diff --git a/ics-openvpn-stripped/main/src/main/res/values-fr/strings.xml b/ics-openvpn-stripped/main/src/main/res/values-fr/strings.xml index 5685ed45..f7168cef 100755 --- a/ics-openvpn-stripped/main/src/main/res/values-fr/strings.xml +++ b/ics-openvpn-stripped/main/src/main/res/values-fr/strings.xml @@ -1,9 +1,10 @@ - + + "OpenVPN pour Android" diff --git a/ics-openvpn-stripped/main/src/main/res/values-hu/strings.xml b/ics-openvpn-stripped/main/src/main/res/values-hu/strings.xml index 4700a72d..f59fd184 100755 --- a/ics-openvpn-stripped/main/src/main/res/values-hu/strings.xml +++ b/ics-openvpn-stripped/main/src/main/res/values-hu/strings.xml @@ -1,9 +1,10 @@ - + + OpenVPN Androidhoz diff --git a/ics-openvpn-stripped/main/src/main/res/values-in/strings.xml b/ics-openvpn-stripped/main/src/main/res/values-in/strings.xml index 4b6baff2..f3a3a8c5 100755 --- a/ics-openvpn-stripped/main/src/main/res/values-in/strings.xml +++ b/ics-openvpn-stripped/main/src/main/res/values-in/strings.xml @@ -1,9 +1,10 @@ - + + OpenVPN untuk Android diff --git a/ics-openvpn-stripped/main/src/main/res/values-it/strings.xml b/ics-openvpn-stripped/main/src/main/res/values-it/strings.xml index 0a0963b8..823b5ac2 100755 --- a/ics-openvpn-stripped/main/src/main/res/values-it/strings.xml +++ b/ics-openvpn-stripped/main/src/main/res/values-it/strings.xml @@ -1,9 +1,10 @@ - + + OpenVPN per Android @@ -325,4 +326,16 @@ Effettuata la lettura del file di configurazione Alcuni file non possono essere trovati. Si prega di selezionare i file da importare nel profilo: Per utilizzare questa applicazione è necessario un provider VPN/gateway VPN che supportino OpenVPN (spesso forniti dal datore di lavoro). Vai a http://community.openvpn.net/ per ulteriori informazioni su OpenVPN e come configurare il proprio server OpenVPN. Registro importazione: + Sovrascrivi il valore del MSS nel payload TCP + Setta il valore del MSS nel payload TCP + Comportamento Client + Caricando… + Mantieni + Elimina + Lista Server + Impostazioni Avanzate + Opzioni Payload + Impostazioni TLS + Profilo VPN duplicato + Duplicazione del profilo: %s diff --git a/ics-openvpn-stripped/main/src/main/res/values-ja/strings.xml b/ics-openvpn-stripped/main/src/main/res/values-ja/strings.xml index 9a5a9e58..6fca174b 100755 --- a/ics-openvpn-stripped/main/src/main/res/values-ja/strings.xml +++ b/ics-openvpn-stripped/main/src/main/res/values-ja/strings.xml @@ -1,9 +1,10 @@ - + + OpenVPN for Android diff --git a/ics-openvpn-stripped/main/src/main/res/values-ko/strings.xml b/ics-openvpn-stripped/main/src/main/res/values-ko/strings.xml index bd9e93a5..82a83236 100755 --- a/ics-openvpn-stripped/main/src/main/res/values-ko/strings.xml +++ b/ics-openvpn-stripped/main/src/main/res/values-ko/strings.xml @@ -1,9 +1,10 @@ - + + 안드로이드용 OpenVPN diff --git a/ics-openvpn-stripped/main/src/main/res/values-nl/strings.xml b/ics-openvpn-stripped/main/src/main/res/values-nl/strings.xml index f36da72f..7e36ce26 100755 --- a/ics-openvpn-stripped/main/src/main/res/values-nl/strings.xml +++ b/ics-openvpn-stripped/main/src/main/res/values-nl/strings.xml @@ -1,9 +1,10 @@ - + + OpenVPN voor Android diff --git a/ics-openvpn-stripped/main/src/main/res/values-no/strings.xml b/ics-openvpn-stripped/main/src/main/res/values-no/strings.xml index 26869374..b5f7aebb 100755 --- a/ics-openvpn-stripped/main/src/main/res/values-no/strings.xml +++ b/ics-openvpn-stripped/main/src/main/res/values-no/strings.xml @@ -1,9 +1,10 @@ - + + OpenVPN for Android diff --git a/ics-openvpn-stripped/main/src/main/res/values-pl/strings.xml b/ics-openvpn-stripped/main/src/main/res/values-pl/strings.xml index ec7294b7..650f2eb1 100755 --- a/ics-openvpn-stripped/main/src/main/res/values-pl/strings.xml +++ b/ics-openvpn-stripped/main/src/main/res/values-pl/strings.xml @@ -1,9 +1,10 @@ - + + OpenVPN dla Androida diff --git a/ics-openvpn-stripped/main/src/main/res/values-pt/strings.xml b/ics-openvpn-stripped/main/src/main/res/values-pt/strings.xml index 9b63b9ac..55ecb403 100755 --- a/ics-openvpn-stripped/main/src/main/res/values-pt/strings.xml +++ b/ics-openvpn-stripped/main/src/main/res/values-pt/strings.xml @@ -1,9 +1,10 @@ - + + OpenVPN para Android diff --git a/ics-openvpn-stripped/main/src/main/res/values-ro/strings.xml b/ics-openvpn-stripped/main/src/main/res/values-ro/strings.xml index aa3bb71a..8f3e469d 100755 --- a/ics-openvpn-stripped/main/src/main/res/values-ro/strings.xml +++ b/ics-openvpn-stripped/main/src/main/res/values-ro/strings.xml @@ -1,9 +1,10 @@ - + + OpenVPN pentru Android diff --git a/ics-openvpn-stripped/main/src/main/res/values-ru/strings.xml b/ics-openvpn-stripped/main/src/main/res/values-ru/strings.xml index 8b9ca566..02b60f45 100755 --- a/ics-openvpn-stripped/main/src/main/res/values-ru/strings.xml +++ b/ics-openvpn-stripped/main/src/main/res/values-ru/strings.xml @@ -1,9 +1,10 @@ - + + OpenVPN для Android diff --git a/ics-openvpn-stripped/main/src/main/res/values-sv/strings.xml b/ics-openvpn-stripped/main/src/main/res/values-sv/strings.xml index 65eb8ada..bb3ead45 100755 --- a/ics-openvpn-stripped/main/src/main/res/values-sv/strings.xml +++ b/ics-openvpn-stripped/main/src/main/res/values-sv/strings.xml @@ -1,9 +1,10 @@ - + + OpenVPN för Android diff --git a/ics-openvpn-stripped/main/src/main/res/values-sw600dp/dimens.xml b/ics-openvpn-stripped/main/src/main/res/values-sw600dp/dimens.xml index b83bb856..94a120d1 100644 --- a/ics-openvpn-stripped/main/src/main/res/values-sw600dp/dimens.xml +++ b/ics-openvpn-stripped/main/src/main/res/values-sw600dp/dimens.xml @@ -1,4 +1,9 @@ + + true diff --git a/ics-openvpn-stripped/main/src/main/res/values-sw600dp/styles.xml b/ics-openvpn-stripped/main/src/main/res/values-sw600dp/styles.xml index de0bb55d..c320388d 100644 --- a/ics-openvpn-stripped/main/src/main/res/values-sw600dp/styles.xml +++ b/ics-openvpn-stripped/main/src/main/res/values-sw600dp/styles.xml @@ -1,4 +1,9 @@ + + 16dp diff --git a/ics-openvpn-stripped/main/src/main/res/values-tr/strings.xml b/ics-openvpn-stripped/main/src/main/res/values-tr/strings.xml index 1dc1815a..4c4dfce0 100755 --- a/ics-openvpn-stripped/main/src/main/res/values-tr/strings.xml +++ b/ics-openvpn-stripped/main/src/main/res/values-tr/strings.xml @@ -1,9 +1,10 @@ - + + Android için OpenVPN @@ -11,7 +12,7 @@ Sunucu Portu: Konum Dizin Okunamıyor - Seçin + Seç İptal Veri Yok LZO sıkıştırma @@ -316,4 +317,20 @@ Kullanıcı adı / Şifre dosyası [Buradan içeri aktar: %s] Kaydı içe aktar: + İstemci davranışı + Yükleniyor… + Izin verilen VPN uygulamaları: %1$s + İzin verilmeyen VPN uygulamaları: %1$s + %s adlı paket artık yüklü değil, izin listesinden çıkarılıyor + Seçilen uygulamar dışındaki tüm uygulamalar için VPN kullanılır + Sadece seçilen uygulamar için VPN kullanılır + Uzak sunucu girişi kaldırılsın mı? + Sakla + Sil + Yenı uzak sunucu ekle + En az bir uzak sunucu tanımlamalı ve etkinleştirmelisiniz. + Sunucu Listesi + İzin verilen uygulamalar + Gelişmiş Ayarlar + TLS Ayarları diff --git a/ics-openvpn-stripped/main/src/main/res/values-uk/strings.xml b/ics-openvpn-stripped/main/src/main/res/values-uk/strings.xml index 0a4f10f9..ebd15ce1 100755 --- a/ics-openvpn-stripped/main/src/main/res/values-uk/strings.xml +++ b/ics-openvpn-stripped/main/src/main/res/values-uk/strings.xml @@ -1,9 +1,10 @@ - + + OpenVPN для Android diff --git a/ics-openvpn-stripped/main/src/main/res/values-v21/styles.xml b/ics-openvpn-stripped/main/src/main/res/values-v21/styles.xml index 892b6cb0..4379dd6d 100644 --- a/ics-openvpn-stripped/main/src/main/res/values-v21/styles.xml +++ b/ics-openvpn-stripped/main/src/main/res/values-v21/styles.xml @@ -1,13 +1,15 @@ + + + + +