From 80285c31e83a8e233016e227a393543d508194eb Mon Sep 17 00:00:00 2001 From: Bernhard Schmidt Date: Tue, 20 Oct 2020 19:17:00 +0200 Subject: New upstream version 2.5~rc3 --- src/openvpn/init.c | 3 +- src/openvpn/manage.c | 30 +++++-- src/openvpn/networking_iproute2.c | 2 + src/openvpn/options.c | 80 +++++++++++------ src/openvpn/route.c | 16 ++-- src/openvpn/socket.c | 58 ++++++++----- src/openvpn/ssl.c | 8 ++ src/openvpn/ssl_ncp.c | 18 +++- src/openvpn/ssl_verify.c | 177 +++++++++++++++++--------------------- src/openvpn/tun.c | 2 +- 10 files changed, 231 insertions(+), 163 deletions(-) (limited to 'src/openvpn') diff --git a/src/openvpn/init.c b/src/openvpn/init.c index d1ad5c8..31ecadc 100644 --- a/src/openvpn/init.c +++ b/src/openvpn/init.c @@ -3646,7 +3646,8 @@ do_close_link_socket(struct context *c) && ( (c->options.persist_remote_ip) || ( c->sig->source != SIG_SOURCE_HARD - && ((c->c1.link_socket_addr.current_remote && c->c1.link_socket_addr.current_remote->ai_next) + && ((c->c1.link_socket_addr.current_remote + && c->c1.link_socket_addr.current_remote->ai_next) || c->options.no_advance)) ))) { diff --git a/src/openvpn/manage.c b/src/openvpn/manage.c index 898cb3b..ac14217 100644 --- a/src/openvpn/manage.c +++ b/src/openvpn/manage.c @@ -3310,12 +3310,17 @@ man_block(struct management *man, volatile int *signal_received, const time_t ex if (man_standalone_ok(man)) { + /* expire time can be already overdue, for this case init zero + * timeout to avoid waiting first time and exit loop early with + * either obtained event or timeout. + */ + tv.tv_usec = 0; + tv.tv_sec = 0; + while (true) { event_reset(man->connection.es); management_socket_set(man, man->connection.es, NULL, NULL); - tv.tv_usec = 0; - tv.tv_sec = 1; if (man_check_for_signals(signal_received)) { status = -1; @@ -3343,6 +3348,10 @@ man_block(struct management *man, volatile int *signal_received, const time_t ex } break; } + + /* wait one second more */ + tv.tv_sec = 1; + tv.tv_usec = 0; } } return status; @@ -3444,7 +3453,7 @@ management_event_loop_n_seconds(struct management *man, int sec) /* set expire time */ update_time(); - if (sec) + if (sec >= 0) { expire = now + sec; } @@ -3474,7 +3483,7 @@ management_event_loop_n_seconds(struct management *man, int sec) /* revert state */ man->persist.standalone_disabled = standalone_disabled_save; } - else + else if (sec > 0) { sleep(sec); } @@ -4117,11 +4126,15 @@ log_history_ref(const struct log_history *h, const int index) void management_sleep(const int n) { - if (management) + if (n < 0) + { + return; + } + else if (management) { management_event_loop_n_seconds(management, n); } - else + else if (n > 0) { sleep(n); } @@ -4132,7 +4145,10 @@ management_sleep(const int n) void management_sleep(const int n) { - sleep(n); + if (n > 0) + { + sleep(n); + } } #endif /* ENABLE_MANAGEMENT */ diff --git a/src/openvpn/networking_iproute2.c b/src/openvpn/networking_iproute2.c index f3b9c61..3b46052 100644 --- a/src/openvpn/networking_iproute2.c +++ b/src/openvpn/networking_iproute2.c @@ -88,6 +88,8 @@ net_iface_mtu_set(openvpn_net_ctx_t *ctx, const char *iface, uint32_t mtu) argv_msg(M_INFO, &argv); openvpn_execve_check(&argv, ctx->es, S_FATAL, "Linux ip link set failed"); + argv_free(&argv); + return 0; } diff --git a/src/openvpn/options.c b/src/openvpn/options.c index 3df803d..658ca53 100644 --- a/src/openvpn/options.c +++ b/src/openvpn/options.c @@ -1983,7 +1983,8 @@ connection_entry_load_re(struct connection_entry *ce, const struct remote_entry } static void -options_postprocess_verify_ce(const struct options *options, const struct connection_entry *ce) +options_postprocess_verify_ce(const struct options *options, + const struct connection_entry *ce) { struct options defaults; int dev = DEV_TYPE_UNDEF; @@ -2011,7 +2012,9 @@ options_postprocess_verify_ce(const struct options *options, const struct connec */ if (ce->proto == PROTO_TCP) { - msg(M_USAGE, "--proto tcp is ambiguous in this context. Please specify --proto tcp-server or --proto tcp-client"); + msg(M_USAGE, + "--proto tcp is ambiguous in this context. Please specify " + "--proto tcp-server or --proto tcp-client"); } /* @@ -2051,8 +2054,9 @@ options_postprocess_verify_ce(const struct options *options, const struct connec if (options->inetd) { - msg(M_WARN, "DEPRECATED OPTION: --inetd mode is deprecated " - "and will be removed in OpenVPN 2.6"); + msg(M_WARN, + "DEPRECATED OPTION: --inetd mode is deprecated and will be removed " + "in OpenVPN 2.6"); } if (options->lladdr && dev != DEV_TYPE_TAP) @@ -2065,7 +2069,9 @@ options_postprocess_verify_ce(const struct options *options, const struct connec */ if (options->ce.tun_mtu_defined && options->ce.link_mtu_defined) { - msg(M_USAGE, "only one of --tun-mtu or --link-mtu may be defined (note that --ifconfig implies --link-mtu %d)", LINK_MTU_DEFAULT); + msg(M_USAGE, + "only one of --tun-mtu or --link-mtu may be defined (note that " + "--ifconfig implies --link-mtu %d)", LINK_MTU_DEFAULT); } if (!proto_is_udp(ce->proto) && options->mtu_test) @@ -2092,18 +2098,23 @@ options_postprocess_verify_ce(const struct options *options, const struct connec if (string_defined_equal(ce->remote, options->ifconfig_local) || string_defined_equal(ce->remote, options->ifconfig_remote_netmask)) { - msg(M_USAGE, "--local and --remote addresses must be distinct from --ifconfig addresses"); + msg(M_USAGE, + "--local and --remote addresses must be distinct from --ifconfig " + "addresses"); } if (string_defined_equal(ce->local, options->ifconfig_local) || string_defined_equal(ce->local, options->ifconfig_remote_netmask)) { - msg(M_USAGE, "--local addresses must be distinct from --ifconfig addresses"); + msg(M_USAGE, + "--local addresses must be distinct from --ifconfig addresses"); } - if (string_defined_equal(options->ifconfig_local, options->ifconfig_remote_netmask)) + if (string_defined_equal(options->ifconfig_local, + options->ifconfig_remote_netmask)) { - msg(M_USAGE, "local and remote/netmask --ifconfig addresses must be different"); + msg(M_USAGE, + "local and remote/netmask --ifconfig addresses must be different"); } if (ce->bind_defined && !ce->bind_local) @@ -2113,12 +2124,14 @@ options_postprocess_verify_ce(const struct options *options, const struct connec if (ce->local && !ce->bind_local) { - msg(M_USAGE, "--local and --nobind don't make sense when used together"); + msg(M_USAGE, + "--local and --nobind don't make sense when used together"); } if (ce->local_port_defined && !ce->bind_local) { - msg(M_USAGE, "--lport and --nobind don't make sense when used together"); + msg(M_USAGE, + "--lport and --nobind don't make sense when used together"); } if (!ce->remote && !ce->bind_local) @@ -2207,7 +2220,8 @@ options_postprocess_verify_ce(const struct options *options, const struct connec if (!proto_is_udp(ce->proto) && ce->explicit_exit_notification) { - msg(M_USAGE, "--explicit-exit-notify can only be used with --proto udp"); + msg(M_USAGE, + "--explicit-exit-notify can only be used with --proto udp"); } if (!ce->remote && ce->proto == PROTO_TCP_CLIENT) @@ -2217,16 +2231,21 @@ options_postprocess_verify_ce(const struct options *options, const struct connec if ((ce->http_proxy_options) && ce->proto != PROTO_TCP_CLIENT) { - msg(M_USAGE, "--http-proxy MUST be used in TCP Client mode (i.e. --proto tcp-client)"); + msg(M_USAGE, + "--http-proxy MUST be used in TCP Client mode (i.e. --proto " + "tcp-client)"); } + if ((ce->http_proxy_options) && !ce->http_proxy_options->server) { - msg(M_USAGE, "--http-proxy not specified but other http proxy options present"); + msg(M_USAGE, + "--http-proxy not specified but other http proxy options present"); } if (ce->http_proxy_options && ce->socks_proxy_server) { - msg(M_USAGE, "--http-proxy can not be used together with --socks-proxy"); + msg(M_USAGE, + "--http-proxy can not be used together with --socks-proxy"); } if (ce->socks_proxy_server && ce->proto == PROTO_TCP_SERVER) @@ -2292,8 +2311,9 @@ options_postprocess_verify_ce(const struct options *options, const struct connec { msg(M_USAGE, "--socks-proxy cannot be used with --mode server"); } - /* blocks force to have a remote embedded, so we check for the - * --remote and bail out if it is present */ + /* blocks force to have a remote embedded, so we check + * for the --remote and bail out if it is present + */ if (options->connection_list->len >1 || options->connection_list->array[0]->remote) { @@ -2310,12 +2330,15 @@ options_postprocess_verify_ce(const struct options *options, const struct connec } if (options->ipchange) { - msg(M_USAGE, "--ipchange cannot be used with --mode server (use --client-connect instead)"); + msg(M_USAGE, + "--ipchange cannot be used with --mode server (use " + "--client-connect instead)"); } if (!(proto_is_dgram(ce->proto) || ce->proto == PROTO_TCP_SERVER)) { - msg(M_USAGE, "--mode server currently only supports " - "--proto udp or --proto tcp-server or --proto tcp6-server"); + msg(M_USAGE, + "--mode server currently only supports --proto udp or --proto " + "tcp-server or --proto tcp6-server"); } if (!proto_is_udp(ce->proto) && (options->cf_max || options->cf_per)) { @@ -2817,12 +2840,14 @@ options_postprocess_mutate_ce(struct options *o, struct connection_entry *ce) } #endif - if (ce->proto == PROTO_TCP_CLIENT && !ce->local && !ce->local_port_defined && !ce->bind_defined) + if (ce->proto == PROTO_TCP_CLIENT && !ce->local + && !ce->local_port_defined && !ce->bind_defined) { ce->bind_local = false; } - if (ce->proto == PROTO_UDP && ce->socks_proxy_server && !ce->local && !ce->local_port_defined && !ce->bind_defined) + if (ce->proto == PROTO_UDP && ce->socks_proxy_server && !ce->local + && !ce->local_port_defined && !ce->bind_defined) { ce->bind_local = false; } @@ -2832,7 +2857,9 @@ options_postprocess_mutate_ce(struct options *o, struct connection_entry *ce) ce->local_port = NULL; } - /* if protocol forcing is enabled, disable all protocols except for the forced one */ + /* if protocol forcing is enabled, disable all protocols + * except for the forced one + */ if (o->proto_force >= 0 && o->proto_force != ce->proto) { ce->flags |= CE_DISABLED; @@ -5690,7 +5717,9 @@ add_option(struct options *options, const sa_family_t af = ascii2af(p[3]); if (proto < 0) { - msg(msglevel, "remote: bad protocol associated with host %s: '%s'", p[1], p[3]); + msg(msglevel, + "remote: bad protocol associated with host %s: '%s'", + p[1], p[3]); goto err; } re.proto = proto; @@ -6210,7 +6239,8 @@ add_option(struct options *options, af = ascii2af(p[1]); if (proto < 0) { - msg(msglevel, "Bad protocol: '%s'. Allowed protocols with --proto option: %s", + msg(msglevel, + "Bad protocol: '%s'. Allowed protocols with --proto option: %s", p[1], proto2ascii_all(&gc)); goto err; diff --git a/src/openvpn/route.c b/src/openvpn/route.c index d75aa5f..5e1dca6 100644 --- a/src/openvpn/route.c +++ b/src/openvpn/route.c @@ -1011,14 +1011,10 @@ redirect_default_route_to_vpn(struct route_list *rl, const struct tuntap *tt, * - we are connecting to a non-IPv4 remote host (i.e. we use IPv6) */ else if (!(rl->rgi.flags & RGI_ADDR_DEFINED) && !local - && (rl->spec.remote_host != IPV4_INVALID_ADDR)) + && (rl->spec.flags & RTSA_REMOTE_HOST)) { msg(M_WARN, "%s Cannot read current default gateway from system", err); } - else if (!(rl->spec.flags & RTSA_REMOTE_HOST)) - { - msg(M_WARN, "%s Cannot obtain current remote host address", err); - } else { #ifndef TARGET_ANDROID @@ -1041,7 +1037,8 @@ redirect_default_route_to_vpn(struct route_list *rl, const struct tuntap *tt, /* route remote host to original default gateway */ /* if remote_host is not ipv4 (ie: ipv6), just skip * adding this special /32 route */ - if (rl->spec.remote_host != IPV4_INVALID_ADDR) + if ((rl->spec.flags & RTSA_REMOTE_HOST) + && rl->spec.remote_host != IPV4_INVALID_ADDR) { add_route3(rl->spec.remote_host, IPV4_NETMASK_HOST, @@ -1479,6 +1476,13 @@ setenv_route_ipv6(struct env_set *es, const struct route_ipv6 *r6, int i) buf_printf( &name2, "route_ipv6_gateway_%d", i ); setenv_str( es, BSTR(&name2), print_in6_addr( r6->gateway, 0, &gc )); + + if (r6->flags & RT_METRIC_DEFINED) + { + struct buffer name3 = alloc_buf_gc( 256, &gc ); + buf_printf( &name3, "route_ipv6_metric_%d", i) ; + setenv_int( es, BSTR(&name3), r6->metric); + } } gc_free(&gc); } diff --git a/src/openvpn/socket.c b/src/openvpn/socket.c index 76bdbfc..9775068 100644 --- a/src/openvpn/socket.c +++ b/src/openvpn/socket.c @@ -378,7 +378,8 @@ do_preresolve(struct context *c) /* HTTP remote hostname does not need to be resolved */ if (!ce->http_proxy_options) { - status = do_preresolve_host(c, remote, ce->remote_port, ce->af, flags); + status = do_preresolve_host(c, remote, ce->remote_port, + ce->af, flags); if (status != 0) { goto err; @@ -417,7 +418,8 @@ do_preresolve(struct context *c) { flags |= GETADDR_PASSIVE; flags &= ~GETADDR_RANDOMIZE; - status = do_preresolve_host(c, ce->local, ce->local_port, ce->af, flags); + status = do_preresolve_host(c, ce->local, ce->local_port, + ce->af, flags); if (status != 0) { goto err; @@ -526,7 +528,9 @@ openvpn_getaddrinfo(unsigned int flags, if ((flags & GETADDR_MENTION_RESOLVE_RETRY) && !resolve_retry_seconds) { - fmt = "RESOLVE: Cannot resolve host address: %s:%s (%s) (I would have retried this name query if you had specified the --resolv-retry option.)"; + fmt = "RESOLVE: Cannot resolve host address: %s:%s (%s) " + "(I would have retried this name query if you had " + "specified the --resolv-retry option.)"; } if (!(flags & GETADDR_RESOLVE) || status == EAI_FAIL) @@ -558,11 +562,13 @@ openvpn_getaddrinfo(unsigned int flags, while (true) { #ifndef _WIN32 + /* force resolv.conf reload */ res_init(); #endif /* try hostname lookup */ hints.ai_flags &= ~AI_NUMERICHOST; - dmsg(D_SOCKET_DEBUG, "GETADDRINFO flags=0x%04x ai_family=%d ai_socktype=%d", + dmsg(D_SOCKET_DEBUG, + "GETADDRINFO flags=0x%04x ai_family=%d ai_socktype=%d", flags, hints.ai_family, hints.ai_socktype); status = getaddrinfo(hostname, servname, &hints, res); @@ -573,7 +579,9 @@ openvpn_getaddrinfo(unsigned int flags, { if (*signal_received == SIGUSR1) /* ignore SIGUSR1 */ { - msg(level, "RESOLVE: Ignored SIGUSR1 signal received during DNS resolution attempt"); + msg(level, + "RESOLVE: Ignored SIGUSR1 signal received during " + "DNS resolution attempt"); *signal_received = 0; } else @@ -634,7 +642,9 @@ openvpn_getaddrinfo(unsigned int flags, /* IP address parse succeeded */ if (flags & GETADDR_RANDOMIZE) { - msg(M_WARN, "WARNING: ignoring --remote-random-hostname because the hostname is an IP address"); + msg(M_WARN, + "WARNING: ignoring --remote-random-hostname because the " + "hostname is an IP address"); } } @@ -1470,14 +1480,14 @@ openvpn_connect(socket_descriptor_t sd, struct pollfd fds[1]; fds[0].fd = sd; fds[0].events = POLLOUT; - status = poll(fds, 1, 0); + status = poll(fds, 1, (connect_timeout > 0) ? 1000 : 0); #else fd_set writes; struct timeval tv; FD_ZERO(&writes); openvpn_fd_set(sd, &writes); - tv.tv_sec = 0; + tv.tv_sec = (connect_timeout > 0) ? 1 : 0; tv.tv_usec = 0; status = select(sd + 1, NULL, &writes, NULL, &tv); @@ -1507,7 +1517,7 @@ openvpn_connect(socket_descriptor_t sd, #endif break; } - management_sleep(1); + management_sleep(0); continue; } @@ -1802,7 +1812,8 @@ resolve_remote(struct link_socket *sock, sock->info.lsa->remote_list = ai; sock->info.lsa->current_remote = ai; - dmsg(D_SOCKET_DEBUG, "RESOLVE_REMOTE flags=0x%04x phase=%d rrs=%d sig=%d status=%d", + dmsg(D_SOCKET_DEBUG, + "RESOLVE_REMOTE flags=0x%04x phase=%d rrs=%d sig=%d status=%d", flags, phase, retry, @@ -3155,22 +3166,22 @@ struct proto_names { /* Indexed by PROTO_x */ static const struct proto_names proto_names[] = { - {"proto-uninitialized", "proto-NONE", AF_UNSPEC, PROTO_NONE}, + {"proto-uninitialized", "proto-NONE", AF_UNSPEC, PROTO_NONE}, /* try IPv4 and IPv6 (client), bind dual-stack (server) */ - {"udp", "UDP", AF_UNSPEC, PROTO_UDP}, - {"tcp-server", "TCP_SERVER", AF_UNSPEC, PROTO_TCP_SERVER}, - {"tcp-client", "TCP_CLIENT", AF_UNSPEC, PROTO_TCP_CLIENT}, - {"tcp", "TCP", AF_UNSPEC, PROTO_TCP}, + {"udp", "UDP", AF_UNSPEC, PROTO_UDP}, + {"tcp-server", "TCP_SERVER", AF_UNSPEC, PROTO_TCP_SERVER}, + {"tcp-client", "TCP_CLIENT", AF_UNSPEC, PROTO_TCP_CLIENT}, + {"tcp", "TCP", AF_UNSPEC, PROTO_TCP}, /* force IPv4 */ - {"udp4", "UDPv4", AF_INET, PROTO_UDP}, - {"tcp4-server","TCPv4_SERVER", AF_INET, PROTO_TCP_SERVER}, - {"tcp4-client","TCPv4_CLIENT", AF_INET, PROTO_TCP_CLIENT}, - {"tcp4", "TCPv4", AF_INET, PROTO_TCP}, + {"udp4", "UDPv4", AF_INET, PROTO_UDP}, + {"tcp4-server", "TCPv4_SERVER", AF_INET, PROTO_TCP_SERVER}, + {"tcp4-client", "TCPv4_CLIENT", AF_INET, PROTO_TCP_CLIENT}, + {"tcp4", "TCPv4", AF_INET, PROTO_TCP}, /* force IPv6 */ - {"udp6","UDPv6", AF_INET6, PROTO_UDP}, - {"tcp6-server","TCPv6_SERVER", AF_INET6, PROTO_TCP_SERVER}, - {"tcp6-client","TCPv6_CLIENT", AF_INET6, PROTO_TCP_CLIENT}, - {"tcp6","TCPv6", AF_INET6, PROTO_TCP}, + {"udp6", "UDPv6", AF_INET6, PROTO_UDP}, + {"tcp6-server", "TCPv6_SERVER", AF_INET6, PROTO_TCP_SERVER}, + {"tcp6-client", "TCPv6_CLIENT", AF_INET6, PROTO_TCP_CLIENT}, + {"tcp6", "TCPv6", AF_INET6, PROTO_TCP}, }; bool @@ -3182,6 +3193,7 @@ proto_is_net(int proto) } return proto != PROTO_NONE; } + bool proto_is_dgram(int proto) { diff --git a/src/openvpn/ssl.c b/src/openvpn/ssl.c index f16114c..c6ba812 100644 --- a/src/openvpn/ssl.c +++ b/src/openvpn/ssl.c @@ -2484,6 +2484,14 @@ key_method_2_read(struct buffer *buf, struct tls_multi *multi, struct tls_sessio multi->remote_ciphername = options_string_extract_option(options, "cipher", NULL); + /* In OCC we send '[null-cipher]' instead 'none' */ + if (multi->remote_ciphername + && strcmp(multi->remote_ciphername, "[null-cipher]") == 0) + { + free(multi->remote_ciphername); + multi->remote_ciphername = string_alloc("none", NULL); + } + if (tls_session_user_pass_enabled(session)) { /* Perform username/password authentication */ diff --git a/src/openvpn/ssl_ncp.c b/src/openvpn/ssl_ncp.c index 5549639..45bddbe 100644 --- a/src/openvpn/ssl_ncp.c +++ b/src/openvpn/ssl_ncp.c @@ -110,7 +110,15 @@ mutate_ncp_cipher_list(const char *list, struct gc_arena *gc) * e.g. replacing AeS-128-gCm with AES-128-GCM */ const cipher_kt_t *ktc = cipher_kt_get(token); - if (!ktc) + if (strcmp(token, "none") == 0) + { + msg(M_WARN, "WARNING: cipher 'none' specified for --data-ciphers. " + "This allows negotiation of NO encryption and " + "tunnelled data WILL then be transmitted in clear text " + "over the network! " + "PLEASE DO RECONSIDER THIS SETTING!"); + } + if (!ktc && strcmp(token, "none") != 0) { msg(M_WARN, "Unsupported cipher in --data-ciphers: %s", token); error_found = true; @@ -118,6 +126,12 @@ mutate_ncp_cipher_list(const char *list, struct gc_arena *gc) else { const char *ovpn_cipher_name = cipher_kt_name(ktc); + if (ktc == NULL) + { + /* NULL resolves to [null-cipher] but we need none for + * data-ciphers */ + ovpn_cipher_name = "none"; + } if (buf_len(&new_list)> 0) { @@ -325,4 +339,4 @@ check_pull_client_ncp(struct context *c, const int found) "to this server."); return false; } -} \ No newline at end of file +} diff --git a/src/openvpn/ssl_verify.c b/src/openvpn/ssl_verify.c index 97ccb93..33115eb 100644 --- a/src/openvpn/ssl_verify.c +++ b/src/openvpn/ssl_verify.c @@ -1068,69 +1068,51 @@ verify_user_pass_script(struct tls_session *session, struct tls_multi *multi, const char *tmp_file = ""; bool ret = false; - /* Is username defined? */ - if ((session->opt->ssl_flags & SSLF_AUTH_USER_PASS_OPTIONAL) || strlen(up->username)) + /* Set environmental variables prior to calling script */ + setenv_str(session->opt->es, "script_type", "user-pass-verify"); + + /* format command line */ + argv_parse_cmd(&argv, session->opt->auth_user_pass_verify_script); + + if (session->opt->auth_user_pass_verify_script_via_file) { - /* Set environmental variables prior to calling script */ - setenv_str(session->opt->es, "script_type", "user-pass-verify"); + struct status_output *so; - if (session->opt->auth_user_pass_verify_script_via_file) + tmp_file = platform_create_temp_file(session->opt->tmp_dir, "up", + &gc); + if (tmp_file) { - struct status_output *so; - - tmp_file = platform_create_temp_file(session->opt->tmp_dir, "up", - &gc); - if (tmp_file) - { - so = status_open(tmp_file, 0, -1, NULL, STATUS_OUTPUT_WRITE); - status_printf(so, "%s", up->username); - status_printf(so, "%s", up->password); - if (!status_close(so)) - { - msg(D_TLS_ERRORS, "TLS Auth Error: could not write username/password to file: %s", - tmp_file); - goto done; - } - } - else + so = status_open(tmp_file, 0, -1, NULL, STATUS_OUTPUT_WRITE); + status_printf(so, "%s", up->username); + status_printf(so, "%s", up->password); + if (!status_close(so)) { - msg(D_TLS_ERRORS, "TLS Auth Error: could not create write " - "username/password to temp file"); + msg(D_TLS_ERRORS, "TLS Auth Error: could not write username/password to file: %s", + tmp_file); + goto done; } + /* pass temp file name to script */ + argv_printf_cat(&argv, "%s", tmp_file); } else { - setenv_str(session->opt->es, "username", up->username); - setenv_str(session->opt->es, "password", up->password); - } - - /* setenv incoming cert common name for script */ - setenv_str(session->opt->es, "common_name", session->common_name); - - /* setenv client real IP address */ - setenv_untrusted(session); - - /* add auth-token environment */ - add_session_token_env(session, multi, up); - - /* format command line */ - argv_parse_cmd(&argv, session->opt->auth_user_pass_verify_script); - argv_printf_cat(&argv, "%s", tmp_file); - - /* call command */ - ret = openvpn_run_script(&argv, session->opt->es, 0, - "--auth-user-pass-verify"); - - if (!session->opt->auth_user_pass_verify_script_via_file) - { - setenv_del(session->opt->es, "password"); + msg(D_TLS_ERRORS, "TLS Auth Error: could not create write " + "username/password to temp file"); } } else { - msg(D_TLS_ERRORS, "TLS Auth Error: peer provided a blank username"); + setenv_str(session->opt->es, "password", up->password); } + /* call command */ + ret = openvpn_run_script(&argv, session->opt->es, 0, + "--auth-user-pass-verify"); + + if (!session->opt->auth_user_pass_verify_script_via_file) + { + setenv_del(session->opt->es, "password"); + } done: if (tmp_file && strlen(tmp_file) > 0) { @@ -1154,48 +1136,31 @@ verify_user_pass_plugin(struct tls_session *session, struct tls_multi *multi, struct key_state *ks = &session->key[KS_PRIMARY]; /* primary key */ #endif - /* Is username defined? */ - if ((session->opt->ssl_flags & SSLF_AUTH_USER_PASS_OPTIONAL) || strlen(up->username)) - { - /* set username/password in private env space */ - setenv_str(session->opt->es, "username", up->username); - setenv_str(session->opt->es, "password", up->password); - - /* setenv incoming cert common name for script */ - setenv_str(session->opt->es, "common_name", session->common_name); + /* set password in private env space */ + setenv_str(session->opt->es, "password", up->password); - /* setenv client real IP address */ - setenv_untrusted(session); - - /* add auth-token environment */ - add_session_token_env(session, multi, up); #ifdef PLUGIN_DEF_AUTH - /* generate filename for deferred auth control file */ - if (!key_state_gen_auth_control_file(ks, session->opt)) - { - msg(D_TLS_ERRORS, "TLS Auth Error (%s): " - "could not create deferred auth control file", __func__); - return retval; - } + /* generate filename for deferred auth control file */ + if (!key_state_gen_auth_control_file(ks, session->opt)) + { + msg(D_TLS_ERRORS, "TLS Auth Error (%s): " + "could not create deferred auth control file", __func__); + return retval; + } #endif - /* call command */ - retval = plugin_call(session->opt->plugins, OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY, NULL, NULL, session->opt->es); + /* call command */ + retval = plugin_call(session->opt->plugins, OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY, NULL, NULL, session->opt->es); #ifdef PLUGIN_DEF_AUTH - /* purge auth control filename (and file itself) for non-deferred returns */ - if (retval != OPENVPN_PLUGIN_FUNC_DEFERRED) - { - key_state_rm_auth_control_file(ks); - } -#endif - - setenv_del(session->opt->es, "password"); - } - else + /* purge auth control filename (and file itself) for non-deferred returns */ + if (retval != OPENVPN_PLUGIN_FUNC_DEFERRED) { - msg(D_TLS_ERRORS, "TLS Auth Error (verify_user_pass_plugin): peer provided a blank username"); + key_state_rm_auth_control_file(ks); } +#endif + + setenv_del(session->opt->es, "password"); return retval; } @@ -1218,12 +1183,30 @@ verify_user_pass_management(struct tls_session *session, int retval = KMDA_ERROR; struct key_state *ks = &session->key[KS_PRIMARY]; /* primary key */ + /* set username/password in private env space */ + setenv_str(session->opt->es, "password", up->password); + + if (management) + { + management_notify_client_needing_auth(management, ks->mda_key_id, session->opt->mda_context, session->opt->es); + } + + setenv_del(session->opt->es, "password"); + + retval = KMDA_SUCCESS; + + return retval; +} +#endif /* ifdef MANAGEMENT_DEF_AUTH */ + +static bool +set_verify_user_pass_env(struct user_pass *up, struct tls_multi *multi, + struct tls_session *session) +{ /* Is username defined? */ if ((session->opt->ssl_flags & SSLF_AUTH_USER_PASS_OPTIONAL) || strlen(up->username)) { - /* set username/password in private env space */ setenv_str(session->opt->es, "username", up->username); - setenv_str(session->opt->es, "password", up->password); /* setenv incoming cert common name for script */ setenv_str(session->opt->es, "common_name", session->common_name); @@ -1236,24 +1219,14 @@ verify_user_pass_management(struct tls_session *session, * allow the management to figure out if it is a new session or a continued one */ add_session_token_env(session, multi, up); - if (management) - { - management_notify_client_needing_auth(management, ks->mda_key_id, session->opt->mda_context, session->opt->es); - } - - setenv_del(session->opt->es, "password"); - - retval = KMDA_SUCCESS; + return true; } else { - msg(D_TLS_ERRORS, "TLS Auth Error (verify_user_pass_management): peer provided a blank username"); + msg(D_TLS_ERRORS, "TLS Auth Error: peer provided a blank username"); + return false; } - - return retval; } -#endif /* ifdef MANAGEMENT_DEF_AUTH */ - /* * Main username/password verification entry point @@ -1325,6 +1298,14 @@ verify_user_pass(struct user_pass *up, struct tls_multi *multi, return; } } + + /* Set the environment variables used by all auth variants */ + if (!set_verify_user_pass_env(up, multi, session)) + { + skip_auth = true; + s1 = OPENVPN_PLUGIN_FUNC_ERROR; + } + /* call plugin(s) and/or script */ if (!skip_auth) { diff --git a/src/openvpn/tun.c b/src/openvpn/tun.c index 9eeaed0..8315a42 100644 --- a/src/openvpn/tun.c +++ b/src/openvpn/tun.c @@ -6571,7 +6571,7 @@ tun_open_device(struct tuntap *tt, const char *dev_node, const char **device_gui if (!*device_guid) { - msg(M_FATAL, "All %s adapters on this system are currently in use.", print_windows_driver(tt->windows_driver)); + msg(M_FATAL, "All %s adapters on this system are currently in use or disabled.", print_windows_driver(tt->windows_driver)); } if (tt->windows_driver != windows_driver) -- cgit v1.2.3