diff options
Diffstat (limited to 'options.c')
-rw-r--r-- | options.c | 282 |
1 files changed, 268 insertions, 14 deletions
@@ -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]) |