summaryrefslogtreecommitdiff
path: root/app/src/main/java/de/blinkt/openvpn
diff options
context:
space:
mode:
Diffstat (limited to 'app/src/main/java/de/blinkt/openvpn')
-rw-r--r--app/src/main/java/de/blinkt/openvpn/LaunchVPN.java2
-rw-r--r--app/src/main/java/de/blinkt/openvpn/VpnProfile.java127
-rw-r--r--app/src/main/java/de/blinkt/openvpn/activities/DisconnectVPN.java2
-rw-r--r--app/src/main/java/de/blinkt/openvpn/activities/LogWindow.java2
-rw-r--r--app/src/main/java/de/blinkt/openvpn/core/CIDRIP.java2
-rw-r--r--app/src/main/java/de/blinkt/openvpn/core/ConfigParser.java280
-rw-r--r--app/src/main/java/de/blinkt/openvpn/core/Connection.java51
-rw-r--r--app/src/main/java/de/blinkt/openvpn/core/DeviceStateReceiver.java12
-rw-r--r--app/src/main/java/de/blinkt/openvpn/core/ICSOpenVPNApplication.java2
-rw-r--r--app/src/main/java/de/blinkt/openvpn/core/LollipopDeviceStateListener.java53
-rw-r--r--app/src/main/java/de/blinkt/openvpn/core/NativeUtils.java3
-rw-r--r--app/src/main/java/de/blinkt/openvpn/core/NetworkSpace.java11
-rw-r--r--app/src/main/java/de/blinkt/openvpn/core/OpenVPNManagement.java2
-rw-r--r--app/src/main/java/de/blinkt/openvpn/core/OpenVPNService.java153
-rw-r--r--app/src/main/java/de/blinkt/openvpn/core/OpenVPNThread.java2
-rw-r--r--app/src/main/java/de/blinkt/openvpn/core/OpenVpnManagementThread.java4
-rw-r--r--app/src/main/java/de/blinkt/openvpn/core/PRNGFixes.java2
-rw-r--r--app/src/main/java/de/blinkt/openvpn/core/ProfileManager.java2
-rw-r--r--app/src/main/java/de/blinkt/openvpn/core/ProxyDetection.java2
-rw-r--r--app/src/main/java/de/blinkt/openvpn/core/VPNLaunchHelper.java3
-rw-r--r--app/src/main/java/de/blinkt/openvpn/core/VpnStatus.java8
-rw-r--r--app/src/main/java/de/blinkt/openvpn/core/X509Utils.java2
-rw-r--r--app/src/main/java/de/blinkt/openvpn/fragments/LogFragment.java2
-rw-r--r--app/src/main/java/de/blinkt/openvpn/views/SeekBarTicks.java2
24 files changed, 560 insertions, 171 deletions
diff --git a/app/src/main/java/de/blinkt/openvpn/LaunchVPN.java b/app/src/main/java/de/blinkt/openvpn/LaunchVPN.java
index d7f3e110..02abd7a1 100644
--- a/app/src/main/java/de/blinkt/openvpn/LaunchVPN.java
+++ b/app/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/app/src/main/java/de/blinkt/openvpn/VpnProfile.java b/app/src/main/java/de/blinkt/openvpn/VpnProfile.java
index fb2ba90d..4f747d21 100644
--- a/app/src/main/java/de/blinkt/openvpn/VpnProfile.java
+++ b/app/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;
@@ -42,6 +42,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;
@@ -51,13 +52,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
@@ -71,7 +73,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";
@@ -106,12 +108,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;
@@ -152,6 +152,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<String> mAllowedAppsVpn = new HashSet<String>();
+ 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;
@@ -159,6 +169,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) {
@@ -206,7 +219,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<String>();
+ 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) {
@@ -267,15 +303,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) {
@@ -365,11 +413,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";
@@ -405,7 +448,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) {
@@ -470,6 +513,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 += "<connection>\n";
+ cfg += conn.getConnectionBlock();
+ cfg += "</connection>\n";
+ }
+ }
+ }
+
+
+
return cfg;
}
@@ -639,6 +695,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<String>) 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) {
@@ -769,6 +846,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/app/src/main/java/de/blinkt/openvpn/activities/DisconnectVPN.java b/app/src/main/java/de/blinkt/openvpn/activities/DisconnectVPN.java
index 4940d5d6..dfd815e4 100644
--- a/app/src/main/java/de/blinkt/openvpn/activities/DisconnectVPN.java
+++ b/app/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/app/src/main/java/de/blinkt/openvpn/activities/LogWindow.java b/app/src/main/java/de/blinkt/openvpn/activities/LogWindow.java
index 5e4f9517..45f09c8e 100644
--- a/app/src/main/java/de/blinkt/openvpn/activities/LogWindow.java
+++ b/app/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/app/src/main/java/de/blinkt/openvpn/core/CIDRIP.java b/app/src/main/java/de/blinkt/openvpn/core/CIDRIP.java
index ac9a8ccb..e525abd5 100644
--- a/app/src/main/java/de/blinkt/openvpn/core/CIDRIP.java
+++ b/app/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/app/src/main/java/de/blinkt/openvpn/core/ConfigParser.java b/app/src/main/java/de/blinkt/openvpn/core/ConfigParser.java
index 0d8230b7..5dc96bbc 100644
--- a/app/src/main/java/de/blinkt/openvpn/core/ConfigParser.java
+++ b/app/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<String, Vector<Vector<String>>> options = new HashMap<String, Vector<Vector<String>>>();
private HashMap<String, Vector<String>> meta = new HashMap<String, Vector<String>>();
-
- 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<String> metaarg = parsemeta(line);
- meta.put(metaarg.get(0),metaarg);
- continue;
- }
- Vector<String> args = parseline(line);
+ // Check for OpenVPN Access Server Meta information
+ if (line.startsWith("# OVPN_ACCESS_SERVER_")) {
+ Vector<String> metaarg = parsemeta(line);
+ meta.put(metaarg.get(0), metaarg);
+ continue;
+ }
+ Vector<String> 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<Vector<String>>());
- }
- options.get(optionname).add(args);
- }
+ String optionname = args.get(0);
+ if (!options.containsKey(optionname)) {
+ options.put(optionname, new Vector<Vector<String>>());
+ }
+ options.get(optionname).add(args);
+ }
+ } catch (java.lang.OutOfMemoryError memoryError) {
+ throw new ConfigParseError("File too large to parse: " + memoryError.getLocalizedMessage());
+ }
}
private Vector<String> 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<String> parseline(String line) throws ConfigParseError {
- Vector<String> parameters = new Vector<String>();
+ Vector<String> parameters = new Vector<String>();
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<String> 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<Vector<String>> tlsauthoptions = getAllOption("tls-auth", 1, 2);
if(tlsauthoptions!=null) {
for(Vector<String> 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<String> port = getOption("port", 1,1);
- if(port!=null){
- np.mServerPort = port.get(1);
- }
-
- Vector<String> rport = getOption("rport", 1,1);
- if(rport!=null){
- np.mServerPort = rport.get(1);
- }
-
- Vector<String> proto = getOption("proto", 1,1);
- if(proto!=null){
- np.mUseUdp=isUdpProto(proto.get(1));
- }
-
- // Parse remote config
- Vector<Vector<String>> remotes = getAllOption("remote",1,3);
-
- if(remotes!=null && remotes.size()>=1 ) {
- Vector<String> 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<Vector<String>> 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<String> verb = getOption("verb",1,1);
@@ -615,7 +587,7 @@ public class ConfigParser {
if(connectretrymax!=null)
np.mConnectRetryMax =connectretrymax.get(1);
- Vector<Vector<String>> remotetls = getAllOption("remote-cert-tls", 1, 1);
+ Vector<Vector<String>> 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<Connection, Connection[]> conns = parseConnectionOptions(null);
+ np.mConnections =conns.second;
+
+ Vector<Vector<String>> connectionBlocks = getAllOption("connection", 1, 1);
+
+ if (np.mConnections.length > 0 && connectionBlocks !=null ) {
+ throw new ConfigParseError("Using a <connection> block and --remote is not allowed.");
+ }
+
+ if (connectionBlocks!=null) {
+ np.mConnections = new Connection[connectionBlocks.size()];
+
+ int connIndex = 0;
+ for (Vector<String> conn : connectionBlocks) {
+ Pair<Connection, Connection[]> connectionBlockConnection =
+ parseConnection(conn.get(1), conns.first);
+
+ if (connectionBlockConnection.second.length != 1)
+ throw new ConfigParseError("A <connection> block must have exactly one remote");
+ np.mConnections[connIndex] = connectionBlockConnection.second[0];
+ connIndex++;
+ }
+ }
+ if(getOption("remote-random", 0, 0) != null)
+ np.mRemoteRandom=true;
+
+ Vector<String> 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<String> 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<Connection, Connection[]> 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<Connection, Connection[]> conn = connectionParser.parseConnectionOptions(defaultValues);
+
+ return conn;
+ }
+
+ private Pair<Connection, Connection[]> 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<String> port = getOption("port", 1,1);
+ if(port!=null){
+ conn.mServerPort = port.get(1);
+ }
+
+ Vector<String> rport = getOption("rport", 1,1);
+ if(rport!=null){
+ conn.mServerPort = rport.get(1);
+ }
+
+ Vector<String> proto = getOption("proto", 1,1);
+ if(proto!=null){
+ conn.mUseUdp=isUdpProto(proto.get(1));
+ }
+
+
+ // Parse remote config
+ Vector<Vector<String>> remotes = getAllOption("remote",1,3);
+
+
+ // Assume that we need custom options if connectionDefault are set
+ if(connDefault!=null) {
+ for (Vector<Vector<String>> 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<Vector<String>>();
+
+ Connection[] connections = new Connection[remotes.size()];
+
+
+ int i=0;
+ for (Vector<String> 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<Vector<String>> defgw) {
for (Vector<String> redirect: defgw)
for (int i=1;i<redirect.size();i++){
@@ -673,25 +761,21 @@ public class ConfigParser {
}
}
- public void useExtraRemotesAsCustom(boolean b) {
- this.extraRemotesAsCustom = b;
- }
-
private boolean isUdpProto(String proto) throws ConfigParseError {
boolean isudp;
if(proto.equals("udp") || proto.equals("udp6"))
isudp=true;
else if (proto.equals("tcp-client") ||
- proto.equals("tcp") ||
+ proto.equals("tcp") ||
proto.equals("tcp6") ||
proto.endsWith("tcp6-client"))
isudp =false;
- else
+ else
throw new ConfigParseError("Unsupported option to --proto " + proto);
return isudp;
}
- static public void useEmbbedUserAuth(VpnProfile np,String inlinedata)
+ static public void useEmbbedUserAuth(VpnProfile np, String inlinedata)
{
String data = VpnProfile.getEmbeddedContent(inlinedata);
String[] parts = data.split("\n");
diff --git a/app/src/main/java/de/blinkt/openvpn/core/Connection.java b/app/src/main/java/de/blinkt/openvpn/core/Connection.java
new file mode 100644
index 00000000..b10664ce
--- /dev/null
+++ b/app/src/main/java/de/blinkt/openvpn/core/Connection.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2012-2014 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.text.TextUtils;
+
+import java.io.Serializable;
+
+public class Connection implements Serializable, Cloneable {
+ public String mServerName = "openvpn.blinkt.de";
+ public String mServerPort = "1194";
+ public boolean mUseUdp = true;
+ public String mCustomConfiguration="";
+ public boolean mUseCustomConfig=false;
+ public boolean mEnabled=true;
+
+ private static final long serialVersionUID = 92031902903829089L;
+
+
+ public String getConnectionBlock() {
+ String cfg="";
+
+ // Server Address
+ cfg += "remote ";
+ cfg += mServerName;
+ cfg += " ";
+ cfg += mServerPort;
+ if (mUseUdp)
+ cfg += " udp\n";
+ else
+ cfg += " tcp-client\n";
+
+ if (!TextUtils.isEmpty(mCustomConfiguration) && mUseCustomConfig) {
+ cfg += mCustomConfiguration;
+ cfg += "\n";
+ }
+ return cfg;
+ }
+
+ @Override
+ public Connection clone() throws CloneNotSupportedException {
+ return (Connection) super.clone();
+ }
+
+ public boolean isOnlyRemote() {
+ return TextUtils.isEmpty(mCustomConfiguration) || !mUseCustomConfig;
+ }
+}
diff --git a/app/src/main/java/de/blinkt/openvpn/core/DeviceStateReceiver.java b/app/src/main/java/de/blinkt/openvpn/core/DeviceStateReceiver.java
index 0d75ae51..4ccf5472 100644
--- a/app/src/main/java/de/blinkt/openvpn/core/DeviceStateReceiver.java
+++ b/app/src/main/java/de/blinkt/openvpn/core/DeviceStateReceiver.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;
@@ -182,18 +182,14 @@ public class DeviceStateReceiver extends BroadcastReceiver implements ByteCountL
screen = connectState.DISCONNECTED;
if (shouldBeConnected()) {
- if (sendusr1) {
- if (lastNetwork == -1) {
- mManagement.resume();
- } else {
- mManagement.reconnect();
- }
+ if (lastNetwork == -1) {
+ mManagement.resume();
} else {
mManagement.networkChange();
+
}
}
-
lastNetwork = newnet;
}
} else if (networkInfo == null) {
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 83e760ca..56a574dc 100644
--- a/app/src/main/java/de/blinkt/openvpn/core/ICSOpenVPNApplication.java
+++ b/app/src/main/java/de/blinkt/openvpn/core/ICSOpenVPNApplication.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/app/src/main/java/de/blinkt/openvpn/core/LollipopDeviceStateListener.java b/app/src/main/java/de/blinkt/openvpn/core/LollipopDeviceStateListener.java
new file mode 100644
index 00000000..440458e4
--- /dev/null
+++ b/app/src/main/java/de/blinkt/openvpn/core/LollipopDeviceStateListener.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2012-2014 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.annotation.TargetApi;
+import android.net.ConnectivityManager;
+import android.net.LinkProperties;
+import android.net.Network;
+import android.net.NetworkCapabilities;
+import android.os.Build;
+
+/**
+ * Created by arne on 26.11.14.
+ */
+@TargetApi(Build.VERSION_CODES.LOLLIPOP)
+public class LollipopDeviceStateListener extends ConnectivityManager.NetworkCallback {
+
+ private String mLastConnectedStatus;
+ private String mLastLinkProperties;
+ private String mLastNetworkCapabilities;
+
+ @Override
+ public void onAvailable(Network network) {
+ super.onAvailable(network);
+
+ if (!network.toString().equals(mLastConnectedStatus)) {
+ mLastConnectedStatus = network.toString();
+ VpnStatus.logDebug("Connected to " + mLastConnectedStatus);
+ }
+ }
+
+ @Override
+ public void onLinkPropertiesChanged(Network network, LinkProperties linkProperties) {
+ super.onLinkPropertiesChanged(network, linkProperties);
+
+ if (!linkProperties.toString().equals(mLastLinkProperties)) {
+ mLastLinkProperties = linkProperties.toString();
+ VpnStatus.logDebug(String.format("Linkproperties of %s: %s", network, linkProperties));
+ }
+ }
+
+ @Override
+ public void onCapabilitiesChanged(Network network, NetworkCapabilities networkCapabilities) {
+ super.onCapabilitiesChanged(network, networkCapabilities);
+ if (!networkCapabilities.toString().equals(mLastNetworkCapabilities)) {
+ mLastNetworkCapabilities = networkCapabilities.toString();
+ VpnStatus.logDebug(String.format("Network capabilities of %s: %s", network, networkCapabilities));
+ }
+ }
+}
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 6d7ffdf2..f67b7730 100644
--- a/app/src/main/java/de/blinkt/openvpn/core/NativeUtils.java
+++ b/app/src/main/java/de/blinkt/openvpn/core/NativeUtils.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;
@@ -9,6 +9,7 @@ import java.security.InvalidKeyException;
public class NativeUtils {
public static native byte[] rsasign(byte[] input,int pkey) throws InvalidKeyException;
+ public static native String[] getIfconfig() throws IllegalArgumentException;
static native void jniclose(int fdint);
static {
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 35f46513..26354689 100644
--- a/app/src/main/java/de/blinkt/openvpn/core/NetworkSpace.java
+++ b/app/src/main/java/de/blinkt/openvpn/core/NetworkSpace.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;
@@ -21,6 +21,8 @@ import se.leap.bitmaskclient.BuildConfig;
public class NetworkSpace {
+
+
static class ipAddress implements Comparable<ipAddress> {
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/app/src/main/java/de/blinkt/openvpn/core/OpenVPNManagement.java b/app/src/main/java/de/blinkt/openvpn/core/OpenVPNManagement.java
index e90c16d1..1f28c77d 100644
--- a/app/src/main/java/de/blinkt/openvpn/core/OpenVPNManagement.java
+++ b/app/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/app/src/main/java/de/blinkt/openvpn/core/OpenVPNService.java b/app/src/main/java/de/blinkt/openvpn/core/OpenVPNService.java
index d9830955..578d95e7 100644
--- a/app/src/main/java/de/blinkt/openvpn/core/OpenVPNService.java
+++ b/app/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/app/src/main/java/de/blinkt/openvpn/core/OpenVPNThread.java b/app/src/main/java/de/blinkt/openvpn/core/OpenVPNThread.java
index e36a5b8a..298a6c40 100644
--- a/app/src/main/java/de/blinkt/openvpn/core/OpenVPNThread.java
+++ b/app/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/app/src/main/java/de/blinkt/openvpn/core/OpenVpnManagementThread.java b/app/src/main/java/de/blinkt/openvpn/core/OpenVpnManagementThread.java
index 37094a1b..1c3b3362 100644
--- a/app/src/main/java/de/blinkt/openvpn/core/OpenVpnManagementThread.java
+++ b/app/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/app/src/main/java/de/blinkt/openvpn/core/PRNGFixes.java b/app/src/main/java/de/blinkt/openvpn/core/PRNGFixes.java
index bca0a4ab..a788426a 100644
--- a/app/src/main/java/de/blinkt/openvpn/core/PRNGFixes.java
+++ b/app/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/app/src/main/java/de/blinkt/openvpn/core/ProfileManager.java b/app/src/main/java/de/blinkt/openvpn/core/ProfileManager.java
index 2a26152e..1ebc0a57 100644
--- a/app/src/main/java/de/blinkt/openvpn/core/ProfileManager.java
+++ b/app/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/app/src/main/java/de/blinkt/openvpn/core/ProxyDetection.java b/app/src/main/java/de/blinkt/openvpn/core/ProxyDetection.java
index cf953863..6e2abb13 100644
--- a/app/src/main/java/de/blinkt/openvpn/core/ProxyDetection.java
+++ b/app/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/app/src/main/java/de/blinkt/openvpn/core/VPNLaunchHelper.java b/app/src/main/java/de/blinkt/openvpn/core/VPNLaunchHelper.java
index 208aa359..73ed05bc 100644
--- a/app/src/main/java/de/blinkt/openvpn/core/VPNLaunchHelper.java
+++ b/app/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/app/src/main/java/de/blinkt/openvpn/core/VpnStatus.java b/app/src/main/java/de/blinkt/openvpn/core/VpnStatus.java
index 25558f13..ffc8097d 100644
--- a/app/src/main/java/de/blinkt/openvpn/core/VpnStatus.java
+++ b/app/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/app/src/main/java/de/blinkt/openvpn/core/X509Utils.java b/app/src/main/java/de/blinkt/openvpn/core/X509Utils.java
index ff383e0f..0786967b 100644
--- a/app/src/main/java/de/blinkt/openvpn/core/X509Utils.java
+++ b/app/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/app/src/main/java/de/blinkt/openvpn/fragments/LogFragment.java b/app/src/main/java/de/blinkt/openvpn/fragments/LogFragment.java
index 77fc21e6..199caa63 100644
--- a/app/src/main/java/de/blinkt/openvpn/fragments/LogFragment.java
+++ b/app/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/app/src/main/java/de/blinkt/openvpn/views/SeekBarTicks.java b/app/src/main/java/de/blinkt/openvpn/views/SeekBarTicks.java
index e25c2859..82378b00 100644
--- a/app/src/main/java/de/blinkt/openvpn/views/SeekBarTicks.java
+++ b/app/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;