diff options
| author | Arne Schwabe <arne@rfc2549.org> | 2015-01-09 16:46:21 +0100 | 
|---|---|---|
| committer | Arne Schwabe <arne@rfc2549.org> | 2015-01-09 16:46:21 +0100 | 
| commit | 21c8890c31ae63484b47a6b92262cd5fd2c818b7 (patch) | |
| tree | df3fa4526816ab2d91cda4109654f16bce4f898c | |
| parent | 3c7cb13eca715b932af8479914f3db6a2df0bd50 (diff) | |
ignore engine dynamic
--HG--
extra : source : 38fce154fd50742236c876042a5bb2f7d157570e
| -rw-r--r-- | main/src/main/java/de/blinkt/openvpn/core/ConfigParser.java | 1030 | 
1 files changed, 502 insertions, 528 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 5dc96bbc..5f5d486c 100644 --- a/main/src/main/java/de/blinkt/openvpn/core/ConfigParser.java +++ b/main/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; +    }  }  | 
