From 74842cba92591aa9fbf64e8c6f39900a68b0c11c Mon Sep 17 00:00:00 2001 From: cyBerta Date: Fri, 19 Oct 2018 23:15:13 +0200 Subject: #8919 update dependencies --- .../java/de/blinkt/openvpn/core/ConfigParser.java | 379 ++++++++++++--------- 1 file changed, 213 insertions(+), 166 deletions(-) (limited to 'app/src/main/java/de/blinkt/openvpn/core/ConfigParser.java') diff --git a/app/src/main/java/de/blinkt/openvpn/core/ConfigParser.java b/app/src/main/java/de/blinkt/openvpn/core/ConfigParser.java index 9889754d..0148bfb7 100644 --- a/app/src/main/java/de/blinkt/openvpn/core/ConfigParser.java +++ b/app/src/main/java/de/blinkt/openvpn/core/ConfigParser.java @@ -5,17 +5,15 @@ package de.blinkt.openvpn.core; -import android.text.TextUtils; +import android.os.Build; import android.support.v4.util.Pair; +import android.text.TextUtils; import java.io.BufferedReader; import java.io.IOException; import java.io.Reader; import java.io.StringReader; -import java.util.Collections; -import java.util.HashMap; -import java.util.Locale; -import java.util.Vector; +import java.util.*; import de.blinkt.openvpn.VpnProfile; @@ -29,10 +27,127 @@ public class ConfigParser { public static final String CONVERTED_PROFILE = "converted Profile"; - private HashMap>> options = new HashMap>>(); + final String[] unsupportedOptions = {"config", + "tls-server" + + }; + // Ignore all scripts + // in most cases these won't work and user who wish to execute scripts will + // figure out themselves + private final String[] ignoreOptions = {"tls-client", + "allow-recursive-routing", + "askpass", + "auth-nocache", + "up", + "down", + "route-up", + "ipchange", + "route-pre-down", + "auth-user-pass-verify", + "block-outside-dns", + "client-cert-not-required", + "dhcp-release", + "dhcp-renew", + "dh", + "group", + "ip-win32", + "ifconfig-nowarn", + "management-hold", + "management", + "management-client", + "management-query-remote", + "management-query-passwords", + "management-query-proxy", + "management-external-key", + "management-forget-disconnect", + "management-signal", + "management-log-cache", + "management-up-down", + "management-client-user", + "management-client-group", + "pause-exit", + "preresolve", + "plugin", + "machine-readable-output", + "persist-key", + "push", + "register-dns", + "route-delay", + "route-gateway", + "route-metric", + "route-method", + "status", + "script-security", + "show-net-up", + "suppress-timestamps", + "tap-sleep", + "tmp-dir", + "tun-ipv6", + "topology", + "user", + "win-sys", + }; + private final String[][] ignoreOptionsWithArg = + { + {"setenv", "IV_GUI_VER"}, + {"setenv", "IV_PLAT_VER"}, + {"setenv", "IV_OPENVPN_GUI_VERSION"}, + {"engine", "dynamic"}, + {"setenv", "CLIENT_CERT"}, + {"resolv-retry", "60"} + }; + private final String[] connectionOptions = { + "local", + "remote", + "float", + "port", + "connect-retry", + "connect-timeout", + "connect-retry-max", + "link-mtu", + "tun-mtu", + "tun-mtu-extra", + "fragment", + "mtu-disc", + "local-port", + "remote-port", + "bind", + "nobind", + "proto", + "http-proxy", + "http-proxy-retry", + "http-proxy-timeout", + "http-proxy-option", + "socks-proxy", + "socks-proxy-retry", + "http-proxy-user-pass", + "explicit-exit-notify", + }; + private HashSet connectionOptionsSet = new HashSet<>(Arrays.asList(connectionOptions)); + + private HashMap>> options = new HashMap<>(); private HashMap> meta = new HashMap>(); private String auth_user_pass_file; + static public void useEmbbedUserAuth(VpnProfile np, String inlinedata) { + String data = VpnProfile.getEmbeddedContent(inlinedata); + String[] parts = data.split("\n"); + if (parts.length >= 2) { + np.mUsername = parts[0]; + np.mPassword = parts[1]; + } + } + + static public void useEmbbedHttpAuth(Connection c, String inlinedata) { + String data = VpnProfile.getEmbeddedContent(inlinedata); + String[] parts = data.split("\n"); + if (parts.length >= 2) { + c.mProxyAuthUser = parts[0]; + c.mProxyAuthPassword = parts[1]; + c.mUseProxyAuth = true; + } + } + public void parseConfig(Reader reader) throws IOException, ConfigParseError { HashMap optionAliases = new HashMap<>(); @@ -76,7 +191,7 @@ public class ConfigParser { checkinlinefile(args, br); String optionname = args.get(0); - if (optionAliases.get(optionname)!=null) + if (optionAliases.get(optionname) != null) optionname = optionAliases.get(optionname); if (!options.containsKey(optionname)) { @@ -119,8 +234,8 @@ public class ConfigParser { } } while (true); - if(inlinefile.endsWith("\n")) - inlinefile = inlinefile.substring(0, inlinefile.length()-1); + if (inlinefile.endsWith("\n")) + inlinefile = inlinefile.substring(0, inlinefile.length() - 1); args.clear(); args.add(argname); @@ -133,11 +248,6 @@ public class ConfigParser { return auth_user_pass_file; } - enum linestate { - initial, - readin_single_quote, reading_quoted, reading_unquoted, done - } - private boolean space(char c) { // I really hope nobody is using zero bytes inside his/her config file // to sperate parameter but here we go: @@ -145,15 +255,6 @@ public class ConfigParser { } - public static class ConfigParseError extends Exception { - private static final long serialVersionUID = -60L; - - public ConfigParseError(String msg) { - super(msg); - } - } - - // adapted openvpn's parse function to java private Vector parseline(String line) throws ConfigParseError { Vector parameters = new Vector(); @@ -226,7 +327,7 @@ public class ConfigParser { backslash = false; } - /* store parameter character */ + /* store parameter character */ if (out != 0) { currentarg += out; } @@ -235,105 +336,6 @@ public class ConfigParser { return parameters; } - - final String[] unsupportedOptions = {"config", - "tls-server" - - }; - - // Ignore all scripts - // in most cases these won't work and user who wish to execute scripts will - // figure out themselves - final String[] ignoreOptions = {"tls-client", - "askpass", - "auth-nocache", - "up", - "down", - "route-up", - "ipchange", - "route-up", - "route-pre-down", - "auth-user-pass-verify", - "block-outside-dns", - "dhcp-release", - "dhcp-renew", - "dh", - "group", - "allow-recursive-routing", - "ip-win32", - "ifconfig-nowarn", - "management-hold", - "management", - "management-client", - "management-query-remote", - "management-query-passwords", - "management-query-proxy", - "management-external-key", - "management-forget-disconnect", - "management-signal", - "management-log-cache", - "management-up-down", - "management-client-user", - "management-client-group", - "pause-exit", - "preresolve", - "plugin", - "machine-readable-output", - "persist-key", - "push", - "register-dns", - "route-delay", - "route-gateway", - "route-metric", - "route-method", - "status", - "script-security", - "show-net-up", - "suppress-timestamps", - "tmp-dir", - "tun-ipv6", - "topology", - "user", - "win-sys", - }; - - final String[][] ignoreOptionsWithArg = - { - {"setenv", "IV_GUI_VER"}, - {"setenv", "IV_OPENVPN_GUI_VERSION"}, - {"engine", "dynamic"}, - {"setenv", "CLIENT_CERT"}, - {"resolve-retry","60"} - }; - - final String[] connectionOptions = { - "local", - "remote", - "float", - "port", - "connect-retry", - "connect-timeout", - "connect-retry-max", - "link-mtu", - "tun-mtu", - "tun-mtu-extra", - "fragment", - "mtu-disc", - "local-port", - "remote-port", - "bind", - "nobind", - "proto", - "http-proxy", - "http-proxy-retry", - "http-proxy-timeout", - "http-proxy-option", - "socks-proxy", - "socks-proxy-retry", - "explicit-exit-notify", - }; - - // This method is far too long @SuppressWarnings("ConstantConditions") public VpnProfile convertProfile() throws ConfigParseError, IOException { @@ -403,8 +405,8 @@ public class ConfigParser { } Vector routeNoPull = getOption("route-nopull", 0, 0); - if (routeNoPull!=null) - np.mRoutenopull=true; + if (routeNoPull != null) + np.mRoutenopull = true; // Also recognize tls-auth [inline] direction ... Vector> tlsauthoptions = getAllOption("tls-auth", 1, 2); @@ -426,7 +428,7 @@ public class ConfigParser { np.mTLSAuthDirection = direction.get(1); Vector tlscrypt = getOption("tls-crypt", 1, 1); - if (tlscrypt!=null) { + if (tlscrypt != null) { np.mUseTLSAuth = true; np.mTLSAuthFilename = tlscrypt.get(1); np.mTLSAuthDirection = "tls-crypt"; @@ -467,7 +469,7 @@ public class ConfigParser { } - Vector tunmtu = getOption("mtu", 1, 1); + Vector tunmtu = getOption("tun-mtu", 1, 1); if (tunmtu != null) { try { @@ -478,7 +480,6 @@ public class ConfigParser { } - Vector mode = getOption("mode", 1, 1); if (mode != null) { if (!mode.get(1).equals("p2p")) @@ -592,9 +593,9 @@ public class ConfigParser { } - Vector x509usernamefield = getOption("x509-username-field", 1,1); - if (x509usernamefield!=null) { - np.mx509UsernameField = x509usernamefield.get(1); + Vector x509usernamefield = getOption("x509-username-field", 1, 1); + if (x509usernamefield != null) { + np.mx509UsernameField = x509usernamefield.get(1); } @@ -666,7 +667,7 @@ public class ConfigParser { if (crlfile != null) { // If the 'dir' parameter is present just add it as custom option .. if (crlfile.size() == 3 && crlfile.get(2).equals("dir")) - np.mCustomConfigOptions += TextUtils.join(" ", crlfile) + "\n"; + np.mCustomConfigOptions += join(" ", crlfile) + "\n"; else // Save the filename for the config converter to add later np.mCrlFilename = crlfile.get(1); @@ -732,6 +733,13 @@ public class ConfigParser { return np; } + private String join(String s, Vector str) { + if (Build.VERSION.SDK_INT > 26) + return String.join(s, str); + else + return TextUtils.join(s, str); + } + private Pair parseConnection(String connection, Connection defaultValues) throws IOException, ConfigParseError { // Parse a connection Block as a new configuration file @@ -783,20 +791,48 @@ public class ConfigParser { } } - // Parse remote config - Vector> remotes = getAllOption("remote", 1, 3); + Vector proxy = getOption("socks-proxy", 1, 2); + if (proxy == null) + proxy = getOption("http-proxy", 2, 2); + + if (proxy != null) { + if (proxy.get(0).equals("socks-proxy")) { + conn.mProxyType = Connection.ProxyType.SOCKS5; + // socks defaults to 1080, http always sets port + conn.mProxyPort = "1080"; + } else { + conn.mProxyType = Connection.ProxyType.HTTP; + } + + conn.mProxyName = proxy.get(1); + if (proxy.size() >= 3) + conn.mProxyPort = proxy.get(2); + } + Vector httpproxyauthhttp = getOption("http-proxy-user-pass", 1, 1); + if (httpproxyauthhttp != null) + useEmbbedHttpAuth(conn, httpproxyauthhttp.get(1)); - // Assume that we need custom options if connectionDefault are set - if (connDefault != null) { - for (Vector> option : options.values()) { - conn.mCustomConfiguration += getOptionStrings(option); + // Parse remote config + Vector> remotes = getAllOption("remote", 1, 3); + + + Vector optionsToRemove = new Vector<>(); + // Assume that we need custom options if connectionDefault are set or in the connection specific set + for (Map.Entry>> option : options.entrySet()) { + if (connDefault != null || connectionOptionsSet.contains(option.getKey())) { + conn.mCustomConfiguration += getOptionStrings(option.getValue()); + optionsToRemove.add(option.getKey()); } - if (!TextUtils.isEmpty(conn.mCustomConfiguration)) - conn.mUseCustomConfig = true; } + for (String o: optionsToRemove) + options.remove(o); + + if (!(conn.mCustomConfiguration == null || "".equals(conn.mCustomConfiguration.trim()))) + conn.mUseCustomConfig = true; + // Make remotes empty to simplify code if (remotes == null) remotes = new Vector>(); @@ -821,6 +857,7 @@ public class ConfigParser { } i++; } + return Pair.create(conn, connections); } @@ -830,19 +867,19 @@ public class ConfigParser { boolean noIpv4 = false; if (defaultRoute) - for (Vector redirect : defgw) - for (int i = 1; i < redirect.size(); i++) { - if (redirect.get(i).equals("block-local")) - np.mAllowLocalLAN = false; - else if (redirect.get(i).equals("unblock-local")) - np.mAllowLocalLAN = true; - else if (redirect.get(i).equals("!ipv4")) - noIpv4=true; - else if (redirect.get(i).equals("ipv6")) - np.mUseDefaultRoutev6=true; - } + for (Vector redirect : defgw) + for (int i = 1; i < redirect.size(); i++) { + if (redirect.get(i).equals("block-local")) + np.mAllowLocalLAN = false; + else if (redirect.get(i).equals("unblock-local")) + np.mAllowLocalLAN = true; + else if (redirect.get(i).equals("!ipv4")) + noIpv4 = true; + else if (redirect.get(i).equals("ipv6")) + np.mUseDefaultRoutev6 = true; + } if (defaultRoute && !noIpv4) - np.mUseDefaultRoute=true; + np.mUseDefaultRoute = true; } private boolean isUdpProto(String proto) throws ConfigParseError { @@ -861,15 +898,6 @@ public class ConfigParser { return isudp; } - static public void useEmbbedUserAuth(VpnProfile np, String inlinedata) { - String data = VpnProfile.getEmbeddedContent(inlinedata); - String[] parts = data.split("\n"); - if (parts.length >= 2) { - np.mUsername = parts[0]; - np.mPassword = parts[1]; - } - } - private void checkIgnoreAndInvalidOptions(VpnProfile np) throws ConfigParseError { for (String option : unsupportedOptions) if (options.containsKey(option)) @@ -880,7 +908,16 @@ public class ConfigParser { options.remove(option); - if (options.size() > 0) { + boolean customOptions=false; + for (Vector> option: options.values()) + { + for (Vector optionsline : option) { + if (!ignoreThisOption(optionsline)) { + customOptions = true; + } + } + } + if (customOptions) { np.mCustomConfigOptions = "# These options found in the config file do not map to config settings:\n" + np.mCustomConfigOptions; @@ -894,7 +931,6 @@ public class ConfigParser { } } - boolean ignoreThisOption(Vector option) { for (String[] ignoreOption : ignoreOptionsWithArg) { @@ -920,7 +956,7 @@ public class ConfigParser { if (!ignoreThisOption(optionsline)) { // Check if option had been inlined and inline again if (optionsline.size() == 2 && - ("extra-certs".equals(optionsline.get(0)) || "http-proxy-user-pass".equals(optionsline.get(0)))) { + "extra-certs".equals(optionsline.get(0))) { custom += VpnProfile.insertFileData(optionsline.get(0), optionsline.get(1)); } else { for (String arg : optionsline) @@ -932,7 +968,6 @@ public class ConfigParser { return custom; } - private void fixup(VpnProfile np) { if (np.mRemoteCN.equals(np.mServerName)) { np.mRemoteCN = ""; @@ -947,7 +982,6 @@ public class ConfigParser { return alloptions.lastElement(); } - private Vector> getAllOption(String option, int minarg, int maxarg) throws ConfigParseError { Vector> args = options.get(option); if (args == null) @@ -964,6 +998,19 @@ public class ConfigParser { return args; } + enum linestate { + initial, + readin_single_quote, reading_quoted, reading_unquoted, done + } + + public static class ConfigParseError extends Exception { + private static final long serialVersionUID = -60L; + + public ConfigParseError(String msg) { + super(msg); + } + } + } -- cgit v1.2.3