aboutsummaryrefslogtreecommitdiff
path: root/options.c
diff options
context:
space:
mode:
Diffstat (limited to 'options.c')
-rw-r--r--options.c282
1 files changed, 268 insertions, 14 deletions
diff --git a/options.c b/options.c
index 15a1d62..bc6616b 100644
--- a/options.c
+++ b/options.c
@@ -5,7 +5,10 @@
* packet encryption, packet authentication, and
* packet compression.
*
- * Copyright (C) 2002-2009 OpenVPN Technologies, Inc. <sales@openvpn.net>
+ * Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net>
+ *
+ * Additions for eurephia plugin done by:
+ * David Sommerseth <dazo@users.sourceforge.net> Copyright (C) 2009
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
@@ -75,6 +78,9 @@ const char title_string[] =
#ifdef ENABLE_PKCS11
" [PKCS11]"
#endif
+#ifdef ENABLE_EUREPHIA
+ " [eurephia]"
+#endif
" built on " __DATE__
;
@@ -96,6 +102,7 @@ static const char usage_message[] =
"--mode m : Major mode, m = 'p2p' (default, point-to-point) or 'server'.\n"
"--proto p : Use protocol p for communicating with peer.\n"
" p = udp (default), tcp-server, or tcp-client\n"
+ "--proto-force p : only consider protocol p in list of connection profiles.\n"
"--connect-retry n : For --proto tcp-client, number of seconds to wait\n"
" between connection retries (default=%d).\n"
"--connect-timeout n : For --proto tcp-client, connection timeout (in seconds).\n"
@@ -110,8 +117,9 @@ static const char usage_message[] =
" up is a file containing username/password on 2 lines, or\n"
" 'stdin' to prompt from console. Add auth='ntlm' if\n"
" the proxy requires NTLM authentication.\n"
- "--http-proxy s p 'auto': Like the above directive, but automatically determine\n"
- " auth method and query for username/password if needed.\n"
+ "--http-proxy s p 'auto[-nct]' : Like the above directive, but automatically\n"
+ " determine auth method and query for username/password\n"
+ " if needed. auto-nct disables weak proxy auth methods.\n"
"--http-proxy-retry : Retry indefinitely on HTTP proxy errors.\n"
"--http-proxy-timeout n : Proxy timeout in seconds, default=5.\n"
"--http-proxy-option type [parm] : Set extended HTTP proxy options.\n"
@@ -200,6 +208,9 @@ static const char usage_message[] =
" Add 'bypass-dns' flag to similarly bypass tunnel for DNS.\n"
"--redirect-private [flags]: Like --redirect-gateway, but omit actually changing\n"
" the default gateway. Useful when pushing private subnets.\n"
+#ifdef ENABLE_PUSH_PEER_INFO
+ "--push-peer-info : (client only) push client info to server.\n"
+#endif
"--setenv name value : Set a custom environmental variable to pass to script.\n"
"--setenv FORWARD_COMPATIBLE 1 : Relax config file syntax checking to allow\n"
" directives for future OpenVPN versions to be ignored.\n"
@@ -621,6 +632,8 @@ static const char usage_message[] =
"--dhcp-pre-release : Ask Windows to release the previous TAP adapter lease on\n"
" startup.\n"
"--dhcp-release : Ask Windows to release the TAP adapter lease on shutdown.\n"
+ "--register-dns : Run net stop dnscache, net start dnscache, ipconfig /flushdns\n"
+ " and ipconfig /registerdns on connection initiation.\n"
"--tap-sleep n : Sleep for n seconds after TAP adapter open before\n"
" attempting to set adapter properties.\n"
"--pause-exit : When run from a console window, pause before exiting.\n"
@@ -697,6 +710,7 @@ init_options (struct options *o, const bool init_gc)
o->route_delay_window = 30;
o->max_routes = MAX_ROUTES_DEFAULT;
o->resolve_retry_seconds = RESOLV_RETRY_INFINITE;
+ o->proto_force = -1;
#ifdef ENABLE_OCC
o->occ = true;
#endif
@@ -771,7 +785,9 @@ void
uninit_options (struct options *o)
{
if (o->gc_owned)
- gc_free (&o->gc);
+ {
+ gc_free (&o->gc);
+ }
}
#ifdef ENABLE_DEBUG
@@ -1357,6 +1373,9 @@ show_settings (const struct options *o)
SHOW_INT (transition_window);
SHOW_BOOL (single_session);
+#ifdef ENABLE_PUSH_PEER_INFO
+ SHOW_BOOL (push_peer_info);
+#endif
SHOW_BOOL (tls_exit);
SHOW_STR (tls_auth_file);
@@ -1423,6 +1442,142 @@ init_http_options_if_undefined (struct options *o)
#endif
+#if HTTP_PROXY_FALLBACK
+
+static struct http_proxy_options *
+parse_http_proxy_override (const char *server,
+ const char *port,
+ const char *flags,
+ const int msglevel,
+ struct gc_arena *gc)
+{
+ if (server && port)
+ {
+ struct http_proxy_options *ho;
+ const int int_port = atoi(port);
+
+ if (!legal_ipv4_port (int_port))
+ {
+ msg (msglevel, "Bad http-proxy port number: %s", port);
+ return NULL;
+ }
+
+ ALLOC_OBJ_CLEAR_GC (ho, struct http_proxy_options, gc);
+ ho->server = string_alloc(server, gc);
+ ho->port = int_port;
+ ho->retry = true;
+ ho->timeout = 5;
+ if (flags && !strcmp(flags, "nct"))
+ ho->auth_retry = PAR_NCT;
+ else
+ ho->auth_retry = PAR_ALL;
+ ho->http_version = "1.0";
+ ho->user_agent = "OpenVPN-Autoproxy/1.0";
+ return ho;
+ }
+ else
+ return NULL;
+}
+
+struct http_proxy_options *
+parse_http_proxy_fallback (struct context *c,
+ const char *server,
+ const char *port,
+ const char *flags,
+ const int msglevel)
+{
+ struct gc_arena gc = gc_new ();
+ struct http_proxy_options *ret = NULL;
+ struct http_proxy_options *hp = parse_http_proxy_override(server, port, flags, msglevel, &gc);
+ if (hp)
+ {
+ struct hpo_store *hpos = c->options.hpo_store;
+ if (!hpos)
+ {
+ ALLOC_OBJ_CLEAR_GC (hpos, struct hpo_store, &c->options.gc);
+ c->options.hpo_store = hpos;
+ }
+ hpos->hpo = *hp;
+ hpos->hpo.server = hpos->server;
+ strncpynt(hpos->server, hp->server, sizeof(hpos->server));
+ ret = &hpos->hpo;
+ }
+ gc_free (&gc);
+ return ret;
+}
+
+static void
+http_proxy_warn(const char *name)
+{
+ msg (M_WARN, "Note: option %s ignored because no TCP-based connection profiles are defined", name);
+}
+
+void
+options_postprocess_http_proxy_fallback (struct options *o)
+{
+ struct connection_list *l = o->connection_list;
+ if (l)
+ {
+ int i;
+ for (i = 0; i < l->len; ++i)
+ {
+ struct connection_entry *ce = l->array[i];
+ if (ce->proto == PROTO_TCPv4_CLIENT || ce->proto == PROTO_TCPv4)
+ {
+ if (l->len < CONNECTION_LIST_SIZE)
+ {
+ struct connection_entry *newce;
+ ALLOC_OBJ_GC (newce, struct connection_entry, &o->gc);
+ *newce = *ce;
+ newce->flags |= CE_HTTP_PROXY_FALLBACK;
+ newce->http_proxy_options = NULL;
+ newce->ce_http_proxy_fallback_timestamp = 0;
+ l->array[l->len++] = newce;
+ }
+ return;
+ }
+ }
+ }
+ http_proxy_warn("http-proxy-fallback");
+}
+
+void
+options_postprocess_http_proxy_override (struct options *o)
+{
+ const struct connection_list *l = o->connection_list;
+ if (l)
+ {
+ int i;
+ bool succeed = false;
+ for (i = 0; i < l->len; ++i)
+ {
+ struct connection_entry *ce = l->array[i];
+ if (ce->proto == PROTO_TCPv4_CLIENT || ce->proto == PROTO_TCPv4)
+ {
+ ce->http_proxy_options = o->http_proxy_override;
+ succeed = true;
+ }
+ }
+ if (succeed)
+ {
+ for (i = 0; i < l->len; ++i)
+ {
+ struct connection_entry *ce = l->array[i];
+ if (ce->proto == PROTO_UDPv4)
+ {
+ ce->flags |= CE_DISABLED;
+ }
+ }
+ }
+ else
+ {
+ http_proxy_warn("http-proxy-override");
+ }
+ }
+}
+
+#endif
+
#if ENABLE_CONNECTION
static struct connection_list *
@@ -1936,6 +2091,9 @@ options_postprocess_verify_ce (const struct options *options, const struct conne
MUST_BE_UNDEF (transition_window);
MUST_BE_UNDEF (tls_auth_file);
MUST_BE_UNDEF (single_session);
+#ifdef ENABLE_PUSH_PEER_INFO
+ MUST_BE_UNDEF (push_peer_info);
+#endif
MUST_BE_UNDEF (tls_exit);
MUST_BE_UNDEF (crl_file);
MUST_BE_UNDEF (key_method);
@@ -1992,6 +2150,10 @@ options_postprocess_mutate_ce (struct options *o, struct connection_entry *ce)
if (!ce->bind_local)
ce->local_port = 0;
+
+ /* if protocol forcing is enabled, disable all protocols except for the forced one */
+ if (o->proto_force >= 0 && is_proto_tcp(o->proto_force) != is_proto_tcp(ce->proto))
+ ce->flags |= CE_DISABLED;
}
static void
@@ -2107,7 +2269,7 @@ options_postprocess_mutate (struct options *o)
* For compatibility with 2.0.x, map multiple --remote options
* into connection list (connection lists added in 2.1).
*/
- if (o->remote_list->len > 1)
+ if (o->remote_list->len > 1 || o->force_connection_list)
{
const struct remote_list *rl = o->remote_list;
int i;
@@ -2124,7 +2286,7 @@ options_postprocess_mutate (struct options *o)
*ace = ce;
}
}
- else if (o->remote_list->len == 1) /* one --remote option specfied */
+ else if (o->remote_list->len == 1) /* one --remote option specified */
{
connection_entry_load_re (&o->ce, o->remote_list->array[0]);
}
@@ -2138,6 +2300,13 @@ options_postprocess_mutate (struct options *o)
int i;
for (i = 0; i < o->connection_list->len; ++i)
options_postprocess_mutate_ce (o, o->connection_list->array[i]);
+
+#if HTTP_PROXY_FALLBACK
+ if (o->http_proxy_override)
+ options_postprocess_http_proxy_override(o);
+ else if (o->http_proxy_fallback)
+ options_postprocess_http_proxy_fallback(o);
+#endif
}
else
#endif
@@ -2758,7 +2927,7 @@ usage_version (void)
{
msg (M_INFO|M_NOPREFIX, "%s", title_string);
msg (M_INFO|M_NOPREFIX, "Originally developed by James Yonan");
- msg (M_INFO|M_NOPREFIX, "Copyright (C) 2002-2009 OpenVPN Technologies, Inc. <sales@openvpn.net>");
+ msg (M_INFO|M_NOPREFIX, "Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net>");
#ifndef ENABLE_SMALL
#ifdef CONFIGURE_CALL
msg (M_INFO|M_NOPREFIX, "\n%s\n", CONFIGURE_CALL);
@@ -3347,6 +3516,15 @@ msglevel_forward_compatible (struct options *options, const int msglevel)
}
static void
+warn_multiple_script (const char *script, const char *type) {
+ if (script) {
+ msg (M_WARN, "Multiple --%s scripts defined. "
+ "The previously configured script is overridden.", type);
+ }
+}
+
+
+static void
add_option (struct options *options,
char *p[],
const char *file,
@@ -3651,6 +3829,29 @@ add_option (struct options *options,
}
}
#endif
+#ifdef ENABLE_CONNECTION
+ else if (streq (p[0], "remote-ip-hint") && p[1])
+ {
+ VERIFY_PERMISSION (OPT_P_GENERAL);
+ options->remote_ip_hint = p[1];
+ }
+#endif
+#if HTTP_PROXY_FALLBACK
+ else if (streq (p[0], "http-proxy-fallback"))
+ {
+ VERIFY_PERMISSION (OPT_P_GENERAL);
+ options->http_proxy_fallback = true;
+ options->force_connection_list = true;
+ }
+ else if (streq (p[0], "http-proxy-override") && p[1] && p[2])
+ {
+ VERIFY_PERMISSION (OPT_P_GENERAL);
+ options->http_proxy_override = parse_http_proxy_override(p[1], p[2], p[3], msglevel, &options->gc);
+ if (!options->http_proxy_override)
+ goto err;
+ options->force_connection_list = true;
+ }
+#endif
else if (streq (p[0], "remote") && p[1])
{
struct remote_entry re;
@@ -3723,6 +3924,7 @@ add_option (struct options *options,
VERIFY_PERMISSION (OPT_P_SCRIPT);
if (!no_more_than_n_args (msglevel, p, 2, NM_QUOTE_HINT))
goto err;
+ warn_multiple_script (options->ipchange, "ipchange");
options->ipchange = string_substitute (p[1], ',', ' ', &options->gc);
}
else if (streq (p[0], "float"))
@@ -3769,6 +3971,7 @@ add_option (struct options *options,
VERIFY_PERMISSION (OPT_P_SCRIPT);
if (!no_more_than_n_args (msglevel, p, 2, NM_QUOTE_HINT))
goto err;
+ warn_multiple_script (options->up_script, "up");
options->up_script = p[1];
}
else if (streq (p[0], "down") && p[1])
@@ -3776,6 +3979,7 @@ add_option (struct options *options,
VERIFY_PERMISSION (OPT_P_SCRIPT);
if (!no_more_than_n_args (msglevel, p, 2, NM_QUOTE_HINT))
goto err;
+ warn_multiple_script (options->down_script, "down");
options->down_script = p[1];
}
else if (streq (p[0], "down-pre"))
@@ -3835,7 +4039,7 @@ add_option (struct options *options,
{
if (options->inetd != -1)
{
- msg (msglevel, opterr);
+ msg (msglevel, "%s", opterr);
goto err;
}
else
@@ -3845,7 +4049,7 @@ add_option (struct options *options,
{
if (options->inetd != -1)
{
- msg (msglevel, opterr);
+ msg (msglevel, "%s", opterr);
goto err;
}
else
@@ -3855,7 +4059,7 @@ add_option (struct options *options,
{
if (name != NULL)
{
- msg (msglevel, opterr);
+ msg (msglevel, "%s", opterr);
goto err;
}
name = p[z];
@@ -4150,6 +4354,19 @@ add_option (struct options *options,
}
options->ce.proto = proto;
}
+ else if (streq (p[0], "proto-force") && p[1])
+ {
+ int proto_force;
+ VERIFY_PERMISSION (OPT_P_GENERAL);
+ proto_force = ascii2proto (p[1]);
+ if (proto_force < 0)
+ {
+ msg (msglevel, "Bad --proto-force protocol: '%s'", p[1]);
+ goto err;
+ }
+ options->proto_force = proto_force;
+ options->force_connection_list = true;
+ }
#ifdef GENERAL_PROXY_SUPPORT
else if (streq (p[0], "auto-proxy"))
{
@@ -4211,8 +4428,13 @@ add_option (struct options *options,
if (p[3])
{
+ /* auto -- try to figure out proxy addr, port, and type automatically */
+ /* semiauto -- given proxy addr:port, try to figure out type automatically */
+ /* (auto|semiauto)-nct -- disable proxy auth cleartext protocols (i.e. basic auth) */
if (streq (p[3], "auto"))
- ho->auth_retry = true;
+ ho->auth_retry = PAR_ALL;
+ else if (streq (p[3], "auto-nct"))
+ ho->auth_retry = PAR_NCT;
else
{
ho->auth_method_string = "basic";
@@ -4440,6 +4662,7 @@ add_option (struct options *options,
VERIFY_PERMISSION (OPT_P_SCRIPT);
if (!no_more_than_n_args (msglevel, p, 2, NM_QUOTE_HINT))
goto err;
+ warn_multiple_script (options->route_script, "route-up");
options->route_script = p[1];
}
else if (streq (p[0], "route-noexec"))
@@ -4769,6 +4992,7 @@ add_option (struct options *options,
msg (msglevel, "--auth-user-pass-verify requires a second parameter ('via-env' or 'via-file')");
goto err;
}
+ warn_multiple_script (options->auth_user_pass_verify_script, "auth-user-pass-verify");
options->auth_user_pass_verify_script = p[1];
}
else if (streq (p[0], "client-connect") && p[1])
@@ -4776,6 +5000,7 @@ add_option (struct options *options,
VERIFY_PERMISSION (OPT_P_SCRIPT);
if (!no_more_than_n_args (msglevel, p, 2, NM_QUOTE_HINT))
goto err;
+ warn_multiple_script (options->client_connect_script, "client-connect");
options->client_connect_script = p[1];
}
else if (streq (p[0], "client-disconnect") && p[1])
@@ -4783,6 +5008,7 @@ add_option (struct options *options,
VERIFY_PERMISSION (OPT_P_SCRIPT);
if (!no_more_than_n_args (msglevel, p, 2, NM_QUOTE_HINT))
goto err;
+ warn_multiple_script (options->client_disconnect_script, "client-disconnect");
options->client_disconnect_script = p[1];
}
else if (streq (p[0], "learn-address") && p[1])
@@ -4790,6 +5016,7 @@ add_option (struct options *options,
VERIFY_PERMISSION (OPT_P_SCRIPT);
if (!no_more_than_n_args (msglevel, p, 2, NM_QUOTE_HINT))
goto err;
+ warn_multiple_script (options->learn_address_script, "learn-address");
options->learn_address_script = p[1];
}
else if (streq (p[0], "tmp-dir") && p[1])
@@ -5125,7 +5352,7 @@ add_option (struct options *options,
VERIFY_PERMISSION (OPT_P_IPWIN32);
options->tuntap_options.dhcp_release = true;
}
- else if (streq (p[0], "dhcp-rr") && p[1]) /* standalone method for internal use */
+ else if (streq (p[0], "dhcp-internal") && p[1]) /* standalone method for internal use */
{
unsigned int adapter_index;
VERIFY_PERMISSION (OPT_P_GENERAL);
@@ -5136,13 +5363,26 @@ add_option (struct options *options,
dhcp_release_by_adapter_index (adapter_index);
if (options->tuntap_options.dhcp_renew)
dhcp_renew_by_adapter_index (adapter_index);
- openvpn_exit (OPENVPN_EXIT_STATUS_USAGE); /* exit point */
+ openvpn_exit (OPENVPN_EXIT_STATUS_GOOD); /* exit point */
+ }
+ else if (streq (p[0], "register-dns"))
+ {
+ VERIFY_PERMISSION (OPT_P_IPWIN32);
+ options->tuntap_options.register_dns = true;
+ }
+ else if (streq (p[0], "rdns-internal")) /* standalone method for internal use */
+ {
+ VERIFY_PERMISSION (OPT_P_GENERAL);
+ set_debug_level (options->verbosity, SDL_CONSTRAIN);
+ if (options->tuntap_options.register_dns)
+ ipconfig_register_dns (NULL);
+ openvpn_exit (OPENVPN_EXIT_STATUS_GOOD); /* exit point */
}
else if (streq (p[0], "show-valid-subnets"))
{
VERIFY_PERMISSION (OPT_P_GENERAL);
show_valid_win32_tun_subnets ();
- openvpn_exit (OPENVPN_EXIT_STATUS_USAGE); /* exit point */
+ openvpn_exit (OPENVPN_EXIT_STATUS_GOOD); /* exit point */
}
else if (streq (p[0], "pause-exit"))
{
@@ -5502,6 +5742,12 @@ add_option (struct options *options,
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->pkcs12_file = p[1];
+#if ENABLE_INLINE_FILES
+ if (streq (p[1], INLINE_FILE_TAG) && p[2])
+ {
+ options->pkcs12_file_inline = p[2];
+ }
+#endif
}
else if (streq (p[0], "askpass"))
{
@@ -5523,6 +5769,13 @@ add_option (struct options *options,
VERIFY_PERMISSION (OPT_P_GENERAL);
options->single_session = true;
}
+#ifdef ENABLE_PUSH_PEER_INFO
+ else if (streq (p[0], "push-peer-info"))
+ {
+ VERIFY_PERMISSION (OPT_P_GENERAL);
+ options->push_peer_info = true;
+ }
+#endif
else if (streq (p[0], "tls-exit"))
{
VERIFY_PERMISSION (OPT_P_GENERAL);
@@ -5543,6 +5796,7 @@ add_option (struct options *options,
VERIFY_PERMISSION (OPT_P_SCRIPT);
if (!no_more_than_n_args (msglevel, p, 2, NM_QUOTE_HINT))
goto err;
+ warn_multiple_script (options->tls_verify, "tls-verify");
options->tls_verify = string_substitute (p[1], ',', ' ', &options->gc);
}
else if (streq (p[0], "tls-export-cert") && p[1])