aboutsummaryrefslogtreecommitdiff
path: root/options.c
diff options
context:
space:
mode:
Diffstat (limited to 'options.c')
-rw-r--r--options.c184
1 files changed, 179 insertions, 5 deletions
diff --git a/options.c b/options.c
index 3a2a6c5..b78158e 100644
--- a/options.c
+++ b/options.c
@@ -196,6 +196,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"
@@ -761,7 +764,9 @@ void
uninit_options (struct options *o)
{
if (o->gc_owned)
- gc_free (&o->gc);
+ {
+ gc_free (&o->gc);
+ }
}
#ifdef ENABLE_DEBUG
@@ -1346,6 +1351,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);
@@ -1412,6 +1420,137 @@ 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 *hp = parse_http_proxy_override(server, port, flags, msglevel, &gc);
+ 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));
+ gc_free (&gc);
+ return &hpos->hpo;
+}
+
+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 *
@@ -1924,6 +2063,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);
@@ -2095,7 +2237,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;
@@ -2112,7 +2254,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]);
}
@@ -2126,6 +2268,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
@@ -3633,11 +3782,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|OPT_P_CONNECTION);
- // fixme
+ 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;
@@ -5514,6 +5681,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);