diff options
Diffstat (limited to 'main/src/main/java/de/blinkt/openvpn/core/ConfigParser.java')
-rw-r--r-- | main/src/main/java/de/blinkt/openvpn/core/ConfigParser.java | 338 |
1 files changed, 166 insertions, 172 deletions
diff --git a/main/src/main/java/de/blinkt/openvpn/core/ConfigParser.java b/main/src/main/java/de/blinkt/openvpn/core/ConfigParser.java index 10fcb12a..611f77d5 100644 --- a/main/src/main/java/de/blinkt/openvpn/core/ConfigParser.java +++ b/main/src/main/java/de/blinkt/openvpn/core/ConfigParser.java @@ -13,10 +13,7 @@ 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; @@ -30,10 +27,126 @@ public class ConfigParser { public static final String CONVERTED_PROFILE = "converted Profile"; + 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", + "allow-recursive-routing", + "askpass", + "auth-nocache", + "up", + "down", + "route-up", + "ipchange", + "route-up", + "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", + "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", + "http-proxy-user-pass", + "explicit-exit-notify", + }; + private HashSet<String> connectionOptionsSet = new HashSet<>(Arrays.asList(connectionOptions)); + private HashMap<String, Vector<Vector<String>>> options = new HashMap<>(); private HashMap<String, Vector<String>> meta = new HashMap<String, Vector<String>>(); 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<String, String> optionAliases = new HashMap<>(); @@ -77,7 +190,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)) { @@ -120,8 +233,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); @@ -134,11 +247,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: @@ -146,15 +254,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<String> parseline(String line) throws ConfigParseError { Vector<String> parameters = new Vector<String>(); @@ -227,7 +326,7 @@ public class ConfigParser { backslash = false; } - /* store parameter character */ + /* store parameter character */ if (out != 0) { currentarg += out; } @@ -236,107 +335,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", - "allow-recursive-routing", - "askpass", - "auth-nocache", - "up", - "down", - "route-up", - "ipchange", - "route-up", - "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", - "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", - "http-proxy-user-pass", - "explicit-exit-notify", - }; - - // This method is far too long @SuppressWarnings("ConstantConditions") public VpnProfile convertProfile() throws ConfigParseError, IOException { @@ -406,8 +404,8 @@ public class ConfigParser { } Vector<String> 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<Vector<String>> tlsauthoptions = getAllOption("tls-auth", 1, 2); @@ -429,7 +427,7 @@ public class ConfigParser { np.mTLSAuthDirection = direction.get(1); Vector<String> tlscrypt = getOption("tls-crypt", 1, 1); - if (tlscrypt!=null) { + if (tlscrypt != null) { np.mUseTLSAuth = true; np.mTLSAuthFilename = tlscrypt.get(1); np.mTLSAuthDirection = "tls-crypt"; @@ -481,7 +479,6 @@ public class ConfigParser { } - Vector<String> mode = getOption("mode", 1, 1); if (mode != null) { if (!mode.get(1).equals("p2p")) @@ -595,9 +592,9 @@ public class ConfigParser { } - Vector<String> x509usernamefield = getOption("x509-username-field", 1,1); - if (x509usernamefield!=null) { - np.mx509UsernameField = x509usernamefield.get(1); + Vector<String> x509usernamefield = getOption("x509-username-field", 1, 1); + if (x509usernamefield != null) { + np.mx509UsernameField = x509usernamefield.get(1); } @@ -812,7 +809,7 @@ public class ConfigParser { } Vector<String> httpproxyauthhttp = getOption("http-proxy-user-pass", 1, 1); - if (httpproxyauthhttp!=null) + if (httpproxyauthhttp != null) useEmbbedHttpAuth(conn, httpproxyauthhttp.get(1)); @@ -820,16 +817,21 @@ public class ConfigParser { 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); + Vector <String> optionsToRemove = new Vector<>(); + // Assume that we need custom options if connectionDefault are set or in the connection specific set + for (Map.Entry<String, Vector<Vector<String>>> option : options.entrySet()) { + if (connDefault != null || connectionOptionsSet.contains(option.getKey())) { + conn.mCustomConfiguration += getOptionStrings(option.getValue()); + optionsToRemove.add(option.getKey()); } - if (!(conn.mCustomConfiguration == null || "".equals(conn.mCustomConfiguration.trim()))) - 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<Vector<String>>(); @@ -854,6 +856,7 @@ public class ConfigParser { } i++; } + return Pair.create(conn, connections); } @@ -863,19 +866,19 @@ public class ConfigParser { boolean noIpv4 = false; if (defaultRoute) - for (Vector<String> 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<String> 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 { @@ -894,25 +897,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]; - } - } - - 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; - } - } - private void checkIgnoreAndInvalidOptions(VpnProfile np) throws ConfigParseError { for (String option : unsupportedOptions) if (options.containsKey(option)) @@ -937,7 +921,6 @@ public class ConfigParser { } } - boolean ignoreThisOption(Vector<String> option) { for (String[] ignoreOption : ignoreOptionsWithArg) { @@ -975,7 +958,6 @@ public class ConfigParser { return custom; } - private void fixup(VpnProfile np) { if (np.mRemoteCN.equals(np.mServerName)) { np.mRemoteCN = ""; @@ -990,7 +972,6 @@ public class ConfigParser { 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) @@ -1007,6 +988,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); + } + } + } |