summaryrefslogtreecommitdiff
path: root/app/src/main/java/de
diff options
context:
space:
mode:
authorParménides GV <parmegv@sdf.org>2015-01-31 01:19:49 +0100
committerParménides GV <parmegv@sdf.org>2015-01-31 01:19:49 +0100
commitc95a21a736fadb46685e051064b0ec1efdae667a (patch)
tree90c4af22d047b7297a66a9e623c86c5af63b12f6 /app/src/main/java/de
parent1a4643dc08a86dcd9650afa2255945df14445f2d (diff)
Updated ics-openvpn to rev 1020.
Improved build.gradle script.
Diffstat (limited to 'app/src/main/java/de')
-rw-r--r--app/src/main/java/de/blinkt/openvpn/core/ConfigParser.java1030
-rw-r--r--app/src/main/java/de/blinkt/openvpn/core/NetworkSpace.java13
-rw-r--r--app/src/main/java/de/blinkt/openvpn/core/OpenVPNService.java34
3 files changed, 543 insertions, 534 deletions
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 5dc96bbc..5f5d486c 100644
--- a/app/src/main/java/de/blinkt/openvpn/core/ConfigParser.java
+++ b/app/src/main/java/de/blinkt/openvpn/core/ConfigParser.java
@@ -28,11 +28,11 @@ import de.blinkt.openvpn.VpnProfile;
public class ConfigParser {
- public static final String CONVERTED_PROFILE = "converted Profile";
- private HashMap<String, Vector<Vector<String>>> options = new HashMap<String, Vector<Vector<String>>>();
- private HashMap<String, Vector<String>> meta = new HashMap<String, Vector<String>>();
+ public static final String CONVERTED_PROFILE = "converted Profile";
+ private HashMap<String, Vector<Vector<String>>> options = new HashMap<String, Vector<Vector<String>>>();
+ private HashMap<String, Vector<String>> meta = new HashMap<String, Vector<String>>();
- public void parseConfig(Reader reader) throws IOException, ConfigParseError {
+ public void parseConfig(Reader reader) throws IOException, ConfigParseError {
BufferedReader br = new BufferedReader(reader);
@@ -75,192 +75,176 @@ public class ConfigParser {
} catch (java.lang.OutOfMemoryError memoryError) {
throw new ConfigParseError("File too large to parse: " + memoryError.getLocalizedMessage());
}
- }
+ }
- private Vector<String> parsemeta(String line) {
- String meta = line.split("#\\sOVPN_ACCESS_SERVER_", 2)[1];
- String[] parts = meta.split("=",2);
- Vector<String> rval = new Vector<String>();
+ private Vector<String> parsemeta(String line) {
+ String meta = line.split("#\\sOVPN_ACCESS_SERVER_", 2)[1];
+ String[] parts = meta.split("=", 2);
+ Vector<String> rval = new Vector<String>();
Collections.addAll(rval, parts);
- return rval;
-
- }
-
- private void checkinlinefile(Vector<String> args, BufferedReader br) throws IOException, ConfigParseError {
- String arg0 = args.get(0).trim();
- // CHeck for <foo>
- if(arg0.startsWith("<") && arg0.endsWith(">")) {
- String argname = arg0.substring(1, arg0.length()-1);
- String inlinefile = VpnProfile.INLINE_TAG;
-
- String endtag = String.format("</%s>",argname);
- do {
- String line = br.readLine();
- if(line==null){
- throw new ConfigParseError(String.format("No endtag </%s> for starttag <%s> found",argname,argname));
- }
- if(line.trim().equals(endtag))
- break;
- else {
- inlinefile+=line;
- inlinefile+= "\n";
- }
- } while(true);
-
- args.clear();
- args.add(argname);
- args.add(inlinefile);
- }
-
- }
-
- enum linestate {
- initial,
- readin_single_quote
- , reading_quoted, reading_unquoted, done}
-
- private boolean space(char c) {
- // I really hope nobody is using zero bytes inside his/her config file
- // to sperate parameter but here we go:
- return Character.isWhitespace(c) || c == '\0';
-
- }
-
- public class ConfigParseError extends Exception {
- private static final long serialVersionUID = -60L;
-
- public ConfigParseError(String msg) {
- super(msg);
- }
- }
-
-
- // adapted openvpn's parse function to java
- private Vector<String> parseline(String line) throws ConfigParseError {
- Vector<String> parameters = new Vector<String>();
-
- if (line.length()==0)
- return parameters;
-
-
- linestate state = linestate.initial;
- boolean backslash = false;
- char out=0;
-
- int pos=0;
- String currentarg="";
-
- do {
- // Emulate the c parsing ...
- char in;
- if(pos < line.length())
- in = line.charAt(pos);
- else
- in = '\0';
-
- if (!backslash && in == '\\' && state != linestate.readin_single_quote)
- {
- backslash = true;
- }
- else
- {
- if (state == linestate.initial)
- {
- if (!space (in))
- {
- if (in == ';' || in == '#') /* comment */
- break;
- if (!backslash && in == '\"')
- state = linestate.reading_quoted;
- else if (!backslash && in == '\'')
- state = linestate.readin_single_quote;
- else
- {
- out = in;
- state = linestate.reading_unquoted;
- }
- }
- }
- else if (state == linestate.reading_unquoted)
- {
- if (!backslash && space (in))
- state = linestate.done;
- else
- out = in;
- }
- else if (state == linestate.reading_quoted)
- {
- if (!backslash && in == '\"')
- state = linestate.done;
- else
- out = in;
- }
- else if (state == linestate.readin_single_quote)
- {
- if (in == '\'')
- state = linestate.done;
- else
- out = in;
- }
-
- if (state == linestate.done)
- {
- /* ASSERT (parm_len > 0); */
- state = linestate.initial;
- parameters.add(currentarg);
- currentarg = "";
- out =0;
- }
-
- if (backslash && out!=0)
- {
- if (!(out == '\\' || out == '\"' || space (out)))
- {
- throw new ConfigParseError("Options warning: Bad backslash ('\\') usage");
- }
- }
- backslash = false;
- }
+ return rval;
+
+ }
+
+ private void checkinlinefile(Vector<String> args, BufferedReader br) throws IOException, ConfigParseError {
+ String arg0 = args.get(0).trim();
+ // CHeck for <foo>
+ if (arg0.startsWith("<") && arg0.endsWith(">")) {
+ String argname = arg0.substring(1, arg0.length() - 1);
+ String inlinefile = VpnProfile.INLINE_TAG;
+
+ String endtag = String.format("</%s>", argname);
+ do {
+ String line = br.readLine();
+ if (line == null) {
+ throw new ConfigParseError(String.format("No endtag </%s> for starttag <%s> found", argname, argname));
+ }
+ if (line.trim().equals(endtag))
+ break;
+ else {
+ inlinefile += line;
+ inlinefile += "\n";
+ }
+ } while (true);
+
+ args.clear();
+ args.add(argname);
+ args.add(inlinefile);
+ }
+
+ }
+
+ enum linestate {
+ initial,
+ readin_single_quote, reading_quoted, reading_unquoted, done
+ }
+
+ private boolean space(char c) {
+ // I really hope nobody is using zero bytes inside his/her config file
+ // to sperate parameter but here we go:
+ return Character.isWhitespace(c) || c == '\0';
+
+ }
+
+ public class ConfigParseError extends Exception {
+ private static final long serialVersionUID = -60L;
+
+ public ConfigParseError(String msg) {
+ super(msg);
+ }
+ }
+
+
+ // adapted openvpn's parse function to java
+ private Vector<String> parseline(String line) throws ConfigParseError {
+ Vector<String> parameters = new Vector<String>();
+
+ if (line.length() == 0)
+ return parameters;
+
+
+ linestate state = linestate.initial;
+ boolean backslash = false;
+ char out = 0;
+
+ int pos = 0;
+ String currentarg = "";
+
+ do {
+ // Emulate the c parsing ...
+ char in;
+ if (pos < line.length())
+ in = line.charAt(pos);
+ else
+ in = '\0';
+
+ if (!backslash && in == '\\' && state != linestate.readin_single_quote) {
+ backslash = true;
+ } else {
+ if (state == linestate.initial) {
+ if (!space(in)) {
+ if (in == ';' || in == '#') /* comment */
+ break;
+ if (!backslash && in == '\"')
+ state = linestate.reading_quoted;
+ else if (!backslash && in == '\'')
+ state = linestate.readin_single_quote;
+ else {
+ out = in;
+ state = linestate.reading_unquoted;
+ }
+ }
+ } else if (state == linestate.reading_unquoted) {
+ if (!backslash && space(in))
+ state = linestate.done;
+ else
+ out = in;
+ } else if (state == linestate.reading_quoted) {
+ if (!backslash && in == '\"')
+ state = linestate.done;
+ else
+ out = in;
+ } else if (state == linestate.readin_single_quote) {
+ if (in == '\'')
+ state = linestate.done;
+ else
+ out = in;
+ }
+
+ if (state == linestate.done) {
+ /* ASSERT (parm_len > 0); */
+ state = linestate.initial;
+ parameters.add(currentarg);
+ currentarg = "";
+ out = 0;
+ }
+
+ if (backslash && out != 0) {
+ if (!(out == '\\' || out == '\"' || space(out))) {
+ throw new ConfigParseError("Options warning: Bad backslash ('\\') usage");
+ }
+ }
+ backslash = false;
+ }
/* store parameter character */
- if (out!=0)
- {
- currentarg+=out;
- }
- } while (pos++ < line.length());
-
- return parameters;
- }
-
-
- final String[] unsupportedOptions = { "config",
- "tls-server"
-
- };
-
- // Ignore all scripts
- // in most cases these won't work and user who wish to execute scripts will
- // figure out themselves
- final String[] ignoreOptions = { "tls-client",
- "askpass",
- "auth-nocache",
- "up",
- "down",
- "route-up",
- "ipchange",
- "route-up",
- "route-pre-down",
- "auth-user-pass-verify",
- "dhcp-release",
- "dhcp-renew",
- "dh",
+ if (out != 0) {
+ currentarg += out;
+ }
+ } while (pos++ < line.length());
+
+ return parameters;
+ }
+
+
+ final String[] unsupportedOptions = {"config",
+ "tls-server"
+
+ };
+
+ // Ignore all scripts
+ // in most cases these won't work and user who wish to execute scripts will
+ // figure out themselves
+ final String[] ignoreOptions = {"tls-client",
+ "askpass",
+ "auth-nocache",
+ "up",
+ "down",
+ "route-up",
+ "ipchange",
+ "route-up",
+ "route-pre-down",
+ "auth-user-pass-verify",
+ "dhcp-release",
+ "dhcp-renew",
+ "dh",
"group",
"ip-win32",
"management-hold",
"management",
"management-client",
"management-query-remote",
- "management-query-passwords",
+ "management-query-passwords",
"management-query-proxy",
"management-external-key",
"management-forget-disconnect",
@@ -269,32 +253,32 @@ public class ConfigParser {
"management-up-down",
"management-client-user",
"management-client-group",
- "pause-exit",
+ "pause-exit",
"plugin",
"machine-readable-output",
- "persist-key",
- "register-dns",
- "route-delay",
- "route-gateway",
- "route-metric",
- "route-method",
- "status",
- "script-security",
- "show-net-up",
- "suppress-timestamps",
- "tmp-dir",
- "tun-ipv6",
- "topology",
+ "persist-key",
+ "register-dns",
+ "route-delay",
+ "route-gateway",
+ "route-metric",
+ "route-method",
+ "status",
+ "script-security",
+ "show-net-up",
+ "suppress-timestamps",
+ "tmp-dir",
+ "tun-ipv6",
+ "topology",
"user",
"win-sys",
-
};
final String[][] ignoreOptionsWithArg =
- {
- {"setenv", "IV_GUI_VER"},
- {"setenv", "IV_OPENVPN_GUI_VERSION"}
- };
+ {
+ {"setenv", "IV_GUI_VER"},
+ {"setenv", "IV_OPENVPN_GUI_VERSION"},
+ {"engine", "dynamic"}
+ };
final String[] connectionOptions = {
"local",
@@ -326,70 +310,67 @@ public class ConfigParser {
// This method is far too long
- @SuppressWarnings("ConstantConditions")
+ @SuppressWarnings("ConstantConditions")
public VpnProfile convertProfile() throws ConfigParseError, IOException {
- boolean noauthtypeset=true;
- VpnProfile np = new VpnProfile(CONVERTED_PROFILE);
- // Pull, client, tls-client
- np.clearDefaults();
-
- if(options.containsKey("client") || options.containsKey("pull")) {
- np.mUsePull=true;
- options.remove("pull");
- options.remove("client");
- }
-
- Vector<String> secret = getOption("secret", 1, 2);
- if(secret!=null)
- {
- np.mAuthenticationType=VpnProfile.TYPE_STATICKEYS;
- noauthtypeset=false;
- np.mUseTLSAuth=true;
- np.mTLSAuthFilename=secret.get(1);
- if(secret.size()==3)
- np.mTLSAuthDirection=secret.get(2);
-
- }
-
- Vector<Vector<String>> routes = getAllOption("route", 1, 4);
- if(routes!=null) {
- String routeopt = "";
+ boolean noauthtypeset = true;
+ VpnProfile np = new VpnProfile(CONVERTED_PROFILE);
+ // Pull, client, tls-client
+ np.clearDefaults();
+
+ if (options.containsKey("client") || options.containsKey("pull")) {
+ np.mUsePull = true;
+ options.remove("pull");
+ options.remove("client");
+ }
+
+ Vector<String> secret = getOption("secret", 1, 2);
+ if (secret != null) {
+ np.mAuthenticationType = VpnProfile.TYPE_STATICKEYS;
+ noauthtypeset = false;
+ np.mUseTLSAuth = true;
+ np.mTLSAuthFilename = secret.get(1);
+ if (secret.size() == 3)
+ np.mTLSAuthDirection = secret.get(2);
+
+ }
+
+ Vector<Vector<String>> routes = getAllOption("route", 1, 4);
+ if (routes != null) {
+ String routeopt = "";
String routeExcluded = "";
- for(Vector<String> route:routes){
- String netmask = "255.255.255.255";
+ for (Vector<String> route : routes) {
+ String netmask = "255.255.255.255";
String gateway = "vpn_gateway";
- if(route.size() >= 3)
- netmask = route.get(2);
+ if (route.size() >= 3)
+ netmask = route.get(2);
if (route.size() >= 4)
gateway = route.get(3);
- String net = route.get(1);
- try {
- CIDRIP cidr = new CIDRIP(net, netmask);
+ String net = route.get(1);
+ try {
+ CIDRIP cidr = new CIDRIP(net, netmask);
if (gateway.equals("net_gateway"))
routeExcluded += cidr.toString() + " ";
else
- routeopt+=cidr.toString() + " ";
- } catch (ArrayIndexOutOfBoundsException aioob) {
- throw new ConfigParseError("Could not parse netmask of route " + netmask);
- } catch (NumberFormatException ne) {
-
-
+ routeopt += cidr.toString() + " ";
+ } catch (ArrayIndexOutOfBoundsException aioob) {
+ throw new ConfigParseError("Could not parse netmask of route " + netmask);
+ } catch (NumberFormatException ne) {
- throw new ConfigParseError("Could not parse netmask of route " + netmask);
- }
+ throw new ConfigParseError("Could not parse netmask of route " + netmask);
+ }
- }
- np.mCustomRoutes=routeopt;
- np.mExcludedRoutes=routeExcluded;
- }
+ }
+ np.mCustomRoutes = routeopt;
+ np.mExcludedRoutes = routeExcluded;
+ }
Vector<Vector<String>> routesV6 = getAllOption("route-ipv6", 1, 4);
- if (routesV6!=null) {
+ if (routesV6 != null) {
String customIPv6Routes = "";
- for (Vector<String> route:routesV6){
+ for (Vector<String> route : routesV6) {
customIPv6Routes += route.get(1) + " ";
}
@@ -397,39 +378,36 @@ public class ConfigParser {
}
// Also recognize tls-auth [inline] direction ...
- Vector<Vector<String>> tlsauthoptions = getAllOption("tls-auth", 1, 2);
- if(tlsauthoptions!=null) {
- for(Vector<String> tlsauth:tlsauthoptions) {
- if(tlsauth!=null)
- {
- if(!tlsauth.get(1).equals("[inline]")) {
- np.mTLSAuthFilename=tlsauth.get(1);
- np.mUseTLSAuth=true;
- }
- if(tlsauth.size()==3)
- np.mTLSAuthDirection=tlsauth.get(2);
- }
- }
- }
-
- Vector<String> direction = getOption("key-direction", 1, 1);
- if(direction!=null)
- np.mTLSAuthDirection=direction.get(1);
+ Vector<Vector<String>> tlsauthoptions = getAllOption("tls-auth", 1, 2);
+ if (tlsauthoptions != null) {
+ for (Vector<String> tlsauth : tlsauthoptions) {
+ if (tlsauth != null) {
+ if (!tlsauth.get(1).equals("[inline]")) {
+ np.mTLSAuthFilename = tlsauth.get(1);
+ np.mUseTLSAuth = true;
+ }
+ if (tlsauth.size() == 3)
+ np.mTLSAuthDirection = tlsauth.get(2);
+ }
+ }
+ }
+
+ Vector<String> direction = getOption("key-direction", 1, 1);
+ if (direction != null)
+ np.mTLSAuthDirection = direction.get(1);
Vector<Vector<String>> defgw = getAllOption("redirect-gateway", 0, 5);
- if(defgw != null)
- {
- np.mUseDefaultRoute=true;
+ if (defgw != null) {
+ np.mUseDefaultRoute = true;
checkRedirectParameters(np, defgw);
}
- Vector<Vector<String>> redirectPrivate = getAllOption("redirect-private",0,5);
- if (redirectPrivate != null)
- {
- checkRedirectParameters(np,redirectPrivate);
+ Vector<Vector<String>> redirectPrivate = getAllOption("redirect-private", 0, 5);
+ if (redirectPrivate != null) {
+ checkRedirectParameters(np, redirectPrivate);
}
- Vector<String> dev =getOption("dev",1,1);
- Vector<String> devtype =getOption("dev-type",1,1);
+ Vector<String> dev = getOption("dev", 1, 1);
+ Vector<String> devtype = getOption("dev-type", 1, 1);
if ((devtype != null && devtype.get(1).equals("tun")) ||
(dev != null && dev.get(1).startsWith("tun")) ||
@@ -437,15 +415,15 @@ public class ConfigParser {
//everything okay
} else {
throw new ConfigParseError("Sorry. Only tun mode is supported. See the FAQ for more detail");
- }
+ }
- Vector<String> mssfix = getOption("mssfix",0,1);
+ Vector<String> mssfix = getOption("mssfix", 0, 1);
- if (mssfix!=null) {
- if (mssfix.size()>=2) {
+ if (mssfix != null) {
+ if (mssfix.size() >= 2) {
try {
- np.mMssFix=Integer.parseInt(mssfix.get(1));
- } catch(NumberFormatException e) {
+ np.mMssFix = Integer.parseInt(mssfix.get(1));
+ } catch (NumberFormatException e) {
throw new ConfigParseError("Argument to --mssfix has to be an integer");
}
} else {
@@ -454,172 +432,171 @@ public class ConfigParser {
}
- Vector<String> mode =getOption("mode",1,1);
- if (mode != null){
- if(!mode.get(1).equals("p2p"))
- throw new ConfigParseError("Invalid mode for --mode specified, need p2p");
- }
-
-
-
- Vector<Vector<String>> dhcpoptions = getAllOption("dhcp-option", 2, 2);
- if(dhcpoptions!=null) {
- for(Vector<String> dhcpoption:dhcpoptions) {
- String type=dhcpoption.get(1);
- String arg = dhcpoption.get(2);
- if(type.equals("DOMAIN")) {
- np.mSearchDomain=dhcpoption.get(2);
- } else if(type.equals("DNS")) {
- np.mOverrideDNS=true;
- if(np.mDNS1.equals(VpnProfile.DEFAULT_DNS1))
- np.mDNS1=arg;
- else
- np.mDNS2=arg;
- }
- }
- }
-
- Vector<String> ifconfig = getOption("ifconfig", 2, 2);
- if(ifconfig!=null) {
- try {
- CIDRIP cidr = new CIDRIP(ifconfig.get(1), ifconfig.get(2));
- np.mIPv4Address=cidr.toString();
- } catch (NumberFormatException nfe) {
- throw new ConfigParseError("Could not pase ifconfig IP address: " + nfe.getLocalizedMessage());
- }
-
- }
-
- if(getOption("remote-random-hostname", 0, 0)!=null)
- np.mUseRandomHostname=true;
-
- if(getOption("float", 0, 0)!=null)
- np.mUseFloat=true;
-
- if(getOption("comp-lzo", 0, 1)!=null)
- np.mUseLzo=true;
-
- Vector<String> cipher = getOption("cipher", 1, 1);
- if(cipher!=null)
- np.mCipher= cipher.get(1);
-
- Vector<String> auth = getOption("auth", 1, 1);
- if(auth!=null)
- np.mAuth = auth.get(1);
-
-
- Vector<String> ca = getOption("ca",1,1);
- if(ca!=null){
- np.mCaFilename = ca.get(1);
- }
-
- Vector<String> cert = getOption("cert",1,1);
- if(cert!=null){
- np.mClientCertFilename = cert.get(1);
- np.mAuthenticationType = VpnProfile.TYPE_CERTIFICATES;
- noauthtypeset=false;
- }
- Vector<String> key= getOption("key",1,1);
- if(key!=null)
- np.mClientKeyFilename=key.get(1);
-
- Vector<String> pkcs12 = getOption("pkcs12",1,1);
- if(pkcs12!=null) {
- np.mPKCS12Filename = pkcs12.get(1);
- np.mAuthenticationType = VpnProfile.TYPE_KEYSTORE;
- noauthtypeset=false;
- }
-
- Vector<String> cryptoapicert = getOption("cryptoapicert",1,1);
- if(cryptoapicert!=null) {
+ Vector<String> mode = getOption("mode", 1, 1);
+ if (mode != null) {
+ if (!mode.get(1).equals("p2p"))
+ throw new ConfigParseError("Invalid mode for --mode specified, need p2p");
+ }
+
+
+ Vector<Vector<String>> dhcpoptions = getAllOption("dhcp-option", 2, 2);
+ if (dhcpoptions != null) {
+ for (Vector<String> dhcpoption : dhcpoptions) {
+ String type = dhcpoption.get(1);
+ String arg = dhcpoption.get(2);
+ if (type.equals("DOMAIN")) {
+ np.mSearchDomain = dhcpoption.get(2);
+ } else if (type.equals("DNS")) {
+ np.mOverrideDNS = true;
+ if (np.mDNS1.equals(VpnProfile.DEFAULT_DNS1))
+ np.mDNS1 = arg;
+ else
+ np.mDNS2 = arg;
+ }
+ }
+ }
+
+ Vector<String> ifconfig = getOption("ifconfig", 2, 2);
+ if (ifconfig != null) {
+ try {
+ CIDRIP cidr = new CIDRIP(ifconfig.get(1), ifconfig.get(2));
+ np.mIPv4Address = cidr.toString();
+ } catch (NumberFormatException nfe) {
+ throw new ConfigParseError("Could not pase ifconfig IP address: " + nfe.getLocalizedMessage());
+ }
+
+ }
+
+ if (getOption("remote-random-hostname", 0, 0) != null)
+ np.mUseRandomHostname = true;
+
+ if (getOption("float", 0, 0) != null)
+ np.mUseFloat = true;
+
+ if (getOption("comp-lzo", 0, 1) != null)
+ np.mUseLzo = true;
+
+ Vector<String> cipher = getOption("cipher", 1, 1);
+ if (cipher != null)
+ np.mCipher = cipher.get(1);
+
+ Vector<String> auth = getOption("auth", 1, 1);
+ if (auth != null)
+ np.mAuth = auth.get(1);
+
+
+ Vector<String> ca = getOption("ca", 1, 1);
+ if (ca != null) {
+ np.mCaFilename = ca.get(1);
+ }
+
+ Vector<String> cert = getOption("cert", 1, 1);
+ if (cert != null) {
+ np.mClientCertFilename = cert.get(1);
+ np.mAuthenticationType = VpnProfile.TYPE_CERTIFICATES;
+ noauthtypeset = false;
+ }
+ Vector<String> key = getOption("key", 1, 1);
+ if (key != null)
+ np.mClientKeyFilename = key.get(1);
+
+ Vector<String> pkcs12 = getOption("pkcs12", 1, 1);
+ if (pkcs12 != null) {
+ np.mPKCS12Filename = pkcs12.get(1);
np.mAuthenticationType = VpnProfile.TYPE_KEYSTORE;
- noauthtypeset=false;
+ noauthtypeset = false;
}
- Vector<String> compatnames = getOption("compat-names",1,2);
- Vector<String> nonameremapping = getOption("no-name-remapping",1,1);
- Vector<String> tlsremote = getOption("tls-remote",1,1);
- if(tlsremote!=null){
- np.mRemoteCN = tlsremote.get(1);
- np.mCheckRemoteCN=true;
- np.mX509AuthType = VpnProfile.X509_VERIFY_TLSREMOTE;
+ Vector<String> cryptoapicert = getOption("cryptoapicert", 1, 1);
+ if (cryptoapicert != null) {
+ np.mAuthenticationType = VpnProfile.TYPE_KEYSTORE;
+ noauthtypeset = false;
+ }
- if((compatnames!=null && compatnames.size() > 2) ||
- (nonameremapping!=null))
- np.mX509AuthType = VpnProfile.X509_VERIFY_TLSREMOTE_COMPAT_NOREMAPPING;
- }
+ Vector<String> compatnames = getOption("compat-names", 1, 2);
+ Vector<String> nonameremapping = getOption("no-name-remapping", 1, 1);
+ Vector<String> tlsremote = getOption("tls-remote", 1, 1);
+ if (tlsremote != null) {
+ np.mRemoteCN = tlsremote.get(1);
+ np.mCheckRemoteCN = true;
+ np.mX509AuthType = VpnProfile.X509_VERIFY_TLSREMOTE;
+
+ if ((compatnames != null && compatnames.size() > 2) ||
+ (nonameremapping != null))
+ np.mX509AuthType = VpnProfile.X509_VERIFY_TLSREMOTE_COMPAT_NOREMAPPING;
+ }
- Vector<String> verifyx509name = getOption("verify-x509-name",1,2);
- if(verifyx509name!=null){
- np.mRemoteCN = verifyx509name.get(1);
- np.mCheckRemoteCN=true;
- 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
- throw new ConfigParseError("Unknown parameter to x509-verify-name: " + verifyx509name.get(2) );
- } else {
- np.mX509AuthType = VpnProfile.X509_VERIFY_TLSREMOTE_DN;
- }
+ Vector<String> verifyx509name = getOption("verify-x509-name", 1, 2);
+ if (verifyx509name != null) {
+ np.mRemoteCN = verifyx509name.get(1);
+ np.mCheckRemoteCN = true;
+ 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
+ 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);
- if(verb!=null){
- np.mVerb=verb.get(1);
- }
+ Vector<String> verb = getOption("verb", 1, 1);
+ if (verb != null) {
+ np.mVerb = verb.get(1);
+ }
- if(getOption("nobind", 0, 0) != null)
- np.mNobind=true;
+ if (getOption("nobind", 0, 0) != null)
+ np.mNobind = true;
- if(getOption("persist-tun", 0,0) != null)
- np.mPersistTun=true;
+ if (getOption("persist-tun", 0, 0) != null)
+ np.mPersistTun = true;
- Vector<String> connectretry = getOption("connect-retry", 1, 1);
- if(connectretry!=null)
- np.mConnectRetry =connectretry.get(1);
+ Vector<String> connectretry = getOption("connect-retry", 1, 1);
+ if (connectretry != null)
+ np.mConnectRetry = connectretry.get(1);
- Vector<String> connectretrymax = getOption("connect-retry-max", 1, 1);
- if(connectretrymax!=null)
- np.mConnectRetryMax =connectretrymax.get(1);
+ Vector<String> connectretrymax = getOption("connect-retry-max", 1, 1);
+ if (connectretrymax != null)
+ np.mConnectRetryMax = connectretrymax.get(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;
- else
- options.put("remotetls",remotetls);
-
- Vector<String> authuser = getOption("auth-user-pass",0,1);
- if(authuser !=null){
- if(noauthtypeset) {
- np.mAuthenticationType=VpnProfile.TYPE_USERPASS;
- } else if(np.mAuthenticationType==VpnProfile.TYPE_CERTIFICATES) {
- np.mAuthenticationType=VpnProfile.TYPE_USERPASS_CERTIFICATES;
- } else if(np.mAuthenticationType==VpnProfile.TYPE_KEYSTORE) {
- np.mAuthenticationType=VpnProfile.TYPE_USERPASS_KEYSTORE;
- }
- if(authuser.size()>1) {
- // Set option value to password get to embed later.
- np.mUsername=null;
- useEmbbedUserAuth(np, authuser.get(1));
- }
- }
+ if (remotetls != null)
+ if (remotetls.get(0).get(1).equals("server"))
+ np.mExpectTLSCert = true;
+ else
+ options.put("remotetls", remotetls);
+
+ Vector<String> authuser = getOption("auth-user-pass", 0, 1);
+ if (authuser != null) {
+ if (noauthtypeset) {
+ np.mAuthenticationType = VpnProfile.TYPE_USERPASS;
+ } else if (np.mAuthenticationType == VpnProfile.TYPE_CERTIFICATES) {
+ np.mAuthenticationType = VpnProfile.TYPE_USERPASS_CERTIFICATES;
+ } else if (np.mAuthenticationType == VpnProfile.TYPE_KEYSTORE) {
+ np.mAuthenticationType = VpnProfile.TYPE_USERPASS_KEYSTORE;
+ }
+ if (authuser.size() > 1) {
+ // Set option value to password get to embed later.
+ np.mUsername = null;
+ useEmbbedUserAuth(np, authuser.get(1));
+ }
+ }
Pair<Connection, Connection[]> conns = parseConnectionOptions(null);
- np.mConnections =conns.second;
+ 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 (np.mConnections.length > 0 && connectionBlocks != null) {
+ throw new ConfigParseError("Using a <connection> block and --remote is not allowed.");
}
- if (connectionBlocks!=null) {
+ if (connectionBlocks != null) {
np.mConnections = new Connection[connectionBlocks.size()];
int connIndex = 0;
@@ -633,43 +610,43 @@ public class ConfigParser {
connIndex++;
}
}
- if(getOption("remote-random", 0, 0) != null)
- np.mRemoteRandom=true;
+ if (getOption("remote-random", 0, 0) != null)
+ np.mRemoteRandom = true;
Vector<String> protoforce = getOption("proto-force", 1, 1);
- if(protoforce!=null) {
+ if (protoforce != null) {
boolean disableUDP;
String protoToDisable = protoforce.get(1);
if (protoToDisable.equals("udp"))
- disableUDP=true;
+ disableUDP = true;
else if (protoToDisable.equals("tcp"))
- disableUDP=false;
+ 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;
+ 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);
+ Vector<String> friendlyname = meta.get("FRIENDLY_NAME");
+ if (friendlyname != null && friendlyname.size() > 1)
+ np.mName = friendlyname.get(1);
- Vector<String> ocusername = meta.get("USERNAME");
- if(ocusername !=null && ocusername.size() > 1)
- np.mUsername=ocusername.get(1);
+ Vector<String> ocusername = meta.get("USERNAME");
+ if (ocusername != null && ocusername.size() > 1)
+ np.mUsername = ocusername.get(1);
checkIgnoreAndInvalidOptions(np);
- fixup(np);
+ fixup(np);
- return np;
- }
+ return np;
+ }
private Pair<Connection, Connection[]> parseConnection(String connection, Connection defaultValues) throws IOException, ConfigParseError {
- // Parse a connection Block as a new configuration file
+ // Parse a connection Block as a new configuration file
ConfigParser connectionParser = new ConfigParser();
@@ -683,7 +660,7 @@ public class ConfigParser {
private Pair<Connection, Connection[]> parseConnectionOptions(Connection connDefault) throws ConfigParseError {
Connection conn;
- if (connDefault!=null)
+ if (connDefault != null)
try {
conn = connDefault.clone();
} catch (CloneNotSupportedException e) {
@@ -693,28 +670,28 @@ public class ConfigParser {
else
conn = new Connection();
- Vector<String> port = getOption("port", 1,1);
- if(port!=null){
+ 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){
+ 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));
+ 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);
+ Vector<Vector<String>> remotes = getAllOption("remote", 1, 3);
// Assume that we need custom options if connectionDefault are set
- if(connDefault!=null) {
+ if (connDefault != null) {
for (Vector<Vector<String>> option : options.values()) {
conn.mCustomConfiguration += getOptionStrings(option);
@@ -724,14 +701,14 @@ public class ConfigParser {
conn.mUseCustomConfig = true;
}
// Make remotes empty to simplify code
- if (remotes==null)
+ if (remotes == null)
remotes = new Vector<Vector<String>>();
Connection[] connections = new Connection[remotes.size()];
- int i=0;
- for (Vector<String> remote: remotes) {
+ int i = 0;
+ for (Vector<String> remote : remotes) {
try {
connections[i] = conn.clone();
} catch (CloneNotSupportedException e) {
@@ -739,7 +716,7 @@ public class ConfigParser {
}
switch (remote.size()) {
case 4:
- connections[i].mUseUdp=isUdpProto(remote.get(3));
+ connections[i].mUseUdp = isUdpProto(remote.get(3));
case 3:
connections[i].mServerPort = remote.get(2);
case 2:
@@ -752,63 +729,60 @@ public class ConfigParser {
}
private void checkRedirectParameters(VpnProfile np, Vector<Vector<String>> defgw) {
- for (Vector<String> redirect: defgw)
- for (int i=1;i<redirect.size();i++){
+ for (Vector<String> redirect : defgw)
+ for (int i = 1; i < redirect.size(); i++) {
if (redirect.get(i).equals("block-local"))
- np.mAllowLocalLAN=false;
+ np.mAllowLocalLAN = false;
else if (redirect.get(i).equals("unblock-local"))
- np.mAllowLocalLAN=true;
+ np.mAllowLocalLAN = true;
}
}
- 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("tcp6") ||
- proto.endsWith("tcp6-client"))
- isudp =false;
- else
- throw new ConfigParseError("Unsupported option to --proto " + proto);
- return isudp;
- }
-
- static public void useEmbbedUserAuth(VpnProfile np, String inlinedata)
- {
- String data = VpnProfile.getEmbeddedContent(inlinedata);
- String[] parts = data.split("\n");
- if(parts.length >= 2) {
- np.mUsername=parts[0];
- np.mPassword=parts[1];
- }
- }
-
- private void checkIgnoreAndInvalidOptions(VpnProfile np) throws ConfigParseError {
- for(String option:unsupportedOptions)
- if(options.containsKey(option))
- throw new ConfigParseError(String.format("Unsupported Option %s encountered in config file. Aborting",option));
+ 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("tcp6") ||
+ proto.endsWith("tcp6-client"))
+ isudp = false;
+ else
+ throw new ConfigParseError("Unsupported option to --proto " + proto);
+ return isudp;
+ }
- for(String option:ignoreOptions)
- // removing an item which is not in the map is no error
- options.remove(option);
+ static public void useEmbbedUserAuth(VpnProfile np, String inlinedata) {
+ String data = VpnProfile.getEmbeddedContent(inlinedata);
+ String[] parts = data.split("\n");
+ if (parts.length >= 2) {
+ np.mUsername = parts[0];
+ np.mPassword = parts[1];
+ }
+ }
+ private void checkIgnoreAndInvalidOptions(VpnProfile np) throws ConfigParseError {
+ for (String option : unsupportedOptions)
+ if (options.containsKey(option))
+ throw new ConfigParseError(String.format("Unsupported Option %s encountered in config file. Aborting", option));
+ for (String option : ignoreOptions)
+ // removing an item which is not in the map is no error
+ options.remove(option);
- if(options.size()> 0) {
- np.mCustomConfigOptions += "# These Options were found in the config file do not map to config settings:\n";
+ if (options.size() > 0) {
+ np.mCustomConfigOptions += "# These Options were found in the config file do not map to config settings:\n";
- for(Vector<Vector<String>> option:options.values()) {
+ for (Vector<Vector<String>> option : options.values()) {
- np.mCustomConfigOptions += getOptionStrings(option);
+ np.mCustomConfigOptions += getOptionStrings(option);
- }
- np.mUseCustomConfig=true;
+ }
+ np.mUseCustomConfig = true;
- }
- }
+ }
+ }
boolean ignoreThisOption(Vector<String> option) {
@@ -843,35 +817,35 @@ public class ConfigParser {
private void fixup(VpnProfile np) {
- if(np.mRemoteCN.equals(np.mServerName)) {
- np.mRemoteCN="";
- }
- }
-
- private Vector<String> getOption(String option, int minarg, int maxarg) throws ConfigParseError {
- Vector<Vector<String>> alloptions = getAllOption(option, minarg, maxarg);
- if(alloptions==null)
- return null;
- else
- return alloptions.lastElement();
- }
-
-
- private Vector<Vector<String>> getAllOption(String option, int minarg, int maxarg) throws ConfigParseError {
- Vector<Vector<String>> args = options.get(option);
- if(args==null)
- return null;
-
- for(Vector<String> optionline:args)
-
- if(optionline.size()< (minarg+1) || optionline.size() > maxarg+1) {
- String err = String.format(Locale.getDefault(),"Option %s has %d parameters, expected between %d and %d",
- option,optionline.size()-1,minarg,maxarg );
- throw new ConfigParseError(err);
- }
- options.remove(option);
- return args;
- }
+ if (np.mRemoteCN.equals(np.mServerName)) {
+ np.mRemoteCN = "";
+ }
+ }
+
+ private Vector<String> getOption(String option, int minarg, int maxarg) throws ConfigParseError {
+ Vector<Vector<String>> alloptions = getAllOption(option, minarg, maxarg);
+ if (alloptions == null)
+ return null;
+ else
+ return alloptions.lastElement();
+ }
+
+
+ private Vector<Vector<String>> getAllOption(String option, int minarg, int maxarg) throws ConfigParseError {
+ Vector<Vector<String>> args = options.get(option);
+ if (args == null)
+ return null;
+
+ for (Vector<String> optionline : args)
+
+ if (optionline.size() < (minarg + 1) || optionline.size() > maxarg + 1) {
+ String err = String.format(Locale.getDefault(), "Option %s has %d parameters, expected between %d and %d",
+ option, optionline.size() - 1, minarg, maxarg);
+ throw new ConfigParseError(err);
+ }
+ options.remove(option);
+ return args;
+ }
}
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 26354689..c86f9e44 100644
--- a/app/src/main/java/de/blinkt/openvpn/core/NetworkSpace.java
+++ b/app/src/main/java/de/blinkt/openvpn/core/NetworkSpace.java
@@ -172,8 +172,16 @@ public class NetworkSpace {
}
public boolean containsNet(ipAddress network) {
- return getFirstAddress().compareTo(network.getFirstAddress()) != 1 &&
- getLastAddress().compareTo(network.getLastAddress()) != -1;
+ // this.first >= net.first && this.last <= net.last
+ BigInteger ourFirst = getFirstAddress();
+ BigInteger ourLast = getLastAddress();
+ BigInteger netFirst = network.getFirstAddress();
+ BigInteger netLast = network.getLastAddress();
+
+ boolean a = ourFirst.compareTo(netFirst) != 1;
+ boolean b = ourLast.compareTo(netLast) != -1;
+ return a && b;
+
}
}
@@ -320,6 +328,7 @@ public class NetworkSpace {
boolean skipIp=false;
// If there is any smaller net that is excluded we may not add the positive route back
+
for (ipAddress calculatedIp: ipsSorted) {
if(!calculatedIp.included && origIp.containsNet(calculatedIp)) {
skipIp=true;
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 3cb5527b..3c1ec064 100644
--- a/app/src/main/java/de/blinkt/openvpn/core/OpenVPNService.java
+++ b/app/src/main/java/de/blinkt/openvpn/core/OpenVPNService.java
@@ -51,6 +51,8 @@ import static de.blinkt.openvpn.core.NetworkSpace.ipAddress;
import static de.blinkt.openvpn.core.VpnStatus.ConnectionStatus.LEVEL_CONNECTED;
import static de.blinkt.openvpn.core.VpnStatus.ConnectionStatus.LEVEL_CONNECTING_NO_SERVER_REPLY_YET;
import static de.blinkt.openvpn.core.VpnStatus.ConnectionStatus.LEVEL_WAITING_FOR_USER_INPUT;
+import static de.blinkt.openvpn.core.VpnStatus.ConnectionStatus.LEVEL_NOTCONNECTED;
+import static de.blinkt.openvpn.core.VpnStatus.ConnectionStatus.LEVEL_NONETWORK;
import se.leap.bitmaskclient.Dashboard;
@@ -174,7 +176,7 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac
mNotificationManager.notify(OPENVPN_STATUS, notification);
- startForeground(OPENVPN_STATUS, notification);
+ //startForeground(OPENVPN_STATUS, notification);
}
private int getIconByConnectionStatus(ConnectionStatus level) {
@@ -552,9 +554,15 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac
Collection<ipAddress> positiveIPv4Routes = mRoutes.getPositiveIPList();
Collection<ipAddress> positiveIPv6Routes = mRoutesv6.getPositiveIPList();
+ ipAddress multicastRange = new ipAddress(new CIDRIP("224.0.0.0", 3), true);
+
for (NetworkSpace.ipAddress route : positiveIPv4Routes) {
try {
- builder.addRoute(route.getIPv4Address(), route.networkMask);
+
+ if (multicastRange.containsNet(route))
+ VpnStatus.logDebug(R.string.ignore_multicast_route, route.toString());
+ else
+ builder.addRoute(route.getIPv4Address(), route.networkMask);
} catch (IllegalArgumentException ia) {
VpnStatus.logError(getString(R.string.route_rejected) + route + " " + ia.getLocalizedMessage());
}
@@ -607,7 +615,10 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac
try {
//Debug.stopMethodTracing();
- return builder.establish();
+ ParcelFileDescriptor tun = builder.establish();
+ if (tun==null)
+ throw new NullPointerException("Android establish() method returned null (Really broken network configuration?)");
+ return tun;
} catch (Exception e) {
VpnStatus.logError(R.string.tun_open_error);
VpnStatus.logError(getString(R.string.error) + e.getLocalizedMessage());
@@ -843,6 +854,21 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac
mDisplayBytecount = true;
mConnecttime = System.currentTimeMillis();
lowpriority = true;
+ if(mProfile.mPersistTun) {
+ NotificationManager ns = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
+ ns.cancel(OPENVPN_STATUS);
+ return;
+ }
+ } else if (level == LEVEL_NONETWORK || level == LEVEL_NOTCONNECTED) {
+ NotificationManager ns = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
+ ns.cancel(OPENVPN_STATUS);
+ return;
+ } else if (level != LEVEL_NOTCONNECTED && mConnecttime > 0) {
+ mDisplayBytecount = false;
+ String msg = "Traffic is blocked until the VPN becomes active.";
+ String ticker = msg;
+ showNotification(msg, ticker, lowpriority , 0, level);
+ return;
} else {
mDisplayBytecount = false;
}
@@ -876,7 +902,7 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac
humanReadableByteCount(diffOut / OpenVPNManagement.mBytecountInterval, true));
boolean lowpriority = !mNotificationAlwaysVisible;
- showNotification(netstat, null, lowpriority, mConnecttime, LEVEL_CONNECTED);
+ //showNotification(netstat, null, lowpriority, mConnecttime, LEVEL_CONNECTED);
}
}