summaryrefslogtreecommitdiff
path: root/src/openvpn
diff options
context:
space:
mode:
Diffstat (limited to 'src/openvpn')
-rw-r--r--src/openvpn/errlevel.h1
-rw-r--r--src/openvpn/init.c14
-rw-r--r--src/openvpn/manage.c30
-rw-r--r--src/openvpn/networking_iproute2.c2
-rw-r--r--src/openvpn/networking_sitnl.c44
-rw-r--r--src/openvpn/openvpn.vcxproj4
-rw-r--r--src/openvpn/options.c86
-rw-r--r--src/openvpn/otime.h1
-rw-r--r--src/openvpn/pool.c18
-rw-r--r--src/openvpn/route.c62
-rw-r--r--src/openvpn/socket.c71
-rw-r--r--src/openvpn/socks.c9
-rw-r--r--src/openvpn/ssl.c8
-rw-r--r--src/openvpn/ssl_ncp.c18
-rw-r--r--src/openvpn/ssl_verify.c177
-rw-r--r--src/openvpn/tun.c233
16 files changed, 518 insertions, 260 deletions
diff --git a/src/openvpn/errlevel.h b/src/openvpn/errlevel.h
index e448fc3..5663f84 100644
--- a/src/openvpn/errlevel.h
+++ b/src/openvpn/errlevel.h
@@ -91,6 +91,7 @@
#define D_OSBUF LOGLEV(3, 43, 0) /* show socket/tun/tap buffer sizes */
#define D_PS_PROXY LOGLEV(3, 44, 0) /* messages related to --port-share option */
#define D_PF_INFO LOGLEV(3, 45, 0) /* packet filter informational messages */
+#define D_IFCONFIG LOGLEV(3, 0, 0) /* show ifconfig info (don't mute) */
#define D_SHOW_PARMS LOGLEV(4, 50, 0) /* show all parameters on program initiation */
#define D_SHOW_OCC LOGLEV(4, 51, 0) /* show options compatibility string */
diff --git a/src/openvpn/init.c b/src/openvpn/init.c
index a785934..31ecadc 100644
--- a/src/openvpn/init.c
+++ b/src/openvpn/init.c
@@ -500,6 +500,17 @@ next_connection_entry(struct context *c)
*/
if (!c->options.persist_remote_ip)
{
+ /* Connection entry addrinfo objects might have been
+ * resolved earlier but the entry itself might have been
+ * skipped by management on the previous loop.
+ * If so, clear the addrinfo objects as close_instance does
+ */
+ if (c->c1.link_socket_addr.remote_list)
+ {
+ clear_remote_addrlist(&c->c1.link_socket_addr,
+ !c->options.resolve_in_advance);
+ }
+
/* close_instance should have cleared the addrinfo objects */
ASSERT(c->c1.link_socket_addr.current_remote == NULL);
ASSERT(c->c1.link_socket_addr.remote_list == NULL);
@@ -3635,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/networking_sitnl.c b/src/openvpn/networking_sitnl.c
index 713a213..2bc70a5 100644
--- a/src/openvpn/networking_sitnl.c
+++ b/src/openvpn/networking_sitnl.c
@@ -345,6 +345,13 @@ sitnl_send(struct nlmsghdr *payload, pid_t peer, unsigned int groups,
* continue;
* }
*/
+
+ if (h->nlmsg_type == NLMSG_DONE)
+ {
+ ret = 0;
+ goto out;
+ }
+
if (h->nlmsg_type == NLMSG_ERROR)
{
err = (struct nlmsgerr *)NLMSG_DATA(h);
@@ -360,7 +367,11 @@ sitnl_send(struct nlmsghdr *payload, pid_t peer, unsigned int groups,
ret = 0;
if (cb)
{
- ret = cb(h, arg_cb);
+ int r = cb(h, arg_cb);
+ if (r <= 0)
+ {
+ ret = r;
+ }
}
}
else
@@ -375,8 +386,12 @@ sitnl_send(struct nlmsghdr *payload, pid_t peer, unsigned int groups,
if (cb)
{
- ret = cb(h, arg_cb);
- goto out;
+ int r = cb(h, arg_cb);
+ if (r <= 0)
+ {
+ ret = r;
+ goto out;
+ }
}
else
{
@@ -410,6 +425,7 @@ typedef struct {
int addr_size;
inet_address_t gw;
char iface[IFNAMSIZ];
+ bool default_only;
} route_res_t;
static int
@@ -421,6 +437,12 @@ sitnl_route_save(struct nlmsghdr *n, void *arg)
int len = n->nlmsg_len - NLMSG_LENGTH(sizeof(*r));
unsigned int ifindex = 0;
+ /* filter-out non-zero dst prefixes */
+ if (res->default_only && r->rtm_dst_len != 0)
+ {
+ return 1;
+ }
+
while (RTA_OK(rta, len))
{
switch (rta->rta_type)
@@ -477,11 +499,25 @@ sitnl_route_best_gw(sa_family_t af_family, const inet_address_t *dst,
{
case AF_INET:
res.addr_size = sizeof(in_addr_t);
- req.n.nlmsg_flags |= NLM_F_DUMP;
+ /*
+ * kernel can't return 0.0.0.0/8 host route, dump all
+ * the routes and filter for 0.0.0.0/0 in cb()
+ */
+ if (!dst || !dst->ipv4)
+ {
+ req.n.nlmsg_flags |= NLM_F_DUMP;
+ res.default_only = true;
+ }
+ else
+ {
+ req.r.rtm_dst_len = 32;
+ }
break;
case AF_INET6:
res.addr_size = sizeof(struct in6_addr);
+ /* kernel can return ::/128 host route */
+ req.r.rtm_dst_len = 128;
break;
default:
diff --git a/src/openvpn/openvpn.vcxproj b/src/openvpn/openvpn.vcxproj
index 5367979..3863854 100644
--- a/src/openvpn/openvpn.vcxproj
+++ b/src/openvpn/openvpn.vcxproj
@@ -92,7 +92,7 @@
</ClCompile>
<ResourceCompile />
<Link>
- <AdditionalDependencies>legacy_stdio_definitions.lib;Ncrypt.lib;libssl.lib;libcrypto.lib;lzo2.lib;pkcs11-helper.dll.lib;gdi32.lib;ws2_32.lib;wininet.lib;crypt32.lib;iphlpapi.lib;winmm.lib;Fwpuclnt.lib;Rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalDependencies>legacy_stdio_definitions.lib;Ncrypt.lib;libssl.lib;libcrypto.lib;lzo2.lib;pkcs11-helper.dll.lib;gdi32.lib;ws2_32.lib;wininet.lib;crypt32.lib;iphlpapi.lib;winmm.lib;Fwpuclnt.lib;Rpcrt4.lib;setupapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(OPENSSL_HOME)/lib;$(LZO_HOME)/lib;$(PKCS11H_HOME)/lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<SubSystem>Console</SubSystem>
</Link>
@@ -122,7 +122,7 @@
</ClCompile>
<ResourceCompile />
<Link>
- <AdditionalDependencies>legacy_stdio_definitions.lib;Ncrypt.lib;libssl.lib;libcrypto.lib;lzo2.lib;pkcs11-helper.dll.lib;gdi32.lib;ws2_32.lib;wininet.lib;crypt32.lib;iphlpapi.lib;winmm.lib;Fwpuclnt.lib;Rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalDependencies>legacy_stdio_definitions.lib;Ncrypt.lib;libssl.lib;libcrypto.lib;lzo2.lib;pkcs11-helper.dll.lib;gdi32.lib;ws2_32.lib;wininet.lib;crypt32.lib;iphlpapi.lib;winmm.lib;Fwpuclnt.lib;Rpcrt4.lib;setupapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(OPENSSL_HOME)/lib;$(LZO_HOME)/lib;$(PKCS11H_HOME)/lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<SubSystem>Console</SubSystem>
</Link>
diff --git a/src/openvpn/options.c b/src/openvpn/options.c
index 8bf82c5..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)
@@ -2181,10 +2194,11 @@ options_postprocess_verify_ce(const struct options *options, const struct connec
}
if (options->tuntap_options.dhcp_options
+ && options->windows_driver != WINDOWS_DRIVER_WINTUN
&& options->tuntap_options.ip_win32_type != IPW32_SET_DHCP_MASQ
&& options->tuntap_options.ip_win32_type != IPW32_SET_ADAPTIVE)
{
- msg(M_USAGE, "--dhcp-options requires --ip-win32 dynamic or adaptive");
+ msg(M_USAGE, "--dhcp-option requires --ip-win32 dynamic or adaptive");
}
if (options->windows_driver == WINDOWS_DRIVER_WINTUN && dev != DEV_TYPE_TUN)
@@ -2206,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)
@@ -2216,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)
@@ -2291,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");
}
- /* <connection> blocks force to have a remote embedded, so we check for the
- * --remote and bail out if it is present */
+ /* <connection> 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)
{
@@ -2309,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))
{
@@ -2816,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;
}
@@ -2831,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;
@@ -5689,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;
@@ -6209,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;
@@ -7439,7 +7470,8 @@ add_option(struct options *options,
VERIFY_PERMISSION(OPT_P_IPWIN32);
bool ipv6dns = false;
- if (streq(p[1], "DOMAIN") && p[2])
+ if ((streq(p[1], "DOMAIN") || streq(p[1], "ADAPTER_DOMAIN_SUFFIX"))
+ && p[2])
{
o->domain = p[2];
}
diff --git a/src/openvpn/otime.h b/src/openvpn/otime.h
index a6f7ec2..78d20ba 100644
--- a/src/openvpn/otime.h
+++ b/src/openvpn/otime.h
@@ -84,6 +84,7 @@ update_time(void)
openvpn_gettimeofday(&tv, NULL);
#else
update_now(time(NULL));
+ now_usec = 0;
#endif
}
diff --git a/src/openvpn/pool.c b/src/openvpn/pool.c
index 1f74ac5..ece0784 100644
--- a/src/openvpn/pool.c
+++ b/src/openvpn/pool.c
@@ -224,6 +224,24 @@ ifconfig_pool_init(const bool ipv4_pool, enum pool_type type, in_addr_t start,
}
pool->ipv6.base = ipv6_base;
+
+ /* if a pool starts at a base address that has all-zero in the
+ * host part, that first IPv6 address must not be assigned to
+ * clients because it is not usable (subnet anycast address).
+ * Start with 1, then.
+ *
+ * NOTE: this will also (mis-)fire for something like
+ * ifconfig-ipv6-pool 2001:db8:0:1:1234::0/64
+ * as we only check the rightmost 32 bits of the host part. So be it.
+ */
+ if (base == 0)
+ {
+ msg(D_IFCONFIG_POOL, "IFCONFIG POOL IPv6: incrementing pool start "
+ "to avoid ::0 assignment");
+ base++;
+ pool->ipv6.base.s6_addr[15]++;
+ }
+
pool_ipv6_size = ipv6_netbits >= 112
? (1 << (128 - ipv6_netbits)) - base
: IFCONFIG_POOL_MAX;
diff --git a/src/openvpn/route.c b/src/openvpn/route.c
index f127a90..5e1dca6 100644
--- a/src/openvpn/route.c
+++ b/src/openvpn/route.c
@@ -49,6 +49,10 @@
#include <linux/rtnetlink.h> /* RTM_GETROUTE etc. */
#endif
+#if defined(TARGET_NETBSD)
+#include <net/route.h> /* RT_ROUNDUP(), RT_ADVANCE() */
+#endif
+
#ifdef _WIN32
#include "openvpn-msg.h"
@@ -323,6 +327,10 @@ init_route(struct route_ipv4 *r,
if (get_special_addr(rl, ro->network, (in_addr_t *) &special.s_addr, &status))
{
+ if (!status)
+ {
+ goto fail;
+ }
special.s_addr = htonl(special.s_addr);
ret = openvpn_getaddrinfo(0, inet_ntoa(special), NULL, 0, NULL,
AF_INET, network_list);
@@ -619,7 +627,7 @@ init_route_list(struct route_list *rl,
rl->flags = opt->flags;
- if (remote_host)
+ if (remote_host != IPV4_INVALID_ADDR)
{
rl->spec.remote_host = remote_host;
rl->spec.flags |= RTSA_REMOTE_HOST;
@@ -1003,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
@@ -1033,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,
@@ -1471,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);
}
@@ -1979,25 +1991,24 @@ add_route_ipv6(struct route_ipv6 *r6, const struct tuntap *tt,
}
else
{
- struct buffer out = alloc_buf_gc(64, &gc);
+ DWORD adapter_index;
if (r6->adapter_index) /* vpn server special route */
{
- buf_printf(&out, "interface=%lu", r6->adapter_index );
+ adapter_index = r6->adapter_index;
gateway_needed = true;
}
else
{
- buf_printf(&out, "interface=%lu", tt->adapter_index );
+ adapter_index = tt->adapter_index;
}
- device = buf_bptr(&out);
- /* netsh interface ipv6 add route 2001:db8::/32 MyTunDevice */
- argv_printf(&argv, "%s%s interface ipv6 add route %s/%d %s",
+ /* netsh interface ipv6 add route 2001:db8::/32 42 */
+ argv_printf(&argv, "%s%s interface ipv6 add route %s/%d %lu",
get_win_sys_path(),
NETSH_PATH_SUFFIX,
network,
r6->netbits,
- device);
+ adapter_index);
/* next-hop depends on TUN or TAP mode:
* - in TAP mode, we use the "real" next-hop
@@ -2423,25 +2434,24 @@ delete_route_ipv6(const struct route_ipv6 *r6, const struct tuntap *tt,
}
else
{
- struct buffer out = alloc_buf_gc(64, &gc);
+ DWORD adapter_index;
if (r6->adapter_index) /* vpn server special route */
{
- buf_printf(&out, "interface=%lu", r6->adapter_index );
+ adapter_index = r6->adapter_index;
gateway_needed = true;
}
else
{
- buf_printf(&out, "interface=%lu", tt->adapter_index );
+ adapter_index = tt->adapter_index;
}
- device = buf_bptr(&out);
- /* netsh interface ipv6 delete route 2001:db8::/32 MyTunDevice */
- argv_printf(&argv, "%s%s interface ipv6 delete route %s/%d %s",
+ /* netsh interface ipv6 delete route 2001:db8::/32 42 */
+ argv_printf(&argv, "%s%s interface ipv6 delete route %s/%d %lu",
get_win_sys_path(),
NETSH_PATH_SUFFIX,
network,
r6->netbits,
- device);
+ adapter_index);
/* next-hop depends on TUN or TAP mode:
* - in TAP mode, we use the "real" next-hop
@@ -3408,11 +3418,15 @@ struct rtmsg {
/* the route socket code is identical for all 4 supported BSDs and for
* MacOS X (Darwin), with one crucial difference: when going from
- * 32 bit to 64 bit, the BSDs increased the structure size but kept
+ * 32 bit to 64 bit, FreeBSD/OpenBSD increased the structure size but kept
* source code compatibility by keeping the use of "long", while
* MacOS X decided to keep binary compatibility by *changing* the API
* to use "uint32_t", thus 32 bit on all OS X variants
*
+ * NetBSD does the MacOS way of "fixed number of bits, no matter if
+ * 32 or 64 bit OS", but chose uint64_t. For maximum portability, we
+ * just use the OS RT_ROUNDUP() macro, which is guaranteed to be correct.
+ *
* We used to have a large amount of duplicate code here which really
* differed only in this (long) vs. (uint32_t) - IMHO, worse than
* having a combined block for all BSDs with this single #ifdef inside
@@ -3421,6 +3435,8 @@ struct rtmsg {
#if defined(TARGET_DARWIN)
#define ROUNDUP(a) \
((a) > 0 ? (1 + (((a) - 1) | (sizeof(uint32_t) - 1))) : sizeof(uint32_t))
+#elif defined(TARGET_NETBSD)
+#define ROUNDUP(a) RT_ROUNDUP(a)
#else
#define ROUNDUP(a) \
((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
@@ -3729,7 +3745,7 @@ get_default_gateway_ipv6(struct route_ipv6_gateway_info *rgi6,
}
if (write(sockfd, (char *)&m_rtmsg, l) < 0)
{
- msg(M_WARN, "GDG6: problem writing to routing socket");
+ msg(M_WARN|M_ERRNO, "GDG6: problem writing to routing socket");
goto done;
}
diff --git a/src/openvpn/socket.c b/src/openvpn/socket.c
index c486327..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");
}
}
@@ -1141,8 +1151,8 @@ create_socket(struct link_socket *sock, struct addrinfo *addr)
#if defined(TARGET_LINUX)
if (sock->bind_dev)
{
- msg (M_INFO, "Using bind-dev %s", sock->bind_dev);
- if (setsockopt (sock->sd, SOL_SOCKET, SO_BINDTODEVICE, sock->bind_dev, strlen (sock->bind_dev) + 1) != 0)
+ msg(M_INFO, "Using bind-dev %s", sock->bind_dev);
+ if (setsockopt(sock->sd, SOL_SOCKET, SO_BINDTODEVICE, sock->bind_dev, strlen(sock->bind_dev) + 1) != 0)
{
msg(M_WARN|M_ERRNO, "WARN: setsockopt SO_BINDTODEVICE=%s failed", sock->bind_dev);
}
@@ -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,
@@ -2030,8 +2041,14 @@ phase2_inetd(struct link_socket *sock, const struct frame *frame,
}
else
{
- msg(M_WARN, "inetd(%s): getsockname(%d) failed, using AF_INET",
+ int saved_errno = errno;
+ msg(M_WARN|M_ERRNO, "inetd(%s): getsockname(%d) failed, using AF_INET",
proto2ascii(sock->info.proto, sock->info.af, false), (int)sock->sd);
+ /* if not called with a socket on stdin, --inetd cannot work */
+ if (saved_errno == ENOTSOCK)
+ {
+ msg(M_FATAL, "ERROR: socket required for --inetd operation");
+ }
}
}
#else /* ifdef HAVE_GETSOCKNAME */
@@ -2047,7 +2064,6 @@ phase2_inetd(struct link_socket *sock, const struct frame *frame,
false,
sock->inetd == INETD_NOWAIT,
signal_received);
-
}
ASSERT(!remote_changed);
}
@@ -3150,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
@@ -3177,6 +3193,7 @@ proto_is_net(int proto)
}
return proto != PROTO_NONE;
}
+
bool
proto_is_dgram(int proto)
{
diff --git a/src/openvpn/socks.c b/src/openvpn/socks.c
index 57f0cee..36df747 100644
--- a/src/openvpn/socks.c
+++ b/src/openvpn/socks.c
@@ -312,7 +312,7 @@ recv_socks_reply(socket_descriptor_t sd,
char atyp = '\0';
int alen = 0;
int len = 0;
- char buf[22];
+ char buf[270]; /* 4 + alen(max 256) + 2 */
const int timeout_sec = 5;
if (addr != NULL)
@@ -381,7 +381,10 @@ recv_socks_reply(socket_descriptor_t sd,
break;
case '\x03': /* DOMAINNAME */
- alen = (unsigned char) c;
+ /* RFC 1928, section 5: 1 byte length, <n> bytes name,
+ * so the total "address length" is (length+1)
+ */
+ alen = (unsigned char) c + 1;
break;
case '\x04': /* IP V6 */
@@ -451,7 +454,7 @@ establish_socks_proxy_passthru(struct socks_proxy_info *p,
const char *servname, /* openvpn server port */
volatile int *signal_received)
{
- char buf[128];
+ char buf[270];
size_t len;
if (!socks_handshake(p, sd, signal_received))
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 923131a..8315a42 100644
--- a/src/openvpn/tun.c
+++ b/src/openvpn/tun.c
@@ -68,7 +68,7 @@ const static GUID GUID_DEVINTERFACE_NET = { 0xcac88484, 0x7515, 0x4c03, { 0x82,
#define NI_OPTIONS (1<<2)
static void netsh_ifconfig(const struct tuntap_options *to,
- const char *flex_name,
+ DWORD adapter_index,
const in_addr_t ip,
const in_addr_t netmask,
const unsigned int flags);
@@ -79,7 +79,7 @@ static void windows_set_mtu(const int iface_index,
static void netsh_set_dns6_servers(const struct in6_addr *addr_list,
const int addr_len,
- const char *flex_name);
+ DWORD adapter_index);
static void netsh_command(const struct argv *a, int n, int msglevel);
@@ -115,11 +115,17 @@ do_address_service(const bool add, const short family, const struct tuntap *tt)
{
addr.address.ipv4.s_addr = htonl(tt->local);
addr.prefix_len = netmask_to_netbits2(tt->adapter_netmask);
+ msg(D_IFCONFIG, "INET address service: %s %s/%d",
+ add ? "add" : "remove",
+ print_in_addr_t(tt->local, 0, &gc), addr.prefix_len);
}
else
{
addr.address.ipv6 = tt->local_ipv6;
- addr.prefix_len = tt->netbits_ipv6;
+ addr.prefix_len = (tt->type == DEV_TYPE_TUN) ? 128 : tt->netbits_ipv6;
+ msg(D_IFCONFIG, "INET6 address service: %s %s/%d",
+ add ? "add" : "remove",
+ print_in6_addr(tt->local_ipv6, 0, &gc), addr.prefix_len);
}
if (!send_msg_iservice(pipe, &addr, sizeof(addr), &ack, "TUN"))
@@ -143,6 +149,61 @@ out:
}
static bool
+do_dns_domain_service(bool add, const struct tuntap *tt)
+{
+ bool ret = false;
+ ack_message_t ack;
+ struct gc_arena gc = gc_new();
+ HANDLE pipe = tt->options.msg_channel;
+
+ if (!tt->options.domain) /* no domain to add or delete */
+ {
+ return true;
+ }
+
+ /* Use dns_cfg_msg with addr_len = 0 for setting only the DOMAIN */
+ dns_cfg_message_t dns = {
+ .header = {
+ (add ? msg_add_dns_cfg : msg_del_dns_cfg),
+ sizeof(dns_cfg_message_t),
+ 0
+ },
+ .iface = { .index = tt->adapter_index, .name = "" },
+ .domains = "", /* set below */
+ .family = AF_INET, /* unused */
+ .addr_len = 0 /* add/delete only the domain, not DNS servers */
+ };
+
+ strncpynt(dns.iface.name, tt->actual_name, sizeof(dns.iface.name));
+ strncpynt(dns.domains, tt->options.domain, sizeof(dns.domains));
+ /* truncation of domain name is not checked as it can't happen
+ * with 512 bytes room in dns.domains.
+ */
+
+ msg(D_LOW, "%s dns domain on '%s' (if_index = %d) using service",
+ (add ? "Setting" : "Deleting"), dns.iface.name, dns.iface.index);
+ if (!send_msg_iservice(pipe, &dns, sizeof(dns), &ack, "TUN"))
+ {
+ goto out;
+ }
+
+ if (ack.error_number != NO_ERROR)
+ {
+ msg(M_WARN, "TUN: %s dns domain failed using service: %s [status=%u if_name=%s]",
+ (add ? "adding" : "deleting"), strerror_win32(ack.error_number, &gc),
+ ack.error_number, dns.iface.name);
+ goto out;
+ }
+
+ msg(M_INFO, "DNS domain %s using service", (add ? "set" : "deleted"));
+ ret = true;
+
+out:
+ gc_free(&gc);
+ return ret;
+}
+
+static bool
do_dns_service(bool add, const short family, const struct tuntap *tt)
{
bool ret = false;
@@ -158,6 +219,7 @@ do_dns_service(bool add, const short family, const struct tuntap *tt)
return true;
}
+ /* Use dns_cfg_msg with domain = "" for setting only the DNS servers */
dns_cfg_message_t dns = {
.header = {
(add ? msg_add_dns_cfg : msg_del_dns_cfg),
@@ -1088,26 +1150,40 @@ do_ifconfig_ipv6(struct tuntap *tt, const char *ifname, int tun_mtu,
else if (tt->options.msg_channel)
{
do_address_service(true, AF_INET6, tt);
- add_route_connected_v6_net(tt, es);
+ if (tt->type == DEV_TYPE_TUN)
+ {
+ add_route_connected_v6_net(tt, es);
+ }
do_dns_service(true, AF_INET6, tt);
do_set_mtu_service(tt, AF_INET6, tun_mtu);
+ /* If IPv4 is not enabled, set DNS domain here */
+ if (!tt->did_ifconfig_setup)
+ {
+ do_dns_domain_service(true, tt);
+ }
}
else
{
- /* example: netsh interface ipv6 set address interface=42
- * 2001:608:8003::d store=active
+ /* example: netsh interface ipv6 set address 42
+ * 2001:608:8003::d/bits store=active
+ */
+
+ /* in TUN mode, we only simulate a subnet, so the interface
+ * is configured with /128 + a route to fe80::8. In TAP mode,
+ * the correct netbits must be set, and no on-link route
*/
- char iface[64];
+ int netbits = (tt->type == DEV_TYPE_TUN) ? 128 : tt->netbits_ipv6;
- openvpn_snprintf(iface, sizeof(iface), "interface=%lu",
- tt->adapter_index);
- argv_printf(&argv, "%s%s interface ipv6 set address %s %s store=active",
- get_win_sys_path(), NETSH_PATH_SUFFIX, iface,
- ifconfig_ipv6_local);
+ argv_printf(&argv, "%s%s interface ipv6 set address %lu %s/%d store=active",
+ get_win_sys_path(), NETSH_PATH_SUFFIX, tt->adapter_index,
+ ifconfig_ipv6_local, netbits);
netsh_command(&argv, 4, M_FATAL);
- add_route_connected_v6_net(tt, es);
+ if (tt->type == DEV_TYPE_TUN)
+ {
+ add_route_connected_v6_net(tt, es);
+ }
/* set ipv6 dns servers if any are specified */
- netsh_set_dns6_servers(tt->options.dns6, tt->options.dns6_len, ifname);
+ netsh_set_dns6_servers(tt->options.dns6, tt->options.dns6_len, tt->adapter_index);
windows_set_mtu(tt->adapter_index, AF_INET6, tun_mtu);
}
#else /* platforms we have no IPv6 code for */
@@ -1224,7 +1300,7 @@ do_ifconfig_ipv4(struct tuntap *tt, const char *ifname, int tun_mtu,
argv_printf(&argv, "%s %s netmask 255.255.255.255", IFCONFIG_PATH,
ifname);
}
- else if (tt->topology == TOP_SUBNET)
+ else if (tt->type == DEV_TYPE_TUN && tt->topology == TOP_SUBNET)
{
argv_printf(&argv, "%s %s %s %s netmask %s mtu %d up", IFCONFIG_PATH,
ifname, ifconfig_local, ifconfig_local,
@@ -1243,7 +1319,7 @@ do_ifconfig_ipv4(struct tuntap *tt, const char *ifname, int tun_mtu,
solaris_error_close(tt, es, ifname, false);
}
- if (!tun && tt->topology == TOP_SUBNET)
+ if (!tun && tt->type == DEV_TYPE_TUN && tt->topology == TOP_SUBNET)
{
/* Add a network route for the local tun interface */
struct route_ipv4 r;
@@ -1274,7 +1350,7 @@ do_ifconfig_ipv4(struct tuntap *tt, const char *ifname, int tun_mtu,
IFCONFIG_PATH, ifname, ifconfig_local,
ifconfig_remote_netmask, tun_mtu);
}
- else if (tt->topology == TOP_SUBNET)
+ else if (tt->type == DEV_TYPE_TUN && tt->topology == TOP_SUBNET)
{
remote_end = create_arbitrary_remote( tt );
argv_printf(&argv, "%s %s %s %s mtu %d netmask %s up -link0",
@@ -1292,7 +1368,7 @@ do_ifconfig_ipv4(struct tuntap *tt, const char *ifname, int tun_mtu,
openvpn_execve_check(&argv, es, S_FATAL, "OpenBSD ifconfig failed");
/* Add a network route for the local tun interface */
- if (!tun && tt->topology == TOP_SUBNET)
+ if (!tun && tt->type == DEV_TYPE_TUN && tt->topology == TOP_SUBNET)
{
struct route_ipv4 r;
CLEAR(r);
@@ -1312,7 +1388,7 @@ do_ifconfig_ipv4(struct tuntap *tt, const char *ifname, int tun_mtu,
IFCONFIG_PATH, ifname, ifconfig_local,
ifconfig_remote_netmask, tun_mtu);
}
- else if (tt->topology == TOP_SUBNET)
+ else if (tt->type == DEV_TYPE_TUN && tt->topology == TOP_SUBNET)
{
remote_end = create_arbitrary_remote(tt);
argv_printf(&argv, "%s %s %s %s mtu %d netmask %s up", IFCONFIG_PATH,
@@ -1334,7 +1410,7 @@ do_ifconfig_ipv4(struct tuntap *tt, const char *ifname, int tun_mtu,
openvpn_execve_check(&argv, es, S_FATAL, "NetBSD ifconfig failed");
/* Add a network route for the local tun interface */
- if (!tun && tt->topology == TOP_SUBNET)
+ if (!tun && tt->type == DEV_TYPE_TUN && tt->topology == TOP_SUBNET)
{
struct route_ipv4 r;
CLEAR(r);
@@ -1366,7 +1442,7 @@ do_ifconfig_ipv4(struct tuntap *tt, const char *ifname, int tun_mtu,
}
else
{
- if (tt->topology == TOP_SUBNET)
+ if (tt->type == DEV_TYPE_TUN && tt->topology == TOP_SUBNET)
{
argv_printf(&argv, "%s %s %s %s netmask %s mtu %d up",
IFCONFIG_PATH, ifname, ifconfig_local, ifconfig_local,
@@ -1384,7 +1460,7 @@ do_ifconfig_ipv4(struct tuntap *tt, const char *ifname, int tun_mtu,
openvpn_execve_check(&argv, es, S_FATAL, "Mac OS X ifconfig failed");
/* Add a network route for the local tun interface */
- if (!tun && tt->topology == TOP_SUBNET)
+ if (!tun && tt->type == DEV_TYPE_TUN && tt->topology == TOP_SUBNET)
{
struct route_ipv4 r;
CLEAR(r);
@@ -1406,7 +1482,7 @@ do_ifconfig_ipv4(struct tuntap *tt, const char *ifname, int tun_mtu,
IFCONFIG_PATH, ifname, ifconfig_local,
ifconfig_remote_netmask, tun_mtu);
}
- else if (tt->topology == TOP_SUBNET)
+ else if (tt->type == DEV_TYPE_TUN && tt->topology == TOP_SUBNET)
{
remote_end = create_arbitrary_remote( tt );
argv_printf(&argv, "%s %s %s %s mtu %d netmask %s up", IFCONFIG_PATH,
@@ -1423,7 +1499,7 @@ do_ifconfig_ipv4(struct tuntap *tt, const char *ifname, int tun_mtu,
openvpn_execve_check(&argv, es, S_FATAL, "FreeBSD ifconfig failed");
/* Add a network route for the local tun interface */
- if (!tun && tt->topology == TOP_SUBNET)
+ if (!tun && tt->type == DEV_TYPE_TUN && tt->topology == TOP_SUBNET)
{
struct route_ipv4 r;
CLEAR(r);
@@ -1455,8 +1531,6 @@ do_ifconfig_ipv4(struct tuntap *tt, const char *ifname, int tun_mtu,
env_set_destroy(aix_es);
}
#elif defined (_WIN32)
- ASSERT(ifname != NULL);
-
if (tt->options.ip_win32_type == IPW32_SET_MANUAL)
{
msg(M_INFO,
@@ -1472,10 +1546,11 @@ do_ifconfig_ipv4(struct tuntap *tt, const char *ifname, int tun_mtu,
{
do_address_service(true, AF_INET, tt);
do_dns_service(true, AF_INET, tt);
+ do_dns_domain_service(true, tt);
}
else if (tt->options.ip_win32_type == IPW32_SET_NETSH)
{
- netsh_ifconfig(&tt->options, ifname, tt->local,
+ netsh_ifconfig(&tt->options, tt->adapter_index, tt->local,
tt->adapter_netmask, NI_IP_NETMASK|NI_OPTIONS);
}
if (tt->options.msg_channel)
@@ -1993,6 +2068,11 @@ open_tun(const char *dev, const char *dev_type, const char *dev_node, struct tun
#ifdef ENABLE_FEATURE_TUN_PERSIST
+/* TUNSETGROUP appeared in 2.6.23 */
+#ifndef TUNSETGROUP
+# define TUNSETGROUP _IOW('T', 206, int)
+#endif
+
void
tuncfg(const char *dev, const char *dev_type, const char *dev_node,
int persist_mode, const char *username, const char *groupname,
@@ -2032,7 +2112,7 @@ tuncfg(const char *dev, const char *dev_type, const char *dev_node,
}
else if (ioctl(tt->fd, TUNSETGROUP, platform_state_group.gr->gr_gid) < 0)
{
- msg(M_ERR, "Cannot ioctl TUNSETOWNER(%s) %s", groupname, dev);
+ msg(M_ERR, "Cannot ioctl TUNSETGROUP(%s) %s", groupname, dev);
}
}
close_tun(tt, ctx);
@@ -5263,23 +5343,29 @@ ip_addr_member_of(const in_addr_t addr, const IP_ADDR_STRING *ias)
* Set the ipv6 dns servers on the specified interface.
* The list of dns servers currently set on the interface
* are cleared first.
- * No action is taken if number of addresses (addr_len) < 1.
*/
static void
netsh_set_dns6_servers(const struct in6_addr *addr_list,
const int addr_len,
- const char *flex_name)
+ DWORD adapter_index)
{
struct gc_arena gc = gc_new();
struct argv argv = argv_new();
+ /* delete existing DNS settings from TAP interface */
+ argv_printf(&argv, "%s%s interface ipv6 delete dns %lu all",
+ get_win_sys_path(),
+ NETSH_PATH_SUFFIX,
+ adapter_index);
+ netsh_command(&argv, 2, M_FATAL);
+
for (int i = 0; i < addr_len; ++i)
{
const char *fmt = (i == 0) ?
- "%s%s interface ipv6 set dns %s static %s"
- : "%s%s interface ipv6 add dns %s %s";
+ "%s%s interface ipv6 set dns %lu static %s"
+ : "%s%s interface ipv6 add dns %lu %s";
argv_printf(&argv, fmt, get_win_sys_path(),
- NETSH_PATH_SUFFIX, flex_name,
+ NETSH_PATH_SUFFIX, adapter_index,
print_in6_addr(addr_list[i], 0, &gc));
/* disable slow address validation on Windows 7 and higher */
@@ -5301,7 +5387,7 @@ netsh_ifconfig_options(const char *type,
const in_addr_t *addr_list,
const int addr_len,
const IP_ADDR_STRING *current,
- const char *flex_name,
+ DWORD adapter_index,
const bool test_first)
{
struct gc_arena gc = gc_new();
@@ -5325,11 +5411,11 @@ netsh_ifconfig_options(const char *type,
/* delete existing DNS/WINS settings from TAP interface */
if (delete_first)
{
- argv_printf(&argv, "%s%s interface ip delete %s %s all",
+ argv_printf(&argv, "%s%s interface ip delete %s %lu all",
get_win_sys_path(),
NETSH_PATH_SUFFIX,
type,
- flex_name);
+ adapter_index);
netsh_command(&argv, 2, M_FATAL);
}
@@ -5342,14 +5428,14 @@ netsh_ifconfig_options(const char *type,
if (delete_first || !test_first || !ip_addr_member_of(addr_list[i], current))
{
const char *fmt = count ?
- "%s%s interface ip add %s %s %s"
- : "%s%s interface ip set %s %s static %s";
+ "%s%s interface ip add %s %lu %s"
+ : "%s%s interface ip set %s %lu static %s";
argv_printf(&argv, fmt,
get_win_sys_path(),
NETSH_PATH_SUFFIX,
type,
- flex_name,
+ adapter_index,
print_in_addr_t(addr_list[i], 0, &gc));
/* disable slow address validation on Windows 7 and higher */
@@ -5365,8 +5451,8 @@ netsh_ifconfig_options(const char *type,
}
else
{
- msg(M_INFO, "NETSH: \"%s\" %s %s [already set]",
- flex_name,
+ msg(M_INFO, "NETSH: %lu %s %s [already set]",
+ adapter_index,
type,
print_in_addr_t(addr_list[i], 0, &gc));
}
@@ -5397,7 +5483,7 @@ init_ip_addr_string2(IP_ADDR_STRING *dest, const IP_ADDR_STRING *src1, const IP_
static void
netsh_ifconfig(const struct tuntap_options *to,
- const char *flex_name,
+ DWORD adapter_index,
const in_addr_t ip,
const in_addr_t netmask,
const unsigned int flags)
@@ -5410,27 +5496,26 @@ netsh_ifconfig(const struct tuntap_options *to,
if (flags & NI_TEST_FIRST)
{
const IP_ADAPTER_INFO *list = get_adapter_info_list(&gc);
- const int index = get_adapter_index_flexible(flex_name);
- ai = get_adapter(list, index);
- pai = get_per_adapter_info(index, &gc);
+ ai = get_adapter(list, adapter_index);
+ pai = get_per_adapter_info(adapter_index, &gc);
}
if (flags & NI_IP_NETMASK)
{
if (test_adapter_ip_netmask(ai, ip, netmask))
{
- msg(M_INFO, "NETSH: \"%s\" %s/%s [already set]",
- flex_name,
+ msg(M_INFO, "NETSH: %lu %s/%s [already set]",
+ adapter_index,
print_in_addr_t(ip, 0, &gc),
print_in_addr_t(netmask, 0, &gc));
}
else
{
- /* example: netsh interface ip set address my-tap static 10.3.0.1 255.255.255.0 */
- argv_printf(&argv, "%s%s interface ip set address %s static %s %s",
+ /* example: netsh interface ip set address 42 static 10.3.0.1 255.255.255.0 */
+ argv_printf(&argv, "%s%s interface ip set address %lu static %s %s",
get_win_sys_path(),
NETSH_PATH_SUFFIX,
- flex_name,
+ adapter_index,
print_in_addr_t(ip, 0, &gc),
print_in_addr_t(netmask, 0, &gc));
@@ -5449,7 +5534,7 @@ netsh_ifconfig(const struct tuntap_options *to,
to->dns,
to->dns_len,
pai ? &pai->DnsServerList : NULL,
- flex_name,
+ adapter_index,
BOOL_CAST(flags & NI_TEST_FIRST));
if (ai && ai->HaveWins)
{
@@ -5460,7 +5545,7 @@ netsh_ifconfig(const struct tuntap_options *to,
to->wins,
to->wins_len,
ai ? wins : NULL,
- flex_name,
+ adapter_index,
BOOL_CAST(flags & NI_TEST_FIRST));
}
@@ -5469,16 +5554,16 @@ netsh_ifconfig(const struct tuntap_options *to,
}
static void
-netsh_enable_dhcp(const char *actual_name)
+netsh_enable_dhcp(DWORD adapter_index)
{
struct argv argv = argv_new();
- /* example: netsh interface ip set address my-tap dhcp */
+ /* example: netsh interface ip set address 42 dhcp */
argv_printf(&argv,
- "%s%s interface ip set address %s dhcp",
+ "%s%s interface ip set address %lu dhcp",
get_win_sys_path(),
NETSH_PATH_SUFFIX,
- actual_name);
+ adapter_index);
netsh_command(&argv, 4, M_FATAL);
@@ -5624,7 +5709,7 @@ tun_standby(struct tuntap *tt)
{
msg(M_INFO, "NOTE: now trying netsh (this may take some time)");
netsh_ifconfig(&tt->options,
- tt->actual_name,
+ tt->adapter_index,
tt->local,
tt->adapter_netmask,
NI_TEST_FIRST|NI_IP_NETMASK|NI_OPTIONS);
@@ -6486,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)
@@ -6529,7 +6614,7 @@ tuntap_set_ip_props(const struct tuntap *tt, bool *dhcp_masq, bool *dhcp_masq_po
}
else
{
- netsh_enable_dhcp(tt->actual_name);
+ netsh_enable_dhcp(tt->adapter_index);
}
}
*dhcp_masq = true;
@@ -6543,7 +6628,7 @@ tuntap_set_ip_props(const struct tuntap *tt, bool *dhcp_masq, bool *dhcp_masq_po
if (dhcp_status(tt->adapter_index) != DHCP_STATUS_ENABLED)
{
netsh_ifconfig(&tt->options,
- tt->actual_name,
+ tt->adapter_index,
tt->local,
tt->adapter_netmask,
NI_TEST_FIRST | NI_IP_NETMASK | NI_OPTIONS);
@@ -6675,15 +6760,25 @@ netsh_delete_address_dns(const struct tuntap *tt, bool ipv6, struct gc_arena *gc
if (len > 0)
{
argv_printf(&argv,
- "%s%s interface %s delete dns %s all",
+ "%s%s interface %s delete dns %lu all",
get_win_sys_path(),
NETSH_PATH_SUFFIX,
ipv6 ? "ipv6" : "ipv4",
- tt->actual_name);
+ tt->adapter_index);
netsh_command(&argv, 1, M_WARN);
}
- if (ipv6)
+ if (!ipv6 && tt->options.wins_len > 0)
+ {
+ argv_printf(&argv,
+ "%s%s interface ipv4 delete winsservers %lu all",
+ get_win_sys_path(),
+ NETSH_PATH_SUFFIX,
+ tt->adapter_index);
+ netsh_command(&argv, 1, M_WARN);
+ }
+
+ if (ipv6 && tt->type == DEV_TYPE_TUN)
{
delete_route_connected_v6_net(tt);
}
@@ -6692,7 +6787,7 @@ netsh_delete_address_dns(const struct tuntap *tt, bool ipv6, struct gc_arena *gc
* address we added (pointed out by Cedric Tabary).
*/
- /* netsh interface ipvX delete address \"%s\" %s */
+ /* netsh interface ipvX delete address %lu %s */
if (ipv6)
{
ifconfig_ip_local = print_in6_addr(tt->local_ipv6, 0, gc);
@@ -6702,11 +6797,11 @@ netsh_delete_address_dns(const struct tuntap *tt, bool ipv6, struct gc_arena *gc
ifconfig_ip_local = print_in_addr_t(tt->local, 0, gc);
}
argv_printf(&argv,
- "%s%s interface %s delete address %s %s store=active",
+ "%s%s interface %s delete address %lu %s store=active",
get_win_sys_path(),
NETSH_PATH_SUFFIX,
ipv6 ? "ipv6" : "ipv4",
- tt->actual_name,
+ tt->adapter_index,
ifconfig_ip_local);
netsh_command(&argv, 1, M_WARN);
@@ -6728,6 +6823,11 @@ close_tun(struct tuntap *tt, openvpn_net_ctx_t *ctx)
}
else if (tt->options.msg_channel)
{
+ /* If IPv4 is not enabled, delete DNS domain here */
+ if (!tt->did_ifconfig_setup)
+ {
+ do_dns_domain_service(false, tt);
+ }
if (tt->options.dns6_len > 0)
{
do_dns_service(false, AF_INET6, tt);
@@ -6753,6 +6853,7 @@ close_tun(struct tuntap *tt, openvpn_net_ctx_t *ctx)
}
else if (tt->options.msg_channel)
{
+ do_dns_domain_service(false, tt);
do_dns_service(false, AF_INET, tt);
do_address_service(false, AF_INET, tt);
}