diff options
author | Bernhard Schmidt <berni@debian.org> | 2019-02-20 14:11:51 +0100 |
---|---|---|
committer | Bernhard Schmidt <berni@debian.org> | 2019-02-20 14:11:51 +0100 |
commit | 39ddb9cc8281bd239b94a3023da6329edb6718c1 (patch) | |
tree | dc6a8e7f1018f59f088c5b06b48eb24efe17f22d /src/openvpn | |
parent | d5078cc44b8919a25cb7507e9e6da1d66f25bb5b (diff) | |
parent | 87356242baf10c8b2a94d9013e436ed2a0dada53 (diff) |
Update upstream source from tag 'upstream/2.4.7'
Update to upstream version '2.4.7'
with Debian dir d01da6ef78dc8ce91265e8f319468f6c34d23af8
Diffstat (limited to 'src/openvpn')
-rw-r--r-- | src/openvpn/Makefile.in | 368 | ||||
-rw-r--r-- | src/openvpn/argv.c | 7 | ||||
-rw-r--r-- | src/openvpn/buffer.c | 71 | ||||
-rw-r--r-- | src/openvpn/buffer.h | 67 | ||||
-rw-r--r-- | src/openvpn/crypto.c | 6 | ||||
-rw-r--r-- | src/openvpn/crypto.h | 2 | ||||
-rw-r--r-- | src/openvpn/crypto_openssl.c | 11 | ||||
-rw-r--r-- | src/openvpn/cryptoapi.c | 87 | ||||
-rw-r--r-- | src/openvpn/init.c | 42 | ||||
-rw-r--r-- | src/openvpn/misc.c | 16 | ||||
-rw-r--r-- | src/openvpn/misc.h | 4 | ||||
-rw-r--r-- | src/openvpn/mroute.c | 7 | ||||
-rw-r--r-- | src/openvpn/mtu.h | 8 | ||||
-rw-r--r-- | src/openvpn/openssl_compat.h | 20 | ||||
-rw-r--r-- | src/openvpn/openvpn.c | 3 | ||||
-rw-r--r-- | src/openvpn/options.c | 82 | ||||
-rw-r--r-- | src/openvpn/options.h | 5 | ||||
-rw-r--r-- | src/openvpn/plugin.c | 5 | ||||
-rw-r--r-- | src/openvpn/push.c | 17 | ||||
-rw-r--r-- | src/openvpn/socket.c | 140 | ||||
-rw-r--r-- | src/openvpn/socket.h | 12 | ||||
-rw-r--r-- | src/openvpn/ssl.c | 72 | ||||
-rw-r--r-- | src/openvpn/ssl.h | 17 | ||||
-rw-r--r-- | src/openvpn/ssl_backend.h | 25 | ||||
-rw-r--r-- | src/openvpn/ssl_common.h | 6 | ||||
-rw-r--r-- | src/openvpn/ssl_mbedtls.c | 32 | ||||
-rw-r--r-- | src/openvpn/ssl_openssl.c | 118 | ||||
-rw-r--r-- | src/openvpn/tun.c | 95 |
28 files changed, 1027 insertions, 318 deletions
diff --git a/src/openvpn/Makefile.in b/src/openvpn/Makefile.in index 69fa9c8..6aab503 100644 --- a/src/openvpn/Makefile.in +++ b/src/openvpn/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.16.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2018 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -217,7 +217,41 @@ am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) -I$(top_builddir)/include depcomp = $(SHELL) $(top_srcdir)/depcomp -am__depfiles_maybe = depfiles +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/argv.Po ./$(DEPDIR)/base64.Po \ + ./$(DEPDIR)/block_dns.Po ./$(DEPDIR)/buffer.Po \ + ./$(DEPDIR)/clinat.Po ./$(DEPDIR)/comp-lz4.Po \ + ./$(DEPDIR)/comp.Po ./$(DEPDIR)/compstub.Po \ + ./$(DEPDIR)/console.Po ./$(DEPDIR)/console_builtin.Po \ + ./$(DEPDIR)/console_systemd.Po ./$(DEPDIR)/crypto.Po \ + ./$(DEPDIR)/crypto_mbedtls.Po ./$(DEPDIR)/crypto_openssl.Po \ + ./$(DEPDIR)/cryptoapi.Po ./$(DEPDIR)/dhcp.Po \ + ./$(DEPDIR)/error.Po ./$(DEPDIR)/event.Po \ + ./$(DEPDIR)/fdmisc.Po ./$(DEPDIR)/forward.Po \ + ./$(DEPDIR)/fragment.Po ./$(DEPDIR)/gremlin.Po \ + ./$(DEPDIR)/helper.Po ./$(DEPDIR)/httpdigest.Po \ + ./$(DEPDIR)/init.Po ./$(DEPDIR)/interval.Po \ + ./$(DEPDIR)/list.Po ./$(DEPDIR)/lladdr.Po ./$(DEPDIR)/lzo.Po \ + ./$(DEPDIR)/manage.Po ./$(DEPDIR)/mbuf.Po ./$(DEPDIR)/misc.Po \ + ./$(DEPDIR)/mroute.Po ./$(DEPDIR)/mss.Po ./$(DEPDIR)/mstats.Po \ + ./$(DEPDIR)/mtcp.Po ./$(DEPDIR)/mtu.Po ./$(DEPDIR)/mudp.Po \ + ./$(DEPDIR)/multi.Po ./$(DEPDIR)/ntlm.Po ./$(DEPDIR)/occ.Po \ + ./$(DEPDIR)/openvpn.Po ./$(DEPDIR)/options.Po \ + ./$(DEPDIR)/otime.Po ./$(DEPDIR)/packet_id.Po \ + ./$(DEPDIR)/perf.Po ./$(DEPDIR)/pf.Po ./$(DEPDIR)/ping.Po \ + ./$(DEPDIR)/pkcs11.Po ./$(DEPDIR)/pkcs11_mbedtls.Po \ + ./$(DEPDIR)/pkcs11_openssl.Po ./$(DEPDIR)/platform.Po \ + ./$(DEPDIR)/plugin.Po ./$(DEPDIR)/pool.Po ./$(DEPDIR)/proto.Po \ + ./$(DEPDIR)/proxy.Po ./$(DEPDIR)/ps.Po ./$(DEPDIR)/push.Po \ + ./$(DEPDIR)/reliable.Po ./$(DEPDIR)/route.Po \ + ./$(DEPDIR)/schedule.Po ./$(DEPDIR)/session_id.Po \ + ./$(DEPDIR)/shaper.Po ./$(DEPDIR)/sig.Po ./$(DEPDIR)/socket.Po \ + ./$(DEPDIR)/socks.Po ./$(DEPDIR)/ssl.Po \ + ./$(DEPDIR)/ssl_mbedtls.Po ./$(DEPDIR)/ssl_openssl.Po \ + ./$(DEPDIR)/ssl_verify.Po ./$(DEPDIR)/ssl_verify_mbedtls.Po \ + ./$(DEPDIR)/ssl_verify_openssl.Po ./$(DEPDIR)/status.Po \ + ./$(DEPDIR)/tls_crypt.Po ./$(DEPDIR)/tun.Po \ + ./$(DEPDIR)/win32.Po am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) @@ -434,7 +468,6 @@ plugindir = @plugindir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ -runstatedir = @runstatedir@ sampledir = @sampledir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ @@ -520,8 +553,8 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_srcdir)/build/ltrc.inc $(am__empty): @@ -593,82 +626,88 @@ mostlyclean-compile: distclean-compile: -rm -f *.tab.c -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/argv.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/base64.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/block_dns.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/buffer.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/clinat.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/comp-lz4.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/comp.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/compstub.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/console.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/console_builtin.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/console_systemd.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/crypto.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/crypto_mbedtls.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/crypto_openssl.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cryptoapi.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dhcp.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/error.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/event.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fdmisc.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/forward.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fragment.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gremlin.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/helper.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/httpdigest.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/init.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/interval.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/list.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lladdr.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lzo.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/manage.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mbuf.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/misc.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mroute.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mss.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mstats.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mtcp.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mtu.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mudp.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/multi.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ntlm.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/occ.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openvpn.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/options.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/otime.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/packet_id.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/perf.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pf.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ping.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pkcs11.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pkcs11_mbedtls.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pkcs11_openssl.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/platform.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plugin.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pool.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/proto.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/proxy.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ps.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/push.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/reliable.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/route.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/schedule.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/session_id.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/shaper.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sig.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/socket.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/socks.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssl.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssl_mbedtls.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssl_openssl.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssl_verify.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssl_verify_mbedtls.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssl_verify_openssl.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/status.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tls_crypt.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tun.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/win32.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/argv.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/base64.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/block_dns.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/buffer.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/clinat.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/comp-lz4.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/comp.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/compstub.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/console.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/console_builtin.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/console_systemd.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/crypto.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/crypto_mbedtls.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/crypto_openssl.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cryptoapi.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dhcp.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/error.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/event.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fdmisc.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/forward.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fragment.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gremlin.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/helper.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/httpdigest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/init.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/interval.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/list.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lladdr.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lzo.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/manage.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mbuf.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/misc.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mroute.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mss.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mstats.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mtcp.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mtu.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mudp.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/multi.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ntlm.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/occ.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openvpn.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/options.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/otime.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/packet_id.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/perf.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pf.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ping.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pkcs11.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pkcs11_mbedtls.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pkcs11_openssl.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/platform.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plugin.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pool.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/proto.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/proxy.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ps.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/push.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/reliable.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/route.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/schedule.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/session_id.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/shaper.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sig.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/socket.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/socks.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssl.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssl_mbedtls.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssl_openssl.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssl_verify.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssl_verify_mbedtls.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssl_verify_openssl.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/status.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tls_crypt.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tun.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/win32.Po@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @@ -749,7 +788,10 @@ cscopelist-am: $(am__tagged_files) distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -distdir: $(DISTFILES) +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ @@ -823,7 +865,82 @@ clean-am: clean-generic clean-libtool clean-sbinPROGRAMS \ mostlyclean-am distclean: distclean-am - -rm -rf ./$(DEPDIR) + -rm -f ./$(DEPDIR)/argv.Po + -rm -f ./$(DEPDIR)/base64.Po + -rm -f ./$(DEPDIR)/block_dns.Po + -rm -f ./$(DEPDIR)/buffer.Po + -rm -f ./$(DEPDIR)/clinat.Po + -rm -f ./$(DEPDIR)/comp-lz4.Po + -rm -f ./$(DEPDIR)/comp.Po + -rm -f ./$(DEPDIR)/compstub.Po + -rm -f ./$(DEPDIR)/console.Po + -rm -f ./$(DEPDIR)/console_builtin.Po + -rm -f ./$(DEPDIR)/console_systemd.Po + -rm -f ./$(DEPDIR)/crypto.Po + -rm -f ./$(DEPDIR)/crypto_mbedtls.Po + -rm -f ./$(DEPDIR)/crypto_openssl.Po + -rm -f ./$(DEPDIR)/cryptoapi.Po + -rm -f ./$(DEPDIR)/dhcp.Po + -rm -f ./$(DEPDIR)/error.Po + -rm -f ./$(DEPDIR)/event.Po + -rm -f ./$(DEPDIR)/fdmisc.Po + -rm -f ./$(DEPDIR)/forward.Po + -rm -f ./$(DEPDIR)/fragment.Po + -rm -f ./$(DEPDIR)/gremlin.Po + -rm -f ./$(DEPDIR)/helper.Po + -rm -f ./$(DEPDIR)/httpdigest.Po + -rm -f ./$(DEPDIR)/init.Po + -rm -f ./$(DEPDIR)/interval.Po + -rm -f ./$(DEPDIR)/list.Po + -rm -f ./$(DEPDIR)/lladdr.Po + -rm -f ./$(DEPDIR)/lzo.Po + -rm -f ./$(DEPDIR)/manage.Po + -rm -f ./$(DEPDIR)/mbuf.Po + -rm -f ./$(DEPDIR)/misc.Po + -rm -f ./$(DEPDIR)/mroute.Po + -rm -f ./$(DEPDIR)/mss.Po + -rm -f ./$(DEPDIR)/mstats.Po + -rm -f ./$(DEPDIR)/mtcp.Po + -rm -f ./$(DEPDIR)/mtu.Po + -rm -f ./$(DEPDIR)/mudp.Po + -rm -f ./$(DEPDIR)/multi.Po + -rm -f ./$(DEPDIR)/ntlm.Po + -rm -f ./$(DEPDIR)/occ.Po + -rm -f ./$(DEPDIR)/openvpn.Po + -rm -f ./$(DEPDIR)/options.Po + -rm -f ./$(DEPDIR)/otime.Po + -rm -f ./$(DEPDIR)/packet_id.Po + -rm -f ./$(DEPDIR)/perf.Po + -rm -f ./$(DEPDIR)/pf.Po + -rm -f ./$(DEPDIR)/ping.Po + -rm -f ./$(DEPDIR)/pkcs11.Po + -rm -f ./$(DEPDIR)/pkcs11_mbedtls.Po + -rm -f ./$(DEPDIR)/pkcs11_openssl.Po + -rm -f ./$(DEPDIR)/platform.Po + -rm -f ./$(DEPDIR)/plugin.Po + -rm -f ./$(DEPDIR)/pool.Po + -rm -f ./$(DEPDIR)/proto.Po + -rm -f ./$(DEPDIR)/proxy.Po + -rm -f ./$(DEPDIR)/ps.Po + -rm -f ./$(DEPDIR)/push.Po + -rm -f ./$(DEPDIR)/reliable.Po + -rm -f ./$(DEPDIR)/route.Po + -rm -f ./$(DEPDIR)/schedule.Po + -rm -f ./$(DEPDIR)/session_id.Po + -rm -f ./$(DEPDIR)/shaper.Po + -rm -f ./$(DEPDIR)/sig.Po + -rm -f ./$(DEPDIR)/socket.Po + -rm -f ./$(DEPDIR)/socks.Po + -rm -f ./$(DEPDIR)/ssl.Po + -rm -f ./$(DEPDIR)/ssl_mbedtls.Po + -rm -f ./$(DEPDIR)/ssl_openssl.Po + -rm -f ./$(DEPDIR)/ssl_verify.Po + -rm -f ./$(DEPDIR)/ssl_verify_mbedtls.Po + -rm -f ./$(DEPDIR)/ssl_verify_openssl.Po + -rm -f ./$(DEPDIR)/status.Po + -rm -f ./$(DEPDIR)/tls_crypt.Po + -rm -f ./$(DEPDIR)/tun.Po + -rm -f ./$(DEPDIR)/win32.Po -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags @@ -869,7 +986,82 @@ install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am - -rm -rf ./$(DEPDIR) + -rm -f ./$(DEPDIR)/argv.Po + -rm -f ./$(DEPDIR)/base64.Po + -rm -f ./$(DEPDIR)/block_dns.Po + -rm -f ./$(DEPDIR)/buffer.Po + -rm -f ./$(DEPDIR)/clinat.Po + -rm -f ./$(DEPDIR)/comp-lz4.Po + -rm -f ./$(DEPDIR)/comp.Po + -rm -f ./$(DEPDIR)/compstub.Po + -rm -f ./$(DEPDIR)/console.Po + -rm -f ./$(DEPDIR)/console_builtin.Po + -rm -f ./$(DEPDIR)/console_systemd.Po + -rm -f ./$(DEPDIR)/crypto.Po + -rm -f ./$(DEPDIR)/crypto_mbedtls.Po + -rm -f ./$(DEPDIR)/crypto_openssl.Po + -rm -f ./$(DEPDIR)/cryptoapi.Po + -rm -f ./$(DEPDIR)/dhcp.Po + -rm -f ./$(DEPDIR)/error.Po + -rm -f ./$(DEPDIR)/event.Po + -rm -f ./$(DEPDIR)/fdmisc.Po + -rm -f ./$(DEPDIR)/forward.Po + -rm -f ./$(DEPDIR)/fragment.Po + -rm -f ./$(DEPDIR)/gremlin.Po + -rm -f ./$(DEPDIR)/helper.Po + -rm -f ./$(DEPDIR)/httpdigest.Po + -rm -f ./$(DEPDIR)/init.Po + -rm -f ./$(DEPDIR)/interval.Po + -rm -f ./$(DEPDIR)/list.Po + -rm -f ./$(DEPDIR)/lladdr.Po + -rm -f ./$(DEPDIR)/lzo.Po + -rm -f ./$(DEPDIR)/manage.Po + -rm -f ./$(DEPDIR)/mbuf.Po + -rm -f ./$(DEPDIR)/misc.Po + -rm -f ./$(DEPDIR)/mroute.Po + -rm -f ./$(DEPDIR)/mss.Po + -rm -f ./$(DEPDIR)/mstats.Po + -rm -f ./$(DEPDIR)/mtcp.Po + -rm -f ./$(DEPDIR)/mtu.Po + -rm -f ./$(DEPDIR)/mudp.Po + -rm -f ./$(DEPDIR)/multi.Po + -rm -f ./$(DEPDIR)/ntlm.Po + -rm -f ./$(DEPDIR)/occ.Po + -rm -f ./$(DEPDIR)/openvpn.Po + -rm -f ./$(DEPDIR)/options.Po + -rm -f ./$(DEPDIR)/otime.Po + -rm -f ./$(DEPDIR)/packet_id.Po + -rm -f ./$(DEPDIR)/perf.Po + -rm -f ./$(DEPDIR)/pf.Po + -rm -f ./$(DEPDIR)/ping.Po + -rm -f ./$(DEPDIR)/pkcs11.Po + -rm -f ./$(DEPDIR)/pkcs11_mbedtls.Po + -rm -f ./$(DEPDIR)/pkcs11_openssl.Po + -rm -f ./$(DEPDIR)/platform.Po + -rm -f ./$(DEPDIR)/plugin.Po + -rm -f ./$(DEPDIR)/pool.Po + -rm -f ./$(DEPDIR)/proto.Po + -rm -f ./$(DEPDIR)/proxy.Po + -rm -f ./$(DEPDIR)/ps.Po + -rm -f ./$(DEPDIR)/push.Po + -rm -f ./$(DEPDIR)/reliable.Po + -rm -f ./$(DEPDIR)/route.Po + -rm -f ./$(DEPDIR)/schedule.Po + -rm -f ./$(DEPDIR)/session_id.Po + -rm -f ./$(DEPDIR)/shaper.Po + -rm -f ./$(DEPDIR)/sig.Po + -rm -f ./$(DEPDIR)/socket.Po + -rm -f ./$(DEPDIR)/socks.Po + -rm -f ./$(DEPDIR)/ssl.Po + -rm -f ./$(DEPDIR)/ssl_mbedtls.Po + -rm -f ./$(DEPDIR)/ssl_openssl.Po + -rm -f ./$(DEPDIR)/ssl_verify.Po + -rm -f ./$(DEPDIR)/ssl_verify_mbedtls.Po + -rm -f ./$(DEPDIR)/ssl_verify_openssl.Po + -rm -f ./$(DEPDIR)/status.Po + -rm -f ./$(DEPDIR)/tls_crypt.Po + -rm -f ./$(DEPDIR)/tun.Po + -rm -f ./$(DEPDIR)/win32.Po -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic @@ -890,9 +1082,9 @@ uninstall-am: uninstall-sbinPROGRAMS .MAKE: install-am install-strip -.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ - clean-libtool clean-sbinPROGRAMS cscopelist-am ctags ctags-am \ - distclean distclean-compile distclean-generic \ +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ + clean-generic clean-libtool clean-sbinPROGRAMS cscopelist-am \ + ctags ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ diff --git a/src/openvpn/argv.c b/src/openvpn/argv.c index 124e1c4..7d06951 100644 --- a/src/openvpn/argv.c +++ b/src/openvpn/argv.c @@ -250,6 +250,13 @@ argv_printf_arglist(struct argv *a, const char *format, va_list arglist) openvpn_snprintf(numstr, sizeof(numstr), "%u", va_arg(arglist, unsigned int)); argv_append(a, string_alloc(numstr, NULL)); } + else if (!strcmp(term, "%lu")) + { + char numstr[64]; + openvpn_snprintf(numstr, sizeof(numstr), "%lu", + va_arg(arglist, unsigned long)); + argv_append(a, string_alloc(numstr, NULL)); + } else if (!strcmp(term, "%s/%d")) { char numstr[64]; diff --git a/src/openvpn/buffer.c b/src/openvpn/buffer.c index f2ab066..f9c76b1 100644 --- a/src/openvpn/buffer.c +++ b/src/openvpn/buffer.c @@ -1234,49 +1234,44 @@ void buffer_list_aggregate_separator(struct buffer_list *bl, const size_t max_len, const char *sep) { - int sep_len = strlen(sep); + const int sep_len = strlen(sep); + struct buffer_entry *more = bl->head; + size_t size = 0; + int count = 0; + for (count = 0; more; ++count) + { + size_t extra_len = BLEN(&more->buf) + sep_len; + if (size + extra_len > max_len) + { + break; + } + + size += extra_len; + more = more->next; + } - if (bl->head) + if (count >= 2) { - struct buffer_entry *more = bl->head; - size_t size = 0; - int count = 0; - for (count = 0; more; ++count) - { - size_t extra_len = BLEN(&more->buf) + sep_len; - if (size + extra_len > max_len) - { - break; - } + struct buffer_entry *f; + ALLOC_OBJ_CLEAR(f, struct buffer_entry); + f->buf = alloc_buf(size + 1); /* prevent 0-byte malloc */ - size += extra_len; - more = more->next; + struct buffer_entry *e = bl->head; + for (size_t i = 0; e && i < count; ++i) + { + struct buffer_entry *next = e->next; + buf_copy(&f->buf, &e->buf); + buf_write(&f->buf, sep, sep_len); + free_buf(&e->buf); + free(e); + e = next; } - - if (count >= 2) + bl->head = f; + bl->size -= count - 1; + f->next = more; + if (!more) { - int i; - struct buffer_entry *e = bl->head, *f; - - ALLOC_OBJ_CLEAR(f, struct buffer_entry); - f->buf = alloc_buf(size + 1); /* prevent 0-byte malloc */ - f->buf.capacity = size; - for (i = 0; e && i < count; ++i) - { - struct buffer_entry *next = e->next; - buf_copy(&f->buf, &e->buf); - buf_write(&f->buf, sep, sep_len); - free_buf(&e->buf); - free(e); - e = next; - } - bl->head = f; - bl->size -= count - 1; - f->next = more; - if (!more) - { - bl->tail = f; - } + bl->tail = f; } } } diff --git a/src/openvpn/buffer.h b/src/openvpn/buffer.h index e37254c..c510c00 100644 --- a/src/openvpn/buffer.h +++ b/src/openvpn/buffer.h @@ -1082,26 +1082,93 @@ struct buffer_list int max_size; /* maximum size list should grow to */ }; +/** + * Allocate an empty buffer list of capacity \c max_size. + * + * @param max_size the capacity of the list to allocate + * + * @return the new list + */ struct buffer_list *buffer_list_new(const int max_size); +/** + * Frees a buffer list and all the buffers in it. + * + * @param ol the list to free + */ void buffer_list_free(struct buffer_list *ol); +/** + * Checks if the list is valid and non-empty + * + * @param ol the list to check + * + * @return true iff \c ol is not NULL and contains at least one buffer + */ bool buffer_list_defined(const struct buffer_list *ol); +/** + * Empty the list \c ol and frees all the contained buffers + * + * @param ol the list to reset + */ void buffer_list_reset(struct buffer_list *ol); +/** + * Allocates and appends a new buffer containing \c str as data to \c ol + * + * @param ol the list to append the new buffer to + * @param str the string to copy into the new buffer + */ void buffer_list_push(struct buffer_list *ol, const char *str); +/** + * Allocates and appends a new buffer containing \c data of length \c size. + * + * @param ol the list to append the new buffer to + * @param data the data to copy into the new buffer + * @param size the length of \c data to copy into the buffer + * + * @return the new buffer + */ struct buffer_entry *buffer_list_push_data(struct buffer_list *ol, const void *data, size_t size); +/** + * Retrieve the head buffer + * + * @param ol the list to retrieve the buffer from + * + * @return a pointer to the head buffer or NULL if the list is empty + */ struct buffer *buffer_list_peek(struct buffer_list *ol); void buffer_list_advance(struct buffer_list *ol, int n); void buffer_list_pop(struct buffer_list *ol); +/** + * Aggregates as many buffers as possible from \c bl in a new buffer of maximum + * length \c max_len . + * All the aggregated buffers are removed from the list and replaced by the new + * one, followed by any additional (non-aggregated) data. + * + * @param bl the list of buffer to aggregate + * @param max the maximum length of the aggregated buffer + */ void buffer_list_aggregate(struct buffer_list *bl, const size_t max); +/** + * Aggregates as many buffers as possible from \c bl in a new buffer + * of maximum length \c max_len . \c sep is written after + * each copied buffer (also after the last one). All the aggregated buffers are + * removed from the list and replaced by the new one, followed by any additional + * (non-aggregated) data. + * Nothing happens if \c max_len is not enough to aggregate at least 2 buffers. + * + * @param bl the list of buffer to aggregate + * @param max_len the maximum length of the aggregated buffer + * @param sep the separator to put between buffers during aggregation + */ void buffer_list_aggregate_separator(struct buffer_list *bl, const size_t max_len, const char *sep); diff --git a/src/openvpn/crypto.c b/src/openvpn/crypto.c index dba3aa5..59e5ac5 100644 --- a/src/openvpn/crypto.c +++ b/src/openvpn/crypto.c @@ -721,7 +721,7 @@ crypto_adjust_frame_parameters(struct frame *frame, bool packet_id, bool packet_id_long_form) { - size_t crypto_overhead = 0; + unsigned int crypto_overhead = 0; if (packet_id) { @@ -749,10 +749,10 @@ crypto_adjust_frame_parameters(struct frame *frame, frame_add_to_extra_frame(frame, crypto_overhead); msg(D_MTU_DEBUG, "%s: Adjusting frame parameters for crypto by %u bytes", - __func__, (unsigned int) crypto_overhead); + __func__, crypto_overhead); } -size_t +unsigned int crypto_max_overhead(void) { return packet_id_size(true) + OPENVPN_MAX_IV_LENGTH diff --git a/src/openvpn/crypto.h b/src/openvpn/crypto.h index e42f697..185bfd3 100644 --- a/src/openvpn/crypto.h +++ b/src/openvpn/crypto.h @@ -426,7 +426,7 @@ void crypto_adjust_frame_parameters(struct frame *frame, bool packet_id_long_form); /** Return the worst-case OpenVPN crypto overhead (in bytes) */ -size_t crypto_max_overhead(void); +unsigned int crypto_max_overhead(void); /* Minimum length of the nonce used by the PRNG */ #define NONCE_SECRET_LEN_MIN 16 diff --git a/src/openvpn/crypto_openssl.c b/src/openvpn/crypto_openssl.c index eae2b91..71602f3 100644 --- a/src/openvpn/crypto_openssl.c +++ b/src/openvpn/crypto_openssl.c @@ -199,7 +199,16 @@ crypto_print_openssl_errors(const unsigned int flags) "in common with the client. Your --tls-cipher setting might be " "too restrictive."); } - + else if (ERR_GET_REASON(err) == SSL_R_UNSUPPORTED_PROTOCOL) + { + msg(D_CRYPT_ERRORS, "TLS error: Unsupported protocol. This typically " + "indicates that client and server have no common TLS version enabled. " + "This can be caused by mismatched tls-version-min and tls-version-max " + "options on client and server. " + "If your OpenVPN client is between v2.3.6 and v2.3.2 try adding " + "tls-version-min 1.0 to the client configuration to use TLS 1.0+ " + "instead of TLS 1.0 only"); + } msg(flags, "OpenSSL: %s", ERR_error_string(err, NULL)); } } diff --git a/src/openvpn/cryptoapi.c b/src/openvpn/cryptoapi.c index 89d253c..720fce0 100644 --- a/src/openvpn/cryptoapi.c +++ b/src/openvpn/cryptoapi.c @@ -217,22 +217,21 @@ rsa_pub_dec(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, in * Sign the hash in 'from' using NCryptSignHash(). This requires an NCRYPT * key handle in cd->crypt_prov. On return the signature is in 'to'. Returns * the length of the signature or 0 on error. + * If the hash_algo is not NULL, PKCS #1 DigestInfo header gets added + * to 'from', else it is signed as is. * For now we support only RSA and the padding is assumed to be PKCS1 v1.5 */ static int -priv_enc_CNG(const CAPI_DATA *cd, const unsigned char *from, int flen, - unsigned char *to, int tlen, int padding) +priv_enc_CNG(const CAPI_DATA *cd, const wchar_t *hash_algo, const unsigned char *from, + int flen, unsigned char *to, int tlen, int padding) { NCRYPT_KEY_HANDLE hkey = cd->crypt_prov; - DWORD len; + DWORD len = 0; ASSERT(cd->key_spec == CERT_NCRYPT_KEY_SPEC); msg(D_LOW, "Signing hash using CNG: data size = %d", flen); - /* The hash OID is already in 'from'. So set the hash algorithm - * in the padding info struct to NULL. - */ - BCRYPT_PKCS1_PADDING_INFO padinfo = {NULL}; + BCRYPT_PKCS1_PADDING_INFO padinfo = {hash_algo}; DWORD status; status = NCryptSignHash(hkey, padding? &padinfo : NULL, (BYTE*) from, flen, @@ -270,7 +269,7 @@ rsa_priv_enc(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, i } if (cd->key_spec == CERT_NCRYPT_KEY_SPEC) { - return priv_enc_CNG(cd, from, flen, to, RSA_size(rsa), padding); + return priv_enc_CNG(cd, NULL, from, flen, to, RSA_size(rsa), padding); } /* Unfortunately, there is no "CryptSign()" function in CryptoAPI, that would @@ -334,6 +333,69 @@ rsa_priv_enc(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, i return len; } +/* + * Sign the hash in |m| and return the signature in |sig|. + * Returns 1 on success, 0 on error. + * NCryptSignHash() is used to sign and it is instructed to add the + * the PKCS #1 DigestInfo header to |m| unless the hash algorithm is + * the MD5/SHA1 combination used in TLS 1.1 and earlier versions. + */ +static int +rsa_sign_CNG(int type, const unsigned char *m, unsigned int m_len, + unsigned char *sig, unsigned int *siglen, const RSA *rsa) +{ + CAPI_DATA *cd = (CAPI_DATA *) RSA_meth_get0_app_data(RSA_get_method(rsa)); + const wchar_t *alg = NULL; + int padding = RSA_PKCS1_PADDING; + + *siglen = 0; + if (cd == NULL) + { + RSAerr(RSA_F_RSA_OSSL_PRIVATE_ENCRYPT, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + switch (type) + { + case NID_md5: + alg = BCRYPT_MD5_ALGORITHM; + break; + + case NID_sha1: + alg = BCRYPT_SHA1_ALGORITHM; + break; + + case NID_sha256: + alg = BCRYPT_SHA256_ALGORITHM; + break; + + case NID_sha384: + alg = BCRYPT_SHA384_ALGORITHM; + break; + + case NID_sha512: + alg = BCRYPT_SHA512_ALGORITHM; + break; + + case NID_md5_sha1: + if (m_len != SSL_SIG_LENGTH) + { + RSAerr(RSA_F_RSA_SIGN, RSA_R_INVALID_MESSAGE_LENGTH); + return 0; + } + /* No DigestInfo header is required -- set alg-name to NULL */ + alg = NULL; + break; + default: + msg(M_WARN, "cryptoapicert: Unknown hash type NID=0x%x", type); + RSAerr(RSA_F_RSA_SIGN, RSA_R_UNKNOWN_ALGORITHM_TYPE); + return 0; + } + + *siglen = priv_enc_CNG(cd, alg, m, (int)m_len, sig, RSA_size(rsa), padding); + return (siglen == 0) ? 0 : 1; +} + /* decrypt */ static int rsa_priv_dec(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) @@ -555,6 +617,15 @@ SSL_CTX_use_CryptoAPI_certificate(SSL_CTX *ssl_ctx, const char *cert_prop) RSA_meth_set_finish(my_rsa_method, finish); RSA_meth_set0_app_data(my_rsa_method, cd); + /* For CNG, set the RSA_sign method which gets priority over priv_enc(). + * This method is called with the raw hash without the digestinfo + * header and works better when using NCryptSignHash() with some tokens. + */ + if (cd->key_spec == CERT_NCRYPT_KEY_SPEC) + { + RSA_meth_set_sign(my_rsa_method, rsa_sign_CNG); + } + rsa = RSA_new(); if (rsa == NULL) { diff --git a/src/openvpn/init.c b/src/openvpn/init.c index 6968c77..1cdef31 100644 --- a/src/openvpn/init.c +++ b/src/openvpn/init.c @@ -613,6 +613,31 @@ uninit_proxy(struct context *c) uninit_proxy_dowork(c); } +/* + * Saves the initial state of NCP-regotiable + * options into a storage which persists over SIGUSR1. + */ +static void +save_ncp_options(struct context *c) +{ +#ifdef ENABLE_CRYPTO + c->c1.ciphername = c->options.ciphername; + c->c1.authname = c->options.authname; + c->c1.keysize = c->options.keysize; +#endif +} + +/* Restores NCP-negotiable options to original values */ +static void +restore_ncp_options(struct context *c) +{ +#ifdef ENABLE_CRYPTO + c->options.ciphername = c->c1.ciphername; + c->options.authname = c->c1.authname; + c->options.keysize = c->c1.keysize; +#endif +} + void context_init_1(struct context *c) { @@ -622,6 +647,8 @@ context_init_1(struct context *c) init_connection_list(c); + save_ncp_options(c); + #if defined(ENABLE_PKCS11) if (c->first_time) { @@ -1017,6 +1044,7 @@ print_openssl_info(const struct options *options) if (options->show_tls_ciphers) { show_available_tls_ciphers(options->cipher_list, + options->cipher_list_tls13, options->tls_cert_profile); } if (options->show_curves) @@ -1693,6 +1721,9 @@ do_open_tun(struct context *c) if (c->c1.tuntap) { oldtunfd = c->c1.tuntap->fd; + free(c->c1.tuntap); + c->c1.tuntap = NULL; + c->c1.tuntap_owned = false; } #endif @@ -2607,10 +2638,6 @@ do_init_crypto_tls_c1(struct context *c) options->tls_crypt_inline, options->tls_server); } - c->c1.ciphername = options->ciphername; - c->c1.authname = options->authname; - c->c1.keysize = options->keysize; - #if 0 /* was: #if ENABLE_INLINE_FILES -- Note that enabling this code will break restarts */ if (options->priv_key_file_inline) { @@ -2622,11 +2649,6 @@ do_init_crypto_tls_c1(struct context *c) else { msg(D_INIT_MEDIUM, "Re-using SSL/TLS context"); - - /* Restore pre-NCP cipher options */ - c->options.ciphername = c->c1.ciphername; - c->options.authname = c->c1.authname; - c->options.keysize = c->c1.keysize; } } @@ -4317,6 +4339,8 @@ close_instance(struct context *c) /* free key schedules */ do_close_free_key_schedule(c, (c->mode == CM_P2P || c->mode == CM_TOP)); + restore_ncp_options(c); + /* close TCP/UDP connection */ do_close_link_socket(c); diff --git a/src/openvpn/misc.c b/src/openvpn/misc.c index 77bb671..581a890 100644 --- a/src/openvpn/misc.c +++ b/src/openvpn/misc.c @@ -1261,7 +1261,7 @@ purge_user_pass(struct user_pass *up, const bool force) * don't show warning if the pass has been replaced by a token: this is an * artificial "auth-nocache" */ - else if (!warn_shown && (!up->tokenized)) + else if (!warn_shown) { msg(M_WARN, "WARNING: this configuration may cache passwords in memory -- use the auth-nocache option to prevent this"); warn_shown = true; @@ -1269,14 +1269,18 @@ purge_user_pass(struct user_pass *up, const bool force) } void -set_auth_token(struct user_pass *up, const char *token) +set_auth_token(struct user_pass *up, struct user_pass *tk, const char *token) { - if (token && strlen(token) && up && up->defined && !up->nocache) + + if (token && strlen(token) && up && up->defined) { - CLEAR(up->password); - strncpynt(up->password, token, USER_PASS_LEN); - up->tokenized = true; + strncpynt(tk->password, token, USER_PASS_LEN); + strncpynt(tk->username, up->username, USER_PASS_LEN); + tk->defined = true; } + + /* Cleans user/pass for nocache */ + purge_user_pass(up, false); } /* diff --git a/src/openvpn/misc.h b/src/openvpn/misc.h index 9f358ae..a64ddcc 100644 --- a/src/openvpn/misc.h +++ b/src/openvpn/misc.h @@ -173,7 +173,6 @@ struct user_pass { bool defined; bool nocache; - bool tokenized; /* true if password has been substituted by a token */ bool wait_for_push; /* true if this object is waiting for a push-reply */ /* max length of username/password */ @@ -255,7 +254,8 @@ void fail_user_pass(const char *prefix, void purge_user_pass(struct user_pass *up, const bool force); -void set_auth_token(struct user_pass *up, const char *token); +void set_auth_token(struct user_pass *up, struct user_pass *tk, + const char *token); /* * Process string received by untrusted peer before diff --git a/src/openvpn/mroute.c b/src/openvpn/mroute.c index 28940a8..db8c987 100644 --- a/src/openvpn/mroute.c +++ b/src/openvpn/mroute.c @@ -477,6 +477,13 @@ mroute_addr_print_ex(const struct mroute_addr *ma, { buf_printf(&out, "%s", print_in_addr_t(maddr.v4mappedv6.addr, IA_NET_ORDER, gc)); + /* we only print port numbers for v4mapped v6 as of + * today, because "v6addr:port" is too ambiguous + */ + if (maddr.type & MR_WITH_PORT) + { + buf_printf(&out, ":%d", ntohs(maddr.v6.port)); + } } else { diff --git a/src/openvpn/mtu.h b/src/openvpn/mtu.h index a82154a..cfa8d2f 100644 --- a/src/openvpn/mtu.h +++ b/src/openvpn/mtu.h @@ -271,12 +271,18 @@ frame_add_to_link_mtu(struct frame *frame, const int increment) } static inline void -frame_add_to_extra_frame(struct frame *frame, const int increment) +frame_add_to_extra_frame(struct frame *frame, const unsigned int increment) { frame->extra_frame += increment; } static inline void +frame_remove_from_extra_frame(struct frame *frame, const unsigned int decrement) +{ + frame->extra_frame -= decrement; +} + +static inline void frame_add_to_extra_tun(struct frame *frame, const int increment) { frame->extra_tun += increment; diff --git a/src/openvpn/openssl_compat.h b/src/openvpn/openssl_compat.h index 9f53069..e680702 100644 --- a/src/openvpn/openssl_compat.h +++ b/src/openvpn/openssl_compat.h @@ -584,6 +584,26 @@ RSA_meth_set_init(RSA_METHOD *meth, int (*init) (RSA *rsa)) } #endif +#if !defined (HAVE_RSA_METH_SET_SIGN) +/** + * Set the sign function of an RSA_METHOD object + * + * @param meth The RSA_METHOD object + * @param sign The sign function + * @return 1 on success, 0 on error + */ +static inline +int RSA_meth_set_sign(RSA_METHOD *meth, + int (*sign) (int type, const unsigned char *m, + unsigned int m_length, + unsigned char *sigret, unsigned int *siglen, + const RSA *rsa)) +{ + meth->rsa_sign = sign; + return 1; +} +#endif + #if !defined(HAVE_RSA_METH_SET_FINISH) /** * Set the finish function of an RSA_METHOD object diff --git a/src/openvpn/openvpn.c b/src/openvpn/openvpn.c index b9e914a..3819889 100644 --- a/src/openvpn/openvpn.c +++ b/src/openvpn/openvpn.c @@ -329,6 +329,7 @@ openvpn_main(int argc, char *argv[]) } while (c.sig->signal_received == SIGUSR1); + env_set_destroy(c.es); uninit_options(&c.options); gc_reset(&c.gc); } @@ -337,8 +338,6 @@ openvpn_main(int argc, char *argv[]) context_gc_free(&c); - env_set_destroy(c.es); - #ifdef ENABLE_MANAGEMENT /* close management interface */ close_management(); diff --git a/src/openvpn/options.c b/src/openvpn/options.c index d1adfb6..f951814 100644 --- a/src/openvpn/options.c +++ b/src/openvpn/options.c @@ -1031,67 +1031,6 @@ get_ip_addr(const char *ip_string, int msglevel, bool *error) return ret; } -/* helper: parse a text string containing an IPv6 address + netbits - * in "standard format" (2001:dba::/32) - * "/nn" is optional, default to /64 if missing - * - * return true if parsing succeeded, modify *network and *netbits - */ -bool -get_ipv6_addr( const char *prefix_str, struct in6_addr *network, - unsigned int *netbits, int msglevel) -{ - char *sep, *endp; - int bits; - struct in6_addr t_network; - - sep = strchr( prefix_str, '/' ); - if (sep == NULL) - { - bits = 64; - } - else - { - bits = strtol( sep+1, &endp, 10 ); - if (*endp != '\0' || bits < 0 || bits > 128) - { - msg(msglevel, "IPv6 prefix '%s': invalid '/bits' spec", prefix_str); - return false; - } - } - - /* temporary replace '/' in caller-provided string with '\0', otherwise - * inet_pton() will refuse prefix string - * (alternative would be to strncpy() the prefix to temporary buffer) - */ - - if (sep != NULL) - { - *sep = '\0'; - } - - if (inet_pton( AF_INET6, prefix_str, &t_network ) != 1) - { - msg(msglevel, "IPv6 prefix '%s': invalid IPv6 address", prefix_str); - return false; - } - - if (sep != NULL) - { - *sep = '/'; - } - - if (netbits != NULL) - { - *netbits = bits; - } - if (network != NULL) - { - *network = t_network; - } - return true; /* parsing OK, values set */ -} - /** * Returns newly allocated string containing address part without "/nn". * @@ -1769,6 +1708,7 @@ show_settings(const struct options *o) SHOW_STR(cryptoapi_cert); #endif SHOW_STR(cipher_list); + SHOW_STR(cipher_list_tls13); SHOW_STR(tls_cert_profile); SHOW_STR(tls_verify); SHOW_STR(tls_export_cert); @@ -2783,6 +2723,7 @@ options_postprocess_verify_ce(const struct options *options, const struct connec MUST_BE_UNDEF(pkcs12_file); #endif MUST_BE_UNDEF(cipher_list); + MUST_BE_UNDEF(cipher_list_tls13); MUST_BE_UNDEF(tls_cert_profile); MUST_BE_UNDEF(tls_verify); MUST_BE_UNDEF(tls_export_cert); @@ -3498,7 +3439,7 @@ calc_options_string_link_mtu(const struct options *o, const struct frame *frame) struct key_type fake_kt; init_key_type(&fake_kt, o->ciphername, o->authname, o->keysize, true, false); - frame_add_to_extra_frame(&fake_frame, -(crypto_max_overhead())); + frame_remove_from_extra_frame(&fake_frame, crypto_max_overhead()); crypto_adjust_frame_parameters(&fake_frame, &fake_kt, o->use_iv, o->replay, cipher_kt_mode_ofb_cfb(fake_kt.cipher)); frame_finalize(&fake_frame, o->ce.link_mtu_defined, o->ce.link_mtu, @@ -3787,11 +3728,15 @@ options_warning_safe_scan2(const int msglevel, const char *b1_name, const char *b2_name) { - /* we will stop sending 'proto xxx' in OCC in a future version - * (because it's not useful), and to reduce questions when - * interoperating, we start not-printing a warning about it today + /* We will stop sending 'key-method', 'keydir', 'proto' and 'tls-auth' in + * OCC in a future version (because it's not useful). To reduce questions + * when interoperating, we no longer printing a warning about it. */ - if (strncmp(p1, "proto ", 6) == 0) + if (strprefix(p1, "key-method ") + || strprefix(p1, "keydir ") + || strprefix(p1, "proto ") + || strprefix(p1, "tls-auth ") + || strprefix(p1, "tun-ipv6")) { return; } @@ -7874,6 +7819,11 @@ add_option(struct options *options, VERIFY_PERMISSION(OPT_P_GENERAL); options->tls_cert_profile = p[1]; } + else if (streq(p[0], "tls-ciphersuites") && p[1] && !p[2]) + { + VERIFY_PERMISSION(OPT_P_GENERAL); + options->cipher_list_tls13 = p[1]; + } else if (streq(p[0], "crl-verify") && p[1] && ((p[2] && streq(p[2], "dir")) || (p[2] && streq(p[1], INLINE_FILE_TAG) ) || !p[2]) && !p[3]) { diff --git a/src/openvpn/options.h b/src/openvpn/options.h index 0421c93..f3cafea 100644 --- a/src/openvpn/options.h +++ b/src/openvpn/options.h @@ -503,6 +503,7 @@ struct options const char *priv_key_file; const char *pkcs12_file; const char *cipher_list; + const char *cipher_list_tls13; const char *tls_cert_profile; const char *ecdh_curve; const char *tls_verify; @@ -817,8 +818,4 @@ void options_string_import(struct options *options, unsigned int *option_types_found, struct env_set *es); -bool get_ipv6_addr( const char *prefix_str, struct in6_addr *network, - unsigned int *netbits, int msglevel ); - - #endif /* ifndef OPTIONS_H */ diff --git a/src/openvpn/plugin.c b/src/openvpn/plugin.c index ddd9e85..0ab99ab 100644 --- a/src/openvpn/plugin.c +++ b/src/openvpn/plugin.c @@ -43,6 +43,7 @@ #include "misc.h" #include "plugin.h" #include "ssl_backend.h" +#include "base64.h" #include "win32.h" #include "memdbg.h" @@ -410,7 +411,9 @@ plugin_log(openvpn_plugin_log_flags_t flags, const char *name, const char *forma static struct openvpn_plugin_callbacks callbacks = { plugin_log, plugin_vlog, - secure_memzero /* plugin_secure_memzero */ + secure_memzero, /* plugin_secure_memzero */ + openvpn_base64_encode, /* plugin_base64_encode */ + openvpn_base64_decode, /* plugin_base64_decode */ }; diff --git a/src/openvpn/push.c b/src/openvpn/push.c index 6a30e47..dd5bd41 100644 --- a/src/openvpn/push.c +++ b/src/openvpn/push.c @@ -55,8 +55,20 @@ receive_auth_failed(struct context *c, const struct buffer *buffer) if (c->options.pull) { - switch (auth_retry_get()) + /* Before checking how to react on AUTH_FAILED, first check if the + * failed auth might be the result of an expired auth-token. + * Note that a server restart will trigger a generic AUTH_FAILED + * instead an AUTH_FAILED,SESSION so handle all AUTH_FAILED message + * identical for this scenario */ + if (ssl_clean_auth_token()) { + c->sig->signal_received = SIGUSR1; /* SOFT-SIGUSR1 -- Auth failure error */ + c->sig->signal_text = "auth-failure (auth-token)"; + } + else + { + switch (auth_retry_get()) + { case AR_NONE: c->sig->signal_received = SIGTERM; /* SOFT-SIGTERM -- Auth failure error */ break; @@ -70,8 +82,9 @@ receive_auth_failed(struct context *c, const struct buffer *buffer) default: ASSERT(0); + } + c->sig->signal_text = "auth-failure"; } - c->sig->signal_text = "auth-failure"; #ifdef ENABLE_MANAGEMENT if (management) { diff --git a/src/openvpn/socket.c b/src/openvpn/socket.c index 211e744..c76d206 100644 --- a/src/openvpn/socket.c +++ b/src/openvpn/socket.c @@ -74,12 +74,116 @@ sf2gaf(const unsigned int getaddr_flags, /* * Functions related to the translation of DNS names to IP addresses. */ +static int +get_addr_generic(sa_family_t af, unsigned int flags, const char *hostname, + void *network, unsigned int *netbits, + int resolve_retry_seconds, volatile int *signal_received, + int msglevel) +{ + char *endp, *sep, *var_host = NULL; + struct addrinfo *ai = NULL; + unsigned long bits; + uint8_t max_bits; + int ret = -1; + + if (!hostname) + { + msg(M_NONFATAL, "Can't resolve null hostname!"); + goto out; + } + + /* assign family specific default values */ + switch (af) + { + case AF_INET: + bits = 0; + max_bits = sizeof(in_addr_t) * 8; + break; + case AF_INET6: + bits = 64; + max_bits = sizeof(struct in6_addr) * 8; + break; + default: + msg(M_WARN, + "Unsupported AF family passed to getaddrinfo for %s (%d)", + hostname, af); + goto out; + } + + /* we need to modify the hostname received as input, but we don't want to + * touch it directly as it might be a constant string. + * + * Therefore, we clone the string here and free it at the end of the + * function */ + var_host = strdup(hostname); + if (!var_host) + { + msg(M_NONFATAL | M_ERRNO, + "Can't allocate hostname buffer for getaddrinfo"); + goto out; + } + + /* check if this hostname has a /bits suffix */ + sep = strchr(var_host , '/'); + if (sep) + { + bits = strtoul(sep + 1, &endp, 10); + if ((*endp != '\0') || (bits > max_bits)) + { + msg(msglevel, "IP prefix '%s': invalid '/bits' spec (%s)", hostname, + sep + 1); + goto out; + } + *sep = '\0'; + } + + ret = openvpn_getaddrinfo(flags & ~GETADDR_HOST_ORDER, var_host, NULL, + resolve_retry_seconds, signal_received, af, &ai); + if ((ret == 0) && network) + { + struct in6_addr *ip6; + in_addr_t *ip4; + + switch (af) + { + case AF_INET: + ip4 = network; + *ip4 = ((struct sockaddr_in *)ai->ai_addr)->sin_addr.s_addr; + + if (flags & GETADDR_HOST_ORDER) + { + *ip4 = ntohl(*ip4); + } + break; + case AF_INET6: + ip6 = network; + *ip6 = ((struct sockaddr_in6 *)ai->ai_addr)->sin6_addr; + break; + default: + /* can't get here because 'af' was previously checked */ + msg(M_WARN, + "Unsupported AF family for %s (%d)", var_host, af); + goto out; + } + } + + if (netbits) + { + *netbits = bits; + } + + /* restore '/' separator, if any */ + if (sep) + { + *sep = '/'; + } +out: + freeaddrinfo(ai); + free(var_host); + + return ret; +} -/* - * Translate IP addr or hostname to in_addr_t. - * If resolve error, try again for - * resolve_retry_seconds seconds. - */ in_addr_t getaddr(unsigned int flags, const char *hostname, @@ -87,20 +191,19 @@ getaddr(unsigned int flags, bool *succeeded, volatile int *signal_received) { - struct addrinfo *ai; + in_addr_t addr; int status; - status = openvpn_getaddrinfo(flags & ~GETADDR_HOST_ORDER, hostname, NULL, - resolve_retry_seconds, signal_received, AF_INET, &ai); + + status = get_addr_generic(AF_INET, flags, hostname, &addr, NULL, + resolve_retry_seconds, signal_received, + M_WARN); if (status==0) { - struct in_addr ia; if (succeeded) { *succeeded = true; } - ia = ((struct sockaddr_in *)ai->ai_addr)->sin_addr; - freeaddrinfo(ai); - return (flags & GETADDR_HOST_ORDER) ? ntohl(ia.s_addr) : ia.s_addr; + return addr; } else { @@ -112,6 +215,19 @@ getaddr(unsigned int flags, } } +bool +get_ipv6_addr(const char *hostname, struct in6_addr *network, + unsigned int *netbits, int msglevel) +{ + if (get_addr_generic(AF_INET6, GETADDR_RESOLVE, hostname, network, netbits, + 0, NULL, msglevel) < 0) + { + return false; + } + + return true; /* parsing OK, values set */ +} + static inline bool streqnull(const char *a, const char *b) { diff --git a/src/openvpn/socket.h b/src/openvpn/socket.h index 479d115..80e8128 100644 --- a/src/openvpn/socket.h +++ b/src/openvpn/socket.h @@ -532,12 +532,24 @@ bool unix_socket_get_peer_uid_gid(const socket_descriptor_t sd, int *uid, int *g #define GETADDR_CACHE_MASK (GETADDR_DATAGRAM|GETADDR_PASSIVE) +/** + * Translate an IPv4 addr or hostname from string form to in_addr_t + * + * In case of resolve error, it will try again for + * resolve_retry_seconds seconds. + */ in_addr_t getaddr(unsigned int flags, const char *hostname, int resolve_retry_seconds, bool *succeeded, volatile int *signal_received); +/** + * Translate an IPv6 addr or hostname from string form to in6_addr + */ +bool get_ipv6_addr(const char *hostname, struct in6_addr *network, + unsigned int *netbits, int msglevel); + int openvpn_getaddrinfo(unsigned int flags, const char *hostname, const char *servname, diff --git a/src/openvpn/ssl.c b/src/openvpn/ssl.c index ab42f0c..9696e9b 100644 --- a/src/openvpn/ssl.c +++ b/src/openvpn/ssl.c @@ -400,6 +400,7 @@ pem_password_callback(char *buf, int size, int rwflag, void *u) static bool auth_user_pass_enabled; /* GLOBAL */ static struct user_pass auth_user_pass; /* GLOBAL */ +static struct user_pass auth_token; /* GLOBAL */ #ifdef ENABLE_CLIENT_CR static char *auth_challenge; /* GLOBAL */ @@ -409,7 +410,7 @@ void auth_user_pass_setup(const char *auth_file, const struct static_challenge_info *sci) { auth_user_pass_enabled = true; - if (!auth_user_pass.defined) + if (!auth_user_pass.defined && !auth_token.defined) { #if AUTO_USERID get_user_pass_auto_userid(&auth_user_pass, auth_file); @@ -451,7 +452,7 @@ ssl_set_auth_nocache(void) { passbuf.nocache = true; auth_user_pass.nocache = true; - /* wait for push-reply, because auth-token may invert nocache */ + /* wait for push-reply, because auth-token may still need the username */ auth_user_pass.wait_for_push = true; } @@ -461,15 +462,18 @@ ssl_set_auth_nocache(void) void ssl_set_auth_token(const char *token) { - if (auth_user_pass.nocache) - { - msg(M_INFO, - "auth-token received, disabling auth-nocache for the " - "authentication token"); - auth_user_pass.nocache = false; - } + set_auth_token(&auth_user_pass, &auth_token, token); +} - set_auth_token(&auth_user_pass, token); +/* + * Cleans an auth token and checks if it was active + */ +bool +ssl_clean_auth_token (void) +{ + bool wasdefined = auth_token.defined; + purge_user_pass(&auth_token, true); + return wasdefined; } /* @@ -624,9 +628,10 @@ init_ssl(const struct options *options, struct tls_root_ctx *new_ctx) tls_ctx_set_cert_profile(new_ctx, options->tls_cert_profile); /* Allowable ciphers */ - /* Since @SECLEVEL also influces loading of certificates, set the + /* Since @SECLEVEL also influences loading of certificates, set the * cipher restrictions before loading certificates */ tls_ctx_restrict_ciphers(new_ctx, options->cipher_list); + tls_ctx_restrict_ciphers_tls13(new_ctx, options->cipher_list_tls13); if (!tls_ctx_set_options(new_ctx, options->ssl_flags)) { @@ -1993,7 +1998,7 @@ tls_session_update_crypto_params(struct tls_session *session, } /* Update frame parameters: undo worst-case overhead, add actual overhead */ - frame_add_to_extra_frame(frame, -(crypto_max_overhead())); + frame_remove_from_extra_frame(frame, crypto_max_overhead()); crypto_adjust_frame_parameters(frame, &session->opt->key_type, options->use_iv, options->replay, packet_id_long_form); frame_finalize(frame, options->ce.link_mtu_defined, options->ce.link_mtu, @@ -2381,19 +2386,26 @@ key_method_2_write(struct buffer *buf, struct tls_session *session) #else auth_user_pass_setup(session->opt->auth_user_pass_file, NULL); #endif - if (!write_string(buf, auth_user_pass.username, -1)) + struct user_pass *up = &auth_user_pass; + + /* + * If we have a valid auth-token, send that instead of real + * username/password + */ + if (auth_token.defined) + up = &auth_token; + + if (!write_string(buf, up->username, -1)) { goto error; } - if (!write_string(buf, auth_user_pass.password, -1)) + else if (!write_string(buf, up->password, -1)) { goto error; } /* if auth-nocache was specified, the auth_user_pass object reaches * a "complete" state only after having received the push-reply * message. - * This is the case because auth-token statement in a push-reply would - * invert its nocache. * * For this reason, skip the purge operation here if no push-reply * message has been received yet. @@ -3664,8 +3676,8 @@ tls_pre_decrypt(struct tls_multi *multi, } /* - * We have an authenticated packet (if --tls-auth was set). - * Now pass to our reliability level which deals with + * We have an authenticated control channel packet (if --tls-auth was set). + * Now pass to our reliability layer which deals with * packet acknowledgements, retransmits, sequencing, etc. */ { @@ -4127,6 +4139,30 @@ tls_check_ncp_cipher_list(const char *list) return 0 < strlen(list) && !unsupported_cipher_found; } +void +show_available_tls_ciphers(const char *cipher_list, + const char *cipher_list_tls13, + const char *tls_cert_profile) +{ + printf("Available TLS Ciphers, listed in order of preference:\n"); + +#if (ENABLE_CRYPTO_OPENSSL && OPENSSL_VERSION_NUMBER >= 0x1010100fL) + printf("\nFor TLS 1.3 and newer (--tls-ciphersuites):\n\n"); + show_available_tls_ciphers_list(cipher_list_tls13, tls_cert_profile, true); +#else + (void) cipher_list_tls13; /* Avoid unused warning */ +#endif + + printf("\nFor TLS 1.2 and older (--tls-cipher):\n\n"); + show_available_tls_ciphers_list(cipher_list, tls_cert_profile, false); + + printf("\n" + "Be aware that that whether a cipher suite in this list can actually work\n" + "depends on the specific setup of both peers. See the man page entries of\n" + "--tls-cipher and --show-tls for more details.\n\n" + ); +} + /* * Dump a human-readable rendition of an openvpn packet * into a garbage collectable string which is returned. diff --git a/src/openvpn/ssl.h b/src/openvpn/ssl.h index 132424e..8066789 100644 --- a/src/openvpn/ssl.h +++ b/src/openvpn/ssl.h @@ -78,7 +78,7 @@ /* * Define number of buffers for send and receive in the reliability layer. */ -#define TLS_RELIABLE_N_SEND_BUFFERS 4 /* also window size for reliablity layer */ +#define TLS_RELIABLE_N_SEND_BUFFERS 4 /* also window size for reliability layer */ #define TLS_RELIABLE_N_REC_BUFFERS 8 /* @@ -438,6 +438,8 @@ void ssl_set_auth_token(const char *token); */ void ssl_purge_auth_challenge(void); +bool ssl_clean_auth_token(void); + void ssl_put_auth_challenge(const char *cr_str); #endif @@ -600,6 +602,19 @@ bool is_hard_reset(int op, int key_method); void delayed_auth_pass_purge(void); + +/* + * Show the TLS ciphers that are available for us to use in the SSL + * library with headers hinting their usage and warnings about usage. + * + * @param cipher_list list of allowed TLS cipher, or NULL. + * @param cipher_list_tls13 list of allowed TLS 1.3+ cipher, or NULL + * @param tls_cert_profile TLS certificate crypto profile name. + */ +void +show_available_tls_ciphers(const char *cipher_list, + const char *cipher_list_tls13, + const char *tls_cert_profile); #endif /* ENABLE_CRYPTO */ #endif /* ifndef OPENVPN_SSL_H */ diff --git a/src/openvpn/ssl_backend.h b/src/openvpn/ssl_backend.h index e704de8..c614efa 100644 --- a/src/openvpn/ssl_backend.h +++ b/src/openvpn/ssl_backend.h @@ -171,7 +171,8 @@ bool tls_ctx_initialised(struct tls_root_ctx *ctx); bool tls_ctx_set_options(struct tls_root_ctx *ctx, unsigned int ssl_flags); /** - * Restrict the list of ciphers that can be used within the TLS context. + * Restrict the list of ciphers that can be used within the TLS context for TLS 1.2 + * and below * * @param ctx TLS context to restrict, must be valid. * @param ciphers String containing : delimited cipher names, or NULL to use @@ -180,6 +181,16 @@ bool tls_ctx_set_options(struct tls_root_ctx *ctx, unsigned int ssl_flags); void tls_ctx_restrict_ciphers(struct tls_root_ctx *ctx, const char *ciphers); /** + * Restrict the list of ciphers that can be used within the TLS context for TLS 1.3 + * and higher + * + * @param ctx TLS context to restrict, must be valid. + * @param ciphers String containing : delimited cipher names, or NULL to use + * sane defaults. + */ +void tls_ctx_restrict_ciphers_tls13(struct tls_root_ctx *ctx, const char *ciphers); + +/** * Set the TLS certificate profile. The profile defines which crypto * algorithms may be used in the supplied certificate. * @@ -515,15 +526,19 @@ int key_state_read_plaintext(struct key_state_ssl *ks_ssl, struct buffer *buf, void print_details(struct key_state_ssl *ks_ssl, const char *prefix); /* - * Show the TLS ciphers that are available for us to use in the OpenSSL - * library. + * Show the TLS ciphers that are available for us to use in the + * library depending on the TLS version. This function prints + * a list of ciphers without headers/footers. * * @param cipher_list list of allowed TLS cipher, or NULL. * @param tls_cert_profile TLS certificate crypto profile name. + * @param tls13 Select if <=TLS1.2 or TLS1.3+ ciphers + * should be shown */ void -show_available_tls_ciphers(const char *cipher_list, - const char *tls_cert_profile); +show_available_tls_ciphers_list(const char *cipher_list, + const char *tls_cert_profile, + bool tls13); /* * Show the available elliptic curves in the crypto library diff --git a/src/openvpn/ssl_common.h b/src/openvpn/ssl_common.h index c7565d8..ac25ffa 100644 --- a/src/openvpn/ssl_common.h +++ b/src/openvpn/ssl_common.h @@ -556,10 +556,4 @@ struct tls_multi * sessions with the remote peer. */ }; - -#define SHOW_TLS_CIPHER_LIST_WARNING \ - "Be aware that that whether a cipher suite in this list can actually work\n" \ - "depends on the specific setup of both peers. See the man page entries of\n" \ - "--tls-cipher and --show-tls for more details.\n\n" - #endif /* SSL_COMMON_H_ */ diff --git a/src/openvpn/ssl_mbedtls.c b/src/openvpn/ssl_mbedtls.c index 3f579e1..89b1b67 100644 --- a/src/openvpn/ssl_mbedtls.c +++ b/src/openvpn/ssl_mbedtls.c @@ -232,6 +232,19 @@ tls_translate_cipher_name(const char *cipher_name) } void +tls_ctx_restrict_ciphers_tls13(struct tls_root_ctx *ctx, const char *ciphers) +{ + if (ciphers == NULL) + { + /* Nothing to do, return without warning message */ + return; + } + + msg(M_WARN, "mbed TLS does not support setting tls-ciphersuites. " + "Ignoring TLS 1.3 cipher list: %s", ciphers); +} + +void tls_ctx_restrict_ciphers(struct tls_root_ctx *ctx, const char *ciphers) { char *tmp_ciphers, *tmp_ciphers_orig, *token; @@ -853,7 +866,7 @@ tls_ctx_personalise_random(struct tls_root_ctx *ctx) const md_kt_t *sha256_kt = md_kt_get("SHA256"); mbedtls_x509_crt *cert = ctx->crt_chain; - if (0 != md_full(sha256_kt, cert->tbs.p, cert->tbs.len, sha256_hash)) + if (!md_full(sha256_kt, cert->tbs.p, cert->tbs.len, sha256_hash)) { msg(M_WARN, "WARNING: failed to personalise random"); } @@ -1327,9 +1340,15 @@ print_details(struct key_state_ssl *ks_ssl, const char *prefix) } void -show_available_tls_ciphers(const char *cipher_list, - const char *tls_cert_profile) +show_available_tls_ciphers_list(const char *cipher_list, + const char *tls_cert_profile, + bool tls13) { + if (tls13) + { + /* mbed TLS has no TLS 1.3 support currently */ + return; + } struct tls_root_ctx tls_ctx; const int *ciphers = mbedtls_ssl_list_ciphersuites(); @@ -1342,18 +1361,11 @@ show_available_tls_ciphers(const char *cipher_list, ciphers = tls_ctx.allowed_ciphers; } -#ifndef ENABLE_SMALL - printf("Available TLS Ciphers,\n"); - printf("listed in order of preference:\n\n"); -#endif - while (*ciphers != 0) { printf("%s\n", mbedtls_ssl_get_ciphersuite_name(*ciphers)); ciphers++; } - printf("\n" SHOW_TLS_CIPHER_LIST_WARNING); - tls_ctx_free(&tls_ctx); } diff --git a/src/openvpn/ssl_openssl.c b/src/openvpn/ssl_openssl.c index e57b6d2..a78dae9 100644 --- a/src/openvpn/ssl_openssl.c +++ b/src/openvpn/ssl_openssl.c @@ -423,6 +423,62 @@ tls_ctx_restrict_ciphers(struct tls_root_ctx *ctx, const char *ciphers) } void +convert_tls13_list_to_openssl(char *openssl_ciphers, size_t len, + const char *ciphers) +{ + /* + * OpenSSL (and official IANA) cipher names have _ in them. We + * historically used names with - in them. Silently convert names + * with - to names with _ to support both + */ + if (strlen(ciphers) >= (len - 1)) + { + msg(M_FATAL, + "Failed to set restricted TLS 1.3 cipher list, too long (>%d).", + (int) (len - 1)); + } + + strncpy(openssl_ciphers, ciphers, len); + + for (size_t i = 0; i < strlen(openssl_ciphers); i++) + { + if (openssl_ciphers[i] == '-') + { + openssl_ciphers[i] = '_'; + } + } +} + +void +tls_ctx_restrict_ciphers_tls13(struct tls_root_ctx *ctx, const char *ciphers) +{ + if (ciphers == NULL) + { + /* default cipher list of OpenSSL 1.1.1 is sane, do not set own + * default as we do with tls-cipher */ + return; + } + +#if (OPENSSL_VERSION_NUMBER < 0x1010100fL) + crypto_msg(M_WARN, "Not compiled with OpenSSL 1.1.1 or higher. " + "Ignoring TLS 1.3 only tls-ciphersuites '%s' setting.", + ciphers); +#else + ASSERT(NULL != ctx); + + char openssl_ciphers[4096]; + convert_tls13_list_to_openssl(openssl_ciphers, sizeof(openssl_ciphers), + ciphers); + + if (!SSL_CTX_set_ciphersuites(ctx->ctx, openssl_ciphers)) + { + crypto_msg(M_FATAL, "Failed to set restricted TLS 1.3 cipher list: %s", + openssl_ciphers); + } +#endif +} + +void tls_ctx_set_cert_profile(struct tls_root_ctx *ctx, const char *profile) { #ifdef HAVE_SSL_CTX_SET_SECURITY_LEVEL @@ -627,7 +683,7 @@ tls_ctx_load_ecdh_params(struct tls_root_ctx *ctx, const char *curve_name EC_KEY_free(ecdh); #else /* ifndef OPENSSL_NO_EC */ - msg(M_DEBUG, "Your OpenSSL library was built without elliptic curve support." + msg(D_LOW, "Your OpenSSL library was built without elliptic curve support." " Skipping ECDH parameter loading."); #endif /* OPENSSL_NO_EC */ } @@ -1778,14 +1834,11 @@ print_details(struct key_state_ssl *ks_ssl, const char *prefix) } void -show_available_tls_ciphers(const char *cipher_list, - const char *tls_cert_profile) +show_available_tls_ciphers_list(const char *cipher_list, + const char *tls_cert_profile, + const bool tls13) { struct tls_root_ctx tls_ctx; - SSL *ssl; - const char *cipher_name; - const tls_cipher_name_pair *pair; - int priority = 0; tls_ctx.ctx = SSL_CTX_new(SSLv23_method()); if (!tls_ctx.ctx) @@ -1793,34 +1846,59 @@ show_available_tls_ciphers(const char *cipher_list, crypto_msg(M_FATAL, "Cannot create SSL_CTX object"); } - ssl = SSL_new(tls_ctx.ctx); - if (!ssl) +#if (OPENSSL_VERSION_NUMBER >= 0x1010100fL) + if (tls13) { - crypto_msg(M_FATAL, "Cannot create SSL object"); + SSL_CTX_set_min_proto_version(tls_ctx.ctx, TLS1_3_VERSION); + tls_ctx_restrict_ciphers_tls13(&tls_ctx, cipher_list); + } + else +#endif + { + SSL_CTX_set_max_proto_version(tls_ctx.ctx, TLS1_2_VERSION); + tls_ctx_restrict_ciphers(&tls_ctx, cipher_list); } tls_ctx_set_cert_profile(&tls_ctx, tls_cert_profile); - tls_ctx_restrict_ciphers(&tls_ctx, cipher_list); - printf("Available TLS Ciphers,\n"); - printf("listed in order of preference:\n\n"); - while ((cipher_name = SSL_get_cipher_list(ssl, priority++))) + SSL *ssl = SSL_new(tls_ctx.ctx); + if (!ssl) { - pair = tls_get_cipher_name_pair(cipher_name, strlen(cipher_name)); + crypto_msg(M_FATAL, "Cannot create SSL object"); + } + +#if (OPENSSL_VERSION_NUMBER < 0x1010000fL) + STACK_OF(SSL_CIPHER) *sk = SSL_get_ciphers(ssl); +#else + STACK_OF(SSL_CIPHER) *sk = SSL_get1_supported_ciphers(ssl); +#endif + for (int i=0;i < sk_SSL_CIPHER_num(sk);i++) + { + const SSL_CIPHER *c = sk_SSL_CIPHER_value(sk, i); + + const char *cipher_name = SSL_CIPHER_get_name(c); - if (NULL == pair) + const tls_cipher_name_pair *pair = + tls_get_cipher_name_pair(cipher_name, strlen(cipher_name)); + + if (tls13) + { + printf("%s\n", cipher_name); + } + else if (NULL == pair) { /* No translation found, print warning */ - printf("%s (No IANA name known to OpenVPN, use OpenSSL name.)\n", cipher_name); + printf("%s (No IANA name known to OpenVPN, use OpenSSL name.)\n", + cipher_name); } else { printf("%s\n", pair->iana_name); } - } - printf("\n" SHOW_TLS_CIPHER_LIST_WARNING); - +#if (OPENSSL_VERSION_NUMBER >= 0x1010000fL) + sk_SSL_CIPHER_free(sk); +#endif SSL_free(ssl); SSL_CTX_free(tls_ctx.ctx); } diff --git a/src/openvpn/tun.c b/src/openvpn/tun.c index 0e44e9b..63f9d1b 100644 --- a/src/openvpn/tun.c +++ b/src/openvpn/tun.c @@ -845,7 +845,7 @@ delete_route_connected_v6_net(struct tuntap *tt, #endif /* if defined(_WIN32) || defined(TARGET_DARWIN) || defined(TARGET_NETBSD) || defined(TARGET_OPENBSD) */ #if defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY) \ - || defined(TARGET_OPENBSD) + || defined(TARGET_NETBSD) || defined(TARGET_OPENBSD) /* we can't use true subnet mode on tun on all platforms, as that * conflicts with IPv6 (wants to use ND then, which we don't do), * but the OSes want "a remote address that is different from ours" @@ -890,7 +890,7 @@ do_ifconfig(struct tuntap *tt, bool do_ipv6 = false; struct argv argv = argv_new(); - msg( M_DEBUG, "do_ifconfig, tt->did_ifconfig_ipv6_setup=%d", + msg( D_LOW, "do_ifconfig, tt->did_ifconfig_ipv6_setup=%d", tt->did_ifconfig_ipv6_setup ); /* @@ -1091,7 +1091,7 @@ do_ifconfig(struct tuntap *tt, actual ); } - 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", @@ -1173,7 +1173,7 @@ do_ifconfig(struct tuntap *tt, } } - 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; @@ -1210,7 +1210,7 @@ do_ifconfig(struct tuntap *tt, 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, @@ -1239,7 +1239,7 @@ do_ifconfig(struct tuntap *tt, 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); @@ -1269,6 +1269,8 @@ do_ifconfig(struct tuntap *tt, #elif defined(TARGET_NETBSD) + in_addr_t remote_end; /* for "virtual" subnet topology */ + if (tun) { argv_printf(&argv, @@ -1280,14 +1282,15 @@ do_ifconfig(struct tuntap *tt, 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, actual, ifconfig_local, - ifconfig_local, + print_in_addr_t(remote_end, 0, &gc), tun_mtu, ifconfig_remote_netmask ); @@ -1312,6 +1315,18 @@ do_ifconfig(struct tuntap *tt, argv_msg(M_INFO, &argv); openvpn_execve_check(&argv, es, S_FATAL, "NetBSD ifconfig failed"); + /* Add a network route for the local tun interface */ + if (!tun && tt->type == DEV_TYPE_TUN && tt->topology == TOP_SUBNET) + { + struct route_ipv4 r; + CLEAR(r); + r.flags = RT_DEFINED; + r.network = tt->local & tt->remote_netmask; + r.netmask = tt->remote_netmask; + r.gateway = remote_end; + add_route(&r, tt, 0, NULL, es); + } + if (do_ipv6) { argv_printf(&argv, @@ -1357,7 +1372,7 @@ do_ifconfig(struct tuntap *tt, } 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", @@ -1387,7 +1402,7 @@ do_ifconfig(struct tuntap *tt, tt->did_ifconfig = true; /* 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); @@ -1430,7 +1445,7 @@ do_ifconfig(struct tuntap *tt, 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, @@ -1460,7 +1475,7 @@ do_ifconfig(struct tuntap *tt, tt->did_ifconfig = true; /* 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); @@ -3685,7 +3700,8 @@ get_tap_reg(struct gc_arena *gc) if (status == ERROR_SUCCESS && data_type == REG_SZ) { - if (!strcmp(component_id, TAP_WIN_COMPONENT_ID)) + if (!strcmp(component_id, TAP_WIN_COMPONENT_ID) || + !strcmp(component_id, "root\\" TAP_WIN_COMPONENT_ID)) { struct tap_reg *reg; ALLOC_OBJ_CLEAR_GC(reg, struct tap_reg, gc); @@ -5356,6 +5372,49 @@ netsh_enable_dhcp(const struct tuntap_options *to, argv_reset(&argv); } +/* Enable dhcp on tap adapter using iservice */ +static bool +service_enable_dhcp(const struct tuntap *tt) +{ + DWORD len; + bool ret = false; + ack_message_t ack; + struct gc_arena gc = gc_new(); + HANDLE pipe = tt->options.msg_channel; + + enable_dhcp_message_t dhcp = { + .header = { + msg_enable_dhcp, + sizeof(enable_dhcp_message_t), + 0 + }, + .iface = { .index = tt->adapter_index, .name = "" } + }; + + if (!WriteFile(pipe, &dhcp, sizeof(dhcp), &len, NULL) + || !ReadFile(pipe, &ack, sizeof(ack), &len, NULL)) + { + msg(M_WARN, "Enable_dhcp: could not talk to service: %s [%lu]", + strerror_win32(GetLastError(), &gc), GetLastError()); + goto out; + } + + if (ack.error_number != NO_ERROR) + { + msg(M_NONFATAL, "TUN: enabling dhcp using service failed: %s [status=%u if_index=%d]", + strerror_win32(ack.error_number, &gc), ack.error_number, dhcp.iface.index); + } + else + { + msg(M_INFO, "DHCP enabled on interface %d using service", dhcp.iface.index); + ret = true; + } + +out: + gc_free(&gc); + return ret; +} + /* * Return a TAP name for netsh commands. */ @@ -5836,7 +5895,15 @@ open_tun(const char *dev, const char *dev_type, const char *dev_node, struct tun */ if (dhcp_status(tt->adapter_index) == DHCP_STATUS_DISABLED) { - netsh_enable_dhcp(&tt->options, tt->actual_name); + /* try using the service if available, else directly execute netsh */ + if (tt->options.msg_channel) + { + service_enable_dhcp(tt); + } + else + { + netsh_enable_dhcp(&tt->options, tt->actual_name); + } } dhcp_masq = true; dhcp_masq_post = true; |