diff options
Diffstat (limited to 'options.c')
-rw-r--r-- | options.c | 184 |
1 files changed, 179 insertions, 5 deletions
@@ -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); |