summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlberto Gonzalez Iniesta <agi@inittab.org>2016-11-21 09:37:33 +0100
committerAlberto Gonzalez Iniesta <agi@inittab.org>2016-11-21 09:37:33 +0100
commit93b77cacdbb7e6f310c4e20f85c3a24ed5ba18ba (patch)
tree55a7688c9969ef4d01625caa58c7f679098c76eb
parentdaa9ef0efeb5e10a1b43820fbab3a4ff5fbd22f1 (diff)
parent20c8675ba46bda97330a4117c459a59a9f1c465e (diff)
Merge tag 'upstream/2.4_beta1'
Upstream version 2.4~beta1
-rw-r--r--.gitignore9
-rw-r--r--ChangeLog1186
-rw-r--r--INSTALL55
-rw-r--r--INSTALL-win32.txt77
-rw-r--r--Makefile.am17
-rw-r--r--Makefile.in117
-rw-r--r--README12
-rw-r--r--README.IPv627
-rw-r--r--README.polarssl2
-rw-r--r--TODO.IPv610
-rw-r--r--aclocal.m4171
-rw-r--r--build/Makefile.in49
-rw-r--r--build/msvc/Makefile.in49
-rw-r--r--build/msvc/msvc-generate/Makefile.in51
-rw-r--r--[-rwxr-xr-x]build/msvc/msvc-generate/Makefile.mak27
-rwxr-xr-xcompile347
-rw-r--r--config-msvc.h11
-rw-r--r--config-version.h.in1
-rwxr-xr-xconfig.guess192
-rw-r--r--config.h.in98
-rwxr-xr-xconfig.sub40
-rwxr-xr-xconfigure3468
-rw-r--r--configure.ac462
-rw-r--r--contrib/keychain-mcd/Makefile13
-rw-r--r--contrib/keychain-mcd/cert_data.c734
-rw-r--r--contrib/keychain-mcd/cert_data.h46
-rw-r--r--contrib/keychain-mcd/common_osx.c94
-rw-r--r--contrib/keychain-mcd/common_osx.h36
-rw-r--r--contrib/keychain-mcd/crypto_osx.c75
-rw-r--r--contrib/keychain-mcd/crypto_osx.h44
-rw-r--r--contrib/keychain-mcd/keychain-mcd.8161
-rw-r--r--contrib/keychain-mcd/main.c255
-rw-r--r--contrib/pull-resolv-conf/client.up13
-rw-r--r--distro/Makefile.in49
-rw-r--r--distro/rpm/Makefile.in51
-rw-r--r--distro/rpm/openvpn.spec2
-rw-r--r--distro/systemd/openvpn-client@.service12
-rw-r--r--distro/systemd/openvpn-server@.service15
-rw-r--r--doc/Makefile.in51
-rw-r--r--doc/management-notes.txt46
-rw-r--r--doc/openvpn.8922
-rw-r--r--include/Makefile.am7
-rw-r--r--include/Makefile.in103
-rw-r--r--include/openvpn-msg.h116
-rw-r--r--include/openvpn-plugin.h39
-rw-r--r--include/openvpn-plugin.h.in827
-rw-r--r--ltmain.sh5420
-rw-r--r--m4/ax_socklen_t.m42
-rw-r--r--m4/libtool.m42562
-rw-r--r--m4/ltoptions.m4127
-rw-r--r--m4/ltversion.m412
-rwxr-xr-xmissing4
-rw-r--r--msvc-env.bat2
-rw-r--r--sample/Makefile.in49
-rw-r--r--sample/sample-config-files/client.conf9
-rw-r--r--sample/sample-config-files/loopback-client1
-rw-r--r--sample/sample-config-files/loopback-server1
-rw-r--r--sample/sample-config-files/server.conf25
-rw-r--r--sample/sample-config-files/static-home.conf3
-rw-r--r--sample/sample-config-files/static-office.conf3
-rwxr-xr-xsample/sample-keys/gen-sample-keys.sh12
-rw-r--r--sample/sample-keys/sample-ca/01.pem113
-rw-r--r--sample/sample-keys/sample-ca/02.pem103
-rw-r--r--sample/sample-keys/sample-ca/03.pem103
-rw-r--r--sample/sample-keys/sample-ca/ca.crl21
-rw-r--r--sample/sample-keys/sample-ca/ca.crt35
-rw-r--r--sample/sample-keys/sample-ca/ca.key52
-rw-r--r--sample/sample-keys/sample-ca/client-pass.key30
-rw-r--r--sample/sample-keys/sample-ca/client-revoked.crt103
-rw-r--r--sample/sample-keys/sample-ca/client-revoked.csr17
-rw-r--r--sample/sample-keys/sample-ca/client-revoked.key28
-rw-r--r--sample/sample-keys/sample-ca/client.crt103
-rw-r--r--sample/sample-keys/sample-ca/client.csr17
-rw-r--r--sample/sample-keys/sample-ca/client.key28
-rw-r--r--sample/sample-keys/sample-ca/client.p12bin0 -> 4533 bytes
-rw-r--r--sample/sample-keys/sample-ca/index.txt3
-rw-r--r--sample/sample-keys/sample-ca/index.txt.attr1
-rw-r--r--sample/sample-keys/sample-ca/index.txt.attr.old1
-rw-r--r--sample/sample-keys/sample-ca/index.txt.old3
-rw-r--r--sample/sample-keys/sample-ca/secp256k1.pem0
-rw-r--r--sample/sample-keys/sample-ca/serial1
-rw-r--r--sample/sample-keys/sample-ca/serial.old1
-rw-r--r--sample/sample-keys/sample-ca/server.crt113
-rw-r--r--sample/sample-keys/sample-ca/server.csr17
-rw-r--r--sample/sample-keys/sample-ca/server.key28
-rw-r--r--sample/sample-keys/ta.key21
-rw-r--r--sample/sample-plugins/keying-material-exporter-demo/README68
-rwxr-xr-xsample/sample-plugins/keying-material-exporter-demo/build15
-rw-r--r--sample/sample-plugins/keying-material-exporter-demo/client.ovpn18
-rwxr-xr-xsample/sample-plugins/keying-material-exporter-demo/http-client.py20
-rwxr-xr-xsample/sample-plugins/keying-material-exporter-demo/http-server.py41
-rw-r--r--sample/sample-plugins/keying-material-exporter-demo/keyingmaterialexporter.c269
-rw-r--r--sample/sample-plugins/keying-material-exporter-demo/server.ovpn18
-rw-r--r--sample/sample-plugins/log/log_v3.c8
-rw-r--r--src/Makefile.in49
-rw-r--r--src/compat/Makefile.am1
-rw-r--r--src/compat/Makefile.in60
-rw-r--r--src/compat/compat-gettimeofday.c4
-rw-r--r--src/compat/compat-inet_ntop.c2
-rw-r--r--src/compat/compat-inet_pton.c2
-rw-r--r--src/compat/compat-lz4.c1524
-rw-r--r--src/compat/compat-lz4.h360
-rw-r--r--src/compat/compat.vcxproj3
-rw-r--r--src/compat/compat.vcxproj.filters3
-rw-r--r--src/openvpn/Makefile.am24
-rw-r--r--src/openvpn/Makefile.in214
-rw-r--r--src/openvpn/argv.c315
-rw-r--r--src/openvpn/argv.h70
-rw-r--r--src/openvpn/base64.c6
-rw-r--r--src/openvpn/base64.h4
-rw-r--r--src/openvpn/block_dns.c332
-rw-r--r--src/openvpn/block_dns.h40
-rw-r--r--src/openvpn/buffer.c69
-rw-r--r--src/openvpn/buffer.h38
-rw-r--r--src/openvpn/clinat.c4
-rw-r--r--src/openvpn/clinat.h2
-rw-r--r--src/openvpn/common.h2
-rw-r--r--src/openvpn/comp-lz4.c307
-rw-r--r--src/openvpn/comp-lz4.h42
-rw-r--r--src/openvpn/comp.c167
-rw-r--r--src/openvpn/comp.h198
-rw-r--r--src/openvpn/compstub.c169
-rw-r--r--src/openvpn/console.c228
-rw-r--r--src/openvpn/console.h89
-rw-r--r--src/openvpn/console_builtin.c261
-rw-r--r--src/openvpn/console_systemd.c122
-rw-r--r--src/openvpn/crypto.c821
-rw-r--r--src/openvpn/crypto.h162
-rw-r--r--src/openvpn/crypto_backend.h112
-rw-r--r--src/openvpn/crypto_mbedtls.c785
-rw-r--r--src/openvpn/crypto_mbedtls.h (renamed from src/openvpn/crypto_polarssl.h)77
-rw-r--r--src/openvpn/crypto_openssl.c282
-rw-r--r--src/openvpn/crypto_openssl.h7
-rw-r--r--src/openvpn/crypto_polarssl.c712
-rw-r--r--src/openvpn/cryptoapi.c2
-rw-r--r--src/openvpn/errlevel.h4
-rw-r--r--src/openvpn/error.c44
-rw-r--r--src/openvpn/error.h33
-rw-r--r--src/openvpn/event.c8
-rw-r--r--src/openvpn/event.h4
-rw-r--r--src/openvpn/fdmisc.c4
-rw-r--r--src/openvpn/fdmisc.h2
-rw-r--r--src/openvpn/forward-inline.h6
-rw-r--r--src/openvpn/forward.c304
-rw-r--r--src/openvpn/forward.h32
-rw-r--r--src/openvpn/helper.c2
-rw-r--r--src/openvpn/init.c1125
-rw-r--r--src/openvpn/init.h4
-rw-r--r--src/openvpn/interval.h9
-rw-r--r--src/openvpn/lzo.c151
-rw-r--r--src/openvpn/lzo.h222
-rw-r--r--src/openvpn/manage.c449
-rw-r--r--src/openvpn/manage.h39
-rw-r--r--src/openvpn/misc.c728
-rw-r--r--src/openvpn/misc.h73
-rw-r--r--src/openvpn/mroute.c143
-rw-r--r--src/openvpn/mroute.h57
-rw-r--r--src/openvpn/mtcp.c34
-rw-r--r--src/openvpn/mtu.c44
-rw-r--r--src/openvpn/mtu.h8
-rw-r--r--src/openvpn/mudp.c104
-rw-r--r--src/openvpn/mudp.h2
-rw-r--r--src/openvpn/multi.c410
-rw-r--r--src/openvpn/multi.h65
-rw-r--r--src/openvpn/occ.c2
-rw-r--r--src/openvpn/openvpn.c8
-rw-r--r--src/openvpn/openvpn.h71
-rw-r--r--src/openvpn/openvpn.vcxproj12
-rw-r--r--src/openvpn/openvpn.vcxproj.filters18
-rw-r--r--src/openvpn/options.c2026
-rw-r--r--src/openvpn/options.h130
-rw-r--r--src/openvpn/otime.h8
-rw-r--r--src/openvpn/packet_id.c7
-rw-r--r--src/openvpn/packet_id.h8
-rw-r--r--src/openvpn/pf.c2
-rw-r--r--src/openvpn/pkcs11.c7
-rw-r--r--src/openvpn/pkcs11_mbedtls.c (renamed from src/openvpn/pkcs11_polarssl.c)53
-rw-r--r--src/openvpn/platform.c20
-rw-r--r--src/openvpn/platform.h2
-rw-r--r--src/openvpn/plugin.c37
-rw-r--r--src/openvpn/plugin.h12
-rw-r--r--src/openvpn/proto.h39
-rw-r--r--src/openvpn/proxy.c131
-rw-r--r--src/openvpn/proxy.h21
-rw-r--r--src/openvpn/ps.c59
-rw-r--r--src/openvpn/ps.h2
-rw-r--r--src/openvpn/push.c444
-rw-r--r--src/openvpn/push.h8
-rw-r--r--src/openvpn/reliable.c4
-rw-r--r--src/openvpn/reliable.h4
-rw-r--r--src/openvpn/route.c1517
-rw-r--r--src/openvpn/route.h115
-rw-r--r--src/openvpn/session_id.c4
-rw-r--r--src/openvpn/session_id.h4
-rw-r--r--src/openvpn/shaper.h2
-rw-r--r--src/openvpn/sig.c67
-rw-r--r--src/openvpn/sig.h13
-rw-r--r--src/openvpn/socket.c1938
-rw-r--r--src/openvpn/socket.h297
-rw-r--r--src/openvpn/socks.c48
-rw-r--r--src/openvpn/socks.h13
-rw-r--r--src/openvpn/ssl.c1132
-rw-r--r--src/openvpn/ssl.h102
-rw-r--r--src/openvpn/ssl_backend.h67
-rw-r--r--src/openvpn/ssl_common.h84
-rw-r--r--src/openvpn/ssl_mbedtls.c (renamed from src/openvpn/ssl_polarssl.c)582
-rw-r--r--src/openvpn/ssl_mbedtls.h (renamed from src/openvpn/ssl_polarssl.h)36
-rw-r--r--src/openvpn/ssl_openssl.c301
-rw-r--r--src/openvpn/ssl_openssl.h7
-rw-r--r--src/openvpn/ssl_verify.c209
-rw-r--r--src/openvpn/ssl_verify.h47
-rw-r--r--src/openvpn/ssl_verify_backend.h51
-rw-r--r--src/openvpn/ssl_verify_mbedtls.c511
-rw-r--r--src/openvpn/ssl_verify_mbedtls.h (renamed from src/openvpn/ssl_verify_polarssl.h)22
-rw-r--r--src/openvpn/ssl_verify_openssl.c263
-rw-r--r--src/openvpn/ssl_verify_polarssl.c397
-rw-r--r--src/openvpn/syshead.h105
-rw-r--r--src/openvpn/tls_crypt.c254
-rw-r--r--src/openvpn/tls_crypt.h144
-rw-r--r--src/openvpn/tun.c830
-rw-r--r--src/openvpn/tun.h43
-rw-r--r--src/openvpn/win32.c285
-rw-r--r--src/openvpn/win32.h7
-rw-r--r--src/openvpn/win32_wfp.h359
-rw-r--r--src/openvpnserv/Makefile.am16
-rw-r--r--src/openvpnserv/Makefile.in181
-rw-r--r--src/openvpnserv/automatic.c415
-rw-r--r--src/openvpnserv/common.c218
-rw-r--r--src/openvpnserv/interactive.c1652
-rwxr-xr-xsrc/openvpnserv/openvpnserv.c534
-rw-r--r--src/openvpnserv/openvpnserv.vcxproj2
-rw-r--r--src/openvpnserv/service.c861
-rw-r--r--src/openvpnserv/service.h215
-rw-r--r--src/openvpnserv/validate.c249
-rw-r--r--src/openvpnserv/validate.h48
-rw-r--r--src/plugins/Makefile.in49
-rw-r--r--src/plugins/auth-pam/Makefile.am1
-rw-r--r--src/plugins/auth-pam/Makefile.in61
-rw-r--r--src/plugins/auth-pam/auth-pam.c91
-rw-r--r--src/plugins/auth-pam/utils.c113
-rw-r--r--src/plugins/auth-pam/utils.h66
-rw-r--r--src/plugins/down-root/Makefile.in57
-rw-r--r--tests/Makefile.am12
-rw-r--r--tests/Makefile.in314
-rw-r--r--tests/t_client.rc-sample101
-rwxr-xr-xtests/t_client.sh141
-rwxr-xr-xtests/t_client.sh.in141
-rwxr-xr-xtests/t_lpback.sh2
-rw-r--r--tests/unit_tests/Makefile.am5
-rw-r--r--tests/unit_tests/Makefile.in666
-rw-r--r--tests/unit_tests/example_test/Makefile.am13
-rw-r--r--tests/unit_tests/example_test/Makefile.in800
-rw-r--r--tests/unit_tests/example_test/test.c46
-rw-r--r--tests/unit_tests/example_test/test2.c21
-rw-r--r--tests/unit_tests/openvpn/Makefile.am37
-rw-r--r--tests/unit_tests/openvpn/Makefile.in1035
-rw-r--r--tests/unit_tests/openvpn/mock_msg.c92
-rw-r--r--tests/unit_tests/openvpn/test_argv.c194
-rw-r--r--tests/unit_tests/openvpn/test_tls_crypt.c242
-rw-r--r--tests/unit_tests/plugins/Makefile.am3
-rw-r--r--tests/unit_tests/plugins/Makefile.in666
-rw-r--r--tests/unit_tests/plugins/auth-pam/Makefile.am12
-rw-r--r--tests/unit_tests/plugins/auth-pam/Makefile.in788
-rw-r--r--tests/unit_tests/plugins/auth-pam/test_search_and_replace.c78
-rwxr-xr-xtests/update_t_client_ips.sh16
-rw-r--r--vendor/Makefile.am22
-rw-r--r--vendor/Makefile.in504
-rw-r--r--version.m49
268 files changed, 36278 insertions, 19103 deletions
diff --git a/.gitignore b/.gitignore
index 0571e80..fc1e223 100644
--- a/.gitignore
+++ b/.gitignore
@@ -51,7 +51,16 @@ config-msvc-local.h
config-msvc-version.h
doc/openvpn.8.html
distro/rpm/openvpn.spec
+
tests/t_client.sh
tests/t_client-*-20??????-??????/
+t_client.rc
+t_client_ips.rc
+
src/openvpn/openvpn
+include/openvpn-plugin.h
config-version.h
+nbproject
+test-driver
+compile
+stamp-h2
diff --git a/ChangeLog b/ChangeLog
index 537e213..991aeb6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,200 +1,356 @@
OpenVPN Change Log
-Copyright (C) 2002-2015 OpenVPN Technologies, Inc. <sales@openvpn.net>
+Copyright (C) 2002-2016 OpenVPN Technologies, Inc. <sales@openvpn.net>
-2016.05.09 -- Version 2.3.11
-James Yonan (1):
- Fixed port-share bug with DoS potential
+2016.11.17 -- Version 2.4_beta1
+Arne Schwabe (1):
+ Make Changes.rst nicer for 2.4 release
+
+David Sommerseth (16):
+ Update .mailmap to unify and clean up odd names and e-mail addresses
+ cleanup: Remove NOP code sections in ssl.c:tls_process()
+ Remove last rest of INSTALL-win32.txt references
+ auth-gen-token: Add --auth-gen-token option
+ auth-gen-token: Generate an auth-token per client
+ auth-gen-token: Push generated auth-tokens to the client
+ auth-gen-token: Authenticate generated auth-tokens when client re-authenticates
+ Fix builds with --disable-crypto
+ man: Improve the --keepalive section
+ console: Fix compiler warning
+ systemd: Improve the systemd unit files
+ tun: Fix compiler warnings
+ file checks: Merge warn_if_group_others_accessible() into check_file_access()
+ tun: Fix weird commit error causing a double assignment
+ options: Remove --tls-remote
+ Remove unused variable in argv_printf_arglist()
-Jens Neuhalfen (2):
- Make intent of utun device name validation clear
- Fix buffer overflow by user supplied data
+Gert Doering (10):
+ openvpn version line: remove [IPv6], add [AEAD] if available
+ clean up *sig_info handling in link_socket_init_phase2()
+ check c->c2.link_socket before calling do_init_route_ipv6_list()
+ Check previously-unchecked buf_alloc_write() call in crypto self-test.
+ Fix potential division by zero in shaper_reset()
+ Repair topology subnet on FreeBSD 11
+ Repair topology subnet on OpenBSD
+ Add in_port_t check to configure.ac
+ Fix compilation on MinGW with -std=c99
+ Replace WIN32 by _WIN32
-Leonardo Basilio (1):
- Correctly report TCP connection timeout on windows.
+Heiko Hund (4):
+ put argv_* functions into own file, add unit tests
+ Remove unused and unecessary argv interfaces
+ remove unused system_str from struct argv
+ Factor out %sc handling from argv_printf()
Lev Stipakov (1):
- Report Windows bitness
+ Drop recursively routed packets
-Michael McConville (1):
- Fix undefined signed shift overflow
-
-Niels Ole Salscheider (1):
- Fix build with libressl
-
-Samuli Seppänen (1):
- Improve LZO, PAM and OpenSSL documentation
+Samuli Seppänen (6):
+ Remove INSTALL-win32.txt that is now hosted in openvpn-build
+ Fix update_t_client_ips.sh for out of tree builds
+ Make sure that all relevant files under test go to release tarballs
+ Allow passing extra arguments to fping/fping6 in t_client.rc
+ Prevent generation of duplicate EXPECT_IFCONFIG entries
+ Fix a logic problem in handling of --up scripts in t_client.sh
Selva Nair (2):
- Ensure input read using systemd-ask-password is null terminated
- Support reading the challenge-response from console
+ Support --block-outside-dns on multiple tunnels
+ Unbreak windows build
+
+Steffan Karger (19):
+ Fix use-after-free bug in prepare_push_reply()
+ Remove verbose msg() from send_push_reply()
+ Limit --reneg-bytes to 64MB when using small block ciphers
+ Add a revoked cert to the sample keys
+ Fix --tls-version-max in mbed TLS builds
+ Don't deference type-punned pointers
+ Fix builds on compilers without anonymous union support
+ Refactor static/tls-auth key loading
+ Add missing includes in error.h
+ Make argv unit tests obey {MBEDTLS, OPENSSL}_{LIBS, CFLAGS}
+ Move private file access checks to options_postprocess_filechecks()
+ Deprecate key-method 1
+ Refactor CRL handling
+ Remove unneeded check for extra_certs_file_inline
+ Fix missing return value checks in multi_process_float()
+ Restore pre-NCP cipher options on SIGUSR1
+ Remove unused variables from do_init_crypto_static()
+ Add control channel encryption (--tls-crypt)
+ Add --tls-crypt unit tests
+
+
+2016.10.19 -- Version 2.4_alpha2
-Steffan Karger (10):
- openssl: improve logging
- polarssl: improve logging
- Update manpage: OpenSSL might also need /dev/urandom inside chroot
- socks.c: fix check on get_user_pass() return value(s)
- Fix OCSP_check.sh
- hardening: add safe FD_SET() wrapper openvpn_fd_set()
- Fix memory leak in argv_extract_cmd_name()
- Replace MSG_TEST() macro for static inline msg_test()
- Restrict default TLS cipher list
- Various Changes.rst fixes
-
-ValdikSS (3):
- Clarify mssfix documentation
- Clarify --block-outside-dns documentation
- Update --block-outside-dns to work on Windows Vista
+David Sommerseth (1):
+ Update .mailmap to unify and clean up odd names and e-mail addresses
+Steffan Karger (1):
+ Fix use-after-free bug in prepare_push_reply()
-2016.01.04 -- Version 2.3.10
-Gert Doering (1):
- Prepare for v2.3.10 release, list PolarSSL 1.2 to 1.3 upgrade
-Jan Just Keijser (1):
- Make certificate expiry warning patch (091edd8e299686) work on OpenSSL 1.0.1 and earlier.
+2016.10.17 -- Version 2.4_alpha1
-Lev Stipakov (1):
- Repair IPv6 netsh calls if Win XP is detected
+Adriaan de Jong (2):
+ Fixed a bug where PolarSSL gave an error when using an inline file tag.
+ Fix --show-pkcs11-ids (Bug #239)
-Phillip Smith (1):
- Use bob.example.com and alice.example.com to improve clarity of documentation
+Alexander Pyhalov (1):
+ Default gateway can't be determined on illumos/Solaris platforms
-Steffan Karger (6):
- Remove unused variables from ssl_verify_polarssl.c's x509_get_serial()
- Upgrade OpenVPN 2.3 to PolarSSL 1.3
- Warn user if their certificate has expired
- Make assert_failed() print the failed condition
- cleanup: get rid of httpdigest.c type warnings
- Fix regression in setups without a client certificate
+Alon Bar-Lev (1):
+ pkcs11: use generic evp key instead of rsa
-Yegor Yefremov (1):
- polarssl: fix unreachable code
+Andris Kalnozols (3):
+ Fix some typos in the man page.
+ Do not upcase x509-username-field for mixed-case arguments.
+ extract_x509_extension(): hide status message during normal operation.
-2015.12.15 -- Version 2.3.9
-Arne Schwabe (7):
- Show extra-certs in current parameters.
- Fix commit a3160fc1bd7368395745b9cee6e40fb819f5564c
+Arne Schwabe (100):
+ Document man agent-external-key
+ Options parsing demands unnecessary configuration if PKCS11 is used
+ Error message if max-routes used incorrectly
+ Properly require --key even if defined(MANAGMENT_EXTERNAL_KEY)
+ Remove dnsflags_to_socktype, it is not used anywhere
+ Fix the proto is used inconsistently warning
+ Remove dead code path and putenv functionality
+ Remove unused function xor
+ Move static prototype definition from header into c file
+ Remove unused function no_tap_ifconfig
+ Add the client id (CID) to the output of the status command
+ Print client id only if compiled with man agent support. Otherwise print an empty string.
+ Allow routes to be set before opening tun, similar to ifconfig before opening tun
+ Add ability to send/receive file descriptors via management interface
+ Android platform specific changes.
+ Emulate persist-tun on Android
+ Document the Android implementation in OpenVPN
+ Only print script warnings when a script is used. Remove stray mention of script-security system.
+ Fix #ifdefs for P2MP_SERVER
+ Move settings of user script into set_user_script function
+ Move checking of script file access into set_user_script
+ Fix another #ifdef/#if P2MP_SERVER
+ PATCHv3 Remove unused variables or put them to the defines they are being used in
+ Add support of utun devices under Mac OS X
+ Add support to ignore specific options.
+ Add a note what setenv opt does for OpenVPN < 2.3.3
+ Implement custom HTTP header for http-proxy, and always send user-agent:
+ Add reporting of UI version to basic push-peer-info set.
+ Change the type of all ports in openvpn to const char* and let getaddrinfo resolve the port together with the hostname.
+ Fix compile error in ssl_openssl introduced by polar external-management patch
+ Simplify print_sockaddr_ex function, merge duplicate ipv4/ipv6 logic.
+ Split the PROTO_UDP_xx options into AF_INET/AF_INET6 and PROTO_TCP/PROTO_UDP part.
+ Fix two instances of asserting AF_INET
+ Fix assertion when SIGUSR1 is received while getaddrinfo is successful
+ Split link_socket_init_phase1 and link_socket_init_phase2 into smaller more managable/readable functions. No functional changes
+ Change proto_remote() function to return a constant string
+ Remove the ip-remote-hint option.
+ change the type of 'remote' to addrinfo*, and rename to 'remote_list'.
+ When resolving fails print the error message from socket layer
+ Implement dual stack client support for OpenVPN
+ Move ASSERT so external-key with OpenSSL works again
+ Implement listing on IPv4/IPv6 dual socket on all platform
+ Add warning for using connection block variables after connection blocks
+ Update IPv6 related readme files
+ Introduce safety check for http proxy options
+ Fix warning for max-routes: do not quit when parsing an old configuration. Format the message to be more like the other deprecated options
+ Fix connecting to localhost on Android
+ Move the initialization of the environment to the top so c2.es is initialized
+ Workaround broken Android 4.4 VpnService API for persist-tun mode
+ Implement an easy parsable log output that allows access to flags of the log message
+ Introduce an option to resolve dns names in advance for --remote, --local and --http-proxy
+ Fix for server selecting address family
+ Don't show the connection profile store in options->ce if there is a connection_list defined.
+ Add gateway and device to android control messages
+ Clean up of socket code.
+ Fix assert when using port-share
+ Work around Solaris getaddrinfo() returing ai_protocol=0
+ Fix man page and OSCP script: tls_serial_{n} is decimal
+ Remove ENABLE_BUFFER_LIST
+ Fix server routes not working in topology subnet with --server [v3]
+ Always enable http-proxy and socks-proxy
+ Remove deprecated --max-routes option from manual
+ Add documentation for PERSIST_TUN_ACTION (Android specific)
+ Remove possibility of using --tls-auth with non OpenVPN Static key files
+ Remove unused function sock_addr_set
+ Document the default for tls-cipher.
+ Report missing end-tags of inline files as errors
+ Fix commit e473b7c if an inline file happens to have a line break exactly at buffer limit
+ Show extra-certs in current parameters, fix clang warning and logic error in preresolve
+ Remove unused function h_errno_msg
+ Add support for requesting the fd again to rebind to the next interface.
+ Don't redirect the gateway on Android even if requested
+ Fix loglevel of protect socket message
+ Extend network-change command to allow reprotecting on the same network (for short connection losses)
+ Use pseudo gw as default gw on Android as a workaround for not being able to read /proc/net/route
+ Remove #ifdefs for client nat support.
+ Do not install a host route for the VPN on Android
+ Fix commit c67acea173dc9ee37220f5b9ff14ede081181992
Do not set the buffer size by default but rely on the operation system default.
+ Start Changes.rst that lists changes in 2.4.0
Remove --enable-password-save option
Reflect enable-password-save change in documentation
Also remove second instance of enable-password-save in the man page
Detect config lines that are too long and give a warning/error
+ Implement the compression V2 data format for stub and lz4.
+ Fix assert when comp is called with unknown algorithm, always call comp init method
+ Ignore stamp-h2 we generate during build process
+ Implement inlining of crl files
+ Complete push-peer-info documentation and allow IV_PLAT_VER for other platforms than Windows if the client UI supplies it.
+ Remove http-proxy-timeout, socks timeout and set default of server-poll-timeout to 120s
+ Add documentation for http-proxy-user-pass option
+ Remove http-proxy-retry and socks-proxy-retry.
+ Update android documentation to match source code
+ Use AES ciphers in our sample configuration files and add a few modern 2.4 examples
+ Fix ENABLE_CRYPTO_OPENSSL set to YES even with --disable-crypto set
+ Prefer RECVDSTADDR to PKTINFO for IPv4 in OS X since it actually works (unlike PKTINFO)
+ Incorporate the Debian typo fixes where appropriate and make show_opt default message clearer
+ Enable TCP non-linear packet ID
+ Change the hold command to communicate the time that OpenVPN would wait to the UI.
+ Remove tun-ipv6 Option. Instead assume that IPv6 is always supported.
Boris Lytochkin (1):
Log serial number of revoked certificate
-Christos Trochalakis (1):
- Adjust server-ipv6 documentation
-
-David Sommerseth (1):
- Avoid partial authentication state when using --disabled in CCD configs
-
-Fish (1):
- Make "block-outside-dns" option platform agnostic
-
-Gert Doering (7):
- Un-break --auth-user-pass on windows
- Replace unaligned 16bit access to TCP MSS value with bytewise access
- Repair test_local_addr() on WIN32
- Fix possible heap overflow on read accessing getaddrinfo() result.
- Fix FreeBSD-specific mishandling of gc arena pointer in create_arbitrary_remote()
- remove unused gc_arena in FreeBSD close_tun()
- Fix isatty() check for good.
-
-Heiko Hund (1):
- put virtual IPv6 addresses into env
-
-Lev Stipakov (5):
- Use adapter index instead of name for windows IPv6 interface config
- Client-side part for server restart notification
- Use adapter index for add/delete_route_ipv6
- Pass adapter index to up/down scripts
- Fix VS2013 compilation
-
-Lukasz Kutyla (1):
- Fix privilege drop if first connection attempt fails
-
-Michal Ludvig (1):
- Support for username-only auth file.
-
-Samuli Seppänen (2):
- Add CONTRIBUTING.rst
- Updates to Changes.rst
-
-Selva Nair (4):
- Fix termination when windows suspends/sleeps
- Do not hard-code windows systemroot in env_block
- Handle ctrl-C and ctrl-break events on Windows
- Unbreak read username password from management
-
-Steffan Karger (11):
- Replace strdup() calls for string_alloc() calls
- Check return value of ms_error_text()
- Increase control channel packet size for faster handshakes
- hardening: add insurance to exit on a failed ASSERT()
- Fix memory leak in auth-pam plugin
- Fix (potential) memory leak in init_route_list()
- Fix unintialized variable in plugin_vlog()
- Add macro to ensure we exit on fatal errors
- Fix memory leak in add_option() by simplifying get_ipv6_addr
- openssl: properly check return value of RAND_bytes()
- Fix rand_bytes return value checking
-
-ValdikSS (1):
- Add Windows DNS Leak fix using WFP ('block-outside-dns')
-
-janjust (1):
- Fix "White space before end tags can break the config parser"
-
-
-2015.08.03 -- Version 2.3.8
-Arne Schwabe (2):
- Report missing endtags of inline files as warnings
- Fix commit e473b7c if an inline file happens to have a line break exactly at buffer limit
-
-Gert Doering (2):
- Produce a meaningful error message if --daemon gets in the way of asking for passwords.
- Document --daemon changes and consequences (--askpass, --auth-nocache).
-
-Holger Kummert (1):
- Del ipv6 addr on close of linux tun interface
+Christian Hesse (1):
+ fix build with automake 1.13(.1)
-James Geboski (1):
- Fix --askpass not allowing for password input via stdin
+Christian Niessner (1):
+ Fix corner case in NTLM authentication (trac #172)
-Steffan Karger (5):
- write pid file immediately after daemonizing
- Make __func__ work with Visual Studio too
- fix regression: query password before becoming daemon
- Fix using management interface to get passwords.
- Fix overflow check in openvpn_decrypt()
+Christos Trochalakis (1):
+ Adjust server-ipv6 documentation
+Cristian Rodriguez (1):
+ Use SSL_MODE_RELEASE_BUFFERS if available
-2015.06.02 -- Version 2.3.7
-Alexander Pyhalov (1):
- Default gateway can't be determined on illumos/Solaris platforms
+Daniel Hahler (1):
+ options: fix option check for "plugin"
-Arne Schwabe (1):
- Warn that tls-auth with free form files is going to be removed from OpenVPN 2.4
+Daniel Kubec (4):
+ Added support for TLS Keying Material Exporters [RFC-5705]
+ Added document for TLS Keying Material Exporters [RFC-5705]
+ sample-plugin: TLS Keying Material Exporter [RFC-5705] demonstration plug-in
+ Fix buffer size parameter for exported keying material.
-David Sommerseth (6):
+David Sommerseth (44):
+ Make git ignore some more files
+ Remove the support for using system() when executing external programs or scripts
+ Fix double-free issue in pf_destroy_context()
+ Reset the version.m4 version for the master branch
+ Avoid recursion in virtual_output_callback_func()
+ The get_default_gateway() function uses warn() instead of msg()
+ Improve the git revision tracking
+ man page: Update man page about the tls_digest_{n} environment variable
+ Remove the --disable-eurephia configure option
+ plugin: Extend the plug-in v3 API to identify the SSL implementation used
+ autoconf: Fix typo
+ t_client.sh: Check for fping/fping6 availability
+ t_client.sh: Write errors to stderr and document requirements
+ t_client.sh: Add prepare/cleanup possibilties for each test case
+ Fix file checks when --chroot is being used
+ Adjusted autotools files to build more cleanly on newer autoconf/automake versions
+ Improve error reporting on file access to --client-config-dir and --ccd-exclusive
+ Don't let openvpn_popen() keep zombies around
+ Don't try to use systemd-ask-password if it is not available
+ Clean up the pipe closing in openvpn_popen()
+ Add systemd unit file for OpenVPN
+ systemd: Use systemd functions to consider systemd availability
+ systemd: Reworked the systemd unit file to handle server and client configs better
autotools: Fix wrong ./configure help screen default values
down-root plugin: Replaced system() calls with execve()
down-root: Improve error messages
plugin, down-root: Fix compiler warnings
sockets: Remove the limitation of --tcp-nodelay to be server-only
plugins, down-root: Code style clean-up
+ Provide compile time OpenVPN version information to plug-ins
+ Provide OpenVPN runtime version information to plug-ins
+ Avoid partial authentication state when using --disabled in CCD configs
+ Only build and run cmocka unit tests if its submodule is initialized
+ Another fix related to unit test framework
+ Remove NOP function and callers
+ Revert "Drop recursively routed packets"
+ Fix client connection instant timeout
+ t_client.sh: Make OpenVPN write PID file to avoid various sudo issues
+ t_client.sh: Add support for Kerberos/ksu
+ t_client.sh: Improve detection if the OpenVPN process did start during tests
+ Rework the user input interface to make it more modular
+ Re-implement the systemd support using the new query user API
+ systemd: Do not mask usernames when querying for it via systemd-ask-password
+ Move memcmp_constant_time() to crypto.h
David Woodhouse (2):
pkcs11: Load p11-kit-proxy.so module by default
Make 'provider' option to --show-pkcs11-ids optional where p11-kit is present
+Davide Brini (2):
+ Provide more accurate warning message
+ Document authfile for socks server
+
+Dmitrij Tejblum (1):
+ Fix is_ipv6 in case of tap interface.
+
+Dorian Harmans (1):
+ Add CHACHA20-POLY1305 ciphersuite IANA name translations.
+
Felix Janda (1):
Use OPENVPN_ETH_P_* so that <netinet/if_ether.h> is unecessary
-Gert Doering (17):
- New approach to handle peer-id related changes to link-mtu (2.3 version)
+Fish (1):
+ Add lz4 support to MSVC.
+
+Gert Doering (110):
+ Implement --mssfix handling for IPv6 packets.
+ Fix option inconsistency warnings about "proto" and "tun-ipv6"
+ Fix parameter type for IP_TOS setsockopt on non-Linux systems.
+ Fix client crash on double PUSH_REPLY.
+ Update README.IPv6 to match what is in 2.3.0
+ Repair "tcp server queue overflow" brokenness, more <stdbool.h> fallout.
+ Permit pool size of /64.../112 for ifconfig-ipv6-pool
+ Add MIN() compatibility macro
+ Fix directly connected routes for "topology subnet" on Solaris.
+ Print "Virtual IPv6 Address" on management interface queries [v4]
+ Use constrain_int() instead of MIN()+syshead.c compat definition - v2.
+ Fix NULL-pointer crash in route_list_add_vpn_gateway().
+ Fix usage of 'compression ...' from global config.
+ Make push-peer-info visible in "normal" per-instance environment.
+ Fix problem with UDP tunneling due to mishandled pktinfo structures.
+ Improve documentation and help text for --route-ipv6.
+ Fix argument type warning introduced by http extra proxy header patch.
+ Fix IPv6 examples in t_client.rc-sample
+ Fix slow memory drain on each client renegotiation.
+ t_client.sh: ignore fields from "ip -6 route show" output that distort results.
+ Fix IPv6_V6ONLY logic.
+ Implement LZ4 compression.
+ Provide LZ4 sources in src/compat/ and use if no system lz4 library found.
+ Document "lz4" argument to "compress" config option.
+ Make code and documentation for --remote-random-hostname consistent.
+ Reduce IV_OPENVPN_GUI_VERSION= to IV_GUI_VER=
+ remove some 'unused variable' warnings
+ Cleanup ir6->netbits handling.
+ Document issue with --chroot, /dev/urandom and PolarSSL.
+ Rename 'struct route' to 'struct route_ipv4'
+ Replace copied structure elements with including <net/route.h>
+ Add "test-driver" and "compile" to .gitignore
+ Fix crash when using --inetd.
+ IPv6 address/route delete fix for Win8
+ Add SSL library version reporting.
+ Minor t_client.sh cleanups
+ Repair --multihome on FreeBSD for IPv4 sockets.
+ Rewrite manpage section about --multihome
+ More IPv6-related updates to the openvpn man page.
+ Conditionalize calls to print_default_gateway on !ENABLE_SMALL
+ Merge get_default_gateway() implementation for all 4+1 BSD variants.
+ Drop incoming fe80:: packets silently now.
+ Recognize AIX, define TARGET_AIX
+ Add tap driver initialization and ifconfig for AIX.
+ implement adding/deleting routes on AIX, for IPv4 and IPv6
+ Make t_client.sh work on AIX.
+ Fix t_lpback.sh platform-dependent failures
+ Call init script helpers with explicit path (./)
+ Fix windows build on older mingw versions.
+ New approach to handle peer-id related changes to link-mtu.
+ Print remote IPv4 address on a dual-stack v6 socket in IPv4 format
Fix incorrect use of get_ipv6_addr() for iroute options.
+ Remove count_netmask_bits(), convert users to use netmask_to_netbits2()
+ Fix leftover 'if (false) ;' statements
Print helpful error message on --mktun/--rmtun if not available.
explain effect of --topology subnet on --ifconfig
Add note about file permissions and --crl-verify to manpage.
@@ -210,328 +366,288 @@ Gert Doering (17):
Use EAI_AGAIN instead of EAI_SYSTEM for openvpn_getaddrinfo().
Move res_init() call to inner openvpn_getaddrinfo() loop
Fix FreeBSD ifconfig for topology subnet tunnels.
+ Produce a meaningful error message if --daemon gets in the way of asking for passwords.
+ Document --daemon changes and consequences (--askpass, --auth-nocache).
+ Fix build on OpenSolaris (non-gmake)
+ Un-break --auth-user-pass on windows
+ refactor struct route_ipv6, bring in line with struct route_ipv4 again
+ refactor struct route_ipv6_list, bring in line with struct route_list again
+ Add route_ipv6_gateway* data structures for rgi6 support.
+ Create basic infrastructure for IPv6 default gateway handling / redirection.
+ Make client delay less before sending PUSH_REQUEST
+ get_default_gateway_ipv6(): Linux / Netlink implementation.
+ Implement handling of overlapping IPv6 routes with IPv6 remote VPN server address
+ Implement '--redirect-gateway ipv6'
+ get_default_gateway_ipv6(): *BSD / MacOS / Solaris PF_ROUTE implementation
+ Fix IPv6 host routes to LAN gateway on OpenSolaris
+ Replace unaligned 16bit access to TCP MSS value with bytewise access
+ Repair test_local_addr() on WIN32
+ Add custom check for inet_pton()/inet_ntop() on MinGW/WIN32
+ get_default_gateway_ipv6(): Win32 implementation using GetBestRoute2()
+ Remove support for snappy compression.
+ Fix info.af == AF_UNSPEC case for server with --mtu-disc
+ Fix FreeBSD-specific mishandling of gc arena pointer in create_arbitrary_remote()
+ remove unused gc_arena in FreeBSD close_tun()
+ Un-break compilation on *BSD
+ Fix isatty() check for good.
+ Fix openserv/validate.o linking issues on mingw.
+ Fix library order in -lmbedtls test.
+ Implement push-remove option to selectively remove pushed options.
+ Upgrade bundled compat-lz4 to upstream release r131.
+ Change --enable-pedantic to use -std=c99 and not -ansi (C90).
+ Fix problems with NCP and --inetd.
+ Do not abort t_client run if OpenVPN instance does not start.
+ Fix IP_PKTINFO related compilation failure on NetBSD 7.0
+ Show compile-time variant for --multihome in --version output.
+ Fix win32 building with C99 mode
+ Fix t_client runs on OpenSolaris
+ make t_client robust against sudoers misconfiguration
+ add POSTINIT_CMD_suf to t_client.sh and sample config
+ Fix --multihome for IPv6 on 64bit BSD systems.
+ Enable -D_SVR4_2 for compilation on Solaris
+ Revert "Enable -D_SVR4_2 for compilation on Solaris"
+ Enable -D_XPG4_2 for compilation on Solaris
Guy Yur (1):
Fix --redirect-private in --dev tap mode.
-Jan Just Keijser (1):
- include ifconfig_ environment variables in --up-restart env set
-
-Jonathan K. Bullard (1):
- Fix null pointer dereference in options.c
-
-Lev Stipakov (1):
- Fix mssfix default value in connection_list context
-
-Matthias Andree (1):
- Manual page update for Re-enabled TLS version negotiation.
-
-Mike Gilbert (1):
- Include systemd units in the source tarball (make dist)
-
-Robert Fischer (1):
- Updated manpage for --rport and --lport
-
-Samuli Seppänen (2):
- Properly escape dashes on the man-page
- Improve documentation in --script-security section of the man-page
-
-Steffan Karger (14):
- Really fix '--cipher none' regression
- Update doxygen (a bit)
- Set tls-version-max to 1.1 if cryptoapicert is used
- Account for peer-id in frame size calculation
- Disable SSL compression
- Fix frame size calculation for non-CBC modes.
- Allow for CN/username of 64 characters (fixes off-by-one)
- Remove unneeded parameter 'first_time' from possibly_become_daemon()
- Re-enable TLS version negotiation by default
- Remove size limit for files inlined in config
- Improve --tls-cipher and --show-tls man page description
- Re-read auth-user-pass file on (re)connect if required
- Clarify --capath option in manpage
- Call daemon() before initializing crypto library
-
-
-2014.11.28 -- Version 2.3.6
-David Sommerseth (1):
- systemd: Reworked the systemd unit file to handle server and client configs better
-
-Gert Doering (1):
- Add client-only support for peer-id.
-
-Samuli Seppänen (1):
- Fix to --shaper documentation on the man-page
-
-Steffan Karger (4):
- Fix assertion error when using --cipher none
- Add --tls-version-max
- Modernize sample keys and sample configs
- Drop too-short control channel packets instead of asserting out.
-
-
-2014.10.24 -- Version 2.3.5
-Andris Kalnozols (2):
- Fix some typos in the man page.
- Do not upcase x509-username-field for mixed-case arguments.
-
-Arne Schwabe (1):
- Fix server routes not working in topology subnet with --server [v3]
-
-David Sommerseth (4):
- Improve error reporting on file access to --client-config-dir and --ccd-exclusive
- Don't let openvpn_popen() keep zombies around
- Add systemd unit file for OpenVPN
- systemd: Use systemd functions to consider systemd availability
-
-Gert Doering (3):
- Drop incoming fe80:: packets silently now.
- Fix t_lpback.sh platform-dependent failures
- Call init script helpers with explicit path (./)
+Heikki Hannikainen (1):
+ Always load intermediate certificates from a PKCS#12 file
-Heiko Hund (1):
+Heiko Hund (20):
+ Fix display of plugin hook types
+ Support UTF-8 --client-config-dir
+ close more file descriptors on exec
+ Ignore UTF-8 byte order mark
+ reintroduce --no-name-remapping option
+ make --tls-remote compatible with pre 2.3 configs
+ add new option for X.509 name verification
+ Support non-ASCII TAP adapter names on Windows
+ Support non-ASCII characters in Windows tmp path
+ make sure sa_family_t is defined
+ convert struct signal_info element
+ grow route lists dynamically
+ fix route struct name
refine assertion to allow other modes than CBC
+ Fix compilation on Windows
+ fix warnings on Windows
+ extend management interface command "state"
+ put virtual IPv6 addresses into env
+ interactive service v3
+ Windows: do_ifconfig() after open_tun()
+
+Holger Kummert (1):
+ Del ipv6 addr on close of linux tun interface
Hubert Kario (2):
ocsp_check - signature verification and cert staus results are separate
ocsp_check - double check if ocsp didn't report any errors in execution
+Ilya Shipitsin (3):
+ initial travis-ci support
+ skip t_lpback.sh and t_cltsrv.sh if openvpn configured --disable-crypto
+ enable "--disable-crypto" build configuration for travis
+
+Ivo Manca (1):
+ Plug memory leak in mbedTLS backend
+
James Bekkema (1):
Fix socket-flag/TCP_NODELAY on Mac OS X
-James Yonan (6):
- Fixed several instances of declarations after statements.
- In socket.c, fixed issue where uninitialized value (err) is being passed to to gai_strerror.
- Explicitly cast the third parameter of setsockopt to const void * to avoid warning.
- MSVC 2008 doesn't support dimensioning an array with a const var nor using %z as a printf format specifier.
+James Geboski (1):
+ Fix --askpass not allowing for password input via stdin
+
+James Yonan (14):
+ Added support for the Snappy compression algorithm
+ Always push basic set of peer info values to server.
+ TLS version negotiation
+ Added "setenv opt" directive prefix. If present, and if the directive that follows is recognized, it will be processed as if the "setenv opt" prefix was absent. If present and if the directive that follows is not recognized, the directive will be ignored rather than cause a fatal error.
+ MSVC fixes
+ Set SSL_OP_NO_TICKET flag in SSL context for OpenSSL builds, to disable TLS stateless session resumption.
+ Use native strtoull() with MSVC 2013.
Define PATH_SEPARATOR for MSVC builds.
Fixed some compile issues with show_library_versions()
+ Added flags parameter to format_hex_ex.
+ Extended x509-track for OpenSSL to report SHA1 fingerprint.
+ Fixed port-share bug with DoS potential
+ Added directive to specify HTTP proxy credentials in config.
+ Bind to local socket before dropping privileges
+
+Jan Just Keijser (5):
+ man page patch for missing options
+ make 'explicit-exit-notify' pullable again
+ include ifconfig_ environment variables in --up-restart env set
+ Author: Jan Just Keijser <janjust@nikhef.nl>
+ Make certificate expiry warning patch (091edd8e299686) work on OpenSSL 1.0.1 and earlier.
Jann Horn (1):
Remove quadratic complexity from openvpn_base64_decode()
-Mike Gilbert (1):
- Add configure check for the path to systemd-ask-password
-
-Philipp Hagemeister (2):
- Add topology in sample server configuration file
- Implement on-link route adding for iproute2
+Jeffrey Cutter (1):
+ Update contrib/pull-resolv-conf/client.up for no DOMAIN
-Samuel Thibault (1):
- Ensure that client-connect files are always deleted
-
-Steffan Karger (13):
- Remove function without effect (cipher_ok() always returned true).
- Remove unneeded wrapper functions in crypto_openssl.c
- Fix bug that incorrectly refuses oid representation eku's in polar builds
- Update README.polarssl
- Rename ALLOW_NON_CBC_CIPHERS to ENABLE_OFB_CFB_MODE, and add to configure.
- Add proper check for crypto modes (CBC or OFB/CFB)
- Improve --show-ciphers to show if a cipher can be used in static key mode
- Extend t_lpback tests to test all ciphers reported by --show-ciphers
- Don't exit daemon if opening or parsing the CRL fails.
- Fix typo in cipher_kt_mode_{cbc, ofb_cfb}() doxygen.
- Fix regression with password protected private keys (polarssl)
- ssl_polarssl.c: fix includes and make casts explicit
- Remove unused variables from ssl_verify_openssl.c extract_x509_extension()
-
-TDivine (1):
- Fix "code=995" bug with windows NDIS6 tap driver.
-
-
-2014.04.30 -- Version 2.3.4
-Arne Schwabe (1):
- Fix man page and OSCP script: tls_serial_{n} is decimal
-
-Dmitrij Tejblum (1):
- Fix is_ipv6 in case of tap interface.
-
-Gert Doering (7):
- IPv6 address/route delete fix for Win8
- Add SSL library version reporting.
- Minor t_client.sh cleanups
- Repair --multihome on FreeBSD for IPv4 sockets.
- Rewrite manpage section about --multihome
- More IPv6-related updates to the openvpn man page.
- Conditionalize calls to print_default_gateway on !ENABLE_SMALL
-
-James Yonan (2):
- Use native strtoull() with MSVC 2013.
- When tls-version-min is unspecified, revert to original versioning approach.
-
-Steffan Karger (4):
- Change signedness of hash in x509_get_sha1_hash(), fixes compiler warning.
- Fix OCSP_check.sh to also use decimal for stdout verification.
- Fix build system to accept non-system crypto library locations for plugins.
- Make serial env exporting consistent amongst OpenSSL and PolarSSL builds.
-
-Yawning Angel (1):
- Fix SOCKSv5 method selection
-
-kangsterizer (1):
- Fix typo in sample build script to use LDFLAGS
-
-
-2014.04.08 -- Version 2.3.3
-Alon Bar-Lev (1):
- pkcs11: use generic evp key instead of rsa
-
-Arne Schwabe (8):
- Add support of utun devices under Mac OS X
- Add support to ignore specific options.
- Add a note what setenv opt does for OpenVPN < 2.3.3
- Add reporting of UI version to basic push-peer-info set.
- Fix compile error in ssl_openssl introduced by polar external-management patch
- Fix assertion when SIGUSR1 is received while getaddrinfo is successful
- Add warning for using connection block variables after connection blocks
- Introduce safety check for http proxy options
-
-David Sommerseth (5):
- man page: Update man page about the tls_digest_{n} environment variable
- Remove the --disable-eurephia configure option
- plugin: Extend the plug-in v3 API to identify the SSL implementation used
- autoconf: Fix typo
- Fix file checks when --chroot is being used
-
-Davide Brini (1):
- Document authfile for socks server
-
-Gert Doering (9):
- Fix IPv6 examples in t_client.rc-sample
- Fix slow memory drain on each client renegotiation.
- t_client.sh: ignore fields from "ip -6 route show" output that distort results.
- Make code and documentation for --remote-random-hostname consistent.
- Reduce IV_OPENVPN_GUI_VERSION= to IV_GUI_VER=
- Document issue with --chroot, /dev/urandom and PolarSSL.
- Rename 'struct route' to 'struct route_ipv4'
- Replace copied structure elements with including <net/route.h>
- Workaround missing SSL_OP_NO_TICKET in earlier OpenSSL versions
-
-Heikki Hannikainen (1):
- Always load intermediate certificates from a PKCS#12 file
-
-Heiko Hund (2):
- Support non-ASCII TAP adapter names on Windows
- Support non-ASCII characters in Windows tmp path
-
-James Yonan (3):
- TLS version negotiation
- Added "setenv opt" directive prefix.
- Set SSL_OP_NO_TICKET flag in SSL context for OpenSSL builds, to disable TLS stateless session resumption.
+Jens Neuhalfen (6):
+ Make intent of utun device name validation clear
+ Fix buffer overflow by user supplied data
+ ignore the local config file t_client.rc in git
+ Prevent integration test timeout bc. of sudo
+ Add unit testing support via cmocka
+ Add a test for auth-pam searchandreplace
Jens Wagner (1):
Fix spurious ignoring of pushed config options (trac#349).
-Joachim Schipper (3):
+Jesse Glick (1):
+ Allow use of NetBeans without saving nbproject/ directory.
+
+Joachim Schipper (5):
+ doc/management-notes.txt: fix typo
+ Fix typo in ./configure message
Refactor tls_ctx_use_external_private_key()
--management-external-key for PolarSSL
external_pkcs1_sign: Support non-RSA_SIG_RAW hash_ids
-Josh Cepek (2):
+Jonathan K. Bullard (3):
+ Fix mismatch of fprintf format specifier and argument type
+ Fix null pointer dereference in options.c
+ Fail if options have extra parameters [v2]
+
+Josh Cepek (7):
+ Fix parameter listing in non-debug builds at verb 4
+ (updated) [PATCH] Warn when using verb levels >=7 without debug
+ Fix proto tcp6 for server & non-P2MP modes
+ Fix Windows script execution when called from script hooks
Correct error text when no Windows TAP device is present
Require a 1.2.x PolarSSL version
+ Push an IPv6 CIDR mask used by the server, not the pool's size
-Klee Dienes (1):
- tls_ctx_load_ca: Improve certificate error messages
-
-Max Muster (1):
- Remove duplicate cipher entries from TLS translation table.
-
-Peter Sagerson (1):
- Fix configure interaction with static OpenSSL libraries
-
-Steffan Karger (7):
- Do not pass struct tls_session* as void* in key_state_ssl_init().
- Require polarssl >= 1.2.10 for polarssl-builds, which fixes CVE-2013-5915.
- Use RSA_generate_key_ex() instead of deprecated, RSA_generate_key()
- Also update TLSv1_method() calls in support code to SSLv23_method() calls.
- Update TLSv1 error messages to SSLv23 to reflect changes from commit 4b67f98
- If --tls-cipher is supplied, make --show-tls parse the list.
- Add openssl-specific common cipher list names to ssl.c.
-
-Tamas TEVESZ (1):
- Add support for client-cert-not-required for PolarSSL.
-
-Thomas Veerman (1):
- Fix "." in description of utun.
-
-
-2013.05.31 -- Version 2.3.2
-Arne Schwabe (3):
- Only print script warnings when a script is used. Remove stray mention of script-security system.
- Move settings of user script into set_user_script function
- Move checking of script file access into set_user_script
+Julien Muchembled (1):
+ Fix --mtu-disc option with IPv6 transport
-Davide Brini (1):
- Provide more accurate warning message
+Kenneth Rose (1):
+ Fix v3 plugins to support returning values back to OpenVPN.
-Gert Doering (2):
- Fix NULL-pointer crash in route_list_add_vpn_gateway().
- Fix problem with UDP tunneling due to mishandled pktinfo structures.
+Klee Dienes (1):
+ tls_ctx_load_ca: Improve certificate error messages
-James Yonan (1):
- Always push basic set of peer info values to server.
+Leon Klingele (1):
+ Add link to bug tracker
-Jan Just Keijser (1):
- make 'explicit-exit-notify' pullable again
+Leonardo Basilio (1):
+ Correctly report TCP connection timeout on windows.
-Josh Cepek (2):
- Fix proto tcp6 for server & non-P2MP modes
- Fix Windows script execution when called from script hooks
+Lev Stipakov (26):
+ Peer-id patch v7
+ Add the peer-id to the output of the status command
+ Prevent memory drain for long lasting floating sessions
+ Disallow lameduck's float to an address taken by another client
+ Fix NULL dereferencing
+ Fix mssfix default value in connection_list context
+ This fixes MSVS 2013 compilation.
+ Continuation of MSVS fixes
+ Fast recovery when host is in unreachable network
+ Fix compilation error with --disable-crypto
+ Send push reply right after async auth complete
+ Fix compilation with --disable-server
+ Refine float logging
+ Generate openvpn-plugin.h for MSVC build
+ Replace variable length array with malloc
+ Use adapter index instead of name for windows IPv6 interface config
+ Notify clients about server's exit/restart
+ Use adapter index for add/delete_route_ipv6
+ Pass adapter index to up/down scripts
+ Detecting and logging Windows versions
+ Report Windows bitness
+ Fix "implicit declaration" compiler warning
+ Drop recursively routed packets
+ Support for disabled peer-id
+ Exclude peer-id from pulled options digest
+ Use separate list for per-client push options
-Steffan Karger (2):
- Fixed tls-cipher translation bug in openssl-build
- Fixed usage of stale define USE_SSL to ENABLE_SSL
+Lukasz Kutyla (1):
+ Fix privilege drop if first connection attempt fails
-svimik (1):
- Fix segfault when enabling pf plug-ins
+Matthias Andree (1):
+ Enable TCP_NODELAY configuration on FreeBSD.
+Max Muster (1):
+ Remove duplicate cipher entries from TLS translation table.
+Michael McConville (1):
+ Fix undefined signed shift overflow
-2013.03.29 -- Version 2.3.1
-Arne Schwabe (4):
- Remove dead code path and putenv functionality
- Remove unused function xor
- Move static prototype definition from header into c file
- Remove unused function no_tap_ifconfig
+Michal Ludvig (1):
+ Support for username-only auth file.
-Christian Hesse (1):
- fix build with automake 1.13(.1)
+Mike Gilbert (2):
+ Add configure check for the path to systemd-ask-password
+ Include systemd units in the source tarball (make dist)
-Christian Niessner (1):
- Fix corner case in NTLM authentication (trac #172)
+Niels Ole Salscheider (1):
+ Fix build with libressl
-Gert Doering (5):
- Update README.IPv6 to match what is in 2.3.0
- Repair "tcp server queue overflow" brokenness, more <stdbool.h> fallout.
- Permit pool size of /64.../112 for ifconfig-ipv6-pool
- Add MIN() compatibility macro
- Fix directly connected routes for "topology subnet" on Solaris.
+Peter Sagerson (1):
+ Fix configure interaction with static OpenSSL libraries
-Heiko Hund (5):
- close more file descriptors on exec
- Ignore UTF-8 byte order mark
- reintroduce --no-name-remapping option
- make --tls-remote compatible with pre 2.3 configs
- add new option for X.509 name verification
+Philipp Hagemeister (2):
+ Add topology in sample server configuration file
+ Implement on-link route adding for iproute2
-Jan Just Keijser (1):
- man page patch for missing options
+Phillip Smith (1):
+ Use bob.example.com and alice.example.com to improve clarity of documentation
-Josh Cepek (2):
- Fix parameter listing in non-debug builds at verb 4
- (updated) [PATCH] Warn when using verb levels >=7 without debug
+Robert Fischer (1):
+ Updated manpage for --rport and --lport
-Matthias Andree (1):
- Enable TCP_NODELAY configuration on FreeBSD.
+Samuel Thibault (1):
+ Ensure that client-connect files are always deleted
-Samuli Seppänen (4):
+Samuli Seppänen (15):
Removed ChangeLog.IPv6
Added cross-compilation information INSTALL-win32.txt
Updated README
Cleaned up and updated INSTALL
-
-Steffan Karger (7):
+ Fix to --shaper documentation on the man-page
+ Properly escape dashes on the man-page
+ Improve documentation in --script-security section of the man-page
+ Add CONTRIBUTING.rst
+ Update CONTRIBUTING.rst to allow GitHub PRs for code review purposes
+ Clarify the fact that build instructions in README are for release tarballs
+ Mention tap-windows6 in INSTALL file
+ Use an up-to-date easy-rsa URL on the man-page
+ Clarify which Windows versions require which TUN/TAP driver
+ Deprecate the automatic part of openvpnserv.exe in favor of openvpnserv2.exe
+ Automatically cache expected IPs for t_client.sh on the first run
+
+Selva Nair (26):
+ Fix termination when windows suspends/sleeps
+ Do not hard-code windows systemroot in env_block
+ Handle ctrl-C and ctrl-break events on Windows
+ Unbreak read username password from management
+ Restrict options/configs for startup through interactive service
+ Send stdout and stderr of OpenVPN started by interactive service to NUL
+ Handle localized Administrators group name in windows
+ Fix interactive service ignoring stop command if openvpn is running
+ Use appropriate buffer size for WideCharToMultiByte output in interactive.c
+ Refactor and move the block-outside-dns code to a new file (block_dns.[ch])
+ Add support for block-outside-dns through the interactive service
+ Ensure input read using systemd-ask-password is null terminated
+ Support reading the challenge-response from console
+ Make error non-fatal while deleting address using netsh
+ Add support for register-dns through interactive service
+ Fix handling of out of memory error in interactive service
+ Fix the comparison of pull options hash on restart
+ Set WFP engine handle to NULL in win_wfp_uninit()
+ Make block-outside-dns work with persist-tun
+ Add an option to filter options received from server
+ Ignore SIGUSR1/SIGHUP during exit notification
+ Fix management-external-cert option parsing error
+ Return process id of openvpn from interactive service to client
+ Exponentially back off on repeated connect retries
+ Promptly close the netcmd_semaphore handle after use
+ Avoid format specifier %zu for Windows compatibility
+
+Steffan Karger (180):
PolarSSL-1.2 support
Improve PolarSSL key_state_read_{cipher, plain}text messages
Improve verify_callback messages
@@ -539,54 +655,216 @@ Steffan Karger (7):
Switch to IANA names for TLS ciphers.
Fixed autoconf script to properly detect missing pkcs11 with polarssl.
Use constant time memcmp when comparing HMACs in openvpn_decrypt.
+ Fixed tls-cipher translation bug in openssl-build
+ Fixed usage of stale define USE_SSL to ENABLE_SSL
+ Do not pass struct tls_session* as void* in key_state_ssl_init().
+ Require polarssl >= 1.2.10 for polarssl-builds, which fixes CVE-2013-5915.
+ Also update TLSv1_method() calls in support code to SSLv23_method() calls.
+ Update TLSv1 error messages to SSLv23 to reflect changes from commit 4b67f98
+ If --tls-cipher is supplied, make --show-tls parse the list.
+ Remove OpenSSL tmp_rsa_callback. Removes support for ephemeral RSA in TLS.
+ Make tls_ctx_restrict_ciphers accept NULL as char *cipher_list.
+ Disable export ciphers by default for OpenSSL builds.
+ Fix compiler warning for unused result of write()
+ Remove unused variables from ssl_verify_polarssl.c's x509_get_serial()
+ Fix compiler warnings in ssl_polarssl.c
+ Bump minimum OpenSSL version to 0.9.8
+ Add openssl-specific common cipher list names to ssl.c.
+ Disable unsupported TLS cipher modes by default, cleans --show-tls output.
+ configure.ac: check for SSL_OP_NO_TICKET flag in OpenSSL
+ configure.ac: use CPPFLAGS for SSL_OP_NO_TICKET check
+ Upgrade to PolarSSL 1.3
+ Improve error reporting during key/cert loading with PolarSSL.
+ Update openvpn-plugin.h for PolarSSL 1.3.
+ Add support for elliptic curve diffie-hellmann key exchange (ECDH)
+ Add an elliptic curve testing cert chain to the sample keys
+ Change signedness of hash in x509_get_sha1_hash(), fixes compiler warning.
+ Fix OCSP_check.sh to also use decimal for stdout verification.
+ Make serial env exporting consistent amongst OpenSSL and PolarSSL builds.
+ Fix build system to accept non-system crypto library locations for plugins.
+ Remove function without effect (cipher_ok() always returned true).
+ Remove unneeded wrapper functions in crypto_openssl.c
+ Remove unneeded defines (were needed for pre-0.9.7 OpenSSL).
+ Fix merge error in a6c573d, the ssl ctx is now abstracted.
+ Use generic openvpn_x509_cert_t in ssl_verify_polarssl.c
+ Fix ssl.c, ssl_verify_* includes
+ Move #include "ssl_verify.h" from ssl.h to the source files that need it.
+ Remove dependency on manage.h from ssl_verify.h
+ Remove unused variable 'proxy' from socket_restart_pause()
+ Add (default disabled) --enable-werror option to configure
+ Fix --disable-ssl builds, were broken by cleanup in 63dc03d.
+ configure.ac: fix SSL_OP_NO_TICKET check
+ Fix bug that incorrectly refuses oid representation eku's in polar builds
+ Update README.polarssl
+ cleanup: remove #if 0'ed function initiate_untrusted_session() from ssl.c.
+ Rename ALLOW_NON_CBC_CIPHERS to ENABLE_OFB_CFB_MODE, and add to configure.
+ Add proper check for crypto modes (CBC or OFB/CFB)
+ Improve --show-ciphers to show if a cipher can be used in static key mode
+ Extend t_lpback tests to test all ciphers reported by --show-ciphers
+ Don't issue warning for 'translate to self' tls-ciphers
+ Don't exit daemon if opening or parsing the CRL fails.
+ Define dummy SSL_OP_NO_TICKET flag if not present in OpenSSL.
+ Fix typo in cipher_kt_mode_{cbc, ofb_cfb}() doxygen.
+ Fix some unintialized variable warnings
+ Fix clang warning in options.c
+ Fix compiler warnings in ssl_polarssl.c.
+ Fix regression with password protected private keys (polarssl)
+ Remove unused variables from ssl_verify_openssl.c extract_x509_extension()
+ Fix assertion error when using --cipher none
+ Add --tls-version-max
+ Modernize sample keys and sample configs
+ Drop too-short control channel packets instead of asserting out.
+ Really fix '--cipher none' regression
+ Update doxygen (a bit)
+ Set tls-version-max to 1.1 if cryptoapicert is used
+ openssl: add crypto_msg(), to easily log openssl errors
+ openssl: add more descriptive message for 'no shared cipher' error
+ Remove ENABLE_SSL define (and --disable-ssl configure option)
+ openssl: use crypto_msg(), get rid of openssl-specific code in error.c
+ Add option to disable Diffie Hellman key exchange by setting '--dh none'
+ Account for peer-id in frame size calculation
+ Disable SSL compression
+ Use tls-auth in sample config files
+ Fix frame size calculation for non-CBC modes.
+ Get rid of old OpenSSL workarounds.
+ polarssl: make sure to always null-terminate the cn
+ Allow for CN/username of 64 characters (fixes off-by-one)
+ Change float log message to include common name, if available.
+ Remove unneeded parameter 'first_time' from possibly_become_daemon()
+ Remove size limit for files inlined in config
+ polarssl: remove code duplication in key_state_write_plaintext{, _const}()
+ Improve --tls-cipher and --show-tls man page description
+ polarssl: disable 1/n-1 record splitting
+ cleanup: remove md5 helper functions
+ Re-read auth-user-pass file on (re)connect if required
+ Clarify --capath option in manpage
+ Call daemon() before initializing crypto library
+ write pid file immediately after daemonizing
+ Increase control channel packet size for faster handshakes
+ Make __func__ work with Visual Studio too
+ fix regression: query password before becoming daemon
+ Fix using management interface to get passwords.
+ reintroduce md5_digest wrapper struct to fix gcc warnings
+ Fix out-of-tree builds; openvpn-plugin.h should be in AC_CONFIG_HEADERS
+ Fix overflow check in openvpn_decrypt()
+ Replace strdup() calls for string_alloc() calls
+ Check return value of ms_error_text()
+ polarssl: add easy logging for PolarSSL errors
+ polarssl: Improve PolarSSL logging
+ openssl: be less verbose about cipher translation errors
+ hardening: add insurance to exit on a failed ASSERT()
+ Fix memory leak in auth-pam plugin
+ openssl: remove usage of OPENSSL_malloc() from show_available_curves
+ polarssl: fix --client-cert-not-required
+ polarssl: add --verify-client-cert optional support
+ Fix (potential) memory leak in init_route_list()
+ Add macro to ensure we exit on fatal errors
+ polarssl: also allocate PKCS#11 certificate object on demand
+ polarssl: don't use deprecated functions anymore
+ polarssl: require >= 1.3.8
+ Fix memory leak in add_option() by simplifying get_ipv6_addr
+ remove nonsense const specifier in nonfatal() return value
+ openssl: properly check return value of RAND_bytes()
+ Fix rand_bytes return value checking
+ Fix openssl builds with custom-built library: specify most-dependent first
+ Support duplicate x509 field values in environment
+ Warn user if their certificate has expired
+ Disable certificate notBefore/notAfter sanity check on OpenSSL < 1.0.2
+ Make assert_failed() print the failed condition
+ cleanup: get rid of httpdigest.c type warnings
+ Fix regression in setups without a client certificate
+ polarssl: actually use polarssl debug logging
+ polarssl: optimize polar_ok() for non-errors
+ Update manpage: OpenSSL might also need /dev/urandom inside chroot
+ polarssl: use wrappers to access md_info_t member functions
+ polarssl: remove now redundant 128-bit blowfish key override
+ socks.c: fix check on get_user_pass() return value(s)
+ configure.ac: simplify crypto library configuration
+ configure.ac: fix polarssl autodetection
+ Allow NULL argument in cipher_ctx_get_cipher_kt()
+ Remove reuse of key_type during init of data channel auth and tls-auth
+ Move crypto_options into key_state and stop using context in SSL-mode.
+ Move key_ctx_bi into crypto_options
+ Move packet_id into crypto_options
+ Change openvpn_encrypt() to append to work buffer only
+ Create separate function for replay check
+ Add AEAD cipher support (GCM)
+ Add cipher name translation for OpenSSL.
+ Add preliminary server-side support for negotiable crypto parameters
+ Minor AEAD patch cleanup
+ Clean up get_tls_handhake_key()
+ Fix OCSP_check.sh
+ Make AEAD modes work with OpenSSL 1.0.1-1.0.1c
+ hardening: add safe FD_SET() wrapper openvpn_fd_set()
+ Only include aead encrypt/decrypt functions if AEAD modes are supported
+ Fix potential null-pointer dereference
+ Fix memory leak in argv_extract_cmd_name()
+ Replace MSG_TEST() macro for static inline msg_test()
+ fixup: change init_key_type() param name in declaration too
+ Further restrict default cipher list
+ PolarSSL x509_get_sha1_hash now returns correct SHA1 fingerprint.
+ Implemented x509-track for PolarSSL.
+ Migrate to mbed TLS 2.x
+ Rename files with 'polarssl' in the name to 'mbedtls'
+ configure.ac: link to all mbed TLS libs during library detection
+ mbedtls: check that private key and certificate match on start
+ mbedtls: improve error reporting in tls verify callback
+ Remove trailing newline from verify callback error messages
+ Don't limit max incoming message size based on c2->frame
+ cleanup: remove alloc_buffers argument from multi_top_init()
+ mbedtls: don't set debug threshold if compiled without MBEDTLS_DEBUG_C
+ Add client-side support for cipher negotiation
+ Add options to restrict cipher negotiation
+ Add server-side support for cipher negotiation
+ Allow ncp-disable and ncp-ciphers to be specified in ccd files
+ Fix '--cipher none --cipher' crash
+ Discourage using 64-bit block ciphers
+ Fix unittests for out-of-source builds
+ Fix --mssfix when using NCP
+ Drop gnu89/c89 support, switch to c99
+ cleanup: remove code duplication in msg_test()
+ Add SHA256 fingerprint support
+ Make sure options->ciphername and options->authname are always defined
+ Update cipher-related man page text
+ Fix duplicate PUSH_REPLY options
+ Check --ncp-ciphers list on startup
+TDivine (1):
+ Fix "code=995" bug with windows NDIS6 tap driver.
-2013.01.07 -- Version 2.3.0
-Gert Doering (2):
- Fix parameter type for IP_TOS setsockopt on non-Linux systems.
- Fix client crash on double PUSH_REPLY.
-
-2012.12.17 -- Version 2.3_rc2
-Adriaan de Jong (1):
- Fix --show-pkcs11-ids (Bug #239)
+Tamas TEVESZ (1):
+ Add support for client-cert-not-required for PolarSSL.
-Arne Schwabe (4):
- Error message if max-routes used incorrectly
- Properly require --key even if defined(MANAGMENT_EXTERNAL_KEY)
- Remove dnsflags_to_socktype, it is not used anywhere
- Fix the proto is used inconsistently warning
+Thomas Veerman (2):
+ Fix "." in description of utun.
+ Update expiry date in management event loop
-David Sommerseth (3):
- Fix double-free issue in pf_destroy_context()
- The get_default_gateway() function uses warn() instead of msg()
- Avoid recursion in virtual_output_callback_func()
+ValdikSS (4):
+ Add Windows DNS Leak fix using WFP ('block-outside-dns')
+ Clarify mssfix documentation
+ Clarify --block-outside-dns documentation
+ Update --block-outside-dns to work on Windows Vista
-Gert Doering (2):
- Implement --mssfix handling for IPv6 packets.
- Fix option inconsistency warnings about "proto" and "tun-ipv6"
+Vasily Kulikov (1):
+ Mac OS X Keychain management client
-Joachim Schipper (2):
- doc/management-notes.txt: fix typo
- Fix typo in ./configure message
+Yawning Angel (1):
+ Fix SOCKSv5 method selection
-2012.10.31 -- Version 2.3_rc1
-Adriaan de Jong (1):
- Fixed a bug where PolarSSL gave an error when using an inline file tag.
+Yegor Yefremov (3):
+ socket: remove duplicate expression
+ polarssl: fix unreachable code
+ cert_data: fix memory leak
-Arne Schwabe (2):
- Document man agent-external-key
- Options parsing demands unnecessary configuration if PKCS11 is used
+janjust (1):
+ Fix "White space before end tags can break the config parser"
-David Sommerseth (2):
- Make git ignore some more files
- Remove the support for using system() when executing external programs or scripts
+kangsterizer (1):
+ Fix typo in sample build script to use LDFLAGS
-Heiko Hund (2):
- Fix display of plugin hook types
- Support UTF-8 --client-config-dir
+svimik (1):
+ Fix segfault when enabling pf plug-ins
-Kenneth Rose (1):
- Fix v3 plugins to support returning values back to OpenVPN.
2012.09.12 -- Version 2.3_beta1
Arne Schwabe (7):
diff --git a/INSTALL b/INSTALL
index d914ed2..4c6d21f 100644
--- a/INSTALL
+++ b/INSTALL
@@ -12,14 +12,6 @@ QUICK START:
Unix:
./configure && make && make-install
- Cross-compile for Windows on Unix
-
- See INSTALL-win32.txt
-
- Compile OpenVPN with OpenSSL/LZO built from source tarballs
-
- See INSTALL-nonstandard.txt
-
*************************************************************************
To download OpenVPN, go to:
@@ -34,10 +26,14 @@ To download easy-rsa go to:
https://github.com/OpenVPN/easy-rsa
-To download tap-windows driver source code go to:
+To download tap-windows (NDIS 5) driver source code go to:
https://github.com/OpenVPN/tap-windows
+To download tap-windows (NDIS 6) driver source code go to:
+
+ https://github.com/OpenVPN/tap-windows6
+
To get the cross-compilation environment go to:
https://github.com/OpenVPN/openvpn-build
@@ -75,26 +71,11 @@ REQUIRES:
a virtual point-to-point IP or Ethernet device. See
TUN/TAP Driver Configuration section below for more info.
- (2) PAM/PAM-Devel (Pluggable Authentication Modules). In most
- Linux distributions, these packages are usually listed as
- the following (here is what they look like on Fedora):
-
- pam-1.1.8-18.fc22.x86_64.rpm (64-bit package)
- pam-devel-1.1.8-18.fc.22.x86_64.rpm (64-bit package)
-
OPTIONAL (but recommended):
(1) OpenSSL library, necessary for encryption, version 0.9.8 or higher
- required, available from http://www.openssl.org/. If you build
- OpenSSL from source tarball, you will need to let OpenVPN-2.3.x
- know where the libraries and header files were installed to:
-
- If you configured OpenSSL with stock options, it will install
- the headers (i.e. - .h files) in /usr/local/ssl/include and
- the libraries (i.e. - .a or .so files) in /usr/local/ssl/lib/openssl
-
+ required, available from http://www.openssl.org/
(2) PolarSSL library, an alternative for encryption, version 1.1 or higher
required, available from https://polarssl.org/
-
(3) LZO real-time compression library, required for link compression,
available from http://www.oberhumer.com/opensource/lzo/
OpenBSD users can use ports or packages to install lzo, but remember
@@ -106,6 +87,10 @@ OPTIONAL (for developers only):
-- available from http://www.gnu.org/software/software.html
(2) Dmalloc library
-- available from http://dmalloc.com/
+ (3) If using t_client.sh test framework, fping/fping6 is needed
+ -- Available from http://www.fping.org/
+ Note: t_client.sh needs an external configured OpenVPN server.
+ See t_client.rc-sample for more info.
*************************************************************************
@@ -225,14 +210,10 @@ ENVIRONMENT for ./configure:
MAN2HTML path to man2html utility
GIT path to git utility
TAP_CFLAGS C compiler flags for tap
- OPENSSL_CRYPTO_CFLAGS
- C compiler flags for OPENSSL_CRYPTO, overriding pkg-config
- OPENSSL_CRYPTO_LIBS
- linker flags for OPENSSL_CRYPTO, overriding pkg-config
- OPENSSL_SSL_CFLAGS
- C compiler flags for OPENSSL_SSL, overriding pkg-config
- OPENSSL_SSL_LIBS
- linker flags for OPENSSL_SSL, overriding pkg-config
+ OPENSSL_CFLAGS
+ C compiler flags for OpenSSL, overriding pkg-config
+ OPENSSL_LIBS
+ linker flags for OpenSSL, overriding pkg-config
POLARSSL_CFLAGS
C compiler flags for polarssl
POLARSSL_LIBS
@@ -313,13 +294,13 @@ TUN/TAP Driver Configuration:
http://www.whiteboard.ne.jp/~admin2/tuntap/
-* Windows XP/2003/Vista/7:
+* Windows
OpenVPN on Windows needs a TUN/TAP kernel driver to work. OpenVPN installers
include this driver, so installing it separately is not usually required.
- The driver source code is available here:
-
- https://github.com/OpenVPN/tap-windows
+ Windows XP/2003 must use the NDIS 5 (tap-windows) driver, whereas on more
+ recent Windows versions it is recommended to use the NDIS 6 driver
+ (tap-windows6) instead.
*************************************************************************
diff --git a/INSTALL-win32.txt b/INSTALL-win32.txt
deleted file mode 100644
index 7c05685..0000000
--- a/INSTALL-win32.txt
+++ /dev/null
@@ -1,77 +0,0 @@
-UPGRADING FROM 2.3-ALPHA1 AND EARLIER
-
-OpenVPN Windows installer went through major changes in
-2.3-alpha2. To avoid any unexpected behavior, it is strongly
-suggested to upgrade as follows.
-
-First backup configuration files and certificates from your
-current installation; by default they're in
-
- C:\Program Files\OpenVPN\config (32-bit Windows)
- C:\Program Files (x86)\OpenVPN\config (64-bit Windows)
-
-After this, stop the openvpn-gui or the openvpn service
-wrapper, if either of them is running and uninstall OpenVPN.
-Finally, remove the OpenVPN install directory entirely (e.g.
-using Windows Explorer as administrator).
-
-Finally, install the new version of OpenVPN and copy over
-your configuration files and certificates, which now go to
-
- C:\Program Files\OpenVPN\config
-
-provided you did not install the 32-bit version on 64-bit
-Windows.
-
-IMPORTANT NOTE FOR WINDOWS VISTA/7 USERS
-
-Note that on Windows Vista, you will need to run the OpenVPN
-GUI with administrator privileges, so that it can add routes
-to the routing table that are pulled from the OpenVPN server.
-You can do this by right-clicking on the OpenVPN GUI
-desktop icon, and selecting "Run as administrator".
-
-GENERAL QUICKSTART FOR WINDOWS
-
-The OpenVPN Client requires a configuration file
-and key/certificate files. You should obtain
-these and save them to OpenVPN's configuration
-directory, usually C:\Program Files\OpenVPN\config.
-
-You can run OpenVPN as a Windows system service or by using
-the client GUI. To use the OpenVPN GUI, double click on the
-desktop icon or start menu icon. The OpenVPN GUI is a
-system-tray applet, so an icon for the GUI will appear in
-the lower-right corner of the screen. Right click on the
-system tray icon, and a menu should appear showing the names
-of your OpenVPN configuration files, and giving you the
-option to connect.
-
-BUILDING OPENVPN FOR WINDOWS
-
-Official OpenVPN Windows releases are cross-compiled on Linux using the
-openvpn-build buildsystem:
-
- https://community.openvpn.net/openvpn/wiki/BuildingUsingGenericBuildsystem
-
-First setup the build environment as shown in the above article. Then fetch the
-openvpn-build repository:
-
- git clone https://github.com/OpenVPN/openvpn-build.git
-
-Review the build configuration:
-
- openvpn-build/generic/build.vars
- openvpn-build/windows-nsis/build-complete.vars
-
-Build (unsigned):
-
- cd openvpn-build/windows-nsis
- ./build-complete
-
-Build (signed):
-
- cd openvpn-build/windows-nsis
- ./build-complete --sign --sign-pkcs12=<pkcs12-file>\
- --sign-pkcs12-pass=<pkcs12-file-password> \
- --sign-timestamp="<timestamp-url>"
diff --git a/Makefile.am b/Makefile.am
index 93e21ba..8e9581b 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -54,7 +54,7 @@ BUILT_SOURCES = \
config-version.h
endif
-SUBDIRS = build distro include src sample doc tests
+SUBDIRS = build distro include src sample doc vendor tests
dist_doc_DATA = \
README \
@@ -66,7 +66,6 @@ dist_doc_DATA = \
dist_noinst_DATA = \
.gitignore \
.gitattributes \
- config-version.h.in \
PORTS \
README.IPv6 TODO.IPv6 \
README.polarssl \
@@ -75,12 +74,6 @@ dist_noinst_DATA = \
msvc-dev.bat \
msvc-build.bat
-if WIN32
-dist_doc_DATA += INSTALL-win32.txt
-else
-dist_noinst_DATA += INSTALL-win32.txt
-endif
-
dist_noinst_HEADERS = \
config-msvc.h \
config-msvc-version.h.in
@@ -91,8 +84,12 @@ root_DATA = version.sh
endif
config-version.h:
- @CONFIGURE_GIT_REVISION="`GIT_DIR=\"$(top_srcdir)/.git\" $(GIT) rev-parse --symbolic-full-name HEAD`/`GIT_DIR=\"$(top_srcdir)/.git\" $(GIT) rev-parse --short=16 HEAD`"; \
- $(SED) "s#@CONFIGURE_GIT_REVISION[@]#$${CONFIGURE_GIT_REVISION}#g" "$(srcdir)/config-version.h.in" > config-version.h.tmp
+ @CONFIGURE_GIT_CHFILES="`GIT_DIR=\"$(top_srcdir)/.git\" $(GIT) diff-files --name-status -r --ignore-submodules --quiet -- || echo \"+\"`"; \
+ CONFIGURE_GIT_UNCOMMITTED="`GIT_DIR=\"$(top_srcdir)/.git\" $(GIT) diff-index --cached --quiet --ignore-submodules HEAD || echo \"*\"`"; \
+ CONFIGURE_GIT_REVISION="`GIT_DIR=\"$(top_srcdir)/.git\" $(GIT) rev-parse --symbolic-full-name HEAD | cut -d/ -f3-`/`GIT_DIR=\"$(top_srcdir)/.git\" $(GIT) rev-parse --short=16 HEAD`"; \
+ echo "#define CONFIGURE_GIT_REVISION \"$${CONFIGURE_GIT_REVISION}\"" > config-version.h.tmp; \
+ echo "#define CONFIGURE_GIT_FLAGS \"$${CONFIGURE_GIT_CHFILES}$${CONFIGURE_GIT_UNCOMMITTED}\"" >> config-version.h.tmp
+
@if ! [ -f config-version.h ] || ! cmp -s config-version.h.tmp config-version.h; then \
echo "replacing config-version.h"; \
mv config-version.h.tmp config-version.h; \
diff --git a/Makefile.in b/Makefile.in
index 080c46e..8cb1c6e 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.15 from Makefile.am.
+# Makefile.in generated by automake 1.13.4 from Makefile.am.
# @configure_input@
-# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -42,17 +42,7 @@
VPATH = @srcdir@
-am__is_gnu_make = { \
- if test -z '$(MAKELEVEL)'; then \
- false; \
- elif test -n '$(MAKE_HOST)'; then \
- true; \
- elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
- true; \
- else \
- false; \
- fi; \
-}
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
am__make_running_with_option = \
case $${target_option-} in \
?) ;; \
@@ -115,9 +105,13 @@ PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
-@WIN32_TRUE@am__append_1 = INSTALL-win32.txt
-@WIN32_FALSE@am__append_2 = INSTALL-win32.txt
subdir = .
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+ $(top_srcdir)/configure $(am__configure_deps) \
+ $(srcdir)/config.h.in $(srcdir)/version.sh.in $(dist_doc_DATA) \
+ $(dist_noinst_DATA) $(dist_noinst_HEADERS) AUTHORS COPYING \
+ ChangeLog INSTALL NEWS README config.guess config.sub depcomp \
+ install-sh missing ltmain.sh
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/ax_emptyarray.m4 \
$(top_srcdir)/m4/ax_socklen_t.m4 \
@@ -128,14 +122,10 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_emptyarray.m4 \
$(top_srcdir)/compat.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
-DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \
- $(am__configure_deps) $(am__dist_doc_DATA_DIST) \
- $(am__dist_noinst_DATA_DIST) $(dist_noinst_HEADERS) \
- $(am__DIST_COMMON)
am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
configure.lineno config.status.lineno
mkinstalldirs = $(install_sh) -d
-CONFIG_HEADER = config.h
+CONFIG_HEADER = config.h $(top_builddir)/include/openvpn-plugin.h
CONFIG_CLEAN_FILES = version.sh
CONFIG_CLEAN_VPATH_FILES =
AM_V_P = $(am__v_P_@AM_V@)
@@ -165,8 +155,6 @@ am__can_run_installinfo = \
n|no|NO) false;; \
*) (install-info --version) >/dev/null 2>&1;; \
esac
-am__dist_doc_DATA_DIST = README README.IPv6 README.polarssl \
- COPYRIGHT.GPL COPYING INSTALL-win32.txt
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
am__vpath_adj = case $$p in \
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
@@ -195,10 +183,6 @@ am__uninstall_files_from_dir = { \
$(am__cd) "$$dir" && rm -f $$files; }; \
}
am__installdirs = "$(DESTDIR)$(docdir)" "$(DESTDIR)$(rootdir)"
-am__dist_noinst_DATA_DIST = .gitignore .gitattributes \
- config-version.h.in PORTS README.IPv6 TODO.IPv6 \
- README.polarssl openvpn.sln msvc-env.bat msvc-dev.bat \
- msvc-build.bat INSTALL-win32.txt
DATA = $(dist_doc_DATA) $(dist_noinst_DATA) $(root_DATA)
HEADERS = $(dist_noinst_HEADERS)
RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
@@ -231,10 +215,6 @@ ETAGS = etags
CTAGS = ctags
CSCOPE = cscope
DIST_SUBDIRS = $(SUBDIRS)
-am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/config.h.in \
- $(srcdir)/version.sh.in AUTHORS COPYING ChangeLog INSTALL NEWS \
- README compile config.guess config.sub depcomp install-sh \
- ltmain.sh missing
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
distdir = $(PACKAGE)-$(VERSION)
top_distdir = $(distdir)
@@ -289,6 +269,7 @@ AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
+CMAKE = @CMAKE@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
@@ -323,25 +304,31 @@ LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
-LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+LZ4_CFLAGS = @LZ4_CFLAGS@
+LZ4_LIBS = @LZ4_LIBS@
LZO_CFLAGS = @LZO_CFLAGS@
LZO_LIBS = @LZO_LIBS@
MAKEINFO = @MAKEINFO@
MAN2HTML = @MAN2HTML@
MANIFEST_TOOL = @MANIFEST_TOOL@
+MBEDTLS_CFLAGS = @MBEDTLS_CFLAGS@
+MBEDTLS_LIBS = @MBEDTLS_LIBS@
MKDIR_P = @MKDIR_P@
NETSTAT = @NETSTAT@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
-OPENSSL_CRYPTO_CFLAGS = @OPENSSL_CRYPTO_CFLAGS@
-OPENSSL_CRYPTO_LIBS = @OPENSSL_CRYPTO_LIBS@
-OPENSSL_SSL_CFLAGS = @OPENSSL_SSL_CFLAGS@
-OPENSSL_SSL_LIBS = @OPENSSL_SSL_LIBS@
+OPENSSL_CFLAGS = @OPENSSL_CFLAGS@
+OPENSSL_LIBS = @OPENSSL_LIBS@
+OPENVPN_VERSION_MAJOR = @OPENVPN_VERSION_MAJOR@
+OPENVPN_VERSION_MINOR = @OPENVPN_VERSION_MINOR@
+OPENVPN_VERSION_PATCH = @OPENVPN_VERSION_PATCH@
OPTIONAL_CRYPTO_CFLAGS = @OPTIONAL_CRYPTO_CFLAGS@
OPTIONAL_CRYPTO_LIBS = @OPTIONAL_CRYPTO_LIBS@
OPTIONAL_DL_LIBS = @OPTIONAL_DL_LIBS@
+OPTIONAL_LZ4_CFLAGS = @OPTIONAL_LZ4_CFLAGS@
+OPTIONAL_LZ4_LIBS = @OPTIONAL_LZ4_LIBS@
OPTIONAL_LZO_CFLAGS = @OPTIONAL_LZO_CFLAGS@
OPTIONAL_LZO_LIBS = @OPTIONAL_LZO_LIBS@
OPTIONAL_PKCS11_HELPER_CFLAGS = @OPTIONAL_PKCS11_HELPER_CFLAGS@
@@ -367,8 +354,6 @@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
PLUGIN_AUTH_PAM_CFLAGS = @PLUGIN_AUTH_PAM_CFLAGS@
PLUGIN_AUTH_PAM_LIBS = @PLUGIN_AUTH_PAM_LIBS@
-POLARSSL_CFLAGS = @POLARSSL_CFLAGS@
-POLARSSL_LIBS = @POLARSSL_LIBS@
RANLIB = @RANLIB@
RC = @RC@
ROUTE = @ROUTE@
@@ -383,6 +368,11 @@ TAP_CFLAGS = @TAP_CFLAGS@
TAP_WIN_COMPONENT_ID = @TAP_WIN_COMPONENT_ID@
TAP_WIN_MIN_MAJOR = @TAP_WIN_MIN_MAJOR@
TAP_WIN_MIN_MINOR = @TAP_WIN_MIN_MINOR@
+TEST_CFLAGS = @TEST_CFLAGS@
+TEST_LDFLAGS = @TEST_LDFLAGS@
+VENDOR_BUILD_ROOT = @VENDOR_BUILD_ROOT@
+VENDOR_DIST_ROOT = @VENDOR_DIST_ROOT@
+VENDOR_SRC_ROOT = @VENDOR_SRC_ROOT@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
@@ -466,12 +456,25 @@ EXTRA_DIST = \
@GIT_CHECKOUT_TRUE@BUILT_SOURCES = \
@GIT_CHECKOUT_TRUE@ config-version.h
-SUBDIRS = build distro include src sample doc tests
-dist_doc_DATA = README README.IPv6 README.polarssl COPYRIGHT.GPL \
- COPYING $(am__append_1)
-dist_noinst_DATA = .gitignore .gitattributes config-version.h.in PORTS \
- README.IPv6 TODO.IPv6 README.polarssl openvpn.sln msvc-env.bat \
- msvc-dev.bat msvc-build.bat $(am__append_2)
+SUBDIRS = build distro include src sample doc vendor tests
+dist_doc_DATA = \
+ README \
+ README.IPv6 \
+ README.polarssl \
+ COPYRIGHT.GPL \
+ COPYING
+
+dist_noinst_DATA = \
+ .gitignore \
+ .gitattributes \
+ PORTS \
+ README.IPv6 TODO.IPv6 \
+ README.polarssl \
+ openvpn.sln \
+ msvc-env.bat \
+ msvc-dev.bat \
+ msvc-build.bat
+
dist_noinst_HEADERS = \
config-msvc.h \
config-msvc-version.h.in
@@ -497,6 +500,7 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign Makefile
+.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
@@ -517,8 +521,8 @@ $(ACLOCAL_M4): $(am__aclocal_m4_deps)
$(am__aclocal_m4_deps):
config.h: stamp-h1
- @test -f $@ || rm -f stamp-h1
- @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1
+ @if test ! -f $@; then rm -f stamp-h1; else :; fi
+ @if test ! -f $@; then $(MAKE) $(AM_MAKEFLAGS) stamp-h1; else :; fi
stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status
@rm -f stamp-h1
@@ -771,16 +775,10 @@ dist-xz: distdir
$(am__post_remove_distdir)
dist-tarZ: distdir
- @echo WARNING: "Support for distribution archives compressed with" \
- "legacy program 'compress' is deprecated." >&2
- @echo WARNING: "It will be removed altogether in Automake 2.0" >&2
tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
$(am__post_remove_distdir)
dist-shar: distdir
- @echo WARNING: "Support for shar distribution archives is" \
- "deprecated." >&2
- @echo WARNING: "It will be removed altogether in Automake 2.0" >&2
shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
$(am__post_remove_distdir)
@@ -815,17 +813,16 @@ distcheck: dist
esac
chmod -R a-w $(distdir)
chmod u+w $(distdir)
- mkdir $(distdir)/_build $(distdir)/_build/sub $(distdir)/_inst
+ mkdir $(distdir)/_build $(distdir)/_inst
chmod a-w $(distdir)
test -d $(distdir)/_build || exit 0; \
dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
&& dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
&& am__cwd=`pwd` \
- && $(am__cd) $(distdir)/_build/sub \
- && ../../configure \
+ && $(am__cd) $(distdir)/_build \
+ && ../configure --srcdir=.. --prefix="$$dc_install_base" \
$(AM_DISTCHECK_CONFIGURE_FLAGS) \
$(DISTCHECK_CONFIGURE_FLAGS) \
- --srcdir=../.. --prefix="$$dc_install_base" \
&& $(MAKE) $(AM_MAKEFLAGS) \
&& $(MAKE) $(AM_MAKEFLAGS) dvi \
&& $(MAKE) $(AM_MAKEFLAGS) check \
@@ -1012,14 +1009,16 @@ uninstall-am: uninstall-dist_docDATA uninstall-rootDATA
tags tags-am uninstall uninstall-am uninstall-dist_docDATA \
uninstall-rootDATA
-.PRECIOUS: Makefile
-
.PHONY: config-version.h
config-version.h:
- @CONFIGURE_GIT_REVISION="`GIT_DIR=\"$(top_srcdir)/.git\" $(GIT) rev-parse --symbolic-full-name HEAD`/`GIT_DIR=\"$(top_srcdir)/.git\" $(GIT) rev-parse --short=16 HEAD`"; \
- $(SED) "s#@CONFIGURE_GIT_REVISION[@]#$${CONFIGURE_GIT_REVISION}#g" "$(srcdir)/config-version.h.in" > config-version.h.tmp
+ @CONFIGURE_GIT_CHFILES="`GIT_DIR=\"$(top_srcdir)/.git\" $(GIT) diff-files --name-status -r --ignore-submodules --quiet -- || echo \"+\"`"; \
+ CONFIGURE_GIT_UNCOMMITTED="`GIT_DIR=\"$(top_srcdir)/.git\" $(GIT) diff-index --cached --quiet --ignore-submodules HEAD || echo \"*\"`"; \
+ CONFIGURE_GIT_REVISION="`GIT_DIR=\"$(top_srcdir)/.git\" $(GIT) rev-parse --symbolic-full-name HEAD | cut -d/ -f3-`/`GIT_DIR=\"$(top_srcdir)/.git\" $(GIT) rev-parse --short=16 HEAD`"; \
+ echo "#define CONFIGURE_GIT_REVISION \"$${CONFIGURE_GIT_REVISION}\"" > config-version.h.tmp; \
+ echo "#define CONFIGURE_GIT_FLAGS \"$${CONFIGURE_GIT_CHFILES}$${CONFIGURE_GIT_UNCOMMITTED}\"" >> config-version.h.tmp
+
@if ! [ -f config-version.h ] || ! cmp -s config-version.h.tmp config-version.h; then \
echo "replacing config-version.h"; \
mv config-version.h.tmp config-version.h; \
diff --git a/README b/README
index 349e08a..103a75a 100644
--- a/README
+++ b/README
@@ -7,12 +7,14 @@ as published by the Free Software Foundation.
*************************************************************************
-For the latest version of OpenVPN, go to:
+To get the latest release of OpenVPN, go to:
- http://openvpn.net/
+ https://openvpn.net/index.php/download/community-downloads.html
To Build and Install,
+ tar -zxf openvpn-<version>.tar.gz
+ cd openvpn-<version>
./configure
make
make install
@@ -27,6 +29,9 @@ For detailed information on OpenVPN, including examples, see the man page
For a sample VPN configuration, see
http://openvpn.net/howto.html
+To report an issue, see
+ https://community.openvpn.net/openvpn/report
+
For a description of OpenVPN's underlying protocol,
see the file ssl.h included in the source distribution.
@@ -34,9 +39,6 @@ For a description of OpenVPN's underlying protocol,
Other Files & Directories:
-* INSTALL-win32.txt -- installation instructions
- for Windows
-
* configure.ac -- script to rebuild our configure
script and makefile.
diff --git a/README.IPv6 b/README.IPv6
index 56c97ab..18068fe 100644
--- a/README.IPv6
+++ b/README.IPv6
@@ -35,31 +35,22 @@ over an IPv6 network ("OpenVPN over IPv6").
The code in 2.3.0 supersedes the IPv6 transport patches from JuanJo Ciarlante,
formerly located at http://github.com/jjo/openvpn-ipv6
+OpenVPN 2.4.0 includes a big overhaul of the IPv6 transport patches
+originally implemented for the Android client (ics-openvpn)
-Use the following options to select IPv6 transport:
+IPv4/IPv6 transport is automatically is selected when resolving addresses.
+Use a 6 or 4 suffix to force IPv6/IPv4:
--proto udp6
+ --proto tcp4
--proto tcp6-client
- --proto tcp6-server
+ --proto tcp4-server
--proto tcp6 --client / --proto tcp6 --server
-On systems that permit IPv4 connections on IPv6 sockets (Linux by
-default, FreeBSD and NetBSD if you turn off the "v6only" sysctl by
-running "sysctl -w net.inet6.ip6.v6only=0"), an OpenVPN server can
+On systems that allow IPv4 connections on IPv6 sockets
+(all systems supporting IPV6_V6ONLY setsockopt), an OpenVPN server can
handle IPv4 connections on the IPv6 socket as well, making it a true
-dual-stacked server.
+dual-stacked server. Use bind ipv6only to disable this behaviour.
On other systems, as of 2.3.0, you need to run separate server instances
for IPv4 and IPv6.
-
-The client side code is not really "dual-stacked" yet, as it does not
-automatically try both address families when connecting to a dual-stacked
-server. For now, you can achieve this with <connection> stanzas in your
-openvpn config:
-
- <connection>
- remote my.dual.stack.server 1194 udp6
- </connection>
- <connection>
- remote my.dual.stack.server 1194 udp
- </connection>
diff --git a/README.polarssl b/README.polarssl
index d34d44a..6f1fa51 100644
--- a/README.polarssl
+++ b/README.polarssl
@@ -7,7 +7,7 @@ To Build and Install,
make
make install
-This version depends on PolarSSL 1.3 (and requires at least 1.3.8).
+This version depends on PolarSSL 1.3 (and requires at least 1.3.3).
*************************************************************************
diff --git a/TODO.IPv6 b/TODO.IPv6
index 29d7554..24bf865 100644
--- a/TODO.IPv6
+++ b/TODO.IPv6
@@ -183,7 +183,7 @@ tun0: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> mtu 1500
TODO for IPv6 transport support
-------------------------------
-[ Last updated: 10-Jun-2012. ]
+[ Last updated: 2014-01-03. ]
* All platforms:
o mgmt console: as currently passes straight in_addr_t bits around
@@ -191,19 +191,25 @@ TODO for IPv6 transport support
o make possible to get AF from getaddrinfo() answer, ie allow openvpn to
use ipv4/6 if DNS returns A/AAAA without specifying protocol.
Hard: requires deep changes in initialization/calling logic
+ - Done by dual stack patches
o use AI_PASSIVE
+ - Done by dual stack patches
o the getaddr()/getaddr6() interface is not prepared for handling socktype
"tagging", currently I abuse the sockflags bits for getting the ai_socktype
downstream.
+ - Still done by flags, seems clean enough.
o implement comparison for mapped addesses: server in dual stack
listening IPv6 must permit incoming streams from allowed IPv4 peer,
currently you need to pass eg: --remote ffff::1.2.3.4
-
+ - OpenVPN will compare all address of a remote
+ but will still fail on mapped addresses
* win32:
o find out about mapped addresses, as I can't make it work
with bound at ::1 and connect to 127.0.0.1
+ - Should be fixed by 8832c6c - "Implement listing on IPv4/IPv6 dual
+ socket on all platform"
diff --git a/aclocal.m4 b/aclocal.m4
index 863dad6..4f1bb12 100644
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -1,6 +1,6 @@
-# generated automatically by aclocal 1.15 -*- Autoconf -*-
+# generated automatically by aclocal 1.13.4 -*- Autoconf -*-
-# Copyright (C) 1996-2014 Free Software Foundation, Inc.
+# Copyright (C) 1996-2013 Free Software Foundation, Inc.
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -20,7 +20,7 @@ You have another version of autoconf. It may work, but is not guaranteed to.
If you have problems, you may need to regenerate the build system entirely.
To do so, use the procedure documented by the package, typically 'autoreconf'.])])
-# Copyright (C) 2002-2014 Free Software Foundation, Inc.
+# Copyright (C) 2002-2013 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -32,10 +32,10 @@ To do so, use the procedure documented by the package, typically 'autoreconf'.])
# generated from the m4 files accompanying Automake X.Y.
# (This private macro should not be called outside this file.)
AC_DEFUN([AM_AUTOMAKE_VERSION],
-[am__api_version='1.15'
+[am__api_version='1.13'
dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
dnl require some minimum version. Point them to the right macro.
-m4_if([$1], [1.15], [],
+m4_if([$1], [1.13.4], [],
[AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
])
@@ -51,14 +51,14 @@ m4_define([_AM_AUTOCONF_VERSION], [])
# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
# This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
-[AM_AUTOMAKE_VERSION([1.15])dnl
+[AM_AUTOMAKE_VERSION([1.13.4])dnl
m4_ifndef([AC_AUTOCONF_VERSION],
[m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
# AM_AUX_DIR_EXPAND -*- Autoconf -*-
-# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+# Copyright (C) 2001-2013 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -103,14 +103,15 @@ _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
# configured tree to be moved without reconfiguration.
AC_DEFUN([AM_AUX_DIR_EXPAND],
-[AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl
-# Expand $ac_aux_dir to an absolute path.
-am_aux_dir=`cd "$ac_aux_dir" && pwd`
+[dnl Rely on autoconf to set up CDPATH properly.
+AC_PREREQ([2.50])dnl
+# expand $ac_aux_dir to an absolute path
+am_aux_dir=`cd $ac_aux_dir && pwd`
])
# AM_CONDITIONAL -*- Autoconf -*-
-# Copyright (C) 1997-2014 Free Software Foundation, Inc.
+# Copyright (C) 1997-2013 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -141,7 +142,7 @@ AC_CONFIG_COMMANDS_PRE(
Usually this means the macro was only invoked conditionally.]])
fi])])
-# Copyright (C) 1999-2014 Free Software Foundation, Inc.
+# Copyright (C) 1999-2013 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -332,7 +333,7 @@ _AM_SUBST_NOTMAKE([am__nodep])dnl
# Generate code to set up dependency tracking. -*- Autoconf -*-
-# Copyright (C) 1999-2014 Free Software Foundation, Inc.
+# Copyright (C) 1999-2013 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -408,7 +409,7 @@ AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
# Do all the work for Automake. -*- Autoconf -*-
-# Copyright (C) 1996-2014 Free Software Foundation, Inc.
+# Copyright (C) 1996-2013 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -417,12 +418,6 @@ AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
# This macro actually does too much. Some checks are only needed if
# your package does certain things. But this isn't really a big deal.
-dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O.
-m4_define([AC_PROG_CC],
-m4_defn([AC_PROG_CC])
-[_AM_PROG_CC_C_O
-])
-
# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
# AM_INIT_AUTOMAKE([OPTIONS])
# -----------------------------------------------
@@ -498,8 +493,8 @@ AC_REQUIRE([AC_PROG_MKDIR_P])dnl
# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
AC_SUBST([mkdir_p], ['$(MKDIR_P)'])
-# We need awk for the "check" target (and possibly the TAP driver). The
-# system "awk" is bad on some platforms.
+# We need awk for the "check" target. The system "awk" is bad on
+# some platforms.
AC_REQUIRE([AC_PROG_AWK])dnl
AC_REQUIRE([AC_PROG_MAKE_SET])dnl
AC_REQUIRE([AM_SET_LEADING_DOT])dnl
@@ -531,51 +526,6 @@ dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below.
AC_CONFIG_COMMANDS_PRE(dnl
[m4_provide_if([_AM_COMPILER_EXEEXT],
[AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl
-
-# POSIX will say in a future version that running "rm -f" with no argument
-# is OK; and we want to be able to make that assumption in our Makefile
-# recipes. So use an aggressive probe to check that the usage we want is
-# actually supported "in the wild" to an acceptable degree.
-# See automake bug#10828.
-# To make any issue more visible, cause the running configure to be aborted
-# by default if the 'rm' program in use doesn't match our expectations; the
-# user can still override this though.
-if rm -f && rm -fr && rm -rf; then : OK; else
- cat >&2 <<'END'
-Oops!
-
-Your 'rm' program seems unable to run without file operands specified
-on the command line, even when the '-f' option is present. This is contrary
-to the behaviour of most rm programs out there, and not conforming with
-the upcoming POSIX standard: <http://austingroupbugs.net/view.php?id=542>
-
-Please tell bug-automake@gnu.org about your system, including the value
-of your $PATH and any error possibly output before this message. This
-can help us improve future automake versions.
-
-END
- if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then
- echo 'Configuration will proceed anyway, since you have set the' >&2
- echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2
- echo >&2
- else
- cat >&2 <<'END'
-Aborting the configuration process, to ensure you take notice of the issue.
-
-You can download and install GNU coreutils to get an 'rm' implementation
-that behaves properly: <http://www.gnu.org/software/coreutils/>.
-
-If you want to complete the configuration process using your problematic
-'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM
-to "yes", and re-run configure.
-
-END
- AC_MSG_ERROR([Your 'rm' program is bad, sorry.])
- fi
-fi
-dnl The trailing newline in this macro's definition is deliberate, for
-dnl backward compatibility and to allow trailing 'dnl'-style comments
-dnl after the AM_INIT_AUTOMAKE invocation. See automake bug#16841.
])
dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not
@@ -584,6 +534,7 @@ dnl mangled by Autoconf and run in a shell conditional statement.
m4_define([_AC_COMPILER_EXEEXT],
m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])])
+
# When config.status generates a header, we must update the stamp-h file.
# This file resides in the same directory as the config header
# that is generated. The stamp files are numbered to have different names.
@@ -605,7 +556,7 @@ for _am_header in $config_headers :; do
done
echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
-# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+# Copyright (C) 2001-2013 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -616,7 +567,7 @@ echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_co
# Define $install_sh.
AC_DEFUN([AM_PROG_INSTALL_SH],
[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
-if test x"${install_sh+set}" != xset; then
+if test x"${install_sh}" != xset; then
case $am_aux_dir in
*\ * | *\ *)
install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
@@ -626,7 +577,7 @@ if test x"${install_sh+set}" != xset; then
fi
AC_SUBST([install_sh])])
-# Copyright (C) 2003-2014 Free Software Foundation, Inc.
+# Copyright (C) 2003-2013 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -647,7 +598,7 @@ AC_SUBST([am__leading_dot])])
# Check to see how 'make' treats includes. -*- Autoconf -*-
-# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+# Copyright (C) 2001-2013 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -697,7 +648,7 @@ rm -f confinc confmf
# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*-
-# Copyright (C) 1997-2014 Free Software Foundation, Inc.
+# Copyright (C) 1997-2013 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -736,7 +687,7 @@ fi
# Helper functions for option handling. -*- Autoconf -*-
-# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+# Copyright (C) 2001-2013 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -765,73 +716,9 @@ AC_DEFUN([_AM_SET_OPTIONS],
AC_DEFUN([_AM_IF_OPTION],
[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
-# Copyright (C) 1999-2014 Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# _AM_PROG_CC_C_O
-# ---------------
-# Like AC_PROG_CC_C_O, but changed for automake. We rewrite AC_PROG_CC
-# to automatically call this.
-AC_DEFUN([_AM_PROG_CC_C_O],
-[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
-AC_REQUIRE_AUX_FILE([compile])dnl
-AC_LANG_PUSH([C])dnl
-AC_CACHE_CHECK(
- [whether $CC understands -c and -o together],
- [am_cv_prog_cc_c_o],
- [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])])
- # Make sure it works both with $CC and with simple cc.
- # Following AC_PROG_CC_C_O, we do the test twice because some
- # compilers refuse to overwrite an existing .o file with -o,
- # though they will create one.
- am_cv_prog_cc_c_o=yes
- for am_i in 1 2; do
- if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \
- && test -f conftest2.$ac_objext; then
- : OK
- else
- am_cv_prog_cc_c_o=no
- break
- fi
- done
- rm -f core conftest*
- unset am_i])
-if test "$am_cv_prog_cc_c_o" != yes; then
- # Losing compiler, so override with the script.
- # FIXME: It is wrong to rewrite CC.
- # But if we don't then we get into trouble of one sort or another.
- # A longer-term fix would be to have automake use am__CC in this case,
- # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
- CC="$am_aux_dir/compile $CC"
-fi
-AC_LANG_POP([C])])
-
-# For backward compatibility.
-AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])])
-
-# Copyright (C) 2001-2014 Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# AM_RUN_LOG(COMMAND)
-# -------------------
-# Run COMMAND, save the exit status in ac_status, and log it.
-# (This has been adapted from Autoconf's _AC_RUN_LOG macro.)
-AC_DEFUN([AM_RUN_LOG],
-[{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD
- ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
- (exit $ac_status); }])
-
# Check to make sure that the build environment is sane. -*- Autoconf -*-
-# Copyright (C) 1996-2014 Free Software Foundation, Inc.
+# Copyright (C) 1996-2013 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -912,7 +799,7 @@ AC_CONFIG_COMMANDS_PRE(
rm -f conftest.file
])
-# Copyright (C) 2009-2014 Free Software Foundation, Inc.
+# Copyright (C) 2009-2013 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -972,7 +859,7 @@ AC_SUBST([AM_BACKSLASH])dnl
_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl
])
-# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+# Copyright (C) 2001-2013 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -1000,7 +887,7 @@ fi
INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
AC_SUBST([INSTALL_STRIP_PROGRAM])])
-# Copyright (C) 2006-2014 Free Software Foundation, Inc.
+# Copyright (C) 2006-2013 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -1019,7 +906,7 @@ AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
# Check how to create a tarball. -*- Autoconf -*-
-# Copyright (C) 2004-2014 Free Software Foundation, Inc.
+# Copyright (C) 2004-2013 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
diff --git a/build/Makefile.in b/build/Makefile.in
index 8c35125..2127ae8 100644
--- a/build/Makefile.in
+++ b/build/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.15 from Makefile.am.
+# Makefile.in generated by automake 1.13.4 from Makefile.am.
# @configure_input@
-# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -24,17 +24,7 @@
# Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net>
#
VPATH = @srcdir@
-am__is_gnu_make = { \
- if test -z '$(MAKELEVEL)'; then \
- false; \
- elif test -n '$(MAKE_HOST)'; then \
- true; \
- elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
- true; \
- else \
- false; \
- fi; \
-}
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
am__make_running_with_option = \
case $${target_option-} in \
?) ;; \
@@ -98,6 +88,7 @@ POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
subdir = build
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/ax_emptyarray.m4 \
$(top_srcdir)/m4/ax_socklen_t.m4 \
@@ -108,9 +99,9 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_emptyarray.m4 \
$(top_srcdir)/compat.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
-DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
mkinstalldirs = $(install_sh) -d
-CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_HEADER = $(top_builddir)/config.h \
+ $(top_builddir)/include/openvpn-plugin.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
AM_V_P = $(am__v_P_@AM_V@)
@@ -168,7 +159,6 @@ am__define_uniq_tagged_files = \
ETAGS = etags
CTAGS = ctags
DIST_SUBDIRS = $(SUBDIRS)
-am__DIST_COMMON = $(srcdir)/Makefile.in
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
am__relativize = \
dir0=`pwd`; \
@@ -207,6 +197,7 @@ AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
+CMAKE = @CMAKE@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
@@ -241,25 +232,31 @@ LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
-LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+LZ4_CFLAGS = @LZ4_CFLAGS@
+LZ4_LIBS = @LZ4_LIBS@
LZO_CFLAGS = @LZO_CFLAGS@
LZO_LIBS = @LZO_LIBS@
MAKEINFO = @MAKEINFO@
MAN2HTML = @MAN2HTML@
MANIFEST_TOOL = @MANIFEST_TOOL@
+MBEDTLS_CFLAGS = @MBEDTLS_CFLAGS@
+MBEDTLS_LIBS = @MBEDTLS_LIBS@
MKDIR_P = @MKDIR_P@
NETSTAT = @NETSTAT@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
-OPENSSL_CRYPTO_CFLAGS = @OPENSSL_CRYPTO_CFLAGS@
-OPENSSL_CRYPTO_LIBS = @OPENSSL_CRYPTO_LIBS@
-OPENSSL_SSL_CFLAGS = @OPENSSL_SSL_CFLAGS@
-OPENSSL_SSL_LIBS = @OPENSSL_SSL_LIBS@
+OPENSSL_CFLAGS = @OPENSSL_CFLAGS@
+OPENSSL_LIBS = @OPENSSL_LIBS@
+OPENVPN_VERSION_MAJOR = @OPENVPN_VERSION_MAJOR@
+OPENVPN_VERSION_MINOR = @OPENVPN_VERSION_MINOR@
+OPENVPN_VERSION_PATCH = @OPENVPN_VERSION_PATCH@
OPTIONAL_CRYPTO_CFLAGS = @OPTIONAL_CRYPTO_CFLAGS@
OPTIONAL_CRYPTO_LIBS = @OPTIONAL_CRYPTO_LIBS@
OPTIONAL_DL_LIBS = @OPTIONAL_DL_LIBS@
+OPTIONAL_LZ4_CFLAGS = @OPTIONAL_LZ4_CFLAGS@
+OPTIONAL_LZ4_LIBS = @OPTIONAL_LZ4_LIBS@
OPTIONAL_LZO_CFLAGS = @OPTIONAL_LZO_CFLAGS@
OPTIONAL_LZO_LIBS = @OPTIONAL_LZO_LIBS@
OPTIONAL_PKCS11_HELPER_CFLAGS = @OPTIONAL_PKCS11_HELPER_CFLAGS@
@@ -285,8 +282,6 @@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
PLUGIN_AUTH_PAM_CFLAGS = @PLUGIN_AUTH_PAM_CFLAGS@
PLUGIN_AUTH_PAM_LIBS = @PLUGIN_AUTH_PAM_LIBS@
-POLARSSL_CFLAGS = @POLARSSL_CFLAGS@
-POLARSSL_LIBS = @POLARSSL_LIBS@
RANLIB = @RANLIB@
RC = @RC@
ROUTE = @ROUTE@
@@ -301,6 +296,11 @@ TAP_CFLAGS = @TAP_CFLAGS@
TAP_WIN_COMPONENT_ID = @TAP_WIN_COMPONENT_ID@
TAP_WIN_MIN_MAJOR = @TAP_WIN_MIN_MAJOR@
TAP_WIN_MIN_MINOR = @TAP_WIN_MIN_MINOR@
+TEST_CFLAGS = @TEST_CFLAGS@
+TEST_LDFLAGS = @TEST_LDFLAGS@
+VENDOR_BUILD_ROOT = @VENDOR_BUILD_ROOT@
+VENDOR_DIST_ROOT = @VENDOR_DIST_ROOT@
+VENDOR_SRC_ROOT = @VENDOR_SRC_ROOT@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
@@ -380,6 +380,7 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign build/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign build/Makefile
+.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
@@ -675,8 +676,6 @@ uninstall-am:
mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
ps ps-am tags tags-am uninstall uninstall-am
-.PRECIOUS: Makefile
-
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
diff --git a/build/msvc/Makefile.in b/build/msvc/Makefile.in
index 31b72e7..e4a9303 100644
--- a/build/msvc/Makefile.in
+++ b/build/msvc/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.15 from Makefile.am.
+# Makefile.in generated by automake 1.13.4 from Makefile.am.
# @configure_input@
-# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -25,17 +25,7 @@
# Copyright (C) 2006-2012 Alon Bar-Lev <alon.barlev@gmail.com>
#
VPATH = @srcdir@
-am__is_gnu_make = { \
- if test -z '$(MAKELEVEL)'; then \
- false; \
- elif test -n '$(MAKE_HOST)'; then \
- true; \
- elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
- true; \
- else \
- false; \
- fi; \
-}
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
am__make_running_with_option = \
case $${target_option-} in \
?) ;; \
@@ -99,6 +89,7 @@ POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
subdir = build/msvc
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/ax_emptyarray.m4 \
$(top_srcdir)/m4/ax_socklen_t.m4 \
@@ -109,9 +100,9 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_emptyarray.m4 \
$(top_srcdir)/compat.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
-DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
mkinstalldirs = $(install_sh) -d
-CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_HEADER = $(top_builddir)/config.h \
+ $(top_builddir)/include/openvpn-plugin.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
AM_V_P = $(am__v_P_@AM_V@)
@@ -169,7 +160,6 @@ am__define_uniq_tagged_files = \
ETAGS = etags
CTAGS = ctags
DIST_SUBDIRS = $(SUBDIRS)
-am__DIST_COMMON = $(srcdir)/Makefile.in
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
am__relativize = \
dir0=`pwd`; \
@@ -208,6 +198,7 @@ AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
+CMAKE = @CMAKE@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
@@ -242,25 +233,31 @@ LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
-LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+LZ4_CFLAGS = @LZ4_CFLAGS@
+LZ4_LIBS = @LZ4_LIBS@
LZO_CFLAGS = @LZO_CFLAGS@
LZO_LIBS = @LZO_LIBS@
MAKEINFO = @MAKEINFO@
MAN2HTML = @MAN2HTML@
MANIFEST_TOOL = @MANIFEST_TOOL@
+MBEDTLS_CFLAGS = @MBEDTLS_CFLAGS@
+MBEDTLS_LIBS = @MBEDTLS_LIBS@
MKDIR_P = @MKDIR_P@
NETSTAT = @NETSTAT@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
-OPENSSL_CRYPTO_CFLAGS = @OPENSSL_CRYPTO_CFLAGS@
-OPENSSL_CRYPTO_LIBS = @OPENSSL_CRYPTO_LIBS@
-OPENSSL_SSL_CFLAGS = @OPENSSL_SSL_CFLAGS@
-OPENSSL_SSL_LIBS = @OPENSSL_SSL_LIBS@
+OPENSSL_CFLAGS = @OPENSSL_CFLAGS@
+OPENSSL_LIBS = @OPENSSL_LIBS@
+OPENVPN_VERSION_MAJOR = @OPENVPN_VERSION_MAJOR@
+OPENVPN_VERSION_MINOR = @OPENVPN_VERSION_MINOR@
+OPENVPN_VERSION_PATCH = @OPENVPN_VERSION_PATCH@
OPTIONAL_CRYPTO_CFLAGS = @OPTIONAL_CRYPTO_CFLAGS@
OPTIONAL_CRYPTO_LIBS = @OPTIONAL_CRYPTO_LIBS@
OPTIONAL_DL_LIBS = @OPTIONAL_DL_LIBS@
+OPTIONAL_LZ4_CFLAGS = @OPTIONAL_LZ4_CFLAGS@
+OPTIONAL_LZ4_LIBS = @OPTIONAL_LZ4_LIBS@
OPTIONAL_LZO_CFLAGS = @OPTIONAL_LZO_CFLAGS@
OPTIONAL_LZO_LIBS = @OPTIONAL_LZO_LIBS@
OPTIONAL_PKCS11_HELPER_CFLAGS = @OPTIONAL_PKCS11_HELPER_CFLAGS@
@@ -286,8 +283,6 @@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
PLUGIN_AUTH_PAM_CFLAGS = @PLUGIN_AUTH_PAM_CFLAGS@
PLUGIN_AUTH_PAM_LIBS = @PLUGIN_AUTH_PAM_LIBS@
-POLARSSL_CFLAGS = @POLARSSL_CFLAGS@
-POLARSSL_LIBS = @POLARSSL_LIBS@
RANLIB = @RANLIB@
RC = @RC@
ROUTE = @ROUTE@
@@ -302,6 +297,11 @@ TAP_CFLAGS = @TAP_CFLAGS@
TAP_WIN_COMPONENT_ID = @TAP_WIN_COMPONENT_ID@
TAP_WIN_MIN_MAJOR = @TAP_WIN_MIN_MAJOR@
TAP_WIN_MIN_MINOR = @TAP_WIN_MIN_MINOR@
+TEST_CFLAGS = @TEST_CFLAGS@
+TEST_LDFLAGS = @TEST_LDFLAGS@
+VENDOR_BUILD_ROOT = @VENDOR_BUILD_ROOT@
+VENDOR_DIST_ROOT = @VENDOR_DIST_ROOT@
+VENDOR_SRC_ROOT = @VENDOR_SRC_ROOT@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
@@ -378,6 +378,7 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign build/msvc/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign build/msvc/Makefile
+.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
@@ -673,8 +674,6 @@ uninstall-am:
mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
ps ps-am tags tags-am uninstall uninstall-am
-.PRECIOUS: Makefile
-
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
diff --git a/build/msvc/msvc-generate/Makefile.in b/build/msvc/msvc-generate/Makefile.in
index ab3b358..54a8e19 100644
--- a/build/msvc/msvc-generate/Makefile.in
+++ b/build/msvc/msvc-generate/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.15 from Makefile.am.
+# Makefile.in generated by automake 1.13.4 from Makefile.am.
# @configure_input@
-# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -26,17 +26,7 @@
#
VPATH = @srcdir@
-am__is_gnu_make = { \
- if test -z '$(MAKELEVEL)'; then \
- false; \
- elif test -n '$(MAKE_HOST)'; then \
- true; \
- elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
- true; \
- else \
- false; \
- fi; \
-}
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
am__make_running_with_option = \
case $${target_option-} in \
?) ;; \
@@ -100,6 +90,8 @@ POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
subdir = build/msvc/msvc-generate
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+ $(dist_noinst_DATA)
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/ax_emptyarray.m4 \
$(top_srcdir)/m4/ax_socklen_t.m4 \
@@ -110,10 +102,9 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_emptyarray.m4 \
$(top_srcdir)/compat.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
-DIST_COMMON = $(srcdir)/Makefile.am $(dist_noinst_DATA) \
- $(am__DIST_COMMON)
mkinstalldirs = $(install_sh) -d
-CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_HEADER = $(top_builddir)/config.h \
+ $(top_builddir)/include/openvpn-plugin.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
AM_V_P = $(am__v_P_@AM_V@)
@@ -137,7 +128,6 @@ am__can_run_installinfo = \
esac
DATA = $(dist_noinst_DATA)
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
-am__DIST_COMMON = $(srcdir)/Makefile.in
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
@@ -151,6 +141,7 @@ AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
+CMAKE = @CMAKE@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
@@ -185,25 +176,31 @@ LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
-LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+LZ4_CFLAGS = @LZ4_CFLAGS@
+LZ4_LIBS = @LZ4_LIBS@
LZO_CFLAGS = @LZO_CFLAGS@
LZO_LIBS = @LZO_LIBS@
MAKEINFO = @MAKEINFO@
MAN2HTML = @MAN2HTML@
MANIFEST_TOOL = @MANIFEST_TOOL@
+MBEDTLS_CFLAGS = @MBEDTLS_CFLAGS@
+MBEDTLS_LIBS = @MBEDTLS_LIBS@
MKDIR_P = @MKDIR_P@
NETSTAT = @NETSTAT@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
-OPENSSL_CRYPTO_CFLAGS = @OPENSSL_CRYPTO_CFLAGS@
-OPENSSL_CRYPTO_LIBS = @OPENSSL_CRYPTO_LIBS@
-OPENSSL_SSL_CFLAGS = @OPENSSL_SSL_CFLAGS@
-OPENSSL_SSL_LIBS = @OPENSSL_SSL_LIBS@
+OPENSSL_CFLAGS = @OPENSSL_CFLAGS@
+OPENSSL_LIBS = @OPENSSL_LIBS@
+OPENVPN_VERSION_MAJOR = @OPENVPN_VERSION_MAJOR@
+OPENVPN_VERSION_MINOR = @OPENVPN_VERSION_MINOR@
+OPENVPN_VERSION_PATCH = @OPENVPN_VERSION_PATCH@
OPTIONAL_CRYPTO_CFLAGS = @OPTIONAL_CRYPTO_CFLAGS@
OPTIONAL_CRYPTO_LIBS = @OPTIONAL_CRYPTO_LIBS@
OPTIONAL_DL_LIBS = @OPTIONAL_DL_LIBS@
+OPTIONAL_LZ4_CFLAGS = @OPTIONAL_LZ4_CFLAGS@
+OPTIONAL_LZ4_LIBS = @OPTIONAL_LZ4_LIBS@
OPTIONAL_LZO_CFLAGS = @OPTIONAL_LZO_CFLAGS@
OPTIONAL_LZO_LIBS = @OPTIONAL_LZO_LIBS@
OPTIONAL_PKCS11_HELPER_CFLAGS = @OPTIONAL_PKCS11_HELPER_CFLAGS@
@@ -229,8 +226,6 @@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
PLUGIN_AUTH_PAM_CFLAGS = @PLUGIN_AUTH_PAM_CFLAGS@
PLUGIN_AUTH_PAM_LIBS = @PLUGIN_AUTH_PAM_LIBS@
-POLARSSL_CFLAGS = @POLARSSL_CFLAGS@
-POLARSSL_LIBS = @POLARSSL_LIBS@
RANLIB = @RANLIB@
RC = @RC@
ROUTE = @ROUTE@
@@ -245,6 +240,11 @@ TAP_CFLAGS = @TAP_CFLAGS@
TAP_WIN_COMPONENT_ID = @TAP_WIN_COMPONENT_ID@
TAP_WIN_MIN_MAJOR = @TAP_WIN_MIN_MAJOR@
TAP_WIN_MIN_MINOR = @TAP_WIN_MIN_MINOR@
+TEST_CFLAGS = @TEST_CFLAGS@
+TEST_LDFLAGS = @TEST_LDFLAGS@
+VENDOR_BUILD_ROOT = @VENDOR_BUILD_ROOT@
+VENDOR_DIST_ROOT = @VENDOR_DIST_ROOT@
+VENDOR_SRC_ROOT = @VENDOR_SRC_ROOT@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
@@ -325,6 +325,7 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign build/msvc/msvc-generate/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign build/msvc/msvc-generate/Makefile
+.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
@@ -500,8 +501,6 @@ uninstall-am:
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
tags-am uninstall uninstall-am
-.PRECIOUS: Makefile
-
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
diff --git a/build/msvc/msvc-generate/Makefile.mak b/build/msvc/msvc-generate/Makefile.mak
index 72415f1..59fc9f0 100755..100644
--- a/build/msvc/msvc-generate/Makefile.mak
+++ b/build/msvc/msvc-generate/Makefile.mak
@@ -1,13 +1,28 @@
# Copyright (C) 2008-2012 Alon Bar-Lev <alon.barlev@gmail.com>
CONFIG=$(SOURCEBASE)/version.m4
-INPUT=$(SOURCEBASE)/config-msvc-version.h.in
-OUTPUT=$(SOURCEBASE)/config-msvc-version.h
-all: $(OUTPUT)
+INPUT_MSVC_VER=$(SOURCEBASE)/config-msvc-version.h.in
+OUTPUT_MSVC_VER=$(SOURCEBASE)/config-msvc-version.h
-$(OUTPUT): $(INPUT) $(CONFIG)
- cscript //nologo msvc-generate.js --config="$(CONFIG)" --input="$(INPUT)" --output="$(OUTPUT)"
+INPUT_PLUGIN=$(SOURCEBASE)/include/openvpn-plugin.h.in
+OUTPUT_PLUGIN=$(SOURCEBASE)/include/openvpn-plugin.h
+
+INPUT_PLUGIN_CONFIG=version.m4.in
+OUTPUT_PLUGIN_CONFIG=version.m4
+
+all: $(OUTPUT_MSVC_VER) $(OUTPUT_PLUGIN)
+
+$(OUTPUT_MSVC_VER): $(INPUT_MSVC_VER) $(CONFIG)
+ cscript //nologo msvc-generate.js --config="$(CONFIG)" --input="$(INPUT_MSVC_VER)" --output="$(OUTPUT_MSVC_VER)"
+
+$(OUTPUT_PLUGIN_CONFIG): $(INPUT_PLUGIN_CONFIG)
+ cscript //nologo msvc-generate.js --config="$(CONFIG)" --input="$(INPUT_PLUGIN_CONFIG)" --output="$(OUTPUT_PLUGIN_CONFIG)"
+
+$(OUTPUT_PLUGIN): $(INPUT_PLUGIN) $(OUTPUT_PLUGIN_CONFIG)
+ cscript //nologo msvc-generate.js --config="$(OUTPUT_PLUGIN_CONFIG)" --input="$(INPUT_PLUGIN)" --output="$(OUTPUT_PLUGIN)"
clean:
- -del "$(OUTPUT)"
+ -del "$(OUTPUT_MSVC_VER)"
+ -del "$(OUTPUT_PLUGIN)"
+ -del "$(OUTPUT_PLUGIN_CONFIG)"
diff --git a/compile b/compile
deleted file mode 100755
index 531136b..0000000
--- a/compile
+++ /dev/null
@@ -1,347 +0,0 @@
-#! /bin/sh
-# Wrapper for compilers which do not understand '-c -o'.
-
-scriptversion=2012-10-14.11; # UTC
-
-# Copyright (C) 1999-2013 Free Software Foundation, Inc.
-# Written by Tom Tromey <tromey@cygnus.com>.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2, or (at your option)
-# any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-# As a special exception to the GNU General Public License, if you
-# distribute this file as part of a program that contains a
-# configuration script generated by Autoconf, you may include it under
-# the same distribution terms that you use for the rest of that program.
-
-# This file is maintained in Automake, please report
-# bugs to <bug-automake@gnu.org> or send patches to
-# <automake-patches@gnu.org>.
-
-nl='
-'
-
-# We need space, tab and new line, in precisely that order. Quoting is
-# there to prevent tools from complaining about whitespace usage.
-IFS=" "" $nl"
-
-file_conv=
-
-# func_file_conv build_file lazy
-# Convert a $build file to $host form and store it in $file
-# Currently only supports Windows hosts. If the determined conversion
-# type is listed in (the comma separated) LAZY, no conversion will
-# take place.
-func_file_conv ()
-{
- file=$1
- case $file in
- / | /[!/]*) # absolute file, and not a UNC file
- if test -z "$file_conv"; then
- # lazily determine how to convert abs files
- case `uname -s` in
- MINGW*)
- file_conv=mingw
- ;;
- CYGWIN*)
- file_conv=cygwin
- ;;
- *)
- file_conv=wine
- ;;
- esac
- fi
- case $file_conv/,$2, in
- *,$file_conv,*)
- ;;
- mingw/*)
- file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'`
- ;;
- cygwin/*)
- file=`cygpath -m "$file" || echo "$file"`
- ;;
- wine/*)
- file=`winepath -w "$file" || echo "$file"`
- ;;
- esac
- ;;
- esac
-}
-
-# func_cl_dashL linkdir
-# Make cl look for libraries in LINKDIR
-func_cl_dashL ()
-{
- func_file_conv "$1"
- if test -z "$lib_path"; then
- lib_path=$file
- else
- lib_path="$lib_path;$file"
- fi
- linker_opts="$linker_opts -LIBPATH:$file"
-}
-
-# func_cl_dashl library
-# Do a library search-path lookup for cl
-func_cl_dashl ()
-{
- lib=$1
- found=no
- save_IFS=$IFS
- IFS=';'
- for dir in $lib_path $LIB
- do
- IFS=$save_IFS
- if $shared && test -f "$dir/$lib.dll.lib"; then
- found=yes
- lib=$dir/$lib.dll.lib
- break
- fi
- if test -f "$dir/$lib.lib"; then
- found=yes
- lib=$dir/$lib.lib
- break
- fi
- if test -f "$dir/lib$lib.a"; then
- found=yes
- lib=$dir/lib$lib.a
- break
- fi
- done
- IFS=$save_IFS
-
- if test "$found" != yes; then
- lib=$lib.lib
- fi
-}
-
-# func_cl_wrapper cl arg...
-# Adjust compile command to suit cl
-func_cl_wrapper ()
-{
- # Assume a capable shell
- lib_path=
- shared=:
- linker_opts=
- for arg
- do
- if test -n "$eat"; then
- eat=
- else
- case $1 in
- -o)
- # configure might choose to run compile as 'compile cc -o foo foo.c'.
- eat=1
- case $2 in
- *.o | *.[oO][bB][jJ])
- func_file_conv "$2"
- set x "$@" -Fo"$file"
- shift
- ;;
- *)
- func_file_conv "$2"
- set x "$@" -Fe"$file"
- shift
- ;;
- esac
- ;;
- -I)
- eat=1
- func_file_conv "$2" mingw
- set x "$@" -I"$file"
- shift
- ;;
- -I*)
- func_file_conv "${1#-I}" mingw
- set x "$@" -I"$file"
- shift
- ;;
- -l)
- eat=1
- func_cl_dashl "$2"
- set x "$@" "$lib"
- shift
- ;;
- -l*)
- func_cl_dashl "${1#-l}"
- set x "$@" "$lib"
- shift
- ;;
- -L)
- eat=1
- func_cl_dashL "$2"
- ;;
- -L*)
- func_cl_dashL "${1#-L}"
- ;;
- -static)
- shared=false
- ;;
- -Wl,*)
- arg=${1#-Wl,}
- save_ifs="$IFS"; IFS=','
- for flag in $arg; do
- IFS="$save_ifs"
- linker_opts="$linker_opts $flag"
- done
- IFS="$save_ifs"
- ;;
- -Xlinker)
- eat=1
- linker_opts="$linker_opts $2"
- ;;
- -*)
- set x "$@" "$1"
- shift
- ;;
- *.cc | *.CC | *.cxx | *.CXX | *.[cC]++)
- func_file_conv "$1"
- set x "$@" -Tp"$file"
- shift
- ;;
- *.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO])
- func_file_conv "$1" mingw
- set x "$@" "$file"
- shift
- ;;
- *)
- set x "$@" "$1"
- shift
- ;;
- esac
- fi
- shift
- done
- if test -n "$linker_opts"; then
- linker_opts="-link$linker_opts"
- fi
- exec "$@" $linker_opts
- exit 1
-}
-
-eat=
-
-case $1 in
- '')
- echo "$0: No command. Try '$0 --help' for more information." 1>&2
- exit 1;
- ;;
- -h | --h*)
- cat <<\EOF
-Usage: compile [--help] [--version] PROGRAM [ARGS]
-
-Wrapper for compilers which do not understand '-c -o'.
-Remove '-o dest.o' from ARGS, run PROGRAM with the remaining
-arguments, and rename the output as expected.
-
-If you are trying to build a whole package this is not the
-right script to run: please start by reading the file 'INSTALL'.
-
-Report bugs to <bug-automake@gnu.org>.
-EOF
- exit $?
- ;;
- -v | --v*)
- echo "compile $scriptversion"
- exit $?
- ;;
- cl | *[/\\]cl | cl.exe | *[/\\]cl.exe )
- func_cl_wrapper "$@" # Doesn't return...
- ;;
-esac
-
-ofile=
-cfile=
-
-for arg
-do
- if test -n "$eat"; then
- eat=
- else
- case $1 in
- -o)
- # configure might choose to run compile as 'compile cc -o foo foo.c'.
- # So we strip '-o arg' only if arg is an object.
- eat=1
- case $2 in
- *.o | *.obj)
- ofile=$2
- ;;
- *)
- set x "$@" -o "$2"
- shift
- ;;
- esac
- ;;
- *.c)
- cfile=$1
- set x "$@" "$1"
- shift
- ;;
- *)
- set x "$@" "$1"
- shift
- ;;
- esac
- fi
- shift
-done
-
-if test -z "$ofile" || test -z "$cfile"; then
- # If no '-o' option was seen then we might have been invoked from a
- # pattern rule where we don't need one. That is ok -- this is a
- # normal compilation that the losing compiler can handle. If no
- # '.c' file was seen then we are probably linking. That is also
- # ok.
- exec "$@"
-fi
-
-# Name of file we expect compiler to create.
-cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'`
-
-# Create the lock directory.
-# Note: use '[/\\:.-]' here to ensure that we don't use the same name
-# that we are using for the .o file. Also, base the name on the expected
-# object file name, since that is what matters with a parallel build.
-lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d
-while true; do
- if mkdir "$lockdir" >/dev/null 2>&1; then
- break
- fi
- sleep 1
-done
-# FIXME: race condition here if user kills between mkdir and trap.
-trap "rmdir '$lockdir'; exit 1" 1 2 15
-
-# Run the compile.
-"$@"
-ret=$?
-
-if test -f "$cofile"; then
- test "$cofile" = "$ofile" || mv "$cofile" "$ofile"
-elif test -f "${cofile}bj"; then
- test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile"
-fi
-
-rmdir "$lockdir"
-exit $ret
-
-# Local Variables:
-# mode: shell-script
-# sh-indentation: 2
-# eval: (add-hook 'write-file-hooks 'time-stamp)
-# time-stamp-start: "scriptversion="
-# time-stamp-format: "%:y-%02m-%02d.%02H"
-# time-stamp-time-zone: "UTC"
-# time-stamp-end: "; # UTC"
-# End:
diff --git a/config-msvc.h b/config-msvc.h
index ae43a5f..9c8d423 100644
--- a/config-msvc.h
+++ b/config-msvc.h
@@ -12,13 +12,14 @@
#define ENABLE_FRAGMENT 1
#define ENABLE_HTTP_PROXY 1
#define ENABLE_LZO 1
+#define ENABLE_LZ4 1
+#define NEED_COMPAT_LZ4 1
#define ENABLE_MANAGEMENT 1
#define ENABLE_MULTIHOME 1
#define ENABLE_PKCS11 1
#define ENABLE_PLUGIN 1
#define ENABLE_PORT_SHARE 1
#define ENABLE_SOCKS 1
-#define ENABLE_SSL 1
#define HAVE_ERRNO_H 1
#define HAVE_FCNTL_H 1
@@ -92,7 +93,10 @@
#define strncasecmp strnicmp
#define strcasecmp _stricmp
+
+#if _MSC_VER<1900
#define snprintf _snprintf
+#endif
#if _MSC_VER < 1800
#define strtoull strtoul
@@ -127,3 +131,8 @@ typedef __int8 int8_t;
#include <config-msvc-local.h>
#endif
+// Vista and above has implementation of inet_ntop / inet_pton
+#if _WIN32_WINNT >= _WIN32_WINNT_VISTA
+ #define HAVE_INET_NTOP
+ #define HAVE_INET_PTON
+#endif
diff --git a/config-version.h.in b/config-version.h.in
deleted file mode 100644
index 27ee36a..0000000
--- a/config-version.h.in
+++ /dev/null
@@ -1 +0,0 @@
-#define CONFIGURE_GIT_REVISION "@CONFIGURE_GIT_REVISION@"
diff --git a/config.guess b/config.guess
index 1f5c50c..b79252d 100755
--- a/config.guess
+++ b/config.guess
@@ -1,8 +1,8 @@
#! /bin/sh
# Attempt to guess a canonical system name.
-# Copyright 1992-2014 Free Software Foundation, Inc.
+# Copyright 1992-2013 Free Software Foundation, Inc.
-timestamp='2014-03-23'
+timestamp='2013-06-10'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@@ -50,7 +50,7 @@ version="\
GNU config.guess ($timestamp)
Originally written by Per Bothner.
-Copyright 1992-2014 Free Software Foundation, Inc.
+Copyright 1992-2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -149,7 +149,7 @@ Linux|GNU|GNU/*)
LIBC=gnu
#endif
EOF
- eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`
+ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'`
;;
esac
@@ -826,7 +826,7 @@ EOF
*:MINGW*:*)
echo ${UNAME_MACHINE}-pc-mingw32
exit ;;
- *:MSYS*:*)
+ i*:MSYS*:*)
echo ${UNAME_MACHINE}-pc-msys
exit ;;
i*:windows32*:*)
@@ -969,10 +969,10 @@ EOF
eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; }
;;
- openrisc*:Linux:*:*)
- echo or1k-unknown-linux-${LIBC}
+ or1k:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
- or32:Linux:*:* | or1k*:Linux:*:*)
+ or32:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
padre:Linux:*:*)
@@ -1260,26 +1260,16 @@ EOF
if test "$UNAME_PROCESSOR" = unknown ; then
UNAME_PROCESSOR=powerpc
fi
- if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then
- if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
- if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
- (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
- grep IS_64BIT_ARCH >/dev/null
- then
- case $UNAME_PROCESSOR in
- i386) UNAME_PROCESSOR=x86_64 ;;
- powerpc) UNAME_PROCESSOR=powerpc64 ;;
- esac
- fi
+ if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+ if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
+ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+ grep IS_64BIT_ARCH >/dev/null
+ then
+ case $UNAME_PROCESSOR in
+ i386) UNAME_PROCESSOR=x86_64 ;;
+ powerpc) UNAME_PROCESSOR=powerpc64 ;;
+ esac
fi
- elif test "$UNAME_PROCESSOR" = i386 ; then
- # Avoid executing cc on OS X 10.9, as it ships with a stub
- # that puts up a graphical alert prompting to install
- # developer tools. Any system running Mac OS X 10.7 or
- # later (Darwin 11 and later) is required to have a 64-bit
- # processor. This is not true of the ARM version of Darwin
- # that Apple uses in portable devices.
- UNAME_PROCESSOR=x86_64
fi
echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
exit ;;
@@ -1371,6 +1361,154 @@ EOF
exit ;;
esac
+eval $set_cc_for_build
+cat >$dummy.c <<EOF
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+ /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed,
+ I don't know.... */
+ printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+ printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+ "4"
+#else
+ ""
+#endif
+ ); exit (0);
+#endif
+#endif
+
+#if defined (__arm) && defined (__acorn) && defined (__unix)
+ printf ("arm-acorn-riscix\n"); exit (0);
+#endif
+
+#if defined (hp300) && !defined (hpux)
+ printf ("m68k-hp-bsd\n"); exit (0);
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+ int version;
+ version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+ if (version < 4)
+ printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+ else
+ printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
+ exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+ printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+ printf ("ns32k-encore-mach\n"); exit (0);
+#else
+ printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+ printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+ printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+ printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+ struct utsname un;
+
+ uname(&un);
+
+ if (strncmp(un.version, "V2", 2) == 0) {
+ printf ("i386-sequent-ptx2\n"); exit (0);
+ }
+ if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+ printf ("i386-sequent-ptx1\n"); exit (0);
+ }
+ printf ("i386-sequent-ptx\n"); exit (0);
+
+#endif
+
+#if defined (vax)
+# if !defined (ultrix)
+# include <sys/param.h>
+# if defined (BSD)
+# if BSD == 43
+ printf ("vax-dec-bsd4.3\n"); exit (0);
+# else
+# if BSD == 199006
+ printf ("vax-dec-bsd4.3reno\n"); exit (0);
+# else
+ printf ("vax-dec-bsd\n"); exit (0);
+# endif
+# endif
+# else
+ printf ("vax-dec-bsd\n"); exit (0);
+# endif
+# else
+ printf ("vax-dec-ultrix\n"); exit (0);
+# endif
+#endif
+
+#if defined (alliant) && defined (i860)
+ printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+ exit (1);
+}
+EOF
+
+$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` &&
+ { echo "$SYSTEM_NAME"; exit; }
+
+# Apollos put the system type in the environment.
+
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; }
+
+# Convex versions that predate uname can use getsysinfo(1)
+
+if [ -x /usr/convex/getsysinfo ]
+then
+ case `getsysinfo -f cpu_type` in
+ c1*)
+ echo c1-convex-bsd
+ exit ;;
+ c2*)
+ if getsysinfo -f scalar_acc
+ then echo c32-convex-bsd
+ else echo c2-convex-bsd
+ fi
+ exit ;;
+ c34*)
+ echo c34-convex-bsd
+ exit ;;
+ c38*)
+ echo c38-convex-bsd
+ exit ;;
+ c4*)
+ echo c4-convex-bsd
+ exit ;;
+ esac
+fi
+
cat >&2 <<EOF
$0: unable to guess system type
diff --git a/config.h.in b/config.h.in
index 11487ff..88a53da 100644
--- a/config.h.in
+++ b/config.h.in
@@ -18,21 +18,27 @@
/* Dimension to use for empty array declaration */
#undef EMPTY_ARRAY_SIZE
+/* Enable async push */
+#undef ENABLE_ASYNC_PUSH
+
/* Enable client capability only */
#undef ENABLE_CLIENT_ONLY
/* Enable client/server capability */
#undef ENABLE_CLIENT_SERVER
+/* Enable compression stub capability */
+#undef ENABLE_COMP_STUB
+
/* Enable crypto library */
#undef ENABLE_CRYPTO
+/* Use mbed TLS library */
+#undef ENABLE_CRYPTO_MBEDTLS
+
/* Use OpenSSL library */
#undef ENABLE_CRYPTO_OPENSSL
-/* Use PolarSSL library */
-#undef ENABLE_CRYPTO_POLARSSL
-
/* Enable debugging support */
#undef ENABLE_DEBUG
@@ -45,18 +51,15 @@
/* Enable internal fragmentation support */
#undef ENABLE_FRAGMENT
-/* Enable HTTP proxy support */
-#undef ENABLE_HTTP_PROXY
-
/* enable iproute2 support */
#undef ENABLE_IPROUTE
+/* Enable LZ4 compression library */
+#undef ENABLE_LZ4
+
/* Enable LZO compression library */
#undef ENABLE_LZO
-/* Enable LZO stub capability */
-#undef ENABLE_LZO_STUB
-
/* Enable management server capability */
#undef ENABLE_MANAGEMENT
@@ -84,12 +87,6 @@
/* Enable smaller executable size */
#undef ENABLE_SMALL
-/* Enable Socks proxy support */
-#undef ENABLE_SOCKS
-
-/* Enable ssl library */
-#undef ENABLE_SSL
-
/* Enable strict options check between peers */
#undef ENABLE_STRICT_OPTIONS_CHECK
@@ -105,6 +102,12 @@
/* Define to 1 if you have the `access' function. */
#undef HAVE_ACCESS
+/* Use crypto library */
+#undef HAVE_AEAD_CIPHER_MODES
+
+/* Compiler supports anonymous unions */
+#undef HAVE_ANONYMOUS_UNION_SUPPORT
+
/* Define to 1 if you have the <arpa/inet.h> header file. */
#undef HAVE_ARPA_INET_H
@@ -184,6 +187,9 @@
/* Define to 1 if you have the <dlfcn.h> header file. */
#undef HAVE_DLFCN_H
+/* Define to 1 if you have the <dmalloc.h> header file. */
+#undef HAVE_DMALLOC_H
+
/* Define to 1 if you have the `dup' function. */
#undef HAVE_DUP
@@ -208,6 +214,9 @@
/* Define to 1 if you have the <err.h> header file. */
#undef HAVE_ERR_H
+/* Define to 1 if you have the `EVP_aes_256_gcm' function. */
+#undef HAVE_EVP_AES_256_GCM
+
/* Define to 1 if you have the `EVP_CIPHER_CTX_set_key_length' function. */
#undef HAVE_EVP_CIPHER_CTX_SET_KEY_LENGTH
@@ -277,6 +286,9 @@
/* struct in_pktinfo needed for IP_PKTINFO support */
#undef HAVE_IN_PKTINFO
+/* Define to 1 if the system has the type `in_port_t'. */
+#undef HAVE_IN_PORT_T
+
/* struct iovec needed for IPv6 support */
#undef HAVE_IOVEC
@@ -286,12 +298,12 @@
/* struct iphdr needed for IPv6 support */
#undef HAVE_IPHDR
+/* struct in_pktinfo.ipi_spec_dst needed for IP_PKTINFO support */
+#undef HAVE_IPI_SPEC_DST
+
/* Define to 1 if you have the <libgen.h> header file. */
#undef HAVE_LIBGEN_H
-/* Define to 1 if you have the `polarssl' library (-lpolarssl). */
-#undef HAVE_LIBPOLARSSL
-
/* Define to 1 if you have the <limits.h> header file. */
#undef HAVE_LIMITS_H
@@ -307,6 +319,9 @@
/* Define to 1 if you have the `listen' function. */
#undef HAVE_LISTEN
+/* Define to 1 if you have the <lz4.h> header file. */
+#undef HAVE_LZ4_H
+
/* Define to 1 if you have the <lzo1x.h> header file. */
#undef HAVE_LZO1X_H
@@ -319,6 +334,12 @@
/* Define to 1 if you have the <lzo/lzoutil.h> header file. */
#undef HAVE_LZO_LZOUTIL_H
+/* Define to 1 if you have the `mbedtls_cipher_check_tag' function. */
+#undef HAVE_MBEDTLS_CIPHER_CHECK_TAG
+
+/* Define to 1 if you have the `mbedtls_cipher_write_tag' function. */
+#undef HAVE_MBEDTLS_CIPHER_WRITE_TAG
+
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
@@ -364,7 +385,7 @@
/* Define to 1 if you have the `openlog' function. */
#undef HAVE_OPENLOG
-/* Use crypto library */
+/* OpenSSL engine support available */
#undef HAVE_OPENSSL_ENGINE
/* Define to 1 if you have the `poll' function. */
@@ -391,6 +412,9 @@
/* Define to 1 if you have the <resolv.h> header file. */
#undef HAVE_RESOLV_H
+/* sa_family_t, needed to hold AF_* info */
+#undef HAVE_SA_FAMILY_T
+
/* Define to 1 if you have the `sd_booted' function. */
#undef HAVE_SD_BOOTED
@@ -430,6 +454,9 @@
/* struct sock_extended_err needed for extended socket error support */
#undef HAVE_SOCK_EXTENDED_ERR
+/* Define to 1 if you have the `SSL_CTX_new' function. */
+#undef HAVE_SSL_CTX_NEW
+
/* Define to 1 if you have the `stat' function. */
#undef HAVE_STAT
@@ -481,6 +508,9 @@
/* Define to 1 if you have the <sys/file.h> header file. */
#undef HAVE_SYS_FILE_H
+/* Define to 1 if you have the <sys/inotify.h> header file. */
+#undef HAVE_SYS_INOTIFY_H
+
/* Define to 1 if you have the <sys/ioctl.h> header file. */
#undef HAVE_SYS_IOCTL_H
@@ -535,6 +565,9 @@
/* Define to 1 if you have the `unlink' function. */
#undef HAVE_UNLINK
+/* Define to 1 if you have the <valgrind/memcheck.h> header file. */
+#undef HAVE_VALGRIND_MEMCHECK_H
+
/* Define to 1 if you have the <versionhelpers.h> header file. */
#undef HAVE_VERSIONHELPERS_H
@@ -571,9 +604,22 @@
/* Path to iproute tool */
#undef IPROUTE_PATH
-/* Define to the sub-directory where libtool stores uninstalled libraries. */
+/* Define to the sub-directory in which libtool stores uninstalled libraries.
+ */
#undef LT_OBJDIR
+/* use copy of LZ4 source in compat/ */
+#undef NEED_COMPAT_LZ4
+
+/* OpenVPN major version - integer */
+#undef OPENVPN_VERSION_MAJOR
+
+/* OpenVPN minor version - integer */
+#undef OPENVPN_VERSION_MINOR
+
+/* OpenVPN patch level - may be a string or integer */
+#undef OPENVPN_VERSION_PATCH
+
/* Version in windows resource format */
#undef OPENVPN_VERSION_RESOURCE
@@ -604,6 +650,9 @@
/* Path separator */
#undef PATH_SEPARATOR_STR
+/* Enable pedantic mode */
+#undef PEDANTIC
+
/* Define as the return type of signal handlers (`int' or `void'). */
#undef RETSIGTYPE
@@ -637,6 +686,9 @@
/* Path to systemd-ask-password tool */
#undef SYSTEMD_ASK_PASSWORD_PATH
+/* systemd is newer than v216 */
+#undef SYSTEMD_NEWER_THAN_216
+
/* The tap-windows id */
#undef TAP_WIN_COMPONENT_ID
@@ -646,6 +698,9 @@
/* The tap-windows version number is required for OpenVPN */
#undef TAP_WIN_MIN_MINOR
+/* Are we running AIX? */
+#undef TARGET_AIX
+
/* A string representing our host */
#undef TARGET_ALIAS
@@ -741,6 +796,9 @@
/* Workaround missing in_addr_t */
#undef in_addr_t
+/* Workaround missing in_port_t */
+#undef in_port_t
+
/* Define to `__inline__' or `__inline' if that's what the C compiler
calls it, or to nothing if 'inline' is not supported under any name. */
#ifndef __cplusplus
diff --git a/config.sub b/config.sub
index 66c5074..c765b34 100755
--- a/config.sub
+++ b/config.sub
@@ -1,8 +1,8 @@
#! /bin/sh
# Configuration validation subroutine script.
-# Copyright 1992-2014 Free Software Foundation, Inc.
+# Copyright 1992-2013 Free Software Foundation, Inc.
-timestamp='2014-07-28'
+timestamp='2013-04-24'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@@ -68,7 +68,7 @@ Report bugs and patches to <config-patches@gnu.org>."
version="\
GNU config.sub ($timestamp)
-Copyright 1992-2014 Free Software Foundation, Inc.
+Copyright 1992-2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -257,7 +257,7 @@ case $basic_machine in
| avr | avr32 \
| be32 | be64 \
| bfin \
- | c4x | c8051 | clipper \
+ | c4x | clipper \
| d10v | d30v | dlx | dsp16xx \
| epiphany \
| fido | fr30 | frv \
@@ -265,7 +265,6 @@ case $basic_machine in
| hexagon \
| i370 | i860 | i960 | ia64 \
| ip2k | iq2000 \
- | k1om \
| le32 | le64 \
| lm32 \
| m32c | m32r | m32rle | m68000 | m68k | m88k \
@@ -283,10 +282,8 @@ case $basic_machine in
| mips64vr5900 | mips64vr5900el \
| mipsisa32 | mipsisa32el \
| mipsisa32r2 | mipsisa32r2el \
- | mipsisa32r6 | mipsisa32r6el \
| mipsisa64 | mipsisa64el \
| mipsisa64r2 | mipsisa64r2el \
- | mipsisa64r6 | mipsisa64r6el \
| mipsisa64sb1 | mipsisa64sb1el \
| mipsisa64sr71k | mipsisa64sr71kel \
| mipsr5900 | mipsr5900el \
@@ -298,7 +295,8 @@ case $basic_machine in
| nds32 | nds32le | nds32be \
| nios | nios2 | nios2eb | nios2el \
| ns16k | ns32k \
- | open8 | or1k | or1knd | or32 \
+ | open8 \
+ | or1k | or32 \
| pdp10 | pdp11 | pj | pjl \
| powerpc | powerpc64 | powerpc64le | powerpcle \
| pyramid \
@@ -326,7 +324,7 @@ case $basic_machine in
c6x)
basic_machine=tic6x-unknown
;;
- m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip)
+ m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip)
basic_machine=$basic_machine-unknown
os=-none
;;
@@ -374,7 +372,7 @@ case $basic_machine in
| be32-* | be64-* \
| bfin-* | bs2000-* \
| c[123]* | c30-* | [cjt]90-* | c4x-* \
- | c8051-* | clipper-* | craynv-* | cydra-* \
+ | clipper-* | craynv-* | cydra-* \
| d10v-* | d30v-* | dlx-* \
| elxsi-* \
| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
@@ -383,7 +381,6 @@ case $basic_machine in
| hexagon-* \
| i*86-* | i860-* | i960-* | ia64-* \
| ip2k-* | iq2000-* \
- | k1om-* \
| le32-* | le64-* \
| lm32-* \
| m32c-* | m32r-* | m32rle-* \
@@ -403,10 +400,8 @@ case $basic_machine in
| mips64vr5900-* | mips64vr5900el-* \
| mipsisa32-* | mipsisa32el-* \
| mipsisa32r2-* | mipsisa32r2el-* \
- | mipsisa32r6-* | mipsisa32r6el-* \
| mipsisa64-* | mipsisa64el-* \
| mipsisa64r2-* | mipsisa64r2el-* \
- | mipsisa64r6-* | mipsisa64r6el-* \
| mipsisa64sb1-* | mipsisa64sb1el-* \
| mipsisa64sr71k-* | mipsisa64sr71kel-* \
| mipsr5900-* | mipsr5900el-* \
@@ -418,7 +413,6 @@ case $basic_machine in
| nios-* | nios2-* | nios2eb-* | nios2el-* \
| none-* | np1-* | ns16k-* | ns32k-* \
| open8-* \
- | or1k*-* \
| orion-* \
| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
@@ -800,7 +794,7 @@ case $basic_machine in
os=-mingw64
;;
mingw32)
- basic_machine=i686-pc
+ basic_machine=i386-pc
os=-mingw32
;;
mingw32ce)
@@ -828,10 +822,6 @@ case $basic_machine in
basic_machine=powerpc-unknown
os=-morphos
;;
- moxiebox)
- basic_machine=moxie-unknown
- os=-moxiebox
- ;;
msdos)
basic_machine=i386-pc
os=-msdos
@@ -840,7 +830,7 @@ case $basic_machine in
basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
;;
msys)
- basic_machine=i686-pc
+ basic_machine=i386-pc
os=-msys
;;
mvs)
@@ -1377,14 +1367,14 @@ case $os in
| -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
| -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
| -linux-newlib* | -linux-musl* | -linux-uclibc* \
- | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \
+ | -uxpv* | -beos* | -mpeix* | -udk* \
| -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
| -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
| -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
| -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
| -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
| -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
- | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* | -tirtos*)
+ | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*)
# Remember, each alternative MUST END IN *, to match a version number.
;;
-qnx*)
@@ -1556,9 +1546,6 @@ case $basic_machine in
c4x-* | tic4x-*)
os=-coff
;;
- c8051-*)
- os=-elf
- ;;
hexagon-*)
os=-elf
;;
@@ -1602,6 +1589,9 @@ case $basic_machine in
mips*-*)
os=-elf
;;
+ or1k-*)
+ os=-elf
+ ;;
or32-*)
os=-coff
;;
diff --git a/configure b/configure
index 9a4ba5b..1d72fe3 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for OpenVPN 2.3.11.
+# Generated by GNU Autoconf 2.69 for OpenVPN 2.4_beta1.
#
# Report bugs to <openvpn-users@lists.sourceforge.net>.
#
@@ -590,8 +590,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='OpenVPN'
PACKAGE_TARNAME='openvpn'
-PACKAGE_VERSION='2.3.11'
-PACKAGE_STRING='OpenVPN 2.3.11'
+PACKAGE_VERSION='2.4_beta1'
+PACKAGE_STRING='OpenVPN 2.4_beta1'
PACKAGE_BUGREPORT='openvpn-users@lists.sourceforge.net'
PACKAGE_URL=''
@@ -636,8 +636,18 @@ ac_subst_vars='am__EXEEXT_FALSE
am__EXEEXT_TRUE
LTLIBOBJS
LIBOBJS
+CMOCKA_INITIALIZED_FALSE
+CMOCKA_INITIALIZED_TRUE
+CMAKE
+TEST_CFLAGS
+TEST_LDFLAGS
+VENDOR_DIST_ROOT
+VENDOR_BUILD_ROOT
+VENDOR_SRC_ROOT
sampledir
plugindir
+ENABLE_CRYPTO_FALSE
+ENABLE_CRYPTO_TRUE
ENABLE_PLUGIN_DOWN_ROOT_FALSE
ENABLE_PLUGIN_DOWN_ROOT_TRUE
ENABLE_PLUGIN_AUTH_PAM_FALSE
@@ -651,6 +661,8 @@ PLUGIN_AUTH_PAM_CFLAGS
OPTIONAL_PKCS11_HELPER_LIBS
OPTIONAL_PKCS11_HELPER_CFLAGS
OPTIONAL_SYSTEMD_LIBS
+OPTIONAL_LZ4_LIBS
+OPTIONAL_LZ4_CFLAGS
OPTIONAL_LZO_LIBS
OPTIONAL_LZO_CFLAGS
OPTIONAL_CRYPTO_LIBS
@@ -664,14 +676,16 @@ P11KIT_LIBS
P11KIT_CFLAGS
libsystemd_LIBS
libsystemd_CFLAGS
+ENABLE_SYSTEMD_FALSE
+ENABLE_SYSTEMD_TRUE
+LZ4_LIBS
+LZ4_CFLAGS
LZO_LIBS
LZO_CFLAGS
-POLARSSL_LIBS
-POLARSSL_CFLAGS
-OPENSSL_SSL_LIBS
-OPENSSL_SSL_CFLAGS
-OPENSSL_CRYPTO_LIBS
-OPENSSL_CRYPTO_CFLAGS
+MBEDTLS_LIBS
+MBEDTLS_CFLAGS
+OPENSSL_LIBS
+OPENSSL_CFLAGS
PKCS11_HELPER_LIBS
PKCS11_HELPER_CFLAGS
LIBPAM_LIBS
@@ -681,7 +695,6 @@ TAP_CFLAGS
SOCKETS_LIBS
DL_LIBS
RC
-LT_SYS_LIBRARY_PATH
OTOOL64
OTOOL
LIPO
@@ -767,6 +780,9 @@ am__isrc
INSTALL_DATA
INSTALL_SCRIPT
INSTALL_PROGRAM
+OPENVPN_VERSION_PATCH
+OPENVPN_VERSION_MINOR
+OPENVPN_VERSION_MAJOR
target_alias
host_alias
build_alias
@@ -811,18 +827,16 @@ enable_option_checking
enable_silent_rules
enable_dependency_tracking
enable_lzo
-enable_lzo_stub
+enable_lz4
+enable_comp_stub
enable_crypto
enable_ofb_cfb
-enable_ssl
enable_x509_alt_username
enable_multi
enable_server
enable_plugins
enable_management
enable_pkcs11
-enable_socks
-enable_http_proxy
enable_fragment
enable_multihome
enable_port_share
@@ -836,9 +850,11 @@ enable_plugin_down_root
enable_pam_dlopen
enable_strict
enable_pedantic
+enable_werror
enable_strict_options
enable_selinux
enable_systemd
+enable_async_push
with_special_build
with_mem_check
with_crypto_library
@@ -847,7 +863,6 @@ enable_shared
enable_static
with_pic
enable_fast_install
-with_aix_soname
with_gnu_ld
with_sysroot
enable_libtool_lock
@@ -871,20 +886,19 @@ NETSTAT
MAN2HTML
GIT
SYSTEMD_ASK_PASSWORD
-LT_SYS_LIBRARY_PATH
TAP_CFLAGS
LIBPAM_CFLAGS
LIBPAM_LIBS
PKCS11_HELPER_CFLAGS
PKCS11_HELPER_LIBS
-OPENSSL_CRYPTO_CFLAGS
-OPENSSL_CRYPTO_LIBS
-OPENSSL_SSL_CFLAGS
-OPENSSL_SSL_LIBS
-POLARSSL_CFLAGS
-POLARSSL_LIBS
+OPENSSL_CFLAGS
+OPENSSL_LIBS
+MBEDTLS_CFLAGS
+MBEDTLS_LIBS
LZO_CFLAGS
LZO_LIBS
+LZ4_CFLAGS
+LZ4_LIBS
libsystemd_CFLAGS
libsystemd_LIBS
P11KIT_CFLAGS
@@ -1429,7 +1443,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures OpenVPN 2.3.11 to adapt to many kinds of systems.
+\`configure' configures OpenVPN 2.4_beta1 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1499,7 +1513,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of OpenVPN 2.3.11:";;
+ short | recursive ) echo "Configuration of OpenVPN 2.4_beta1:";;
esac
cat <<\_ACEOF
@@ -1514,14 +1528,11 @@ Optional Features:
--disable-dependency-tracking
speeds up one-time build
--disable-lzo disable LZO compression support [default=yes]
- --enable-lzo-stub don't compile LZO compression support but still
- allow limited interoperability with LZO-enabled
- peers [default=no]
+ --disable-lz4 Disable LZ4 compression support
+ --enable-comp-stub Don't compile compression support but still allow limited interoperability with compression-enabled peers
--disable-crypto disable crypto support [default=yes]
--disable-ofb-cfb disable support for OFB and CFB cipher modes
[default=yes]
- --disable-ssl disable SSL support for TLS-based key exchange
- [default=yes]
--enable-x509-alt-username
enable the --x509-username-field feature
[default=no]
@@ -1532,8 +1543,6 @@ Optional Features:
--disable-plugins disable plug-in support [default=yes]
--disable-management disable management server support [default=yes]
--enable-pkcs11 enable pkcs11 support [default=no]
- --disable-socks disable Socks support [default=yes]
- --disable-http-proxy disable HTTP proxy support [default=yes]
--disable-fragment disable internal fragmentation support (--fragment)
[default=yes]
--disable-multihome disable multi-homed UDP server support (--multihome)
@@ -1556,10 +1565,14 @@ Optional Features:
[default=no]
--enable-pedantic enable pedantic compiler warnings, will not generate
a working executable (debugging option) [default=no]
+ --enable-werror promote compiler warnings to errors, will cause
+ builds to fail is the compiler issues warnings
+ (debugging option) [default=no]
--enable-strict-options enable strict options check between peers (debugging
option) [default=no]
--enable-selinux enable SELinux support [default=no]
--enable-systemd enable systemd suppport [default=no]
+ --enable-async-push enable async-push support [default=no]
--enable-shared[=PKGS] build shared libraries [default=yes]
--enable-static[=PKGS] build static libraries [default=yes]
--enable-fast-install[=PKGS]
@@ -1575,16 +1588,13 @@ Optional Packages:
TYPE=no|dmalloc|valgrind|ssl [default=no]
--with-crypto-library=library
build with the given crypto library,
- TYPE=openssl|polarssl [default=openssl]
+ TYPE=openssl|mbedtls [default=openssl]
--with-plugindir plugin directory [default=LIBDIR/openvpn]
--with-pic[=PKGS] try to use only PIC/non-PIC objects [default=use
both]
- --with-aix-soname=aix|svr4|both
- shared library versioning (aka "SONAME") variant to
- provide on AIX, [default=aix].
--with-gnu-ld assume the C compiler uses GNU ld [default=no]
- --with-sysroot[=DIR] Search for dependent libraries within DIR (or the
- compiler's sysroot if not specified).
+ --with-sysroot=DIR Search for dependent libraries within DIR
+ (or the compiler's sysroot if not specified).
Some influential environment variables:
CC C compiler command
@@ -1608,8 +1618,6 @@ Some influential environment variables:
GIT path to git utility
SYSTEMD_ASK_PASSWORD
path to systemd-ask-password utility
- LT_SYS_LIBRARY_PATH
- User-defined run-time library search path.
TAP_CFLAGS C compiler flags for tap
LIBPAM_CFLAGS
C compiler flags for libpam
@@ -1618,20 +1626,18 @@ Some influential environment variables:
C compiler flags for PKCS11_HELPER, overriding pkg-config
PKCS11_HELPER_LIBS
linker flags for PKCS11_HELPER, overriding pkg-config
- OPENSSL_CRYPTO_CFLAGS
- C compiler flags for OPENSSL_CRYPTO, overriding pkg-config
- OPENSSL_CRYPTO_LIBS
- linker flags for OPENSSL_CRYPTO, overriding pkg-config
- OPENSSL_SSL_CFLAGS
- C compiler flags for OPENSSL_SSL, overriding pkg-config
- OPENSSL_SSL_LIBS
- linker flags for OPENSSL_SSL, overriding pkg-config
- POLARSSL_CFLAGS
- C compiler flags for polarssl
- POLARSSL_LIBS
- linker flags for polarssl
+ OPENSSL_CFLAGS
+ C compiler flags for OpenSSL
+ OPENSSL_LIBS
+ linker flags for OpenSSL
+ MBEDTLS_CFLAGS
+ C compiler flags for mbedtls
+ MBEDTLS_LIBS
+ linker flags for mbedtls
LZO_CFLAGS C compiler flags for lzo
LZO_LIBS linker flags for lzo
+ LZ4_CFLAGS C compiler flags for lz4
+ LZ4_LIBS linker flags for lz4
libsystemd_CFLAGS
C compiler flags for libsystemd, overriding pkg-config
libsystemd_LIBS
@@ -1706,7 +1712,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-OpenVPN configure 2.3.11
+OpenVPN configure 2.4_beta1
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2439,6 +2445,63 @@ rm -f conftest.val
} # ac_fn_c_compute_int
+# ac_fn_c_check_member LINENO AGGR MEMBER ax_cv_socklen_t_equiv INCLUDES
+# ----------------------------------------------------------------------
+# Tries to find if the field MEMBER exists in type AGGR, after including
+# INCLUDES, setting cache variable VAR accordingly.
+ac_fn_c_check_member ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2.$3" >&5
+$as_echo_n "checking for $2.$3... " >&6; }
+if eval \${$4+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$5
+int
+main ()
+{
+static $2 ac_aggr;
+if (ac_aggr.$3)
+return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ eval "$4=yes"
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$5
+int
+main ()
+{
+static $2 ac_aggr;
+if (sizeof ac_aggr.$3)
+return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ eval "$4=yes"
+else
+ eval "$4=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$4
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_member
+
# ac_fn_c_check_decl LINENO SYMBOL ax_cv_socklen_t_equiv INCLUDES
# ---------------------------------------------------------------
# Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR
@@ -2488,7 +2551,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by OpenVPN $as_me 2.3.11, which was
+It was created by OpenVPN $as_me 2.4_beta1, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@@ -2852,7 +2915,22 @@ if test -z "${htmldir}"; then
fi
-$as_echo "#define OPENVPN_VERSION_RESOURCE 2,3,11,0" >>confdefs.h
+$as_echo "#define OPENVPN_VERSION_RESOURCE 2,4,0,0" >>confdefs.h
+
+OPENVPN_VERSION_MAJOR=2
+
+OPENVPN_VERSION_MINOR=4
+
+OPENVPN_VERSION_PATCH=_beta1
+
+
+$as_echo "#define OPENVPN_VERSION_MAJOR 2" >>confdefs.h
+
+
+$as_echo "#define OPENVPN_VERSION_MINOR 4" >>confdefs.h
+
+
+$as_echo "#define OPENVPN_VERSION_PATCH \"_beta1\"" >>confdefs.h
ac_aux_dir=
@@ -2884,13 +2962,13 @@ ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var.
ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var.
-ac_config_headers="$ac_config_headers config.h"
+ac_config_headers="$ac_config_headers config.h include/openvpn-plugin.h"
-am__api_version='1.15'
+am__api_version='1.13'
# Find a good install program. We prefer a C program (faster),
# so one script is as good as another. But avoid the broken or
@@ -3062,8 +3140,8 @@ test "$program_suffix" != NONE &&
ac_script='s/[\\$]/&&/g;s/;s,x,x,$//'
program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"`
-# Expand $ac_aux_dir to an absolute path.
-am_aux_dir=`cd "$ac_aux_dir" && pwd`
+# expand $ac_aux_dir to an absolute path
+am_aux_dir=`cd $ac_aux_dir && pwd`
if test x"${MISSING+set}" != xset; then
case $am_aux_dir in
@@ -3082,7 +3160,7 @@ else
$as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;}
fi
-if test x"${install_sh+set}" != xset; then
+if test x"${install_sh}" != xset; then
case $am_aux_dir in
*\ * | *\ *)
install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
@@ -3376,7 +3454,7 @@ fi
# Define the identity of the package.
PACKAGE='openvpn'
- VERSION='2.3.11'
+ VERSION='2.4_beta1'
cat >>confdefs.h <<_ACEOF
@@ -3410,8 +3488,8 @@ MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"}
# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
mkdir_p='$(MKDIR_P)'
-# We need awk for the "check" target (and possibly the TAP driver). The
-# system "awk" is bad on some platforms.
+# We need awk for the "check" target. The system "awk" is bad on
+# some platforms.
# Always define AMTAR for backward compatibility. Yes, it's still used
# in the wild :-( We should find a proper way to deprecate it ...
AMTAR='$${TAR-tar}'
@@ -3426,48 +3504,6 @@ am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'
-
-# POSIX will say in a future version that running "rm -f" with no argument
-# is OK; and we want to be able to make that assumption in our Makefile
-# recipes. So use an aggressive probe to check that the usage we want is
-# actually supported "in the wild" to an acceptable degree.
-# See automake bug#10828.
-# To make any issue more visible, cause the running configure to be aborted
-# by default if the 'rm' program in use doesn't match our expectations; the
-# user can still override this though.
-if rm -f && rm -fr && rm -rf; then : OK; else
- cat >&2 <<'END'
-Oops!
-
-Your 'rm' program seems unable to run without file operands specified
-on the command line, even when the '-f' option is present. This is contrary
-to the behaviour of most rm programs out there, and not conforming with
-the upcoming POSIX standard: <http://austingroupbugs.net/view.php?id=542>
-
-Please tell bug-automake@gnu.org about your system, including the value
-of your $PATH and any error possibly output before this message. This
-can help us improve future automake versions.
-
-END
- if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then
- echo 'Configuration will proceed anyway, since you have set the' >&2
- echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2
- echo >&2
- else
- cat >&2 <<'END'
-Aborting the configuration process, to ensure you take notice of the issue.
-
-You can download and install GNU coreutils to get an 'rm' implementation
-that behaves properly: <http://www.gnu.org/software/coreutils/>.
-
-If you want to complete the configuration process using your problematic
-'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM
-to "yes", and re-run configure.
-
-END
- as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5
- fi
-fi
# Make sure we can run config.sub.
$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5
@@ -4391,65 +4427,6 @@ ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_c_compiler_gnu
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5
-$as_echo_n "checking whether $CC understands -c and -o together... " >&6; }
-if ${am_cv_prog_cc_c_o+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
- # Make sure it works both with $CC and with simple cc.
- # Following AC_PROG_CC_C_O, we do the test twice because some
- # compilers refuse to overwrite an existing .o file with -o,
- # though they will create one.
- am_cv_prog_cc_c_o=yes
- for am_i in 1 2; do
- if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5
- ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } \
- && test -f conftest2.$ac_objext; then
- : OK
- else
- am_cv_prog_cc_c_o=no
- break
- fi
- done
- rm -f core conftest*
- unset am_i
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5
-$as_echo "$am_cv_prog_cc_c_o" >&6; }
-if test "$am_cv_prog_cc_c_o" != yes; then
- # Losing compiler, so override with the script.
- # FIXME: It is wrong to rewrite CC.
- # But if we don't then we get into trouble of one sort or another.
- # A longer-term fix would be to have automake use am__CC in this case,
- # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
- CC="$am_aux_dir/compile $CC"
-fi
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-
depcc="$CC" am_compiler_list=
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5
@@ -5047,11 +5024,20 @@ else
fi
-# Check whether --enable-lzo-stub was given.
-if test "${enable_lzo_stub+set}" = set; then :
- enableval=$enable_lzo_stub;
+# Check whether --enable-lz4 was given.
+if test "${enable_lz4+set}" = set; then :
+ enableval=$enable_lz4; enable_lz4="$enableval"
+else
+ enable_lz4="yes"
+
+fi
+
+
+# Check whether --enable-comp-stub was given.
+if test "${enable_comp_stub+set}" = set; then :
+ enableval=$enable_comp_stub; enable_comp_stub="$enableval"
else
- enable_lzo_stub="no"
+ enable_comp_stub="no"
fi
@@ -5074,15 +5060,6 @@ else
fi
-# Check whether --enable-ssl was given.
-if test "${enable_ssl+set}" = set; then :
- enableval=$enable_ssl;
-else
- enable_ssl="yes"
-
-fi
-
-
# Check whether --enable-x509-alt-username was given.
if test "${enable_x509_alt_username+set}" = set; then :
enableval=$enable_x509_alt_username;
@@ -5137,24 +5114,6 @@ else
fi
-# Check whether --enable-socks was given.
-if test "${enable_socks+set}" = set; then :
- enableval=$enable_socks;
-else
- enable_socks="yes"
-
-fi
-
-
-# Check whether --enable-http-proxy was given.
-if test "${enable_http_proxy+set}" = set; then :
- enableval=$enable_http_proxy;
-else
- enable_http_proxy="yes"
-
-fi
-
-
# Check whether --enable-fragment was given.
if test "${enable_fragment+set}" = set; then :
enableval=$enable_fragment;
@@ -5283,6 +5242,15 @@ else
fi
+# Check whether --enable-werror was given.
+if test "${enable_werror+set}" = set; then :
+ enableval=$enable_werror;
+else
+ enable_werror="no"
+
+fi
+
+
# Check whether --enable-strict-options was given.
if test "${enable_strict_options+set}" = set; then :
enableval=$enable_strict_options;
@@ -5310,6 +5278,15 @@ else
fi
+# Check whether --enable-async-push was given.
+if test "${enable_async_push+set}" = set; then :
+ enableval=$enable_async_push; enable_async_push="yes"
+else
+ enable_async_push="no"
+
+fi
+
+
# Check whether --with-special-build was given.
if test "${with_special_build+set}" = set; then :
@@ -5342,7 +5319,7 @@ fi
if test "${with_crypto_library+set}" = set; then :
withval=$with_crypto_library;
case "${withval}" in
- openssl|polarssl) ;;
+ openssl|mbedtls) ;;
*) as_fn_error $? "bad value ${withval} for --with-crypto-library" "$LINENO" 5 ;;
esac
@@ -5388,6 +5365,7 @@ cat >>confdefs.h <<_ACEOF
#define TARGET_PREFIX "S"
_ACEOF
+ CPPFLAGS="$CPPFLAGS -D_XPG4_2"
;;
*-*-openbsd*)
@@ -5430,6 +5408,7 @@ _ACEOF
have_tap_header="yes"
CPPFLAGS="$CPPFLAGS -no-cpp-precomp"
+ ac_cv_type_struct_in_pktinfo=no
;;
*-mingw*)
@@ -5441,7 +5420,7 @@ cat >>confdefs.h <<_ACEOF
_ACEOF
CPPFLAGS="${CPPFLAGS} -DWIN32_LEAN_AND_MEAN"
- CPPFLAGS="${CPPFLAGS} -DNTDDI_VERSION=NTDDI_WINXP -D_WIN32_WINNT=_WIN32_WINNT_WINXP"
+ CPPFLAGS="${CPPFLAGS} -DNTDDI_VERSION=NTDDI_VISTA -D_WIN32_WINNT=_WIN32_WINNT_VISTA"
WIN32=yes
;;
*-*-dragonfly*)
@@ -5454,6 +5433,19 @@ cat >>confdefs.h <<_ACEOF
_ACEOF
;;
+ *-aix*)
+
+$as_echo "#define TARGET_AIX 1" >>confdefs.h
+
+
+cat >>confdefs.h <<_ACEOF
+#define TARGET_PREFIX "A"
+_ACEOF
+
+ ROUTE="/usr/sbin/route"
+ have_tap_header="yes"
+ ac_cv_header_net_if_h="no" # exists, but breaks things
+ ;;
*)
cat >>confdefs.h <<_ACEOF
@@ -6174,6 +6166,12 @@ cat >>confdefs.h <<_ACEOF
_ACEOF
+# Set -std=c99 unless user already specified a -std=
+case "${CFLAGS}" in
+ *-std=*) ;;
+ *) CFLAGS="${CFLAGS} -std=c99" ;;
+esac
+
#
# Libtool
#
@@ -6186,8 +6184,8 @@ esac
-macro_version='2.4.6'
-macro_revision='2.4.6'
+macro_version='2.4.2'
+macro_revision='1.3337'
@@ -6201,7 +6199,7 @@ macro_revision='2.4.6'
-ltmain=$ac_aux_dir/ltmain.sh
+ltmain="$ac_aux_dir/ltmain.sh"
# Backslashify metacharacters that are still active within
# double-quoted strings.
@@ -6250,7 +6248,7 @@ func_echo_all ()
$ECHO ""
}
-case $ECHO in
+case "$ECHO" in
printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5
$as_echo "printf" >&6; } ;;
print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5
@@ -6443,19 +6441,19 @@ test -z "$GREP" && GREP=grep
# Check whether --with-gnu-ld was given.
if test "${with_gnu_ld+set}" = set; then :
- withval=$with_gnu_ld; test no = "$withval" || with_gnu_ld=yes
+ withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes
else
with_gnu_ld=no
fi
ac_prog=ld
-if test yes = "$GCC"; then
+if test "$GCC" = yes; then
# Check if gcc -print-prog-name=ld gives a path.
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5
$as_echo_n "checking for ld used by $CC... " >&6; }
case $host in
*-*-mingw*)
- # gcc leaves a trailing carriage return, which upsets mingw
+ # gcc leaves a trailing carriage return which upsets mingw
ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
*)
ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
@@ -6469,7 +6467,7 @@ $as_echo_n "checking for ld used by $CC... " >&6; }
while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do
ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"`
done
- test -z "$LD" && LD=$ac_prog
+ test -z "$LD" && LD="$ac_prog"
;;
"")
# If it fails, then pretend we aren't using GCC.
@@ -6480,7 +6478,7 @@ $as_echo_n "checking for ld used by $CC... " >&6; }
with_gnu_ld=unknown
;;
esac
-elif test yes = "$with_gnu_ld"; then
+elif test "$with_gnu_ld" = yes; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5
$as_echo_n "checking for GNU ld... " >&6; }
else
@@ -6491,32 +6489,32 @@ if ${lt_cv_path_LD+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -z "$LD"; then
- lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
for ac_dir in $PATH; do
- IFS=$lt_save_ifs
+ IFS="$lt_save_ifs"
test -z "$ac_dir" && ac_dir=.
if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
- lt_cv_path_LD=$ac_dir/$ac_prog
+ lt_cv_path_LD="$ac_dir/$ac_prog"
# Check to see if the program is GNU ld. I'd rather use --version,
# but apparently some variants of GNU ld only accept -v.
# Break only if it was the GNU/non-GNU ld that we prefer.
case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
*GNU* | *'with BFD'*)
- test no != "$with_gnu_ld" && break
+ test "$with_gnu_ld" != no && break
;;
*)
- test yes != "$with_gnu_ld" && break
+ test "$with_gnu_ld" != yes && break
;;
esac
fi
done
- IFS=$lt_save_ifs
+ IFS="$lt_save_ifs"
else
- lt_cv_path_LD=$LD # Let the user override the test with a path.
+ lt_cv_path_LD="$LD" # Let the user override the test with a path.
fi
fi
-LD=$lt_cv_path_LD
+LD="$lt_cv_path_LD"
if test -n "$LD"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5
$as_echo "$LD" >&6; }
@@ -6559,38 +6557,33 @@ if ${lt_cv_path_NM+:} false; then :
else
if test -n "$NM"; then
# Let the user override the test.
- lt_cv_path_NM=$NM
+ lt_cv_path_NM="$NM"
else
- lt_nm_to_check=${ac_tool_prefix}nm
+ lt_nm_to_check="${ac_tool_prefix}nm"
if test -n "$ac_tool_prefix" && test "$build" = "$host"; then
lt_nm_to_check="$lt_nm_to_check nm"
fi
for lt_tmp_nm in $lt_nm_to_check; do
- lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do
- IFS=$lt_save_ifs
+ IFS="$lt_save_ifs"
test -z "$ac_dir" && ac_dir=.
- tmp_nm=$ac_dir/$lt_tmp_nm
- if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then
+ tmp_nm="$ac_dir/$lt_tmp_nm"
+ if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then
# Check to see if the nm accepts a BSD-compat flag.
- # Adding the 'sed 1q' prevents false positives on HP-UX, which says:
+ # Adding the `sed 1q' prevents false positives on HP-UX, which says:
# nm: unknown option "B" ignored
# Tru64's nm complains that /dev/null is an invalid object file
- # MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty
- case $build_os in
- mingw*) lt_bad_file=conftest.nm/nofile ;;
- *) lt_bad_file=/dev/null ;;
- esac
- case `"$tmp_nm" -B $lt_bad_file 2>&1 | sed '1q'` in
- *$lt_bad_file* | *'Invalid file or object type'*)
+ case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in
+ */dev/null* | *'Invalid file or object type'*)
lt_cv_path_NM="$tmp_nm -B"
- break 2
+ break
;;
*)
case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
*/dev/null*)
lt_cv_path_NM="$tmp_nm -p"
- break 2
+ break
;;
*)
lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
@@ -6601,15 +6594,15 @@ else
esac
fi
done
- IFS=$lt_save_ifs
+ IFS="$lt_save_ifs"
done
: ${lt_cv_path_NM=no}
fi
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5
$as_echo "$lt_cv_path_NM" >&6; }
-if test no != "$lt_cv_path_NM"; then
- NM=$lt_cv_path_NM
+if test "$lt_cv_path_NM" != "no"; then
+ NM="$lt_cv_path_NM"
else
# Didn't find any BSD compatible name lister, look for dumpbin.
if test -n "$DUMPBIN"; then :
@@ -6715,9 +6708,9 @@ esac
fi
fi
- case `$DUMPBIN -symbols -headers /dev/null 2>&1 | sed '1q'` in
+ case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in
*COFF*)
- DUMPBIN="$DUMPBIN -symbols -headers"
+ DUMPBIN="$DUMPBIN -symbols"
;;
*)
DUMPBIN=:
@@ -6725,8 +6718,8 @@ fi
esac
fi
- if test : != "$DUMPBIN"; then
- NM=$DUMPBIN
+ if test "$DUMPBIN" != ":"; then
+ NM="$DUMPBIN"
fi
fi
test -z "$NM" && NM=nm
@@ -6766,7 +6759,7 @@ if ${lt_cv_sys_max_cmd_len+:} false; then :
$as_echo_n "(cached) " >&6
else
i=0
- teststring=ABCD
+ teststring="ABCD"
case $build_os in
msdosdjgpp*)
@@ -6806,7 +6799,7 @@ else
lt_cv_sys_max_cmd_len=8192;
;;
- bitrig* | darwin* | dragonfly* | freebsd* | netbsd* | openbsd*)
+ netbsd* | freebsd* | openbsd* | darwin* | dragonfly*)
# This has been around since 386BSD, at least. Likely further.
if test -x /sbin/sysctl; then
lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`
@@ -6856,23 +6849,22 @@ else
;;
*)
lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null`
- if test -n "$lt_cv_sys_max_cmd_len" && \
- test undefined != "$lt_cv_sys_max_cmd_len"; then
+ if test -n "$lt_cv_sys_max_cmd_len"; then
lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
else
# Make teststring a little bigger before we do anything with it.
# a 1K string should be a reasonable start.
- for i in 1 2 3 4 5 6 7 8; do
+ for i in 1 2 3 4 5 6 7 8 ; do
teststring=$teststring$teststring
done
SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}}
# If test is not a shell built-in, we'll probably end up computing a
# maximum length that is only half of the actual maximum length, but
# we can't tell.
- while { test X`env echo "$teststring$teststring" 2>/dev/null` \
+ while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \
= "X$teststring$teststring"; } >/dev/null 2>&1 &&
- test 17 != "$i" # 1/2 MB should be enough
+ test $i != 17 # 1/2 MB should be enough
do
i=`expr $i + 1`
teststring=$teststring$teststring
@@ -6890,7 +6882,7 @@ else
fi
-if test -n "$lt_cv_sys_max_cmd_len"; then
+if test -n $lt_cv_sys_max_cmd_len ; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5
$as_echo "$lt_cv_sys_max_cmd_len" >&6; }
else
@@ -6908,6 +6900,30 @@ max_cmd_len=$lt_cv_sys_max_cmd_len
: ${MV="mv -f"}
: ${RM="rm -f"}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands some XSI constructs" >&5
+$as_echo_n "checking whether the shell understands some XSI constructs... " >&6; }
+# Try some XSI features
+xsi_shell=no
+( _lt_dummy="a/b/c"
+ test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \
+ = c,a/b,b/c, \
+ && eval 'test $(( 1 + 1 )) -eq 2 \
+ && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \
+ && xsi_shell=yes
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $xsi_shell" >&5
+$as_echo "$xsi_shell" >&6; }
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands \"+=\"" >&5
+$as_echo_n "checking whether the shell understands \"+=\"... " >&6; }
+lt_shell_append=no
+( foo=bar; set foo baz; eval "$1+=\$2" && test "$foo" = barbaz ) \
+ >/dev/null 2>&1 \
+ && lt_shell_append=yes
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_shell_append" >&5
+$as_echo "$lt_shell_append" >&6; }
+
+
if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
lt_unset=unset
else
@@ -7030,13 +7046,13 @@ esac
reload_cmds='$LD$reload_flag -o $output$reload_objs'
case $host_os in
cygwin* | mingw* | pw32* | cegcc*)
- if test yes != "$GCC"; then
+ if test "$GCC" != yes; then
reload_cmds=false
fi
;;
darwin*)
- if test yes = "$GCC"; then
- reload_cmds='$LTCC $LTCFLAGS -nostdlib $wl-r -o $output$reload_objs'
+ if test "$GCC" = yes; then
+ reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs'
else
reload_cmds='$LD$reload_flag -o $output$reload_objs'
fi
@@ -7161,13 +7177,13 @@ lt_cv_deplibs_check_method='unknown'
# Need to set the preceding variable on all platforms that support
# interlibrary dependencies.
# 'none' -- dependencies not supported.
-# 'unknown' -- same as none, but documents that we really don't know.
+# `unknown' -- same as none, but documents that we really don't know.
# 'pass_all' -- all dependencies passed with no checks.
# 'test_compile' -- check by making test program.
# 'file_magic [[regex]]' -- check by looking for files in library path
-# that responds to the $file_magic_cmd with a given extended regex.
-# If you have 'file' or equivalent on your system and you're not sure
-# whether 'pass_all' will *always* work, you probably want this one.
+# which responds to the $file_magic_cmd with a given extended regex.
+# If you have `file' or equivalent on your system and you're not sure
+# whether `pass_all' will *always* work, you probably want this one.
case $host_os in
aix[4-9]*)
@@ -7194,7 +7210,8 @@ mingw* | pw32*)
# Base MSYS/MinGW do not provide the 'file' command needed by
# func_win32_libid shell function, so use a weaker test based on 'objdump',
# unless we find 'file', for example because we are cross-compiling.
- if ( file / ) >/dev/null 2>&1; then
+ # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin.
+ if ( test "$lt_cv_nm_interface" = "BSD nm" && file / ) >/dev/null 2>&1; then
lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
lt_cv_file_magic_cmd='func_win32_libid'
else
@@ -7230,6 +7247,10 @@ freebsd* | dragonfly*)
fi
;;
+gnu*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
haiku*)
lt_cv_deplibs_check_method=pass_all
;;
@@ -7268,7 +7289,7 @@ irix5* | irix6* | nonstopux*)
;;
# This must be glibc/ELF.
-linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+linux* | k*bsd*-gnu | kopensolaris*-gnu)
lt_cv_deplibs_check_method=pass_all
;;
@@ -7290,8 +7311,8 @@ newos6*)
lt_cv_deplibs_check_method=pass_all
;;
-openbsd* | bitrig*)
- if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then
+openbsd*)
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$'
else
lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
@@ -7344,9 +7365,6 @@ sysv4 | sysv4.3*)
tpf*)
lt_cv_deplibs_check_method=pass_all
;;
-os2*)
- lt_cv_deplibs_check_method=pass_all
- ;;
esac
fi
@@ -7501,8 +7519,8 @@ else
case $host_os in
cygwin* | mingw* | pw32* | cegcc*)
- # two different shell functions defined in ltmain.sh;
- # decide which one to use based on capabilities of $DLLTOOL
+ # two different shell functions defined in ltmain.sh
+ # decide which to use based on capabilities of $DLLTOOL
case `$DLLTOOL --help 2>&1` in
*--identify-strict*)
lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib
@@ -7514,7 +7532,7 @@ cygwin* | mingw* | pw32* | cegcc*)
;;
*)
# fallback: assume linklib IS sharedlib
- lt_cv_sharedlib_from_linklib_cmd=$ECHO
+ lt_cv_sharedlib_from_linklib_cmd="$ECHO"
;;
esac
@@ -7668,7 +7686,7 @@ if ac_fn_c_try_compile "$LINENO"; then :
ac_status=$?
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; }
- if test 0 -eq "$ac_status"; then
+ if test "$ac_status" -eq 0; then
# Ensure the archiver fails upon bogus file names.
rm -f conftest.$ac_objext libconftest.a
{ { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5
@@ -7676,7 +7694,7 @@ if ac_fn_c_try_compile "$LINENO"; then :
ac_status=$?
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; }
- if test 0 -ne "$ac_status"; then
+ if test "$ac_status" -ne 0; then
lt_cv_ar_at_file=@
fi
fi
@@ -7689,7 +7707,7 @@ fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5
$as_echo "$lt_cv_ar_at_file" >&6; }
-if test no = "$lt_cv_ar_at_file"; then
+if test "x$lt_cv_ar_at_file" = xno; then
archiver_list_spec=
else
archiver_list_spec=$lt_cv_ar_at_file
@@ -7906,7 +7924,7 @@ old_postuninstall_cmds=
if test -n "$RANLIB"; then
case $host_os in
- bitrig* | openbsd*)
+ openbsd*)
old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib"
;;
*)
@@ -7996,7 +8014,7 @@ cygwin* | mingw* | pw32* | cegcc*)
symcode='[ABCDGISTW]'
;;
hpux*)
- if test ia64 = "$host_cpu"; then
+ if test "$host_cpu" = ia64; then
symcode='[ABCDEGRST]'
fi
;;
@@ -8029,44 +8047,14 @@ case `$NM -V 2>&1` in
symcode='[ABCDGIRSTW]' ;;
esac
-if test "$lt_cv_nm_interface" = "MS dumpbin"; then
- # Gets list of data symbols to import.
- lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'"
- # Adjust the below global symbol transforms to fixup imported variables.
- lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'"
- lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'"
- lt_c_name_lib_hook="\
- -e 's/^I .* \(lib.*\)$/ {\"\1\", (void *) 0},/p'\
- -e 's/^I .* \(.*\)$/ {\"lib\1\", (void *) 0},/p'"
-else
- # Disable hooks by default.
- lt_cv_sys_global_symbol_to_import=
- lt_cdecl_hook=
- lt_c_name_hook=
- lt_c_name_lib_hook=
-fi
-
# Transform an extracted symbol line into a proper C declaration.
# Some systems (esp. on ia64) link data and code symbols differently,
# so use this general approach.
-lt_cv_sys_global_symbol_to_cdecl="sed -n"\
-$lt_cdecl_hook\
-" -e 's/^T .* \(.*\)$/extern int \1();/p'"\
-" -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'"
+lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
# Transform an extracted symbol line into symbol name and symbol address
-lt_cv_sys_global_symbol_to_c_name_address="sed -n"\
-$lt_c_name_hook\
-" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\
-" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'"
-
-# Transform an extracted symbol line into symbol name with lib prefix and
-# symbol address.
-lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n"\
-$lt_c_name_lib_hook\
-" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\
-" -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\
-" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"lib\1\", (void *) \&\1},/p'"
+lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\)[ ]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (void *) \&\2},/p'"
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\)[ ]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"lib\2\", (void *) \&\2},/p'"
# Handle CRLF in mingw tool chain
opt_cr=
@@ -8084,24 +8072,21 @@ for ac_symprfx in "" "_"; do
# Write the raw and C identifiers.
if test "$lt_cv_nm_interface" = "MS dumpbin"; then
- # Fake it for dumpbin and say T for any non-static function,
- # D for any global variable and I for any imported variable.
+ # Fake it for dumpbin and say T for any non-static function
+ # and D for any global variable.
# Also find C++ and __fastcall symbols from MSVC++,
# which start with @ or ?.
lt_cv_sys_global_symbol_pipe="$AWK '"\
" {last_section=section; section=\$ 3};"\
" /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\
" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\
-" /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\
-" /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\
-" /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\
" \$ 0!~/External *\|/{next};"\
" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\
" {if(hide[section]) next};"\
-" {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\
-" {split(\$ 0,a,/\||\r/); split(a[2],s)};"\
-" s[1]~/^[@?]/{print f,s[1],s[1]; next};"\
-" s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\
+" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\
+" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\
+" s[1]~/^[@?]/{print s[1], s[1]; next};"\
+" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\
" ' prfx=^$ac_symprfx"
else
lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
@@ -8149,11 +8134,11 @@ _LT_EOF
if $GREP ' nm_test_func$' "$nlist" >/dev/null; then
cat <<_LT_EOF > conftest.$ac_ext
/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */
-#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE
-/* DATA imports from DLLs on WIN32 can't be const, because runtime
+#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE)
+/* DATA imports from DLLs on WIN32 con't be const, because runtime
relocations are performed -- see ld's documentation on pseudo-relocs. */
# define LT_DLSYM_CONST
-#elif defined __osf__
+#elif defined(__osf__)
/* This system does not cope well with relocations in const data. */
# define LT_DLSYM_CONST
#else
@@ -8179,7 +8164,7 @@ lt__PROGRAM__LTX_preloaded_symbols[] =
{
{ "@PROGRAM@", (void *) 0 },
_LT_EOF
- $SED "s/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext
+ $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext
cat <<\_LT_EOF >> conftest.$ac_ext
{0, (void *) 0}
};
@@ -8199,13 +8184,13 @@ _LT_EOF
mv conftest.$ac_objext conftstm.$ac_objext
lt_globsym_save_LIBS=$LIBS
lt_globsym_save_CFLAGS=$CFLAGS
- LIBS=conftstm.$ac_objext
+ LIBS="conftstm.$ac_objext"
CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag"
if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
(eval $ac_link) 2>&5
ac_status=$?
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; } && test -s conftest$ac_exeext; then
+ test $ac_status = 0; } && test -s conftest${ac_exeext}; then
pipe_works=yes
fi
LIBS=$lt_globsym_save_LIBS
@@ -8226,7 +8211,7 @@ _LT_EOF
rm -rf conftest* conftst*
# Do not use the global_symbol_pipe unless it works.
- if test yes = "$pipe_works"; then
+ if test "$pipe_works" = yes; then
break
else
lt_cv_sys_global_symbol_pipe=
@@ -8279,16 +8264,6 @@ fi
-
-
-
-
-
-
-
-
-
-
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5
$as_echo_n "checking for sysroot... " >&6; }
@@ -8301,9 +8276,9 @@ fi
lt_sysroot=
-case $with_sysroot in #(
+case ${with_sysroot} in #(
yes)
- if test yes = "$GCC"; then
+ if test "$GCC" = yes; then
lt_sysroot=`$CC --print-sysroot 2>/dev/null`
fi
;; #(
@@ -8313,8 +8288,8 @@ case $with_sysroot in #(
no|'')
;; #(
*)
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_sysroot" >&5
-$as_echo "$with_sysroot" >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${with_sysroot}" >&5
+$as_echo "${with_sysroot}" >&6; }
as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5
;;
esac
@@ -8326,99 +8301,18 @@ $as_echo "${lt_sysroot:-no}" >&6; }
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a working dd" >&5
-$as_echo_n "checking for a working dd... " >&6; }
-if ${ac_cv_path_lt_DD+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- printf 0123456789abcdef0123456789abcdef >conftest.i
-cat conftest.i conftest.i >conftest2.i
-: ${lt_DD:=$DD}
-if test -z "$lt_DD"; then
- ac_path_lt_DD_found=false
- # Loop through the user's path and test for each of PROGNAME-LIST
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_prog in dd; do
- for ac_exec_ext in '' $ac_executable_extensions; do
- ac_path_lt_DD="$as_dir/$ac_prog$ac_exec_ext"
- as_fn_executable_p "$ac_path_lt_DD" || continue
-if "$ac_path_lt_DD" bs=32 count=1 <conftest2.i >conftest.out 2>/dev/null; then
- cmp -s conftest.i conftest.out \
- && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=:
-fi
- $ac_path_lt_DD_found && break 3
- done
- done
- done
-IFS=$as_save_IFS
- if test -z "$ac_cv_path_lt_DD"; then
- :
- fi
-else
- ac_cv_path_lt_DD=$lt_DD
-fi
-
-rm -f conftest.i conftest2.i conftest.out
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_lt_DD" >&5
-$as_echo "$ac_cv_path_lt_DD" >&6; }
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to truncate binary pipes" >&5
-$as_echo_n "checking how to truncate binary pipes... " >&6; }
-if ${lt_cv_truncate_bin+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- printf 0123456789abcdef0123456789abcdef >conftest.i
-cat conftest.i conftest.i >conftest2.i
-lt_cv_truncate_bin=
-if "$ac_cv_path_lt_DD" bs=32 count=1 <conftest2.i >conftest.out 2>/dev/null; then
- cmp -s conftest.i conftest.out \
- && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1"
-fi
-rm -f conftest.i conftest2.i conftest.out
-test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q"
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_truncate_bin" >&5
-$as_echo "$lt_cv_truncate_bin" >&6; }
-
-
-
-
-
-
-
-# Calculate cc_basename. Skip known compiler wrappers and cross-prefix.
-func_cc_basename ()
-{
- for cc_temp in $*""; do
- case $cc_temp in
- compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
- distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
- \-*) ;;
- *) break;;
- esac
- done
- func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
-}
-
# Check whether --enable-libtool-lock was given.
if test "${enable_libtool_lock+set}" = set; then :
enableval=$enable_libtool_lock;
fi
-test no = "$enable_libtool_lock" || enable_libtool_lock=yes
+test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
# Some flags need to be propagated to the compiler or linker for good
# libtool support.
case $host in
ia64-*-hpux*)
- # Find out what ABI is being produced by ac_compile, and set mode
- # options accordingly.
+ # Find out which ABI we are using.
echo 'int i;' > conftest.$ac_ext
if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
(eval $ac_compile) 2>&5
@@ -8427,25 +8321,24 @@ ia64-*-hpux*)
test $ac_status = 0; }; then
case `/usr/bin/file conftest.$ac_objext` in
*ELF-32*)
- HPUX_IA64_MODE=32
+ HPUX_IA64_MODE="32"
;;
*ELF-64*)
- HPUX_IA64_MODE=64
+ HPUX_IA64_MODE="64"
;;
esac
fi
rm -rf conftest*
;;
*-*-irix6*)
- # Find out what ABI is being produced by ac_compile, and set linker
- # options accordingly.
+ # Find out which ABI we are using.
echo '#line '$LINENO' "configure"' > conftest.$ac_ext
if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
(eval $ac_compile) 2>&5
ac_status=$?
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; }; then
- if test yes = "$lt_cv_prog_gnu_ld"; then
+ if test "$lt_cv_prog_gnu_ld" = yes; then
case `/usr/bin/file conftest.$ac_objext` in
*32-bit*)
LD="${LD-ld} -melf32bsmip"
@@ -8474,50 +8367,9 @@ ia64-*-hpux*)
rm -rf conftest*
;;
-mips64*-*linux*)
- # Find out what ABI is being produced by ac_compile, and set linker
- # options accordingly.
- echo '#line '$LINENO' "configure"' > conftest.$ac_ext
- if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
- (eval $ac_compile) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; then
- emul=elf
- case `/usr/bin/file conftest.$ac_objext` in
- *32-bit*)
- emul="${emul}32"
- ;;
- *64-bit*)
- emul="${emul}64"
- ;;
- esac
- case `/usr/bin/file conftest.$ac_objext` in
- *MSB*)
- emul="${emul}btsmip"
- ;;
- *LSB*)
- emul="${emul}ltsmip"
- ;;
- esac
- case `/usr/bin/file conftest.$ac_objext` in
- *N32*)
- emul="${emul}n32"
- ;;
- esac
- LD="${LD-ld} -m $emul"
- fi
- rm -rf conftest*
- ;;
-
-x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \
+x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \
s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
- # Find out what ABI is being produced by ac_compile, and set linker
- # options accordingly. Note that the listed cases only cover the
- # situations where additional linker options are needed (such as when
- # doing 32-bit compilation for a host where ld defaults to 64-bit, or
- # vice versa); the common cases where no linker options are needed do
- # not appear in the list.
+ # Find out which ABI we are using.
echo 'int i;' > conftest.$ac_ext
if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
(eval $ac_compile) 2>&5
@@ -8531,19 +8383,9 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
LD="${LD-ld} -m elf_i386_fbsd"
;;
x86_64-*linux*)
- case `/usr/bin/file conftest.o` in
- *x86-64*)
- LD="${LD-ld} -m elf32_x86_64"
- ;;
- *)
- LD="${LD-ld} -m elf_i386"
- ;;
- esac
- ;;
- powerpc64le-*linux*)
- LD="${LD-ld} -m elf32lppclinux"
+ LD="${LD-ld} -m elf_i386"
;;
- powerpc64-*linux*)
+ ppc64-*linux*|powerpc64-*linux*)
LD="${LD-ld} -m elf32ppclinux"
;;
s390x-*linux*)
@@ -8562,10 +8404,7 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
x86_64-*linux*)
LD="${LD-ld} -m elf_x86_64"
;;
- powerpcle-*linux*)
- LD="${LD-ld} -m elf64lppc"
- ;;
- powerpc-*linux*)
+ ppc*-*linux*|powerpc*-*linux*)
LD="${LD-ld} -m elf64ppc"
;;
s390*-*linux*|s390*-*tpf*)
@@ -8583,7 +8422,7 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
*-*-sco3.2v5*)
# On SCO OpenServer 5, we need -belf to get full-featured binaries.
- SAVE_CFLAGS=$CFLAGS
+ SAVE_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS -belf"
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5
$as_echo_n "checking whether the C compiler needs -belf... " >&6; }
@@ -8623,14 +8462,13 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5
$as_echo "$lt_cv_cc_needs_belf" >&6; }
- if test yes != "$lt_cv_cc_needs_belf"; then
+ if test x"$lt_cv_cc_needs_belf" != x"yes"; then
# this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
- CFLAGS=$SAVE_CFLAGS
+ CFLAGS="$SAVE_CFLAGS"
fi
;;
*-*solaris*)
- # Find out what ABI is being produced by ac_compile, and set linker
- # options accordingly.
+ # Find out which ABI we are using.
echo 'int i;' > conftest.$ac_ext
if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
(eval $ac_compile) 2>&5
@@ -8642,7 +8480,7 @@ $as_echo "$lt_cv_cc_needs_belf" >&6; }
case $lt_cv_prog_gnu_ld in
yes*)
case $host in
- i?86-*-solaris*|x86_64-*-solaris*)
+ i?86-*-solaris*)
LD="${LD-ld} -m elf_x86_64"
;;
sparc*-*-solaris*)
@@ -8651,7 +8489,7 @@ $as_echo "$lt_cv_cc_needs_belf" >&6; }
esac
# GNU ld 2.21 introduced _sol2 emulations. Use them if available.
if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then
- LD=${LD-ld}_sol2
+ LD="${LD-ld}_sol2"
fi
;;
*)
@@ -8667,7 +8505,7 @@ $as_echo "$lt_cv_cc_needs_belf" >&6; }
;;
esac
-need_locks=$enable_libtool_lock
+need_locks="$enable_libtool_lock"
if test -n "$ac_tool_prefix"; then
# Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args.
@@ -8778,7 +8616,7 @@ else
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5
$as_echo "$lt_cv_path_mainfest_tool" >&6; }
-if test yes != "$lt_cv_path_mainfest_tool"; then
+if test "x$lt_cv_path_mainfest_tool" != xyes; then
MANIFEST_TOOL=:
fi
@@ -9281,7 +9119,7 @@ if ${lt_cv_apple_cc_single_mod+:} false; then :
$as_echo_n "(cached) " >&6
else
lt_cv_apple_cc_single_mod=no
- if test -z "$LT_MULTI_MODULE"; then
+ if test -z "${LT_MULTI_MODULE}"; then
# By default we will add the -single_module flag. You can override
# by either setting the environment variable LT_MULTI_MODULE
# non-empty at configure time, or by adding -multi_module to the
@@ -9299,7 +9137,7 @@ else
cat conftest.err >&5
# Otherwise, if the output was created with a 0 exit code from
# the compiler, it worked.
- elif test -f libconftest.dylib && test 0 = "$_lt_result"; then
+ elif test -f libconftest.dylib && test $_lt_result -eq 0; then
lt_cv_apple_cc_single_mod=yes
else
cat conftest.err >&5
@@ -9338,7 +9176,7 @@ else
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
- LDFLAGS=$save_LDFLAGS
+ LDFLAGS="$save_LDFLAGS"
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5
@@ -9367,7 +9205,7 @@ _LT_EOF
_lt_result=$?
if test -s conftest.err && $GREP force_load conftest.err; then
cat conftest.err >&5
- elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then
+ elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then
lt_cv_ld_force_load=yes
else
cat conftest.err >&5
@@ -9380,32 +9218,32 @@ fi
$as_echo "$lt_cv_ld_force_load" >&6; }
case $host_os in
rhapsody* | darwin1.[012])
- _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;;
+ _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;;
darwin1.*)
- _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;;
+ _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
darwin*) # darwin 5.x on
# if running on 10.5 or later, the deployment target defaults
# to the OS version, if on x86, and 10.4, the deployment
# target defaults to 10.4. Don't you love it?
case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in
10.0,*86*-darwin8*|10.0,*-darwin[91]*)
- _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;;
- 10.[012][,.]*)
- _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;;
+ _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
+ 10.[012]*)
+ _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
10.*)
- _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;;
+ _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
esac
;;
esac
- if test yes = "$lt_cv_apple_cc_single_mod"; then
+ if test "$lt_cv_apple_cc_single_mod" = "yes"; then
_lt_dar_single_mod='$single_module'
fi
- if test yes = "$lt_cv_ld_exported_symbols_list"; then
- _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym'
+ if test "$lt_cv_ld_exported_symbols_list" = "yes"; then
+ _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym'
else
- _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib'
+ _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}'
fi
- if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then
+ if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then
_lt_dsymutil='~$DSYMUTIL $lib || :'
else
_lt_dsymutil=
@@ -9413,41 +9251,6 @@ $as_echo "$lt_cv_ld_force_load" >&6; }
;;
esac
-# func_munge_path_list VARIABLE PATH
-# -----------------------------------
-# VARIABLE is name of variable containing _space_ separated list of
-# directories to be munged by the contents of PATH, which is string
-# having a format:
-# "DIR[:DIR]:"
-# string "DIR[ DIR]" will be prepended to VARIABLE
-# ":DIR[:DIR]"
-# string "DIR[ DIR]" will be appended to VARIABLE
-# "DIRP[:DIRP]::[DIRA:]DIRA"
-# string "DIRP[ DIRP]" will be prepended to VARIABLE and string
-# "DIRA[ DIRA]" will be appended to VARIABLE
-# "DIR[:DIR]"
-# VARIABLE will be replaced by "DIR[ DIR]"
-func_munge_path_list ()
-{
- case x$2 in
- x)
- ;;
- *:)
- eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\"
- ;;
- x:*)
- eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\"
- ;;
- *::*)
- eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\"
- eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\"
- ;;
- *)
- eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\"
- ;;
- esac
-}
-
for ac_header in dlfcn.h
do :
ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default
@@ -9782,14 +9585,14 @@ if test "${enable_shared+set}" = set; then :
*)
enable_shared=no
# Look at the argument we got. We use all the common list separators.
- lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
for pkg in $enableval; do
- IFS=$lt_save_ifs
+ IFS="$lt_save_ifs"
if test "X$pkg" = "X$p"; then
enable_shared=yes
fi
done
- IFS=$lt_save_ifs
+ IFS="$lt_save_ifs"
;;
esac
else
@@ -9813,14 +9616,14 @@ if test "${enable_static+set}" = set; then :
*)
enable_static=no
# Look at the argument we got. We use all the common list separators.
- lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
for pkg in $enableval; do
- IFS=$lt_save_ifs
+ IFS="$lt_save_ifs"
if test "X$pkg" = "X$p"; then
enable_static=yes
fi
done
- IFS=$lt_save_ifs
+ IFS="$lt_save_ifs"
;;
esac
else
@@ -9844,14 +9647,14 @@ if test "${with_pic+set}" = set; then :
*)
pic_mode=default
# Look at the argument we got. We use all the common list separators.
- lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
for lt_pkg in $withval; do
- IFS=$lt_save_ifs
+ IFS="$lt_save_ifs"
if test "X$lt_pkg" = "X$lt_p"; then
pic_mode=yes
fi
done
- IFS=$lt_save_ifs
+ IFS="$lt_save_ifs"
;;
esac
else
@@ -9859,6 +9662,8 @@ else
fi
+test -z "$pic_mode" && pic_mode=default
+
@@ -9874,14 +9679,14 @@ if test "${enable_fast_install+set}" = set; then :
*)
enable_fast_install=no
# Look at the argument we got. We use all the common list separators.
- lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
for pkg in $enableval; do
- IFS=$lt_save_ifs
+ IFS="$lt_save_ifs"
if test "X$pkg" = "X$p"; then
enable_fast_install=yes
fi
done
- IFS=$lt_save_ifs
+ IFS="$lt_save_ifs"
;;
esac
else
@@ -9895,63 +9700,11 @@ fi
- shared_archive_member_spec=
-case $host,$enable_shared in
-power*-*-aix[5-9]*,yes)
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking which variant of shared library versioning to provide" >&5
-$as_echo_n "checking which variant of shared library versioning to provide... " >&6; }
-
-# Check whether --with-aix-soname was given.
-if test "${with_aix_soname+set}" = set; then :
- withval=$with_aix_soname; case $withval in
- aix|svr4|both)
- ;;
- *)
- as_fn_error $? "Unknown argument to --with-aix-soname" "$LINENO" 5
- ;;
- esac
- lt_cv_with_aix_soname=$with_aix_soname
-else
- if ${lt_cv_with_aix_soname+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- lt_cv_with_aix_soname=aix
-fi
-
- with_aix_soname=$lt_cv_with_aix_soname
-fi
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_aix_soname" >&5
-$as_echo "$with_aix_soname" >&6; }
- if test aix != "$with_aix_soname"; then
- # For the AIX way of multilib, we name the shared archive member
- # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o',
- # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File.
- # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag,
- # the AIX toolchain works better with OBJECT_MODE set (default 32).
- if test 64 = "${OBJECT_MODE-32}"; then
- shared_archive_member_spec=shr_64
- else
- shared_archive_member_spec=shr
- fi
- fi
- ;;
-*)
- with_aix_soname=aix
- ;;
-esac
-
-
-
-
-
-
-
# This can be used to rebuild libtool when needed
-LIBTOOL_DEPS=$ltmain
+LIBTOOL_DEPS="$ltmain"
# Always use our own libtool.
LIBTOOL='$(SHELL) $(top_builddir)/libtool'
@@ -10000,7 +9753,7 @@ test -z "$LN_S" && LN_S="ln -s"
-if test -n "${ZSH_VERSION+set}"; then
+if test -n "${ZSH_VERSION+set}" ; then
setopt NO_GLOB_SUBST
fi
@@ -10039,7 +9792,7 @@ aix3*)
# AIX sometimes has problems with the GCC collect2 program. For some
# reason, if we set the COLLECT_NAMES environment variable, the problems
# vanish in a puff of smoke.
- if test set != "${COLLECT_NAMES+set}"; then
+ if test "X${COLLECT_NAMES+set}" != Xset; then
COLLECT_NAMES=
export COLLECT_NAMES
fi
@@ -10050,14 +9803,14 @@ esac
ofile=libtool
can_build_shared=yes
-# All known linkers require a '.a' archive for static linking (except MSVC,
+# All known linkers require a `.a' archive for static linking (except MSVC,
# which needs '.lib').
libext=a
-with_gnu_ld=$lt_cv_prog_gnu_ld
+with_gnu_ld="$lt_cv_prog_gnu_ld"
-old_CC=$CC
-old_CFLAGS=$CFLAGS
+old_CC="$CC"
+old_CFLAGS="$CFLAGS"
# Set sane defaults for various variables
test -z "$CC" && CC=cc
@@ -10066,8 +9819,15 @@ test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS
test -z "$LD" && LD=ld
test -z "$ac_objext" && ac_objext=o
-func_cc_basename $compiler
-cc_basename=$func_cc_basename_result
+for cc_temp in $compiler""; do
+ case $cc_temp in
+ compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+ distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+ \-*) ;;
+ *) break;;
+ esac
+done
+cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
# Only perform the check for file, if the check method requires it
@@ -10082,22 +9842,22 @@ if ${lt_cv_path_MAGIC_CMD+:} false; then :
else
case $MAGIC_CMD in
[\\/*] | ?:[\\/]*)
- lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path.
+ lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
;;
*)
- lt_save_MAGIC_CMD=$MAGIC_CMD
- lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+ lt_save_MAGIC_CMD="$MAGIC_CMD"
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
ac_dummy="/usr/bin$PATH_SEPARATOR$PATH"
for ac_dir in $ac_dummy; do
- IFS=$lt_save_ifs
+ IFS="$lt_save_ifs"
test -z "$ac_dir" && ac_dir=.
- if test -f "$ac_dir/${ac_tool_prefix}file"; then
- lt_cv_path_MAGIC_CMD=$ac_dir/"${ac_tool_prefix}file"
+ if test -f $ac_dir/${ac_tool_prefix}file; then
+ lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file"
if test -n "$file_magic_test_file"; then
case $deplibs_check_method in
"file_magic "*)
file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
- MAGIC_CMD=$lt_cv_path_MAGIC_CMD
+ MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
$EGREP "$file_magic_regex" > /dev/null; then
:
@@ -10120,13 +9880,13 @@ _LT_EOF
break
fi
done
- IFS=$lt_save_ifs
- MAGIC_CMD=$lt_save_MAGIC_CMD
+ IFS="$lt_save_ifs"
+ MAGIC_CMD="$lt_save_MAGIC_CMD"
;;
esac
fi
-MAGIC_CMD=$lt_cv_path_MAGIC_CMD
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
if test -n "$MAGIC_CMD"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5
$as_echo "$MAGIC_CMD" >&6; }
@@ -10148,22 +9908,22 @@ if ${lt_cv_path_MAGIC_CMD+:} false; then :
else
case $MAGIC_CMD in
[\\/*] | ?:[\\/]*)
- lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path.
+ lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
;;
*)
- lt_save_MAGIC_CMD=$MAGIC_CMD
- lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+ lt_save_MAGIC_CMD="$MAGIC_CMD"
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
ac_dummy="/usr/bin$PATH_SEPARATOR$PATH"
for ac_dir in $ac_dummy; do
- IFS=$lt_save_ifs
+ IFS="$lt_save_ifs"
test -z "$ac_dir" && ac_dir=.
- if test -f "$ac_dir/file"; then
- lt_cv_path_MAGIC_CMD=$ac_dir/"file"
+ if test -f $ac_dir/file; then
+ lt_cv_path_MAGIC_CMD="$ac_dir/file"
if test -n "$file_magic_test_file"; then
case $deplibs_check_method in
"file_magic "*)
file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
- MAGIC_CMD=$lt_cv_path_MAGIC_CMD
+ MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
$EGREP "$file_magic_regex" > /dev/null; then
:
@@ -10186,13 +9946,13 @@ _LT_EOF
break
fi
done
- IFS=$lt_save_ifs
- MAGIC_CMD=$lt_save_MAGIC_CMD
+ IFS="$lt_save_ifs"
+ MAGIC_CMD="$lt_save_MAGIC_CMD"
;;
esac
fi
-MAGIC_CMD=$lt_cv_path_MAGIC_CMD
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
if test -n "$MAGIC_CMD"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5
$as_echo "$MAGIC_CMD" >&6; }
@@ -10213,7 +9973,7 @@ esac
# Use C for the default configuration in the libtool script
-lt_save_CC=$CC
+lt_save_CC="$CC"
ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@@ -10275,7 +10035,7 @@ if test -n "$compiler"; then
lt_prog_compiler_no_builtin_flag=
-if test yes = "$GCC"; then
+if test "$GCC" = yes; then
case $cc_basename in
nvcc*)
lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;;
@@ -10291,7 +10051,7 @@ else
lt_cv_prog_compiler_rtti_exceptions=no
ac_outfile=conftest.$ac_objext
echo "$lt_simple_compile_test_code" > conftest.$ac_ext
- lt_compiler_flag="-fno-rtti -fno-exceptions" ## exclude from sc_useless_quotes_in_assignment
+ lt_compiler_flag="-fno-rtti -fno-exceptions"
# Insert the option either (1) after the last *FLAGS variable, or
# (2) before a word containing "conftest.", or (3) at the end.
# Note that $ac_compile itself does not contain backslashes and begins
@@ -10321,7 +10081,7 @@ fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5
$as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; }
-if test yes = "$lt_cv_prog_compiler_rtti_exceptions"; then
+if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then
lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions"
else
:
@@ -10339,18 +10099,17 @@ lt_prog_compiler_pic=
lt_prog_compiler_static=
- if test yes = "$GCC"; then
+ if test "$GCC" = yes; then
lt_prog_compiler_wl='-Wl,'
lt_prog_compiler_static='-static'
case $host_os in
aix*)
# All AIX code is PIC.
- if test ia64 = "$host_cpu"; then
+ if test "$host_cpu" = ia64; then
# AIX 5 now supports IA64 processor
lt_prog_compiler_static='-Bstatic'
fi
- lt_prog_compiler_pic='-fPIC'
;;
amigaos*)
@@ -10361,8 +10120,8 @@ lt_prog_compiler_static=
;;
m68k)
# FIXME: we need at least 68020 code to build shared libraries, but
- # adding the '-m68020' flag to GCC prevents building anything better,
- # like '-m68040'.
+ # adding the `-m68020' flag to GCC prevents building anything better,
+ # like `-m68040'.
lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4'
;;
esac
@@ -10378,11 +10137,6 @@ lt_prog_compiler_static=
# Although the cygwin gcc ignores -fPIC, still need this for old-style
# (--disable-auto-import) libraries
lt_prog_compiler_pic='-DDLL_EXPORT'
- case $host_os in
- os2*)
- lt_prog_compiler_static='$wl-static'
- ;;
- esac
;;
darwin* | rhapsody*)
@@ -10453,7 +10207,7 @@ lt_prog_compiler_static=
case $host_os in
aix*)
lt_prog_compiler_wl='-Wl,'
- if test ia64 = "$host_cpu"; then
+ if test "$host_cpu" = ia64; then
# AIX 5 now supports IA64 processor
lt_prog_compiler_static='-Bstatic'
else
@@ -10461,29 +10215,10 @@ lt_prog_compiler_static=
fi
;;
- darwin* | rhapsody*)
- # PIC is the default on this platform
- # Common symbols not allowed in MH_DYLIB files
- lt_prog_compiler_pic='-fno-common'
- case $cc_basename in
- nagfor*)
- # NAG Fortran compiler
- lt_prog_compiler_wl='-Wl,-Wl,,'
- lt_prog_compiler_pic='-PIC'
- lt_prog_compiler_static='-Bstatic'
- ;;
- esac
- ;;
-
mingw* | cygwin* | pw32* | os2* | cegcc*)
# This hack is so that the source file can tell whether it is being
# built for inclusion in a dll (and should export symbols for example).
lt_prog_compiler_pic='-DDLL_EXPORT'
- case $host_os in
- os2*)
- lt_prog_compiler_static='$wl-static'
- ;;
- esac
;;
hpux9* | hpux10* | hpux11*)
@@ -10499,7 +10234,7 @@ lt_prog_compiler_static=
;;
esac
# Is there a better lt_prog_compiler_static that works with the bundled CC?
- lt_prog_compiler_static='$wl-a ${wl}archive'
+ lt_prog_compiler_static='${wl}-a ${wl}archive'
;;
irix5* | irix6* | nonstopux*)
@@ -10508,9 +10243,9 @@ lt_prog_compiler_static=
lt_prog_compiler_static='-non_shared'
;;
- linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+ linux* | k*bsd*-gnu | kopensolaris*-gnu)
case $cc_basename in
- # old Intel for x86_64, which still supported -KPIC.
+ # old Intel for x86_64 which still supported -KPIC.
ecc*)
lt_prog_compiler_wl='-Wl,'
lt_prog_compiler_pic='-KPIC'
@@ -10535,12 +10270,6 @@ lt_prog_compiler_static=
lt_prog_compiler_pic='-PIC'
lt_prog_compiler_static='-Bstatic'
;;
- tcc*)
- # Fabrice Bellard et al's Tiny C Compiler
- lt_prog_compiler_wl='-Wl,'
- lt_prog_compiler_pic='-fPIC'
- lt_prog_compiler_static='-static'
- ;;
pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)
# Portland Group compilers (*not* the Pentium gcc compiler,
# which looks to be a dead project)
@@ -10638,7 +10367,7 @@ lt_prog_compiler_static=
;;
sysv4*MP*)
- if test -d /usr/nec; then
+ if test -d /usr/nec ;then
lt_prog_compiler_pic='-Kconform_pic'
lt_prog_compiler_static='-Bstatic'
fi
@@ -10667,7 +10396,7 @@ lt_prog_compiler_static=
fi
case $host_os in
- # For platforms that do not support PIC, -DPIC is meaningless:
+ # For platforms which do not support PIC, -DPIC is meaningless:
*djgpp*)
lt_prog_compiler_pic=
;;
@@ -10699,7 +10428,7 @@ else
lt_cv_prog_compiler_pic_works=no
ac_outfile=conftest.$ac_objext
echo "$lt_simple_compile_test_code" > conftest.$ac_ext
- lt_compiler_flag="$lt_prog_compiler_pic -DPIC" ## exclude from sc_useless_quotes_in_assignment
+ lt_compiler_flag="$lt_prog_compiler_pic -DPIC"
# Insert the option either (1) after the last *FLAGS variable, or
# (2) before a word containing "conftest.", or (3) at the end.
# Note that $ac_compile itself does not contain backslashes and begins
@@ -10729,7 +10458,7 @@ fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5
$as_echo "$lt_cv_prog_compiler_pic_works" >&6; }
-if test yes = "$lt_cv_prog_compiler_pic_works"; then
+if test x"$lt_cv_prog_compiler_pic_works" = xyes; then
case $lt_prog_compiler_pic in
"" | " "*) ;;
*) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;;
@@ -10761,7 +10490,7 @@ if ${lt_cv_prog_compiler_static_works+:} false; then :
$as_echo_n "(cached) " >&6
else
lt_cv_prog_compiler_static_works=no
- save_LDFLAGS=$LDFLAGS
+ save_LDFLAGS="$LDFLAGS"
LDFLAGS="$LDFLAGS $lt_tmp_static_flag"
echo "$lt_simple_link_test_code" > conftest.$ac_ext
if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
@@ -10780,13 +10509,13 @@ else
fi
fi
$RM -r conftest*
- LDFLAGS=$save_LDFLAGS
+ LDFLAGS="$save_LDFLAGS"
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5
$as_echo "$lt_cv_prog_compiler_static_works" >&6; }
-if test yes = "$lt_cv_prog_compiler_static_works"; then
+if test x"$lt_cv_prog_compiler_static_works" = xyes; then
:
else
lt_prog_compiler_static=
@@ -10906,8 +10635,8 @@ $as_echo "$lt_cv_prog_compiler_c_o" >&6; }
-hard_links=nottested
-if test no = "$lt_cv_prog_compiler_c_o" && test no != "$need_locks"; then
+hard_links="nottested"
+if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then
# do not overwrite the value of need_locks provided by the user
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5
$as_echo_n "checking if we can lock with hard links... " >&6; }
@@ -10919,9 +10648,9 @@ $as_echo_n "checking if we can lock with hard links... " >&6; }
ln conftest.a conftest.b 2>/dev/null && hard_links=no
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5
$as_echo "$hard_links" >&6; }
- if test no = "$hard_links"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&5
-$as_echo "$as_me: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&2;}
+ if test "$hard_links" = no; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5
+$as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;}
need_locks=warn
fi
else
@@ -10964,9 +10693,9 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie
# included in the symbol list
include_expsyms=
# exclude_expsyms can be an extended regexp of symbols to exclude
- # it will be wrapped by ' (' and ')$', so one must not match beginning or
- # end of line. Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc',
- # as well as any symbol that contains 'd'.
+ # it will be wrapped by ` (' and `)$', so one must not match beginning or
+ # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
+ # as well as any symbol that contains `d'.
exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'
# Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
# platforms (ab)use it in PIC code, but their linkers get confused if
@@ -10981,7 +10710,7 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie
# FIXME: the MSVC++ port hasn't been tested in a loooong time
# When not using gcc, we currently assume that we are using
# Microsoft Visual C++.
- if test yes != "$GCC"; then
+ if test "$GCC" != yes; then
with_gnu_ld=no
fi
;;
@@ -10989,7 +10718,7 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie
# we just hope/assume this is gcc and not c89 (= MSVC++)
with_gnu_ld=yes
;;
- openbsd* | bitrig*)
+ openbsd*)
with_gnu_ld=no
;;
esac
@@ -10999,7 +10728,7 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie
# On some targets, GNU ld is compatible enough with the native linker
# that we're better off using the native interface for both.
lt_use_gnu_ld_interface=no
- if test yes = "$with_gnu_ld"; then
+ if test "$with_gnu_ld" = yes; then
case $host_os in
aix*)
# The AIX port of GNU ld has always aspired to compatibility
@@ -11021,24 +10750,24 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie
esac
fi
- if test yes = "$lt_use_gnu_ld_interface"; then
+ if test "$lt_use_gnu_ld_interface" = yes; then
# If archive_cmds runs LD, not CC, wlarc should be empty
- wlarc='$wl'
+ wlarc='${wl}'
# Set some defaults for GNU ld with shared library support. These
# are reset later if shared libraries are not supported. Putting them
# here allows them to be overridden if necessary.
runpath_var=LD_RUN_PATH
- hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
- export_dynamic_flag_spec='$wl--export-dynamic'
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ export_dynamic_flag_spec='${wl}--export-dynamic'
# ancient GNU ld didn't support --whole-archive et. al.
if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then
- whole_archive_flag_spec=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive'
+ whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
else
whole_archive_flag_spec=
fi
supports_anon_versioning=no
- case `$LD -v | $SED -e 's/(^)\+)\s\+//' 2>&1` in
+ case `$LD -v 2>&1` in
*GNU\ gold*) supports_anon_versioning=yes ;;
*\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11
*\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
@@ -11051,7 +10780,7 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie
case $host_os in
aix[3-9]*)
# On AIX/PPC, the GNU linker is very broken
- if test ia64 != "$host_cpu"; then
+ if test "$host_cpu" != ia64; then
ld_shlibs=no
cat <<_LT_EOF 1>&2
@@ -11070,7 +10799,7 @@ _LT_EOF
case $host_cpu in
powerpc)
# see comment about AmigaOS4 .so support
- archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
archive_expsym_cmds=''
;;
m68k)
@@ -11086,7 +10815,7 @@ _LT_EOF
allow_undefined_flag=unsupported
# Joseph Beckenbach <jrb3@best.com> says some releases of gcc
# support --undefined. This deserves some investigation. FIXME
- archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
else
ld_shlibs=no
fi
@@ -11096,7 +10825,7 @@ _LT_EOF
# _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless,
# as there is no search path for DLLs.
hardcode_libdir_flag_spec='-L$libdir'
- export_dynamic_flag_spec='$wl--export-all-symbols'
+ export_dynamic_flag_spec='${wl}--export-all-symbols'
allow_undefined_flag=unsupported
always_export_symbols=no
enable_shared_with_static_runtimes=yes
@@ -11104,89 +10833,61 @@ _LT_EOF
exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'
if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
- archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
- # If the export-symbols file already is a .def file, use it as
- # is; otherwise, prepend EXPORTS...
- archive_expsym_cmds='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then
- cp $export_symbols $output_objdir/$soname.def;
- else
- echo EXPORTS > $output_objdir/$soname.def;
- cat $export_symbols >> $output_objdir/$soname.def;
- fi~
- $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ # If the export-symbols file already is a .def file (1st line
+ # is EXPORTS), use it as is; otherwise, prepend...
+ archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+ cp $export_symbols $output_objdir/$soname.def;
+ else
+ echo EXPORTS > $output_objdir/$soname.def;
+ cat $export_symbols >> $output_objdir/$soname.def;
+ fi~
+ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
else
ld_shlibs=no
fi
;;
haiku*)
- archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
link_all_deplibs=yes
;;
- os2*)
- hardcode_libdir_flag_spec='-L$libdir'
- hardcode_minus_L=yes
- allow_undefined_flag=unsupported
- shrext_cmds=.dll
- archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
- $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
- $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
- $ECHO EXPORTS >> $output_objdir/$libname.def~
- emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~
- $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
- emximp -o $lib $output_objdir/$libname.def'
- archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
- $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
- $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
- $ECHO EXPORTS >> $output_objdir/$libname.def~
- prefix_cmds="$SED"~
- if test EXPORTS = "`$SED 1q $export_symbols`"; then
- prefix_cmds="$prefix_cmds -e 1d";
- fi~
- prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~
- cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~
- $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
- emximp -o $lib $output_objdir/$libname.def'
- old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
- enable_shared_with_static_runtimes=yes
- ;;
-
interix[3-9]*)
hardcode_direct=no
hardcode_shlibpath_var=no
- hardcode_libdir_flag_spec='$wl-rpath,$libdir'
- export_dynamic_flag_spec='$wl-E'
+ hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+ export_dynamic_flag_spec='${wl}-E'
# Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
# Instead, shared libraries are loaded at an image base (0x10000000 by
# default) and relocated if they conflict, which is a slow very memory
# consuming and fragmenting process. To avoid this, we pick a random,
# 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
# time. Moving up from 0x10000000 also allows more sbrk(2) space.
- archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
- archive_expsym_cmds='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
;;
gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu)
tmp_diet=no
- if test linux-dietlibc = "$host_os"; then
+ if test "$host_os" = linux-dietlibc; then
case $cc_basename in
diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn)
esac
fi
if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \
- && test no = "$tmp_diet"
+ && test "$tmp_diet" = no
then
tmp_addflag=' $pic_flag'
tmp_sharedflag='-shared'
case $cc_basename,$host_cpu in
pgcc*) # Portland Group C compiler
- whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+ whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
tmp_addflag=' $pic_flag'
;;
pgf77* | pgf90* | pgf95* | pgfortran*)
# Portland Group f77 and f90 compilers
- whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+ whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
tmp_addflag=' $pic_flag -Mnomain' ;;
ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64
tmp_addflag=' -i_dynamic' ;;
@@ -11197,47 +10898,42 @@ _LT_EOF
lf95*) # Lahey Fortran 8.1
whole_archive_flag_spec=
tmp_sharedflag='--shared' ;;
- nagfor*) # NAGFOR 5.3
- tmp_sharedflag='-Wl,-shared' ;;
xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below)
tmp_sharedflag='-qmkshrobj'
tmp_addflag= ;;
nvcc*) # Cuda Compiler Driver 2.2
- whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+ whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
compiler_needs_object=yes
;;
esac
case `$CC -V 2>&1 | sed 5q` in
*Sun\ C*) # Sun C 5.9
- whole_archive_flag_spec='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+ whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
compiler_needs_object=yes
tmp_sharedflag='-G' ;;
*Sun\ F*) # Sun Fortran 8.3
tmp_sharedflag='-G' ;;
esac
- archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- if test yes = "$supports_anon_versioning"; then
+ if test "x$supports_anon_versioning" = xyes; then
archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~
- cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
- echo "local: *; };" >> $output_objdir/$libname.ver~
- $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib'
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
fi
case $cc_basename in
- tcc*)
- export_dynamic_flag_spec='-rdynamic'
- ;;
xlf* | bgf* | bgxlf* | mpixlf*)
# IBM XL Fortran 10.1 on PPC cannot create shared libs itself
whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive'
- hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib'
- if test yes = "$supports_anon_versioning"; then
+ if test "x$supports_anon_versioning" = xyes; then
archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~
- cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
- echo "local: *; };" >> $output_objdir/$libname.ver~
- $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
fi
;;
esac
@@ -11251,8 +10947,8 @@ _LT_EOF
archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
wlarc=
else
- archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
- archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
fi
;;
@@ -11270,8 +10966,8 @@ _LT_EOF
_LT_EOF
elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
- archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
- archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
else
ld_shlibs=no
fi
@@ -11283,7 +10979,7 @@ _LT_EOF
ld_shlibs=no
cat <<_LT_EOF 1>&2
-*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot
+*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not
*** reliably create shared libraries on SCO systems. Therefore, libtool
*** is disabling shared libraries support. We urge you to upgrade GNU
*** binutils to release 2.16.91.0.3 or newer. Another option is to modify
@@ -11298,9 +10994,9 @@ _LT_EOF
# DT_RUNPATH tag from executables and libraries. But doing so
# requires that you compile everything twice, which is a pain.
if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
- hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
- archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
- archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
else
ld_shlibs=no
fi
@@ -11317,15 +11013,15 @@ _LT_EOF
*)
if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
- archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
- archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
else
ld_shlibs=no
fi
;;
esac
- if test no = "$ld_shlibs"; then
+ if test "$ld_shlibs" = no; then
runpath_var=
hardcode_libdir_flag_spec=
export_dynamic_flag_spec=
@@ -11341,7 +11037,7 @@ _LT_EOF
# Note: this linker hardcodes the directories in LIBPATH if there
# are no directories specified by -L.
hardcode_minus_L=yes
- if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then
+ if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then
# Neither direct hardcoding nor static linking is supported with a
# broken collect2.
hardcode_direct=unsupported
@@ -11349,57 +11045,34 @@ _LT_EOF
;;
aix[4-9]*)
- if test ia64 = "$host_cpu"; then
+ if test "$host_cpu" = ia64; then
# On IA64, the linker does run time linking by default, so we don't
# have to do anything special.
aix_use_runtimelinking=no
exp_sym_flag='-Bexport'
- no_entry_flag=
+ no_entry_flag=""
else
# If we're using GNU nm, then we don't want the "-C" option.
- # -C means demangle to GNU nm, but means don't demangle to AIX nm.
- # Without the "-l" option, or with the "-B" option, AIX nm treats
- # weak defined symbols like other global defined symbols, whereas
- # GNU nm marks them as "W".
- # While the 'weak' keyword is ignored in the Export File, we need
- # it in the Import File for the 'aix-soname' feature, so we have
- # to replace the "-B" option with "-P" for AIX nm.
+ # -C means demangle to AIX nm, but means don't demangle with GNU nm
+ # Also, AIX nm treats weak defined symbols like other global
+ # defined symbols, whereas GNU nm marks them as "W".
if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
- export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols'
+ export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
else
- export_symbols_cmds='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
+ export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
fi
aix_use_runtimelinking=no
# Test if we are trying to use run time linking or normal
# AIX style linking. If -brtl is somewhere in LDFLAGS, we
- # have runtime linking enabled, and use it for executables.
- # For shared libraries, we enable/disable runtime linking
- # depending on the kind of the shared library created -
- # when "with_aix_soname,aix_use_runtimelinking" is:
- # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables
- # "aix,yes" lib.so shared, rtl:yes, for executables
- # lib.a static archive
- # "both,no" lib.so.V(shr.o) shared, rtl:yes
- # lib.a(lib.so.V) shared, rtl:no, for executables
- # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables
- # lib.a(lib.so.V) shared, rtl:no
- # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables
- # lib.a static archive
+ # need to do runtime linking.
case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*)
for ld_flag in $LDFLAGS; do
- if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then
+ if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
aix_use_runtimelinking=yes
break
fi
done
- if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then
- # With aix-soname=svr4, we create the lib.so.V shared archives only,
- # so we don't have lib.a shared libs to link our executables.
- # We have to force runtime linking in this case.
- aix_use_runtimelinking=yes
- LDFLAGS="$LDFLAGS -Wl,-brtl"
- fi
;;
esac
@@ -11418,21 +11091,13 @@ _LT_EOF
hardcode_direct_absolute=yes
hardcode_libdir_separator=':'
link_all_deplibs=yes
- file_list_spec='$wl-f,'
- case $with_aix_soname,$aix_use_runtimelinking in
- aix,*) ;; # traditional, no import file
- svr4,* | *,yes) # use import file
- # The Import File defines what to hardcode.
- hardcode_direct=no
- hardcode_direct_absolute=no
- ;;
- esac
+ file_list_spec='${wl}-f,'
- if test yes = "$GCC"; then
+ if test "$GCC" = yes; then
case $host_os in aix4.[012]|aix4.[012].*)
# We only want to do this on AIX 4.2 and lower, the check
# below for broken collect2 doesn't work under 4.3+
- collect2name=`$CC -print-prog-name=collect2`
+ collect2name=`${CC} -print-prog-name=collect2`
if test -f "$collect2name" &&
strings "$collect2name" | $GREP resolve_lib_name >/dev/null
then
@@ -11451,42 +11116,35 @@ _LT_EOF
;;
esac
shared_flag='-shared'
- if test yes = "$aix_use_runtimelinking"; then
- shared_flag="$shared_flag "'$wl-G'
+ if test "$aix_use_runtimelinking" = yes; then
+ shared_flag="$shared_flag "'${wl}-G'
fi
- # Need to ensure runtime linking is disabled for the traditional
- # shared library, or the linker may eventually find shared libraries
- # /with/ Import File - we do not want to mix them.
- shared_flag_aix='-shared'
- shared_flag_svr4='-shared $wl-G'
else
# not using gcc
- if test ia64 = "$host_cpu"; then
+ if test "$host_cpu" = ia64; then
# VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
# chokes on -Wl,-G. The following line is correct:
shared_flag='-G'
else
- if test yes = "$aix_use_runtimelinking"; then
- shared_flag='$wl-G'
+ if test "$aix_use_runtimelinking" = yes; then
+ shared_flag='${wl}-G'
else
- shared_flag='$wl-bM:SRE'
+ shared_flag='${wl}-bM:SRE'
fi
- shared_flag_aix='$wl-bM:SRE'
- shared_flag_svr4='$wl-G'
fi
fi
- export_dynamic_flag_spec='$wl-bexpall'
+ export_dynamic_flag_spec='${wl}-bexpall'
# It seems that -bexpall does not export symbols beginning with
# underscore (_), so it is better to generate a list of symbols to export.
always_export_symbols=yes
- if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then
+ if test "$aix_use_runtimelinking" = yes; then
# Warning - without using the other runtime loading flags (-brtl),
# -berok will link without error, but may produce a broken library.
allow_undefined_flag='-berok'
# Determine the default libpath from the value encoded in an
# empty executable.
- if test set = "${lt_cv_aix_libpath+set}"; then
+ if test "${lt_cv_aix_libpath+set}" = set; then
aix_libpath=$lt_cv_aix_libpath
else
if ${lt_cv_aix_libpath_+:} false; then :
@@ -11521,7 +11179,7 @@ fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
if test -z "$lt_cv_aix_libpath_"; then
- lt_cv_aix_libpath_=/usr/lib:/lib
+ lt_cv_aix_libpath_="/usr/lib:/lib"
fi
fi
@@ -11529,17 +11187,17 @@ fi
aix_libpath=$lt_cv_aix_libpath_
fi
- hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath"
- archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag
+ hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
+ archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
else
- if test ia64 = "$host_cpu"; then
- hardcode_libdir_flag_spec='$wl-R $libdir:/usr/lib:/lib'
+ if test "$host_cpu" = ia64; then
+ hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib'
allow_undefined_flag="-z nodefs"
- archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols"
+ archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
else
# Determine the default libpath from the value encoded in an
# empty executable.
- if test set = "${lt_cv_aix_libpath+set}"; then
+ if test "${lt_cv_aix_libpath+set}" = set; then
aix_libpath=$lt_cv_aix_libpath
else
if ${lt_cv_aix_libpath_+:} false; then :
@@ -11574,7 +11232,7 @@ fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
if test -z "$lt_cv_aix_libpath_"; then
- lt_cv_aix_libpath_=/usr/lib:/lib
+ lt_cv_aix_libpath_="/usr/lib:/lib"
fi
fi
@@ -11582,33 +11240,21 @@ fi
aix_libpath=$lt_cv_aix_libpath_
fi
- hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath"
+ hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
# Warning - without using the other run time loading flags,
# -berok will link without error, but may produce a broken library.
- no_undefined_flag=' $wl-bernotok'
- allow_undefined_flag=' $wl-berok'
- if test yes = "$with_gnu_ld"; then
+ no_undefined_flag=' ${wl}-bernotok'
+ allow_undefined_flag=' ${wl}-berok'
+ if test "$with_gnu_ld" = yes; then
# We only use this code for GNU lds that support --whole-archive.
- whole_archive_flag_spec='$wl--whole-archive$convenience $wl--no-whole-archive'
+ whole_archive_flag_spec='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
else
# Exported symbols can be pulled into shared objects from archives
whole_archive_flag_spec='$convenience'
fi
archive_cmds_need_lc=yes
- archive_expsym_cmds='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d'
- # -brtl affects multiple linker settings, -berok does not and is overridden later
- compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([, ]\\)%-berok\\1%g"`'
- if test svr4 != "$with_aix_soname"; then
- # This is similar to how AIX traditionally builds its shared libraries.
- archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname'
- fi
- if test aix != "$with_aix_soname"; then
- archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp'
- else
- # used by -dlpreopen to get the symbols
- archive_expsym_cmds="$archive_expsym_cmds"'~$MV $output_objdir/$realname.d/$soname $output_objdir'
- fi
- archive_expsym_cmds="$archive_expsym_cmds"'~$RM -r $output_objdir/$realname.d'
+ # This is similar to how AIX traditionally builds its shared libraries.
+ archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
fi
fi
;;
@@ -11617,7 +11263,7 @@ fi
case $host_cpu in
powerpc)
# see comment about AmigaOS4 .so support
- archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
archive_expsym_cmds=''
;;
m68k)
@@ -11647,17 +11293,16 @@ fi
# Tell ltmain to make .lib files, not .a files.
libext=lib
# Tell ltmain to make .dll files, not .so files.
- shrext_cmds=.dll
+ shrext_cmds=".dll"
# FIXME: Setting linknames here is a bad hack.
- archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames='
- archive_expsym_cmds='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then
- cp "$export_symbols" "$output_objdir/$soname.def";
- echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp";
- else
- $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp;
- fi~
- $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
- linknames='
+ archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames='
+ archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+ sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp;
+ else
+ sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp;
+ fi~
+ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+ linknames='
# The linker will not automatically build a static lib if we build a DLL.
# _LT_TAGVAR(old_archive_from_new_cmds, )='true'
enable_shared_with_static_runtimes=yes
@@ -11666,18 +11311,18 @@ fi
# Don't use ranlib
old_postinstall_cmds='chmod 644 $oldlib'
postlink_cmds='lt_outputfile="@OUTPUT@"~
- lt_tool_outputfile="@TOOL_OUTPUT@"~
- case $lt_outputfile in
- *.exe|*.EXE) ;;
- *)
- lt_outputfile=$lt_outputfile.exe
- lt_tool_outputfile=$lt_tool_outputfile.exe
- ;;
- esac~
- if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then
- $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
- $RM "$lt_outputfile.manifest";
- fi'
+ lt_tool_outputfile="@TOOL_OUTPUT@"~
+ case $lt_outputfile in
+ *.exe|*.EXE) ;;
+ *)
+ lt_outputfile="$lt_outputfile.exe"
+ lt_tool_outputfile="$lt_tool_outputfile.exe"
+ ;;
+ esac~
+ if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then
+ $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+ $RM "$lt_outputfile.manifest";
+ fi'
;;
*)
# Assume MSVC wrapper
@@ -11686,7 +11331,7 @@ fi
# Tell ltmain to make .lib files, not .a files.
libext=lib
# Tell ltmain to make .dll files, not .so files.
- shrext_cmds=.dll
+ shrext_cmds=".dll"
# FIXME: Setting linknames here is a bad hack.
archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames='
# The linker will automatically build a .lib file if we build a DLL.
@@ -11705,24 +11350,24 @@ fi
hardcode_direct=no
hardcode_automatic=yes
hardcode_shlibpath_var=unsupported
- if test yes = "$lt_cv_ld_force_load"; then
- whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
+ if test "$lt_cv_ld_force_load" = "yes"; then
+ whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
else
whole_archive_flag_spec=''
fi
link_all_deplibs=yes
- allow_undefined_flag=$_lt_dar_allow_undefined
+ allow_undefined_flag="$_lt_dar_allow_undefined"
case $cc_basename in
- ifort*|nagfor*) _lt_dar_can_shared=yes ;;
+ ifort*) _lt_dar_can_shared=yes ;;
*) _lt_dar_can_shared=$GCC ;;
esac
- if test yes = "$_lt_dar_can_shared"; then
+ if test "$_lt_dar_can_shared" = "yes"; then
output_verbose_link_cmd=func_echo_all
- archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil"
- module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil"
- archive_expsym_cmds="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil"
- module_expsym_cmds="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil"
+ archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
+ module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}"
+ archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}"
+ module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}"
else
ld_shlibs=no
@@ -11764,33 +11409,33 @@ fi
;;
hpux9*)
- if test yes = "$GCC"; then
- archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
+ if test "$GCC" = yes; then
+ archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
else
- archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
+ archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
fi
- hardcode_libdir_flag_spec='$wl+b $wl$libdir'
+ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
hardcode_libdir_separator=:
hardcode_direct=yes
# hardcode_minus_L: Not really in the search PATH,
# but as the default location of the library.
hardcode_minus_L=yes
- export_dynamic_flag_spec='$wl-E'
+ export_dynamic_flag_spec='${wl}-E'
;;
hpux10*)
- if test yes,no = "$GCC,$with_gnu_ld"; then
- archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ if test "$GCC" = yes && test "$with_gnu_ld" = no; then
+ archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
else
archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
fi
- if test no = "$with_gnu_ld"; then
- hardcode_libdir_flag_spec='$wl+b $wl$libdir'
+ if test "$with_gnu_ld" = no; then
+ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
hardcode_libdir_separator=:
hardcode_direct=yes
hardcode_direct_absolute=yes
- export_dynamic_flag_spec='$wl-E'
+ export_dynamic_flag_spec='${wl}-E'
# hardcode_minus_L: Not really in the search PATH,
# but as the default location of the library.
hardcode_minus_L=yes
@@ -11798,25 +11443,25 @@ fi
;;
hpux11*)
- if test yes,no = "$GCC,$with_gnu_ld"; then
+ if test "$GCC" = yes && test "$with_gnu_ld" = no; then
case $host_cpu in
hppa*64*)
- archive_cmds='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
;;
ia64*)
- archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
;;
*)
- archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
;;
esac
else
case $host_cpu in
hppa*64*)
- archive_cmds='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
;;
ia64*)
- archive_cmds='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
;;
*)
@@ -11828,7 +11473,7 @@ if ${lt_cv_prog_compiler__b+:} false; then :
$as_echo_n "(cached) " >&6
else
lt_cv_prog_compiler__b=no
- save_LDFLAGS=$LDFLAGS
+ save_LDFLAGS="$LDFLAGS"
LDFLAGS="$LDFLAGS -b"
echo "$lt_simple_link_test_code" > conftest.$ac_ext
if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
@@ -11847,14 +11492,14 @@ else
fi
fi
$RM -r conftest*
- LDFLAGS=$save_LDFLAGS
+ LDFLAGS="$save_LDFLAGS"
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5
$as_echo "$lt_cv_prog_compiler__b" >&6; }
-if test yes = "$lt_cv_prog_compiler__b"; then
- archive_cmds='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+if test x"$lt_cv_prog_compiler__b" = xyes; then
+ archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
else
archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
fi
@@ -11862,8 +11507,8 @@ fi
;;
esac
fi
- if test no = "$with_gnu_ld"; then
- hardcode_libdir_flag_spec='$wl+b $wl$libdir'
+ if test "$with_gnu_ld" = no; then
+ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
hardcode_libdir_separator=:
case $host_cpu in
@@ -11874,7 +11519,7 @@ fi
*)
hardcode_direct=yes
hardcode_direct_absolute=yes
- export_dynamic_flag_spec='$wl-E'
+ export_dynamic_flag_spec='${wl}-E'
# hardcode_minus_L: Not really in the search PATH,
# but as the default location of the library.
@@ -11885,8 +11530,8 @@ fi
;;
irix5* | irix6* | nonstopux*)
- if test yes = "$GCC"; then
- archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+ if test "$GCC" = yes; then
+ archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
# Try to use the -exported_symbol ld option, if it does not
# work, assume that -exports_file does not work either and
# implicitly export all symbols.
@@ -11896,8 +11541,8 @@ $as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >
if ${lt_cv_irix_exported_symbol+:} false; then :
$as_echo_n "(cached) " >&6
else
- save_LDFLAGS=$LDFLAGS
- LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null"
+ save_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
int foo (void) { return 0; }
@@ -11909,34 +11554,24 @@ else
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
- LDFLAGS=$save_LDFLAGS
+ LDFLAGS="$save_LDFLAGS"
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5
$as_echo "$lt_cv_irix_exported_symbol" >&6; }
- if test yes = "$lt_cv_irix_exported_symbol"; then
- archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib'
+ if test "$lt_cv_irix_exported_symbol" = yes; then
+ archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib'
fi
else
- archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
- archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib'
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib'
fi
archive_cmds_need_lc='no'
- hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
hardcode_libdir_separator=:
inherit_rpath=yes
link_all_deplibs=yes
;;
- linux*)
- case $cc_basename in
- tcc*)
- # Fabrice Bellard et al's Tiny C Compiler
- ld_shlibs=yes
- archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
- ;;
- esac
- ;;
-
netbsd*)
if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out
@@ -11951,7 +11586,7 @@ $as_echo "$lt_cv_irix_exported_symbol" >&6; }
newsos6)
archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
hardcode_direct=yes
- hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
hardcode_libdir_separator=:
hardcode_shlibpath_var=no
;;
@@ -11959,19 +11594,27 @@ $as_echo "$lt_cv_irix_exported_symbol" >&6; }
*nto* | *qnx*)
;;
- openbsd* | bitrig*)
+ openbsd*)
if test -f /usr/libexec/ld.so; then
hardcode_direct=yes
hardcode_shlibpath_var=no
hardcode_direct_absolute=yes
- if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
- archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols'
- hardcode_libdir_flag_spec='$wl-rpath,$libdir'
- export_dynamic_flag_spec='$wl-E'
+ archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols'
+ hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+ export_dynamic_flag_spec='${wl}-E'
else
- archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
- hardcode_libdir_flag_spec='$wl-rpath,$libdir'
+ case $host_os in
+ openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_libdir_flag_spec='-R$libdir'
+ ;;
+ *)
+ archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+ ;;
+ esac
fi
else
ld_shlibs=no
@@ -11982,53 +11625,33 @@ $as_echo "$lt_cv_irix_exported_symbol" >&6; }
hardcode_libdir_flag_spec='-L$libdir'
hardcode_minus_L=yes
allow_undefined_flag=unsupported
- shrext_cmds=.dll
- archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
- $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
- $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
- $ECHO EXPORTS >> $output_objdir/$libname.def~
- emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~
- $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
- emximp -o $lib $output_objdir/$libname.def'
- archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
- $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
- $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
- $ECHO EXPORTS >> $output_objdir/$libname.def~
- prefix_cmds="$SED"~
- if test EXPORTS = "`$SED 1q $export_symbols`"; then
- prefix_cmds="$prefix_cmds -e 1d";
- fi~
- prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~
- cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~
- $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
- emximp -o $lib $output_objdir/$libname.def'
- old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
- enable_shared_with_static_runtimes=yes
+ archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
+ old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
;;
osf3*)
- if test yes = "$GCC"; then
- allow_undefined_flag=' $wl-expect_unresolved $wl\*'
- archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+ if test "$GCC" = yes; then
+ allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
else
allow_undefined_flag=' -expect_unresolved \*'
- archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
fi
archive_cmds_need_lc='no'
- hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
hardcode_libdir_separator=:
;;
osf4* | osf5*) # as osf3* with the addition of -msym flag
- if test yes = "$GCC"; then
- allow_undefined_flag=' $wl-expect_unresolved $wl\*'
- archive_cmds='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
- hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
+ if test "$GCC" = yes; then
+ allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+ archive_cmds='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
else
allow_undefined_flag=' -expect_unresolved \*'
- archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~
- $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp'
+ $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp'
# Both c and cxx compiler support -rpath directly
hardcode_libdir_flag_spec='-rpath $libdir'
@@ -12039,24 +11662,24 @@ $as_echo "$lt_cv_irix_exported_symbol" >&6; }
solaris*)
no_undefined_flag=' -z defs'
- if test yes = "$GCC"; then
- wlarc='$wl'
- archive_cmds='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags'
+ if test "$GCC" = yes; then
+ wlarc='${wl}'
+ archive_cmds='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
- $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+ $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
else
case `$CC -V 2>&1` in
*"Compilers 5.0"*)
wlarc=''
- archive_cmds='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
- $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp'
+ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp'
;;
*)
- wlarc='$wl'
- archive_cmds='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags'
+ wlarc='${wl}'
+ archive_cmds='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags'
archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
- $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+ $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
;;
esac
fi
@@ -12066,11 +11689,11 @@ $as_echo "$lt_cv_irix_exported_symbol" >&6; }
solaris2.[0-5] | solaris2.[0-5].*) ;;
*)
# The compiler driver will combine and reorder linker options,
- # but understands '-z linker_flag'. GCC discards it without '$wl',
+ # but understands `-z linker_flag'. GCC discards it without `$wl',
# but is careful enough not to reorder.
# Supported since Solaris 2.6 (maybe 2.5.1?)
- if test yes = "$GCC"; then
- whole_archive_flag_spec='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract'
+ if test "$GCC" = yes; then
+ whole_archive_flag_spec='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
else
whole_archive_flag_spec='-z allextract$convenience -z defaultextract'
fi
@@ -12080,10 +11703,10 @@ $as_echo "$lt_cv_irix_exported_symbol" >&6; }
;;
sunos4*)
- if test sequent = "$host_vendor"; then
+ if test "x$host_vendor" = xsequent; then
# Use $CC to link under sequent, because it throws in some extra .o
# files that make .init and .fini sections work.
- archive_cmds='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'
else
archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
fi
@@ -12132,43 +11755,43 @@ $as_echo "$lt_cv_irix_exported_symbol" >&6; }
;;
sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
- no_undefined_flag='$wl-z,text'
+ no_undefined_flag='${wl}-z,text'
archive_cmds_need_lc=no
hardcode_shlibpath_var=no
runpath_var='LD_RUN_PATH'
- if test yes = "$GCC"; then
- archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ if test "$GCC" = yes; then
+ archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
else
- archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
fi
;;
sysv5* | sco3.2v5* | sco5v6*)
- # Note: We CANNOT use -z defs as we might desire, because we do not
+ # Note: We can NOT use -z defs as we might desire, because we do not
# link with -lc, and that would cause any symbols used from libc to
# always be unresolved, which means just about no library would
# ever link correctly. If we're not using GNU ld we use -z text
# though, which does catch some bad symbols but isn't as heavy-handed
# as -z defs.
- no_undefined_flag='$wl-z,text'
- allow_undefined_flag='$wl-z,nodefs'
+ no_undefined_flag='${wl}-z,text'
+ allow_undefined_flag='${wl}-z,nodefs'
archive_cmds_need_lc=no
hardcode_shlibpath_var=no
- hardcode_libdir_flag_spec='$wl-R,$libdir'
+ hardcode_libdir_flag_spec='${wl}-R,$libdir'
hardcode_libdir_separator=':'
link_all_deplibs=yes
- export_dynamic_flag_spec='$wl-Bexport'
+ export_dynamic_flag_spec='${wl}-Bexport'
runpath_var='LD_RUN_PATH'
- if test yes = "$GCC"; then
- archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ if test "$GCC" = yes; then
+ archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
else
- archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
fi
;;
@@ -12183,10 +11806,10 @@ $as_echo "$lt_cv_irix_exported_symbol" >&6; }
;;
esac
- if test sni = "$host_vendor"; then
+ if test x$host_vendor = xsni; then
case $host in
sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
- export_dynamic_flag_spec='$wl-Blargedynsym'
+ export_dynamic_flag_spec='${wl}-Blargedynsym'
;;
esac
fi
@@ -12194,7 +11817,7 @@ $as_echo "$lt_cv_irix_exported_symbol" >&6; }
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5
$as_echo "$ld_shlibs" >&6; }
-test no = "$ld_shlibs" && can_build_shared=no
+test "$ld_shlibs" = no && can_build_shared=no
with_gnu_ld=$with_gnu_ld
@@ -12220,7 +11843,7 @@ x|xyes)
# Assume -lc should be added
archive_cmds_need_lc=yes
- if test yes,yes = "$GCC,$enable_shared"; then
+ if test "$enable_shared" = yes && test "$GCC" = yes; then
case $archive_cmds in
*'~'*)
# FIXME: we may have to deal with multi-command sequences.
@@ -12435,14 +12058,14 @@ esac
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5
$as_echo_n "checking dynamic linker characteristics... " >&6; }
-if test yes = "$GCC"; then
+if test "$GCC" = yes; then
case $host_os in
- darwin*) lt_awk_arg='/^libraries:/,/LR/' ;;
- *) lt_awk_arg='/^libraries:/' ;;
+ darwin*) lt_awk_arg="/^libraries:/,/LR/" ;;
+ *) lt_awk_arg="/^libraries:/" ;;
esac
case $host_os in
- mingw* | cegcc*) lt_sed_strip_eq='s|=\([A-Za-z]:\)|\1|g' ;;
- *) lt_sed_strip_eq='s|=/|/|g' ;;
+ mingw* | cegcc*) lt_sed_strip_eq="s,=\([A-Za-z]:\),\1,g" ;;
+ *) lt_sed_strip_eq="s,=/,/,g" ;;
esac
lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq`
case $lt_search_path_spec in
@@ -12458,35 +12081,28 @@ if test yes = "$GCC"; then
;;
esac
# Ok, now we have the path, separated by spaces, we can step through it
- # and add multilib dir if necessary...
+ # and add multilib dir if necessary.
lt_tmp_lt_search_path_spec=
- lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null`
- # ...but if some path component already ends with the multilib dir we assume
- # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer).
- case "$lt_multi_os_dir; $lt_search_path_spec " in
- "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*)
- lt_multi_os_dir=
- ;;
- esac
+ lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null`
for lt_sys_path in $lt_search_path_spec; do
- if test -d "$lt_sys_path$lt_multi_os_dir"; then
- lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir"
- elif test -n "$lt_multi_os_dir"; then
+ if test -d "$lt_sys_path/$lt_multi_os_dir"; then
+ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir"
+ else
test -d "$lt_sys_path" && \
lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path"
fi
done
lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk '
-BEGIN {RS = " "; FS = "/|\n";} {
- lt_foo = "";
- lt_count = 0;
+BEGIN {RS=" "; FS="/|\n";} {
+ lt_foo="";
+ lt_count=0;
for (lt_i = NF; lt_i > 0; lt_i--) {
if ($lt_i != "" && $lt_i != ".") {
if ($lt_i == "..") {
lt_count++;
} else {
if (lt_count == 0) {
- lt_foo = "/" $lt_i lt_foo;
+ lt_foo="/" $lt_i lt_foo;
} else {
lt_count--;
}
@@ -12500,7 +12116,7 @@ BEGIN {RS = " "; FS = "/|\n";} {
# for these hosts.
case $host_os in
mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\
- $SED 's|/\([A-Za-z]:\)|\1|g'` ;;
+ $SED 's,/\([A-Za-z]:\),\1,g'` ;;
esac
sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP`
else
@@ -12509,7 +12125,7 @@ fi
library_names_spec=
libname_spec='lib$name'
soname_spec=
-shrext_cmds=.so
+shrext_cmds=".so"
postinstall_cmds=
postuninstall_cmds=
finish_cmds=
@@ -12526,16 +12142,14 @@ hardcode_into_libs=no
# flags to be left without arguments
need_version=unknown
-
-
case $host_os in
aix3*)
version_type=linux # correct to gnu/linux during the next big refactor
- library_names_spec='$libname$release$shared_ext$versuffix $libname.a'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
shlibpath_var=LIBPATH
# AIX 3 has no versioning support, so we append a major version to the name.
- soname_spec='$libname$release$shared_ext$major'
+ soname_spec='${libname}${release}${shared_ext}$major'
;;
aix[4-9]*)
@@ -12543,91 +12157,41 @@ aix[4-9]*)
need_lib_prefix=no
need_version=no
hardcode_into_libs=yes
- if test ia64 = "$host_cpu"; then
+ if test "$host_cpu" = ia64; then
# AIX 5 supports IA64
- library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext'
+ library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
shlibpath_var=LD_LIBRARY_PATH
else
# With GCC up to 2.95.x, collect2 would create an import file
# for dependence libraries. The import file would start with
- # the line '#! .'. This would cause the generated library to
- # depend on '.', always an invalid library. This was fixed in
+ # the line `#! .'. This would cause the generated library to
+ # depend on `.', always an invalid library. This was fixed in
# development snapshots of GCC prior to 3.0.
case $host_os in
aix4 | aix4.[01] | aix4.[01].*)
if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
echo ' yes '
- echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then
+ echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then
:
else
can_build_shared=no
fi
;;
esac
- # Using Import Files as archive members, it is possible to support
- # filename-based versioning of shared library archives on AIX. While
- # this would work for both with and without runtime linking, it will
- # prevent static linking of such archives. So we do filename-based
- # shared library versioning with .so extension only, which is used
- # when both runtime linking and shared linking is enabled.
- # Unfortunately, runtime linking may impact performance, so we do
- # not want this to be the default eventually. Also, we use the
- # versioned .so libs for executables only if there is the -brtl
- # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only.
- # To allow for filename-based versioning support, we need to create
- # libNAME.so.V as an archive file, containing:
- # *) an Import File, referring to the versioned filename of the
- # archive as well as the shared archive member, telling the
- # bitwidth (32 or 64) of that shared object, and providing the
- # list of exported symbols of that shared object, eventually
- # decorated with the 'weak' keyword
- # *) the shared object with the F_LOADONLY flag set, to really avoid
- # it being seen by the linker.
- # At run time we better use the real file rather than another symlink,
- # but for link time we create the symlink libNAME.so -> libNAME.so.V
-
- case $with_aix_soname,$aix_use_runtimelinking in
- # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct
+ # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
# soname into executable. Probably we can add versioning support to
# collect2, so additional links can be useful in future.
- aix,yes) # traditional libtool
- dynamic_linker='AIX unversionable lib.so'
+ if test "$aix_use_runtimelinking" = yes; then
# If using run time linking (on AIX 4.2 or later) use lib<name>.so
# instead of lib<name>.a to let people know that these are not
# typical AIX shared libraries.
- library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
- ;;
- aix,no) # traditional AIX only
- dynamic_linker='AIX lib.a(lib.so.V)'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ else
# We preserve .a as extension for shared libraries through AIX4.2
# and later when we are not doing run time linking.
- library_names_spec='$libname$release.a $libname.a'
- soname_spec='$libname$release$shared_ext$major'
- ;;
- svr4,*) # full svr4 only
- dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o)"
- library_names_spec='$libname$release$shared_ext$major $libname$shared_ext'
- # We do not specify a path in Import Files, so LIBPATH fires.
- shlibpath_overrides_runpath=yes
- ;;
- *,yes) # both, prefer svr4
- dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o), lib.a(lib.so.V)"
- library_names_spec='$libname$release$shared_ext$major $libname$shared_ext'
- # unpreferred sharedlib libNAME.a needs extra handling
- postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"'
- postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"'
- # We do not specify a path in Import Files, so LIBPATH fires.
- shlibpath_overrides_runpath=yes
- ;;
- *,no) # both, prefer aix
- dynamic_linker="AIX lib.a(lib.so.V), lib.so.V($shared_archive_member_spec.o)"
- library_names_spec='$libname$release.a $libname.a'
- soname_spec='$libname$release$shared_ext$major'
- # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling
- postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)'
- postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"'
- ;;
- esac
+ library_names_spec='${libname}${release}.a $libname.a'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ fi
shlibpath_var=LIBPATH
fi
;;
@@ -12637,18 +12201,18 @@ amigaos*)
powerpc)
# Since July 2007 AmigaOS4 officially supports .so libraries.
# When compiling the executable, add -use-dynld -Lsobjs: to the compileline.
- library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
;;
m68k)
library_names_spec='$libname.ixlibrary $libname.a'
# Create ${libname}_ixlibrary.a entries in /sys/libs.
- finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+ finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
;;
esac
;;
beos*)
- library_names_spec='$libname$shared_ext'
+ library_names_spec='${libname}${shared_ext}'
dynamic_linker="$host_os ld.so"
shlibpath_var=LIBRARY_PATH
;;
@@ -12656,8 +12220,8 @@ beos*)
bsdi[45]*)
version_type=linux # correct to gnu/linux during the next big refactor
need_version=no
- library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
- soname_spec='$libname$release$shared_ext$major'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
shlibpath_var=LD_LIBRARY_PATH
sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
@@ -12669,7 +12233,7 @@ bsdi[45]*)
cygwin* | mingw* | pw32* | cegcc*)
version_type=windows
- shrext_cmds=.dll
+ shrext_cmds=".dll"
need_version=no
need_lib_prefix=no
@@ -12678,8 +12242,8 @@ cygwin* | mingw* | pw32* | cegcc*)
# gcc
library_names_spec='$libname.dll.a'
# DLL is installed to $(libdir)/../bin by postinstall_cmds
- postinstall_cmds='base_file=`basename \$file`~
- dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~
+ postinstall_cmds='base_file=`basename \${file}`~
+ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
dldir=$destdir/`dirname \$dlpath`~
test -d \$dldir || mkdir -p \$dldir~
$install_prog $dir/$dlname \$dldir/$dlname~
@@ -12695,17 +12259,17 @@ cygwin* | mingw* | pw32* | cegcc*)
case $host_os in
cygwin*)
# Cygwin DLLs use 'cyg' prefix rather than 'lib'
- soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext'
+ soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"
;;
mingw* | cegcc*)
# MinGW DLLs use traditional 'lib' prefix
- soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext'
+ soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
;;
pw32*)
# pw32 DLLs use 'pw' prefix rather than 'lib'
- library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext'
+ library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
;;
esac
dynamic_linker='Win32 ld.exe'
@@ -12714,8 +12278,8 @@ cygwin* | mingw* | pw32* | cegcc*)
*,cl*)
# Native MSVC
libname_spec='$name'
- soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext'
- library_names_spec='$libname.dll.lib'
+ soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+ library_names_spec='${libname}.dll.lib'
case $build_os in
mingw*)
@@ -12742,7 +12306,7 @@ cygwin* | mingw* | pw32* | cegcc*)
sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
;;
*)
- sys_lib_search_path_spec=$LIB
+ sys_lib_search_path_spec="$LIB"
if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then
# It is most probably a Windows format PATH.
sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
@@ -12755,8 +12319,8 @@ cygwin* | mingw* | pw32* | cegcc*)
esac
# DLL is installed to $(libdir)/../bin by postinstall_cmds
- postinstall_cmds='base_file=`basename \$file`~
- dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~
+ postinstall_cmds='base_file=`basename \${file}`~
+ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
dldir=$destdir/`dirname \$dlpath`~
test -d \$dldir || mkdir -p \$dldir~
$install_prog $dir/$dlname \$dldir/$dlname'
@@ -12769,7 +12333,7 @@ cygwin* | mingw* | pw32* | cegcc*)
*)
# Assume MSVC wrapper
- library_names_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext $libname.lib'
+ library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib'
dynamic_linker='Win32 ld.exe'
;;
esac
@@ -12782,8 +12346,8 @@ darwin* | rhapsody*)
version_type=darwin
need_lib_prefix=no
need_version=no
- library_names_spec='$libname$release$major$shared_ext $libname$shared_ext'
- soname_spec='$libname$release$major$shared_ext'
+ library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext'
+ soname_spec='${libname}${release}${major}$shared_ext'
shlibpath_overrides_runpath=yes
shlibpath_var=DYLD_LIBRARY_PATH
shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
@@ -12796,8 +12360,8 @@ dgux*)
version_type=linux # correct to gnu/linux during the next big refactor
need_lib_prefix=no
need_version=no
- library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
- soname_spec='$libname$release$shared_ext$major'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
+ soname_spec='${libname}${release}${shared_ext}$major'
shlibpath_var=LD_LIBRARY_PATH
;;
@@ -12815,13 +12379,12 @@ freebsd* | dragonfly*)
version_type=freebsd-$objformat
case $version_type in
freebsd-elf*)
- library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
- soname_spec='$libname$release$shared_ext$major'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
need_version=no
need_lib_prefix=no
;;
freebsd-*)
- library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
need_version=yes
;;
esac
@@ -12846,15 +12409,26 @@ freebsd* | dragonfly*)
esac
;;
+gnu*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
haiku*)
version_type=linux # correct to gnu/linux during the next big refactor
need_lib_prefix=no
need_version=no
dynamic_linker="$host_os runtime_loader"
- library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
- soname_spec='$libname$release$shared_ext$major'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
shlibpath_var=LIBRARY_PATH
- shlibpath_overrides_runpath=no
+ shlibpath_overrides_runpath=yes
sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib'
hardcode_into_libs=yes
;;
@@ -12872,15 +12446,14 @@ hpux9* | hpux10* | hpux11*)
dynamic_linker="$host_os dld.so"
shlibpath_var=LD_LIBRARY_PATH
shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
- library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
- soname_spec='$libname$release$shared_ext$major'
- if test 32 = "$HPUX_IA64_MODE"; then
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ if test "X$HPUX_IA64_MODE" = X32; then
sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
- sys_lib_dlsearch_path_spec=/usr/lib/hpux32
else
sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
- sys_lib_dlsearch_path_spec=/usr/lib/hpux64
fi
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
;;
hppa*64*)
shrext_cmds='.sl'
@@ -12888,8 +12461,8 @@ hpux9* | hpux10* | hpux11*)
dynamic_linker="$host_os dld.sl"
shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
- library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
- soname_spec='$libname$release$shared_ext$major'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
;;
@@ -12898,8 +12471,8 @@ hpux9* | hpux10* | hpux11*)
dynamic_linker="$host_os dld.sl"
shlibpath_var=SHLIB_PATH
shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
- library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
- soname_spec='$libname$release$shared_ext$major'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
;;
esac
# HP-UX runs *really* slowly unless shared libraries are mode 555, ...
@@ -12912,8 +12485,8 @@ interix[3-9]*)
version_type=linux # correct to gnu/linux during the next big refactor
need_lib_prefix=no
need_version=no
- library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
- soname_spec='$libname$release$shared_ext$major'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
shlibpath_var=LD_LIBRARY_PATH
shlibpath_overrides_runpath=no
@@ -12924,7 +12497,7 @@ irix5* | irix6* | nonstopux*)
case $host_os in
nonstopux*) version_type=nonstopux ;;
*)
- if test yes = "$lt_cv_prog_gnu_ld"; then
+ if test "$lt_cv_prog_gnu_ld" = yes; then
version_type=linux # correct to gnu/linux during the next big refactor
else
version_type=irix
@@ -12932,8 +12505,8 @@ irix5* | irix6* | nonstopux*)
esac
need_lib_prefix=no
need_version=no
- soname_spec='$libname$release$shared_ext$major'
- library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
case $host_os in
irix5* | nonstopux*)
libsuff= shlibsuff=
@@ -12952,8 +12525,8 @@ irix5* | irix6* | nonstopux*)
esac
shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
shlibpath_overrides_runpath=no
- sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff"
- sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff"
+ sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+ sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
hardcode_into_libs=yes
;;
@@ -12962,33 +12535,13 @@ linux*oldld* | linux*aout* | linux*coff*)
dynamic_linker=no
;;
-linux*android*)
- version_type=none # Android doesn't support versioned libraries.
- need_lib_prefix=no
- need_version=no
- library_names_spec='$libname$release$shared_ext'
- soname_spec='$libname$release$shared_ext'
- finish_cmds=
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes
-
- # This implies no fast_install, which is unacceptable.
- # Some rework will be needed to allow for fast_install
- # before this can be enabled.
- hardcode_into_libs=yes
-
- dynamic_linker='Android linker'
- # Don't embed -rpath directories since the linker doesn't support them.
- hardcode_libdir_flag_spec='-L$libdir'
- ;;
-
# This must be glibc/ELF.
-linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+linux* | k*bsd*-gnu | kopensolaris*-gnu)
version_type=linux # correct to gnu/linux during the next big refactor
need_lib_prefix=no
need_version=no
- library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
- soname_spec='$libname$release$shared_ext$major'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
shlibpath_var=LD_LIBRARY_PATH
shlibpath_overrides_runpath=no
@@ -13035,15 +12588,11 @@ fi
# Add ABI-specific directories to the system library path.
sys_lib_dlsearch_path_spec="/lib64 /usr/lib64 /lib /usr/lib"
- # Ideally, we could use ldconfig to report *all* directores which are
- # searched for libraries, however this is still not possible. Aside from not
- # being certain /sbin/ldconfig is available, command
- # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64,
- # even though it is searched at run-time. Try to do the best guess by
- # appending ld.so.conf contents (and includes) to the search path.
+ # Append ld.so.conf contents to the search path
if test -f /etc/ld.so.conf; then
lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '`
sys_lib_dlsearch_path_spec="$sys_lib_dlsearch_path_spec $lt_ld_extra"
+
fi
# We used to test for /lib/ld.so.1 and disable shared libraries on
@@ -13060,12 +12609,12 @@ netbsd*)
need_lib_prefix=no
need_version=no
if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
- library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
dynamic_linker='NetBSD (a.out) ld.so'
else
- library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
- soname_spec='$libname$release$shared_ext$major'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
dynamic_linker='NetBSD ld.elf_so'
fi
shlibpath_var=LD_LIBRARY_PATH
@@ -13075,7 +12624,7 @@ netbsd*)
newsos6)
version_type=linux # correct to gnu/linux during the next big refactor
- library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
shlibpath_var=LD_LIBRARY_PATH
shlibpath_overrides_runpath=yes
;;
@@ -13084,68 +12633,58 @@ newsos6)
version_type=qnx
need_lib_prefix=no
need_version=no
- library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
- soname_spec='$libname$release$shared_ext$major'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
shlibpath_var=LD_LIBRARY_PATH
shlibpath_overrides_runpath=no
hardcode_into_libs=yes
dynamic_linker='ldqnx.so'
;;
-openbsd* | bitrig*)
+openbsd*)
version_type=sunos
- sys_lib_dlsearch_path_spec=/usr/lib
+ sys_lib_dlsearch_path_spec="/usr/lib"
need_lib_prefix=no
- if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then
- need_version=no
- else
- need_version=yes
- fi
- library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+ # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
+ case $host_os in
+ openbsd3.3 | openbsd3.3.*) need_version=yes ;;
+ *) need_version=no ;;
+ esac
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ case $host_os in
+ openbsd2.[89] | openbsd2.[89].*)
+ shlibpath_overrides_runpath=no
+ ;;
+ *)
+ shlibpath_overrides_runpath=yes
+ ;;
+ esac
+ else
+ shlibpath_overrides_runpath=yes
+ fi
;;
os2*)
libname_spec='$name'
- version_type=windows
- shrext_cmds=.dll
- need_version=no
+ shrext_cmds=".dll"
need_lib_prefix=no
- # OS/2 can only load a DLL with a base name of 8 characters or less.
- soname_spec='`test -n "$os2dllname" && libname="$os2dllname";
- v=$($ECHO $release$versuffix | tr -d .-);
- n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _);
- $ECHO $n$v`$shared_ext'
- library_names_spec='${libname}_dll.$libext'
+ library_names_spec='$libname${shared_ext} $libname.a'
dynamic_linker='OS/2 ld.exe'
- shlibpath_var=BEGINLIBPATH
- sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
- sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
- postinstall_cmds='base_file=`basename \$file`~
- dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~
- dldir=$destdir/`dirname \$dlpath`~
- test -d \$dldir || mkdir -p \$dldir~
- $install_prog $dir/$dlname \$dldir/$dlname~
- chmod a+x \$dldir/$dlname~
- if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
- eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
- fi'
- postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~
- dlpath=$dir/\$dldll~
- $RM \$dlpath'
+ shlibpath_var=LIBPATH
;;
osf3* | osf4* | osf5*)
version_type=osf
need_lib_prefix=no
need_version=no
- soname_spec='$libname$release$shared_ext$major'
- library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
shlibpath_var=LD_LIBRARY_PATH
sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
- sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
;;
rdos*)
@@ -13156,8 +12695,8 @@ solaris*)
version_type=linux # correct to gnu/linux during the next big refactor
need_lib_prefix=no
need_version=no
- library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
- soname_spec='$libname$release$shared_ext$major'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
shlibpath_var=LD_LIBRARY_PATH
shlibpath_overrides_runpath=yes
hardcode_into_libs=yes
@@ -13167,11 +12706,11 @@ solaris*)
sunos4*)
version_type=sunos
- library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
shlibpath_var=LD_LIBRARY_PATH
shlibpath_overrides_runpath=yes
- if test yes = "$with_gnu_ld"; then
+ if test "$with_gnu_ld" = yes; then
need_lib_prefix=no
fi
need_version=yes
@@ -13179,8 +12718,8 @@ sunos4*)
sysv4 | sysv4.3*)
version_type=linux # correct to gnu/linux during the next big refactor
- library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
- soname_spec='$libname$release$shared_ext$major'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
shlibpath_var=LD_LIBRARY_PATH
case $host_vendor in
sni)
@@ -13201,24 +12740,24 @@ sysv4 | sysv4.3*)
;;
sysv4*MP*)
- if test -d /usr/nec; then
+ if test -d /usr/nec ;then
version_type=linux # correct to gnu/linux during the next big refactor
- library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext'
- soname_spec='$libname$shared_ext.$major'
+ library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
+ soname_spec='$libname${shared_ext}.$major'
shlibpath_var=LD_LIBRARY_PATH
fi
;;
sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
- version_type=sco
+ version_type=freebsd-elf
need_lib_prefix=no
need_version=no
- library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext'
- soname_spec='$libname$release$shared_ext$major'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
shlibpath_var=LD_LIBRARY_PATH
shlibpath_overrides_runpath=yes
hardcode_into_libs=yes
- if test yes = "$with_gnu_ld"; then
+ if test "$with_gnu_ld" = yes; then
sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
else
sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
@@ -13236,7 +12775,7 @@ tpf*)
version_type=linux # correct to gnu/linux during the next big refactor
need_lib_prefix=no
need_version=no
- library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
shlibpath_var=LD_LIBRARY_PATH
shlibpath_overrides_runpath=no
hardcode_into_libs=yes
@@ -13244,8 +12783,8 @@ tpf*)
uts4*)
version_type=linux # correct to gnu/linux during the next big refactor
- library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
- soname_spec='$libname$release$shared_ext$major'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
shlibpath_var=LD_LIBRARY_PATH
;;
@@ -13255,35 +12794,20 @@ uts4*)
esac
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5
$as_echo "$dynamic_linker" >&6; }
-test no = "$dynamic_linker" && can_build_shared=no
+test "$dynamic_linker" = no && can_build_shared=no
variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
-if test yes = "$GCC"; then
+if test "$GCC" = yes; then
variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
fi
-if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then
- sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec
+if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then
+ sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec"
fi
-
-if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then
- sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec
+if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then
+ sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec"
fi
-# remember unaugmented sys_lib_dlsearch_path content for libtool script decls...
-configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec
-
-# ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code
-func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH"
-
-# to be used as default LT_SYS_LIBRARY_PATH value in generated libtool
-configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH
-
-
-
-
-
-
@@ -13380,15 +12904,15 @@ $as_echo_n "checking how to hardcode library paths into programs... " >&6; }
hardcode_action=
if test -n "$hardcode_libdir_flag_spec" ||
test -n "$runpath_var" ||
- test yes = "$hardcode_automatic"; then
+ test "X$hardcode_automatic" = "Xyes" ; then
# We can hardcode non-existent directories.
- if test no != "$hardcode_direct" &&
+ if test "$hardcode_direct" != no &&
# If the only mechanism to avoid hardcoding is shlibpath_var, we
# have to relink, otherwise we might link with an installed library
# when we should be linking with a yet-to-be-installed one
- ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, )" &&
- test no != "$hardcode_minus_L"; then
+ ## test "$_LT_TAGVAR(hardcode_shlibpath_var, )" != no &&
+ test "$hardcode_minus_L" != no; then
# Linking always hardcodes the temporary library directory.
hardcode_action=relink
else
@@ -13403,12 +12927,12 @@ fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5
$as_echo "$hardcode_action" >&6; }
-if test relink = "$hardcode_action" ||
- test yes = "$inherit_rpath"; then
+if test "$hardcode_action" = relink ||
+ test "$inherit_rpath" = yes; then
# Fast installation is not supported
enable_fast_install=no
-elif test yes = "$shlibpath_overrides_runpath" ||
- test no = "$enable_shared"; then
+elif test "$shlibpath_overrides_runpath" = yes ||
+ test "$enable_shared" = no; then
# Fast installation is not necessary
enable_fast_install=needless
fi
@@ -13418,7 +12942,7 @@ fi
- if test yes != "$enable_dlopen"; then
+ if test "x$enable_dlopen" != xyes; then
enable_dlopen=unknown
enable_dlopen_self=unknown
enable_dlopen_self_static=unknown
@@ -13428,23 +12952,23 @@ else
case $host_os in
beos*)
- lt_cv_dlopen=load_add_on
+ lt_cv_dlopen="load_add_on"
lt_cv_dlopen_libs=
lt_cv_dlopen_self=yes
;;
mingw* | pw32* | cegcc*)
- lt_cv_dlopen=LoadLibrary
+ lt_cv_dlopen="LoadLibrary"
lt_cv_dlopen_libs=
;;
cygwin*)
- lt_cv_dlopen=dlopen
+ lt_cv_dlopen="dlopen"
lt_cv_dlopen_libs=
;;
darwin*)
- # if libdl is installed we need to link against it
+ # if libdl is installed we need to link against it
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
$as_echo_n "checking for dlopen in -ldl... " >&6; }
if ${ac_cv_lib_dl_dlopen+:} false; then :
@@ -13482,10 +13006,10 @@ fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5
$as_echo "$ac_cv_lib_dl_dlopen" >&6; }
if test "x$ac_cv_lib_dl_dlopen" = xyes; then :
- lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl
+ lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
else
- lt_cv_dlopen=dyld
+ lt_cv_dlopen="dyld"
lt_cv_dlopen_libs=
lt_cv_dlopen_self=yes
@@ -13493,18 +13017,10 @@ fi
;;
- tpf*)
- # Don't try to run any link tests for TPF. We know it's impossible
- # because TPF is a cross-compiler, and we know how we open DSOs.
- lt_cv_dlopen=dlopen
- lt_cv_dlopen_libs=
- lt_cv_dlopen_self=no
- ;;
-
*)
ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load"
if test "x$ac_cv_func_shl_load" = xyes; then :
- lt_cv_dlopen=shl_load
+ lt_cv_dlopen="shl_load"
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5
$as_echo_n "checking for shl_load in -ldld... " >&6; }
@@ -13543,11 +13059,11 @@ fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5
$as_echo "$ac_cv_lib_dld_shl_load" >&6; }
if test "x$ac_cv_lib_dld_shl_load" = xyes; then :
- lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld
+ lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"
else
ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen"
if test "x$ac_cv_func_dlopen" = xyes; then :
- lt_cv_dlopen=dlopen
+ lt_cv_dlopen="dlopen"
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
$as_echo_n "checking for dlopen in -ldl... " >&6; }
@@ -13586,7 +13102,7 @@ fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5
$as_echo "$ac_cv_lib_dl_dlopen" >&6; }
if test "x$ac_cv_lib_dl_dlopen" = xyes; then :
- lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl
+ lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5
$as_echo_n "checking for dlopen in -lsvld... " >&6; }
@@ -13625,7 +13141,7 @@ fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5
$as_echo "$ac_cv_lib_svld_dlopen" >&6; }
if test "x$ac_cv_lib_svld_dlopen" = xyes; then :
- lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld
+ lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5
$as_echo_n "checking for dld_link in -ldld... " >&6; }
@@ -13664,7 +13180,7 @@ fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5
$as_echo "$ac_cv_lib_dld_dld_link" >&6; }
if test "x$ac_cv_lib_dld_dld_link" = xyes; then :
- lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld
+ lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"
fi
@@ -13685,21 +13201,21 @@ fi
;;
esac
- if test no = "$lt_cv_dlopen"; then
- enable_dlopen=no
- else
+ if test "x$lt_cv_dlopen" != xno; then
enable_dlopen=yes
+ else
+ enable_dlopen=no
fi
case $lt_cv_dlopen in
dlopen)
- save_CPPFLAGS=$CPPFLAGS
- test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+ save_CPPFLAGS="$CPPFLAGS"
+ test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
- save_LDFLAGS=$LDFLAGS
+ save_LDFLAGS="$LDFLAGS"
wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
- save_LIBS=$LIBS
+ save_LIBS="$LIBS"
LIBS="$lt_cv_dlopen_libs $LIBS"
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5
@@ -13707,7 +13223,7 @@ $as_echo_n "checking whether a program can dlopen itself... " >&6; }
if ${lt_cv_dlopen_self+:} false; then :
$as_echo_n "(cached) " >&6
else
- if test yes = "$cross_compiling"; then :
+ if test "$cross_compiling" = yes; then :
lt_cv_dlopen_self=cross
else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
@@ -13754,9 +13270,9 @@ else
# endif
#endif
-/* When -fvisibility=hidden is used, assume the code has been annotated
+/* When -fvisbility=hidden is used, assume the code has been annotated
correspondingly for the symbols needed. */
-#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
int fnord () __attribute__((visibility("default")));
#endif
@@ -13786,7 +13302,7 @@ _LT_EOF
(eval $ac_link) 2>&5
ac_status=$?
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then
+ test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then
(./conftest; exit; ) >&5 2>/dev/null
lt_status=$?
case x$lt_status in
@@ -13806,14 +13322,14 @@ fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5
$as_echo "$lt_cv_dlopen_self" >&6; }
- if test yes = "$lt_cv_dlopen_self"; then
+ if test "x$lt_cv_dlopen_self" = xyes; then
wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\"
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5
$as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; }
if ${lt_cv_dlopen_self_static+:} false; then :
$as_echo_n "(cached) " >&6
else
- if test yes = "$cross_compiling"; then :
+ if test "$cross_compiling" = yes; then :
lt_cv_dlopen_self_static=cross
else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
@@ -13860,9 +13376,9 @@ else
# endif
#endif
-/* When -fvisibility=hidden is used, assume the code has been annotated
+/* When -fvisbility=hidden is used, assume the code has been annotated
correspondingly for the symbols needed. */
-#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
int fnord () __attribute__((visibility("default")));
#endif
@@ -13892,7 +13408,7 @@ _LT_EOF
(eval $ac_link) 2>&5
ac_status=$?
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then
+ test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then
(./conftest; exit; ) >&5 2>/dev/null
lt_status=$?
case x$lt_status in
@@ -13913,9 +13429,9 @@ fi
$as_echo "$lt_cv_dlopen_self_static" >&6; }
fi
- CPPFLAGS=$save_CPPFLAGS
- LDFLAGS=$save_LDFLAGS
- LIBS=$save_LIBS
+ CPPFLAGS="$save_CPPFLAGS"
+ LDFLAGS="$save_LDFLAGS"
+ LIBS="$save_LIBS"
;;
esac
@@ -13959,7 +13475,7 @@ else
# FIXME - insert some real tests, host_os isn't really good enough
case $host_os in
darwin*)
- if test -n "$STRIP"; then
+ if test -n "$STRIP" ; then
striplib="$STRIP -x"
old_striplib="$STRIP -S"
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
@@ -13987,7 +13503,7 @@ fi
- # Report what library types will actually be built
+ # Report which library types will actually be built
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5
$as_echo_n "checking if libtool supports shared libraries... " >&6; }
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5
@@ -13995,13 +13511,13 @@ $as_echo "$can_build_shared" >&6; }
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5
$as_echo_n "checking whether to build shared libraries... " >&6; }
- test no = "$can_build_shared" && enable_shared=no
+ test "$can_build_shared" = "no" && enable_shared=no
# On AIX, shared libraries and static libraries use the same namespace, and
# are all built from PIC.
case $host_os in
aix3*)
- test yes = "$enable_shared" && enable_static=no
+ test "$enable_shared" = yes && enable_static=no
if test -n "$RANLIB"; then
archive_cmds="$archive_cmds~\$RANLIB \$lib"
postinstall_cmds='$RANLIB $lib'
@@ -14009,12 +13525,8 @@ $as_echo_n "checking whether to build shared libraries... " >&6; }
;;
aix[4-9]*)
- if test ia64 != "$host_cpu"; then
- case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in
- yes,aix,yes) ;; # shared object as lib.so file only
- yes,svr4,*) ;; # shared object as lib.so archive member only
- yes,*) enable_static=no ;; # shared object in lib.a archive as well
- esac
+ if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+ test "$enable_shared" = yes && enable_static=no
fi
;;
esac
@@ -14024,7 +13536,7 @@ $as_echo "$enable_shared" >&6; }
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5
$as_echo_n "checking whether to build static libraries... " >&6; }
# Make sure either enable_shared or enable_static is yes.
- test yes = "$enable_shared" || enable_static=yes
+ test "$enable_shared" = yes || enable_static=yes
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5
$as_echo "$enable_static" >&6; }
@@ -14038,7 +13550,7 @@ ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_c_compiler_gnu
-CC=$lt_save_CC
+CC="$lt_save_CC"
@@ -14168,7 +13680,7 @@ objext_RC=$objext
lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }'
# Code to be used in simple link tests
-lt_simple_link_test_code=$lt_simple_compile_test_code
+lt_simple_link_test_code="$lt_simple_compile_test_code"
# ltmain only uses $CC for tagged configurations so make sure $CC is set.
@@ -14202,7 +13714,7 @@ $RM -r conftest*
# Allow CC to be a program name with arguments.
-lt_save_CC=$CC
+lt_save_CC="$CC"
lt_save_CFLAGS=$CFLAGS
lt_save_GCC=$GCC
GCC=
@@ -14210,8 +13722,15 @@ CC=${RC-"windres"}
CFLAGS=
compiler=$CC
compiler_RC=$CC
-func_cc_basename $compiler
-cc_basename=$func_cc_basename_result
+for cc_temp in $compiler""; do
+ case $cc_temp in
+ compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+ distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+ \-*) ;;
+ *) break;;
+ esac
+done
+cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
lt_cv_prog_compiler_c_o_RC=yes
@@ -14666,7 +14185,7 @@ fi
ac_fn_c_check_type "$LINENO" "socklen_t" "ac_cv_type_socklen_t" "
#include <sys/types.h>
-#ifdef WIN32
+#ifdef _WIN32
#include <ws2tcpip.h>
#else
#include <sys/socket.h>
@@ -14914,6 +14433,9 @@ SOCKET_INCLUDES="
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
+#ifdef HAVE_NET_IF_H
+#include <net/if.h>
+#endif
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
@@ -14966,6 +14488,22 @@ $as_echo "#define in_addr_t uint32_t" >>confdefs.h
fi
+ac_fn_c_check_type "$LINENO" "in_port_t" "ac_cv_type_in_port_t" "${SOCKET_INCLUDES}
+
+"
+if test "x$ac_cv_type_in_port_t" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_IN_PORT_T 1
+_ACEOF
+
+
+else
+
+$as_echo "#define in_port_t uint16_t" >>confdefs.h
+
+fi
+
ac_fn_c_check_type "$LINENO" "struct iphdr" "ac_cv_type_struct_iphdr" "${SOCKET_INCLUDES}
"
@@ -15011,6 +14549,24 @@ $as_echo "#define HAVE_IN_PKTINFO 1" >>confdefs.h
fi
+ac_fn_c_check_type "$LINENO" "sa_family_t" "ac_cv_type_sa_family_t" "${SOCKET_INCLUDES}
+
+"
+if test "x$ac_cv_type_sa_family_t" = xyes; then :
+
+$as_echo "#define HAVE_SA_FAMILY_T 1" >>confdefs.h
+
+fi
+
+ac_fn_c_check_member "$LINENO" "struct in_pktinfo" "ipi_spec_dst" "ac_cv_member_struct_in_pktinfo_ipi_spec_dst" "${SOCKET_INCLUDES}
+
+"
+if test "x$ac_cv_member_struct_in_pktinfo_ipi_spec_dst" = xyes; then :
+
+$as_echo "#define HAVE_IPI_SPEC_DST 1" >>confdefs.h
+
+fi
+
ac_fn_c_check_type "$LINENO" "struct sockaddr_in6" "ac_cv_type_struct_sockaddr_in6" "${SOCKET_INCLUDES}
"
@@ -15033,6 +14589,44 @@ cat >>confdefs.h <<_ACEOF
#define HAVE_DECL_SO_MARK $ac_have_decl
_ACEOF
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking anonymous union support..." >&5
+$as_echo "$as_me: checking anonymous union support..." >&6;}
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+ struct mystruct {
+ union {
+ int m1;
+ char m2;
+ };
+ };
+
+int
+main ()
+{
+
+ struct mystruct s;
+ s.m1 = 1; s.m2 = 2;
+
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_ANONYMOUS_UNION_SUPPORT /**/" >>confdefs.h
+
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
ac_fn_c_check_decl "$LINENO" "SIGHUP" "ac_cv_have_decl_SIGHUP" "
#ifdef HAVE_SIGNAL_H
@@ -15560,7 +15154,7 @@ fi
old_LIBS="${LIBS}"
LIBS="${LIBS} ${SOCKETS_LIBS}"
-for ac_func in sendmsg recvmsg inet_ntop inet_pton
+for ac_func in sendmsg recvmsg
do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
@@ -15576,6 +15170,46 @@ done
if test "${WIN32}" = "yes"; then
+# normal autoconf function checking does not find inet_ntop/inet_pton
+# because they need to include the actual header file and link ws2_32.dll
+ LIBS="${LIBS} -lws2_32"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for MinGW inet_ntop()/inet_pton()" >&5
+$as_echo_n "checking for MinGW inet_ntop()/inet_pton()... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <ws2tcpip.h>
+
+int
+main ()
+{
+
+int r = (int) inet_ntop (0, NULL, NULL, 0);
+ r += inet_pton(AF_INET, NULL, NULL);
+return r;
+
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: OK" >&5
+$as_echo "OK" >&6; }
+
+$as_echo "#define HAVE_INET_NTOP 1" >>confdefs.h
+
+
+$as_echo "#define HAVE_INET_PTON 1" >>confdefs.h
+
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5
+$as_echo "not found" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
$as_echo "#define HAVE_SOCKET 1" >>confdefs.h
@@ -15642,6 +15276,18 @@ $as_echo "#define HAVE_POLL 1" >>confdefs.h
else
+ for ac_func in inet_ntop inet_pton
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
for ac_func in socket recv recvfrom send sendto listen accept connect bind select gethostbyname inet_ntoa
do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
@@ -15981,8 +15627,13 @@ fi
case "${with_mem_check}" in
valgrind)
- ac_fn_c_check_header_mongrel "$LINENO" "valgrind/memcheck.h" "ac_cv_header_valgrind_memcheck_h" "$ac_includes_default"
+ for ac_header in valgrind/memcheck.h
+do :
+ ac_fn_c_check_header_mongrel "$LINENO" "valgrind/memcheck.h" "ac_cv_header_valgrind_memcheck_h" "$ac_includes_default"
if test "x$ac_cv_header_valgrind_memcheck_h" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_VALGRIND_MEMCHECK_H 1
+_ACEOF
CFLAGS="${CFLAGS} -g -fno-inline"
@@ -15994,12 +15645,18 @@ else
fi
+done
;;
dmalloc)
- ac_fn_c_check_header_mongrel "$LINENO" "dmalloc.h" "ac_cv_header_dmalloc_h" "$ac_includes_default"
+ for ac_header in dmalloc.h
+do :
+ ac_fn_c_check_header_mongrel "$LINENO" "dmalloc.h" "ac_cv_header_dmalloc_h" "$ac_includes_default"
if test "x$ac_cv_header_dmalloc_h" = xyes; then :
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for malloc in -ldmalloc" >&5
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_DMALLOC_H 1
+_ACEOF
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for malloc in -ldmalloc" >&5
$as_echo_n "checking for malloc in -ldmalloc... " >&6; }
if ${ac_cv_lib_dmalloc_malloc+:} false; then :
$as_echo_n "(cached) " >&6
@@ -16052,6 +15709,7 @@ else
fi
+done
;;
ssl)
@@ -16181,181 +15839,27 @@ $as_echo "yes" >&6; }
have_pkcs11_helper="yes"
fi
+if test "${enable_crypto}" = "yes" -a "${with_crypto_library}" = "openssl"; then
-pkg_failed=no
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for OPENSSL_CRYPTO" >&5
-$as_echo_n "checking for OPENSSL_CRYPTO... " >&6; }
-if test -n "$OPENSSL_CRYPTO_CFLAGS"; then
- pkg_cv_OPENSSL_CRYPTO_CFLAGS="$OPENSSL_CRYPTO_CFLAGS"
- elif test -n "$PKG_CONFIG"; then
- if test -n "$PKG_CONFIG" && \
- { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libcrypto >= 0.9.6\""; } >&5
- ($PKG_CONFIG --exists --print-errors "libcrypto >= 0.9.6") 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; then
- pkg_cv_OPENSSL_CRYPTO_CFLAGS=`$PKG_CONFIG --cflags "libcrypto >= 0.9.6" 2>/dev/null`
- test "x$?" != "x0" && pkg_failed=yes
-else
- pkg_failed=yes
-fi
- else
- pkg_failed=untried
-fi
-if test -n "$OPENSSL_CRYPTO_LIBS"; then
- pkg_cv_OPENSSL_CRYPTO_LIBS="$OPENSSL_CRYPTO_LIBS"
- elif test -n "$PKG_CONFIG"; then
- if test -n "$PKG_CONFIG" && \
- { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libcrypto >= 0.9.6\""; } >&5
- ($PKG_CONFIG --exists --print-errors "libcrypto >= 0.9.6") 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; then
- pkg_cv_OPENSSL_CRYPTO_LIBS=`$PKG_CONFIG --libs "libcrypto >= 0.9.6" 2>/dev/null`
- test "x$?" != "x0" && pkg_failed=yes
-else
- pkg_failed=yes
-fi
- else
- pkg_failed=untried
-fi
-
-
-
-if test $pkg_failed = yes; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-
-if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
- _pkg_short_errors_supported=yes
-else
- _pkg_short_errors_supported=no
-fi
- if test $_pkg_short_errors_supported = yes; then
- OPENSSL_CRYPTO_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libcrypto >= 0.9.6" 2>&1`
- else
- OPENSSL_CRYPTO_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libcrypto >= 0.9.6" 2>&1`
- fi
- # Put the nasty error message in config.log where it belongs
- echo "$OPENSSL_CRYPTO_PKG_ERRORS" >&5
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for RSA_new in -lcrypto" >&5
-$as_echo_n "checking for RSA_new in -lcrypto... " >&6; }
-if ${ac_cv_lib_crypto_RSA_new+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lcrypto $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char RSA_new ();
-int
-main ()
-{
-return RSA_new ();
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- ac_cv_lib_crypto_RSA_new=yes
-else
- ac_cv_lib_crypto_RSA_new=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypto_RSA_new" >&5
-$as_echo "$ac_cv_lib_crypto_RSA_new" >&6; }
-if test "x$ac_cv_lib_crypto_RSA_new" = xyes; then :
-
- have_openssl_crypto="yes"
- OPENSSL_CRYPTO_LIBS="-lcrypto"
-
-
-fi
-
-
-elif test $pkg_failed = untried; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for RSA_new in -lcrypto" >&5
-$as_echo_n "checking for RSA_new in -lcrypto... " >&6; }
-if ${ac_cv_lib_crypto_RSA_new+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lcrypto $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char RSA_new ();
-int
-main ()
-{
-return RSA_new ();
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- ac_cv_lib_crypto_RSA_new=yes
-else
- ac_cv_lib_crypto_RSA_new=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypto_RSA_new" >&5
-$as_echo "$ac_cv_lib_crypto_RSA_new" >&6; }
-if test "x$ac_cv_lib_crypto_RSA_new" = xyes; then :
-
- have_openssl_crypto="yes"
- OPENSSL_CRYPTO_LIBS="-lcrypto"
-
-
-fi
-
-
-else
- OPENSSL_CRYPTO_CFLAGS=$pkg_cv_OPENSSL_CRYPTO_CFLAGS
- OPENSSL_CRYPTO_LIBS=$pkg_cv_OPENSSL_CRYPTO_LIBS
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
- have_openssl_crypto="yes"
-fi
+ if test -z "${OPENSSL_CFLAGS}" -a -z "${OPENSSL_LIBS}"; then
+ # if the user did not explicitly specify flags, try to autodetect
pkg_failed=no
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for OPENSSL_SSL" >&5
-$as_echo_n "checking for OPENSSL_SSL... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for OPENSSL" >&5
+$as_echo_n "checking for OPENSSL... " >&6; }
-if test -n "$OPENSSL_SSL_CFLAGS"; then
- pkg_cv_OPENSSL_SSL_CFLAGS="$OPENSSL_SSL_CFLAGS"
+if test -n "$OPENSSL_CFLAGS"; then
+ pkg_cv_OPENSSL_CFLAGS="$OPENSSL_CFLAGS"
elif test -n "$PKG_CONFIG"; then
if test -n "$PKG_CONFIG" && \
- { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libssl >= 0.9.6\""; } >&5
- ($PKG_CONFIG --exists --print-errors "libssl >= 0.9.6") 2>&5
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libcrypto >= 0.9.8, libssl >= 0.9.8\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "libcrypto >= 0.9.8, libssl >= 0.9.8") 2>&5
ac_status=$?
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; }; then
- pkg_cv_OPENSSL_SSL_CFLAGS=`$PKG_CONFIG --cflags "libssl >= 0.9.6" 2>/dev/null`
+ pkg_cv_OPENSSL_CFLAGS=`$PKG_CONFIG --cflags "libcrypto >= 0.9.8, libssl >= 0.9.8" 2>/dev/null`
test "x$?" != "x0" && pkg_failed=yes
else
pkg_failed=yes
@@ -16363,16 +15867,16 @@ fi
else
pkg_failed=untried
fi
-if test -n "$OPENSSL_SSL_LIBS"; then
- pkg_cv_OPENSSL_SSL_LIBS="$OPENSSL_SSL_LIBS"
+if test -n "$OPENSSL_LIBS"; then
+ pkg_cv_OPENSSL_LIBS="$OPENSSL_LIBS"
elif test -n "$PKG_CONFIG"; then
if test -n "$PKG_CONFIG" && \
- { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libssl >= 0.9.6\""; } >&5
- ($PKG_CONFIG --exists --print-errors "libssl >= 0.9.6") 2>&5
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libcrypto >= 0.9.8, libssl >= 0.9.8\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "libcrypto >= 0.9.8, libssl >= 0.9.8") 2>&5
ac_status=$?
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; }; then
- pkg_cv_OPENSSL_SSL_LIBS=`$PKG_CONFIG --libs "libssl >= 0.9.6" 2>/dev/null`
+ pkg_cv_OPENSSL_LIBS=`$PKG_CONFIG --libs "libcrypto >= 0.9.8, libssl >= 0.9.8" 2>/dev/null`
test "x$?" != "x0" && pkg_failed=yes
else
pkg_failed=yes
@@ -16393,130 +15897,52 @@ else
_pkg_short_errors_supported=no
fi
if test $_pkg_short_errors_supported = yes; then
- OPENSSL_SSL_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libssl >= 0.9.6" 2>&1`
+ OPENSSL_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libcrypto >= 0.9.8, libssl >= 0.9.8" 2>&1`
else
- OPENSSL_SSL_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libssl >= 0.9.6" 2>&1`
+ OPENSSL_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libcrypto >= 0.9.8, libssl >= 0.9.8" 2>&1`
fi
# Put the nasty error message in config.log where it belongs
- echo "$OPENSSL_SSL_PKG_ERRORS" >&5
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for SSL_CTX_new in -lssl" >&5
-$as_echo_n "checking for SSL_CTX_new in -lssl... " >&6; }
-if ${ac_cv_lib_ssl_SSL_CTX_new+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lssl -lcrypto
- $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char SSL_CTX_new ();
-int
-main ()
-{
-return SSL_CTX_new ();
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- ac_cv_lib_ssl_SSL_CTX_new=yes
-else
- ac_cv_lib_ssl_SSL_CTX_new=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ssl_SSL_CTX_new" >&5
-$as_echo "$ac_cv_lib_ssl_SSL_CTX_new" >&6; }
-if test "x$ac_cv_lib_ssl_SSL_CTX_new" = xyes; then :
-
- have_openssl_ssl="yes"
- OPENSSL_SSL_LIBS="-lssl"
-
-fi
+ echo "$OPENSSL_PKG_ERRORS" >&5
+ have_openssl="no" # Provide if-not-found to prevent erroring out
elif test $pkg_failed = untried; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for SSL_CTX_new in -lssl" >&5
-$as_echo_n "checking for SSL_CTX_new in -lssl... " >&6; }
-if ${ac_cv_lib_ssl_SSL_CTX_new+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lssl -lcrypto
- $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char SSL_CTX_new ();
-int
-main ()
-{
-return SSL_CTX_new ();
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- ac_cv_lib_ssl_SSL_CTX_new=yes
-else
- ac_cv_lib_ssl_SSL_CTX_new=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ssl_SSL_CTX_new" >&5
-$as_echo "$ac_cv_lib_ssl_SSL_CTX_new" >&6; }
-if test "x$ac_cv_lib_ssl_SSL_CTX_new" = xyes; then :
-
- have_openssl_ssl="yes"
- OPENSSL_SSL_LIBS="-lssl"
-
-fi
-
+ have_openssl="no" # Provide if-not-found to prevent erroring out
else
- OPENSSL_SSL_CFLAGS=$pkg_cv_OPENSSL_SSL_CFLAGS
- OPENSSL_SSL_LIBS=$pkg_cv_OPENSSL_SSL_LIBS
+ OPENSSL_CFLAGS=$pkg_cv_OPENSSL_CFLAGS
+ OPENSSL_LIBS=$pkg_cv_OPENSSL_LIBS
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
- have_openssl_ssl="yes"
+ have_openssl="yes"
fi
-if test "${have_openssl_crypto}" = "yes"; then
+ OPENSSL_LIBS=${OPENSSL_LIBS:--lssl -lcrypto}
+ fi
+
saved_CFLAGS="${CFLAGS}"
saved_LIBS="${LIBS}"
- CFLAGS="${CFLAGS} ${OPENSSL_CRYPTO_CFLAGS}"
- LIBS="${LIBS} ${OPENSSL_CRYPTO_LIBS}"
- for ac_func in EVP_CIPHER_CTX_set_key_length
+ CFLAGS="${CFLAGS} ${OPENSSL_CFLAGS}"
+ LIBS="${LIBS} ${OPENSSL_LIBS}"
+
+ for ac_func in SSL_CTX_new EVP_CIPHER_CTX_set_key_length
do :
- ac_fn_c_check_func "$LINENO" "EVP_CIPHER_CTX_set_key_length" "ac_cv_func_EVP_CIPHER_CTX_set_key_length"
-if test "x$ac_cv_func_EVP_CIPHER_CTX_set_key_length" = xyes; then :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
cat >>confdefs.h <<_ACEOF
-#define HAVE_EVP_CIPHER_CTX_SET_KEY_LENGTH 1
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
_ACEOF
+else
+ as_fn_error $? "openssl check failed" "$LINENO" 5
+
fi
done
+
have_openssl_engine="yes"
for ac_func in \
ENGINE_load_builtin_engines \
@@ -16537,66 +15963,55 @@ else
fi
done
+ if test "${have_openssl_engine}" = "yes"; then
- CFLAGS="${saved_CFLAGS}"
- LIBS="${saved_LIBS}"
-fi
+$as_echo "#define HAVE_OPENSSL_ENGINE 1" >>confdefs.h
+ fi
+ have_crypto_aead_modes="yes"
+ for ac_func in EVP_aes_256_gcm
+do :
+ ac_fn_c_check_func "$LINENO" "EVP_aes_256_gcm" "ac_cv_func_EVP_aes_256_gcm"
+if test "x$ac_cv_func_EVP_aes_256_gcm" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_EVP_AES_256_GCM 1
+_ACEOF
-have_polarssl_ssl="yes"
-have_polarssl_crypto="yes"
-if test -z "${POLARSSL_LIBS}"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ssl_init in -lpolarssl" >&5
-$as_echo_n "checking for ssl_init in -lpolarssl... " >&6; }
-if ${ac_cv_lib_polarssl_ssl_init+:} false; then :
- $as_echo_n "(cached) " >&6
else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lpolarssl ${PKCS11_HELPER_LIBS}
- $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
+ have_crypto_aead_modes="no"; break
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char ssl_init ();
-int
-main ()
-{
-return ssl_init ();
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- ac_cv_lib_polarssl_ssl_init=yes
-else
- ac_cv_lib_polarssl_ssl_init=no
fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_polarssl_ssl_init" >&5
-$as_echo "$ac_cv_lib_polarssl_ssl_init" >&6; }
-if test "x$ac_cv_lib_polarssl_ssl_init" = xyes; then :
- POLARSSL_LIBS="-lpolarssl"
-else
+done
- have_polarssl_ssl="no"
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for aes_crypt_cbc in -lpolarssl" >&5
-$as_echo_n "checking for aes_crypt_cbc in -lpolarssl... " >&6; }
-if ${ac_cv_lib_polarssl_aes_crypt_cbc+:} false; then :
+
+ CFLAGS="${saved_CFLAGS}"
+ LIBS="${saved_LIBS}"
+
+ have_crypto="yes"
+
+$as_echo "#define ENABLE_CRYPTO_OPENSSL 1" >>confdefs.h
+
+ CRYPTO_CFLAGS="${OPENSSL_CFLAGS}"
+ CRYPTO_LIBS="${OPENSSL_LIBS}"
+elif test "${enable_crypto}" = "yes" -a "${with_crypto_library}" = "mbedtls"; then
+
+
+
+ saved_CFLAGS="${CFLAGS}"
+ saved_LIBS="${LIBS}"
+
+ if test -z "${MBEDTLS_CFLAGS}" -a -z "${MBEDTLS_LIBS}"; then
+ # if the user did not explicitly specify flags, try to autodetect
+ LIBS="${LIBS} -lmbedtls -lmbedx509 -lmbedcrypto"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for mbedtls_ssl_init in -lmbedtls" >&5
+$as_echo_n "checking for mbedtls_ssl_init in -lmbedtls... " >&6; }
+if ${ac_cv_lib_mbedtls_mbedtls_ssl_init+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_check_lib_save_LIBS=$LIBS
-LIBS="-lpolarssl ${PKCS11_HELPER_LIBS}
- $LIBS"
+LIBS="-lmbedtls ${PKCS11_HELPER_LIBS}
+ $LIBS"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
@@ -16606,57 +16021,49 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
#ifdef __cplusplus
extern "C"
#endif
-char aes_crypt_cbc ();
+char mbedtls_ssl_init ();
int
main ()
{
-return aes_crypt_cbc ();
+return mbedtls_ssl_init ();
;
return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
- ac_cv_lib_polarssl_aes_crypt_cbc=yes
+ ac_cv_lib_mbedtls_mbedtls_ssl_init=yes
else
- ac_cv_lib_polarssl_aes_crypt_cbc=no
+ ac_cv_lib_mbedtls_mbedtls_ssl_init=no
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_polarssl_aes_crypt_cbc" >&5
-$as_echo "$ac_cv_lib_polarssl_aes_crypt_cbc" >&6; }
-if test "x$ac_cv_lib_polarssl_aes_crypt_cbc" = xyes; then :
- cat >>confdefs.h <<_ACEOF
-#define HAVE_LIBPOLARSSL 1
-_ACEOF
-
- LIBS="-lpolarssl $LIBS"
-
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_mbedtls_mbedtls_ssl_init" >&5
+$as_echo "$ac_cv_lib_mbedtls_mbedtls_ssl_init" >&6; }
+if test "x$ac_cv_lib_mbedtls_mbedtls_ssl_init" = xyes; then :
+ MBEDTLS_LIBS="-lmbedtls -lmbedx509 -lmbedcrypto"
else
- have_polarssl_crypto="no"
+ as_fn_error $? "Could not find mbed TLS." "$LINENO" 5
fi
+ fi
-fi
-
-fi
+ CFLAGS="${MBEDTLS_CFLAGS} ${PKCS11_HELPER_CFLAGS} ${CFLAGS}"
+ LIBS="${MBEDTLS_LIBS} ${PKCS11_HELPER_LIBS} ${LIBS}"
-if test "${with_crypto_library}" = "polarssl" ; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking polarssl version" >&5
-$as_echo_n "checking polarssl version... " >&6; }
- old_CFLAGS="${CFLAGS}"
- CFLAGS="${POLARSSL_CFLAGS} ${CFLAGS}"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking mbedtls version" >&5
+$as_echo_n "checking mbedtls version... " >&6; }
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
-#include <polarssl/version.h>
+#include <mbedtls/version.h>
int
main ()
{
-#if POLARSSL_VERSION_NUMBER < 0x01030800 || POLARSSL_VERSION_NUMBER >= 0x01040000
+#if MBEDTLS_VERSION_NUMBER < 0x02000000 || MBEDTLS_VERSION_NUMBER >= 0x03000000
#error invalid version
#endif
@@ -16669,22 +16076,22 @@ if ac_fn_c_try_compile "$LINENO"; then :
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5
$as_echo "ok" >&6; }
else
- as_fn_error $? "PolarSSL 1.3.x required and must be 1.3.8 or later" "$LINENO" 5
+ as_fn_error $? "mbed TLS 2.y.z required" "$LINENO" 5
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
- polarssl_with_pkcs11="no"
+ mbedtls_with_pkcs11="no"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
-#include <polarssl/config.h>
+#include <mbedtls/config.h>
int
main ()
{
-#ifndef POLARSSL_PKCS11_C
+#ifndef MBEDTLS_PKCS11_C
#error pkcs11 wrapper missing
#endif
@@ -16694,29 +16101,58 @@ main ()
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
- polarssl_with_pkcs11="yes"
+ mbedtls_with_pkcs11="yes"
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
- CFLAGS="${old_CFLAGS}"
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking polarssl pkcs11 support" >&5
-$as_echo_n "checking polarssl pkcs11 support... " >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking mbedtls pkcs11 support" >&5
+$as_echo_n "checking mbedtls pkcs11 support... " >&6; }
if test "${enable_pkcs11}" = "yes"; then
- if test "${polarssl_with_pkcs11}" = "yes"; then
+ if test "${mbedtls_with_pkcs11}" = "yes"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5
$as_echo "ok" >&6; }
else
- as_fn_error $? "polarssl has no pkcs11 wrapper compiled in" "$LINENO" 5
+ as_fn_error $? "mbedtls has no pkcs11 wrapper compiled in" "$LINENO" 5
fi
else
- if test "${polarssl_with_pkcs11}" != "yes"; then
+ if test "${mbedtls_with_pkcs11}" != "yes"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5
$as_echo "ok" >&6; }
else
- as_fn_error $? "PolarSSL compiled with PKCS11, while OpenVPN is not" "$LINENO" 5
+ as_fn_error $? "mbed TLS compiled with PKCS11, while OpenVPN is not" "$LINENO" 5
fi
fi
+ have_crypto_aead_modes="yes"
+ for ac_func in \
+ mbedtls_cipher_write_tag \
+ mbedtls_cipher_check_tag \
+
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+else
+ have_crypto_aead_modes="no"; break
+
+fi
+done
+
+
+ CFLAGS="${saved_CFLAGS}"
+ LIBS="${saved_LIBS}"
+ have_crypto="yes"
+
+$as_echo "#define ENABLE_CRYPTO_MBEDTLS 1" >>confdefs.h
+
+ CRYPTO_CFLAGS="${MBEDTLS_CFLAGS}"
+ CRYPTO_LIBS="${MBEDTLS_LIBS}"
+elif test "${enable_crypto}" = "yes"; then
+ as_fn_error $? "Invalid crypto library: ${with_crypto_library}" "$LINENO" 5
fi
@@ -16875,6 +16311,108 @@ fi
+
+if test "$enable_lz4" = "yes" && test "$enable_comp_stub" = "no"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for LZ4 Library and Header files..." >&5
+$as_echo "$as_me: checking for LZ4 Library and Header files..." >&6;}
+ havelz4lib=1
+
+ # if LZ4_LIBS is set, we assume it will work, otherwise test
+ if test -z "${LZ4_LIBS}"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for LZ4_compress in -llz4" >&5
+$as_echo_n "checking for LZ4_compress in -llz4... " >&6; }
+if ${ac_cv_lib_lz4_LZ4_compress+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-llz4 $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char LZ4_compress ();
+int
+main ()
+{
+return LZ4_compress ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_lz4_LZ4_compress=yes
+else
+ ac_cv_lib_lz4_LZ4_compress=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lz4_LZ4_compress" >&5
+$as_echo "$ac_cv_lib_lz4_LZ4_compress" >&6; }
+if test "x$ac_cv_lib_lz4_LZ4_compress" = xyes; then :
+ LZ4_LIBS="-llz4"
+else
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: LZ4 library not found." >&5
+$as_echo "LZ4 library not found." >&6; }
+ havelz4lib=0
+
+fi
+
+ fi
+
+ saved_CFLAGS="${CFLAGS}"
+ CFLAGS="${CFLAGS} ${LZ4_CFLAGS}"
+ for ac_header in lz4.h
+do :
+ ac_fn_c_check_header_mongrel "$LINENO" "lz4.h" "ac_cv_header_lz4_h" "$ac_includes_default"
+if test "x$ac_cv_header_lz4_h" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_LZ4_H 1
+_ACEOF
+
+else
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: LZ4 headers not found." >&5
+$as_echo "LZ4 headers not found." >&6; }
+ havelz4lib=0
+
+fi
+
+done
+
+
+ if test $havelz4lib = 0 ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: LZ4 library or header not found, using version in src/compat/compat-lz4.*" >&5
+$as_echo "LZ4 library or header not found, using version in src/compat/compat-lz4.*" >&6; }
+
+$as_echo "#define NEED_COMPAT_LZ4 1" >>confdefs.h
+
+ LZ4_LIBS=""
+ fi
+ OPTIONAL_LZ4_CFLAGS="${LZ4_CFLAGS}"
+ OPTIONAL_LZ4_LIBS="${LZ4_LIBS}"
+
+$as_echo "#define ENABLE_LZ4 1" >>confdefs.h
+
+ CFLAGS="${saved_CFLAGS}"
+fi
+
+
+ if test "${enable_systemd}" = "yes"; then
+ ENABLE_SYSTEMD_TRUE=
+ ENABLE_SYSTEMD_FALSE='#'
+else
+ ENABLE_SYSTEMD_TRUE='#'
+ ENABLE_SYSTEMD_FALSE=
+fi
+
if test "$enable_systemd" = "yes" ; then
pkg_failed=no
@@ -17129,6 +16667,19 @@ else
$as_echo "yes" >&6; }
fi
+
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libsystemd > 216\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "libsystemd > 216") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+
+$as_echo "#define SYSTEMD_NEWER_THAN_216 1" >>confdefs.h
+
+
+fi
+
for ac_header in systemd/sd-daemon.h
do :
ac_fn_c_check_header_mongrel "$LINENO" "systemd/sd-daemon.h" "ac_cv_header_systemd_sd_daemon_h" "$ac_includes_default"
@@ -17206,8 +16757,8 @@ _ACEOF
fi
if test "${enable_x509_alt_username}" = "yes"; then
- if test "${with_crypto_library}" = "polarssl" ; then
- as_fn_error $? "PolarSSL does not support the --x509-username-field feature" "$LINENO" 5
+ if test "${with_crypto_library}" = "mbedtls" ; then
+ as_fn_error $? "mbed TLS does not support the --x509-username-field feature" "$LINENO" 5
fi
@@ -17227,12 +16778,6 @@ $as_echo "#define ENABLE_CLIENT_ONLY 1" >>confdefs.h
test "${enable_management}" = "yes" &&
$as_echo "#define ENABLE_MANAGEMENT 1" >>confdefs.h
-test "${enable_socks}" = "yes" &&
-$as_echo "#define ENABLE_SOCKS 1" >>confdefs.h
-
-test "${enable_http_proxy}" = "yes" &&
-$as_echo "#define ENABLE_HTTP_PROXY 1" >>confdefs.h
-
test "${enable_multihome}" = "yes" &&
$as_echo "#define ENABLE_MULTIHOME 1" >>confdefs.h
@@ -17258,49 +16803,16 @@ test "${enable_strict_options}" = "yes" &&
$as_echo "#define ENABLE_STRICT_OPTIONS_CHECK 1" >>confdefs.h
-case "${with_crypto_library}" in
- openssl)
- have_crypto_crypto="${have_openssl_crypto}"
- have_crypto_ssl="${have_openssl_ssl}"
- CRYPTO_CRYPTO_CFLAGS="${OPENSSL_CRYPTO_CFLAGS}"
- CRYPTO_CRYPTO_LIBS="${OPENSSL_CRYPTO_LIBS}"
- CRYPTO_SSL_CFLAGS="${OPENSSL_SSL_CFLAGS}"
- CRYPTO_SSL_LIBS="${OPENSSL_SSL_LIBS}"
-
-$as_echo "#define ENABLE_CRYPTO_OPENSSL 1" >>confdefs.h
-
- test "${have_openssl_engine}" = "yes" &&
-$as_echo "#define HAVE_OPENSSL_ENGINE 1" >>confdefs.h
-
- ;;
- polarssl)
- have_crypto_crypto="${have_polarssl_crypto}"
- have_crypto_ssl="${have_polarssl_ssl}"
- CRYPTO_CRYPTO_CFLAGS="${POLARSSL_CFLAGS}"
- CRYPTO_CRYPTO_LIBS="${POLARSSL_LIBS}"
-
-$as_echo "#define ENABLE_CRYPTO_POLARSSL 1" >>confdefs.h
-
- ;;
-esac
-
-if test "${enable_ssl}" = "yes"; then
- test "${enable_crypto}" != "yes" && as_fn_error $? "crypto must be enabled for ssl" "$LINENO" 5
- test "${have_crypto_ssl}" != "yes" && as_fn_error $? "${with_ssl_library} ssl is required but missing" "$LINENO" 5
- OPTIONAL_CRYPTO_CFLAGS="${OPTIONAL_CRYPTO_CFLAGS} ${CRYPTO_SSL_CFLAGS}"
- OPTIONAL_CRYPTO_LIBS="${OPTIONAL_CRYPTO_LIBS} ${CRYPTO_SSL_LIBS}"
-
-$as_echo "#define ENABLE_SSL 1" >>confdefs.h
-
-fi
-
if test "${enable_crypto}" = "yes"; then
- test "${have_crypto_crypto}" != "yes" && as_fn_error $? "${with_crypto_library} crypto is required but missing" "$LINENO" 5
+ test "${have_crypto}" != "yes" && as_fn_error $? "${with_crypto_library} crypto is required but missing" "$LINENO" 5
test "${enable_crypto_ofb_cfb}" = "yes" &&
$as_echo "#define ENABLE_OFB_CFB_MODE 1" >>confdefs.h
- OPTIONAL_CRYPTO_CFLAGS="${OPTIONAL_CRYPTO_CFLAGS} ${CRYPTO_CRYPTO_CFLAGS}"
- OPTIONAL_CRYPTO_LIBS="${OPTIONAL_CRYPTO_LIBS} ${CRYPTO_CRYPTO_LIBS}"
+ test "${have_crypto_aead_modes}" = "yes" &&
+$as_echo "#define HAVE_AEAD_CIPHER_MODES 1" >>confdefs.h
+
+ OPTIONAL_CRYPTO_CFLAGS="${OPTIONAL_CRYPTO_CFLAGS} ${CRYPTO_CFLAGS}"
+ OPTIONAL_CRYPTO_LIBS="${OPTIONAL_CRYPTO_LIBS} ${CRYPTO_LIBS}"
$as_echo "#define ENABLE_CRYPTO 1" >>confdefs.h
@@ -17344,19 +16856,17 @@ if test "${enable_lzo}" = "yes"; then
$as_echo "#define ENABLE_LZO 1" >>confdefs.h
fi
-if test "${enable_lzo_stub}" = "yes"; then
- test "${enable_lzo}" = "yes" && as_fn_error $? "Cannot have both lzo stub and lzo enabled" "$LINENO" 5
-
-$as_echo "#define ENABLE_LZO_STUB 1" >>confdefs.h
+if test "${enable_comp_stub}" = "yes"; then
+ test "${enable_lzo}" = "yes" && as_fn_error $? "Cannot have both comp stub and lzo enabled (use --disable-lzo)" "$LINENO" 5
+ test "${enable_lz4}" = "yes" && as_fn_error $? "Cannot have both comp stub and LZ4 enabled (use --disable-lz4)" "$LINENO" 5
-
-$as_echo "#define ENABLE_LZO 1" >>confdefs.h
+$as_echo "#define ENABLE_COMP_STUB 1" >>confdefs.h
fi
if test "${enable_pkcs11}" = "yes"; then
test "${have_pkcs11_helper}" != "yes" && as_fn_error $? "PKCS11 enabled but libpkcs11-helper is missing" "$LINENO" 5
- test "${enable_ssl}" != "yes" && as_fn_error $? "PKCS11 can be enabled only if SSL is enabled" "$LINENO" 5
+ test "${enable_crypto}" != "yes" && as_fn_error $? "PKCS11 can be enabled only if crypto is enabled" "$LINENO" 5
OPTIONAL_PKCS11_HELPER_CFLAGS="${PKCS11_HELPER_CFLAGS}"
OPTIONAL_PKCS11_HELPER_LIBS="${PKCS11_HELPER_LIBS}"
@@ -17445,11 +16955,16 @@ fi
if test "${enable_pedantic}" = "yes"; then
enable_strict="yes"
CFLAGS="${CFLAGS} -pedantic"
- test "${WIN32}" != "yes" && CFLAGS="${CFLAGS} -ansi"
+
+$as_echo "#define PEDANTIC 1" >>confdefs.h
+
fi
if test "${enable_strict}" = "yes"; then
CFLAGS="${CFLAGS} -Wall -Wno-unused-parameter -Wno-unused-function"
fi
+if test "${enable_werror}" = "yes"; then
+ CFLAGS="${CFLAGS} -Werror"
+fi
if test "${WIN32}" = "yes"; then
test -z "${MAN2HTML}" && as_fn_error $? "man2html is required for win32" "$LINENO" 5
@@ -17468,6 +16983,26 @@ $as_echo "#define USE_PAM_DLOPEN 1" >>confdefs.h
fi
fi
+if test "${enable_async_push}" = "yes"; then
+ for ac_header in sys/inotify.h
+do :
+ ac_fn_c_check_header_mongrel "$LINENO" "sys/inotify.h" "ac_cv_header_sys_inotify_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_inotify_h" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_SYS_INOTIFY_H 1
+_ACEOF
+
+$as_echo "#define ENABLE_ASYNC_PUSH 1" >>confdefs.h
+
+else
+ as_fn_error $? "inotify.h not found." "$LINENO" 5
+
+fi
+
+done
+
+fi
+
CONFIGURE_DEFINES="`set | grep '^enable_.*=' ; set | grep '^with_.*='`"
cat >>confdefs.h <<_ACEOF
@@ -17510,6 +17045,8 @@ _ACEOF
+
+
if test "${WIN32}" = "yes"; then
WIN32_TRUE=
WIN32_FALSE='#'
@@ -17542,13 +17079,114 @@ else
ENABLE_PLUGIN_DOWN_ROOT_FALSE=
fi
+ if test "${enable_crypto}" = "yes"; then
+ ENABLE_CRYPTO_TRUE=
+ ENABLE_CRYPTO_FALSE='#'
+else
+ ENABLE_CRYPTO_TRUE='#'
+ ENABLE_CRYPTO_FALSE=
+fi
+
plugindir="${with_plugindir}"
sampledir="\$(docdir)/sample"
-ac_config_files="$ac_config_files version.sh Makefile build/Makefile build/msvc/Makefile build/msvc/msvc-generate/Makefile distro/Makefile distro/rpm/Makefile distro/rpm/openvpn.spec include/Makefile src/Makefile src/compat/Makefile src/openvpn/Makefile src/openvpnserv/Makefile src/plugins/Makefile src/plugins/auth-pam/Makefile src/plugins/down-root/Makefile tests/Makefile sample/Makefile doc/Makefile"
+VENDOR_SRC_ROOT="\$(abs_top_srcdir)/vendor/"
+VENDOR_DIST_ROOT="\$(abs_top_builddir)/vendor/dist"
+VENDOR_BUILD_ROOT="\$(abs_top_builddir)/vendor/.build"
+
+
+
+
+TEST_LDFLAGS="-lcmocka -L\$(abs_top_builddir)/vendor/dist/lib -Wl,-rpath,\$(abs_top_builddir)/vendor/dist/lib"
+TEST_CFLAGS="-I\$(top_srcdir)/include -I\$(abs_top_builddir)/vendor/dist/include"
+
+
+
+
+# Check if cmake is available and cmocka git submodule is initialized,
+# needed for unit testing
+for ac_prog in cmake
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CMAKE+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CMAKE"; then
+ ac_cv_prog_CMAKE="$CMAKE" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CMAKE="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CMAKE=$ac_cv_prog_CMAKE
+if test -n "$CMAKE"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CMAKE" >&5
+$as_echo "$CMAKE" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$CMAKE" && break
+done
+
+if test -n "${CMAKE}"; then
+ if test -f "${srcdir}/vendor/cmocka/CMakeLists.txt"; then
+ if true; then
+ CMOCKA_INITIALIZED_TRUE=
+ CMOCKA_INITIALIZED_FALSE='#'
+else
+ CMOCKA_INITIALIZED_TRUE='#'
+ CMOCKA_INITIALIZED_FALSE=
+fi
+
+ else
+ if false; then
+ CMOCKA_INITIALIZED_TRUE=
+ CMOCKA_INITIALIZED_FALSE='#'
+else
+ CMOCKA_INITIALIZED_TRUE='#'
+ CMOCKA_INITIALIZED_FALSE=
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: !! WARNING !! The cmoka git submodule has not been initialized or updated. Unit testing cannot be performed." >&5
+$as_echo "!! WARNING !! The cmoka git submodule has not been initialized or updated. Unit testing cannot be performed." >&6; }
+ fi
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: !! WARNING !! CMake is NOT available. Unit testing cannot be performed." >&5
+$as_echo "!! WARNING !! CMake is NOT available. Unit testing cannot be performed." >&6; }
+ if false; then
+ CMOCKA_INITIALIZED_TRUE=
+ CMOCKA_INITIALIZED_FALSE='#'
+else
+ CMOCKA_INITIALIZED_TRUE='#'
+ CMOCKA_INITIALIZED_FALSE=
+fi
+
+fi
+
+
+ac_config_files="$ac_config_files version.sh Makefile build/Makefile build/msvc/Makefile build/msvc/msvc-generate/Makefile distro/Makefile distro/rpm/Makefile distro/rpm/openvpn.spec include/Makefile src/Makefile src/compat/Makefile src/openvpn/Makefile src/openvpnserv/Makefile src/plugins/Makefile src/plugins/auth-pam/Makefile src/plugins/down-root/Makefile tests/Makefile tests/unit_tests/Makefile tests/unit_tests/example_test/Makefile tests/unit_tests/openvpn/Makefile tests/unit_tests/plugins/Makefile tests/unit_tests/plugins/auth-pam/Makefile vendor/Makefile sample/Makefile doc/Makefile"
ac_config_files="$ac_config_files tests/t_client.sh"
@@ -17685,6 +17323,10 @@ if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then
as_fn_error $? "conditional \"am__fastdepCC\" was never defined.
Usually this means the macro was only invoked conditionally." "$LINENO" 5
fi
+if test -z "${ENABLE_SYSTEMD_TRUE}" && test -z "${ENABLE_SYSTEMD_FALSE}"; then
+ as_fn_error $? "conditional \"ENABLE_SYSTEMD\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
if test -z "${WIN32_TRUE}" && test -z "${WIN32_FALSE}"; then
as_fn_error $? "conditional \"WIN32\" was never defined.
Usually this means the macro was only invoked conditionally." "$LINENO" 5
@@ -17701,6 +17343,22 @@ if test -z "${ENABLE_PLUGIN_DOWN_ROOT_TRUE}" && test -z "${ENABLE_PLUGIN_DOWN_RO
as_fn_error $? "conditional \"ENABLE_PLUGIN_DOWN_ROOT\" was never defined.
Usually this means the macro was only invoked conditionally." "$LINENO" 5
fi
+if test -z "${ENABLE_CRYPTO_TRUE}" && test -z "${ENABLE_CRYPTO_FALSE}"; then
+ as_fn_error $? "conditional \"ENABLE_CRYPTO\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${CMOCKA_INITIALIZED_TRUE}" && test -z "${CMOCKA_INITIALIZED_FALSE}"; then
+ as_fn_error $? "conditional \"CMOCKA_INITIALIZED\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${CMOCKA_INITIALIZED_TRUE}" && test -z "${CMOCKA_INITIALIZED_FALSE}"; then
+ as_fn_error $? "conditional \"CMOCKA_INITIALIZED\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${CMOCKA_INITIALIZED_TRUE}" && test -z "${CMOCKA_INITIALIZED_FALSE}"; then
+ as_fn_error $? "conditional \"CMOCKA_INITIALIZED\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
: "${CONFIG_STATUS=./config.status}"
ac_write_fail=0
@@ -18098,7 +17756,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by OpenVPN $as_me 2.3.11, which was
+This file was extended by OpenVPN $as_me 2.4_beta1, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -18164,7 +17822,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
-OpenVPN config.status 2.3.11
+OpenVPN config.status 2.4_beta1
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
@@ -18302,7 +17960,6 @@ enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`'
enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`'
pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`'
enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`'
-shared_archive_member_spec='`$ECHO "$shared_archive_member_spec" | $SED "$delay_single_quote_subst"`'
SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`'
ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`'
PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`'
@@ -18350,13 +18007,10 @@ compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`'
GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`'
lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`'
lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`'
-lt_cv_sys_global_symbol_to_import='`$ECHO "$lt_cv_sys_global_symbol_to_import" | $SED "$delay_single_quote_subst"`'
lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`'
lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`'
-lt_cv_nm_interface='`$ECHO "$lt_cv_nm_interface" | $SED "$delay_single_quote_subst"`'
nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`'
lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`'
-lt_cv_truncate_bin='`$ECHO "$lt_cv_truncate_bin" | $SED "$delay_single_quote_subst"`'
objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`'
MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`'
lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`'
@@ -18421,8 +18075,7 @@ finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`'
finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`'
hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`'
sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`'
-configure_time_dlsearch_path='`$ECHO "$configure_time_dlsearch_path" | $SED "$delay_single_quote_subst"`'
-configure_time_lt_sys_library_path='`$ECHO "$configure_time_lt_sys_library_path" | $SED "$delay_single_quote_subst"`'
+sys_lib_dlsearch_path_spec='`$ECHO "$sys_lib_dlsearch_path_spec" | $SED "$delay_single_quote_subst"`'
hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`'
enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`'
enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`'
@@ -18516,12 +18169,9 @@ CFLAGS \
compiler \
lt_cv_sys_global_symbol_pipe \
lt_cv_sys_global_symbol_to_cdecl \
-lt_cv_sys_global_symbol_to_import \
lt_cv_sys_global_symbol_to_c_name_address \
lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \
-lt_cv_nm_interface \
nm_file_list_spec \
-lt_cv_truncate_bin \
lt_prog_compiler_no_builtin_flag \
lt_prog_compiler_pic \
lt_prog_compiler_wl \
@@ -18575,7 +18225,7 @@ include_expsyms_RC \
file_list_spec_RC; do
case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
*[\\\\\\\`\\"\\\$]*)
- eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes
+ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\""
;;
*)
eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
@@ -18602,8 +18252,7 @@ postinstall_cmds \
postuninstall_cmds \
finish_cmds \
sys_lib_search_path_spec \
-configure_time_dlsearch_path \
-configure_time_lt_sys_library_path \
+sys_lib_dlsearch_path_spec \
reload_cmds_RC \
old_archive_cmds_RC \
old_archive_from_new_cmds_RC \
@@ -18617,7 +18266,7 @@ prelink_cmds_RC \
postlink_cmds_RC; do
case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
*[\\\\\\\`\\"\\\$]*)
- eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes
+ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\""
;;
*)
eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
@@ -18626,16 +18275,19 @@ postlink_cmds_RC; do
done
ac_aux_dir='$ac_aux_dir'
+xsi_shell='$xsi_shell'
+lt_shell_append='$lt_shell_append'
-# See if we are running on zsh, and set the options that allow our
+# See if we are running on zsh, and set the options which allow our
# commands through without removal of \ escapes INIT.
-if test -n "\${ZSH_VERSION+set}"; then
+if test -n "\${ZSH_VERSION+set}" ; then
setopt NO_GLOB_SUBST
fi
PACKAGE='$PACKAGE'
VERSION='$VERSION'
+ TIMESTAMP='$TIMESTAMP'
RM='$RM'
ofile='$ofile'
@@ -18653,6 +18305,7 @@ for ac_config_target in $ac_config_targets
do
case $ac_config_target in
"config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;;
+ "include/openvpn-plugin.h") CONFIG_HEADERS="$CONFIG_HEADERS include/openvpn-plugin.h" ;;
"depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;;
"libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;;
"version.sh") CONFIG_FILES="$CONFIG_FILES version.sh" ;;
@@ -18672,6 +18325,12 @@ do
"src/plugins/auth-pam/Makefile") CONFIG_FILES="$CONFIG_FILES src/plugins/auth-pam/Makefile" ;;
"src/plugins/down-root/Makefile") CONFIG_FILES="$CONFIG_FILES src/plugins/down-root/Makefile" ;;
"tests/Makefile") CONFIG_FILES="$CONFIG_FILES tests/Makefile" ;;
+ "tests/unit_tests/Makefile") CONFIG_FILES="$CONFIG_FILES tests/unit_tests/Makefile" ;;
+ "tests/unit_tests/example_test/Makefile") CONFIG_FILES="$CONFIG_FILES tests/unit_tests/example_test/Makefile" ;;
+ "tests/unit_tests/openvpn/Makefile") CONFIG_FILES="$CONFIG_FILES tests/unit_tests/openvpn/Makefile" ;;
+ "tests/unit_tests/plugins/Makefile") CONFIG_FILES="$CONFIG_FILES tests/unit_tests/plugins/Makefile" ;;
+ "tests/unit_tests/plugins/auth-pam/Makefile") CONFIG_FILES="$CONFIG_FILES tests/unit_tests/plugins/auth-pam/Makefile" ;;
+ "vendor/Makefile") CONFIG_FILES="$CONFIG_FILES vendor/Makefile" ;;
"sample/Makefile") CONFIG_FILES="$CONFIG_FILES sample/Makefile" ;;
"doc/Makefile") CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;;
"tests/t_client.sh") CONFIG_FILES="$CONFIG_FILES tests/t_client.sh" ;;
@@ -19365,53 +19024,55 @@ $as_echo X"$file" |
;;
"libtool":C)
- # See if we are running on zsh, and set the options that allow our
+ # See if we are running on zsh, and set the options which allow our
# commands through without removal of \ escapes.
- if test -n "${ZSH_VERSION+set}"; then
+ if test -n "${ZSH_VERSION+set}" ; then
setopt NO_GLOB_SUBST
fi
- cfgfile=${ofile}T
+ cfgfile="${ofile}T"
trap "$RM \"$cfgfile\"; exit 1" 1 2 15
$RM "$cfgfile"
cat <<_LT_EOF >> "$cfgfile"
#! $SHELL
-# Generated automatically by $as_me ($PACKAGE) $VERSION
+
+# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services.
+# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION
# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
# NOTE: Changes made to this file will be lost: look at ltmain.sh.
-
-# Provide generalized library-building support services.
-# Written by Gordon Matzigkeit, 1996
-
-# Copyright (C) 2014 Free Software Foundation, Inc.
-# This is free software; see the source for copying conditions. There is NO
-# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
-# GNU Libtool is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of of the License, or
-# (at your option) any later version.
#
-# As a special exception to the GNU General Public License, if you
-# distribute this file as part of a program or library that is built
-# using GNU Libtool, you may include this file under the same
-# distribution terms that you use for the rest of that program.
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
+# 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+# Foundation, Inc.
+# Written by Gordon Matzigkeit, 1996
+#
+# This file is part of GNU Libtool.
+#
+# GNU Libtool is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
#
-# GNU Libtool is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
+# As a special exception to the GNU General Public License,
+# if you distribute this file as part of a program or library that
+# is built using GNU Libtool, you may include this file under the
+# same distribution terms that you use for the rest of that program.
+#
+# GNU Libtool is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
+# along with GNU Libtool; see the file COPYING. If not, a copy
+# can be downloaded from http://www.gnu.org/licenses/gpl.html, or
+# obtained by writing to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
# The names of the tagged configurations supported by this script.
-available_tags='RC '
-
-# Configured defaults for sys_lib_dlsearch_path munging.
-: \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"}
+available_tags="RC "
# ### BEGIN LIBTOOL CONFIG
@@ -19440,9 +19101,6 @@ pic_mode=$pic_mode
# Whether or not to optimize for fast installation.
fast_install=$enable_fast_install
-# Shared archive member basename,for filename based shared library versioning on AIX.
-shared_archive_member_spec=$shared_archive_member_spec
-
# Shell to use when invoking shell scripts.
SHELL=$lt_SHELL
@@ -19554,27 +19212,18 @@ global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe
# Transform the output of nm in a proper C declaration.
global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl
-# Transform the output of nm into a list of symbols to manually relocate.
-global_symbol_to_import=$lt_lt_cv_sys_global_symbol_to_import
-
# Transform the output of nm in a C name address pair.
global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address
# Transform the output of nm in a C name address pair when lib prefix is needed.
global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix
-# The name lister interface.
-nm_interface=$lt_lt_cv_nm_interface
-
# Specify filename containing input files for \$NM.
nm_file_list_spec=$lt_nm_file_list_spec
-# The root where to search for dependent libraries,and where our libraries should be installed.
+# The root where to search for dependent libraries,and in which our libraries should be installed.
lt_sysroot=$lt_sysroot
-# Command to truncate a binary pipe.
-lt_truncate_bin=$lt_lt_cv_truncate_bin
-
# The name of the directory that contains temporary libtool files.
objdir=$objdir
@@ -19665,11 +19314,8 @@ hardcode_into_libs=$hardcode_into_libs
# Compile-time system search path for libraries.
sys_lib_search_path_spec=$lt_sys_lib_search_path_spec
-# Detected run-time system search path for libraries.
-sys_lib_dlsearch_path_spec=$lt_configure_time_dlsearch_path
-
-# Explicit LT_SYS_LIBRARY_PATH set during ./configure time.
-configure_time_lt_sys_library_path=$lt_configure_time_lt_sys_library_path
+# Run-time system search path for libraries.
+sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec
# Whether dlopen is supported.
dlopen_support=$enable_dlopen
@@ -19762,13 +19408,13 @@ hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec
# Whether we need a single "-rpath" flag with a separated argument.
hardcode_libdir_separator=$lt_hardcode_libdir_separator
-# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes
+# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
# DIR into the resulting binary.
hardcode_direct=$hardcode_direct
-# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes
+# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
# DIR into the resulting binary and the resulting library dependency is
-# "absolute",i.e impossible to change by setting \$shlibpath_var if the
+# "absolute",i.e impossible to change by setting \${shlibpath_var} if the
# library is relocated.
hardcode_direct_absolute=$hardcode_direct_absolute
@@ -19820,72 +19466,13 @@ hardcode_action=$hardcode_action
_LT_EOF
- cat <<'_LT_EOF' >> "$cfgfile"
-
-# ### BEGIN FUNCTIONS SHARED WITH CONFIGURE
-
-# func_munge_path_list VARIABLE PATH
-# -----------------------------------
-# VARIABLE is name of variable containing _space_ separated list of
-# directories to be munged by the contents of PATH, which is string
-# having a format:
-# "DIR[:DIR]:"
-# string "DIR[ DIR]" will be prepended to VARIABLE
-# ":DIR[:DIR]"
-# string "DIR[ DIR]" will be appended to VARIABLE
-# "DIRP[:DIRP]::[DIRA:]DIRA"
-# string "DIRP[ DIRP]" will be prepended to VARIABLE and string
-# "DIRA[ DIRA]" will be appended to VARIABLE
-# "DIR[:DIR]"
-# VARIABLE will be replaced by "DIR[ DIR]"
-func_munge_path_list ()
-{
- case x$2 in
- x)
- ;;
- *:)
- eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\"
- ;;
- x:*)
- eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\"
- ;;
- *::*)
- eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\"
- eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\"
- ;;
- *)
- eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\"
- ;;
- esac
-}
-
-
-# Calculate cc_basename. Skip known compiler wrappers and cross-prefix.
-func_cc_basename ()
-{
- for cc_temp in $*""; do
- case $cc_temp in
- compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
- distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
- \-*) ;;
- *) break;;
- esac
- done
- func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
-}
-
-
-# ### END FUNCTIONS SHARED WITH CONFIGURE
-
-_LT_EOF
-
case $host_os in
aix3*)
cat <<\_LT_EOF >> "$cfgfile"
# AIX sometimes has problems with the GCC collect2 program. For some
# reason, if we set the COLLECT_NAMES environment variable, the problems
# vanish in a puff of smoke.
-if test set != "${COLLECT_NAMES+set}"; then
+if test "X${COLLECT_NAMES+set}" != Xset; then
COLLECT_NAMES=
export COLLECT_NAMES
fi
@@ -19894,7 +19481,7 @@ _LT_EOF
esac
-ltmain=$ac_aux_dir/ltmain.sh
+ltmain="$ac_aux_dir/ltmain.sh"
# We use sed instead of cat because bash on DJGPP gets confused if
@@ -19904,6 +19491,165 @@ ltmain=$ac_aux_dir/ltmain.sh
sed '$q' "$ltmain" >> "$cfgfile" \
|| (rm -f "$cfgfile"; exit 1)
+ if test x"$xsi_shell" = xyes; then
+ sed -e '/^func_dirname ()$/,/^} # func_dirname /c\
+func_dirname ()\
+{\
+\ case ${1} in\
+\ */*) func_dirname_result="${1%/*}${2}" ;;\
+\ * ) func_dirname_result="${3}" ;;\
+\ esac\
+} # Extended-shell func_dirname implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+ sed -e '/^func_basename ()$/,/^} # func_basename /c\
+func_basename ()\
+{\
+\ func_basename_result="${1##*/}"\
+} # Extended-shell func_basename implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+ sed -e '/^func_dirname_and_basename ()$/,/^} # func_dirname_and_basename /c\
+func_dirname_and_basename ()\
+{\
+\ case ${1} in\
+\ */*) func_dirname_result="${1%/*}${2}" ;;\
+\ * ) func_dirname_result="${3}" ;;\
+\ esac\
+\ func_basename_result="${1##*/}"\
+} # Extended-shell func_dirname_and_basename implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+ sed -e '/^func_stripname ()$/,/^} # func_stripname /c\
+func_stripname ()\
+{\
+\ # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are\
+\ # positional parameters, so assign one to ordinary parameter first.\
+\ func_stripname_result=${3}\
+\ func_stripname_result=${func_stripname_result#"${1}"}\
+\ func_stripname_result=${func_stripname_result%"${2}"}\
+} # Extended-shell func_stripname implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+ sed -e '/^func_split_long_opt ()$/,/^} # func_split_long_opt /c\
+func_split_long_opt ()\
+{\
+\ func_split_long_opt_name=${1%%=*}\
+\ func_split_long_opt_arg=${1#*=}\
+} # Extended-shell func_split_long_opt implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+ sed -e '/^func_split_short_opt ()$/,/^} # func_split_short_opt /c\
+func_split_short_opt ()\
+{\
+\ func_split_short_opt_arg=${1#??}\
+\ func_split_short_opt_name=${1%"$func_split_short_opt_arg"}\
+} # Extended-shell func_split_short_opt implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+ sed -e '/^func_lo2o ()$/,/^} # func_lo2o /c\
+func_lo2o ()\
+{\
+\ case ${1} in\
+\ *.lo) func_lo2o_result=${1%.lo}.${objext} ;;\
+\ *) func_lo2o_result=${1} ;;\
+\ esac\
+} # Extended-shell func_lo2o implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+ sed -e '/^func_xform ()$/,/^} # func_xform /c\
+func_xform ()\
+{\
+ func_xform_result=${1%.*}.lo\
+} # Extended-shell func_xform implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+ sed -e '/^func_arith ()$/,/^} # func_arith /c\
+func_arith ()\
+{\
+ func_arith_result=$(( $* ))\
+} # Extended-shell func_arith implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+ sed -e '/^func_len ()$/,/^} # func_len /c\
+func_len ()\
+{\
+ func_len_result=${#1}\
+} # Extended-shell func_len implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+fi
+
+if test x"$lt_shell_append" = xyes; then
+ sed -e '/^func_append ()$/,/^} # func_append /c\
+func_append ()\
+{\
+ eval "${1}+=\\${2}"\
+} # Extended-shell func_append implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+ sed -e '/^func_append_quoted ()$/,/^} # func_append_quoted /c\
+func_append_quoted ()\
+{\
+\ func_quote_for_eval "${2}"\
+\ eval "${1}+=\\\\ \\$func_quote_for_eval_result"\
+} # Extended-shell func_append_quoted implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+ # Save a `func_append' function call where possible by direct use of '+='
+ sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+ test 0 -eq $? || _lt_function_replace_fail=:
+else
+ # Save a `func_append' function call even when '+=' is not available
+ sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+ test 0 -eq $? || _lt_function_replace_fail=:
+fi
+
+if test x"$_lt_function_replace_fail" = x":"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to substitute extended shell functions in $ofile" >&5
+$as_echo "$as_me: WARNING: Unable to substitute extended shell functions in $ofile" >&2;}
+fi
+
+
mv -f "$cfgfile" "$ofile" ||
(rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
chmod +x "$ofile"
@@ -19990,13 +19736,13 @@ hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_RC
# Whether we need a single "-rpath" flag with a separated argument.
hardcode_libdir_separator=$lt_hardcode_libdir_separator_RC
-# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes
+# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
# DIR into the resulting binary.
hardcode_direct=$hardcode_direct_RC
-# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes
+# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
# DIR into the resulting binary and the resulting library dependency is
-# "absolute",i.e impossible to change by setting \$shlibpath_var if the
+# "absolute",i.e impossible to change by setting \${shlibpath_var} if the
# library is relocated.
hardcode_direct_absolute=$hardcode_direct_absolute_RC
diff --git a/configure.ac b/configure.ac
index 773cded..4a45f05 100644
--- a/configure.ac
+++ b/configure.ac
@@ -30,9 +30,15 @@ m4_include(version.m4)
AC_INIT([PRODUCT_NAME], [PRODUCT_VERSION], [PRODUCT_BUGREPORT], [PRODUCT_TARNAME])
m4_include(compat.m4)
AC_DEFINE([OPENVPN_VERSION_RESOURCE], [PRODUCT_VERSION_RESOURCE], [Version in windows resource format])
+AC_SUBST([OPENVPN_VERSION_MAJOR], [PRODUCT_VERSION_MAJOR], [OpenVPN major version])
+AC_SUBST([OPENVPN_VERSION_MINOR], [PRODUCT_VERSION_MINOR], [OpenVPN minor version])
+AC_SUBST([OPENVPN_VERSION_PATCH], [PRODUCT_VERSION_PATCH], [OpenVPN patch level - may be a string or integer])
+AC_DEFINE([OPENVPN_VERSION_MAJOR], [PRODUCT_VERSION_MAJOR], [OpenVPN major version - integer])
+AC_DEFINE([OPENVPN_VERSION_MINOR], [PRODUCT_VERSION_MINOR], [OpenVPN minor version - integer])
+AC_DEFINE([OPENVPN_VERSION_PATCH], ["PRODUCT_VERSION_PATCH"], [OpenVPN patch level - may be a string or integer])
AC_CONFIG_AUX_DIR([.])
-AC_CONFIG_HEADERS([config.h])
+AC_CONFIG_HEADERS([config.h include/openvpn-plugin.h])
AC_CONFIG_SRCDIR([src/openvpn/syshead.h])
AC_CONFIG_MACRO_DIR([m4])
@@ -60,11 +66,16 @@ AC_ARG_ENABLE(
[enable_lzo="yes"]
)
-AC_ARG_ENABLE(
- [lzo-stub],
- [AS_HELP_STRING([--enable-lzo-stub], [don't compile LZO compression support but still allow limited interoperability with LZO-enabled peers @<:@default=no@:>@])],
- ,
- [enable_lzo_stub="no"]
+AC_ARG_ENABLE(lz4,
+ [ --disable-lz4 Disable LZ4 compression support],
+ [enable_lz4="$enableval"],
+ [enable_lz4="yes"]
+)
+
+AC_ARG_ENABLE(comp-stub,
+ [ --enable-comp-stub Don't compile compression support but still allow limited interoperability with compression-enabled peers],
+ [enable_comp_stub="$enableval"],
+ [enable_comp_stub="no"]
)
AC_ARG_ENABLE(
@@ -82,13 +93,6 @@ AC_ARG_ENABLE(
)
AC_ARG_ENABLE(
- [ssl],
- [AS_HELP_STRING([--disable-ssl], [disable SSL support for TLS-based key exchange @<:@default=yes@:>@])],
- ,
- [enable_ssl="yes"]
-)
-
-AC_ARG_ENABLE(
[x509-alt-username],
[AS_HELP_STRING([--enable-x509-alt-username], [enable the --x509-username-field feature @<:@default=no@:>@])],
,
@@ -131,20 +135,6 @@ AC_ARG_ENABLE(
)
AC_ARG_ENABLE(
- [socks],
- [AS_HELP_STRING([--disable-socks], [disable Socks support @<:@default=yes@:>@])],
- ,
- [enable_socks="yes"]
-)
-
-AC_ARG_ENABLE(
- [http-proxy],
- [AS_HELP_STRING([--disable-http-proxy], [disable HTTP proxy support @<:@default=yes@:>@])],
- ,
- [enable_http_proxy="yes"]
-)
-
-AC_ARG_ENABLE(
[fragment],
[AS_HELP_STRING([--disable-fragment], [disable internal fragmentation support (--fragment) @<:@default=yes@:>@])],
,
@@ -247,6 +237,13 @@ AC_ARG_ENABLE(
)
AC_ARG_ENABLE(
+ [werror],
+ [AS_HELP_STRING([--enable-werror], [promote compiler warnings to errors, will cause builds to fail is the compiler issues warnings (debugging option) @<:@default=no@:>@])],
+ ,
+ [enable_werror="no"]
+)
+
+AC_ARG_ENABLE(
[strict-options],
[AS_HELP_STRING([--enable-strict-options], [enable strict options check between peers (debugging option) @<:@default=no@:>@])],
,
@@ -267,6 +264,13 @@ AC_ARG_ENABLE(
[enable_systemd="no"]
)
+AC_ARG_ENABLE(
+ [async-push],
+ [AS_HELP_STRING([--enable-async-push], [enable async-push support @<:@default=no@:>@])],
+ [enable_async_push="yes"],
+ [enable_async_push="no"]
+)
+
AC_ARG_WITH(
[special-build],
[AS_HELP_STRING([--with-special-build=STRING], [specify special build string])],
@@ -287,10 +291,10 @@ AC_ARG_WITH(
AC_ARG_WITH(
[crypto-library],
- [AS_HELP_STRING([--with-crypto-library=library], [build with the given crypto library, TYPE=openssl|polarssl @<:@default=openssl@:>@])],
+ [AS_HELP_STRING([--with-crypto-library=library], [build with the given crypto library, TYPE=openssl|mbedtls @<:@default=openssl@:>@])],
[
- case "${withval}" in
- openssl|polarssl) ;;
+ case "${withval}" in
+ openssl|mbedtls) ;;
*) AC_MSG_ERROR([bad value ${withval} for --with-crypto-library]) ;;
esac
],
@@ -314,6 +318,7 @@ case "$host" in
*-*-solaris*)
AC_DEFINE([TARGET_SOLARIS], [1], [Are we running on Solaris?])
AC_DEFINE_UNQUOTED([TARGET_PREFIX], ["S"], [Target prefix])
+ CPPFLAGS="$CPPFLAGS -D_XPG4_2"
;;
*-*-openbsd*)
AC_DEFINE([TARGET_OPENBSD], [1], [Are we running on OpenBSD?])
@@ -333,18 +338,26 @@ case "$host" in
have_tap_header="yes"
dnl some Mac OS X tendering (we use vararg macros...)
CPPFLAGS="$CPPFLAGS -no-cpp-precomp"
+ ac_cv_type_struct_in_pktinfo=no
;;
*-mingw*)
AC_DEFINE([TARGET_WIN32], [1], [Are we running WIN32?])
AC_DEFINE_UNQUOTED([TARGET_PREFIX], ["W"], [Target prefix])
CPPFLAGS="${CPPFLAGS} -DWIN32_LEAN_AND_MEAN"
- CPPFLAGS="${CPPFLAGS} -DNTDDI_VERSION=NTDDI_WINXP -D_WIN32_WINNT=_WIN32_WINNT_WINXP"
+ CPPFLAGS="${CPPFLAGS} -DNTDDI_VERSION=NTDDI_VISTA -D_WIN32_WINNT=_WIN32_WINNT_VISTA"
WIN32=yes
;;
*-*-dragonfly*)
AC_DEFINE([TARGET_DRAGONFLY], [1], [Are we running on DragonFlyBSD?])
AC_DEFINE_UNQUOTED([TARGET_PREFIX], ["D"], [Target prefix])
;;
+ *-aix*)
+ AC_DEFINE([TARGET_AIX], [1], [Are we running AIX?])
+ AC_DEFINE_UNQUOTED([TARGET_PREFIX], ["A"], [Target prefix])
+ ROUTE="/usr/sbin/route"
+ have_tap_header="yes"
+ ac_cv_header_net_if_h="no" # exists, but breaks things
+ ;;
*)
AC_DEFINE_UNQUOTED([TARGET_PREFIX], ["X"], [Target prefix])
have_tap_header="yes"
@@ -377,6 +390,12 @@ AC_DEFINE_UNQUOTED([IPROUTE_PATH], ["$IPROUTE"], [Path to iproute tool])
AC_DEFINE_UNQUOTED([ROUTE_PATH], ["$ROUTE"], [Path to route tool])
AC_DEFINE_UNQUOTED([SYSTEMD_ASK_PASSWORD_PATH], ["$SYSTEMD_ASK_PASSWORD"], [Path to systemd-ask-password tool])
+# Set -std=c99 unless user already specified a -std=
+case "${CFLAGS}" in
+ *-std=*) ;;
+ *) CFLAGS="${CFLAGS} -std=c99" ;;
+esac
+
#
# Libtool
#
@@ -444,6 +463,9 @@ SOCKET_INCLUDES="
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
+#ifdef HAVE_NET_IF_H
+#include <net/if.h>
+#endif
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
@@ -477,6 +499,12 @@ AC_CHECK_TYPES(
[AC_DEFINE([in_addr_t], [uint32_t], [Workaround missing in_addr_t])],
[[${SOCKET_INCLUDES}]]
)
+AC_CHECK_TYPES(
+ [in_port_t],
+ ,
+ [AC_DEFINE([in_port_t], [uint16_t], [Workaround missing in_port_t])],
+ [[${SOCKET_INCLUDES}]]
+)
AC_CHECK_TYPE(
[struct iphdr],
[AC_DEFINE([HAVE_IPHDR], [1], [struct iphdr needed for IPv6 support])],
@@ -508,6 +536,18 @@ AC_CHECK_TYPE(
[[${SOCKET_INCLUDES}]]
)
AC_CHECK_TYPE(
+ [sa_family_t],
+ [AC_DEFINE([HAVE_SA_FAMILY_T], [1], [sa_family_t, needed to hold AF_* info])],
+ ,
+ [[${SOCKET_INCLUDES}]]
+)
+AC_CHECK_MEMBER(
+ [struct in_pktinfo.ipi_spec_dst],
+ [AC_DEFINE([HAVE_IPI_SPEC_DST], [1], [struct in_pktinfo.ipi_spec_dst needed for IP_PKTINFO support])],
+ ,
+ [[${SOCKET_INCLUDES}]]
+)
+AC_CHECK_TYPE(
[struct sockaddr_in6],
,
[AC_MSG_ERROR([struct sockaddr_in6 not found, needed for ipv6 transport support.])],
@@ -519,6 +559,28 @@ AC_CHECK_DECLS(
,
[[${SOCKET_INCLUDES}]]
)
+AC_CHECKING([anonymous union support])
+AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[
+ struct mystruct {
+ union {
+ int m1;
+ char m2;
+ };
+ };
+ ]],
+ [[
+ struct mystruct s;
+ s.m1 = 1; s.m2 = 2;
+ ]]
+ )],
+ [
+ AC_MSG_RESULT([yes])
+ AC_DEFINE([HAVE_ANONYMOUS_UNION_SUPPORT], [], [Compiler supports anonymous unions])
+ ],
+ [AC_MSG_RESULT([no])]
+)
dnl We emulate signals in Windows
AC_CHECK_DECLS(
@@ -610,7 +672,7 @@ AC_SUBST([SOCKETS_LIBS])
old_LIBS="${LIBS}"
LIBS="${LIBS} ${SOCKETS_LIBS}"
-AC_CHECK_FUNCS([sendmsg recvmsg inet_ntop inet_pton])
+AC_CHECK_FUNCS([sendmsg recvmsg])
# Windows use stdcall for winsock so we cannot auto detect these
m4_define(
[SOCKET_FUNCS],
@@ -622,6 +684,27 @@ m4_define(
[setsockopt getsockopt getsockname poll]dnl
)
if test "${WIN32}" = "yes"; then
+# normal autoconf function checking does not find inet_ntop/inet_pton
+# because they need to include the actual header file and link ws2_32.dll
+ LIBS="${LIBS} -lws2_32"
+ AC_MSG_CHECKING([for MinGW inet_ntop()/inet_pton()])
+ AC_LINK_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[
+#include <ws2tcpip.h>
+ ]],
+ [[
+int r = (int) inet_ntop (0, NULL, NULL, 0);
+ r += inet_pton(AF_INET, NULL, NULL);
+return r;
+ ]]
+ )],
+ [AC_MSG_RESULT([OK])
+ AC_DEFINE([HAVE_INET_NTOP],[1],[MinGW inet_ntop])
+ AC_DEFINE([HAVE_INET_PTON],[1],[MinGW inet_pton])
+ ],
+ [AC_MSG_RESULT([not found])]
+ )
m4_foreach(
[F],
m4_split(SOCKET_FUNCS SOCKET_OPT_FUNCS),
@@ -629,6 +712,7 @@ if test "${WIN32}" = "yes"; then
AC_DEFINE([UF], [1], [Win32 builtin])
)
else
+ AC_CHECK_FUNCS([inet_ntop inet_pton])
AC_CHECK_FUNCS(
SOCKET_FUNCS,
,
@@ -686,7 +770,7 @@ fi
case "${with_mem_check}" in
valgrind)
- AC_CHECK_HEADER(
+ AC_CHECK_HEADERS(
[valgrind/memcheck.h],
[
CFLAGS="${CFLAGS} -g -fno-inline"
@@ -700,7 +784,7 @@ case "${with_mem_check}" in
)
;;
dmalloc)
- AC_CHECK_HEADER(
+ AC_CHECK_HEADERS(
[dmalloc.h],
[AC_CHECK_LIB(
[dmalloc],
@@ -742,42 +826,32 @@ PKG_CHECK_MODULES(
[]
)
-PKG_CHECK_MODULES(
- [OPENSSL_CRYPTO],
- [libcrypto >= 0.9.6],
- [have_openssl_crypto="yes"],
- [AC_CHECK_LIB(
- [crypto],
- [RSA_new],
- [
- have_openssl_crypto="yes"
- OPENSSL_CRYPTO_LIBS="-lcrypto"
- ]
- )]
-)
+if test "${enable_crypto}" = "yes" -a "${with_crypto_library}" = "openssl"; then
+ AC_ARG_VAR([OPENSSL_CFLAGS], [C compiler flags for OpenSSL])
+ AC_ARG_VAR([OPENSSL_LIBS], [linker flags for OpenSSL])
+
+ if test -z "${OPENSSL_CFLAGS}" -a -z "${OPENSSL_LIBS}"; then
+ # if the user did not explicitly specify flags, try to autodetect
+ PKG_CHECK_MODULES(
+ [OPENSSL],
+ [libcrypto >= 0.9.8, libssl >= 0.9.8],
+ [have_openssl="yes"],
+ [have_openssl="no"] # Provide if-not-found to prevent erroring out
+ )
-PKG_CHECK_MODULES(
- [OPENSSL_SSL],
- [libssl >= 0.9.6],
- [have_openssl_ssl="yes"],
- [AC_CHECK_LIB(
- [ssl],
- [SSL_CTX_new],
- [
- have_openssl_ssl="yes"
- OPENSSL_SSL_LIBS="-lssl"
- ],
- [],
- [-lcrypto]
- )]
-)
+ OPENSSL_LIBS=${OPENSSL_LIBS:--lssl -lcrypto}
+ fi
-if test "${have_openssl_crypto}" = "yes"; then
saved_CFLAGS="${CFLAGS}"
saved_LIBS="${LIBS}"
- CFLAGS="${CFLAGS} ${OPENSSL_CRYPTO_CFLAGS}"
- LIBS="${LIBS} ${OPENSSL_CRYPTO_LIBS}"
- AC_CHECK_FUNCS([EVP_CIPHER_CTX_set_key_length])
+ CFLAGS="${CFLAGS} ${OPENSSL_CFLAGS}"
+ LIBS="${LIBS} ${OPENSSL_LIBS}"
+
+ AC_CHECK_FUNCS([SSL_CTX_new EVP_CIPHER_CTX_set_key_length],
+ ,
+ [AC_MSG_ERROR([openssl check failed])]
+ )
+
have_openssl_engine="yes"
AC_CHECK_FUNCS(
[ \
@@ -788,83 +862,109 @@ if test "${have_openssl_crypto}" = "yes"; then
,
[have_openssl_engine="no"; break]
)
+ if test "${have_openssl_engine}" = "yes"; then
+ AC_DEFINE([HAVE_OPENSSL_ENGINE], [1], [OpenSSL engine support available])
+ fi
+
+ have_crypto_aead_modes="yes"
+ AC_CHECK_FUNCS(
+ [EVP_aes_256_gcm],
+ ,
+ [have_crypto_aead_modes="no"; break]
+ )
CFLAGS="${saved_CFLAGS}"
LIBS="${saved_LIBS}"
-fi
-AC_ARG_VAR([POLARSSL_CFLAGS], [C compiler flags for polarssl])
-AC_ARG_VAR([POLARSSL_LIBS], [linker flags for polarssl])
-have_polarssl_ssl="yes"
-have_polarssl_crypto="yes"
-if test -z "${POLARSSL_LIBS}"; then
- AC_CHECK_LIB(
- [polarssl],
- [ssl_init],
- [POLARSSL_LIBS="-lpolarssl"],
- [
- have_polarssl_ssl="no"
- AC_CHECK_LIB(
- [polarssl],
- [aes_crypt_cbc],
- ,
- [have_polarssl_crypto="no"],
- [${PKCS11_HELPER_LIBS}]
- )
- ],
- [${PKCS11_HELPER_LIBS}]
- )
-fi
+ have_crypto="yes"
+ AC_DEFINE([ENABLE_CRYPTO_OPENSSL], [1], [Use OpenSSL library])
+ CRYPTO_CFLAGS="${OPENSSL_CFLAGS}"
+ CRYPTO_LIBS="${OPENSSL_LIBS}"
+elif test "${enable_crypto}" = "yes" -a "${with_crypto_library}" = "mbedtls"; then
+ AC_ARG_VAR([MBEDTLS_CFLAGS], [C compiler flags for mbedtls])
+ AC_ARG_VAR([MBEDTLS_LIBS], [linker flags for mbedtls])
-if test "${with_crypto_library}" = "polarssl" ; then
- AC_MSG_CHECKING([polarssl version])
- old_CFLAGS="${CFLAGS}"
- CFLAGS="${POLARSSL_CFLAGS} ${CFLAGS}"
+ saved_CFLAGS="${CFLAGS}"
+ saved_LIBS="${LIBS}"
+
+ if test -z "${MBEDTLS_CFLAGS}" -a -z "${MBEDTLS_LIBS}"; then
+ # if the user did not explicitly specify flags, try to autodetect
+ LIBS="${LIBS} -lmbedtls -lmbedx509 -lmbedcrypto"
+ AC_CHECK_LIB(
+ [mbedtls],
+ [mbedtls_ssl_init],
+ [MBEDTLS_LIBS="-lmbedtls -lmbedx509 -lmbedcrypto"],
+ [AC_MSG_ERROR([Could not find mbed TLS.])],
+ [${PKCS11_HELPER_LIBS}]
+ )
+ fi
+
+ CFLAGS="${MBEDTLS_CFLAGS} ${PKCS11_HELPER_CFLAGS} ${CFLAGS}"
+ LIBS="${MBEDTLS_LIBS} ${PKCS11_HELPER_LIBS} ${LIBS}"
+
+ AC_MSG_CHECKING([mbedtls version])
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM(
[[
-#include <polarssl/version.h>
+#include <mbedtls/version.h>
]],
[[
-#if POLARSSL_VERSION_NUMBER < 0x01030800 || POLARSSL_VERSION_NUMBER >= 0x01040000
+#if MBEDTLS_VERSION_NUMBER < 0x02000000 || MBEDTLS_VERSION_NUMBER >= 0x03000000
#error invalid version
#endif
]]
)],
[AC_MSG_RESULT([ok])],
- [AC_MSG_ERROR([PolarSSL 1.3.x required and must be 1.3.8 or later])]
+ [AC_MSG_ERROR([mbed TLS 2.y.z required])]
)
- polarssl_with_pkcs11="no"
+ mbedtls_with_pkcs11="no"
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM(
[[
-#include <polarssl/config.h>
+#include <mbedtls/config.h>
]],
[[
-#ifndef POLARSSL_PKCS11_C
+#ifndef MBEDTLS_PKCS11_C
#error pkcs11 wrapper missing
#endif
]]
)],
- polarssl_with_pkcs11="yes")
- CFLAGS="${old_CFLAGS}"
+ mbedtls_with_pkcs11="yes")
- AC_MSG_CHECKING([polarssl pkcs11 support])
+ AC_MSG_CHECKING([mbedtls pkcs11 support])
if test "${enable_pkcs11}" = "yes"; then
- if test "${polarssl_with_pkcs11}" = "yes"; then
+ if test "${mbedtls_with_pkcs11}" = "yes"; then
AC_MSG_RESULT([ok])
else
- AC_MSG_ERROR([polarssl has no pkcs11 wrapper compiled in])
+ AC_MSG_ERROR([mbedtls has no pkcs11 wrapper compiled in])
fi
else
- if test "${polarssl_with_pkcs11}" != "yes"; then
+ if test "${mbedtls_with_pkcs11}" != "yes"; then
AC_MSG_RESULT([ok])
else
- AC_MSG_ERROR([PolarSSL compiled with PKCS11, while OpenVPN is not])
+ AC_MSG_ERROR([mbed TLS compiled with PKCS11, while OpenVPN is not])
fi
fi
+ have_crypto_aead_modes="yes"
+ AC_CHECK_FUNCS(
+ [ \
+ mbedtls_cipher_write_tag \
+ mbedtls_cipher_check_tag \
+ ],
+ ,
+ [have_crypto_aead_modes="no"; break]
+ )
+
+ CFLAGS="${saved_CFLAGS}"
+ LIBS="${saved_LIBS}"
+ have_crypto="yes"
+ AC_DEFINE([ENABLE_CRYPTO_MBEDTLS], [1], [Use mbed TLS library])
+ CRYPTO_CFLAGS="${MBEDTLS_CFLAGS}"
+ CRYPTO_LIBS="${MBEDTLS_LIBS}"
+elif test "${enable_crypto}" = "yes"; then
+ AC_MSG_ERROR([Invalid crypto library: ${with_crypto_library}])
fi
AC_ARG_VAR([LZO_CFLAGS], [C compiler flags for lzo])
@@ -907,16 +1007,62 @@ if test "${have_lzo}" = "yes"; then
CFLAGS="${saved_CFLAGS}"
fi
+dnl
+dnl check for LZ4 library
+dnl
+
+AC_ARG_VAR([LZ4_CFLAGS], [C compiler flags for lz4])
+AC_ARG_VAR([LZ4_LIBS], [linker flags for lz4])
+if test "$enable_lz4" = "yes" && test "$enable_comp_stub" = "no"; then
+ AC_CHECKING([for LZ4 Library and Header files])
+ havelz4lib=1
+
+ # if LZ4_LIBS is set, we assume it will work, otherwise test
+ if test -z "${LZ4_LIBS}"; then
+ AC_CHECK_LIB(lz4, LZ4_compress,
+ [ LZ4_LIBS="-llz4" ],
+ [
+ AC_MSG_RESULT([LZ4 library not found.])
+ havelz4lib=0
+ ])
+ fi
+
+ saved_CFLAGS="${CFLAGS}"
+ CFLAGS="${CFLAGS} ${LZ4_CFLAGS}"
+ AC_CHECK_HEADERS(lz4.h,
+ ,
+ [
+ AC_MSG_RESULT([LZ4 headers not found.])
+ havelz4lib=0
+ ])
+
+ if test $havelz4lib = 0 ; then
+ AC_MSG_RESULT([LZ4 library or header not found, using version in src/compat/compat-lz4.*])
+ AC_DEFINE([NEED_COMPAT_LZ4], [1], [use copy of LZ4 source in compat/])
+ LZ4_LIBS=""
+ fi
+ OPTIONAL_LZ4_CFLAGS="${LZ4_CFLAGS}"
+ OPTIONAL_LZ4_LIBS="${LZ4_LIBS}"
+ AC_DEFINE(ENABLE_LZ4, 1, [Enable LZ4 compression library])
+ CFLAGS="${saved_CFLAGS}"
+fi
+
dnl
dnl Check for systemd
dnl
-
+AM_CONDITIONAL([ENABLE_SYSTEMD], [test "${enable_systemd}" = "yes"])
if test "$enable_systemd" = "yes" ; then
PKG_CHECK_MODULES([libsystemd], [systemd libsystemd],
[],
[PKG_CHECK_MODULES([libsystemd], [libsystemd-daemon])]
)
+
+ PKG_CHECK_EXISTS( [libsystemd > 216],
+ [AC_DEFINE([SYSTEMD_NEWER_THAN_216], [1],
+ [systemd is newer than v216])]
+ )
+
AC_CHECK_HEADERS(systemd/sd-daemon.h,
,
[
@@ -950,8 +1096,8 @@ fi
dnl enable --x509-username-field feature if requested
if test "${enable_x509_alt_username}" = "yes"; then
- if test "${with_crypto_library}" = "polarssl" ; then
- AC_MSG_ERROR([PolarSSL does not support the --x509-username-field feature])
+ if test "${with_crypto_library}" = "mbedtls" ; then
+ AC_MSG_ERROR([mbed TLS does not support the --x509-username-field feature])
fi
AC_DEFINE([ENABLE_X509ALTUSERNAME], [1], [Enable --x509-username-field feature])
@@ -961,8 +1107,6 @@ test "${ac_cv_header_sys_uio_h}" = "yes" && AC_DEFINE([HAVE_IOVEC], [1], [struct
test "${enable_multi}" = "yes" && AC_DEFINE([ENABLE_CLIENT_SERVER], [1], [Enable client/server capability])
test "${enable_server}" = "no" && AC_DEFINE([ENABLE_CLIENT_ONLY], [1], [Enable client capability only])
test "${enable_management}" = "yes" && AC_DEFINE([ENABLE_MANAGEMENT], [1], [Enable management server capability])
-test "${enable_socks}" = "yes" && AC_DEFINE([ENABLE_SOCKS], [1], [Enable Socks proxy support])
-test "${enable_http_proxy}" = "yes" && AC_DEFINE([ENABLE_HTTP_PROXY], [1], [Enable HTTP proxy support])
test "${enable_multihome}" = "yes" && AC_DEFINE([ENABLE_MULTIHOME], [1], [Enable multi-homed UDP server capability])
test "${enable_debug}" = "yes" && AC_DEFINE([ENABLE_DEBUG], [1], [Enable debugging support])
test "${enable_small}" = "yes" && AC_DEFINE([ENABLE_SMALL], [1], [Enable smaller executable size])
@@ -972,39 +1116,12 @@ test "${enable_def_auth}" = "yes" && AC_DEFINE([ENABLE_DEF_AUTH], [1], [Enable d
test "${enable_pf}" = "yes" && AC_DEFINE([ENABLE_PF], [1], [Enable internal packet filter])
test "${enable_strict_options}" = "yes" && AC_DEFINE([ENABLE_STRICT_OPTIONS_CHECK], [1], [Enable strict options check between peers])
-case "${with_crypto_library}" in
- openssl)
- have_crypto_crypto="${have_openssl_crypto}"
- have_crypto_ssl="${have_openssl_ssl}"
- CRYPTO_CRYPTO_CFLAGS="${OPENSSL_CRYPTO_CFLAGS}"
- CRYPTO_CRYPTO_LIBS="${OPENSSL_CRYPTO_LIBS}"
- CRYPTO_SSL_CFLAGS="${OPENSSL_SSL_CFLAGS}"
- CRYPTO_SSL_LIBS="${OPENSSL_SSL_LIBS}"
- AC_DEFINE([ENABLE_CRYPTO_OPENSSL], [1], [Use OpenSSL library])
- test "${have_openssl_engine}" = "yes" && AC_DEFINE([HAVE_OPENSSL_ENGINE], [1], [Use crypto library])
- ;;
- polarssl)
- have_crypto_crypto="${have_polarssl_crypto}"
- have_crypto_ssl="${have_polarssl_ssl}"
- CRYPTO_CRYPTO_CFLAGS="${POLARSSL_CFLAGS}"
- CRYPTO_CRYPTO_LIBS="${POLARSSL_LIBS}"
- AC_DEFINE([ENABLE_CRYPTO_POLARSSL], [1], [Use PolarSSL library])
- ;;
-esac
-
-if test "${enable_ssl}" = "yes"; then
- test "${enable_crypto}" != "yes" && AC_MSG_ERROR([crypto must be enabled for ssl])
- test "${have_crypto_ssl}" != "yes" && AC_MSG_ERROR([${with_ssl_library} ssl is required but missing])
- OPTIONAL_CRYPTO_CFLAGS="${OPTIONAL_CRYPTO_CFLAGS} ${CRYPTO_SSL_CFLAGS}"
- OPTIONAL_CRYPTO_LIBS="${OPTIONAL_CRYPTO_LIBS} ${CRYPTO_SSL_LIBS}"
- AC_DEFINE([ENABLE_SSL], [1], [Enable ssl library])
-fi
-
if test "${enable_crypto}" = "yes"; then
- test "${have_crypto_crypto}" != "yes" && AC_MSG_ERROR([${with_crypto_library} crypto is required but missing])
+ test "${have_crypto}" != "yes" && AC_MSG_ERROR([${with_crypto_library} crypto is required but missing])
test "${enable_crypto_ofb_cfb}" = "yes" && AC_DEFINE([ENABLE_OFB_CFB_MODE], [1], [Enable OFB and CFB cipher modes])
- OPTIONAL_CRYPTO_CFLAGS="${OPTIONAL_CRYPTO_CFLAGS} ${CRYPTO_CRYPTO_CFLAGS}"
- OPTIONAL_CRYPTO_LIBS="${OPTIONAL_CRYPTO_LIBS} ${CRYPTO_CRYPTO_LIBS}"
+ test "${have_crypto_aead_modes}" = "yes" && AC_DEFINE([HAVE_AEAD_CIPHER_MODES], [1], [Use crypto library])
+ OPTIONAL_CRYPTO_CFLAGS="${OPTIONAL_CRYPTO_CFLAGS} ${CRYPTO_CFLAGS}"
+ OPTIONAL_CRYPTO_LIBS="${OPTIONAL_CRYPTO_LIBS} ${CRYPTO_LIBS}"
AC_DEFINE([ENABLE_CRYPTO], [1], [Enable crypto library])
fi
@@ -1038,15 +1155,15 @@ if test "${enable_lzo}" = "yes"; then
OPTIONAL_LZO_LIBS="${LZO_LIBS}"
AC_DEFINE([ENABLE_LZO], [1], [Enable LZO compression library])
fi
-if test "${enable_lzo_stub}" = "yes"; then
- test "${enable_lzo}" = "yes" && AC_MSG_ERROR([Cannot have both lzo stub and lzo enabled])
- AC_DEFINE([ENABLE_LZO_STUB], [1], [Enable LZO stub capability])
- AC_DEFINE([ENABLE_LZO], [1], [Enable LZO compression library])
+if test "${enable_comp_stub}" = "yes"; then
+ test "${enable_lzo}" = "yes" && AC_MSG_ERROR([Cannot have both comp stub and lzo enabled (use --disable-lzo)])
+ test "${enable_lz4}" = "yes" && AC_MSG_ERROR([Cannot have both comp stub and LZ4 enabled (use --disable-lz4)])
+ AC_DEFINE([ENABLE_COMP_STUB], [1], [Enable compression stub capability])
fi
if test "${enable_pkcs11}" = "yes"; then
test "${have_pkcs11_helper}" != "yes" && AC_MSG_ERROR([PKCS11 enabled but libpkcs11-helper is missing])
- test "${enable_ssl}" != "yes" && AC_MSG_ERROR([PKCS11 can be enabled only if SSL is enabled])
+ test "${enable_crypto}" != "yes" && AC_MSG_ERROR([PKCS11 can be enabled only if crypto is enabled])
OPTIONAL_PKCS11_HELPER_CFLAGS="${PKCS11_HELPER_CFLAGS}"
OPTIONAL_PKCS11_HELPER_LIBS="${PKCS11_HELPER_LIBS}"
AC_DEFINE([ENABLE_PKCS11], [1], [Enable PKCS11])
@@ -1062,11 +1179,14 @@ fi
if test "${enable_pedantic}" = "yes"; then
enable_strict="yes"
CFLAGS="${CFLAGS} -pedantic"
- test "${WIN32}" != "yes" && CFLAGS="${CFLAGS} -ansi"
+ AC_DEFINE([PEDANTIC], [1], [Enable pedantic mode])
fi
if test "${enable_strict}" = "yes"; then
CFLAGS="${CFLAGS} -Wall -Wno-unused-parameter -Wno-unused-function"
fi
+if test "${enable_werror}" = "yes"; then
+ CFLAGS="${CFLAGS} -Werror"
+fi
if test "${WIN32}" = "yes"; then
test -z "${MAN2HTML}" && AC_MSG_ERROR([man2html is required for win32])
@@ -1083,6 +1203,14 @@ if test "${enable_plugin_auth_pam}" = "yes"; then
fi
fi
+if test "${enable_async_push}" = "yes"; then
+ AC_CHECK_HEADERS(
+ [sys/inotify.h],
+ AC_DEFINE([ENABLE_ASYNC_PUSH], [1], [Enable async push]),
+ AC_MSG_ERROR([inotify.h not found.])
+ )
+fi
+
CONFIGURE_DEFINES="`set | grep '^enable_.*=' ; set | grep '^with_.*='`"
AC_DEFINE_UNQUOTED([CONFIGURE_DEFINES], ["`echo ${CONFIGURE_DEFINES}`"], [Configuration settings])
@@ -1102,6 +1230,8 @@ AC_SUBST([OPTIONAL_CRYPTO_CFLAGS])
AC_SUBST([OPTIONAL_CRYPTO_LIBS])
AC_SUBST([OPTIONAL_LZO_CFLAGS])
AC_SUBST([OPTIONAL_LZO_LIBS])
+AC_SUBST([OPTIONAL_LZ4_CFLAGS])
+AC_SUBST([OPTIONAL_LZ4_LIBS])
AC_SUBST([OPTIONAL_SYSTEMD_LIBS])
AC_SUBST([OPTIONAL_PKCS11_HELPER_CFLAGS])
AC_SUBST([OPTIONAL_PKCS11_HELPER_LIBS])
@@ -1113,12 +1243,42 @@ AM_CONDITIONAL([WIN32], [test "${WIN32}" = "yes"])
AM_CONDITIONAL([GIT_CHECKOUT], [test "${GIT_CHECKOUT}" = "yes"])
AM_CONDITIONAL([ENABLE_PLUGIN_AUTH_PAM], [test "${enable_plugin_auth_pam}" = "yes"])
AM_CONDITIONAL([ENABLE_PLUGIN_DOWN_ROOT], [test "${enable_plugin_down_root}" = "yes"])
+AM_CONDITIONAL([ENABLE_CRYPTO], [test "${enable_crypto}" = "yes"])
plugindir="${with_plugindir}"
sampledir="\$(docdir)/sample"
AC_SUBST([plugindir])
AC_SUBST([sampledir])
+VENDOR_SRC_ROOT="\$(abs_top_srcdir)/vendor/"
+VENDOR_DIST_ROOT="\$(abs_top_builddir)/vendor/dist"
+VENDOR_BUILD_ROOT="\$(abs_top_builddir)/vendor/.build"
+AC_SUBST([VENDOR_SRC_ROOT])
+AC_SUBST([VENDOR_BUILD_ROOT])
+AC_SUBST([VENDOR_DIST_ROOT])
+
+TEST_LDFLAGS="-lcmocka -L\$(abs_top_builddir)/vendor/dist/lib -Wl,-rpath,\$(abs_top_builddir)/vendor/dist/lib"
+TEST_CFLAGS="-I\$(top_srcdir)/include -I\$(abs_top_builddir)/vendor/dist/include"
+
+AC_SUBST([TEST_LDFLAGS])
+AC_SUBST([TEST_CFLAGS])
+
+# Check if cmake is available and cmocka git submodule is initialized,
+# needed for unit testing
+AC_CHECK_PROGS([CMAKE], [cmake])
+if test -n "${CMAKE}"; then
+ if test -f "${srcdir}/vendor/cmocka/CMakeLists.txt"; then
+ AM_CONDITIONAL([CMOCKA_INITIALIZED], [true])
+ else
+ AM_CONDITIONAL([CMOCKA_INITIALIZED], [false])
+ AC_MSG_RESULT([!! WARNING !! The cmoka git submodule has not been initialized or updated. Unit testing cannot be performed.])
+ fi
+else
+ AC_MSG_RESULT([!! WARNING !! CMake is NOT available. Unit testing cannot be performed.])
+ AM_CONDITIONAL([CMOCKA_INITIALIZED], [false])
+fi
+
+
AC_CONFIG_FILES([
version.sh
Makefile
@@ -1137,6 +1297,12 @@ AC_CONFIG_FILES([
src/plugins/auth-pam/Makefile
src/plugins/down-root/Makefile
tests/Makefile
+ tests/unit_tests/Makefile
+ tests/unit_tests/example_test/Makefile
+ tests/unit_tests/openvpn/Makefile
+ tests/unit_tests/plugins/Makefile
+ tests/unit_tests/plugins/auth-pam/Makefile
+ vendor/Makefile
sample/Makefile
doc/Makefile
])
diff --git a/contrib/keychain-mcd/Makefile b/contrib/keychain-mcd/Makefile
new file mode 100644
index 0000000..c6431df
--- /dev/null
+++ b/contrib/keychain-mcd/Makefile
@@ -0,0 +1,13 @@
+CFILES = cert_data.c common_osx.c crypto_osx.c main.c
+OFILES = $(CFILES:.c=.o) ../../src/openvpn/base64.o
+prog = keychain-mcd
+
+CC = gcc
+CFLAGS = -Wall
+LDFLAGS = -framework CoreFoundation -framework Security -framework CoreServices
+
+$(prog): $(OFILES)
+ $(CC) $(LDFLAGS) $(OFILES) -o $(prog)
+
+%.o: %.c
+ $(CC) $(CFLAGS) -c $< -o $@
diff --git a/contrib/keychain-mcd/cert_data.c b/contrib/keychain-mcd/cert_data.c
new file mode 100644
index 0000000..a04bf79
--- /dev/null
+++ b/contrib/keychain-mcd/cert_data.c
@@ -0,0 +1,734 @@
+/*
+ * OpenVPN -- An application to securely tunnel IP networks
+ * over a single UDP port, with support for SSL/TLS-based
+ * session authentication and key exchange,
+ * packet encryption, packet authentication, and
+ * packet compression.
+ *
+ * Copyright (C) 2010 Brian Raderman <brian@irregularexpression.org>
+ * Copyright (C) 2013-2015 Vasily Kulikov <segoon@openwall.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program (see the file COPYING included with this
+ * distribution); if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#include "cert_data.h"
+#include <CommonCrypto/CommonDigest.h>
+#include <openssl/ssl.h>
+
+#include "common_osx.h"
+#include "crypto_osx.h"
+#include <err.h>
+
+CFStringRef kCertDataSubjectName = CFSTR("subject"),
+ kCertDataIssuerName = CFSTR("issuer"),
+ kCertDataSha1Name = CFSTR("SHA1"),
+ kCertDataMd5Name = CFSTR("MD5"),
+ kCertDataSerialName = CFSTR("serial"),
+ kCertNameFwdSlash = CFSTR("/"),
+ kCertNameEquals = CFSTR("=");
+CFStringRef kCertNameOrganization = CFSTR("o"),
+ kCertNameOrganizationalUnit = CFSTR("ou"),
+ kCertNameCountry = CFSTR("c"),
+ kCertNameLocality = CFSTR("l"),
+ kCertNameState = CFSTR("st"),
+ kCertNameCommonName = CFSTR("cn"),
+ kCertNameEmail = CFSTR("e");
+CFStringRef kStringSpace = CFSTR(" "),
+ kStringEmpty = CFSTR("");
+
+typedef struct _CertName
+{
+ CFArrayRef countryName, organization, organizationalUnit, commonName, description, emailAddress,
+ stateName, localityName;
+} CertName, *CertNameRef;
+
+typedef struct _DescData
+{
+ CFStringRef name, value;
+} DescData, *DescDataRef;
+
+void destroyDescData(DescDataRef pData);
+
+CertNameRef createCertName()
+{
+ CertNameRef pCertName = (CertNameRef)malloc(sizeof(CertName));
+ pCertName->countryName = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+ pCertName->organization = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+ pCertName->organizationalUnit = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+ pCertName->commonName = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+ pCertName->description = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+ pCertName->emailAddress = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+ pCertName->stateName = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+ pCertName->localityName = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+ return pCertName;
+}
+
+void destroyCertName(CertNameRef pCertName)
+{
+ if (!pCertName)
+ return;
+
+ CFRelease(pCertName->countryName);
+ CFRelease(pCertName->organization);
+ CFRelease(pCertName->organizationalUnit);
+ CFRelease(pCertName->commonName);
+ CFRelease(pCertName->description);
+ CFRelease(pCertName->emailAddress);
+ CFRelease(pCertName->stateName);
+ CFRelease(pCertName->localityName);
+ free(pCertName);
+}
+
+bool CFStringRefCmpCString(CFStringRef cfstr, const char *str)
+{
+ CFStringRef tmp = CFStringCreateWithCStringNoCopy(NULL, str, kCFStringEncodingUTF8, kCFAllocatorNull);
+ CFComparisonResult cresult = CFStringCompare(cfstr, tmp, 0);
+ bool result = cresult == kCFCompareEqualTo;
+ CFRelease(tmp);
+ return result;
+}
+
+CFDateRef GetDateFieldFromCertificate(SecCertificateRef certificate, CFTypeRef oid)
+{
+ const void *keys[] = { oid };
+ CFDictionaryRef dict = NULL;
+ CFErrorRef error;
+ CFDateRef date = NULL;
+
+ CFArrayRef keySelection = CFArrayCreate(NULL, keys , sizeof(keys)/sizeof(keys[0]), &kCFTypeArrayCallBacks);
+ dict = SecCertificateCopyValues(certificate, keySelection, &error);
+ if (dict == NULL)
+ {
+ printErrorMsg("GetDateFieldFromCertificate: SecCertificateCopyValues", error);
+ goto release_ks;
+ }
+ CFDictionaryRef vals = dict ? CFDictionaryGetValue(dict, oid) : NULL;
+ CFNumberRef vals2 = vals ? CFDictionaryGetValue(vals, kSecPropertyKeyValue) : NULL;
+ if (vals2 == NULL)
+ goto release_dict;
+
+ CFAbsoluteTime validityNotBefore;
+ if (CFNumberGetValue(vals2, kCFNumberDoubleType, &validityNotBefore))
+ date = CFDateCreate(kCFAllocatorDefault,validityNotBefore);
+
+release_dict:
+ CFRelease(dict);
+release_ks:
+ CFRelease(keySelection);
+ return date;
+}
+
+CFArrayRef GetFieldsFromCertificate(SecCertificateRef certificate, CFTypeRef oid)
+{
+ CFMutableArrayRef fields = CFArrayCreateMutable(NULL, 0, NULL);
+ CertNameRef pCertName = createCertName();
+ const void* keys[] = { oid, };
+ CFDictionaryRef dict;
+ CFErrorRef error;
+
+ CFArrayRef keySelection = CFArrayCreate(NULL, keys , 1, NULL);
+
+ dict = SecCertificateCopyValues(certificate, keySelection, &error);
+ if (dict == NULL) {
+ printErrorMsg("GetFieldsFromCertificate: SecCertificateCopyValues", error);
+ CFRelease(keySelection);
+ CFRelease(fields);
+ destroyCertName(pCertName);
+ return NULL;
+ }
+ CFDictionaryRef vals = CFDictionaryGetValue(dict, oid);
+ CFArrayRef vals2 = vals ? CFDictionaryGetValue(vals, kSecPropertyKeyValue) : NULL;
+ if (vals2)
+ {
+ for(int i = 0; i < CFArrayGetCount(vals2); i++) {
+ CFDictionaryRef subDict = CFArrayGetValueAtIndex(vals2, i);
+ CFStringRef label = CFDictionaryGetValue(subDict, kSecPropertyKeyLabel);
+ CFStringRef value = CFDictionaryGetValue(subDict, kSecPropertyKeyValue);
+
+ if (CFStringCompare(label, kSecOIDEmailAddress, 0) == kCFCompareEqualTo)
+ CFArrayAppendValue((CFMutableArrayRef)pCertName->emailAddress, value);
+ else if (CFStringCompare(label, kSecOIDCountryName, 0) == kCFCompareEqualTo)
+ CFArrayAppendValue((CFMutableArrayRef)pCertName->countryName, value);
+ else if (CFStringCompare(label, kSecOIDOrganizationName, 0) == kCFCompareEqualTo)
+ CFArrayAppendValue((CFMutableArrayRef)pCertName->organization, value);
+ else if (CFStringCompare(label, kSecOIDOrganizationalUnitName, 0) == kCFCompareEqualTo)
+ CFArrayAppendValue((CFMutableArrayRef)pCertName->organizationalUnit, value);
+ else if (CFStringCompare(label, kSecOIDCommonName, 0) == kCFCompareEqualTo)
+ CFArrayAppendValue((CFMutableArrayRef)pCertName->commonName, value);
+ else if (CFStringCompare(label, kSecOIDDescription, 0) == kCFCompareEqualTo)
+ CFArrayAppendValue((CFMutableArrayRef)pCertName->description, value);
+ else if (CFStringCompare(label, kSecOIDStateProvinceName, 0) == kCFCompareEqualTo)
+ CFArrayAppendValue((CFMutableArrayRef)pCertName->stateName, value);
+ else if (CFStringCompare(label, kSecOIDLocalityName, 0) == kCFCompareEqualTo)
+ CFArrayAppendValue((CFMutableArrayRef)pCertName->localityName, value);
+ }
+ CFArrayAppendValue(fields, pCertName);
+ }
+
+ CFRelease(dict);
+ CFRelease(keySelection);
+ return fields;
+}
+
+CertDataRef createCertDataFromCertificate(SecCertificateRef certificate)
+{
+ CertDataRef pCertData = (CertDataRef)malloc(sizeof(CertData));
+ pCertData->subject = GetFieldsFromCertificate(certificate, kSecOIDX509V1SubjectName);
+ pCertData->issuer = GetFieldsFromCertificate(certificate, kSecOIDX509V1IssuerName);
+
+ CFDataRef data = SecCertificateCopyData(certificate);
+ if (data == NULL)
+ {
+ warnx("SecCertificateCopyData() returned NULL");
+ destroyCertData(pCertData);
+ return NULL;
+ }
+
+ unsigned char sha1[CC_SHA1_DIGEST_LENGTH];
+ CC_SHA1(CFDataGetBytePtr(data), CFDataGetLength(data), sha1);
+ pCertData->sha1 = createHexString(sha1, CC_SHA1_DIGEST_LENGTH);
+
+ unsigned char md5[CC_MD5_DIGEST_LENGTH];
+ CC_MD5(CFDataGetBytePtr(data), CFDataGetLength(data), md5);
+ pCertData->md5 = createHexString((unsigned char*)md5, CC_MD5_DIGEST_LENGTH);
+
+ CFDataRef serial = SecCertificateCopySerialNumber(certificate, NULL);
+ pCertData->serial = createHexString((unsigned char *)CFDataGetBytePtr(serial), CFDataGetLength(serial));
+ CFRelease(serial);
+
+ return pCertData;
+}
+
+CFStringRef stringFromRange(const char *cstring, CFRange range)
+{
+ CFStringRef str = CFStringCreateWithBytes (NULL, (uint8*)&cstring[range.location], range.length, kCFStringEncodingUTF8, false);
+ CFMutableStringRef mutableStr = CFStringCreateMutableCopy(NULL, 0, str);
+ CFStringTrimWhitespace(mutableStr);
+ CFRelease(str);
+ return mutableStr;
+}
+
+DescDataRef createDescData(const char *description, CFRange nameRange, CFRange valueRange)
+{
+ DescDataRef pRetVal = (DescDataRef)malloc(sizeof(DescData));
+
+ memset(pRetVal, 0, sizeof(DescData));
+
+ if (nameRange.length > 0)
+ pRetVal->name = stringFromRange(description, nameRange);
+
+ if (valueRange.length > 0)
+ pRetVal->value = stringFromRange(description, valueRange);
+
+#if 0
+ fprintf(stderr, "name = '%s', value = '%s'\n",
+ CFStringGetCStringPtr(pRetVal->name, kCFStringEncodingUTF8),
+ CFStringGetCStringPtr(pRetVal->value, kCFStringEncodingUTF8));
+#endif
+ return pRetVal;
+}
+
+void destroyDescData(DescDataRef pData)
+{
+ if (pData->name)
+ CFRelease(pData->name);
+
+ if (pData->value)
+ CFRelease(pData->value);
+
+ free(pData);
+}
+
+CFArrayRef createDescDataPairs(const char *description)
+{
+ int numChars = strlen(description);
+ CFRange nameRange, valueRange;
+ DescDataRef pData;
+ CFMutableArrayRef retVal = CFArrayCreateMutable(NULL, 0, NULL);
+
+ int i = 0;
+
+ nameRange = CFRangeMake(0, 0);
+ valueRange = CFRangeMake(0, 0);
+ bool bInValue = false;
+
+ while(i < numChars)
+ {
+ if (!bInValue && (description[i] != ':'))
+ {
+ nameRange.length++;
+ }
+ else if (bInValue && (description[i] != ':'))
+ {
+ valueRange.length++;
+ }
+ else if(!bInValue)
+ {
+ bInValue = true;
+ valueRange.location = i + 1;
+ valueRange.length = 0;
+ }
+ else //(bInValue)
+ {
+ bInValue = false;
+ while(description[i] != ' ')
+ {
+ valueRange.length--;
+ i--;
+ }
+
+ pData = createDescData(description, nameRange, valueRange);
+ CFArrayAppendValue(retVal, pData);
+
+ nameRange.location = i + 1;
+ nameRange.length = 0;
+ }
+
+ i++;
+ }
+
+ pData = createDescData(description, nameRange, valueRange);
+ CFArrayAppendValue(retVal, pData);
+ return retVal;
+}
+
+void arrayDestroyDescData(const void *val, void *context)
+{
+ DescDataRef pData = (DescDataRef) val;
+ destroyDescData(pData);
+}
+
+
+int parseNameComponent(CFStringRef dn, CFStringRef *pName, CFStringRef *pValue)
+{
+ CFArrayRef nameStrings = CFStringCreateArrayBySeparatingStrings(NULL, dn, kCertNameEquals);
+
+ *pName = *pValue = NULL;
+
+ if (CFArrayGetCount(nameStrings) != 2)
+ return 0;
+
+ CFMutableStringRef str;
+
+ str = CFStringCreateMutableCopy(NULL, 0, CFArrayGetValueAtIndex(nameStrings, 0));
+ CFStringTrimWhitespace(str);
+ *pName = str;
+
+ str = CFStringCreateMutableCopy(NULL, 0, CFArrayGetValueAtIndex(nameStrings, 1));
+ CFStringTrimWhitespace(str);
+ *pValue = str;
+
+ CFRelease(nameStrings);
+ return 1;
+}
+
+int tryAppendSingleCertField(CertNameRef pCertName, CFArrayRef where, CFStringRef key,
+ CFStringRef name, CFStringRef value)
+{
+ if (CFStringCompareWithOptions(name, key, CFRangeMake(0, CFStringGetLength(name)), kCFCompareCaseInsensitive)
+ == kCFCompareEqualTo) {
+ CFArrayAppendValue((CFMutableArrayRef)where, value);
+ return 1;
+ }
+ return 0;
+}
+
+int appendCertField(CertNameRef pCert, CFStringRef name, CFStringRef value)
+{
+ struct {
+ CFArrayRef field;
+ CFStringRef key;
+ } fields[] = {
+ { pCert->organization, kCertNameOrganization},
+ { pCert->organizationalUnit, kCertNameOrganizationalUnit},
+ { pCert->countryName, kCertNameCountry},
+ { pCert->localityName, kCertNameLocality},
+ { pCert->stateName, kCertNameState},
+ { pCert->commonName, kCertNameCommonName},
+ { pCert->emailAddress, kCertNameEmail},
+ };
+ int i;
+ int ret = 0;
+
+ for (i=0; i<sizeof(fields)/sizeof(fields[0]); i++)
+ ret += tryAppendSingleCertField(pCert, fields[i].field, fields[i].key, name, value);
+ return ret;
+}
+
+int parseCertName(CFStringRef nameDesc, CFMutableArrayRef names)
+{
+ CFArrayRef nameStrings = CFStringCreateArrayBySeparatingStrings(NULL, nameDesc, kCertNameFwdSlash);
+ int count = CFArrayGetCount(nameStrings);
+ int i;
+ int ret = 1;
+
+ CertNameRef pCertName = createCertName();
+
+ for(i = 0;i < count;i++)
+ {
+ CFMutableStringRef dn = CFStringCreateMutableCopy(NULL, 0, CFArrayGetValueAtIndex(nameStrings, i));
+ CFStringTrimWhitespace(dn);
+
+ CFStringRef name, value;
+
+ if (!parseNameComponent(dn, &name, &value))
+ ret = 0;
+
+ if (!name || !value)
+ {
+ if (name)
+ CFRelease(name);
+
+ if (value)
+ CFRelease(value);
+ if (name && !value)
+ ret = 0;
+
+ CFRelease(dn);
+ continue;
+ }
+
+ if (!appendCertField(pCertName, name, value))
+ ret = 0;
+ CFRelease(name);
+ CFRelease(value);
+ CFRelease(dn);
+ }
+
+ CFArrayAppendValue(names, pCertName);
+ CFRelease(nameStrings);
+ return ret;
+}
+
+int arrayParseDescDataPair(const void *val, void *context)
+{
+ DescDataRef pDescData = (DescDataRef)val;
+ CertDataRef pCertData = (CertDataRef)context;
+ int ret = 1;
+
+ if (!pDescData->name || !pDescData->value)
+ return 0;
+
+ if (CFStringCompareWithOptions(pDescData->name, kCertDataSubjectName, CFRangeMake(0, CFStringGetLength(pDescData->name)), kCFCompareCaseInsensitive) == kCFCompareEqualTo)
+ ret = parseCertName(pDescData->value, (CFMutableArrayRef)pCertData->subject);
+ else if (CFStringCompareWithOptions(pDescData->name, kCertDataIssuerName, CFRangeMake(0, CFStringGetLength(pDescData->name)), kCFCompareCaseInsensitive) == kCFCompareEqualTo)
+ ret = parseCertName(pDescData->value, (CFMutableArrayRef)pCertData->issuer);
+ else if (CFStringCompareWithOptions(pDescData->name, kCertDataSha1Name, CFRangeMake(0, CFStringGetLength(pDescData->name)), kCFCompareCaseInsensitive) == kCFCompareEqualTo)
+ pCertData->sha1 = CFRetain(pDescData->value);
+ else if (CFStringCompareWithOptions(pDescData->name, kCertDataMd5Name, CFRangeMake(0, CFStringGetLength(pDescData->name)), kCFCompareCaseInsensitive) == kCFCompareEqualTo)
+ pCertData->md5 = CFRetain(pDescData->value);
+ else if (CFStringCompareWithOptions(pDescData->name, kCertDataSerialName, CFRangeMake(0, CFStringGetLength(pDescData->name)), kCFCompareCaseInsensitive) == kCFCompareEqualTo)
+ pCertData->serial = CFRetain(pDescData->value);
+ else
+ return 0;
+
+ return ret;
+}
+
+CertDataRef createCertDataFromString(const char *description)
+{
+ CertDataRef pCertData = (CertDataRef)malloc(sizeof(CertData));
+ pCertData->subject = CFArrayCreateMutable(NULL, 0, NULL);
+ pCertData->issuer = CFArrayCreateMutable(NULL, 0, NULL);
+ pCertData->sha1 = NULL;
+ pCertData->md5 = NULL;
+ pCertData->serial = NULL;
+
+ CFArrayRef pairs = createDescDataPairs(description);
+ for (int i=0; i<CFArrayGetCount(pairs); i++)
+ if (!arrayParseDescDataPair(CFArrayGetValueAtIndex(pairs, i), pCertData)) {
+ arrayDestroyDescData(pCertData, NULL);
+ CFArrayApplyFunction(pairs, CFRangeMake(0, CFArrayGetCount(pairs)), arrayDestroyDescData, NULL);
+ CFRelease(pairs);
+ return 0;
+ }
+
+ CFArrayApplyFunction(pairs, CFRangeMake(0, CFArrayGetCount(pairs)), arrayDestroyDescData, NULL);
+ CFRelease(pairs);
+ return pCertData;
+}
+
+void arrayDestroyCertName(const void *val, void *context)
+{
+ CertNameRef pCertName = (CertNameRef)val;
+ destroyCertName(pCertName);
+}
+
+void destroyCertData(CertDataRef pCertData)
+{
+ if (pCertData->subject)
+ {
+ CFArrayApplyFunction(pCertData->subject, CFRangeMake(0, CFArrayGetCount(pCertData->subject)), arrayDestroyCertName, NULL);
+ CFRelease(pCertData->subject);
+ }
+
+ if (pCertData->issuer)
+ {
+ CFArrayApplyFunction(pCertData->issuer, CFRangeMake(0, CFArrayGetCount(pCertData->issuer)), arrayDestroyCertName, NULL);
+ CFRelease(pCertData->issuer);
+ }
+
+ if (pCertData->sha1)
+ CFRelease(pCertData->sha1);
+
+ if (pCertData->md5)
+ CFRelease(pCertData->md5);
+
+ if (pCertData->serial)
+ CFRelease(pCertData->serial);
+
+ free(pCertData);
+}
+
+bool stringArrayMatchesTemplate(CFArrayRef strings, CFArrayRef templateArray)
+{
+ int templateCount, stringCount, i;
+
+ templateCount = CFArrayGetCount(templateArray);
+
+ if (templateCount > 0)
+ {
+ stringCount = CFArrayGetCount(strings);
+ if (stringCount != templateCount)
+ return false;
+
+ for(i = 0;i < stringCount;i++)
+ {
+ CFStringRef str, template;
+
+ template = (CFStringRef)CFArrayGetValueAtIndex(templateArray, i);
+ str = (CFStringRef)CFArrayGetValueAtIndex(strings, i);
+
+ if (CFStringCompareWithOptions(template, str, CFRangeMake(0, CFStringGetLength(template)), kCFCompareCaseInsensitive) != kCFCompareEqualTo)
+ return false;
+ }
+ }
+
+ return true;
+
+}
+
+bool certNameMatchesTemplate(CertNameRef pCertName, CertNameRef pTemplate)
+{
+ if (!stringArrayMatchesTemplate(pCertName->countryName, pTemplate->countryName))
+ return false;
+ else if (!stringArrayMatchesTemplate(pCertName->organization, pTemplate->organization))
+ return false;
+ else if (!stringArrayMatchesTemplate(pCertName->organizationalUnit, pTemplate->organizationalUnit))
+ return false;
+ else if (!stringArrayMatchesTemplate(pCertName->commonName, pTemplate->commonName))
+ return false;
+ else if (!stringArrayMatchesTemplate(pCertName->emailAddress, pTemplate->emailAddress))
+ return false;
+ else if (!stringArrayMatchesTemplate(pCertName->stateName, pTemplate->stateName))
+ return false;
+ else if (!stringArrayMatchesTemplate(pCertName->localityName, pTemplate->localityName))
+ return false;
+ else
+ return true;
+}
+
+bool certNameArrayMatchesTemplate(CFArrayRef certNameArray, CFArrayRef templateArray)
+{
+ int templateCount, certCount, i;
+
+ templateCount = CFArrayGetCount(templateArray);
+
+ if (templateCount > 0)
+ {
+ certCount = CFArrayGetCount(certNameArray);
+ if (certCount != templateCount)
+ return false;
+
+ for(i = 0;i < certCount;i++)
+ {
+ CertNameRef pName, pTemplateName;
+
+ pTemplateName = (CertNameRef)CFArrayGetValueAtIndex(templateArray, i);
+ pName = (CertNameRef)CFArrayGetValueAtIndex(certNameArray, i);
+
+ if (!certNameMatchesTemplate(pName, pTemplateName))
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool hexStringMatchesTemplate(CFStringRef str, CFStringRef template)
+{
+ if (template)
+ {
+ if (!str)
+ return false;
+
+ CFMutableStringRef strMutable, templateMutable;
+
+ strMutable = CFStringCreateMutableCopy(NULL, 0, str);
+ templateMutable = CFStringCreateMutableCopy(NULL, 0, template);
+
+ CFStringFindAndReplace(strMutable, kStringSpace, kStringEmpty, CFRangeMake(0, CFStringGetLength(strMutable)), 0);
+ CFStringFindAndReplace(templateMutable, kStringSpace, kStringEmpty, CFRangeMake(0, CFStringGetLength(templateMutable)), 0);
+
+ CFComparisonResult result = CFStringCompareWithOptions(templateMutable, strMutable, CFRangeMake(0, CFStringGetLength(templateMutable)), kCFCompareCaseInsensitive);
+
+ CFRelease(strMutable);
+ CFRelease(templateMutable);
+
+ if (result != kCFCompareEqualTo)
+ return false;
+ }
+
+ return true;
+}
+
+bool certDataMatchesTemplate(CertDataRef pCertData, CertDataRef pTemplate)
+{
+ if (!certNameArrayMatchesTemplate(pCertData->subject, pTemplate->subject))
+ return false;
+
+ if (!certNameArrayMatchesTemplate(pCertData->issuer, pTemplate->issuer))
+ return false;
+
+ if (!hexStringMatchesTemplate(pCertData->sha1, pTemplate->sha1))
+ return false;
+
+ if (!hexStringMatchesTemplate(pCertData->md5, pTemplate->md5))
+ return false;
+
+ if (!hexStringMatchesTemplate(pCertData->serial, pTemplate->serial))
+ return false;
+
+ return true;
+}
+
+bool certExpired(SecCertificateRef certificate)
+{
+ bool result;
+ CFDateRef notAfter = GetDateFieldFromCertificate(certificate, kSecOIDX509V1ValidityNotAfter);
+ CFDateRef notBefore = GetDateFieldFromCertificate(certificate, kSecOIDX509V1ValidityNotBefore);
+ CFDateRef now = CFDateCreate(kCFAllocatorDefault, CFAbsoluteTimeGetCurrent());
+
+ if (!notAfter || !notBefore || !now)
+ {
+ warnx("GetDateFieldFromCertificate() returned NULL");
+ result = true;
+ }
+ else
+ {
+ if (CFDateCompare(notBefore, now, NULL) != kCFCompareLessThan ||
+ CFDateCompare(now, notAfter, NULL) != kCFCompareLessThan)
+ result = true;
+ else
+ result = false;
+ }
+
+ CFRelease(notAfter);
+ CFRelease(notBefore);
+ CFRelease(now);
+ return result;
+}
+
+SecIdentityRef findIdentity(CertDataRef pCertDataTemplate)
+{
+ const void *keys[] = {
+ kSecClass,
+ kSecReturnRef,
+ kSecMatchLimit
+ };
+ const void *values[] = {
+ kSecClassIdentity,
+ kCFBooleanTrue,
+ kSecMatchLimitAll
+ };
+ CFArrayRef result = NULL;
+
+ CFDictionaryRef query = CFDictionaryCreate(NULL, keys, values,
+ sizeof(keys) / sizeof(*keys),
+ &kCFTypeDictionaryKeyCallBacks,
+ &kCFTypeDictionaryValueCallBacks);
+ OSStatus status = SecItemCopyMatching(query, (CFTypeRef*)&result);
+ CFRelease(query);
+ if (status != noErr)
+ {
+ warnx ("No identities in keychain found");
+ return NULL;
+ }
+
+ SecIdentityRef bestIdentity = NULL;
+ CFDateRef bestNotBeforeDate = NULL;
+
+ for (int i=0; i<CFArrayGetCount(result); i++)
+ {
+ SecIdentityRef identity = (SecIdentityRef)CFArrayGetValueAtIndex(result, i);
+ if (identity == NULL)
+ {
+ warnx ("identity == NULL");
+ continue;
+ }
+
+ SecCertificateRef certificate = NULL;
+ SecIdentityCopyCertificate (identity, &certificate);
+ if (certificate == NULL)
+ {
+ warnx ("SecIdentityCopyCertificate() returned NULL");
+ continue;
+ }
+
+ CertDataRef pCertData2 = createCertDataFromCertificate(certificate);
+ if (pCertData2 == NULL)
+ {
+ warnx ("createCertDataFromCertificate() returned NULL");
+ goto release_cert;
+ }
+ bool bMatches = certDataMatchesTemplate(pCertData2, pCertDataTemplate);
+ bool bExpired = certExpired(certificate);
+ destroyCertData(pCertData2);
+
+ if (bMatches && !bExpired)
+ {
+ CFDateRef notBeforeDate = GetDateFieldFromCertificate(certificate, kSecOIDX509V1ValidityNotBefore);
+ if (!notBeforeDate)
+ {
+ warnx ("GetDateFieldFromCertificate() returned NULL");
+ goto release_cert;
+ }
+ if (bestIdentity == NULL)
+ {
+ CFRetain(identity);
+ bestIdentity = identity;
+
+ bestNotBeforeDate = notBeforeDate;
+ CFRetain(notBeforeDate);
+ }
+ else if (CFDateCompare(bestNotBeforeDate, notBeforeDate, NULL) == kCFCompareLessThan)
+ {
+ CFRelease(bestIdentity);
+ CFRetain(identity);
+ bestIdentity = identity;
+
+ bestNotBeforeDate = notBeforeDate;
+ CFRetain(notBeforeDate);
+ }
+ CFRelease(notBeforeDate);
+ }
+ release_cert:
+ CFRelease(certificate);
+ }
+ CFRelease(result);
+
+ return bestIdentity;
+}
diff --git a/contrib/keychain-mcd/cert_data.h b/contrib/keychain-mcd/cert_data.h
new file mode 100644
index 0000000..407cca1
--- /dev/null
+++ b/contrib/keychain-mcd/cert_data.h
@@ -0,0 +1,46 @@
+/*
+ * OpenVPN -- An application to securely tunnel IP networks
+ * over a single UDP port, with support for SSL/TLS-based
+ * session authentication and key exchange,
+ * packet encryption, packet authentication, and
+ * packet compression.
+ *
+ * Copyright (C) 2010 Brian Raderman <brian@irregularexpression.org>
+ * Copyright (C) 2013-2015 Vasily Kulikov <segoon@openwall.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program (see the file COPYING included with this
+ * distribution); if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __cert_data_h__
+#define __cert_data_h__
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <Security/Security.h>
+
+typedef struct _CertData
+{
+ CFArrayRef subject;
+ CFArrayRef issuer;
+ CFStringRef serial;
+ CFStringRef md5, sha1;
+} CertData, *CertDataRef;
+
+CertDataRef createCertDataFromCertificate(SecCertificateRef certificate);
+CertDataRef createCertDataFromString(const char *description);
+void destroyCertData(CertDataRef pCertData);
+bool certDataMatchesTemplate(CertDataRef pCertData, CertDataRef pTemplate);
+void printCertData(CertDataRef pCertData);
+SecIdentityRef findIdentity(CertDataRef pCertDataTemplate);
+
+#endif
diff --git a/contrib/keychain-mcd/common_osx.c b/contrib/keychain-mcd/common_osx.c
new file mode 100644
index 0000000..3effa8b
--- /dev/null
+++ b/contrib/keychain-mcd/common_osx.c
@@ -0,0 +1,94 @@
+/*
+ * OpenVPN -- An application to securely tunnel IP networks
+ * over a single UDP port, with support for SSL/TLS-based
+ * session authentication and key exchange,
+ * packet encryption, packet authentication, and
+ * packet compression.
+ *
+ * Copyright (C) 2010 Brian Raderman <brian@irregularexpression.org>
+ * Copyright (C) 2013-2015 Vasily Kulikov <segoon@openwall.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program (see the file COPYING included with this
+ * distribution); if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+#include "config.h"
+#include "syshead.h"
+#include "common.h"
+#include "buffer.h"
+#include "error.h"
+*/
+
+#include "common_osx.h"
+#include <err.h>
+
+void printCFString(CFStringRef str)
+{
+ CFIndex bufferLength = CFStringGetLength(str) + 1;
+ char *pBuffer = (char*)malloc(sizeof(char) * bufferLength);
+ CFStringGetCString(str, pBuffer, bufferLength, kCFStringEncodingUTF8);
+ warnx("%s\n", pBuffer);
+ free(pBuffer);
+}
+
+char* cfstringToCstr(CFStringRef str)
+{
+ CFIndex bufferLength = CFStringGetLength(str) + 1;
+ char *pBuffer = (char*)malloc(sizeof(char) * bufferLength);
+ CFStringGetCString(str, pBuffer, bufferLength, kCFStringEncodingUTF8);
+ return pBuffer;
+}
+
+void appendHexChar(CFMutableStringRef str, unsigned char halfByte)
+{
+ if (halfByte < 10)
+ {
+ CFStringAppendFormat (str, NULL, CFSTR("%d"), halfByte);
+ }
+ else
+ {
+ char tmp[2] = {'A'+halfByte-10, 0};
+ CFStringAppendCString(str, tmp, kCFStringEncodingUTF8);
+ }
+}
+
+CFStringRef createHexString(unsigned char *pData, int length)
+{
+ unsigned char byte, low, high;
+ int i;
+ CFMutableStringRef str = CFStringCreateMutable(NULL, 0);
+
+ for(i = 0;i < length;i++)
+ {
+ byte = pData[i];
+ low = byte & 0x0F;
+ high = (byte >> 4);
+
+ appendHexChar(str, high);
+ appendHexChar(str, low);
+
+ if (i != (length - 1))
+ CFStringAppendCString(str, " ", kCFStringEncodingUTF8);
+ }
+
+ return str;
+}
+
+void printHex(unsigned char *pData, int length)
+{
+ CFStringRef hexStr = createHexString(pData, length);
+ printCFString(hexStr);
+ CFRelease(hexStr);
+}
diff --git a/contrib/keychain-mcd/common_osx.h b/contrib/keychain-mcd/common_osx.h
new file mode 100644
index 0000000..4273548
--- /dev/null
+++ b/contrib/keychain-mcd/common_osx.h
@@ -0,0 +1,36 @@
+/*
+ * OpenVPN -- An application to securely tunnel IP networks
+ * over a single UDP port, with support for SSL/TLS-based
+ * session authentication and key exchange,
+ * packet encryption, packet authentication, and
+ * packet compression.
+ *
+ * Copyright (C) 2010 Brian Raderman <brian@irregularexpression.org>
+ * Copyright (C) 2013-2015 Vasily Kulikov <segoon@openwall.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program (see the file COPYING included with this
+ * distribution); if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef __common_osx_h__
+#define __common_osx_h__
+
+#include <CoreFoundation/CoreFoundation.h>
+
+void printCFString(CFStringRef str);
+char* cfstringToCstr(CFStringRef str);
+CFStringRef createHexString(unsigned char *pData, int length);
+void printHex(unsigned char *pData, int length);
+
+#endif //__Common_osx_h__
diff --git a/contrib/keychain-mcd/crypto_osx.c b/contrib/keychain-mcd/crypto_osx.c
new file mode 100644
index 0000000..87ba09b
--- /dev/null
+++ b/contrib/keychain-mcd/crypto_osx.c
@@ -0,0 +1,75 @@
+/*
+ * OpenVPN -- An application to securely tunnel IP networks
+ * over a single UDP port, with support for SSL/TLS-based
+ * session authentication and key exchange,
+ * packet encryption, packet authentication, and
+ * packet compression.
+ *
+ * Copyright (C) 2010 Brian Raderman <brian@irregularexpression.org>
+ * Copyright (C) 2013-2015 Vasily Kulikov <segoon@openwall.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program (see the file COPYING included with this
+ * distribution); if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#include <CommonCrypto/CommonDigest.h>
+#include <Security/SecKey.h>
+#include <Security/Security.h>
+
+#include "crypto_osx.h"
+#include <err.h>
+
+void printErrorMsg(const char *func, CFErrorRef error)
+{
+ CFStringRef desc = CFErrorCopyDescription(error);
+ warnx("%s failed: %s", func, CFStringGetCStringPtr(desc, kCFStringEncodingUTF8));
+ CFRelease(desc);
+}
+
+void printErrorStatusMsg(const char *func, OSStatus status)
+{
+ CFStringRef error;
+ error = SecCopyErrorMessageString(status, NULL);
+ if (error)
+ {
+ warnx("%s failed: %s", func, CFStringGetCStringPtr(error, kCFStringEncodingUTF8));
+ CFRelease(error);
+ }
+ else
+ warnx("%s failed: %X", func, (int)status);
+}
+
+void signData(SecIdentityRef identity, const uint8_t *from, int flen, uint8_t *to, size_t *tlen)
+{
+ SecKeyRef privateKey = NULL;
+ OSStatus status;
+
+ status = SecIdentityCopyPrivateKey(identity, &privateKey);
+ if (status != noErr)
+ {
+ printErrorStatusMsg("signData: SecIdentityCopyPrivateKey", status);
+ *tlen = 0;
+ return;
+ }
+
+ status = SecKeyRawSign(privateKey, kSecPaddingPKCS1, from, flen, to, tlen);
+ CFRelease(privateKey);
+ if (status != noErr)
+ {
+ printErrorStatusMsg("signData: SecKeyRawSign", status);
+ *tlen = 0;
+ return;
+ }
+}
diff --git a/contrib/keychain-mcd/crypto_osx.h b/contrib/keychain-mcd/crypto_osx.h
new file mode 100644
index 0000000..0da58b6
--- /dev/null
+++ b/contrib/keychain-mcd/crypto_osx.h
@@ -0,0 +1,44 @@
+/*
+ * OpenVPN -- An application to securely tunnel IP networks
+ * over a single UDP port, with support for SSL/TLS-based
+ * session authentication and key exchange,
+ * packet encryption, packet authentication, and
+ * packet compression.
+ *
+ * Copyright (C) 2010 Brian Raderman <brian@irregularexpression.org>
+ * Copyright (C) 2013-2015 Vasily Kulikov <segoon@openwall.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program (see the file COPYING included with this
+ * distribution); if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef __crypto_osx_h__
+#define __crypto_osx_h__
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <Security/Security.h>
+
+extern OSStatus SecKeyRawSign (
+ SecKeyRef key,
+ SecPadding padding,
+ const uint8_t *dataToSign,
+ size_t dataToSignLen,
+ uint8_t *sig,
+ size_t *sigLen
+);
+
+void signData(SecIdentityRef identity, const uint8_t *from, int flen, uint8_t *to, size_t *tlen);
+void printErrorMsg(const char *func, CFErrorRef error);
+
+#endif //__crypto_osx_h__
diff --git a/contrib/keychain-mcd/keychain-mcd.8 b/contrib/keychain-mcd/keychain-mcd.8
new file mode 100644
index 0000000..676b164
--- /dev/null
+++ b/contrib/keychain-mcd/keychain-mcd.8
@@ -0,0 +1,161 @@
+.TH keychain-mcd 8
+.SH NAME
+
+keychain-mcd \- Mac OS X Keychain management daemon for OpenVPN
+
+.SH SYNOPSIS
+
+.B keychain-mcd
+.I identity-template management-server-ip management-server-port
+[
+.I password-file
+]
+
+.SH DESCRIPTION
+
+.B keychain-mcd
+is Mac OS X Keychain management daemon for OpenVPN.
+It loads the certificate and private key from the Mac OSX Keychain (Mac OSX Only).
+.B keychain-mcd
+connects to OpenVPN via management interface and handles
+certificate and private key commands (namely
+.B NEED-CERTIFICATE
+and
+.B RSA-SIGN
+commands).
+
+.B keychain-mcd
+makes it possible to use any smart card supported by Mac OSX using the tokend interface, but also any
+kind of certificate, residing in the Keychain, where you have access to
+the private key. This option has been tested on the client side with an Aladdin eToken
+on Mac OSX Leopard and with software certificates stored in the Keychain on Mac OS X.
+
+Note that Mac OS X might need to present the user with an authentication GUI when the Keychain
+is accessed by keychain-mcd.
+
+Use
+.B keychain-mcd
+along with
+.B --management-external-key
+and/or
+.B --management-external-cert
+passed to
+.B openvpn.
+
+.SH OPTIONS
+
+.TP
+.BR identity-template
+
+A select string which is used to choose a keychain identity from
+Mac OS X Keychain or
+.I auto
+if the identity template is passed from openvpn.
+
+\fBSubject\fR, \fBIssuer\fR, \fBSerial\fR, \fBSHA1\fR, \fBMD5\fR selectors can be used.
+
+To select a certificate based on a string search in the
+certificate's subject and/or issuer:
+
+.nf
+
+"SUBJECT:c=US/o=Apple Inc./ou=me.com/cn=username ISSUER:c=US/o=Apple Computer, Inc./ou=Apple Computer Certificate Authority/cn=Apple .Mac Certificate Authority"
+
+.fi
+
+.I "Distinguished Name Component Abbreviations:"
+.br
+o = organization
+.br
+ou = organizational unit
+.br
+c = country
+.br
+l = locality
+.br
+st = state
+.br
+cn = common name
+.br
+e = email
+.br
+
+All of the distinguished name components are optional, although you do need to specify at least one of them. You can
+add spaces around the '/' and '=' characters, e.g. "SUBJECT: c = US / o = Apple Inc.". You do not need to specify
+both the subject and the issuer, one or the other will work fine.
+The identity searching algorithm will return the
+certificate it finds that matches all of the criteria you have specified.
+If there are several certificates matching all of the criteria then the youngest certificate is returned
+(i.e. with the greater "not before" validity field).
+You can also include the MD5 and/or SHA1 thumbprints and/or serial number
+along with the subject and issuer.
+
+To select a certificate based on certificate's MD5 or SHA1 thumbprint:
+
+.nf
+"SHA1: 30 F7 3A 7A B7 73 2A 98 54 33 4A A7 00 6F 6E AC EC D1 EF 02"
+
+"MD5: D5 F5 11 F1 38 EB 5F 4D CF 23 B6 94 E8 33 D8 B5"
+.fi
+
+Again, you can include both the SHA1 and the MD5 thumbprints, but you can also use just one of them.
+The thumbprint hex strings can easily be copy-and-pasted from the OSX Keychain Access GUI in the Applications/Utilities folder.
+The hex string comparison is not case sensitive.
+
+To select a certificate based on certificate's serial number:
+
+"Serial: 3E 9B 6F 02 00 00 00 01 1F 20"
+
+If
+.BR identity-template
+equals to
+.I auto
+then the actual identity template is
+obtained from argument of NEED-CERTIFICATE notification of openvpn.
+In this case the argument of NEED-CERTIFICATE must begin with 'macosx-keychain:' prefix
+and the rest of it must contain the actual identity template in the format described above.
+
+
+.TP
+.BR management-server-ip
+OpenVPN management IP to connect to.
+Both IPv4 and IPv6 addresses can be used.
+
+.TP
+.BR management-server-port
+OpenVPN management port to connect to.
+Use
+.B unix
+for
+.I management-server-port
+and socket path for
+.I management-server-ip
+to connect to a local unix socket.
+
+.TP
+.BR password-file
+
+Password file containing the management password on first line.
+The password will be used to connect to
+.B openvpn
+management interface.
+
+Pass
+.I password-file
+to
+.B keychain-mcd
+if
+.I pw-file
+was specified in
+.B --management
+option to
+.B openvpn.
+
+
+.SH AUTHOR
+
+Vasily Kulikov <segoon@openwall.com>
+
+.SH "SEE ALSO"
+
+.BR openvpn (8)
diff --git a/contrib/keychain-mcd/main.c b/contrib/keychain-mcd/main.c
new file mode 100644
index 0000000..2263b7d
--- /dev/null
+++ b/contrib/keychain-mcd/main.c
@@ -0,0 +1,255 @@
+/*
+ * OpenVPN -- An application to securely tunnel IP networks
+ * over a single UDP port, with support for SSL/TLS-based
+ * session authentication and key exchange,
+ * packet encryption, packet authentication, and
+ * packet compression.
+ *
+ * Copyright (C) 2015 Vasily Kulikov <segoon@openwall.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program (see the file COPYING included with this
+ * distribution); if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <sys/un.h>
+#include <err.h>
+#include <netdb.h>
+
+#include <Security/Security.h>
+#include <CoreServices/CoreServices.h>
+
+#include "cert_data.h"
+#include "crypto_osx.h"
+#include "../../src/openvpn/base64.h"
+
+
+SecIdentityRef template_to_identity(const char *template)
+{
+ SecIdentityRef identity;
+ CertDataRef pCertDataTemplate = createCertDataFromString(template);
+ if (pCertDataTemplate == NULL)
+ errx(1, "Bad certificate template");
+ identity = findIdentity(pCertDataTemplate);
+ if (identity == NULL)
+ errx(1, "No such identify");
+ fprintf(stderr, "Identity found\n");
+ destroyCertData(pCertDataTemplate);
+ return identity;
+}
+
+int connect_to_management_server(const char *ip, const char *port)
+{
+ int fd;
+ struct sockaddr_un addr_un;
+ struct sockaddr *addr;
+ size_t addr_len;
+
+ if (strcmp(port, "unix") == 0) {
+ addr = (struct sockaddr*)&addr_un;
+ addr_len = sizeof(addr_un);
+
+ addr_un.sun_family = AF_UNIX;
+ strncpy(addr_un.sun_path, ip, sizeof(addr_un.sun_path));
+ fd = socket(AF_UNIX, SOCK_STREAM, 0);
+ }
+ else {
+ int rv;
+ struct addrinfo *result;
+ struct addrinfo hints;
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
+
+ rv = getaddrinfo(ip, port, &hints, &result);
+ if (rv < 0)
+ errx(1, "getaddrinfo: %s", gai_strerror(rv));
+ if (result == NULL)
+ errx(1, "getaddrinfo returned 0 addressed");
+
+ /* Use the first found address */
+ fd = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
+ addr = result->ai_addr;
+ addr_len = result->ai_addrlen;
+ }
+ if (fd < 0)
+ err(1, "socket");
+
+ if (connect(fd, addr, addr_len) < 0)
+ err(1, "connect");
+
+ return fd;
+}
+
+int is_prefix(const char *s, const char *prefix)
+{
+ return strncmp(s, prefix, strlen(prefix)) == 0;
+}
+
+void handle_rsasign(FILE *man_file, SecIdentityRef identity, const char *input)
+{
+ const char *input_b64 = strchr(input, ':') + 1;
+ char *input_binary;
+ int input_len;
+ char *output_binary;
+ size_t output_len;
+ char *output_b64;
+
+ input_len = strlen(input_b64)*8/6 + 4;
+ input_binary = malloc(input_len);
+ input_len = openvpn_base64_decode(input_b64, input_binary, input_len);
+ if (input_len < 0)
+ errx(1, "openvpn_base64_decode: overflow");
+
+ output_len = 1024;
+ output_binary = malloc(output_len);
+ signData(identity, (const uint8_t *)input_binary, input_len, (uint8_t *)output_binary, &output_len);
+ if (output_len == 0)
+ errx(1, "handle_rsasign: failed to sign data");
+
+ openvpn_base64_encode(output_binary, output_len, &output_b64);
+ fprintf(man_file, "rsa-sig\n%s\nEND\n", output_b64);
+ free(output_b64);
+ free(input_binary);
+ free(output_binary);
+
+ fprintf(stderr, "Handled RSA_SIGN command\n");
+}
+
+void handle_needcertificate(FILE *man_file, SecIdentityRef identity)
+{
+ OSStatus status;
+ SecCertificateRef certificate = NULL;
+ CFDataRef data;
+ const unsigned char *cert;
+ size_t cert_len;
+ char *result_b64, *tmp_b64;
+
+ status = SecIdentityCopyCertificate(identity, &certificate);
+ if (status != noErr) {
+ const char *msg = GetMacOSStatusErrorString(status);
+ err(1, "SecIdentityCopyCertificate() failed: %s", msg);
+ }
+
+ data = SecCertificateCopyData(certificate);
+ if (data == NULL)
+ err(1, "SecCertificateCopyData() returned NULL");
+
+ cert = CFDataGetBytePtr(data);
+ cert_len = CFDataGetLength(data);
+
+ openvpn_base64_encode(cert, cert_len, &result_b64);
+#if 0
+ fprintf(stderr, "certificate %s\n", result_b64);
+#endif
+
+ fprintf(man_file, "certificate\n");
+ fprintf(man_file, "-----BEGIN CERTIFICATE-----\n");
+ tmp_b64 = result_b64;
+ while (strlen(tmp_b64) > 64) {
+ fprintf(man_file, "%.64s\n", tmp_b64);
+ tmp_b64 += 64;
+ }
+ if (*tmp_b64)
+ fprintf(man_file, "%s\n", tmp_b64);
+ fprintf(man_file, "-----END CERTIFICATE-----\n");
+ fprintf(man_file, "END\n");
+
+ free(result_b64);
+ CFRelease(data);
+ CFRelease(certificate);
+
+ fprintf(stderr, "Handled NEED 'cert' command\n");
+}
+
+void management_loop(SecIdentityRef identity, int man_fd, const char *password)
+{
+ char *buffer = NULL;
+ size_t buffer_len = 0;
+ FILE *man = fdopen(man_fd, "w+");
+ if (man == 0)
+ err(1, "fdopen");
+
+ if (password)
+ fprintf(man, "%s\n", password);
+
+ while (1) {
+ if (getline(&buffer, &buffer_len, man) < 0)
+ err(1, "getline");
+#if 0
+ fprintf(stderr, "M: %s", buffer);
+#endif
+
+ if (is_prefix(buffer, ">RSA_SIGN:"))
+ handle_rsasign(man, identity, buffer);
+ if (is_prefix(buffer, ">NEED-CERTIFICATE")) {
+ if (!identity) {
+ const char prefix[] = ">NEED-CERTIFICATE:macosx-keychain:";
+ if (!is_prefix(buffer, prefix))
+ errx(1, "No identity template is passed via command line and " \
+ "NEED-CERTIFICATE management interface command " \
+ "misses 'macosx-keychain' prefix.");
+ identity = template_to_identity(buffer+strlen(prefix));
+ }
+ handle_needcertificate(man, identity);
+ }
+ if (is_prefix(buffer, ">FATAL"))
+ fprintf(stderr, "Fatal message from OpenVPN: %s\n", buffer+7);
+ if (is_prefix(buffer, ">INFO"))
+ fprintf(stderr, "INFO message from OpenVPN: %s\n", buffer+6);
+ }
+}
+
+char *read_password(const char *fname)
+{
+ char *password = NULL;
+ FILE *pwf = fopen(fname, "r");
+ size_t n = 0;
+
+ if (pwf == NULL)
+ errx(1, "fopen(%s) failed", fname);
+ if (getline(&password, &n, pwf) < 0)
+ err(1, "getline");
+ fclose(pwf);
+ return password;
+}
+
+int main(int argc, char* argv[])
+{
+ if (argc < 4)
+ err(1, "usage: %s <identity_template> <management_ip> <management_port> [<pw-file>]", argv[0]);
+
+ char *identity_template = argv[1];
+ char *s_ip = argv[2];
+ char *s_port = argv[3];
+ char *password = NULL;
+ int man_fd;
+
+ if (argc > 4) {
+ char *s_pw_file = argv[4];
+ password = read_password(s_pw_file);
+ }
+
+ SecIdentityRef identity = NULL;
+ if (strcmp(identity_template, "auto"))
+ identity = template_to_identity(identity_template);
+ man_fd = connect_to_management_server(s_ip, s_port);
+ fprintf(stderr, "Successfully connected to openvpn\n");
+
+ management_loop(identity, man_fd, password);
+}
diff --git a/contrib/pull-resolv-conf/client.up b/contrib/pull-resolv-conf/client.up
index b28d4d1..8858b47 100644
--- a/contrib/pull-resolv-conf/client.up
+++ b/contrib/pull-resolv-conf/client.up
@@ -50,9 +50,10 @@ nl='
# or
# "dhcp-option DNS 10.10.10.10" (multiple allowed)
-# each DNS option becomes a "nameserver" option in resolv.con
+# each DNS option becomes a "nameserver" option in resolv.conf
# if we get one DOMAIN, that becomes "domain" in resolv.conf
# if we get multiple DOMAINS, those become "search" lines in resolv.conf
+# if we get no DOMAINS, then don't use either domain or search.
while true; do
eval fopt=\$foreign_option_${i}
@@ -78,13 +79,15 @@ while true; do
i=$((i + 1))
done
-ds=domain
-if [ $ndoms -gt 1 ]; then
- ds=search
+ds=""
+if [ $ndoms -eq 1 ]; then
+ ds="${nl}domain"
+elif [ $ndoms -gt 1 ]; then
+ ds="${nl}search"
fi
# This is the complete file - "$domains" has a leading space already
-out="# resolv.conf autogenerated by ${0} (${1})${nl}${dns}${nl}${ds}${domains}"
+out="# resolv.conf autogenerated by ${0} (${1})${nl}${dns}${ds}${domains}"
# use resolvconf if it's available
if type resolvconf >/dev/null 2>&1; then
diff --git a/distro/Makefile.in b/distro/Makefile.in
index 0fa6696..66d04fd 100644
--- a/distro/Makefile.in
+++ b/distro/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.15 from Makefile.am.
+# Makefile.in generated by automake 1.13.4 from Makefile.am.
# @configure_input@
-# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -25,17 +25,7 @@
# Copyright (C) 2006-2012 Alon Bar-Lev <alon.barlev@gmail.com>
#
VPATH = @srcdir@
-am__is_gnu_make = { \
- if test -z '$(MAKELEVEL)'; then \
- false; \
- elif test -n '$(MAKE_HOST)'; then \
- true; \
- elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
- true; \
- else \
- false; \
- fi; \
-}
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
am__make_running_with_option = \
case $${target_option-} in \
?) ;; \
@@ -99,6 +89,7 @@ POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
subdir = distro
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/ax_emptyarray.m4 \
$(top_srcdir)/m4/ax_socklen_t.m4 \
@@ -109,9 +100,9 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_emptyarray.m4 \
$(top_srcdir)/compat.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
-DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
mkinstalldirs = $(install_sh) -d
-CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_HEADER = $(top_builddir)/config.h \
+ $(top_builddir)/include/openvpn-plugin.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
AM_V_P = $(am__v_P_@AM_V@)
@@ -169,7 +160,6 @@ am__define_uniq_tagged_files = \
ETAGS = etags
CTAGS = ctags
DIST_SUBDIRS = $(SUBDIRS)
-am__DIST_COMMON = $(srcdir)/Makefile.in
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
am__relativize = \
dir0=`pwd`; \
@@ -208,6 +198,7 @@ AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
+CMAKE = @CMAKE@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
@@ -242,25 +233,31 @@ LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
-LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+LZ4_CFLAGS = @LZ4_CFLAGS@
+LZ4_LIBS = @LZ4_LIBS@
LZO_CFLAGS = @LZO_CFLAGS@
LZO_LIBS = @LZO_LIBS@
MAKEINFO = @MAKEINFO@
MAN2HTML = @MAN2HTML@
MANIFEST_TOOL = @MANIFEST_TOOL@
+MBEDTLS_CFLAGS = @MBEDTLS_CFLAGS@
+MBEDTLS_LIBS = @MBEDTLS_LIBS@
MKDIR_P = @MKDIR_P@
NETSTAT = @NETSTAT@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
-OPENSSL_CRYPTO_CFLAGS = @OPENSSL_CRYPTO_CFLAGS@
-OPENSSL_CRYPTO_LIBS = @OPENSSL_CRYPTO_LIBS@
-OPENSSL_SSL_CFLAGS = @OPENSSL_SSL_CFLAGS@
-OPENSSL_SSL_LIBS = @OPENSSL_SSL_LIBS@
+OPENSSL_CFLAGS = @OPENSSL_CFLAGS@
+OPENSSL_LIBS = @OPENSSL_LIBS@
+OPENVPN_VERSION_MAJOR = @OPENVPN_VERSION_MAJOR@
+OPENVPN_VERSION_MINOR = @OPENVPN_VERSION_MINOR@
+OPENVPN_VERSION_PATCH = @OPENVPN_VERSION_PATCH@
OPTIONAL_CRYPTO_CFLAGS = @OPTIONAL_CRYPTO_CFLAGS@
OPTIONAL_CRYPTO_LIBS = @OPTIONAL_CRYPTO_LIBS@
OPTIONAL_DL_LIBS = @OPTIONAL_DL_LIBS@
+OPTIONAL_LZ4_CFLAGS = @OPTIONAL_LZ4_CFLAGS@
+OPTIONAL_LZ4_LIBS = @OPTIONAL_LZ4_LIBS@
OPTIONAL_LZO_CFLAGS = @OPTIONAL_LZO_CFLAGS@
OPTIONAL_LZO_LIBS = @OPTIONAL_LZO_LIBS@
OPTIONAL_PKCS11_HELPER_CFLAGS = @OPTIONAL_PKCS11_HELPER_CFLAGS@
@@ -286,8 +283,6 @@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
PLUGIN_AUTH_PAM_CFLAGS = @PLUGIN_AUTH_PAM_CFLAGS@
PLUGIN_AUTH_PAM_LIBS = @PLUGIN_AUTH_PAM_LIBS@
-POLARSSL_CFLAGS = @POLARSSL_CFLAGS@
-POLARSSL_LIBS = @POLARSSL_LIBS@
RANLIB = @RANLIB@
RC = @RC@
ROUTE = @ROUTE@
@@ -302,6 +297,11 @@ TAP_CFLAGS = @TAP_CFLAGS@
TAP_WIN_COMPONENT_ID = @TAP_WIN_COMPONENT_ID@
TAP_WIN_MIN_MAJOR = @TAP_WIN_MIN_MAJOR@
TAP_WIN_MIN_MINOR = @TAP_WIN_MIN_MINOR@
+TEST_CFLAGS = @TEST_CFLAGS@
+TEST_LDFLAGS = @TEST_LDFLAGS@
+VENDOR_BUILD_ROOT = @VENDOR_BUILD_ROOT@
+VENDOR_DIST_ROOT = @VENDOR_DIST_ROOT@
+VENDOR_SRC_ROOT = @VENDOR_SRC_ROOT@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
@@ -379,6 +379,7 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign distro/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign distro/Makefile
+.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
@@ -674,8 +675,6 @@ uninstall-am:
mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
ps ps-am tags tags-am uninstall uninstall-am
-.PRECIOUS: Makefile
-
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
diff --git a/distro/rpm/Makefile.in b/distro/rpm/Makefile.in
index 9722c20..ac2eace 100644
--- a/distro/rpm/Makefile.in
+++ b/distro/rpm/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.15 from Makefile.am.
+# Makefile.in generated by automake 1.13.4 from Makefile.am.
# @configure_input@
-# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -26,17 +26,7 @@
#
VPATH = @srcdir@
-am__is_gnu_make = { \
- if test -z '$(MAKELEVEL)'; then \
- false; \
- elif test -n '$(MAKE_HOST)'; then \
- true; \
- elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
- true; \
- else \
- false; \
- fi; \
-}
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
am__make_running_with_option = \
case $${target_option-} in \
?) ;; \
@@ -100,6 +90,8 @@ POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
subdir = distro/rpm
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+ $(srcdir)/openvpn.spec.in $(dist_noinst_DATA)
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/ax_emptyarray.m4 \
$(top_srcdir)/m4/ax_socklen_t.m4 \
@@ -110,10 +102,9 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_emptyarray.m4 \
$(top_srcdir)/compat.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
-DIST_COMMON = $(srcdir)/Makefile.am $(dist_noinst_DATA) \
- $(am__DIST_COMMON)
mkinstalldirs = $(install_sh) -d
-CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_HEADER = $(top_builddir)/config.h \
+ $(top_builddir)/include/openvpn-plugin.h
CONFIG_CLEAN_FILES = openvpn.spec
CONFIG_CLEAN_VPATH_FILES =
AM_V_P = $(am__v_P_@AM_V@)
@@ -137,7 +128,6 @@ am__can_run_installinfo = \
esac
DATA = $(dist_noinst_DATA)
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
-am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/openvpn.spec.in
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
@@ -151,6 +141,7 @@ AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
+CMAKE = @CMAKE@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
@@ -185,25 +176,31 @@ LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
-LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+LZ4_CFLAGS = @LZ4_CFLAGS@
+LZ4_LIBS = @LZ4_LIBS@
LZO_CFLAGS = @LZO_CFLAGS@
LZO_LIBS = @LZO_LIBS@
MAKEINFO = @MAKEINFO@
MAN2HTML = @MAN2HTML@
MANIFEST_TOOL = @MANIFEST_TOOL@
+MBEDTLS_CFLAGS = @MBEDTLS_CFLAGS@
+MBEDTLS_LIBS = @MBEDTLS_LIBS@
MKDIR_P = @MKDIR_P@
NETSTAT = @NETSTAT@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
-OPENSSL_CRYPTO_CFLAGS = @OPENSSL_CRYPTO_CFLAGS@
-OPENSSL_CRYPTO_LIBS = @OPENSSL_CRYPTO_LIBS@
-OPENSSL_SSL_CFLAGS = @OPENSSL_SSL_CFLAGS@
-OPENSSL_SSL_LIBS = @OPENSSL_SSL_LIBS@
+OPENSSL_CFLAGS = @OPENSSL_CFLAGS@
+OPENSSL_LIBS = @OPENSSL_LIBS@
+OPENVPN_VERSION_MAJOR = @OPENVPN_VERSION_MAJOR@
+OPENVPN_VERSION_MINOR = @OPENVPN_VERSION_MINOR@
+OPENVPN_VERSION_PATCH = @OPENVPN_VERSION_PATCH@
OPTIONAL_CRYPTO_CFLAGS = @OPTIONAL_CRYPTO_CFLAGS@
OPTIONAL_CRYPTO_LIBS = @OPTIONAL_CRYPTO_LIBS@
OPTIONAL_DL_LIBS = @OPTIONAL_DL_LIBS@
+OPTIONAL_LZ4_CFLAGS = @OPTIONAL_LZ4_CFLAGS@
+OPTIONAL_LZ4_LIBS = @OPTIONAL_LZ4_LIBS@
OPTIONAL_LZO_CFLAGS = @OPTIONAL_LZO_CFLAGS@
OPTIONAL_LZO_LIBS = @OPTIONAL_LZO_LIBS@
OPTIONAL_PKCS11_HELPER_CFLAGS = @OPTIONAL_PKCS11_HELPER_CFLAGS@
@@ -229,8 +226,6 @@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
PLUGIN_AUTH_PAM_CFLAGS = @PLUGIN_AUTH_PAM_CFLAGS@
PLUGIN_AUTH_PAM_LIBS = @PLUGIN_AUTH_PAM_LIBS@
-POLARSSL_CFLAGS = @POLARSSL_CFLAGS@
-POLARSSL_LIBS = @POLARSSL_LIBS@
RANLIB = @RANLIB@
RC = @RC@
ROUTE = @ROUTE@
@@ -245,6 +240,11 @@ TAP_CFLAGS = @TAP_CFLAGS@
TAP_WIN_COMPONENT_ID = @TAP_WIN_COMPONENT_ID@
TAP_WIN_MIN_MAJOR = @TAP_WIN_MIN_MAJOR@
TAP_WIN_MIN_MINOR = @TAP_WIN_MIN_MINOR@
+TEST_CFLAGS = @TEST_CFLAGS@
+TEST_LDFLAGS = @TEST_LDFLAGS@
+VENDOR_BUILD_ROOT = @VENDOR_BUILD_ROOT@
+VENDOR_DIST_ROOT = @VENDOR_DIST_ROOT@
+VENDOR_SRC_ROOT = @VENDOR_SRC_ROOT@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
@@ -325,6 +325,7 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign distro/rpm/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign distro/rpm/Makefile
+.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
@@ -502,8 +503,6 @@ uninstall-am:
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
tags-am uninstall uninstall-am
-.PRECIOUS: Makefile
-
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
diff --git a/distro/rpm/openvpn.spec b/distro/rpm/openvpn.spec
index 6152d10..3c29313 100644
--- a/distro/rpm/openvpn.spec
+++ b/distro/rpm/openvpn.spec
@@ -13,7 +13,7 @@
Summary: OpenVPN is a robust and highly flexible VPN daemon by James Yonan.
Name: openvpn
-Version: 2.3.11
+Version: 2.4_beta1
Release: 1
URL: http://openvpn.net/
Source0: http://prdownloads.sourceforge.net/openvpn/%{name}-%{version}.tar.gz
diff --git a/distro/systemd/openvpn-client@.service b/distro/systemd/openvpn-client@.service
index 56d93a9..18b84dd 100644
--- a/distro/systemd/openvpn-client@.service
+++ b/distro/systemd/openvpn-client@.service
@@ -3,15 +3,17 @@ Description=OpenVPN tunnel for %I
After=syslog.target network-online.target
Wants=network-online.target
Documentation=man:openvpn(8)
-Documentation=https://community.openvpn.net/openvpn/wiki/Openvpn23ManPage
+Documentation=https://community.openvpn.net/openvpn/wiki/Openvpn24ManPage
Documentation=https://community.openvpn.net/openvpn/wiki/HOWTO
[Service]
PrivateTmp=true
-Type=forking
-PIDFile=/var/run/openvpn/client_%i.pid
-ExecStart=/usr/sbin/openvpn --cd /etc/openvpn/client --config %i.conf --daemon --writepid /var/run/openvpn/client_%i.pid
-CapabilityBoundingSet=CAP_IPC_LOCK CAP_NET_ADMIN CAP_NET_BIND_SERVICE CAP_NET_RAW CAP_SETGID CAP_SETUID CAP_SYS_CHROOT CAP_DAC_READ_SEARCH
+RuntimeDirectory=openvpn-client
+RuntimeDirectoryMode=0710
+WorkingDirectory=/etc/openvpn/client
+ExecStartPre=/bin/sh -c 'grep -q -E ^daemon %i.conf || exit 0 && /usr/bin/echo "OpenVPN configuration cannot contain --daemon when being managed by systemd" ; exit 1'
+ExecStart=/usr/sbin/openvpn --suppress-timestamps --nobind --config %i.conf
+CapabilityBoundingSet=CAP_IPC_LOCK CAP_NET_ADMIN CAP_NET_RAW CAP_SETGID CAP_SETUID CAP_SYS_CHROOT CAP_DAC_OVERRIDE
LimitNPROC=10
DeviceAllow=/dev/null rw
DeviceAllow=/dev/net/tun rw
diff --git a/distro/systemd/openvpn-server@.service b/distro/systemd/openvpn-server@.service
index c4c9a12..a2b7b52 100644
--- a/distro/systemd/openvpn-server@.service
+++ b/distro/systemd/openvpn-server@.service
@@ -1,16 +1,19 @@
[Unit]
Description=OpenVPN service for %I
-After=syslog.target network.target
+After=syslog.target network-online.target
+Wants=network-online.target
Documentation=man:openvpn(8)
-Documentation=https://community.openvpn.net/openvpn/wiki/Openvpn23ManPage
+Documentation=https://community.openvpn.net/openvpn/wiki/Openvpn24ManPage
Documentation=https://community.openvpn.net/openvpn/wiki/HOWTO
[Service]
PrivateTmp=true
-Type=forking
-PIDFile=/var/run/openvpn/server_%i.pid
-ExecStart=/usr/sbin/openvpn --cd /etc/openvpn/server --status /var/run/openvpn/server_%i-status.log --status-version 2 --config %i.conf --daemon --writepid /var/run/openvpn/server_%i.pid
-CapabilityBoundingSet=CAP_IPC_LOCK CAP_NET_ADMIN CAP_NET_BIND_SERVICE CAP_NET_RAW CAP_SETGID CAP_SETUID CAP_SYS_CHROOT CAP_DAC_READ_SEARCH
+RuntimeDirectory=openvpn-server
+RuntimeDirectoryMode=0710
+WorkingDirectory=/etc/openvpn/server
+ExecStartPre=/bin/sh -c 'grep -q -E ^daemon %i.conf || exit 0 && /usr/bin/echo "OpenVPN configuration cannot contain --daemon when being managed by systemd" ; exit 1'
+ExecStart=/usr/sbin/openvpn --status %t/openvpn-server/status-%i.log --status-version 2 --suppress-timestamps --config %i.conf
+CapabilityBoundingSet=CAP_IPC_LOCK CAP_NET_ADMIN CAP_NET_BIND_SERVICE CAP_NET_RAW CAP_SETGID CAP_SETUID CAP_SYS_CHROOT CAP_DAC_OVERRIDE
LimitNPROC=10
DeviceAllow=/dev/null rw
DeviceAllow=/dev/net/tun rw
diff --git a/doc/Makefile.in b/doc/Makefile.in
index cb2e2c2..8e37bca 100644
--- a/doc/Makefile.in
+++ b/doc/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.15 from Makefile.am.
+# Makefile.in generated by automake 1.13.4 from Makefile.am.
# @configure_input@
-# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -26,17 +26,7 @@
#
VPATH = @srcdir@
-am__is_gnu_make = { \
- if test -z '$(MAKELEVEL)'; then \
- false; \
- elif test -n '$(MAKE_HOST)'; then \
- true; \
- elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
- true; \
- else \
- false; \
- fi; \
-}
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
am__make_running_with_option = \
case $${target_option-} in \
?) ;; \
@@ -101,6 +91,8 @@ build_triplet = @build@
host_triplet = @host@
@WIN32_TRUE@am__append_1 = openvpn.8
subdir = doc
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+ $(dist_man_MANS) $(dist_doc_DATA) $(am__dist_noinst_DATA_DIST)
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/ax_emptyarray.m4 \
$(top_srcdir)/m4/ax_socklen_t.m4 \
@@ -111,10 +103,9 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_emptyarray.m4 \
$(top_srcdir)/compat.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
-DIST_COMMON = $(srcdir)/Makefile.am $(dist_doc_DATA) \
- $(am__dist_noinst_DATA_DIST) $(am__DIST_COMMON)
mkinstalldirs = $(install_sh) -d
-CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_HEADER = $(top_builddir)/config.h \
+ $(top_builddir)/include/openvpn-plugin.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
AM_V_P = $(am__v_P_@AM_V@)
@@ -171,7 +162,6 @@ MANS = $(dist_man_MANS)
am__dist_noinst_DATA_DIST = README.plugins openvpn.8
DATA = $(dist_doc_DATA) $(dist_noinst_DATA) $(nodist_html_DATA)
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
-am__DIST_COMMON = $(dist_man_MANS) $(srcdir)/Makefile.in
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
@@ -185,6 +175,7 @@ AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
+CMAKE = @CMAKE@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
@@ -219,25 +210,31 @@ LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
-LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+LZ4_CFLAGS = @LZ4_CFLAGS@
+LZ4_LIBS = @LZ4_LIBS@
LZO_CFLAGS = @LZO_CFLAGS@
LZO_LIBS = @LZO_LIBS@
MAKEINFO = @MAKEINFO@
MAN2HTML = @MAN2HTML@
MANIFEST_TOOL = @MANIFEST_TOOL@
+MBEDTLS_CFLAGS = @MBEDTLS_CFLAGS@
+MBEDTLS_LIBS = @MBEDTLS_LIBS@
MKDIR_P = @MKDIR_P@
NETSTAT = @NETSTAT@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
-OPENSSL_CRYPTO_CFLAGS = @OPENSSL_CRYPTO_CFLAGS@
-OPENSSL_CRYPTO_LIBS = @OPENSSL_CRYPTO_LIBS@
-OPENSSL_SSL_CFLAGS = @OPENSSL_SSL_CFLAGS@
-OPENSSL_SSL_LIBS = @OPENSSL_SSL_LIBS@
+OPENSSL_CFLAGS = @OPENSSL_CFLAGS@
+OPENSSL_LIBS = @OPENSSL_LIBS@
+OPENVPN_VERSION_MAJOR = @OPENVPN_VERSION_MAJOR@
+OPENVPN_VERSION_MINOR = @OPENVPN_VERSION_MINOR@
+OPENVPN_VERSION_PATCH = @OPENVPN_VERSION_PATCH@
OPTIONAL_CRYPTO_CFLAGS = @OPTIONAL_CRYPTO_CFLAGS@
OPTIONAL_CRYPTO_LIBS = @OPTIONAL_CRYPTO_LIBS@
OPTIONAL_DL_LIBS = @OPTIONAL_DL_LIBS@
+OPTIONAL_LZ4_CFLAGS = @OPTIONAL_LZ4_CFLAGS@
+OPTIONAL_LZ4_LIBS = @OPTIONAL_LZ4_LIBS@
OPTIONAL_LZO_CFLAGS = @OPTIONAL_LZO_CFLAGS@
OPTIONAL_LZO_LIBS = @OPTIONAL_LZO_LIBS@
OPTIONAL_PKCS11_HELPER_CFLAGS = @OPTIONAL_PKCS11_HELPER_CFLAGS@
@@ -263,8 +260,6 @@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
PLUGIN_AUTH_PAM_CFLAGS = @PLUGIN_AUTH_PAM_CFLAGS@
PLUGIN_AUTH_PAM_LIBS = @PLUGIN_AUTH_PAM_LIBS@
-POLARSSL_CFLAGS = @POLARSSL_CFLAGS@
-POLARSSL_LIBS = @POLARSSL_LIBS@
RANLIB = @RANLIB@
RC = @RC@
ROUTE = @ROUTE@
@@ -279,6 +274,11 @@ TAP_CFLAGS = @TAP_CFLAGS@
TAP_WIN_COMPONENT_ID = @TAP_WIN_COMPONENT_ID@
TAP_WIN_MIN_MAJOR = @TAP_WIN_MIN_MAJOR@
TAP_WIN_MIN_MINOR = @TAP_WIN_MIN_MINOR@
+TEST_CFLAGS = @TEST_CFLAGS@
+TEST_LDFLAGS = @TEST_LDFLAGS@
+VENDOR_BUILD_ROOT = @VENDOR_BUILD_ROOT@
+VENDOR_DIST_ROOT = @VENDOR_DIST_ROOT@
+VENDOR_SRC_ROOT = @VENDOR_SRC_ROOT@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
@@ -361,6 +361,7 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign doc/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign doc/Makefile
+.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
@@ -631,8 +632,6 @@ uninstall-man: uninstall-man8
ps ps-am tags-am uninstall uninstall-am uninstall-dist_docDATA \
uninstall-man uninstall-man8 uninstall-nodist_htmlDATA
-.PRECIOUS: Makefile
-
@WIN32_TRUE@openvpn.8.html: $(srcdir)/openvpn.8
@WIN32_TRUE@ $(MAN2HTML) < $(srcdir)/openvpn.8 > openvpn.8.html
diff --git a/doc/management-notes.txt b/doc/management-notes.txt
index ef39b85..dd870eb 100644
--- a/doc/management-notes.txt
+++ b/doc/management-notes.txt
@@ -168,9 +168,12 @@ be reset by restarts.
OpenVPN will indicate that it is in a hold state by
sending a real-time notification to the management
-client:
+client, the parameter indicates how long OpenVPN would
+wait without UI (as influenced by connect-retry exponential
+backoff). The UI needs to wait for releasing the hold if it
+wants similar behavior:
- >HOLD:Waiting for hold release
+ >HOLD:Waiting for hold release:10
Command examples:
@@ -366,14 +369,23 @@ Command examples:
same time enable real-time state notification
of future state transitions.
-The output format consists of 4 comma-separated parameters:
+The output format consists of up to 9 comma-separated parameters:
(a) the integer unix date/time,
(b) the state name,
(c) optional descriptive string (used mostly on RECONNECTING
and EXITING to show the reason for the disconnect),
- (d) optional TUN/TAP local IP address (shown for ASSIGN_IP
- and CONNECTED), and
- (e) optional address of remote server (OpenVPN 2.1 or higher).
+ (d) optional TUN/TAP local IPv4 address
+ (e) optional address of remote server,
+ (f) optional port of remote server,
+ (g) optional local address,
+ (h) optional local port, and
+ (i) optional TUN/TAP local IPv6 address.
+
+Fields (e)-(h) are shown for CONNECTED state,
+(d) and (i) are shown for ASSIGN_IP and CONNECTED states.
+
+(e) is available starting from OpenVPN 2.1
+(f)-(i) are available starting from OpenVPN 2.4
Real-time state notifications will have a ">STATE:" prefix
prepended to them.
@@ -777,6 +789,28 @@ correct signature.
This capability is intended to allow the use of arbitrary cryptographic
service providers with OpenVPN via the management interface.
+COMMAND -- certificate (OpenVPN 2.4 or higher)
+----------------------------------------------
+Provides support for external storage of the certificate. Requires the
+--management-external-cert option. This option can be used instead of "cert"
+in client mode. On SSL protocol initialization a notification will be sent
+to the management interface with a hint as follows:
+
+>NEED-CERTIFICATE:macosx-keychain:subject:o=OpenVPN-TEST
+
+The management interface client should use the hint to obtain the specific
+SSL certificate and then return base64 encoded certificate as follows:
+
+certificate
+[BASE64_CERT_LINE]
+.
+.
+.
+END
+
+This capability is intended to allow the use of certificates
+stored outside of the filesystem (e.g. in Mac OS X Keychain)
+with OpenVPN via the management interface.
OUTPUT FORMAT
-------------
diff --git a/doc/openvpn.8 b/doc/openvpn.8
index 1cad9be..e997b09 100644
--- a/doc/openvpn.8
+++ b/doc/openvpn.8
@@ -21,13 +21,13 @@
.\" 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
.\"
.\" Manual page for openvpn
-.\
+.\"
.\" SH section heading
.\" SS subsection heading
.\" LP paragraph
.\" IP indented paragraph
.\" TP hanging label
-.\
+.\"
.\" .nf -- no formatting
.\" .fi -- resume formatting
.\" .ft 3 -- boldface
@@ -37,7 +37,7 @@
.TH openvpn 8 "17 November 2008"
.\"*********************************************************
.SH NAME
-openvpn - secure IP tunnel daemon.
+openvpn \- secure IP tunnel daemon.
.\"*********************************************************
.SH SYNOPSIS
.ft 3
@@ -221,6 +221,9 @@ options.
indicates the protocol to use when connecting with the
remote, and may be "tcp" or "udp".
+For forcing IPv4 or IPv6 connection suffix tcp or udp
+with 4/6 like udp4/udp6/tcp4/tcp6.
+
The client will move on to the next host in the list,
in the event of connection failure.
Note that at any given time, the OpenVPN client
@@ -265,9 +268,11 @@ not match
If
.B host
is a DNS name which resolves to multiple IP addresses,
-the first address returned by the system getaddrinfo() function
-will be used (no DNS randomization inside OpenVPN 2.3.x, and
-it will not try multiple addresses).
+OpenVPN will try them in the order that the system getaddrinfo()
+presents them, so priorization and DNS randomization is done
+by the system library. Unless an IP version is forced by the
+protocol specification (4/6 suffix), OpenVPN will try both IPv4
+and IPv6 addresses, in the order getaddrinfo() returns them.
.\"*********************************************************
.TP
.B \-\-remote\-random\-hostname
@@ -311,20 +316,18 @@ remote 198.19.34.56 443 tcp
<connection>
remote 198.19.34.56 443 tcp
-http-proxy 192.168.0.8 8080
-http-proxy-retry
+http\-proxy 192.168.0.8 8080
</connection>
<connection>
remote 198.19.36.99 443 tcp
-http-proxy 192.168.0.8 8080
-http-proxy-retry
+http\-proxy 192.168.0.8 8080
</connection>
-persist-key
-persist-tun
+persist\-key
+persist\-tun
pkcs12 client.p12
-ns-cert-type server
+ns\-cert\-type server
verb 3
.in -4
.ft
@@ -343,30 +346,27 @@ a
block:
.B bind,
-.B connect-retry,
-.B connect-retry-max,
-.B connect-timeout,
-.B explicit-exit-notify,
+.B connect\-retry,
+.B connect\-retry\-max,
+.B connect\-timeout,
+.B explicit\-exit\-notify,
.B float,
.B fragment,
-.B http-proxy,
-.B http-proxy-option,
-.B http-proxy-retry,
-.B http-proxy-timeout,
-.B link-mtu,
+.B http\-proxy,
+.B http\-proxy\-option,
+.B link\-mtu,
.B local,
.B lport,
.B mssfix,
-.B mtu-disc,
+.B mtu\-disc,
.B nobind,
.B port,
.B proto,
.B remote,
.B rport,
-.B socks-proxy,
-.B socks-proxy-retry,
-.B tun-mtu and
-.B tun-mtu-extra.
+.B socks\-proxy,
+.B tun\-mtu and
+.B tun\-mtu\-extra.
A defaulting mechanism exists for specifying options to apply to
all
@@ -415,9 +415,9 @@ for communicating with remote host.
.B p
can be
.B udp,
-.B tcp-client,
+.B tcp\-client,
or
-.B tcp-server.
+.B tcp\-server.
The default protocol is
.B udp
@@ -434,7 +434,7 @@ For TCP operation, one peer must use
and the other must use
.B \-\-proto tcp\-client.
A peer started with
-.B tcp-server
+.B tcp\-server
will wait indefinitely for an incoming connection. A peer
started with
.B tcp\-client
@@ -462,31 +462,27 @@ application-level UDP protocols, or tunneling protocols which don't
possess a built-in reliability layer.
.\"*********************************************************
.TP
-.B \-\-connect\-retry n
-For
-.B \-\-proto tcp\-client,
-take
-.B n
-as the
-number of seconds to wait
-between connection retries (default=5).
-.\"*********************************************************
-.TP
-.B \-\-connect\-timeout n
-For
-.B \-\-proto tcp\-client,
-set connection timeout to
+.B \-\-connect\-retry n [max]
+Wait
.B n
-seconds (default=10).
+seconds between connection attempts (default=5). Repeated reconnection
+attempts are slowed down after 5 retries per remote by doubling the wait
+time after each unsuccessful attempt. The optional argument
+.B max
+specifies the maximum value of wait time in seconds at which it gets
+capped (default=300).
.\"*********************************************************
.TP
.B \-\-connect\-retry\-max n
-For
-.B \-\-proto tcp\-client,
-take
.B n
-as the
-number of retries of connection attempt (default=infinite).
+specifies the number of times each
+.B \-\-remote
+or
+.B <connection>
+entry is tried. Specifying
+.B n
+as one would try each entry exactly once. A successful connection
+resets the counter. (default=unlimited).
.\"*********************************************************
.TP
.B \-\-show\-proxy\-settings
@@ -502,9 +498,12 @@ and port
If HTTP Proxy-Authenticate is required,
.B authfile
is a file containing a username and password on 2 lines, or
-"stdin" to prompt from console.
+"stdin" to prompt from console. Its content can also be specified
+in the config file with the
+.B \-\-http\-proxy\-user\-pass
+option. (See section on inline files)
-.B auth-method
+.B auth\-method
should be one of "none", "basic", or "ntlm".
HTTP Digest authentication is supported as well, but only via
@@ -517,7 +516,7 @@ flags (below).
The
.B auto
flag causes OpenVPN to automatically determine the
-.B auth-method
+.B auth\-method
and query stdin or the management interface for
username/password credentials, if required. This flag
exists on OpenVPN 2.1 or higher.
@@ -529,17 +528,6 @@ determine the authentication method, but to reject weak
authentication protocols such as HTTP Basic Authentication.
.\"*********************************************************
.TP
-.B \-\-http\-proxy\-retry
-Retry indefinitely on HTTP proxy errors. If an HTTP proxy error
-occurs, simulate a SIGUSR1 reset.
-.\"*********************************************************
-.TP
-.B \-\-http\-proxy\-timeout n
-Set proxy timeout to
-.B n
-seconds, default=5.
-.\"*********************************************************
-.TP
.B \-\-http\-proxy\-option type [parm]
Set extended HTTP proxy options.
Repeat to set multiple options.
@@ -552,6 +540,13 @@ Set HTTP version number to
.B AGENT user-agent --
Set HTTP "User-Agent" string to
.B user-agent.
+
+.B CUSTOM\-HEADER name content --
+Adds the custom Header with
+.B name
+as name and
+.B content
+as the content of the custom HTTP header.
.\"*********************************************************
.TP
.B \-\-socks\-proxy server [port] [authfile]
@@ -565,11 +560,6 @@ and port
"stdin" to prompt from console.
.\"*********************************************************
.TP
-.B \-\-socks\-proxy\-retry
-Retry indefinitely on Socks proxy errors. If a Socks proxy error
-occurs, simulate a SIGUSR1 reset.
-.\"*********************************************************
-.TP
.B \-\-resolv\-retry n
If hostname resolve fails for
.B \-\-remote,
@@ -582,7 +572,7 @@ Set
to "infinite" to retry indefinitely.
By default,
-.B \-\-resolv-retry infinite
+.B \-\-resolv\-retry infinite
is enabled. You can disable by setting n=0.
.\"*********************************************************
.TP
@@ -685,7 +675,7 @@ option. The port can also be set directly using the
option.
.\"*********************************************************
.TP
-.B \-\-bind
+.B \-\-bind [ipv6only]
Bind to local address and port. This is the default unless any of
.B \-\-proto tcp\-client
,
@@ -693,6 +683,12 @@ Bind to local address and port. This is the default unless any of
or
.B \-\-socks\-proxy
are used.
+
+If the
+.B ipv6only
+keyword is present OpenVPN will bind only to IPv6 (as oposed
+to IPv6 and IPv4) when a IPv6 socket is opened.
+
.\"*********************************************************
.TP
.B \-\-nobind
@@ -760,13 +756,13 @@ directive, this directive must always be compatible between client and server.
.B mode
can be one of:
-.B net30 --
+.B net30 \-\-
Use a point-to-point topology, by allocating one /30 subnet per client.
This is designed to allow point-to-point semantics when some
or all of the connecting clients might be Windows systems. This is the
default on OpenVPN 2.0.
-.B p2p --
+.B p2p \-\-
Use a point-to-point topology where the remote endpoint of the client's
tun interface always points to the local endpoint of the server's tun interface.
This mode allocates a single IP address per connecting client.
@@ -776,7 +772,7 @@ is functionally equivalent to the
.B \-\-ifconfig\-pool\-linear
directive which is available in OpenVPN 2.0 and is now deprecated.
-.B subnet --
+.B subnet \-\-
Use a subnet rather than a point-to-point topology by
configuring the tun interface with a local IP address and subnet mask,
similar to the topology used in
@@ -801,18 +797,6 @@ changes the interpretation of the arguments of
to mean "address netmask", no longer "local remote".
.\"*********************************************************
.TP
-.B \-\-tun\-ipv6
-Build a tun link capable of forwarding IPv6 traffic.
-Should be used in conjunction with
-.B \-\-dev tun
-or
-.B \-\-dev tunX.
-A warning will be displayed
-if no specific IPv6 TUN support for your OS has been compiled into OpenVPN.
-
-See below for further IPv6-related configuration options.
-.\"*********************************************************
-.TP
.B \-\-dev\-node node
Explicitly set the device node rather than using
/dev/net/tun, /dev/tun, /dev/tap, etc. If OpenVPN
@@ -892,7 +876,7 @@ you will be pinging across the VPN.
For TAP devices, which provide
the ability to create virtual
ethernet segments, or TUN devices in
-.B \-\-topology subnet
+.B --topology subnet
mode (which create virtual "multipoint networks"),
.B \-\-ifconfig
is used to set an IP address and
@@ -984,7 +968,7 @@ when
is specified.
.B metric
-default \-\- taken from
+default -- taken from
.B \-\-route\-metric
otherwise 0.
@@ -1019,13 +1003,6 @@ table (not supported on all OSes).
address if OpenVPN is being run in client mode, and is undefined in server mode.
.\"*********************************************************
.TP
-.B \-\-max\-routes n
-Allow a maximum number of n
-.B \-\-route
-options to be specified, either in the local configuration file,
-or pulled from an OpenVPN server. By default, n=100.
-.\"*********************************************************
-.TP
.B \-\-route\-gateway gw|'dhcp'
Specify a default gateway
.B gw
@@ -1193,7 +1170,7 @@ that the original default route is restored.
Option flags:
-.B local --
+.B local \-\-
Add the
.B local
flag if both OpenVPN servers are directly connected via a common subnet,
@@ -1203,7 +1180,7 @@ flag will cause step
.B 1
above to be omitted.
-.B autolocal --
+.B autolocal \-\-
Try to automatically determine whether to enable
.B local
flag above.
@@ -1230,6 +1207,17 @@ on non-Windows clients).
Block access to local LAN when the tunnel is active, except for
the LAN gateway itself. This is accomplished by routing the local
LAN (except for the LAN gateway address) into the tunnel.
+
+.B ipv6 --
+Redirect IPv6 routing into the tunnel. This works similar to the
+.B def1
+flag, that is, more specific IPv6 routes are added (2000::/4, 3000::/4),
+covering the whole IPv6 unicast space.
+
+.B !ipv4 --
+Do not redirect IPv4 traffic - typically used in the flag pair
+.B "ipv6 !ipv4"
+to redirect IPv6-only.
.\"*********************************************************
.TP
.B \-\-link\-mtu n
@@ -1626,16 +1614,25 @@ and
are mutually exclusive and cannot be used together.
.\"*********************************************************
.TP
-.B \-\-keepalive n m
+.B \-\-keepalive interval timeout
A helper directive designed to simplify the expression of
.B \-\-ping
and
+.B \-\-ping\-restart.
+
+This option can be used on both client and server side, but it is
+in enough to add this on the server side as it will push appropriate
+.B \-\-ping
+and
.B \-\-ping\-restart
-in server mode configurations.
+options to the client. If used on both server and client,
+the values pushed from server will override the client local values.
-The server timeout is set twice the value of the second argument.
-This ensures that a timeout is detected on client side
-before the server side drops the connection.
+The
+.B timeout
+argument will be twice as long on the server side. This ensures that
+a timeout is detected on client side before the server side drops
+the connection.
For example,
.B \-\-keepalive 10 60
@@ -1645,13 +1642,13 @@ expands as follows:
.ft 3
.in +4
if mode server:
- ping 10
- ping-restart 120
- push "ping 10"
- push "ping-restart 60"
+ ping 10 # Argument: interval
+ ping\-restart 120 # Argument: timeout*2
+ push "ping 10" # Argument: interval
+ push "ping\-restart 60" # Argument: timeout
else
- ping 10
- ping-restart 60
+ ping 10 # Argument: interval
+ ping\-restart 60 # Argument: timeout
.in -4
.ft
.fi
@@ -1979,16 +1976,16 @@ and scripts. Lower
values are more restrictive, higher values are more permissive. Settings for
.B level:
-.B 0 --
+.B 0 \-\-
Strictly no calling of external programs.
.br
-.B 1 --
+.B 1 \-\-
(Default) Only call built-in executables such as ifconfig, ip, route, or netsh.
.br
-.B 2 --
+.B 2 \-\-
Allow calling of built-in executables and user-defined scripts.
.br
-.B 3 --
+.B 3 \-\-
Allow passwords to be passed to scripts via environmental variables (potentially unsafe).
OpenVPN releases before v2.3 also supported a
@@ -2320,6 +2317,12 @@ otherwise would be prepended. In particular, this applies to
log messages sent to stdout.
.\"*********************************************************
.TP
+.B \-\-machine\-readable\-output
+Always write timestamps and message flags to log messages, even when they
+otherwise would not be prefixed. In particular, this applies to
+log messages sent to stdout.
+.\"*********************************************************
+.TP
.B \-\-writepid file
Write OpenVPN's main process ID to
.B file.
@@ -2420,13 +2423,13 @@ Set output verbosity to
Level 3 is recommended if you want a good summary
of what's happening without being swamped by output.
-.B 0 --
+.B 0 \-\-
No output except fatal errors.
.br
-.B 1 to 4 --
+.B 1 to 4 \-\-
Normal usage range.
.br
-.B 5 --
+.B 5 \-\-
Output
.B R
and
@@ -2434,7 +2437,7 @@ and
characters to the console for each packet read and write, uppercase is
used for TCP/UDP packets and lowercase is used for TUN/TAP packets.
.br
-.B 6 to 11 --
+.B 6 to 11 \-\-
Debug info range (see errlevel.h for additional
information on debug levels).
.\"*********************************************************
@@ -2464,12 +2467,34 @@ consecutive messages in the same category. This is useful to
limit repetitive logging of similar message types.
.\"*********************************************************
.TP
+.B \-\-compress [algorithm]
+Enable a compression algorithm.
+
+The
+.B algorithm
+parameter may be "lzo", "lz4", or empty. LZO and LZ4
+are different compression algorithms, with LZ4 generally
+offering the best performance with least CPU usage.
+For backwards compatibility with OpenVPN versions before 2.4, use "lzo"
+(which is identical to the older option "\-\-comp\-lzo yes").
+
+If the
+.B algorithm
+parameter is empty, compression will be turned off, but the packet
+framing for compression will still be enabled, allowing a different
+setting to be pushed later.
+.\"*********************************************************
+.TP
.B \-\-comp\-lzo [mode]
-Use fast LZO compression -- may add up to 1 byte per
+Use LZO compression -- may add up to 1 byte per
packet for incompressible data.
.B mode
may be "yes", "no", or "adaptive" (default).
+This option is deprecated in favor of the newer
+.B --compress
+option.
+
In a server mode setup, it is possible to selectively turn
compression on or off for individual clients.
@@ -2491,14 +2516,14 @@ for example:
.nf
.ft 3
.in +4
-comp-lzo yes
+comp\-lzo yes
push "comp\-lzo yes"
.in -4
.ft
.fi
The first line sets the
-.B comp-lzo
+.B comp\-lzo
setting for the server
side of the link, the second sets the client side.
.\"*********************************************************
@@ -2558,7 +2583,7 @@ to the port, using a telnet client in "raw" mode. Once connected,
type "help" for a list of commands.
For detailed documentation on the management interface, see
-the management-notes.txt file in the
+the management\-notes.txt file in the
.B management
folder of
the OpenVPN source distribution.
@@ -2599,12 +2624,23 @@ Allow management interface to override
.B \-\-remote
directives (client-only).
.\"*********************************************************
+.TP
.B \-\-management\-external\-key
Allows usage for external private key file instead of
.B \-\-key
option (client-only).
.\"*********************************************************
.TP
+.B \-\-management\-external\-cert certificate-hint
+Allows usage for external certificate instead of
+.B \-\-cert
+option (client-only).
+.B certificate-hint
+is an arbitrary string which is passed to a management
+interface client as an argument of NEED-CERTIFICATE notification.
+Requires \-\-management\-external\-key.
+.\"*********************************************************
+.TP
.B \-\-management\-forget\-disconnect
Make OpenVPN forget passwords when management session
disconnects.
@@ -2650,7 +2686,7 @@ distribution for detailed notes.
.TP
.B \-\-management\-client\-pf
Management interface clients must specify a packet
-filter file for each connecting client. See management-notes.txt
+filter file for each connecting client. See management\-notes.txt
in OpenVPN distribution for detailed notes.
.\"*********************************************************
.TP
@@ -2694,11 +2730,23 @@ OpenVPN in the order that they are declared in the config
file. If both a plugin and script are configured for the same
callback, the script will be called last. If the
return code of the module/script controls an authentication
-function (such as tls-verify, auth-user-pass-verify, or
-client-connect), then
+function (such as tls\-verify, auth\-user\-pass\-verify, or
+client\-connect), then
every module and script must return success (0) in order for
the connection to be authenticated.
.\"*********************************************************
+.TP
+.B \-\-keying-material-exporter label len
+Save Exported Keying Material [RFC5705] of len bytes (must be
+between 16 and 4095 bytes) using label in environment
+(exported_keying_material) for use by plugins in
+OPENVPN_PLUGIN_TLS_FINAL callback.
+
+Note that exporter labels have the potential to collide with existing PRF
+labels. In order to prevent this, labels MUST begin with "EXPORTER".
+
+This option requires OpenSSL 1.0.1 or newer.
+.\"*********************************************************
.SS Server Mode
Starting with OpenVPN 2.0, a multi-client TCP/UDP server mode
is supported, and can be enabled with the
@@ -2729,15 +2777,15 @@ expands as follows:
.ft 3
.in +4
mode server
- tls-server
+ tls\-server
push "topology [topology]"
if dev tun AND (topology == net30 OR topology == p2p):
ifconfig 10.8.0.1 10.8.0.2
if !nopool:
- ifconfig-pool 10.8.0.4 10.8.0.251
+ ifconfig\-pool 10.8.0.4 10.8.0.251
route 10.8.0.0 255.255.255.0
- if client-to-client:
+ if client\-to\-client:
push "route 10.8.0.0 255.255.255.0"
else if topology == net30:
push "route 10.8.0.1"
@@ -2745,10 +2793,10 @@ expands as follows:
if dev tap OR (dev tun AND topology == subnet):
ifconfig 10.8.0.1 255.255.255.0
if !nopool:
- ifconfig-pool 10.8.0.2 10.8.0.254 255.255.255.0
- push "route-gateway 10.8.0.1"
- if route-gateway unset:
- route-gateway 10.8.0.2
+ ifconfig\-pool 10.8.0.2 10.8.0.254 255.255.255.0
+ push "route\-gateway 10.8.0.1"
+ if route\-gateway unset:
+ route\-gateway 10.8.0.2
.in -4
.ft
@@ -2815,17 +2863,17 @@ for OpenVPN to allocate to connecting
clients.
For example,
-.B server-bridge 10.8.0.4 255.255.255.0 10.8.0.128 10.8.0.254
+.B server\-bridge 10.8.0.4 255.255.255.0 10.8.0.128 10.8.0.254
expands as follows:
.nf
.ft 3
.in +4
mode server
-tls-server
+tls\-server
-ifconfig-pool 10.8.0.128 10.8.0.254 255.255.255.0
-push "route-gateway 10.8.0.4"
+ifconfig\-pool 10.8.0.128 10.8.0.254 255.255.255.0
+push "route\-gateway 10.8.0.4"
.in -4
.ft
.fi
@@ -2838,9 +2886,9 @@ In another example,
.ft 3
.in +4
mode server
-tls-server
+tls\-server
-push "route-gateway dhcp"
+push "route\-gateway dhcp"
.in -4
.ft
.fi
@@ -2853,7 +2901,7 @@ expands as follows:
.ft 3
.in +4
mode server
-tls-server
+tls\-server
.in -4
.ft
.fi
@@ -2894,18 +2942,76 @@ as with a
configuration file. This option will ignore
.B \-\-push
options at the global config file level.
+.\"*********************************************************
+.TP
+.B \-\-push\-remove opt
+selectively remove all
+.B \-\-push
+options matching "opt" from the option list for a client. "opt" is matched
+as a substring against the whole option string to-be-pushed to the client, so
+.B \-\-push\-remove route
+would remove all
+.B \-\-push route ...
+and
+.B \-\-push route-ipv6 ...
+statements, while
+.B \-\-push\-remove 'route-ipv6 2001:'
+would only remove IPv6 routes for 2001:... networks.
+
+.B \-\-push\-remove
+can only be used in a client-specific context, like in a
+.B \-\-client\-config\-dir
+file, or
+.B \-\-client\-connect
+script or plugin -- similar to
+.B \-\-push\-reset,
+just more selective.
+
+NOTE: to
+.I change
+an option,
+.B \-\-push\-remove
+can be used to first remove the old value, and then add a new
+.B \-\-push
+option with the new value.
+.\"*********************************************************
.TP
.B \-\-push\-peer\-info
-Push additional information about the client to server. The additional information
-consists of the following data:
+Push additional information about the client to server.
+The following data is always pushed to the server:
IV_VER=<version> -- the client OpenVPN version
IV_PLAT=[linux|solaris|openbsd|mac|netbsd|freebsd|win] -- the client OS platform
+IV_LZO_STUB=1 -- if client was built with LZO stub capability
+
+IV_LZ4=1 -- if the client supports LZ4 compressions.
+
+IV_RGI6=1 -- if the client supports
+.B \-\-redirect\-gateway
+for ipv6
+
+IV_PROTO=2 -- if the client supports peer-id floating mechansim
+
+IV_NCP=2 -- negotiable ciphers, client supports
+.B \-\-cipher
+pushed by the server, a value of 2 or greater indicates client
+supports AES-GCM-128 and AES-GCM-256.
+
+IV_UI_VER=<gui_id> <version> -- the UI version of a UI if one is
+running, for example "de.blinkt.openvpn 0.5.47" for the
+Android app.
+
+When
+.B \-\-push\-peer\-info
+is enabled the additional information consists of the following data:
+
IV_HWADDR=<mac address> -- the MAC address of clients default gateway
-IV_LZO_STUB=1 -- if client was built with LZO stub capability
+IV_SSL=<version string> -- the ssl version used by the client, e.g. "OpenSSL 1.0.2f 28 Jan 2016".
+
+IV_PLAT_VER=x.y - the version of the operating system, e.g. 6.1 for Windows 7.
UV_<name>=<value> -- client environment variables whose names start with "UV_"
.\"*********************************************************
@@ -2941,7 +3047,7 @@ parameter will also be pushed to clients.
.\"*********************************************************
.TP
.B \-\-ifconfig\-pool\-persist file [seconds]
-Persist/unpersist ifconfig-pool
+Persist/unpersist ifconfig\-pool
data to
.B file,
at
@@ -2992,14 +3098,14 @@ This option is deprecated, and should be replaced with
which is functionally equivalent.
.\"*********************************************************
.TP
-.B \-\-ifconfig\-push local remote-netmask [alias]
+.B \-\-ifconfig\-push local remote\-netmask [alias]
Push virtual IP endpoints for client tunnel,
overriding the \-\-ifconfig\-pool dynamic allocation.
The parameters
.B local
and
-.B remote-netmask
+.B remote\-netmask
are set according to the
.B \-\-ifconfig
directive which you want to execute on the client machine to
@@ -3015,9 +3121,9 @@ The optional
.B alias
parameter may be used in cases where NAT causes the client view
of its local endpoint to differ from the server view. In this case
-.B local/remote-netmask
+.B local/remote\-netmask
will refer to the server view while
-.B alias/remote-netmask
+.B alias/remote\-netmask
will refer to the client view.
This option must be associated with a specific client instance,
@@ -3218,7 +3324,7 @@ without needing to restart the server.
The following
options are legal in a client-specific context:
-.B \-\-push, \-\-push\-reset, \-\-iroute, \-\-ifconfig\-push,
+.B \-\-push, \-\-push\-reset, \-\-push\-remove, \-\-iroute, \-\-ifconfig\-push,
and
.B \-\-config.
.\"*********************************************************
@@ -3298,8 +3404,8 @@ The macro expands as follows:
.ft 3
.in +4
if mode server:
- socket-flags TCP_NODELAY
- push "socket-flags TCP_NODELAY"
+ socket\-flags TCP_NODELAY
+ push "socket\-flags TCP_NODELAY"
.in -4
.ft
.fi
@@ -3365,8 +3471,10 @@ DoS scenario, legitimate connections might also be refused.
For the best protection against DoS attacks in server mode,
use
.B \-\-proto udp
-and
-.B \-\-tls\-auth.
+and either
+.B \-\-tls\-auth
+or
+.B \-\-tls\-crypt\fR.
.\"*********************************************************
.TP
.B \-\-learn\-address cmd
@@ -3383,19 +3491,19 @@ Three arguments will be appended to any arguments in
.B cmd
as follows:
-.B [1] operation --
+.B [1] operation \-\-
"add", "update", or "delete" based on whether or not
the address is being added to, modified, or deleted from
OpenVPN's internal routing table.
.br
-.B [2] address --
+.B [2] address \-\-
The address being learned or unlearned. This can be
an IPv4 address such as "198.162.10.14", an IPv4 subnet
such as "198.162.10.0/24", or an ethernet MAC address (when
.B \-\-dev tap
is being used) such as "00:FF:01:02:03:04".
.br
-.B [3] common name --
+.B [3] common name \-\-
The common name on the certificate associated with the
client linked to this address. Only present for "add"
or "update" operations, not "delete".
@@ -3431,7 +3539,7 @@ and/or escaped using a backslash, and should be separated by one or more spaces.
If
.B method
-is set to "via-env", OpenVPN will call
+is set to "via\-env", OpenVPN will call
.B script
with the environmental variables
.B username
@@ -3444,7 +3552,7 @@ unprivileged processes.
If
.B method
-is set to "via-file", OpenVPN will write the username and
+is set to "via\-file", OpenVPN will write the username and
password to the first two lines of a temporary file. The filename
will be passed as an argument to
.B script,
@@ -3482,18 +3590,40 @@ strings are handled. Never use these strings in such a way
that they might be escaped or evaluated by a shell interpreter.
For a sample script that performs PAM authentication, see
-.B sample-scripts/auth-pam.pl
+.B sample\-scripts/auth\-pam.pl
in the OpenVPN source distribution.
.\"*********************************************************
.TP
+.B \-\-auth\-gen\-token [lifetime]
+After successful user/password authentication, the OpenVPN
+server will with this option generate a temporary
+authentication token and push that to client. On the following
+renegotiations, the OpenVPN client will pass this token instead
+of the users password. On the server side the server will do
+the token authentication internally and it will NOT do any
+additional authentications against configured external
+user/password authentication mechanisms.
+
+The
+.B lifetime
+argument defines how long the generated token is valid. The
+lifetime is defined in seconds. If lifetime is not set
+or it is set to 0, the token will never expire.
+
+This feature is useful for environments which is configured
+to use One Time Passwords (OTP) as part of the user/password
+authentications and that authentication mechanism does not
+implement any auth-token support.
+.\"*********************************************************
+.TP
.B \-\-opt\-verify
Clients that connect with options that are incompatible
with those of the server will be disconnected.
Options that will be compared for compatibility include
-dev-type, link-mtu, tun-mtu, proto, tun-ipv6, ifconfig,
-comp-lzo, fragment, keydir, cipher, auth, keysize, secret,
-no-replay, no-iv, tls-auth, key-method, tls-server, and tls-client.
+dev\-type, link\-mtu, tun\-mtu, proto, ifconfig,
+comp\-lzo, fragment, keydir, cipher, auth, keysize, secret,
+no\-replay, no\-iv, tls\-auth, key\-method, tls\-server, and tls\-client.
This option requires that
.B \-\-disable\-occ
@@ -3518,18 +3648,63 @@ to empty strings (""). The authentication module/script MUST have logic
to detect this condition and respond accordingly.
.\"*********************************************************
.TP
-.B \-\-client\-cert\-not\-required
+.B \-\-client\-cert\-not\-required (DEPRECATED)
Don't require client certificate, client will authenticate
using username/password only. Be aware that using this directive
is less secure than requiring certificates from all clients.
+
+.B Please note:
+This option is now deprecated and will be removed in OpenVPN v2.5.
+It is replaced by
+.B \-\-verify\-client\-cert
+which allows for more flexibility. The option
+.B \-\-verify\-client\-cert none
+is functionally equivalent to
+.B \-\-client\-cert\-not\-required
+.
+
+.\"*********************************************************
+.TP
+.B \-\-verify\-client\-cert none|optional|require
+Specify whether the client is required to supply a valid certificate.
+
+Possible options are
+
+.B none
+: a client certificate is not required. the client need to authenticate
+using username/password only. Be aware that using this directive
+is less secure than requiring certificates from all clients.
+
If you use this directive, the
entire responsibility of authentication will rest on your
.B \-\-auth\-user\-pass\-verify
script, so keep in mind that bugs in your script
could potentially compromise the security of your VPN.
-If you don't use this directive, but you also specify an
+.B \-\-verify\-client\-cert none
+is functionally equivalent to
+.B \-\-client\-cert\-not\-required.
+
+.B optional
+: a client may present a certificate but it is not required to do so.
+When using this directive, you should also use a
+.B \-\-auth\-user\-pass\-verify
+script to ensure that clients are authenticated using a
+certificate, a username and password, or possibly even both.
+
+Again, the entire responsibility of authentication will rest on your
+.B \-\-auth\-user\-pass\-verify
+script, so keep in mind that bugs in your script
+could potentially compromise the security of your VPN.
+
+.B require
+: this is the default option. A client is required to present a
+certificate, otherwise VPN access is refused.
+
+If you don't use this directive (or use
+.B \-\-verify\-client\-cert require
+) but you also specify an
.B \-\-auth\-user\-pass\-verify
script, then OpenVPN will perform double authentication. The
client certificate verification AND the
@@ -3591,11 +3766,7 @@ carriage-return. no-remapping is only available on the server side.
.B Please note:
This option is immediately deprecated. It is only implemented
to make the transition to the new formatting less intrusive. It will be
-removed either in OpenVPN v2.4 or v2.5. So please make sure you use the
-.B \-\-verify\-x509\-name
-option instead of
-.B \-\-tls\-remote
-as soon as possible and update your scripts where necessary.
+removed in OpenVPN v2.5. So please update your scripts/plug-ins where necessary.
.\"*********************************************************
.TP
.B \-\-no\-name\-remapping (DEPRECATED)
@@ -3608,8 +3779,8 @@ It ensures compatibility with server configurations using the
option.
.B Please note:
-This option is now deprecated. It will be removed either in OpenVPN v2.4
-or v2.5. So please make sure you support the new X.509 name formatting
+This option is now deprecated. It will be removed in OpenVPN v2.5.
+So please make sure you support the new X.509 name formatting
described with the
.B \-\-compat\-names
option as soon as possible.
@@ -3654,7 +3825,7 @@ of OpenVPN's client mode. This directive is equivalent to:
.ft 3
.in +4
pull
- tls-client
+ tls\-client
.in -4
.ft
.fi
@@ -3681,6 +3852,57 @@ in situations where you don't trust the server to have control
over the client's routing table.
.\"*********************************************************
.TP
+.B \-\-pull\-filter accept|ignore|reject \fItext\fR
+Filter options received from the server if the option starts with
+\fItext\fR. Runs on client. The action flag
+.B accept
+allows the option,
+.B ignore
+removes it and
+.B reject
+flags an error and triggers a SIGUSR1 restart.
+The filters may be specified multiple times, and each filter is
+applied in the order it is specified. The filtering of each
+option stops as soon as a match is found. Unmatched options are accepted
+by default.
+
+Prefix comparison is used to match \fItext\fR against the
+received option so that
+
+.nf
+.ft 3
+.in +4
+\-\-pull\-filter ignore "route"
+.in -4
+.ft
+.fi
+
+would remove all pushed options starting with
+.B route
+which would include, for example,
+.B route\-gateway.
+Enclose \fItext\fR in quotes to embed spaces.
+
+.nf
+.ft 3
+.in +4
+\-\-pull\-filter accept "route 192.168.1."
+\-\-pull\-filter ignore "route "
+.in -4
+.ft
+.fi
+
+would remove all routes that do not start with 192.168.1.
+
+This option may be used only on clients.
+Note that
+.B reject
+may result in a repeated cycle of failure and reconnect,
+unless multiple remotes are specified and connection to the next remote
+succeeds. To silently ignore an option pushed by the server, use
+.B ignore.
+.\"*********************************************************
+.TP
.B \-\-auth\-user\-pass [up]
Authenticate with server using username/password.
.B up
@@ -3718,15 +3940,15 @@ tries to connect.
.B type
can be one of:
-.B none --
+.B none \-\-
Client will exit with a fatal error (this is the default).
.br
-.B nointeract --
+.B nointeract \-\-
Client will retry the connection without requerying for an
.B \-\-auth\-user\-pass
username/password. Use this option for unattended clients.
.br
-.B interact --
+.B interact \-\-
Client will requery for an
.B \-\-auth\-user\-pass
username/password and/or private key password before attempting a reconnection.
@@ -3751,14 +3973,12 @@ description of the OpenVPN challenge/response protocol.
.\"*********************************************************
.TP
.B \-\-server\-poll\-timeout n
-when polling possible remote servers to connect to
-in a round-robin fashion, spend no more than
+.B \-\-connect\-timeout n
+when connecting to a remote server do not wait for more than
.B n
seconds waiting for a response before trying the next server.
-As this only makes sense in client-to-server setups, it cannot
-be used in point-to-point setups using
-.B \-\-secret
-symmetrical key mode.
+The default value is 120s. This timeout includes proxy and TCP
+connect timeouts.
.\"*********************************************************
.TP
.B \-\-explicit\-exit\-notify [n]
@@ -3769,8 +3989,23 @@ option will tell the server to immediately close its client instance object
rather than waiting for a timeout. The
.B n
parameter (default=1) controls the maximum number of attempts that the client
-will try to resend the exit notification message. OpenVPN will not send any exit
+will try to resend the exit notification message.
+
+In UDP server mode, send RESTART control channel command to connected clients. The
+.B n
+parameter (default=1) controls client behavior. With
+.B n
+= 1 client will attempt to reconnect
+to the same server, with
+.B n
+= 2 client will advance to the next server.
+
+OpenVPN will not send any exit
notifications unless this option is enabled.
+.TP
+.B \-\-allow\-recursive\-routing
+When this option is set, OpenVPN will not drop incoming tun packets
+with same destination as host.
.\"*********************************************************
.SS Data Channel Encryption Options:
These options are meaningful for both Static & TLS-negotiated key modes
@@ -3852,8 +4087,9 @@ options. Useful when using inline files (See section on inline files).
.\"*********************************************************
.TP
.B \-\-auth alg
-Authenticate packets with HMAC using message
-digest algorithm
+Authenticate data channel packets and (if enabled)
+.B tls-auth
+control channel packets with HMAC using message digest algorithm
.B alg.
(The default is
.B SHA1
@@ -3862,7 +4098,17 @@ HMAC is a commonly used message authentication algorithm (MAC) that uses
a data string, a secure hash algorithm, and a key, to produce
a digital signature.
-OpenVPN's usage of HMAC is to first encrypt a packet, then HMAC the resulting ciphertext.
+The OpenVPN data channel protocol uses encrypt-then-mac (i.e. first encrypt a
+packet, then HMAC the resulting ciphertext), which prevents padding oracle
+attacks.
+
+If an AEAD cipher mode (e.g. GCM) is chosen, the specified
+.B \-\-auth
+algorithm is ignored for the data channel, and the authentication method of the
+AEAD cipher is used instead. Note that
+.B alg
+still specifies the digest used for
+.B tls-auth\fR.
In static-key encryption mode, the HMAC key
is included in the key file generated by
@@ -3885,25 +4131,57 @@ Encrypt data channel packets with cipher algorithm
The default is
.B BF-CBC,
an abbreviation for Blowfish in Cipher Block Chaining mode.
-Blowfish has the advantages of being fast, very secure, and allowing key sizes
-of up to 448 bits. Blowfish is designed to be used in situations where
-keys are changed infrequently.
-For more information on blowfish, see
-.I http://www.counterpane.com/blowfish.html
+Using BF-CBC is no longer recommended, because of it's 64-bit block size. This
+small block size allows attacks based on collisions, as demonstrated by SWEET32.
+See https://community.openvpn.net/openvpn/wiki/SWEET32 for details.
-To see other ciphers that are available with
-OpenVPN, use the
+To see other ciphers that are available with OpenVPN, use the
.B \-\-show\-ciphers
option.
-OpenVPN supports the CBC, CFB, and OFB cipher modes,
-however CBC is recommended and CFB and OFB should
-be considered advanced modes.
-
Set
.B alg=none
to disable encryption.
+
+As of OpenVPN 2.4, cipher negotiation (NCP) can override the cipher specified by
+.B \-\-cipher\fR.
+See
+.B \-\-ncp-ciphers
+and
+.B \-\-ncp-disable
+for more on NCP.
+
+.\"*********************************************************
+.TP
+.B \-\-ncp\-ciphers cipher_list
+Restrict the allowed ciphers to be negotiated to the ciphers in
+.B cipher_list\fR.
+.B cipher_list
+is a colon-separated list of ciphers, and defaults to
+"AES-256-GCM:AES-128-GCM".
+
+For servers, the first cipher from
+.B cipher_list
+will be pushed to clients that support cipher negotiation.
+
+Cipher negotiation is enabled in client-server mode only. I.e. if
+.B \-\-mode
+is set to 'server' (server-side, implied by setting
+.B \-\-server
+), or if
+.B \-\-pull
+is specified (client-side, implied by setting \-\-client).
+
+If both peers support and do not disable NCP, the negotiated cipher will
+override the cipher specified by
+.B \-\-cipher\fR.
+
+.\"*********************************************************
+.TP
+.B \-\-ncp\-disable
+Disable "negotiable crypto parameters". This completely disables cipher
+negotiation.
.\"*********************************************************
.TP
.B \-\-keysize n
@@ -4006,7 +4284,7 @@ is 15 seconds.
This option is only relevant in UDP mode, i.e.
when either
.B \-\-proto udp
-is specifed, or no
+is specified, or no
.B \-\-proto
option is specified.
@@ -4202,14 +4480,9 @@ will succeed, both OpenVPN
peers will exchange temporary session keys, and the tunnel will begin
passing data.
-The OpenVPN distribution contains a set of scripts for
-managing RSA certificates & keys,
-located in the
-.I easy-rsa
-subdirectory.
-
-The easy-rsa package is also rendered in web form here:
-.I http://openvpn.net/easyrsa.html
+The OpenVPN project provides a set of scripts for
+managing RSA certificates & keys:
+.I https://github.com/OpenVPN/easy-rsa
.\"*********************************************************
.TP
.B \-\-tls\-server
@@ -4247,7 +4520,6 @@ they are distributed with OpenVPN, they are totally insecure.
.TP
.B \-\-capath dir
Directory containing trusted certificates (CAs and CRLs).
-Available with OpenSSL version >= 0.9.7 dev.
Not available with PolarSSL.
When using the
@@ -4271,13 +4543,25 @@ for more information.
File containing Diffie Hellman parameters
in .pem format (required for
.B \-\-tls\-server
-only). Use
+only).
-.B openssl dhparam \-out dh1024.pem 1024
+Set
+.B file=none
+to disable Diffie Hellman key exchange (and use ECDH only). Note that this
+requires peers to be using an SSL library that supports ECDH TLS cipher suites
+(e.g. OpenSSL 1.0.1+, or PolarSSL 1.3+).
-to generate your own, or use the existing dh1024.pem file
-included with the OpenVPN distribution. Diffie Hellman parameters
-may be considered public.
+Use
+.B openssl dhparam \-out dh2048.pem 2048
+to generate 2048-bit DH parameters. Diffie Hellman parameters may be considered
+public.
+.\"*********************************************************
+.TP
+.B \-\-ecdh\-curve name
+Specify the curve to use for elliptic curve Diffie Hellman. Available
+curves can be listed with
+.B \-\-show\-curves
+. The specified curve will only be used for ECDH TLS-ciphers.
.\"*********************************************************
.TP
.B \-\-cert file
@@ -4348,26 +4632,17 @@ above).
.\"*********************************************************
.TP
.B \-\-tls\-version\-min version ['or\-highest']
-Enable TLS version negotiation, and set the minimum
+Sets the minimum
TLS version we will accept from the peer (default is "1.0").
Examples for version
include "1.0", "1.1", or "1.2". If 'or-highest' is specified
and version is not recognized, we will only accept the highest TLS
version supported by the local SSL implementation.
-
-Also see
-.B \-\-tls\-version\-max
-below, for information on compatibility.
.\"*********************************************************
.TP
.B \-\-tls\-version\-max version
Set the maximum TLS version we will use (default is the highest version
supported). Examples for version include "1.0", "1.1", or "1.2".
-
-If and only if this is set to 1.0, and OpenSSL is used (not PolarSSL),
-then OpenVPN will set up OpenSSL to use a fixed TLSv1 handshake. All
-other configurations will autonegotiate in the given limits, and the
-choice of handshake versions is left to the SSL implementation.
.\"*********************************************************
.TP
.B \-\-pkcs12 file
@@ -4429,7 +4704,7 @@ and
.B \-\-pkcs12.
If p11-kit is present on the system, its
-.B p11-kit-proxy.so
+.B p11\-kit\-proxy.so
module will be loaded by default if either the
.B \-\-pkcs11\-id
or
@@ -4505,7 +4780,10 @@ exchanged over the TLS session.
In method 1 (the default for OpenVPN 1.x), both sides generate
random encrypt and HMAC-send keys which are forwarded to
-the other host over the TLS channel.
+the other host over the TLS channel. Method 1 is
+.B deprecated in OpenVPN 2.4
+, and
+.B will be removed in OpenVPN 2.5\fR.
In method 2, (the default for OpenVPN 2.0)
the client generates a random key. Both client
@@ -4556,7 +4834,8 @@ your VPN connection. But it is also easy to unwittingly use it to carefully
align a gun with your foot, or just break your connection. Use with care!
The default for \-\-tls\-cipher is to use PolarSSL's default cipher list
-when using PolarSSL or "DEFAULT:!EXP:!LOW:!MEDIUM:!PSK:!SRP:!kRSA" when using
+when using PolarSSL or
+"DEFAULT:!EXP:!LOW:!MEDIUM:!kDH:!kECDH:!DSS:!PSK:!SRP:!kRSA" when using
OpenSSL.
.\"*********************************************************
.TP
@@ -4657,8 +4936,8 @@ Exit on TLS negotiation failure.
.\"*********************************************************
.TP
.B \-\-tls\-auth file [direction]
-Add an additional layer of HMAC authentication on top of the TLS
-control channel to protect against DoS attacks.
+Add an additional layer of HMAC authentication on top of the TLS control channel
+to mitigate DoS attacks and attacks on the TLS stack.
In a nutshell,
.B \-\-tls\-auth
@@ -4668,27 +4947,11 @@ bearing an incorrect HMAC signature can be dropped immediately without
response.
.B file
-(required) is a key file which can be in one of two formats:
-
-.B (1)
-An OpenVPN static key file generated by
+(required) is a file in OpenVPN static key format which can be generated by
.B \-\-genkey
-(required if
-.B direction
-parameter is used).
-.B (2) DEPRECATED
-A freeform passphrase file. In this case the HMAC key will
-be derived by taking a secure hash of this file, similar to
-the
-.BR md5sum (1)
-or
-.BR sha1sum (1)
-commands. This option is deprecated and will stop working in OpenVPN 2.4 and
-newer releases.
-
-OpenVPN will first try format (1), and if the file fails to parse as
-a static key file, format (2) will be used.
+Older versions (up to 2.3) supported a freeform passphrase file.
+This is no longer supported in newer versions (2.4+).
See the
.B \-\-secret
@@ -4745,12 +5008,39 @@ option which will keep OpenVPN's replay protection state
in a file so that it is not lost across restarts.
It should be emphasized that this feature is optional and that the
-passphrase/key file used with
+key file used with
.B \-\-tls\-auth
gives a peer nothing more than the power to initiate a TLS
handshake. It is not used to encrypt or authenticate any tunnel data.
.\"*********************************************************
.TP
+.B \-\-tls\-crypt keyfile
+
+Encrypt and authenticate all control channel packets with the key from
+.B keyfile.
+(See
+.B \-\-tls\-auth
+for more background.)
+
+Encrypting (and authenticating) control channel packets:
+.RS
+.IP \[bu] 2
+provides more privacy by hiding the certificate used for the TLS connection,
+.IP \[bu]
+makes it harder to identify OpenVPN traffic as such,
+.IP \[bu]
+provides "poor-man's" post-quantum security, against attackers who will never
+know the pre-shared key (i.e. no forward secrecy).
+.RE
+
+.IP
+In contrast to
+.B \-\-tls\-auth\fR,
+.B \-\-tls\-crypt
+does *not* require the user to set
+.B \-\-key\-direction\fR.
+.\"*********************************************************
+.TP
.B \-\-askpass [file]
Get certificate password from console or
.B file
@@ -4837,7 +5127,7 @@ peer certificate you will accept. This feature allows you to write a script
which will test the X509 name on a certificate and decide whether or
not it should be accepted. For a simple perl script which will test
the common name field on the certificate, see the file
-.B verify-cn
+.B verify\-cn
in the OpenVPN distribution.
See the "Environmental Variables" section below for
@@ -4848,7 +5138,7 @@ additional parameters passed as environmental variables.
Store the certificates the clients uses upon connection to this
directory. This will be done before \-\-tls\-verify is called. The
certificates will use a temporary name and will be deleted when
-the tls-verify script returns. The file name used for the certificate
+the tls\-verify script returns. The file name used for the certificate
is available via the peer_cert environment variable.
.\"*********************************************************
.TP
@@ -4892,49 +5182,6 @@ prefix will be left as-is. This automatic upcasing feature
is deprecated and will be removed in a future release.
.\"*********************************************************
.TP
-.B \-\-tls\-remote name (DEPRECATED)
-Accept connections only from a host with X509 name
-or common name equal to
-.B name.
-The remote host must also pass all other tests
-of verification.
-
-.B NOTE:
-Because tls-remote may test against a common name prefix,
-only use this option when you are using OpenVPN with a custom CA
-certificate that is under your control.
-Never use this option when your client certificates are signed by
-a third party, such as a commercial web CA.
-
-Name can also be a common name prefix, for example if you
-want a client to only accept connections to "Server-1",
-"Server-2", etc., you can simply use
-.B \-\-tls\-remote Server
-
-Using a common name prefix is a useful alternative to managing
-a CRL (Certificate Revocation List) on the client, since it allows the client
-to refuse all certificates except for those associated
-with designated servers.
-
-.B \-\-tls\-remote
-is a useful replacement for the
-.B \-\-tls\-verify
-option to verify the remote host, because
-.B \-\-tls\-remote
-works in a
-.B \-\-chroot
-environment too.
-
-.B Please also note:
-This option is now deprecated. It will be removed either in OpenVPN v2.4
-or v2.5. So please make sure you support the new X.509 name formatting
-described with the
-.B \-\-compat\-names
-option as soon as possible by updating your configurations to use
-.B \-\-verify\-x509\-name
-instead.
-.\"*********************************************************
-.TP
.B \-\-verify\-x509\-name name type
Accept connections only if a host's X.509 name is equal to
.B name.
@@ -4951,11 +5198,11 @@ Which RDN is verified as name depends on the
option. But it defaults to the common name (CN), e.g. a certificate with a
subject DN "C=KG, ST=NA, L=Bishkek, CN=Server-1" would be matched by:
-.B \-\-verify\-x509\-name 'C=KG, ST=NA, L=Bishkek, CN=Server-1'
+.B \-\-verify\-x509\-name 'C=KG, ST=NA, L=Bishkek, CN=Server\-1'
and
-.B \-\-verify\-x509\-name Server-1 name
+.B \-\-verify\-x509\-name Server\-1 name
or you could use
-.B \-\-verify\-x509\-name Server- name-prefix
+.B \-\-verify\-x509\-name Server -name-prefix
if you want a client to only accept connections to "Server-1", "Server-2", etc.
.B \-\-verify\-x509\-name
@@ -4989,7 +5236,6 @@ to save values from full cert chain. Values will be encoded
as X509_<depth>_<attribute>=<value>. Multiple
.B \-\-x509\-track
options can be defined to track multiple attributes.
-Not available with PolarSSL.
.\"*********************************************************
.TP
.B \-\-ns\-cert\-type client|server
@@ -5000,7 +5246,7 @@ designation of "client" or "server".
This is a useful security option for clients, to ensure that
the host they connect with is a designated server.
-See the easy-rsa/build-key-server script for an example
+See the easy\-rsa/build\-key\-server script for an example
of how to generate a certificate with the
.B nsCertType
field set to "server".
@@ -5143,6 +5389,13 @@ an ECDSA cipher suite will not work if you are using an RSA certificate, etc.).
Show currently available hardware-based crypto acceleration
engines supported by the OpenSSL library.
.\"*********************************************************
+.TP
+.B \-\-show\-curves
+(Standalone)
+Show all available elliptic curves to use with the
+.B \-\-ecdh\-curve
+option.
+.\"*********************************************************
.SS Generate a random key:
Used only for non-TLS static key encryption mode.
.\"*********************************************************
@@ -5253,7 +5506,7 @@ IP address and netmask using
Don't use this option unless you are also using
.B \-\-ifconfig.
-.B manual --
+.B manual \-\-
Don't set the IP address or netmask automatically.
Instead output a message
to the console telling the user to configure the
@@ -5279,7 +5532,7 @@ virtual DHCP server address. In
.B \-\-dev tun
mode, OpenVPN will cause the DHCP server to masquerade as if it were
coming from the remote endpoint. The optional offset parameter is
-an integer which is > -256 and < 256 and which defaults to 0.
+an integer which is > \-256 and < 256 and which defaults to 0.
If offset is positive, the DHCP server will masquerade as the IP
address at network address + offset.
If offset is negative, the DHCP server will masquerade as the IP
@@ -5298,13 +5551,13 @@ because it prevents routes involving the TAP-Win32 adapter from
being lost when the system goes to sleep. The default
lease time is one year.
-.B netsh --
+.B netsh \-\-
Automatically set the IP address and netmask using
the Windows command-line "netsh"
command. This method appears to work correctly on
Windows XP but not Windows 2000.
-.B ipapi --
+.B ipapi \-\-
Automatically set the IP address and netmask using the
Windows IP Helper API. This approach
does not have ideal semantics, though testing has indicated
@@ -5313,7 +5566,7 @@ it is best to leave the TCP/IP properties for the TAP-Win32
adapter in their default state, i.e. "Obtain an IP address
automatically."
-.B adaptive --
+.B adaptive \-\-
(Default) Try
.B dynamic
method initially and fail over to
@@ -5370,28 +5623,28 @@ on the TAP-Win32 adapter, and is particularly useful for
configuring an OpenVPN client to access a Samba server
across the VPN.
-.B DOMAIN name --
+.B DOMAIN name \-\-
Set Connection-specific DNS Suffix.
-.B DNS addr --
+.B DNS addr \-\-
Set primary domain name server address. Repeat
this option to set secondary DNS server addresses.
-.B WINS addr --
+.B WINS addr \-\-
Set primary WINS server address (NetBIOS over TCP/IP Name Server).
Repeat this option to set secondary WINS server addresses.
-.B NBDD addr --
+.B NBDD addr \-\-
Set primary NBDD server address (NetBIOS over TCP/IP Datagram Distribution Server)
Repeat this option
to set secondary NBDD server addresses.
-.B NTP addr --
+.B NTP addr \-\-
Set primary NTP server address (Network Time Protocol).
Repeat this option
to set secondary NTP server addresses.
-.B NBT type --
+.B NBT type \-\-
Set NetBIOS over TCP/IP Node type. Possible options:
.B 1
= b-node (broadcasts),
@@ -5498,7 +5751,7 @@ Windows explorer when OpenVPN is run on a configuration
file using the right-click explorer menu.
.\"*********************************************************
.TP
-.B \-\-service exit\-event [0|1]
+.B \-\-service exit-event [0|1]
Should be used when OpenVPN is being automatically executed by another
program in such
a context that no interaction with the user via display or keyboard
@@ -5540,7 +5793,7 @@ option. On non-Windows systems, the
command provides similar functionality.
.\"*********************************************************
.TP
-.B \-\-allow\-nonadmin [TAP-adapter]
+.B \-\-allow\-nonadmin [TAP\-adapter]
(Standalone)
Set
.B TAP-adapter
@@ -5584,12 +5837,21 @@ if certificates are stored as private objects.
If p11-kit is present on the system, the
.B provider
argument is optional; if omitted the default
-.B p11-kit-proxy.so
+.B p11\-kit\-proxy.so
module will be queried.
.B \-\-verb
option can be used BEFORE this option to produce debugging information.
.\"*********************************************************
+.SS Standalone Debug Options:
+.\"*********************************************************
+.TP
+.B \-\-show\-gateway [v6target]
+(Standalone)
+Show current IPv4 and IPv6 default gateway and interface towards the
+gateway (if the protocol in question is enabled). If an IPv6 address
+is passed as argument, the IPv6 route for this host is reported.
+.\"*********************************************************
.SS IPv6 Related Options
.\"*********************************************************
The following options exist to support IPv6 tunneling in peer-to-peer
@@ -5608,24 +5870,28 @@ if no gateway is specified.
.TP
.B \-\-route\-ipv6 ipv6addr/bits [gateway] [metric]
setup IPv6 routing in the system to send the specified IPv6 network
-into OpenVPN's ``tun'' device
+into OpenVPN's ``tun''. The gateway parameter is only used for
+IPv6 routes across ``tap'' devices, and if missing, the ``ipv6remote''
+field from
+.B \-\-ifconfig\-ipv6
+is used.
.TP
.B \-\-server\-ipv6 ipv6addr/bits
convenience-function to enable a number of IPv6 related options at
once, namely
-.B \-\-ifconfig\-ipv6, \-\-ifconfig\-ipv6\-pool, \-\-tun\-ipv6
+.B \-\-ifconfig\-ipv6, \-\-ifconfig\-ipv6\-pool
and
.B \-\-push tun\-ipv6
-Is only accepted if ``\-\-mode server'' or ``\-\-server'' is set.
+Is only accepted if ``\-\-mode server'' or ``\-\-server'' is set. Pushing of the
+.B \-\-tun\-ipv6
+directive is done for older clients which require an explicit
+``\-\-tun\-ipv6'' in their configuration.
.TP
.B \-\-ifconfig\-ipv6\-pool ipv6addr/bits
Specify an IPv6 address pool for dynamic assignment to clients. The
pool starts at
.B ipv6addr
-and increments by +1 for every new client (linear mode). The
-.B /bits
-setting controls the size of the pool. Due to implementation details,
-the pool size must be between /64 and /112.
+and matches the offset determined from the start of the IPv4 pool.
.TP
.B \-\-ifconfig\-ipv6\-push ipv6addr/bits ipv6remote
for ccd/ per-client static IPv6 interface configuration, see
@@ -6035,7 +6301,7 @@ Set on program initiation and reset on SIGHUP.
.\"*********************************************************
.TP
.B local_port
-The local port number, specified by
+The local port number or name, specified by
.B \-\-port
or
.B \-\-lport.
@@ -6047,7 +6313,7 @@ The password provided by a connecting client.
Set prior to
.B \-\-auth\-user\-pass\-verify
script execution only when the
-.B via-env
+.B via\-env
modifier is specified, and deleted from the environment
after the script returns.
.\"*********************************************************
@@ -6150,10 +6416,10 @@ documentation for
.B script_type
Prior to execution of any script, this variable is set to the type of
script being run. It can be one of the following:
-.B up, down, ipchange, route-up, tls-verify, auth-user-pass-verify,
-.B client-connect, client-disconnect,
+.B up, down, ipchange, route\-up, tls\-verify, auth\-user\-pass\-verify,
+.B client\-connect, client\-disconnect,
or
-.B learn-address.
+.B learn\-address.
Set prior to execution of any script.
.\"*********************************************************
.TP
@@ -6163,15 +6429,15 @@ The reason for exit or restart. Can be one of
(controlled by
.B \-\-inactive
option),
-.B ping-exit
+.B ping\-exit
(controlled by
.B \-\-ping\-exit
option),
-.B ping-restart
+.B ping\-restart
(controlled by
.B \-\-ping\-restart
option),
-.B connection-reset
+.B connection\-reset
(triggered on TCP connection reset),
.B error,
or
@@ -6203,9 +6469,8 @@ Set prior to execution of the
script.
.\"*********************************************************
.TP
-.B tls_digest_{n}
-Contains the certificate SHA1 fingerprint/digest hash value,
-where
+.B tls_digest_{n} / tls_digest_sha256_{n}
+Contains the certificate SHA1 / SHA256 fingerprint, where
.B n
is the verification level. Only set for TLS connections. Set prior
to execution of
@@ -6306,7 +6571,7 @@ The username provided by a connecting client.
Set prior to
.B \-\-auth\-user\-pass\-verify
script execution only when the
-.B via-env
+.B via\-env
modifier is specified.
.\"*********************************************************
.TP
@@ -6324,7 +6589,7 @@ no string remapping occurs on these field values (except for remapping
of control characters to "_").
For example, the following variables would be set on the
OpenVPN server using the sample client certificate
-in sample-keys (client.crt).
+in sample\-keys (client.crt).
Note that the verification level is 0 for the client certificate
and 1 for the CA certificate.
@@ -6347,7 +6612,8 @@ X509_1_C=KG
.\"*********************************************************
.SH INLINE FILE SUPPORT
OpenVPN allows including files in the main configuration for the
-.B \-\-ca, \-\-cert, \-\-dh, \-\-extra\-certs, \-\-key, \-\-pkcs12, \-\-secret
+.B \-\-ca, \-\-cert, \-\-dh, \-\-extra\-certs, \-\-key, \-\-pkcs12, \-\-secret,
+.B \-\-crl\-verify, \-\-http\-proxy\-user\-pass
and
.B \-\-tls\-auth
options.
diff --git a/include/Makefile.am b/include/Makefile.am
index 13dee61..498b3b5 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -10,6 +10,9 @@
#
MAINTAINERCLEANFILES = \
- $(srcdir)/Makefile.in
+ $(srcdir)/Makefile.in \
+ $(srcdir)/openvpn-plugin.h.in
-include_HEADERS = openvpn-plugin.h
+include_HEADERS = \
+ openvpn-plugin.h \
+ openvpn-msg.h
diff --git a/include/Makefile.in b/include/Makefile.in
index 05d51a7..051cf1f 100644
--- a/include/Makefile.in
+++ b/include/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.15 from Makefile.am.
+# Makefile.in generated by automake 1.13.4 from Makefile.am.
# @configure_input@
-# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -26,17 +26,7 @@
#
VPATH = @srcdir@
-am__is_gnu_make = { \
- if test -z '$(MAKELEVEL)'; then \
- false; \
- elif test -n '$(MAKE_HOST)'; then \
- true; \
- elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
- true; \
- else \
- false; \
- fi; \
-}
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
am__make_running_with_option = \
case $${target_option-} in \
?) ;; \
@@ -100,6 +90,8 @@ POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
subdir = include
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+ $(srcdir)/openvpn-plugin.h.in $(include_HEADERS)
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/ax_emptyarray.m4 \
$(top_srcdir)/m4/ax_socklen_t.m4 \
@@ -110,10 +102,8 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_emptyarray.m4 \
$(top_srcdir)/compat.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
-DIST_COMMON = $(srcdir)/Makefile.am $(include_HEADERS) \
- $(am__DIST_COMMON)
mkinstalldirs = $(install_sh) -d
-CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_HEADER = $(top_builddir)/config.h openvpn-plugin.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
AM_V_P = $(am__v_P_@AM_V@)
@@ -164,7 +154,8 @@ am__uninstall_files_from_dir = { \
}
am__installdirs = "$(DESTDIR)$(includedir)"
HEADERS = $(include_HEADERS)
-am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \
+ $(LISP)openvpn-plugin.h.in
# Read a list of newline-separated strings from the standard input,
# and print each of them once, without duplicates. Input order is
# *not* preserved.
@@ -183,7 +174,6 @@ am__define_uniq_tagged_files = \
done | $(am__uniquify_input)`
ETAGS = etags
CTAGS = ctags
-am__DIST_COMMON = $(srcdir)/Makefile.in
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
@@ -197,6 +187,7 @@ AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
+CMAKE = @CMAKE@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
@@ -231,25 +222,31 @@ LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
-LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+LZ4_CFLAGS = @LZ4_CFLAGS@
+LZ4_LIBS = @LZ4_LIBS@
LZO_CFLAGS = @LZO_CFLAGS@
LZO_LIBS = @LZO_LIBS@
MAKEINFO = @MAKEINFO@
MAN2HTML = @MAN2HTML@
MANIFEST_TOOL = @MANIFEST_TOOL@
+MBEDTLS_CFLAGS = @MBEDTLS_CFLAGS@
+MBEDTLS_LIBS = @MBEDTLS_LIBS@
MKDIR_P = @MKDIR_P@
NETSTAT = @NETSTAT@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
-OPENSSL_CRYPTO_CFLAGS = @OPENSSL_CRYPTO_CFLAGS@
-OPENSSL_CRYPTO_LIBS = @OPENSSL_CRYPTO_LIBS@
-OPENSSL_SSL_CFLAGS = @OPENSSL_SSL_CFLAGS@
-OPENSSL_SSL_LIBS = @OPENSSL_SSL_LIBS@
+OPENSSL_CFLAGS = @OPENSSL_CFLAGS@
+OPENSSL_LIBS = @OPENSSL_LIBS@
+OPENVPN_VERSION_MAJOR = @OPENVPN_VERSION_MAJOR@
+OPENVPN_VERSION_MINOR = @OPENVPN_VERSION_MINOR@
+OPENVPN_VERSION_PATCH = @OPENVPN_VERSION_PATCH@
OPTIONAL_CRYPTO_CFLAGS = @OPTIONAL_CRYPTO_CFLAGS@
OPTIONAL_CRYPTO_LIBS = @OPTIONAL_CRYPTO_LIBS@
OPTIONAL_DL_LIBS = @OPTIONAL_DL_LIBS@
+OPTIONAL_LZ4_CFLAGS = @OPTIONAL_LZ4_CFLAGS@
+OPTIONAL_LZ4_LIBS = @OPTIONAL_LZ4_LIBS@
OPTIONAL_LZO_CFLAGS = @OPTIONAL_LZO_CFLAGS@
OPTIONAL_LZO_LIBS = @OPTIONAL_LZO_LIBS@
OPTIONAL_PKCS11_HELPER_CFLAGS = @OPTIONAL_PKCS11_HELPER_CFLAGS@
@@ -275,8 +272,6 @@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
PLUGIN_AUTH_PAM_CFLAGS = @PLUGIN_AUTH_PAM_CFLAGS@
PLUGIN_AUTH_PAM_LIBS = @PLUGIN_AUTH_PAM_LIBS@
-POLARSSL_CFLAGS = @POLARSSL_CFLAGS@
-POLARSSL_LIBS = @POLARSSL_LIBS@
RANLIB = @RANLIB@
RC = @RC@
ROUTE = @ROUTE@
@@ -291,6 +286,11 @@ TAP_CFLAGS = @TAP_CFLAGS@
TAP_WIN_COMPONENT_ID = @TAP_WIN_COMPONENT_ID@
TAP_WIN_MIN_MAJOR = @TAP_WIN_MIN_MAJOR@
TAP_WIN_MIN_MINOR = @TAP_WIN_MIN_MINOR@
+TEST_CFLAGS = @TEST_CFLAGS@
+TEST_LDFLAGS = @TEST_LDFLAGS@
+VENDOR_BUILD_ROOT = @VENDOR_BUILD_ROOT@
+VENDOR_DIST_ROOT = @VENDOR_DIST_ROOT@
+VENDOR_SRC_ROOT = @VENDOR_SRC_ROOT@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
@@ -349,10 +349,15 @@ top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
MAINTAINERCLEANFILES = \
- $(srcdir)/Makefile.in
+ $(srcdir)/Makefile.in \
+ $(srcdir)/openvpn-plugin.h.in
+
+include_HEADERS = \
+ openvpn-plugin.h \
+ openvpn-msg.h
-include_HEADERS = openvpn-plugin.h
-all: all-am
+all: openvpn-plugin.h
+ $(MAKE) $(AM_MAKEFLAGS) all-am
.SUFFIXES:
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@@ -367,6 +372,7 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign include/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign include/Makefile
+.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
@@ -385,6 +391,17 @@ $(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
+openvpn-plugin.h: stamp-h2
+ @if test ! -f $@; then rm -f stamp-h2; else :; fi
+ @if test ! -f $@; then $(MAKE) $(AM_MAKEFLAGS) stamp-h2; else :; fi
+
+stamp-h2: $(srcdir)/openvpn-plugin.h.in $(top_builddir)/config.status
+ @rm -f stamp-h2
+ cd $(top_builddir) && $(SHELL) ./config.status include/openvpn-plugin.h
+
+distclean-hdr:
+ -rm -f openvpn-plugin.h stamp-h2
+
mostlyclean-libtool:
-rm -f *.lo
@@ -496,7 +513,7 @@ distdir: $(DISTFILES)
done
check-am: all-am
check: check-am
-all-am: Makefile $(HEADERS)
+all-am: Makefile $(HEADERS) openvpn-plugin.h
installdirs:
for dir in "$(DESTDIR)$(includedir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
@@ -538,7 +555,7 @@ clean-am: clean-generic clean-libtool mostlyclean-am
distclean: distclean-am
-rm -f Makefile
-distclean-am: clean-am distclean-generic distclean-tags
+distclean-am: clean-am distclean-generic distclean-hdr distclean-tags
dvi: dvi-am
@@ -598,23 +615,21 @@ ps-am:
uninstall-am: uninstall-includeHEADERS
-.MAKE: install-am install-strip
+.MAKE: all install-am install-strip
.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
clean-libtool cscopelist-am ctags ctags-am distclean \
- 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 install-exec-am install-html install-html-am \
- install-includeHEADERS install-info install-info-am \
- install-man install-pdf install-pdf-am install-ps \
- install-ps-am install-strip installcheck installcheck-am \
- installdirs maintainer-clean maintainer-clean-generic \
- mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
- ps ps-am tags tags-am uninstall uninstall-am \
- uninstall-includeHEADERS
-
-.PRECIOUS: Makefile
+ distclean-generic distclean-hdr 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 install-exec-am install-html \
+ install-html-am install-includeHEADERS install-info \
+ install-info-am install-man install-pdf install-pdf-am \
+ install-ps install-ps-am install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-generic \
+ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \
+ uninstall-am uninstall-includeHEADERS
# Tell versions [3.59,3.63) of GNU make to not export all variables.
diff --git a/include/openvpn-msg.h b/include/openvpn-msg.h
new file mode 100644
index 0000000..4c13acf
--- /dev/null
+++ b/include/openvpn-msg.h
@@ -0,0 +1,116 @@
+/*
+ * OpenVPN -- An application to securely tunnel IP networks
+ * over a single TCP/UDP port, with support for SSL/TLS-based
+ * session authentication and key exchange,
+ * packet encryption, packet authentication, and
+ * packet compression.
+ *
+ * Copyright (C) 2013 Heiko Hund <heiko.hund@sophos.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program (see the file COPYING included with this
+ * distribution); if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef OPENVPN_MSG_H_
+#define OPENVPN_MSG_H_
+
+typedef enum {
+ msg_acknowledgement,
+ msg_add_address,
+ msg_del_address,
+ msg_add_route,
+ msg_del_route,
+ msg_add_dns_cfg,
+ msg_del_dns_cfg,
+ msg_add_nbt_cfg,
+ msg_del_nbt_cfg,
+ msg_flush_neighbors,
+ msg_add_block_dns,
+ msg_del_block_dns,
+ msg_register_dns
+} message_type_t;
+
+typedef struct {
+ message_type_t type;
+ size_t size;
+ int message_id;
+} message_header_t;
+
+typedef union {
+ struct in_addr ipv4;
+ struct in6_addr ipv6;
+} inet_address_t;
+
+typedef struct {
+ int index;
+ char name[256];
+} interface_t;
+
+typedef struct {
+ message_header_t header;
+ short family;
+ inet_address_t address;
+ int prefix_len;
+ interface_t iface;
+} address_message_t;
+
+typedef struct {
+ message_header_t header;
+ short family;
+ inet_address_t prefix;
+ int prefix_len;
+ inet_address_t gateway;
+ interface_t iface;
+ int metric;
+} route_message_t;
+
+typedef struct {
+ message_header_t header;
+ interface_t iface;
+ char domains[512];
+ struct in_addr primary_ipv4;
+ struct in_addr secondary_ipv4;
+ struct in_addr6 primary_ipv6;
+ struct in_addr6 secondary_ipv6;
+} dns_cfg_message_t;
+
+typedef struct {
+ message_header_t header;
+ interface_t iface;
+ int disable_nbt;
+ int nbt_type;
+ char scope_id[256];
+ struct in_addr primary_nbns;
+ struct in_addr secondary_nbns;
+} nbt_cfg_message_t;
+
+// TODO: NTP
+
+typedef struct {
+ message_header_t header;
+ short family;
+ interface_t iface;
+} flush_neighbors_message_t;
+
+typedef struct {
+ message_header_t header;
+ int error_number;
+} ack_message_t;
+
+typedef struct {
+ message_header_t header;
+ interface_t iface;
+} block_dns_message_t;
+
+#endif
diff --git a/include/openvpn-plugin.h b/include/openvpn-plugin.h
index 5f2d407..9df3fb4 100644
--- a/include/openvpn-plugin.h
+++ b/include/openvpn-plugin.h
@@ -1,3 +1,4 @@
+/* include/openvpn-plugin.h. Generated from openvpn-plugin.h.in by configure. */
/*
* OpenVPN -- An application to securely tunnel IP networks
* over a single TCP/UDP port, with support for SSL/TLS-based
@@ -27,12 +28,12 @@
#define OPENVPN_PLUGIN_VERSION 3
-#ifdef ENABLE_SSL
-#ifdef ENABLE_CRYPTO_POLARSSL
-#include <polarssl/x509_crt.h>
+#ifdef ENABLE_CRYPTO
+#ifdef ENABLE_CRYPTO_MBEDTLS
+#include <mbedtls/x509_crt.h>
#ifndef __OPENVPN_X509_CERT_T_DECLARED
#define __OPENVPN_X509_CERT_T_DECLARED
-typedef x509_crt openvpn_x509_cert_t;
+typedef mbedtls_x509_crt openvpn_x509_cert_t;
#endif
#else
#include <openssl/x509.h>
@@ -49,6 +50,13 @@ typedef X509 openvpn_x509_cert_t;
extern "C" {
#endif
+/* Provide some basic version information to plug-ins at OpenVPN compile time
+ * This is will not be the complete version
+ */
+#define OPENVPN_VERSION_MAJOR 2
+#define OPENVPN_VERSION_MINOR 4
+#define OPENVPN_VERSION_PATCH "_beta1"
+
/*
* Plug-in types. These types correspond to the set of script callbacks
* supported by OpenVPN.
@@ -147,7 +155,7 @@ typedef void *openvpn_plugin_handle_t;
/*
* For Windows (needs to be modified for MSVC)
*/
-#if defined(WIN32) && !defined(OPENVPN_PLUGIN_H)
+#if defined(_WIN32) && !defined(OPENVPN_PLUGIN_H)
# define OPENVPN_EXPORT __declspec(dllexport)
#else
# define OPENVPN_EXPORT
@@ -208,8 +216,11 @@ struct openvpn_plugin_string_list
* which identifies the SSL implementation OpenVPN is compiled
* against.
*
+ * 3 Added ovpn_version, ovpn_version_major, ovpn_version_minor
+ * and ovpn_version_patch to provide the runtime version of
+ * OpenVPN to plug-ins.
*/
-#define OPENVPN_PLUGINv3_STRUCTVER 2
+#define OPENVPN_PLUGINv3_STRUCTVER 3
/**
* Definitions needed for the plug-in callback functions.
@@ -246,7 +257,7 @@ typedef void (*plugin_vlog_t) (openvpn_plugin_log_flags_t flags,
const char *format,
va_list arglist) _ovpn_chk_fmt(3, 0);
-#undef _ovpn_chk_fmt
+/* #undef _ovpn_chk_fmt */
/**
* Used by the openvpn_plugin_open_v3() function to pass callback
@@ -267,13 +278,13 @@ struct openvpn_plugin_callbacks
/**
* Used by the openvpn_plugin_open_v3() function to indicate to the
* plug-in what kind of SSL implementation OpenVPN uses. This is
- * to avoid SEGV issues when OpenVPN is complied against PolarSSL
+ * to avoid SEGV issues when OpenVPN is complied against mbed TLS
* and the plug-in against OpenSSL.
*/
typedef enum {
SSLAPI_NONE,
SSLAPI_OPENSSL,
- SSLAPI_POLARSSL
+ SSLAPI_MBEDTLS
} ovpnSSLAPI;
/**
@@ -304,6 +315,10 @@ struct openvpn_plugin_args_open_in
const char ** const envp;
struct openvpn_plugin_callbacks *callbacks;
const ovpnSSLAPI ssl_api;
+ const char *ovpn_version;
+ const unsigned int ovpn_version_major;
+ const unsigned int ovpn_version_minor;
+ const char * const ovpn_version_patch;
};
@@ -358,9 +373,9 @@ struct openvpn_plugin_args_open_return
* *per_client_context : the per-client context pointer which was returned by
* openvpn_plugin_client_constructor_v1, if defined.
*
- * current_cert_depth : Certificate depth of the certificate being passed over (only if compiled with ENABLE_SSL defined)
+ * current_cert_depth : Certificate depth of the certificate being passed over (only if compiled with ENABLE_CRYPTO defined)
*
- * *current_cert : X509 Certificate object received from the client (only if compiled with ENABLE_SSL defined)
+ * *current_cert : X509 Certificate object received from the client (only if compiled with ENABLE_CRYPTO defined)
*
*/
struct openvpn_plugin_args_func_in
@@ -370,7 +385,7 @@ struct openvpn_plugin_args_func_in
const char ** const envp;
openvpn_plugin_handle_t handle;
void *per_client_context;
-#ifdef ENABLE_SSL
+#ifdef ENABLE_CRYPTO
int current_cert_depth;
openvpn_x509_cert_t *current_cert;
#else
diff --git a/include/openvpn-plugin.h.in b/include/openvpn-plugin.h.in
new file mode 100644
index 0000000..34ad18b
--- /dev/null
+++ b/include/openvpn-plugin.h.in
@@ -0,0 +1,827 @@
+/*
+ * OpenVPN -- An application to securely tunnel IP networks
+ * over a single TCP/UDP port, with support for SSL/TLS-based
+ * session authentication and key exchange,
+ * packet encryption, packet authentication, and
+ * packet compression.
+ *
+ * Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program (see the file COPYING included with this
+ * distribution); if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef OPENVPN_PLUGIN_H_
+#define OPENVPN_PLUGIN_H_
+
+#define OPENVPN_PLUGIN_VERSION 3
+
+#ifdef ENABLE_CRYPTO
+#ifdef ENABLE_CRYPTO_MBEDTLS
+#include <mbedtls/x509_crt.h>
+#ifndef __OPENVPN_X509_CERT_T_DECLARED
+#define __OPENVPN_X509_CERT_T_DECLARED
+typedef mbedtls_x509_crt openvpn_x509_cert_t;
+#endif
+#else
+#include <openssl/x509.h>
+#ifndef __OPENVPN_X509_CERT_T_DECLARED
+#define __OPENVPN_X509_CERT_T_DECLARED
+typedef X509 openvpn_x509_cert_t;
+#endif
+#endif
+#endif
+
+#include <stdarg.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Provide some basic version information to plug-ins at OpenVPN compile time
+ * This is will not be the complete version
+ */
+#define OPENVPN_VERSION_MAJOR @OPENVPN_VERSION_MAJOR@
+#define OPENVPN_VERSION_MINOR @OPENVPN_VERSION_MINOR@
+#define OPENVPN_VERSION_PATCH "@OPENVPN_VERSION_PATCH@"
+
+/*
+ * Plug-in types. These types correspond to the set of script callbacks
+ * supported by OpenVPN.
+ *
+ * This is the general call sequence to expect when running in server mode:
+ *
+ * Initial Server Startup:
+ *
+ * FUNC: openvpn_plugin_open_v1
+ * FUNC: openvpn_plugin_client_constructor_v1 (this is the top-level "generic"
+ * client template)
+ * FUNC: openvpn_plugin_func_v1 OPENVPN_PLUGIN_UP
+ * FUNC: openvpn_plugin_func_v1 OPENVPN_PLUGIN_ROUTE_UP
+ *
+ * New Client Connection:
+ *
+ * FUNC: openvpn_plugin_client_constructor_v1
+ * FUNC: openvpn_plugin_func_v1 OPENVPN_PLUGIN_ENABLE_PF
+ * FUNC: openvpn_plugin_func_v1 OPENVPN_PLUGIN_TLS_VERIFY (called once for every cert
+ * in the server chain)
+ * FUNC: openvpn_plugin_func_v1 OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY
+ * FUNC: openvpn_plugin_func_v1 OPENVPN_PLUGIN_TLS_FINAL
+ * FUNC: openvpn_plugin_func_v1 OPENVPN_PLUGIN_IPCHANGE
+ *
+ * [If OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY returned OPENVPN_PLUGIN_FUNC_DEFERRED,
+ * we don't proceed until authentication is verified via auth_control_file]
+ *
+ * FUNC: openvpn_plugin_func_v1 OPENVPN_PLUGIN_CLIENT_CONNECT_V2
+ * FUNC: openvpn_plugin_func_v1 OPENVPN_PLUGIN_LEARN_ADDRESS
+ *
+ * [Client session ensues]
+ *
+ * For each "TLS soft reset", according to reneg-sec option (or similar):
+ *
+ * FUNC: openvpn_plugin_func_v1 OPENVPN_PLUGIN_ENABLE_PF
+ *
+ * FUNC: openvpn_plugin_func_v1 OPENVPN_PLUGIN_TLS_VERIFY (called once for every cert
+ * in the server chain)
+ * FUNC: openvpn_plugin_func_v1 OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY
+ * FUNC: openvpn_plugin_func_v1 OPENVPN_PLUGIN_TLS_FINAL
+ *
+ * [If OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY returned OPENVPN_PLUGIN_FUNC_DEFERRED,
+ * we expect that authentication is verified via auth_control_file within
+ * the number of seconds defined by the "hand-window" option. Data channel traffic
+ * will continue to flow uninterrupted during this period.]
+ *
+ * [Client session continues]
+ *
+ * FUNC: openvpn_plugin_func_v1 OPENVPN_PLUGIN_CLIENT_DISCONNECT
+ * FUNC: openvpn_plugin_client_destructor_v1
+ *
+ * [ some time may pass ]
+ *
+ * FUNC: openvpn_plugin_func_v1 OPENVPN_PLUGIN_LEARN_ADDRESS (this coincides with a
+ * lazy free of initial
+ * learned addr object)
+ * Server Shutdown:
+ *
+ * FUNC: openvpn_plugin_func_v1 OPENVPN_PLUGIN_DOWN
+ * FUNC: openvpn_plugin_client_destructor_v1 (top-level "generic" client)
+ * FUNC: openvpn_plugin_close_v1
+ */
+#define OPENVPN_PLUGIN_UP 0
+#define OPENVPN_PLUGIN_DOWN 1
+#define OPENVPN_PLUGIN_ROUTE_UP 2
+#define OPENVPN_PLUGIN_IPCHANGE 3
+#define OPENVPN_PLUGIN_TLS_VERIFY 4
+#define OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY 5
+#define OPENVPN_PLUGIN_CLIENT_CONNECT 6
+#define OPENVPN_PLUGIN_CLIENT_DISCONNECT 7
+#define OPENVPN_PLUGIN_LEARN_ADDRESS 8
+#define OPENVPN_PLUGIN_CLIENT_CONNECT_V2 9
+#define OPENVPN_PLUGIN_TLS_FINAL 10
+#define OPENVPN_PLUGIN_ENABLE_PF 11
+#define OPENVPN_PLUGIN_ROUTE_PREDOWN 12
+#define OPENVPN_PLUGIN_N 13
+
+/*
+ * Build a mask out of a set of plug-in types.
+ */
+#define OPENVPN_PLUGIN_MASK(x) (1<<(x))
+
+/*
+ * A pointer to a plugin-defined object which contains
+ * the object state.
+ */
+typedef void *openvpn_plugin_handle_t;
+
+/*
+ * Return value for openvpn_plugin_func_v1 function
+ */
+#define OPENVPN_PLUGIN_FUNC_SUCCESS 0
+#define OPENVPN_PLUGIN_FUNC_ERROR 1
+#define OPENVPN_PLUGIN_FUNC_DEFERRED 2
+
+/*
+ * For Windows (needs to be modified for MSVC)
+ */
+#if defined(_WIN32) && !defined(OPENVPN_PLUGIN_H)
+# define OPENVPN_EXPORT __declspec(dllexport)
+#else
+# define OPENVPN_EXPORT
+#endif
+
+/*
+ * If OPENVPN_PLUGIN_H is defined, we know that we are being
+ * included in an OpenVPN compile, rather than a plugin compile.
+ */
+#ifdef OPENVPN_PLUGIN_H
+
+/*
+ * We are compiling OpenVPN.
+ */
+#define OPENVPN_PLUGIN_DEF typedef
+#define OPENVPN_PLUGIN_FUNC(name) (*name)
+
+#else
+
+/*
+ * We are compiling plugin.
+ */
+#define OPENVPN_PLUGIN_DEF OPENVPN_EXPORT
+#define OPENVPN_PLUGIN_FUNC(name) name
+
+#endif
+
+/*
+ * Used by openvpn_plugin_func to return structured
+ * data. The plugin should allocate all structure
+ * instances, name strings, and value strings with
+ * malloc, since OpenVPN will assume that it
+ * can free the list by calling free() over the same.
+ */
+struct openvpn_plugin_string_list
+{
+ struct openvpn_plugin_string_list *next;
+ char *name;
+ char *value;
+};
+
+
+/* openvpn_plugin_{open,func}_v3() related structs */
+
+/* Defines version of the v3 plugin argument structs
+ *
+ * Whenever one or more of these structs are modified, this constant
+ * must be updated. A changelog should be appended in this comment
+ * as well, to make it easier to see what information is available
+ * in the different versions.
+ *
+ * Version Comment
+ * 1 Initial plugin v3 structures providing the same API as
+ * the v2 plugin interface, X509 certificate information +
+ * a logging API for plug-ins.
+ *
+ * 2 Added ssl_api member in struct openvpn_plugin_args_open_in
+ * which identifies the SSL implementation OpenVPN is compiled
+ * against.
+ *
+ * 3 Added ovpn_version, ovpn_version_major, ovpn_version_minor
+ * and ovpn_version_patch to provide the runtime version of
+ * OpenVPN to plug-ins.
+ */
+#define OPENVPN_PLUGINv3_STRUCTVER 3
+
+/**
+ * Definitions needed for the plug-in callback functions.
+ */
+typedef enum
+{
+ PLOG_ERR = (1 << 0), /* Error condition message */
+ PLOG_WARN = (1 << 1), /* General warning message */
+ PLOG_NOTE = (1 << 2), /* Informational message */
+ PLOG_DEBUG = (1 << 3), /* Debug message, displayed if verb >= 7 */
+
+ PLOG_ERRNO = (1 << 8), /* Add error description to message */
+ PLOG_NOMUTE = (1 << 9), /* Mute setting does not apply for message */
+
+} openvpn_plugin_log_flags_t;
+
+
+#ifdef __GNUC__
+#if __USE_MINGW_ANSI_STDIO
+# define _ovpn_chk_fmt(a, b) __attribute__ ((format(gnu_printf, (a), (b))))
+#else
+# define _ovpn_chk_fmt(a, b) __attribute__ ((format(__printf__, (a), (b))))
+#endif
+#else
+# define _ovpn_chk_fmt(a, b)
+#endif
+
+typedef void (*plugin_log_t) (openvpn_plugin_log_flags_t flags,
+ const char *plugin_name,
+ const char *format, ...) _ovpn_chk_fmt(3, 4);
+
+typedef void (*plugin_vlog_t) (openvpn_plugin_log_flags_t flags,
+ const char *plugin_name,
+ const char *format,
+ va_list arglist) _ovpn_chk_fmt(3, 0);
+
+#undef _ovpn_chk_fmt
+
+/**
+ * Used by the openvpn_plugin_open_v3() function to pass callback
+ * function pointers to the plug-in.
+ *
+ * plugin_log
+ * plugin_vlog : Use these functions to add information to the OpenVPN log file.
+ * Messages will only be displayed if the plugin_name parameter
+ * is set. PLOG_DEBUG messages will only be displayed with plug-in
+ * debug log verbosity (at the time of writing that's verb >= 7).
+ */
+struct openvpn_plugin_callbacks
+{
+ plugin_log_t plugin_log;
+ plugin_vlog_t plugin_vlog;
+};
+
+/**
+ * Used by the openvpn_plugin_open_v3() function to indicate to the
+ * plug-in what kind of SSL implementation OpenVPN uses. This is
+ * to avoid SEGV issues when OpenVPN is complied against mbed TLS
+ * and the plug-in against OpenSSL.
+ */
+typedef enum {
+ SSLAPI_NONE,
+ SSLAPI_OPENSSL,
+ SSLAPI_MBEDTLS
+} ovpnSSLAPI;
+
+/**
+ * Arguments used to transport variables to the plug-in.
+ * The struct openvpn_plugin_args_open_in is only used
+ * by the openvpn_plugin_open_v3() function.
+ *
+ * STRUCT MEMBERS
+ *
+ * type_mask : Set by OpenVPN to the logical OR of all script
+ * types which this version of OpenVPN supports.
+ *
+ * argv : a NULL-terminated array of options provided to the OpenVPN
+ * "plug-in" directive. argv[0] is the dynamic library pathname.
+ *
+ * envp : a NULL-terminated array of OpenVPN-set environmental
+ * variables in "name=value" format. Note that for security reasons,
+ * these variables are not actually written to the "official"
+ * environmental variable store of the process.
+ *
+ * callbacks : a pointer to the plug-in callback function struct.
+ *
+ */
+struct openvpn_plugin_args_open_in
+{
+ const int type_mask;
+ const char ** const argv;
+ const char ** const envp;
+ struct openvpn_plugin_callbacks *callbacks;
+ const ovpnSSLAPI ssl_api;
+ const char *ovpn_version;
+ const unsigned int ovpn_version_major;
+ const unsigned int ovpn_version_minor;
+ const char * const ovpn_version_patch;
+};
+
+
+/**
+ * Arguments used to transport variables from the plug-in back
+ * to the OpenVPN process. The struct openvpn_plugin_args_open_return
+ * is only used by the openvpn_plugin_open_v3() function.
+ *
+ * STRUCT MEMBERS
+ *
+ * *type_mask : The plug-in should set this value to the logical OR of all script
+ * types which the plug-in wants to intercept. For example, if the
+ * script wants to intercept the client-connect and client-disconnect
+ * script types:
+ *
+ * *type_mask = OPENVPN_PLUGIN_MASK(OPENVPN_PLUGIN_CLIENT_CONNECT)
+ * | OPENVPN_PLUGIN_MASK(OPENVPN_PLUGIN_CLIENT_DISCONNECT)
+ *
+ * *handle : Pointer to a global plug-in context, created by the plug-in. This pointer
+ * is passed on to the other plug-in calls.
+ *
+ * return_list : used to return data back to OpenVPN.
+ *
+ */
+struct openvpn_plugin_args_open_return
+{
+ int type_mask;
+ openvpn_plugin_handle_t *handle;
+ struct openvpn_plugin_string_list **return_list;
+};
+
+/**
+ * Arguments used to transport variables to and from the
+ * plug-in. The struct openvpn_plugin_args_func is only used
+ * by the openvpn_plugin_func_v3() function.
+ *
+ * STRUCT MEMBERS:
+ *
+ * type : one of the PLUGIN_x types.
+ *
+ * argv : a NULL-terminated array of "command line" options which
+ * would normally be passed to the script. argv[0] is the dynamic
+ * library pathname.
+ *
+ * envp : a NULL-terminated array of OpenVPN-set environmental
+ * variables in "name=value" format. Note that for security reasons,
+ * these variables are not actually written to the "official"
+ * environmental variable store of the process.
+ *
+ * *handle : Pointer to a global plug-in context, created by the plug-in's openvpn_plugin_open_v3().
+ *
+ * *per_client_context : the per-client context pointer which was returned by
+ * openvpn_plugin_client_constructor_v1, if defined.
+ *
+ * current_cert_depth : Certificate depth of the certificate being passed over (only if compiled with ENABLE_CRYPTO defined)
+ *
+ * *current_cert : X509 Certificate object received from the client (only if compiled with ENABLE_CRYPTO defined)
+ *
+ */
+struct openvpn_plugin_args_func_in
+{
+ const int type;
+ const char ** const argv;
+ const char ** const envp;
+ openvpn_plugin_handle_t handle;
+ void *per_client_context;
+#ifdef ENABLE_CRYPTO
+ int current_cert_depth;
+ openvpn_x509_cert_t *current_cert;
+#else
+ int __current_cert_depth_disabled; /* Unused, for compatibility purposes only */
+ void *__current_cert_disabled; /* Unused, for compatibility purposes only */
+#endif
+};
+
+
+/**
+ * Arguments used to transport variables to and from the
+ * plug-in. The struct openvpn_plugin_args_func is only used
+ * by the openvpn_plugin_func_v3() function.
+ *
+ * STRUCT MEMBERS:
+ *
+ * return_list : used to return data back to OpenVPN for further processing/usage by
+ * the OpenVPN executable.
+ *
+ */
+struct openvpn_plugin_args_func_return
+{
+ struct openvpn_plugin_string_list **return_list;
+};
+
+/*
+ * Multiple plugin modules can be cascaded, and modules can be
+ * used in tandem with scripts. The order of operation is that
+ * the module func() functions are called in the order that
+ * the modules were specified in the config file. If a script
+ * was specified as well, it will be called last. If the
+ * return code of the module/script controls an authentication
+ * function (such as tls-verify or auth-user-pass-verify), then
+ * every module and script must return success (0) in order for
+ * the connection to be authenticated.
+ *
+ * Notes:
+ *
+ * Plugins which use a privilege-separation model (by forking in
+ * their initialization function before the main OpenVPN process
+ * downgrades root privileges and/or executes a chroot) must
+ * daemonize after a fork if the "daemon" environmental variable is
+ * set. In addition, if the "daemon_log_redirect" variable is set,
+ * the plugin should preserve stdout/stderr across the daemon()
+ * syscall. See the daemonize() function in plugin/auth-pam/auth-pam.c
+ * for an example.
+ */
+
+/*
+ * Prototypes for functions which OpenVPN plug-ins must define.
+ */
+
+/*
+ * FUNCTION: openvpn_plugin_open_v2
+ *
+ * REQUIRED: YES
+ *
+ * Called on initial plug-in load. OpenVPN will preserve plug-in state
+ * across SIGUSR1 restarts but not across SIGHUP restarts. A SIGHUP reset
+ * will cause the plugin to be closed and reopened.
+ *
+ * ARGUMENTS
+ *
+ * *type_mask : Set by OpenVPN to the logical OR of all script
+ * types which this version of OpenVPN supports. The plug-in
+ * should set this value to the logical OR of all script types
+ * which the plug-in wants to intercept. For example, if the
+ * script wants to intercept the client-connect and
+ * client-disconnect script types:
+ *
+ * *type_mask = OPENVPN_PLUGIN_MASK(OPENVPN_PLUGIN_CLIENT_CONNECT)
+ * | OPENVPN_PLUGIN_MASK(OPENVPN_PLUGIN_CLIENT_DISCONNECT)
+ *
+ * argv : a NULL-terminated array of options provided to the OpenVPN
+ * "plug-in" directive. argv[0] is the dynamic library pathname.
+ *
+ * envp : a NULL-terminated array of OpenVPN-set environmental
+ * variables in "name=value" format. Note that for security reasons,
+ * these variables are not actually written to the "official"
+ * environmental variable store of the process.
+ *
+ * return_list : used to return data back to OpenVPN.
+ *
+ * RETURN VALUE
+ *
+ * An openvpn_plugin_handle_t value on success, NULL on failure
+ */
+OPENVPN_PLUGIN_DEF openvpn_plugin_handle_t OPENVPN_PLUGIN_FUNC(openvpn_plugin_open_v2)
+ (unsigned int *type_mask,
+ const char *argv[],
+ const char *envp[],
+ struct openvpn_plugin_string_list **return_list);
+
+/*
+ * FUNCTION: openvpn_plugin_func_v2
+ *
+ * Called to perform the work of a given script type.
+ *
+ * REQUIRED: YES
+ *
+ * ARGUMENTS
+ *
+ * handle : the openvpn_plugin_handle_t value which was returned by
+ * openvpn_plugin_open.
+ *
+ * type : one of the PLUGIN_x types
+ *
+ * argv : a NULL-terminated array of "command line" options which
+ * would normally be passed to the script. argv[0] is the dynamic
+ * library pathname.
+ *
+ * envp : a NULL-terminated array of OpenVPN-set environmental
+ * variables in "name=value" format. Note that for security reasons,
+ * these variables are not actually written to the "official"
+ * environmental variable store of the process.
+ *
+ * per_client_context : the per-client context pointer which was returned by
+ * openvpn_plugin_client_constructor_v1, if defined.
+ *
+ * return_list : used to return data back to OpenVPN.
+ *
+ * RETURN VALUE
+ *
+ * OPENVPN_PLUGIN_FUNC_SUCCESS on success, OPENVPN_PLUGIN_FUNC_ERROR on failure
+ *
+ * In addition, OPENVPN_PLUGIN_FUNC_DEFERRED may be returned by
+ * OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY. This enables asynchronous
+ * authentication where the plugin (or one of its agents) may indicate
+ * authentication success/failure some number of seconds after the return
+ * of the OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY handler by writing a single
+ * char to the file named by auth_control_file in the environmental variable
+ * list (envp).
+ *
+ * first char of auth_control_file:
+ * '0' -- indicates auth failure
+ * '1' -- indicates auth success
+ *
+ * OpenVPN will delete the auth_control_file after it goes out of scope.
+ *
+ * If an OPENVPN_PLUGIN_ENABLE_PF handler is defined and returns success
+ * for a particular client instance, packet filtering will be enabled for that
+ * instance. OpenVPN will then attempt to read the packet filter configuration
+ * from the temporary file named by the environmental variable pf_file. This
+ * file may be generated asynchronously and may be dynamically updated during the
+ * client session, however the client will be blocked from sending or receiving
+ * VPN tunnel packets until the packet filter file has been generated. OpenVPN
+ * will periodically test the packet filter file over the life of the client
+ * instance and reload when modified. OpenVPN will delete the packet filter file
+ * when the client instance goes out of scope.
+ *
+ * Packet filter file grammar:
+ *
+ * [CLIENTS DROP|ACCEPT]
+ * {+|-}common_name1
+ * {+|-}common_name2
+ * . . .
+ * [SUBNETS DROP|ACCEPT]
+ * {+|-}subnet1
+ * {+|-}subnet2
+ * . . .
+ * [END]
+ *
+ * Subnet: IP-ADDRESS | IP-ADDRESS/NUM_NETWORK_BITS
+ *
+ * CLIENTS refers to the set of clients (by their common-name) which
+ * this instance is allowed ('+') to connect to, or is excluded ('-')
+ * from connecting to. Note that in the case of client-to-client
+ * connections, such communication must be allowed by the packet filter
+ * configuration files of both clients.
+ *
+ * SUBNETS refers to IP addresses or IP address subnets which this
+ * instance may connect to ('+') or is excluded ('-') from connecting
+ * to.
+ *
+ * DROP or ACCEPT defines default policy when there is no explicit match
+ * for a common-name or subnet. The [END] tag must exist. A special
+ * purpose tag called [KILL] will immediately kill the client instance.
+ * A given client or subnet rule applies to both incoming and outgoing
+ * packets.
+ *
+ * See plugin/defer/simple.c for an example on using asynchronous
+ * authentication and client-specific packet filtering.
+ */
+OPENVPN_PLUGIN_DEF int OPENVPN_PLUGIN_FUNC(openvpn_plugin_func_v2)
+ (openvpn_plugin_handle_t handle,
+ const int type,
+ const char *argv[],
+ const char *envp[],
+ void *per_client_context,
+ struct openvpn_plugin_string_list **return_list);
+
+
+/*
+ * FUNCTION: openvpn_plugin_open_v3
+ *
+ * REQUIRED: YES
+ *
+ * Called on initial plug-in load. OpenVPN will preserve plug-in state
+ * across SIGUSR1 restarts but not across SIGHUP restarts. A SIGHUP reset
+ * will cause the plugin to be closed and reopened.
+ *
+ * ARGUMENTS
+ *
+ * version : fixed value, defines the API version of the OpenVPN plug-in API. The plug-in
+ * should validate that this value is matching the OPENVPN_PLUGINv3_STRUCTVER
+ * value.
+ *
+ * arguments : Structure with all arguments available to the plug-in.
+ *
+ * retptr : used to return data back to OpenVPN.
+ *
+ * RETURN VALUE
+ *
+ * OPENVPN_PLUGIN_FUNC_SUCCESS on success, OPENVPN_PLUGIN_FUNC_ERROR on failure
+ */
+OPENVPN_PLUGIN_DEF int OPENVPN_PLUGIN_FUNC(openvpn_plugin_open_v3)
+ (const int version,
+ struct openvpn_plugin_args_open_in const *arguments,
+ struct openvpn_plugin_args_open_return *retptr);
+
+/*
+ * FUNCTION: openvpn_plugin_func_v3
+ *
+ * Called to perform the work of a given script type.
+ *
+ * REQUIRED: YES
+ *
+ * ARGUMENTS
+ *
+ * version : fixed value, defines the API version of the OpenVPN plug-in API. The plug-in
+ * should validate that this value is matching the OPENVPN_PLUGIN_VERSION value.
+ *
+ * handle : the openvpn_plugin_handle_t value which was returned by
+ * openvpn_plugin_open.
+ *
+ * return_list : used to return data back to OpenVPN.
+ *
+ * RETURN VALUE
+ *
+ * OPENVPN_PLUGIN_FUNC_SUCCESS on success, OPENVPN_PLUGIN_FUNC_ERROR on failure
+ *
+ * In addition, OPENVPN_PLUGIN_FUNC_DEFERRED may be returned by
+ * OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY. This enables asynchronous
+ * authentication where the plugin (or one of its agents) may indicate
+ * authentication success/failure some number of seconds after the return
+ * of the OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY handler by writing a single
+ * char to the file named by auth_control_file in the environmental variable
+ * list (envp).
+ *
+ * first char of auth_control_file:
+ * '0' -- indicates auth failure
+ * '1' -- indicates auth success
+ *
+ * OpenVPN will delete the auth_control_file after it goes out of scope.
+ *
+ * If an OPENVPN_PLUGIN_ENABLE_PF handler is defined and returns success
+ * for a particular client instance, packet filtering will be enabled for that
+ * instance. OpenVPN will then attempt to read the packet filter configuration
+ * from the temporary file named by the environmental variable pf_file. This
+ * file may be generated asynchronously and may be dynamically updated during the
+ * client session, however the client will be blocked from sending or receiving
+ * VPN tunnel packets until the packet filter file has been generated. OpenVPN
+ * will periodically test the packet filter file over the life of the client
+ * instance and reload when modified. OpenVPN will delete the packet filter file
+ * when the client instance goes out of scope.
+ *
+ * Packet filter file grammar:
+ *
+ * [CLIENTS DROP|ACCEPT]
+ * {+|-}common_name1
+ * {+|-}common_name2
+ * . . .
+ * [SUBNETS DROP|ACCEPT]
+ * {+|-}subnet1
+ * {+|-}subnet2
+ * . . .
+ * [END]
+ *
+ * Subnet: IP-ADDRESS | IP-ADDRESS/NUM_NETWORK_BITS
+ *
+ * CLIENTS refers to the set of clients (by their common-name) which
+ * this instance is allowed ('+') to connect to, or is excluded ('-')
+ * from connecting to. Note that in the case of client-to-client
+ * connections, such communication must be allowed by the packet filter
+ * configuration files of both clients.
+ *
+ * SUBNETS refers to IP addresses or IP address subnets which this
+ * instance may connect to ('+') or is excluded ('-') from connecting
+ * to.
+ *
+ * DROP or ACCEPT defines default policy when there is no explicit match
+ * for a common-name or subnet. The [END] tag must exist. A special
+ * purpose tag called [KILL] will immediately kill the client instance.
+ * A given client or subnet rule applies to both incoming and outgoing
+ * packets.
+ *
+ * See plugin/defer/simple.c for an example on using asynchronous
+ * authentication and client-specific packet filtering.
+ */
+OPENVPN_PLUGIN_DEF int OPENVPN_PLUGIN_FUNC(openvpn_plugin_func_v3)
+ (const int version,
+ struct openvpn_plugin_args_func_in const *arguments,
+ struct openvpn_plugin_args_func_return *retptr);
+
+/*
+ * FUNCTION: openvpn_plugin_close_v1
+ *
+ * REQUIRED: YES
+ *
+ * ARGUMENTS
+ *
+ * handle : the openvpn_plugin_handle_t value which was returned by
+ * openvpn_plugin_open.
+ *
+ * Called immediately prior to plug-in unload.
+ */
+OPENVPN_PLUGIN_DEF void OPENVPN_PLUGIN_FUNC(openvpn_plugin_close_v1)
+ (openvpn_plugin_handle_t handle);
+
+/*
+ * FUNCTION: openvpn_plugin_abort_v1
+ *
+ * REQUIRED: NO
+ *
+ * ARGUMENTS
+ *
+ * handle : the openvpn_plugin_handle_t value which was returned by
+ * openvpn_plugin_open.
+ *
+ * Called when OpenVPN is in the process of aborting due to a fatal error.
+ * Will only be called on an open context returned by a prior successful
+ * openvpn_plugin_open callback.
+ */
+OPENVPN_PLUGIN_DEF void OPENVPN_PLUGIN_FUNC(openvpn_plugin_abort_v1)
+ (openvpn_plugin_handle_t handle);
+
+/*
+ * FUNCTION: openvpn_plugin_client_constructor_v1
+ *
+ * Called to allocate a per-client memory region, which
+ * is then passed to the openvpn_plugin_func_v2 function.
+ * This function is called every time the OpenVPN server
+ * constructs a client instance object, which normally
+ * occurs when a session-initiating packet is received
+ * by a new client, even before the client has authenticated.
+ *
+ * This function should allocate the private memory needed
+ * by the plugin to track individual OpenVPN clients, and
+ * return a void * to this memory region.
+ *
+ * REQUIRED: NO
+ *
+ * ARGUMENTS
+ *
+ * handle : the openvpn_plugin_handle_t value which was returned by
+ * openvpn_plugin_open.
+ *
+ * RETURN VALUE
+ *
+ * void * pointer to plugin's private per-client memory region, or NULL
+ * if no memory region is required.
+ */
+OPENVPN_PLUGIN_DEF void * OPENVPN_PLUGIN_FUNC(openvpn_plugin_client_constructor_v1)
+ (openvpn_plugin_handle_t handle);
+
+/*
+ * FUNCTION: openvpn_plugin_client_destructor_v1
+ *
+ * This function is called on client instance object destruction.
+ *
+ * REQUIRED: NO
+ *
+ * ARGUMENTS
+ *
+ * handle : the openvpn_plugin_handle_t value which was returned by
+ * openvpn_plugin_open.
+ *
+ * per_client_context : the per-client context pointer which was returned by
+ * openvpn_plugin_client_constructor_v1, if defined.
+ */
+OPENVPN_PLUGIN_DEF void OPENVPN_PLUGIN_FUNC(openvpn_plugin_client_destructor_v1)
+ (openvpn_plugin_handle_t handle, void *per_client_context);
+
+/*
+ * FUNCTION: openvpn_plugin_select_initialization_point_v1
+ *
+ * Several different points exist in OpenVPN's initialization sequence where
+ * the openvpn_plugin_open function can be called. While the default is
+ * OPENVPN_PLUGIN_INIT_PRE_DAEMON, this function can be used to select a
+ * different initialization point. For example, if your plugin needs to
+ * return configuration parameters to OpenVPN, use
+ * OPENVPN_PLUGIN_INIT_PRE_CONFIG_PARSE.
+ *
+ * REQUIRED: NO
+ *
+ * RETURN VALUE:
+ *
+ * An OPENVPN_PLUGIN_INIT_x value.
+ */
+#define OPENVPN_PLUGIN_INIT_PRE_CONFIG_PARSE 1
+#define OPENVPN_PLUGIN_INIT_PRE_DAEMON 2 /* default */
+#define OPENVPN_PLUGIN_INIT_POST_DAEMON 3
+#define OPENVPN_PLUGIN_INIT_POST_UID_CHANGE 4
+
+OPENVPN_PLUGIN_DEF int OPENVPN_PLUGIN_FUNC(openvpn_plugin_select_initialization_point_v1)
+ (void);
+
+/*
+ * FUNCTION: openvpn_plugin_min_version_required_v1
+ *
+ * This function is called by OpenVPN to query the minimum
+ plugin interface version number required by the plugin.
+ *
+ * REQUIRED: NO
+ *
+ * RETURN VALUE
+ *
+ * The minimum OpenVPN plugin interface version number necessary to support
+ * this plugin.
+ */
+OPENVPN_PLUGIN_DEF int OPENVPN_PLUGIN_FUNC(openvpn_plugin_min_version_required_v1)
+ (void);
+
+/*
+ * Deprecated functions which are still supported for backward compatibility.
+ */
+
+OPENVPN_PLUGIN_DEF openvpn_plugin_handle_t OPENVPN_PLUGIN_FUNC(openvpn_plugin_open_v1)
+ (unsigned int *type_mask,
+ const char *argv[],
+ const char *envp[]);
+
+OPENVPN_PLUGIN_DEF int OPENVPN_PLUGIN_FUNC(openvpn_plugin_func_v1)
+ (openvpn_plugin_handle_t handle, const int type, const char *argv[], const char *envp[]);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* OPENVPN_PLUGIN_H_ */
diff --git a/ltmain.sh b/ltmain.sh
index 0f0a2da..63ae69d 100644
--- a/ltmain.sh
+++ b/ltmain.sh
@@ -1,12 +1,9 @@
-#! /bin/sh
-## DO NOT EDIT - This file generated from ./build-aux/ltmain.in
-## by inline-source v2014-01-03.01
-# libtool (GNU libtool) 2.4.6
-# Provide generalized library-building support services.
+# libtool (GNU libtool) 2.4.2
# Written by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
-# Copyright (C) 1996-2015 Free Software Foundation, Inc.
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006,
+# 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
# This is free software; see the source for copying conditions. There is NO
# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
@@ -26,2112 +23,881 @@
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-
-PROGRAM=libtool
-PACKAGE=libtool
-VERSION=2.4.6
-package_revision=2.4.6
-
-
-## ------ ##
-## Usage. ##
-## ------ ##
-
-# Run './libtool --help' for help with using this script from the
-# command line.
-
-
-## ------------------------------- ##
-## User overridable command paths. ##
-## ------------------------------- ##
-
-# After configure completes, it has a better idea of some of the
-# shell tools we need than the defaults used by the functions shared
-# with bootstrap, so set those here where they can still be over-
-# ridden by the user, but otherwise take precedence.
-
-: ${AUTOCONF="autoconf"}
-: ${AUTOMAKE="automake"}
-
-
-## -------------------------- ##
-## Source external libraries. ##
-## -------------------------- ##
-
-# Much of our low-level functionality needs to be sourced from external
-# libraries, which are installed to $pkgauxdir.
-
-# Set a version string for this script.
-scriptversion=2015-01-20.17; # UTC
-
-# General shell script boiler plate, and helper functions.
-# Written by Gary V. Vaughan, 2004
+# along with GNU Libtool; see the file COPYING. If not, a copy
+# can be downloaded from http://www.gnu.org/licenses/gpl.html,
+# or obtained by writing to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-# Copyright (C) 2004-2015 Free Software Foundation, Inc.
-# This is free software; see the source for copying conditions. There is NO
-# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3 of the License, or
-# (at your option) any later version.
-
-# As a special exception to the GNU General Public License, if you distribute
-# this file as part of a program or library that is built using GNU Libtool,
-# you may include this file under the same distribution terms that you use
-# for the rest of that program.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNES FOR A PARTICULAR PURPOSE. See the GNU
-# General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-# Please report bugs or propose patches to gary@gnu.org.
-
-
-## ------ ##
-## Usage. ##
-## ------ ##
-
-# Evaluate this file near the top of your script to gain access to
-# the functions and variables defined here:
+# Usage: $progname [OPTION]... [MODE-ARG]...
#
-# . `echo "$0" | ${SED-sed} 's|[^/]*$||'`/build-aux/funclib.sh
+# Provide generalized library-building support services.
#
-# If you need to override any of the default environment variable
-# settings, do that before evaluating this file.
-
-
-## -------------------- ##
-## Shell normalisation. ##
-## -------------------- ##
+# --config show all configuration variables
+# --debug enable verbose shell tracing
+# -n, --dry-run display commands without modifying any files
+# --features display basic configuration information and exit
+# --mode=MODE use operation mode MODE
+# --preserve-dup-deps don't remove duplicate dependency libraries
+# --quiet, --silent don't print informational messages
+# --no-quiet, --no-silent
+# print informational messages (default)
+# --no-warn don't display warning messages
+# --tag=TAG use configuration variables from tag TAG
+# -v, --verbose print more informational messages than default
+# --no-verbose don't print the extra informational messages
+# --version print version information
+# -h, --help, --help-all print short, long, or detailed help message
+#
+# MODE must be one of the following:
+#
+# clean remove files from the build directory
+# compile compile a source file into a libtool object
+# execute automatically set library path, then run a program
+# finish complete the installation of libtool libraries
+# install install libraries or executables
+# link create a library or an executable
+# uninstall remove libraries from an installed directory
+#
+# MODE-ARGS vary depending on the MODE. When passed as first option,
+# `--mode=MODE' may be abbreviated as `MODE' or a unique abbreviation of that.
+# Try `$progname --help --mode=MODE' for a more detailed description of MODE.
+#
+# When reporting a bug, please describe a test case to reproduce it and
+# include the following information:
+#
+# host-triplet: $host
+# shell: $SHELL
+# compiler: $LTCC
+# compiler flags: $LTCFLAGS
+# linker: $LD (gnu? $with_gnu_ld)
+# $progname: (GNU libtool) 2.4.2
+# automake: $automake_version
+# autoconf: $autoconf_version
+#
+# Report bugs to <bug-libtool@gnu.org>.
+# GNU libtool home page: <http://www.gnu.org/software/libtool/>.
+# General help using GNU software: <http://www.gnu.org/gethelp/>.
-# Some shells need a little help to be as Bourne compatible as possible.
-# Before doing anything else, make sure all that help has been provided!
+PROGRAM=libtool
+PACKAGE=libtool
+VERSION=2.4.2
+TIMESTAMP=""
+package_revision=1.3337
-DUALCASE=1; export DUALCASE # for MKS sh
-if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
emulate sh
NULLCMD=:
- # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+ # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
# is contrary to our usage. Disable this feature.
alias -g '${1+"$@"}'='"$@"'
setopt NO_GLOB_SUBST
else
- case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac
+ case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac
fi
+BIN_SH=xpg4; export BIN_SH # for Tru64
+DUALCASE=1; export DUALCASE # for MKS sh
-# NLS nuisances: We save the old values in case they are required later.
-_G_user_locale=
-_G_safe_locale=
-for _G_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES
-do
- eval "if test set = \"\${$_G_var+set}\"; then
- save_$_G_var=\$$_G_var
- $_G_var=C
- export $_G_var
- _G_user_locale=\"$_G_var=\\\$save_\$_G_var; \$_G_user_locale\"
- _G_safe_locale=\"$_G_var=C; \$_G_safe_locale\"
- fi"
-done
-
-# CDPATH.
-(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
-
-# Make sure IFS has a sensible default
-sp=' '
-nl='
-'
-IFS="$sp $nl"
-
-# There are apparently some retarded systems that use ';' as a PATH separator!
-if test "${PATH_SEPARATOR+set}" != set; then
- PATH_SEPARATOR=:
- (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
- (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
- PATH_SEPARATOR=';'
- }
-fi
-
-
-
-## ------------------------- ##
-## Locate command utilities. ##
-## ------------------------- ##
-
-
-# func_executable_p FILE
-# ----------------------
-# Check that FILE is an executable regular file.
-func_executable_p ()
-{
- test -f "$1" && test -x "$1"
-}
-
-
-# func_path_progs PROGS_LIST CHECK_FUNC [PATH]
-# --------------------------------------------
-# Search for either a program that responds to --version with output
-# containing "GNU", or else returned by CHECK_FUNC otherwise, by
-# trying all the directories in PATH with each of the elements of
-# PROGS_LIST.
-#
-# CHECK_FUNC should accept the path to a candidate program, and
-# set $func_check_prog_result if it truncates its output less than
-# $_G_path_prog_max characters.
-func_path_progs ()
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
{
- _G_progs_list=$1
- _G_check_func=$2
- _G_PATH=${3-"$PATH"}
-
- _G_path_prog_max=0
- _G_path_prog_found=false
- _G_save_IFS=$IFS; IFS=${PATH_SEPARATOR-:}
- for _G_dir in $_G_PATH; do
- IFS=$_G_save_IFS
- test -z "$_G_dir" && _G_dir=.
- for _G_prog_name in $_G_progs_list; do
- for _exeext in '' .EXE; do
- _G_path_prog=$_G_dir/$_G_prog_name$_exeext
- func_executable_p "$_G_path_prog" || continue
- case `"$_G_path_prog" --version 2>&1` in
- *GNU*) func_path_progs_result=$_G_path_prog _G_path_prog_found=: ;;
- *) $_G_check_func $_G_path_prog
- func_path_progs_result=$func_check_prog_result
- ;;
- esac
- $_G_path_prog_found && break 3
- done
- done
- done
- IFS=$_G_save_IFS
- test -z "$func_path_progs_result" && {
- echo "no acceptable sed could be found in \$PATH" >&2
- exit 1
- }
-}
-
-
-# We want to be able to use the functions in this file before configure
-# has figured out where the best binaries are kept, which means we have
-# to search for them ourselves - except when the results are already set
-# where we skip the searches.
-
-# Unless the user overrides by setting SED, search the path for either GNU
-# sed, or the sed that truncates its output the least.
-test -z "$SED" && {
- _G_sed_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/
- for _G_i in 1 2 3 4 5 6 7; do
- _G_sed_script=$_G_sed_script$nl$_G_sed_script
- done
- echo "$_G_sed_script" 2>/dev/null | sed 99q >conftest.sed
- _G_sed_script=
-
- func_check_prog_sed ()
- {
- _G_path_prog=$1
-
- _G_count=0
- printf 0123456789 >conftest.in
- while :
- do
- cat conftest.in conftest.in >conftest.tmp
- mv conftest.tmp conftest.in
- cp conftest.in conftest.nl
- echo '' >> conftest.nl
- "$_G_path_prog" -f conftest.sed <conftest.nl >conftest.out 2>/dev/null || break
- diff conftest.out conftest.nl >/dev/null 2>&1 || break
- _G_count=`expr $_G_count + 1`
- if test "$_G_count" -gt "$_G_path_prog_max"; then
- # Best one so far, save it but keep looking for a better one
- func_check_prog_result=$_G_path_prog
- _G_path_prog_max=$_G_count
- fi
- # 10*(2^10) chars as input seems more than enough
- test 10 -lt "$_G_count" && break
- done
- rm -f conftest.in conftest.tmp conftest.nl conftest.out
- }
-
- func_path_progs "sed gsed" func_check_prog_sed $PATH:/usr/xpg4/bin
- rm -f conftest.sed
- SED=$func_path_progs_result
+ eval 'cat <<_LTECHO_EOF
+$1
+_LTECHO_EOF'
}
+# NLS nuisances: We save the old values to restore during execute mode.
+lt_user_locale=
+lt_safe_locale=
+for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES
+do
+ eval "if test \"\${$lt_var+set}\" = set; then
+ save_$lt_var=\$$lt_var
+ $lt_var=C
+ export $lt_var
+ lt_user_locale=\"$lt_var=\\\$save_\$lt_var; \$lt_user_locale\"
+ lt_safe_locale=\"$lt_var=C; \$lt_safe_locale\"
+ fi"
+done
+LC_ALL=C
+LANGUAGE=C
+export LANGUAGE LC_ALL
-# Unless the user overrides by setting GREP, search the path for either GNU
-# grep, or the grep that truncates its output the least.
-test -z "$GREP" && {
- func_check_prog_grep ()
- {
- _G_path_prog=$1
-
- _G_count=0
- _G_path_prog_max=0
- printf 0123456789 >conftest.in
- while :
- do
- cat conftest.in conftest.in >conftest.tmp
- mv conftest.tmp conftest.in
- cp conftest.in conftest.nl
- echo 'GREP' >> conftest.nl
- "$_G_path_prog" -e 'GREP$' -e '-(cannot match)-' <conftest.nl >conftest.out 2>/dev/null || break
- diff conftest.out conftest.nl >/dev/null 2>&1 || break
- _G_count=`expr $_G_count + 1`
- if test "$_G_count" -gt "$_G_path_prog_max"; then
- # Best one so far, save it but keep looking for a better one
- func_check_prog_result=$_G_path_prog
- _G_path_prog_max=$_G_count
- fi
- # 10*(2^10) chars as input seems more than enough
- test 10 -lt "$_G_count" && break
- done
- rm -f conftest.in conftest.tmp conftest.nl conftest.out
- }
+$lt_unset CDPATH
- func_path_progs "grep ggrep" func_check_prog_grep $PATH:/usr/xpg4/bin
- GREP=$func_path_progs_result
-}
+# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh
+# is ksh but when the shell is invoked as "sh" and the current value of
+# the _XPG environment variable is not equal to 1 (one), the special
+# positional parameter $0, within a function call, is the name of the
+# function.
+progpath="$0"
-## ------------------------------- ##
-## User overridable command paths. ##
-## ------------------------------- ##
-# All uppercase variable names are used for environment variables. These
-# variables can be overridden by the user before calling a script that
-# uses them if a suitable command of that name is not already available
-# in the command search PATH.
: ${CP="cp -f"}
-: ${ECHO="printf %s\n"}
-: ${EGREP="$GREP -E"}
-: ${FGREP="$GREP -F"}
-: ${LN_S="ln -s"}
+test "${ECHO+set}" = set || ECHO=${as_echo-'printf %s\n'}
: ${MAKE="make"}
: ${MKDIR="mkdir"}
: ${MV="mv -f"}
: ${RM="rm -f"}
: ${SHELL="${CONFIG_SHELL-/bin/sh}"}
+: ${Xsed="$SED -e 1s/^X//"}
+# Global variables:
+EXIT_SUCCESS=0
+EXIT_FAILURE=1
+EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing.
+EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake.
-## -------------------- ##
-## Useful sed snippets. ##
-## -------------------- ##
+exit_status=$EXIT_SUCCESS
-sed_dirname='s|/[^/]*$||'
-sed_basename='s|^.*/||'
+# Make sure IFS has a sensible default
+lt_nl='
+'
+IFS=" $lt_nl"
-# Sed substitution that helps us do robust quoting. It backslashifies
-# metacharacters that are still active within double-quoted strings.
-sed_quote_subst='s|\([`"$\\]\)|\\\1|g'
+dirname="s,/[^/]*$,,"
+basename="s,^.*/,,"
-# Same as above, but do not quote variable references.
-sed_double_quote_subst='s/\(["`\\]\)/\\\1/g'
+# func_dirname file append nondir_replacement
+# Compute the dirname of FILE. If nonempty, add APPEND to the result,
+# otherwise set result to NONDIR_REPLACEMENT.
+func_dirname ()
+{
+ func_dirname_result=`$ECHO "${1}" | $SED "$dirname"`
+ if test "X$func_dirname_result" = "X${1}"; then
+ func_dirname_result="${3}"
+ else
+ func_dirname_result="$func_dirname_result${2}"
+ fi
+} # func_dirname may be replaced by extended shell implementation
-# Sed substitution that turns a string into a regex matching for the
-# string literally.
-sed_make_literal_regex='s|[].[^$\\*\/]|\\&|g'
-# Sed substitution that converts a w32 file name or path
-# that contains forward slashes, into one that contains
-# (escaped) backslashes. A very naive implementation.
-sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g'
-
-# Re-'\' parameter expansions in output of sed_double_quote_subst that
-# were '\'-ed in input to the same. If an odd number of '\' preceded a
-# '$' in input to sed_double_quote_subst, that '$' was protected from
-# expansion. Since each input '\' is now two '\'s, look for any number
-# of runs of four '\'s followed by two '\'s and then a '$'. '\' that '$'.
-_G_bs='\\'
-_G_bs2='\\\\'
-_G_bs4='\\\\\\\\'
-_G_dollar='\$'
-sed_double_backslash="\
- s/$_G_bs4/&\\
-/g
- s/^$_G_bs2$_G_dollar/$_G_bs&/
- s/\\([^$_G_bs]\\)$_G_bs2$_G_dollar/\\1$_G_bs2$_G_bs$_G_dollar/g
- s/\n//g"
+# func_basename file
+func_basename ()
+{
+ func_basename_result=`$ECHO "${1}" | $SED "$basename"`
+} # func_basename may be replaced by extended shell implementation
+
+
+# func_dirname_and_basename file append nondir_replacement
+# perform func_basename and func_dirname in a single function
+# call:
+# dirname: Compute the dirname of FILE. If nonempty,
+# add APPEND to the result, otherwise set result
+# to NONDIR_REPLACEMENT.
+# value returned in "$func_dirname_result"
+# basename: Compute filename of FILE.
+# value retuned in "$func_basename_result"
+# Implementation must be kept synchronized with func_dirname
+# and func_basename. For efficiency, we do not delegate to
+# those functions but instead duplicate the functionality here.
+func_dirname_and_basename ()
+{
+ # Extract subdirectory from the argument.
+ func_dirname_result=`$ECHO "${1}" | $SED -e "$dirname"`
+ if test "X$func_dirname_result" = "X${1}"; then
+ func_dirname_result="${3}"
+ else
+ func_dirname_result="$func_dirname_result${2}"
+ fi
+ func_basename_result=`$ECHO "${1}" | $SED -e "$basename"`
+} # func_dirname_and_basename may be replaced by extended shell implementation
-## ----------------- ##
-## Global variables. ##
-## ----------------- ##
+# func_stripname prefix suffix name
+# strip PREFIX and SUFFIX off of NAME.
+# PREFIX and SUFFIX must not contain globbing or regex special
+# characters, hashes, percent signs, but SUFFIX may contain a leading
+# dot (in which case that matches only a dot).
+# func_strip_suffix prefix name
+func_stripname ()
+{
+ case ${2} in
+ .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;;
+ *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;;
+ esac
+} # func_stripname may be replaced by extended shell implementation
-# Except for the global variables explicitly listed below, the following
-# functions in the '^func_' namespace, and the '^require_' namespace
-# variables initialised in the 'Resource management' section, sourcing
-# this file will not pollute your global namespace with anything
-# else. There's no portable way to scope variables in Bourne shell
-# though, so actually running these functions will sometimes place
-# results into a variable named after the function, and often use
-# temporary variables in the '^_G_' namespace. If you are careful to
-# avoid using those namespaces casually in your sourcing script, things
-# should continue to work as you expect. And, of course, you can freely
-# overwrite any of the functions or variables defined here before
-# calling anything to customize them.
-EXIT_SUCCESS=0
-EXIT_FAILURE=1
-EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing.
-EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake.
+# These SED scripts presuppose an absolute path with a trailing slash.
+pathcar='s,^/\([^/]*\).*$,\1,'
+pathcdr='s,^/[^/]*,,'
+removedotparts=':dotsl
+ s@/\./@/@g
+ t dotsl
+ s,/\.$,/,'
+collapseslashes='s@/\{1,\}@/@g'
+finalslash='s,/*$,/,'
-# Allow overriding, eg assuming that you follow the convention of
-# putting '$debug_cmd' at the start of all your functions, you can get
-# bash to show function call trace with:
-#
-# debug_cmd='eval echo "${FUNCNAME[0]} $*" >&2' bash your-script-name
-debug_cmd=${debug_cmd-":"}
-exit_cmd=:
+# func_normal_abspath PATH
+# Remove doubled-up and trailing slashes, "." path components,
+# and cancel out any ".." path components in PATH after making
+# it an absolute path.
+# value returned in "$func_normal_abspath_result"
+func_normal_abspath ()
+{
+ # Start from root dir and reassemble the path.
+ func_normal_abspath_result=
+ func_normal_abspath_tpath=$1
+ func_normal_abspath_altnamespace=
+ case $func_normal_abspath_tpath in
+ "")
+ # Empty path, that just means $cwd.
+ func_stripname '' '/' "`pwd`"
+ func_normal_abspath_result=$func_stripname_result
+ return
+ ;;
+ # The next three entries are used to spot a run of precisely
+ # two leading slashes without using negated character classes;
+ # we take advantage of case's first-match behaviour.
+ ///*)
+ # Unusual form of absolute path, do nothing.
+ ;;
+ //*)
+ # Not necessarily an ordinary path; POSIX reserves leading '//'
+ # and for example Cygwin uses it to access remote file shares
+ # over CIFS/SMB, so we conserve a leading double slash if found.
+ func_normal_abspath_altnamespace=/
+ ;;
+ /*)
+ # Absolute path, do nothing.
+ ;;
+ *)
+ # Relative path, prepend $cwd.
+ func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath
+ ;;
+ esac
+ # Cancel out all the simple stuff to save iterations. We also want
+ # the path to end with a slash for ease of parsing, so make sure
+ # there is one (and only one) here.
+ func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \
+ -e "$removedotparts" -e "$collapseslashes" -e "$finalslash"`
+ while :; do
+ # Processed it all yet?
+ if test "$func_normal_abspath_tpath" = / ; then
+ # If we ascended to the root using ".." the result may be empty now.
+ if test -z "$func_normal_abspath_result" ; then
+ func_normal_abspath_result=/
+ fi
+ break
+ fi
+ func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \
+ -e "$pathcar"`
+ func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \
+ -e "$pathcdr"`
+ # Figure out what to do with it
+ case $func_normal_abspath_tcomponent in
+ "")
+ # Trailing empty path component, ignore it.
+ ;;
+ ..)
+ # Parent dir; strip last assembled component from result.
+ func_dirname "$func_normal_abspath_result"
+ func_normal_abspath_result=$func_dirname_result
+ ;;
+ *)
+ # Actual path component, append it.
+ func_normal_abspath_result=$func_normal_abspath_result/$func_normal_abspath_tcomponent
+ ;;
+ esac
+ done
+ # Restore leading double-slash if one was found on entry.
+ func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result
+}
-# By convention, finish your script with:
-#
-# exit $exit_status
-#
-# so that you can set exit_status to non-zero if you want to indicate
-# something went wrong during execution without actually bailing out at
-# the point of failure.
-exit_status=$EXIT_SUCCESS
+# func_relative_path SRCDIR DSTDIR
+# generates a relative path from SRCDIR to DSTDIR, with a trailing
+# slash if non-empty, suitable for immediately appending a filename
+# without needing to append a separator.
+# value returned in "$func_relative_path_result"
+func_relative_path ()
+{
+ func_relative_path_result=
+ func_normal_abspath "$1"
+ func_relative_path_tlibdir=$func_normal_abspath_result
+ func_normal_abspath "$2"
+ func_relative_path_tbindir=$func_normal_abspath_result
+
+ # Ascend the tree starting from libdir
+ while :; do
+ # check if we have found a prefix of bindir
+ case $func_relative_path_tbindir in
+ $func_relative_path_tlibdir)
+ # found an exact match
+ func_relative_path_tcancelled=
+ break
+ ;;
+ $func_relative_path_tlibdir*)
+ # found a matching prefix
+ func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir"
+ func_relative_path_tcancelled=$func_stripname_result
+ if test -z "$func_relative_path_result"; then
+ func_relative_path_result=.
+ fi
+ break
+ ;;
+ *)
+ func_dirname $func_relative_path_tlibdir
+ func_relative_path_tlibdir=${func_dirname_result}
+ if test "x$func_relative_path_tlibdir" = x ; then
+ # Have to descend all the way to the root!
+ func_relative_path_result=../$func_relative_path_result
+ func_relative_path_tcancelled=$func_relative_path_tbindir
+ break
+ fi
+ func_relative_path_result=../$func_relative_path_result
+ ;;
+ esac
+ done
-# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh
-# is ksh but when the shell is invoked as "sh" and the current value of
-# the _XPG environment variable is not equal to 1 (one), the special
-# positional parameter $0, within a function call, is the name of the
-# function.
-progpath=$0
+ # Now calculate path; take care to avoid doubling-up slashes.
+ func_stripname '' '/' "$func_relative_path_result"
+ func_relative_path_result=$func_stripname_result
+ func_stripname '/' '/' "$func_relative_path_tcancelled"
+ if test "x$func_stripname_result" != x ; then
+ func_relative_path_result=${func_relative_path_result}/${func_stripname_result}
+ fi
-# The name of this program.
-progname=`$ECHO "$progpath" |$SED "$sed_basename"`
+ # Normalisation. If bindir is libdir, return empty string,
+ # else relative path ending with a slash; either way, target
+ # file name can be directly appended.
+ if test ! -z "$func_relative_path_result"; then
+ func_stripname './' '' "$func_relative_path_result/"
+ func_relative_path_result=$func_stripname_result
+ fi
+}
+
+# The name of this program:
+func_dirname_and_basename "$progpath"
+progname=$func_basename_result
-# Make sure we have an absolute progpath for reexecution:
+# Make sure we have an absolute path for reexecution:
case $progpath in
[\\/]*|[A-Za-z]:\\*) ;;
*[\\/]*)
- progdir=`$ECHO "$progpath" |$SED "$sed_dirname"`
+ progdir=$func_dirname_result
progdir=`cd "$progdir" && pwd`
- progpath=$progdir/$progname
+ progpath="$progdir/$progname"
;;
*)
- _G_IFS=$IFS
+ save_IFS="$IFS"
IFS=${PATH_SEPARATOR-:}
for progdir in $PATH; do
- IFS=$_G_IFS
+ IFS="$save_IFS"
test -x "$progdir/$progname" && break
done
- IFS=$_G_IFS
+ IFS="$save_IFS"
test -n "$progdir" || progdir=`pwd`
- progpath=$progdir/$progname
+ progpath="$progdir/$progname"
;;
esac
+# Sed substitution that helps us do robust quoting. It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed="${SED}"' -e 1s/^X//'
+sed_quote_subst='s/\([`"$\\]\)/\\\1/g'
-## ----------------- ##
-## Standard options. ##
-## ----------------- ##
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\(["`\\]\)/\\\1/g'
-# The following options affect the operation of the functions defined
-# below, and should be set appropriately depending on run-time para-
-# meters passed on the command line.
+# Sed substitution that turns a string into a regex matching for the
+# string literally.
+sed_make_literal_regex='s,[].[^$\\*\/],\\&,g'
+# Sed substitution that converts a w32 file name or path
+# which contains forward slashes, into one that contains
+# (escaped) backslashes. A very naive implementation.
+lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g'
+
+# Re-`\' parameter expansions in output of double_quote_subst that were
+# `\'-ed in input to the same. If an odd number of `\' preceded a '$'
+# in input to double_quote_subst, that '$' was protected from expansion.
+# Since each input `\' is now two `\'s, look for any number of runs of
+# four `\'s followed by two `\'s and then a '$'. `\' that '$'.
+bs='\\'
+bs2='\\\\'
+bs4='\\\\\\\\'
+dollar='\$'
+sed_double_backslash="\
+ s/$bs4/&\\
+/g
+ s/^$bs2$dollar/$bs&/
+ s/\\([^$bs]\\)$bs2$dollar/\\1$bs2$bs$dollar/g
+ s/\n//g"
+
+# Standard options:
opt_dry_run=false
+opt_help=false
opt_quiet=false
opt_verbose=false
+opt_warning=:
-# Categories 'all' and 'none' are always available. Append any others
-# you will pass as the first argument to func_warning from your own
-# code.
-warning_categories=
-
-# By default, display warnings according to 'opt_warning_types'. Set
-# 'warning_func' to ':' to elide all warnings, or func_fatal_error to
-# treat the next displayed warning as a fatal error.
-warning_func=func_warn_and_continue
-
-# Set to 'all' to display all warnings, 'none' to suppress all
-# warnings, or a space delimited list of some subset of
-# 'warning_categories' to display only the listed warnings.
-opt_warning_types=all
-
-
-## -------------------- ##
-## Resource management. ##
-## -------------------- ##
-
-# This section contains definitions for functions that each ensure a
-# particular resource (a file, or a non-empty configuration variable for
-# example) is available, and if appropriate to extract default values
-# from pertinent package files. Call them using their associated
-# 'require_*' variable to ensure that they are executed, at most, once.
-#
-# It's entirely deliberate that calling these functions can set
-# variables that don't obey the namespace limitations obeyed by the rest
-# of this file, in order that that they be as useful as possible to
-# callers.
-
-
-# require_term_colors
-# -------------------
-# Allow display of bold text on terminals that support it.
-require_term_colors=func_require_term_colors
-func_require_term_colors ()
-{
- $debug_cmd
-
- test -t 1 && {
- # COLORTERM and USE_ANSI_COLORS environment variables take
- # precedence, because most terminfo databases neglect to describe
- # whether color sequences are supported.
- test -n "${COLORTERM+set}" && : ${USE_ANSI_COLORS="1"}
-
- if test 1 = "$USE_ANSI_COLORS"; then
- # Standard ANSI escape sequences
- tc_reset=''
- tc_bold=''; tc_standout=''
- tc_red=''; tc_green=''
- tc_blue=''; tc_cyan=''
- else
- # Otherwise trust the terminfo database after all.
- test -n "`tput sgr0 2>/dev/null`" && {
- tc_reset=`tput sgr0`
- test -n "`tput bold 2>/dev/null`" && tc_bold=`tput bold`
- tc_standout=$tc_bold
- test -n "`tput smso 2>/dev/null`" && tc_standout=`tput smso`
- test -n "`tput setaf 1 2>/dev/null`" && tc_red=`tput setaf 1`
- test -n "`tput setaf 2 2>/dev/null`" && tc_green=`tput setaf 2`
- test -n "`tput setaf 4 2>/dev/null`" && tc_blue=`tput setaf 4`
- test -n "`tput setaf 5 2>/dev/null`" && tc_cyan=`tput setaf 5`
- }
- fi
- }
-
- require_term_colors=:
-}
-
-
-## ----------------- ##
-## Function library. ##
-## ----------------- ##
-
-# This section contains a variety of useful functions to call in your
-# scripts. Take note of the portable wrappers for features provided by
-# some modern shells, which will fall back to slower equivalents on
-# less featureful shells.
-
-
-# func_append VAR VALUE
-# ---------------------
-# Append VALUE onto the existing contents of VAR.
-
- # We should try to minimise forks, especially on Windows where they are
- # unreasonably slow, so skip the feature probes when bash or zsh are
- # being used:
- if test set = "${BASH_VERSION+set}${ZSH_VERSION+set}"; then
- : ${_G_HAVE_ARITH_OP="yes"}
- : ${_G_HAVE_XSI_OPS="yes"}
- # The += operator was introduced in bash 3.1
- case $BASH_VERSION in
- [12].* | 3.0 | 3.0*) ;;
- *)
- : ${_G_HAVE_PLUSEQ_OP="yes"}
- ;;
- esac
- fi
-
- # _G_HAVE_PLUSEQ_OP
- # Can be empty, in which case the shell is probed, "yes" if += is
- # useable or anything else if it does not work.
- test -z "$_G_HAVE_PLUSEQ_OP" \
- && (eval 'x=a; x+=" b"; test "a b" = "$x"') 2>/dev/null \
- && _G_HAVE_PLUSEQ_OP=yes
-
-if test yes = "$_G_HAVE_PLUSEQ_OP"
-then
- # This is an XSI compatible shell, allowing a faster implementation...
- eval 'func_append ()
- {
- $debug_cmd
-
- eval "$1+=\$2"
- }'
-else
- # ...otherwise fall back to using expr, which is often a shell builtin.
- func_append ()
- {
- $debug_cmd
-
- eval "$1=\$$1\$2"
- }
-fi
-
-
-# func_append_quoted VAR VALUE
-# ----------------------------
-# Quote VALUE and append to the end of shell variable VAR, separated
-# by a space.
-if test yes = "$_G_HAVE_PLUSEQ_OP"; then
- eval 'func_append_quoted ()
- {
- $debug_cmd
-
- func_quote_for_eval "$2"
- eval "$1+=\\ \$func_quote_for_eval_result"
- }'
-else
- func_append_quoted ()
- {
- $debug_cmd
-
- func_quote_for_eval "$2"
- eval "$1=\$$1\\ \$func_quote_for_eval_result"
- }
-fi
-
-
-# func_append_uniq VAR VALUE
-# --------------------------
-# Append unique VALUE onto the existing contents of VAR, assuming
-# entries are delimited by the first character of VALUE. For example:
-#
-# func_append_uniq options " --another-option option-argument"
-#
-# will only append to $options if " --another-option option-argument "
-# is not already present somewhere in $options already (note spaces at
-# each end implied by leading space in second argument).
-func_append_uniq ()
+# func_echo arg...
+# Echo program name prefixed message, along with the current mode
+# name if it has been set yet.
+func_echo ()
{
- $debug_cmd
-
- eval _G_current_value='`$ECHO $'$1'`'
- _G_delim=`expr "$2" : '\(.\)'`
-
- case $_G_delim$_G_current_value$_G_delim in
- *"$2$_G_delim"*) ;;
- *) func_append "$@" ;;
- esac
+ $ECHO "$progname: ${opt_mode+$opt_mode: }$*"
}
-
-# func_arith TERM...
-# ------------------
-# Set func_arith_result to the result of evaluating TERMs.
- test -z "$_G_HAVE_ARITH_OP" \
- && (eval 'test 2 = $(( 1 + 1 ))') 2>/dev/null \
- && _G_HAVE_ARITH_OP=yes
-
-if test yes = "$_G_HAVE_ARITH_OP"; then
- eval 'func_arith ()
- {
- $debug_cmd
-
- func_arith_result=$(( $* ))
- }'
-else
- func_arith ()
- {
- $debug_cmd
-
- func_arith_result=`expr "$@"`
- }
-fi
-
-
-# func_basename FILE
-# ------------------
-# Set func_basename_result to FILE with everything up to and including
-# the last / stripped.
-if test yes = "$_G_HAVE_XSI_OPS"; then
- # If this shell supports suffix pattern removal, then use it to avoid
- # forking. Hide the definitions single quotes in case the shell chokes
- # on unsupported syntax...
- _b='func_basename_result=${1##*/}'
- _d='case $1 in
- */*) func_dirname_result=${1%/*}$2 ;;
- * ) func_dirname_result=$3 ;;
- esac'
-
-else
- # ...otherwise fall back to using sed.
- _b='func_basename_result=`$ECHO "$1" |$SED "$sed_basename"`'
- _d='func_dirname_result=`$ECHO "$1" |$SED "$sed_dirname"`
- if test "X$func_dirname_result" = "X$1"; then
- func_dirname_result=$3
- else
- func_append func_dirname_result "$2"
- fi'
-fi
-
-eval 'func_basename ()
-{
- $debug_cmd
-
- '"$_b"'
-}'
-
-
-# func_dirname FILE APPEND NONDIR_REPLACEMENT
-# -------------------------------------------
-# Compute the dirname of FILE. If nonempty, add APPEND to the result,
-# otherwise set result to NONDIR_REPLACEMENT.
-eval 'func_dirname ()
-{
- $debug_cmd
-
- '"$_d"'
-}'
-
-
-# func_dirname_and_basename FILE APPEND NONDIR_REPLACEMENT
-# --------------------------------------------------------
-# Perform func_basename and func_dirname in a single function
-# call:
-# dirname: Compute the dirname of FILE. If nonempty,
-# add APPEND to the result, otherwise set result
-# to NONDIR_REPLACEMENT.
-# value returned in "$func_dirname_result"
-# basename: Compute filename of FILE.
-# value retuned in "$func_basename_result"
-# For efficiency, we do not delegate to the functions above but instead
-# duplicate the functionality here.
-eval 'func_dirname_and_basename ()
-{
- $debug_cmd
-
- '"$_b"'
- '"$_d"'
-}'
-
-
-# func_echo ARG...
-# ----------------
-# Echo program name prefixed message.
-func_echo ()
+# func_verbose arg...
+# Echo program name prefixed message in verbose mode only.
+func_verbose ()
{
- $debug_cmd
+ $opt_verbose && func_echo ${1+"$@"}
- _G_message=$*
-
- func_echo_IFS=$IFS
- IFS=$nl
- for _G_line in $_G_message; do
- IFS=$func_echo_IFS
- $ECHO "$progname: $_G_line"
- done
- IFS=$func_echo_IFS
+ # A bug in bash halts the script if the last line of a function
+ # fails when set -e is in force, so we need another command to
+ # work around that:
+ :
}
-
-# func_echo_all ARG...
-# --------------------
+# func_echo_all arg...
# Invoke $ECHO with all args, space-separated.
func_echo_all ()
{
$ECHO "$*"
}
-
-# func_echo_infix_1 INFIX ARG...
-# ------------------------------
-# Echo program name, followed by INFIX on the first line, with any
-# additional lines not showing INFIX.
-func_echo_infix_1 ()
-{
- $debug_cmd
-
- $require_term_colors
-
- _G_infix=$1; shift
- _G_indent=$_G_infix
- _G_prefix="$progname: $_G_infix: "
- _G_message=$*
-
- # Strip color escape sequences before counting printable length
- for _G_tc in "$tc_reset" "$tc_bold" "$tc_standout" "$tc_red" "$tc_green" "$tc_blue" "$tc_cyan"
- do
- test -n "$_G_tc" && {
- _G_esc_tc=`$ECHO "$_G_tc" | $SED "$sed_make_literal_regex"`
- _G_indent=`$ECHO "$_G_indent" | $SED "s|$_G_esc_tc||g"`
- }
- done
- _G_indent="$progname: "`echo "$_G_indent" | $SED 's|.| |g'`" " ## exclude from sc_prohibit_nested_quotes
-
- func_echo_infix_1_IFS=$IFS
- IFS=$nl
- for _G_line in $_G_message; do
- IFS=$func_echo_infix_1_IFS
- $ECHO "$_G_prefix$tc_bold$_G_line$tc_reset" >&2
- _G_prefix=$_G_indent
- done
- IFS=$func_echo_infix_1_IFS
-}
-
-
-# func_error ARG...
-# -----------------
+# func_error arg...
# Echo program name prefixed message to standard error.
func_error ()
{
- $debug_cmd
+ $ECHO "$progname: ${opt_mode+$opt_mode: }"${1+"$@"} 1>&2
+}
- $require_term_colors
+# func_warning arg...
+# Echo program name prefixed warning message to standard error.
+func_warning ()
+{
+ $opt_warning && $ECHO "$progname: ${opt_mode+$opt_mode: }warning: "${1+"$@"} 1>&2
- func_echo_infix_1 " $tc_standout${tc_red}error$tc_reset" "$*" >&2
+ # bash bug again:
+ :
}
-
-# func_fatal_error ARG...
-# -----------------------
+# func_fatal_error arg...
# Echo program name prefixed message to standard error, and exit.
func_fatal_error ()
{
- $debug_cmd
-
- func_error "$*"
+ func_error ${1+"$@"}
exit $EXIT_FAILURE
}
+# func_fatal_help arg...
+# Echo program name prefixed message to standard error, followed by
+# a help hint, and exit.
+func_fatal_help ()
+{
+ func_error ${1+"$@"}
+ func_fatal_error "$help"
+}
+help="Try \`$progname --help' for more information." ## default
-# func_grep EXPRESSION FILENAME
-# -----------------------------
+
+# func_grep expression filename
# Check whether EXPRESSION matches any line of FILENAME, without output.
func_grep ()
{
- $debug_cmd
-
$GREP "$1" "$2" >/dev/null 2>&1
}
-# func_len STRING
-# ---------------
-# Set func_len_result to the length of STRING. STRING may not
-# start with a hyphen.
- test -z "$_G_HAVE_XSI_OPS" \
- && (eval 'x=a/b/c;
- test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \
- && _G_HAVE_XSI_OPS=yes
-
-if test yes = "$_G_HAVE_XSI_OPS"; then
- eval 'func_len ()
- {
- $debug_cmd
-
- func_len_result=${#1}
- }'
-else
- func_len ()
- {
- $debug_cmd
-
- func_len_result=`expr "$1" : ".*" 2>/dev/null || echo $max_cmd_len`
- }
-fi
-
-
-# func_mkdir_p DIRECTORY-PATH
-# ---------------------------
+# func_mkdir_p directory-path
# Make sure the entire path to DIRECTORY-PATH is available.
func_mkdir_p ()
{
- $debug_cmd
+ my_directory_path="$1"
+ my_dir_list=
- _G_directory_path=$1
- _G_dir_list=
+ if test -n "$my_directory_path" && test "$opt_dry_run" != ":"; then
- if test -n "$_G_directory_path" && test : != "$opt_dry_run"; then
-
- # Protect directory names starting with '-'
- case $_G_directory_path in
- -*) _G_directory_path=./$_G_directory_path ;;
+ # Protect directory names starting with `-'
+ case $my_directory_path in
+ -*) my_directory_path="./$my_directory_path" ;;
esac
# While some portion of DIR does not yet exist...
- while test ! -d "$_G_directory_path"; do
+ while test ! -d "$my_directory_path"; do
# ...make a list in topmost first order. Use a colon delimited
# list incase some portion of path contains whitespace.
- _G_dir_list=$_G_directory_path:$_G_dir_list
+ my_dir_list="$my_directory_path:$my_dir_list"
# If the last portion added has no slash in it, the list is done
- case $_G_directory_path in */*) ;; *) break ;; esac
+ case $my_directory_path in */*) ;; *) break ;; esac
# ...otherwise throw away the child directory and loop
- _G_directory_path=`$ECHO "$_G_directory_path" | $SED -e "$sed_dirname"`
+ my_directory_path=`$ECHO "$my_directory_path" | $SED -e "$dirname"`
done
- _G_dir_list=`$ECHO "$_G_dir_list" | $SED 's|:*$||'`
+ my_dir_list=`$ECHO "$my_dir_list" | $SED 's,:*$,,'`
- func_mkdir_p_IFS=$IFS; IFS=:
- for _G_dir in $_G_dir_list; do
- IFS=$func_mkdir_p_IFS
- # mkdir can fail with a 'File exist' error if two processes
+ save_mkdir_p_IFS="$IFS"; IFS=':'
+ for my_dir in $my_dir_list; do
+ IFS="$save_mkdir_p_IFS"
+ # mkdir can fail with a `File exist' error if two processes
# try to create one of the directories concurrently. Don't
# stop in that case!
- $MKDIR "$_G_dir" 2>/dev/null || :
+ $MKDIR "$my_dir" 2>/dev/null || :
done
- IFS=$func_mkdir_p_IFS
+ IFS="$save_mkdir_p_IFS"
# Bail out if we (or some other process) failed to create a directory.
- test -d "$_G_directory_path" || \
- func_fatal_error "Failed to create '$1'"
+ test -d "$my_directory_path" || \
+ func_fatal_error "Failed to create \`$1'"
fi
}
-# func_mktempdir [BASENAME]
-# -------------------------
+# func_mktempdir [string]
# Make a temporary directory that won't clash with other running
# libtool processes, and avoids race conditions if possible. If
-# given, BASENAME is the basename for that directory.
+# given, STRING is the basename for that directory.
func_mktempdir ()
{
- $debug_cmd
-
- _G_template=${TMPDIR-/tmp}/${1-$progname}
+ my_template="${TMPDIR-/tmp}/${1-$progname}"
- if test : = "$opt_dry_run"; then
+ if test "$opt_dry_run" = ":"; then
# Return a directory name, but don't create it in dry-run mode
- _G_tmpdir=$_G_template-$$
+ my_tmpdir="${my_template}-$$"
else
# If mktemp works, use that first and foremost
- _G_tmpdir=`mktemp -d "$_G_template-XXXXXXXX" 2>/dev/null`
+ my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null`
- if test ! -d "$_G_tmpdir"; then
+ if test ! -d "$my_tmpdir"; then
# Failing that, at least try and use $RANDOM to avoid a race
- _G_tmpdir=$_G_template-${RANDOM-0}$$
+ my_tmpdir="${my_template}-${RANDOM-0}$$"
- func_mktempdir_umask=`umask`
+ save_mktempdir_umask=`umask`
umask 0077
- $MKDIR "$_G_tmpdir"
- umask $func_mktempdir_umask
+ $MKDIR "$my_tmpdir"
+ umask $save_mktempdir_umask
fi
# If we're not in dry-run mode, bomb out on failure
- test -d "$_G_tmpdir" || \
- func_fatal_error "cannot create temporary directory '$_G_tmpdir'"
+ test -d "$my_tmpdir" || \
+ func_fatal_error "cannot create temporary directory \`$my_tmpdir'"
fi
- $ECHO "$_G_tmpdir"
+ $ECHO "$my_tmpdir"
}
-# func_normal_abspath PATH
-# ------------------------
-# Remove doubled-up and trailing slashes, "." path components,
-# and cancel out any ".." path components in PATH after making
-# it an absolute path.
-func_normal_abspath ()
+# func_quote_for_eval arg
+# Aesthetically quote ARG to be evaled later.
+# This function returns two values: FUNC_QUOTE_FOR_EVAL_RESULT
+# is double-quoted, suitable for a subsequent eval, whereas
+# FUNC_QUOTE_FOR_EVAL_UNQUOTED_RESULT has merely all characters
+# which are still active within double quotes backslashified.
+func_quote_for_eval ()
{
- $debug_cmd
+ case $1 in
+ *[\\\`\"\$]*)
+ func_quote_for_eval_unquoted_result=`$ECHO "$1" | $SED "$sed_quote_subst"` ;;
+ *)
+ func_quote_for_eval_unquoted_result="$1" ;;
+ esac
- # These SED scripts presuppose an absolute path with a trailing slash.
- _G_pathcar='s|^/\([^/]*\).*$|\1|'
- _G_pathcdr='s|^/[^/]*||'
- _G_removedotparts=':dotsl
- s|/\./|/|g
- t dotsl
- s|/\.$|/|'
- _G_collapseslashes='s|/\{1,\}|/|g'
- _G_finalslash='s|/*$|/|'
-
- # Start from root dir and reassemble the path.
- func_normal_abspath_result=
- func_normal_abspath_tpath=$1
- func_normal_abspath_altnamespace=
- case $func_normal_abspath_tpath in
- "")
- # Empty path, that just means $cwd.
- func_stripname '' '/' "`pwd`"
- func_normal_abspath_result=$func_stripname_result
- return
- ;;
- # The next three entries are used to spot a run of precisely
- # two leading slashes without using negated character classes;
- # we take advantage of case's first-match behaviour.
- ///*)
- # Unusual form of absolute path, do nothing.
- ;;
- //*)
- # Not necessarily an ordinary path; POSIX reserves leading '//'
- # and for example Cygwin uses it to access remote file shares
- # over CIFS/SMB, so we conserve a leading double slash if found.
- func_normal_abspath_altnamespace=/
- ;;
- /*)
- # Absolute path, do nothing.
+ case $func_quote_for_eval_unquoted_result in
+ # Double-quote args containing shell metacharacters to delay
+ # word splitting, command substitution and and variable
+ # expansion for a subsequent eval.
+ # Many Bourne shells cannot handle close brackets correctly
+ # in scan sets, so we specify it separately.
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
+ func_quote_for_eval_result="\"$func_quote_for_eval_unquoted_result\""
;;
*)
- # Relative path, prepend $cwd.
- func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath
- ;;
+ func_quote_for_eval_result="$func_quote_for_eval_unquoted_result"
esac
-
- # Cancel out all the simple stuff to save iterations. We also want
- # the path to end with a slash for ease of parsing, so make sure
- # there is one (and only one) here.
- func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \
- -e "$_G_removedotparts" -e "$_G_collapseslashes" -e "$_G_finalslash"`
- while :; do
- # Processed it all yet?
- if test / = "$func_normal_abspath_tpath"; then
- # If we ascended to the root using ".." the result may be empty now.
- if test -z "$func_normal_abspath_result"; then
- func_normal_abspath_result=/
- fi
- break
- fi
- func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \
- -e "$_G_pathcar"`
- func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \
- -e "$_G_pathcdr"`
- # Figure out what to do with it
- case $func_normal_abspath_tcomponent in
- "")
- # Trailing empty path component, ignore it.
- ;;
- ..)
- # Parent dir; strip last assembled component from result.
- func_dirname "$func_normal_abspath_result"
- func_normal_abspath_result=$func_dirname_result
- ;;
- *)
- # Actual path component, append it.
- func_append func_normal_abspath_result "/$func_normal_abspath_tcomponent"
- ;;
- esac
- done
- # Restore leading double-slash if one was found on entry.
- func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result
-}
-
-
-# func_notquiet ARG...
-# --------------------
-# Echo program name prefixed message only when not in quiet mode.
-func_notquiet ()
-{
- $debug_cmd
-
- $opt_quiet || func_echo ${1+"$@"}
-
- # A bug in bash halts the script if the last line of a function
- # fails when set -e is in force, so we need another command to
- # work around that:
- :
}
-# func_relative_path SRCDIR DSTDIR
-# --------------------------------
-# Set func_relative_path_result to the relative path from SRCDIR to DSTDIR.
-func_relative_path ()
-{
- $debug_cmd
-
- func_relative_path_result=
- func_normal_abspath "$1"
- func_relative_path_tlibdir=$func_normal_abspath_result
- func_normal_abspath "$2"
- func_relative_path_tbindir=$func_normal_abspath_result
-
- # Ascend the tree starting from libdir
- while :; do
- # check if we have found a prefix of bindir
- case $func_relative_path_tbindir in
- $func_relative_path_tlibdir)
- # found an exact match
- func_relative_path_tcancelled=
- break
- ;;
- $func_relative_path_tlibdir*)
- # found a matching prefix
- func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir"
- func_relative_path_tcancelled=$func_stripname_result
- if test -z "$func_relative_path_result"; then
- func_relative_path_result=.
- fi
- break
- ;;
- *)
- func_dirname $func_relative_path_tlibdir
- func_relative_path_tlibdir=$func_dirname_result
- if test -z "$func_relative_path_tlibdir"; then
- # Have to descend all the way to the root!
- func_relative_path_result=../$func_relative_path_result
- func_relative_path_tcancelled=$func_relative_path_tbindir
- break
- fi
- func_relative_path_result=../$func_relative_path_result
- ;;
- esac
- done
-
- # Now calculate path; take care to avoid doubling-up slashes.
- func_stripname '' '/' "$func_relative_path_result"
- func_relative_path_result=$func_stripname_result
- func_stripname '/' '/' "$func_relative_path_tcancelled"
- if test -n "$func_stripname_result"; then
- func_append func_relative_path_result "/$func_stripname_result"
- fi
-
- # Normalisation. If bindir is libdir, return '.' else relative path.
- if test -n "$func_relative_path_result"; then
- func_stripname './' '' "$func_relative_path_result"
- func_relative_path_result=$func_stripname_result
- fi
-
- test -n "$func_relative_path_result" || func_relative_path_result=.
-
- :
-}
-
-
-# func_quote_for_eval ARG...
-# --------------------------
-# Aesthetically quote ARGs to be evaled later.
-# This function returns two values:
-# i) func_quote_for_eval_result
-# double-quoted, suitable for a subsequent eval
-# ii) func_quote_for_eval_unquoted_result
-# has all characters that are still active within double
-# quotes backslashified.
-func_quote_for_eval ()
-{
- $debug_cmd
-
- func_quote_for_eval_unquoted_result=
- func_quote_for_eval_result=
- while test 0 -lt $#; do
- case $1 in
- *[\\\`\"\$]*)
- _G_unquoted_arg=`printf '%s\n' "$1" |$SED "$sed_quote_subst"` ;;
- *)
- _G_unquoted_arg=$1 ;;
- esac
- if test -n "$func_quote_for_eval_unquoted_result"; then
- func_append func_quote_for_eval_unquoted_result " $_G_unquoted_arg"
- else
- func_append func_quote_for_eval_unquoted_result "$_G_unquoted_arg"
- fi
-
- case $_G_unquoted_arg in
- # Double-quote args containing shell metacharacters to delay
- # word splitting, command substitution and variable expansion
- # for a subsequent eval.
- # Many Bourne shells cannot handle close brackets correctly
- # in scan sets, so we specify it separately.
- *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
- _G_quoted_arg=\"$_G_unquoted_arg\"
- ;;
- *)
- _G_quoted_arg=$_G_unquoted_arg
- ;;
- esac
-
- if test -n "$func_quote_for_eval_result"; then
- func_append func_quote_for_eval_result " $_G_quoted_arg"
- else
- func_append func_quote_for_eval_result "$_G_quoted_arg"
- fi
- shift
- done
-}
-
-
-# func_quote_for_expand ARG
-# -------------------------
+# func_quote_for_expand arg
# Aesthetically quote ARG to be evaled later; same as above,
# but do not quote variable references.
func_quote_for_expand ()
{
- $debug_cmd
-
case $1 in
*[\\\`\"]*)
- _G_arg=`$ECHO "$1" | $SED \
- -e "$sed_double_quote_subst" -e "$sed_double_backslash"` ;;
+ my_arg=`$ECHO "$1" | $SED \
+ -e "$double_quote_subst" -e "$sed_double_backslash"` ;;
*)
- _G_arg=$1 ;;
+ my_arg="$1" ;;
esac
- case $_G_arg in
+ case $my_arg in
# Double-quote args containing shell metacharacters to delay
# word splitting and command substitution for a subsequent eval.
# Many Bourne shells cannot handle close brackets correctly
# in scan sets, so we specify it separately.
*[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
- _G_arg=\"$_G_arg\"
+ my_arg="\"$my_arg\""
;;
esac
- func_quote_for_expand_result=$_G_arg
+ func_quote_for_expand_result="$my_arg"
}
-# func_stripname PREFIX SUFFIX NAME
-# ---------------------------------
-# strip PREFIX and SUFFIX from NAME, and store in func_stripname_result.
-# PREFIX and SUFFIX must not contain globbing or regex special
-# characters, hashes, percent signs, but SUFFIX may contain a leading
-# dot (in which case that matches only a dot).
-if test yes = "$_G_HAVE_XSI_OPS"; then
- eval 'func_stripname ()
- {
- $debug_cmd
-
- # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are
- # positional parameters, so assign one to ordinary variable first.
- func_stripname_result=$3
- func_stripname_result=${func_stripname_result#"$1"}
- func_stripname_result=${func_stripname_result%"$2"}
- }'
-else
- func_stripname ()
- {
- $debug_cmd
-
- case $2 in
- .*) func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%\\\\$2\$%%"`;;
- *) func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%$2\$%%"`;;
- esac
- }
-fi
-
-
-# func_show_eval CMD [FAIL_EXP]
-# -----------------------------
-# Unless opt_quiet is true, then output CMD. Then, if opt_dryrun is
+# func_show_eval cmd [fail_exp]
+# Unless opt_silent is true, then output CMD. Then, if opt_dryrun is
# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP
# is given, then evaluate it.
func_show_eval ()
{
- $debug_cmd
-
- _G_cmd=$1
- _G_fail_exp=${2-':'}
+ my_cmd="$1"
+ my_fail_exp="${2-:}"
- func_quote_for_expand "$_G_cmd"
- eval "func_notquiet $func_quote_for_expand_result"
+ ${opt_silent-false} || {
+ func_quote_for_expand "$my_cmd"
+ eval "func_echo $func_quote_for_expand_result"
+ }
- $opt_dry_run || {
- eval "$_G_cmd"
- _G_status=$?
- if test 0 -ne "$_G_status"; then
- eval "(exit $_G_status); $_G_fail_exp"
+ if ${opt_dry_run-false}; then :; else
+ eval "$my_cmd"
+ my_status=$?
+ if test "$my_status" -eq 0; then :; else
+ eval "(exit $my_status); $my_fail_exp"
fi
- }
+ fi
}
-# func_show_eval_locale CMD [FAIL_EXP]
-# ------------------------------------
-# Unless opt_quiet is true, then output CMD. Then, if opt_dryrun is
+# func_show_eval_locale cmd [fail_exp]
+# Unless opt_silent is true, then output CMD. Then, if opt_dryrun is
# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP
# is given, then evaluate it. Use the saved locale for evaluation.
func_show_eval_locale ()
{
- $debug_cmd
-
- _G_cmd=$1
- _G_fail_exp=${2-':'}
+ my_cmd="$1"
+ my_fail_exp="${2-:}"
- $opt_quiet || {
- func_quote_for_expand "$_G_cmd"
+ ${opt_silent-false} || {
+ func_quote_for_expand "$my_cmd"
eval "func_echo $func_quote_for_expand_result"
}
- $opt_dry_run || {
- eval "$_G_user_locale
- $_G_cmd"
- _G_status=$?
- eval "$_G_safe_locale"
- if test 0 -ne "$_G_status"; then
- eval "(exit $_G_status); $_G_fail_exp"
+ if ${opt_dry_run-false}; then :; else
+ eval "$lt_user_locale
+ $my_cmd"
+ my_status=$?
+ eval "$lt_safe_locale"
+ if test "$my_status" -eq 0; then :; else
+ eval "(exit $my_status); $my_fail_exp"
fi
- }
+ fi
}
-
# func_tr_sh
-# ----------
# Turn $1 into a string suitable for a shell variable name.
# Result is stored in $func_tr_sh_result. All characters
# not in the set a-zA-Z0-9_ are replaced with '_'. Further,
# if $1 begins with a digit, a '_' is prepended as well.
func_tr_sh ()
{
- $debug_cmd
-
- case $1 in
- [0-9]* | *[!a-zA-Z0-9_]*)
- func_tr_sh_result=`$ECHO "$1" | $SED -e 's/^\([0-9]\)/_\1/' -e 's/[^a-zA-Z0-9_]/_/g'`
- ;;
- * )
- func_tr_sh_result=$1
- ;;
- esac
-}
-
-
-# func_verbose ARG...
-# -------------------
-# Echo program name prefixed message in verbose mode only.
-func_verbose ()
-{
- $debug_cmd
-
- $opt_verbose && func_echo "$*"
-
- :
-}
-
-
-# func_warn_and_continue ARG...
-# -----------------------------
-# Echo program name prefixed warning message to standard error.
-func_warn_and_continue ()
-{
- $debug_cmd
-
- $require_term_colors
-
- func_echo_infix_1 "${tc_red}warning$tc_reset" "$*" >&2
-}
-
-
-# func_warning CATEGORY ARG...
-# ----------------------------
-# Echo program name prefixed warning message to standard error. Warning
-# messages can be filtered according to CATEGORY, where this function
-# elides messages where CATEGORY is not listed in the global variable
-# 'opt_warning_types'.
-func_warning ()
-{
- $debug_cmd
-
- # CATEGORY must be in the warning_categories list!
- case " $warning_categories " in
- *" $1 "*) ;;
- *) func_internal_error "invalid warning category '$1'" ;;
- esac
-
- _G_category=$1
- shift
-
- case " $opt_warning_types " in
- *" $_G_category "*) $warning_func ${1+"$@"} ;;
- esac
-}
-
-
-# func_sort_ver VER1 VER2
-# -----------------------
-# 'sort -V' is not generally available.
-# Note this deviates from the version comparison in automake
-# in that it treats 1.5 < 1.5.0, and treats 1.4.4a < 1.4-p3a
-# but this should suffice as we won't be specifying old
-# version formats or redundant trailing .0 in bootstrap.conf.
-# If we did want full compatibility then we should probably
-# use m4_version_compare from autoconf.
-func_sort_ver ()
-{
- $debug_cmd
-
- printf '%s\n%s\n' "$1" "$2" \
- | sort -t. -k 1,1n -k 2,2n -k 3,3n -k 4,4n -k 5,5n -k 6,6n -k 7,7n -k 8,8n -k 9,9n
-}
-
-# func_lt_ver PREV CURR
-# ---------------------
-# Return true if PREV and CURR are in the correct order according to
-# func_sort_ver, otherwise false. Use it like this:
-#
-# func_lt_ver "$prev_ver" "$proposed_ver" || func_fatal_error "..."
-func_lt_ver ()
-{
- $debug_cmd
-
- test "x$1" = x`func_sort_ver "$1" "$2" | $SED 1q`
-}
-
-
-# Local variables:
-# mode: shell-script
-# sh-indentation: 2
-# eval: (add-hook 'before-save-hook 'time-stamp)
-# time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC"
-# time-stamp-time-zone: "UTC"
-# End:
-#! /bin/sh
-
-# Set a version string for this script.
-scriptversion=2014-01-07.03; # UTC
-
-# A portable, pluggable option parser for Bourne shell.
-# Written by Gary V. Vaughan, 2010
-
-# Copyright (C) 2010-2015 Free Software Foundation, Inc.
-# This is free software; see the source for copying conditions. There is NO
-# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-# Please report bugs or propose patches to gary@gnu.org.
-
-
-## ------ ##
-## Usage. ##
-## ------ ##
-
-# This file is a library for parsing options in your shell scripts along
-# with assorted other useful supporting features that you can make use
-# of too.
-#
-# For the simplest scripts you might need only:
-#
-# #!/bin/sh
-# . relative/path/to/funclib.sh
-# . relative/path/to/options-parser
-# scriptversion=1.0
-# func_options ${1+"$@"}
-# eval set dummy "$func_options_result"; shift
-# ...rest of your script...
-#
-# In order for the '--version' option to work, you will need to have a
-# suitably formatted comment like the one at the top of this file
-# starting with '# Written by ' and ending with '# warranty; '.
-#
-# For '-h' and '--help' to work, you will also need a one line
-# description of your script's purpose in a comment directly above the
-# '# Written by ' line, like the one at the top of this file.
-#
-# The default options also support '--debug', which will turn on shell
-# execution tracing (see the comment above debug_cmd below for another
-# use), and '--verbose' and the func_verbose function to allow your script
-# to display verbose messages only when your user has specified
-# '--verbose'.
-#
-# After sourcing this file, you can plug processing for additional
-# options by amending the variables from the 'Configuration' section
-# below, and following the instructions in the 'Option parsing'
-# section further down.
-
-## -------------- ##
-## Configuration. ##
-## -------------- ##
-
-# You should override these variables in your script after sourcing this
-# file so that they reflect the customisations you have added to the
-# option parser.
-
-# The usage line for option parsing errors and the start of '-h' and
-# '--help' output messages. You can embed shell variables for delayed
-# expansion at the time the message is displayed, but you will need to
-# quote other shell meta-characters carefully to prevent them being
-# expanded when the contents are evaled.
-usage='$progpath [OPTION]...'
-
-# Short help message in response to '-h' and '--help'. Add to this or
-# override it after sourcing this library to reflect the full set of
-# options your script accepts.
-usage_message="\
- --debug enable verbose shell tracing
- -W, --warnings=CATEGORY
- report the warnings falling in CATEGORY [all]
- -v, --verbose verbosely report processing
- --version print version information and exit
- -h, --help print short or long help message and exit
-"
-
-# Additional text appended to 'usage_message' in response to '--help'.
-long_help_message="
-Warning categories include:
- 'all' show all warnings
- 'none' turn off all the warnings
- 'error' warnings are treated as fatal errors"
-
-# Help message printed before fatal option parsing errors.
-fatal_help="Try '\$progname --help' for more information."
-
-
-
-## ------------------------- ##
-## Hook function management. ##
-## ------------------------- ##
-
-# This section contains functions for adding, removing, and running hooks
-# to the main code. A hook is just a named list of of function, that can
-# be run in order later on.
-
-# func_hookable FUNC_NAME
-# -----------------------
-# Declare that FUNC_NAME will run hooks added with
-# 'func_add_hook FUNC_NAME ...'.
-func_hookable ()
-{
- $debug_cmd
-
- func_append hookable_fns " $1"
-}
-
-
-# func_add_hook FUNC_NAME HOOK_FUNC
-# ---------------------------------
-# Request that FUNC_NAME call HOOK_FUNC before it returns. FUNC_NAME must
-# first have been declared "hookable" by a call to 'func_hookable'.
-func_add_hook ()
-{
- $debug_cmd
-
- case " $hookable_fns " in
- *" $1 "*) ;;
- *) func_fatal_error "'$1' does not accept hook functions." ;;
- esac
-
- eval func_append ${1}_hooks '" $2"'
-}
-
-
-# func_remove_hook FUNC_NAME HOOK_FUNC
-# ------------------------------------
-# Remove HOOK_FUNC from the list of functions called by FUNC_NAME.
-func_remove_hook ()
-{
- $debug_cmd
-
- eval ${1}_hooks='`$ECHO "\$'$1'_hooks" |$SED "s| '$2'||"`'
-}
-
-
-# func_run_hooks FUNC_NAME [ARG]...
-# ---------------------------------
-# Run all hook functions registered to FUNC_NAME.
-# It is assumed that the list of hook functions contains nothing more
-# than a whitespace-delimited list of legal shell function names, and
-# no effort is wasted trying to catch shell meta-characters or preserve
-# whitespace.
-func_run_hooks ()
-{
- $debug_cmd
-
- case " $hookable_fns " in
- *" $1 "*) ;;
- *) func_fatal_error "'$1' does not support hook funcions.n" ;;
- esac
-
- eval _G_hook_fns=\$$1_hooks; shift
-
- for _G_hook in $_G_hook_fns; do
- eval $_G_hook '"$@"'
-
- # store returned options list back into positional
- # parameters for next 'cmd' execution.
- eval _G_hook_result=\$${_G_hook}_result
- eval set dummy "$_G_hook_result"; shift
- done
-
- func_quote_for_eval ${1+"$@"}
- func_run_hooks_result=$func_quote_for_eval_result
-}
-
-
-
-## --------------- ##
-## Option parsing. ##
-## --------------- ##
-
-# In order to add your own option parsing hooks, you must accept the
-# full positional parameter list in your hook function, remove any
-# options that you action, and then pass back the remaining unprocessed
-# options in '<hooked_function_name>_result', escaped suitably for
-# 'eval'. Like this:
-#
-# my_options_prep ()
-# {
-# $debug_cmd
-#
-# # Extend the existing usage message.
-# usage_message=$usage_message'
-# -s, --silent don'\''t print informational messages
-# '
-#
-# func_quote_for_eval ${1+"$@"}
-# my_options_prep_result=$func_quote_for_eval_result
-# }
-# func_add_hook func_options_prep my_options_prep
-#
-#
-# my_silent_option ()
-# {
-# $debug_cmd
-#
-# # Note that for efficiency, we parse as many options as we can
-# # recognise in a loop before passing the remainder back to the
-# # caller on the first unrecognised argument we encounter.
-# while test $# -gt 0; do
-# opt=$1; shift
-# case $opt in
-# --silent|-s) opt_silent=: ;;
-# # Separate non-argument short options:
-# -s*) func_split_short_opt "$_G_opt"
-# set dummy "$func_split_short_opt_name" \
-# "-$func_split_short_opt_arg" ${1+"$@"}
-# shift
-# ;;
-# *) set dummy "$_G_opt" "$*"; shift; break ;;
-# esac
-# done
-#
-# func_quote_for_eval ${1+"$@"}
-# my_silent_option_result=$func_quote_for_eval_result
-# }
-# func_add_hook func_parse_options my_silent_option
-#
-#
-# my_option_validation ()
-# {
-# $debug_cmd
-#
-# $opt_silent && $opt_verbose && func_fatal_help "\
-# '--silent' and '--verbose' options are mutually exclusive."
-#
-# func_quote_for_eval ${1+"$@"}
-# my_option_validation_result=$func_quote_for_eval_result
-# }
-# func_add_hook func_validate_options my_option_validation
-#
-# You'll alse need to manually amend $usage_message to reflect the extra
-# options you parse. It's preferable to append if you can, so that
-# multiple option parsing hooks can be added safely.
-
-
-# func_options [ARG]...
-# ---------------------
-# All the functions called inside func_options are hookable. See the
-# individual implementations for details.
-func_hookable func_options
-func_options ()
-{
- $debug_cmd
-
- func_options_prep ${1+"$@"}
- eval func_parse_options \
- ${func_options_prep_result+"$func_options_prep_result"}
- eval func_validate_options \
- ${func_parse_options_result+"$func_parse_options_result"}
-
- eval func_run_hooks func_options \
- ${func_validate_options_result+"$func_validate_options_result"}
-
- # save modified positional parameters for caller
- func_options_result=$func_run_hooks_result
-}
-
-
-# func_options_prep [ARG]...
-# --------------------------
-# All initialisations required before starting the option parse loop.
-# Note that when calling hook functions, we pass through the list of
-# positional parameters. If a hook function modifies that list, and
-# needs to propogate that back to rest of this script, then the complete
-# modified list must be put in 'func_run_hooks_result' before
-# returning.
-func_hookable func_options_prep
-func_options_prep ()
-{
- $debug_cmd
-
- # Option defaults:
- opt_verbose=false
- opt_warning_types=
-
- func_run_hooks func_options_prep ${1+"$@"}
-
- # save modified positional parameters for caller
- func_options_prep_result=$func_run_hooks_result
-}
-
-
-# func_parse_options [ARG]...
-# ---------------------------
-# The main option parsing loop.
-func_hookable func_parse_options
-func_parse_options ()
-{
- $debug_cmd
-
- func_parse_options_result=
-
- # this just eases exit handling
- while test $# -gt 0; do
- # Defer to hook functions for initial option parsing, so they
- # get priority in the event of reusing an option name.
- func_run_hooks func_parse_options ${1+"$@"}
-
- # Adjust func_parse_options positional parameters to match
- eval set dummy "$func_run_hooks_result"; shift
-
- # Break out of the loop if we already parsed every option.
- test $# -gt 0 || break
-
- _G_opt=$1
- shift
- case $_G_opt in
- --debug|-x) debug_cmd='set -x'
- func_echo "enabling shell trace mode"
- $debug_cmd
- ;;
-
- --no-warnings|--no-warning|--no-warn)
- set dummy --warnings none ${1+"$@"}
- shift
- ;;
-
- --warnings|--warning|-W)
- test $# = 0 && func_missing_arg $_G_opt && break
- case " $warning_categories $1" in
- *" $1 "*)
- # trailing space prevents matching last $1 above
- func_append_uniq opt_warning_types " $1"
- ;;
- *all)
- opt_warning_types=$warning_categories
- ;;
- *none)
- opt_warning_types=none
- warning_func=:
- ;;
- *error)
- opt_warning_types=$warning_categories
- warning_func=func_fatal_error
- ;;
- *)
- func_fatal_error \
- "unsupported warning category: '$1'"
- ;;
- esac
- shift
- ;;
-
- --verbose|-v) opt_verbose=: ;;
- --version) func_version ;;
- -\?|-h) func_usage ;;
- --help) func_help ;;
-
- # Separate optargs to long options (plugins may need this):
- --*=*) func_split_equals "$_G_opt"
- set dummy "$func_split_equals_lhs" \
- "$func_split_equals_rhs" ${1+"$@"}
- shift
- ;;
-
- # Separate optargs to short options:
- -W*)
- func_split_short_opt "$_G_opt"
- set dummy "$func_split_short_opt_name" \
- "$func_split_short_opt_arg" ${1+"$@"}
- shift
- ;;
-
- # Separate non-argument short options:
- -\?*|-h*|-v*|-x*)
- func_split_short_opt "$_G_opt"
- set dummy "$func_split_short_opt_name" \
- "-$func_split_short_opt_arg" ${1+"$@"}
- shift
- ;;
-
- --) break ;;
- -*) func_fatal_help "unrecognised option: '$_G_opt'" ;;
- *) set dummy "$_G_opt" ${1+"$@"}; shift; break ;;
- esac
- done
-
- # save modified positional parameters for caller
- func_quote_for_eval ${1+"$@"}
- func_parse_options_result=$func_quote_for_eval_result
+ case $1 in
+ [0-9]* | *[!a-zA-Z0-9_]*)
+ func_tr_sh_result=`$ECHO "$1" | $SED 's/^\([0-9]\)/_\1/; s/[^a-zA-Z0-9_]/_/g'`
+ ;;
+ * )
+ func_tr_sh_result=$1
+ ;;
+ esac
}
-# func_validate_options [ARG]...
-# ------------------------------
-# Perform any sanity checks on option settings and/or unconsumed
-# arguments.
-func_hookable func_validate_options
-func_validate_options ()
+# func_version
+# Echo version message to standard output and exit.
+func_version ()
{
- $debug_cmd
-
- # Display all warnings if -W was not given.
- test -n "$opt_warning_types" || opt_warning_types=" $warning_categories"
+ $opt_debug
- func_run_hooks func_validate_options ${1+"$@"}
-
- # Bail if the options were screwed!
- $exit_cmd $EXIT_FAILURE
-
- # save modified positional parameters for caller
- func_validate_options_result=$func_run_hooks_result
+ $SED -n '/(C)/!b go
+ :more
+ /\./!{
+ N
+ s/\n# / /
+ b more
+ }
+ :go
+ /^# '$PROGRAM' (GNU /,/# warranty; / {
+ s/^# //
+ s/^# *$//
+ s/\((C)\)[ 0-9,-]*\( [1-9][0-9]*\)/\1\2/
+ p
+ }' < "$progpath"
+ exit $?
}
-
-
-## ----------------- ##
-## Helper functions. ##
-## ----------------- ##
-
-# This section contains the helper functions used by the rest of the
-# hookable option parser framework in ascii-betical order.
-
-
-# func_fatal_help ARG...
-# ----------------------
-# Echo program name prefixed message to standard error, followed by
-# a help hint, and exit.
-func_fatal_help ()
+# func_usage
+# Echo short help message to standard output and exit.
+func_usage ()
{
- $debug_cmd
+ $opt_debug
- eval \$ECHO \""Usage: $usage"\"
- eval \$ECHO \""$fatal_help"\"
- func_error ${1+"$@"}
- exit $EXIT_FAILURE
+ $SED -n '/^# Usage:/,/^# *.*--help/ {
+ s/^# //
+ s/^# *$//
+ s/\$progname/'$progname'/
+ p
+ }' < "$progpath"
+ echo
+ $ECHO "run \`$progname --help | more' for full usage"
+ exit $?
}
-
-# func_help
-# ---------
-# Echo long help message to standard output and exit.
+# func_help [NOEXIT]
+# Echo long help message to standard output and exit,
+# unless 'noexit' is passed as argument.
func_help ()
{
- $debug_cmd
-
- func_usage_message
- $ECHO "$long_help_message"
- exit 0
+ $opt_debug
+
+ $SED -n '/^# Usage:/,/# Report bugs to/ {
+ :print
+ s/^# //
+ s/^# *$//
+ s*\$progname*'$progname'*
+ s*\$host*'"$host"'*
+ s*\$SHELL*'"$SHELL"'*
+ s*\$LTCC*'"$LTCC"'*
+ s*\$LTCFLAGS*'"$LTCFLAGS"'*
+ s*\$LD*'"$LD"'*
+ s/\$with_gnu_ld/'"$with_gnu_ld"'/
+ s/\$automake_version/'"`(${AUTOMAKE-automake} --version) 2>/dev/null |$SED 1q`"'/
+ s/\$autoconf_version/'"`(${AUTOCONF-autoconf} --version) 2>/dev/null |$SED 1q`"'/
+ p
+ d
+ }
+ /^# .* home page:/b print
+ /^# General help using/b print
+ ' < "$progpath"
+ ret=$?
+ if test -z "$1"; then
+ exit $ret
+ fi
}
-
-# func_missing_arg ARGNAME
-# ------------------------
+# func_missing_arg argname
# Echo program name prefixed message to standard error and set global
# exit_cmd.
func_missing_arg ()
{
- $debug_cmd
+ $opt_debug
- func_error "Missing argument for '$1'."
+ func_error "missing argument for $1."
exit_cmd=exit
}
-# func_split_equals STRING
-# ------------------------
-# Set func_split_equals_lhs and func_split_equals_rhs shell variables after
-# splitting STRING at the '=' sign.
-test -z "$_G_HAVE_XSI_OPS" \
- && (eval 'x=a/b/c;
- test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \
- && _G_HAVE_XSI_OPS=yes
-
-if test yes = "$_G_HAVE_XSI_OPS"
-then
- # This is an XSI compatible shell, allowing a faster implementation...
- eval 'func_split_equals ()
- {
- $debug_cmd
-
- func_split_equals_lhs=${1%%=*}
- func_split_equals_rhs=${1#*=}
- test "x$func_split_equals_lhs" = "x$1" \
- && func_split_equals_rhs=
- }'
-else
- # ...otherwise fall back to using expr, which is often a shell builtin.
- func_split_equals ()
- {
- $debug_cmd
-
- func_split_equals_lhs=`expr "x$1" : 'x\([^=]*\)'`
- func_split_equals_rhs=
- test "x$func_split_equals_lhs" = "x$1" \
- || func_split_equals_rhs=`expr "x$1" : 'x[^=]*=\(.*\)$'`
- }
-fi #func_split_equals
-
-
-# func_split_short_opt SHORTOPT
-# -----------------------------
+# func_split_short_opt shortopt
# Set func_split_short_opt_name and func_split_short_opt_arg shell
# variables after splitting SHORTOPT after the 2nd character.
-if test yes = "$_G_HAVE_XSI_OPS"
-then
- # This is an XSI compatible shell, allowing a faster implementation...
- eval 'func_split_short_opt ()
- {
- $debug_cmd
-
- func_split_short_opt_arg=${1#??}
- func_split_short_opt_name=${1%"$func_split_short_opt_arg"}
- }'
-else
- # ...otherwise fall back to using expr, which is often a shell builtin.
- func_split_short_opt ()
- {
- $debug_cmd
-
- func_split_short_opt_name=`expr "x$1" : 'x-\(.\)'`
- func_split_short_opt_arg=`expr "x$1" : 'x-.\(.*\)$'`
- }
-fi #func_split_short_opt
-
-
-# func_usage
-# ----------
-# Echo short help message to standard output and exit.
-func_usage ()
+func_split_short_opt ()
{
- $debug_cmd
+ my_sed_short_opt='1s/^\(..\).*$/\1/;q'
+ my_sed_short_rest='1s/^..\(.*\)$/\1/;q'
- func_usage_message
- $ECHO "Run '$progname --help |${PAGER-more}' for full usage"
- exit 0
-}
+ func_split_short_opt_name=`$ECHO "$1" | $SED "$my_sed_short_opt"`
+ func_split_short_opt_arg=`$ECHO "$1" | $SED "$my_sed_short_rest"`
+} # func_split_short_opt may be replaced by extended shell implementation
-# func_usage_message
-# ------------------
-# Echo short help message to standard output.
-func_usage_message ()
+# func_split_long_opt longopt
+# Set func_split_long_opt_name and func_split_long_opt_arg shell
+# variables after splitting LONGOPT at the `=' sign.
+func_split_long_opt ()
{
- $debug_cmd
+ my_sed_long_opt='1s/^\(--[^=]*\)=.*/\1/;q'
+ my_sed_long_arg='1s/^--[^=]*=//'
- eval \$ECHO \""Usage: $usage"\"
- echo
- $SED -n 's|^# ||
- /^Written by/{
- x;p;x
- }
- h
- /^Written by/q' < "$progpath"
- echo
- eval \$ECHO \""$usage_message"\"
-}
+ func_split_long_opt_name=`$ECHO "$1" | $SED "$my_sed_long_opt"`
+ func_split_long_opt_arg=`$ECHO "$1" | $SED "$my_sed_long_arg"`
+} # func_split_long_opt may be replaced by extended shell implementation
+exit_cmd=:
-# func_version
-# ------------
-# Echo version message to standard output and exit.
-func_version ()
-{
- $debug_cmd
- printf '%s\n' "$progname $scriptversion"
- $SED -n '
- /(C)/!b go
- :more
- /\./!{
- N
- s|\n# | |
- b more
- }
- :go
- /^# Written by /,/# warranty; / {
- s|^# ||
- s|^# *$||
- s|\((C)\)[ 0-9,-]*[ ,-]\([1-9][0-9]* \)|\1 \2|
- p
- }
- /^# Written by / {
- s|^# ||
- p
- }
- /^warranty; /q' < "$progpath"
- exit $?
-}
-# Local variables:
-# mode: shell-script
-# sh-indentation: 2
-# eval: (add-hook 'before-save-hook 'time-stamp)
-# time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC"
-# time-stamp-time-zone: "UTC"
-# End:
+magic="%%%MAGIC variable%%%"
+magic_exe="%%%MAGIC EXE variable%%%"
-# Set a version string.
-scriptversion='(GNU libtool) 2.4.6'
+# Global variables.
+nonopt=
+preserve_args=
+lo2o="s/\\.lo\$/.${objext}/"
+o2lo="s/\\.${objext}\$/.lo/"
+extracted_archives=
+extracted_serial=0
+# If this variable is set in any of the actions, the command in it
+# will be execed at the end. This prevents here-documents from being
+# left over by shells.
+exec_cmd=
-# func_echo ARG...
-# ----------------
-# Libtool also displays the current mode in messages, so override
-# funclib.sh func_echo with this custom definition.
-func_echo ()
+# func_append var value
+# Append VALUE to the end of shell variable VAR.
+func_append ()
{
- $debug_cmd
-
- _G_message=$*
-
- func_echo_IFS=$IFS
- IFS=$nl
- for _G_line in $_G_message; do
- IFS=$func_echo_IFS
- $ECHO "$progname${opt_mode+: $opt_mode}: $_G_line"
- done
- IFS=$func_echo_IFS
-}
+ eval "${1}=\$${1}\${2}"
+} # func_append may be replaced by extended shell implementation
-
-# func_warning ARG...
-# -------------------
-# Libtool warnings are not categorized, so override funclib.sh
-# func_warning with this simpler definition.
-func_warning ()
+# func_append_quoted var value
+# Quote VALUE and append to the end of shell variable VAR, separated
+# by a space.
+func_append_quoted ()
{
- $debug_cmd
-
- $warning_func ${1+"$@"}
-}
+ func_quote_for_eval "${2}"
+ eval "${1}=\$${1}\\ \$func_quote_for_eval_result"
+} # func_append_quoted may be replaced by extended shell implementation
-## ---------------- ##
-## Options parsing. ##
-## ---------------- ##
-
-# Hook in the functions to make sure our own options are parsed during
-# the option parsing loop.
-
-usage='$progpath [OPTION]... [MODE-ARG]...'
-
-# Short help message in response to '-h'.
-usage_message="Options:
- --config show all configuration variables
- --debug enable verbose shell tracing
- -n, --dry-run display commands without modifying any files
- --features display basic configuration information and exit
- --mode=MODE use operation mode MODE
- --no-warnings equivalent to '-Wnone'
- --preserve-dup-deps don't remove duplicate dependency libraries
- --quiet, --silent don't print informational messages
- --tag=TAG use configuration variables from tag TAG
- -v, --verbose print more informational messages than default
- --version print version information
- -W, --warnings=CATEGORY report the warnings falling in CATEGORY [all]
- -h, --help, --help-all print short, long, or detailed help message
-"
-
-# Additional text appended to 'usage_message' in response to '--help'.
-func_help ()
+# func_arith arithmetic-term...
+func_arith ()
{
- $debug_cmd
-
- func_usage_message
- $ECHO "$long_help_message
-
-MODE must be one of the following:
-
- clean remove files from the build directory
- compile compile a source file into a libtool object
- execute automatically set library path, then run a program
- finish complete the installation of libtool libraries
- install install libraries or executables
- link create a library or an executable
- uninstall remove libraries from an installed directory
-
-MODE-ARGS vary depending on the MODE. When passed as first option,
-'--mode=MODE' may be abbreviated as 'MODE' or a unique abbreviation of that.
-Try '$progname --help --mode=MODE' for a more detailed description of MODE.
-
-When reporting a bug, please describe a test case to reproduce it and
-include the following information:
-
- host-triplet: $host
- shell: $SHELL
- compiler: $LTCC
- compiler flags: $LTCFLAGS
- linker: $LD (gnu? $with_gnu_ld)
- version: $progname (GNU libtool) 2.4.6
- automake: `($AUTOMAKE --version) 2>/dev/null |$SED 1q`
- autoconf: `($AUTOCONF --version) 2>/dev/null |$SED 1q`
-
-Report bugs to <bug-libtool@gnu.org>.
-GNU libtool home page: <http://www.gnu.org/software/libtool/>.
-General help using GNU software: <http://www.gnu.org/gethelp/>."
- exit 0
-}
+ func_arith_result=`expr "${@}"`
+} # func_arith may be replaced by extended shell implementation
-# func_lo2o OBJECT-NAME
-# ---------------------
-# Transform OBJECT-NAME from a '.lo' suffix to the platform specific
-# object suffix.
+# func_len string
+# STRING may not start with a hyphen.
+func_len ()
+{
+ func_len_result=`expr "${1}" : ".*" 2>/dev/null || echo $max_cmd_len`
+} # func_len may be replaced by extended shell implementation
-lo2o=s/\\.lo\$/.$objext/
-o2lo=s/\\.$objext\$/.lo/
-if test yes = "$_G_HAVE_XSI_OPS"; then
- eval 'func_lo2o ()
- {
- case $1 in
- *.lo) func_lo2o_result=${1%.lo}.$objext ;;
- * ) func_lo2o_result=$1 ;;
- esac
- }'
+# func_lo2o object
+func_lo2o ()
+{
+ func_lo2o_result=`$ECHO "${1}" | $SED "$lo2o"`
+} # func_lo2o may be replaced by extended shell implementation
- # func_xform LIBOBJ-OR-SOURCE
- # ---------------------------
- # Transform LIBOBJ-OR-SOURCE from a '.o' or '.c' (or otherwise)
- # suffix to a '.lo' libtool-object suffix.
- eval 'func_xform ()
- {
- func_xform_result=${1%.*}.lo
- }'
-else
- # ...otherwise fall back to using sed.
- func_lo2o ()
- {
- func_lo2o_result=`$ECHO "$1" | $SED "$lo2o"`
- }
- func_xform ()
- {
- func_xform_result=`$ECHO "$1" | $SED 's|\.[^.]*$|.lo|'`
- }
-fi
+# func_xform libobj-or-source
+func_xform ()
+{
+ func_xform_result=`$ECHO "${1}" | $SED 's/\.[^.]*$/.lo/'`
+} # func_xform may be replaced by extended shell implementation
-# func_fatal_configuration ARG...
-# -------------------------------
+# func_fatal_configuration arg...
# Echo program name prefixed message to standard error, followed by
# a configuration failure hint, and exit.
func_fatal_configuration ()
{
- func__fatal_error ${1+"$@"} \
- "See the $PACKAGE documentation for more information." \
- "Fatal configuration error."
+ func_error ${1+"$@"}
+ func_error "See the $PACKAGE documentation for more information."
+ func_fatal_error "Fatal configuration error."
}
# func_config
-# -----------
# Display the configuration for all the tags in this script.
func_config ()
{
@@ -2149,19 +915,17 @@ func_config ()
exit $?
}
-
# func_features
-# -------------
# Display the features supported by this script.
func_features ()
{
echo "host: $host"
- if test yes = "$build_libtool_libs"; then
+ if test "$build_libtool_libs" = yes; then
echo "enable shared libraries"
else
echo "disable shared libraries"
fi
- if test yes = "$build_old_libs"; then
+ if test "$build_old_libs" = yes; then
echo "enable static libraries"
else
echo "disable static libraries"
@@ -2170,297 +934,289 @@ func_features ()
exit $?
}
-
-# func_enable_tag TAGNAME
-# -----------------------
+# func_enable_tag tagname
# Verify that TAGNAME is valid, and either flag an error and exit, or
# enable the TAGNAME tag. We also add TAGNAME to the global $taglist
# variable here.
func_enable_tag ()
{
- # Global variable:
- tagname=$1
+ # Global variable:
+ tagname="$1"
- re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$"
- re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$"
- sed_extractcf=/$re_begincf/,/$re_endcf/p
+ re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$"
+ re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$"
+ sed_extractcf="/$re_begincf/,/$re_endcf/p"
- # Validate tagname.
- case $tagname in
- *[!-_A-Za-z0-9,/]*)
- func_fatal_error "invalid tag name: $tagname"
- ;;
- esac
+ # Validate tagname.
+ case $tagname in
+ *[!-_A-Za-z0-9,/]*)
+ func_fatal_error "invalid tag name: $tagname"
+ ;;
+ esac
- # Don't test for the "default" C tag, as we know it's
- # there but not specially marked.
- case $tagname in
- CC) ;;
+ # Don't test for the "default" C tag, as we know it's
+ # there but not specially marked.
+ case $tagname in
+ CC) ;;
*)
- if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then
- taglist="$taglist $tagname"
-
- # Evaluate the configuration. Be careful to quote the path
- # and the sed script, to avoid splitting on whitespace, but
- # also don't use non-portable quotes within backquotes within
- # quotes we have to do it in 2 steps:
- extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"`
- eval "$extractedcf"
- else
- func_error "ignoring unknown tag $tagname"
- fi
- ;;
- esac
+ if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then
+ taglist="$taglist $tagname"
+
+ # Evaluate the configuration. Be careful to quote the path
+ # and the sed script, to avoid splitting on whitespace, but
+ # also don't use non-portable quotes within backquotes within
+ # quotes we have to do it in 2 steps:
+ extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"`
+ eval "$extractedcf"
+ else
+ func_error "ignoring unknown tag $tagname"
+ fi
+ ;;
+ esac
}
-
# func_check_version_match
-# ------------------------
# Ensure that we are using m4 macros, and libtool script from the same
# release of libtool.
func_check_version_match ()
{
- if test "$package_revision" != "$macro_revision"; then
- if test "$VERSION" != "$macro_version"; then
- if test -z "$macro_version"; then
- cat >&2 <<_LT_EOF
+ if test "$package_revision" != "$macro_revision"; then
+ if test "$VERSION" != "$macro_version"; then
+ if test -z "$macro_version"; then
+ cat >&2 <<_LT_EOF
$progname: Version mismatch error. This is $PACKAGE $VERSION, but the
$progname: definition of this LT_INIT comes from an older release.
$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION
$progname: and run autoconf again.
_LT_EOF
- else
- cat >&2 <<_LT_EOF
+ else
+ cat >&2 <<_LT_EOF
$progname: Version mismatch error. This is $PACKAGE $VERSION, but the
$progname: definition of this LT_INIT comes from $PACKAGE $macro_version.
$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION
$progname: and run autoconf again.
_LT_EOF
- fi
- else
- cat >&2 <<_LT_EOF
+ fi
+ else
+ cat >&2 <<_LT_EOF
$progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision,
$progname: but the definition of this LT_INIT comes from revision $macro_revision.
$progname: You should recreate aclocal.m4 with macros from revision $package_revision
$progname: of $PACKAGE $VERSION and run autoconf again.
_LT_EOF
- fi
-
- exit $EXIT_MISMATCH
fi
-}
+ exit $EXIT_MISMATCH
+ fi
+}
-# libtool_options_prep [ARG]...
-# -----------------------------
-# Preparation for options parsed by libtool.
-libtool_options_prep ()
-{
- $debug_mode
- # Option defaults:
- opt_config=false
- opt_dlopen=
- opt_dry_run=false
- opt_help=false
- opt_mode=
- opt_preserve_dup_deps=false
- opt_quiet=false
+# Shorthand for --mode=foo, only valid as the first argument
+case $1 in
+clean|clea|cle|cl)
+ shift; set dummy --mode clean ${1+"$@"}; shift
+ ;;
+compile|compil|compi|comp|com|co|c)
+ shift; set dummy --mode compile ${1+"$@"}; shift
+ ;;
+execute|execut|execu|exec|exe|ex|e)
+ shift; set dummy --mode execute ${1+"$@"}; shift
+ ;;
+finish|finis|fini|fin|fi|f)
+ shift; set dummy --mode finish ${1+"$@"}; shift
+ ;;
+install|instal|insta|inst|ins|in|i)
+ shift; set dummy --mode install ${1+"$@"}; shift
+ ;;
+link|lin|li|l)
+ shift; set dummy --mode link ${1+"$@"}; shift
+ ;;
+uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u)
+ shift; set dummy --mode uninstall ${1+"$@"}; shift
+ ;;
+esac
- nonopt=
- preserve_args=
- # Shorthand for --mode=foo, only valid as the first argument
- case $1 in
- clean|clea|cle|cl)
- shift; set dummy --mode clean ${1+"$@"}; shift
- ;;
- compile|compil|compi|comp|com|co|c)
- shift; set dummy --mode compile ${1+"$@"}; shift
- ;;
- execute|execut|execu|exec|exe|ex|e)
- shift; set dummy --mode execute ${1+"$@"}; shift
- ;;
- finish|finis|fini|fin|fi|f)
- shift; set dummy --mode finish ${1+"$@"}; shift
- ;;
- install|instal|insta|inst|ins|in|i)
- shift; set dummy --mode install ${1+"$@"}; shift
- ;;
- link|lin|li|l)
- shift; set dummy --mode link ${1+"$@"}; shift
- ;;
- uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u)
- shift; set dummy --mode uninstall ${1+"$@"}; shift
- ;;
- esac
- # Pass back the list of options.
- func_quote_for_eval ${1+"$@"}
- libtool_options_prep_result=$func_quote_for_eval_result
-}
-func_add_hook func_options_prep libtool_options_prep
+# Option defaults:
+opt_debug=:
+opt_dry_run=false
+opt_config=false
+opt_preserve_dup_deps=false
+opt_features=false
+opt_finish=false
+opt_help=false
+opt_help_all=false
+opt_silent=:
+opt_warning=:
+opt_verbose=:
+opt_silent=false
+opt_verbose=false
-# libtool_parse_options [ARG]...
-# ---------------------------------
-# Provide handling for libtool specific options.
-libtool_parse_options ()
+# Parse options once, thoroughly. This comes as soon as possible in the
+# script to make things like `--version' happen as quickly as we can.
{
- $debug_cmd
+ # this just eases exit handling
+ while test $# -gt 0; do
+ opt="$1"
+ shift
+ case $opt in
+ --debug|-x) opt_debug='set -x'
+ func_echo "enabling shell trace mode"
+ $opt_debug
+ ;;
+ --dry-run|--dryrun|-n)
+ opt_dry_run=:
+ ;;
+ --config)
+ opt_config=:
+func_config
+ ;;
+ --dlopen|-dlopen)
+ optarg="$1"
+ opt_dlopen="${opt_dlopen+$opt_dlopen
+}$optarg"
+ shift
+ ;;
+ --preserve-dup-deps)
+ opt_preserve_dup_deps=:
+ ;;
+ --features)
+ opt_features=:
+func_features
+ ;;
+ --finish)
+ opt_finish=:
+set dummy --mode finish ${1+"$@"}; shift
+ ;;
+ --help)
+ opt_help=:
+ ;;
+ --help-all)
+ opt_help_all=:
+opt_help=': help-all'
+ ;;
+ --mode)
+ test $# = 0 && func_missing_arg $opt && break
+ optarg="$1"
+ opt_mode="$optarg"
+case $optarg in
+ # Valid mode arguments:
+ clean|compile|execute|finish|install|link|relink|uninstall) ;;
+
+ # Catch anything else as an error
+ *) func_error "invalid argument for $opt"
+ exit_cmd=exit
+ break
+ ;;
+esac
+ shift
+ ;;
+ --no-silent|--no-quiet)
+ opt_silent=false
+func_append preserve_args " $opt"
+ ;;
+ --no-warning|--no-warn)
+ opt_warning=false
+func_append preserve_args " $opt"
+ ;;
+ --no-verbose)
+ opt_verbose=false
+func_append preserve_args " $opt"
+ ;;
+ --silent|--quiet)
+ opt_silent=:
+func_append preserve_args " $opt"
+ opt_verbose=false
+ ;;
+ --verbose|-v)
+ opt_verbose=:
+func_append preserve_args " $opt"
+opt_silent=false
+ ;;
+ --tag)
+ test $# = 0 && func_missing_arg $opt && break
+ optarg="$1"
+ opt_tag="$optarg"
+func_append preserve_args " $opt $optarg"
+func_enable_tag "$optarg"
+ shift
+ ;;
+
+ -\?|-h) func_usage ;;
+ --help) func_help ;;
+ --version) func_version ;;
+
+ # Separate optargs to long options:
+ --*=*)
+ func_split_long_opt "$opt"
+ set dummy "$func_split_long_opt_name" "$func_split_long_opt_arg" ${1+"$@"}
+ shift
+ ;;
+
+ # Separate non-argument short options:
+ -\?*|-h*|-n*|-v*)
+ func_split_short_opt "$opt"
+ set dummy "$func_split_short_opt_name" "-$func_split_short_opt_arg" ${1+"$@"}
+ shift
+ ;;
+
+ --) break ;;
+ -*) func_fatal_help "unrecognized option \`$opt'" ;;
+ *) set dummy "$opt" ${1+"$@"}; shift; break ;;
+ esac
+ done
- # Perform our own loop to consume as many options as possible in
- # each iteration.
- while test $# -gt 0; do
- _G_opt=$1
- shift
- case $_G_opt in
- --dry-run|--dryrun|-n)
- opt_dry_run=:
- ;;
-
- --config) func_config ;;
-
- --dlopen|-dlopen)
- opt_dlopen="${opt_dlopen+$opt_dlopen
-}$1"
- shift
- ;;
-
- --preserve-dup-deps)
- opt_preserve_dup_deps=: ;;
-
- --features) func_features ;;
-
- --finish) set dummy --mode finish ${1+"$@"}; shift ;;
-
- --help) opt_help=: ;;
-
- --help-all) opt_help=': help-all' ;;
-
- --mode) test $# = 0 && func_missing_arg $_G_opt && break
- opt_mode=$1
- case $1 in
- # Valid mode arguments:
- clean|compile|execute|finish|install|link|relink|uninstall) ;;
-
- # Catch anything else as an error
- *) func_error "invalid argument for $_G_opt"
- exit_cmd=exit
- break
- ;;
- esac
- shift
- ;;
-
- --no-silent|--no-quiet)
- opt_quiet=false
- func_append preserve_args " $_G_opt"
- ;;
-
- --no-warnings|--no-warning|--no-warn)
- opt_warning=false
- func_append preserve_args " $_G_opt"
- ;;
-
- --no-verbose)
- opt_verbose=false
- func_append preserve_args " $_G_opt"
- ;;
-
- --silent|--quiet)
- opt_quiet=:
- opt_verbose=false
- func_append preserve_args " $_G_opt"
- ;;
-
- --tag) test $# = 0 && func_missing_arg $_G_opt && break
- opt_tag=$1
- func_append preserve_args " $_G_opt $1"
- func_enable_tag "$1"
- shift
- ;;
-
- --verbose|-v) opt_quiet=false
- opt_verbose=:
- func_append preserve_args " $_G_opt"
- ;;
-
- # An option not handled by this hook function:
- *) set dummy "$_G_opt" ${1+"$@"}; shift; break ;;
- esac
- done
+ # Validate options:
+ # save first non-option argument
+ if test "$#" -gt 0; then
+ nonopt="$opt"
+ shift
+ fi
- # save modified positional parameters for caller
- func_quote_for_eval ${1+"$@"}
- libtool_parse_options_result=$func_quote_for_eval_result
-}
-func_add_hook func_parse_options libtool_parse_options
+ # preserve --debug
+ test "$opt_debug" = : || func_append preserve_args " --debug"
+ case $host in
+ *cygwin* | *mingw* | *pw32* | *cegcc*)
+ # don't eliminate duplications in $postdeps and $predeps
+ opt_duplicate_compiler_generated_deps=:
+ ;;
+ *)
+ opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps
+ ;;
+ esac
+ $opt_help || {
+ # Sanity checks first:
+ func_check_version_match
-# libtool_validate_options [ARG]...
-# ---------------------------------
-# Perform any sanity checks on option settings and/or unconsumed
-# arguments.
-libtool_validate_options ()
-{
- # save first non-option argument
- if test 0 -lt $#; then
- nonopt=$1
- shift
+ if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then
+ func_fatal_configuration "not configured to build any kind of library"
fi
- # preserve --debug
- test : = "$debug_cmd" || func_append preserve_args " --debug"
-
- case $host in
- # Solaris2 added to fix http://debbugs.gnu.org/cgi/bugreport.cgi?bug=16452
- # see also: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59788
- *cygwin* | *mingw* | *pw32* | *cegcc* | *solaris2* | *os2*)
- # don't eliminate duplications in $postdeps and $predeps
- opt_duplicate_compiler_generated_deps=:
- ;;
- *)
- opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps
- ;;
- esac
-
- $opt_help || {
- # Sanity checks first:
- func_check_version_match
+ # Darwin sucks
+ eval std_shrext=\"$shrext_cmds\"
- test yes != "$build_libtool_libs" \
- && test yes != "$build_old_libs" \
- && func_fatal_configuration "not configured to build any kind of library"
-
- # Darwin sucks
- eval std_shrext=\"$shrext_cmds\"
+ # Only execute mode is allowed to have -dlopen flags.
+ if test -n "$opt_dlopen" && test "$opt_mode" != execute; then
+ func_error "unrecognized option \`-dlopen'"
+ $ECHO "$help" 1>&2
+ exit $EXIT_FAILURE
+ fi
- # Only execute mode is allowed to have -dlopen flags.
- if test -n "$opt_dlopen" && test execute != "$opt_mode"; then
- func_error "unrecognized option '-dlopen'"
- $ECHO "$help" 1>&2
- exit $EXIT_FAILURE
- fi
+ # Change the help message to a mode-specific one.
+ generic_help="$help"
+ help="Try \`$progname --help --mode=$opt_mode' for more information."
+ }
- # Change the help message to a mode-specific one.
- generic_help=$help
- help="Try '$progname --help --mode=$opt_mode' for more information."
- }
- # Pass back the unparsed argument list
- func_quote_for_eval ${1+"$@"}
- libtool_validate_options_result=$func_quote_for_eval_result
+ # Bail if the options were screwed
+ $exit_cmd $EXIT_FAILURE
}
-func_add_hook func_validate_options libtool_validate_options
-
-# Process options as early as possible so that --help and --version
-# can return quickly.
-func_options ${1+"$@"}
-eval set dummy "$func_options_result"; shift
@@ -2468,52 +1224,24 @@ eval set dummy "$func_options_result"; shift
## Main. ##
## ----------- ##
-magic='%%%MAGIC variable%%%'
-magic_exe='%%%MAGIC EXE variable%%%'
-
-# Global variables.
-extracted_archives=
-extracted_serial=0
-
-# If this variable is set in any of the actions, the command in it
-# will be execed at the end. This prevents here-documents from being
-# left over by shells.
-exec_cmd=
-
-
-# A function that is used when there is no print builtin or printf.
-func_fallback_echo ()
-{
- eval 'cat <<_LTECHO_EOF
-$1
-_LTECHO_EOF'
-}
-
-# func_generated_by_libtool
-# True iff stdin has been generated by Libtool. This function is only
-# a basic sanity check; it will hardly flush out determined imposters.
-func_generated_by_libtool_p ()
-{
- $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1
-}
-
# func_lalib_p file
-# True iff FILE is a libtool '.la' library or '.lo' object file.
+# True iff FILE is a libtool `.la' library or `.lo' object file.
# This function is only a basic sanity check; it will hardly flush out
# determined imposters.
func_lalib_p ()
{
test -f "$1" &&
- $SED -e 4q "$1" 2>/dev/null | func_generated_by_libtool_p
+ $SED -e 4q "$1" 2>/dev/null \
+ | $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1
}
# func_lalib_unsafe_p file
-# True iff FILE is a libtool '.la' library or '.lo' object file.
+# True iff FILE is a libtool `.la' library or `.lo' object file.
# This function implements the same check as func_lalib_p without
# resorting to external programs. To this end, it redirects stdin and
# closes it afterwards, without saving the original file descriptor.
# As a safety measure, use it only where a negative result would be
-# fatal anyway. Works if 'file' does not exist.
+# fatal anyway. Works if `file' does not exist.
func_lalib_unsafe_p ()
{
lalib_p=no
@@ -2521,13 +1249,13 @@ func_lalib_unsafe_p ()
for lalib_p_l in 1 2 3 4
do
read lalib_p_line
- case $lalib_p_line in
+ case "$lalib_p_line" in
\#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;;
esac
done
exec 0<&5 5<&-
fi
- test yes = "$lalib_p"
+ test "$lalib_p" = yes
}
# func_ltwrapper_script_p file
@@ -2536,8 +1264,7 @@ func_lalib_unsafe_p ()
# determined imposters.
func_ltwrapper_script_p ()
{
- test -f "$1" &&
- $lt_truncate_bin < "$1" 2>/dev/null | func_generated_by_libtool_p
+ func_lalib_p "$1"
}
# func_ltwrapper_executable_p file
@@ -2562,7 +1289,7 @@ func_ltwrapper_scriptname ()
{
func_dirname_and_basename "$1" "" "."
func_stripname '' '.exe' "$func_basename_result"
- func_ltwrapper_scriptname_result=$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper
+ func_ltwrapper_scriptname_result="$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper"
}
# func_ltwrapper_p file
@@ -2581,13 +1308,11 @@ func_ltwrapper_p ()
# FAIL_CMD may read-access the current command in variable CMD!
func_execute_cmds ()
{
- $debug_cmd
-
+ $opt_debug
save_ifs=$IFS; IFS='~'
for cmd in $1; do
- IFS=$sp$nl
- eval cmd=\"$cmd\"
IFS=$save_ifs
+ eval cmd=\"$cmd\"
func_show_eval "$cmd" "${2-:}"
done
IFS=$save_ifs
@@ -2599,11 +1324,10 @@ func_execute_cmds ()
# Note that it is not necessary on cygwin/mingw to append a dot to
# FILE even if both FILE and FILE.exe exist: automatic-append-.exe
# behavior happens only for exec(3), not for open(2)! Also, sourcing
-# 'FILE.' does not work on cygwin managed mounts.
+# `FILE.' does not work on cygwin managed mounts.
func_source ()
{
- $debug_cmd
-
+ $opt_debug
case $1 in
*/* | *\\*) . "$1" ;;
*) . "./$1" ;;
@@ -2630,10 +1354,10 @@ func_resolve_sysroot ()
# store the result into func_replace_sysroot_result.
func_replace_sysroot ()
{
- case $lt_sysroot:$1 in
+ case "$lt_sysroot:$1" in
?*:"$lt_sysroot"*)
func_stripname "$lt_sysroot" '' "$1"
- func_replace_sysroot_result='='$func_stripname_result
+ func_replace_sysroot_result="=$func_stripname_result"
;;
*)
# Including no sysroot.
@@ -2650,8 +1374,7 @@ func_replace_sysroot ()
# arg is usually of the form 'gcc ...'
func_infer_tag ()
{
- $debug_cmd
-
+ $opt_debug
if test -n "$available_tags" && test -z "$tagname"; then
CC_quoted=
for arg in $CC; do
@@ -2670,7 +1393,7 @@ func_infer_tag ()
for z in $available_tags; do
if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then
# Evaluate the configuration.
- eval "`$SED -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`"
+ eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`"
CC_quoted=
for arg in $CC; do
# Double-quote args containing other shell metacharacters.
@@ -2695,7 +1418,7 @@ func_infer_tag ()
# line option must be used.
if test -z "$tagname"; then
func_echo "unable to infer tagged configuration"
- func_fatal_error "specify a tag with '--tag'"
+ func_fatal_error "specify a tag with \`--tag'"
# else
# func_verbose "using $tagname tagged configuration"
fi
@@ -2711,15 +1434,15 @@ func_infer_tag ()
# but don't create it if we're doing a dry run.
func_write_libtool_object ()
{
- write_libobj=$1
- if test yes = "$build_libtool_libs"; then
- write_lobj=\'$2\'
+ write_libobj=${1}
+ if test "$build_libtool_libs" = yes; then
+ write_lobj=\'${2}\'
else
write_lobj=none
fi
- if test yes = "$build_old_libs"; then
- write_oldobj=\'$3\'
+ if test "$build_old_libs" = yes; then
+ write_oldobj=\'${3}\'
else
write_oldobj=none
fi
@@ -2727,7 +1450,7 @@ func_write_libtool_object ()
$opt_dry_run || {
cat >${write_libobj}T <<EOF
# $write_libobj - a libtool object file
-# Generated by $PROGRAM (GNU $PACKAGE) $VERSION
+# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
#
# Please DO NOT delete this file!
# It is necessary for linking the library.
@@ -2739,7 +1462,7 @@ pic_object=$write_lobj
non_pic_object=$write_oldobj
EOF
- $MV "${write_libobj}T" "$write_libobj"
+ $MV "${write_libobj}T" "${write_libobj}"
}
}
@@ -2759,9 +1482,8 @@ EOF
# be empty on error (or when ARG is empty)
func_convert_core_file_wine_to_w32 ()
{
- $debug_cmd
-
- func_convert_core_file_wine_to_w32_result=$1
+ $opt_debug
+ func_convert_core_file_wine_to_w32_result="$1"
if test -n "$1"; then
# Unfortunately, winepath does not exit with a non-zero error code, so we
# are forced to check the contents of stdout. On the other hand, if the
@@ -2769,9 +1491,9 @@ func_convert_core_file_wine_to_w32 ()
# *an error message* to stdout. So we must check for both error code of
# zero AND non-empty stdout, which explains the odd construction:
func_convert_core_file_wine_to_w32_tmp=`winepath -w "$1" 2>/dev/null`
- if test "$?" -eq 0 && test -n "$func_convert_core_file_wine_to_w32_tmp"; then
+ if test "$?" -eq 0 && test -n "${func_convert_core_file_wine_to_w32_tmp}"; then
func_convert_core_file_wine_to_w32_result=`$ECHO "$func_convert_core_file_wine_to_w32_tmp" |
- $SED -e "$sed_naive_backslashify"`
+ $SED -e "$lt_sed_naive_backslashify"`
else
func_convert_core_file_wine_to_w32_result=
fi
@@ -2792,19 +1514,18 @@ func_convert_core_file_wine_to_w32 ()
# are convertible, then the result may be empty.
func_convert_core_path_wine_to_w32 ()
{
- $debug_cmd
-
+ $opt_debug
# unfortunately, winepath doesn't convert paths, only file names
- func_convert_core_path_wine_to_w32_result=
+ func_convert_core_path_wine_to_w32_result=""
if test -n "$1"; then
oldIFS=$IFS
IFS=:
for func_convert_core_path_wine_to_w32_f in $1; do
IFS=$oldIFS
func_convert_core_file_wine_to_w32 "$func_convert_core_path_wine_to_w32_f"
- if test -n "$func_convert_core_file_wine_to_w32_result"; then
+ if test -n "$func_convert_core_file_wine_to_w32_result" ; then
if test -z "$func_convert_core_path_wine_to_w32_result"; then
- func_convert_core_path_wine_to_w32_result=$func_convert_core_file_wine_to_w32_result
+ func_convert_core_path_wine_to_w32_result="$func_convert_core_file_wine_to_w32_result"
else
func_append func_convert_core_path_wine_to_w32_result ";$func_convert_core_file_wine_to_w32_result"
fi
@@ -2833,8 +1554,7 @@ func_convert_core_path_wine_to_w32 ()
# environment variable; do not put it in $PATH.
func_cygpath ()
{
- $debug_cmd
-
+ $opt_debug
if test -n "$LT_CYGPATH" && test -f "$LT_CYGPATH"; then
func_cygpath_result=`$LT_CYGPATH "$@" 2>/dev/null`
if test "$?" -ne 0; then
@@ -2843,7 +1563,7 @@ func_cygpath ()
fi
else
func_cygpath_result=
- func_error "LT_CYGPATH is empty or specifies non-existent file: '$LT_CYGPATH'"
+ func_error "LT_CYGPATH is empty or specifies non-existent file: \`$LT_CYGPATH'"
fi
}
#end: func_cygpath
@@ -2854,11 +1574,10 @@ func_cygpath ()
# result in func_convert_core_msys_to_w32_result.
func_convert_core_msys_to_w32 ()
{
- $debug_cmd
-
+ $opt_debug
# awkward: cmd appends spaces to result
func_convert_core_msys_to_w32_result=`( cmd //c echo "$1" ) 2>/dev/null |
- $SED -e 's/[ ]*$//' -e "$sed_naive_backslashify"`
+ $SED -e 's/[ ]*$//' -e "$lt_sed_naive_backslashify"`
}
#end: func_convert_core_msys_to_w32
@@ -2869,14 +1588,13 @@ func_convert_core_msys_to_w32 ()
# func_to_host_file_result to ARG1).
func_convert_file_check ()
{
- $debug_cmd
-
- if test -z "$2" && test -n "$1"; then
+ $opt_debug
+ if test -z "$2" && test -n "$1" ; then
func_error "Could not determine host file name corresponding to"
- func_error " '$1'"
+ func_error " \`$1'"
func_error "Continuing, but uninstalled executables may not work."
# Fallback:
- func_to_host_file_result=$1
+ func_to_host_file_result="$1"
fi
}
# end func_convert_file_check
@@ -2888,11 +1606,10 @@ func_convert_file_check ()
# func_to_host_file_result to a simplistic fallback value (see below).
func_convert_path_check ()
{
- $debug_cmd
-
+ $opt_debug
if test -z "$4" && test -n "$3"; then
func_error "Could not determine the host path corresponding to"
- func_error " '$3'"
+ func_error " \`$3'"
func_error "Continuing, but uninstalled executables may not work."
# Fallback. This is a deliberately simplistic "conversion" and
# should not be "improved". See libtool.info.
@@ -2901,7 +1618,7 @@ func_convert_path_check ()
func_to_host_path_result=`echo "$3" |
$SED -e "$lt_replace_pathsep_chars"`
else
- func_to_host_path_result=$3
+ func_to_host_path_result="$3"
fi
fi
}
@@ -2913,10 +1630,9 @@ func_convert_path_check ()
# and appending REPL if ORIG matches BACKPAT.
func_convert_path_front_back_pathsep ()
{
- $debug_cmd
-
+ $opt_debug
case $4 in
- $1 ) func_to_host_path_result=$3$func_to_host_path_result
+ $1 ) func_to_host_path_result="$3$func_to_host_path_result"
;;
esac
case $4 in
@@ -2930,7 +1646,7 @@ func_convert_path_front_back_pathsep ()
##################################################
# $build to $host FILE NAME CONVERSION FUNCTIONS #
##################################################
-# invoked via '$to_host_file_cmd ARG'
+# invoked via `$to_host_file_cmd ARG'
#
# In each case, ARG is the path to be converted from $build to $host format.
# Result will be available in $func_to_host_file_result.
@@ -2941,8 +1657,7 @@ func_convert_path_front_back_pathsep ()
# in func_to_host_file_result.
func_to_host_file ()
{
- $debug_cmd
-
+ $opt_debug
$to_host_file_cmd "$1"
}
# end func_to_host_file
@@ -2954,8 +1669,7 @@ func_to_host_file ()
# in (the comma separated) LAZY, no conversion takes place.
func_to_tool_file ()
{
- $debug_cmd
-
+ $opt_debug
case ,$2, in
*,"$to_tool_file_cmd",*)
func_to_tool_file_result=$1
@@ -2973,7 +1687,7 @@ func_to_tool_file ()
# Copy ARG to func_to_host_file_result.
func_convert_file_noop ()
{
- func_to_host_file_result=$1
+ func_to_host_file_result="$1"
}
# end func_convert_file_noop
@@ -2984,12 +1698,11 @@ func_convert_file_noop ()
# func_to_host_file_result.
func_convert_file_msys_to_w32 ()
{
- $debug_cmd
-
- func_to_host_file_result=$1
+ $opt_debug
+ func_to_host_file_result="$1"
if test -n "$1"; then
func_convert_core_msys_to_w32 "$1"
- func_to_host_file_result=$func_convert_core_msys_to_w32_result
+ func_to_host_file_result="$func_convert_core_msys_to_w32_result"
fi
func_convert_file_check "$1" "$func_to_host_file_result"
}
@@ -3001,9 +1714,8 @@ func_convert_file_msys_to_w32 ()
# func_to_host_file_result.
func_convert_file_cygwin_to_w32 ()
{
- $debug_cmd
-
- func_to_host_file_result=$1
+ $opt_debug
+ func_to_host_file_result="$1"
if test -n "$1"; then
# because $build is cygwin, we call "the" cygpath in $PATH; no need to use
# LT_CYGPATH in this case.
@@ -3019,12 +1731,11 @@ func_convert_file_cygwin_to_w32 ()
# and a working winepath. Returns result in func_to_host_file_result.
func_convert_file_nix_to_w32 ()
{
- $debug_cmd
-
- func_to_host_file_result=$1
+ $opt_debug
+ func_to_host_file_result="$1"
if test -n "$1"; then
func_convert_core_file_wine_to_w32 "$1"
- func_to_host_file_result=$func_convert_core_file_wine_to_w32_result
+ func_to_host_file_result="$func_convert_core_file_wine_to_w32_result"
fi
func_convert_file_check "$1" "$func_to_host_file_result"
}
@@ -3036,13 +1747,12 @@ func_convert_file_nix_to_w32 ()
# Returns result in func_to_host_file_result.
func_convert_file_msys_to_cygwin ()
{
- $debug_cmd
-
- func_to_host_file_result=$1
+ $opt_debug
+ func_to_host_file_result="$1"
if test -n "$1"; then
func_convert_core_msys_to_w32 "$1"
func_cygpath -u "$func_convert_core_msys_to_w32_result"
- func_to_host_file_result=$func_cygpath_result
+ func_to_host_file_result="$func_cygpath_result"
fi
func_convert_file_check "$1" "$func_to_host_file_result"
}
@@ -3055,14 +1765,13 @@ func_convert_file_msys_to_cygwin ()
# in func_to_host_file_result.
func_convert_file_nix_to_cygwin ()
{
- $debug_cmd
-
- func_to_host_file_result=$1
+ $opt_debug
+ func_to_host_file_result="$1"
if test -n "$1"; then
# convert from *nix to w32, then use cygpath to convert from w32 to cygwin.
func_convert_core_file_wine_to_w32 "$1"
func_cygpath -u "$func_convert_core_file_wine_to_w32_result"
- func_to_host_file_result=$func_cygpath_result
+ func_to_host_file_result="$func_cygpath_result"
fi
func_convert_file_check "$1" "$func_to_host_file_result"
}
@@ -3072,7 +1781,7 @@ func_convert_file_nix_to_cygwin ()
#############################################
# $build to $host PATH CONVERSION FUNCTIONS #
#############################################
-# invoked via '$to_host_path_cmd ARG'
+# invoked via `$to_host_path_cmd ARG'
#
# In each case, ARG is the path to be converted from $build to $host format.
# The result will be available in $func_to_host_path_result.
@@ -3096,11 +1805,10 @@ func_convert_file_nix_to_cygwin ()
to_host_path_cmd=
func_init_to_host_path_cmd ()
{
- $debug_cmd
-
+ $opt_debug
if test -z "$to_host_path_cmd"; then
func_stripname 'func_convert_file_' '' "$to_host_file_cmd"
- to_host_path_cmd=func_convert_path_$func_stripname_result
+ to_host_path_cmd="func_convert_path_${func_stripname_result}"
fi
}
@@ -3110,8 +1818,7 @@ func_init_to_host_path_cmd ()
# in func_to_host_path_result.
func_to_host_path ()
{
- $debug_cmd
-
+ $opt_debug
func_init_to_host_path_cmd
$to_host_path_cmd "$1"
}
@@ -3122,7 +1829,7 @@ func_to_host_path ()
# Copy ARG to func_to_host_path_result.
func_convert_path_noop ()
{
- func_to_host_path_result=$1
+ func_to_host_path_result="$1"
}
# end func_convert_path_noop
@@ -3133,9 +1840,8 @@ func_convert_path_noop ()
# func_to_host_path_result.
func_convert_path_msys_to_w32 ()
{
- $debug_cmd
-
- func_to_host_path_result=$1
+ $opt_debug
+ func_to_host_path_result="$1"
if test -n "$1"; then
# Remove leading and trailing path separator characters from ARG. MSYS
# behavior is inconsistent here; cygpath turns them into '.;' and ';.';
@@ -3143,7 +1849,7 @@ func_convert_path_msys_to_w32 ()
func_stripname : : "$1"
func_to_host_path_tmp1=$func_stripname_result
func_convert_core_msys_to_w32 "$func_to_host_path_tmp1"
- func_to_host_path_result=$func_convert_core_msys_to_w32_result
+ func_to_host_path_result="$func_convert_core_msys_to_w32_result"
func_convert_path_check : ";" \
"$func_to_host_path_tmp1" "$func_to_host_path_result"
func_convert_path_front_back_pathsep ":*" "*:" ";" "$1"
@@ -3157,9 +1863,8 @@ func_convert_path_msys_to_w32 ()
# func_to_host_file_result.
func_convert_path_cygwin_to_w32 ()
{
- $debug_cmd
-
- func_to_host_path_result=$1
+ $opt_debug
+ func_to_host_path_result="$1"
if test -n "$1"; then
# See func_convert_path_msys_to_w32:
func_stripname : : "$1"
@@ -3178,15 +1883,14 @@ func_convert_path_cygwin_to_w32 ()
# a working winepath. Returns result in func_to_host_file_result.
func_convert_path_nix_to_w32 ()
{
- $debug_cmd
-
- func_to_host_path_result=$1
+ $opt_debug
+ func_to_host_path_result="$1"
if test -n "$1"; then
# See func_convert_path_msys_to_w32:
func_stripname : : "$1"
func_to_host_path_tmp1=$func_stripname_result
func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1"
- func_to_host_path_result=$func_convert_core_path_wine_to_w32_result
+ func_to_host_path_result="$func_convert_core_path_wine_to_w32_result"
func_convert_path_check : ";" \
"$func_to_host_path_tmp1" "$func_to_host_path_result"
func_convert_path_front_back_pathsep ":*" "*:" ";" "$1"
@@ -3200,16 +1904,15 @@ func_convert_path_nix_to_w32 ()
# Returns result in func_to_host_file_result.
func_convert_path_msys_to_cygwin ()
{
- $debug_cmd
-
- func_to_host_path_result=$1
+ $opt_debug
+ func_to_host_path_result="$1"
if test -n "$1"; then
# See func_convert_path_msys_to_w32:
func_stripname : : "$1"
func_to_host_path_tmp1=$func_stripname_result
func_convert_core_msys_to_w32 "$func_to_host_path_tmp1"
func_cygpath -u -p "$func_convert_core_msys_to_w32_result"
- func_to_host_path_result=$func_cygpath_result
+ func_to_host_path_result="$func_cygpath_result"
func_convert_path_check : : \
"$func_to_host_path_tmp1" "$func_to_host_path_result"
func_convert_path_front_back_pathsep ":*" "*:" : "$1"
@@ -3224,9 +1927,8 @@ func_convert_path_msys_to_cygwin ()
# func_to_host_file_result.
func_convert_path_nix_to_cygwin ()
{
- $debug_cmd
-
- func_to_host_path_result=$1
+ $opt_debug
+ func_to_host_path_result="$1"
if test -n "$1"; then
# Remove leading and trailing path separator characters from
# ARG. msys behavior is inconsistent here, cygpath turns them
@@ -3235,7 +1937,7 @@ func_convert_path_nix_to_cygwin ()
func_to_host_path_tmp1=$func_stripname_result
func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1"
func_cygpath -u -p "$func_convert_core_path_wine_to_w32_result"
- func_to_host_path_result=$func_cygpath_result
+ func_to_host_path_result="$func_cygpath_result"
func_convert_path_check : : \
"$func_to_host_path_tmp1" "$func_to_host_path_result"
func_convert_path_front_back_pathsep ":*" "*:" : "$1"
@@ -3244,31 +1946,13 @@ func_convert_path_nix_to_cygwin ()
# end func_convert_path_nix_to_cygwin
-# func_dll_def_p FILE
-# True iff FILE is a Windows DLL '.def' file.
-# Keep in sync with _LT_DLL_DEF_P in libtool.m4
-func_dll_def_p ()
-{
- $debug_cmd
-
- func_dll_def_p_tmp=`$SED -n \
- -e 's/^[ ]*//' \
- -e '/^\(;.*\)*$/d' \
- -e 's/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p' \
- -e q \
- "$1"`
- test DEF = "$func_dll_def_p_tmp"
-}
-
-
# func_mode_compile arg...
func_mode_compile ()
{
- $debug_cmd
-
+ $opt_debug
# Get the compilation command and the source file.
base_compile=
- srcfile=$nonopt # always keep a non-empty value in "srcfile"
+ srcfile="$nonopt" # always keep a non-empty value in "srcfile"
suppress_opt=yes
suppress_output=
arg_mode=normal
@@ -3281,12 +1965,12 @@ func_mode_compile ()
case $arg_mode in
arg )
# do not "continue". Instead, add this to base_compile
- lastarg=$arg
+ lastarg="$arg"
arg_mode=normal
;;
target )
- libobj=$arg
+ libobj="$arg"
arg_mode=normal
continue
;;
@@ -3296,7 +1980,7 @@ func_mode_compile ()
case $arg in
-o)
test -n "$libobj" && \
- func_fatal_error "you cannot specify '-o' more than once"
+ func_fatal_error "you cannot specify \`-o' more than once"
arg_mode=target
continue
;;
@@ -3325,12 +2009,12 @@ func_mode_compile ()
func_stripname '-Wc,' '' "$arg"
args=$func_stripname_result
lastarg=
- save_ifs=$IFS; IFS=,
+ save_ifs="$IFS"; IFS=','
for arg in $args; do
- IFS=$save_ifs
+ IFS="$save_ifs"
func_append_quoted lastarg "$arg"
done
- IFS=$save_ifs
+ IFS="$save_ifs"
func_stripname ' ' '' "$lastarg"
lastarg=$func_stripname_result
@@ -3343,8 +2027,8 @@ func_mode_compile ()
# Accept the current argument as the source file.
# The previous "srcfile" becomes the current argument.
#
- lastarg=$srcfile
- srcfile=$arg
+ lastarg="$srcfile"
+ srcfile="$arg"
;;
esac # case $arg
;;
@@ -3359,13 +2043,13 @@ func_mode_compile ()
func_fatal_error "you must specify an argument for -Xcompile"
;;
target)
- func_fatal_error "you must specify a target with '-o'"
+ func_fatal_error "you must specify a target with \`-o'"
;;
*)
# Get the name of the library object.
test -z "$libobj" && {
func_basename "$srcfile"
- libobj=$func_basename_result
+ libobj="$func_basename_result"
}
;;
esac
@@ -3385,7 +2069,7 @@ func_mode_compile ()
case $libobj in
*.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;;
*)
- func_fatal_error "cannot determine name of library object from '$libobj'"
+ func_fatal_error "cannot determine name of library object from \`$libobj'"
;;
esac
@@ -3394,8 +2078,8 @@ func_mode_compile ()
for arg in $later; do
case $arg in
-shared)
- test yes = "$build_libtool_libs" \
- || func_fatal_configuration "cannot build a shared library"
+ test "$build_libtool_libs" != yes && \
+ func_fatal_configuration "can not build a shared library"
build_old_libs=no
continue
;;
@@ -3421,17 +2105,17 @@ func_mode_compile ()
func_quote_for_eval "$libobj"
test "X$libobj" != "X$func_quote_for_eval_result" \
&& $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"' &()|`$[]' \
- && func_warning "libobj name '$libobj' may not contain shell special characters."
+ && func_warning "libobj name \`$libobj' may not contain shell special characters."
func_dirname_and_basename "$obj" "/" ""
- objname=$func_basename_result
- xdir=$func_dirname_result
- lobj=$xdir$objdir/$objname
+ objname="$func_basename_result"
+ xdir="$func_dirname_result"
+ lobj=${xdir}$objdir/$objname
test -z "$base_compile" && \
func_fatal_help "you must specify a compilation command"
# Delete any leftover library objects.
- if test yes = "$build_old_libs"; then
+ if test "$build_old_libs" = yes; then
removelist="$obj $lobj $libobj ${libobj}T"
else
removelist="$lobj $libobj ${libobj}T"
@@ -3443,16 +2127,16 @@ func_mode_compile ()
pic_mode=default
;;
esac
- if test no = "$pic_mode" && test pass_all != "$deplibs_check_method"; then
+ if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then
# non-PIC code in shared libraries is not supported
pic_mode=default
fi
# Calculate the filename of the output object if compiler does
# not support -o with -c
- if test no = "$compiler_c_o"; then
- output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.$objext
- lockfile=$output_obj.lock
+ if test "$compiler_c_o" = no; then
+ output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.${objext}
+ lockfile="$output_obj.lock"
else
output_obj=
need_locks=no
@@ -3461,12 +2145,12 @@ func_mode_compile ()
# Lock this critical section if it is needed
# We use this script file to make the link, it avoids creating a new file
- if test yes = "$need_locks"; then
+ if test "$need_locks" = yes; then
until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do
func_echo "Waiting for $lockfile to be removed"
sleep 2
done
- elif test warn = "$need_locks"; then
+ elif test "$need_locks" = warn; then
if test -f "$lockfile"; then
$ECHO "\
*** ERROR, $lockfile exists and contains:
@@ -3474,7 +2158,7 @@ func_mode_compile ()
This indicates that another process is trying to use the same
temporary object file, and libtool could not work around it because
-your compiler does not support '-c' and '-o' together. If you
+your compiler does not support \`-c' and \`-o' together. If you
repeat this compilation, it may succeed, by chance, but you had better
avoid parallel builds (make -j) in this platform, or get a better
compiler."
@@ -3496,11 +2180,11 @@ compiler."
qsrcfile=$func_quote_for_eval_result
# Only build a PIC object if we are building libtool libraries.
- if test yes = "$build_libtool_libs"; then
+ if test "$build_libtool_libs" = yes; then
# Without this assignment, base_compile gets emptied.
fbsd_hideous_sh_bug=$base_compile
- if test no != "$pic_mode"; then
+ if test "$pic_mode" != no; then
command="$base_compile $qsrcfile $pic_flag"
else
# Don't build PIC code
@@ -3517,7 +2201,7 @@ compiler."
func_show_eval_locale "$command" \
'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE'
- if test warn = "$need_locks" &&
+ if test "$need_locks" = warn &&
test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then
$ECHO "\
*** ERROR, $lockfile contains:
@@ -3528,7 +2212,7 @@ $srcfile
This indicates that another process is trying to use the same
temporary object file, and libtool could not work around it because
-your compiler does not support '-c' and '-o' together. If you
+your compiler does not support \`-c' and \`-o' together. If you
repeat this compilation, it may succeed, by chance, but you had better
avoid parallel builds (make -j) in this platform, or get a better
compiler."
@@ -3544,20 +2228,20 @@ compiler."
fi
# Allow error messages only from the first compilation.
- if test yes = "$suppress_opt"; then
+ if test "$suppress_opt" = yes; then
suppress_output=' >/dev/null 2>&1'
fi
fi
# Only build a position-dependent object if we build old libraries.
- if test yes = "$build_old_libs"; then
- if test yes != "$pic_mode"; then
+ if test "$build_old_libs" = yes; then
+ if test "$pic_mode" != yes; then
# Don't build PIC code
command="$base_compile $qsrcfile$pie_flag"
else
command="$base_compile $qsrcfile $pic_flag"
fi
- if test yes = "$compiler_c_o"; then
+ if test "$compiler_c_o" = yes; then
func_append command " -o $obj"
fi
@@ -3566,7 +2250,7 @@ compiler."
func_show_eval_locale "$command" \
'$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE'
- if test warn = "$need_locks" &&
+ if test "$need_locks" = warn &&
test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then
$ECHO "\
*** ERROR, $lockfile contains:
@@ -3577,7 +2261,7 @@ $srcfile
This indicates that another process is trying to use the same
temporary object file, and libtool could not work around it because
-your compiler does not support '-c' and '-o' together. If you
+your compiler does not support \`-c' and \`-o' together. If you
repeat this compilation, it may succeed, by chance, but you had better
avoid parallel builds (make -j) in this platform, or get a better
compiler."
@@ -3597,7 +2281,7 @@ compiler."
func_write_libtool_object "$libobj" "$objdir/$objname" "$objname"
# Unlock the critical section if it was locked
- if test no != "$need_locks"; then
+ if test "$need_locks" != no; then
removelist=$lockfile
$RM "$lockfile"
fi
@@ -3607,7 +2291,7 @@ compiler."
}
$opt_help || {
- test compile = "$opt_mode" && func_mode_compile ${1+"$@"}
+ test "$opt_mode" = compile && func_mode_compile ${1+"$@"}
}
func_mode_help ()
@@ -3627,7 +2311,7 @@ func_mode_help ()
Remove files from the build directory.
RM is the name of the program to use to delete files associated with each FILE
-(typically '/bin/rm'). RM-OPTIONS are options (such as '-f') to be passed
+(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed
to RM.
If FILE is a libtool library, object or program, all the files associated
@@ -3646,16 +2330,16 @@ This mode accepts the following additional options:
-no-suppress do not suppress compiler output for multiple passes
-prefer-pic try to build PIC objects only
-prefer-non-pic try to build non-PIC objects only
- -shared do not build a '.o' file suitable for static linking
- -static only build a '.o' file suitable for static linking
+ -shared do not build a \`.o' file suitable for static linking
+ -static only build a \`.o' file suitable for static linking
-Wc,FLAG pass FLAG directly to the compiler
-COMPILE-COMMAND is a command to be used in creating a 'standard' object file
+COMPILE-COMMAND is a command to be used in creating a \`standard' object file
from the given SOURCEFILE.
The output file name is determined by removing the directory component from
-SOURCEFILE, then substituting the C source code suffix '.c' with the
-library object suffix, '.lo'."
+SOURCEFILE, then substituting the C source code suffix \`.c' with the
+library object suffix, \`.lo'."
;;
execute)
@@ -3668,7 +2352,7 @@ This mode accepts the following additional options:
-dlopen FILE add the directory containing FILE to the library path
-This mode sets the library path environment variable according to '-dlopen'
+This mode sets the library path environment variable according to \`-dlopen'
flags.
If any of the ARGS are libtool executable wrappers, then they are translated
@@ -3687,7 +2371,7 @@ Complete the installation of libtool libraries.
Each LIBDIR is a directory that contains libtool libraries.
The commands that this mode executes may require superuser privileges. Use
-the '--dry-run' option if you just want to see what would be executed."
+the \`--dry-run' option if you just want to see what would be executed."
;;
install)
@@ -3697,7 +2381,7 @@ the '--dry-run' option if you just want to see what would be executed."
Install executables or libraries.
INSTALL-COMMAND is the installation command. The first component should be
-either the 'install' or 'cp' program.
+either the \`install' or \`cp' program.
The following components of INSTALL-COMMAND are treated specially:
@@ -3723,7 +2407,7 @@ The following components of LINK-COMMAND are treated specially:
-avoid-version do not add a version suffix if possible
-bindir BINDIR specify path to binaries directory (for systems where
libraries must be found in the PATH setting at runtime)
- -dlopen FILE '-dlpreopen' FILE if it cannot be dlopened at runtime
+ -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime
-dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols
-export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3)
-export-symbols SYMFILE
@@ -3737,8 +2421,7 @@ The following components of LINK-COMMAND are treated specially:
-no-install link a not-installable executable
-no-undefined declare that a library does not refer to external symbols
-o OUTPUT-FILE create OUTPUT-FILE from the specified objects
- -objectlist FILE use a list of object files found in FILE to specify objects
- -os2dllname NAME force a short DLL name on OS/2 (no effect on other OSes)
+ -objectlist FILE Use a list of object files found in FILE to specify objects
-precious-files-regex REGEX
don't remove output files matching REGEX
-release RELEASE specify package release information
@@ -3758,20 +2441,20 @@ The following components of LINK-COMMAND are treated specially:
-Xlinker FLAG pass linker-specific FLAG directly to the linker
-XCClinker FLAG pass link-specific FLAG to the compiler driver (CC)
-All other options (arguments beginning with '-') are ignored.
+All other options (arguments beginning with \`-') are ignored.
-Every other argument is treated as a filename. Files ending in '.la' are
+Every other argument is treated as a filename. Files ending in \`.la' are
treated as uninstalled libtool libraries, other files are standard or library
object files.
-If the OUTPUT-FILE ends in '.la', then a libtool library is created,
-only library objects ('.lo' files) may be specified, and '-rpath' is
+If the OUTPUT-FILE ends in \`.la', then a libtool library is created,
+only library objects (\`.lo' files) may be specified, and \`-rpath' is
required, except when creating a convenience library.
-If OUTPUT-FILE ends in '.a' or '.lib', then a standard library is created
-using 'ar' and 'ranlib', or on Windows using 'lib'.
+If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created
+using \`ar' and \`ranlib', or on Windows using \`lib'.
-If OUTPUT-FILE ends in '.lo' or '.$objext', then a reloadable object file
+If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file
is created, otherwise an executable program is created."
;;
@@ -3782,7 +2465,7 @@ is created, otherwise an executable program is created."
Remove libraries from an installation directory.
RM is the name of the program to use to delete files associated with each FILE
-(typically '/bin/rm'). RM-OPTIONS are options (such as '-f') to be passed
+(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed
to RM.
If FILE is a libtool library, all the files associated with it are deleted.
@@ -3790,17 +2473,17 @@ Otherwise, only FILE itself is deleted using RM."
;;
*)
- func_fatal_help "invalid operation mode '$opt_mode'"
+ func_fatal_help "invalid operation mode \`$opt_mode'"
;;
esac
echo
- $ECHO "Try '$progname --help' for more information about other modes."
+ $ECHO "Try \`$progname --help' for more information about other modes."
}
# Now that we've collected a possible --mode arg, show help if necessary
if $opt_help; then
- if test : = "$opt_help"; then
+ if test "$opt_help" = :; then
func_mode_help
else
{
@@ -3808,7 +2491,7 @@ if $opt_help; then
for opt_mode in compile link execute install finish uninstall clean; do
func_mode_help
done
- } | $SED -n '1p; 2,$s/^Usage:/ or: /p'
+ } | sed -n '1p; 2,$s/^Usage:/ or: /p'
{
func_help noexit
for opt_mode in compile link execute install finish uninstall clean; do
@@ -3816,7 +2499,7 @@ if $opt_help; then
func_mode_help
done
} |
- $SED '1d
+ sed '1d
/^When reporting/,/^Report/{
H
d
@@ -3833,17 +2516,16 @@ fi
# func_mode_execute arg...
func_mode_execute ()
{
- $debug_cmd
-
+ $opt_debug
# The first argument is the command name.
- cmd=$nonopt
+ cmd="$nonopt"
test -z "$cmd" && \
func_fatal_help "you must specify a COMMAND"
# Handle -dlopen flags immediately.
for file in $opt_dlopen; do
test -f "$file" \
- || func_fatal_help "'$file' is not a file"
+ || func_fatal_help "\`$file' is not a file"
dir=
case $file in
@@ -3853,7 +2535,7 @@ func_mode_execute ()
# Check to see that this really is a libtool archive.
func_lalib_unsafe_p "$file" \
- || func_fatal_help "'$lib' is not a valid libtool archive"
+ || func_fatal_help "\`$lib' is not a valid libtool archive"
# Read the libtool library.
dlname=
@@ -3864,18 +2546,18 @@ func_mode_execute ()
if test -z "$dlname"; then
# Warn if it was a shared library.
test -n "$library_names" && \
- func_warning "'$file' was not linked with '-export-dynamic'"
+ func_warning "\`$file' was not linked with \`-export-dynamic'"
continue
fi
func_dirname "$file" "" "."
- dir=$func_dirname_result
+ dir="$func_dirname_result"
if test -f "$dir/$objdir/$dlname"; then
func_append dir "/$objdir"
else
if test ! -f "$dir/$dlname"; then
- func_fatal_error "cannot find '$dlname' in '$dir' or '$dir/$objdir'"
+ func_fatal_error "cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'"
fi
fi
;;
@@ -3883,18 +2565,18 @@ func_mode_execute ()
*.lo)
# Just add the directory containing the .lo file.
func_dirname "$file" "" "."
- dir=$func_dirname_result
+ dir="$func_dirname_result"
;;
*)
- func_warning "'-dlopen' is ignored for non-libtool libraries and objects"
+ func_warning "\`-dlopen' is ignored for non-libtool libraries and objects"
continue
;;
esac
# Get the absolute pathname.
absdir=`cd "$dir" && pwd`
- test -n "$absdir" && dir=$absdir
+ test -n "$absdir" && dir="$absdir"
# Now add the directory to shlibpath_var.
if eval "test -z \"\$$shlibpath_var\""; then
@@ -3906,7 +2588,7 @@ func_mode_execute ()
# This variable tells wrapper scripts just to set shlibpath_var
# rather than running their programs.
- libtool_execute_magic=$magic
+ libtool_execute_magic="$magic"
# Check if any of the arguments is a wrapper script.
args=
@@ -3919,12 +2601,12 @@ func_mode_execute ()
if func_ltwrapper_script_p "$file"; then
func_source "$file"
# Transform arg to wrapped name.
- file=$progdir/$program
+ file="$progdir/$program"
elif func_ltwrapper_executable_p "$file"; then
func_ltwrapper_scriptname "$file"
func_source "$func_ltwrapper_scriptname_result"
# Transform arg to wrapped name.
- file=$progdir/$program
+ file="$progdir/$program"
fi
;;
esac
@@ -3932,15 +2614,7 @@ func_mode_execute ()
func_append_quoted args "$file"
done
- if $opt_dry_run; then
- # Display what would be done.
- if test -n "$shlibpath_var"; then
- eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\""
- echo "export $shlibpath_var"
- fi
- $ECHO "$cmd$args"
- exit $EXIT_SUCCESS
- else
+ if test "X$opt_dry_run" = Xfalse; then
if test -n "$shlibpath_var"; then
# Export the shlibpath_var.
eval "export $shlibpath_var"
@@ -3957,18 +2631,25 @@ func_mode_execute ()
done
# Now prepare to actually exec the command.
- exec_cmd=\$cmd$args
+ exec_cmd="\$cmd$args"
+ else
+ # Display what would be done.
+ if test -n "$shlibpath_var"; then
+ eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\""
+ echo "export $shlibpath_var"
+ fi
+ $ECHO "$cmd$args"
+ exit $EXIT_SUCCESS
fi
}
-test execute = "$opt_mode" && func_mode_execute ${1+"$@"}
+test "$opt_mode" = execute && func_mode_execute ${1+"$@"}
# func_mode_finish arg...
func_mode_finish ()
{
- $debug_cmd
-
+ $opt_debug
libs=
libdirs=
admincmds=
@@ -3982,11 +2663,11 @@ func_mode_finish ()
if func_lalib_unsafe_p "$opt"; then
func_append libs " $opt"
else
- func_warning "'$opt' is not a valid libtool archive"
+ func_warning "\`$opt' is not a valid libtool archive"
fi
else
- func_fatal_error "invalid argument '$opt'"
+ func_fatal_error "invalid argument \`$opt'"
fi
done
@@ -4001,12 +2682,12 @@ func_mode_finish ()
# Remove sysroot references
if $opt_dry_run; then
for lib in $libs; do
- echo "removing references to $lt_sysroot and '=' prefixes from $lib"
+ echo "removing references to $lt_sysroot and \`=' prefixes from $lib"
done
else
tmpdir=`func_mktempdir`
for lib in $libs; do
- $SED -e "$sysroot_cmd s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \
+ sed -e "${sysroot_cmd} s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \
> $tmpdir/tmp-la
mv -f $tmpdir/tmp-la $lib
done
@@ -4031,7 +2712,7 @@ func_mode_finish ()
fi
# Exit here if they wanted silent mode.
- $opt_quiet && exit $EXIT_SUCCESS
+ $opt_silent && exit $EXIT_SUCCESS
if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
echo "----------------------------------------------------------------------"
@@ -4042,27 +2723,27 @@ func_mode_finish ()
echo
echo "If you ever happen to want to link against installed libraries"
echo "in a given directory, LIBDIR, you must either use libtool, and"
- echo "specify the full pathname of the library, or use the '-LLIBDIR'"
+ echo "specify the full pathname of the library, or use the \`-LLIBDIR'"
echo "flag during linking and do at least one of the following:"
if test -n "$shlibpath_var"; then
- echo " - add LIBDIR to the '$shlibpath_var' environment variable"
+ echo " - add LIBDIR to the \`$shlibpath_var' environment variable"
echo " during execution"
fi
if test -n "$runpath_var"; then
- echo " - add LIBDIR to the '$runpath_var' environment variable"
+ echo " - add LIBDIR to the \`$runpath_var' environment variable"
echo " during linking"
fi
if test -n "$hardcode_libdir_flag_spec"; then
libdir=LIBDIR
eval flag=\"$hardcode_libdir_flag_spec\"
- $ECHO " - use the '$flag' linker flag"
+ $ECHO " - use the \`$flag' linker flag"
fi
if test -n "$admincmds"; then
$ECHO " - have your system administrator run these commands:$admincmds"
fi
if test -f /etc/ld.so.conf; then
- echo " - have your system administrator add LIBDIR to '/etc/ld.so.conf'"
+ echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'"
fi
echo
@@ -4081,20 +2762,18 @@ func_mode_finish ()
exit $EXIT_SUCCESS
}
-test finish = "$opt_mode" && func_mode_finish ${1+"$@"}
+test "$opt_mode" = finish && func_mode_finish ${1+"$@"}
# func_mode_install arg...
func_mode_install ()
{
- $debug_cmd
-
+ $opt_debug
# There may be an optional sh(1) argument at the beginning of
# install_prog (especially on Windows NT).
- if test "$SHELL" = "$nonopt" || test /bin/sh = "$nonopt" ||
+ if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh ||
# Allow the use of GNU shtool's install command.
- case $nonopt in *shtool*) :;; *) false;; esac
- then
+ case $nonopt in *shtool*) :;; *) false;; esac; then
# Aesthetically quote it.
func_quote_for_eval "$nonopt"
install_prog="$func_quote_for_eval_result "
@@ -4121,7 +2800,7 @@ func_mode_install ()
opts=
prev=
install_type=
- isdir=false
+ isdir=no
stripme=
no_mode=:
for arg
@@ -4134,7 +2813,7 @@ func_mode_install ()
fi
case $arg in
- -d) isdir=: ;;
+ -d) isdir=yes ;;
-f)
if $install_cp; then :; else
prev=$arg
@@ -4152,7 +2831,7 @@ func_mode_install ()
*)
# If the previous option needed an argument, then skip it.
if test -n "$prev"; then
- if test X-m = "X$prev" && test -n "$install_override_mode"; then
+ if test "x$prev" = x-m && test -n "$install_override_mode"; then
arg2=$install_override_mode
no_mode=false
fi
@@ -4177,7 +2856,7 @@ func_mode_install ()
func_fatal_help "you must specify an install program"
test -n "$prev" && \
- func_fatal_help "the '$prev' option requires an argument"
+ func_fatal_help "the \`$prev' option requires an argument"
if test -n "$install_override_mode" && $no_mode; then
if $install_cp; then :; else
@@ -4199,19 +2878,19 @@ func_mode_install ()
dest=$func_stripname_result
# Check to see that the destination is a directory.
- test -d "$dest" && isdir=:
- if $isdir; then
- destdir=$dest
+ test -d "$dest" && isdir=yes
+ if test "$isdir" = yes; then
+ destdir="$dest"
destname=
else
func_dirname_and_basename "$dest" "" "."
- destdir=$func_dirname_result
- destname=$func_basename_result
+ destdir="$func_dirname_result"
+ destname="$func_basename_result"
# Not a directory, so check to see that there is only one file specified.
set dummy $files; shift
test "$#" -gt 1 && \
- func_fatal_help "'$dest' is not a directory"
+ func_fatal_help "\`$dest' is not a directory"
fi
case $destdir in
[\\/]* | [A-Za-z]:[\\/]*) ;;
@@ -4220,7 +2899,7 @@ func_mode_install ()
case $file in
*.lo) ;;
*)
- func_fatal_help "'$destdir' must be an absolute directory name"
+ func_fatal_help "\`$destdir' must be an absolute directory name"
;;
esac
done
@@ -4229,7 +2908,7 @@ func_mode_install ()
# This variable tells wrapper scripts just to set variables rather
# than running their programs.
- libtool_install_magic=$magic
+ libtool_install_magic="$magic"
staticlibs=
future_libdirs=
@@ -4249,7 +2928,7 @@ func_mode_install ()
# Check to see that this really is a libtool archive.
func_lalib_unsafe_p "$file" \
- || func_fatal_help "'$file' is not a valid libtool archive"
+ || func_fatal_help "\`$file' is not a valid libtool archive"
library_names=
old_library=
@@ -4271,7 +2950,7 @@ func_mode_install ()
fi
func_dirname "$file" "/" ""
- dir=$func_dirname_result
+ dir="$func_dirname_result"
func_append dir "$objdir"
if test -n "$relink_command"; then
@@ -4285,7 +2964,7 @@ func_mode_install ()
# are installed into $libdir/../bin (currently, that works fine)
# but it's something to keep an eye on.
test "$inst_prefix_dir" = "$destdir" && \
- func_fatal_error "error: cannot install '$file' to a directory not ending in $libdir"
+ func_fatal_error "error: cannot install \`$file' to a directory not ending in $libdir"
if test -n "$inst_prefix_dir"; then
# Stick the inst_prefix_dir data into the link command.
@@ -4294,36 +2973,29 @@ func_mode_install ()
relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%%"`
fi
- func_warning "relinking '$file'"
+ func_warning "relinking \`$file'"
func_show_eval "$relink_command" \
- 'func_fatal_error "error: relink '\''$file'\'' with the above command before installing it"'
+ 'func_fatal_error "error: relink \`$file'\'' with the above command before installing it"'
fi
# See the names of the shared library.
set dummy $library_names; shift
if test -n "$1"; then
- realname=$1
+ realname="$1"
shift
- srcname=$realname
- test -n "$relink_command" && srcname=${realname}T
+ srcname="$realname"
+ test -n "$relink_command" && srcname="$realname"T
# Install the shared library and build the symlinks.
func_show_eval "$install_shared_prog $dir/$srcname $destdir/$realname" \
'exit $?'
- tstripme=$stripme
+ tstripme="$stripme"
case $host_os in
cygwin* | mingw* | pw32* | cegcc*)
case $realname in
*.dll.a)
- tstripme=
- ;;
- esac
- ;;
- os2*)
- case $realname in
- *_dll.a)
- tstripme=
+ tstripme=""
;;
esac
;;
@@ -4334,7 +3006,7 @@ func_mode_install ()
if test "$#" -gt 0; then
# Delete the old symlinks, and create new ones.
- # Try 'ln -sf' first, because the 'ln' binary might depend on
+ # Try `ln -sf' first, because the `ln' binary might depend on
# the symlink we replace! Solaris /bin/ln does not understand -f,
# so we also need to try rm && ln -s.
for linkname
@@ -4345,14 +3017,14 @@ func_mode_install ()
fi
# Do each command in the postinstall commands.
- lib=$destdir/$realname
+ lib="$destdir/$realname"
func_execute_cmds "$postinstall_cmds" 'exit $?'
fi
# Install the pseudo-library for information purposes.
func_basename "$file"
- name=$func_basename_result
- instname=$dir/${name}i
+ name="$func_basename_result"
+ instname="$dir/$name"i
func_show_eval "$install_prog $instname $destdir/$name" 'exit $?'
# Maybe install the static library, too.
@@ -4364,11 +3036,11 @@ func_mode_install ()
# Figure out destination file name, if it wasn't already specified.
if test -n "$destname"; then
- destfile=$destdir/$destname
+ destfile="$destdir/$destname"
else
func_basename "$file"
- destfile=$func_basename_result
- destfile=$destdir/$destfile
+ destfile="$func_basename_result"
+ destfile="$destdir/$destfile"
fi
# Deduce the name of the destination old-style object file.
@@ -4378,11 +3050,11 @@ func_mode_install ()
staticdest=$func_lo2o_result
;;
*.$objext)
- staticdest=$destfile
+ staticdest="$destfile"
destfile=
;;
*)
- func_fatal_help "cannot copy a libtool object to '$destfile'"
+ func_fatal_help "cannot copy a libtool object to \`$destfile'"
;;
esac
@@ -4391,7 +3063,7 @@ func_mode_install ()
func_show_eval "$install_prog $file $destfile" 'exit $?'
# Install the old object if enabled.
- if test yes = "$build_old_libs"; then
+ if test "$build_old_libs" = yes; then
# Deduce the name of the old-style object file.
func_lo2o "$file"
staticobj=$func_lo2o_result
@@ -4403,23 +3075,23 @@ func_mode_install ()
*)
# Figure out destination file name, if it wasn't already specified.
if test -n "$destname"; then
- destfile=$destdir/$destname
+ destfile="$destdir/$destname"
else
func_basename "$file"
- destfile=$func_basename_result
- destfile=$destdir/$destfile
+ destfile="$func_basename_result"
+ destfile="$destdir/$destfile"
fi
# If the file is missing, and there is a .exe on the end, strip it
# because it is most likely a libtool script we actually want to
# install
- stripped_ext=
+ stripped_ext=""
case $file in
*.exe)
if test ! -f "$file"; then
func_stripname '' '.exe' "$file"
file=$func_stripname_result
- stripped_ext=.exe
+ stripped_ext=".exe"
fi
;;
esac
@@ -4447,19 +3119,19 @@ func_mode_install ()
# Check the variables that should have been set.
test -z "$generated_by_libtool_version" && \
- func_fatal_error "invalid libtool wrapper script '$wrapper'"
+ func_fatal_error "invalid libtool wrapper script \`$wrapper'"
- finalize=:
+ finalize=yes
for lib in $notinst_deplibs; do
# Check to see that each library is installed.
libdir=
if test -f "$lib"; then
func_source "$lib"
fi
- libfile=$libdir/`$ECHO "$lib" | $SED 's%^.*/%%g'`
+ libfile="$libdir/"`$ECHO "$lib" | $SED 's%^.*/%%g'` ### testsuite: skip nested quoting test
if test -n "$libdir" && test ! -f "$libfile"; then
- func_warning "'$lib' has not been installed in '$libdir'"
- finalize=false
+ func_warning "\`$lib' has not been installed in \`$libdir'"
+ finalize=no
fi
done
@@ -4467,29 +3139,29 @@ func_mode_install ()
func_source "$wrapper"
outputname=
- if test no = "$fast_install" && test -n "$relink_command"; then
+ if test "$fast_install" = no && test -n "$relink_command"; then
$opt_dry_run || {
- if $finalize; then
+ if test "$finalize" = yes; then
tmpdir=`func_mktempdir`
func_basename "$file$stripped_ext"
- file=$func_basename_result
- outputname=$tmpdir/$file
+ file="$func_basename_result"
+ outputname="$tmpdir/$file"
# Replace the output file specification.
relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'`
- $opt_quiet || {
+ $opt_silent || {
func_quote_for_expand "$relink_command"
eval "func_echo $func_quote_for_expand_result"
}
if eval "$relink_command"; then :
else
- func_error "error: relink '$file' with the above command before installing it"
+ func_error "error: relink \`$file' with the above command before installing it"
$opt_dry_run || ${RM}r "$tmpdir"
continue
fi
- file=$outputname
+ file="$outputname"
else
- func_warning "cannot relink '$file'"
+ func_warning "cannot relink \`$file'"
fi
}
else
@@ -4526,10 +3198,10 @@ func_mode_install ()
for file in $staticlibs; do
func_basename "$file"
- name=$func_basename_result
+ name="$func_basename_result"
# Set up the ranlib parameters.
- oldlib=$destdir/$name
+ oldlib="$destdir/$name"
func_to_tool_file "$oldlib" func_convert_file_msys_to_w32
tool_oldlib=$func_to_tool_file_result
@@ -4544,18 +3216,18 @@ func_mode_install ()
done
test -n "$future_libdirs" && \
- func_warning "remember to run '$progname --finish$future_libdirs'"
+ func_warning "remember to run \`$progname --finish$future_libdirs'"
if test -n "$current_libdirs"; then
# Maybe just do a dry run.
$opt_dry_run && current_libdirs=" -n$current_libdirs"
- exec_cmd='$SHELL "$progpath" $preserve_args --finish$current_libdirs'
+ exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs'
else
exit $EXIT_SUCCESS
fi
}
-test install = "$opt_mode" && func_mode_install ${1+"$@"}
+test "$opt_mode" = install && func_mode_install ${1+"$@"}
# func_generate_dlsyms outputname originator pic_p
@@ -4563,17 +3235,16 @@ test install = "$opt_mode" && func_mode_install ${1+"$@"}
# a dlpreopen symbol table.
func_generate_dlsyms ()
{
- $debug_cmd
-
- my_outputname=$1
- my_originator=$2
- my_pic_p=${3-false}
- my_prefix=`$ECHO "$my_originator" | $SED 's%[^a-zA-Z0-9]%_%g'`
+ $opt_debug
+ my_outputname="$1"
+ my_originator="$2"
+ my_pic_p="${3-no}"
+ my_prefix=`$ECHO "$my_originator" | sed 's%[^a-zA-Z0-9]%_%g'`
my_dlsyms=
- if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then
+ if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
if test -n "$NM" && test -n "$global_symbol_pipe"; then
- my_dlsyms=${my_outputname}S.c
+ my_dlsyms="${my_outputname}S.c"
else
func_error "not configured to extract global symbols from dlpreopened files"
fi
@@ -4584,7 +3255,7 @@ func_generate_dlsyms ()
"") ;;
*.c)
# Discover the nlist of each of the dlfiles.
- nlist=$output_objdir/$my_outputname.nm
+ nlist="$output_objdir/${my_outputname}.nm"
func_show_eval "$RM $nlist ${nlist}S ${nlist}T"
@@ -4592,36 +3263,34 @@ func_generate_dlsyms ()
func_verbose "creating $output_objdir/$my_dlsyms"
$opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\
-/* $my_dlsyms - symbol resolution table for '$my_outputname' dlsym emulation. */
-/* Generated by $PROGRAM (GNU $PACKAGE) $VERSION */
+/* $my_dlsyms - symbol resolution table for \`$my_outputname' dlsym emulation. */
+/* Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION */
#ifdef __cplusplus
extern \"C\" {
#endif
-#if defined __GNUC__ && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4))
+#if defined(__GNUC__) && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4))
#pragma GCC diagnostic ignored \"-Wstrict-prototypes\"
#endif
/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */
-#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE
-/* DATA imports from DLLs on WIN32 can't be const, because runtime
+#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE)
+/* DATA imports from DLLs on WIN32 con't be const, because runtime
relocations are performed -- see ld's documentation on pseudo-relocs. */
# define LT_DLSYM_CONST
-#elif defined __osf__
+#elif defined(__osf__)
/* This system does not cope well with relocations in const data. */
# define LT_DLSYM_CONST
#else
# define LT_DLSYM_CONST const
#endif
-#define STREQ(s1, s2) (strcmp ((s1), (s2)) == 0)
-
/* External symbol declarations for the compiler. */\
"
- if test yes = "$dlself"; then
- func_verbose "generating symbol list for '$output'"
+ if test "$dlself" = yes; then
+ func_verbose "generating symbol list for \`$output'"
$opt_dry_run || echo ': @PROGRAM@ ' > "$nlist"
@@ -4629,7 +3298,7 @@ extern \"C\" {
progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP`
for progfile in $progfiles; do
func_to_tool_file "$progfile" func_convert_file_msys_to_w32
- func_verbose "extracting global C symbols from '$func_to_tool_file_result'"
+ func_verbose "extracting global C symbols from \`$func_to_tool_file_result'"
$opt_dry_run || eval "$NM $func_to_tool_file_result | $global_symbol_pipe >> '$nlist'"
done
@@ -4649,10 +3318,10 @@ extern \"C\" {
# Prepare the list of exported symbols
if test -z "$export_symbols"; then
- export_symbols=$output_objdir/$outputname.exp
+ export_symbols="$output_objdir/$outputname.exp"
$opt_dry_run || {
$RM $export_symbols
- eval "$SED -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"'
+ eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"'
case $host in
*cygwin* | *mingw* | *cegcc* )
eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
@@ -4662,7 +3331,7 @@ extern \"C\" {
}
else
$opt_dry_run || {
- eval "$SED -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"'
+ eval "${SED} -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"'
eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T'
eval '$MV "$nlist"T "$nlist"'
case $host in
@@ -4676,22 +3345,22 @@ extern \"C\" {
fi
for dlprefile in $dlprefiles; do
- func_verbose "extracting global C symbols from '$dlprefile'"
+ func_verbose "extracting global C symbols from \`$dlprefile'"
func_basename "$dlprefile"
- name=$func_basename_result
+ name="$func_basename_result"
case $host in
*cygwin* | *mingw* | *cegcc* )
# if an import library, we need to obtain dlname
if func_win32_import_lib_p "$dlprefile"; then
func_tr_sh "$dlprefile"
eval "curr_lafile=\$libfile_$func_tr_sh_result"
- dlprefile_dlbasename=
+ dlprefile_dlbasename=""
if test -n "$curr_lafile" && func_lalib_p "$curr_lafile"; then
# Use subshell, to avoid clobbering current variable values
dlprefile_dlname=`source "$curr_lafile" && echo "$dlname"`
- if test -n "$dlprefile_dlname"; then
+ if test -n "$dlprefile_dlname" ; then
func_basename "$dlprefile_dlname"
- dlprefile_dlbasename=$func_basename_result
+ dlprefile_dlbasename="$func_basename_result"
else
# no lafile. user explicitly requested -dlpreopen <import library>.
$sharedlib_from_linklib_cmd "$dlprefile"
@@ -4699,7 +3368,7 @@ extern \"C\" {
fi
fi
$opt_dry_run || {
- if test -n "$dlprefile_dlbasename"; then
+ if test -n "$dlprefile_dlbasename" ; then
eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"'
else
func_warning "Could not compute DLL name from $name"
@@ -4755,11 +3424,6 @@ extern \"C\" {
echo '/* NONE */' >> "$output_objdir/$my_dlsyms"
fi
- func_show_eval '$RM "${nlist}I"'
- if test -n "$global_symbol_to_import"; then
- eval "$global_symbol_to_import"' < "$nlist"S > "$nlist"I'
- fi
-
echo >> "$output_objdir/$my_dlsyms" "\
/* The mapping between symbol names and symbols. */
@@ -4768,30 +3432,11 @@ typedef struct {
void *address;
} lt_dlsymlist;
extern LT_DLSYM_CONST lt_dlsymlist
-lt_${my_prefix}_LTX_preloaded_symbols[];\
-"
-
- if test -s "$nlist"I; then
- echo >> "$output_objdir/$my_dlsyms" "\
-static void lt_syminit(void)
-{
- LT_DLSYM_CONST lt_dlsymlist *symbol = lt_${my_prefix}_LTX_preloaded_symbols;
- for (; symbol->name; ++symbol)
- {"
- $SED 's/.*/ if (STREQ (symbol->name, \"&\")) symbol->address = (void *) \&&;/' < "$nlist"I >> "$output_objdir/$my_dlsyms"
- echo >> "$output_objdir/$my_dlsyms" "\
- }
-}"
- fi
- echo >> "$output_objdir/$my_dlsyms" "\
+lt_${my_prefix}_LTX_preloaded_symbols[];
LT_DLSYM_CONST lt_dlsymlist
lt_${my_prefix}_LTX_preloaded_symbols[] =
-{ {\"$my_originator\", (void *) 0},"
-
- if test -s "$nlist"I; then
- echo >> "$output_objdir/$my_dlsyms" "\
- {\"@INIT@\", (void *) &lt_syminit},"
- fi
+{\
+ { \"$my_originator\", (void *) 0 },"
case $need_lib_prefix in
no)
@@ -4833,7 +3478,9 @@ static const void *lt_preloaded_setup() {
*-*-hpux*)
pic_flag_for_symtable=" $pic_flag" ;;
*)
- $my_pic_p && pic_flag_for_symtable=" $pic_flag"
+ if test "X$my_pic_p" != Xno; then
+ pic_flag_for_symtable=" $pic_flag"
+ fi
;;
esac
;;
@@ -4850,10 +3497,10 @@ static const void *lt_preloaded_setup() {
func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?'
# Clean up the generated files.
- func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T" "${nlist}I"'
+ func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T"'
# Transform the symbol file into the correct name.
- symfileobj=$output_objdir/${my_outputname}S.$objext
+ symfileobj="$output_objdir/${my_outputname}S.$objext"
case $host in
*cygwin* | *mingw* | *cegcc* )
if test -f "$output_objdir/$my_outputname.def"; then
@@ -4871,7 +3518,7 @@ static const void *lt_preloaded_setup() {
esac
;;
*)
- func_fatal_error "unknown suffix for '$my_dlsyms'"
+ func_fatal_error "unknown suffix for \`$my_dlsyms'"
;;
esac
else
@@ -4885,32 +3532,6 @@ static const void *lt_preloaded_setup() {
fi
}
-# func_cygming_gnu_implib_p ARG
-# This predicate returns with zero status (TRUE) if
-# ARG is a GNU/binutils-style import library. Returns
-# with nonzero status (FALSE) otherwise.
-func_cygming_gnu_implib_p ()
-{
- $debug_cmd
-
- func_to_tool_file "$1" func_convert_file_msys_to_w32
- func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'`
- test -n "$func_cygming_gnu_implib_tmp"
-}
-
-# func_cygming_ms_implib_p ARG
-# This predicate returns with zero status (TRUE) if
-# ARG is an MS-style import library. Returns
-# with nonzero status (FALSE) otherwise.
-func_cygming_ms_implib_p ()
-{
- $debug_cmd
-
- func_to_tool_file "$1" func_convert_file_msys_to_w32
- func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'`
- test -n "$func_cygming_ms_implib_tmp"
-}
-
# func_win32_libid arg
# return the library type of file 'arg'
#
@@ -4920,9 +3541,8 @@ func_cygming_ms_implib_p ()
# Despite the name, also deal with 64 bit binaries.
func_win32_libid ()
{
- $debug_cmd
-
- win32_libid_type=unknown
+ $opt_debug
+ win32_libid_type="unknown"
win32_fileres=`file -L $1 2>/dev/null`
case $win32_fileres in
*ar\ archive\ import\ library*) # definitely import
@@ -4932,29 +3552,16 @@ func_win32_libid ()
# Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD.
if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null |
$EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then
- case $nm_interface in
- "MS dumpbin")
- if func_cygming_ms_implib_p "$1" ||
- func_cygming_gnu_implib_p "$1"
- then
- win32_nmres=import
- else
- win32_nmres=
- fi
- ;;
- *)
- func_to_tool_file "$1" func_convert_file_msys_to_w32
- win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" |
- $SED -n -e '
+ func_to_tool_file "$1" func_convert_file_msys_to_w32
+ win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" |
+ $SED -n -e '
1,100{
/ I /{
- s|.*|import|
+ s,.*,import,
p
q
}
}'`
- ;;
- esac
case $win32_nmres in
import*) win32_libid_type="x86 archive import";;
*) win32_libid_type="x86 archive static";;
@@ -4986,8 +3593,7 @@ func_win32_libid ()
# $sharedlib_from_linklib_result
func_cygming_dll_for_implib ()
{
- $debug_cmd
-
+ $opt_debug
sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$1"`
}
@@ -5004,8 +3610,7 @@ func_cygming_dll_for_implib ()
# specified import library.
func_cygming_dll_for_implib_fallback_core ()
{
- $debug_cmd
-
+ $opt_debug
match_literal=`$ECHO "$1" | $SED "$sed_make_literal_regex"`
$OBJDUMP -s --section "$1" "$2" 2>/dev/null |
$SED '/^Contents of section '"$match_literal"':/{
@@ -5041,8 +3646,8 @@ func_cygming_dll_for_implib_fallback_core ()
/./p' |
# we now have a list, one entry per line, of the stringified
# contents of the appropriate section of all members of the
- # archive that possess that section. Heuristic: eliminate
- # all those that have a first or second character that is
+ # archive which possess that section. Heuristic: eliminate
+ # all those which have a first or second character that is
# a '.' (that is, objdump's representation of an unprintable
# character.) This should work for all archives with less than
# 0x302f exports -- but will fail for DLLs whose name actually
@@ -5053,6 +3658,30 @@ func_cygming_dll_for_implib_fallback_core ()
$SED -e '/^\./d;/^.\./d;q'
}
+# func_cygming_gnu_implib_p ARG
+# This predicate returns with zero status (TRUE) if
+# ARG is a GNU/binutils-style import library. Returns
+# with nonzero status (FALSE) otherwise.
+func_cygming_gnu_implib_p ()
+{
+ $opt_debug
+ func_to_tool_file "$1" func_convert_file_msys_to_w32
+ func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'`
+ test -n "$func_cygming_gnu_implib_tmp"
+}
+
+# func_cygming_ms_implib_p ARG
+# This predicate returns with zero status (TRUE) if
+# ARG is an MS-style import library. Returns
+# with nonzero status (FALSE) otherwise.
+func_cygming_ms_implib_p ()
+{
+ $opt_debug
+ func_to_tool_file "$1" func_convert_file_msys_to_w32
+ func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'`
+ test -n "$func_cygming_ms_implib_tmp"
+}
+
# func_cygming_dll_for_implib_fallback ARG
# Platform-specific function to extract the
# name of the DLL associated with the specified
@@ -5066,17 +3695,16 @@ func_cygming_dll_for_implib_fallback_core ()
# $sharedlib_from_linklib_result
func_cygming_dll_for_implib_fallback ()
{
- $debug_cmd
-
- if func_cygming_gnu_implib_p "$1"; then
+ $opt_debug
+ if func_cygming_gnu_implib_p "$1" ; then
# binutils import library
sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$7' "$1"`
- elif func_cygming_ms_implib_p "$1"; then
+ elif func_cygming_ms_implib_p "$1" ; then
# ms-generated import library
sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$6' "$1"`
else
# unknown
- sharedlib_from_linklib_result=
+ sharedlib_from_linklib_result=""
fi
}
@@ -5084,11 +3712,10 @@ func_cygming_dll_for_implib_fallback ()
# func_extract_an_archive dir oldlib
func_extract_an_archive ()
{
- $debug_cmd
-
- f_ex_an_ar_dir=$1; shift
- f_ex_an_ar_oldlib=$1
- if test yes = "$lock_old_archive_extraction"; then
+ $opt_debug
+ f_ex_an_ar_dir="$1"; shift
+ f_ex_an_ar_oldlib="$1"
+ if test "$lock_old_archive_extraction" = yes; then
lockfile=$f_ex_an_ar_oldlib.lock
until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do
func_echo "Waiting for $lockfile to be removed"
@@ -5097,7 +3724,7 @@ func_extract_an_archive ()
fi
func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" \
'stat=$?; rm -f "$lockfile"; exit $stat'
- if test yes = "$lock_old_archive_extraction"; then
+ if test "$lock_old_archive_extraction" = yes; then
$opt_dry_run || rm -f "$lockfile"
fi
if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then
@@ -5111,23 +3738,22 @@ func_extract_an_archive ()
# func_extract_archives gentop oldlib ...
func_extract_archives ()
{
- $debug_cmd
-
- my_gentop=$1; shift
+ $opt_debug
+ my_gentop="$1"; shift
my_oldlibs=${1+"$@"}
- my_oldobjs=
- my_xlib=
- my_xabs=
- my_xdir=
+ my_oldobjs=""
+ my_xlib=""
+ my_xabs=""
+ my_xdir=""
for my_xlib in $my_oldlibs; do
# Extract the objects.
case $my_xlib in
- [\\/]* | [A-Za-z]:[\\/]*) my_xabs=$my_xlib ;;
+ [\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;;
*) my_xabs=`pwd`"/$my_xlib" ;;
esac
func_basename "$my_xlib"
- my_xlib=$func_basename_result
+ my_xlib="$func_basename_result"
my_xlib_u=$my_xlib
while :; do
case " $extracted_archives " in
@@ -5139,7 +3765,7 @@ func_extract_archives ()
esac
done
extracted_archives="$extracted_archives $my_xlib_u"
- my_xdir=$my_gentop/$my_xlib_u
+ my_xdir="$my_gentop/$my_xlib_u"
func_mkdir_p "$my_xdir"
@@ -5152,23 +3778,22 @@ func_extract_archives ()
cd $my_xdir || exit $?
darwin_archive=$my_xabs
darwin_curdir=`pwd`
- func_basename "$darwin_archive"
- darwin_base_archive=$func_basename_result
+ darwin_base_archive=`basename "$darwin_archive"`
darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true`
if test -n "$darwin_arches"; then
darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'`
darwin_arch=
func_verbose "$darwin_base_archive has multiple architectures $darwin_arches"
- for darwin_arch in $darwin_arches; do
- func_mkdir_p "unfat-$$/$darwin_base_archive-$darwin_arch"
- $LIPO -thin $darwin_arch -output "unfat-$$/$darwin_base_archive-$darwin_arch/$darwin_base_archive" "$darwin_archive"
- cd "unfat-$$/$darwin_base_archive-$darwin_arch"
- func_extract_an_archive "`pwd`" "$darwin_base_archive"
+ for darwin_arch in $darwin_arches ; do
+ func_mkdir_p "unfat-$$/${darwin_base_archive}-${darwin_arch}"
+ $LIPO -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}"
+ cd "unfat-$$/${darwin_base_archive}-${darwin_arch}"
+ func_extract_an_archive "`pwd`" "${darwin_base_archive}"
cd "$darwin_curdir"
- $RM "unfat-$$/$darwin_base_archive-$darwin_arch/$darwin_base_archive"
+ $RM "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}"
done # $darwin_arches
## Okay now we've a bunch of thin objects, gotta fatten them up :)
- darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$sed_basename" | sort -u`
+ darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$basename" | sort -u`
darwin_file=
darwin_files=
for darwin_file in $darwin_filelist; do
@@ -5190,7 +3815,7 @@ func_extract_archives ()
my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | sort | $NL2SP`
done
- func_extract_archives_result=$my_oldobjs
+ func_extract_archives_result="$my_oldobjs"
}
@@ -5205,7 +3830,7 @@ func_extract_archives ()
#
# ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR
# variable will take. If 'yes', then the emitted script
-# will assume that the directory where it is stored is
+# will assume that the directory in which it is stored is
# the $objdir directory. This is a cygwin/mingw-specific
# behavior.
func_emit_wrapper ()
@@ -5216,7 +3841,7 @@ func_emit_wrapper ()
#! $SHELL
# $output - temporary wrapper script for $objdir/$outputname
-# Generated by $PROGRAM (GNU $PACKAGE) $VERSION
+# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
#
# The $output program cannot be directly executed until all the libtool
# libraries that it depends on are installed.
@@ -5273,9 +3898,9 @@ _LTECHO_EOF'
# Very basic option parsing. These options are (a) specific to
# the libtool wrapper, (b) are identical between the wrapper
-# /script/ and the wrapper /executable/ that is used only on
+# /script/ and the wrapper /executable/ which is used only on
# windows platforms, and (c) all begin with the string "--lt-"
-# (application programs are unlikely to have options that match
+# (application programs are unlikely to have options which match
# this pattern).
#
# There are only two supported options: --lt-debug and
@@ -5308,7 +3933,7 @@ func_parse_lt_options ()
# Print the debug banner immediately:
if test -n \"\$lt_option_debug\"; then
- echo \"$outputname:$output:\$LINENO: libtool wrapper (GNU $PACKAGE) $VERSION\" 1>&2
+ echo \"${outputname}:${output}:\${LINENO}: libtool wrapper (GNU $PACKAGE$TIMESTAMP) $VERSION\" 1>&2
fi
}
@@ -5319,7 +3944,7 @@ func_lt_dump_args ()
lt_dump_args_N=1;
for lt_arg
do
- \$ECHO \"$outputname:$output:\$LINENO: newargv[\$lt_dump_args_N]: \$lt_arg\"
+ \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[\$lt_dump_args_N]: \$lt_arg\"
lt_dump_args_N=\`expr \$lt_dump_args_N + 1\`
done
}
@@ -5333,7 +3958,7 @@ func_exec_program_core ()
*-*-mingw | *-*-os2* | *-cegcc*)
$ECHO "\
if test -n \"\$lt_option_debug\"; then
- \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir\\\\\$program\" 1>&2
+ \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir\\\\\$program\" 1>&2
func_lt_dump_args \${1+\"\$@\"} 1>&2
fi
exec \"\$progdir\\\\\$program\" \${1+\"\$@\"}
@@ -5343,7 +3968,7 @@ func_exec_program_core ()
*)
$ECHO "\
if test -n \"\$lt_option_debug\"; then
- \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir/\$program\" 1>&2
+ \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir/\$program\" 1>&2
func_lt_dump_args \${1+\"\$@\"} 1>&2
fi
exec \"\$progdir/\$program\" \${1+\"\$@\"}
@@ -5418,13 +4043,13 @@ func_exec_program ()
test -n \"\$absdir\" && thisdir=\"\$absdir\"
"
- if test yes = "$fast_install"; then
+ if test "$fast_install" = yes; then
$ECHO "\
program=lt-'$outputname'$exeext
progdir=\"\$thisdir/$objdir\"
if test ! -f \"\$progdir/\$program\" ||
- { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | $SED 1q\`; \\
+ { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\
test \"X\$file\" != \"X\$progdir/\$program\"; }; then
file=\"\$\$-\$program\"
@@ -5441,7 +4066,7 @@ func_exec_program ()
if test -n \"\$relink_command\"; then
if relink_command_output=\`eval \$relink_command 2>&1\`; then :
else
- \$ECHO \"\$relink_command_output\" >&2
+ $ECHO \"\$relink_command_output\" >&2
$RM \"\$progdir/\$file\"
exit 1
fi
@@ -5476,7 +4101,7 @@ func_exec_program ()
fi
# Export our shlibpath_var if we have one.
- if test yes = "$shlibpath_overrides_runpath" && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
+ if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
$ECHO "\
# Add our own library path to $shlibpath_var
$shlibpath_var=\"$temp_rpath\$$shlibpath_var\"
@@ -5496,7 +4121,7 @@ func_exec_program ()
fi
else
# The program doesn't exist.
- \$ECHO \"\$0: error: '\$progdir/\$program' does not exist\" 1>&2
+ \$ECHO \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2
\$ECHO \"This script is just a wrapper for \$program.\" 1>&2
\$ECHO \"See the $PACKAGE documentation for more information.\" 1>&2
exit 1
@@ -5515,7 +4140,7 @@ func_emit_cwrapperexe_src ()
cat <<EOF
/* $cwrappersource - temporary wrapper executable for $objdir/$outputname
- Generated by $PROGRAM (GNU $PACKAGE) $VERSION
+ Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
The $output program cannot be directly executed until all the libtool
libraries that it depends on are installed.
@@ -5550,45 +4175,47 @@ EOF
#include <fcntl.h>
#include <sys/stat.h>
-#define STREQ(s1, s2) (strcmp ((s1), (s2)) == 0)
-
/* declarations of non-ANSI functions */
-#if defined __MINGW32__
+#if defined(__MINGW32__)
# ifdef __STRICT_ANSI__
int _putenv (const char *);
# endif
-#elif defined __CYGWIN__
+#elif defined(__CYGWIN__)
# ifdef __STRICT_ANSI__
char *realpath (const char *, char *);
int putenv (char *);
int setenv (const char *, const char *, int);
# endif
-/* #elif defined other_platform || defined ... */
+/* #elif defined (other platforms) ... */
#endif
/* portability defines, excluding path handling macros */
-#if defined _MSC_VER
+#if defined(_MSC_VER)
# define setmode _setmode
# define stat _stat
# define chmod _chmod
# define getcwd _getcwd
# define putenv _putenv
# define S_IXUSR _S_IEXEC
-#elif defined __MINGW32__
+# ifndef _INTPTR_T_DEFINED
+# define _INTPTR_T_DEFINED
+# define intptr_t int
+# endif
+#elif defined(__MINGW32__)
# define setmode _setmode
# define stat _stat
# define chmod _chmod
# define getcwd _getcwd
# define putenv _putenv
-#elif defined __CYGWIN__
+#elif defined(__CYGWIN__)
# define HAVE_SETENV
# define FOPEN_WB "wb"
-/* #elif defined other platforms ... */
+/* #elif defined (other platforms) ... */
#endif
-#if defined PATH_MAX
+#if defined(PATH_MAX)
# define LT_PATHMAX PATH_MAX
-#elif defined MAXPATHLEN
+#elif defined(MAXPATHLEN)
# define LT_PATHMAX MAXPATHLEN
#else
# define LT_PATHMAX 1024
@@ -5607,8 +4234,8 @@ int setenv (const char *, const char *, int);
# define PATH_SEPARATOR ':'
#endif
-#if defined _WIN32 || defined __MSDOS__ || defined __DJGPP__ || \
- defined __OS2__
+#if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \
+ defined (__OS2__)
# define HAVE_DOS_BASED_FILE_SYSTEM
# define FOPEN_WB "wb"
# ifndef DIR_SEPARATOR_2
@@ -5641,10 +4268,10 @@ int setenv (const char *, const char *, int);
#define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type)))
#define XFREE(stale) do { \
- if (stale) { free (stale); stale = 0; } \
+ if (stale) { free ((void *) stale); stale = 0; } \
} while (0)
-#if defined LT_DEBUGWRAPPER
+#if defined(LT_DEBUGWRAPPER)
static int lt_debug = 1;
#else
static int lt_debug = 0;
@@ -5673,16 +4300,11 @@ void lt_dump_script (FILE *f);
EOF
cat <<EOF
-#if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 5)
-# define externally_visible volatile
-#else
-# define externally_visible __attribute__((externally_visible)) volatile
-#endif
-externally_visible const char * MAGIC_EXE = "$magic_exe";
+volatile const char * MAGIC_EXE = "$magic_exe";
const char * LIB_PATH_VARNAME = "$shlibpath_var";
EOF
- if test yes = "$shlibpath_overrides_runpath" && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
+ if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
func_to_host_path "$temp_rpath"
cat <<EOF
const char * LIB_PATH_VALUE = "$func_to_host_path_result";
@@ -5706,7 +4328,7 @@ const char * EXE_PATH_VALUE = "";
EOF
fi
- if test yes = "$fast_install"; then
+ if test "$fast_install" = yes; then
cat <<EOF
const char * TARGET_PROGRAM_NAME = "lt-$outputname"; /* hopefully, no .exe */
EOF
@@ -5735,12 +4357,12 @@ main (int argc, char *argv[])
char *actual_cwrapper_name;
char *target_name;
char *lt_argv_zero;
- int rval = 127;
+ intptr_t rval = 127;
int i;
program_name = (char *) xstrdup (base_name (argv[0]));
- newargz = XMALLOC (char *, (size_t) argc + 1);
+ newargz = XMALLOC (char *, argc + 1);
/* very simple arg parsing; don't want to rely on getopt
* also, copy all non cwrapper options to newargz, except
@@ -5749,10 +4371,10 @@ main (int argc, char *argv[])
newargc=0;
for (i = 1; i < argc; i++)
{
- if (STREQ (argv[i], dumpscript_opt))
+ if (strcmp (argv[i], dumpscript_opt) == 0)
{
EOF
- case $host in
+ case "$host" in
*mingw* | *cygwin* )
# make stdout use "unix" line endings
echo " setmode(1,_O_BINARY);"
@@ -5763,12 +4385,12 @@ EOF
lt_dump_script (stdout);
return 0;
}
- if (STREQ (argv[i], debug_opt))
+ if (strcmp (argv[i], debug_opt) == 0)
{
lt_debug = 1;
continue;
}
- if (STREQ (argv[i], ltwrapper_option_prefix))
+ if (strcmp (argv[i], ltwrapper_option_prefix) == 0)
{
/* however, if there is an option in the LTWRAPPER_OPTION_PREFIX
namespace, but it is not one of the ones we know about and
@@ -5791,7 +4413,7 @@ EOF
EOF
cat <<EOF
/* The GNU banner must be the first non-error debug message */
- lt_debugprintf (__FILE__, __LINE__, "libtool wrapper (GNU $PACKAGE) $VERSION\n");
+ lt_debugprintf (__FILE__, __LINE__, "libtool wrapper (GNU $PACKAGE$TIMESTAMP) $VERSION\n");
EOF
cat <<"EOF"
lt_debugprintf (__FILE__, __LINE__, "(main) argv[0]: %s\n", argv[0]);
@@ -5902,7 +4524,7 @@ EOF
cat <<"EOF"
/* execv doesn't actually work on mingw as expected on unix */
newargz = prepare_spawn (newargz);
- rval = (int) _spawnv (_P_WAIT, lt_argv_zero, (const char * const *) newargz);
+ rval = _spawnv (_P_WAIT, lt_argv_zero, (const char * const *) newargz);
if (rval == -1)
{
/* failed to start process */
@@ -5947,7 +4569,7 @@ base_name (const char *name)
{
const char *base;
-#if defined HAVE_DOS_BASED_FILE_SYSTEM
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
/* Skip over the disk name in MSDOS pathnames. */
if (isalpha ((unsigned char) name[0]) && name[1] == ':')
name += 2;
@@ -6006,7 +4628,7 @@ find_executable (const char *wrapper)
const char *p_next;
/* static buffer for getcwd */
char tmp[LT_PATHMAX + 1];
- size_t tmp_len;
+ int tmp_len;
char *concat_name;
lt_debugprintf (__FILE__, __LINE__, "(find_executable): %s\n",
@@ -6016,7 +4638,7 @@ find_executable (const char *wrapper)
return NULL;
/* Absolute path? */
-#if defined HAVE_DOS_BASED_FILE_SYSTEM
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':')
{
concat_name = xstrdup (wrapper);
@@ -6034,7 +4656,7 @@ find_executable (const char *wrapper)
return concat_name;
XFREE (concat_name);
}
-#if defined HAVE_DOS_BASED_FILE_SYSTEM
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
}
#endif
@@ -6057,7 +4679,7 @@ find_executable (const char *wrapper)
for (q = p; *q; q++)
if (IS_PATH_SEPARATOR (*q))
break;
- p_len = (size_t) (q - p);
+ p_len = q - p;
p_next = (*q == '\0' ? q : q + 1);
if (p_len == 0)
{
@@ -6176,7 +4798,7 @@ strendzap (char *str, const char *pat)
if (patlen <= len)
{
str += len - patlen;
- if (STREQ (str, pat))
+ if (strcmp (str, pat) == 0)
*str = '\0';
}
return str;
@@ -6241,7 +4863,7 @@ lt_setenv (const char *name, const char *value)
char *str = xstrdup (value);
setenv (name, str, 1);
#else
- size_t len = strlen (name) + 1 + strlen (value) + 1;
+ int len = strlen (name) + 1 + strlen (value) + 1;
char *str = XMALLOC (char, len);
sprintf (str, "%s=%s", name, value);
if (putenv (str) != EXIT_SUCCESS)
@@ -6258,8 +4880,8 @@ lt_extend_str (const char *orig_value, const char *add, int to_end)
char *new_value;
if (orig_value && *orig_value)
{
- size_t orig_value_len = strlen (orig_value);
- size_t add_len = strlen (add);
+ int orig_value_len = strlen (orig_value);
+ int add_len = strlen (add);
new_value = XMALLOC (char, add_len + orig_value_len + 1);
if (to_end)
{
@@ -6290,10 +4912,10 @@ lt_update_exe_path (const char *name, const char *value)
{
char *new_value = lt_extend_str (getenv (name), value, 0);
/* some systems can't cope with a ':'-terminated path #' */
- size_t len = strlen (new_value);
- while ((len > 0) && IS_PATH_SEPARATOR (new_value[len-1]))
+ int len = strlen (new_value);
+ while (((len = strlen (new_value)) > 0) && IS_PATH_SEPARATOR (new_value[len-1]))
{
- new_value[--len] = '\0';
+ new_value[len-1] = '\0';
}
lt_setenv (name, new_value);
XFREE (new_value);
@@ -6460,47 +5082,27 @@ EOF
# True if ARG is an import lib, as indicated by $file_magic_cmd
func_win32_import_lib_p ()
{
- $debug_cmd
-
+ $opt_debug
case `eval $file_magic_cmd \"\$1\" 2>/dev/null | $SED -e 10q` in
*import*) : ;;
*) false ;;
esac
}
-# func_suncc_cstd_abi
-# !!ONLY CALL THIS FOR SUN CC AFTER $compile_command IS FULLY EXPANDED!!
-# Several compiler flags select an ABI that is incompatible with the
-# Cstd library. Avoid specifying it if any are in CXXFLAGS.
-func_suncc_cstd_abi ()
-{
- $debug_cmd
-
- case " $compile_command " in
- *" -compat=g "*|*\ -std=c++[0-9][0-9]\ *|*" -library=stdcxx4 "*|*" -library=stlport4 "*)
- suncc_use_cstd_abi=no
- ;;
- *)
- suncc_use_cstd_abi=yes
- ;;
- esac
-}
-
# func_mode_link arg...
func_mode_link ()
{
- $debug_cmd
-
+ $opt_debug
case $host in
*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
# It is impossible to link a dll without this setting, and
# we shouldn't force the makefile maintainer to figure out
- # what system we are compiling for in order to pass an extra
+ # which system we are compiling for in order to pass an extra
# flag for every libtool invocation.
# allow_undefined=no
# FIXME: Unfortunately, there are problems with the above when trying
- # to make a dll that has undefined symbols, in which case not
+ # to make a dll which has undefined symbols, in which case not
# even a static library is built. For now, we need to specify
# -no-undefined on the libtool link line when we can be certain
# that all symbols are satisfied, otherwise we get a static library.
@@ -6544,11 +5146,10 @@ func_mode_link ()
module=no
no_install=no
objs=
- os2dllname=
non_pic_objects=
precious_files_regex=
prefer_static_libs=no
- preload=false
+ preload=no
prev=
prevarg=
release=
@@ -6560,7 +5161,7 @@ func_mode_link ()
vinfo=
vinfo_number=no
weak_libs=
- single_module=$wl-single_module
+ single_module="${wl}-single_module"
func_infer_tag $base_compile
# We need to know -static, to get the right output filenames.
@@ -6568,15 +5169,15 @@ func_mode_link ()
do
case $arg in
-shared)
- test yes != "$build_libtool_libs" \
- && func_fatal_configuration "cannot build a shared library"
+ test "$build_libtool_libs" != yes && \
+ func_fatal_configuration "can not build a shared library"
build_old_libs=no
break
;;
-all-static | -static | -static-libtool-libs)
case $arg in
-all-static)
- if test yes = "$build_libtool_libs" && test -z "$link_static_flag"; then
+ if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then
func_warning "complete static linking is impossible in this configuration"
fi
if test -n "$link_static_flag"; then
@@ -6609,7 +5210,7 @@ func_mode_link ()
# Go through the arguments, transforming them on the way.
while test "$#" -gt 0; do
- arg=$1
+ arg="$1"
shift
func_quote_for_eval "$arg"
qarg=$func_quote_for_eval_unquoted_result
@@ -6626,21 +5227,21 @@ func_mode_link ()
case $prev in
bindir)
- bindir=$arg
+ bindir="$arg"
prev=
continue
;;
dlfiles|dlprefiles)
- $preload || {
+ if test "$preload" = no; then
# Add the symbol object into the linking commands.
func_append compile_command " @SYMFILE@"
func_append finalize_command " @SYMFILE@"
- preload=:
- }
+ preload=yes
+ fi
case $arg in
*.la | *.lo) ;; # We handle these cases below.
force)
- if test no = "$dlself"; then
+ if test "$dlself" = no; then
dlself=needless
export_dynamic=yes
fi
@@ -6648,9 +5249,9 @@ func_mode_link ()
continue
;;
self)
- if test dlprefiles = "$prev"; then
+ if test "$prev" = dlprefiles; then
dlself=yes
- elif test dlfiles = "$prev" && test yes != "$dlopen_self"; then
+ elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then
dlself=yes
else
dlself=needless
@@ -6660,7 +5261,7 @@ func_mode_link ()
continue
;;
*)
- if test dlfiles = "$prev"; then
+ if test "$prev" = dlfiles; then
func_append dlfiles " $arg"
else
func_append dlprefiles " $arg"
@@ -6671,14 +5272,14 @@ func_mode_link ()
esac
;;
expsyms)
- export_symbols=$arg
+ export_symbols="$arg"
test -f "$arg" \
- || func_fatal_error "symbol file '$arg' does not exist"
+ || func_fatal_error "symbol file \`$arg' does not exist"
prev=
continue
;;
expsyms_regex)
- export_symbols_regex=$arg
+ export_symbols_regex="$arg"
prev=
continue
;;
@@ -6696,13 +5297,7 @@ func_mode_link ()
continue
;;
inst_prefix)
- inst_prefix_dir=$arg
- prev=
- continue
- ;;
- mllvm)
- # Clang does not use LLVM to link, so we can simply discard any
- # '-mllvm $arg' options when doing the link step.
+ inst_prefix_dir="$arg"
prev=
continue
;;
@@ -6726,21 +5321,21 @@ func_mode_link ()
if test -z "$pic_object" ||
test -z "$non_pic_object" ||
- test none = "$pic_object" &&
- test none = "$non_pic_object"; then
- func_fatal_error "cannot find name of object for '$arg'"
+ test "$pic_object" = none &&
+ test "$non_pic_object" = none; then
+ func_fatal_error "cannot find name of object for \`$arg'"
fi
# Extract subdirectory from the argument.
func_dirname "$arg" "/" ""
- xdir=$func_dirname_result
+ xdir="$func_dirname_result"
- if test none != "$pic_object"; then
+ if test "$pic_object" != none; then
# Prepend the subdirectory the object is found in.
- pic_object=$xdir$pic_object
+ pic_object="$xdir$pic_object"
- if test dlfiles = "$prev"; then
- if test yes = "$build_libtool_libs" && test yes = "$dlopen_support"; then
+ if test "$prev" = dlfiles; then
+ if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then
func_append dlfiles " $pic_object"
prev=
continue
@@ -6751,7 +5346,7 @@ func_mode_link ()
fi
# CHECK ME: I think I busted this. -Ossama
- if test dlprefiles = "$prev"; then
+ if test "$prev" = dlprefiles; then
# Preload the old-style object.
func_append dlprefiles " $pic_object"
prev=
@@ -6759,23 +5354,23 @@ func_mode_link ()
# A PIC object.
func_append libobjs " $pic_object"
- arg=$pic_object
+ arg="$pic_object"
fi
# Non-PIC object.
- if test none != "$non_pic_object"; then
+ if test "$non_pic_object" != none; then
# Prepend the subdirectory the object is found in.
- non_pic_object=$xdir$non_pic_object
+ non_pic_object="$xdir$non_pic_object"
# A standard non-PIC object
func_append non_pic_objects " $non_pic_object"
- if test -z "$pic_object" || test none = "$pic_object"; then
- arg=$non_pic_object
+ if test -z "$pic_object" || test "$pic_object" = none ; then
+ arg="$non_pic_object"
fi
else
# If the PIC object exists, use it instead.
# $xdir was prepended to $pic_object above.
- non_pic_object=$pic_object
+ non_pic_object="$pic_object"
func_append non_pic_objects " $non_pic_object"
fi
else
@@ -6783,7 +5378,7 @@ func_mode_link ()
if $opt_dry_run; then
# Extract subdirectory from the argument.
func_dirname "$arg" "/" ""
- xdir=$func_dirname_result
+ xdir="$func_dirname_result"
func_lo2o "$arg"
pic_object=$xdir$objdir/$func_lo2o_result
@@ -6791,29 +5386,24 @@ func_mode_link ()
func_append libobjs " $pic_object"
func_append non_pic_objects " $non_pic_object"
else
- func_fatal_error "'$arg' is not a valid libtool object"
+ func_fatal_error "\`$arg' is not a valid libtool object"
fi
fi
done
else
- func_fatal_error "link input file '$arg' does not exist"
+ func_fatal_error "link input file \`$arg' does not exist"
fi
arg=$save_arg
prev=
continue
;;
- os2dllname)
- os2dllname=$arg
- prev=
- continue
- ;;
precious_regex)
- precious_files_regex=$arg
+ precious_files_regex="$arg"
prev=
continue
;;
release)
- release=-$arg
+ release="-$arg"
prev=
continue
;;
@@ -6825,7 +5415,7 @@ func_mode_link ()
func_fatal_error "only absolute run-paths are allowed"
;;
esac
- if test rpath = "$prev"; then
+ if test "$prev" = rpath; then
case "$rpath " in
*" $arg "*) ;;
*) func_append rpath " $arg" ;;
@@ -6840,7 +5430,7 @@ func_mode_link ()
continue
;;
shrext)
- shrext_cmds=$arg
+ shrext_cmds="$arg"
prev=
continue
;;
@@ -6880,7 +5470,7 @@ func_mode_link ()
esac
fi # test -n "$prev"
- prevarg=$arg
+ prevarg="$arg"
case $arg in
-all-static)
@@ -6894,7 +5484,7 @@ func_mode_link ()
-allow-undefined)
# FIXME: remove this flag sometime in the future.
- func_fatal_error "'-allow-undefined' must not be used because it is the default"
+ func_fatal_error "\`-allow-undefined' must not be used because it is the default"
;;
-avoid-version)
@@ -6926,7 +5516,7 @@ func_mode_link ()
if test -n "$export_symbols" || test -n "$export_symbols_regex"; then
func_fatal_error "more than one -exported-symbols argument is not allowed"
fi
- if test X-export-symbols = "X$arg"; then
+ if test "X$arg" = "X-export-symbols"; then
prev=expsyms
else
prev=expsyms_regex
@@ -6960,9 +5550,9 @@ func_mode_link ()
func_stripname "-L" '' "$arg"
if test -z "$func_stripname_result"; then
if test "$#" -gt 0; then
- func_fatal_error "require no space between '-L' and '$1'"
+ func_fatal_error "require no space between \`-L' and \`$1'"
else
- func_fatal_error "need path for '-L' option"
+ func_fatal_error "need path for \`-L' option"
fi
fi
func_resolve_sysroot "$func_stripname_result"
@@ -6973,8 +5563,8 @@ func_mode_link ()
*)
absdir=`cd "$dir" && pwd`
test -z "$absdir" && \
- func_fatal_error "cannot determine absolute directory name of '$dir'"
- dir=$absdir
+ func_fatal_error "cannot determine absolute directory name of \`$dir'"
+ dir="$absdir"
;;
esac
case "$deplibs " in
@@ -7009,7 +5599,7 @@ func_mode_link ()
;;
-l*)
- if test X-lc = "X$arg" || test X-lm = "X$arg"; then
+ if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then
case $host in
*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*)
# These systems don't actually have a C or math library (as such)
@@ -7017,11 +5607,11 @@ func_mode_link ()
;;
*-*-os2*)
# These systems don't actually have a C library (as such)
- test X-lc = "X$arg" && continue
+ test "X$arg" = "X-lc" && continue
;;
- *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig*)
+ *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
# Do not include libc due to us having libc/libc_r.
- test X-lc = "X$arg" && continue
+ test "X$arg" = "X-lc" && continue
;;
*-*-rhapsody* | *-*-darwin1.[012])
# Rhapsody C and math libraries are in the System framework
@@ -7030,16 +5620,16 @@ func_mode_link ()
;;
*-*-sco3.2v5* | *-*-sco5v6*)
# Causes problems with __ctype
- test X-lc = "X$arg" && continue
+ test "X$arg" = "X-lc" && continue
;;
*-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*)
# Compiler inserts libc in the correct place for threads to work
- test X-lc = "X$arg" && continue
+ test "X$arg" = "X-lc" && continue
;;
esac
- elif test X-lc_r = "X$arg"; then
+ elif test "X$arg" = "X-lc_r"; then
case $host in
- *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig*)
+ *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
# Do not include libc_r directly, use -pthread flag.
continue
;;
@@ -7049,11 +5639,6 @@ func_mode_link ()
continue
;;
- -mllvm)
- prev=mllvm
- continue
- ;;
-
-module)
module=yes
continue
@@ -7083,7 +5668,7 @@ func_mode_link ()
;;
-multi_module)
- single_module=$wl-multi_module
+ single_module="${wl}-multi_module"
continue
;;
@@ -7097,8 +5682,8 @@ func_mode_link ()
*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*)
# The PATH hackery in wrapper scripts is required on Windows
# and Darwin in order for the loader to find any dlls it needs.
- func_warning "'-no-install' is ignored for $host"
- func_warning "assuming '-no-fast-install' instead"
+ func_warning "\`-no-install' is ignored for $host"
+ func_warning "assuming \`-no-fast-install' instead"
fast_install=no
;;
*) no_install=yes ;;
@@ -7116,11 +5701,6 @@ func_mode_link ()
continue
;;
- -os2dllname)
- prev=os2dllname
- continue
- ;;
-
-o) prev=output ;;
-precious-files-regex)
@@ -7208,14 +5788,14 @@ func_mode_link ()
func_stripname '-Wc,' '' "$arg"
args=$func_stripname_result
arg=
- save_ifs=$IFS; IFS=,
+ save_ifs="$IFS"; IFS=','
for flag in $args; do
- IFS=$save_ifs
+ IFS="$save_ifs"
func_quote_for_eval "$flag"
func_append arg " $func_quote_for_eval_result"
func_append compiler_flags " $func_quote_for_eval_result"
done
- IFS=$save_ifs
+ IFS="$save_ifs"
func_stripname ' ' '' "$arg"
arg=$func_stripname_result
;;
@@ -7224,15 +5804,15 @@ func_mode_link ()
func_stripname '-Wl,' '' "$arg"
args=$func_stripname_result
arg=
- save_ifs=$IFS; IFS=,
+ save_ifs="$IFS"; IFS=','
for flag in $args; do
- IFS=$save_ifs
+ IFS="$save_ifs"
func_quote_for_eval "$flag"
func_append arg " $wl$func_quote_for_eval_result"
func_append compiler_flags " $wl$func_quote_for_eval_result"
func_append linker_flags " $func_quote_for_eval_result"
done
- IFS=$save_ifs
+ IFS="$save_ifs"
func_stripname ' ' '' "$arg"
arg=$func_stripname_result
;;
@@ -7255,7 +5835,7 @@ func_mode_link ()
# -msg_* for osf cc
-msg_*)
func_quote_for_eval "$arg"
- arg=$func_quote_for_eval_result
+ arg="$func_quote_for_eval_result"
;;
# Flags to be passed through unchanged, with rationale:
@@ -7267,46 +5847,25 @@ func_mode_link ()
# -m*, -t[45]*, -txscale* architecture-specific flags for GCC
# -F/path path to uninstalled frameworks, gcc on darwin
# -p, -pg, --coverage, -fprofile-* profiling flags for GCC
- # -fstack-protector* stack protector flags for GCC
# @file GCC response files
# -tp=* Portland pgcc target processor selection
# --sysroot=* for sysroot support
- # -O*, -g*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization
- # -stdlib=* select c++ std lib with clang
+ # -O*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization
-64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \
-t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \
- -O*|-g*|-flto*|-fwhopr*|-fuse-linker-plugin|-fstack-protector*|-stdlib=*)
+ -O*|-flto*|-fwhopr*|-fuse-linker-plugin)
func_quote_for_eval "$arg"
- arg=$func_quote_for_eval_result
+ arg="$func_quote_for_eval_result"
func_append compile_command " $arg"
func_append finalize_command " $arg"
func_append compiler_flags " $arg"
continue
;;
- -Z*)
- if test os2 = "`expr $host : '.*\(os2\)'`"; then
- # OS/2 uses -Zxxx to specify OS/2-specific options
- compiler_flags="$compiler_flags $arg"
- func_append compile_command " $arg"
- func_append finalize_command " $arg"
- case $arg in
- -Zlinker | -Zstack)
- prev=xcompiler
- ;;
- esac
- continue
- else
- # Otherwise treat like 'Some other compiler flag' below
- func_quote_for_eval "$arg"
- arg=$func_quote_for_eval_result
- fi
- ;;
-
# Some other compiler flag.
-* | +*)
func_quote_for_eval "$arg"
- arg=$func_quote_for_eval_result
+ arg="$func_quote_for_eval_result"
;;
*.$objext)
@@ -7327,21 +5886,21 @@ func_mode_link ()
if test -z "$pic_object" ||
test -z "$non_pic_object" ||
- test none = "$pic_object" &&
- test none = "$non_pic_object"; then
- func_fatal_error "cannot find name of object for '$arg'"
+ test "$pic_object" = none &&
+ test "$non_pic_object" = none; then
+ func_fatal_error "cannot find name of object for \`$arg'"
fi
# Extract subdirectory from the argument.
func_dirname "$arg" "/" ""
- xdir=$func_dirname_result
+ xdir="$func_dirname_result"
- test none = "$pic_object" || {
+ if test "$pic_object" != none; then
# Prepend the subdirectory the object is found in.
- pic_object=$xdir$pic_object
+ pic_object="$xdir$pic_object"
- if test dlfiles = "$prev"; then
- if test yes = "$build_libtool_libs" && test yes = "$dlopen_support"; then
+ if test "$prev" = dlfiles; then
+ if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then
func_append dlfiles " $pic_object"
prev=
continue
@@ -7352,7 +5911,7 @@ func_mode_link ()
fi
# CHECK ME: I think I busted this. -Ossama
- if test dlprefiles = "$prev"; then
+ if test "$prev" = dlprefiles; then
# Preload the old-style object.
func_append dlprefiles " $pic_object"
prev=
@@ -7360,23 +5919,23 @@ func_mode_link ()
# A PIC object.
func_append libobjs " $pic_object"
- arg=$pic_object
- }
+ arg="$pic_object"
+ fi
# Non-PIC object.
- if test none != "$non_pic_object"; then
+ if test "$non_pic_object" != none; then
# Prepend the subdirectory the object is found in.
- non_pic_object=$xdir$non_pic_object
+ non_pic_object="$xdir$non_pic_object"
# A standard non-PIC object
func_append non_pic_objects " $non_pic_object"
- if test -z "$pic_object" || test none = "$pic_object"; then
- arg=$non_pic_object
+ if test -z "$pic_object" || test "$pic_object" = none ; then
+ arg="$non_pic_object"
fi
else
# If the PIC object exists, use it instead.
# $xdir was prepended to $pic_object above.
- non_pic_object=$pic_object
+ non_pic_object="$pic_object"
func_append non_pic_objects " $non_pic_object"
fi
else
@@ -7384,7 +5943,7 @@ func_mode_link ()
if $opt_dry_run; then
# Extract subdirectory from the argument.
func_dirname "$arg" "/" ""
- xdir=$func_dirname_result
+ xdir="$func_dirname_result"
func_lo2o "$arg"
pic_object=$xdir$objdir/$func_lo2o_result
@@ -7392,7 +5951,7 @@ func_mode_link ()
func_append libobjs " $pic_object"
func_append non_pic_objects " $non_pic_object"
else
- func_fatal_error "'$arg' is not a valid libtool object"
+ func_fatal_error "\`$arg' is not a valid libtool object"
fi
fi
;;
@@ -7408,11 +5967,11 @@ func_mode_link ()
# A libtool-controlled library.
func_resolve_sysroot "$arg"
- if test dlfiles = "$prev"; then
+ if test "$prev" = dlfiles; then
# This library was specified with -dlopen.
func_append dlfiles " $func_resolve_sysroot_result"
prev=
- elif test dlprefiles = "$prev"; then
+ elif test "$prev" = dlprefiles; then
# The library was specified with -dlpreopen.
func_append dlprefiles " $func_resolve_sysroot_result"
prev=
@@ -7427,7 +5986,7 @@ func_mode_link ()
# Unknown arguments in both finalize_command and compile_command need
# to be aesthetically quoted because they are evaled later.
func_quote_for_eval "$arg"
- arg=$func_quote_for_eval_result
+ arg="$func_quote_for_eval_result"
;;
esac # arg
@@ -7439,9 +5998,9 @@ func_mode_link ()
done # argument parsing loop
test -n "$prev" && \
- func_fatal_help "the '$prevarg' option requires an argument"
+ func_fatal_help "the \`$prevarg' option requires an argument"
- if test yes = "$export_dynamic" && test -n "$export_dynamic_flag_spec"; then
+ if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then
eval arg=\"$export_dynamic_flag_spec\"
func_append compile_command " $arg"
func_append finalize_command " $arg"
@@ -7450,23 +6009,20 @@ func_mode_link ()
oldlibs=
# calculate the name of the file, without its directory
func_basename "$output"
- outputname=$func_basename_result
- libobjs_save=$libobjs
+ outputname="$func_basename_result"
+ libobjs_save="$libobjs"
if test -n "$shlibpath_var"; then
# get the directories listed in $shlibpath_var
- eval shlib_search_path=\`\$ECHO \"\$$shlibpath_var\" \| \$SED \'s/:/ /g\'\`
+ eval shlib_search_path=\`\$ECHO \"\${$shlibpath_var}\" \| \$SED \'s/:/ /g\'\`
else
shlib_search_path=
fi
eval sys_lib_search_path=\"$sys_lib_search_path_spec\"
eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\"
- # Definition is injected by LT_CONFIG during libtool generation.
- func_munge_path_list sys_lib_dlsearch_path "$LT_SYS_LIBRARY_PATH"
-
func_dirname "$output" "/" ""
- output_objdir=$func_dirname_result$objdir
+ output_objdir="$func_dirname_result$objdir"
func_to_tool_file "$output_objdir/"
tool_output_objdir=$func_to_tool_file_result
# Create the object directory.
@@ -7489,7 +6045,7 @@ func_mode_link ()
# Find all interdependent deplibs by searching for libraries
# that are linked more than once (e.g. -la -lb -la)
for deplib in $deplibs; do
- if $opt_preserve_dup_deps; then
+ if $opt_preserve_dup_deps ; then
case "$libs " in
*" $deplib "*) func_append specialdeplibs " $deplib" ;;
esac
@@ -7497,7 +6053,7 @@ func_mode_link ()
func_append libs " $deplib"
done
- if test lib = "$linkmode"; then
+ if test "$linkmode" = lib; then
libs="$predeps $libs $compiler_lib_search_path $postdeps"
# Compute libraries that are listed more than once in $predeps
@@ -7529,7 +6085,7 @@ func_mode_link ()
case $file in
*.la) ;;
*)
- func_fatal_help "libraries can '-dlopen' only libtool libraries: $file"
+ func_fatal_help "libraries can \`-dlopen' only libtool libraries: $file"
;;
esac
done
@@ -7537,7 +6093,7 @@ func_mode_link ()
prog)
compile_deplibs=
finalize_deplibs=
- alldeplibs=false
+ alldeplibs=no
newdlfiles=
newdlprefiles=
passes="conv scan dlopen dlpreopen link"
@@ -7549,29 +6105,29 @@ func_mode_link ()
for pass in $passes; do
# The preopen pass in lib mode reverses $deplibs; put it back here
# so that -L comes before libs that need it for instance...
- if test lib,link = "$linkmode,$pass"; then
+ if test "$linkmode,$pass" = "lib,link"; then
## FIXME: Find the place where the list is rebuilt in the wrong
## order, and fix it there properly
tmp_deplibs=
for deplib in $deplibs; do
tmp_deplibs="$deplib $tmp_deplibs"
done
- deplibs=$tmp_deplibs
+ deplibs="$tmp_deplibs"
fi
- if test lib,link = "$linkmode,$pass" ||
- test prog,scan = "$linkmode,$pass"; then
- libs=$deplibs
+ if test "$linkmode,$pass" = "lib,link" ||
+ test "$linkmode,$pass" = "prog,scan"; then
+ libs="$deplibs"
deplibs=
fi
- if test prog = "$linkmode"; then
+ if test "$linkmode" = prog; then
case $pass in
- dlopen) libs=$dlfiles ;;
- dlpreopen) libs=$dlprefiles ;;
+ dlopen) libs="$dlfiles" ;;
+ dlpreopen) libs="$dlprefiles" ;;
link) libs="$deplibs %DEPLIBS% $dependency_libs" ;;
esac
fi
- if test lib,dlpreopen = "$linkmode,$pass"; then
+ if test "$linkmode,$pass" = "lib,dlpreopen"; then
# Collect and forward deplibs of preopened libtool libs
for lib in $dlprefiles; do
# Ignore non-libtool-libs
@@ -7592,26 +6148,26 @@ func_mode_link ()
esac
done
done
- libs=$dlprefiles
+ libs="$dlprefiles"
fi
- if test dlopen = "$pass"; then
+ if test "$pass" = dlopen; then
# Collect dlpreopened libraries
- save_deplibs=$deplibs
+ save_deplibs="$deplibs"
deplibs=
fi
for deplib in $libs; do
lib=
- found=false
+ found=no
case $deplib in
-mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \
|-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*)
- if test prog,link = "$linkmode,$pass"; then
+ if test "$linkmode,$pass" = "prog,link"; then
compile_deplibs="$deplib $compile_deplibs"
finalize_deplibs="$deplib $finalize_deplibs"
else
func_append compiler_flags " $deplib"
- if test lib = "$linkmode"; then
+ if test "$linkmode" = lib ; then
case "$new_inherited_linker_flags " in
*" $deplib "*) ;;
* ) func_append new_inherited_linker_flags " $deplib" ;;
@@ -7621,13 +6177,13 @@ func_mode_link ()
continue
;;
-l*)
- if test lib != "$linkmode" && test prog != "$linkmode"; then
- func_warning "'-l' is ignored for archives/objects"
+ if test "$linkmode" != lib && test "$linkmode" != prog; then
+ func_warning "\`-l' is ignored for archives/objects"
continue
fi
func_stripname '-l' '' "$deplib"
name=$func_stripname_result
- if test lib = "$linkmode"; then
+ if test "$linkmode" = lib; then
searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path"
else
searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path"
@@ -7635,22 +6191,31 @@ func_mode_link ()
for searchdir in $searchdirs; do
for search_ext in .la $std_shrext .so .a; do
# Search the libtool library
- lib=$searchdir/lib$name$search_ext
+ lib="$searchdir/lib${name}${search_ext}"
if test -f "$lib"; then
- if test .la = "$search_ext"; then
- found=:
+ if test "$search_ext" = ".la"; then
+ found=yes
else
- found=false
+ found=no
fi
break 2
fi
done
done
- if $found; then
- # deplib is a libtool library
+ if test "$found" != yes; then
+ # deplib doesn't seem to be a libtool library
+ if test "$linkmode,$pass" = "prog,link"; then
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ else
+ deplibs="$deplib $deplibs"
+ test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs"
+ fi
+ continue
+ else # deplib is a libtool library
# If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib,
# We need to do some special things here, and not later.
- if test yes = "$allow_libtool_libs_with_static_runtimes"; then
+ if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
case " $predeps $postdeps " in
*" $deplib "*)
if func_lalib_p "$lib"; then
@@ -7658,19 +6223,19 @@ func_mode_link ()
old_library=
func_source "$lib"
for l in $old_library $library_names; do
- ll=$l
+ ll="$l"
done
- if test "X$ll" = "X$old_library"; then # only static version available
- found=false
+ if test "X$ll" = "X$old_library" ; then # only static version available
+ found=no
func_dirname "$lib" "" "."
- ladir=$func_dirname_result
+ ladir="$func_dirname_result"
lib=$ladir/$old_library
- if test prog,link = "$linkmode,$pass"; then
+ if test "$linkmode,$pass" = "prog,link"; then
compile_deplibs="$deplib $compile_deplibs"
finalize_deplibs="$deplib $finalize_deplibs"
else
deplibs="$deplib $deplibs"
- test lib = "$linkmode" && newdependency_libs="$deplib $newdependency_libs"
+ test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs"
fi
continue
fi
@@ -7679,25 +6244,15 @@ func_mode_link ()
*) ;;
esac
fi
- else
- # deplib doesn't seem to be a libtool library
- if test prog,link = "$linkmode,$pass"; then
- compile_deplibs="$deplib $compile_deplibs"
- finalize_deplibs="$deplib $finalize_deplibs"
- else
- deplibs="$deplib $deplibs"
- test lib = "$linkmode" && newdependency_libs="$deplib $newdependency_libs"
- fi
- continue
fi
;; # -l
*.ltframework)
- if test prog,link = "$linkmode,$pass"; then
+ if test "$linkmode,$pass" = "prog,link"; then
compile_deplibs="$deplib $compile_deplibs"
finalize_deplibs="$deplib $finalize_deplibs"
else
deplibs="$deplib $deplibs"
- if test lib = "$linkmode"; then
+ if test "$linkmode" = lib ; then
case "$new_inherited_linker_flags " in
*" $deplib "*) ;;
* ) func_append new_inherited_linker_flags " $deplib" ;;
@@ -7710,18 +6265,18 @@ func_mode_link ()
case $linkmode in
lib)
deplibs="$deplib $deplibs"
- test conv = "$pass" && continue
+ test "$pass" = conv && continue
newdependency_libs="$deplib $newdependency_libs"
func_stripname '-L' '' "$deplib"
func_resolve_sysroot "$func_stripname_result"
func_append newlib_search_path " $func_resolve_sysroot_result"
;;
prog)
- if test conv = "$pass"; then
+ if test "$pass" = conv; then
deplibs="$deplib $deplibs"
continue
fi
- if test scan = "$pass"; then
+ if test "$pass" = scan; then
deplibs="$deplib $deplibs"
else
compile_deplibs="$deplib $compile_deplibs"
@@ -7732,13 +6287,13 @@ func_mode_link ()
func_append newlib_search_path " $func_resolve_sysroot_result"
;;
*)
- func_warning "'-L' is ignored for archives/objects"
+ func_warning "\`-L' is ignored for archives/objects"
;;
esac # linkmode
continue
;; # -L
-R*)
- if test link = "$pass"; then
+ if test "$pass" = link; then
func_stripname '-R' '' "$deplib"
func_resolve_sysroot "$func_stripname_result"
dir=$func_resolve_sysroot_result
@@ -7756,7 +6311,7 @@ func_mode_link ()
lib=$func_resolve_sysroot_result
;;
*.$libext)
- if test conv = "$pass"; then
+ if test "$pass" = conv; then
deplibs="$deplib $deplibs"
continue
fi
@@ -7767,26 +6322,21 @@ func_mode_link ()
case " $dlpreconveniencelibs " in
*" $deplib "*) ;;
*)
- valid_a_lib=false
+ valid_a_lib=no
case $deplibs_check_method in
match_pattern*)
set dummy $deplibs_check_method; shift
match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
if eval "\$ECHO \"$deplib\"" 2>/dev/null | $SED 10q \
| $EGREP "$match_pattern_regex" > /dev/null; then
- valid_a_lib=:
+ valid_a_lib=yes
fi
;;
pass_all)
- valid_a_lib=:
+ valid_a_lib=yes
;;
esac
- if $valid_a_lib; then
- echo
- $ECHO "*** Warning: Linking the shared library $output against the"
- $ECHO "*** static library $deplib is not portable!"
- deplibs="$deplib $deplibs"
- else
+ if test "$valid_a_lib" != yes; then
echo
$ECHO "*** Warning: Trying to link with static lib archive $deplib."
echo "*** I have the capability to make that library automatically link in when"
@@ -7794,13 +6344,18 @@ func_mode_link ()
echo "*** shared version of the library, which you do not appear to have"
echo "*** because the file extensions .$libext of this argument makes me believe"
echo "*** that it is just a static archive that I should not use here."
+ else
+ echo
+ $ECHO "*** Warning: Linking the shared library $output against the"
+ $ECHO "*** static library $deplib is not portable!"
+ deplibs="$deplib $deplibs"
fi
;;
esac
continue
;;
prog)
- if test link != "$pass"; then
+ if test "$pass" != link; then
deplibs="$deplib $deplibs"
else
compile_deplibs="$deplib $compile_deplibs"
@@ -7811,10 +6366,10 @@ func_mode_link ()
esac # linkmode
;; # *.$libext
*.lo | *.$objext)
- if test conv = "$pass"; then
+ if test "$pass" = conv; then
deplibs="$deplib $deplibs"
- elif test prog = "$linkmode"; then
- if test dlpreopen = "$pass" || test yes != "$dlopen_support" || test no = "$build_libtool_libs"; then
+ elif test "$linkmode" = prog; then
+ if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then
# If there is no dlopen support or we're linking statically,
# we need to preload.
func_append newdlprefiles " $deplib"
@@ -7827,20 +6382,22 @@ func_mode_link ()
continue
;;
%DEPLIBS%)
- alldeplibs=:
+ alldeplibs=yes
continue
;;
esac # case $deplib
- $found || test -f "$lib" \
- || func_fatal_error "cannot find the library '$lib' or unhandled argument '$deplib'"
+ if test "$found" = yes || test -f "$lib"; then :
+ else
+ func_fatal_error "cannot find the library \`$lib' or unhandled argument \`$deplib'"
+ fi
# Check to see that this really is a libtool archive.
func_lalib_unsafe_p "$lib" \
- || func_fatal_error "'$lib' is not a valid libtool archive"
+ || func_fatal_error "\`$lib' is not a valid libtool archive"
func_dirname "$lib" "" "."
- ladir=$func_dirname_result
+ ladir="$func_dirname_result"
dlname=
dlopen=
@@ -7870,30 +6427,30 @@ func_mode_link ()
done
fi
dependency_libs=`$ECHO " $dependency_libs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
- if test lib,link = "$linkmode,$pass" ||
- test prog,scan = "$linkmode,$pass" ||
- { test prog != "$linkmode" && test lib != "$linkmode"; }; then
+ if test "$linkmode,$pass" = "lib,link" ||
+ test "$linkmode,$pass" = "prog,scan" ||
+ { test "$linkmode" != prog && test "$linkmode" != lib; }; then
test -n "$dlopen" && func_append dlfiles " $dlopen"
test -n "$dlpreopen" && func_append dlprefiles " $dlpreopen"
fi
- if test conv = "$pass"; then
+ if test "$pass" = conv; then
# Only check for convenience libraries
deplibs="$lib $deplibs"
if test -z "$libdir"; then
if test -z "$old_library"; then
- func_fatal_error "cannot find name of link library for '$lib'"
+ func_fatal_error "cannot find name of link library for \`$lib'"
fi
# It is a libtool convenience library, so add in its objects.
func_append convenience " $ladir/$objdir/$old_library"
func_append old_convenience " $ladir/$objdir/$old_library"
- elif test prog != "$linkmode" && test lib != "$linkmode"; then
- func_fatal_error "'$lib' is not a convenience library"
+ elif test "$linkmode" != prog && test "$linkmode" != lib; then
+ func_fatal_error "\`$lib' is not a convenience library"
fi
tmp_libs=
for deplib in $dependency_libs; do
deplibs="$deplib $deplibs"
- if $opt_preserve_dup_deps; then
+ if $opt_preserve_dup_deps ; then
case "$tmp_libs " in
*" $deplib "*) func_append specialdeplibs " $deplib" ;;
esac
@@ -7907,26 +6464,26 @@ func_mode_link ()
# Get the name of the library we link against.
linklib=
if test -n "$old_library" &&
- { test yes = "$prefer_static_libs" ||
- test built,no = "$prefer_static_libs,$installed"; }; then
+ { test "$prefer_static_libs" = yes ||
+ test "$prefer_static_libs,$installed" = "built,no"; }; then
linklib=$old_library
else
for l in $old_library $library_names; do
- linklib=$l
+ linklib="$l"
done
fi
if test -z "$linklib"; then
- func_fatal_error "cannot find name of link library for '$lib'"
+ func_fatal_error "cannot find name of link library for \`$lib'"
fi
# This library was specified with -dlopen.
- if test dlopen = "$pass"; then
- test -z "$libdir" \
- && func_fatal_error "cannot -dlopen a convenience library: '$lib'"
+ if test "$pass" = dlopen; then
+ if test -z "$libdir"; then
+ func_fatal_error "cannot -dlopen a convenience library: \`$lib'"
+ fi
if test -z "$dlname" ||
- test yes != "$dlopen_support" ||
- test no = "$build_libtool_libs"
- then
+ test "$dlopen_support" != yes ||
+ test "$build_libtool_libs" = no; then
# If there is no dlname, no dlopen support or we're linking
# statically, we need to preload. We also need to preload any
# dependent libraries so libltdl's deplib preloader doesn't
@@ -7940,40 +6497,40 @@ func_mode_link ()
# We need an absolute path.
case $ladir in
- [\\/]* | [A-Za-z]:[\\/]*) abs_ladir=$ladir ;;
+ [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;;
*)
abs_ladir=`cd "$ladir" && pwd`
if test -z "$abs_ladir"; then
- func_warning "cannot determine absolute directory name of '$ladir'"
+ func_warning "cannot determine absolute directory name of \`$ladir'"
func_warning "passing it literally to the linker, although it might fail"
- abs_ladir=$ladir
+ abs_ladir="$ladir"
fi
;;
esac
func_basename "$lib"
- laname=$func_basename_result
+ laname="$func_basename_result"
# Find the relevant object directory and library name.
- if test yes = "$installed"; then
+ if test "X$installed" = Xyes; then
if test ! -f "$lt_sysroot$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then
- func_warning "library '$lib' was moved."
- dir=$ladir
- absdir=$abs_ladir
- libdir=$abs_ladir
+ func_warning "library \`$lib' was moved."
+ dir="$ladir"
+ absdir="$abs_ladir"
+ libdir="$abs_ladir"
else
- dir=$lt_sysroot$libdir
- absdir=$lt_sysroot$libdir
+ dir="$lt_sysroot$libdir"
+ absdir="$lt_sysroot$libdir"
fi
- test yes = "$hardcode_automatic" && avoidtemprpath=yes
+ test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes
else
if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then
- dir=$ladir
- absdir=$abs_ladir
+ dir="$ladir"
+ absdir="$abs_ladir"
# Remove this search path later
func_append notinst_path " $abs_ladir"
else
- dir=$ladir/$objdir
- absdir=$abs_ladir/$objdir
+ dir="$ladir/$objdir"
+ absdir="$abs_ladir/$objdir"
# Remove this search path later
func_append notinst_path " $abs_ladir"
fi
@@ -7982,11 +6539,11 @@ func_mode_link ()
name=$func_stripname_result
# This library was specified with -dlpreopen.
- if test dlpreopen = "$pass"; then
- if test -z "$libdir" && test prog = "$linkmode"; then
- func_fatal_error "only libraries may -dlpreopen a convenience library: '$lib'"
+ if test "$pass" = dlpreopen; then
+ if test -z "$libdir" && test "$linkmode" = prog; then
+ func_fatal_error "only libraries may -dlpreopen a convenience library: \`$lib'"
fi
- case $host in
+ case "$host" in
# special handling for platforms with PE-DLLs.
*cygwin* | *mingw* | *cegcc* )
# Linker will automatically link against shared library if both
@@ -8030,9 +6587,9 @@ func_mode_link ()
if test -z "$libdir"; then
# Link the convenience library
- if test lib = "$linkmode"; then
+ if test "$linkmode" = lib; then
deplibs="$dir/$old_library $deplibs"
- elif test prog,link = "$linkmode,$pass"; then
+ elif test "$linkmode,$pass" = "prog,link"; then
compile_deplibs="$dir/$old_library $compile_deplibs"
finalize_deplibs="$dir/$old_library $finalize_deplibs"
else
@@ -8042,14 +6599,14 @@ func_mode_link ()
fi
- if test prog = "$linkmode" && test link != "$pass"; then
+ if test "$linkmode" = prog && test "$pass" != link; then
func_append newlib_search_path " $ladir"
deplibs="$lib $deplibs"
- linkalldeplibs=false
- if test no != "$link_all_deplibs" || test -z "$library_names" ||
- test no = "$build_libtool_libs"; then
- linkalldeplibs=:
+ linkalldeplibs=no
+ if test "$link_all_deplibs" != no || test -z "$library_names" ||
+ test "$build_libtool_libs" = no; then
+ linkalldeplibs=yes
fi
tmp_libs=
@@ -8061,14 +6618,14 @@ func_mode_link ()
;;
esac
# Need to link against all dependency_libs?
- if $linkalldeplibs; then
+ if test "$linkalldeplibs" = yes; then
deplibs="$deplib $deplibs"
else
# Need to hardcode shared library paths
# or/and link against static libraries
newdependency_libs="$deplib $newdependency_libs"
fi
- if $opt_preserve_dup_deps; then
+ if $opt_preserve_dup_deps ; then
case "$tmp_libs " in
*" $deplib "*) func_append specialdeplibs " $deplib" ;;
esac
@@ -8078,15 +6635,15 @@ func_mode_link ()
continue
fi # $linkmode = prog...
- if test prog,link = "$linkmode,$pass"; then
+ if test "$linkmode,$pass" = "prog,link"; then
if test -n "$library_names" &&
- { { test no = "$prefer_static_libs" ||
- test built,yes = "$prefer_static_libs,$installed"; } ||
+ { { test "$prefer_static_libs" = no ||
+ test "$prefer_static_libs,$installed" = "built,yes"; } ||
test -z "$old_library"; }; then
# We need to hardcode the library path
- if test -n "$shlibpath_var" && test -z "$avoidtemprpath"; then
+ if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then
# Make sure the rpath contains only unique directories.
- case $temp_rpath: in
+ case "$temp_rpath:" in
*"$absdir:"*) ;;
*) func_append temp_rpath "$absdir:" ;;
esac
@@ -8115,9 +6672,9 @@ func_mode_link ()
esac
fi # $linkmode,$pass = prog,link...
- if $alldeplibs &&
- { test pass_all = "$deplibs_check_method" ||
- { test yes = "$build_libtool_libs" &&
+ if test "$alldeplibs" = yes &&
+ { test "$deplibs_check_method" = pass_all ||
+ { test "$build_libtool_libs" = yes &&
test -n "$library_names"; }; }; then
# We only need to search for static libraries
continue
@@ -8126,19 +6683,19 @@ func_mode_link ()
link_static=no # Whether the deplib will be linked statically
use_static_libs=$prefer_static_libs
- if test built = "$use_static_libs" && test yes = "$installed"; then
+ if test "$use_static_libs" = built && test "$installed" = yes; then
use_static_libs=no
fi
if test -n "$library_names" &&
- { test no = "$use_static_libs" || test -z "$old_library"; }; then
+ { test "$use_static_libs" = no || test -z "$old_library"; }; then
case $host in
- *cygwin* | *mingw* | *cegcc* | *os2*)
+ *cygwin* | *mingw* | *cegcc*)
# No point in relinking DLLs because paths are not encoded
func_append notinst_deplibs " $lib"
need_relink=no
;;
*)
- if test no = "$installed"; then
+ if test "$installed" = no; then
func_append notinst_deplibs " $lib"
need_relink=yes
fi
@@ -8148,24 +6705,24 @@ func_mode_link ()
# Warn about portability, can't link against -module's on some
# systems (darwin). Don't bleat about dlopened modules though!
- dlopenmodule=
+ dlopenmodule=""
for dlpremoduletest in $dlprefiles; do
if test "X$dlpremoduletest" = "X$lib"; then
- dlopenmodule=$dlpremoduletest
+ dlopenmodule="$dlpremoduletest"
break
fi
done
- if test -z "$dlopenmodule" && test yes = "$shouldnotlink" && test link = "$pass"; then
+ if test -z "$dlopenmodule" && test "$shouldnotlink" = yes && test "$pass" = link; then
echo
- if test prog = "$linkmode"; then
+ if test "$linkmode" = prog; then
$ECHO "*** Warning: Linking the executable $output against the loadable module"
else
$ECHO "*** Warning: Linking the shared library $output against the loadable module"
fi
$ECHO "*** $linklib is not portable!"
fi
- if test lib = "$linkmode" &&
- test yes = "$hardcode_into_libs"; then
+ if test "$linkmode" = lib &&
+ test "$hardcode_into_libs" = yes; then
# Hardcode the library path.
# Skip directories that are in the system default run-time
# search path.
@@ -8193,43 +6750,43 @@ func_mode_link ()
# figure out the soname
set dummy $library_names
shift
- realname=$1
+ realname="$1"
shift
libname=`eval "\\$ECHO \"$libname_spec\""`
# use dlname if we got it. it's perfectly good, no?
if test -n "$dlname"; then
- soname=$dlname
+ soname="$dlname"
elif test -n "$soname_spec"; then
# bleh windows
case $host in
- *cygwin* | mingw* | *cegcc* | *os2*)
+ *cygwin* | mingw* | *cegcc*)
func_arith $current - $age
major=$func_arith_result
- versuffix=-$major
+ versuffix="-$major"
;;
esac
eval soname=\"$soname_spec\"
else
- soname=$realname
+ soname="$realname"
fi
# Make a new name for the extract_expsyms_cmds to use
- soroot=$soname
+ soroot="$soname"
func_basename "$soroot"
- soname=$func_basename_result
+ soname="$func_basename_result"
func_stripname 'lib' '.dll' "$soname"
newlib=libimp-$func_stripname_result.a
# If the library has no export list, then create one now
if test -f "$output_objdir/$soname-def"; then :
else
- func_verbose "extracting exported symbol list from '$soname'"
+ func_verbose "extracting exported symbol list from \`$soname'"
func_execute_cmds "$extract_expsyms_cmds" 'exit $?'
fi
# Create $newlib
if test -f "$output_objdir/$newlib"; then :; else
- func_verbose "generating import library for '$soname'"
+ func_verbose "generating import library for \`$soname'"
func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?'
fi
# make sure the library variables are pointing to the new library
@@ -8237,58 +6794,58 @@ func_mode_link ()
linklib=$newlib
fi # test -n "$old_archive_from_expsyms_cmds"
- if test prog = "$linkmode" || test relink != "$opt_mode"; then
+ if test "$linkmode" = prog || test "$opt_mode" != relink; then
add_shlibpath=
add_dir=
add=
lib_linked=yes
case $hardcode_action in
immediate | unsupported)
- if test no = "$hardcode_direct"; then
- add=$dir/$linklib
+ if test "$hardcode_direct" = no; then
+ add="$dir/$linklib"
case $host in
- *-*-sco3.2v5.0.[024]*) add_dir=-L$dir ;;
- *-*-sysv4*uw2*) add_dir=-L$dir ;;
+ *-*-sco3.2v5.0.[024]*) add_dir="-L$dir" ;;
+ *-*-sysv4*uw2*) add_dir="-L$dir" ;;
*-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \
- *-*-unixware7*) add_dir=-L$dir ;;
+ *-*-unixware7*) add_dir="-L$dir" ;;
*-*-darwin* )
- # if the lib is a (non-dlopened) module then we cannot
+ # if the lib is a (non-dlopened) module then we can not
# link against it, someone is ignoring the earlier warnings
if /usr/bin/file -L $add 2> /dev/null |
- $GREP ": [^:]* bundle" >/dev/null; then
+ $GREP ": [^:]* bundle" >/dev/null ; then
if test "X$dlopenmodule" != "X$lib"; then
$ECHO "*** Warning: lib $linklib is a module, not a shared library"
- if test -z "$old_library"; then
+ if test -z "$old_library" ; then
echo
echo "*** And there doesn't seem to be a static archive available"
echo "*** The link will probably fail, sorry"
else
- add=$dir/$old_library
+ add="$dir/$old_library"
fi
elif test -n "$old_library"; then
- add=$dir/$old_library
+ add="$dir/$old_library"
fi
fi
esac
- elif test no = "$hardcode_minus_L"; then
+ elif test "$hardcode_minus_L" = no; then
case $host in
- *-*-sunos*) add_shlibpath=$dir ;;
+ *-*-sunos*) add_shlibpath="$dir" ;;
esac
- add_dir=-L$dir
- add=-l$name
- elif test no = "$hardcode_shlibpath_var"; then
- add_shlibpath=$dir
- add=-l$name
+ add_dir="-L$dir"
+ add="-l$name"
+ elif test "$hardcode_shlibpath_var" = no; then
+ add_shlibpath="$dir"
+ add="-l$name"
else
lib_linked=no
fi
;;
relink)
- if test yes = "$hardcode_direct" &&
- test no = "$hardcode_direct_absolute"; then
- add=$dir/$linklib
- elif test yes = "$hardcode_minus_L"; then
- add_dir=-L$absdir
+ if test "$hardcode_direct" = yes &&
+ test "$hardcode_direct_absolute" = no; then
+ add="$dir/$linklib"
+ elif test "$hardcode_minus_L" = yes; then
+ add_dir="-L$absdir"
# Try looking first in the location we're being installed to.
if test -n "$inst_prefix_dir"; then
case $libdir in
@@ -8297,10 +6854,10 @@ func_mode_link ()
;;
esac
fi
- add=-l$name
- elif test yes = "$hardcode_shlibpath_var"; then
- add_shlibpath=$dir
- add=-l$name
+ add="-l$name"
+ elif test "$hardcode_shlibpath_var" = yes; then
+ add_shlibpath="$dir"
+ add="-l$name"
else
lib_linked=no
fi
@@ -8308,7 +6865,7 @@ func_mode_link ()
*) lib_linked=no ;;
esac
- if test yes != "$lib_linked"; then
+ if test "$lib_linked" != yes; then
func_fatal_configuration "unsupported hardcode properties"
fi
@@ -8318,15 +6875,15 @@ func_mode_link ()
*) func_append compile_shlibpath "$add_shlibpath:" ;;
esac
fi
- if test prog = "$linkmode"; then
+ if test "$linkmode" = prog; then
test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs"
test -n "$add" && compile_deplibs="$add $compile_deplibs"
else
test -n "$add_dir" && deplibs="$add_dir $deplibs"
test -n "$add" && deplibs="$add $deplibs"
- if test yes != "$hardcode_direct" &&
- test yes != "$hardcode_minus_L" &&
- test yes = "$hardcode_shlibpath_var"; then
+ if test "$hardcode_direct" != yes &&
+ test "$hardcode_minus_L" != yes &&
+ test "$hardcode_shlibpath_var" = yes; then
case :$finalize_shlibpath: in
*":$libdir:"*) ;;
*) func_append finalize_shlibpath "$libdir:" ;;
@@ -8335,33 +6892,33 @@ func_mode_link ()
fi
fi
- if test prog = "$linkmode" || test relink = "$opt_mode"; then
+ if test "$linkmode" = prog || test "$opt_mode" = relink; then
add_shlibpath=
add_dir=
add=
# Finalize command for both is simple: just hardcode it.
- if test yes = "$hardcode_direct" &&
- test no = "$hardcode_direct_absolute"; then
- add=$libdir/$linklib
- elif test yes = "$hardcode_minus_L"; then
- add_dir=-L$libdir
- add=-l$name
- elif test yes = "$hardcode_shlibpath_var"; then
+ if test "$hardcode_direct" = yes &&
+ test "$hardcode_direct_absolute" = no; then
+ add="$libdir/$linklib"
+ elif test "$hardcode_minus_L" = yes; then
+ add_dir="-L$libdir"
+ add="-l$name"
+ elif test "$hardcode_shlibpath_var" = yes; then
case :$finalize_shlibpath: in
*":$libdir:"*) ;;
*) func_append finalize_shlibpath "$libdir:" ;;
esac
- add=-l$name
- elif test yes = "$hardcode_automatic"; then
+ add="-l$name"
+ elif test "$hardcode_automatic" = yes; then
if test -n "$inst_prefix_dir" &&
- test -f "$inst_prefix_dir$libdir/$linklib"; then
- add=$inst_prefix_dir$libdir/$linklib
+ test -f "$inst_prefix_dir$libdir/$linklib" ; then
+ add="$inst_prefix_dir$libdir/$linklib"
else
- add=$libdir/$linklib
+ add="$libdir/$linklib"
fi
else
# We cannot seem to hardcode it, guess we'll fake it.
- add_dir=-L$libdir
+ add_dir="-L$libdir"
# Try looking first in the location we're being installed to.
if test -n "$inst_prefix_dir"; then
case $libdir in
@@ -8370,10 +6927,10 @@ func_mode_link ()
;;
esac
fi
- add=-l$name
+ add="-l$name"
fi
- if test prog = "$linkmode"; then
+ if test "$linkmode" = prog; then
test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs"
test -n "$add" && finalize_deplibs="$add $finalize_deplibs"
else
@@ -8381,43 +6938,43 @@ func_mode_link ()
test -n "$add" && deplibs="$add $deplibs"
fi
fi
- elif test prog = "$linkmode"; then
+ elif test "$linkmode" = prog; then
# Here we assume that one of hardcode_direct or hardcode_minus_L
# is not unsupported. This is valid on all known static and
# shared platforms.
- if test unsupported != "$hardcode_direct"; then
- test -n "$old_library" && linklib=$old_library
+ if test "$hardcode_direct" != unsupported; then
+ test -n "$old_library" && linklib="$old_library"
compile_deplibs="$dir/$linklib $compile_deplibs"
finalize_deplibs="$dir/$linklib $finalize_deplibs"
else
compile_deplibs="-l$name -L$dir $compile_deplibs"
finalize_deplibs="-l$name -L$dir $finalize_deplibs"
fi
- elif test yes = "$build_libtool_libs"; then
+ elif test "$build_libtool_libs" = yes; then
# Not a shared library
- if test pass_all != "$deplibs_check_method"; then
+ if test "$deplibs_check_method" != pass_all; then
# We're trying link a shared library against a static one
# but the system doesn't support it.
# Just print a warning and add the library to dependency_libs so
# that the program can be linked against the static library.
echo
- $ECHO "*** Warning: This system cannot link to static lib archive $lib."
+ $ECHO "*** Warning: This system can not link to static lib archive $lib."
echo "*** I have the capability to make that library automatically link in when"
echo "*** you link to this library. But I can only do this if you have a"
echo "*** shared version of the library, which you do not appear to have."
- if test yes = "$module"; then
+ if test "$module" = yes; then
echo "*** But as you try to build a module library, libtool will still create "
echo "*** a static module, that should work as long as the dlopening application"
echo "*** is linked with the -dlopen flag to resolve symbols at runtime."
if test -z "$global_symbol_pipe"; then
echo
echo "*** However, this would only work if libtool was able to extract symbol"
- echo "*** lists from a program, using 'nm' or equivalent, but libtool could"
+ echo "*** lists from a program, using \`nm' or equivalent, but libtool could"
echo "*** not find such a program. So, this module is probably useless."
- echo "*** 'nm' from GNU binutils and a full rebuild may help."
+ echo "*** \`nm' from GNU binutils and a full rebuild may help."
fi
- if test no = "$build_old_libs"; then
+ if test "$build_old_libs" = no; then
build_libtool_libs=module
build_old_libs=yes
else
@@ -8430,11 +6987,11 @@ func_mode_link ()
fi
fi # link shared/static library?
- if test lib = "$linkmode"; then
+ if test "$linkmode" = lib; then
if test -n "$dependency_libs" &&
- { test yes != "$hardcode_into_libs" ||
- test yes = "$build_old_libs" ||
- test yes = "$link_static"; }; then
+ { test "$hardcode_into_libs" != yes ||
+ test "$build_old_libs" = yes ||
+ test "$link_static" = yes; }; then
# Extract -R from dependency_libs
temp_deplibs=
for libdir in $dependency_libs; do
@@ -8448,12 +7005,12 @@ func_mode_link ()
*) func_append temp_deplibs " $libdir";;
esac
done
- dependency_libs=$temp_deplibs
+ dependency_libs="$temp_deplibs"
fi
func_append newlib_search_path " $absdir"
# Link against this library
- test no = "$link_static" && newdependency_libs="$abs_ladir/$laname $newdependency_libs"
+ test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs"
# ... and its dependency_libs
tmp_libs=
for deplib in $dependency_libs; do
@@ -8463,7 +7020,7 @@ func_mode_link ()
func_resolve_sysroot "$func_stripname_result";;
*) func_resolve_sysroot "$deplib" ;;
esac
- if $opt_preserve_dup_deps; then
+ if $opt_preserve_dup_deps ; then
case "$tmp_libs " in
*" $func_resolve_sysroot_result "*)
func_append specialdeplibs " $func_resolve_sysroot_result" ;;
@@ -8472,12 +7029,12 @@ func_mode_link ()
func_append tmp_libs " $func_resolve_sysroot_result"
done
- if test no != "$link_all_deplibs"; then
+ if test "$link_all_deplibs" != no; then
# Add the search paths of all dependency libraries
for deplib in $dependency_libs; do
path=
case $deplib in
- -L*) path=$deplib ;;
+ -L*) path="$deplib" ;;
*.la)
func_resolve_sysroot "$deplib"
deplib=$func_resolve_sysroot_result
@@ -8485,12 +7042,12 @@ func_mode_link ()
dir=$func_dirname_result
# We need an absolute path.
case $dir in
- [\\/]* | [A-Za-z]:[\\/]*) absdir=$dir ;;
+ [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;;
*)
absdir=`cd "$dir" && pwd`
if test -z "$absdir"; then
- func_warning "cannot determine absolute directory name of '$dir'"
- absdir=$dir
+ func_warning "cannot determine absolute directory name of \`$dir'"
+ absdir="$dir"
fi
;;
esac
@@ -8498,35 +7055,35 @@ func_mode_link ()
case $host in
*-*-darwin*)
depdepl=
- eval deplibrary_names=`$SED -n -e 's/^library_names=\(.*\)$/\1/p' $deplib`
- if test -n "$deplibrary_names"; then
- for tmp in $deplibrary_names; do
+ eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib`
+ if test -n "$deplibrary_names" ; then
+ for tmp in $deplibrary_names ; do
depdepl=$tmp
done
- if test -f "$absdir/$objdir/$depdepl"; then
- depdepl=$absdir/$objdir/$depdepl
- darwin_install_name=`$OTOOL -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'`
+ if test -f "$absdir/$objdir/$depdepl" ; then
+ depdepl="$absdir/$objdir/$depdepl"
+ darwin_install_name=`${OTOOL} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'`
if test -z "$darwin_install_name"; then
- darwin_install_name=`$OTOOL64 -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'`
+ darwin_install_name=`${OTOOL64} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'`
fi
- func_append compiler_flags " $wl-dylib_file $wl$darwin_install_name:$depdepl"
- func_append linker_flags " -dylib_file $darwin_install_name:$depdepl"
+ func_append compiler_flags " ${wl}-dylib_file ${wl}${darwin_install_name}:${depdepl}"
+ func_append linker_flags " -dylib_file ${darwin_install_name}:${depdepl}"
path=
fi
fi
;;
*)
- path=-L$absdir/$objdir
+ path="-L$absdir/$objdir"
;;
esac
else
- eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
+ eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
test -z "$libdir" && \
- func_fatal_error "'$deplib' is not a valid libtool archive"
+ func_fatal_error "\`$deplib' is not a valid libtool archive"
test "$absdir" != "$libdir" && \
- func_warning "'$deplib' seems to be moved"
+ func_warning "\`$deplib' seems to be moved"
- path=-L$absdir
+ path="-L$absdir"
fi
;;
esac
@@ -8538,23 +7095,23 @@ func_mode_link ()
fi # link_all_deplibs != no
fi # linkmode = lib
done # for deplib in $libs
- if test link = "$pass"; then
- if test prog = "$linkmode"; then
+ if test "$pass" = link; then
+ if test "$linkmode" = "prog"; then
compile_deplibs="$new_inherited_linker_flags $compile_deplibs"
finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs"
else
compiler_flags="$compiler_flags "`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
fi
fi
- dependency_libs=$newdependency_libs
- if test dlpreopen = "$pass"; then
+ dependency_libs="$newdependency_libs"
+ if test "$pass" = dlpreopen; then
# Link the dlpreopened libraries before other libraries
for deplib in $save_deplibs; do
deplibs="$deplib $deplibs"
done
fi
- if test dlopen != "$pass"; then
- test conv = "$pass" || {
+ if test "$pass" != dlopen; then
+ if test "$pass" != conv; then
# Make sure lib_search_path contains only unique directories.
lib_search_path=
for dir in $newlib_search_path; do
@@ -8564,12 +7121,12 @@ func_mode_link ()
esac
done
newlib_search_path=
- }
+ fi
- if test prog,link = "$linkmode,$pass"; then
- vars="compile_deplibs finalize_deplibs"
+ if test "$linkmode,$pass" != "prog,link"; then
+ vars="deplibs"
else
- vars=deplibs
+ vars="compile_deplibs finalize_deplibs"
fi
for var in $vars dependency_libs; do
# Add libraries to $var in reverse order
@@ -8627,93 +7184,62 @@ func_mode_link ()
eval $var=\"$tmp_libs\"
done # for var
fi
-
- # Add Sun CC postdeps if required:
- test CXX = "$tagname" && {
- case $host_os in
- linux*)
- case `$CC -V 2>&1 | sed 5q` in
- *Sun\ C*) # Sun C++ 5.9
- func_suncc_cstd_abi
-
- if test no != "$suncc_use_cstd_abi"; then
- func_append postdeps ' -library=Cstd -library=Crun'
- fi
- ;;
- esac
- ;;
-
- solaris*)
- func_cc_basename "$CC"
- case $func_cc_basename_result in
- CC* | sunCC*)
- func_suncc_cstd_abi
-
- if test no != "$suncc_use_cstd_abi"; then
- func_append postdeps ' -library=Cstd -library=Crun'
- fi
- ;;
- esac
- ;;
- esac
- }
-
# Last step: remove runtime libs from dependency_libs
# (they stay in deplibs)
tmp_libs=
- for i in $dependency_libs; do
+ for i in $dependency_libs ; do
case " $predeps $postdeps $compiler_lib_search_path " in
*" $i "*)
- i=
+ i=""
;;
esac
- if test -n "$i"; then
+ if test -n "$i" ; then
func_append tmp_libs " $i"
fi
done
dependency_libs=$tmp_libs
done # for pass
- if test prog = "$linkmode"; then
- dlfiles=$newdlfiles
+ if test "$linkmode" = prog; then
+ dlfiles="$newdlfiles"
fi
- if test prog = "$linkmode" || test lib = "$linkmode"; then
- dlprefiles=$newdlprefiles
+ if test "$linkmode" = prog || test "$linkmode" = lib; then
+ dlprefiles="$newdlprefiles"
fi
case $linkmode in
oldlib)
- if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then
- func_warning "'-dlopen' is ignored for archives"
+ if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+ func_warning "\`-dlopen' is ignored for archives"
fi
case " $deplibs" in
*\ -l* | *\ -L*)
- func_warning "'-l' and '-L' are ignored for archives" ;;
+ func_warning "\`-l' and \`-L' are ignored for archives" ;;
esac
test -n "$rpath" && \
- func_warning "'-rpath' is ignored for archives"
+ func_warning "\`-rpath' is ignored for archives"
test -n "$xrpath" && \
- func_warning "'-R' is ignored for archives"
+ func_warning "\`-R' is ignored for archives"
test -n "$vinfo" && \
- func_warning "'-version-info/-version-number' is ignored for archives"
+ func_warning "\`-version-info/-version-number' is ignored for archives"
test -n "$release" && \
- func_warning "'-release' is ignored for archives"
+ func_warning "\`-release' is ignored for archives"
test -n "$export_symbols$export_symbols_regex" && \
- func_warning "'-export-symbols' is ignored for archives"
+ func_warning "\`-export-symbols' is ignored for archives"
# Now set the variables for building old libraries.
build_libtool_libs=no
- oldlibs=$output
+ oldlibs="$output"
func_append objs "$old_deplibs"
;;
lib)
- # Make sure we only generate libraries of the form 'libNAME.la'.
+ # Make sure we only generate libraries of the form `libNAME.la'.
case $outputname in
lib*)
func_stripname 'lib' '.la' "$outputname"
@@ -8722,10 +7248,10 @@ func_mode_link ()
eval libname=\"$libname_spec\"
;;
*)
- test no = "$module" \
- && func_fatal_help "libtool library '$output' must begin with 'lib'"
+ test "$module" = no && \
+ func_fatal_help "libtool library \`$output' must begin with \`lib'"
- if test no != "$need_lib_prefix"; then
+ if test "$need_lib_prefix" != no; then
# Add the "lib" prefix for modules if required
func_stripname '' '.la' "$outputname"
name=$func_stripname_result
@@ -8739,8 +7265,8 @@ func_mode_link ()
esac
if test -n "$objs"; then
- if test pass_all != "$deplibs_check_method"; then
- func_fatal_error "cannot build libtool library '$output' from non-libtool objects on this host:$objs"
+ if test "$deplibs_check_method" != pass_all; then
+ func_fatal_error "cannot build libtool library \`$output' from non-libtool objects on this host:$objs"
else
echo
$ECHO "*** Warning: Linking the shared library $output against the non-libtool"
@@ -8749,21 +7275,21 @@ func_mode_link ()
fi
fi
- test no = "$dlself" \
- || func_warning "'-dlopen self' is ignored for libtool libraries"
+ test "$dlself" != no && \
+ func_warning "\`-dlopen self' is ignored for libtool libraries"
set dummy $rpath
shift
- test 1 -lt "$#" \
- && func_warning "ignoring multiple '-rpath's for a libtool library"
+ test "$#" -gt 1 && \
+ func_warning "ignoring multiple \`-rpath's for a libtool library"
- install_libdir=$1
+ install_libdir="$1"
oldlibs=
if test -z "$rpath"; then
- if test yes = "$build_libtool_libs"; then
+ if test "$build_libtool_libs" = yes; then
# Building a libtool convenience library.
- # Some compilers have problems with a '.al' extension so
+ # Some compilers have problems with a `.al' extension so
# convenience libraries should have the same extension an
# archive normally would.
oldlibs="$output_objdir/$libname.$libext $oldlibs"
@@ -8772,20 +7298,20 @@ func_mode_link ()
fi
test -n "$vinfo" && \
- func_warning "'-version-info/-version-number' is ignored for convenience libraries"
+ func_warning "\`-version-info/-version-number' is ignored for convenience libraries"
test -n "$release" && \
- func_warning "'-release' is ignored for convenience libraries"
+ func_warning "\`-release' is ignored for convenience libraries"
else
# Parse the version information argument.
- save_ifs=$IFS; IFS=:
+ save_ifs="$IFS"; IFS=':'
set dummy $vinfo 0 0 0
shift
- IFS=$save_ifs
+ IFS="$save_ifs"
test -n "$7" && \
- func_fatal_help "too many parameters to '-version-info'"
+ func_fatal_help "too many parameters to \`-version-info'"
# convert absolute version numbers to libtool ages
# this retains compatibility with .la files and attempts
@@ -8793,42 +7319,42 @@ func_mode_link ()
case $vinfo_number in
yes)
- number_major=$1
- number_minor=$2
- number_revision=$3
+ number_major="$1"
+ number_minor="$2"
+ number_revision="$3"
#
# There are really only two kinds -- those that
# use the current revision as the major version
# and those that subtract age and use age as
# a minor version. But, then there is irix
- # that has an extra 1 added just for fun
+ # which has an extra 1 added just for fun
#
case $version_type in
# correct linux to gnu/linux during the next big refactor
- darwin|freebsd-elf|linux|osf|windows|none)
+ darwin|linux|osf|windows|none)
func_arith $number_major + $number_minor
current=$func_arith_result
- age=$number_minor
- revision=$number_revision
+ age="$number_minor"
+ revision="$number_revision"
;;
- freebsd-aout|qnx|sunos)
- current=$number_major
- revision=$number_minor
- age=0
+ freebsd-aout|freebsd-elf|qnx|sunos)
+ current="$number_major"
+ revision="$number_minor"
+ age="0"
;;
irix|nonstopux)
func_arith $number_major + $number_minor
current=$func_arith_result
- age=$number_minor
- revision=$number_minor
+ age="$number_minor"
+ revision="$number_minor"
lt_irix_increment=no
;;
esac
;;
no)
- current=$1
- revision=$2
- age=$3
+ current="$1"
+ revision="$2"
+ age="$3"
;;
esac
@@ -8836,30 +7362,30 @@ func_mode_link ()
case $current in
0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
*)
- func_error "CURRENT '$current' must be a nonnegative integer"
- func_fatal_error "'$vinfo' is not valid version information"
+ func_error "CURRENT \`$current' must be a nonnegative integer"
+ func_fatal_error "\`$vinfo' is not valid version information"
;;
esac
case $revision in
0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
*)
- func_error "REVISION '$revision' must be a nonnegative integer"
- func_fatal_error "'$vinfo' is not valid version information"
+ func_error "REVISION \`$revision' must be a nonnegative integer"
+ func_fatal_error "\`$vinfo' is not valid version information"
;;
esac
case $age in
0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
*)
- func_error "AGE '$age' must be a nonnegative integer"
- func_fatal_error "'$vinfo' is not valid version information"
+ func_error "AGE \`$age' must be a nonnegative integer"
+ func_fatal_error "\`$vinfo' is not valid version information"
;;
esac
if test "$age" -gt "$current"; then
- func_error "AGE '$age' is greater than the current interface number '$current'"
- func_fatal_error "'$vinfo' is not valid version information"
+ func_error "AGE \`$age' is greater than the current interface number \`$current'"
+ func_fatal_error "\`$vinfo' is not valid version information"
fi
# Calculate the version variables.
@@ -8874,36 +7400,26 @@ func_mode_link ()
# verstring for coding it into the library header
func_arith $current - $age
major=.$func_arith_result
- versuffix=$major.$age.$revision
+ versuffix="$major.$age.$revision"
# Darwin ld doesn't like 0 for these options...
func_arith $current + 1
minor_current=$func_arith_result
- xlcverstring="$wl-compatibility_version $wl$minor_current $wl-current_version $wl$minor_current.$revision"
+ xlcverstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision"
verstring="-compatibility_version $minor_current -current_version $minor_current.$revision"
- # On Darwin other compilers
- case $CC in
- nagfor*)
- verstring="$wl-compatibility_version $wl$minor_current $wl-current_version $wl$minor_current.$revision"
- ;;
- *)
- verstring="-compatibility_version $minor_current -current_version $minor_current.$revision"
- ;;
- esac
;;
freebsd-aout)
- major=.$current
- versuffix=.$current.$revision
+ major=".$current"
+ versuffix=".$current.$revision";
;;
freebsd-elf)
- func_arith $current - $age
- major=.$func_arith_result
- versuffix=$major.$age.$revision
+ major=".$current"
+ versuffix=".$current"
;;
irix | nonstopux)
- if test no = "$lt_irix_increment"; then
+ if test "X$lt_irix_increment" = "Xno"; then
func_arith $current - $age
else
func_arith $current - $age + 1
@@ -8914,74 +7430,69 @@ func_mode_link ()
nonstopux) verstring_prefix=nonstopux ;;
*) verstring_prefix=sgi ;;
esac
- verstring=$verstring_prefix$major.$revision
+ verstring="$verstring_prefix$major.$revision"
# Add in all the interfaces that we are compatible with.
loop=$revision
- while test 0 -ne "$loop"; do
+ while test "$loop" -ne 0; do
func_arith $revision - $loop
iface=$func_arith_result
func_arith $loop - 1
loop=$func_arith_result
- verstring=$verstring_prefix$major.$iface:$verstring
+ verstring="$verstring_prefix$major.$iface:$verstring"
done
- # Before this point, $major must not contain '.'.
+ # Before this point, $major must not contain `.'.
major=.$major
- versuffix=$major.$revision
+ versuffix="$major.$revision"
;;
linux) # correct to gnu/linux during the next big refactor
func_arith $current - $age
major=.$func_arith_result
- versuffix=$major.$age.$revision
+ versuffix="$major.$age.$revision"
;;
osf)
func_arith $current - $age
major=.$func_arith_result
- versuffix=.$current.$age.$revision
- verstring=$current.$age.$revision
+ versuffix=".$current.$age.$revision"
+ verstring="$current.$age.$revision"
# Add in all the interfaces that we are compatible with.
loop=$age
- while test 0 -ne "$loop"; do
+ while test "$loop" -ne 0; do
func_arith $current - $loop
iface=$func_arith_result
func_arith $loop - 1
loop=$func_arith_result
- verstring=$verstring:$iface.0
+ verstring="$verstring:${iface}.0"
done
# Make executables depend on our current version.
- func_append verstring ":$current.0"
+ func_append verstring ":${current}.0"
;;
qnx)
- major=.$current
- versuffix=.$current
- ;;
-
- sco)
- major=.$current
- versuffix=.$current
+ major=".$current"
+ versuffix=".$current"
;;
sunos)
- major=.$current
- versuffix=.$current.$revision
+ major=".$current"
+ versuffix=".$current.$revision"
;;
windows)
# Use '-' rather than '.', since we only want one
- # extension on DOS 8.3 file systems.
+ # extension on DOS 8.3 filesystems.
func_arith $current - $age
major=$func_arith_result
- versuffix=-$major
+ versuffix="-$major"
;;
*)
- func_fatal_configuration "unknown library version type '$version_type'"
+ func_fatal_configuration "unknown library version type \`$version_type'"
;;
esac
@@ -8995,45 +7506,42 @@ func_mode_link ()
verstring=
;;
*)
- verstring=0.0
+ verstring="0.0"
;;
esac
- if test no = "$need_version"; then
+ if test "$need_version" = no; then
versuffix=
else
- versuffix=.0.0
+ versuffix=".0.0"
fi
fi
# Remove version info from name if versioning should be avoided
- if test yes,no = "$avoid_version,$need_version"; then
+ if test "$avoid_version" = yes && test "$need_version" = no; then
major=
versuffix=
- verstring=
+ verstring=""
fi
# Check to see if the archive will have undefined symbols.
- if test yes = "$allow_undefined"; then
- if test unsupported = "$allow_undefined_flag"; then
- if test yes = "$build_old_libs"; then
- func_warning "undefined symbols not allowed in $host shared libraries; building static only"
- build_libtool_libs=no
- else
- func_fatal_error "can't build $host shared library unless -no-undefined is specified"
- fi
+ if test "$allow_undefined" = yes; then
+ if test "$allow_undefined_flag" = unsupported; then
+ func_warning "undefined symbols not allowed in $host shared libraries"
+ build_libtool_libs=no
+ build_old_libs=yes
fi
else
# Don't allow undefined symbols.
- allow_undefined_flag=$no_undefined_flag
+ allow_undefined_flag="$no_undefined_flag"
fi
fi
- func_generate_dlsyms "$libname" "$libname" :
+ func_generate_dlsyms "$libname" "$libname" "yes"
func_append libobjs " $symfileobj"
- test " " = "$libobjs" && libobjs=
+ test "X$libobjs" = "X " && libobjs=
- if test relink != "$opt_mode"; then
+ if test "$opt_mode" != relink; then
# Remove our outputs, but don't remove object files since they
# may have been created when compiling PIC objects.
removelist=
@@ -9042,8 +7550,8 @@ func_mode_link ()
case $p in
*.$objext | *.gcno)
;;
- $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/$libname$release.*)
- if test -n "$precious_files_regex"; then
+ $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*)
+ if test "X$precious_files_regex" != "X"; then
if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1
then
continue
@@ -9059,11 +7567,11 @@ func_mode_link ()
fi
# Now set the variables for building old libraries.
- if test yes = "$build_old_libs" && test convenience != "$build_libtool_libs"; then
+ if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then
func_append oldlibs " $output_objdir/$libname.$libext"
# Transform .lo files to .o files.
- oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.$libext$/d; $lo2o" | $NL2SP`
+ oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; $lo2o" | $NL2SP`
fi
# Eliminate all temporary directories.
@@ -9084,13 +7592,13 @@ func_mode_link ()
*) func_append finalize_rpath " $libdir" ;;
esac
done
- if test yes != "$hardcode_into_libs" || test yes = "$build_old_libs"; then
+ if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then
dependency_libs="$temp_xrpath $dependency_libs"
fi
fi
# Make sure dlfiles contains only unique files that won't be dlpreopened
- old_dlfiles=$dlfiles
+ old_dlfiles="$dlfiles"
dlfiles=
for lib in $old_dlfiles; do
case " $dlprefiles $dlfiles " in
@@ -9100,7 +7608,7 @@ func_mode_link ()
done
# Make sure dlprefiles contains only unique files
- old_dlprefiles=$dlprefiles
+ old_dlprefiles="$dlprefiles"
dlprefiles=
for lib in $old_dlprefiles; do
case "$dlprefiles " in
@@ -9109,7 +7617,7 @@ func_mode_link ()
esac
done
- if test yes = "$build_libtool_libs"; then
+ if test "$build_libtool_libs" = yes; then
if test -n "$rpath"; then
case $host in
*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*)
@@ -9133,7 +7641,7 @@ func_mode_link ()
;;
*)
# Add libc to deplibs on all other systems if necessary.
- if test yes = "$build_libtool_need_lc"; then
+ if test "$build_libtool_need_lc" = "yes"; then
func_append deplibs " -lc"
fi
;;
@@ -9149,9 +7657,9 @@ func_mode_link ()
# I'm not sure if I'm treating the release correctly. I think
# release should show up in the -l (ie -lgmp5) so we don't want to
# add it in twice. Is that correct?
- release=
- versuffix=
- major=
+ release=""
+ versuffix=""
+ major=""
newdeplibs=
droppeddeps=no
case $deplibs_check_method in
@@ -9180,20 +7688,20 @@ EOF
-l*)
func_stripname -l '' "$i"
name=$func_stripname_result
- if test yes = "$allow_libtool_libs_with_static_runtimes"; then
+ if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
case " $predeps $postdeps " in
*" $i "*)
func_append newdeplibs " $i"
- i=
+ i=""
;;
esac
fi
- if test -n "$i"; then
+ if test -n "$i" ; then
libname=`eval "\\$ECHO \"$libname_spec\""`
deplib_matches=`eval "\\$ECHO \"$library_names_spec\""`
set dummy $deplib_matches; shift
deplib_match=$1
- if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0; then
+ if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
func_append newdeplibs " $i"
else
droppeddeps=yes
@@ -9223,20 +7731,20 @@ EOF
$opt_dry_run || $RM conftest
if $LTCC $LTCFLAGS -o conftest conftest.c $i; then
ldd_output=`ldd conftest`
- if test yes = "$allow_libtool_libs_with_static_runtimes"; then
+ if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
case " $predeps $postdeps " in
*" $i "*)
func_append newdeplibs " $i"
- i=
+ i=""
;;
esac
fi
- if test -n "$i"; then
+ if test -n "$i" ; then
libname=`eval "\\$ECHO \"$libname_spec\""`
deplib_matches=`eval "\\$ECHO \"$library_names_spec\""`
set dummy $deplib_matches; shift
deplib_match=$1
- if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0; then
+ if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
func_append newdeplibs " $i"
else
droppeddeps=yes
@@ -9273,24 +7781,24 @@ EOF
-l*)
func_stripname -l '' "$a_deplib"
name=$func_stripname_result
- if test yes = "$allow_libtool_libs_with_static_runtimes"; then
+ if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
case " $predeps $postdeps " in
*" $a_deplib "*)
func_append newdeplibs " $a_deplib"
- a_deplib=
+ a_deplib=""
;;
esac
fi
- if test -n "$a_deplib"; then
+ if test -n "$a_deplib" ; then
libname=`eval "\\$ECHO \"$libname_spec\""`
if test -n "$file_magic_glob"; then
libnameglob=`func_echo_all "$libname" | $SED -e $file_magic_glob`
else
libnameglob=$libname
fi
- test yes = "$want_nocaseglob" && nocaseglob=`shopt -p nocaseglob`
+ test "$want_nocaseglob" = yes && nocaseglob=`shopt -p nocaseglob`
for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
- if test yes = "$want_nocaseglob"; then
+ if test "$want_nocaseglob" = yes; then
shopt -s nocaseglob
potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null`
$nocaseglob
@@ -9308,25 +7816,25 @@ EOF
# We might still enter an endless loop, since a link
# loop can be closed while we follow links,
# but so what?
- potlib=$potent_lib
+ potlib="$potent_lib"
while test -h "$potlib" 2>/dev/null; do
- potliblink=`ls -ld $potlib | $SED 's/.* -> //'`
+ potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'`
case $potliblink in
- [\\/]* | [A-Za-z]:[\\/]*) potlib=$potliblink;;
- *) potlib=`$ECHO "$potlib" | $SED 's|[^/]*$||'`"$potliblink";;
+ [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";;
+ *) potlib=`$ECHO "$potlib" | $SED 's,[^/]*$,,'`"$potliblink";;
esac
done
if eval $file_magic_cmd \"\$potlib\" 2>/dev/null |
$SED -e 10q |
$EGREP "$file_magic_regex" > /dev/null; then
func_append newdeplibs " $a_deplib"
- a_deplib=
+ a_deplib=""
break 2
fi
done
done
fi
- if test -n "$a_deplib"; then
+ if test -n "$a_deplib" ; then
droppeddeps=yes
echo
$ECHO "*** Warning: linker path does not have real file for library $a_deplib."
@@ -9334,7 +7842,7 @@ EOF
echo "*** you link to this library. But I can only do this if you have a"
echo "*** shared version of the library, which you do not appear to have"
echo "*** because I did check the linker path looking for a file starting"
- if test -z "$potlib"; then
+ if test -z "$potlib" ; then
$ECHO "*** with $libname but no candidates were found. (...for file magic test)"
else
$ECHO "*** with $libname and none of the candidates passed a file format test"
@@ -9357,30 +7865,30 @@ EOF
-l*)
func_stripname -l '' "$a_deplib"
name=$func_stripname_result
- if test yes = "$allow_libtool_libs_with_static_runtimes"; then
+ if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
case " $predeps $postdeps " in
*" $a_deplib "*)
func_append newdeplibs " $a_deplib"
- a_deplib=
+ a_deplib=""
;;
esac
fi
- if test -n "$a_deplib"; then
+ if test -n "$a_deplib" ; then
libname=`eval "\\$ECHO \"$libname_spec\""`
for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
potential_libs=`ls $i/$libname[.-]* 2>/dev/null`
for potent_lib in $potential_libs; do
- potlib=$potent_lib # see symlink-check above in file_magic test
+ potlib="$potent_lib" # see symlink-check above in file_magic test
if eval "\$ECHO \"$potent_lib\"" 2>/dev/null | $SED 10q | \
$EGREP "$match_pattern_regex" > /dev/null; then
func_append newdeplibs " $a_deplib"
- a_deplib=
+ a_deplib=""
break 2
fi
done
done
fi
- if test -n "$a_deplib"; then
+ if test -n "$a_deplib" ; then
droppeddeps=yes
echo
$ECHO "*** Warning: linker path does not have real file for library $a_deplib."
@@ -9388,7 +7896,7 @@ EOF
echo "*** you link to this library. But I can only do this if you have a"
echo "*** shared version of the library, which you do not appear to have"
echo "*** because I did check the linker path looking for a file starting"
- if test -z "$potlib"; then
+ if test -z "$potlib" ; then
$ECHO "*** with $libname but no candidates were found. (...for regex pattern test)"
else
$ECHO "*** with $libname and none of the candidates passed a file format test"
@@ -9404,18 +7912,18 @@ EOF
done # Gone through all deplibs.
;;
none | unknown | *)
- newdeplibs=
+ newdeplibs=""
tmp_deplibs=`$ECHO " $deplibs" | $SED 's/ -lc$//; s/ -[LR][^ ]*//g'`
- if test yes = "$allow_libtool_libs_with_static_runtimes"; then
- for i in $predeps $postdeps; do
+ if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+ for i in $predeps $postdeps ; do
# can't use Xsed below, because $i might contain '/'
- tmp_deplibs=`$ECHO " $tmp_deplibs" | $SED "s|$i||"`
+ tmp_deplibs=`$ECHO " $tmp_deplibs" | $SED "s,$i,,"`
done
fi
case $tmp_deplibs in
*[!\ \ ]*)
echo
- if test none = "$deplibs_check_method"; then
+ if test "X$deplibs_check_method" = "Xnone"; then
echo "*** Warning: inter-library dependencies are not supported in this platform."
else
echo "*** Warning: inter-library dependencies are not known to be supported."
@@ -9439,8 +7947,8 @@ EOF
;;
esac
- if test yes = "$droppeddeps"; then
- if test yes = "$module"; then
+ if test "$droppeddeps" = yes; then
+ if test "$module" = yes; then
echo
echo "*** Warning: libtool could not satisfy all declared inter-library"
$ECHO "*** dependencies of module $libname. Therefore, libtool will create"
@@ -9449,12 +7957,12 @@ EOF
if test -z "$global_symbol_pipe"; then
echo
echo "*** However, this would only work if libtool was able to extract symbol"
- echo "*** lists from a program, using 'nm' or equivalent, but libtool could"
+ echo "*** lists from a program, using \`nm' or equivalent, but libtool could"
echo "*** not find such a program. So, this module is probably useless."
- echo "*** 'nm' from GNU binutils and a full rebuild may help."
+ echo "*** \`nm' from GNU binutils and a full rebuild may help."
fi
- if test no = "$build_old_libs"; then
- oldlibs=$output_objdir/$libname.$libext
+ if test "$build_old_libs" = no; then
+ oldlibs="$output_objdir/$libname.$libext"
build_libtool_libs=module
build_old_libs=yes
else
@@ -9465,14 +7973,14 @@ EOF
echo "*** automatically added whenever a program is linked with this library"
echo "*** or is declared to -dlopen it."
- if test no = "$allow_undefined"; then
+ if test "$allow_undefined" = no; then
echo
echo "*** Since this library must not contain undefined symbols,"
echo "*** because either the platform does not support them or"
echo "*** it was explicitly requested with -no-undefined,"
echo "*** libtool will only create a static version of it."
- if test no = "$build_old_libs"; then
- oldlibs=$output_objdir/$libname.$libext
+ if test "$build_old_libs" = no; then
+ oldlibs="$output_objdir/$libname.$libext"
build_libtool_libs=module
build_old_libs=yes
else
@@ -9518,7 +8026,7 @@ EOF
*) func_append new_libs " $deplib" ;;
esac
done
- deplibs=$new_libs
+ deplibs="$new_libs"
# All the library-specific variables (install_libdir is set above).
library_names=
@@ -9526,25 +8034,25 @@ EOF
dlname=
# Test again, we may have decided not to build it any more
- if test yes = "$build_libtool_libs"; then
- # Remove $wl instances when linking with ld.
+ if test "$build_libtool_libs" = yes; then
+ # Remove ${wl} instances when linking with ld.
# FIXME: should test the right _cmds variable.
case $archive_cmds in
*\$LD\ *) wl= ;;
esac
- if test yes = "$hardcode_into_libs"; then
+ if test "$hardcode_into_libs" = yes; then
# Hardcode the library paths
hardcode_libdirs=
dep_rpath=
- rpath=$finalize_rpath
- test relink = "$opt_mode" || rpath=$compile_rpath$rpath
+ rpath="$finalize_rpath"
+ test "$opt_mode" != relink && rpath="$compile_rpath$rpath"
for libdir in $rpath; do
if test -n "$hardcode_libdir_flag_spec"; then
if test -n "$hardcode_libdir_separator"; then
func_replace_sysroot "$libdir"
libdir=$func_replace_sysroot_result
if test -z "$hardcode_libdirs"; then
- hardcode_libdirs=$libdir
+ hardcode_libdirs="$libdir"
else
# Just accumulate the unique libdirs.
case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
@@ -9569,7 +8077,7 @@ EOF
# Substitute the hardcoded libdirs into the rpath.
if test -n "$hardcode_libdir_separator" &&
test -n "$hardcode_libdirs"; then
- libdir=$hardcode_libdirs
+ libdir="$hardcode_libdirs"
eval "dep_rpath=\"$hardcode_libdir_flag_spec\""
fi
if test -n "$runpath_var" && test -n "$perm_rpath"; then
@@ -9583,8 +8091,8 @@ EOF
test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs"
fi
- shlibpath=$finalize_shlibpath
- test relink = "$opt_mode" || shlibpath=$compile_shlibpath$shlibpath
+ shlibpath="$finalize_shlibpath"
+ test "$opt_mode" != relink && shlibpath="$compile_shlibpath$shlibpath"
if test -n "$shlibpath"; then
eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var"
fi
@@ -9594,19 +8102,19 @@ EOF
eval library_names=\"$library_names_spec\"
set dummy $library_names
shift
- realname=$1
+ realname="$1"
shift
if test -n "$soname_spec"; then
eval soname=\"$soname_spec\"
else
- soname=$realname
+ soname="$realname"
fi
if test -z "$dlname"; then
dlname=$soname
fi
- lib=$output_objdir/$realname
+ lib="$output_objdir/$realname"
linknames=
for link
do
@@ -9620,7 +8128,7 @@ EOF
delfiles=
if test -n "$export_symbols" && test -n "$include_expsyms"; then
$opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp"
- export_symbols=$output_objdir/$libname.uexp
+ export_symbols="$output_objdir/$libname.uexp"
func_append delfiles " $export_symbols"
fi
@@ -9629,31 +8137,31 @@ EOF
cygwin* | mingw* | cegcc*)
if test -n "$export_symbols" && test -z "$export_symbols_regex"; then
# exporting using user supplied symfile
- func_dll_def_p "$export_symbols" || {
+ if test "x`$SED 1q $export_symbols`" != xEXPORTS; then
# and it's NOT already a .def file. Must figure out
# which of the given symbols are data symbols and tag
# them as such. So, trigger use of export_symbols_cmds.
# export_symbols gets reassigned inside the "prepare
# the list of exported symbols" if statement, so the
# include_expsyms logic still works.
- orig_export_symbols=$export_symbols
+ orig_export_symbols="$export_symbols"
export_symbols=
always_export_symbols=yes
- }
+ fi
fi
;;
esac
# Prepare the list of exported symbols
if test -z "$export_symbols"; then
- if test yes = "$always_export_symbols" || test -n "$export_symbols_regex"; then
- func_verbose "generating symbol list for '$libname.la'"
- export_symbols=$output_objdir/$libname.exp
+ if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then
+ func_verbose "generating symbol list for \`$libname.la'"
+ export_symbols="$output_objdir/$libname.exp"
$opt_dry_run || $RM $export_symbols
cmds=$export_symbols_cmds
- save_ifs=$IFS; IFS='~'
+ save_ifs="$IFS"; IFS='~'
for cmd1 in $cmds; do
- IFS=$save_ifs
+ IFS="$save_ifs"
# Take the normal branch if the nm_file_list_spec branch
# doesn't work or if tool conversion is not needed.
case $nm_file_list_spec~$to_tool_file_cmd in
@@ -9667,7 +8175,7 @@ EOF
try_normal_branch=no
;;
esac
- if test yes = "$try_normal_branch" \
+ if test "$try_normal_branch" = yes \
&& { test "$len" -lt "$max_cmd_len" \
|| test "$max_cmd_len" -le -1; }
then
@@ -9678,7 +8186,7 @@ EOF
output_la=$func_basename_result
save_libobjs=$libobjs
save_output=$output
- output=$output_objdir/$output_la.nm
+ output=${output_objdir}/${output_la}.nm
func_to_tool_file "$output"
libobjs=$nm_file_list_spec$func_to_tool_file_result
func_append delfiles " $output"
@@ -9701,8 +8209,8 @@ EOF
break
fi
done
- IFS=$save_ifs
- if test -n "$export_symbols_regex" && test : != "$skipped_export"; then
+ IFS="$save_ifs"
+ if test -n "$export_symbols_regex" && test "X$skipped_export" != "X:"; then
func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
func_show_eval '$MV "${export_symbols}T" "$export_symbols"'
fi
@@ -9710,16 +8218,16 @@ EOF
fi
if test -n "$export_symbols" && test -n "$include_expsyms"; then
- tmp_export_symbols=$export_symbols
- test -n "$orig_export_symbols" && tmp_export_symbols=$orig_export_symbols
+ tmp_export_symbols="$export_symbols"
+ test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols"
$opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"'
fi
- if test : != "$skipped_export" && test -n "$orig_export_symbols"; then
+ if test "X$skipped_export" != "X:" && test -n "$orig_export_symbols"; then
# The given exports_symbols file has to be filtered, so filter it.
- func_verbose "filter symbol list for '$libname.la' to tag DATA exports"
+ func_verbose "filter symbol list for \`$libname.la' to tag DATA exports"
# FIXME: $output_objdir/$libname.filter potentially contains lots of
- # 's' commands, which not all seds can handle. GNU sed should be fine
+ # 's' commands which not all seds can handle. GNU sed should be fine
# though. Also, the filter scales superlinearly with the number of
# global variables. join(1) would be nice here, but unfortunately
# isn't a blessed tool.
@@ -9738,11 +8246,11 @@ EOF
;;
esac
done
- deplibs=$tmp_deplibs
+ deplibs="$tmp_deplibs"
if test -n "$convenience"; then
if test -n "$whole_archive_flag_spec" &&
- test yes = "$compiler_needs_object" &&
+ test "$compiler_needs_object" = yes &&
test -z "$libobjs"; then
# extract the archives, so we have objects to list.
# TODO: could optimize this to just extract one archive.
@@ -9753,7 +8261,7 @@ EOF
eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
test "X$libobjs" = "X " && libobjs=
else
- gentop=$output_objdir/${outputname}x
+ gentop="$output_objdir/${outputname}x"
func_append generated " $gentop"
func_extract_archives $gentop $convenience
@@ -9762,18 +8270,18 @@ EOF
fi
fi
- if test yes = "$thread_safe" && test -n "$thread_safe_flag_spec"; then
+ if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then
eval flag=\"$thread_safe_flag_spec\"
func_append linker_flags " $flag"
fi
# Make a backup of the uninstalled library when relinking
- if test relink = "$opt_mode"; then
+ if test "$opt_mode" = relink; then
$opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $?
fi
# Do each of the archive commands.
- if test yes = "$module" && test -n "$module_cmds"; then
+ if test "$module" = yes && test -n "$module_cmds" ; then
if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then
eval test_cmds=\"$module_expsym_cmds\"
cmds=$module_expsym_cmds
@@ -9791,7 +8299,7 @@ EOF
fi
fi
- if test : != "$skipped_export" &&
+ if test "X$skipped_export" != "X:" &&
func_len " $test_cmds" &&
len=$func_len_result &&
test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then
@@ -9824,8 +8332,8 @@ EOF
last_robj=
k=1
- if test -n "$save_libobjs" && test : != "$skipped_export" && test yes = "$with_gnu_ld"; then
- output=$output_objdir/$output_la.lnkscript
+ if test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "$with_gnu_ld" = yes; then
+ output=${output_objdir}/${output_la}.lnkscript
func_verbose "creating GNU ld script: $output"
echo 'INPUT (' > $output
for obj in $save_libobjs
@@ -9837,14 +8345,14 @@ EOF
func_append delfiles " $output"
func_to_tool_file "$output"
output=$func_to_tool_file_result
- elif test -n "$save_libobjs" && test : != "$skipped_export" && test -n "$file_list_spec"; then
- output=$output_objdir/$output_la.lnk
+ elif test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "X$file_list_spec" != X; then
+ output=${output_objdir}/${output_la}.lnk
func_verbose "creating linker input file list: $output"
: > $output
set x $save_libobjs
shift
firstobj=
- if test yes = "$compiler_needs_object"; then
+ if test "$compiler_needs_object" = yes; then
firstobj="$1 "
shift
fi
@@ -9859,7 +8367,7 @@ EOF
else
if test -n "$save_libobjs"; then
func_verbose "creating reloadable object files..."
- output=$output_objdir/$output_la-$k.$objext
+ output=$output_objdir/$output_la-${k}.$objext
eval test_cmds=\"$reload_cmds\"
func_len " $test_cmds"
len0=$func_len_result
@@ -9871,13 +8379,13 @@ EOF
func_len " $obj"
func_arith $len + $func_len_result
len=$func_arith_result
- if test -z "$objlist" ||
+ if test "X$objlist" = X ||
test "$len" -lt "$max_cmd_len"; then
func_append objlist " $obj"
else
# The command $test_cmds is almost too long, add a
# command to the queue.
- if test 1 -eq "$k"; then
+ if test "$k" -eq 1 ; then
# The first file doesn't have a previous command to add.
reload_objs=$objlist
eval concat_cmds=\"$reload_cmds\"
@@ -9887,10 +8395,10 @@ EOF
reload_objs="$objlist $last_robj"
eval concat_cmds=\"\$concat_cmds~$reload_cmds~\$RM $last_robj\"
fi
- last_robj=$output_objdir/$output_la-$k.$objext
+ last_robj=$output_objdir/$output_la-${k}.$objext
func_arith $k + 1
k=$func_arith_result
- output=$output_objdir/$output_la-$k.$objext
+ output=$output_objdir/$output_la-${k}.$objext
objlist=" $obj"
func_len " $last_robj"
func_arith $len0 + $func_len_result
@@ -9902,9 +8410,9 @@ EOF
# files will link in the last one created.
test -z "$concat_cmds" || concat_cmds=$concat_cmds~
reload_objs="$objlist $last_robj"
- eval concat_cmds=\"\$concat_cmds$reload_cmds\"
+ eval concat_cmds=\"\${concat_cmds}$reload_cmds\"
if test -n "$last_robj"; then
- eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\"
+ eval concat_cmds=\"\${concat_cmds}~\$RM $last_robj\"
fi
func_append delfiles " $output"
@@ -9912,9 +8420,9 @@ EOF
output=
fi
- ${skipped_export-false} && {
- func_verbose "generating symbol list for '$libname.la'"
- export_symbols=$output_objdir/$libname.exp
+ if ${skipped_export-false}; then
+ func_verbose "generating symbol list for \`$libname.la'"
+ export_symbols="$output_objdir/$libname.exp"
$opt_dry_run || $RM $export_symbols
libobjs=$output
# Append the command to create the export file.
@@ -9923,16 +8431,16 @@ EOF
if test -n "$last_robj"; then
eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\"
fi
- }
+ fi
test -n "$save_libobjs" &&
func_verbose "creating a temporary reloadable object file: $output"
# Loop through the commands generated above and execute them.
- save_ifs=$IFS; IFS='~'
+ save_ifs="$IFS"; IFS='~'
for cmd in $concat_cmds; do
- IFS=$save_ifs
- $opt_quiet || {
+ IFS="$save_ifs"
+ $opt_silent || {
func_quote_for_expand "$cmd"
eval "func_echo $func_quote_for_expand_result"
}
@@ -9940,7 +8448,7 @@ EOF
lt_exit=$?
# Restore the uninstalled library and exit
- if test relink = "$opt_mode"; then
+ if test "$opt_mode" = relink; then
( cd "$output_objdir" && \
$RM "${realname}T" && \
$MV "${realname}U" "$realname" )
@@ -9949,7 +8457,7 @@ EOF
exit $lt_exit
}
done
- IFS=$save_ifs
+ IFS="$save_ifs"
if test -n "$export_symbols_regex" && ${skipped_export-false}; then
func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
@@ -9957,18 +8465,18 @@ EOF
fi
fi
- ${skipped_export-false} && {
+ if ${skipped_export-false}; then
if test -n "$export_symbols" && test -n "$include_expsyms"; then
- tmp_export_symbols=$export_symbols
- test -n "$orig_export_symbols" && tmp_export_symbols=$orig_export_symbols
+ tmp_export_symbols="$export_symbols"
+ test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols"
$opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"'
fi
if test -n "$orig_export_symbols"; then
# The given exports_symbols file has to be filtered, so filter it.
- func_verbose "filter symbol list for '$libname.la' to tag DATA exports"
+ func_verbose "filter symbol list for \`$libname.la' to tag DATA exports"
# FIXME: $output_objdir/$libname.filter potentially contains lots of
- # 's' commands, which not all seds can handle. GNU sed should be fine
+ # 's' commands which not all seds can handle. GNU sed should be fine
# though. Also, the filter scales superlinearly with the number of
# global variables. join(1) would be nice here, but unfortunately
# isn't a blessed tool.
@@ -9977,7 +8485,7 @@ EOF
export_symbols=$output_objdir/$libname.def
$opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols
fi
- }
+ fi
libobjs=$output
# Restore the value of output.
@@ -9991,7 +8499,7 @@ EOF
# value of $libobjs for piecewise linking.
# Do each of the archive commands.
- if test yes = "$module" && test -n "$module_cmds"; then
+ if test "$module" = yes && test -n "$module_cmds" ; then
if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then
cmds=$module_expsym_cmds
else
@@ -10013,7 +8521,7 @@ EOF
# Add any objects from preloaded convenience libraries
if test -n "$dlprefiles"; then
- gentop=$output_objdir/${outputname}x
+ gentop="$output_objdir/${outputname}x"
func_append generated " $gentop"
func_extract_archives $gentop $dlprefiles
@@ -10021,12 +8529,11 @@ EOF
test "X$libobjs" = "X " && libobjs=
fi
- save_ifs=$IFS; IFS='~'
+ save_ifs="$IFS"; IFS='~'
for cmd in $cmds; do
- IFS=$sp$nl
+ IFS="$save_ifs"
eval cmd=\"$cmd\"
- IFS=$save_ifs
- $opt_quiet || {
+ $opt_silent || {
func_quote_for_expand "$cmd"
eval "func_echo $func_quote_for_expand_result"
}
@@ -10034,7 +8541,7 @@ EOF
lt_exit=$?
# Restore the uninstalled library and exit
- if test relink = "$opt_mode"; then
+ if test "$opt_mode" = relink; then
( cd "$output_objdir" && \
$RM "${realname}T" && \
$MV "${realname}U" "$realname" )
@@ -10043,10 +8550,10 @@ EOF
exit $lt_exit
}
done
- IFS=$save_ifs
+ IFS="$save_ifs"
# Restore the uninstalled library and exit
- if test relink = "$opt_mode"; then
+ if test "$opt_mode" = relink; then
$opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $?
if test -n "$convenience"; then
@@ -10066,39 +8573,39 @@ EOF
done
# If -module or -export-dynamic was specified, set the dlname.
- if test yes = "$module" || test yes = "$export_dynamic"; then
+ if test "$module" = yes || test "$export_dynamic" = yes; then
# On all known operating systems, these are identical.
- dlname=$soname
+ dlname="$soname"
fi
fi
;;
obj)
- if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then
- func_warning "'-dlopen' is ignored for objects"
+ if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+ func_warning "\`-dlopen' is ignored for objects"
fi
case " $deplibs" in
*\ -l* | *\ -L*)
- func_warning "'-l' and '-L' are ignored for objects" ;;
+ func_warning "\`-l' and \`-L' are ignored for objects" ;;
esac
test -n "$rpath" && \
- func_warning "'-rpath' is ignored for objects"
+ func_warning "\`-rpath' is ignored for objects"
test -n "$xrpath" && \
- func_warning "'-R' is ignored for objects"
+ func_warning "\`-R' is ignored for objects"
test -n "$vinfo" && \
- func_warning "'-version-info' is ignored for objects"
+ func_warning "\`-version-info' is ignored for objects"
test -n "$release" && \
- func_warning "'-release' is ignored for objects"
+ func_warning "\`-release' is ignored for objects"
case $output in
*.lo)
test -n "$objs$old_deplibs" && \
- func_fatal_error "cannot build library object '$output' from non-libtool objects"
+ func_fatal_error "cannot build library object \`$output' from non-libtool objects"
libobj=$output
func_lo2o "$libobj"
@@ -10106,7 +8613,7 @@ EOF
;;
*)
libobj=
- obj=$output
+ obj="$output"
;;
esac
@@ -10119,19 +8626,17 @@ EOF
# the extraction.
reload_conv_objs=
gentop=
- # if reload_cmds runs $LD directly, get rid of -Wl from
- # whole_archive_flag_spec and hope we can get by with turning comma
- # into space.
- case $reload_cmds in
- *\$LD[\ \$]*) wl= ;;
- esac
+ # reload_cmds runs $LD directly, so let us get rid of
+ # -Wl from whole_archive_flag_spec and hope we can get by with
+ # turning comma into space..
+ wl=
+
if test -n "$convenience"; then
if test -n "$whole_archive_flag_spec"; then
eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\"
- test -n "$wl" || tmp_whole_archive_flags=`$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'`
- reload_conv_objs=$reload_objs\ $tmp_whole_archive_flags
+ reload_conv_objs=$reload_objs\ `$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'`
else
- gentop=$output_objdir/${obj}x
+ gentop="$output_objdir/${obj}x"
func_append generated " $gentop"
func_extract_archives $gentop $convenience
@@ -10140,12 +8645,12 @@ EOF
fi
# If we're not building shared, we need to use non_pic_objs
- test yes = "$build_libtool_libs" || libobjs=$non_pic_objects
+ test "$build_libtool_libs" != yes && libobjs="$non_pic_objects"
# Create the old-style object.
- reload_objs=$objs$old_deplibs' '`$ECHO "$libobjs" | $SP2NL | $SED "/\.$libext$/d; /\.lib$/d; $lo2o" | $NL2SP`' '$reload_conv_objs
+ reload_objs="$objs$old_deplibs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; /\.lib$/d; $lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test
- output=$obj
+ output="$obj"
func_execute_cmds "$reload_cmds" 'exit $?'
# Exit if we aren't doing a library object file.
@@ -10157,7 +8662,7 @@ EOF
exit $EXIT_SUCCESS
fi
- test yes = "$build_libtool_libs" || {
+ if test "$build_libtool_libs" != yes; then
if test -n "$gentop"; then
func_show_eval '${RM}r "$gentop"'
fi
@@ -10167,12 +8672,12 @@ EOF
# $show "echo timestamp > $libobj"
# $opt_dry_run || eval "echo timestamp > $libobj" || exit $?
exit $EXIT_SUCCESS
- }
+ fi
- if test -n "$pic_flag" || test default != "$pic_mode"; then
+ if test -n "$pic_flag" || test "$pic_mode" != default; then
# Only do commands if we really have different PIC objects.
reload_objs="$libobjs $reload_conv_objs"
- output=$libobj
+ output="$libobj"
func_execute_cmds "$reload_cmds" 'exit $?'
fi
@@ -10189,14 +8694,16 @@ EOF
output=$func_stripname_result.exe;;
esac
test -n "$vinfo" && \
- func_warning "'-version-info' is ignored for programs"
+ func_warning "\`-version-info' is ignored for programs"
test -n "$release" && \
- func_warning "'-release' is ignored for programs"
+ func_warning "\`-release' is ignored for programs"
- $preload \
- && test unknown,unknown,unknown = "$dlopen_support,$dlopen_self,$dlopen_self_static" \
- && func_warning "'LT_INIT([dlopen])' not used. Assuming no dlopen support."
+ test "$preload" = yes \
+ && test "$dlopen_support" = unknown \
+ && test "$dlopen_self" = unknown \
+ && test "$dlopen_self_static" = unknown && \
+ func_warning "\`LT_INIT([dlopen])' not used. Assuming no dlopen support."
case $host in
*-*-rhapsody* | *-*-darwin1.[012])
@@ -10210,11 +8717,11 @@ EOF
*-*-darwin*)
# Don't allow lazy linking, it breaks C++ global constructors
# But is supposedly fixed on 10.4 or later (yay!).
- if test CXX = "$tagname"; then
+ if test "$tagname" = CXX ; then
case ${MACOSX_DEPLOYMENT_TARGET-10.0} in
10.[0123])
- func_append compile_command " $wl-bind_at_load"
- func_append finalize_command " $wl-bind_at_load"
+ func_append compile_command " ${wl}-bind_at_load"
+ func_append finalize_command " ${wl}-bind_at_load"
;;
esac
fi
@@ -10250,7 +8757,7 @@ EOF
*) func_append new_libs " $deplib" ;;
esac
done
- compile_deplibs=$new_libs
+ compile_deplibs="$new_libs"
func_append compile_command " $compile_deplibs"
@@ -10274,7 +8781,7 @@ EOF
if test -n "$hardcode_libdir_flag_spec"; then
if test -n "$hardcode_libdir_separator"; then
if test -z "$hardcode_libdirs"; then
- hardcode_libdirs=$libdir
+ hardcode_libdirs="$libdir"
else
# Just accumulate the unique libdirs.
case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
@@ -10297,7 +8804,7 @@ EOF
fi
case $host in
*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
- testbindir=`$ECHO "$libdir" | $SED -e 's*/lib$*/bin*'`
+ testbindir=`${ECHO} "$libdir" | ${SED} -e 's*/lib$*/bin*'`
case :$dllsearchpath: in
*":$libdir:"*) ;;
::) dllsearchpath=$libdir;;
@@ -10314,10 +8821,10 @@ EOF
# Substitute the hardcoded libdirs into the rpath.
if test -n "$hardcode_libdir_separator" &&
test -n "$hardcode_libdirs"; then
- libdir=$hardcode_libdirs
+ libdir="$hardcode_libdirs"
eval rpath=\" $hardcode_libdir_flag_spec\"
fi
- compile_rpath=$rpath
+ compile_rpath="$rpath"
rpath=
hardcode_libdirs=
@@ -10325,7 +8832,7 @@ EOF
if test -n "$hardcode_libdir_flag_spec"; then
if test -n "$hardcode_libdir_separator"; then
if test -z "$hardcode_libdirs"; then
- hardcode_libdirs=$libdir
+ hardcode_libdirs="$libdir"
else
# Just accumulate the unique libdirs.
case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
@@ -10350,43 +8857,45 @@ EOF
# Substitute the hardcoded libdirs into the rpath.
if test -n "$hardcode_libdir_separator" &&
test -n "$hardcode_libdirs"; then
- libdir=$hardcode_libdirs
+ libdir="$hardcode_libdirs"
eval rpath=\" $hardcode_libdir_flag_spec\"
fi
- finalize_rpath=$rpath
+ finalize_rpath="$rpath"
- if test -n "$libobjs" && test yes = "$build_old_libs"; then
+ if test -n "$libobjs" && test "$build_old_libs" = yes; then
# Transform all the library objects into standard objects.
compile_command=`$ECHO "$compile_command" | $SP2NL | $SED "$lo2o" | $NL2SP`
finalize_command=`$ECHO "$finalize_command" | $SP2NL | $SED "$lo2o" | $NL2SP`
fi
- func_generate_dlsyms "$outputname" "@PROGRAM@" false
+ func_generate_dlsyms "$outputname" "@PROGRAM@" "no"
# template prelinking step
if test -n "$prelink_cmds"; then
func_execute_cmds "$prelink_cmds" 'exit $?'
fi
- wrappers_required=:
+ wrappers_required=yes
case $host in
*cegcc* | *mingw32ce*)
# Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway.
- wrappers_required=false
+ wrappers_required=no
;;
*cygwin* | *mingw* )
- test yes = "$build_libtool_libs" || wrappers_required=false
+ if test "$build_libtool_libs" != yes; then
+ wrappers_required=no
+ fi
;;
*)
- if test no = "$need_relink" || test yes != "$build_libtool_libs"; then
- wrappers_required=false
+ if test "$need_relink" = no || test "$build_libtool_libs" != yes; then
+ wrappers_required=no
fi
;;
esac
- $wrappers_required || {
+ if test "$wrappers_required" = no; then
# Replace the output file specification.
compile_command=`$ECHO "$compile_command" | $SED 's%@OUTPUT@%'"$output"'%g'`
- link_command=$compile_command$compile_rpath
+ link_command="$compile_command$compile_rpath"
# We have no uninstalled library dependencies, so finalize right now.
exit_status=0
@@ -10399,12 +8908,12 @@ EOF
fi
# Delete the generated files.
- if test -f "$output_objdir/${outputname}S.$objext"; then
- func_show_eval '$RM "$output_objdir/${outputname}S.$objext"'
+ if test -f "$output_objdir/${outputname}S.${objext}"; then
+ func_show_eval '$RM "$output_objdir/${outputname}S.${objext}"'
fi
exit $exit_status
- }
+ fi
if test -n "$compile_shlibpath$finalize_shlibpath"; then
compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command"
@@ -10434,9 +8943,9 @@ EOF
fi
fi
- if test yes = "$no_install"; then
+ if test "$no_install" = yes; then
# We don't need to create a wrapper script.
- link_command=$compile_var$compile_command$compile_rpath
+ link_command="$compile_var$compile_command$compile_rpath"
# Replace the output file specification.
link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output"'%g'`
# Delete the old output file.
@@ -10453,28 +8962,27 @@ EOF
exit $EXIT_SUCCESS
fi
- case $hardcode_action,$fast_install in
- relink,*)
- # Fast installation is not supported
- link_command=$compile_var$compile_command$compile_rpath
- relink_command=$finalize_var$finalize_command$finalize_rpath
+ if test "$hardcode_action" = relink; then
+ # Fast installation is not supported
+ link_command="$compile_var$compile_command$compile_rpath"
+ relink_command="$finalize_var$finalize_command$finalize_rpath"
- func_warning "this platform does not like uninstalled shared libraries"
- func_warning "'$output' will be relinked during installation"
- ;;
- *,yes)
- link_command=$finalize_var$compile_command$finalize_rpath
- relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'`
- ;;
- *,no)
- link_command=$compile_var$compile_command$compile_rpath
- relink_command=$finalize_var$finalize_command$finalize_rpath
- ;;
- *,needless)
- link_command=$finalize_var$compile_command$finalize_rpath
- relink_command=
- ;;
- esac
+ func_warning "this platform does not like uninstalled shared libraries"
+ func_warning "\`$output' will be relinked during installation"
+ else
+ if test "$fast_install" != no; then
+ link_command="$finalize_var$compile_command$finalize_rpath"
+ if test "$fast_install" = yes; then
+ relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'`
+ else
+ # fast_install is set to needless
+ relink_command=
+ fi
+ else
+ link_command="$compile_var$compile_command$compile_rpath"
+ relink_command="$finalize_var$finalize_command$finalize_rpath"
+ fi
+ fi
# Replace the output file specification.
link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'`
@@ -10531,8 +9039,8 @@ EOF
func_dirname_and_basename "$output" "" "."
output_name=$func_basename_result
output_path=$func_dirname_result
- cwrappersource=$output_path/$objdir/lt-$output_name.c
- cwrapper=$output_path/$output_name.exe
+ cwrappersource="$output_path/$objdir/lt-$output_name.c"
+ cwrapper="$output_path/$output_name.exe"
$RM $cwrappersource $cwrapper
trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15
@@ -10553,7 +9061,7 @@ EOF
trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15
$opt_dry_run || {
# note: this script will not be executed, so do not chmod.
- if test "x$build" = "x$host"; then
+ if test "x$build" = "x$host" ; then
$cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result
else
func_emit_wrapper no > $func_ltwrapper_scriptname_result
@@ -10576,27 +9084,25 @@ EOF
# See if we need to build an old-fashioned archive.
for oldlib in $oldlibs; do
- case $build_libtool_libs in
- convenience)
- oldobjs="$libobjs_save $symfileobj"
- addlibs=$convenience
- build_libtool_libs=no
- ;;
- module)
- oldobjs=$libobjs_save
- addlibs=$old_convenience
+ if test "$build_libtool_libs" = convenience; then
+ oldobjs="$libobjs_save $symfileobj"
+ addlibs="$convenience"
+ build_libtool_libs=no
+ else
+ if test "$build_libtool_libs" = module; then
+ oldobjs="$libobjs_save"
build_libtool_libs=no
- ;;
- *)
+ else
oldobjs="$old_deplibs $non_pic_objects"
- $preload && test -f "$symfileobj" \
- && func_append oldobjs " $symfileobj"
- addlibs=$old_convenience
- ;;
- esac
+ if test "$preload" = yes && test -f "$symfileobj"; then
+ func_append oldobjs " $symfileobj"
+ fi
+ fi
+ addlibs="$old_convenience"
+ fi
if test -n "$addlibs"; then
- gentop=$output_objdir/${outputname}x
+ gentop="$output_objdir/${outputname}x"
func_append generated " $gentop"
func_extract_archives $gentop $addlibs
@@ -10604,13 +9110,13 @@ EOF
fi
# Do each command in the archive commands.
- if test -n "$old_archive_from_new_cmds" && test yes = "$build_libtool_libs"; then
+ if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then
cmds=$old_archive_from_new_cmds
else
# Add any objects from preloaded convenience libraries
if test -n "$dlprefiles"; then
- gentop=$output_objdir/${outputname}x
+ gentop="$output_objdir/${outputname}x"
func_append generated " $gentop"
func_extract_archives $gentop $dlprefiles
@@ -10631,7 +9137,7 @@ EOF
:
else
echo "copying selected object files to avoid basename conflicts..."
- gentop=$output_objdir/${outputname}x
+ gentop="$output_objdir/${outputname}x"
func_append generated " $gentop"
func_mkdir_p "$gentop"
save_oldobjs=$oldobjs
@@ -10640,7 +9146,7 @@ EOF
for obj in $save_oldobjs
do
func_basename "$obj"
- objbase=$func_basename_result
+ objbase="$func_basename_result"
case " $oldobjs " in
" ") oldobjs=$obj ;;
*[\ /]"$objbase "*)
@@ -10709,18 +9215,18 @@ EOF
else
# the above command should be used before it gets too long
oldobjs=$objlist
- if test "$obj" = "$last_oldobj"; then
+ if test "$obj" = "$last_oldobj" ; then
RANLIB=$save_RANLIB
fi
test -z "$concat_cmds" || concat_cmds=$concat_cmds~
- eval concat_cmds=\"\$concat_cmds$old_archive_cmds\"
+ eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\"
objlist=
len=$len0
fi
done
RANLIB=$save_RANLIB
oldobjs=$objlist
- if test -z "$oldobjs"; then
+ if test "X$oldobjs" = "X" ; then
eval cmds=\"\$concat_cmds\"
else
eval cmds=\"\$concat_cmds~\$old_archive_cmds\"
@@ -10737,7 +9243,7 @@ EOF
case $output in
*.la)
old_library=
- test yes = "$build_old_libs" && old_library=$libname.$libext
+ test "$build_old_libs" = yes && old_library="$libname.$libext"
func_verbose "creating $output"
# Preserve any variables that may affect compiler behavior
@@ -10752,31 +9258,31 @@ EOF
fi
done
# Quote the link command for shipping.
- relink_command="(cd `pwd`; $SHELL \"$progpath\" $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)"
+ relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)"
relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"`
- if test yes = "$hardcode_automatic"; then
+ if test "$hardcode_automatic" = yes ; then
relink_command=
fi
# Only create the output if not a dry run.
$opt_dry_run || {
for installed in no yes; do
- if test yes = "$installed"; then
+ if test "$installed" = yes; then
if test -z "$install_libdir"; then
break
fi
- output=$output_objdir/${outputname}i
+ output="$output_objdir/$outputname"i
# Replace all uninstalled libtool libraries with the installed ones
newdependency_libs=
for deplib in $dependency_libs; do
case $deplib in
*.la)
func_basename "$deplib"
- name=$func_basename_result
+ name="$func_basename_result"
func_resolve_sysroot "$deplib"
- eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $func_resolve_sysroot_result`
+ eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $func_resolve_sysroot_result`
test -z "$libdir" && \
- func_fatal_error "'$deplib' is not a valid libtool archive"
+ func_fatal_error "\`$deplib' is not a valid libtool archive"
func_append newdependency_libs " ${lt_sysroot:+=}$libdir/$name"
;;
-L*)
@@ -10792,23 +9298,23 @@ EOF
*) func_append newdependency_libs " $deplib" ;;
esac
done
- dependency_libs=$newdependency_libs
+ dependency_libs="$newdependency_libs"
newdlfiles=
for lib in $dlfiles; do
case $lib in
*.la)
func_basename "$lib"
- name=$func_basename_result
- eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
+ name="$func_basename_result"
+ eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
test -z "$libdir" && \
- func_fatal_error "'$lib' is not a valid libtool archive"
+ func_fatal_error "\`$lib' is not a valid libtool archive"
func_append newdlfiles " ${lt_sysroot:+=}$libdir/$name"
;;
*) func_append newdlfiles " $lib" ;;
esac
done
- dlfiles=$newdlfiles
+ dlfiles="$newdlfiles"
newdlprefiles=
for lib in $dlprefiles; do
case $lib in
@@ -10818,34 +9324,34 @@ EOF
# didn't already link the preopened objects directly into
# the library:
func_basename "$lib"
- name=$func_basename_result
- eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
+ name="$func_basename_result"
+ eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
test -z "$libdir" && \
- func_fatal_error "'$lib' is not a valid libtool archive"
+ func_fatal_error "\`$lib' is not a valid libtool archive"
func_append newdlprefiles " ${lt_sysroot:+=}$libdir/$name"
;;
esac
done
- dlprefiles=$newdlprefiles
+ dlprefiles="$newdlprefiles"
else
newdlfiles=
for lib in $dlfiles; do
case $lib in
- [\\/]* | [A-Za-z]:[\\/]*) abs=$lib ;;
+ [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;;
*) abs=`pwd`"/$lib" ;;
esac
func_append newdlfiles " $abs"
done
- dlfiles=$newdlfiles
+ dlfiles="$newdlfiles"
newdlprefiles=
for lib in $dlprefiles; do
case $lib in
- [\\/]* | [A-Za-z]:[\\/]*) abs=$lib ;;
+ [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;;
*) abs=`pwd`"/$lib" ;;
esac
func_append newdlprefiles " $abs"
done
- dlprefiles=$newdlprefiles
+ dlprefiles="$newdlprefiles"
fi
$RM $output
# place dlname in correct position for cygwin
@@ -10861,9 +9367,10 @@ EOF
case $host,$output,$installed,$module,$dlname in
*cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll)
# If a -bindir argument was supplied, place the dll there.
- if test -n "$bindir"; then
+ if test "x$bindir" != x ;
+ then
func_relative_path "$install_libdir" "$bindir"
- tdlname=$func_relative_path_result/$dlname
+ tdlname=$func_relative_path_result$dlname
else
# Otherwise fall back on heuristic.
tdlname=../bin/$dlname
@@ -10872,7 +9379,7 @@ EOF
esac
$ECHO > $output "\
# $outputname - a libtool library file
-# Generated by $PROGRAM (GNU $PACKAGE) $VERSION
+# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
#
# Please DO NOT delete this file!
# It is necessary for linking the library.
@@ -10886,7 +9393,7 @@ library_names='$library_names'
# The name of the static archive.
old_library='$old_library'
-# Linker flags that cannot go in dependency_libs.
+# Linker flags that can not go in dependency_libs.
inherited_linker_flags='$new_inherited_linker_flags'
# Libraries that this one depends upon.
@@ -10912,7 +9419,7 @@ dlpreopen='$dlprefiles'
# Directory that this library needs to be installed in:
libdir='$install_libdir'"
- if test no,yes = "$installed,$need_relink"; then
+ if test "$installed" = no && test "$need_relink" = yes; then
$ECHO >> $output "\
relink_command=\"$relink_command\""
fi
@@ -10927,29 +9434,27 @@ relink_command=\"$relink_command\""
exit $EXIT_SUCCESS
}
-if test link = "$opt_mode" || test relink = "$opt_mode"; then
- func_mode_link ${1+"$@"}
-fi
+{ test "$opt_mode" = link || test "$opt_mode" = relink; } &&
+ func_mode_link ${1+"$@"}
# func_mode_uninstall arg...
func_mode_uninstall ()
{
- $debug_cmd
-
- RM=$nonopt
+ $opt_debug
+ RM="$nonopt"
files=
- rmforce=false
+ rmforce=
exit_status=0
# This variable tells wrapper scripts just to set variables rather
# than running their programs.
- libtool_install_magic=$magic
+ libtool_install_magic="$magic"
for arg
do
case $arg in
- -f) func_append RM " $arg"; rmforce=: ;;
+ -f) func_append RM " $arg"; rmforce=yes ;;
-*) func_append RM " $arg" ;;
*) func_append files " $arg" ;;
esac
@@ -10962,18 +9467,18 @@ func_mode_uninstall ()
for file in $files; do
func_dirname "$file" "" "."
- dir=$func_dirname_result
- if test . = "$dir"; then
- odir=$objdir
+ dir="$func_dirname_result"
+ if test "X$dir" = X.; then
+ odir="$objdir"
else
- odir=$dir/$objdir
+ odir="$dir/$objdir"
fi
func_basename "$file"
- name=$func_basename_result
- test uninstall = "$opt_mode" && odir=$dir
+ name="$func_basename_result"
+ test "$opt_mode" = uninstall && odir="$dir"
# Remember odir for removal later, being careful to avoid duplicates
- if test clean = "$opt_mode"; then
+ if test "$opt_mode" = clean; then
case " $rmdirs " in
*" $odir "*) ;;
*) func_append rmdirs " $odir" ;;
@@ -10988,11 +9493,11 @@ func_mode_uninstall ()
elif test -d "$file"; then
exit_status=1
continue
- elif $rmforce; then
+ elif test "$rmforce" = yes; then
continue
fi
- rmfiles=$file
+ rmfiles="$file"
case $name in
*.la)
@@ -11006,7 +9511,7 @@ func_mode_uninstall ()
done
test -n "$old_library" && func_append rmfiles " $odir/$old_library"
- case $opt_mode in
+ case "$opt_mode" in
clean)
case " $library_names " in
*" $dlname "*) ;;
@@ -11017,12 +9522,12 @@ func_mode_uninstall ()
uninstall)
if test -n "$library_names"; then
# Do each command in the postuninstall commands.
- func_execute_cmds "$postuninstall_cmds" '$rmforce || exit_status=1'
+ func_execute_cmds "$postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1'
fi
if test -n "$old_library"; then
# Do each command in the old_postuninstall commands.
- func_execute_cmds "$old_postuninstall_cmds" '$rmforce || exit_status=1'
+ func_execute_cmds "$old_postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1'
fi
# FIXME: should reinstall the best remaining shared library.
;;
@@ -11038,19 +9543,21 @@ func_mode_uninstall ()
func_source $dir/$name
# Add PIC object to the list of files to remove.
- if test -n "$pic_object" && test none != "$pic_object"; then
+ if test -n "$pic_object" &&
+ test "$pic_object" != none; then
func_append rmfiles " $dir/$pic_object"
fi
# Add non-PIC object to the list of files to remove.
- if test -n "$non_pic_object" && test none != "$non_pic_object"; then
+ if test -n "$non_pic_object" &&
+ test "$non_pic_object" != none; then
func_append rmfiles " $dir/$non_pic_object"
fi
fi
;;
*)
- if test clean = "$opt_mode"; then
+ if test "$opt_mode" = clean ; then
noexename=$name
case $file in
*.exe)
@@ -11077,12 +9584,12 @@ func_mode_uninstall ()
# note $name still contains .exe if it was in $file originally
# as does the version of $file that was added into $rmfiles
- func_append rmfiles " $odir/$name $odir/${name}S.$objext"
- if test yes = "$fast_install" && test -n "$relink_command"; then
+ func_append rmfiles " $odir/$name $odir/${name}S.${objext}"
+ if test "$fast_install" = yes && test -n "$relink_command"; then
func_append rmfiles " $odir/lt-$name"
fi
- if test "X$noexename" != "X$name"; then
- func_append rmfiles " $odir/lt-$noexename.c"
+ if test "X$noexename" != "X$name" ; then
+ func_append rmfiles " $odir/lt-${noexename}.c"
fi
fi
fi
@@ -11091,7 +9598,7 @@ func_mode_uninstall ()
func_show_eval "$RM $rmfiles" 'exit_status=1'
done
- # Try to remove the $objdir's in the directories where we deleted files
+ # Try to remove the ${objdir}s in the directories where we deleted files
for dir in $rmdirs; do
if test -d "$dir"; then
func_show_eval "rmdir $dir >/dev/null 2>&1"
@@ -11101,17 +9608,16 @@ func_mode_uninstall ()
exit $exit_status
}
-if test uninstall = "$opt_mode" || test clean = "$opt_mode"; then
- func_mode_uninstall ${1+"$@"}
-fi
+{ test "$opt_mode" = uninstall || test "$opt_mode" = clean; } &&
+ func_mode_uninstall ${1+"$@"}
test -z "$opt_mode" && {
- help=$generic_help
+ help="$generic_help"
func_fatal_help "you must specify a MODE"
}
test -z "$exec_cmd" && \
- func_fatal_help "invalid operation mode '$opt_mode'"
+ func_fatal_help "invalid operation mode \`$opt_mode'"
if test -n "$exec_cmd"; then
eval exec "$exec_cmd"
@@ -11122,7 +9628,7 @@ exit $exit_status
# The TAGs below are defined such that we never get into a situation
-# where we disable both kinds of libraries. Given conflicting
+# in which we disable both kinds of libraries. Given conflicting
# choices, we go for a static library, that is the most portable,
# since we can't tell whether shared libraries were disabled because
# the user asked for that or because the platform doesn't support
@@ -11145,3 +9651,5 @@ build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac`
# mode:shell-script
# sh-indentation:2
# End:
+# vi:sw=2
+
diff --git a/m4/ax_socklen_t.m4 b/m4/ax_socklen_t.m4
index cd7cad8..b420a17 100644
--- a/m4/ax_socklen_t.m4
+++ b/m4/ax_socklen_t.m4
@@ -55,7 +55,7 @@ getpeername(0,0,&len);
],
[[
#include <sys/types.h>
-#ifdef WIN32
+#ifdef _WIN32
#include <ws2tcpip.h>
#else
#include <sys/socket.h>
diff --git a/m4/libtool.m4 b/m4/libtool.m4
index a644432..56666f0 100644
--- a/m4/libtool.m4
+++ b/m4/libtool.m4
@@ -1,6 +1,8 @@
# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*-
#
-# Copyright (C) 1996-2001, 2003-2015 Free Software Foundation, Inc.
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
+# 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+# Foundation, Inc.
# Written by Gordon Matzigkeit, 1996
#
# This file is free software; the Free Software Foundation gives
@@ -8,30 +10,36 @@
# modifications, as long as this notice is preserved.
m4_define([_LT_COPYING], [dnl
-# Copyright (C) 2014 Free Software Foundation, Inc.
-# This is free software; see the source for copying conditions. There is NO
-# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
-# GNU Libtool is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of of the License, or
-# (at your option) any later version.
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
+# 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+# Foundation, Inc.
+# Written by Gordon Matzigkeit, 1996
+#
+# This file is part of GNU Libtool.
+#
+# GNU Libtool is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
#
-# As a special exception to the GNU General Public License, if you
-# distribute this file as part of a program or library that is built
-# using GNU Libtool, you may include this file under the same
-# distribution terms that you use for the rest of that program.
+# As a special exception to the GNU General Public License,
+# if you distribute this file as part of a program or library that
+# is built using GNU Libtool, you may include this file under the
+# same distribution terms that you use for the rest of that program.
#
-# GNU Libtool is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
+# GNU Libtool is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
+# along with GNU Libtool; see the file COPYING. If not, a copy
+# can be downloaded from http://www.gnu.org/licenses/gpl.html, or
+# obtained by writing to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
])
-# serial 58 LT_INIT
+# serial 57 LT_INIT
# LT_PREREQ(VERSION)
@@ -59,7 +67,7 @@ esac
# LT_INIT([OPTIONS])
# ------------------
AC_DEFUN([LT_INIT],
-[AC_PREREQ([2.62])dnl We use AC_PATH_PROGS_FEATURE_CHECK
+[AC_PREREQ([2.58])dnl We use AC_INCLUDES_DEFAULT
AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl
AC_BEFORE([$0], [LT_LANG])dnl
AC_BEFORE([$0], [LT_OUTPUT])dnl
@@ -83,7 +91,7 @@ dnl Parse OPTIONS
_LT_SET_OPTIONS([$0], [$1])
# This can be used to rebuild libtool when needed
-LIBTOOL_DEPS=$ltmain
+LIBTOOL_DEPS="$ltmain"
# Always use our own libtool.
LIBTOOL='$(SHELL) $(top_builddir)/libtool'
@@ -103,43 +111,26 @@ dnl AC_DEFUN([AC_PROG_LIBTOOL], [])
dnl AC_DEFUN([AM_PROG_LIBTOOL], [])
-# _LT_PREPARE_CC_BASENAME
-# -----------------------
-m4_defun([_LT_PREPARE_CC_BASENAME], [
-# Calculate cc_basename. Skip known compiler wrappers and cross-prefix.
-func_cc_basename ()
-{
- for cc_temp in @S|@*""; do
- case $cc_temp in
- compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;;
- distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;;
- \-*) ;;
- *) break;;
- esac
- done
- func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
-}
-])# _LT_PREPARE_CC_BASENAME
-
-
# _LT_CC_BASENAME(CC)
# -------------------
-# It would be clearer to call AC_REQUIREs from _LT_PREPARE_CC_BASENAME,
-# but that macro is also expanded into generated libtool script, which
-# arranges for $SED and $ECHO to be set by different means.
+# Calculate cc_basename. Skip known compiler wrappers and cross-prefix.
m4_defun([_LT_CC_BASENAME],
-[m4_require([_LT_PREPARE_CC_BASENAME])dnl
-AC_REQUIRE([_LT_DECL_SED])dnl
-AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl
-func_cc_basename $1
-cc_basename=$func_cc_basename_result
+[for cc_temp in $1""; do
+ case $cc_temp in
+ compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;;
+ distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;;
+ \-*) ;;
+ *) break;;
+ esac
+done
+cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
])
# _LT_FILEUTILS_DEFAULTS
# ----------------------
# It is okay to use these file commands and assume they have been set
-# sensibly after 'm4_require([_LT_FILEUTILS_DEFAULTS])'.
+# sensibly after `m4_require([_LT_FILEUTILS_DEFAULTS])'.
m4_defun([_LT_FILEUTILS_DEFAULTS],
[: ${CP="cp -f"}
: ${MV="mv -f"}
@@ -186,16 +177,15 @@ m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl
m4_require([_LT_CMD_OLD_ARCHIVE])dnl
m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl
m4_require([_LT_WITH_SYSROOT])dnl
-m4_require([_LT_CMD_TRUNCATE])dnl
_LT_CONFIG_LIBTOOL_INIT([
-# See if we are running on zsh, and set the options that allow our
+# See if we are running on zsh, and set the options which allow our
# commands through without removal of \ escapes INIT.
-if test -n "\${ZSH_VERSION+set}"; then
+if test -n "\${ZSH_VERSION+set}" ; then
setopt NO_GLOB_SUBST
fi
])
-if test -n "${ZSH_VERSION+set}"; then
+if test -n "${ZSH_VERSION+set}" ; then
setopt NO_GLOB_SUBST
fi
@@ -208,7 +198,7 @@ aix3*)
# AIX sometimes has problems with the GCC collect2 program. For some
# reason, if we set the COLLECT_NAMES environment variable, the problems
# vanish in a puff of smoke.
- if test set != "${COLLECT_NAMES+set}"; then
+ if test "X${COLLECT_NAMES+set}" != Xset; then
COLLECT_NAMES=
export COLLECT_NAMES
fi
@@ -219,14 +209,14 @@ esac
ofile=libtool
can_build_shared=yes
-# All known linkers require a '.a' archive for static linking (except MSVC,
+# All known linkers require a `.a' archive for static linking (except MSVC,
# which needs '.lib').
libext=a
-with_gnu_ld=$lt_cv_prog_gnu_ld
+with_gnu_ld="$lt_cv_prog_gnu_ld"
-old_CC=$CC
-old_CFLAGS=$CFLAGS
+old_CC="$CC"
+old_CFLAGS="$CFLAGS"
# Set sane defaults for various variables
test -z "$CC" && CC=cc
@@ -279,14 +269,14 @@ no_glob_subst='s/\*/\\\*/g'
# _LT_PROG_LTMAIN
# ---------------
-# Note that this code is called both from 'configure', and 'config.status'
+# Note that this code is called both from `configure', and `config.status'
# now that we use AC_CONFIG_COMMANDS to generate libtool. Notably,
-# 'config.status' has no value for ac_aux_dir unless we are using Automake,
+# `config.status' has no value for ac_aux_dir unless we are using Automake,
# so we pass a copy along to make sure it has a sensible value anyway.
m4_defun([_LT_PROG_LTMAIN],
[m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl
_LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir'])
-ltmain=$ac_aux_dir/ltmain.sh
+ltmain="$ac_aux_dir/ltmain.sh"
])# _LT_PROG_LTMAIN
@@ -296,7 +286,7 @@ ltmain=$ac_aux_dir/ltmain.sh
# So that we can recreate a full libtool script including additional
# tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS
-# in macros and then make a single call at the end using the 'libtool'
+# in macros and then make a single call at the end using the `libtool'
# label.
@@ -431,8 +421,8 @@ m4_define([_lt_decl_all_varnames],
# _LT_CONFIG_STATUS_DECLARE([VARNAME])
# ------------------------------------
-# Quote a variable value, and forward it to 'config.status' so that its
-# declaration there will have the same value as in 'configure'. VARNAME
+# Quote a variable value, and forward it to `config.status' so that its
+# declaration there will have the same value as in `configure'. VARNAME
# must have a single quote delimited value for this to work.
m4_define([_LT_CONFIG_STATUS_DECLARE],
[$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`'])
@@ -456,7 +446,7 @@ m4_defun([_LT_CONFIG_STATUS_DECLARATIONS],
# Output comment and list of tags supported by the script
m4_defun([_LT_LIBTOOL_TAGS],
[_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl
-available_tags='_LT_TAGS'dnl
+available_tags="_LT_TAGS"dnl
])
@@ -484,7 +474,7 @@ m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl
# _LT_LIBTOOL_CONFIG_VARS
# -----------------------
# Produce commented declarations of non-tagged libtool config variables
-# suitable for insertion in the LIBTOOL CONFIG section of the 'libtool'
+# suitable for insertion in the LIBTOOL CONFIG section of the `libtool'
# script. Tagged libtool config variables (even for the LIBTOOL CONFIG
# section) are produced by _LT_LIBTOOL_TAG_VARS.
m4_defun([_LT_LIBTOOL_CONFIG_VARS],
@@ -510,8 +500,8 @@ m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])])
# Send accumulated output to $CONFIG_STATUS. Thanks to the lists of
# variables for single and double quote escaping we saved from calls
# to _LT_DECL, we can put quote escaped variables declarations
-# into 'config.status', and then the shell code to quote escape them in
-# for loops in 'config.status'. Finally, any additional code accumulated
+# into `config.status', and then the shell code to quote escape them in
+# for loops in `config.status'. Finally, any additional code accumulated
# from calls to _LT_CONFIG_LIBTOOL_INIT is expanded.
m4_defun([_LT_CONFIG_COMMANDS],
[AC_PROVIDE_IFELSE([LT_OUTPUT],
@@ -557,7 +547,7 @@ for var in lt_decl_all_varnames([[ \
]], lt_decl_quote_varnames); do
case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
*[[\\\\\\\`\\"\\\$]]*)
- eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes
+ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\""
;;
*)
eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
@@ -570,7 +560,7 @@ for var in lt_decl_all_varnames([[ \
]], lt_decl_dquote_varnames); do
case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
*[[\\\\\\\`\\"\\\$]]*)
- eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes
+ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\""
;;
*)
eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
@@ -586,7 +576,7 @@ _LT_OUTPUT_LIBTOOL_INIT
# Generate a child script FILE with all initialization necessary to
# reuse the environment learned by the parent script, and make the
# file executable. If COMMENT is supplied, it is inserted after the
-# '#!' sequence but before initialization text begins. After this
+# `#!' sequence but before initialization text begins. After this
# macro, additional text can be appended to FILE to form the body of
# the child script. The macro ends with non-zero status if the
# file could not be fully written (such as if the disk is full).
@@ -608,7 +598,7 @@ AS_SHELL_SANITIZE
_AS_PREPARE
exec AS_MESSAGE_FD>&1
_ASEOF
-test 0 = "$lt_write_fail" && chmod +x $1[]dnl
+test $lt_write_fail = 0 && chmod +x $1[]dnl
m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT
# LT_OUTPUT
@@ -631,7 +621,7 @@ exec AS_MESSAGE_LOG_FD>>config.log
} >&AS_MESSAGE_LOG_FD
lt_cl_help="\
-'$as_me' creates a local libtool stub from the current configuration,
+\`$as_me' creates a local libtool stub from the current configuration,
for use in further configure time tests before the real libtool is
generated.
@@ -653,7 +643,7 @@ Copyright (C) 2011 Free Software Foundation, Inc.
This config.lt script is free software; the Free Software Foundation
gives unlimited permision to copy, distribute and modify it."
-while test 0 != $[#]
+while test $[#] != 0
do
case $[1] in
--version | --v* | -V )
@@ -666,10 +656,10 @@ do
lt_cl_silent=: ;;
-*) AC_MSG_ERROR([unrecognized option: $[1]
-Try '$[0] --help' for more information.]) ;;
+Try \`$[0] --help' for more information.]) ;;
*) AC_MSG_ERROR([unrecognized argument: $[1]
-Try '$[0] --help' for more information.]) ;;
+Try \`$[0] --help' for more information.]) ;;
esac
shift
done
@@ -695,7 +685,7 @@ chmod +x "$CONFIG_LT"
# open by configure. Here we exec the FD to /dev/null, effectively closing
# config.log, so it can be properly (re)opened and appended to by config.lt.
lt_cl_success=:
-test yes = "$silent" &&
+test "$silent" = yes &&
lt_config_lt_args="$lt_config_lt_args --quiet"
exec AS_MESSAGE_LOG_FD>/dev/null
$SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false
@@ -715,31 +705,27 @@ m4_defun([_LT_CONFIG],
_LT_CONFIG_SAVE_COMMANDS([
m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl
m4_if(_LT_TAG, [C], [
- # See if we are running on zsh, and set the options that allow our
+ # See if we are running on zsh, and set the options which allow our
# commands through without removal of \ escapes.
- if test -n "${ZSH_VERSION+set}"; then
+ if test -n "${ZSH_VERSION+set}" ; then
setopt NO_GLOB_SUBST
fi
- cfgfile=${ofile}T
+ cfgfile="${ofile}T"
trap "$RM \"$cfgfile\"; exit 1" 1 2 15
$RM "$cfgfile"
cat <<_LT_EOF >> "$cfgfile"
#! $SHELL
-# Generated automatically by $as_me ($PACKAGE) $VERSION
+
+# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services.
+# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION
# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
# NOTE: Changes made to this file will be lost: look at ltmain.sh.
-
-# Provide generalized library-building support services.
-# Written by Gordon Matzigkeit, 1996
-
+#
_LT_COPYING
_LT_LIBTOOL_TAGS
-# Configured defaults for sys_lib_dlsearch_path munging.
-: \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"}
-
# ### BEGIN LIBTOOL CONFIG
_LT_LIBTOOL_CONFIG_VARS
_LT_LIBTOOL_TAG_VARS
@@ -747,24 +733,13 @@ _LT_LIBTOOL_TAG_VARS
_LT_EOF
- cat <<'_LT_EOF' >> "$cfgfile"
-
-# ### BEGIN FUNCTIONS SHARED WITH CONFIGURE
-
-_LT_PREPARE_MUNGE_PATH_LIST
-_LT_PREPARE_CC_BASENAME
-
-# ### END FUNCTIONS SHARED WITH CONFIGURE
-
-_LT_EOF
-
case $host_os in
aix3*)
cat <<\_LT_EOF >> "$cfgfile"
# AIX sometimes has problems with the GCC collect2 program. For some
# reason, if we set the COLLECT_NAMES environment variable, the problems
# vanish in a puff of smoke.
-if test set != "${COLLECT_NAMES+set}"; then
+if test "X${COLLECT_NAMES+set}" != Xset; then
COLLECT_NAMES=
export COLLECT_NAMES
fi
@@ -781,6 +756,8 @@ _LT_EOF
sed '$q' "$ltmain" >> "$cfgfile" \
|| (rm -f "$cfgfile"; exit 1)
+ _LT_PROG_REPLACE_SHELLFNS
+
mv -f "$cfgfile" "$ofile" ||
(rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
chmod +x "$ofile"
@@ -798,6 +775,7 @@ _LT_EOF
[m4_if([$1], [], [
PACKAGE='$PACKAGE'
VERSION='$VERSION'
+ TIMESTAMP='$TIMESTAMP'
RM='$RM'
ofile='$ofile'], [])
])dnl /_LT_CONFIG_SAVE_COMMANDS
@@ -996,7 +974,7 @@ m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[
AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod],
[lt_cv_apple_cc_single_mod=no
- if test -z "$LT_MULTI_MODULE"; then
+ if test -z "${LT_MULTI_MODULE}"; then
# By default we will add the -single_module flag. You can override
# by either setting the environment variable LT_MULTI_MODULE
# non-empty at configure time, or by adding -multi_module to the
@@ -1014,7 +992,7 @@ m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[
cat conftest.err >&AS_MESSAGE_LOG_FD
# Otherwise, if the output was created with a 0 exit code from
# the compiler, it worked.
- elif test -f libconftest.dylib && test 0 = "$_lt_result"; then
+ elif test -f libconftest.dylib && test $_lt_result -eq 0; then
lt_cv_apple_cc_single_mod=yes
else
cat conftest.err >&AS_MESSAGE_LOG_FD
@@ -1032,7 +1010,7 @@ m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[
AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])],
[lt_cv_ld_exported_symbols_list=yes],
[lt_cv_ld_exported_symbols_list=no])
- LDFLAGS=$save_LDFLAGS
+ LDFLAGS="$save_LDFLAGS"
])
AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load],
@@ -1054,7 +1032,7 @@ _LT_EOF
_lt_result=$?
if test -s conftest.err && $GREP force_load conftest.err; then
cat conftest.err >&AS_MESSAGE_LOG_FD
- elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then
+ elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then
lt_cv_ld_force_load=yes
else
cat conftest.err >&AS_MESSAGE_LOG_FD
@@ -1064,32 +1042,32 @@ _LT_EOF
])
case $host_os in
rhapsody* | darwin1.[[012]])
- _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;;
+ _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;;
darwin1.*)
- _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;;
+ _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
darwin*) # darwin 5.x on
# if running on 10.5 or later, the deployment target defaults
# to the OS version, if on x86, and 10.4, the deployment
# target defaults to 10.4. Don't you love it?
case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in
10.0,*86*-darwin8*|10.0,*-darwin[[91]]*)
- _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;;
- 10.[[012]][[,.]]*)
- _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;;
+ _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
+ 10.[[012]]*)
+ _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
10.*)
- _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;;
+ _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
esac
;;
esac
- if test yes = "$lt_cv_apple_cc_single_mod"; then
+ if test "$lt_cv_apple_cc_single_mod" = "yes"; then
_lt_dar_single_mod='$single_module'
fi
- if test yes = "$lt_cv_ld_exported_symbols_list"; then
- _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym'
+ if test "$lt_cv_ld_exported_symbols_list" = "yes"; then
+ _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym'
else
- _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib'
+ _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}'
fi
- if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then
+ if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then
_lt_dsymutil='~$DSYMUTIL $lib || :'
else
_lt_dsymutil=
@@ -1109,29 +1087,29 @@ m4_defun([_LT_DARWIN_LINKER_FEATURES],
_LT_TAGVAR(hardcode_direct, $1)=no
_LT_TAGVAR(hardcode_automatic, $1)=yes
_LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
- if test yes = "$lt_cv_ld_force_load"; then
- _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
+ if test "$lt_cv_ld_force_load" = "yes"; then
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes],
[FC], [_LT_TAGVAR(compiler_needs_object, $1)=yes])
else
_LT_TAGVAR(whole_archive_flag_spec, $1)=''
fi
_LT_TAGVAR(link_all_deplibs, $1)=yes
- _LT_TAGVAR(allow_undefined_flag, $1)=$_lt_dar_allow_undefined
+ _LT_TAGVAR(allow_undefined_flag, $1)="$_lt_dar_allow_undefined"
case $cc_basename in
- ifort*|nagfor*) _lt_dar_can_shared=yes ;;
+ ifort*) _lt_dar_can_shared=yes ;;
*) _lt_dar_can_shared=$GCC ;;
esac
- if test yes = "$_lt_dar_can_shared"; then
+ if test "$_lt_dar_can_shared" = "yes"; then
output_verbose_link_cmd=func_echo_all
- _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil"
- _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil"
- _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil"
- _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil"
+ _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
+ _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}"
+ _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}"
+ _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}"
m4_if([$1], [CXX],
-[ if test yes != "$lt_cv_apple_cc_single_mod"; then
- _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dsymutil"
- _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil"
+[ if test "$lt_cv_apple_cc_single_mod" != "yes"; then
+ _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}"
+ _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}"
fi
],[])
else
@@ -1151,7 +1129,7 @@ m4_defun([_LT_DARWIN_LINKER_FEATURES],
# Allow to override them for all tags through lt_cv_aix_libpath.
m4_defun([_LT_SYS_MODULE_PATH_AIX],
[m4_require([_LT_DECL_SED])dnl
-if test set = "${lt_cv_aix_libpath+set}"; then
+if test "${lt_cv_aix_libpath+set}" = set; then
aix_libpath=$lt_cv_aix_libpath
else
AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])],
@@ -1169,7 +1147,7 @@ else
_LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
fi],[])
if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then
- _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=/usr/lib:/lib
+ _LT_TAGVAR([lt_cv_aix_libpath_], [$1])="/usr/lib:/lib"
fi
])
aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])
@@ -1189,8 +1167,8 @@ m4_define([_LT_SHELL_INIT],
# -----------------------
# Find how we can fake an echo command that does not interpret backslash.
# In particular, with Autoconf 2.60 or later we add some code to the start
-# of the generated configure script that will find a shell with a builtin
-# printf (that we can use as an echo command).
+# of the generated configure script which will find a shell with a builtin
+# printf (which we can use as an echo command).
m4_defun([_LT_PROG_ECHO_BACKSLASH],
[ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO
@@ -1218,10 +1196,10 @@ fi
# Invoke $ECHO with all args, space-separated.
func_echo_all ()
{
- $ECHO "$*"
+ $ECHO "$*"
}
-case $ECHO in
+case "$ECHO" in
printf*) AC_MSG_RESULT([printf]) ;;
print*) AC_MSG_RESULT([print -r]) ;;
*) AC_MSG_RESULT([cat]) ;;
@@ -1247,17 +1225,16 @@ _LT_DECL([], [ECHO], [1], [An echo program that protects backslashes])
AC_DEFUN([_LT_WITH_SYSROOT],
[AC_MSG_CHECKING([for sysroot])
AC_ARG_WITH([sysroot],
-[AS_HELP_STRING([--with-sysroot@<:@=DIR@:>@],
- [Search for dependent libraries within DIR (or the compiler's sysroot
- if not specified).])],
+[ --with-sysroot[=DIR] Search for dependent libraries within DIR
+ (or the compiler's sysroot if not specified).],
[], [with_sysroot=no])
dnl lt_sysroot will always be passed unquoted. We quote it here
dnl in case the user passed a directory name.
lt_sysroot=
-case $with_sysroot in #(
+case ${with_sysroot} in #(
yes)
- if test yes = "$GCC"; then
+ if test "$GCC" = yes; then
lt_sysroot=`$CC --print-sysroot 2>/dev/null`
fi
;; #(
@@ -1267,14 +1244,14 @@ case $with_sysroot in #(
no|'')
;; #(
*)
- AC_MSG_RESULT([$with_sysroot])
+ AC_MSG_RESULT([${with_sysroot}])
AC_MSG_ERROR([The sysroot must be an absolute path.])
;;
esac
AC_MSG_RESULT([${lt_sysroot:-no}])
_LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl
-[dependent libraries, and where our libraries should be installed.])])
+[dependent libraries, and in which our libraries should be installed.])])
# _LT_ENABLE_LOCK
# ---------------
@@ -1282,33 +1259,31 @@ m4_defun([_LT_ENABLE_LOCK],
[AC_ARG_ENABLE([libtool-lock],
[AS_HELP_STRING([--disable-libtool-lock],
[avoid locking (might break parallel builds)])])
-test no = "$enable_libtool_lock" || enable_libtool_lock=yes
+test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
# Some flags need to be propagated to the compiler or linker for good
# libtool support.
case $host in
ia64-*-hpux*)
- # Find out what ABI is being produced by ac_compile, and set mode
- # options accordingly.
+ # Find out which ABI we are using.
echo 'int i;' > conftest.$ac_ext
if AC_TRY_EVAL(ac_compile); then
case `/usr/bin/file conftest.$ac_objext` in
*ELF-32*)
- HPUX_IA64_MODE=32
+ HPUX_IA64_MODE="32"
;;
*ELF-64*)
- HPUX_IA64_MODE=64
+ HPUX_IA64_MODE="64"
;;
esac
fi
rm -rf conftest*
;;
*-*-irix6*)
- # Find out what ABI is being produced by ac_compile, and set linker
- # options accordingly.
+ # Find out which ABI we are using.
echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext
if AC_TRY_EVAL(ac_compile); then
- if test yes = "$lt_cv_prog_gnu_ld"; then
+ if test "$lt_cv_prog_gnu_ld" = yes; then
case `/usr/bin/file conftest.$ac_objext` in
*32-bit*)
LD="${LD-ld} -melf32bsmip"
@@ -1337,46 +1312,9 @@ ia64-*-hpux*)
rm -rf conftest*
;;
-mips64*-*linux*)
- # Find out what ABI is being produced by ac_compile, and set linker
- # options accordingly.
- echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext
- if AC_TRY_EVAL(ac_compile); then
- emul=elf
- case `/usr/bin/file conftest.$ac_objext` in
- *32-bit*)
- emul="${emul}32"
- ;;
- *64-bit*)
- emul="${emul}64"
- ;;
- esac
- case `/usr/bin/file conftest.$ac_objext` in
- *MSB*)
- emul="${emul}btsmip"
- ;;
- *LSB*)
- emul="${emul}ltsmip"
- ;;
- esac
- case `/usr/bin/file conftest.$ac_objext` in
- *N32*)
- emul="${emul}n32"
- ;;
- esac
- LD="${LD-ld} -m $emul"
- fi
- rm -rf conftest*
- ;;
-
-x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \
+x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \
s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
- # Find out what ABI is being produced by ac_compile, and set linker
- # options accordingly. Note that the listed cases only cover the
- # situations where additional linker options are needed (such as when
- # doing 32-bit compilation for a host where ld defaults to 64-bit, or
- # vice versa); the common cases where no linker options are needed do
- # not appear in the list.
+ # Find out which ABI we are using.
echo 'int i;' > conftest.$ac_ext
if AC_TRY_EVAL(ac_compile); then
case `/usr/bin/file conftest.o` in
@@ -1386,19 +1324,9 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
LD="${LD-ld} -m elf_i386_fbsd"
;;
x86_64-*linux*)
- case `/usr/bin/file conftest.o` in
- *x86-64*)
- LD="${LD-ld} -m elf32_x86_64"
- ;;
- *)
- LD="${LD-ld} -m elf_i386"
- ;;
- esac
- ;;
- powerpc64le-*linux*)
- LD="${LD-ld} -m elf32lppclinux"
+ LD="${LD-ld} -m elf_i386"
;;
- powerpc64-*linux*)
+ ppc64-*linux*|powerpc64-*linux*)
LD="${LD-ld} -m elf32ppclinux"
;;
s390x-*linux*)
@@ -1417,10 +1345,7 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
x86_64-*linux*)
LD="${LD-ld} -m elf_x86_64"
;;
- powerpcle-*linux*)
- LD="${LD-ld} -m elf64lppc"
- ;;
- powerpc-*linux*)
+ ppc*-*linux*|powerpc*-*linux*)
LD="${LD-ld} -m elf64ppc"
;;
s390*-*linux*|s390*-*tpf*)
@@ -1438,20 +1363,19 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
*-*-sco3.2v5*)
# On SCO OpenServer 5, we need -belf to get full-featured binaries.
- SAVE_CFLAGS=$CFLAGS
+ SAVE_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS -belf"
AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf,
[AC_LANG_PUSH(C)
AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no])
AC_LANG_POP])
- if test yes != "$lt_cv_cc_needs_belf"; then
+ if test x"$lt_cv_cc_needs_belf" != x"yes"; then
# this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
- CFLAGS=$SAVE_CFLAGS
+ CFLAGS="$SAVE_CFLAGS"
fi
;;
*-*solaris*)
- # Find out what ABI is being produced by ac_compile, and set linker
- # options accordingly.
+ # Find out which ABI we are using.
echo 'int i;' > conftest.$ac_ext
if AC_TRY_EVAL(ac_compile); then
case `/usr/bin/file conftest.o` in
@@ -1459,7 +1383,7 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
case $lt_cv_prog_gnu_ld in
yes*)
case $host in
- i?86-*-solaris*|x86_64-*-solaris*)
+ i?86-*-solaris*)
LD="${LD-ld} -m elf_x86_64"
;;
sparc*-*-solaris*)
@@ -1468,7 +1392,7 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
esac
# GNU ld 2.21 introduced _sol2 emulations. Use them if available.
if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then
- LD=${LD-ld}_sol2
+ LD="${LD-ld}_sol2"
fi
;;
*)
@@ -1484,7 +1408,7 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
;;
esac
-need_locks=$enable_libtool_lock
+need_locks="$enable_libtool_lock"
])# _LT_ENABLE_LOCK
@@ -1503,11 +1427,11 @@ AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file],
[echo conftest.$ac_objext > conftest.lst
lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD'
AC_TRY_EVAL([lt_ar_try])
- if test 0 -eq "$ac_status"; then
+ if test "$ac_status" -eq 0; then
# Ensure the archiver fails upon bogus file names.
rm -f conftest.$ac_objext libconftest.a
AC_TRY_EVAL([lt_ar_try])
- if test 0 -ne "$ac_status"; then
+ if test "$ac_status" -ne 0; then
lt_cv_ar_at_file=@
fi
fi
@@ -1515,7 +1439,7 @@ AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file],
])
])
-if test no = "$lt_cv_ar_at_file"; then
+if test "x$lt_cv_ar_at_file" = xno; then
archiver_list_spec=
else
archiver_list_spec=$lt_cv_ar_at_file
@@ -1546,7 +1470,7 @@ old_postuninstall_cmds=
if test -n "$RANLIB"; then
case $host_os in
- bitrig* | openbsd*)
+ openbsd*)
old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib"
;;
*)
@@ -1582,7 +1506,7 @@ AC_CACHE_CHECK([$1], [$2],
[$2=no
m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4])
echo "$lt_simple_compile_test_code" > conftest.$ac_ext
- lt_compiler_flag="$3" ## exclude from sc_useless_quotes_in_assignment
+ lt_compiler_flag="$3"
# Insert the option either (1) after the last *FLAGS variable, or
# (2) before a word containing "conftest.", or (3) at the end.
# Note that $ac_compile itself does not contain backslashes and begins
@@ -1609,7 +1533,7 @@ AC_CACHE_CHECK([$1], [$2],
$RM conftest*
])
-if test yes = "[$]$2"; then
+if test x"[$]$2" = xyes; then
m4_if([$5], , :, [$5])
else
m4_if([$6], , :, [$6])
@@ -1631,7 +1555,7 @@ AC_DEFUN([_LT_LINKER_OPTION],
m4_require([_LT_DECL_SED])dnl
AC_CACHE_CHECK([$1], [$2],
[$2=no
- save_LDFLAGS=$LDFLAGS
+ save_LDFLAGS="$LDFLAGS"
LDFLAGS="$LDFLAGS $3"
echo "$lt_simple_link_test_code" > conftest.$ac_ext
if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
@@ -1650,10 +1574,10 @@ AC_CACHE_CHECK([$1], [$2],
fi
fi
$RM -r conftest*
- LDFLAGS=$save_LDFLAGS
+ LDFLAGS="$save_LDFLAGS"
])
-if test yes = "[$]$2"; then
+if test x"[$]$2" = xyes; then
m4_if([$4], , :, [$4])
else
m4_if([$5], , :, [$5])
@@ -1674,7 +1598,7 @@ AC_DEFUN([LT_CMD_MAX_LEN],
AC_MSG_CHECKING([the maximum length of command line arguments])
AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl
i=0
- teststring=ABCD
+ teststring="ABCD"
case $build_os in
msdosdjgpp*)
@@ -1714,7 +1638,7 @@ AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl
lt_cv_sys_max_cmd_len=8192;
;;
- bitrig* | darwin* | dragonfly* | freebsd* | netbsd* | openbsd*)
+ netbsd* | freebsd* | openbsd* | darwin* | dragonfly*)
# This has been around since 386BSD, at least. Likely further.
if test -x /sbin/sysctl; then
lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`
@@ -1764,23 +1688,22 @@ AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl
;;
*)
lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null`
- if test -n "$lt_cv_sys_max_cmd_len" && \
- test undefined != "$lt_cv_sys_max_cmd_len"; then
+ if test -n "$lt_cv_sys_max_cmd_len"; then
lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
else
# Make teststring a little bigger before we do anything with it.
# a 1K string should be a reasonable start.
- for i in 1 2 3 4 5 6 7 8; do
+ for i in 1 2 3 4 5 6 7 8 ; do
teststring=$teststring$teststring
done
SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}}
# If test is not a shell built-in, we'll probably end up computing a
# maximum length that is only half of the actual maximum length, but
# we can't tell.
- while { test X`env echo "$teststring$teststring" 2>/dev/null` \
+ while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \
= "X$teststring$teststring"; } >/dev/null 2>&1 &&
- test 17 != "$i" # 1/2 MB should be enough
+ test $i != 17 # 1/2 MB should be enough
do
i=`expr $i + 1`
teststring=$teststring$teststring
@@ -1796,7 +1719,7 @@ AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl
;;
esac
])
-if test -n "$lt_cv_sys_max_cmd_len"; then
+if test -n $lt_cv_sys_max_cmd_len ; then
AC_MSG_RESULT($lt_cv_sys_max_cmd_len)
else
AC_MSG_RESULT(none)
@@ -1824,7 +1747,7 @@ m4_defun([_LT_HEADER_DLFCN],
# ----------------------------------------------------------------
m4_defun([_LT_TRY_DLOPEN_SELF],
[m4_require([_LT_HEADER_DLFCN])dnl
-if test yes = "$cross_compiling"; then :
+if test "$cross_compiling" = yes; then :
[$4]
else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
@@ -1871,9 +1794,9 @@ else
# endif
#endif
-/* When -fvisibility=hidden is used, assume the code has been annotated
+/* When -fvisbility=hidden is used, assume the code has been annotated
correspondingly for the symbols needed. */
-#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
int fnord () __attribute__((visibility("default")));
#endif
@@ -1899,7 +1822,7 @@ int main ()
return status;
}]
_LT_EOF
- if AC_TRY_EVAL(ac_link) && test -s "conftest$ac_exeext" 2>/dev/null; then
+ if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then
(./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null
lt_status=$?
case x$lt_status in
@@ -1920,7 +1843,7 @@ rm -fr conftest*
# ------------------
AC_DEFUN([LT_SYS_DLOPEN_SELF],
[m4_require([_LT_HEADER_DLFCN])dnl
-if test yes != "$enable_dlopen"; then
+if test "x$enable_dlopen" != xyes; then
enable_dlopen=unknown
enable_dlopen_self=unknown
enable_dlopen_self_static=unknown
@@ -1930,52 +1853,44 @@ else
case $host_os in
beos*)
- lt_cv_dlopen=load_add_on
+ lt_cv_dlopen="load_add_on"
lt_cv_dlopen_libs=
lt_cv_dlopen_self=yes
;;
mingw* | pw32* | cegcc*)
- lt_cv_dlopen=LoadLibrary
+ lt_cv_dlopen="LoadLibrary"
lt_cv_dlopen_libs=
;;
cygwin*)
- lt_cv_dlopen=dlopen
+ lt_cv_dlopen="dlopen"
lt_cv_dlopen_libs=
;;
darwin*)
- # if libdl is installed we need to link against it
+ # if libdl is installed we need to link against it
AC_CHECK_LIB([dl], [dlopen],
- [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl],[
- lt_cv_dlopen=dyld
+ [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[
+ lt_cv_dlopen="dyld"
lt_cv_dlopen_libs=
lt_cv_dlopen_self=yes
])
;;
- tpf*)
- # Don't try to run any link tests for TPF. We know it's impossible
- # because TPF is a cross-compiler, and we know how we open DSOs.
- lt_cv_dlopen=dlopen
- lt_cv_dlopen_libs=
- lt_cv_dlopen_self=no
- ;;
-
*)
AC_CHECK_FUNC([shl_load],
- [lt_cv_dlopen=shl_load],
+ [lt_cv_dlopen="shl_load"],
[AC_CHECK_LIB([dld], [shl_load],
- [lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld],
+ [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"],
[AC_CHECK_FUNC([dlopen],
- [lt_cv_dlopen=dlopen],
+ [lt_cv_dlopen="dlopen"],
[AC_CHECK_LIB([dl], [dlopen],
- [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl],
+ [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],
[AC_CHECK_LIB([svld], [dlopen],
- [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld],
+ [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"],
[AC_CHECK_LIB([dld], [dld_link],
- [lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld])
+ [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"])
])
])
])
@@ -1984,21 +1899,21 @@ else
;;
esac
- if test no = "$lt_cv_dlopen"; then
- enable_dlopen=no
- else
+ if test "x$lt_cv_dlopen" != xno; then
enable_dlopen=yes
+ else
+ enable_dlopen=no
fi
case $lt_cv_dlopen in
dlopen)
- save_CPPFLAGS=$CPPFLAGS
- test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+ save_CPPFLAGS="$CPPFLAGS"
+ test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
- save_LDFLAGS=$LDFLAGS
+ save_LDFLAGS="$LDFLAGS"
wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
- save_LIBS=$LIBS
+ save_LIBS="$LIBS"
LIBS="$lt_cv_dlopen_libs $LIBS"
AC_CACHE_CHECK([whether a program can dlopen itself],
@@ -2008,7 +1923,7 @@ else
lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross)
])
- if test yes = "$lt_cv_dlopen_self"; then
+ if test "x$lt_cv_dlopen_self" = xyes; then
wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\"
AC_CACHE_CHECK([whether a statically linked program can dlopen itself],
lt_cv_dlopen_self_static, [dnl
@@ -2018,9 +1933,9 @@ else
])
fi
- CPPFLAGS=$save_CPPFLAGS
- LDFLAGS=$save_LDFLAGS
- LIBS=$save_LIBS
+ CPPFLAGS="$save_CPPFLAGS"
+ LDFLAGS="$save_LDFLAGS"
+ LIBS="$save_LIBS"
;;
esac
@@ -2112,8 +2027,8 @@ m4_defun([_LT_COMPILER_FILE_LOCKS],
m4_require([_LT_FILEUTILS_DEFAULTS])dnl
_LT_COMPILER_C_O([$1])
-hard_links=nottested
-if test no = "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" && test no != "$need_locks"; then
+hard_links="nottested"
+if test "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then
# do not overwrite the value of need_locks provided by the user
AC_MSG_CHECKING([if we can lock with hard links])
hard_links=yes
@@ -2123,8 +2038,8 @@ if test no = "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" && test no != "$need_loc
ln conftest.a conftest.b 2>&5 || hard_links=no
ln conftest.a conftest.b 2>/dev/null && hard_links=no
AC_MSG_RESULT([$hard_links])
- if test no = "$hard_links"; then
- AC_MSG_WARN(['$CC' does not support '-c -o', so 'make -j' may be unsafe])
+ if test "$hard_links" = no; then
+ AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe])
need_locks=warn
fi
else
@@ -2151,8 +2066,8 @@ objdir=$lt_cv_objdir
_LT_DECL([], [objdir], [0],
[The name of the directory that contains temporary libtool files])dnl
m4_pattern_allow([LT_OBJDIR])dnl
-AC_DEFINE_UNQUOTED([LT_OBJDIR], "$lt_cv_objdir/",
- [Define to the sub-directory where libtool stores uninstalled libraries.])
+AC_DEFINE_UNQUOTED(LT_OBJDIR, "$lt_cv_objdir/",
+ [Define to the sub-directory in which libtool stores uninstalled libraries.])
])# _LT_CHECK_OBJDIR
@@ -2164,15 +2079,15 @@ m4_defun([_LT_LINKER_HARDCODE_LIBPATH],
_LT_TAGVAR(hardcode_action, $1)=
if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" ||
test -n "$_LT_TAGVAR(runpath_var, $1)" ||
- test yes = "$_LT_TAGVAR(hardcode_automatic, $1)"; then
+ test "X$_LT_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then
# We can hardcode non-existent directories.
- if test no != "$_LT_TAGVAR(hardcode_direct, $1)" &&
+ if test "$_LT_TAGVAR(hardcode_direct, $1)" != no &&
# If the only mechanism to avoid hardcoding is shlibpath_var, we
# have to relink, otherwise we might link with an installed library
# when we should be linking with a yet-to-be-installed one
- ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" &&
- test no != "$_LT_TAGVAR(hardcode_minus_L, $1)"; then
+ ## test "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" != no &&
+ test "$_LT_TAGVAR(hardcode_minus_L, $1)" != no; then
# Linking always hardcodes the temporary library directory.
_LT_TAGVAR(hardcode_action, $1)=relink
else
@@ -2186,12 +2101,12 @@ else
fi
AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)])
-if test relink = "$_LT_TAGVAR(hardcode_action, $1)" ||
- test yes = "$_LT_TAGVAR(inherit_rpath, $1)"; then
+if test "$_LT_TAGVAR(hardcode_action, $1)" = relink ||
+ test "$_LT_TAGVAR(inherit_rpath, $1)" = yes; then
# Fast installation is not supported
enable_fast_install=no
-elif test yes = "$shlibpath_overrides_runpath" ||
- test no = "$enable_shared"; then
+elif test "$shlibpath_overrides_runpath" = yes ||
+ test "$enable_shared" = no; then
# Fast installation is not necessary
enable_fast_install=needless
fi
@@ -2215,7 +2130,7 @@ else
# FIXME - insert some real tests, host_os isn't really good enough
case $host_os in
darwin*)
- if test -n "$STRIP"; then
+ if test -n "$STRIP" ; then
striplib="$STRIP -x"
old_striplib="$STRIP -S"
AC_MSG_RESULT([yes])
@@ -2233,47 +2148,6 @@ _LT_DECL([], [striplib], [1])
])# _LT_CMD_STRIPLIB
-# _LT_PREPARE_MUNGE_PATH_LIST
-# ---------------------------
-# Make sure func_munge_path_list() is defined correctly.
-m4_defun([_LT_PREPARE_MUNGE_PATH_LIST],
-[[# func_munge_path_list VARIABLE PATH
-# -----------------------------------
-# VARIABLE is name of variable containing _space_ separated list of
-# directories to be munged by the contents of PATH, which is string
-# having a format:
-# "DIR[:DIR]:"
-# string "DIR[ DIR]" will be prepended to VARIABLE
-# ":DIR[:DIR]"
-# string "DIR[ DIR]" will be appended to VARIABLE
-# "DIRP[:DIRP]::[DIRA:]DIRA"
-# string "DIRP[ DIRP]" will be prepended to VARIABLE and string
-# "DIRA[ DIRA]" will be appended to VARIABLE
-# "DIR[:DIR]"
-# VARIABLE will be replaced by "DIR[ DIR]"
-func_munge_path_list ()
-{
- case x@S|@2 in
- x)
- ;;
- *:)
- eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'` \@S|@@S|@1\"
- ;;
- x:*)
- eval @S|@1=\"\@S|@@S|@1 `$ECHO @S|@2 | $SED 's/:/ /g'`\"
- ;;
- *::*)
- eval @S|@1=\"\@S|@@S|@1\ `$ECHO @S|@2 | $SED -e 's/.*:://' -e 's/:/ /g'`\"
- eval @S|@1=\"`$ECHO @S|@2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \@S|@@S|@1\"
- ;;
- *)
- eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'`\"
- ;;
- esac
-}
-]])# _LT_PREPARE_PATH_LIST
-
-
# _LT_SYS_DYNAMIC_LINKER([TAG])
# -----------------------------
# PORTME Fill in your ld.so characteristics
@@ -2284,18 +2158,17 @@ m4_require([_LT_FILEUTILS_DEFAULTS])dnl
m4_require([_LT_DECL_OBJDUMP])dnl
m4_require([_LT_DECL_SED])dnl
m4_require([_LT_CHECK_SHELL_FEATURES])dnl
-m4_require([_LT_PREPARE_MUNGE_PATH_LIST])dnl
AC_MSG_CHECKING([dynamic linker characteristics])
m4_if([$1],
[], [
-if test yes = "$GCC"; then
+if test "$GCC" = yes; then
case $host_os in
- darwin*) lt_awk_arg='/^libraries:/,/LR/' ;;
- *) lt_awk_arg='/^libraries:/' ;;
+ darwin*) lt_awk_arg="/^libraries:/,/LR/" ;;
+ *) lt_awk_arg="/^libraries:/" ;;
esac
case $host_os in
- mingw* | cegcc*) lt_sed_strip_eq='s|=\([[A-Za-z]]:\)|\1|g' ;;
- *) lt_sed_strip_eq='s|=/|/|g' ;;
+ mingw* | cegcc*) lt_sed_strip_eq="s,=\([[A-Za-z]]:\),\1,g" ;;
+ *) lt_sed_strip_eq="s,=/,/,g" ;;
esac
lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq`
case $lt_search_path_spec in
@@ -2311,35 +2184,28 @@ if test yes = "$GCC"; then
;;
esac
# Ok, now we have the path, separated by spaces, we can step through it
- # and add multilib dir if necessary...
+ # and add multilib dir if necessary.
lt_tmp_lt_search_path_spec=
- lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null`
- # ...but if some path component already ends with the multilib dir we assume
- # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer).
- case "$lt_multi_os_dir; $lt_search_path_spec " in
- "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*)
- lt_multi_os_dir=
- ;;
- esac
+ lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null`
for lt_sys_path in $lt_search_path_spec; do
- if test -d "$lt_sys_path$lt_multi_os_dir"; then
- lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir"
- elif test -n "$lt_multi_os_dir"; then
+ if test -d "$lt_sys_path/$lt_multi_os_dir"; then
+ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir"
+ else
test -d "$lt_sys_path" && \
lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path"
fi
done
lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk '
-BEGIN {RS = " "; FS = "/|\n";} {
- lt_foo = "";
- lt_count = 0;
+BEGIN {RS=" "; FS="/|\n";} {
+ lt_foo="";
+ lt_count=0;
for (lt_i = NF; lt_i > 0; lt_i--) {
if ($lt_i != "" && $lt_i != ".") {
if ($lt_i == "..") {
lt_count++;
} else {
if (lt_count == 0) {
- lt_foo = "/" $lt_i lt_foo;
+ lt_foo="/" $lt_i lt_foo;
} else {
lt_count--;
}
@@ -2353,7 +2219,7 @@ BEGIN {RS = " "; FS = "/|\n";} {
# for these hosts.
case $host_os in
mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\
- $SED 's|/\([[A-Za-z]]:\)|\1|g'` ;;
+ $SED 's,/\([[A-Za-z]]:\),\1,g'` ;;
esac
sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP`
else
@@ -2362,7 +2228,7 @@ fi])
library_names_spec=
libname_spec='lib$name'
soname_spec=
-shrext_cmds=.so
+shrext_cmds=".so"
postinstall_cmds=
postuninstall_cmds=
finish_cmds=
@@ -2379,17 +2245,14 @@ hardcode_into_libs=no
# flags to be left without arguments
need_version=unknown
-AC_ARG_VAR([LT_SYS_LIBRARY_PATH],
-[User-defined run-time library search path.])
-
case $host_os in
aix3*)
version_type=linux # correct to gnu/linux during the next big refactor
- library_names_spec='$libname$release$shared_ext$versuffix $libname.a'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
shlibpath_var=LIBPATH
# AIX 3 has no versioning support, so we append a major version to the name.
- soname_spec='$libname$release$shared_ext$major'
+ soname_spec='${libname}${release}${shared_ext}$major'
;;
aix[[4-9]]*)
@@ -2397,91 +2260,41 @@ aix[[4-9]]*)
need_lib_prefix=no
need_version=no
hardcode_into_libs=yes
- if test ia64 = "$host_cpu"; then
+ if test "$host_cpu" = ia64; then
# AIX 5 supports IA64
- library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext'
+ library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
shlibpath_var=LD_LIBRARY_PATH
else
# With GCC up to 2.95.x, collect2 would create an import file
# for dependence libraries. The import file would start with
- # the line '#! .'. This would cause the generated library to
- # depend on '.', always an invalid library. This was fixed in
+ # the line `#! .'. This would cause the generated library to
+ # depend on `.', always an invalid library. This was fixed in
# development snapshots of GCC prior to 3.0.
case $host_os in
aix4 | aix4.[[01]] | aix4.[[01]].*)
if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
echo ' yes '
- echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then
+ echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then
:
else
can_build_shared=no
fi
;;
esac
- # Using Import Files as archive members, it is possible to support
- # filename-based versioning of shared library archives on AIX. While
- # this would work for both with and without runtime linking, it will
- # prevent static linking of such archives. So we do filename-based
- # shared library versioning with .so extension only, which is used
- # when both runtime linking and shared linking is enabled.
- # Unfortunately, runtime linking may impact performance, so we do
- # not want this to be the default eventually. Also, we use the
- # versioned .so libs for executables only if there is the -brtl
- # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only.
- # To allow for filename-based versioning support, we need to create
- # libNAME.so.V as an archive file, containing:
- # *) an Import File, referring to the versioned filename of the
- # archive as well as the shared archive member, telling the
- # bitwidth (32 or 64) of that shared object, and providing the
- # list of exported symbols of that shared object, eventually
- # decorated with the 'weak' keyword
- # *) the shared object with the F_LOADONLY flag set, to really avoid
- # it being seen by the linker.
- # At run time we better use the real file rather than another symlink,
- # but for link time we create the symlink libNAME.so -> libNAME.so.V
-
- case $with_aix_soname,$aix_use_runtimelinking in
- # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct
+ # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
# soname into executable. Probably we can add versioning support to
# collect2, so additional links can be useful in future.
- aix,yes) # traditional libtool
- dynamic_linker='AIX unversionable lib.so'
+ if test "$aix_use_runtimelinking" = yes; then
# If using run time linking (on AIX 4.2 or later) use lib<name>.so
# instead of lib<name>.a to let people know that these are not
# typical AIX shared libraries.
- library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
- ;;
- aix,no) # traditional AIX only
- dynamic_linker='AIX lib.a[(]lib.so.V[)]'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ else
# We preserve .a as extension for shared libraries through AIX4.2
# and later when we are not doing run time linking.
- library_names_spec='$libname$release.a $libname.a'
- soname_spec='$libname$release$shared_ext$major'
- ;;
- svr4,*) # full svr4 only
- dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)]"
- library_names_spec='$libname$release$shared_ext$major $libname$shared_ext'
- # We do not specify a path in Import Files, so LIBPATH fires.
- shlibpath_overrides_runpath=yes
- ;;
- *,yes) # both, prefer svr4
- dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)], lib.a[(]lib.so.V[)]"
- library_names_spec='$libname$release$shared_ext$major $libname$shared_ext'
- # unpreferred sharedlib libNAME.a needs extra handling
- postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"'
- postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"'
- # We do not specify a path in Import Files, so LIBPATH fires.
- shlibpath_overrides_runpath=yes
- ;;
- *,no) # both, prefer aix
- dynamic_linker="AIX lib.a[(]lib.so.V[)], lib.so.V[(]$shared_archive_member_spec.o[)]"
- library_names_spec='$libname$release.a $libname.a'
- soname_spec='$libname$release$shared_ext$major'
- # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling
- postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)'
- postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"'
- ;;
- esac
+ library_names_spec='${libname}${release}.a $libname.a'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ fi
shlibpath_var=LIBPATH
fi
;;
@@ -2491,18 +2304,18 @@ amigaos*)
powerpc)
# Since July 2007 AmigaOS4 officially supports .so libraries.
# When compiling the executable, add -use-dynld -Lsobjs: to the compileline.
- library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
;;
m68k)
library_names_spec='$libname.ixlibrary $libname.a'
# Create ${libname}_ixlibrary.a entries in /sys/libs.
- finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+ finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
;;
esac
;;
beos*)
- library_names_spec='$libname$shared_ext'
+ library_names_spec='${libname}${shared_ext}'
dynamic_linker="$host_os ld.so"
shlibpath_var=LIBRARY_PATH
;;
@@ -2510,8 +2323,8 @@ beos*)
bsdi[[45]]*)
version_type=linux # correct to gnu/linux during the next big refactor
need_version=no
- library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
- soname_spec='$libname$release$shared_ext$major'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
shlibpath_var=LD_LIBRARY_PATH
sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
@@ -2523,7 +2336,7 @@ bsdi[[45]]*)
cygwin* | mingw* | pw32* | cegcc*)
version_type=windows
- shrext_cmds=.dll
+ shrext_cmds=".dll"
need_version=no
need_lib_prefix=no
@@ -2532,8 +2345,8 @@ cygwin* | mingw* | pw32* | cegcc*)
# gcc
library_names_spec='$libname.dll.a'
# DLL is installed to $(libdir)/../bin by postinstall_cmds
- postinstall_cmds='base_file=`basename \$file`~
- dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~
+ postinstall_cmds='base_file=`basename \${file}`~
+ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
dldir=$destdir/`dirname \$dlpath`~
test -d \$dldir || mkdir -p \$dldir~
$install_prog $dir/$dlname \$dldir/$dlname~
@@ -2549,17 +2362,17 @@ cygwin* | mingw* | pw32* | cegcc*)
case $host_os in
cygwin*)
# Cygwin DLLs use 'cyg' prefix rather than 'lib'
- soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext'
+ soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
m4_if([$1], [],[
sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"])
;;
mingw* | cegcc*)
# MinGW DLLs use traditional 'lib' prefix
- soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext'
+ soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
;;
pw32*)
# pw32 DLLs use 'pw' prefix rather than 'lib'
- library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext'
+ library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
;;
esac
dynamic_linker='Win32 ld.exe'
@@ -2568,8 +2381,8 @@ m4_if([$1], [],[
*,cl*)
# Native MSVC
libname_spec='$name'
- soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext'
- library_names_spec='$libname.dll.lib'
+ soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
+ library_names_spec='${libname}.dll.lib'
case $build_os in
mingw*)
@@ -2596,7 +2409,7 @@ m4_if([$1], [],[
sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
;;
*)
- sys_lib_search_path_spec=$LIB
+ sys_lib_search_path_spec="$LIB"
if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then
# It is most probably a Windows format PATH.
sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
@@ -2609,8 +2422,8 @@ m4_if([$1], [],[
esac
# DLL is installed to $(libdir)/../bin by postinstall_cmds
- postinstall_cmds='base_file=`basename \$file`~
- dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~
+ postinstall_cmds='base_file=`basename \${file}`~
+ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
dldir=$destdir/`dirname \$dlpath`~
test -d \$dldir || mkdir -p \$dldir~
$install_prog $dir/$dlname \$dldir/$dlname'
@@ -2623,7 +2436,7 @@ m4_if([$1], [],[
*)
# Assume MSVC wrapper
- library_names_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext $libname.lib'
+ library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib'
dynamic_linker='Win32 ld.exe'
;;
esac
@@ -2636,8 +2449,8 @@ darwin* | rhapsody*)
version_type=darwin
need_lib_prefix=no
need_version=no
- library_names_spec='$libname$release$major$shared_ext $libname$shared_ext'
- soname_spec='$libname$release$major$shared_ext'
+ library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext'
+ soname_spec='${libname}${release}${major}$shared_ext'
shlibpath_overrides_runpath=yes
shlibpath_var=DYLD_LIBRARY_PATH
shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
@@ -2650,8 +2463,8 @@ dgux*)
version_type=linux # correct to gnu/linux during the next big refactor
need_lib_prefix=no
need_version=no
- library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
- soname_spec='$libname$release$shared_ext$major'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
+ soname_spec='${libname}${release}${shared_ext}$major'
shlibpath_var=LD_LIBRARY_PATH
;;
@@ -2669,13 +2482,12 @@ freebsd* | dragonfly*)
version_type=freebsd-$objformat
case $version_type in
freebsd-elf*)
- library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
- soname_spec='$libname$release$shared_ext$major'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
need_version=no
need_lib_prefix=no
;;
freebsd-*)
- library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
need_version=yes
;;
esac
@@ -2700,15 +2512,26 @@ freebsd* | dragonfly*)
esac
;;
+gnu*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
haiku*)
version_type=linux # correct to gnu/linux during the next big refactor
need_lib_prefix=no
need_version=no
dynamic_linker="$host_os runtime_loader"
- library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
- soname_spec='$libname$release$shared_ext$major'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
shlibpath_var=LIBRARY_PATH
- shlibpath_overrides_runpath=no
+ shlibpath_overrides_runpath=yes
sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib'
hardcode_into_libs=yes
;;
@@ -2726,15 +2549,14 @@ hpux9* | hpux10* | hpux11*)
dynamic_linker="$host_os dld.so"
shlibpath_var=LD_LIBRARY_PATH
shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
- library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
- soname_spec='$libname$release$shared_ext$major'
- if test 32 = "$HPUX_IA64_MODE"; then
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ if test "X$HPUX_IA64_MODE" = X32; then
sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
- sys_lib_dlsearch_path_spec=/usr/lib/hpux32
else
sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
- sys_lib_dlsearch_path_spec=/usr/lib/hpux64
fi
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
;;
hppa*64*)
shrext_cmds='.sl'
@@ -2742,8 +2564,8 @@ hpux9* | hpux10* | hpux11*)
dynamic_linker="$host_os dld.sl"
shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
- library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
- soname_spec='$libname$release$shared_ext$major'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
;;
@@ -2752,8 +2574,8 @@ hpux9* | hpux10* | hpux11*)
dynamic_linker="$host_os dld.sl"
shlibpath_var=SHLIB_PATH
shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
- library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
- soname_spec='$libname$release$shared_ext$major'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
;;
esac
# HP-UX runs *really* slowly unless shared libraries are mode 555, ...
@@ -2766,8 +2588,8 @@ interix[[3-9]]*)
version_type=linux # correct to gnu/linux during the next big refactor
need_lib_prefix=no
need_version=no
- library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
- soname_spec='$libname$release$shared_ext$major'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
shlibpath_var=LD_LIBRARY_PATH
shlibpath_overrides_runpath=no
@@ -2778,7 +2600,7 @@ irix5* | irix6* | nonstopux*)
case $host_os in
nonstopux*) version_type=nonstopux ;;
*)
- if test yes = "$lt_cv_prog_gnu_ld"; then
+ if test "$lt_cv_prog_gnu_ld" = yes; then
version_type=linux # correct to gnu/linux during the next big refactor
else
version_type=irix
@@ -2786,8 +2608,8 @@ irix5* | irix6* | nonstopux*)
esac
need_lib_prefix=no
need_version=no
- soname_spec='$libname$release$shared_ext$major'
- library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
case $host_os in
irix5* | nonstopux*)
libsuff= shlibsuff=
@@ -2806,8 +2628,8 @@ irix5* | irix6* | nonstopux*)
esac
shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
shlibpath_overrides_runpath=no
- sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff"
- sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff"
+ sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+ sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
hardcode_into_libs=yes
;;
@@ -2816,33 +2638,13 @@ linux*oldld* | linux*aout* | linux*coff*)
dynamic_linker=no
;;
-linux*android*)
- version_type=none # Android doesn't support versioned libraries.
- need_lib_prefix=no
- need_version=no
- library_names_spec='$libname$release$shared_ext'
- soname_spec='$libname$release$shared_ext'
- finish_cmds=
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes
-
- # This implies no fast_install, which is unacceptable.
- # Some rework will be needed to allow for fast_install
- # before this can be enabled.
- hardcode_into_libs=yes
-
- dynamic_linker='Android linker'
- # Don't embed -rpath directories since the linker doesn't support them.
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
- ;;
-
# This must be glibc/ELF.
-linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+linux* | k*bsd*-gnu | kopensolaris*-gnu)
version_type=linux # correct to gnu/linux during the next big refactor
need_lib_prefix=no
need_version=no
- library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
- soname_spec='$libname$release$shared_ext$major'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
shlibpath_var=LD_LIBRARY_PATH
shlibpath_overrides_runpath=no
@@ -2870,15 +2672,11 @@ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
# Add ABI-specific directories to the system library path.
sys_lib_dlsearch_path_spec="/lib64 /usr/lib64 /lib /usr/lib"
- # Ideally, we could use ldconfig to report *all* directores which are
- # searched for libraries, however this is still not possible. Aside from not
- # being certain /sbin/ldconfig is available, command
- # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64,
- # even though it is searched at run-time. Try to do the best guess by
- # appending ld.so.conf contents (and includes) to the search path.
+ # Append ld.so.conf contents to the search path
if test -f /etc/ld.so.conf; then
lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '`
sys_lib_dlsearch_path_spec="$sys_lib_dlsearch_path_spec $lt_ld_extra"
+
fi
# We used to test for /lib/ld.so.1 and disable shared libraries on
@@ -2895,12 +2693,12 @@ netbsd*)
need_lib_prefix=no
need_version=no
if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
- library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
dynamic_linker='NetBSD (a.out) ld.so'
else
- library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
- soname_spec='$libname$release$shared_ext$major'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
dynamic_linker='NetBSD ld.elf_so'
fi
shlibpath_var=LD_LIBRARY_PATH
@@ -2910,7 +2708,7 @@ netbsd*)
newsos6)
version_type=linux # correct to gnu/linux during the next big refactor
- library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
shlibpath_var=LD_LIBRARY_PATH
shlibpath_overrides_runpath=yes
;;
@@ -2919,68 +2717,58 @@ newsos6)
version_type=qnx
need_lib_prefix=no
need_version=no
- library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
- soname_spec='$libname$release$shared_ext$major'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
shlibpath_var=LD_LIBRARY_PATH
shlibpath_overrides_runpath=no
hardcode_into_libs=yes
dynamic_linker='ldqnx.so'
;;
-openbsd* | bitrig*)
+openbsd*)
version_type=sunos
- sys_lib_dlsearch_path_spec=/usr/lib
+ sys_lib_dlsearch_path_spec="/usr/lib"
need_lib_prefix=no
- if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then
- need_version=no
- else
- need_version=yes
- fi
- library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+ # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
+ case $host_os in
+ openbsd3.3 | openbsd3.3.*) need_version=yes ;;
+ *) need_version=no ;;
+ esac
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ case $host_os in
+ openbsd2.[[89]] | openbsd2.[[89]].*)
+ shlibpath_overrides_runpath=no
+ ;;
+ *)
+ shlibpath_overrides_runpath=yes
+ ;;
+ esac
+ else
+ shlibpath_overrides_runpath=yes
+ fi
;;
os2*)
libname_spec='$name'
- version_type=windows
- shrext_cmds=.dll
- need_version=no
+ shrext_cmds=".dll"
need_lib_prefix=no
- # OS/2 can only load a DLL with a base name of 8 characters or less.
- soname_spec='`test -n "$os2dllname" && libname="$os2dllname";
- v=$($ECHO $release$versuffix | tr -d .-);
- n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _);
- $ECHO $n$v`$shared_ext'
- library_names_spec='${libname}_dll.$libext'
+ library_names_spec='$libname${shared_ext} $libname.a'
dynamic_linker='OS/2 ld.exe'
- shlibpath_var=BEGINLIBPATH
- sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
- sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
- postinstall_cmds='base_file=`basename \$file`~
- dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~
- dldir=$destdir/`dirname \$dlpath`~
- test -d \$dldir || mkdir -p \$dldir~
- $install_prog $dir/$dlname \$dldir/$dlname~
- chmod a+x \$dldir/$dlname~
- if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
- eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
- fi'
- postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~
- dlpath=$dir/\$dldll~
- $RM \$dlpath'
+ shlibpath_var=LIBPATH
;;
osf3* | osf4* | osf5*)
version_type=osf
need_lib_prefix=no
need_version=no
- soname_spec='$libname$release$shared_ext$major'
- library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
shlibpath_var=LD_LIBRARY_PATH
sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
- sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
;;
rdos*)
@@ -2991,8 +2779,8 @@ solaris*)
version_type=linux # correct to gnu/linux during the next big refactor
need_lib_prefix=no
need_version=no
- library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
- soname_spec='$libname$release$shared_ext$major'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
shlibpath_var=LD_LIBRARY_PATH
shlibpath_overrides_runpath=yes
hardcode_into_libs=yes
@@ -3002,11 +2790,11 @@ solaris*)
sunos4*)
version_type=sunos
- library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
shlibpath_var=LD_LIBRARY_PATH
shlibpath_overrides_runpath=yes
- if test yes = "$with_gnu_ld"; then
+ if test "$with_gnu_ld" = yes; then
need_lib_prefix=no
fi
need_version=yes
@@ -3014,8 +2802,8 @@ sunos4*)
sysv4 | sysv4.3*)
version_type=linux # correct to gnu/linux during the next big refactor
- library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
- soname_spec='$libname$release$shared_ext$major'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
shlibpath_var=LD_LIBRARY_PATH
case $host_vendor in
sni)
@@ -3036,24 +2824,24 @@ sysv4 | sysv4.3*)
;;
sysv4*MP*)
- if test -d /usr/nec; then
+ if test -d /usr/nec ;then
version_type=linux # correct to gnu/linux during the next big refactor
- library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext'
- soname_spec='$libname$shared_ext.$major'
+ library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
+ soname_spec='$libname${shared_ext}.$major'
shlibpath_var=LD_LIBRARY_PATH
fi
;;
sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
- version_type=sco
+ version_type=freebsd-elf
need_lib_prefix=no
need_version=no
- library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext'
- soname_spec='$libname$release$shared_ext$major'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
shlibpath_var=LD_LIBRARY_PATH
shlibpath_overrides_runpath=yes
hardcode_into_libs=yes
- if test yes = "$with_gnu_ld"; then
+ if test "$with_gnu_ld" = yes; then
sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
else
sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
@@ -3071,7 +2859,7 @@ tpf*)
version_type=linux # correct to gnu/linux during the next big refactor
need_lib_prefix=no
need_version=no
- library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
shlibpath_var=LD_LIBRARY_PATH
shlibpath_overrides_runpath=no
hardcode_into_libs=yes
@@ -3079,8 +2867,8 @@ tpf*)
uts4*)
version_type=linux # correct to gnu/linux during the next big refactor
- library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
- soname_spec='$libname$release$shared_ext$major'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
shlibpath_var=LD_LIBRARY_PATH
;;
@@ -3089,30 +2877,20 @@ uts4*)
;;
esac
AC_MSG_RESULT([$dynamic_linker])
-test no = "$dynamic_linker" && can_build_shared=no
+test "$dynamic_linker" = no && can_build_shared=no
variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
-if test yes = "$GCC"; then
+if test "$GCC" = yes; then
variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
fi
-if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then
- sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec
+if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then
+ sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec"
fi
-
-if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then
- sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec
+if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then
+ sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec"
fi
-# remember unaugmented sys_lib_dlsearch_path content for libtool script decls...
-configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec
-
-# ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code
-func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH"
-
-# to be used as default LT_SYS_LIBRARY_PATH value in generated libtool
-configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH
-
_LT_DECL([], [variables_saved_for_relink], [1],
[Variables whose values should be saved in libtool wrapper scripts and
restored at link time])
@@ -3145,41 +2923,39 @@ _LT_DECL([], [hardcode_into_libs], [0],
[Whether we should hardcode library paths into libraries])
_LT_DECL([], [sys_lib_search_path_spec], [2],
[Compile-time system search path for libraries])
-_LT_DECL([sys_lib_dlsearch_path_spec], [configure_time_dlsearch_path], [2],
- [Detected run-time system search path for libraries])
-_LT_DECL([], [configure_time_lt_sys_library_path], [2],
- [Explicit LT_SYS_LIBRARY_PATH set during ./configure time])
+_LT_DECL([], [sys_lib_dlsearch_path_spec], [2],
+ [Run-time system search path for libraries])
])# _LT_SYS_DYNAMIC_LINKER
# _LT_PATH_TOOL_PREFIX(TOOL)
# --------------------------
-# find a file program that can recognize shared library
+# find a file program which can recognize shared library
AC_DEFUN([_LT_PATH_TOOL_PREFIX],
[m4_require([_LT_DECL_EGREP])dnl
AC_MSG_CHECKING([for $1])
AC_CACHE_VAL(lt_cv_path_MAGIC_CMD,
[case $MAGIC_CMD in
[[\\/*] | ?:[\\/]*])
- lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path.
+ lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
;;
*)
- lt_save_MAGIC_CMD=$MAGIC_CMD
- lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+ lt_save_MAGIC_CMD="$MAGIC_CMD"
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
dnl $ac_dummy forces splitting on constant user-supplied paths.
dnl POSIX.2 word splitting is done only on the output of word expansions,
dnl not every word. This closes a longstanding sh security hole.
ac_dummy="m4_if([$2], , $PATH, [$2])"
for ac_dir in $ac_dummy; do
- IFS=$lt_save_ifs
+ IFS="$lt_save_ifs"
test -z "$ac_dir" && ac_dir=.
- if test -f "$ac_dir/$1"; then
- lt_cv_path_MAGIC_CMD=$ac_dir/"$1"
+ if test -f $ac_dir/$1; then
+ lt_cv_path_MAGIC_CMD="$ac_dir/$1"
if test -n "$file_magic_test_file"; then
case $deplibs_check_method in
"file_magic "*)
file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
- MAGIC_CMD=$lt_cv_path_MAGIC_CMD
+ MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
$EGREP "$file_magic_regex" > /dev/null; then
:
@@ -3202,11 +2978,11 @@ _LT_EOF
break
fi
done
- IFS=$lt_save_ifs
- MAGIC_CMD=$lt_save_MAGIC_CMD
+ IFS="$lt_save_ifs"
+ MAGIC_CMD="$lt_save_MAGIC_CMD"
;;
esac])
-MAGIC_CMD=$lt_cv_path_MAGIC_CMD
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
if test -n "$MAGIC_CMD"; then
AC_MSG_RESULT($MAGIC_CMD)
else
@@ -3224,7 +3000,7 @@ dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], [])
# _LT_PATH_MAGIC
# --------------
-# find a file program that can recognize a shared library
+# find a file program which can recognize a shared library
m4_defun([_LT_PATH_MAGIC],
[_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH)
if test -z "$lt_cv_path_MAGIC_CMD"; then
@@ -3251,16 +3027,16 @@ m4_require([_LT_PROG_ECHO_BACKSLASH])dnl
AC_ARG_WITH([gnu-ld],
[AS_HELP_STRING([--with-gnu-ld],
[assume the C compiler uses GNU ld @<:@default=no@:>@])],
- [test no = "$withval" || with_gnu_ld=yes],
+ [test "$withval" = no || with_gnu_ld=yes],
[with_gnu_ld=no])dnl
ac_prog=ld
-if test yes = "$GCC"; then
+if test "$GCC" = yes; then
# Check if gcc -print-prog-name=ld gives a path.
AC_MSG_CHECKING([for ld used by $CC])
case $host in
*-*-mingw*)
- # gcc leaves a trailing carriage return, which upsets mingw
+ # gcc leaves a trailing carriage return which upsets mingw
ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
*)
ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
@@ -3274,7 +3050,7 @@ if test yes = "$GCC"; then
while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do
ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"`
done
- test -z "$LD" && LD=$ac_prog
+ test -z "$LD" && LD="$ac_prog"
;;
"")
# If it fails, then pretend we aren't using GCC.
@@ -3285,37 +3061,37 @@ if test yes = "$GCC"; then
with_gnu_ld=unknown
;;
esac
-elif test yes = "$with_gnu_ld"; then
+elif test "$with_gnu_ld" = yes; then
AC_MSG_CHECKING([for GNU ld])
else
AC_MSG_CHECKING([for non-GNU ld])
fi
AC_CACHE_VAL(lt_cv_path_LD,
[if test -z "$LD"; then
- lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
for ac_dir in $PATH; do
- IFS=$lt_save_ifs
+ IFS="$lt_save_ifs"
test -z "$ac_dir" && ac_dir=.
if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
- lt_cv_path_LD=$ac_dir/$ac_prog
+ lt_cv_path_LD="$ac_dir/$ac_prog"
# Check to see if the program is GNU ld. I'd rather use --version,
# but apparently some variants of GNU ld only accept -v.
# Break only if it was the GNU/non-GNU ld that we prefer.
case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
*GNU* | *'with BFD'*)
- test no != "$with_gnu_ld" && break
+ test "$with_gnu_ld" != no && break
;;
*)
- test yes != "$with_gnu_ld" && break
+ test "$with_gnu_ld" != yes && break
;;
esac
fi
done
- IFS=$lt_save_ifs
+ IFS="$lt_save_ifs"
else
- lt_cv_path_LD=$LD # Let the user override the test with a path.
+ lt_cv_path_LD="$LD" # Let the user override the test with a path.
fi])
-LD=$lt_cv_path_LD
+LD="$lt_cv_path_LD"
if test -n "$LD"; then
AC_MSG_RESULT($LD)
else
@@ -3369,13 +3145,13 @@ esac
reload_cmds='$LD$reload_flag -o $output$reload_objs'
case $host_os in
cygwin* | mingw* | pw32* | cegcc*)
- if test yes != "$GCC"; then
+ if test "$GCC" != yes; then
reload_cmds=false
fi
;;
darwin*)
- if test yes = "$GCC"; then
- reload_cmds='$LTCC $LTCFLAGS -nostdlib $wl-r -o $output$reload_objs'
+ if test "$GCC" = yes; then
+ reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs'
else
reload_cmds='$LD$reload_flag -o $output$reload_objs'
fi
@@ -3386,43 +3162,6 @@ _LT_TAGDECL([], [reload_cmds], [2])dnl
])# _LT_CMD_RELOAD
-# _LT_PATH_DD
-# -----------
-# find a working dd
-m4_defun([_LT_PATH_DD],
-[AC_CACHE_CHECK([for a working dd], [ac_cv_path_lt_DD],
-[printf 0123456789abcdef0123456789abcdef >conftest.i
-cat conftest.i conftest.i >conftest2.i
-: ${lt_DD:=$DD}
-AC_PATH_PROGS_FEATURE_CHECK([lt_DD], [dd],
-[if "$ac_path_lt_DD" bs=32 count=1 <conftest2.i >conftest.out 2>/dev/null; then
- cmp -s conftest.i conftest.out \
- && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=:
-fi])
-rm -f conftest.i conftest2.i conftest.out])
-])# _LT_PATH_DD
-
-
-# _LT_CMD_TRUNCATE
-# ----------------
-# find command to truncate a binary pipe
-m4_defun([_LT_CMD_TRUNCATE],
-[m4_require([_LT_PATH_DD])
-AC_CACHE_CHECK([how to truncate binary pipes], [lt_cv_truncate_bin],
-[printf 0123456789abcdef0123456789abcdef >conftest.i
-cat conftest.i conftest.i >conftest2.i
-lt_cv_truncate_bin=
-if "$ac_cv_path_lt_DD" bs=32 count=1 <conftest2.i >conftest.out 2>/dev/null; then
- cmp -s conftest.i conftest.out \
- && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1"
-fi
-rm -f conftest.i conftest2.i conftest.out
-test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q"])
-_LT_DECL([lt_truncate_bin], [lt_cv_truncate_bin], [1],
- [Command to truncate a binary pipe])
-])# _LT_CMD_TRUNCATE
-
-
# _LT_CHECK_MAGIC_METHOD
# ----------------------
# how to check for library dependencies
@@ -3438,13 +3177,13 @@ lt_cv_deplibs_check_method='unknown'
# Need to set the preceding variable on all platforms that support
# interlibrary dependencies.
# 'none' -- dependencies not supported.
-# 'unknown' -- same as none, but documents that we really don't know.
+# `unknown' -- same as none, but documents that we really don't know.
# 'pass_all' -- all dependencies passed with no checks.
# 'test_compile' -- check by making test program.
# 'file_magic [[regex]]' -- check by looking for files in library path
-# that responds to the $file_magic_cmd with a given extended regex.
-# If you have 'file' or equivalent on your system and you're not sure
-# whether 'pass_all' will *always* work, you probably want this one.
+# which responds to the $file_magic_cmd with a given extended regex.
+# If you have `file' or equivalent on your system and you're not sure
+# whether `pass_all' will *always* work, you probably want this one.
case $host_os in
aix[[4-9]]*)
@@ -3471,7 +3210,8 @@ mingw* | pw32*)
# Base MSYS/MinGW do not provide the 'file' command needed by
# func_win32_libid shell function, so use a weaker test based on 'objdump',
# unless we find 'file', for example because we are cross-compiling.
- if ( file / ) >/dev/null 2>&1; then
+ # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin.
+ if ( test "$lt_cv_nm_interface" = "BSD nm" && file / ) >/dev/null 2>&1; then
lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
lt_cv_file_magic_cmd='func_win32_libid'
else
@@ -3507,6 +3247,10 @@ freebsd* | dragonfly*)
fi
;;
+gnu*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
haiku*)
lt_cv_deplibs_check_method=pass_all
;;
@@ -3545,7 +3289,7 @@ irix5* | irix6* | nonstopux*)
;;
# This must be glibc/ELF.
-linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+linux* | k*bsd*-gnu | kopensolaris*-gnu)
lt_cv_deplibs_check_method=pass_all
;;
@@ -3567,8 +3311,8 @@ newos6*)
lt_cv_deplibs_check_method=pass_all
;;
-openbsd* | bitrig*)
- if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then
+openbsd*)
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$'
else
lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$'
@@ -3621,9 +3365,6 @@ sysv4 | sysv4.3*)
tpf*)
lt_cv_deplibs_check_method=pass_all
;;
-os2*)
- lt_cv_deplibs_check_method=pass_all
- ;;
esac
])
@@ -3664,38 +3405,33 @@ AC_DEFUN([LT_PATH_NM],
AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM,
[if test -n "$NM"; then
# Let the user override the test.
- lt_cv_path_NM=$NM
+ lt_cv_path_NM="$NM"
else
- lt_nm_to_check=${ac_tool_prefix}nm
+ lt_nm_to_check="${ac_tool_prefix}nm"
if test -n "$ac_tool_prefix" && test "$build" = "$host"; then
lt_nm_to_check="$lt_nm_to_check nm"
fi
for lt_tmp_nm in $lt_nm_to_check; do
- lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do
- IFS=$lt_save_ifs
+ IFS="$lt_save_ifs"
test -z "$ac_dir" && ac_dir=.
- tmp_nm=$ac_dir/$lt_tmp_nm
- if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then
+ tmp_nm="$ac_dir/$lt_tmp_nm"
+ if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then
# Check to see if the nm accepts a BSD-compat flag.
- # Adding the 'sed 1q' prevents false positives on HP-UX, which says:
+ # Adding the `sed 1q' prevents false positives on HP-UX, which says:
# nm: unknown option "B" ignored
# Tru64's nm complains that /dev/null is an invalid object file
- # MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty
- case $build_os in
- mingw*) lt_bad_file=conftest.nm/nofile ;;
- *) lt_bad_file=/dev/null ;;
- esac
- case `"$tmp_nm" -B $lt_bad_file 2>&1 | sed '1q'` in
- *$lt_bad_file* | *'Invalid file or object type'*)
+ case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in
+ */dev/null* | *'Invalid file or object type'*)
lt_cv_path_NM="$tmp_nm -B"
- break 2
+ break
;;
*)
case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
*/dev/null*)
lt_cv_path_NM="$tmp_nm -p"
- break 2
+ break
;;
*)
lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
@@ -3706,21 +3442,21 @@ else
esac
fi
done
- IFS=$lt_save_ifs
+ IFS="$lt_save_ifs"
done
: ${lt_cv_path_NM=no}
fi])
-if test no != "$lt_cv_path_NM"; then
- NM=$lt_cv_path_NM
+if test "$lt_cv_path_NM" != "no"; then
+ NM="$lt_cv_path_NM"
else
# Didn't find any BSD compatible name lister, look for dumpbin.
if test -n "$DUMPBIN"; then :
# Let the user override the test.
else
AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :)
- case `$DUMPBIN -symbols -headers /dev/null 2>&1 | sed '1q'` in
+ case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in
*COFF*)
- DUMPBIN="$DUMPBIN -symbols -headers"
+ DUMPBIN="$DUMPBIN -symbols"
;;
*)
DUMPBIN=:
@@ -3728,8 +3464,8 @@ else
esac
fi
AC_SUBST([DUMPBIN])
- if test : != "$DUMPBIN"; then
- NM=$DUMPBIN
+ if test "$DUMPBIN" != ":"; then
+ NM="$DUMPBIN"
fi
fi
test -z "$NM" && NM=nm
@@ -3775,8 +3511,8 @@ lt_cv_sharedlib_from_linklib_cmd,
case $host_os in
cygwin* | mingw* | pw32* | cegcc*)
- # two different shell functions defined in ltmain.sh;
- # decide which one to use based on capabilities of $DLLTOOL
+ # two different shell functions defined in ltmain.sh
+ # decide which to use based on capabilities of $DLLTOOL
case `$DLLTOOL --help 2>&1` in
*--identify-strict*)
lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib
@@ -3788,7 +3524,7 @@ cygwin* | mingw* | pw32* | cegcc*)
;;
*)
# fallback: assume linklib IS sharedlib
- lt_cv_sharedlib_from_linklib_cmd=$ECHO
+ lt_cv_sharedlib_from_linklib_cmd="$ECHO"
;;
esac
])
@@ -3815,28 +3551,13 @@ AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool
lt_cv_path_mainfest_tool=yes
fi
rm -f conftest*])
-if test yes != "$lt_cv_path_mainfest_tool"; then
+if test "x$lt_cv_path_mainfest_tool" != xyes; then
MANIFEST_TOOL=:
fi
_LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl
])# _LT_PATH_MANIFEST_TOOL
-# _LT_DLL_DEF_P([FILE])
-# ---------------------
-# True iff FILE is a Windows DLL '.def' file.
-# Keep in sync with func_dll_def_p in the libtool script
-AC_DEFUN([_LT_DLL_DEF_P],
-[dnl
- test DEF = "`$SED -n dnl
- -e '\''s/^[[ ]]*//'\'' dnl Strip leading whitespace
- -e '\''/^\(;.*\)*$/d'\'' dnl Delete empty lines and comments
- -e '\''s/^\(EXPORTS\|LIBRARY\)\([[ ]].*\)*$/DEF/p'\'' dnl
- -e q dnl Only consider the first "real" line
- $1`" dnl
-])# _LT_DLL_DEF_P
-
-
# LT_LIB_M
# --------
# check for math library
@@ -3848,11 +3569,11 @@ case $host in
# These system don't have libm, or don't need it
;;
*-ncr-sysv4.3*)
- AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM=-lmw)
+ AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw")
AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm")
;;
*)
- AC_CHECK_LIB(m, cos, LIBM=-lm)
+ AC_CHECK_LIB(m, cos, LIBM="-lm")
;;
esac
AC_SUBST([LIBM])
@@ -3871,7 +3592,7 @@ m4_defun([_LT_COMPILER_NO_RTTI],
_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=
-if test yes = "$GCC"; then
+if test "$GCC" = yes; then
case $cc_basename in
nvcc*)
_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;;
@@ -3923,7 +3644,7 @@ cygwin* | mingw* | pw32* | cegcc*)
symcode='[[ABCDGISTW]]'
;;
hpux*)
- if test ia64 = "$host_cpu"; then
+ if test "$host_cpu" = ia64; then
symcode='[[ABCDEGRST]]'
fi
;;
@@ -3956,44 +3677,14 @@ case `$NM -V 2>&1` in
symcode='[[ABCDGIRSTW]]' ;;
esac
-if test "$lt_cv_nm_interface" = "MS dumpbin"; then
- # Gets list of data symbols to import.
- lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'"
- # Adjust the below global symbol transforms to fixup imported variables.
- lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'"
- lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'"
- lt_c_name_lib_hook="\
- -e 's/^I .* \(lib.*\)$/ {\"\1\", (void *) 0},/p'\
- -e 's/^I .* \(.*\)$/ {\"lib\1\", (void *) 0},/p'"
-else
- # Disable hooks by default.
- lt_cv_sys_global_symbol_to_import=
- lt_cdecl_hook=
- lt_c_name_hook=
- lt_c_name_lib_hook=
-fi
-
# Transform an extracted symbol line into a proper C declaration.
# Some systems (esp. on ia64) link data and code symbols differently,
# so use this general approach.
-lt_cv_sys_global_symbol_to_cdecl="sed -n"\
-$lt_cdecl_hook\
-" -e 's/^T .* \(.*\)$/extern int \1();/p'"\
-" -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'"
+lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
# Transform an extracted symbol line into symbol name and symbol address
-lt_cv_sys_global_symbol_to_c_name_address="sed -n"\
-$lt_c_name_hook\
-" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\
-" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'"
-
-# Transform an extracted symbol line into symbol name with lib prefix and
-# symbol address.
-lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n"\
-$lt_c_name_lib_hook\
-" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\
-" -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\
-" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"lib\1\", (void *) \&\1},/p'"
+lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p'"
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \(lib[[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"lib\2\", (void *) \&\2},/p'"
# Handle CRLF in mingw tool chain
opt_cr=
@@ -4011,24 +3702,21 @@ for ac_symprfx in "" "_"; do
# Write the raw and C identifiers.
if test "$lt_cv_nm_interface" = "MS dumpbin"; then
- # Fake it for dumpbin and say T for any non-static function,
- # D for any global variable and I for any imported variable.
+ # Fake it for dumpbin and say T for any non-static function
+ # and D for any global variable.
# Also find C++ and __fastcall symbols from MSVC++,
# which start with @ or ?.
lt_cv_sys_global_symbol_pipe="$AWK ['"\
" {last_section=section; section=\$ 3};"\
" /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\
" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\
-" /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\
-" /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\
-" /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\
" \$ 0!~/External *\|/{next};"\
" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\
" {if(hide[section]) next};"\
-" {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\
-" {split(\$ 0,a,/\||\r/); split(a[2],s)};"\
-" s[1]~/^[@?]/{print f,s[1],s[1]; next};"\
-" s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\
+" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\
+" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\
+" s[1]~/^[@?]/{print s[1], s[1]; next};"\
+" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\
" ' prfx=^$ac_symprfx]"
else
lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
@@ -4068,11 +3756,11 @@ _LT_EOF
if $GREP ' nm_test_func$' "$nlist" >/dev/null; then
cat <<_LT_EOF > conftest.$ac_ext
/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */
-#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE
-/* DATA imports from DLLs on WIN32 can't be const, because runtime
+#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE)
+/* DATA imports from DLLs on WIN32 con't be const, because runtime
relocations are performed -- see ld's documentation on pseudo-relocs. */
# define LT@&t@_DLSYM_CONST
-#elif defined __osf__
+#elif defined(__osf__)
/* This system does not cope well with relocations in const data. */
# define LT@&t@_DLSYM_CONST
#else
@@ -4098,7 +3786,7 @@ lt__PROGRAM__LTX_preloaded_symbols[[]] =
{
{ "@PROGRAM@", (void *) 0 },
_LT_EOF
- $SED "s/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext
+ $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext
cat <<\_LT_EOF >> conftest.$ac_ext
{0, (void *) 0}
};
@@ -4118,9 +3806,9 @@ _LT_EOF
mv conftest.$ac_objext conftstm.$ac_objext
lt_globsym_save_LIBS=$LIBS
lt_globsym_save_CFLAGS=$CFLAGS
- LIBS=conftstm.$ac_objext
+ LIBS="conftstm.$ac_objext"
CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)"
- if AC_TRY_EVAL(ac_link) && test -s conftest$ac_exeext; then
+ if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then
pipe_works=yes
fi
LIBS=$lt_globsym_save_LIBS
@@ -4141,7 +3829,7 @@ _LT_EOF
rm -rf conftest* conftst*
# Do not use the global_symbol_pipe unless it works.
- if test yes = "$pipe_works"; then
+ if test "$pipe_works" = yes; then
break
else
lt_cv_sys_global_symbol_pipe=
@@ -4168,16 +3856,12 @@ _LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1],
[Take the output of nm and produce a listing of raw symbols and C names])
_LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1],
[Transform the output of nm in a proper C declaration])
-_LT_DECL([global_symbol_to_import], [lt_cv_sys_global_symbol_to_import], [1],
- [Transform the output of nm into a list of symbols to manually relocate])
_LT_DECL([global_symbol_to_c_name_address],
[lt_cv_sys_global_symbol_to_c_name_address], [1],
[Transform the output of nm in a C name address pair])
_LT_DECL([global_symbol_to_c_name_address_lib_prefix],
[lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1],
[Transform the output of nm in a C name address pair when lib prefix is needed])
-_LT_DECL([nm_interface], [lt_cv_nm_interface], [1],
- [The name lister interface])
_LT_DECL([], [nm_file_list_spec], [1],
[Specify filename containing input files for $NM])
]) # _LT_CMD_GLOBAL_SYMBOLS
@@ -4193,18 +3877,17 @@ _LT_TAGVAR(lt_prog_compiler_static, $1)=
m4_if([$1], [CXX], [
# C++ specific cases for pic, static, wl, etc.
- if test yes = "$GXX"; then
+ if test "$GXX" = yes; then
_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
_LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
case $host_os in
aix*)
# All AIX code is PIC.
- if test ia64 = "$host_cpu"; then
+ if test "$host_cpu" = ia64; then
# AIX 5 now supports IA64 processor
_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
fi
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
;;
amigaos*)
@@ -4215,8 +3898,8 @@ m4_if([$1], [CXX], [
;;
m68k)
# FIXME: we need at least 68020 code to build shared libraries, but
- # adding the '-m68020' flag to GCC prevents building anything better,
- # like '-m68040'.
+ # adding the `-m68020' flag to GCC prevents building anything better,
+ # like `-m68040'.
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'
;;
esac
@@ -4232,11 +3915,6 @@ m4_if([$1], [CXX], [
# (--disable-auto-import) libraries
m4_if([$1], [GCJ], [],
[_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
- case $host_os in
- os2*)
- _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static'
- ;;
- esac
;;
darwin* | rhapsody*)
# PIC is the default on this platform
@@ -4286,7 +3964,7 @@ m4_if([$1], [CXX], [
case $host_os in
aix[[4-9]]*)
# All AIX code is PIC.
- if test ia64 = "$host_cpu"; then
+ if test "$host_cpu" = ia64; then
# AIX 5 now supports IA64 processor
_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
else
@@ -4327,14 +4005,14 @@ m4_if([$1], [CXX], [
case $cc_basename in
CC*)
_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
- _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive'
- if test ia64 != "$host_cpu"; then
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
+ if test "$host_cpu" != ia64; then
_LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
fi
;;
aCC*)
_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
- _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
case $host_cpu in
hppa*64*|ia64*)
# +Z the default
@@ -4363,7 +4041,7 @@ m4_if([$1], [CXX], [
;;
esac
;;
- linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+ linux* | k*bsd*-gnu | kopensolaris*-gnu)
case $cc_basename in
KCC*)
# KAI C++ Compiler
@@ -4371,7 +4049,7 @@ m4_if([$1], [CXX], [
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
;;
ecpc* )
- # old Intel C++ for x86_64, which still supported -KPIC.
+ # old Intel C++ for x86_64 which still supported -KPIC.
_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
_LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
@@ -4516,18 +4194,17 @@ m4_if([$1], [CXX], [
fi
],
[
- if test yes = "$GCC"; then
+ if test "$GCC" = yes; then
_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
_LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
case $host_os in
aix*)
# All AIX code is PIC.
- if test ia64 = "$host_cpu"; then
+ if test "$host_cpu" = ia64; then
# AIX 5 now supports IA64 processor
_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
fi
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
;;
amigaos*)
@@ -4538,8 +4215,8 @@ m4_if([$1], [CXX], [
;;
m68k)
# FIXME: we need at least 68020 code to build shared libraries, but
- # adding the '-m68020' flag to GCC prevents building anything better,
- # like '-m68040'.
+ # adding the `-m68020' flag to GCC prevents building anything better,
+ # like `-m68040'.
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'
;;
esac
@@ -4556,11 +4233,6 @@ m4_if([$1], [CXX], [
# (--disable-auto-import) libraries
m4_if([$1], [GCJ], [],
[_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
- case $host_os in
- os2*)
- _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static'
- ;;
- esac
;;
darwin* | rhapsody*)
@@ -4631,7 +4303,7 @@ m4_if([$1], [CXX], [
case $host_os in
aix*)
_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
- if test ia64 = "$host_cpu"; then
+ if test "$host_cpu" = ia64; then
# AIX 5 now supports IA64 processor
_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
else
@@ -4639,30 +4311,11 @@ m4_if([$1], [CXX], [
fi
;;
- darwin* | rhapsody*)
- # PIC is the default on this platform
- # Common symbols not allowed in MH_DYLIB files
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'
- case $cc_basename in
- nagfor*)
- # NAG Fortran compiler
- _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,'
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
- _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
- ;;
- esac
- ;;
-
mingw* | cygwin* | pw32* | os2* | cegcc*)
# This hack is so that the source file can tell whether it is being
# built for inclusion in a dll (and should export symbols for example).
m4_if([$1], [GCJ], [],
[_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
- case $host_os in
- os2*)
- _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static'
- ;;
- esac
;;
hpux9* | hpux10* | hpux11*)
@@ -4678,7 +4331,7 @@ m4_if([$1], [CXX], [
;;
esac
# Is there a better lt_prog_compiler_static that works with the bundled CC?
- _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
;;
irix5* | irix6* | nonstopux*)
@@ -4687,9 +4340,9 @@ m4_if([$1], [CXX], [
_LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
;;
- linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+ linux* | k*bsd*-gnu | kopensolaris*-gnu)
case $cc_basename in
- # old Intel for x86_64, which still supported -KPIC.
+ # old Intel for x86_64 which still supported -KPIC.
ecc*)
_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
@@ -4714,12 +4367,6 @@ m4_if([$1], [CXX], [
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
;;
- tcc*)
- # Fabrice Bellard et al's Tiny C Compiler
- _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
- _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
- ;;
pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)
# Portland Group compilers (*not* the Pentium gcc compiler,
# which looks to be a dead project)
@@ -4817,7 +4464,7 @@ m4_if([$1], [CXX], [
;;
sysv4*MP*)
- if test -d /usr/nec; then
+ if test -d /usr/nec ;then
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic'
_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
fi
@@ -4846,7 +4493,7 @@ m4_if([$1], [CXX], [
fi
])
case $host_os in
- # For platforms that do not support PIC, -DPIC is meaningless:
+ # For platforms which do not support PIC, -DPIC is meaningless:
*djgpp*)
_LT_TAGVAR(lt_prog_compiler_pic, $1)=
;;
@@ -4912,21 +4559,17 @@ m4_if([$1], [CXX], [
case $host_os in
aix[[4-9]]*)
# If we're using GNU nm, then we don't want the "-C" option.
- # -C means demangle to GNU nm, but means don't demangle to AIX nm.
- # Without the "-l" option, or with the "-B" option, AIX nm treats
- # weak defined symbols like other global defined symbols, whereas
- # GNU nm marks them as "W".
- # While the 'weak' keyword is ignored in the Export File, we need
- # it in the Import File for the 'aix-soname' feature, so we have
- # to replace the "-B" option with "-P" for AIX nm.
+ # -C means demangle to AIX nm, but means don't demangle with GNU nm
+ # Also, AIX nm treats weak defined symbols like other global defined
+ # symbols, whereas GNU nm marks them as "W".
if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
- _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols'
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
else
- _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
fi
;;
pw32*)
- _LT_TAGVAR(export_symbols_cmds, $1)=$ltdll_cmds
+ _LT_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds"
;;
cygwin* | mingw* | cegcc*)
case $cc_basename in
@@ -4972,9 +4615,9 @@ m4_if([$1], [CXX], [
# included in the symbol list
_LT_TAGVAR(include_expsyms, $1)=
# exclude_expsyms can be an extended regexp of symbols to exclude
- # it will be wrapped by ' (' and ')$', so one must not match beginning or
- # end of line. Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc',
- # as well as any symbol that contains 'd'.
+ # it will be wrapped by ` (' and `)$', so one must not match beginning or
+ # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
+ # as well as any symbol that contains `d'.
_LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*']
# Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
# platforms (ab)use it in PIC code, but their linkers get confused if
@@ -4990,7 +4633,7 @@ dnl Note also adjust exclude_expsyms for C++ above.
# FIXME: the MSVC++ port hasn't been tested in a loooong time
# When not using gcc, we currently assume that we are using
# Microsoft Visual C++.
- if test yes != "$GCC"; then
+ if test "$GCC" != yes; then
with_gnu_ld=no
fi
;;
@@ -4998,7 +4641,7 @@ dnl Note also adjust exclude_expsyms for C++ above.
# we just hope/assume this is gcc and not c89 (= MSVC++)
with_gnu_ld=yes
;;
- openbsd* | bitrig*)
+ openbsd*)
with_gnu_ld=no
;;
esac
@@ -5008,7 +4651,7 @@ dnl Note also adjust exclude_expsyms for C++ above.
# On some targets, GNU ld is compatible enough with the native linker
# that we're better off using the native interface for both.
lt_use_gnu_ld_interface=no
- if test yes = "$with_gnu_ld"; then
+ if test "$with_gnu_ld" = yes; then
case $host_os in
aix*)
# The AIX port of GNU ld has always aspired to compatibility
@@ -5030,24 +4673,24 @@ dnl Note also adjust exclude_expsyms for C++ above.
esac
fi
- if test yes = "$lt_use_gnu_ld_interface"; then
+ if test "$lt_use_gnu_ld_interface" = yes; then
# If archive_cmds runs LD, not CC, wlarc should be empty
- wlarc='$wl'
+ wlarc='${wl}'
# Set some defaults for GNU ld with shared library support. These
# are reset later if shared libraries are not supported. Putting them
# here allows them to be overridden if necessary.
runpath_var=LD_RUN_PATH
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
- _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
# ancient GNU ld didn't support --whole-archive et. al.
if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then
- _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive'
+ _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
else
_LT_TAGVAR(whole_archive_flag_spec, $1)=
fi
supports_anon_versioning=no
- case `$LD -v | $SED -e 's/([^)]\+)\s\+//' 2>&1` in
+ case `$LD -v 2>&1` in
*GNU\ gold*) supports_anon_versioning=yes ;;
*\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11
*\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
@@ -5060,7 +4703,7 @@ dnl Note also adjust exclude_expsyms for C++ above.
case $host_os in
aix[[3-9]]*)
# On AIX/PPC, the GNU linker is very broken
- if test ia64 != "$host_cpu"; then
+ if test "$host_cpu" != ia64; then
_LT_TAGVAR(ld_shlibs, $1)=no
cat <<_LT_EOF 1>&2
@@ -5079,7 +4722,7 @@ _LT_EOF
case $host_cpu in
powerpc)
# see comment about AmigaOS4 .so support
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
_LT_TAGVAR(archive_expsym_cmds, $1)=''
;;
m68k)
@@ -5095,7 +4738,7 @@ _LT_EOF
_LT_TAGVAR(allow_undefined_flag, $1)=unsupported
# Joseph Beckenbach <jrb3@best.com> says some releases of gcc
# support --undefined. This deserves some investigation. FIXME
- _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
else
_LT_TAGVAR(ld_shlibs, $1)=no
fi
@@ -5105,7 +4748,7 @@ _LT_EOF
# _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
# as there is no search path for DLLs.
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
- _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols'
_LT_TAGVAR(allow_undefined_flag, $1)=unsupported
_LT_TAGVAR(always_export_symbols, $1)=no
_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
@@ -5113,89 +4756,61 @@ _LT_EOF
_LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname']
if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
- # If the export-symbols file already is a .def file, use it as
- # is; otherwise, prepend EXPORTS...
- _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then
- cp $export_symbols $output_objdir/$soname.def;
- else
- echo EXPORTS > $output_objdir/$soname.def;
- cat $export_symbols >> $output_objdir/$soname.def;
- fi~
- $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ # If the export-symbols file already is a .def file (1st line
+ # is EXPORTS), use it as is; otherwise, prepend...
+ _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+ cp $export_symbols $output_objdir/$soname.def;
+ else
+ echo EXPORTS > $output_objdir/$soname.def;
+ cat $export_symbols >> $output_objdir/$soname.def;
+ fi~
+ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
else
_LT_TAGVAR(ld_shlibs, $1)=no
fi
;;
haiku*)
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
_LT_TAGVAR(link_all_deplibs, $1)=yes
;;
- os2*)
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
- _LT_TAGVAR(hardcode_minus_L, $1)=yes
- _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
- shrext_cmds=.dll
- _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
- $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
- $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
- $ECHO EXPORTS >> $output_objdir/$libname.def~
- emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~
- $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
- emximp -o $lib $output_objdir/$libname.def'
- _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
- $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
- $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
- $ECHO EXPORTS >> $output_objdir/$libname.def~
- prefix_cmds="$SED"~
- if test EXPORTS = "`$SED 1q $export_symbols`"; then
- prefix_cmds="$prefix_cmds -e 1d";
- fi~
- prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~
- cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~
- $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
- emximp -o $lib $output_objdir/$libname.def'
- _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
- _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
- ;;
-
interix[[3-9]]*)
_LT_TAGVAR(hardcode_direct, $1)=no
_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
- _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
# Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
# Instead, shared libraries are loaded at an image base (0x10000000 by
# default) and relocated if they conflict, which is a slow very memory
# consuming and fragmenting process. To avoid this, we pick a random,
# 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
# time. Moving up from 0x10000000 also allows more sbrk(2) space.
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
- _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
;;
gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu)
tmp_diet=no
- if test linux-dietlibc = "$host_os"; then
+ if test "$host_os" = linux-dietlibc; then
case $cc_basename in
diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn)
esac
fi
if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \
- && test no = "$tmp_diet"
+ && test "$tmp_diet" = no
then
tmp_addflag=' $pic_flag'
tmp_sharedflag='-shared'
case $cc_basename,$host_cpu in
pgcc*) # Portland Group C compiler
- _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
tmp_addflag=' $pic_flag'
;;
pgf77* | pgf90* | pgf95* | pgfortran*)
# Portland Group f77 and f90 compilers
- _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
tmp_addflag=' $pic_flag -Mnomain' ;;
ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64
tmp_addflag=' -i_dynamic' ;;
@@ -5206,47 +4821,42 @@ _LT_EOF
lf95*) # Lahey Fortran 8.1
_LT_TAGVAR(whole_archive_flag_spec, $1)=
tmp_sharedflag='--shared' ;;
- nagfor*) # NAGFOR 5.3
- tmp_sharedflag='-Wl,-shared' ;;
xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below)
tmp_sharedflag='-qmkshrobj'
tmp_addflag= ;;
nvcc*) # Cuda Compiler Driver 2.2
- _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
_LT_TAGVAR(compiler_needs_object, $1)=yes
;;
esac
case `$CC -V 2>&1 | sed 5q` in
*Sun\ C*) # Sun C 5.9
- _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
_LT_TAGVAR(compiler_needs_object, $1)=yes
tmp_sharedflag='-G' ;;
*Sun\ F*) # Sun Fortran 8.3
tmp_sharedflag='-G' ;;
esac
- _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- if test yes = "$supports_anon_versioning"; then
+ if test "x$supports_anon_versioning" = xyes; then
_LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
- cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
- echo "local: *; };" >> $output_objdir/$libname.ver~
- $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib'
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
fi
case $cc_basename in
- tcc*)
- _LT_TAGVAR(export_dynamic_flag_spec, $1)='-rdynamic'
- ;;
xlf* | bgf* | bgxlf* | mpixlf*)
# IBM XL Fortran 10.1 on PPC cannot create shared libs itself
_LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive'
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
_LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib'
- if test yes = "$supports_anon_versioning"; then
+ if test "x$supports_anon_versioning" = xyes; then
_LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
- cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
- echo "local: *; };" >> $output_objdir/$libname.ver~
- $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
fi
;;
esac
@@ -5260,8 +4870,8 @@ _LT_EOF
_LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
wlarc=
else
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
fi
;;
@@ -5279,8 +4889,8 @@ _LT_EOF
_LT_EOF
elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
else
_LT_TAGVAR(ld_shlibs, $1)=no
fi
@@ -5292,7 +4902,7 @@ _LT_EOF
_LT_TAGVAR(ld_shlibs, $1)=no
cat <<_LT_EOF 1>&2
-*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot
+*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not
*** reliably create shared libraries on SCO systems. Therefore, libtool
*** is disabling shared libraries support. We urge you to upgrade GNU
*** binutils to release 2.16.91.0.3 or newer. Another option is to modify
@@ -5307,9 +4917,9 @@ _LT_EOF
# DT_RUNPATH tag from executables and libraries. But doing so
# requires that you compile everything twice, which is a pain.
if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
else
_LT_TAGVAR(ld_shlibs, $1)=no
fi
@@ -5326,15 +4936,15 @@ _LT_EOF
*)
if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
else
_LT_TAGVAR(ld_shlibs, $1)=no
fi
;;
esac
- if test no = "$_LT_TAGVAR(ld_shlibs, $1)"; then
+ if test "$_LT_TAGVAR(ld_shlibs, $1)" = no; then
runpath_var=
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
_LT_TAGVAR(export_dynamic_flag_spec, $1)=
@@ -5350,7 +4960,7 @@ _LT_EOF
# Note: this linker hardcodes the directories in LIBPATH if there
# are no directories specified by -L.
_LT_TAGVAR(hardcode_minus_L, $1)=yes
- if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then
+ if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then
# Neither direct hardcoding nor static linking is supported with a
# broken collect2.
_LT_TAGVAR(hardcode_direct, $1)=unsupported
@@ -5358,57 +4968,34 @@ _LT_EOF
;;
aix[[4-9]]*)
- if test ia64 = "$host_cpu"; then
+ if test "$host_cpu" = ia64; then
# On IA64, the linker does run time linking by default, so we don't
# have to do anything special.
aix_use_runtimelinking=no
exp_sym_flag='-Bexport'
- no_entry_flag=
+ no_entry_flag=""
else
# If we're using GNU nm, then we don't want the "-C" option.
- # -C means demangle to GNU nm, but means don't demangle to AIX nm.
- # Without the "-l" option, or with the "-B" option, AIX nm treats
- # weak defined symbols like other global defined symbols, whereas
- # GNU nm marks them as "W".
- # While the 'weak' keyword is ignored in the Export File, we need
- # it in the Import File for the 'aix-soname' feature, so we have
- # to replace the "-B" option with "-P" for AIX nm.
+ # -C means demangle to AIX nm, but means don't demangle with GNU nm
+ # Also, AIX nm treats weak defined symbols like other global
+ # defined symbols, whereas GNU nm marks them as "W".
if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
- _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols'
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
else
- _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
fi
aix_use_runtimelinking=no
# Test if we are trying to use run time linking or normal
# AIX style linking. If -brtl is somewhere in LDFLAGS, we
- # have runtime linking enabled, and use it for executables.
- # For shared libraries, we enable/disable runtime linking
- # depending on the kind of the shared library created -
- # when "with_aix_soname,aix_use_runtimelinking" is:
- # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables
- # "aix,yes" lib.so shared, rtl:yes, for executables
- # lib.a static archive
- # "both,no" lib.so.V(shr.o) shared, rtl:yes
- # lib.a(lib.so.V) shared, rtl:no, for executables
- # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables
- # lib.a(lib.so.V) shared, rtl:no
- # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables
- # lib.a static archive
+ # need to do runtime linking.
case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*)
for ld_flag in $LDFLAGS; do
- if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then
+ if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
aix_use_runtimelinking=yes
break
fi
done
- if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then
- # With aix-soname=svr4, we create the lib.so.V shared archives only,
- # so we don't have lib.a shared libs to link our executables.
- # We have to force runtime linking in this case.
- aix_use_runtimelinking=yes
- LDFLAGS="$LDFLAGS -Wl,-brtl"
- fi
;;
esac
@@ -5427,21 +5014,13 @@ _LT_EOF
_LT_TAGVAR(hardcode_direct_absolute, $1)=yes
_LT_TAGVAR(hardcode_libdir_separator, $1)=':'
_LT_TAGVAR(link_all_deplibs, $1)=yes
- _LT_TAGVAR(file_list_spec, $1)='$wl-f,'
- case $with_aix_soname,$aix_use_runtimelinking in
- aix,*) ;; # traditional, no import file
- svr4,* | *,yes) # use import file
- # The Import File defines what to hardcode.
- _LT_TAGVAR(hardcode_direct, $1)=no
- _LT_TAGVAR(hardcode_direct_absolute, $1)=no
- ;;
- esac
+ _LT_TAGVAR(file_list_spec, $1)='${wl}-f,'
- if test yes = "$GCC"; then
+ if test "$GCC" = yes; then
case $host_os in aix4.[[012]]|aix4.[[012]].*)
# We only want to do this on AIX 4.2 and lower, the check
# below for broken collect2 doesn't work under 4.3+
- collect2name=`$CC -print-prog-name=collect2`
+ collect2name=`${CC} -print-prog-name=collect2`
if test -f "$collect2name" &&
strings "$collect2name" | $GREP resolve_lib_name >/dev/null
then
@@ -5460,80 +5039,61 @@ _LT_EOF
;;
esac
shared_flag='-shared'
- if test yes = "$aix_use_runtimelinking"; then
- shared_flag="$shared_flag "'$wl-G'
+ if test "$aix_use_runtimelinking" = yes; then
+ shared_flag="$shared_flag "'${wl}-G'
fi
- # Need to ensure runtime linking is disabled for the traditional
- # shared library, or the linker may eventually find shared libraries
- # /with/ Import File - we do not want to mix them.
- shared_flag_aix='-shared'
- shared_flag_svr4='-shared $wl-G'
else
# not using gcc
- if test ia64 = "$host_cpu"; then
+ if test "$host_cpu" = ia64; then
# VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
# chokes on -Wl,-G. The following line is correct:
shared_flag='-G'
else
- if test yes = "$aix_use_runtimelinking"; then
- shared_flag='$wl-G'
+ if test "$aix_use_runtimelinking" = yes; then
+ shared_flag='${wl}-G'
else
- shared_flag='$wl-bM:SRE'
+ shared_flag='${wl}-bM:SRE'
fi
- shared_flag_aix='$wl-bM:SRE'
- shared_flag_svr4='$wl-G'
fi
fi
- _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall'
# It seems that -bexpall does not export symbols beginning with
# underscore (_), so it is better to generate a list of symbols to export.
_LT_TAGVAR(always_export_symbols, $1)=yes
- if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then
+ if test "$aix_use_runtimelinking" = yes; then
# Warning - without using the other runtime loading flags (-brtl),
# -berok will link without error, but may produce a broken library.
_LT_TAGVAR(allow_undefined_flag, $1)='-berok'
# Determine the default libpath from the value encoded in an
# empty executable.
_LT_SYS_MODULE_PATH_AIX([$1])
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath"
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
else
- if test ia64 = "$host_cpu"; then
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib'
+ if test "$host_cpu" = ia64; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib'
_LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs"
- _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols"
+ _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
else
# Determine the default libpath from the value encoded in an
# empty executable.
_LT_SYS_MODULE_PATH_AIX([$1])
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath"
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
# Warning - without using the other run time loading flags,
# -berok will link without error, but may produce a broken library.
- _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok'
- _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok'
- if test yes = "$with_gnu_ld"; then
+ _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok'
+ _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok'
+ if test "$with_gnu_ld" = yes; then
# We only use this code for GNU lds that support --whole-archive.
- _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive'
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
else
# Exported symbols can be pulled into shared objects from archives
_LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
fi
_LT_TAGVAR(archive_cmds_need_lc, $1)=yes
- _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d'
- # -brtl affects multiple linker settings, -berok does not and is overridden later
- compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`'
- if test svr4 != "$with_aix_soname"; then
- # This is similar to how AIX traditionally builds its shared libraries.
- _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname'
- fi
- if test aix != "$with_aix_soname"; then
- _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp'
- else
- # used by -dlpreopen to get the symbols
- _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV $output_objdir/$realname.d/$soname $output_objdir'
- fi
- _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d'
+ # This is similar to how AIX traditionally builds its shared libraries.
+ _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
fi
fi
;;
@@ -5542,7 +5102,7 @@ _LT_EOF
case $host_cpu in
powerpc)
# see comment about AmigaOS4 .so support
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
_LT_TAGVAR(archive_expsym_cmds, $1)=''
;;
m68k)
@@ -5572,17 +5132,16 @@ _LT_EOF
# Tell ltmain to make .lib files, not .a files.
libext=lib
# Tell ltmain to make .dll files, not .so files.
- shrext_cmds=.dll
+ shrext_cmds=".dll"
# FIXME: Setting linknames here is a bad hack.
- _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames='
- _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then
- cp "$export_symbols" "$output_objdir/$soname.def";
- echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp";
- else
- $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp;
- fi~
- $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
- linknames='
+ _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames='
+ _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+ sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp;
+ else
+ sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp;
+ fi~
+ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+ linknames='
# The linker will not automatically build a static lib if we build a DLL.
# _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
@@ -5591,18 +5150,18 @@ _LT_EOF
# Don't use ranlib
_LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib'
_LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~
- lt_tool_outputfile="@TOOL_OUTPUT@"~
- case $lt_outputfile in
- *.exe|*.EXE) ;;
- *)
- lt_outputfile=$lt_outputfile.exe
- lt_tool_outputfile=$lt_tool_outputfile.exe
- ;;
- esac~
- if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then
- $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
- $RM "$lt_outputfile.manifest";
- fi'
+ lt_tool_outputfile="@TOOL_OUTPUT@"~
+ case $lt_outputfile in
+ *.exe|*.EXE) ;;
+ *)
+ lt_outputfile="$lt_outputfile.exe"
+ lt_tool_outputfile="$lt_tool_outputfile.exe"
+ ;;
+ esac~
+ if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then
+ $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+ $RM "$lt_outputfile.manifest";
+ fi'
;;
*)
# Assume MSVC wrapper
@@ -5611,7 +5170,7 @@ _LT_EOF
# Tell ltmain to make .lib files, not .a files.
libext=lib
# Tell ltmain to make .dll files, not .so files.
- shrext_cmds=.dll
+ shrext_cmds=".dll"
# FIXME: Setting linknames here is a bad hack.
_LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames='
# The linker will automatically build a .lib file if we build a DLL.
@@ -5661,33 +5220,33 @@ _LT_EOF
;;
hpux9*)
- if test yes = "$GCC"; then
- _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
+ if test "$GCC" = yes; then
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
else
- _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
fi
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
_LT_TAGVAR(hardcode_libdir_separator, $1)=:
_LT_TAGVAR(hardcode_direct, $1)=yes
# hardcode_minus_L: Not really in the search PATH,
# but as the default location of the library.
_LT_TAGVAR(hardcode_minus_L, $1)=yes
- _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
;;
hpux10*)
- if test yes,no = "$GCC,$with_gnu_ld"; then
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ if test "$GCC" = yes && test "$with_gnu_ld" = no; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
else
_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
fi
- if test no = "$with_gnu_ld"; then
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir'
+ if test "$with_gnu_ld" = no; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
_LT_TAGVAR(hardcode_libdir_separator, $1)=:
_LT_TAGVAR(hardcode_direct, $1)=yes
_LT_TAGVAR(hardcode_direct_absolute, $1)=yes
- _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
# hardcode_minus_L: Not really in the search PATH,
# but as the default location of the library.
_LT_TAGVAR(hardcode_minus_L, $1)=yes
@@ -5695,25 +5254,25 @@ _LT_EOF
;;
hpux11*)
- if test yes,no = "$GCC,$with_gnu_ld"; then
+ if test "$GCC" = yes && test "$with_gnu_ld" = no; then
case $host_cpu in
hppa*64*)
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
;;
ia64*)
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
;;
*)
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
;;
esac
else
case $host_cpu in
hppa*64*)
- _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
;;
ia64*)
- _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
;;
*)
m4_if($1, [], [
@@ -5721,14 +5280,14 @@ _LT_EOF
# (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does)
_LT_LINKER_OPTION([if $CC understands -b],
_LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b],
- [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'],
+ [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'],
[_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])],
- [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'])
+ [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'])
;;
esac
fi
- if test no = "$with_gnu_ld"; then
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir'
+ if test "$with_gnu_ld" = no; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
_LT_TAGVAR(hardcode_libdir_separator, $1)=:
case $host_cpu in
@@ -5739,7 +5298,7 @@ _LT_EOF
*)
_LT_TAGVAR(hardcode_direct, $1)=yes
_LT_TAGVAR(hardcode_direct_absolute, $1)=yes
- _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
# hardcode_minus_L: Not really in the search PATH,
# but as the default location of the library.
@@ -5750,16 +5309,16 @@ _LT_EOF
;;
irix5* | irix6* | nonstopux*)
- if test yes = "$GCC"; then
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+ if test "$GCC" = yes; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
# Try to use the -exported_symbol ld option, if it does not
# work, assume that -exports_file does not work either and
# implicitly export all symbols.
# This should be the same for all languages, so no per-tag cache variable.
AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol],
[lt_cv_irix_exported_symbol],
- [save_LDFLAGS=$LDFLAGS
- LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null"
+ [save_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null"
AC_LINK_IFELSE(
[AC_LANG_SOURCE(
[AC_LANG_CASE([C], [[int foo (void) { return 0; }]],
@@ -5772,31 +5331,21 @@ _LT_EOF
end]])])],
[lt_cv_irix_exported_symbol=yes],
[lt_cv_irix_exported_symbol=no])
- LDFLAGS=$save_LDFLAGS])
- if test yes = "$lt_cv_irix_exported_symbol"; then
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib'
+ LDFLAGS="$save_LDFLAGS"])
+ if test "$lt_cv_irix_exported_symbol" = yes; then
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib'
fi
else
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib'
fi
_LT_TAGVAR(archive_cmds_need_lc, $1)='no'
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
_LT_TAGVAR(hardcode_libdir_separator, $1)=:
_LT_TAGVAR(inherit_rpath, $1)=yes
_LT_TAGVAR(link_all_deplibs, $1)=yes
;;
- linux*)
- case $cc_basename in
- tcc*)
- # Fabrice Bellard et al's Tiny C Compiler
- _LT_TAGVAR(ld_shlibs, $1)=yes
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
- ;;
- esac
- ;;
-
netbsd*)
if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
_LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out
@@ -5811,7 +5360,7 @@ _LT_EOF
newsos6)
_LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
_LT_TAGVAR(hardcode_direct, $1)=yes
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
_LT_TAGVAR(hardcode_libdir_separator, $1)=:
_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
;;
@@ -5819,19 +5368,27 @@ _LT_EOF
*nto* | *qnx*)
;;
- openbsd* | bitrig*)
+ openbsd*)
if test -f /usr/libexec/ld.so; then
_LT_TAGVAR(hardcode_direct, $1)=yes
_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
_LT_TAGVAR(hardcode_direct_absolute, $1)=yes
- if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols'
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
- _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
else
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
+ case $host_os in
+ openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ ;;
+ esac
fi
else
_LT_TAGVAR(ld_shlibs, $1)=no
@@ -5842,53 +5399,33 @@ _LT_EOF
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
_LT_TAGVAR(hardcode_minus_L, $1)=yes
_LT_TAGVAR(allow_undefined_flag, $1)=unsupported
- shrext_cmds=.dll
- _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
- $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
- $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
- $ECHO EXPORTS >> $output_objdir/$libname.def~
- emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~
- $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
- emximp -o $lib $output_objdir/$libname.def'
- _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
- $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
- $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
- $ECHO EXPORTS >> $output_objdir/$libname.def~
- prefix_cmds="$SED"~
- if test EXPORTS = "`$SED 1q $export_symbols`"; then
- prefix_cmds="$prefix_cmds -e 1d";
- fi~
- prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~
- cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~
- $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
- emximp -o $lib $output_objdir/$libname.def'
- _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
- _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+ _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
+ _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
;;
osf3*)
- if test yes = "$GCC"; then
- _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*'
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+ if test "$GCC" = yes; then
+ _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
else
_LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
fi
_LT_TAGVAR(archive_cmds_need_lc, $1)='no'
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
_LT_TAGVAR(hardcode_libdir_separator, $1)=:
;;
osf4* | osf5*) # as osf3* with the addition of -msym flag
- if test yes = "$GCC"; then
- _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*'
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+ if test "$GCC" = yes; then
+ _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
else
_LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
_LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~
- $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp'
+ $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp'
# Both c and cxx compiler support -rpath directly
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
@@ -5899,24 +5436,24 @@ _LT_EOF
solaris*)
_LT_TAGVAR(no_undefined_flag, $1)=' -z defs'
- if test yes = "$GCC"; then
- wlarc='$wl'
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags'
+ if test "$GCC" = yes; then
+ wlarc='${wl}'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
_LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
- $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+ $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
else
case `$CC -V 2>&1` in
*"Compilers 5.0"*)
wlarc=''
- _LT_TAGVAR(archive_cmds, $1)='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
_LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
- $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp'
+ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp'
;;
*)
- wlarc='$wl'
- _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags'
+ wlarc='${wl}'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags'
_LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
- $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+ $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
;;
esac
fi
@@ -5926,11 +5463,11 @@ _LT_EOF
solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
*)
# The compiler driver will combine and reorder linker options,
- # but understands '-z linker_flag'. GCC discards it without '$wl',
+ # but understands `-z linker_flag'. GCC discards it without `$wl',
# but is careful enough not to reorder.
# Supported since Solaris 2.6 (maybe 2.5.1?)
- if test yes = "$GCC"; then
- _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract'
+ if test "$GCC" = yes; then
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
else
_LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract'
fi
@@ -5940,10 +5477,10 @@ _LT_EOF
;;
sunos4*)
- if test sequent = "$host_vendor"; then
+ if test "x$host_vendor" = xsequent; then
# Use $CC to link under sequent, because it throws in some extra .o
# files that make .init and .fini sections work.
- _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'
else
_LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
fi
@@ -5992,43 +5529,43 @@ _LT_EOF
;;
sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*)
- _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text'
+ _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
_LT_TAGVAR(archive_cmds_need_lc, $1)=no
_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
runpath_var='LD_RUN_PATH'
- if test yes = "$GCC"; then
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ if test "$GCC" = yes; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
else
- _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
fi
;;
sysv5* | sco3.2v5* | sco5v6*)
- # Note: We CANNOT use -z defs as we might desire, because we do not
+ # Note: We can NOT use -z defs as we might desire, because we do not
# link with -lc, and that would cause any symbols used from libc to
# always be unresolved, which means just about no library would
# ever link correctly. If we're not using GNU ld we use -z text
# though, which does catch some bad symbols but isn't as heavy-handed
# as -z defs.
- _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text'
- _LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs'
+ _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+ _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs'
_LT_TAGVAR(archive_cmds_need_lc, $1)=no
_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir'
_LT_TAGVAR(hardcode_libdir_separator, $1)=':'
_LT_TAGVAR(link_all_deplibs, $1)=yes
- _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport'
runpath_var='LD_RUN_PATH'
- if test yes = "$GCC"; then
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ if test "$GCC" = yes; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
else
- _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
fi
;;
@@ -6043,17 +5580,17 @@ _LT_EOF
;;
esac
- if test sni = "$host_vendor"; then
+ if test x$host_vendor = xsni; then
case $host in
sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
- _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Blargedynsym'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Blargedynsym'
;;
esac
fi
fi
])
AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)])
-test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no
+test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no
_LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld
@@ -6070,7 +5607,7 @@ x|xyes)
# Assume -lc should be added
_LT_TAGVAR(archive_cmds_need_lc, $1)=yes
- if test yes,yes = "$GCC,$enable_shared"; then
+ if test "$enable_shared" = yes && test "$GCC" = yes; then
case $_LT_TAGVAR(archive_cmds, $1) in
*'~'*)
# FIXME: we may have to deal with multi-command sequences.
@@ -6150,12 +5687,12 @@ _LT_TAGDECL([], [hardcode_libdir_flag_spec], [1],
_LT_TAGDECL([], [hardcode_libdir_separator], [1],
[Whether we need a single "-rpath" flag with a separated argument])
_LT_TAGDECL([], [hardcode_direct], [0],
- [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes
+ [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes
DIR into the resulting binary])
_LT_TAGDECL([], [hardcode_direct_absolute], [0],
- [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes
+ [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes
DIR into the resulting binary and the resulting library dependency is
- "absolute", i.e impossible to change by setting $shlibpath_var if the
+ "absolute", i.e impossible to change by setting ${shlibpath_var} if the
library is relocated])
_LT_TAGDECL([], [hardcode_minus_L], [0],
[Set to "yes" if using the -LDIR flag during linking hardcodes DIR
@@ -6196,10 +5733,10 @@ dnl [Compiler flag to generate thread safe objects])
# ------------------------
# Ensure that the configuration variables for a C compiler are suitably
# defined. These variables are subsequently used by _LT_CONFIG to write
-# the compiler configuration to 'libtool'.
+# the compiler configuration to `libtool'.
m4_defun([_LT_LANG_C_CONFIG],
[m4_require([_LT_DECL_EGREP])dnl
-lt_save_CC=$CC
+lt_save_CC="$CC"
AC_LANG_PUSH(C)
# Source file extension for C test sources.
@@ -6239,18 +5776,18 @@ if test -n "$compiler"; then
LT_SYS_DLOPEN_SELF
_LT_CMD_STRIPLIB
- # Report what library types will actually be built
+ # Report which library types will actually be built
AC_MSG_CHECKING([if libtool supports shared libraries])
AC_MSG_RESULT([$can_build_shared])
AC_MSG_CHECKING([whether to build shared libraries])
- test no = "$can_build_shared" && enable_shared=no
+ test "$can_build_shared" = "no" && enable_shared=no
# On AIX, shared libraries and static libraries use the same namespace, and
# are all built from PIC.
case $host_os in
aix3*)
- test yes = "$enable_shared" && enable_static=no
+ test "$enable_shared" = yes && enable_static=no
if test -n "$RANLIB"; then
archive_cmds="$archive_cmds~\$RANLIB \$lib"
postinstall_cmds='$RANLIB $lib'
@@ -6258,12 +5795,8 @@ if test -n "$compiler"; then
;;
aix[[4-9]]*)
- if test ia64 != "$host_cpu"; then
- case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in
- yes,aix,yes) ;; # shared object as lib.so file only
- yes,svr4,*) ;; # shared object as lib.so archive member only
- yes,*) enable_static=no ;; # shared object in lib.a archive as well
- esac
+ if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+ test "$enable_shared" = yes && enable_static=no
fi
;;
esac
@@ -6271,13 +5804,13 @@ if test -n "$compiler"; then
AC_MSG_CHECKING([whether to build static libraries])
# Make sure either enable_shared or enable_static is yes.
- test yes = "$enable_shared" || enable_static=yes
+ test "$enable_shared" = yes || enable_static=yes
AC_MSG_RESULT([$enable_static])
_LT_CONFIG($1)
fi
AC_LANG_POP
-CC=$lt_save_CC
+CC="$lt_save_CC"
])# _LT_LANG_C_CONFIG
@@ -6285,14 +5818,14 @@ CC=$lt_save_CC
# --------------------------
# Ensure that the configuration variables for a C++ compiler are suitably
# defined. These variables are subsequently used by _LT_CONFIG to write
-# the compiler configuration to 'libtool'.
+# the compiler configuration to `libtool'.
m4_defun([_LT_LANG_CXX_CONFIG],
[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
m4_require([_LT_DECL_EGREP])dnl
m4_require([_LT_PATH_MANIFEST_TOOL])dnl
-if test -n "$CXX" && ( test no != "$CXX" &&
- ( (test g++ = "$CXX" && `g++ -v >/dev/null 2>&1` ) ||
- (test g++ != "$CXX"))); then
+if test -n "$CXX" && ( test "X$CXX" != "Xno" &&
+ ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) ||
+ (test "X$CXX" != "Xg++"))) ; then
AC_PROG_CXXCPP
else
_lt_caught_CXX_error=yes
@@ -6334,7 +5867,7 @@ _LT_TAGVAR(objext, $1)=$objext
# the CXX compiler isn't working. Some variables (like enable_shared)
# are currently assumed to apply to all compilers on this platform,
# and will be corrupted by setting them based on a non-working compiler.
-if test yes != "$_lt_caught_CXX_error"; then
+if test "$_lt_caught_CXX_error" != yes; then
# Code to be used in simple compile tests
lt_simple_compile_test_code="int some_variable = 0;"
@@ -6376,35 +5909,35 @@ if test yes != "$_lt_caught_CXX_error"; then
if test -n "$compiler"; then
# We don't want -fno-exception when compiling C++ code, so set the
# no_builtin_flag separately
- if test yes = "$GXX"; then
+ if test "$GXX" = yes; then
_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin'
else
_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=
fi
- if test yes = "$GXX"; then
+ if test "$GXX" = yes; then
# Set up default GNU C++ configuration
LT_PATH_LD
# Check if GNU C++ uses GNU ld as the underlying linker, since the
# archiving commands below assume that GNU ld is being used.
- if test yes = "$with_gnu_ld"; then
- _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ if test "$with_gnu_ld" = yes; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
- _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
# If archive_cmds runs LD, not CC, wlarc should be empty
# XXX I think wlarc can be eliminated in ltcf-cxx, but I need to
# investigate it a little bit more. (MM)
- wlarc='$wl'
+ wlarc='${wl}'
# ancient GNU ld didn't support --whole-archive et. al.
if eval "`$CC -print-prog-name=ld` --help 2>&1" |
$GREP 'no-whole-archive' > /dev/null; then
- _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive'
+ _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
else
_LT_TAGVAR(whole_archive_flag_spec, $1)=
fi
@@ -6440,30 +5973,18 @@ if test yes != "$_lt_caught_CXX_error"; then
_LT_TAGVAR(ld_shlibs, $1)=no
;;
aix[[4-9]]*)
- if test ia64 = "$host_cpu"; then
+ if test "$host_cpu" = ia64; then
# On IA64, the linker does run time linking by default, so we don't
# have to do anything special.
aix_use_runtimelinking=no
exp_sym_flag='-Bexport'
- no_entry_flag=
+ no_entry_flag=""
else
aix_use_runtimelinking=no
# Test if we are trying to use run time linking or normal
# AIX style linking. If -brtl is somewhere in LDFLAGS, we
- # have runtime linking enabled, and use it for executables.
- # For shared libraries, we enable/disable runtime linking
- # depending on the kind of the shared library created -
- # when "with_aix_soname,aix_use_runtimelinking" is:
- # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables
- # "aix,yes" lib.so shared, rtl:yes, for executables
- # lib.a static archive
- # "both,no" lib.so.V(shr.o) shared, rtl:yes
- # lib.a(lib.so.V) shared, rtl:no, for executables
- # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables
- # lib.a(lib.so.V) shared, rtl:no
- # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables
- # lib.a static archive
+ # need to do runtime linking.
case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*)
for ld_flag in $LDFLAGS; do
case $ld_flag in
@@ -6473,13 +5994,6 @@ if test yes != "$_lt_caught_CXX_error"; then
;;
esac
done
- if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then
- # With aix-soname=svr4, we create the lib.so.V shared archives only,
- # so we don't have lib.a shared libs to link our executables.
- # We have to force runtime linking in this case.
- aix_use_runtimelinking=yes
- LDFLAGS="$LDFLAGS -Wl,-brtl"
- fi
;;
esac
@@ -6498,21 +6012,13 @@ if test yes != "$_lt_caught_CXX_error"; then
_LT_TAGVAR(hardcode_direct_absolute, $1)=yes
_LT_TAGVAR(hardcode_libdir_separator, $1)=':'
_LT_TAGVAR(link_all_deplibs, $1)=yes
- _LT_TAGVAR(file_list_spec, $1)='$wl-f,'
- case $with_aix_soname,$aix_use_runtimelinking in
- aix,*) ;; # no import file
- svr4,* | *,yes) # use import file
- # The Import File defines what to hardcode.
- _LT_TAGVAR(hardcode_direct, $1)=no
- _LT_TAGVAR(hardcode_direct_absolute, $1)=no
- ;;
- esac
+ _LT_TAGVAR(file_list_spec, $1)='${wl}-f,'
- if test yes = "$GXX"; then
+ if test "$GXX" = yes; then
case $host_os in aix4.[[012]]|aix4.[[012]].*)
# We only want to do this on AIX 4.2 and lower, the check
# below for broken collect2 doesn't work under 4.3+
- collect2name=`$CC -print-prog-name=collect2`
+ collect2name=`${CC} -print-prog-name=collect2`
if test -f "$collect2name" &&
strings "$collect2name" | $GREP resolve_lib_name >/dev/null
then
@@ -6530,84 +6036,64 @@ if test yes != "$_lt_caught_CXX_error"; then
fi
esac
shared_flag='-shared'
- if test yes = "$aix_use_runtimelinking"; then
- shared_flag=$shared_flag' $wl-G'
+ if test "$aix_use_runtimelinking" = yes; then
+ shared_flag="$shared_flag "'${wl}-G'
fi
- # Need to ensure runtime linking is disabled for the traditional
- # shared library, or the linker may eventually find shared libraries
- # /with/ Import File - we do not want to mix them.
- shared_flag_aix='-shared'
- shared_flag_svr4='-shared $wl-G'
else
# not using gcc
- if test ia64 = "$host_cpu"; then
+ if test "$host_cpu" = ia64; then
# VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
# chokes on -Wl,-G. The following line is correct:
shared_flag='-G'
else
- if test yes = "$aix_use_runtimelinking"; then
- shared_flag='$wl-G'
+ if test "$aix_use_runtimelinking" = yes; then
+ shared_flag='${wl}-G'
else
- shared_flag='$wl-bM:SRE'
+ shared_flag='${wl}-bM:SRE'
fi
- shared_flag_aix='$wl-bM:SRE'
- shared_flag_svr4='$wl-G'
fi
fi
- _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall'
# It seems that -bexpall does not export symbols beginning with
# underscore (_), so it is better to generate a list of symbols to
# export.
_LT_TAGVAR(always_export_symbols, $1)=yes
- if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then
+ if test "$aix_use_runtimelinking" = yes; then
# Warning - without using the other runtime loading flags (-brtl),
# -berok will link without error, but may produce a broken library.
- # The "-G" linker flag allows undefined symbols.
- _LT_TAGVAR(no_undefined_flag, $1)='-bernotok'
+ _LT_TAGVAR(allow_undefined_flag, $1)='-berok'
# Determine the default libpath from the value encoded in an empty
# executable.
_LT_SYS_MODULE_PATH_AIX([$1])
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath"
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
else
- if test ia64 = "$host_cpu"; then
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib'
+ if test "$host_cpu" = ia64; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib'
_LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs"
- _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols"
+ _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
else
# Determine the default libpath from the value encoded in an
# empty executable.
_LT_SYS_MODULE_PATH_AIX([$1])
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath"
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
# Warning - without using the other run time loading flags,
# -berok will link without error, but may produce a broken library.
- _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok'
- _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok'
- if test yes = "$with_gnu_ld"; then
+ _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok'
+ _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok'
+ if test "$with_gnu_ld" = yes; then
# We only use this code for GNU lds that support --whole-archive.
- _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive'
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
else
# Exported symbols can be pulled into shared objects from archives
_LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
fi
_LT_TAGVAR(archive_cmds_need_lc, $1)=yes
- _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d'
- # -brtl affects multiple linker settings, -berok does not and is overridden later
- compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`'
- if test svr4 != "$with_aix_soname"; then
- # This is similar to how AIX traditionally builds its shared
- # libraries. Need -bnortl late, we may have -brtl in LDFLAGS.
- _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname'
- fi
- if test aix != "$with_aix_soname"; then
- _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp'
- else
- # used by -dlpreopen to get the symbols
- _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV $output_objdir/$realname.d/$soname $output_objdir'
- fi
- _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d'
+ # This is similar to how AIX traditionally builds its shared
+ # libraries.
+ _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
fi
fi
;;
@@ -6617,7 +6103,7 @@ if test yes != "$_lt_caught_CXX_error"; then
_LT_TAGVAR(allow_undefined_flag, $1)=unsupported
# Joseph Beckenbach <jrb3@best.com> says some releases of gcc
# support --undefined. This deserves some investigation. FIXME
- _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
else
_LT_TAGVAR(ld_shlibs, $1)=no
fi
@@ -6645,58 +6131,57 @@ if test yes != "$_lt_caught_CXX_error"; then
# Tell ltmain to make .lib files, not .a files.
libext=lib
# Tell ltmain to make .dll files, not .so files.
- shrext_cmds=.dll
+ shrext_cmds=".dll"
# FIXME: Setting linknames here is a bad hack.
- _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames='
- _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then
- cp "$export_symbols" "$output_objdir/$soname.def";
- echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp";
- else
- $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp;
- fi~
- $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
- linknames='
+ _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames='
+ _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+ $SED -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp;
+ else
+ $SED -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp;
+ fi~
+ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+ linknames='
# The linker will not automatically build a static lib if we build a DLL.
# _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
# Don't use ranlib
_LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib'
_LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~
- lt_tool_outputfile="@TOOL_OUTPUT@"~
- case $lt_outputfile in
- *.exe|*.EXE) ;;
- *)
- lt_outputfile=$lt_outputfile.exe
- lt_tool_outputfile=$lt_tool_outputfile.exe
- ;;
- esac~
- func_to_tool_file "$lt_outputfile"~
- if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then
- $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
- $RM "$lt_outputfile.manifest";
- fi'
+ lt_tool_outputfile="@TOOL_OUTPUT@"~
+ case $lt_outputfile in
+ *.exe|*.EXE) ;;
+ *)
+ lt_outputfile="$lt_outputfile.exe"
+ lt_tool_outputfile="$lt_tool_outputfile.exe"
+ ;;
+ esac~
+ func_to_tool_file "$lt_outputfile"~
+ if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then
+ $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+ $RM "$lt_outputfile.manifest";
+ fi'
;;
*)
# g++
# _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
# as there is no search path for DLLs.
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
- _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols'
_LT_TAGVAR(allow_undefined_flag, $1)=unsupported
_LT_TAGVAR(always_export_symbols, $1)=no
_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
- # If the export-symbols file already is a .def file, use it as
- # is; otherwise, prepend EXPORTS...
- _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then
- cp $export_symbols $output_objdir/$soname.def;
- else
- echo EXPORTS > $output_objdir/$soname.def;
- cat $export_symbols >> $output_objdir/$soname.def;
- fi~
- $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ # If the export-symbols file already is a .def file (1st line
+ # is EXPORTS), use it as is; otherwise, prepend...
+ _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+ cp $export_symbols $output_objdir/$soname.def;
+ else
+ echo EXPORTS > $output_objdir/$soname.def;
+ cat $export_symbols >> $output_objdir/$soname.def;
+ fi~
+ $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
else
_LT_TAGVAR(ld_shlibs, $1)=no
fi
@@ -6707,34 +6192,6 @@ if test yes != "$_lt_caught_CXX_error"; then
_LT_DARWIN_LINKER_FEATURES($1)
;;
- os2*)
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
- _LT_TAGVAR(hardcode_minus_L, $1)=yes
- _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
- shrext_cmds=.dll
- _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
- $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
- $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
- $ECHO EXPORTS >> $output_objdir/$libname.def~
- emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~
- $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
- emximp -o $lib $output_objdir/$libname.def'
- _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
- $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
- $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
- $ECHO EXPORTS >> $output_objdir/$libname.def~
- prefix_cmds="$SED"~
- if test EXPORTS = "`$SED 1q $export_symbols`"; then
- prefix_cmds="$prefix_cmds -e 1d";
- fi~
- prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~
- cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~
- $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
- emximp -o $lib $output_objdir/$libname.def'
- _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
- _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
- ;;
-
dgux*)
case $cc_basename in
ec++*)
@@ -6769,15 +6226,18 @@ if test yes != "$_lt_caught_CXX_error"; then
_LT_TAGVAR(ld_shlibs, $1)=yes
;;
+ gnu*)
+ ;;
+
haiku*)
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
_LT_TAGVAR(link_all_deplibs, $1)=yes
;;
hpux9*)
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
_LT_TAGVAR(hardcode_libdir_separator, $1)=:
- _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
_LT_TAGVAR(hardcode_direct, $1)=yes
_LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,
# but as the default
@@ -6789,7 +6249,7 @@ if test yes != "$_lt_caught_CXX_error"; then
_LT_TAGVAR(ld_shlibs, $1)=no
;;
aCC*)
- _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
# Commands to make compiler produce verbose output that lists
# what "hidden" libraries, object files and flags are used when
# linking a shared library.
@@ -6798,11 +6258,11 @@ if test yes != "$_lt_caught_CXX_error"; then
# explicitly linking system object files so we need to strip them
# from the output so that they don't get included in the library
# dependencies.
- output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+ output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
;;
*)
- if test yes = "$GXX"; then
- _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
+ if test "$GXX" = yes; then
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
else
# FIXME: insert proper C++ library support
_LT_TAGVAR(ld_shlibs, $1)=no
@@ -6812,15 +6272,15 @@ if test yes != "$_lt_caught_CXX_error"; then
;;
hpux10*|hpux11*)
- if test no = "$with_gnu_ld"; then
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir'
+ if test $with_gnu_ld = no; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
_LT_TAGVAR(hardcode_libdir_separator, $1)=:
case $host_cpu in
hppa*64*|ia64*)
;;
*)
- _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
;;
esac
fi
@@ -6846,13 +6306,13 @@ if test yes != "$_lt_caught_CXX_error"; then
aCC*)
case $host_cpu in
hppa*64*)
- _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
;;
ia64*)
- _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
;;
*)
- _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
;;
esac
# Commands to make compiler produce verbose output that lists
@@ -6863,20 +6323,20 @@ if test yes != "$_lt_caught_CXX_error"; then
# explicitly linking system object files so we need to strip them
# from the output so that they don't get included in the library
# dependencies.
- output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+ output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
;;
*)
- if test yes = "$GXX"; then
- if test no = "$with_gnu_ld"; then
+ if test "$GXX" = yes; then
+ if test $with_gnu_ld = no; then
case $host_cpu in
hppa*64*)
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
;;
ia64*)
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
;;
*)
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
;;
esac
fi
@@ -6891,22 +6351,22 @@ if test yes != "$_lt_caught_CXX_error"; then
interix[[3-9]]*)
_LT_TAGVAR(hardcode_direct, $1)=no
_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
- _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
# Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
# Instead, shared libraries are loaded at an image base (0x10000000 by
# default) and relocated if they conflict, which is a slow very memory
# consuming and fragmenting process. To avoid this, we pick a random,
# 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
# time. Moving up from 0x10000000 also allows more sbrk(2) space.
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
- _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
;;
irix5* | irix6*)
case $cc_basename in
CC*)
# SGI C++
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
# Archives containing C++ object files must be created using
# "CC -ar", where "CC" is the IRIX C++ compiler. This is
@@ -6915,22 +6375,22 @@ if test yes != "$_lt_caught_CXX_error"; then
_LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs'
;;
*)
- if test yes = "$GXX"; then
- if test no = "$with_gnu_ld"; then
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+ if test "$GXX" = yes; then
+ if test "$with_gnu_ld" = no; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
else
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` -o $lib'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib'
fi
fi
_LT_TAGVAR(link_all_deplibs, $1)=yes
;;
esac
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
_LT_TAGVAR(hardcode_libdir_separator, $1)=:
_LT_TAGVAR(inherit_rpath, $1)=yes
;;
- linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+ linux* | k*bsd*-gnu | kopensolaris*-gnu)
case $cc_basename in
KCC*)
# Kuck and Associates, Inc. (KAI) C++ Compiler
@@ -6938,8 +6398,8 @@ if test yes != "$_lt_caught_CXX_error"; then
# KCC will only create a shared library if the output file
# ends with ".so" (or ".sl" for HP-UX), so rename the library
# to its proper name (with version) after linking.
- _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
- _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib $wl-retain-symbols-file,$export_symbols; mv \$templib $lib'
+ _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib'
# Commands to make compiler produce verbose output that lists
# what "hidden" libraries, object files and flags are used when
# linking a shared library.
@@ -6948,10 +6408,10 @@ if test yes != "$_lt_caught_CXX_error"; then
# explicitly linking system object files so we need to strip them
# from the output so that they don't get included in the library
# dependencies.
- output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+ output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
- _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
# Archives containing C++ object files must be created using
# "CC -Bstatic", where "CC" is the KAI C++ compiler.
@@ -6965,59 +6425,59 @@ if test yes != "$_lt_caught_CXX_error"; then
# earlier do not add the objects themselves.
case `$CC -V 2>&1` in
*"Version 7."*)
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
;;
*) # Version 8.0 or newer
tmp_idyn=
case $host_cpu in
ia64*) tmp_idyn=' -i_dynamic';;
esac
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
;;
esac
_LT_TAGVAR(archive_cmds_need_lc, $1)=no
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
- _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
- _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
;;
pgCC* | pgcpp*)
# Portland Group C++ compiler
case `$CC -V` in
*pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*)
_LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~
- rm -rf $tpldir~
- $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~
- compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"'
+ rm -rf $tpldir~
+ $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~
+ compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"'
_LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~
- rm -rf $tpldir~
- $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~
- $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~
- $RANLIB $oldlib'
+ rm -rf $tpldir~
+ $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~
+ $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~
+ $RANLIB $oldlib'
_LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~
- rm -rf $tpldir~
- $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
- $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
+ rm -rf $tpldir~
+ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
+ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
_LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~
- rm -rf $tpldir~
- $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
- $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ rm -rf $tpldir~
+ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
+ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
;;
*) # Version 6 and above use weak symbols
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
;;
esac
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl--rpath $wl$libdir'
- _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
- _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
;;
cxx*)
# Compaq C++
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib $wl-retain-symbols-file $wl$export_symbols'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols'
runpath_var=LD_RUN_PATH
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
@@ -7031,18 +6491,18 @@ if test yes != "$_lt_caught_CXX_error"; then
# explicitly linking system object files so we need to strip them
# from the output so that they don't get included in the library
# dependencies.
- output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed'
+ output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed'
;;
xl* | mpixl* | bgxl*)
# IBM XL 8.0 on PPC, with GNU ld
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
- _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
- _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
- if test yes = "$supports_anon_versioning"; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ if test "x$supports_anon_versioning" = xyes; then
_LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
- cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
- echo "local: *; };" >> $output_objdir/$libname.ver~
- $CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib'
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
fi
;;
*)
@@ -7050,10 +6510,10 @@ if test yes != "$_lt_caught_CXX_error"; then
*Sun\ C*)
# Sun C++ 5.9
_LT_TAGVAR(no_undefined_flag, $1)=' -zdefs'
- _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file $wl$export_symbols'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols'
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
- _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
_LT_TAGVAR(compiler_needs_object, $1)=yes
# Not sure whether something based on
@@ -7111,17 +6571,22 @@ if test yes != "$_lt_caught_CXX_error"; then
_LT_TAGVAR(ld_shlibs, $1)=yes
;;
- openbsd* | bitrig*)
+ openbsd2*)
+ # C++ shared libraries are fairly broken
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+
+ openbsd*)
if test -f /usr/libexec/ld.so; then
_LT_TAGVAR(hardcode_direct, $1)=yes
_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
_LT_TAGVAR(hardcode_direct_absolute, $1)=yes
_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
- if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`"; then
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file,$export_symbols -o $lib'
- _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
- _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+ _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
fi
output_verbose_link_cmd=func_echo_all
else
@@ -7137,9 +6602,9 @@ if test yes != "$_lt_caught_CXX_error"; then
# KCC will only create a shared library if the output file
# ends with ".so" (or ".sl" for HP-UX), so rename the library
# to its proper name (with version) after linking.
- _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+ _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
_LT_TAGVAR(hardcode_libdir_separator, $1)=:
# Archives containing C++ object files must be created using
@@ -7157,17 +6622,17 @@ if test yes != "$_lt_caught_CXX_error"; then
cxx*)
case $host in
osf3*)
- _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*'
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $soname `test -n "$verstring" && func_echo_all "$wl-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+ _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && func_echo_all "${wl}-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
;;
*)
_LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
_LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~
- echo "-hidden">> $lib.exp~
- $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname $wl-input $wl$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~
- $RM $lib.exp'
+ echo "-hidden">> $lib.exp~
+ $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~
+ $RM $lib.exp'
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
;;
esac
@@ -7182,21 +6647,21 @@ if test yes != "$_lt_caught_CXX_error"; then
# explicitly linking system object files so we need to strip them
# from the output so that they don't get included in the library
# dependencies.
- output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+ output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
;;
*)
- if test yes,no = "$GXX,$with_gnu_ld"; then
- _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*'
+ if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+ _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
case $host in
osf3*)
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
;;
*)
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
;;
esac
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
_LT_TAGVAR(hardcode_libdir_separator, $1)=:
# Commands to make compiler produce verbose output that lists
@@ -7242,9 +6707,9 @@ if test yes != "$_lt_caught_CXX_error"; then
# Sun C++ 4.2, 5.x and Centerline C++
_LT_TAGVAR(archive_cmds_need_lc,$1)=yes
_LT_TAGVAR(no_undefined_flag, $1)=' -zdefs'
- _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
_LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
- $CC -G$allow_undefined_flag $wl-M $wl$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+ $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
@@ -7252,7 +6717,7 @@ if test yes != "$_lt_caught_CXX_error"; then
solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
*)
# The compiler driver will combine and reorder linker options,
- # but understands '-z linker_flag'.
+ # but understands `-z linker_flag'.
# Supported since Solaris 2.6 (maybe 2.5.1?)
_LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract'
;;
@@ -7269,30 +6734,30 @@ if test yes != "$_lt_caught_CXX_error"; then
;;
gcx*)
# Green Hills C++ Compiler
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
# The C++ compiler must be used to create the archive.
_LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs'
;;
*)
# GNU C++ compiler with Solaris linker
- if test yes,no = "$GXX,$with_gnu_ld"; then
- _LT_TAGVAR(no_undefined_flag, $1)=' $wl-z ${wl}defs'
+ if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+ _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs'
if $CC --version | $GREP -v '^2\.7' > /dev/null; then
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
_LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
- $CC -shared $pic_flag -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+ $CC -shared $pic_flag -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
# Commands to make compiler produce verbose output that lists
# what "hidden" libraries, object files and flags are used when
# linking a shared library.
output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
else
- # g++ 2.7 appears to require '-G' NOT '-shared' on this
+ # g++ 2.7 appears to require `-G' NOT `-shared' on this
# platform.
- _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
_LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
- $CC -G -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+ $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
# Commands to make compiler produce verbose output that lists
# what "hidden" libraries, object files and flags are used when
@@ -7300,11 +6765,11 @@ if test yes != "$_lt_caught_CXX_error"; then
output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
fi
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $wl$libdir'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir'
case $host_os in
solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
*)
- _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract'
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
;;
esac
fi
@@ -7313,52 +6778,52 @@ if test yes != "$_lt_caught_CXX_error"; then
;;
sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*)
- _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text'
+ _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
_LT_TAGVAR(archive_cmds_need_lc, $1)=no
_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
runpath_var='LD_RUN_PATH'
case $cc_basename in
CC*)
- _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
;;
*)
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
;;
esac
;;
sysv5* | sco3.2v5* | sco5v6*)
- # Note: We CANNOT use -z defs as we might desire, because we do not
+ # Note: We can NOT use -z defs as we might desire, because we do not
# link with -lc, and that would cause any symbols used from libc to
# always be unresolved, which means just about no library would
# ever link correctly. If we're not using GNU ld we use -z text
# though, which does catch some bad symbols but isn't as heavy-handed
# as -z defs.
- _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text'
- _LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs'
+ _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+ _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs'
_LT_TAGVAR(archive_cmds_need_lc, $1)=no
_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir'
_LT_TAGVAR(hardcode_libdir_separator, $1)=':'
_LT_TAGVAR(link_all_deplibs, $1)=yes
- _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport'
runpath_var='LD_RUN_PATH'
case $cc_basename in
CC*)
- _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
_LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~
- '"$_LT_TAGVAR(old_archive_cmds, $1)"
+ '"$_LT_TAGVAR(old_archive_cmds, $1)"
_LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~
- '"$_LT_TAGVAR(reload_cmds, $1)"
+ '"$_LT_TAGVAR(reload_cmds, $1)"
;;
*)
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
;;
esac
;;
@@ -7389,10 +6854,10 @@ if test yes != "$_lt_caught_CXX_error"; then
esac
AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)])
- test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no
+ test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no
- _LT_TAGVAR(GCC, $1)=$GXX
- _LT_TAGVAR(LD, $1)=$LD
+ _LT_TAGVAR(GCC, $1)="$GXX"
+ _LT_TAGVAR(LD, $1)="$LD"
## CAVEAT EMPTOR:
## There is no encapsulation within the following macros, do not change
@@ -7419,7 +6884,7 @@ if test yes != "$_lt_caught_CXX_error"; then
lt_cv_path_LD=$lt_save_path_LD
lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld
lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld
-fi # test yes != "$_lt_caught_CXX_error"
+fi # test "$_lt_caught_CXX_error" != yes
AC_LANG_POP
])# _LT_LANG_CXX_CONFIG
@@ -7441,14 +6906,13 @@ AC_REQUIRE([_LT_DECL_SED])
AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])
func_stripname_cnf ()
{
- case @S|@2 in
- .*) func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%\\\\@S|@2\$%%"`;;
- *) func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%@S|@2\$%%"`;;
+ case ${2} in
+ .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;;
+ *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;;
esac
} # func_stripname_cnf
])# _LT_FUNC_STRIPNAME_CNF
-
# _LT_SYS_HIDDEN_LIBDEPS([TAGNAME])
# ---------------------------------
# Figure out "hidden" library dependencies from verbose
@@ -7532,13 +6996,13 @@ if AC_TRY_EVAL(ac_compile); then
pre_test_object_deps_done=no
for p in `eval "$output_verbose_link_cmd"`; do
- case $prev$p in
+ case ${prev}${p} in
-L* | -R* | -l*)
# Some compilers place space between "-{L,R}" and the path.
# Remove the space.
- if test x-L = "$p" ||
- test x-R = "$p"; then
+ if test $p = "-L" ||
+ test $p = "-R"; then
prev=$p
continue
fi
@@ -7554,16 +7018,16 @@ if AC_TRY_EVAL(ac_compile); then
case $p in
=*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;;
esac
- if test no = "$pre_test_object_deps_done"; then
- case $prev in
+ if test "$pre_test_object_deps_done" = no; then
+ case ${prev} in
-L | -R)
# Internal compiler library paths should come after those
# provided the user. The postdeps already come after the
# user supplied libs so there is no need to process them.
if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then
- _LT_TAGVAR(compiler_lib_search_path, $1)=$prev$p
+ _LT_TAGVAR(compiler_lib_search_path, $1)="${prev}${p}"
else
- _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} $prev$p"
+ _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} ${prev}${p}"
fi
;;
# The "-l" case would never come before the object being
@@ -7571,9 +7035,9 @@ if AC_TRY_EVAL(ac_compile); then
esac
else
if test -z "$_LT_TAGVAR(postdeps, $1)"; then
- _LT_TAGVAR(postdeps, $1)=$prev$p
+ _LT_TAGVAR(postdeps, $1)="${prev}${p}"
else
- _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} $prev$p"
+ _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} ${prev}${p}"
fi
fi
prev=
@@ -7588,15 +7052,15 @@ if AC_TRY_EVAL(ac_compile); then
continue
fi
- if test no = "$pre_test_object_deps_done"; then
+ if test "$pre_test_object_deps_done" = no; then
if test -z "$_LT_TAGVAR(predep_objects, $1)"; then
- _LT_TAGVAR(predep_objects, $1)=$p
+ _LT_TAGVAR(predep_objects, $1)="$p"
else
_LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p"
fi
else
if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then
- _LT_TAGVAR(postdep_objects, $1)=$p
+ _LT_TAGVAR(postdep_objects, $1)="$p"
else
_LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p"
fi
@@ -7627,6 +7091,51 @@ interix[[3-9]]*)
_LT_TAGVAR(postdep_objects,$1)=
_LT_TAGVAR(postdeps,$1)=
;;
+
+linux*)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*)
+ # Sun C++ 5.9
+
+ # The more standards-conforming stlport4 library is
+ # incompatible with the Cstd library. Avoid specifying
+ # it if it's in CXXFLAGS. Ignore libCrun as
+ # -library=stlport4 depends on it.
+ case " $CXX $CXXFLAGS " in
+ *" -library=stlport4 "*)
+ solaris_use_stlport4=yes
+ ;;
+ esac
+
+ if test "$solaris_use_stlport4" != yes; then
+ _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun'
+ fi
+ ;;
+ esac
+ ;;
+
+solaris*)
+ case $cc_basename in
+ CC* | sunCC*)
+ # The more standards-conforming stlport4 library is
+ # incompatible with the Cstd library. Avoid specifying
+ # it if it's in CXXFLAGS. Ignore libCrun as
+ # -library=stlport4 depends on it.
+ case " $CXX $CXXFLAGS " in
+ *" -library=stlport4 "*)
+ solaris_use_stlport4=yes
+ ;;
+ esac
+
+ # Adding this requires a known-good setup of shared libraries for
+ # Sun compiler versions before 5.6, else PIC objects from an old
+ # archive will be linked into the output, leading to subtle bugs.
+ if test "$solaris_use_stlport4" != yes; then
+ _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun'
+ fi
+ ;;
+ esac
+ ;;
esac
])
@@ -7635,7 +7144,7 @@ case " $_LT_TAGVAR(postdeps, $1) " in
esac
_LT_TAGVAR(compiler_lib_search_dirs, $1)=
if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then
- _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | $SED -e 's! -L! !g' -e 's!^ !!'`
+ _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | ${SED} -e 's! -L! !g' -e 's!^ !!'`
fi
_LT_TAGDECL([], [compiler_lib_search_dirs], [1],
[The directories searched by this compiler when creating a shared library])
@@ -7655,10 +7164,10 @@ _LT_TAGDECL([], [compiler_lib_search_path], [1],
# --------------------------
# Ensure that the configuration variables for a Fortran 77 compiler are
# suitably defined. These variables are subsequently used by _LT_CONFIG
-# to write the compiler configuration to 'libtool'.
+# to write the compiler configuration to `libtool'.
m4_defun([_LT_LANG_F77_CONFIG],
[AC_LANG_PUSH(Fortran 77)
-if test -z "$F77" || test no = "$F77"; then
+if test -z "$F77" || test "X$F77" = "Xno"; then
_lt_disable_F77=yes
fi
@@ -7695,7 +7204,7 @@ _LT_TAGVAR(objext, $1)=$objext
# the F77 compiler isn't working. Some variables (like enable_shared)
# are currently assumed to apply to all compilers on this platform,
# and will be corrupted by setting them based on a non-working compiler.
-if test yes != "$_lt_disable_F77"; then
+if test "$_lt_disable_F77" != yes; then
# Code to be used in simple compile tests
lt_simple_compile_test_code="\
subroutine t
@@ -7717,7 +7226,7 @@ if test yes != "$_lt_disable_F77"; then
_LT_LINKER_BOILERPLATE
# Allow CC to be a program name with arguments.
- lt_save_CC=$CC
+ lt_save_CC="$CC"
lt_save_GCC=$GCC
lt_save_CFLAGS=$CFLAGS
CC=${F77-"f77"}
@@ -7731,25 +7240,21 @@ if test yes != "$_lt_disable_F77"; then
AC_MSG_RESULT([$can_build_shared])
AC_MSG_CHECKING([whether to build shared libraries])
- test no = "$can_build_shared" && enable_shared=no
+ test "$can_build_shared" = "no" && enable_shared=no
# On AIX, shared libraries and static libraries use the same namespace, and
# are all built from PIC.
case $host_os in
aix3*)
- test yes = "$enable_shared" && enable_static=no
+ test "$enable_shared" = yes && enable_static=no
if test -n "$RANLIB"; then
archive_cmds="$archive_cmds~\$RANLIB \$lib"
postinstall_cmds='$RANLIB $lib'
fi
;;
aix[[4-9]]*)
- if test ia64 != "$host_cpu"; then
- case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in
- yes,aix,yes) ;; # shared object as lib.so file only
- yes,svr4,*) ;; # shared object as lib.so archive member only
- yes,*) enable_static=no ;; # shared object in lib.a archive as well
- esac
+ if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+ test "$enable_shared" = yes && enable_static=no
fi
;;
esac
@@ -7757,11 +7262,11 @@ if test yes != "$_lt_disable_F77"; then
AC_MSG_CHECKING([whether to build static libraries])
# Make sure either enable_shared or enable_static is yes.
- test yes = "$enable_shared" || enable_static=yes
+ test "$enable_shared" = yes || enable_static=yes
AC_MSG_RESULT([$enable_static])
- _LT_TAGVAR(GCC, $1)=$G77
- _LT_TAGVAR(LD, $1)=$LD
+ _LT_TAGVAR(GCC, $1)="$G77"
+ _LT_TAGVAR(LD, $1)="$LD"
## CAVEAT EMPTOR:
## There is no encapsulation within the following macros, do not change
@@ -7778,9 +7283,9 @@ if test yes != "$_lt_disable_F77"; then
fi # test -n "$compiler"
GCC=$lt_save_GCC
- CC=$lt_save_CC
- CFLAGS=$lt_save_CFLAGS
-fi # test yes != "$_lt_disable_F77"
+ CC="$lt_save_CC"
+ CFLAGS="$lt_save_CFLAGS"
+fi # test "$_lt_disable_F77" != yes
AC_LANG_POP
])# _LT_LANG_F77_CONFIG
@@ -7790,11 +7295,11 @@ AC_LANG_POP
# -------------------------
# Ensure that the configuration variables for a Fortran compiler are
# suitably defined. These variables are subsequently used by _LT_CONFIG
-# to write the compiler configuration to 'libtool'.
+# to write the compiler configuration to `libtool'.
m4_defun([_LT_LANG_FC_CONFIG],
[AC_LANG_PUSH(Fortran)
-if test -z "$FC" || test no = "$FC"; then
+if test -z "$FC" || test "X$FC" = "Xno"; then
_lt_disable_FC=yes
fi
@@ -7831,7 +7336,7 @@ _LT_TAGVAR(objext, $1)=$objext
# the FC compiler isn't working. Some variables (like enable_shared)
# are currently assumed to apply to all compilers on this platform,
# and will be corrupted by setting them based on a non-working compiler.
-if test yes != "$_lt_disable_FC"; then
+if test "$_lt_disable_FC" != yes; then
# Code to be used in simple compile tests
lt_simple_compile_test_code="\
subroutine t
@@ -7853,7 +7358,7 @@ if test yes != "$_lt_disable_FC"; then
_LT_LINKER_BOILERPLATE
# Allow CC to be a program name with arguments.
- lt_save_CC=$CC
+ lt_save_CC="$CC"
lt_save_GCC=$GCC
lt_save_CFLAGS=$CFLAGS
CC=${FC-"f95"}
@@ -7869,25 +7374,21 @@ if test yes != "$_lt_disable_FC"; then
AC_MSG_RESULT([$can_build_shared])
AC_MSG_CHECKING([whether to build shared libraries])
- test no = "$can_build_shared" && enable_shared=no
+ test "$can_build_shared" = "no" && enable_shared=no
# On AIX, shared libraries and static libraries use the same namespace, and
# are all built from PIC.
case $host_os in
aix3*)
- test yes = "$enable_shared" && enable_static=no
+ test "$enable_shared" = yes && enable_static=no
if test -n "$RANLIB"; then
archive_cmds="$archive_cmds~\$RANLIB \$lib"
postinstall_cmds='$RANLIB $lib'
fi
;;
aix[[4-9]]*)
- if test ia64 != "$host_cpu"; then
- case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in
- yes,aix,yes) ;; # shared object as lib.so file only
- yes,svr4,*) ;; # shared object as lib.so archive member only
- yes,*) enable_static=no ;; # shared object in lib.a archive as well
- esac
+ if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+ test "$enable_shared" = yes && enable_static=no
fi
;;
esac
@@ -7895,11 +7396,11 @@ if test yes != "$_lt_disable_FC"; then
AC_MSG_CHECKING([whether to build static libraries])
# Make sure either enable_shared or enable_static is yes.
- test yes = "$enable_shared" || enable_static=yes
+ test "$enable_shared" = yes || enable_static=yes
AC_MSG_RESULT([$enable_static])
- _LT_TAGVAR(GCC, $1)=$ac_cv_fc_compiler_gnu
- _LT_TAGVAR(LD, $1)=$LD
+ _LT_TAGVAR(GCC, $1)="$ac_cv_fc_compiler_gnu"
+ _LT_TAGVAR(LD, $1)="$LD"
## CAVEAT EMPTOR:
## There is no encapsulation within the following macros, do not change
@@ -7919,7 +7420,7 @@ if test yes != "$_lt_disable_FC"; then
GCC=$lt_save_GCC
CC=$lt_save_CC
CFLAGS=$lt_save_CFLAGS
-fi # test yes != "$_lt_disable_FC"
+fi # test "$_lt_disable_FC" != yes
AC_LANG_POP
])# _LT_LANG_FC_CONFIG
@@ -7929,7 +7430,7 @@ AC_LANG_POP
# --------------------------
# Ensure that the configuration variables for the GNU Java Compiler compiler
# are suitably defined. These variables are subsequently used by _LT_CONFIG
-# to write the compiler configuration to 'libtool'.
+# to write the compiler configuration to `libtool'.
m4_defun([_LT_LANG_GCJ_CONFIG],
[AC_REQUIRE([LT_PROG_GCJ])dnl
AC_LANG_SAVE
@@ -7963,7 +7464,7 @@ CC=${GCJ-"gcj"}
CFLAGS=$GCJFLAGS
compiler=$CC
_LT_TAGVAR(compiler, $1)=$CC
-_LT_TAGVAR(LD, $1)=$LD
+_LT_TAGVAR(LD, $1)="$LD"
_LT_CC_BASENAME([$compiler])
# GCJ did not exist at the time GCC didn't implicitly link libc in.
@@ -8000,7 +7501,7 @@ CFLAGS=$lt_save_CFLAGS
# --------------------------
# Ensure that the configuration variables for the GNU Go compiler
# are suitably defined. These variables are subsequently used by _LT_CONFIG
-# to write the compiler configuration to 'libtool'.
+# to write the compiler configuration to `libtool'.
m4_defun([_LT_LANG_GO_CONFIG],
[AC_REQUIRE([LT_PROG_GO])dnl
AC_LANG_SAVE
@@ -8034,7 +7535,7 @@ CC=${GOC-"gccgo"}
CFLAGS=$GOFLAGS
compiler=$CC
_LT_TAGVAR(compiler, $1)=$CC
-_LT_TAGVAR(LD, $1)=$LD
+_LT_TAGVAR(LD, $1)="$LD"
_LT_CC_BASENAME([$compiler])
# Go did not exist at the time GCC didn't implicitly link libc in.
@@ -8071,7 +7572,7 @@ CFLAGS=$lt_save_CFLAGS
# -------------------------
# Ensure that the configuration variables for the Windows resource compiler
# are suitably defined. These variables are subsequently used by _LT_CONFIG
-# to write the compiler configuration to 'libtool'.
+# to write the compiler configuration to `libtool'.
m4_defun([_LT_LANG_RC_CONFIG],
[AC_REQUIRE([LT_PROG_RC])dnl
AC_LANG_SAVE
@@ -8087,7 +7588,7 @@ _LT_TAGVAR(objext, $1)=$objext
lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }'
# Code to be used in simple link tests
-lt_simple_link_test_code=$lt_simple_compile_test_code
+lt_simple_link_test_code="$lt_simple_compile_test_code"
# ltmain only uses $CC for tagged configurations so make sure $CC is set.
_LT_TAG_COMPILER
@@ -8097,7 +7598,7 @@ _LT_COMPILER_BOILERPLATE
_LT_LINKER_BOILERPLATE
# Allow CC to be a program name with arguments.
-lt_save_CC=$CC
+lt_save_CC="$CC"
lt_save_CFLAGS=$CFLAGS
lt_save_GCC=$GCC
GCC=
@@ -8126,7 +7627,7 @@ AC_DEFUN([LT_PROG_GCJ],
[m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ],
[m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ],
[AC_CHECK_TOOL(GCJ, gcj,)
- test set = "${GCJFLAGS+set}" || GCJFLAGS="-g -O2"
+ test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2"
AC_SUBST(GCJFLAGS)])])[]dnl
])
@@ -8237,7 +7738,7 @@ lt_ac_count=0
# Add /usr/xpg4/bin/sed as it is typically found on Solaris
# along with /bin/sed that truncates output.
for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do
- test ! -f "$lt_ac_sed" && continue
+ test ! -f $lt_ac_sed && continue
cat /dev/null > conftest.in
lt_ac_count=0
echo $ECHO_N "0123456789$ECHO_C" >conftest.in
@@ -8254,9 +7755,9 @@ for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do
$lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break
cmp -s conftest.out conftest.nl || break
# 10000 chars as input seems more than enough
- test 10 -lt "$lt_ac_count" && break
+ test $lt_ac_count -gt 10 && break
lt_ac_count=`expr $lt_ac_count + 1`
- if test "$lt_ac_count" -gt "$lt_ac_max"; then
+ if test $lt_ac_count -gt $lt_ac_max; then
lt_ac_max=$lt_ac_count
lt_cv_path_SED=$lt_ac_sed
fi
@@ -8280,7 +7781,27 @@ dnl AC_DEFUN([LT_AC_PROG_SED], [])
# Find out whether the shell is Bourne or XSI compatible,
# or has some other useful features.
m4_defun([_LT_CHECK_SHELL_FEATURES],
-[if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+[AC_MSG_CHECKING([whether the shell understands some XSI constructs])
+# Try some XSI features
+xsi_shell=no
+( _lt_dummy="a/b/c"
+ test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \
+ = c,a/b,b/c, \
+ && eval 'test $(( 1 + 1 )) -eq 2 \
+ && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \
+ && xsi_shell=yes
+AC_MSG_RESULT([$xsi_shell])
+_LT_CONFIG_LIBTOOL_INIT([xsi_shell='$xsi_shell'])
+
+AC_MSG_CHECKING([whether the shell understands "+="])
+lt_shell_append=no
+( foo=bar; set foo baz; eval "$[1]+=\$[2]" && test "$foo" = barbaz ) \
+ >/dev/null 2>&1 \
+ && lt_shell_append=yes
+AC_MSG_RESULT([$lt_shell_append])
+_LT_CONFIG_LIBTOOL_INIT([lt_shell_append='$lt_shell_append'])
+
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
lt_unset=unset
else
lt_unset=false
@@ -8304,9 +7825,102 @@ _LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl
])# _LT_CHECK_SHELL_FEATURES
+# _LT_PROG_FUNCTION_REPLACE (FUNCNAME, REPLACEMENT-BODY)
+# ------------------------------------------------------
+# In `$cfgfile', look for function FUNCNAME delimited by `^FUNCNAME ()$' and
+# '^} FUNCNAME ', and replace its body with REPLACEMENT-BODY.
+m4_defun([_LT_PROG_FUNCTION_REPLACE],
+[dnl {
+sed -e '/^$1 ()$/,/^} # $1 /c\
+$1 ()\
+{\
+m4_bpatsubsts([$2], [$], [\\], [^\([ ]\)], [\\\1])
+} # Extended-shell $1 implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+])
+
+
+# _LT_PROG_REPLACE_SHELLFNS
+# -------------------------
+# Replace existing portable implementations of several shell functions with
+# equivalent extended shell implementations where those features are available..
+m4_defun([_LT_PROG_REPLACE_SHELLFNS],
+[if test x"$xsi_shell" = xyes; then
+ _LT_PROG_FUNCTION_REPLACE([func_dirname], [dnl
+ case ${1} in
+ */*) func_dirname_result="${1%/*}${2}" ;;
+ * ) func_dirname_result="${3}" ;;
+ esac])
+
+ _LT_PROG_FUNCTION_REPLACE([func_basename], [dnl
+ func_basename_result="${1##*/}"])
+
+ _LT_PROG_FUNCTION_REPLACE([func_dirname_and_basename], [dnl
+ case ${1} in
+ */*) func_dirname_result="${1%/*}${2}" ;;
+ * ) func_dirname_result="${3}" ;;
+ esac
+ func_basename_result="${1##*/}"])
+
+ _LT_PROG_FUNCTION_REPLACE([func_stripname], [dnl
+ # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are
+ # positional parameters, so assign one to ordinary parameter first.
+ func_stripname_result=${3}
+ func_stripname_result=${func_stripname_result#"${1}"}
+ func_stripname_result=${func_stripname_result%"${2}"}])
+
+ _LT_PROG_FUNCTION_REPLACE([func_split_long_opt], [dnl
+ func_split_long_opt_name=${1%%=*}
+ func_split_long_opt_arg=${1#*=}])
+
+ _LT_PROG_FUNCTION_REPLACE([func_split_short_opt], [dnl
+ func_split_short_opt_arg=${1#??}
+ func_split_short_opt_name=${1%"$func_split_short_opt_arg"}])
+
+ _LT_PROG_FUNCTION_REPLACE([func_lo2o], [dnl
+ case ${1} in
+ *.lo) func_lo2o_result=${1%.lo}.${objext} ;;
+ *) func_lo2o_result=${1} ;;
+ esac])
+
+ _LT_PROG_FUNCTION_REPLACE([func_xform], [ func_xform_result=${1%.*}.lo])
+
+ _LT_PROG_FUNCTION_REPLACE([func_arith], [ func_arith_result=$(( $[*] ))])
+
+ _LT_PROG_FUNCTION_REPLACE([func_len], [ func_len_result=${#1}])
+fi
+
+if test x"$lt_shell_append" = xyes; then
+ _LT_PROG_FUNCTION_REPLACE([func_append], [ eval "${1}+=\\${2}"])
+
+ _LT_PROG_FUNCTION_REPLACE([func_append_quoted], [dnl
+ func_quote_for_eval "${2}"
+dnl m4 expansion turns \\\\ into \\, and then the shell eval turns that into \
+ eval "${1}+=\\\\ \\$func_quote_for_eval_result"])
+
+ # Save a `func_append' function call where possible by direct use of '+='
+ sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+ test 0 -eq $? || _lt_function_replace_fail=:
+else
+ # Save a `func_append' function call even when '+=' is not available
+ sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+ test 0 -eq $? || _lt_function_replace_fail=:
+fi
+
+if test x"$_lt_function_replace_fail" = x":"; then
+ AC_MSG_WARN([Unable to substitute extended shell functions in $ofile])
+fi
+])
+
# _LT_PATH_CONVERSION_FUNCTIONS
# -----------------------------
-# Determine what file name conversion functions should be used by
+# Determine which file name conversion functions should be used by
# func_to_host_file (and, implicitly, by func_to_host_path). These are needed
# for certain cross-compile configurations and native mingw.
m4_defun([_LT_PATH_CONVERSION_FUNCTIONS],
diff --git a/m4/ltoptions.m4 b/m4/ltoptions.m4
index 94b0829..5d9acd8 100644
--- a/m4/ltoptions.m4
+++ b/m4/ltoptions.m4
@@ -1,14 +1,14 @@
# Helper functions for option handling. -*- Autoconf -*-
#
-# Copyright (C) 2004-2005, 2007-2009, 2011-2015 Free Software
-# Foundation, Inc.
+# Copyright (C) 2004, 2005, 2007, 2008, 2009 Free Software Foundation,
+# Inc.
# Written by Gary V. Vaughan, 2004
#
# This file is free software; the Free Software Foundation gives
# unlimited permission to copy and/or distribute it, with or without
# modifications, as long as this notice is preserved.
-# serial 8 ltoptions.m4
+# serial 7 ltoptions.m4
# This is to help aclocal find these macros, as it can't see m4_define.
AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])])
@@ -29,7 +29,7 @@ m4_define([_LT_SET_OPTION],
[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl
m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]),
_LT_MANGLE_DEFUN([$1], [$2]),
- [m4_warning([Unknown $1 option '$2'])])[]dnl
+ [m4_warning([Unknown $1 option `$2'])])[]dnl
])
@@ -75,15 +75,13 @@ m4_if([$1],[LT_INIT],[
dnl
dnl If no reference was made to various pairs of opposing options, then
dnl we run the default mode handler for the pair. For example, if neither
- dnl 'shared' nor 'disable-shared' was passed, we enable building of shared
+ dnl `shared' nor `disable-shared' was passed, we enable building of shared
dnl archives by default:
_LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED])
_LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC])
_LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC])
_LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install],
- [_LT_ENABLE_FAST_INSTALL])
- _LT_UNLESS_OPTIONS([LT_INIT], [aix-soname=aix aix-soname=both aix-soname=svr4],
- [_LT_WITH_AIX_SONAME([aix])])
+ [_LT_ENABLE_FAST_INSTALL])
])
])# _LT_SET_OPTIONS
@@ -114,7 +112,7 @@ AU_DEFUN([AC_LIBTOOL_DLOPEN],
[_LT_SET_OPTION([LT_INIT], [dlopen])
AC_DIAGNOSE([obsolete],
[$0: Remove this warning and the call to _LT_SET_OPTION when you
-put the 'dlopen' option into LT_INIT's first parameter.])
+put the `dlopen' option into LT_INIT's first parameter.])
])
dnl aclocal-1.4 backwards compatibility:
@@ -150,7 +148,7 @@ AU_DEFUN([AC_LIBTOOL_WIN32_DLL],
_LT_SET_OPTION([LT_INIT], [win32-dll])
AC_DIAGNOSE([obsolete],
[$0: Remove this warning and the call to _LT_SET_OPTION when you
-put the 'win32-dll' option into LT_INIT's first parameter.])
+put the `win32-dll' option into LT_INIT's first parameter.])
])
dnl aclocal-1.4 backwards compatibility:
@@ -159,9 +157,9 @@ dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], [])
# _LT_ENABLE_SHARED([DEFAULT])
# ----------------------------
-# implement the --enable-shared flag, and supports the 'shared' and
-# 'disable-shared' LT_INIT options.
-# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'.
+# implement the --enable-shared flag, and supports the `shared' and
+# `disable-shared' LT_INIT options.
+# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'.
m4_define([_LT_ENABLE_SHARED],
[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl
AC_ARG_ENABLE([shared],
@@ -174,14 +172,14 @@ AC_ARG_ENABLE([shared],
*)
enable_shared=no
# Look at the argument we got. We use all the common list separators.
- lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
for pkg in $enableval; do
- IFS=$lt_save_ifs
+ IFS="$lt_save_ifs"
if test "X$pkg" = "X$p"; then
enable_shared=yes
fi
done
- IFS=$lt_save_ifs
+ IFS="$lt_save_ifs"
;;
esac],
[enable_shared=]_LT_ENABLE_SHARED_DEFAULT)
@@ -213,9 +211,9 @@ dnl AC_DEFUN([AM_DISABLE_SHARED], [])
# _LT_ENABLE_STATIC([DEFAULT])
# ----------------------------
-# implement the --enable-static flag, and support the 'static' and
-# 'disable-static' LT_INIT options.
-# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'.
+# implement the --enable-static flag, and support the `static' and
+# `disable-static' LT_INIT options.
+# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'.
m4_define([_LT_ENABLE_STATIC],
[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl
AC_ARG_ENABLE([static],
@@ -228,14 +226,14 @@ AC_ARG_ENABLE([static],
*)
enable_static=no
# Look at the argument we got. We use all the common list separators.
- lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
for pkg in $enableval; do
- IFS=$lt_save_ifs
+ IFS="$lt_save_ifs"
if test "X$pkg" = "X$p"; then
enable_static=yes
fi
done
- IFS=$lt_save_ifs
+ IFS="$lt_save_ifs"
;;
esac],
[enable_static=]_LT_ENABLE_STATIC_DEFAULT)
@@ -267,9 +265,9 @@ dnl AC_DEFUN([AM_DISABLE_STATIC], [])
# _LT_ENABLE_FAST_INSTALL([DEFAULT])
# ----------------------------------
-# implement the --enable-fast-install flag, and support the 'fast-install'
-# and 'disable-fast-install' LT_INIT options.
-# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'.
+# implement the --enable-fast-install flag, and support the `fast-install'
+# and `disable-fast-install' LT_INIT options.
+# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'.
m4_define([_LT_ENABLE_FAST_INSTALL],
[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl
AC_ARG_ENABLE([fast-install],
@@ -282,14 +280,14 @@ AC_ARG_ENABLE([fast-install],
*)
enable_fast_install=no
# Look at the argument we got. We use all the common list separators.
- lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
for pkg in $enableval; do
- IFS=$lt_save_ifs
+ IFS="$lt_save_ifs"
if test "X$pkg" = "X$p"; then
enable_fast_install=yes
fi
done
- IFS=$lt_save_ifs
+ IFS="$lt_save_ifs"
;;
esac],
[enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT)
@@ -306,14 +304,14 @@ AU_DEFUN([AC_ENABLE_FAST_INSTALL],
[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install])
AC_DIAGNOSE([obsolete],
[$0: Remove this warning and the call to _LT_SET_OPTION when you put
-the 'fast-install' option into LT_INIT's first parameter.])
+the `fast-install' option into LT_INIT's first parameter.])
])
AU_DEFUN([AC_DISABLE_FAST_INSTALL],
[_LT_SET_OPTION([LT_INIT], [disable-fast-install])
AC_DIAGNOSE([obsolete],
[$0: Remove this warning and the call to _LT_SET_OPTION when you put
-the 'disable-fast-install' option into LT_INIT's first parameter.])
+the `disable-fast-install' option into LT_INIT's first parameter.])
])
dnl aclocal-1.4 backwards compatibility:
@@ -321,64 +319,11 @@ dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], [])
dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], [])
-# _LT_WITH_AIX_SONAME([DEFAULT])
-# ----------------------------------
-# implement the --with-aix-soname flag, and support the `aix-soname=aix'
-# and `aix-soname=both' and `aix-soname=svr4' LT_INIT options. DEFAULT
-# is either `aix', `both' or `svr4'. If omitted, it defaults to `aix'.
-m4_define([_LT_WITH_AIX_SONAME],
-[m4_define([_LT_WITH_AIX_SONAME_DEFAULT], [m4_if($1, svr4, svr4, m4_if($1, both, both, aix))])dnl
-shared_archive_member_spec=
-case $host,$enable_shared in
-power*-*-aix[[5-9]]*,yes)
- AC_MSG_CHECKING([which variant of shared library versioning to provide])
- AC_ARG_WITH([aix-soname],
- [AS_HELP_STRING([--with-aix-soname=aix|svr4|both],
- [shared library versioning (aka "SONAME") variant to provide on AIX, @<:@default=]_LT_WITH_AIX_SONAME_DEFAULT[@:>@.])],
- [case $withval in
- aix|svr4|both)
- ;;
- *)
- AC_MSG_ERROR([Unknown argument to --with-aix-soname])
- ;;
- esac
- lt_cv_with_aix_soname=$with_aix_soname],
- [AC_CACHE_VAL([lt_cv_with_aix_soname],
- [lt_cv_with_aix_soname=]_LT_WITH_AIX_SONAME_DEFAULT)
- with_aix_soname=$lt_cv_with_aix_soname])
- AC_MSG_RESULT([$with_aix_soname])
- if test aix != "$with_aix_soname"; then
- # For the AIX way of multilib, we name the shared archive member
- # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o',
- # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File.
- # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag,
- # the AIX toolchain works better with OBJECT_MODE set (default 32).
- if test 64 = "${OBJECT_MODE-32}"; then
- shared_archive_member_spec=shr_64
- else
- shared_archive_member_spec=shr
- fi
- fi
- ;;
-*)
- with_aix_soname=aix
- ;;
-esac
-
-_LT_DECL([], [shared_archive_member_spec], [0],
- [Shared archive member basename, for filename based shared library versioning on AIX])dnl
-])# _LT_WITH_AIX_SONAME
-
-LT_OPTION_DEFINE([LT_INIT], [aix-soname=aix], [_LT_WITH_AIX_SONAME([aix])])
-LT_OPTION_DEFINE([LT_INIT], [aix-soname=both], [_LT_WITH_AIX_SONAME([both])])
-LT_OPTION_DEFINE([LT_INIT], [aix-soname=svr4], [_LT_WITH_AIX_SONAME([svr4])])
-
-
# _LT_WITH_PIC([MODE])
# --------------------
-# implement the --with-pic flag, and support the 'pic-only' and 'no-pic'
+# implement the --with-pic flag, and support the `pic-only' and `no-pic'
# LT_INIT options.
-# MODE is either 'yes' or 'no'. If omitted, it defaults to 'both'.
+# MODE is either `yes' or `no'. If omitted, it defaults to `both'.
m4_define([_LT_WITH_PIC],
[AC_ARG_WITH([pic],
[AS_HELP_STRING([--with-pic@<:@=PKGS@:>@],
@@ -389,17 +334,19 @@ m4_define([_LT_WITH_PIC],
*)
pic_mode=default
# Look at the argument we got. We use all the common list separators.
- lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
for lt_pkg in $withval; do
- IFS=$lt_save_ifs
+ IFS="$lt_save_ifs"
if test "X$lt_pkg" = "X$lt_p"; then
pic_mode=yes
fi
done
- IFS=$lt_save_ifs
+ IFS="$lt_save_ifs"
;;
esac],
- [pic_mode=m4_default([$1], [default])])
+ [pic_mode=default])
+
+test -z "$pic_mode" && pic_mode=m4_default([$1], [default])
_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl
])# _LT_WITH_PIC
@@ -412,7 +359,7 @@ AU_DEFUN([AC_LIBTOOL_PICMODE],
[_LT_SET_OPTION([LT_INIT], [pic-only])
AC_DIAGNOSE([obsolete],
[$0: Remove this warning and the call to _LT_SET_OPTION when you
-put the 'pic-only' option into LT_INIT's first parameter.])
+put the `pic-only' option into LT_INIT's first parameter.])
])
dnl aclocal-1.4 backwards compatibility:
diff --git a/m4/ltversion.m4 b/m4/ltversion.m4
index fa04b52..07a8602 100644
--- a/m4/ltversion.m4
+++ b/m4/ltversion.m4
@@ -1,6 +1,6 @@
# ltversion.m4 -- version numbers -*- Autoconf -*-
#
-# Copyright (C) 2004, 2011-2015 Free Software Foundation, Inc.
+# Copyright (C) 2004 Free Software Foundation, Inc.
# Written by Scott James Remnant, 2004
#
# This file is free software; the Free Software Foundation gives
@@ -9,15 +9,15 @@
# @configure_input@
-# serial 4179 ltversion.m4
+# serial 3337 ltversion.m4
# This file is part of GNU Libtool
-m4_define([LT_PACKAGE_VERSION], [2.4.6])
-m4_define([LT_PACKAGE_REVISION], [2.4.6])
+m4_define([LT_PACKAGE_VERSION], [2.4.2])
+m4_define([LT_PACKAGE_REVISION], [1.3337])
AC_DEFUN([LTVERSION_VERSION],
-[macro_version='2.4.6'
-macro_revision='2.4.6'
+[macro_version='2.4.2'
+macro_revision='1.3337'
_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?])
_LT_DECL(, macro_revision, 0)
])
diff --git a/missing b/missing
index db98974..cdea514 100755
--- a/missing
+++ b/missing
@@ -1,7 +1,7 @@
#! /bin/sh
# Common wrapper for a few potentially missing GNU programs.
-scriptversion=2013-10-28.13; # UTC
+scriptversion=2012-06-26.16; # UTC
# Copyright (C) 1996-2013 Free Software Foundation, Inc.
# Originally written by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
@@ -160,7 +160,7 @@ give_advice ()
;;
autom4te*)
echo "You might have modified some maintainer files that require"
- echo "the 'autom4te' program to be rebuilt."
+ echo "the 'automa4te' program to be rebuilt."
program_details 'autom4te'
;;
bison*|yacc*)
diff --git a/msvc-env.bat b/msvc-env.bat
index 2dd0f00..aabed75 100644
--- a/msvc-env.bat
+++ b/msvc-env.bat
@@ -12,7 +12,7 @@ if "%VCHOME%"=="" SET VCHOME=%VSHOME%\VC
set SOURCEBASE=%cd%
set SOLUTION=openvpn.sln
set CPPFLAGS=%CPPFLAGS%;_CRT_SECURE_NO_WARNINGS;WIN32_LEAN_AND_MEAN;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS
-set CPPFLAGS=%CPPFLAGS%;NTDDI_VERSION=NTDDI_WINXP;_WIN32_WINNT=_WIN32_WINNT_WINXP
+set CPPFLAGS=%CPPFLAGS%;NTDDI_VERSION=NTDDI_VISTA;_WIN32_WINNT=_WIN32_WINNT_VISTA
set CPPFLAGS=%CPPFLAGS%;_USE_32BIT_TIME_T
set CPPFLAGS=%CPPFLAGS%;%EXTRA_CPPFLAGS%
diff --git a/sample/Makefile.in b/sample/Makefile.in
index 9ec41c2..28d710e 100644
--- a/sample/Makefile.in
+++ b/sample/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.15 from Makefile.am.
+# Makefile.in generated by automake 1.13.4 from Makefile.am.
# @configure_input@
-# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -26,17 +26,7 @@
#
VPATH = @srcdir@
-am__is_gnu_make = { \
- if test -z '$(MAKELEVEL)'; then \
- false; \
- elif test -n '$(MAKE_HOST)'; then \
- true; \
- elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
- true; \
- else \
- false; \
- fi; \
-}
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
am__make_running_with_option = \
case $${target_option-} in \
?) ;; \
@@ -100,6 +90,7 @@ POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
subdir = sample
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/ax_emptyarray.m4 \
$(top_srcdir)/m4/ax_socklen_t.m4 \
@@ -110,9 +101,9 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_emptyarray.m4 \
$(top_srcdir)/compat.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
-DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
mkinstalldirs = $(install_sh) -d
-CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_HEADER = $(top_builddir)/config.h \
+ $(top_builddir)/include/openvpn-plugin.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
AM_V_P = $(am__v_P_@AM_V@)
@@ -164,7 +155,6 @@ am__uninstall_files_from_dir = { \
am__installdirs = "$(DESTDIR)$(sampledir)"
DATA = $(sample_DATA)
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
-am__DIST_COMMON = $(srcdir)/Makefile.in
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
@@ -178,6 +168,7 @@ AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
+CMAKE = @CMAKE@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
@@ -212,25 +203,31 @@ LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
-LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+LZ4_CFLAGS = @LZ4_CFLAGS@
+LZ4_LIBS = @LZ4_LIBS@
LZO_CFLAGS = @LZO_CFLAGS@
LZO_LIBS = @LZO_LIBS@
MAKEINFO = @MAKEINFO@
MAN2HTML = @MAN2HTML@
MANIFEST_TOOL = @MANIFEST_TOOL@
+MBEDTLS_CFLAGS = @MBEDTLS_CFLAGS@
+MBEDTLS_LIBS = @MBEDTLS_LIBS@
MKDIR_P = @MKDIR_P@
NETSTAT = @NETSTAT@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
-OPENSSL_CRYPTO_CFLAGS = @OPENSSL_CRYPTO_CFLAGS@
-OPENSSL_CRYPTO_LIBS = @OPENSSL_CRYPTO_LIBS@
-OPENSSL_SSL_CFLAGS = @OPENSSL_SSL_CFLAGS@
-OPENSSL_SSL_LIBS = @OPENSSL_SSL_LIBS@
+OPENSSL_CFLAGS = @OPENSSL_CFLAGS@
+OPENSSL_LIBS = @OPENSSL_LIBS@
+OPENVPN_VERSION_MAJOR = @OPENVPN_VERSION_MAJOR@
+OPENVPN_VERSION_MINOR = @OPENVPN_VERSION_MINOR@
+OPENVPN_VERSION_PATCH = @OPENVPN_VERSION_PATCH@
OPTIONAL_CRYPTO_CFLAGS = @OPTIONAL_CRYPTO_CFLAGS@
OPTIONAL_CRYPTO_LIBS = @OPTIONAL_CRYPTO_LIBS@
OPTIONAL_DL_LIBS = @OPTIONAL_DL_LIBS@
+OPTIONAL_LZ4_CFLAGS = @OPTIONAL_LZ4_CFLAGS@
+OPTIONAL_LZ4_LIBS = @OPTIONAL_LZ4_LIBS@
OPTIONAL_LZO_CFLAGS = @OPTIONAL_LZO_CFLAGS@
OPTIONAL_LZO_LIBS = @OPTIONAL_LZO_LIBS@
OPTIONAL_PKCS11_HELPER_CFLAGS = @OPTIONAL_PKCS11_HELPER_CFLAGS@
@@ -256,8 +253,6 @@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
PLUGIN_AUTH_PAM_CFLAGS = @PLUGIN_AUTH_PAM_CFLAGS@
PLUGIN_AUTH_PAM_LIBS = @PLUGIN_AUTH_PAM_LIBS@
-POLARSSL_CFLAGS = @POLARSSL_CFLAGS@
-POLARSSL_LIBS = @POLARSSL_LIBS@
RANLIB = @RANLIB@
RC = @RC@
ROUTE = @ROUTE@
@@ -272,6 +267,11 @@ TAP_CFLAGS = @TAP_CFLAGS@
TAP_WIN_COMPONENT_ID = @TAP_WIN_COMPONENT_ID@
TAP_WIN_MIN_MAJOR = @TAP_WIN_MIN_MAJOR@
TAP_WIN_MIN_MINOR = @TAP_WIN_MIN_MINOR@
+TEST_CFLAGS = @TEST_CFLAGS@
+TEST_LDFLAGS = @TEST_LDFLAGS@
+VENDOR_BUILD_ROOT = @VENDOR_BUILD_ROOT@
+VENDOR_DIST_ROOT = @VENDOR_DIST_ROOT@
+VENDOR_SRC_ROOT = @VENDOR_SRC_ROOT@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
@@ -359,6 +359,7 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign sample/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign sample/Makefile
+.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
@@ -558,8 +559,6 @@ uninstall-am: uninstall-sampleDATA
mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
ps ps-am tags-am uninstall uninstall-am uninstall-sampleDATA
-.PRECIOUS: Makefile
-
@WIN32_TRUE@client.ovpn: sample-config-files/client.conf
@WIN32_TRUE@ -rm -f client.ovpn
diff --git a/sample/sample-config-files/client.conf b/sample/sample-config-files/client.conf
index 050ef60..f5c69e3 100644
--- a/sample/sample-config-files/client.conf
+++ b/sample/sample-config-files/client.conf
@@ -105,17 +105,20 @@ remote-cert-tls server
# If a tls-auth key is used on the server
# then every client must also have the key.
-;tls-auth ta.key 1
+tls-auth ta.key 1
# Select a cryptographic cipher.
# If the cipher option is used on the server
# then you must also specify it here.
-;cipher x
+# Note that 2.4 client/server will automatically
+# negotiate AES-256-GCM in TLS mode.
+# See also the ncp-cipher option in the manpage
+cipher AES-256-CBC
# Enable compression on the VPN link.
# Don't enable this unless it is also
# enabled in the server config file.
-comp-lzo
+#comp-lzo
# Set log file verbosity.
verb 3
diff --git a/sample/sample-config-files/loopback-client b/sample/sample-config-files/loopback-client
index ebbd1cf..7117307 100644
--- a/sample/sample-config-files/loopback-client
+++ b/sample/sample-config-files/loopback-client
@@ -21,5 +21,6 @@ remote-cert-tls server
ca sample-keys/ca.crt
key sample-keys/client.key
cert sample-keys/client.crt
+tls-auth sample-keys/ta.key 1
ping 1
inactive 120 10000000
diff --git a/sample/sample-config-files/loopback-server b/sample/sample-config-files/loopback-server
index 8cb97be..8e1f39c 100644
--- a/sample/sample-config-files/loopback-server
+++ b/sample/sample-config-files/loopback-server
@@ -21,5 +21,6 @@ dh sample-keys/dh2048.pem
ca sample-keys/ca.crt
key sample-keys/server.key
cert sample-keys/server.crt
+tls-auth sample-keys/ta.key 0
ping 1
inactive 120 10000000
diff --git a/sample/sample-config-files/server.conf b/sample/sample-config-files/server.conf
index 701be3c..aa7d5b3 100644
--- a/sample/sample-config-files/server.conf
+++ b/sample/sample-config-files/server.conf
@@ -241,19 +241,26 @@ keepalive 10 120
# a copy of this key.
# The second parameter should be '0'
# on the server and '1' on the clients.
-;tls-auth ta.key 0 # This file is secret
+tls-auth ta.key 0 # This file is secret
# Select a cryptographic cipher.
# This config item must be copied to
# the client config file as well.
-;cipher BF-CBC # Blowfish (default)
-;cipher AES-128-CBC # AES
-;cipher DES-EDE3-CBC # Triple-DES
-
-# Enable compression on the VPN link.
+# Note that 2.4 client/server will automatically
+# negotiate AES-256-GCM in TLS mode.
+# See also the ncp-cipher option in the manpage
+cipher AES-256-CBC
+
+# Enable compression on the VPN link and push the
+# option to the client (2.4+ only, for earlier
+# versions see below)
+;compress lz4-v2
+;push "compress lz4-v2"
+
+# For compression compatible with older clients use comp-lzo
# If you enable it here, you must also
# enable it in the client config file.
-comp-lzo
+;comp-lzo
# The maximum number of concurrently connected
# clients we want to allow.
@@ -302,3 +309,7 @@ verb 3
# sequential messages of the same message
# category will be output to the log.
;mute 20
+
+# Notify the client that when the server restarts so it
+# can automatically reconnect.
+explicit-exit-notify 1 \ No newline at end of file
diff --git a/sample/sample-config-files/static-home.conf b/sample/sample-config-files/static-home.conf
index c966687..ed0c672 100644
--- a/sample/sample-config-files/static-home.conf
+++ b/sample/sample-config-files/static-home.conf
@@ -26,6 +26,9 @@ up ./home.up
# Our pre-shared static key
secret static.key
+# Cipher to use
+cipher AES-256-CBC
+
# OpenVPN 2.0 uses UDP port 1194 by default
# (official port assignment by iana.org 11/04).
# OpenVPN 1.x uses UDP port 5000 by default.
diff --git a/sample/sample-config-files/static-office.conf b/sample/sample-config-files/static-office.conf
index 68030cc..609ddd0 100644
--- a/sample/sample-config-files/static-office.conf
+++ b/sample/sample-config-files/static-office.conf
@@ -23,6 +23,9 @@ up ./office.up
# Our pre-shared static key
secret static.key
+# Cipher to use
+cipher AES-256-CBC
+
# OpenVPN 2.0 uses UDP port 1194 by default
# (official port assignment by iana.org 11/04).
# OpenVPN 1.x uses UDP port 5000 by default.
diff --git a/sample/sample-keys/gen-sample-keys.sh b/sample/sample-keys/gen-sample-keys.sh
index 414687e..301cff2 100755
--- a/sample/sample-keys/gen-sample-keys.sh
+++ b/sample/sample-keys/gen-sample-keys.sh
@@ -14,6 +14,9 @@ then
exit 1
fi
+# Generate static key for tls-auth (or static key mode)
+$(dirname ${0})/../../src/openvpn/openvpn --genkey --secret ta.key
+
# Create required directories and files
mkdir -p sample-ca
rm -f sample-ca/index.txt
@@ -49,6 +52,14 @@ openssl pkcs12 -export -nodes -password pass:password \
-out sample-ca/client.p12 -inkey sample-ca/client.key \
-in sample-ca/client.crt -certfile sample-ca/ca.crt
+# Create a client cert, revoke it, generate CRL
+openssl req -new -nodes -config openssl.cnf \
+ -keyout sample-ca/client-revoked.key -out sample-ca/client-revoked.csr \
+ -subj "/C=KG/ST=NA/O=OpenVPN-TEST/CN=client-revoked/emailAddress=me@myhost.mydomain"
+openssl ca -batch -config openssl.cnf \
+ -out sample-ca/client-revoked.crt -in sample-ca/client-revoked.csr
+openssl ca -config openssl.cnf -revoke sample-ca/client-revoked.crt
+openssl ca -config openssl.cnf -gencrl -out sample-ca/ca.crl
# Create EC server and client cert (signed by 'regular' RSA CA)
openssl ecparam -out sample-ca/secp256k1.pem -name secp256k1
@@ -73,3 +84,4 @@ openssl dhparam -out dh2048.pem 2048
cp sample-ca/*.key .
cp sample-ca/*.crt .
cp sample-ca/*.p12 .
+cp sample-ca/*.crl .
diff --git a/sample/sample-keys/sample-ca/01.pem b/sample/sample-keys/sample-ca/01.pem
new file mode 100644
index 0000000..6613831
--- /dev/null
+++ b/sample/sample-keys/sample-ca/01.pem
@@ -0,0 +1,113 @@
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 1 (0x1)
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: C=KG, ST=NA, L=BISHKEK, O=OpenVPN-TEST/emailAddress=me@myhost.mydomain
+ Validity
+ Not Before: Oct 28 12:54:32 2016 GMT
+ Not After : Oct 26 12:54:32 2026 GMT
+ Subject: C=KG, ST=NA, O=OpenVPN-TEST, CN=Test-Server/emailAddress=me@myhost.mydomain
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:a6:74:d1:c9:77:5d:ff:d6:22:e3:69:38:8f:e1:
+ 15:0c:e3:46:2c:19:61:31:af:ef:f9:34:5b:0c:bd:
+ 20:d1:76:6a:64:62:f6:89:aa:5b:c9:42:10:44:6f:
+ 07:0f:fe:62:59:96:0b:16:ec:62:3e:18:08:ad:67:
+ 37:b6:53:2d:3d:d9:81:b7:6b:11:d6:fa:23:6a:23:
+ 6c:3c:be:54:91:e3:04:c6:f5:8c:a6:6a:80:9f:ef:
+ e8:5b:63:1e:68:37:09:ef:4d:5c:44:82:e6:2e:0d:
+ e5:d7:94:3f:31:74:50:d1:10:5c:99:4d:b5:9f:80:
+ 2b:46:25:37:8b:a2:3d:ce:02:b2:0a:21:63:82:9c:
+ a1:35:b9:3d:9e:ad:a4:19:3c:f5:b2:3a:d7:aa:d4:
+ b7:6d:c2:95:4d:94:4b:38:6f:b0:60:cf:22:d7:37:
+ 66:62:1d:1a:86:c2:a8:6a:2a:56:e5:d6:c3:e2:31:
+ 34:a6:42:5d:79:da:12:e0:a1:95:d1:17:07:f6:cc:
+ f8:63:fa:01:8a:26:7b:bf:b8:a4:87:8c:b5:a3:59:
+ 23:60:67:07:4a:4c:c1:55:be:60:a1:56:92:6c:97:
+ 53:fb:fe:eb:d3:25:fd:28:23:3e:38:4d:e9:92:90:
+ 8b:a6:5e:22:2f:02:1f:69:c6:fa:88:a5:52:88:cc:
+ 61:a1
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints:
+ CA:FALSE
+ Netscape Cert Type:
+ SSL Server
+ Netscape Comment:
+ OpenSSL Generated Server Certificate
+ X509v3 Subject Key Identifier:
+ 7D:4C:17:FE:59:B2:58:FF:08:BC:F4:88:FC:A3:8F:9F:CA:3B:3B:5E
+ X509v3 Authority Key Identifier:
+ keyid:08:C4:94:ED:23:0A:23:0D:D0:FA:D2:13:E2:3C:B6:65:E7:53:25:10
+ DirName:/C=KG/ST=NA/L=BISHKEK/O=OpenVPN-TEST/emailAddress=me@myhost.mydomain
+ serial:A4:CC:46:13:89:24:40:73
+
+ X509v3 Extended Key Usage:
+ TLS Web Server Authentication
+ X509v3 Key Usage:
+ Digital Signature, Key Encipherment
+ Signature Algorithm: sha256WithRSAEncryption
+ 82:2e:11:99:f4:56:98:ad:23:97:74:5c:69:00:7b:fc:9a:93:
+ 15:20:93:db:d6:83:04:9a:6c:cb:55:cd:5c:07:d6:31:5a:00:
+ 1d:35:eb:8e:74:cd:7a:08:db:cd:1f:89:8c:04:70:f7:35:e0:
+ a7:cc:cf:76:2b:8a:a5:80:7b:c1:72:4e:9a:c6:b7:a2:f5:9c:
+ 23:dc:d7:0d:93:a3:0f:f4:10:7d:8b:1d:85:5e:bb:2f:09:c8:
+ 67:41:38:12:72:14:29:f6:6d:68:b5:8a:97:1c:a1:8f:3d:74:
+ 14:95:c6:88:4f:4c:cd:8b:2e:db:95:b0:98:55:d7:5b:22:1f:
+ f3:de:5c:b4:7b:a0:d9:f2:56:2c:ff:85:b0:16:52:63:11:2b:
+ 14:8e:d0:f8:03:d2:cc:89:35:c0:d5:a3:b9:ec:11:55:e0:17:
+ 43:95:b2:6e:f2:db:80:73:f2:b3:3f:9d:fa:4d:24:6a:60:25:
+ 24:1a:53:10:38:08:d4:fe:fa:06:1a:1e:d3:cc:15:64:c7:9e:
+ 8b:51:ee:b3:50:25:60:88:70:46:39:bd:79:f1:5a:74:67:3d:
+ f0:7e:22:a9:b4:2e:f5:06:45:c3:46:fe:e6:32:40:e6:e1:00:
+ dc:e8:a8:43:fe:f4:66:64:4f:41:45:d5:d2:7b:ab:a0:62:f7:
+ dc:f0:28:d3:c6:9c:21:3e:bd:44:95:4c:20:b4:8f:c3:ae:ee:
+ eb:d7:7a:11:88:2d:3d:18:49:5d:e6:09:b8:5f:c7:24:32:83:
+ dd:5f:ae:03:02:c1:b6:51:0d:62:a2:41:f4:13:12:b2:f2:9a:
+ c1:50:04:63:42:de:41:b3:b3:ab:45:57:9e:8b:01:e0:c5:70:
+ d9:70:0e:ea:84:39:07:08:03:e9:99:b1:60:ce:a9:c6:ce:a4:
+ 61:29:36:3c:58:52:a2:c3:01:4f:4e:c1:e8:af:3b:ca:7c:34:
+ 9c:2a:21:c9:40:17:ce:8c:10:b2:fc:c2:39:43:55:50:19:2d:
+ c9:f0:ab:48:b2:86:e6:cf:1e:13:6c:6a:ed:85:e9:f6:dd:b9:
+ ba:6e:70:6a:e9:78:43:40:a3:c8:64:50:1f:5b:88:0d:88:55:
+ 0f:94:9c:92:44:83:79:0c:38:79:09:c4:93:6a:a8:dc:f3:8b:
+ c4:af:bf:0c:20:7b:76:7b:31:52:01:70:4f:09:be:38:d0:14:
+ ce:62:c6:00:35:cd:fc:eb:68:f1:45:d5:de:6a:3f:8b:3f:dc:
+ 1c:c9:e3:8a:7c:f1:17:53:71:f8:af:c9:43:9f:91:5a:16:0b:
+ 3a:c0:d7:b0:e7:74:54:12:f0:9a:71:5f:f3:dd:6b:c0:69:ec:
+ 9d:4d:14:61:bd:10:21:80
+-----BEGIN CERTIFICATE-----
+MIIFgDCCA2igAwIBAgIBATANBgkqhkiG9w0BAQsFADBmMQswCQYDVQQGEwJLRzEL
+MAkGA1UECBMCTkExEDAOBgNVBAcTB0JJU0hLRUsxFTATBgNVBAoTDE9wZW5WUE4t
+VEVTVDEhMB8GCSqGSIb3DQEJARYSbWVAbXlob3N0Lm15ZG9tYWluMB4XDTE2MTAy
+ODEyNTQzMloXDTI2MTAyNjEyNTQzMlowajELMAkGA1UEBhMCS0cxCzAJBgNVBAgT
+Ak5BMRUwEwYDVQQKEwxPcGVuVlBOLVRFU1QxFDASBgNVBAMTC1Rlc3QtU2VydmVy
+MSEwHwYJKoZIhvcNAQkBFhJtZUBteWhvc3QubXlkb21haW4wggEiMA0GCSqGSIb3
+DQEBAQUAA4IBDwAwggEKAoIBAQCmdNHJd13/1iLjaTiP4RUM40YsGWExr+/5NFsM
+vSDRdmpkYvaJqlvJQhBEbwcP/mJZlgsW7GI+GAitZze2Uy092YG3axHW+iNqI2w8
+vlSR4wTG9YymaoCf7+hbYx5oNwnvTVxEguYuDeXXlD8xdFDREFyZTbWfgCtGJTeL
+oj3OArIKIWOCnKE1uT2eraQZPPWyOteq1LdtwpVNlEs4b7BgzyLXN2ZiHRqGwqhq
+Klbl1sPiMTSmQl152hLgoZXRFwf2zPhj+gGKJnu/uKSHjLWjWSNgZwdKTMFVvmCh
+VpJsl1P7/uvTJf0oIz44TemSkIumXiIvAh9pxvqIpVKIzGGhAgMBAAGjggEzMIIB
+LzAJBgNVHRMEAjAAMBEGCWCGSAGG+EIBAQQEAwIGQDAzBglghkgBhvhCAQ0EJhYk
+T3BlblNTTCBHZW5lcmF0ZWQgU2VydmVyIENlcnRpZmljYXRlMB0GA1UdDgQWBBR9
+TBf+WbJY/wi89Ij8o4+fyjs7XjCBmAYDVR0jBIGQMIGNgBQIxJTtIwojDdD60hPi
+PLZl51MlEKFqpGgwZjELMAkGA1UEBhMCS0cxCzAJBgNVBAgTAk5BMRAwDgYDVQQH
+EwdCSVNIS0VLMRUwEwYDVQQKEwxPcGVuVlBOLVRFU1QxITAfBgkqhkiG9w0BCQEW
+Em1lQG15aG9zdC5teWRvbWFpboIJAKTMRhOJJEBzMBMGA1UdJQQMMAoGCCsGAQUF
+BwMBMAsGA1UdDwQEAwIFoDANBgkqhkiG9w0BAQsFAAOCAgEAgi4RmfRWmK0jl3Rc
+aQB7/JqTFSCT29aDBJpsy1XNXAfWMVoAHTXrjnTNegjbzR+JjARw9zXgp8zPdiuK
+pYB7wXJOmsa3ovWcI9zXDZOjD/QQfYsdhV67LwnIZ0E4EnIUKfZtaLWKlxyhjz10
+FJXGiE9MzYsu25WwmFXXWyIf895ctHug2fJWLP+FsBZSYxErFI7Q+APSzIk1wNWj
+uewRVeAXQ5WybvLbgHPysz+d+k0kamAlJBpTEDgI1P76Bhoe08wVZMeei1Hus1Al
+YIhwRjm9efFadGc98H4iqbQu9QZFw0b+5jJA5uEA3OioQ/70ZmRPQUXV0nuroGL3
+3PAo08acIT69RJVMILSPw67u69d6EYgtPRhJXeYJuF/HJDKD3V+uAwLBtlENYqJB
+9BMSsvKawVAEY0LeQbOzq0VXnosB4MVw2XAO6oQ5BwgD6ZmxYM6pxs6kYSk2PFhS
+osMBT07B6K87ynw0nCohyUAXzowQsvzCOUNVUBktyfCrSLKG5s8eE2xq7YXp9t25
+um5waul4Q0CjyGRQH1uIDYhVD5SckkSDeQw4eQnEk2qo3POLxK+/DCB7dnsxUgFw
+Twm+ONAUzmLGADXN/Oto8UXV3mo/iz/cHMnjinzxF1Nx+K/JQ5+RWhYLOsDXsOd0
+VBLwmnFf891rwGnsnU0UYb0QIYA=
+-----END CERTIFICATE-----
diff --git a/sample/sample-keys/sample-ca/02.pem b/sample/sample-keys/sample-ca/02.pem
new file mode 100644
index 0000000..295f720
--- /dev/null
+++ b/sample/sample-keys/sample-ca/02.pem
@@ -0,0 +1,103 @@
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 2 (0x2)
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: C=KG, ST=NA, L=BISHKEK, O=OpenVPN-TEST/emailAddress=me@myhost.mydomain
+ Validity
+ Not Before: Oct 28 12:54:33 2016 GMT
+ Not After : Oct 26 12:54:33 2026 GMT
+ Subject: C=KG, ST=NA, O=OpenVPN-TEST, CN=Test-Client/emailAddress=me@myhost.mydomain
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:e5:4f:5f:c9:2c:3f:8e:1a:3e:0b:f8:7f:82:d5:
+ ca:c5:6e:94:a4:fd:98:85:c0:1d:eb:94:b5:93:5b:
+ df:c2:c0:3f:9b:8e:5e:a3:d0:91:ca:3e:f4:74:93:
+ 63:86:df:a7:ae:0d:15:28:6d:38:6e:3b:ac:c9:5c:
+ 1f:c7:f7:d5:66:64:b9:07:00:41:6d:b6:a6:1a:ee:
+ f1:bb:ce:bd:39:cc:70:1f:9b:65:d7:3c:3c:97:2e:
+ 8e:1e:31:90:7f:cc:a7:b8:d9:2f:4e:b3:4a:98:6d:
+ a0:15:04:9d:cb:e1:7a:e1:63:f4:96:7a:bb:9e:a8:
+ d8:f0:33:97:67:6d:bf:39:82:0e:a3:b7:2a:15:2d:
+ 99:2b:f8:53:b1:e8:14:0f:d9:b3:a2:4f:2a:f1:63:
+ fd:d5:72:a6:22:b9:d6:be:e4:7b:9e:c8:85:1e:06:
+ 1a:31:24:3d:f3:82:ac:d7:28:7d:a4:4f:4b:c3:fd:
+ 72:27:07:ef:9d:51:71:56:d4:a4:b6:66:d2:74:4f:
+ 97:7f:3f:90:a8:56:8b:5b:14:4a:4f:c0:3d:2d:5a:
+ 90:74:db:da:59:83:4d:dd:2b:0a:81:24:ce:19:ce:
+ 8e:56:10:0f:cd:0d:83:01:d8:75:8b:66:16:40:1b:
+ 47:af:77:1f:d7:c5:cf:0a:d7:7c:f2:7e:a0:a0:5d:
+ fa:67
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints:
+ CA:FALSE
+ X509v3 Subject Key Identifier:
+ B8:DE:77:EB:43:83:FF:95:59:BB:28:78:E4:4D:F2:E5:C7:2E:06:EF
+ X509v3 Authority Key Identifier:
+ keyid:08:C4:94:ED:23:0A:23:0D:D0:FA:D2:13:E2:3C:B6:65:E7:53:25:10
+ DirName:/C=KG/ST=NA/L=BISHKEK/O=OpenVPN-TEST/emailAddress=me@myhost.mydomain
+ serial:A4:CC:46:13:89:24:40:73
+
+ Signature Algorithm: sha256WithRSAEncryption
+ a7:24:5d:b2:2f:49:63:55:90:e0:95:0e:fa:fc:d7:d8:0c:89:
+ 01:15:90:73:39:e9:32:3a:f9:8d:4b:cd:e7:3a:32:c0:fd:bb:
+ ed:3c:d9:cf:ea:0f:f3:6e:18:18:1d:1c:9c:e2:39:e6:c0:1d:
+ 2e:54:14:ec:1b:b2:5a:fd:1a:ac:65:45:9b:d4:0d:4a:3a:53:
+ 95:8d:bd:d3:44:20:17:70:d0:79:b5:f7:2c:dd:2a:0d:bf:b3:
+ d0:a8:1f:5c:db:33:5b:5d:56:24:84:2b:c8:43:32:fc:f3:dc:
+ b5:da:dc:7f:0a:1c:2a:2f:9b:60:ca:2d:6e:fe:98:55:26:d5:
+ 62:a7:3e:f4:49:5c:a9:76:54:87:19:0b:dd:74:ff:02:f0:75:
+ 8a:36:01:cf:29:67:9b:ae:c0:e5:da:da:2b:d9:57:61:92:69:
+ 1d:e3:b2:f4:66:8e:f8:dd:11:13:4c:1d:a5:7f:37:df:4e:fd:
+ 7d:96:ba:ac:6c:39:83:89:8f:05:47:1a:4b:4f:68:38:1a:99:
+ c8:68:1a:31:b9:78:9a:f5:12:ea:23:c2:c6:83:6b:e4:e0:9a:
+ fc:70:aa:bb:ef:00:1f:c9:18:ef:48:c2:fc:ec:e8:4c:e8:92:
+ d6:64:ab:5c:b3:ac:03:da:5f:a9:92:f2:ff:ef:a7:39:6f:d6:
+ 95:fb:44:89:c7:2b:c4:c4:45:b3:49:1a:c1:23:96:0d:f4:0b:
+ 0f:75:3b:6e:2c:4c:60:be:e7:0f:63:f2:3c:f0:9c:58:af:dd:
+ 5e:41:9e:f7:3f:e0:fb:28:be:f0:02:03:01:8c:9e:c5:52:e0:
+ a4:90:e0:b2:04:1b:58:3e:13:49:87:7b:20:27:73:f4:a8:cd:
+ c2:be:c7:c0:e9:8e:2d:d0:58:4b:9e:2f:fa:94:63:b2:99:16:
+ 08:5d:a1:49:1a:3d:29:9a:34:a3:63:ef:fd:79:da:0a:3e:79:
+ b1:cd:6f:f6:11:b7:c0:e8:67:41:36:36:94:a1:09:7a:cc:b9:
+ 4b:63:47:ce:49:c8:02:f9:d9:df:49:c1:04:82:09:f8:5b:92:
+ 4b:98:af:86:5e:fe:2e:48:fe:d6:69:7b:76:a8:c5:32:f6:b0:
+ ed:7e:bf:14:65:ca:fe:fa:bb:43:33:7e:c8:f4:98:a3:f8:0b:
+ 65:85:3d:5a:ed:33:45:12:76:90:9a:ca:34:fe:5a:ae:f6:ac:
+ 4d:9d:b6:28:7f:ac:e3:43:60:9a:dd:ec:a9:21:49:44:4a:74:
+ 48:12:6b:93:3b:08:70:ac:2e:58:f7:68:eb:8e:ba:9f:41:5a:
+ f9:a9:43:46:73:7a:1f:40:74:ce:87:c9:5e:51:67:8e:a3:cc:
+ b8:ea:ac:fe:7b:d8:2b:78
+-----BEGIN CERTIFICATE-----
+MIIFFDCCAvygAwIBAgIBAjANBgkqhkiG9w0BAQsFADBmMQswCQYDVQQGEwJLRzEL
+MAkGA1UECBMCTkExEDAOBgNVBAcTB0JJU0hLRUsxFTATBgNVBAoTDE9wZW5WUE4t
+VEVTVDEhMB8GCSqGSIb3DQEJARYSbWVAbXlob3N0Lm15ZG9tYWluMB4XDTE2MTAy
+ODEyNTQzM1oXDTI2MTAyNjEyNTQzM1owajELMAkGA1UEBhMCS0cxCzAJBgNVBAgT
+Ak5BMRUwEwYDVQQKEwxPcGVuVlBOLVRFU1QxFDASBgNVBAMTC1Rlc3QtQ2xpZW50
+MSEwHwYJKoZIhvcNAQkBFhJtZUBteWhvc3QubXlkb21haW4wggEiMA0GCSqGSIb3
+DQEBAQUAA4IBDwAwggEKAoIBAQDlT1/JLD+OGj4L+H+C1crFbpSk/ZiFwB3rlLWT
+W9/CwD+bjl6j0JHKPvR0k2OG36euDRUobThuO6zJXB/H99VmZLkHAEFttqYa7vG7
+zr05zHAfm2XXPDyXLo4eMZB/zKe42S9Os0qYbaAVBJ3L4XrhY/SWerueqNjwM5dn
+bb85gg6jtyoVLZkr+FOx6BQP2bOiTyrxY/3VcqYiuda+5HueyIUeBhoxJD3zgqzX
+KH2kT0vD/XInB++dUXFW1KS2ZtJ0T5d/P5CoVotbFEpPwD0tWpB029pZg03dKwqB
+JM4Zzo5WEA/NDYMB2HWLZhZAG0evdx/Xxc8K13zyfqCgXfpnAgMBAAGjgcgwgcUw
+CQYDVR0TBAIwADAdBgNVHQ4EFgQUuN5360OD/5VZuyh45E3y5ccuBu8wgZgGA1Ud
+IwSBkDCBjYAUCMSU7SMKIw3Q+tIT4jy2ZedTJRChaqRoMGYxCzAJBgNVBAYTAktH
+MQswCQYDVQQIEwJOQTEQMA4GA1UEBxMHQklTSEtFSzEVMBMGA1UEChMMT3BlblZQ
+Ti1URVNUMSEwHwYJKoZIhvcNAQkBFhJtZUBteWhvc3QubXlkb21haW6CCQCkzEYT
+iSRAczANBgkqhkiG9w0BAQsFAAOCAgEApyRdsi9JY1WQ4JUO+vzX2AyJARWQcznp
+Mjr5jUvN5zoywP277TzZz+oP824YGB0cnOI55sAdLlQU7BuyWv0arGVFm9QNSjpT
+lY2900QgF3DQebX3LN0qDb+z0KgfXNszW11WJIQryEMy/PPctdrcfwocKi+bYMot
+bv6YVSbVYqc+9ElcqXZUhxkL3XT/AvB1ijYBzylnm67A5draK9lXYZJpHeOy9GaO
++N0RE0wdpX833079fZa6rGw5g4mPBUcaS09oOBqZyGgaMbl4mvUS6iPCxoNr5OCa
+/HCqu+8AH8kY70jC/OzoTOiS1mSrXLOsA9pfqZLy/++nOW/WlftEiccrxMRFs0ka
+wSOWDfQLD3U7bixMYL7nD2PyPPCcWK/dXkGe9z/g+yi+8AIDAYyexVLgpJDgsgQb
+WD4TSYd7ICdz9KjNwr7HwOmOLdBYS54v+pRjspkWCF2hSRo9KZo0o2Pv/XnaCj55
+sc1v9hG3wOhnQTY2lKEJesy5S2NHzknIAvnZ30nBBIIJ+FuSS5ivhl7+Lkj+1ml7
+dqjFMvaw7X6/FGXK/vq7QzN+yPSYo/gLZYU9Wu0zRRJ2kJrKNP5arvasTZ22KH+s
+40Ngmt3sqSFJREp0SBJrkzsIcKwuWPdo6466n0Fa+alDRnN6H0B0zofJXlFnjqPM
+uOqs/nvYK3g=
+-----END CERTIFICATE-----
diff --git a/sample/sample-keys/sample-ca/03.pem b/sample/sample-keys/sample-ca/03.pem
new file mode 100644
index 0000000..e4f5a82
--- /dev/null
+++ b/sample/sample-keys/sample-ca/03.pem
@@ -0,0 +1,103 @@
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 3 (0x3)
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: C=KG, ST=NA, L=BISHKEK, O=OpenVPN-TEST/emailAddress=me@myhost.mydomain
+ Validity
+ Not Before: Oct 28 12:54:33 2016 GMT
+ Not After : Oct 26 12:54:33 2026 GMT
+ Subject: C=KG, ST=NA, O=OpenVPN-TEST, CN=client-revoked/emailAddress=me@myhost.mydomain
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:c1:a8:94:78:8a:48:84:7a:54:ab:34:a5:bc:8a:
+ 81:ca:30:8b:9f:df:8f:fd:25:ca:d3:9c:6c:06:b0:
+ d4:b2:64:5a:7b:09:6e:74:23:41:0e:e5:3d:13:73:
+ d5:34:7d:f7:42:e3:65:61:e9:3f:d8:e4:be:85:79:
+ f3:d0:27:bd:8b:de:ce:34:2d:b2:b0:dc:a9:58:1a:
+ 28:95:62:33:4f:4e:05:1a:16:fe:dd:19:2c:d4:ff:
+ e9:c2:77:3d:43:77:6d:65:04:d9:fd:a1:f1:fc:a8:
+ 5b:da:44:43:90:f3:16:a4:b7:48:ee:a7:84:67:ec:
+ 01:85:22:a7:69:a7:1b:bb:4b:8f:8f:ca:61:1c:50:
+ 8b:1a:ed:2d:fb:bd:ac:25:7e:4f:16:a7:63:8b:c7:
+ 34:8d:53:c8:5e:c8:8c:e4:36:70:02:34:f7:f7:0a:
+ 58:58:57:f1:02:65:5a:00:32:e5:62:94:b3:97:b8:
+ e7:f3:75:5c:fc:a5:33:41:4c:c2:5b:fc:e6:f2:7f:
+ f7:a8:4b:db:b2:01:0c:bd:7c:28:dc:c6:83:4c:4f:
+ 43:34:db:2a:e5:38:24:52:96:43:7d:fc:b7:a2:db:
+ 9d:6a:18:89:03:cc:8c:60:22:7f:e8:95:79:14:3e:
+ ad:62:6d:00:6e:d9:b2:be:62:29:65:56:e3:41:3b:
+ 6b:37
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints:
+ CA:FALSE
+ X509v3 Subject Key Identifier:
+ C9:DD:AB:FE:FA:1E:B1:21:9E:93:E4:21:3E:36:9A:1B:A2:85:0D:1F
+ X509v3 Authority Key Identifier:
+ keyid:08:C4:94:ED:23:0A:23:0D:D0:FA:D2:13:E2:3C:B6:65:E7:53:25:10
+ DirName:/C=KG/ST=NA/L=BISHKEK/O=OpenVPN-TEST/emailAddress=me@myhost.mydomain
+ serial:A4:CC:46:13:89:24:40:73
+
+ Signature Algorithm: sha256WithRSAEncryption
+ 6c:e6:8b:2e:58:5e:60:77:bf:b8:9a:88:8c:c9:bd:40:66:cb:
+ c0:d4:5b:21:00:bc:d8:24:39:04:57:ee:9c:65:d1:03:1f:70:
+ e6:5d:e2:ef:08:5c:31:d1:8b:c0:44:30:96:e0:a1:e8:0f:d1:
+ 0e:95:9a:2f:02:6b:06:d6:8c:4d:0a:1f:b8:7b:d9:98:ca:79:
+ f9:30:4d:88:8f:c8:36:6a:4d:b0:f6:df:cf:ac:a3:67:40:e9:
+ 54:4f:61:73:b6:16:9b:e1:35:fe:f3:a4:9b:17:df:e5:bb:a8:
+ f6:63:91:10:c5:b0:5a:00:6e:00:d8:77:f3:35:6b:f4:db:0e:
+ ef:b6:93:6e:41:65:7d:66:82:2d:04:83:d9:d1:fc:ed:26:1c:
+ 04:61:9c:1d:30:dd:8a:e4:9f:0d:81:0d:57:eb:d2:64:f5:42:
+ 69:a1:e4:20:af:0a:20:6b:87:22:85:82:f3:53:19:bd:8f:24:
+ dd:48:bd:98:71:e9:9a:97:15:c4:f5:e5:56:f5:61:f4:3b:1b:
+ 06:e9:8e:cb:00:2f:c4:4e:43:82:f8:a9:c4:9c:ba:96:0a:c7:
+ bf:89:f1:3a:0c:43:aa:3f:96:2e:a3:a7:1d:ef:3c:a1:52:10:
+ dc:d0:c7:19:94:77:75:25:fa:d7:d4:35:ee:54:d3:32:7d:b5:
+ 80:cf:5e:ed:b0:f6:1f:e5:8b:b4:8b:3d:f2:31:74:1f:ef:e5:
+ bb:50:de:5f:24:6e:c7:e0:f2:31:88:9f:25:11:8e:a9:f4:58:
+ 8b:88:e2:5a:34:75:ba:f4:91:b8:80:4c:e3:59:e6:47:e6:3b:
+ 00:c1:30:cd:c1:65:dc:18:e7:f9:d3:af:6f:46:e0:e3:3e:5d:
+ 79:b8:08:19:a4:ac:dc:2b:ad:d3:32:a3:7d:e8:c7:64:4f:92:
+ 83:a4:b8:a3:f2:01:f3:3a:5c:64:0f:13:27:e4:b6:b2:e7:4b:
+ a4:d6:8d:b3:18:ec:3e:2d:17:6a:cc:70:4e:a5:69:f8:f1:5c:
+ 09:b4:18:25:e7:fe:e3:33:dd:a6:82:6d:ed:6a:01:33:45:24:
+ f5:7e:5f:96:59:6d:ea:79:e4:b2:d4:5c:11:68:91:76:1d:19:
+ c9:13:15:44:32:f6:5e:75:72:4e:5f:30:59:e8:05:81:be:3c:
+ 19:41:36:c0:e9:f5:9b:4d:19:8e:b2:72:dc:63:bf:37:05:ac:
+ 88:0a:1f:8c:19:71:2e:24:b7:ad:7a:14:a4:1b:82:26:6d:ed:
+ bd:ba:80:55:b4:09:b3:75:68:38:8b:db:f8:55:27:72:76:85:
+ 2d:9e:db:18:be:ba:c8:d3:93:0d:f5:c9:8f:34:a8:8e:a8:92:
+ 53:ec:5a:a2:cd:16:48:9d
+-----BEGIN CERTIFICATE-----
+MIIFFzCCAv+gAwIBAgIBAzANBgkqhkiG9w0BAQsFADBmMQswCQYDVQQGEwJLRzEL
+MAkGA1UECBMCTkExEDAOBgNVBAcTB0JJU0hLRUsxFTATBgNVBAoTDE9wZW5WUE4t
+VEVTVDEhMB8GCSqGSIb3DQEJARYSbWVAbXlob3N0Lm15ZG9tYWluMB4XDTE2MTAy
+ODEyNTQzM1oXDTI2MTAyNjEyNTQzM1owbTELMAkGA1UEBhMCS0cxCzAJBgNVBAgT
+Ak5BMRUwEwYDVQQKEwxPcGVuVlBOLVRFU1QxFzAVBgNVBAMTDmNsaWVudC1yZXZv
+a2VkMSEwHwYJKoZIhvcNAQkBFhJtZUBteWhvc3QubXlkb21haW4wggEiMA0GCSqG
+SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDBqJR4ikiEelSrNKW8ioHKMIuf34/9JcrT
+nGwGsNSyZFp7CW50I0EO5T0Tc9U0ffdC42Vh6T/Y5L6FefPQJ72L3s40LbKw3KlY
+GiiVYjNPTgUaFv7dGSzU/+nCdz1Dd21lBNn9ofH8qFvaREOQ8xakt0jup4Rn7AGF
+Iqdppxu7S4+PymEcUIsa7S37vawlfk8Wp2OLxzSNU8heyIzkNnACNPf3ClhYV/EC
+ZVoAMuVilLOXuOfzdVz8pTNBTMJb/Obyf/eoS9uyAQy9fCjcxoNMT0M02yrlOCRS
+lkN9/Lei251qGIkDzIxgIn/olXkUPq1ibQBu2bK+YillVuNBO2s3AgMBAAGjgcgw
+gcUwCQYDVR0TBAIwADAdBgNVHQ4EFgQUyd2r/voesSGek+QhPjaaG6KFDR8wgZgG
+A1UdIwSBkDCBjYAUCMSU7SMKIw3Q+tIT4jy2ZedTJRChaqRoMGYxCzAJBgNVBAYT
+AktHMQswCQYDVQQIEwJOQTEQMA4GA1UEBxMHQklTSEtFSzEVMBMGA1UEChMMT3Bl
+blZQTi1URVNUMSEwHwYJKoZIhvcNAQkBFhJtZUBteWhvc3QubXlkb21haW6CCQCk
+zEYTiSRAczANBgkqhkiG9w0BAQsFAAOCAgEAbOaLLlheYHe/uJqIjMm9QGbLwNRb
+IQC82CQ5BFfunGXRAx9w5l3i7whcMdGLwEQwluCh6A/RDpWaLwJrBtaMTQofuHvZ
+mMp5+TBNiI/INmpNsPbfz6yjZ0DpVE9hc7YWm+E1/vOkmxff5buo9mOREMWwWgBu
+ANh38zVr9NsO77aTbkFlfWaCLQSD2dH87SYcBGGcHTDdiuSfDYENV+vSZPVCaaHk
+IK8KIGuHIoWC81MZvY8k3Ui9mHHpmpcVxPXlVvVh9DsbBumOywAvxE5DgvipxJy6
+lgrHv4nxOgxDqj+WLqOnHe88oVIQ3NDHGZR3dSX619Q17lTTMn21gM9e7bD2H+WL
+tIs98jF0H+/lu1DeXyRux+DyMYifJRGOqfRYi4jiWjR1uvSRuIBM41nmR+Y7AMEw
+zcFl3Bjn+dOvb0bg4z5debgIGaSs3Cut0zKjfejHZE+Sg6S4o/IB8zpcZA8TJ+S2
+sudLpNaNsxjsPi0XasxwTqVp+PFcCbQYJef+4zPdpoJt7WoBM0Uk9X5flllt6nnk
+stRcEWiRdh0ZyRMVRDL2XnVyTl8wWegFgb48GUE2wOn1m00ZjrJy3GO/NwWsiAof
+jBlxLiS3rXoUpBuCJm3tvbqAVbQJs3VoOIvb+FUncnaFLZ7bGL66yNOTDfXJjzSo
+jqiSU+xaos0WSJ0=
+-----END CERTIFICATE-----
diff --git a/sample/sample-keys/sample-ca/ca.crl b/sample/sample-keys/sample-ca/ca.crl
new file mode 100644
index 0000000..7ad9d35
--- /dev/null
+++ b/sample/sample-keys/sample-ca/ca.crl
@@ -0,0 +1,21 @@
+-----BEGIN X509 CRL-----
+MIIDZzCCAU8CAQEwDQYJKoZIhvcNAQELBQAwZjELMAkGA1UEBhMCS0cxCzAJBgNV
+BAgTAk5BMRAwDgYDVQQHEwdCSVNIS0VLMRUwEwYDVQQKEwxPcGVuVlBOLVRFU1Qx
+ITAfBgkqhkiG9w0BCQEWEm1lQG15aG9zdC5teWRvbWFpbhcNMTYxMDI4MTI1NDMz
+WhcNMTYxMTI3MTI1NDMzWjAUMBICAQMXDTE2MTAyODEyNTQzM1qggZ4wgZswgZgG
+A1UdIwSBkDCBjYAUCMSU7SMKIw3Q+tIT4jy2ZedTJRChaqRoMGYxCzAJBgNVBAYT
+AktHMQswCQYDVQQIEwJOQTEQMA4GA1UEBxMHQklTSEtFSzEVMBMGA1UEChMMT3Bl
+blZQTi1URVNUMSEwHwYJKoZIhvcNAQkBFhJtZUBteWhvc3QubXlkb21haW6CCQCk
+zEYTiSRAczANBgkqhkiG9w0BAQsFAAOCAgEA8GGYfeiPmEidbPxLFQDIIvnz4QEa
+9mKuB5VFa0l2yNlyMYoN2uXV2bqIzuQ94mnzc5xsMLVRkiSX4lq7HZY3VyTo57Ps
+dpRGKsVOM5rsWgDFycAT4+9OuZMnpntKzmbAlYvaKwnvpQj0xuXP5l1QJSANrtAK
+c/EQ2EmEwrHtcE4HEwOeMzC5ON5EceneLqMg+JTkZURoBW7e9Hk0MJh8HDewRcN0
+0D/+e7/ZuRFt68XDfDhjbXPQVv4vbPKR9OXaXClwJgw+LYvhGe+0s4Lumhb4sP6Z
+oOTjGCXxQOtZJEC1vCb0cahFkuYJu6fCOh0crspGNt0wTgDKp7LXbEJhwv+6wQ6k
+zu+4a6ES8wj2DwXqQaV5txG55S1Q5PMLCw7L7VDrKJr2DXi4PKdToj5b35aS1DU/
+q6JjcxiuzjN7sHfC7elQIudaVEuE2XkpxaQPNdKC4xKLvck7zZMqGUWOwuI1mqya
+WGBfgrkeAllq4cWEF5SWR8iFREo2FBs3CxETgrkWGWWRgu3UsrLC9AXVHntud21e
+dXwTCIbiYZ2Vv7iYI06W+pOwdeQNc6X/sg2QFpWMLLblYlhPy6yu/3zg7TKilDfS
+tu0hmTrsgRKciB5lKWZAuylGUGIGLrmG+LzOq2b9j5yhS9WA5qL83fMVrCoyB3W+
+ISfJElodA9n+UM8=
+-----END X509 CRL-----
diff --git a/sample/sample-keys/sample-ca/ca.crt b/sample/sample-keys/sample-ca/ca.crt
new file mode 100644
index 0000000..2775ca2
--- /dev/null
+++ b/sample/sample-keys/sample-ca/ca.crt
@@ -0,0 +1,35 @@
+-----BEGIN CERTIFICATE-----
+MIIGKDCCBBCgAwIBAgIJAKTMRhOJJEBzMA0GCSqGSIb3DQEBCwUAMGYxCzAJBgNV
+BAYTAktHMQswCQYDVQQIEwJOQTEQMA4GA1UEBxMHQklTSEtFSzEVMBMGA1UEChMM
+T3BlblZQTi1URVNUMSEwHwYJKoZIhvcNAQkBFhJtZUBteWhvc3QubXlkb21haW4w
+HhcNMTYxMDI4MTI1NDMyWhcNMjYxMDI2MTI1NDMyWjBmMQswCQYDVQQGEwJLRzEL
+MAkGA1UECBMCTkExEDAOBgNVBAcTB0JJU0hLRUsxFTATBgNVBAoTDE9wZW5WUE4t
+VEVTVDEhMB8GCSqGSIb3DQEJARYSbWVAbXlob3N0Lm15ZG9tYWluMIICIjANBgkq
+hkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA9EOM8PfRM8VrxwyesCSodTSlBcuyUJ43
+hVW9XBfOJP/PPVv3vgJKCyu/2B5XlP3L2NqJ/TesFGAN9ZBX+fzYJIzNxa6yUjaZ
+HuAXRA7IxlKvO+l92Pl4RazpYELuKiS54RBhhChmxfRo2xEx2cPghFtJWNK2IAcH
+4mKLUYIWGEKhpT/bMqazqlHDGmPkD4HfeLNwTNFDrNi4N5iF1bbfUjwNJF1PGCOz
+o1Ka54TF9KTrTf1Ii8bM5ttUtjsTh0zyxOc/N5yw4Is9VEDIuvndrBDgq+yxLZjO
+13KY+oO5M4uTf4QmM6yPFn4ZyZ23oW3CNF4ytVnfhR5W4rFeHtibbOjOwXBQ+NRw
+jatZqVRpE1gwFR0Z7767cc2OosupM3YR/pTflXAyThVtU5uM1rMxuyedpNWPN5QN
+5qhwyu1qVq1Y2mIWHS8rkN+6Zek4TZ9W05paR8zpjJ1Z8pbtjIFu1RM77cnLoOAT
+KpoyO6avqo3vIDRHoYdoj044ff/0JAOyj049vcdd06KWLPsmNj4FzCyVUQOHR+LA
+6plBJgGf3vyaZfs1ZwwcA/WQHtf1ztrkDPVUWaXixeipsg8CWZb4eIuYbzloc6Ot
+b22wQ7C0cDO5pUjNGJZLYYDX0zIO9rwZSPGQ/gthlwQXg8zrM4MASLLw0hqZ45c0
+ems4nt0QDi8CAwEAAaOB2DCB1TAdBgNVHQ4EFgQUCMSU7SMKIw3Q+tIT4jy2ZedT
+JRAwgZgGA1UdIwSBkDCBjYAUCMSU7SMKIw3Q+tIT4jy2ZedTJRChaqRoMGYxCzAJ
+BgNVBAYTAktHMQswCQYDVQQIEwJOQTEQMA4GA1UEBxMHQklTSEtFSzEVMBMGA1UE
+ChMMT3BlblZQTi1URVNUMSEwHwYJKoZIhvcNAQkBFhJtZUBteWhvc3QubXlkb21h
+aW6CCQCkzEYTiSRAczAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIBBjANBgkqhkiG
+9w0BAQsFAAOCAgEAmavYB0InmvVooI0Ukm9x8qF3ql0LDKwfm1T79aUybOUxscId
+MT26djkAln0abo4mYXPaMYISVTrNNrBMX80Y+aa4DfXW392mKqrPf1L3fVD6jsoi
+5kofqdiojSJs0uHfy+A32XVPrIzTeV3lvE/yDfKDBNb9f+3U8UIyIARXryYm4H6z
+mCqUgocMAB1hFu8Lpf8eeGxrCfsD6yR6PMO8YNGdBfinbhXjfzCFD1ZJ+JxPePww
+ydtL+Z0/dZvVzVehxdHCe8+vdpAjoI/YJk5UPSlAVGooaR+kH6BPbL/7QoVFUBxO
+mDMnTpNFt5GLM5pMExZo2Ef89D9dsXDa9lgv4KTxfbF/Xn5ODQ5rW5i0i+p6REZs
+FND1M0H/0DC14fhTdb8llpJzK0ZAwSf59SaUgrooVMCWzN2Xl4+zVCUik4gvjs6A
+AHXdqL6dHEIG41+BAJHHoS0kkbvw03td1SbktKtbgaDWW7CkGcNhBmkMB7HZiVoW
+yMV8X0WQoEntZfEq+kNePx68D51VR3htiOhBrO88rOXZAAJBoeke8K/CbLRm3av7
+LHM5Q2Ki821yjFpGFGgvMJBt3xvFajG5DwWLsGNXrlGA781UXdZBwmsvg8Z+iIMu
+9+sidZJU68slPre6hQcFPAO4c21csr6yV7LVyOS1We6akeseYAR90fGNrI4=
+-----END CERTIFICATE-----
diff --git a/sample/sample-keys/sample-ca/ca.key b/sample/sample-keys/sample-ca/ca.key
new file mode 100644
index 0000000..29e7d2d
--- /dev/null
+++ b/sample/sample-keys/sample-ca/ca.key
@@ -0,0 +1,52 @@
+-----BEGIN PRIVATE KEY-----
+MIIJRAIBADANBgkqhkiG9w0BAQEFAASCCS4wggkqAgEAAoICAQD0Q4zw99EzxWvH
+DJ6wJKh1NKUFy7JQnjeFVb1cF84k/889W/e+AkoLK7/YHleU/cvY2on9N6wUYA31
+kFf5/NgkjM3FrrJSNpke4BdEDsjGUq876X3Y+XhFrOlgQu4qJLnhEGGEKGbF9Gjb
+ETHZw+CEW0lY0rYgBwfiYotRghYYQqGlP9syprOqUcMaY+QPgd94s3BM0UOs2Lg3
+mIXVtt9SPA0kXU8YI7OjUprnhMX0pOtN/UiLxszm21S2OxOHTPLE5z83nLDgiz1U
+QMi6+d2sEOCr7LEtmM7Xcpj6g7kzi5N/hCYzrI8WfhnJnbehbcI0XjK1Wd+FHlbi
+sV4e2Jts6M7BcFD41HCNq1mpVGkTWDAVHRnvvrtxzY6iy6kzdhH+lN+VcDJOFW1T
+m4zWszG7J52k1Y83lA3mqHDK7WpWrVjaYhYdLyuQ37pl6ThNn1bTmlpHzOmMnVny
+lu2MgW7VEzvtycug4BMqmjI7pq+qje8gNEehh2iPTjh9//QkA7KPTj29x13TopYs
++yY2PgXMLJVRA4dH4sDqmUEmAZ/e/Jpl+zVnDBwD9ZAe1/XO2uQM9VRZpeLF6Kmy
+DwJZlvh4i5hvOWhzo61vbbBDsLRwM7mlSM0YlkthgNfTMg72vBlI8ZD+C2GXBBeD
+zOszgwBIsvDSGpnjlzR6azie3RAOLwIDAQABAoICAQCUZC1Nft/i+b6eMDZ/f+Wv
+Poo6WSM9AsFsCUh+mB+uLpIyDpsVHcLpwmxL2TMP2pdqaGmIIbgysKAKXOR1hHuy
+yK+Btr2yYGTpcu3vdKPYiAbY+OJxXC0K9x7YUhDqHWGnLxJu/TRicjb5Txrf1rWg
+8uw+P9RQ5LSPfZpxq/vMRT56a664uLlRcVZ7w8+a9CVU6H4CzOa2LPrNG6XCzdQh
+20WIn/8bBSVuxRJCMFEqbL5epM7by6xTW0+9XWphugeKQ4oOOOzjnPNnKexIWt+m
+VqKHD8Ybk0elb4MsPbXXcKXsw9WJcv2Chp0X9O7H7SwcMFXSAoVeE65pDaPGTYUt
+luwtsw+82zYtorqtiRc6YV7DutokHaCHME3C7x9o1kyGFnuCFY6JlDlLS7fgEPhZ
+19p5eIcieJ4GQfmASVxGWB0C1AKQHWqeSlr7DF5OEPy5+9a9JjO6pfh/kcfC5WWI
+6vllb+ISrd+XcXTPL/sSKDEb5EFZ4MsBhVXYWMmqKDuyaCuyWy3BiQuz2vEI0tXY
+YZF9Y+/HM61Jy2363ittxC455fYdpB9tVqOKDIYiXDctoaQDkbIfZMzCiozj9zi8
+H4o87i1EmBlyKNWzd3aiuxs581vboG8aCE5HmvYr+pFDfwvf8O4OYJZGehErwZz0
+K74E1IW79Mlec4UBl/HxEQKCAQEA/aj5MBoiXVF3aPxJDpCn67ZsjIDsFlyHyMrf
+qDJIMHhplTI+LAcaJYu4Dj6fsj3ATHUIWjvP/T86Lf2E6qy0ZEmr3KaIskeGgh6e
+YyJXGXH88BKOWgqaE/EEYPXKs1fdZTVfmpFGjoZ0ifJzJ50qJhSeM3jJGeOJdebL
+O0XxsG5blpicwZcyLLQTAETH4a00TXgdqbL1BeALL/Pay5ErZKLw+txOFpDnKsu0
+D2XCHhRMk2ZqpjS6IUnWqUIA4/cn/H+vKTkxEMCNFkB3yLcPE/Hd/SAL9viDO2DY
+jn+b0CObtapEA/eqEXkaBGvCrNNtcg6l1D3yzS8dl2K9qxsq3QKCAQEA9oRjRInp
+nszUijKTs14Ml3vgSe8XcAPV9v+kcwnrbZXMe3fXKbma3/SKU4GNdGfXacWRxqRJ
+TkzziqRvT5MOmdlEdBeHN3gIbjCBvOKzdrbYfNQ5Zcy4ODFhD1QSvLaer8xZbOTR
+lKZ8kszZ3Wj7m3byXQE3ZYCVjRFS/07mP1Jh2/KUhg059a0JQhReydE12FZ40r4Y
+OcL21ldzfLHDod5kjW7LZnIQpuiTD1eDLI2j59qIgg3yh3KIn5Xkmaq1SbqGAuzF
+Gt2x73qfXYB/I/xeR1s3UKSM+bs9S85f/yAqQUSSNbjP4WU0u/zMmV6Ze+VYe7yN
+nGyoS8GuwL3uewKCAQB5aM8cfuXD1KJa1aYCGqrE32PFPE/DxDYZnUC/uJFk4b1n
+c8zeNegF4IIQD1lQbs4DymBdEBPVGtY1/QoJaPBOsBRaYDs9WY6/6PfWazFVNIHk
+Rn1sC3cD5HA8GGkUvhFxx8IisTYcMa7F+A22ADuUTnoKGN3oTkgU7oqHrEqqL6gW
+xKUC4+NYEjimAEXLdqN6EOvhtY4hacLxCL7IgItMd9DvwVJ+6ow6p5VfaU0oKH8e
+bf7N3p7YIAdmq/jRJBM3f8XO7VjWs9LTu7eZkkTdPv8JkLUpWHk3insceWeSj/iP
+UxeK7pewFU6mnw1muyu/U9N7assz+kEnnFM7+pzhAoIBAQCL3hF0kcs7jnwI7Slg
+W7xJNr/LMxzZMVP1EJb9rmMlihi69QPfaK+24ciaGKdppIFUQgSz8AKnqoGD6Eg/
+nfBq2hs8wxy1HCWsX1k9EmNAt/2c1cy7NaxQNbQcPldjOzpOBGO4pRtEfDGyGQiD
+10zqqFJa8pW7wXkY0PuGX/3Db7qWUMx0QozgF41pMKWXXFxwop9q8vBL1ZK3ima8
+GSAmd0gV9wbw2UcZbFwEGGMUpEibBCLvp3oz34glA6bwiSrS6kGe5zfuRlruxWQm
+aQG6KTZUxixcVQCnsNTWbgGJf3Z6Ea3jTTilagbBom1zl3j+EuJhUloGpp/WW84L
+DbiBAoIBAQDo0UOrrWHBmqOg5A9Z7Vub/Oi1Wdfhla4huaTn534Ml63NXpXkYts6
+sYGyyuSdWh0f1bLusWCs5COT5fZFVNvH59/6a7TVlKr/5B9jGNh9+LdP6Qpttd0B
+Xfs7X2u/HiCUgDPj1cVOc9kQuOc+vw9t0WHdsVm+kCutjDd63LItIMbn4Vj9kxJq
+wJiC+x/5Jpw8VjLQ0aPUosU9ZLV2L0g7XgdUPAJbkrb2HGaoxS9uh0bSnOFw9DQh
+eFWCG9EAmyDBh975q8e9kmAOPCVUP2sdOSKgGC5FzSOwRdwkjHI8wa1F3NnxH4rC
+Kt9XP5gPhxALZWWSk4h9gCJDmsl5dMJc
+-----END PRIVATE KEY-----
diff --git a/sample/sample-keys/sample-ca/client-pass.key b/sample/sample-keys/sample-ca/client-pass.key
new file mode 100644
index 0000000..14be4dc
--- /dev/null
+++ b/sample/sample-keys/sample-ca/client-pass.key
@@ -0,0 +1,30 @@
+-----BEGIN RSA PRIVATE KEY-----
+Proc-Type: 4,ENCRYPTED
+DEK-Info: AES-256-CBC,78F6C09B62F40C57290E71382D07BF4D
+
+McT4Z3IZnCc//AXZGGPviFDPorHDv91H3zQcoMtbNzjGnJSMmfXxuQpUcDgOZln9
+dgKchPjPX8/X3X0tEnPVwZP8OjT5gVHhlDxiMP35FummwUNqE9srmGnApQky687b
+Y3bGuhdqAPPtn86rxXCZiKBLzlDXL//6yOd80jDBMTJJB0/tpIdCtxSRqu3uAv73
+TbphSe9TTl77nifGZpDlSba8l9T+jSn7QnLDO0HauNeuMW9NJysqI6QwmRPlcELi
+RAAAEt6ncd6H+a2KmzXJ8exRrLkKyAEbzMCUxtUQ7cADDUoKJKNnkza1yGdMacZc
+IM16AzTJZQU7qS4H6058VOW5NmzWU+rmyz/2OftuRwgiuXaZWYc2TtgA/mHdTOHu
+wpDkWefmDZz2yLzvvJDoaGHHS12R60UP/XSiIVayRBYOZBFxchXnfcvvHRfWP3Az
+NILFUBLjVQTwb0N99s+VLJlr7WM9f12uM7SC6i+f1nPiGToSQw/1UP7XCYGi3ORA
+2U3e1VrzaxwccR9tjwE4j7T/mYV/XU9W5Nk2FtFk3DT0iNe0jxdBfD9aEpa+Pnq4
+c5SeAyXEfF0+50VJ6RM/SKmU8tya1P6gLaHdcjLVa9b2j4X4iYrbkkZJ8ew7pmJu
+2Natn8bcvYRIcS8rherrX9DZGM1Z3lwBWG1xrvoumdBlbxNS+ea0UeYtvm9QUpOK
+0kMBiiiAkO9gG6fE55DZuIKHdssKsxpXnoM+JgZf2xI+aqOaXWG0SWyaamzuCHdl
+cchA3YI7QXDZDMvByR2MMjpqGh/tAEpPGAsZA1TC8QyqhmiWc+9uuXpsIOGNwSse
+4jVS2B2rxu9oRKQDjEh+qS/1Fr10WgWAZfnF0jZi2c+yJng1KgJ8UzlFKICvbHxp
+nDlmqDazhIYtYlYzyjac2wHuNRBAPU2MELgnudIW2L9pIcEiyG7L7vxGtBiCPmfb
+1mTw00NYXy1G5ZvDo58jdQeM3L9YekM8LMJY11AMSPJFzcmAUL8X/Zc3YBcljTRR
+ZgnkVXkeHB21lj+BRyCBVowoAW9jDWz5u/pzIbLKpfBr+CuzQ53mjEFgmSrB/jro
+mTvtz5hmm1IeJXGxPbemLCgiMzFp32aFMIF+R2op0wxDaZo8J5e7gIVIX0VowEh9
+ohukxyl3h3sOIYXMme8EN7PYv9BDdzHt2Eah5ICcmJ8VWPBItztgnHYqDN+igMMG
+dW8RtAtcvc+a71v4MqOE98pFtAx/lPeu5+DgVjWwSB9uaN5Ik5NE6aRd2M0QrR+f
+D+5s8LsjA6UKP1qVrmykNpt7JVy49TSLWpiEQZNBHSJkcc39yjU8dLt2cdDPUZGp
+Iycv7WsOyZcJAdtIGiZuoO2qxFgSBXm+mWIvLmkomwVrdS4MFlOgtehlQkZzXw5x
+0UxgG5XYI3zVa0oILR9ooPM+nDXtnE1ePN3NgNanemi6/2cJZc1eJyDCpH2iMHQY
+O3GwCyuJcGvHXqypB1jENVOQ/VLC9M8z6Td//V/xmF/nPtuRL2xg8nUPpzJbfWti
+ehUZ09cewyyN/W86MZdA9TdzzT/i1YvvZEb+2c2joD1MwqPp6TNw2Y/Hj786td0L
+-----END RSA PRIVATE KEY-----
diff --git a/sample/sample-keys/sample-ca/client-revoked.crt b/sample/sample-keys/sample-ca/client-revoked.crt
new file mode 100644
index 0000000..e4f5a82
--- /dev/null
+++ b/sample/sample-keys/sample-ca/client-revoked.crt
@@ -0,0 +1,103 @@
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 3 (0x3)
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: C=KG, ST=NA, L=BISHKEK, O=OpenVPN-TEST/emailAddress=me@myhost.mydomain
+ Validity
+ Not Before: Oct 28 12:54:33 2016 GMT
+ Not After : Oct 26 12:54:33 2026 GMT
+ Subject: C=KG, ST=NA, O=OpenVPN-TEST, CN=client-revoked/emailAddress=me@myhost.mydomain
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:c1:a8:94:78:8a:48:84:7a:54:ab:34:a5:bc:8a:
+ 81:ca:30:8b:9f:df:8f:fd:25:ca:d3:9c:6c:06:b0:
+ d4:b2:64:5a:7b:09:6e:74:23:41:0e:e5:3d:13:73:
+ d5:34:7d:f7:42:e3:65:61:e9:3f:d8:e4:be:85:79:
+ f3:d0:27:bd:8b:de:ce:34:2d:b2:b0:dc:a9:58:1a:
+ 28:95:62:33:4f:4e:05:1a:16:fe:dd:19:2c:d4:ff:
+ e9:c2:77:3d:43:77:6d:65:04:d9:fd:a1:f1:fc:a8:
+ 5b:da:44:43:90:f3:16:a4:b7:48:ee:a7:84:67:ec:
+ 01:85:22:a7:69:a7:1b:bb:4b:8f:8f:ca:61:1c:50:
+ 8b:1a:ed:2d:fb:bd:ac:25:7e:4f:16:a7:63:8b:c7:
+ 34:8d:53:c8:5e:c8:8c:e4:36:70:02:34:f7:f7:0a:
+ 58:58:57:f1:02:65:5a:00:32:e5:62:94:b3:97:b8:
+ e7:f3:75:5c:fc:a5:33:41:4c:c2:5b:fc:e6:f2:7f:
+ f7:a8:4b:db:b2:01:0c:bd:7c:28:dc:c6:83:4c:4f:
+ 43:34:db:2a:e5:38:24:52:96:43:7d:fc:b7:a2:db:
+ 9d:6a:18:89:03:cc:8c:60:22:7f:e8:95:79:14:3e:
+ ad:62:6d:00:6e:d9:b2:be:62:29:65:56:e3:41:3b:
+ 6b:37
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints:
+ CA:FALSE
+ X509v3 Subject Key Identifier:
+ C9:DD:AB:FE:FA:1E:B1:21:9E:93:E4:21:3E:36:9A:1B:A2:85:0D:1F
+ X509v3 Authority Key Identifier:
+ keyid:08:C4:94:ED:23:0A:23:0D:D0:FA:D2:13:E2:3C:B6:65:E7:53:25:10
+ DirName:/C=KG/ST=NA/L=BISHKEK/O=OpenVPN-TEST/emailAddress=me@myhost.mydomain
+ serial:A4:CC:46:13:89:24:40:73
+
+ Signature Algorithm: sha256WithRSAEncryption
+ 6c:e6:8b:2e:58:5e:60:77:bf:b8:9a:88:8c:c9:bd:40:66:cb:
+ c0:d4:5b:21:00:bc:d8:24:39:04:57:ee:9c:65:d1:03:1f:70:
+ e6:5d:e2:ef:08:5c:31:d1:8b:c0:44:30:96:e0:a1:e8:0f:d1:
+ 0e:95:9a:2f:02:6b:06:d6:8c:4d:0a:1f:b8:7b:d9:98:ca:79:
+ f9:30:4d:88:8f:c8:36:6a:4d:b0:f6:df:cf:ac:a3:67:40:e9:
+ 54:4f:61:73:b6:16:9b:e1:35:fe:f3:a4:9b:17:df:e5:bb:a8:
+ f6:63:91:10:c5:b0:5a:00:6e:00:d8:77:f3:35:6b:f4:db:0e:
+ ef:b6:93:6e:41:65:7d:66:82:2d:04:83:d9:d1:fc:ed:26:1c:
+ 04:61:9c:1d:30:dd:8a:e4:9f:0d:81:0d:57:eb:d2:64:f5:42:
+ 69:a1:e4:20:af:0a:20:6b:87:22:85:82:f3:53:19:bd:8f:24:
+ dd:48:bd:98:71:e9:9a:97:15:c4:f5:e5:56:f5:61:f4:3b:1b:
+ 06:e9:8e:cb:00:2f:c4:4e:43:82:f8:a9:c4:9c:ba:96:0a:c7:
+ bf:89:f1:3a:0c:43:aa:3f:96:2e:a3:a7:1d:ef:3c:a1:52:10:
+ dc:d0:c7:19:94:77:75:25:fa:d7:d4:35:ee:54:d3:32:7d:b5:
+ 80:cf:5e:ed:b0:f6:1f:e5:8b:b4:8b:3d:f2:31:74:1f:ef:e5:
+ bb:50:de:5f:24:6e:c7:e0:f2:31:88:9f:25:11:8e:a9:f4:58:
+ 8b:88:e2:5a:34:75:ba:f4:91:b8:80:4c:e3:59:e6:47:e6:3b:
+ 00:c1:30:cd:c1:65:dc:18:e7:f9:d3:af:6f:46:e0:e3:3e:5d:
+ 79:b8:08:19:a4:ac:dc:2b:ad:d3:32:a3:7d:e8:c7:64:4f:92:
+ 83:a4:b8:a3:f2:01:f3:3a:5c:64:0f:13:27:e4:b6:b2:e7:4b:
+ a4:d6:8d:b3:18:ec:3e:2d:17:6a:cc:70:4e:a5:69:f8:f1:5c:
+ 09:b4:18:25:e7:fe:e3:33:dd:a6:82:6d:ed:6a:01:33:45:24:
+ f5:7e:5f:96:59:6d:ea:79:e4:b2:d4:5c:11:68:91:76:1d:19:
+ c9:13:15:44:32:f6:5e:75:72:4e:5f:30:59:e8:05:81:be:3c:
+ 19:41:36:c0:e9:f5:9b:4d:19:8e:b2:72:dc:63:bf:37:05:ac:
+ 88:0a:1f:8c:19:71:2e:24:b7:ad:7a:14:a4:1b:82:26:6d:ed:
+ bd:ba:80:55:b4:09:b3:75:68:38:8b:db:f8:55:27:72:76:85:
+ 2d:9e:db:18:be:ba:c8:d3:93:0d:f5:c9:8f:34:a8:8e:a8:92:
+ 53:ec:5a:a2:cd:16:48:9d
+-----BEGIN CERTIFICATE-----
+MIIFFzCCAv+gAwIBAgIBAzANBgkqhkiG9w0BAQsFADBmMQswCQYDVQQGEwJLRzEL
+MAkGA1UECBMCTkExEDAOBgNVBAcTB0JJU0hLRUsxFTATBgNVBAoTDE9wZW5WUE4t
+VEVTVDEhMB8GCSqGSIb3DQEJARYSbWVAbXlob3N0Lm15ZG9tYWluMB4XDTE2MTAy
+ODEyNTQzM1oXDTI2MTAyNjEyNTQzM1owbTELMAkGA1UEBhMCS0cxCzAJBgNVBAgT
+Ak5BMRUwEwYDVQQKEwxPcGVuVlBOLVRFU1QxFzAVBgNVBAMTDmNsaWVudC1yZXZv
+a2VkMSEwHwYJKoZIhvcNAQkBFhJtZUBteWhvc3QubXlkb21haW4wggEiMA0GCSqG
+SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDBqJR4ikiEelSrNKW8ioHKMIuf34/9JcrT
+nGwGsNSyZFp7CW50I0EO5T0Tc9U0ffdC42Vh6T/Y5L6FefPQJ72L3s40LbKw3KlY
+GiiVYjNPTgUaFv7dGSzU/+nCdz1Dd21lBNn9ofH8qFvaREOQ8xakt0jup4Rn7AGF
+Iqdppxu7S4+PymEcUIsa7S37vawlfk8Wp2OLxzSNU8heyIzkNnACNPf3ClhYV/EC
+ZVoAMuVilLOXuOfzdVz8pTNBTMJb/Obyf/eoS9uyAQy9fCjcxoNMT0M02yrlOCRS
+lkN9/Lei251qGIkDzIxgIn/olXkUPq1ibQBu2bK+YillVuNBO2s3AgMBAAGjgcgw
+gcUwCQYDVR0TBAIwADAdBgNVHQ4EFgQUyd2r/voesSGek+QhPjaaG6KFDR8wgZgG
+A1UdIwSBkDCBjYAUCMSU7SMKIw3Q+tIT4jy2ZedTJRChaqRoMGYxCzAJBgNVBAYT
+AktHMQswCQYDVQQIEwJOQTEQMA4GA1UEBxMHQklTSEtFSzEVMBMGA1UEChMMT3Bl
+blZQTi1URVNUMSEwHwYJKoZIhvcNAQkBFhJtZUBteWhvc3QubXlkb21haW6CCQCk
+zEYTiSRAczANBgkqhkiG9w0BAQsFAAOCAgEAbOaLLlheYHe/uJqIjMm9QGbLwNRb
+IQC82CQ5BFfunGXRAx9w5l3i7whcMdGLwEQwluCh6A/RDpWaLwJrBtaMTQofuHvZ
+mMp5+TBNiI/INmpNsPbfz6yjZ0DpVE9hc7YWm+E1/vOkmxff5buo9mOREMWwWgBu
+ANh38zVr9NsO77aTbkFlfWaCLQSD2dH87SYcBGGcHTDdiuSfDYENV+vSZPVCaaHk
+IK8KIGuHIoWC81MZvY8k3Ui9mHHpmpcVxPXlVvVh9DsbBumOywAvxE5DgvipxJy6
+lgrHv4nxOgxDqj+WLqOnHe88oVIQ3NDHGZR3dSX619Q17lTTMn21gM9e7bD2H+WL
+tIs98jF0H+/lu1DeXyRux+DyMYifJRGOqfRYi4jiWjR1uvSRuIBM41nmR+Y7AMEw
+zcFl3Bjn+dOvb0bg4z5debgIGaSs3Cut0zKjfejHZE+Sg6S4o/IB8zpcZA8TJ+S2
+sudLpNaNsxjsPi0XasxwTqVp+PFcCbQYJef+4zPdpoJt7WoBM0Uk9X5flllt6nnk
+stRcEWiRdh0ZyRMVRDL2XnVyTl8wWegFgb48GUE2wOn1m00ZjrJy3GO/NwWsiAof
+jBlxLiS3rXoUpBuCJm3tvbqAVbQJs3VoOIvb+FUncnaFLZ7bGL66yNOTDfXJjzSo
+jqiSU+xaos0WSJ0=
+-----END CERTIFICATE-----
diff --git a/sample/sample-keys/sample-ca/client-revoked.csr b/sample/sample-keys/sample-ca/client-revoked.csr
new file mode 100644
index 0000000..83f39c2
--- /dev/null
+++ b/sample/sample-keys/sample-ca/client-revoked.csr
@@ -0,0 +1,17 @@
+-----BEGIN CERTIFICATE REQUEST-----
+MIICsjCCAZoCAQAwbTELMAkGA1UEBhMCS0cxCzAJBgNVBAgTAk5BMRUwEwYDVQQK
+EwxPcGVuVlBOLVRFU1QxFzAVBgNVBAMTDmNsaWVudC1yZXZva2VkMSEwHwYJKoZI
+hvcNAQkBFhJtZUBteWhvc3QubXlkb21haW4wggEiMA0GCSqGSIb3DQEBAQUAA4IB
+DwAwggEKAoIBAQDBqJR4ikiEelSrNKW8ioHKMIuf34/9JcrTnGwGsNSyZFp7CW50
+I0EO5T0Tc9U0ffdC42Vh6T/Y5L6FefPQJ72L3s40LbKw3KlYGiiVYjNPTgUaFv7d
+GSzU/+nCdz1Dd21lBNn9ofH8qFvaREOQ8xakt0jup4Rn7AGFIqdppxu7S4+PymEc
+UIsa7S37vawlfk8Wp2OLxzSNU8heyIzkNnACNPf3ClhYV/ECZVoAMuVilLOXuOfz
+dVz8pTNBTMJb/Obyf/eoS9uyAQy9fCjcxoNMT0M02yrlOCRSlkN9/Lei251qGIkD
+zIxgIn/olXkUPq1ibQBu2bK+YillVuNBO2s3AgMBAAGgADANBgkqhkiG9w0BAQsF
+AAOCAQEAVdY5lxOQyI2WIkH2xtTaUGzo7fOQsY3YFZdguAtc6mywKQj6v7d08uG2
+qaRxzpccpo2HKpWXG9pbKwtCmv9/akxI0NgACmCUnXVzPCJHVcg/Ogd7jDA7Piyc
+fDltLGWmAmoIk+tUM9bnkpR/FSzhu8kewxzI6ukb2lsRG0D49XFj2w6zfcgB1Wgy
+5jwJ//9QxJSqjWw+HX5tMAameqG/gs6uYCx5LF2f7IcM8ezq4k8cmtwu3A9JfZqF
+Vmgnw2SCQ6YSdIxhsyW8lt51TDOySg26FAodnM5TED5jvt+Eu6VqEpAWpbQ8wLUC
+gPGjtAfFdE/LegfC8mn0ZvQNBwv3/Q==
+-----END CERTIFICATE REQUEST-----
diff --git a/sample/sample-keys/sample-ca/client-revoked.key b/sample/sample-keys/sample-ca/client-revoked.key
new file mode 100644
index 0000000..2a88c90
--- /dev/null
+++ b/sample/sample-keys/sample-ca/client-revoked.key
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDBqJR4ikiEelSr
+NKW8ioHKMIuf34/9JcrTnGwGsNSyZFp7CW50I0EO5T0Tc9U0ffdC42Vh6T/Y5L6F
+efPQJ72L3s40LbKw3KlYGiiVYjNPTgUaFv7dGSzU/+nCdz1Dd21lBNn9ofH8qFva
+REOQ8xakt0jup4Rn7AGFIqdppxu7S4+PymEcUIsa7S37vawlfk8Wp2OLxzSNU8he
+yIzkNnACNPf3ClhYV/ECZVoAMuVilLOXuOfzdVz8pTNBTMJb/Obyf/eoS9uyAQy9
+fCjcxoNMT0M02yrlOCRSlkN9/Lei251qGIkDzIxgIn/olXkUPq1ibQBu2bK+Yill
+VuNBO2s3AgMBAAECggEBAIgnu0NIjhW+YFsCp+f4RapfGTutFfI4qPLAjl7h4pkN
+32OTzPmQc8RCPf+4N9UxHzAC6pu9P2uB38W+aUIXPrfhTX74BiM88T8FHTVyFnsS
+cpnWQxg2BAQ5bSORbBxMEjitAYrGWnl18SZzSkHV9zyVtIw+cOQT1TnClIu+tsul
+6P3WeMFrkEjypgwZo1pc37mMJ97IGw6hAERQ1o2EJDEEJ8uK2SlO1WhywfKGbPqY
+A0LxmC1PPuJHpeT85FuFIB9mHf97cgZKGdD4Ue5VdLum6pIVCsiCsnxj8LUPp37u
+rlpqB3Hb66C6t+mOvwAw9OjXL+WNeNeemDvVgD293iECgYEA9BmtCduzs6KHUFM5
+vvUzmiLm7IzEVfw8tm8pRc3Qty5vHA2Nowajiq4MCIccc5yJJMt1phyC9n3HX9UA
+qxgvtq+b3vMnH/N4kBE6NELrAicDyWCa/5FoakMwp28y4NxjMTqe0tiHlH3G3VnF
+8oBgSPahhkBxZzwZagJ25D/HqHECgYEAyxlmg7eNTazXMJ7gqGacWyqLgOWqTazr
+XLvLxpgEwwE6vtbxh1T7kpYbmdZWC7eEN2ooOhs4oEedkhqo5orv0g7MIbMEx0p6
+/yRgNT77kqba7xp5W2e84v7jTl6O68G4F4HW/DDcuEx2gs3jjTp3/CvElXZX5x5Y
+8xCjRP9t4icCgYA/FXejyZS6gvFnb+rHkAUC+6wkTAjdk+940mefM56SCL0MSfBl
+xmxzhaF0fr56nmTPDoncIRgzbbQd7yVaEkkadG3bA4oD9t8clGcvZG/pwX14CLBm
+BgUvGSg0zUcf17UG3vh20yDO3maLhAzlLAo2MQ7zbCoinOSQggyJ1nXZ8QKBgDwX
+vORWKAIGlPk22SQakELNOM+fpJ8s/crHagjNrAMC1x3mPTqco38A2RPQfk8jMoSu
+7U4cBcouxmmXZ8gm7cSKSk3iSRSqbfAWFD1M8GS45+h9PdEUxaeoYRssET+iZtTV
+vwWJc5U4UoxrXNvJo/zB+n16sZGZwhnRH23n4dxbAoGAFjjwQtKjOP5kemsbqDtr
+T3ELIwnjPY0q4mgxNIFc+6UpT+Piv5i2mIq10zmFLijMlLTA058lshHS7RxGTd+/
+NI8gufOuS6iZpGjXwvtfzgXAoaGzXv4MR1ErElK7n2XK3a9GoXVJ0L/+nLdp5Qmj
+nsYL/BDXdn8Fstx4RPcgLMc=
+-----END PRIVATE KEY-----
diff --git a/sample/sample-keys/sample-ca/client.crt b/sample/sample-keys/sample-ca/client.crt
new file mode 100644
index 0000000..295f720
--- /dev/null
+++ b/sample/sample-keys/sample-ca/client.crt
@@ -0,0 +1,103 @@
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 2 (0x2)
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: C=KG, ST=NA, L=BISHKEK, O=OpenVPN-TEST/emailAddress=me@myhost.mydomain
+ Validity
+ Not Before: Oct 28 12:54:33 2016 GMT
+ Not After : Oct 26 12:54:33 2026 GMT
+ Subject: C=KG, ST=NA, O=OpenVPN-TEST, CN=Test-Client/emailAddress=me@myhost.mydomain
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:e5:4f:5f:c9:2c:3f:8e:1a:3e:0b:f8:7f:82:d5:
+ ca:c5:6e:94:a4:fd:98:85:c0:1d:eb:94:b5:93:5b:
+ df:c2:c0:3f:9b:8e:5e:a3:d0:91:ca:3e:f4:74:93:
+ 63:86:df:a7:ae:0d:15:28:6d:38:6e:3b:ac:c9:5c:
+ 1f:c7:f7:d5:66:64:b9:07:00:41:6d:b6:a6:1a:ee:
+ f1:bb:ce:bd:39:cc:70:1f:9b:65:d7:3c:3c:97:2e:
+ 8e:1e:31:90:7f:cc:a7:b8:d9:2f:4e:b3:4a:98:6d:
+ a0:15:04:9d:cb:e1:7a:e1:63:f4:96:7a:bb:9e:a8:
+ d8:f0:33:97:67:6d:bf:39:82:0e:a3:b7:2a:15:2d:
+ 99:2b:f8:53:b1:e8:14:0f:d9:b3:a2:4f:2a:f1:63:
+ fd:d5:72:a6:22:b9:d6:be:e4:7b:9e:c8:85:1e:06:
+ 1a:31:24:3d:f3:82:ac:d7:28:7d:a4:4f:4b:c3:fd:
+ 72:27:07:ef:9d:51:71:56:d4:a4:b6:66:d2:74:4f:
+ 97:7f:3f:90:a8:56:8b:5b:14:4a:4f:c0:3d:2d:5a:
+ 90:74:db:da:59:83:4d:dd:2b:0a:81:24:ce:19:ce:
+ 8e:56:10:0f:cd:0d:83:01:d8:75:8b:66:16:40:1b:
+ 47:af:77:1f:d7:c5:cf:0a:d7:7c:f2:7e:a0:a0:5d:
+ fa:67
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints:
+ CA:FALSE
+ X509v3 Subject Key Identifier:
+ B8:DE:77:EB:43:83:FF:95:59:BB:28:78:E4:4D:F2:E5:C7:2E:06:EF
+ X509v3 Authority Key Identifier:
+ keyid:08:C4:94:ED:23:0A:23:0D:D0:FA:D2:13:E2:3C:B6:65:E7:53:25:10
+ DirName:/C=KG/ST=NA/L=BISHKEK/O=OpenVPN-TEST/emailAddress=me@myhost.mydomain
+ serial:A4:CC:46:13:89:24:40:73
+
+ Signature Algorithm: sha256WithRSAEncryption
+ a7:24:5d:b2:2f:49:63:55:90:e0:95:0e:fa:fc:d7:d8:0c:89:
+ 01:15:90:73:39:e9:32:3a:f9:8d:4b:cd:e7:3a:32:c0:fd:bb:
+ ed:3c:d9:cf:ea:0f:f3:6e:18:18:1d:1c:9c:e2:39:e6:c0:1d:
+ 2e:54:14:ec:1b:b2:5a:fd:1a:ac:65:45:9b:d4:0d:4a:3a:53:
+ 95:8d:bd:d3:44:20:17:70:d0:79:b5:f7:2c:dd:2a:0d:bf:b3:
+ d0:a8:1f:5c:db:33:5b:5d:56:24:84:2b:c8:43:32:fc:f3:dc:
+ b5:da:dc:7f:0a:1c:2a:2f:9b:60:ca:2d:6e:fe:98:55:26:d5:
+ 62:a7:3e:f4:49:5c:a9:76:54:87:19:0b:dd:74:ff:02:f0:75:
+ 8a:36:01:cf:29:67:9b:ae:c0:e5:da:da:2b:d9:57:61:92:69:
+ 1d:e3:b2:f4:66:8e:f8:dd:11:13:4c:1d:a5:7f:37:df:4e:fd:
+ 7d:96:ba:ac:6c:39:83:89:8f:05:47:1a:4b:4f:68:38:1a:99:
+ c8:68:1a:31:b9:78:9a:f5:12:ea:23:c2:c6:83:6b:e4:e0:9a:
+ fc:70:aa:bb:ef:00:1f:c9:18:ef:48:c2:fc:ec:e8:4c:e8:92:
+ d6:64:ab:5c:b3:ac:03:da:5f:a9:92:f2:ff:ef:a7:39:6f:d6:
+ 95:fb:44:89:c7:2b:c4:c4:45:b3:49:1a:c1:23:96:0d:f4:0b:
+ 0f:75:3b:6e:2c:4c:60:be:e7:0f:63:f2:3c:f0:9c:58:af:dd:
+ 5e:41:9e:f7:3f:e0:fb:28:be:f0:02:03:01:8c:9e:c5:52:e0:
+ a4:90:e0:b2:04:1b:58:3e:13:49:87:7b:20:27:73:f4:a8:cd:
+ c2:be:c7:c0:e9:8e:2d:d0:58:4b:9e:2f:fa:94:63:b2:99:16:
+ 08:5d:a1:49:1a:3d:29:9a:34:a3:63:ef:fd:79:da:0a:3e:79:
+ b1:cd:6f:f6:11:b7:c0:e8:67:41:36:36:94:a1:09:7a:cc:b9:
+ 4b:63:47:ce:49:c8:02:f9:d9:df:49:c1:04:82:09:f8:5b:92:
+ 4b:98:af:86:5e:fe:2e:48:fe:d6:69:7b:76:a8:c5:32:f6:b0:
+ ed:7e:bf:14:65:ca:fe:fa:bb:43:33:7e:c8:f4:98:a3:f8:0b:
+ 65:85:3d:5a:ed:33:45:12:76:90:9a:ca:34:fe:5a:ae:f6:ac:
+ 4d:9d:b6:28:7f:ac:e3:43:60:9a:dd:ec:a9:21:49:44:4a:74:
+ 48:12:6b:93:3b:08:70:ac:2e:58:f7:68:eb:8e:ba:9f:41:5a:
+ f9:a9:43:46:73:7a:1f:40:74:ce:87:c9:5e:51:67:8e:a3:cc:
+ b8:ea:ac:fe:7b:d8:2b:78
+-----BEGIN CERTIFICATE-----
+MIIFFDCCAvygAwIBAgIBAjANBgkqhkiG9w0BAQsFADBmMQswCQYDVQQGEwJLRzEL
+MAkGA1UECBMCTkExEDAOBgNVBAcTB0JJU0hLRUsxFTATBgNVBAoTDE9wZW5WUE4t
+VEVTVDEhMB8GCSqGSIb3DQEJARYSbWVAbXlob3N0Lm15ZG9tYWluMB4XDTE2MTAy
+ODEyNTQzM1oXDTI2MTAyNjEyNTQzM1owajELMAkGA1UEBhMCS0cxCzAJBgNVBAgT
+Ak5BMRUwEwYDVQQKEwxPcGVuVlBOLVRFU1QxFDASBgNVBAMTC1Rlc3QtQ2xpZW50
+MSEwHwYJKoZIhvcNAQkBFhJtZUBteWhvc3QubXlkb21haW4wggEiMA0GCSqGSIb3
+DQEBAQUAA4IBDwAwggEKAoIBAQDlT1/JLD+OGj4L+H+C1crFbpSk/ZiFwB3rlLWT
+W9/CwD+bjl6j0JHKPvR0k2OG36euDRUobThuO6zJXB/H99VmZLkHAEFttqYa7vG7
+zr05zHAfm2XXPDyXLo4eMZB/zKe42S9Os0qYbaAVBJ3L4XrhY/SWerueqNjwM5dn
+bb85gg6jtyoVLZkr+FOx6BQP2bOiTyrxY/3VcqYiuda+5HueyIUeBhoxJD3zgqzX
+KH2kT0vD/XInB++dUXFW1KS2ZtJ0T5d/P5CoVotbFEpPwD0tWpB029pZg03dKwqB
+JM4Zzo5WEA/NDYMB2HWLZhZAG0evdx/Xxc8K13zyfqCgXfpnAgMBAAGjgcgwgcUw
+CQYDVR0TBAIwADAdBgNVHQ4EFgQUuN5360OD/5VZuyh45E3y5ccuBu8wgZgGA1Ud
+IwSBkDCBjYAUCMSU7SMKIw3Q+tIT4jy2ZedTJRChaqRoMGYxCzAJBgNVBAYTAktH
+MQswCQYDVQQIEwJOQTEQMA4GA1UEBxMHQklTSEtFSzEVMBMGA1UEChMMT3BlblZQ
+Ti1URVNUMSEwHwYJKoZIhvcNAQkBFhJtZUBteWhvc3QubXlkb21haW6CCQCkzEYT
+iSRAczANBgkqhkiG9w0BAQsFAAOCAgEApyRdsi9JY1WQ4JUO+vzX2AyJARWQcznp
+Mjr5jUvN5zoywP277TzZz+oP824YGB0cnOI55sAdLlQU7BuyWv0arGVFm9QNSjpT
+lY2900QgF3DQebX3LN0qDb+z0KgfXNszW11WJIQryEMy/PPctdrcfwocKi+bYMot
+bv6YVSbVYqc+9ElcqXZUhxkL3XT/AvB1ijYBzylnm67A5draK9lXYZJpHeOy9GaO
++N0RE0wdpX833079fZa6rGw5g4mPBUcaS09oOBqZyGgaMbl4mvUS6iPCxoNr5OCa
+/HCqu+8AH8kY70jC/OzoTOiS1mSrXLOsA9pfqZLy/++nOW/WlftEiccrxMRFs0ka
+wSOWDfQLD3U7bixMYL7nD2PyPPCcWK/dXkGe9z/g+yi+8AIDAYyexVLgpJDgsgQb
+WD4TSYd7ICdz9KjNwr7HwOmOLdBYS54v+pRjspkWCF2hSRo9KZo0o2Pv/XnaCj55
+sc1v9hG3wOhnQTY2lKEJesy5S2NHzknIAvnZ30nBBIIJ+FuSS5ivhl7+Lkj+1ml7
+dqjFMvaw7X6/FGXK/vq7QzN+yPSYo/gLZYU9Wu0zRRJ2kJrKNP5arvasTZ22KH+s
+40Ngmt3sqSFJREp0SBJrkzsIcKwuWPdo6466n0Fa+alDRnN6H0B0zofJXlFnjqPM
+uOqs/nvYK3g=
+-----END CERTIFICATE-----
diff --git a/sample/sample-keys/sample-ca/client.csr b/sample/sample-keys/sample-ca/client.csr
new file mode 100644
index 0000000..3968434
--- /dev/null
+++ b/sample/sample-keys/sample-ca/client.csr
@@ -0,0 +1,17 @@
+-----BEGIN CERTIFICATE REQUEST-----
+MIICrzCCAZcCAQAwajELMAkGA1UEBhMCS0cxCzAJBgNVBAgTAk5BMRUwEwYDVQQK
+EwxPcGVuVlBOLVRFU1QxFDASBgNVBAMTC1Rlc3QtQ2xpZW50MSEwHwYJKoZIhvcN
+AQkBFhJtZUBteWhvc3QubXlkb21haW4wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
+ggEKAoIBAQDlT1/JLD+OGj4L+H+C1crFbpSk/ZiFwB3rlLWTW9/CwD+bjl6j0JHK
+PvR0k2OG36euDRUobThuO6zJXB/H99VmZLkHAEFttqYa7vG7zr05zHAfm2XXPDyX
+Lo4eMZB/zKe42S9Os0qYbaAVBJ3L4XrhY/SWerueqNjwM5dnbb85gg6jtyoVLZkr
++FOx6BQP2bOiTyrxY/3VcqYiuda+5HueyIUeBhoxJD3zgqzXKH2kT0vD/XInB++d
+UXFW1KS2ZtJ0T5d/P5CoVotbFEpPwD0tWpB029pZg03dKwqBJM4Zzo5WEA/NDYMB
+2HWLZhZAG0evdx/Xxc8K13zyfqCgXfpnAgMBAAGgADANBgkqhkiG9w0BAQsFAAOC
+AQEAakLYqsUoaxXNwYnm7QVL8KXe32m1+ot1CUt0XF65YaHLPcDBffpwqCb8jULv
+lRKDbVmqf4SygnIXtTJ2Ii1sB4MPGj94L+y0l9xYn84/sScGety6Trr+Plp5vNMJ
+aafv+NAxZquu/DKtGthdYt1uwgCMa4lm3Kg+E48DddO/XfFIaD/x0Bl7RPIhqiDu
+gKYP4P6uwL9OzD0485wjaYKp85fZ96FCdDTVbNfpwoYXgDihAqf6sUfahtM+o7t+
+BFX60knfbWMPu8O9URq8QzYk6JOG9cW2ngTATXLmz7NslG+5GhtTEzaoromYR3Za
+So7PnagMqjpz1WXvkKCLXvkoMA==
+-----END CERTIFICATE REQUEST-----
diff --git a/sample/sample-keys/sample-ca/client.key b/sample/sample-keys/sample-ca/client.key
new file mode 100644
index 0000000..a497a9c
--- /dev/null
+++ b/sample/sample-keys/sample-ca/client.key
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDlT1/JLD+OGj4L
++H+C1crFbpSk/ZiFwB3rlLWTW9/CwD+bjl6j0JHKPvR0k2OG36euDRUobThuO6zJ
+XB/H99VmZLkHAEFttqYa7vG7zr05zHAfm2XXPDyXLo4eMZB/zKe42S9Os0qYbaAV
+BJ3L4XrhY/SWerueqNjwM5dnbb85gg6jtyoVLZkr+FOx6BQP2bOiTyrxY/3VcqYi
+uda+5HueyIUeBhoxJD3zgqzXKH2kT0vD/XInB++dUXFW1KS2ZtJ0T5d/P5CoVotb
+FEpPwD0tWpB029pZg03dKwqBJM4Zzo5WEA/NDYMB2HWLZhZAG0evdx/Xxc8K13zy
+fqCgXfpnAgMBAAECggEAFsgW/RaPTd/fkDLlACubVJgS3n1vXMJkdpY0n+o9xcxx
+xVOUpXPAODae9MH73ld0Aj+8fWK0e4ckOHEVmzlNEzoog8CLv4mo4P4iOAVnGUnt
+TcaTjJmob2Cpr+g+seO0OhIhuBDp9VDW2Z+2yZ2iJqhWkWiqIS4nN134ycbGe8D2
+4wThVA2SV0umZRxhBo4m14GLtwoTxuLKz7aSsL862Z3LtT7M7ofWcyZTw3A4vQmP
+77GLBxMyNv0qX+f3LZIi+jtsAk5tYqMVL0ZEgZwi5em+KRCwU/2o2BgJDRrRwSU6
+hrK5ycUuuAMUEQjC4ck3u/vcsXmSyjkjue+C1jfsGQKBgQD8LALHK1RAp3nAdxHK
+0MzPiYkrSeiSK+I81NdWqNJ73ReCWUniqT7Q/jh68mBTpYfbSl2mvLbOLZuMvGWh
+5rlaGUWSDj2NzA+yfZoa2z9o1hdcRYNM9c5LCEm/CKKAAoeshemO1i87m+76xwnI
+IwSrflmuy6VzTzbjZVxq5HC8RQKBgQDoyoSFyo5Fpm0hS6J/tFRG6qNZyZ5Ni9E4
+LRQQhzsaLzTK0TfnlYxzF5+Oz79PfpceVF8CZaEXmX2dUReQdAPKhBJO0dTEqB9g
++GRzeu0XamKduOLvvJEAj5EoqzHxxgHQKYKvf1eshDv3Pl8PiXv9sVjdKKkswX0O
+6a3WW+vkuwKBgQDWUUVPJsklZfD5HXlWqRzYaejVjKwHxxoxXydg9HxnXyGC3AYK
+iJLlppo0C9jIXo/XVR3A/vRSyLpB40BxWBlBtObG2imAYOUaattVZe8/V21lM4MD
+HonkhTfAD0OkjgHnI6y7g9eCzuVN52mt2e03H1xzTYrhNHrOyq+//US/DQKBgHII
+GiiLk2us3ZJMwXn69LmUYJYv/DqSPdddxZFfHOVzsFGVcOQhTp5mOQO04krngNEb
+lTrQW7v6tRylx3w8SEsgrPMtOCNpE43lvxcOZStuMoZ+NbQn04PJz9pzGdEMJIE6
+hEjBgUoBsHopdFlhCHq6MASN0WkaEs+GSmBRwNjXAoGBALQEU7fOApGoakwPyuhU
+RZYFf/EFun7Zvt6lF1SWwJ02lTYmCh91lacWVLLwR/fCphp7orlynaAIofJSPsl6
+fTyKv1rpqMS3wMdD/LFGZPh1oyUmweTxsF/0aNVnSS9O9i46ihxLMRMu7wSguLIw
+ycorZrB2bB1WnfmF6bB5qcKC
+-----END PRIVATE KEY-----
diff --git a/sample/sample-keys/sample-ca/client.p12 b/sample/sample-keys/sample-ca/client.p12
new file mode 100644
index 0000000..f8ac2a9
--- /dev/null
+++ b/sample/sample-keys/sample-ca/client.p12
Binary files differ
diff --git a/sample/sample-keys/sample-ca/index.txt b/sample/sample-keys/sample-ca/index.txt
new file mode 100644
index 0000000..30063b2
--- /dev/null
+++ b/sample/sample-keys/sample-ca/index.txt
@@ -0,0 +1,3 @@
+V 261026125432Z 01 unknown /C=KG/ST=NA/O=OpenVPN-TEST/CN=Test-Server/emailAddress=me@myhost.mydomain
+V 261026125433Z 02 unknown /C=KG/ST=NA/O=OpenVPN-TEST/CN=Test-Client/emailAddress=me@myhost.mydomain
+R 261026125433Z 161028125433Z 03 unknown /C=KG/ST=NA/O=OpenVPN-TEST/CN=client-revoked/emailAddress=me@myhost.mydomain
diff --git a/sample/sample-keys/sample-ca/index.txt.attr b/sample/sample-keys/sample-ca/index.txt.attr
new file mode 100644
index 0000000..8f7e63a
--- /dev/null
+++ b/sample/sample-keys/sample-ca/index.txt.attr
@@ -0,0 +1 @@
+unique_subject = yes
diff --git a/sample/sample-keys/sample-ca/index.txt.attr.old b/sample/sample-keys/sample-ca/index.txt.attr.old
new file mode 100644
index 0000000..8f7e63a
--- /dev/null
+++ b/sample/sample-keys/sample-ca/index.txt.attr.old
@@ -0,0 +1 @@
+unique_subject = yes
diff --git a/sample/sample-keys/sample-ca/index.txt.old b/sample/sample-keys/sample-ca/index.txt.old
new file mode 100644
index 0000000..3bfd8f8
--- /dev/null
+++ b/sample/sample-keys/sample-ca/index.txt.old
@@ -0,0 +1,3 @@
+V 261026125432Z 01 unknown /C=KG/ST=NA/O=OpenVPN-TEST/CN=Test-Server/emailAddress=me@myhost.mydomain
+V 261026125433Z 02 unknown /C=KG/ST=NA/O=OpenVPN-TEST/CN=Test-Client/emailAddress=me@myhost.mydomain
+V 261026125433Z 03 unknown /C=KG/ST=NA/O=OpenVPN-TEST/CN=client-revoked/emailAddress=me@myhost.mydomain
diff --git a/sample/sample-keys/sample-ca/secp256k1.pem b/sample/sample-keys/sample-ca/secp256k1.pem
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/sample/sample-keys/sample-ca/secp256k1.pem
diff --git a/sample/sample-keys/sample-ca/serial b/sample/sample-keys/sample-ca/serial
new file mode 100644
index 0000000..6496923
--- /dev/null
+++ b/sample/sample-keys/sample-ca/serial
@@ -0,0 +1 @@
+04
diff --git a/sample/sample-keys/sample-ca/serial.old b/sample/sample-keys/sample-ca/serial.old
new file mode 100644
index 0000000..75016ea
--- /dev/null
+++ b/sample/sample-keys/sample-ca/serial.old
@@ -0,0 +1 @@
+03
diff --git a/sample/sample-keys/sample-ca/server.crt b/sample/sample-keys/sample-ca/server.crt
new file mode 100644
index 0000000..6613831
--- /dev/null
+++ b/sample/sample-keys/sample-ca/server.crt
@@ -0,0 +1,113 @@
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 1 (0x1)
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: C=KG, ST=NA, L=BISHKEK, O=OpenVPN-TEST/emailAddress=me@myhost.mydomain
+ Validity
+ Not Before: Oct 28 12:54:32 2016 GMT
+ Not After : Oct 26 12:54:32 2026 GMT
+ Subject: C=KG, ST=NA, O=OpenVPN-TEST, CN=Test-Server/emailAddress=me@myhost.mydomain
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:a6:74:d1:c9:77:5d:ff:d6:22:e3:69:38:8f:e1:
+ 15:0c:e3:46:2c:19:61:31:af:ef:f9:34:5b:0c:bd:
+ 20:d1:76:6a:64:62:f6:89:aa:5b:c9:42:10:44:6f:
+ 07:0f:fe:62:59:96:0b:16:ec:62:3e:18:08:ad:67:
+ 37:b6:53:2d:3d:d9:81:b7:6b:11:d6:fa:23:6a:23:
+ 6c:3c:be:54:91:e3:04:c6:f5:8c:a6:6a:80:9f:ef:
+ e8:5b:63:1e:68:37:09:ef:4d:5c:44:82:e6:2e:0d:
+ e5:d7:94:3f:31:74:50:d1:10:5c:99:4d:b5:9f:80:
+ 2b:46:25:37:8b:a2:3d:ce:02:b2:0a:21:63:82:9c:
+ a1:35:b9:3d:9e:ad:a4:19:3c:f5:b2:3a:d7:aa:d4:
+ b7:6d:c2:95:4d:94:4b:38:6f:b0:60:cf:22:d7:37:
+ 66:62:1d:1a:86:c2:a8:6a:2a:56:e5:d6:c3:e2:31:
+ 34:a6:42:5d:79:da:12:e0:a1:95:d1:17:07:f6:cc:
+ f8:63:fa:01:8a:26:7b:bf:b8:a4:87:8c:b5:a3:59:
+ 23:60:67:07:4a:4c:c1:55:be:60:a1:56:92:6c:97:
+ 53:fb:fe:eb:d3:25:fd:28:23:3e:38:4d:e9:92:90:
+ 8b:a6:5e:22:2f:02:1f:69:c6:fa:88:a5:52:88:cc:
+ 61:a1
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints:
+ CA:FALSE
+ Netscape Cert Type:
+ SSL Server
+ Netscape Comment:
+ OpenSSL Generated Server Certificate
+ X509v3 Subject Key Identifier:
+ 7D:4C:17:FE:59:B2:58:FF:08:BC:F4:88:FC:A3:8F:9F:CA:3B:3B:5E
+ X509v3 Authority Key Identifier:
+ keyid:08:C4:94:ED:23:0A:23:0D:D0:FA:D2:13:E2:3C:B6:65:E7:53:25:10
+ DirName:/C=KG/ST=NA/L=BISHKEK/O=OpenVPN-TEST/emailAddress=me@myhost.mydomain
+ serial:A4:CC:46:13:89:24:40:73
+
+ X509v3 Extended Key Usage:
+ TLS Web Server Authentication
+ X509v3 Key Usage:
+ Digital Signature, Key Encipherment
+ Signature Algorithm: sha256WithRSAEncryption
+ 82:2e:11:99:f4:56:98:ad:23:97:74:5c:69:00:7b:fc:9a:93:
+ 15:20:93:db:d6:83:04:9a:6c:cb:55:cd:5c:07:d6:31:5a:00:
+ 1d:35:eb:8e:74:cd:7a:08:db:cd:1f:89:8c:04:70:f7:35:e0:
+ a7:cc:cf:76:2b:8a:a5:80:7b:c1:72:4e:9a:c6:b7:a2:f5:9c:
+ 23:dc:d7:0d:93:a3:0f:f4:10:7d:8b:1d:85:5e:bb:2f:09:c8:
+ 67:41:38:12:72:14:29:f6:6d:68:b5:8a:97:1c:a1:8f:3d:74:
+ 14:95:c6:88:4f:4c:cd:8b:2e:db:95:b0:98:55:d7:5b:22:1f:
+ f3:de:5c:b4:7b:a0:d9:f2:56:2c:ff:85:b0:16:52:63:11:2b:
+ 14:8e:d0:f8:03:d2:cc:89:35:c0:d5:a3:b9:ec:11:55:e0:17:
+ 43:95:b2:6e:f2:db:80:73:f2:b3:3f:9d:fa:4d:24:6a:60:25:
+ 24:1a:53:10:38:08:d4:fe:fa:06:1a:1e:d3:cc:15:64:c7:9e:
+ 8b:51:ee:b3:50:25:60:88:70:46:39:bd:79:f1:5a:74:67:3d:
+ f0:7e:22:a9:b4:2e:f5:06:45:c3:46:fe:e6:32:40:e6:e1:00:
+ dc:e8:a8:43:fe:f4:66:64:4f:41:45:d5:d2:7b:ab:a0:62:f7:
+ dc:f0:28:d3:c6:9c:21:3e:bd:44:95:4c:20:b4:8f:c3:ae:ee:
+ eb:d7:7a:11:88:2d:3d:18:49:5d:e6:09:b8:5f:c7:24:32:83:
+ dd:5f:ae:03:02:c1:b6:51:0d:62:a2:41:f4:13:12:b2:f2:9a:
+ c1:50:04:63:42:de:41:b3:b3:ab:45:57:9e:8b:01:e0:c5:70:
+ d9:70:0e:ea:84:39:07:08:03:e9:99:b1:60:ce:a9:c6:ce:a4:
+ 61:29:36:3c:58:52:a2:c3:01:4f:4e:c1:e8:af:3b:ca:7c:34:
+ 9c:2a:21:c9:40:17:ce:8c:10:b2:fc:c2:39:43:55:50:19:2d:
+ c9:f0:ab:48:b2:86:e6:cf:1e:13:6c:6a:ed:85:e9:f6:dd:b9:
+ ba:6e:70:6a:e9:78:43:40:a3:c8:64:50:1f:5b:88:0d:88:55:
+ 0f:94:9c:92:44:83:79:0c:38:79:09:c4:93:6a:a8:dc:f3:8b:
+ c4:af:bf:0c:20:7b:76:7b:31:52:01:70:4f:09:be:38:d0:14:
+ ce:62:c6:00:35:cd:fc:eb:68:f1:45:d5:de:6a:3f:8b:3f:dc:
+ 1c:c9:e3:8a:7c:f1:17:53:71:f8:af:c9:43:9f:91:5a:16:0b:
+ 3a:c0:d7:b0:e7:74:54:12:f0:9a:71:5f:f3:dd:6b:c0:69:ec:
+ 9d:4d:14:61:bd:10:21:80
+-----BEGIN CERTIFICATE-----
+MIIFgDCCA2igAwIBAgIBATANBgkqhkiG9w0BAQsFADBmMQswCQYDVQQGEwJLRzEL
+MAkGA1UECBMCTkExEDAOBgNVBAcTB0JJU0hLRUsxFTATBgNVBAoTDE9wZW5WUE4t
+VEVTVDEhMB8GCSqGSIb3DQEJARYSbWVAbXlob3N0Lm15ZG9tYWluMB4XDTE2MTAy
+ODEyNTQzMloXDTI2MTAyNjEyNTQzMlowajELMAkGA1UEBhMCS0cxCzAJBgNVBAgT
+Ak5BMRUwEwYDVQQKEwxPcGVuVlBOLVRFU1QxFDASBgNVBAMTC1Rlc3QtU2VydmVy
+MSEwHwYJKoZIhvcNAQkBFhJtZUBteWhvc3QubXlkb21haW4wggEiMA0GCSqGSIb3
+DQEBAQUAA4IBDwAwggEKAoIBAQCmdNHJd13/1iLjaTiP4RUM40YsGWExr+/5NFsM
+vSDRdmpkYvaJqlvJQhBEbwcP/mJZlgsW7GI+GAitZze2Uy092YG3axHW+iNqI2w8
+vlSR4wTG9YymaoCf7+hbYx5oNwnvTVxEguYuDeXXlD8xdFDREFyZTbWfgCtGJTeL
+oj3OArIKIWOCnKE1uT2eraQZPPWyOteq1LdtwpVNlEs4b7BgzyLXN2ZiHRqGwqhq
+Klbl1sPiMTSmQl152hLgoZXRFwf2zPhj+gGKJnu/uKSHjLWjWSNgZwdKTMFVvmCh
+VpJsl1P7/uvTJf0oIz44TemSkIumXiIvAh9pxvqIpVKIzGGhAgMBAAGjggEzMIIB
+LzAJBgNVHRMEAjAAMBEGCWCGSAGG+EIBAQQEAwIGQDAzBglghkgBhvhCAQ0EJhYk
+T3BlblNTTCBHZW5lcmF0ZWQgU2VydmVyIENlcnRpZmljYXRlMB0GA1UdDgQWBBR9
+TBf+WbJY/wi89Ij8o4+fyjs7XjCBmAYDVR0jBIGQMIGNgBQIxJTtIwojDdD60hPi
+PLZl51MlEKFqpGgwZjELMAkGA1UEBhMCS0cxCzAJBgNVBAgTAk5BMRAwDgYDVQQH
+EwdCSVNIS0VLMRUwEwYDVQQKEwxPcGVuVlBOLVRFU1QxITAfBgkqhkiG9w0BCQEW
+Em1lQG15aG9zdC5teWRvbWFpboIJAKTMRhOJJEBzMBMGA1UdJQQMMAoGCCsGAQUF
+BwMBMAsGA1UdDwQEAwIFoDANBgkqhkiG9w0BAQsFAAOCAgEAgi4RmfRWmK0jl3Rc
+aQB7/JqTFSCT29aDBJpsy1XNXAfWMVoAHTXrjnTNegjbzR+JjARw9zXgp8zPdiuK
+pYB7wXJOmsa3ovWcI9zXDZOjD/QQfYsdhV67LwnIZ0E4EnIUKfZtaLWKlxyhjz10
+FJXGiE9MzYsu25WwmFXXWyIf895ctHug2fJWLP+FsBZSYxErFI7Q+APSzIk1wNWj
+uewRVeAXQ5WybvLbgHPysz+d+k0kamAlJBpTEDgI1P76Bhoe08wVZMeei1Hus1Al
+YIhwRjm9efFadGc98H4iqbQu9QZFw0b+5jJA5uEA3OioQ/70ZmRPQUXV0nuroGL3
+3PAo08acIT69RJVMILSPw67u69d6EYgtPRhJXeYJuF/HJDKD3V+uAwLBtlENYqJB
+9BMSsvKawVAEY0LeQbOzq0VXnosB4MVw2XAO6oQ5BwgD6ZmxYM6pxs6kYSk2PFhS
+osMBT07B6K87ynw0nCohyUAXzowQsvzCOUNVUBktyfCrSLKG5s8eE2xq7YXp9t25
+um5waul4Q0CjyGRQH1uIDYhVD5SckkSDeQw4eQnEk2qo3POLxK+/DCB7dnsxUgFw
+Twm+ONAUzmLGADXN/Oto8UXV3mo/iz/cHMnjinzxF1Nx+K/JQ5+RWhYLOsDXsOd0
+VBLwmnFf891rwGnsnU0UYb0QIYA=
+-----END CERTIFICATE-----
diff --git a/sample/sample-keys/sample-ca/server.csr b/sample/sample-keys/sample-ca/server.csr
new file mode 100644
index 0000000..d54b7c0
--- /dev/null
+++ b/sample/sample-keys/sample-ca/server.csr
@@ -0,0 +1,17 @@
+-----BEGIN CERTIFICATE REQUEST-----
+MIICrzCCAZcCAQAwajELMAkGA1UEBhMCS0cxCzAJBgNVBAgTAk5BMRUwEwYDVQQK
+EwxPcGVuVlBOLVRFU1QxFDASBgNVBAMTC1Rlc3QtU2VydmVyMSEwHwYJKoZIhvcN
+AQkBFhJtZUBteWhvc3QubXlkb21haW4wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
+ggEKAoIBAQCmdNHJd13/1iLjaTiP4RUM40YsGWExr+/5NFsMvSDRdmpkYvaJqlvJ
+QhBEbwcP/mJZlgsW7GI+GAitZze2Uy092YG3axHW+iNqI2w8vlSR4wTG9YymaoCf
+7+hbYx5oNwnvTVxEguYuDeXXlD8xdFDREFyZTbWfgCtGJTeLoj3OArIKIWOCnKE1
+uT2eraQZPPWyOteq1LdtwpVNlEs4b7BgzyLXN2ZiHRqGwqhqKlbl1sPiMTSmQl15
+2hLgoZXRFwf2zPhj+gGKJnu/uKSHjLWjWSNgZwdKTMFVvmChVpJsl1P7/uvTJf0o
+Iz44TemSkIumXiIvAh9pxvqIpVKIzGGhAgMBAAGgADANBgkqhkiG9w0BAQsFAAOC
+AQEAd1l8S0ApIlcKg8G/WU65NIN7fcUQ5IDHNjzXv2J/yj4s6W/1yBUenm5TIAcp
+CwIFCRl6bcsXIHZbQDgIiLYS1gW7E+oK8JVTRtyDVRxA6+yTf/rv+gJjgr5bE39b
+rtSUxacdbTeiKo1ulo/wEi9uYAL4HoI8LQUK0lbq9w6PLOl6M2N9nhZS/W6RQqSC
+T/2cGMCizAbkbZ/o44intbMkntzR+ISSirXxHjCsLaZptB67v1xdDHShP2aztmyB
+rIs/KG4oUYlt2rwIr2ejpp7HrigmTbw4yXZIqMdp8/THHS8XgoVWuHv0h9GLuuy+
+fMIqE3HCbBtAtQlmYw4RtWBFQg==
+-----END CERTIFICATE REQUEST-----
diff --git a/sample/sample-keys/sample-ca/server.key b/sample/sample-keys/sample-ca/server.key
new file mode 100644
index 0000000..9a0dd80
--- /dev/null
+++ b/sample/sample-keys/sample-ca/server.key
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCmdNHJd13/1iLj
+aTiP4RUM40YsGWExr+/5NFsMvSDRdmpkYvaJqlvJQhBEbwcP/mJZlgsW7GI+GAit
+Zze2Uy092YG3axHW+iNqI2w8vlSR4wTG9YymaoCf7+hbYx5oNwnvTVxEguYuDeXX
+lD8xdFDREFyZTbWfgCtGJTeLoj3OArIKIWOCnKE1uT2eraQZPPWyOteq1LdtwpVN
+lEs4b7BgzyLXN2ZiHRqGwqhqKlbl1sPiMTSmQl152hLgoZXRFwf2zPhj+gGKJnu/
+uKSHjLWjWSNgZwdKTMFVvmChVpJsl1P7/uvTJf0oIz44TemSkIumXiIvAh9pxvqI
+pVKIzGGhAgMBAAECggEAS9AfEIxuYqyMHVl6KoXQiZsmBcXVb8T7HlyLL6UgQmaV
+lH1CXncZ8PNG53ROGim5b6YYDOvC3xchNKEzTbZaf7YGD50Tdf9di+TwUkY5zGxC
+a7/AvLb7OF0TTjQ50CtpOfXZFVctMUKhMWvS0FpyyJWUJzqugyPkEcG3p8BQN/hj
+/ccVxtUhviB6pkzVT4iULcrq78C1LEu4KYatC0z+5FI3VjTCaMJX+nXDshcPGfdQ
+9ablCQcuYRbtiJ/USZj+ZL5jeo9PtxDHtuEmlpkLJ1us7XLgNr0mF3+1E/W2rUjG
+eEFry5BSq7BhnOGmKQ9gn/XQwCBNTH6nw4Jqlc7XMQKBgQDaFT83JnXnZQrCOsgK
+Up0wApmqVJi4Q189+2mugwVEWSUwOGZuNTCVDQzJyTdiAgqMaFMMUFszFZgR9GIJ
+jwvX42c6XwaQdpKudkHSw/6LefLggHFdyN89CluBhaefBR0+dBx8rSZ3OOw/v8fT
+SMET5MnAx0lswKTmVFUDA3AWjQKBgQDDZbK5K3AB0j2XZykO5upj5vSuJD63VCpE
+5YMbsUpCKlIRN7wHZySw7yr2me1Pxlnbt2E1jXfhygqGg6eZSDL//4cNLk8Culw+
+xi9N9CuLroIbT3SxDDFG4ZRjJW/JuPDyrPYvd9EjsvbmNKN2ErxwcjNHoh5RNSdK
+jV7dOFBsZQKBgQChXelZuIazgmt0jqQoJzsSJEpp45Dhf1CA/4ASVfZWvZOr23/H
+emoJUA+vW8k0JwiBHkydJvRkl0zftDG6mvMLesOOSHQF/wbIOs630riNod2aStAX
+siOk+f39l9UQ8GrUJHxTsJduzlrZTOHiL8pWGwtCLvPgmacqmyoQQcH1nQKBgC1M
+9KSNd4hUj8b8Ob6kto62yt9cs9WZA7u5Yi4XalnwqdooC8XDmfQTXuiRQz2NhOO1
+ninmRHbqeoo5F7An1vsW6N6bb+H4Bs7e77So+TeHG87tGua5JuuB/P8HfOVNpT79
+7o2Ov8QBB9DTP1pueZWwREdFRLYbFqLoJ6guGCcpAoGAb/86lf8HhVZKeJ2S49cl
+HBaynzn4FGiVZl/HekmOyHw1ymJCBS3lQMvw2pIDqPqGUReIjJwJVfRYazCQmdSY
+hdlNcrn6nXAN5CVFolStJNpZIQBvTsAwl3dYjs7ycSh8pwDiPUKqmW0FiW1u7i8i
+eyXzuBIBkRx6w+ky7J70VpU=
+-----END PRIVATE KEY-----
diff --git a/sample/sample-keys/ta.key b/sample/sample-keys/ta.key
new file mode 100644
index 0000000..1669036
--- /dev/null
+++ b/sample/sample-keys/ta.key
@@ -0,0 +1,21 @@
+#
+# 2048 bit OpenVPN static key
+#
+-----BEGIN OpenVPN Static key V1-----
+a863b1cbdb911ff4ef3360ce135157e7
+241a465f5045f51cf9a92ebc24da34fd
+5fc48456778c977e374d55a8a7298aef
+40d0ab0c60b5e09838510526b73473a0
+8da46a8c352572dd86d4a871700a915b
+6aaa58a9dac560db2dfdd7ef15a202e1
+fca6913d7ee79c678c5798fbf7bd920c
+caa7a64720908da7254598b052d07f55
+5e31dc5721932cffbdd8965d04107415
+46c86823da18b66aab347e4522cc05ff
+634968889209c96b1024909cd4ce574c
+f829aa9c17d5df4a66043182ee23635d
+8cabf5a7ba02345ad94a3aa25a63d55c
+e13f4ad235a0825e3fe17f9419baff1c
+e73ad1dd652f1e48c7102fe8ee181e54
+10a160ae255f63fd01db1f29e6efcb8e
+-----END OpenVPN Static key V1-----
diff --git a/sample/sample-plugins/keying-material-exporter-demo/README b/sample/sample-plugins/keying-material-exporter-demo/README
new file mode 100644
index 0000000..a245d23
--- /dev/null
+++ b/sample/sample-plugins/keying-material-exporter-demo/README
@@ -0,0 +1,68 @@
+OpenVPN plugin examples. Daniel Kubec <niel@rtfm.cz>
+
+Examples provided:
+
+keyingmaterialexporter.c -- Example based on TLS Keying Material Exporters over HTTP [RFC-5705]
+ (openvpn/doc/keying-material-exporter.txt)
+
+This example demonstrates authenticating a user over HTTP who have already
+established an OpenVPN connecting using the --keying-material-exporter
+feature.
+
+Requires:
+OpenVPN RFC-5705 Support, OpenSSL >= 1.0.1
+
+Files:
+ http-server.py -- Example HTTP Server listen 0.0.0.0:8080
+ http-client.py -- Example HTTP Client connect 10.8.0.1:8080 [GET /$SESSIONID]
+
+ server.ovpn -- Example HTTP SSO VPN Server configuration
+ client.ovpn -- Example HTTP SSO VPN Client configuration
+
+ keyingmaterialexporter.c,
+ keyingmaterialexporter.so -- Example OpenVPN Client and Server plugin
+
+To build:
+ ./build keyingmaterialexporter
+
+To use in OpenVPN:
+
+Enter openvpn/sample/sample-plugins/keyingmaterialexporter directory
+and in separate terminals, start these four processes:
+
+$ openvpn --config ./server.ovpn
+$ openvpn --config ./client.ovpn
+$ ./http-server.py
+$ ./http-client.py
+
+Test:
+
+openvpn --config ./server.ovpn
+##############################
+
+PLUGIN SSO: app session created
+PLUGIN_CALL: POST ./keyingmaterialexporter.so/PLUGIN_TLS_VERIFY status=0
+PLUGIN SSO: app session key: a5885abc84d361803f58ede1ef9c0adf99e720cd
+PLUGIN SSO: app session file: /tmp/openvpn_sso_a5885abc84d361803f58ede1ef9c0adf99e720cd
+PLUGIN SSO: app session user: Test-Client
+
+openvpn --config ./client.ovpn
+##############################
+PLUGIN SSO: app session created
+PLUGIN_CALL: POST ./keyingmaterialexporter.so/PLUGIN_TLS_VERIFY status=0
+PLUGIN SSO: app session key: a5885abc84d361803f58ede1ef9c0adf99e720cd
+PLUGIN SSO: app session file: /tmp/openvpn_sso_user
+PLUGIN_CALL: POST ./keyingmaterialexporter.so/PLUGIN_TLS_FINAL status=0
+
+HTTP_SERVER:
+http-server.py
+################
+http server started
+session file: /tmp/openvpn_sso_a5885abc84d361803f58ede1ef9c0adf99e720cd
+10.8.0.1 - - [02/Apr/2015 15:03:33] "GET /a5885abc84d361803f58ede1ef9c0adf99e720cd HTTP/1.1" 200 -
+session user: Test-Client
+session key: a5885abc84d361803f58ede1ef9c0adf99e720cd
+
+HTTP_SERVER:
+http-client.py
+<html><body><h1>Greetings Test-Client. You are authorized</h1></body></html>
diff --git a/sample/sample-plugins/keying-material-exporter-demo/build b/sample/sample-plugins/keying-material-exporter-demo/build
new file mode 100755
index 0000000..bbb05f7
--- /dev/null
+++ b/sample/sample-plugins/keying-material-exporter-demo/build
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+#
+# Build an OpenVPN plugin module on *nix. The argument should
+# be the base name of the C source file (without the .c).
+#
+
+# This directory is where we will look for openvpn-plugin.h
+CPPFLAGS="${CPPFLAGS:--I../../..}"
+
+CC="${CC:-gcc}"
+CFLAGS="${CFLAGS:--O2 -Wall -g}"
+
+$CC $CPPFLAGS $CFLAGS -fPIC -c $1.c && \
+$CC $CFLAGS -fPIC -shared $LDFLAGS -Wl,-soname,$1.so -o $1.so $1.o -lc
diff --git a/sample/sample-plugins/keying-material-exporter-demo/client.ovpn b/sample/sample-plugins/keying-material-exporter-demo/client.ovpn
new file mode 100644
index 0000000..f02087b
--- /dev/null
+++ b/sample/sample-plugins/keying-material-exporter-demo/client.ovpn
@@ -0,0 +1,18 @@
+tls-client
+pull
+
+keying-material-exporter "EXPORTER_SSO_TEST" 16
+reneg-sec 0
+
+ca ../../sample-keys/ca.crt
+cert ../../sample-keys/client.crt
+key ../../sample-keys/client.key
+
+plugin ./keyingmaterialexporter.so
+
+remote 127.0.0.1 1194
+proto udp
+dev tun
+nobind
+
+verb 4
diff --git a/sample/sample-plugins/keying-material-exporter-demo/http-client.py b/sample/sample-plugins/keying-material-exporter-demo/http-client.py
new file mode 100755
index 0000000..e0570b3
--- /dev/null
+++ b/sample/sample-plugins/keying-material-exporter-demo/http-client.py
@@ -0,0 +1,20 @@
+#!/usr/bin/python
+import sys
+import os
+import httplib
+
+f = '/tmp/openvpn_sso_user'
+with open (f, "r") as myfile:
+ session_key = myfile.read().replace('\n', '')
+
+conn = httplib.HTTPConnection("10.8.0.1:8080")
+conn.request("GET", "/" + session_key)
+r1 = conn.getresponse()
+
+if r1.status == 200:
+ body = r1.read().rstrip()
+ print body
+elif r1.status == 404:
+ print "Authentication failed"
+else:
+ print r1.status, r1.reason
diff --git a/sample/sample-plugins/keying-material-exporter-demo/http-server.py b/sample/sample-plugins/keying-material-exporter-demo/http-server.py
new file mode 100755
index 0000000..45381b5
--- /dev/null
+++ b/sample/sample-plugins/keying-material-exporter-demo/http-server.py
@@ -0,0 +1,41 @@
+#!/usr/bin/python
+from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
+import os
+
+class ExampleHTTPRequestHandler(BaseHTTPRequestHandler):
+
+ def do_GET(self):
+ session_key = os.path.basename(self.path)
+ file = '/tmp/openvpn_sso_' + session_key
+ print 'session file: ' + file
+ try:
+ f = open(file)
+ #send code 200 response
+ self.send_response(200)
+ #send header first
+ self.send_header('Content-type','text-html')
+ self.end_headers()
+ #send file content to client
+ user = f.read().rstrip()
+ print 'session user: ' + user
+ print 'session key: ' + session_key
+ self.wfile.write('<html><body><h1>Greetings ' + user \
+ + '. You are authorized' \
+ '</h1>' \
+ '</body></html>')
+ f.close()
+ return
+ except IOError:
+ self.send_error(404, 'authentication failed')
+
+def run():
+ #ip and port of servr
+ #by default http server port is 80
+ server_address = ('0.0.0.0', 8080)
+ httpd = HTTPServer(server_address, ExampleHTTPRequestHandler)
+ print('http server started')
+ httpd.serve_forever()
+ print('http server stopped')
+
+if __name__ == '__main__':
+ run()
diff --git a/sample/sample-plugins/keying-material-exporter-demo/keyingmaterialexporter.c b/sample/sample-plugins/keying-material-exporter-demo/keyingmaterialexporter.c
new file mode 100644
index 0000000..b0240b8
--- /dev/null
+++ b/sample/sample-plugins/keying-material-exporter-demo/keyingmaterialexporter.c
@@ -0,0 +1,269 @@
+/*
+ * OpenVPN -- An application to securely tunnel IP networks
+ * over a single TCP/UDP port, with support for SSL/TLS-based
+ * session authentication and key exchange,
+ * packet encryption, packet authentication, and
+ * packet compression.
+ *
+ * Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program (see the file COPYING included with this
+ * distribution); if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * This file implements a Sample (HTTP) SSO OpenVPN plugin module
+ *
+ * See the README file for build instructions.
+ */
+
+#define ENABLE_CRYPTO
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "openvpn-plugin.h"
+
+#ifndef MAXPATH
+#define MAXPATH 1024
+#endif
+
+#define ovpn_err(fmt, ...) \
+ plugin->log(PLOG_ERR, "SSO", fmt , ## __VA_ARGS__)
+#define ovpn_dbg(fmt, ...) \
+ plugin->log(PLOG_DEBUG, "SSO", fmt , ## __VA_ARGS__)
+#define ovpn_note(fmt, ...) \
+ plugin->log(PLOG_NOTE, "SSO", fmt , ## __VA_ARGS__)
+
+enum endpoint { CLIENT = 1, SERVER = 2 };
+
+struct plugin {
+ plugin_log_t log;
+ enum endpoint type;
+ int mask;
+};
+
+struct session {
+ char user[48];
+ char key [48];
+};
+
+/*
+ * Given an environmental variable name, search
+ * the envp array for its value, returning it
+ * if found or NULL otherwise.
+ */
+
+static const char *
+get_env(const char *name, const char *envp[])
+{
+ if (envp)
+ {
+ int i;
+ const int namelen = strlen (name);
+ for (i = 0; envp[i]; ++i)
+ {
+ if (!strncmp (envp[i], name, namelen))
+ {
+ const char *cp = envp[i] + namelen;
+ if (*cp == '=')
+ return cp + 1;
+ }
+ }
+ }
+ return NULL;
+}
+
+OPENVPN_EXPORT int
+openvpn_plugin_open_v3 (const int version,
+ struct openvpn_plugin_args_open_in const *args,
+ struct openvpn_plugin_args_open_return *rv)
+{
+ struct plugin *plugin = calloc (1, sizeof(*plugin));
+
+ plugin->type = get_env ("remote_1", args->envp) ? CLIENT : SERVER;
+ plugin->log = args->callbacks->plugin_log;
+
+ plugin->mask = OPENVPN_PLUGIN_MASK(OPENVPN_PLUGIN_TLS_FINAL);
+ plugin->mask |= OPENVPN_PLUGIN_MASK(OPENVPN_PLUGIN_TLS_VERIFY);
+
+ ovpn_note("vpn endpoint type=%s",plugin->type == CLIENT ? "client":"server");
+
+ rv->type_mask = plugin->mask;
+ rv->handle = (void *)plugin;
+
+ return OPENVPN_PLUGIN_FUNC_SUCCESS;
+}
+
+static void
+session_user_set(struct session *sess, X509 *x509)
+{
+ int fn_nid;
+ ASN1_OBJECT *fn;
+ ASN1_STRING *val;
+ X509_NAME *x509_name;
+ X509_NAME_ENTRY *ent;
+ const char *objbuf;
+
+ x509_name = X509_get_subject_name (x509);
+ int i, n = X509_NAME_entry_count (x509_name);
+ for (i = 0; i < n; ++i)
+ {
+ if (!(ent = X509_NAME_get_entry (x509_name, i)))
+ continue;
+ if (!(fn = X509_NAME_ENTRY_get_object (ent)))
+ continue;
+ if (!(val = X509_NAME_ENTRY_get_data (ent)))
+ continue;
+ if ((fn_nid = OBJ_obj2nid (fn)) == NID_undef)
+ continue;
+ if (!(objbuf = OBJ_nid2sn (fn_nid)))
+ continue;
+ /* bug in OpenSSL 0.9.6b ASN1_STRING_to_UTF8 requires this workaround */
+ unsigned char *buf = (unsigned char *)1;
+ if (ASN1_STRING_to_UTF8 (&buf, val) <= 0)
+ continue;
+
+ if (!strncasecmp(objbuf, "CN", 2))
+ snprintf(sess->user, sizeof(sess->user) - 1, (char *)buf);
+
+ OPENSSL_free (buf);
+ }
+}
+
+static int
+tls_verify(struct openvpn_plugin_args_func_in const *args)
+{
+ struct plugin *plugin = (struct plugin *)args->handle;
+ struct session *sess = (struct session *)args->per_client_context;
+
+ /* we store cert subject for the server end point only */
+ if (plugin->type != SERVER)
+ return OPENVPN_PLUGIN_FUNC_SUCCESS;
+
+ if (!args->current_cert) {
+ ovpn_err("this example plugin requires client certificate");
+ return OPENVPN_PLUGIN_FUNC_ERROR;
+ }
+
+ session_user_set(sess, args->current_cert);
+
+ return OPENVPN_PLUGIN_FUNC_SUCCESS;
+}
+
+static void
+file_store(char *file, char *content)
+{
+ FILE *f;
+ if (!(f = fopen(file, "w+")))
+ return;
+
+ fprintf(f, "%s", content);
+ fclose(f);
+}
+
+static void
+server_store(struct openvpn_plugin_args_func_in const *args)
+{
+ struct plugin *plugin = (struct plugin *)args->handle;
+ struct session *sess = (struct session *)args->per_client_context;
+
+ char file[MAXPATH];
+ snprintf(file, sizeof(file) - 1, "/tmp/openvpn_sso_%s", sess->key);
+ ovpn_note("app session file: %s", file);
+ file_store(file, sess->user);
+}
+
+static void
+client_store(struct openvpn_plugin_args_func_in const *args)
+{
+ struct plugin *plugin = (struct plugin *)args->handle;
+ struct session *sess = (struct session *)args->per_client_context;
+
+ char *file = "/tmp/openvpn_sso_user";
+ ovpn_note("app session file: %s", file);
+ file_store(file, sess->key);
+}
+
+static int
+tls_final(struct openvpn_plugin_args_func_in const *args,
+ struct openvpn_plugin_args_func_return *rv)
+{
+ struct plugin *plugin = (struct plugin *)args->handle;
+ struct session *sess = (struct session *)args->per_client_context;
+
+ const char *key;
+ if (!(key = get_env ("exported_keying_material", args->envp)))
+ return OPENVPN_PLUGIN_FUNC_ERROR;
+
+ snprintf(sess->key, sizeof(sess->key) - 1, "%s", key);
+ ovpn_note("app session key: %s", sess->key);
+
+ switch (plugin->type) {
+ case SERVER:
+ server_store(args);
+ break;
+ case CLIENT:
+ client_store(args);
+ return OPENVPN_PLUGIN_FUNC_SUCCESS;
+ }
+
+ ovpn_note("app session user: %s", sess->user);
+ return OPENVPN_PLUGIN_FUNC_SUCCESS;
+}
+
+OPENVPN_EXPORT int
+openvpn_plugin_func_v3 (const int version,
+ struct openvpn_plugin_args_func_in const *args,
+ struct openvpn_plugin_args_func_return *rv)
+{
+ switch(args->type) {
+ case OPENVPN_PLUGIN_TLS_VERIFY:
+ return tls_verify(args);
+ case OPENVPN_PLUGIN_TLS_FINAL:
+ return tls_final(args, rv);
+ }
+ return OPENVPN_PLUGIN_FUNC_SUCCESS;
+}
+
+OPENVPN_EXPORT void *
+openvpn_plugin_client_constructor_v1(openvpn_plugin_handle_t handle)
+{
+ struct plugin *plugin = (struct plugin *)handle;
+ struct session *sess = calloc (1, sizeof(*sess));
+
+ ovpn_note("app session created");
+
+ return (void *)sess;
+}
+
+OPENVPN_EXPORT void
+openvpn_plugin_client_destructor_v1(openvpn_plugin_handle_t handle, void *ctx)
+{
+ struct plugin *plugin = (struct plugin *)handle;
+ struct session *sess = (struct session *)ctx;
+
+ ovpn_note("app session key: %s", sess->key);
+ ovpn_note("app session destroyed");
+
+ free (sess);
+}
+
+OPENVPN_EXPORT void
+openvpn_plugin_close_v1 (openvpn_plugin_handle_t handle)
+{
+ struct plugin *plugin = (struct plugin *)handle;
+ free (plugin);
+}
diff --git a/sample/sample-plugins/keying-material-exporter-demo/server.ovpn b/sample/sample-plugins/keying-material-exporter-demo/server.ovpn
new file mode 100644
index 0000000..5c670b1
--- /dev/null
+++ b/sample/sample-plugins/keying-material-exporter-demo/server.ovpn
@@ -0,0 +1,18 @@
+tls-server
+reneg-sec 0
+
+keying-material-exporter "EXPORTER_SSO_TEST" 16
+duplicate-cn
+
+plugin ./keyingmaterialexporter.so
+ca ../../sample-keys/ca.crt
+cert ../../sample-keys/server.crt
+key ../../sample-keys/server.key
+dh ../../sample-keys/dh2048.pem
+
+server 10.8.0.0 255.255.255.0
+port 1194
+proto udp
+dev tun
+
+verb 4
diff --git a/sample/sample-plugins/log/log_v3.c b/sample/sample-plugins/log/log_v3.c
index 4d3af91..275b1e7 100644
--- a/sample/sample-plugins/log/log_v3.c
+++ b/sample/sample-plugins/log/log_v3.c
@@ -36,7 +36,7 @@
#include <string.h>
#include <stdlib.h>
-#define ENABLE_SSL
+#define ENABLE_CRYPTO
#include "openvpn-plugin.h"
@@ -82,6 +82,7 @@ openvpn_plugin_open_v3 (const int v3structver,
/* Check that we are API compatible */
if( v3structver != OPENVPN_PLUGINv3_STRUCTVER ) {
+ printf("log_v3: ** ERROR ** Incompatible plug-in interface between this plug-in and OpenVPN\n");
return OPENVPN_PLUGIN_FUNC_ERROR;
}
@@ -90,6 +91,11 @@ openvpn_plugin_open_v3 (const int v3structver,
return OPENVPN_PLUGIN_FUNC_ERROR;
}
+ /* Print some version information about the OpenVPN process using this plug-in */
+ printf("log_v3: OpenVPN %s (Major: %i, Minor: %i, Patch: %s)\n",
+ args->ovpn_version, args->ovpn_version_major,
+ args->ovpn_version_minor, args->ovpn_version_patch);
+
/* Which callbacks to intercept. */
ret->type_mask =
OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_UP) |
diff --git a/src/Makefile.in b/src/Makefile.in
index a90f015..8aeb7f5 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.15 from Makefile.am.
+# Makefile.in generated by automake 1.13.4 from Makefile.am.
# @configure_input@
-# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -25,17 +25,7 @@
# Copyright (C) 2006-2012 Alon Bar-Lev <alon.barlev@gmail.com>
#
VPATH = @srcdir@
-am__is_gnu_make = { \
- if test -z '$(MAKELEVEL)'; then \
- false; \
- elif test -n '$(MAKE_HOST)'; then \
- true; \
- elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
- true; \
- else \
- false; \
- fi; \
-}
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
am__make_running_with_option = \
case $${target_option-} in \
?) ;; \
@@ -99,6 +89,7 @@ POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
subdir = src
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/ax_emptyarray.m4 \
$(top_srcdir)/m4/ax_socklen_t.m4 \
@@ -109,9 +100,9 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_emptyarray.m4 \
$(top_srcdir)/compat.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
-DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
mkinstalldirs = $(install_sh) -d
-CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_HEADER = $(top_builddir)/config.h \
+ $(top_builddir)/include/openvpn-plugin.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
AM_V_P = $(am__v_P_@AM_V@)
@@ -169,7 +160,6 @@ am__define_uniq_tagged_files = \
ETAGS = etags
CTAGS = ctags
DIST_SUBDIRS = $(SUBDIRS)
-am__DIST_COMMON = $(srcdir)/Makefile.in
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
am__relativize = \
dir0=`pwd`; \
@@ -208,6 +198,7 @@ AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
+CMAKE = @CMAKE@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
@@ -242,25 +233,31 @@ LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
-LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+LZ4_CFLAGS = @LZ4_CFLAGS@
+LZ4_LIBS = @LZ4_LIBS@
LZO_CFLAGS = @LZO_CFLAGS@
LZO_LIBS = @LZO_LIBS@
MAKEINFO = @MAKEINFO@
MAN2HTML = @MAN2HTML@
MANIFEST_TOOL = @MANIFEST_TOOL@
+MBEDTLS_CFLAGS = @MBEDTLS_CFLAGS@
+MBEDTLS_LIBS = @MBEDTLS_LIBS@
MKDIR_P = @MKDIR_P@
NETSTAT = @NETSTAT@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
-OPENSSL_CRYPTO_CFLAGS = @OPENSSL_CRYPTO_CFLAGS@
-OPENSSL_CRYPTO_LIBS = @OPENSSL_CRYPTO_LIBS@
-OPENSSL_SSL_CFLAGS = @OPENSSL_SSL_CFLAGS@
-OPENSSL_SSL_LIBS = @OPENSSL_SSL_LIBS@
+OPENSSL_CFLAGS = @OPENSSL_CFLAGS@
+OPENSSL_LIBS = @OPENSSL_LIBS@
+OPENVPN_VERSION_MAJOR = @OPENVPN_VERSION_MAJOR@
+OPENVPN_VERSION_MINOR = @OPENVPN_VERSION_MINOR@
+OPENVPN_VERSION_PATCH = @OPENVPN_VERSION_PATCH@
OPTIONAL_CRYPTO_CFLAGS = @OPTIONAL_CRYPTO_CFLAGS@
OPTIONAL_CRYPTO_LIBS = @OPTIONAL_CRYPTO_LIBS@
OPTIONAL_DL_LIBS = @OPTIONAL_DL_LIBS@
+OPTIONAL_LZ4_CFLAGS = @OPTIONAL_LZ4_CFLAGS@
+OPTIONAL_LZ4_LIBS = @OPTIONAL_LZ4_LIBS@
OPTIONAL_LZO_CFLAGS = @OPTIONAL_LZO_CFLAGS@
OPTIONAL_LZO_LIBS = @OPTIONAL_LZO_LIBS@
OPTIONAL_PKCS11_HELPER_CFLAGS = @OPTIONAL_PKCS11_HELPER_CFLAGS@
@@ -286,8 +283,6 @@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
PLUGIN_AUTH_PAM_CFLAGS = @PLUGIN_AUTH_PAM_CFLAGS@
PLUGIN_AUTH_PAM_LIBS = @PLUGIN_AUTH_PAM_LIBS@
-POLARSSL_CFLAGS = @POLARSSL_CFLAGS@
-POLARSSL_LIBS = @POLARSSL_LIBS@
RANLIB = @RANLIB@
RC = @RC@
ROUTE = @ROUTE@
@@ -302,6 +297,11 @@ TAP_CFLAGS = @TAP_CFLAGS@
TAP_WIN_COMPONENT_ID = @TAP_WIN_COMPONENT_ID@
TAP_WIN_MIN_MAJOR = @TAP_WIN_MIN_MAJOR@
TAP_WIN_MIN_MINOR = @TAP_WIN_MIN_MINOR@
+TEST_CFLAGS = @TEST_CFLAGS@
+TEST_LDFLAGS = @TEST_LDFLAGS@
+VENDOR_BUILD_ROOT = @VENDOR_BUILD_ROOT@
+VENDOR_DIST_ROOT = @VENDOR_DIST_ROOT@
+VENDOR_SRC_ROOT = @VENDOR_SRC_ROOT@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
@@ -378,6 +378,7 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign src/Makefile
+.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
@@ -673,8 +674,6 @@ uninstall-am:
mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
ps ps-am tags tags-am uninstall uninstall-am
-.PRECIOUS: Makefile
-
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
diff --git a/src/compat/Makefile.am b/src/compat/Makefile.am
index 273389e..06bab5c 100644
--- a/src/compat/Makefile.am
+++ b/src/compat/Makefile.am
@@ -27,4 +27,5 @@ libcompat_la_SOURCES = \
compat-daemon.c \
compat-inet_ntop.c \
compat-inet_pton.c \
+ compat-lz4.c compat-lz4.h \
compat-versionhelpers.h
diff --git a/src/compat/Makefile.in b/src/compat/Makefile.in
index 52970a7..c7236ed 100644
--- a/src/compat/Makefile.in
+++ b/src/compat/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.15 from Makefile.am.
+# Makefile.in generated by automake 1.13.4 from Makefile.am.
# @configure_input@
-# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -26,17 +26,7 @@
#
VPATH = @srcdir@
-am__is_gnu_make = { \
- if test -z '$(MAKELEVEL)'; then \
- false; \
- elif test -n '$(MAKE_HOST)'; then \
- true; \
- elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
- true; \
- else \
- false; \
- fi; \
-}
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
am__make_running_with_option = \
case $${target_option-} in \
?) ;; \
@@ -100,6 +90,8 @@ POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
subdir = src/compat
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+ $(top_srcdir)/depcomp
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/ax_emptyarray.m4 \
$(top_srcdir)/m4/ax_socklen_t.m4 \
@@ -110,16 +102,16 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_emptyarray.m4 \
$(top_srcdir)/compat.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
-DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
mkinstalldirs = $(install_sh) -d
-CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_HEADER = $(top_builddir)/config.h \
+ $(top_builddir)/include/openvpn-plugin.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
LTLIBRARIES = $(noinst_LTLIBRARIES)
libcompat_la_LIBADD =
am_libcompat_la_OBJECTS = compat-dirname.lo compat-basename.lo \
compat-gettimeofday.lo compat-daemon.lo compat-inet_ntop.lo \
- compat-inet_pton.lo
+ compat-inet_pton.lo compat-lz4.lo
libcompat_la_OBJECTS = $(am_libcompat_la_OBJECTS)
AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
@@ -137,7 +129,7 @@ AM_V_at = $(am__v_at_@AM_V@)
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
am__v_at_0 = @
am__v_at_1 =
-DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) -I$(top_builddir)/include
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
am__mv = mv -f
@@ -185,7 +177,6 @@ am__define_uniq_tagged_files = \
done | $(am__uniquify_input)`
ETAGS = etags
CTAGS = ctags
-am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
@@ -199,6 +190,7 @@ AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
+CMAKE = @CMAKE@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
@@ -233,25 +225,31 @@ LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
-LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+LZ4_CFLAGS = @LZ4_CFLAGS@
+LZ4_LIBS = @LZ4_LIBS@
LZO_CFLAGS = @LZO_CFLAGS@
LZO_LIBS = @LZO_LIBS@
MAKEINFO = @MAKEINFO@
MAN2HTML = @MAN2HTML@
MANIFEST_TOOL = @MANIFEST_TOOL@
+MBEDTLS_CFLAGS = @MBEDTLS_CFLAGS@
+MBEDTLS_LIBS = @MBEDTLS_LIBS@
MKDIR_P = @MKDIR_P@
NETSTAT = @NETSTAT@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
-OPENSSL_CRYPTO_CFLAGS = @OPENSSL_CRYPTO_CFLAGS@
-OPENSSL_CRYPTO_LIBS = @OPENSSL_CRYPTO_LIBS@
-OPENSSL_SSL_CFLAGS = @OPENSSL_SSL_CFLAGS@
-OPENSSL_SSL_LIBS = @OPENSSL_SSL_LIBS@
+OPENSSL_CFLAGS = @OPENSSL_CFLAGS@
+OPENSSL_LIBS = @OPENSSL_LIBS@
+OPENVPN_VERSION_MAJOR = @OPENVPN_VERSION_MAJOR@
+OPENVPN_VERSION_MINOR = @OPENVPN_VERSION_MINOR@
+OPENVPN_VERSION_PATCH = @OPENVPN_VERSION_PATCH@
OPTIONAL_CRYPTO_CFLAGS = @OPTIONAL_CRYPTO_CFLAGS@
OPTIONAL_CRYPTO_LIBS = @OPTIONAL_CRYPTO_LIBS@
OPTIONAL_DL_LIBS = @OPTIONAL_DL_LIBS@
+OPTIONAL_LZ4_CFLAGS = @OPTIONAL_LZ4_CFLAGS@
+OPTIONAL_LZ4_LIBS = @OPTIONAL_LZ4_LIBS@
OPTIONAL_LZO_CFLAGS = @OPTIONAL_LZO_CFLAGS@
OPTIONAL_LZO_LIBS = @OPTIONAL_LZO_LIBS@
OPTIONAL_PKCS11_HELPER_CFLAGS = @OPTIONAL_PKCS11_HELPER_CFLAGS@
@@ -277,8 +275,6 @@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
PLUGIN_AUTH_PAM_CFLAGS = @PLUGIN_AUTH_PAM_CFLAGS@
PLUGIN_AUTH_PAM_LIBS = @PLUGIN_AUTH_PAM_LIBS@
-POLARSSL_CFLAGS = @POLARSSL_CFLAGS@
-POLARSSL_LIBS = @POLARSSL_LIBS@
RANLIB = @RANLIB@
RC = @RC@
ROUTE = @ROUTE@
@@ -293,6 +289,11 @@ TAP_CFLAGS = @TAP_CFLAGS@
TAP_WIN_COMPONENT_ID = @TAP_WIN_COMPONENT_ID@
TAP_WIN_MIN_MAJOR = @TAP_WIN_MIN_MAJOR@
TAP_WIN_MIN_MINOR = @TAP_WIN_MIN_MINOR@
+TEST_CFLAGS = @TEST_CFLAGS@
+TEST_LDFLAGS = @TEST_LDFLAGS@
+VENDOR_BUILD_ROOT = @VENDOR_BUILD_ROOT@
+VENDOR_DIST_ROOT = @VENDOR_DIST_ROOT@
+VENDOR_SRC_ROOT = @VENDOR_SRC_ROOT@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
@@ -367,6 +368,7 @@ libcompat_la_SOURCES = \
compat-daemon.c \
compat-inet_ntop.c \
compat-inet_pton.c \
+ compat-lz4.c compat-lz4.h \
compat-versionhelpers.h
all: all-am
@@ -385,6 +387,7 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/compat/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign src/compat/Makefile
+.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
@@ -429,20 +432,21 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/compat-gettimeofday.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/compat-inet_ntop.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/compat-inet_pton.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/compat-lz4.Plo@am__quote@
.c.o:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $<
.c.obj:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'`
.c.lo:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@@ -661,8 +665,6 @@ uninstall-am:
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
tags tags-am uninstall uninstall-am
-.PRECIOUS: Makefile
-
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
diff --git a/src/compat/compat-gettimeofday.c b/src/compat/compat-gettimeofday.c
index 0f32d5d..19feaae 100644
--- a/src/compat/compat-gettimeofday.c
+++ b/src/compat/compat-gettimeofday.c
@@ -32,7 +32,7 @@
#include "compat.h"
-#ifdef WIN32
+#ifdef _WIN32
/*
* NOTICE: mingw has much faster gettimeofday!
* autoconf will set HAVE_GETTIMEOFDAY
@@ -126,6 +126,6 @@ gettimeofday (struct timeval *tv, void *tz)
return 0;
}
-#endif /* WIN32 */
+#endif /* _WIN32 */
#endif /* HAVE_GETTIMEOFDAY */
diff --git a/src/compat/compat-inet_ntop.c b/src/compat/compat-inet_ntop.c
index 0d52142..786c973 100644
--- a/src/compat/compat-inet_ntop.c
+++ b/src/compat/compat-inet_ntop.c
@@ -32,7 +32,7 @@
#include "compat.h"
-#ifdef WIN32
+#ifdef _WIN32
#include <windows.h>
diff --git a/src/compat/compat-inet_pton.c b/src/compat/compat-inet_pton.c
index cdc8d4b..5965f0d 100644
--- a/src/compat/compat-inet_pton.c
+++ b/src/compat/compat-inet_pton.c
@@ -32,7 +32,7 @@
#include "compat.h"
-#ifdef WIN32
+#ifdef _WIN32
#include <windows.h>
#include <string.h>
diff --git a/src/compat/compat-lz4.c b/src/compat/compat-lz4.c
new file mode 100644
index 0000000..5855ca1
--- /dev/null
+++ b/src/compat/compat-lz4.c
@@ -0,0 +1,1524 @@
+/*
+ LZ4 - Fast LZ compression algorithm
+ Copyright (C) 2011-2015, Yann Collet.
+
+ BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following disclaimer
+ in the documentation and/or other materials provided with the
+ distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ You can contact the author at :
+ - LZ4 source repository : https://github.com/Cyan4973/lz4
+ - LZ4 public forum : https://groups.google.com/forum/#!forum/lz4c
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#elif defined(_MSC_VER)
+#include "config-msvc.h"
+#endif
+
+#ifdef NEED_COMPAT_LZ4
+
+/**************************************
+* Tuning parameters
+**************************************/
+/*
+ * HEAPMODE :
+ * Select how default compression functions will allocate memory for their hash table,
+ * in memory stack (0:default, fastest), or in memory heap (1:requires malloc()).
+ */
+#define HEAPMODE 0
+
+/*
+ * ACCELERATION_DEFAULT :
+ * Select "acceleration" for LZ4_compress_fast() when parameter value <= 0
+ */
+#define ACCELERATION_DEFAULT 1
+
+
+/**************************************
+* CPU Feature Detection
+**************************************/
+/*
+ * LZ4_FORCE_SW_BITCOUNT
+ * Define this parameter if your target system or compiler does not support hardware bit count
+ */
+#if defined(_MSC_VER) && defined(_WIN32_WCE) /* Visual Studio for Windows CE does not support Hardware bit count */
+# define LZ4_FORCE_SW_BITCOUNT
+#endif
+
+
+/**************************************
+* Includes
+**************************************/
+#include "compat-lz4.h"
+
+
+/**************************************
+* Compiler Options
+**************************************/
+#ifdef _MSC_VER /* Visual Studio */
+# define FORCE_INLINE static __forceinline
+# include <intrin.h>
+# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
+# pragma warning(disable : 4293) /* disable: C4293: too large shift (32-bits) */
+#else
+# if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */
+# if defined(__GNUC__) || defined(__clang__)
+# define FORCE_INLINE static inline __attribute__((always_inline))
+# else
+# define FORCE_INLINE static inline
+# endif
+# else
+# define FORCE_INLINE static
+# endif /* __STDC_VERSION__ */
+#endif /* _MSC_VER */
+
+/* LZ4_GCC_VERSION is defined into lz4.h */
+#if (LZ4_GCC_VERSION >= 302) || (__INTEL_COMPILER >= 800) || defined(__clang__)
+# define expect(expr,value) (__builtin_expect ((expr),(value)) )
+#else
+# define expect(expr,value) (expr)
+#endif
+
+#define likely(expr) expect((expr) != 0, 1)
+#define unlikely(expr) expect((expr) != 0, 0)
+
+
+/**************************************
+* Memory routines
+**************************************/
+#include <stdlib.h> /* malloc, calloc, free */
+#define ALLOCATOR(n,s) calloc(n,s)
+#define FREEMEM free
+#include <string.h> /* memset, memcpy */
+#define MEM_INIT memset
+
+
+/**************************************
+* Basic Types
+**************************************/
+#if defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */
+# include <stdint.h>
+ typedef uint8_t BYTE;
+ typedef uint16_t U16;
+ typedef uint32_t U32;
+ typedef int32_t S32;
+ typedef uint64_t U64;
+#else
+ typedef unsigned char BYTE;
+ typedef unsigned short U16;
+ typedef unsigned int U32;
+ typedef signed int S32;
+ typedef unsigned long long U64;
+#endif
+
+
+/**************************************
+* Reading and writing into memory
+**************************************/
+#define STEPSIZE sizeof(size_t)
+
+static unsigned LZ4_64bits(void) { return sizeof(void*)==8; }
+
+static unsigned LZ4_isLittleEndian(void)
+{
+ const union { U32 i; BYTE c[4]; } one = { 1 }; /* don't use static : performance detrimental */
+ return one.c[0];
+}
+
+
+static U16 LZ4_read16(const void* memPtr)
+{
+ U16 val16;
+ memcpy(&val16, memPtr, 2);
+ return val16;
+}
+
+static U16 LZ4_readLE16(const void* memPtr)
+{
+ if (LZ4_isLittleEndian())
+ {
+ return LZ4_read16(memPtr);
+ }
+ else
+ {
+ const BYTE* p = (const BYTE*)memPtr;
+ return (U16)((U16)p[0] + (p[1]<<8));
+ }
+}
+
+static void LZ4_writeLE16(void* memPtr, U16 value)
+{
+ if (LZ4_isLittleEndian())
+ {
+ memcpy(memPtr, &value, 2);
+ }
+ else
+ {
+ BYTE* p = (BYTE*)memPtr;
+ p[0] = (BYTE) value;
+ p[1] = (BYTE)(value>>8);
+ }
+}
+
+static U32 LZ4_read32(const void* memPtr)
+{
+ U32 val32;
+ memcpy(&val32, memPtr, 4);
+ return val32;
+}
+
+static U64 LZ4_read64(const void* memPtr)
+{
+ U64 val64;
+ memcpy(&val64, memPtr, 8);
+ return val64;
+}
+
+static size_t LZ4_read_ARCH(const void* p)
+{
+ if (LZ4_64bits())
+ return (size_t)LZ4_read64(p);
+ else
+ return (size_t)LZ4_read32(p);
+}
+
+
+static void LZ4_copy4(void* dstPtr, const void* srcPtr) { memcpy(dstPtr, srcPtr, 4); }
+
+static void LZ4_copy8(void* dstPtr, const void* srcPtr) { memcpy(dstPtr, srcPtr, 8); }
+
+/* customized version of memcpy, which may overwrite up to 7 bytes beyond dstEnd */
+static void LZ4_wildCopy(void* dstPtr, const void* srcPtr, void* dstEnd)
+{
+ BYTE* d = (BYTE*)dstPtr;
+ const BYTE* s = (const BYTE*)srcPtr;
+ BYTE* e = (BYTE*)dstEnd;
+ do { LZ4_copy8(d,s); d+=8; s+=8; } while (d<e);
+}
+
+
+/**************************************
+* Common Constants
+**************************************/
+#define MINMATCH 4
+
+#define COPYLENGTH 8
+#define LASTLITERALS 5
+#define MFLIMIT (COPYLENGTH+MINMATCH)
+static const int LZ4_minLength = (MFLIMIT+1);
+
+#define KB *(1 <<10)
+#define MB *(1 <<20)
+#define GB *(1U<<30)
+
+#define MAXD_LOG 16
+#define MAX_DISTANCE ((1 << MAXD_LOG) - 1)
+
+#define ML_BITS 4
+#define ML_MASK ((1U<<ML_BITS)-1)
+#define RUN_BITS (8-ML_BITS)
+#define RUN_MASK ((1U<<RUN_BITS)-1)
+
+
+/**************************************
+* Common Utils
+**************************************/
+#define LZ4_STATIC_ASSERT(c) { enum { LZ4_static_assert = 1/(int)(!!(c)) }; } /* use only *after* variable declarations */
+
+
+/**************************************
+* Common functions
+**************************************/
+static unsigned LZ4_NbCommonBytes (register size_t val)
+{
+ if (LZ4_isLittleEndian())
+ {
+ if (LZ4_64bits())
+ {
+# if defined(_MSC_VER) && defined(_WIN64) && !defined(LZ4_FORCE_SW_BITCOUNT)
+ unsigned long r = 0;
+ _BitScanForward64( &r, (U64)val );
+ return (int)(r>>3);
+# elif (defined(__clang__) || (LZ4_GCC_VERSION >= 304)) && !defined(LZ4_FORCE_SW_BITCOUNT)
+ return (__builtin_ctzll((U64)val) >> 3);
+# else
+ static const int DeBruijnBytePos[64] = { 0, 0, 0, 0, 0, 1, 1, 2, 0, 3, 1, 3, 1, 4, 2, 7, 0, 2, 3, 6, 1, 5, 3, 5, 1, 3, 4, 4, 2, 5, 6, 7, 7, 0, 1, 2, 3, 3, 4, 6, 2, 6, 5, 5, 3, 4, 5, 6, 7, 1, 2, 4, 6, 4, 4, 5, 7, 2, 6, 5, 7, 6, 7, 7 };
+ return DeBruijnBytePos[((U64)((val & -(long long)val) * 0x0218A392CDABBD3FULL)) >> 58];
+# endif
+ }
+ else /* 32 bits */
+ {
+# if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT)
+ unsigned long r;
+ _BitScanForward( &r, (U32)val );
+ return (int)(r>>3);
+# elif (defined(__clang__) || (LZ4_GCC_VERSION >= 304)) && !defined(LZ4_FORCE_SW_BITCOUNT)
+ return (__builtin_ctz((U32)val) >> 3);
+# else
+ static const int DeBruijnBytePos[32] = { 0, 0, 3, 0, 3, 1, 3, 0, 3, 2, 2, 1, 3, 2, 0, 1, 3, 3, 1, 2, 2, 2, 2, 0, 3, 1, 2, 0, 1, 0, 1, 1 };
+ return DeBruijnBytePos[((U32)((val & -(S32)val) * 0x077CB531U)) >> 27];
+# endif
+ }
+ }
+ else /* Big Endian CPU */
+ {
+ if (LZ4_64bits())
+ {
+# if defined(_MSC_VER) && defined(_WIN64) && !defined(LZ4_FORCE_SW_BITCOUNT)
+ unsigned long r = 0;
+ _BitScanReverse64( &r, val );
+ return (unsigned)(r>>3);
+# elif (defined(__clang__) || (LZ4_GCC_VERSION >= 304)) && !defined(LZ4_FORCE_SW_BITCOUNT)
+ return (__builtin_clzll((U64)val) >> 3);
+# else
+ unsigned r;
+ if (!(val>>32)) { r=4; } else { r=0; val>>=32; }
+ if (!(val>>16)) { r+=2; val>>=8; } else { val>>=24; }
+ r += (!val);
+ return r;
+# endif
+ }
+ else /* 32 bits */
+ {
+# if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT)
+ unsigned long r = 0;
+ _BitScanReverse( &r, (unsigned long)val );
+ return (unsigned)(r>>3);
+# elif (defined(__clang__) || (LZ4_GCC_VERSION >= 304)) && !defined(LZ4_FORCE_SW_BITCOUNT)
+ return (__builtin_clz((U32)val) >> 3);
+# else
+ unsigned r;
+ if (!(val>>16)) { r=2; val>>=8; } else { r=0; val>>=24; }
+ r += (!val);
+ return r;
+# endif
+ }
+ }
+}
+
+static unsigned LZ4_count(const BYTE* pIn, const BYTE* pMatch, const BYTE* pInLimit)
+{
+ const BYTE* const pStart = pIn;
+
+ while (likely(pIn<pInLimit-(STEPSIZE-1)))
+ {
+ size_t diff = LZ4_read_ARCH(pMatch) ^ LZ4_read_ARCH(pIn);
+ if (!diff) { pIn+=STEPSIZE; pMatch+=STEPSIZE; continue; }
+ pIn += LZ4_NbCommonBytes(diff);
+ return (unsigned)(pIn - pStart);
+ }
+
+ if (LZ4_64bits()) if ((pIn<(pInLimit-3)) && (LZ4_read32(pMatch) == LZ4_read32(pIn))) { pIn+=4; pMatch+=4; }
+ if ((pIn<(pInLimit-1)) && (LZ4_read16(pMatch) == LZ4_read16(pIn))) { pIn+=2; pMatch+=2; }
+ if ((pIn<pInLimit) && (*pMatch == *pIn)) pIn++;
+ return (unsigned)(pIn - pStart);
+}
+
+
+#ifndef LZ4_COMMONDEFS_ONLY
+/**************************************
+* Local Constants
+**************************************/
+#define LZ4_HASHLOG (LZ4_MEMORY_USAGE-2)
+#define HASHTABLESIZE (1 << LZ4_MEMORY_USAGE)
+#define HASH_SIZE_U32 (1 << LZ4_HASHLOG) /* required as macro for static allocation */
+
+static const int LZ4_64Klimit = ((64 KB) + (MFLIMIT-1));
+static const U32 LZ4_skipTrigger = 6; /* Increase this value ==> compression run slower on incompressible data */
+
+
+/**************************************
+* Local Structures and types
+**************************************/
+typedef struct {
+ U32 hashTable[HASH_SIZE_U32];
+ U32 currentOffset;
+ U32 initCheck;
+ const BYTE* dictionary;
+ BYTE* bufferStart; /* obsolete, used for slideInputBuffer */
+ U32 dictSize;
+} LZ4_stream_t_internal;
+
+typedef enum { notLimited = 0, limitedOutput = 1 } limitedOutput_directive;
+typedef enum { byPtr, byU32, byU16 } tableType_t;
+
+typedef enum { noDict = 0, withPrefix64k, usingExtDict } dict_directive;
+typedef enum { noDictIssue = 0, dictSmall } dictIssue_directive;
+
+typedef enum { endOnOutputSize = 0, endOnInputSize = 1 } endCondition_directive;
+typedef enum { full = 0, partial = 1 } earlyEnd_directive;
+
+
+/**************************************
+* Local Utils
+**************************************/
+int LZ4_versionNumber (void) { return LZ4_VERSION_NUMBER; }
+int LZ4_compressBound(int isize) { return LZ4_COMPRESSBOUND(isize); }
+int LZ4_sizeofState() { return LZ4_STREAMSIZE; }
+
+
+
+/********************************
+* Compression functions
+********************************/
+
+static U32 LZ4_hashSequence(U32 sequence, tableType_t const tableType)
+{
+ if (tableType == byU16)
+ return (((sequence) * 2654435761U) >> ((MINMATCH*8)-(LZ4_HASHLOG+1)));
+ else
+ return (((sequence) * 2654435761U) >> ((MINMATCH*8)-LZ4_HASHLOG));
+}
+
+static const U64 prime5bytes = 889523592379ULL;
+static U32 LZ4_hashSequence64(size_t sequence, tableType_t const tableType)
+{
+ const U32 hashLog = (tableType == byU16) ? LZ4_HASHLOG+1 : LZ4_HASHLOG;
+ const U32 hashMask = (1<<hashLog) - 1;
+ return ((sequence * prime5bytes) >> (40 - hashLog)) & hashMask;
+}
+
+static U32 LZ4_hashSequenceT(size_t sequence, tableType_t const tableType)
+{
+ if (LZ4_64bits())
+ return LZ4_hashSequence64(sequence, tableType);
+ return LZ4_hashSequence((U32)sequence, tableType);
+}
+
+static U32 LZ4_hashPosition(const void* p, tableType_t tableType) { return LZ4_hashSequenceT(LZ4_read_ARCH(p), tableType); }
+
+static void LZ4_putPositionOnHash(const BYTE* p, U32 h, void* tableBase, tableType_t const tableType, const BYTE* srcBase)
+{
+ switch (tableType)
+ {
+ case byPtr: { const BYTE** hashTable = (const BYTE**)tableBase; hashTable[h] = p; return; }
+ case byU32: { U32* hashTable = (U32*) tableBase; hashTable[h] = (U32)(p-srcBase); return; }
+ case byU16: { U16* hashTable = (U16*) tableBase; hashTable[h] = (U16)(p-srcBase); return; }
+ }
+}
+
+static void LZ4_putPosition(const BYTE* p, void* tableBase, tableType_t tableType, const BYTE* srcBase)
+{
+ U32 h = LZ4_hashPosition(p, tableType);
+ LZ4_putPositionOnHash(p, h, tableBase, tableType, srcBase);
+}
+
+static const BYTE* LZ4_getPositionOnHash(U32 h, void* tableBase, tableType_t tableType, const BYTE* srcBase)
+{
+ if (tableType == byPtr) { const BYTE** hashTable = (const BYTE**) tableBase; return hashTable[h]; }
+ if (tableType == byU32) { U32* hashTable = (U32*) tableBase; return hashTable[h] + srcBase; }
+ { U16* hashTable = (U16*) tableBase; return hashTable[h] + srcBase; } /* default, to ensure a return */
+}
+
+static const BYTE* LZ4_getPosition(const BYTE* p, void* tableBase, tableType_t tableType, const BYTE* srcBase)
+{
+ U32 h = LZ4_hashPosition(p, tableType);
+ return LZ4_getPositionOnHash(h, tableBase, tableType, srcBase);
+}
+
+FORCE_INLINE int LZ4_compress_generic(
+ void* const ctx,
+ const char* const source,
+ char* const dest,
+ const int inputSize,
+ const int maxOutputSize,
+ const limitedOutput_directive outputLimited,
+ const tableType_t tableType,
+ const dict_directive dict,
+ const dictIssue_directive dictIssue,
+ const U32 acceleration)
+{
+ LZ4_stream_t_internal* const dictPtr = (LZ4_stream_t_internal*)ctx;
+
+ const BYTE* ip = (const BYTE*) source;
+ const BYTE* base;
+ const BYTE* lowLimit;
+ const BYTE* const lowRefLimit = ip - dictPtr->dictSize;
+ const BYTE* const dictionary = dictPtr->dictionary;
+ const BYTE* const dictEnd = dictionary + dictPtr->dictSize;
+ const size_t dictDelta = dictEnd - (const BYTE*)source;
+ const BYTE* anchor = (const BYTE*) source;
+ const BYTE* const iend = ip + inputSize;
+ const BYTE* const mflimit = iend - MFLIMIT;
+ const BYTE* const matchlimit = iend - LASTLITERALS;
+
+ BYTE* op = (BYTE*) dest;
+ BYTE* const olimit = op + maxOutputSize;
+
+ U32 forwardH;
+ size_t refDelta=0;
+
+ /* Init conditions */
+ if ((U32)inputSize > (U32)LZ4_MAX_INPUT_SIZE) return 0; /* Unsupported input size, too large (or negative) */
+ switch(dict)
+ {
+ case noDict:
+ default:
+ base = (const BYTE*)source;
+ lowLimit = (const BYTE*)source;
+ break;
+ case withPrefix64k:
+ base = (const BYTE*)source - dictPtr->currentOffset;
+ lowLimit = (const BYTE*)source - dictPtr->dictSize;
+ break;
+ case usingExtDict:
+ base = (const BYTE*)source - dictPtr->currentOffset;
+ lowLimit = (const BYTE*)source;
+ break;
+ }
+ if ((tableType == byU16) && (inputSize>=LZ4_64Klimit)) return 0; /* Size too large (not within 64K limit) */
+ if (inputSize<LZ4_minLength) goto _last_literals; /* Input too small, no compression (all literals) */
+
+ /* First Byte */
+ LZ4_putPosition(ip, ctx, tableType, base);
+ ip++; forwardH = LZ4_hashPosition(ip, tableType);
+
+ /* Main Loop */
+ for ( ; ; )
+ {
+ const BYTE* match;
+ BYTE* token;
+ {
+ const BYTE* forwardIp = ip;
+ unsigned step = 1;
+ unsigned searchMatchNb = acceleration << LZ4_skipTrigger;
+
+ /* Find a match */
+ do {
+ U32 h = forwardH;
+ ip = forwardIp;
+ forwardIp += step;
+ step = (searchMatchNb++ >> LZ4_skipTrigger);
+
+ if (unlikely(forwardIp > mflimit)) goto _last_literals;
+
+ match = LZ4_getPositionOnHash(h, ctx, tableType, base);
+ if (dict==usingExtDict)
+ {
+ if (match<(const BYTE*)source)
+ {
+ refDelta = dictDelta;
+ lowLimit = dictionary;
+ }
+ else
+ {
+ refDelta = 0;
+ lowLimit = (const BYTE*)source;
+ }
+ }
+ forwardH = LZ4_hashPosition(forwardIp, tableType);
+ LZ4_putPositionOnHash(ip, h, ctx, tableType, base);
+
+ } while ( ((dictIssue==dictSmall) ? (match < lowRefLimit) : 0)
+ || ((tableType==byU16) ? 0 : (match + MAX_DISTANCE < ip))
+ || (LZ4_read32(match+refDelta) != LZ4_read32(ip)) );
+ }
+
+ /* Catch up */
+ while ((ip>anchor) && (match+refDelta > lowLimit) && (unlikely(ip[-1]==match[refDelta-1]))) { ip--; match--; }
+
+ {
+ /* Encode Literal length */
+ unsigned litLength = (unsigned)(ip - anchor);
+ token = op++;
+ if ((outputLimited) && (unlikely(op + litLength + (2 + 1 + LASTLITERALS) + (litLength/255) > olimit)))
+ return 0; /* Check output limit */
+ if (litLength>=RUN_MASK)
+ {
+ int len = (int)litLength-RUN_MASK;
+ *token=(RUN_MASK<<ML_BITS);
+ for(; len >= 255 ; len-=255) *op++ = 255;
+ *op++ = (BYTE)len;
+ }
+ else *token = (BYTE)(litLength<<ML_BITS);
+
+ /* Copy Literals */
+ LZ4_wildCopy(op, anchor, op+litLength);
+ op+=litLength;
+ }
+
+_next_match:
+ /* Encode Offset */
+ LZ4_writeLE16(op, (U16)(ip-match)); op+=2;
+
+ /* Encode MatchLength */
+ {
+ unsigned matchLength;
+
+ if ((dict==usingExtDict) && (lowLimit==dictionary))
+ {
+ const BYTE* limit;
+ match += refDelta;
+ limit = ip + (dictEnd-match);
+ if (limit > matchlimit) limit = matchlimit;
+ matchLength = LZ4_count(ip+MINMATCH, match+MINMATCH, limit);
+ ip += MINMATCH + matchLength;
+ if (ip==limit)
+ {
+ unsigned more = LZ4_count(ip, (const BYTE*)source, matchlimit);
+ matchLength += more;
+ ip += more;
+ }
+ }
+ else
+ {
+ matchLength = LZ4_count(ip+MINMATCH, match+MINMATCH, matchlimit);
+ ip += MINMATCH + matchLength;
+ }
+
+ if ((outputLimited) && (unlikely(op + (1 + LASTLITERALS) + (matchLength>>8) > olimit)))
+ return 0; /* Check output limit */
+ if (matchLength>=ML_MASK)
+ {
+ *token += ML_MASK;
+ matchLength -= ML_MASK;
+ for (; matchLength >= 510 ; matchLength-=510) { *op++ = 255; *op++ = 255; }
+ if (matchLength >= 255) { matchLength-=255; *op++ = 255; }
+ *op++ = (BYTE)matchLength;
+ }
+ else *token += (BYTE)(matchLength);
+ }
+
+ anchor = ip;
+
+ /* Test end of chunk */
+ if (ip > mflimit) break;
+
+ /* Fill table */
+ LZ4_putPosition(ip-2, ctx, tableType, base);
+
+ /* Test next position */
+ match = LZ4_getPosition(ip, ctx, tableType, base);
+ if (dict==usingExtDict)
+ {
+ if (match<(const BYTE*)source)
+ {
+ refDelta = dictDelta;
+ lowLimit = dictionary;
+ }
+ else
+ {
+ refDelta = 0;
+ lowLimit = (const BYTE*)source;
+ }
+ }
+ LZ4_putPosition(ip, ctx, tableType, base);
+ if ( ((dictIssue==dictSmall) ? (match>=lowRefLimit) : 1)
+ && (match+MAX_DISTANCE>=ip)
+ && (LZ4_read32(match+refDelta)==LZ4_read32(ip)) )
+ { token=op++; *token=0; goto _next_match; }
+
+ /* Prepare next loop */
+ forwardH = LZ4_hashPosition(++ip, tableType);
+ }
+
+_last_literals:
+ /* Encode Last Literals */
+ {
+ const size_t lastRun = (size_t)(iend - anchor);
+ if ((outputLimited) && ((op - (BYTE*)dest) + lastRun + 1 + ((lastRun+255-RUN_MASK)/255) > (U32)maxOutputSize))
+ return 0; /* Check output limit */
+ if (lastRun >= RUN_MASK)
+ {
+ size_t accumulator = lastRun - RUN_MASK;
+ *op++ = RUN_MASK << ML_BITS;
+ for(; accumulator >= 255 ; accumulator-=255) *op++ = 255;
+ *op++ = (BYTE) accumulator;
+ }
+ else
+ {
+ *op++ = (BYTE)(lastRun<<ML_BITS);
+ }
+ memcpy(op, anchor, lastRun);
+ op += lastRun;
+ }
+
+ /* End */
+ return (int) (((char*)op)-dest);
+}
+
+
+int LZ4_compress_fast_extState(void* state, const char* source, char* dest, int inputSize, int maxOutputSize, int acceleration)
+{
+ LZ4_resetStream((LZ4_stream_t*)state);
+ if (acceleration < 1) acceleration = ACCELERATION_DEFAULT;
+
+ if (maxOutputSize >= LZ4_compressBound(inputSize))
+ {
+ if (inputSize < LZ4_64Klimit)
+ return LZ4_compress_generic(state, source, dest, inputSize, 0, notLimited, byU16, noDict, noDictIssue, acceleration);
+ else
+ return LZ4_compress_generic(state, source, dest, inputSize, 0, notLimited, LZ4_64bits() ? byU32 : byPtr, noDict, noDictIssue, acceleration);
+ }
+ else
+ {
+ if (inputSize < LZ4_64Klimit)
+ return LZ4_compress_generic(state, source, dest, inputSize, maxOutputSize, limitedOutput, byU16, noDict, noDictIssue, acceleration);
+ else
+ return LZ4_compress_generic(state, source, dest, inputSize, maxOutputSize, limitedOutput, LZ4_64bits() ? byU32 : byPtr, noDict, noDictIssue, acceleration);
+ }
+}
+
+
+int LZ4_compress_fast(const char* source, char* dest, int inputSize, int maxOutputSize, int acceleration)
+{
+#if (HEAPMODE)
+ void* ctxPtr = ALLOCATOR(1, sizeof(LZ4_stream_t)); /* malloc-calloc always properly aligned */
+#else
+ LZ4_stream_t ctx;
+ void* ctxPtr = &ctx;
+#endif
+
+ int result = LZ4_compress_fast_extState(ctxPtr, source, dest, inputSize, maxOutputSize, acceleration);
+
+#if (HEAPMODE)
+ FREEMEM(ctxPtr);
+#endif
+ return result;
+}
+
+
+int LZ4_compress_default(const char* source, char* dest, int inputSize, int maxOutputSize)
+{
+ return LZ4_compress_fast(source, dest, inputSize, maxOutputSize, 1);
+}
+
+
+/* hidden debug function */
+/* strangely enough, gcc generates faster code when this function is uncommented, even if unused */
+int LZ4_compress_fast_force(const char* source, char* dest, int inputSize, int maxOutputSize, int acceleration)
+{
+ LZ4_stream_t ctx;
+
+ LZ4_resetStream(&ctx);
+
+ if (inputSize < LZ4_64Klimit)
+ return LZ4_compress_generic(&ctx, source, dest, inputSize, maxOutputSize, limitedOutput, byU16, noDict, noDictIssue, acceleration);
+ else
+ return LZ4_compress_generic(&ctx, source, dest, inputSize, maxOutputSize, limitedOutput, LZ4_64bits() ? byU32 : byPtr, noDict, noDictIssue, acceleration);
+}
+
+
+/********************************
+* destSize variant
+********************************/
+
+static int LZ4_compress_destSize_generic(
+ void* const ctx,
+ const char* const src,
+ char* const dst,
+ int* const srcSizePtr,
+ const int targetDstSize,
+ const tableType_t tableType)
+{
+ const BYTE* ip = (const BYTE*) src;
+ const BYTE* base = (const BYTE*) src;
+ const BYTE* lowLimit = (const BYTE*) src;
+ const BYTE* anchor = ip;
+ const BYTE* const iend = ip + *srcSizePtr;
+ const BYTE* const mflimit = iend - MFLIMIT;
+ const BYTE* const matchlimit = iend - LASTLITERALS;
+
+ BYTE* op = (BYTE*) dst;
+ BYTE* const oend = op + targetDstSize;
+ BYTE* const oMaxLit = op + targetDstSize - 2 /* offset */ - 8 /* because 8+MINMATCH==MFLIMIT */ - 1 /* token */;
+ BYTE* const oMaxMatch = op + targetDstSize - (LASTLITERALS + 1 /* token */);
+ BYTE* const oMaxSeq = oMaxLit - 1 /* token */;
+
+ U32 forwardH;
+
+
+ /* Init conditions */
+ if (targetDstSize < 1) return 0; /* Impossible to store anything */
+ if ((U32)*srcSizePtr > (U32)LZ4_MAX_INPUT_SIZE) return 0; /* Unsupported input size, too large (or negative) */
+ if ((tableType == byU16) && (*srcSizePtr>=LZ4_64Klimit)) return 0; /* Size too large (not within 64K limit) */
+ if (*srcSizePtr<LZ4_minLength) goto _last_literals; /* Input too small, no compression (all literals) */
+
+ /* First Byte */
+ *srcSizePtr = 0;
+ LZ4_putPosition(ip, ctx, tableType, base);
+ ip++; forwardH = LZ4_hashPosition(ip, tableType);
+
+ /* Main Loop */
+ for ( ; ; )
+ {
+ const BYTE* match;
+ BYTE* token;
+ {
+ const BYTE* forwardIp = ip;
+ unsigned step = 1;
+ unsigned searchMatchNb = 1 << LZ4_skipTrigger;
+
+ /* Find a match */
+ do {
+ U32 h = forwardH;
+ ip = forwardIp;
+ forwardIp += step;
+ step = (searchMatchNb++ >> LZ4_skipTrigger);
+
+ if (unlikely(forwardIp > mflimit))
+ goto _last_literals;
+
+ match = LZ4_getPositionOnHash(h, ctx, tableType, base);
+ forwardH = LZ4_hashPosition(forwardIp, tableType);
+ LZ4_putPositionOnHash(ip, h, ctx, tableType, base);
+
+ } while ( ((tableType==byU16) ? 0 : (match + MAX_DISTANCE < ip))
+ || (LZ4_read32(match) != LZ4_read32(ip)) );
+ }
+
+ /* Catch up */
+ while ((ip>anchor) && (match > lowLimit) && (unlikely(ip[-1]==match[-1]))) { ip--; match--; }
+
+ {
+ /* Encode Literal length */
+ unsigned litLength = (unsigned)(ip - anchor);
+ token = op++;
+ if (op + ((litLength+240)/255) + litLength > oMaxLit)
+ {
+ /* Not enough space for a last match */
+ op--;
+ goto _last_literals;
+ }
+ if (litLength>=RUN_MASK)
+ {
+ unsigned len = litLength - RUN_MASK;
+ *token=(RUN_MASK<<ML_BITS);
+ for(; len >= 255 ; len-=255) *op++ = 255;
+ *op++ = (BYTE)len;
+ }
+ else *token = (BYTE)(litLength<<ML_BITS);
+
+ /* Copy Literals */
+ LZ4_wildCopy(op, anchor, op+litLength);
+ op += litLength;
+ }
+
+_next_match:
+ /* Encode Offset */
+ LZ4_writeLE16(op, (U16)(ip-match)); op+=2;
+
+ /* Encode MatchLength */
+ {
+ size_t matchLength;
+
+ matchLength = LZ4_count(ip+MINMATCH, match+MINMATCH, matchlimit);
+
+ if (op + ((matchLength+240)/255) > oMaxMatch)
+ {
+ /* Match description too long : reduce it */
+ matchLength = (15-1) + (oMaxMatch-op) * 255;
+ }
+ //printf("offset %5i, matchLength%5i \n", (int)(ip-match), matchLength + MINMATCH);
+ ip += MINMATCH + matchLength;
+
+ if (matchLength>=ML_MASK)
+ {
+ *token += ML_MASK;
+ matchLength -= ML_MASK;
+ while (matchLength >= 255) { matchLength-=255; *op++ = 255; }
+ *op++ = (BYTE)matchLength;
+ }
+ else *token += (BYTE)(matchLength);
+ }
+
+ anchor = ip;
+
+ /* Test end of block */
+ if (ip > mflimit) break;
+ if (op > oMaxSeq) break;
+
+ /* Fill table */
+ LZ4_putPosition(ip-2, ctx, tableType, base);
+
+ /* Test next position */
+ match = LZ4_getPosition(ip, ctx, tableType, base);
+ LZ4_putPosition(ip, ctx, tableType, base);
+ if ( (match+MAX_DISTANCE>=ip)
+ && (LZ4_read32(match)==LZ4_read32(ip)) )
+ { token=op++; *token=0; goto _next_match; }
+
+ /* Prepare next loop */
+ forwardH = LZ4_hashPosition(++ip, tableType);
+ }
+
+_last_literals:
+ /* Encode Last Literals */
+ {
+ size_t lastRunSize = (size_t)(iend - anchor);
+ if (op + 1 /* token */ + ((lastRunSize+240)/255) /* litLength */ + lastRunSize /* literals */ > oend)
+ {
+ /* adapt lastRunSize to fill 'dst' */
+ lastRunSize = (oend-op) - 1;
+ lastRunSize -= (lastRunSize+240)/255;
+ }
+ ip = anchor + lastRunSize;
+
+ if (lastRunSize >= RUN_MASK)
+ {
+ size_t accumulator = lastRunSize - RUN_MASK;
+ *op++ = RUN_MASK << ML_BITS;
+ for(; accumulator >= 255 ; accumulator-=255) *op++ = 255;
+ *op++ = (BYTE) accumulator;
+ }
+ else
+ {
+ *op++ = (BYTE)(lastRunSize<<ML_BITS);
+ }
+ memcpy(op, anchor, lastRunSize);
+ op += lastRunSize;
+ }
+
+ /* End */
+ *srcSizePtr = (int) (((const char*)ip)-src);
+ return (int) (((char*)op)-dst);
+}
+
+
+static int LZ4_compress_destSize_extState (void* state, const char* src, char* dst, int* srcSizePtr, int targetDstSize)
+{
+ LZ4_resetStream((LZ4_stream_t*)state);
+
+ if (targetDstSize >= LZ4_compressBound(*srcSizePtr)) /* compression success is guaranteed */
+ {
+ return LZ4_compress_fast_extState(state, src, dst, *srcSizePtr, targetDstSize, 1);
+ }
+ else
+ {
+ if (*srcSizePtr < LZ4_64Klimit)
+ return LZ4_compress_destSize_generic(state, src, dst, srcSizePtr, targetDstSize, byU16);
+ else
+ return LZ4_compress_destSize_generic(state, src, dst, srcSizePtr, targetDstSize, LZ4_64bits() ? byU32 : byPtr);
+ }
+}
+
+
+int LZ4_compress_destSize(const char* src, char* dst, int* srcSizePtr, int targetDstSize)
+{
+#if (HEAPMODE)
+ void* ctx = ALLOCATOR(1, sizeof(LZ4_stream_t)); /* malloc-calloc always properly aligned */
+#else
+ LZ4_stream_t ctxBody;
+ void* ctx = &ctxBody;
+#endif
+
+ int result = LZ4_compress_destSize_extState(ctx, src, dst, srcSizePtr, targetDstSize);
+
+#if (HEAPMODE)
+ FREEMEM(ctx);
+#endif
+ return result;
+}
+
+
+
+/********************************
+* Streaming functions
+********************************/
+
+LZ4_stream_t* LZ4_createStream(void)
+{
+ LZ4_stream_t* lz4s = (LZ4_stream_t*)ALLOCATOR(8, LZ4_STREAMSIZE_U64);
+ LZ4_STATIC_ASSERT(LZ4_STREAMSIZE >= sizeof(LZ4_stream_t_internal)); /* A compilation error here means LZ4_STREAMSIZE is not large enough */
+ LZ4_resetStream(lz4s);
+ return lz4s;
+}
+
+void LZ4_resetStream (LZ4_stream_t* LZ4_stream)
+{
+ MEM_INIT(LZ4_stream, 0, sizeof(LZ4_stream_t));
+}
+
+int LZ4_freeStream (LZ4_stream_t* LZ4_stream)
+{
+ FREEMEM(LZ4_stream);
+ return (0);
+}
+
+
+#define HASH_UNIT sizeof(size_t)
+int LZ4_loadDict (LZ4_stream_t* LZ4_dict, const char* dictionary, int dictSize)
+{
+ LZ4_stream_t_internal* dict = (LZ4_stream_t_internal*) LZ4_dict;
+ const BYTE* p = (const BYTE*)dictionary;
+ const BYTE* const dictEnd = p + dictSize;
+ const BYTE* base;
+
+ if ((dict->initCheck) || (dict->currentOffset > 1 GB)) /* Uninitialized structure, or reuse overflow */
+ LZ4_resetStream(LZ4_dict);
+
+ if (dictSize < (int)HASH_UNIT)
+ {
+ dict->dictionary = NULL;
+ dict->dictSize = 0;
+ return 0;
+ }
+
+ if ((dictEnd - p) > 64 KB) p = dictEnd - 64 KB;
+ dict->currentOffset += 64 KB;
+ base = p - dict->currentOffset;
+ dict->dictionary = p;
+ dict->dictSize = (U32)(dictEnd - p);
+ dict->currentOffset += dict->dictSize;
+
+ while (p <= dictEnd-HASH_UNIT)
+ {
+ LZ4_putPosition(p, dict->hashTable, byU32, base);
+ p+=3;
+ }
+
+ return dict->dictSize;
+}
+
+
+static void LZ4_renormDictT(LZ4_stream_t_internal* LZ4_dict, const BYTE* src)
+{
+ if ((LZ4_dict->currentOffset > 0x80000000) ||
+ ((size_t)LZ4_dict->currentOffset > (size_t)src)) /* address space overflow */
+ {
+ /* rescale hash table */
+ U32 delta = LZ4_dict->currentOffset - 64 KB;
+ const BYTE* dictEnd = LZ4_dict->dictionary + LZ4_dict->dictSize;
+ int i;
+ for (i=0; i<HASH_SIZE_U32; i++)
+ {
+ if (LZ4_dict->hashTable[i] < delta) LZ4_dict->hashTable[i]=0;
+ else LZ4_dict->hashTable[i] -= delta;
+ }
+ LZ4_dict->currentOffset = 64 KB;
+ if (LZ4_dict->dictSize > 64 KB) LZ4_dict->dictSize = 64 KB;
+ LZ4_dict->dictionary = dictEnd - LZ4_dict->dictSize;
+ }
+}
+
+
+int LZ4_compress_fast_continue (LZ4_stream_t* LZ4_stream, const char* source, char* dest, int inputSize, int maxOutputSize, int acceleration)
+{
+ LZ4_stream_t_internal* streamPtr = (LZ4_stream_t_internal*)LZ4_stream;
+ const BYTE* const dictEnd = streamPtr->dictionary + streamPtr->dictSize;
+
+ const BYTE* smallest = (const BYTE*) source;
+ if (streamPtr->initCheck) return 0; /* Uninitialized structure detected */
+ if ((streamPtr->dictSize>0) && (smallest>dictEnd)) smallest = dictEnd;
+ LZ4_renormDictT(streamPtr, smallest);
+ if (acceleration < 1) acceleration = ACCELERATION_DEFAULT;
+
+ /* Check overlapping input/dictionary space */
+ {
+ const BYTE* sourceEnd = (const BYTE*) source + inputSize;
+ if ((sourceEnd > streamPtr->dictionary) && (sourceEnd < dictEnd))
+ {
+ streamPtr->dictSize = (U32)(dictEnd - sourceEnd);
+ if (streamPtr->dictSize > 64 KB) streamPtr->dictSize = 64 KB;
+ if (streamPtr->dictSize < 4) streamPtr->dictSize = 0;
+ streamPtr->dictionary = dictEnd - streamPtr->dictSize;
+ }
+ }
+
+ /* prefix mode : source data follows dictionary */
+ if (dictEnd == (const BYTE*)source)
+ {
+ int result;
+ if ((streamPtr->dictSize < 64 KB) && (streamPtr->dictSize < streamPtr->currentOffset))
+ result = LZ4_compress_generic(LZ4_stream, source, dest, inputSize, maxOutputSize, limitedOutput, byU32, withPrefix64k, dictSmall, acceleration);
+ else
+ result = LZ4_compress_generic(LZ4_stream, source, dest, inputSize, maxOutputSize, limitedOutput, byU32, withPrefix64k, noDictIssue, acceleration);
+ streamPtr->dictSize += (U32)inputSize;
+ streamPtr->currentOffset += (U32)inputSize;
+ return result;
+ }
+
+ /* external dictionary mode */
+ {
+ int result;
+ if ((streamPtr->dictSize < 64 KB) && (streamPtr->dictSize < streamPtr->currentOffset))
+ result = LZ4_compress_generic(LZ4_stream, source, dest, inputSize, maxOutputSize, limitedOutput, byU32, usingExtDict, dictSmall, acceleration);
+ else
+ result = LZ4_compress_generic(LZ4_stream, source, dest, inputSize, maxOutputSize, limitedOutput, byU32, usingExtDict, noDictIssue, acceleration);
+ streamPtr->dictionary = (const BYTE*)source;
+ streamPtr->dictSize = (U32)inputSize;
+ streamPtr->currentOffset += (U32)inputSize;
+ return result;
+ }
+}
+
+
+/* Hidden debug function, to force external dictionary mode */
+int LZ4_compress_forceExtDict (LZ4_stream_t* LZ4_dict, const char* source, char* dest, int inputSize)
+{
+ LZ4_stream_t_internal* streamPtr = (LZ4_stream_t_internal*)LZ4_dict;
+ int result;
+ const BYTE* const dictEnd = streamPtr->dictionary + streamPtr->dictSize;
+
+ const BYTE* smallest = dictEnd;
+ if (smallest > (const BYTE*) source) smallest = (const BYTE*) source;
+ LZ4_renormDictT((LZ4_stream_t_internal*)LZ4_dict, smallest);
+
+ result = LZ4_compress_generic(LZ4_dict, source, dest, inputSize, 0, notLimited, byU32, usingExtDict, noDictIssue, 1);
+
+ streamPtr->dictionary = (const BYTE*)source;
+ streamPtr->dictSize = (U32)inputSize;
+ streamPtr->currentOffset += (U32)inputSize;
+
+ return result;
+}
+
+
+int LZ4_saveDict (LZ4_stream_t* LZ4_dict, char* safeBuffer, int dictSize)
+{
+ LZ4_stream_t_internal* dict = (LZ4_stream_t_internal*) LZ4_dict;
+ const BYTE* previousDictEnd = dict->dictionary + dict->dictSize;
+
+ if ((U32)dictSize > 64 KB) dictSize = 64 KB; /* useless to define a dictionary > 64 KB */
+ if ((U32)dictSize > dict->dictSize) dictSize = dict->dictSize;
+
+ memmove(safeBuffer, previousDictEnd - dictSize, dictSize);
+
+ dict->dictionary = (const BYTE*)safeBuffer;
+ dict->dictSize = (U32)dictSize;
+
+ return dictSize;
+}
+
+
+
+/*******************************
+* Decompression functions
+*******************************/
+/*
+ * This generic decompression function cover all use cases.
+ * It shall be instantiated several times, using different sets of directives
+ * Note that it is essential this generic function is really inlined,
+ * in order to remove useless branches during compilation optimization.
+ */
+FORCE_INLINE int LZ4_decompress_generic(
+ const char* const source,
+ char* const dest,
+ int inputSize,
+ int outputSize, /* If endOnInput==endOnInputSize, this value is the max size of Output Buffer. */
+
+ int endOnInput, /* endOnOutputSize, endOnInputSize */
+ int partialDecoding, /* full, partial */
+ int targetOutputSize, /* only used if partialDecoding==partial */
+ int dict, /* noDict, withPrefix64k, usingExtDict */
+ const BYTE* const lowPrefix, /* == dest if dict == noDict */
+ const BYTE* const dictStart, /* only if dict==usingExtDict */
+ const size_t dictSize /* note : = 0 if noDict */
+ )
+{
+ /* Local Variables */
+ const BYTE* ip = (const BYTE*) source;
+ const BYTE* const iend = ip + inputSize;
+
+ BYTE* op = (BYTE*) dest;
+ BYTE* const oend = op + outputSize;
+ BYTE* cpy;
+ BYTE* oexit = op + targetOutputSize;
+ const BYTE* const lowLimit = lowPrefix - dictSize;
+
+ const BYTE* const dictEnd = (const BYTE*)dictStart + dictSize;
+ const size_t dec32table[] = {4, 1, 2, 1, 4, 4, 4, 4};
+ const size_t dec64table[] = {0, 0, 0, (size_t)-1, 0, 1, 2, 3};
+
+ const int safeDecode = (endOnInput==endOnInputSize);
+ const int checkOffset = ((safeDecode) && (dictSize < (int)(64 KB)));
+
+
+ /* Special cases */
+ if ((partialDecoding) && (oexit> oend-MFLIMIT)) oexit = oend-MFLIMIT; /* targetOutputSize too high => decode everything */
+ if ((endOnInput) && (unlikely(outputSize==0))) return ((inputSize==1) && (*ip==0)) ? 0 : -1; /* Empty output buffer */
+ if ((!endOnInput) && (unlikely(outputSize==0))) return (*ip==0?1:-1);
+
+
+ /* Main Loop */
+ while (1)
+ {
+ unsigned token;
+ size_t length;
+ const BYTE* match;
+
+ /* get literal length */
+ token = *ip++;
+ if ((length=(token>>ML_BITS)) == RUN_MASK)
+ {
+ unsigned s;
+ do
+ {
+ s = *ip++;
+ length += s;
+ }
+ while (likely((endOnInput)?ip<iend-RUN_MASK:1) && (s==255));
+ if ((safeDecode) && unlikely((size_t)(op+length)<(size_t)(op))) goto _output_error; /* overflow detection */
+ if ((safeDecode) && unlikely((size_t)(ip+length)<(size_t)(ip))) goto _output_error; /* overflow detection */
+ }
+
+ /* copy literals */
+ cpy = op+length;
+ if (((endOnInput) && ((cpy>(partialDecoding?oexit:oend-MFLIMIT)) || (ip+length>iend-(2+1+LASTLITERALS))) )
+ || ((!endOnInput) && (cpy>oend-COPYLENGTH)))
+ {
+ if (partialDecoding)
+ {
+ if (cpy > oend) goto _output_error; /* Error : write attempt beyond end of output buffer */
+ if ((endOnInput) && (ip+length > iend)) goto _output_error; /* Error : read attempt beyond end of input buffer */
+ }
+ else
+ {
+ if ((!endOnInput) && (cpy != oend)) goto _output_error; /* Error : block decoding must stop exactly there */
+ if ((endOnInput) && ((ip+length != iend) || (cpy > oend))) goto _output_error; /* Error : input must be consumed */
+ }
+ memcpy(op, ip, length);
+ ip += length;
+ op += length;
+ break; /* Necessarily EOF, due to parsing restrictions */
+ }
+ LZ4_wildCopy(op, ip, cpy);
+ ip += length; op = cpy;
+
+ /* get offset */
+ match = cpy - LZ4_readLE16(ip); ip+=2;
+ if ((checkOffset) && (unlikely(match < lowLimit))) goto _output_error; /* Error : offset outside destination buffer */
+
+ /* get matchlength */
+ length = token & ML_MASK;
+ if (length == ML_MASK)
+ {
+ unsigned s;
+ do
+ {
+ if ((endOnInput) && (ip > iend-LASTLITERALS)) goto _output_error;
+ s = *ip++;
+ length += s;
+ } while (s==255);
+ if ((safeDecode) && unlikely((size_t)(op+length)<(size_t)op)) goto _output_error; /* overflow detection */
+ }
+ length += MINMATCH;
+
+ /* check external dictionary */
+ if ((dict==usingExtDict) && (match < lowPrefix))
+ {
+ if (unlikely(op+length > oend-LASTLITERALS)) goto _output_error; /* doesn't respect parsing restriction */
+
+ if (length <= (size_t)(lowPrefix-match))
+ {
+ /* match can be copied as a single segment from external dictionary */
+ match = dictEnd - (lowPrefix-match);
+ memmove(op, match, length); op += length;
+ }
+ else
+ {
+ /* match encompass external dictionary and current segment */
+ size_t copySize = (size_t)(lowPrefix-match);
+ memcpy(op, dictEnd - copySize, copySize);
+ op += copySize;
+ copySize = length - copySize;
+ if (copySize > (size_t)(op-lowPrefix)) /* overlap within current segment */
+ {
+ BYTE* const endOfMatch = op + copySize;
+ const BYTE* copyFrom = lowPrefix;
+ while (op < endOfMatch) *op++ = *copyFrom++;
+ }
+ else
+ {
+ memcpy(op, lowPrefix, copySize);
+ op += copySize;
+ }
+ }
+ continue;
+ }
+
+ /* copy repeated sequence */
+ cpy = op + length;
+ if (unlikely((op-match)<8))
+ {
+ const size_t dec64 = dec64table[op-match];
+ op[0] = match[0];
+ op[1] = match[1];
+ op[2] = match[2];
+ op[3] = match[3];
+ match += dec32table[op-match];
+ LZ4_copy4(op+4, match);
+ op += 8; match -= dec64;
+ } else { LZ4_copy8(op, match); op+=8; match+=8; }
+
+ if (unlikely(cpy>oend-12))
+ {
+ if (cpy > oend-LASTLITERALS) goto _output_error; /* Error : last LASTLITERALS bytes must be literals */
+ if (op < oend-8)
+ {
+ LZ4_wildCopy(op, match, oend-8);
+ match += (oend-8) - op;
+ op = oend-8;
+ }
+ while (op<cpy) *op++ = *match++;
+ }
+ else
+ LZ4_wildCopy(op, match, cpy);
+ op=cpy; /* correction */
+ }
+
+ /* end of decoding */
+ if (endOnInput)
+ return (int) (((char*)op)-dest); /* Nb of output bytes decoded */
+ else
+ return (int) (((const char*)ip)-source); /* Nb of input bytes read */
+
+ /* Overflow error detected */
+_output_error:
+ return (int) (-(((const char*)ip)-source))-1;
+}
+
+
+int LZ4_decompress_safe(const char* source, char* dest, int compressedSize, int maxDecompressedSize)
+{
+ return LZ4_decompress_generic(source, dest, compressedSize, maxDecompressedSize, endOnInputSize, full, 0, noDict, (BYTE*)dest, NULL, 0);
+}
+
+int LZ4_decompress_safe_partial(const char* source, char* dest, int compressedSize, int targetOutputSize, int maxDecompressedSize)
+{
+ return LZ4_decompress_generic(source, dest, compressedSize, maxDecompressedSize, endOnInputSize, partial, targetOutputSize, noDict, (BYTE*)dest, NULL, 0);
+}
+
+int LZ4_decompress_fast(const char* source, char* dest, int originalSize)
+{
+ return LZ4_decompress_generic(source, dest, 0, originalSize, endOnOutputSize, full, 0, withPrefix64k, (BYTE*)(dest - 64 KB), NULL, 64 KB);
+}
+
+
+/* streaming decompression functions */
+
+typedef struct
+{
+ const BYTE* externalDict;
+ size_t extDictSize;
+ const BYTE* prefixEnd;
+ size_t prefixSize;
+} LZ4_streamDecode_t_internal;
+
+/*
+ * If you prefer dynamic allocation methods,
+ * LZ4_createStreamDecode()
+ * provides a pointer (void*) towards an initialized LZ4_streamDecode_t structure.
+ */
+LZ4_streamDecode_t* LZ4_createStreamDecode(void)
+{
+ LZ4_streamDecode_t* lz4s = (LZ4_streamDecode_t*) ALLOCATOR(1, sizeof(LZ4_streamDecode_t));
+ return lz4s;
+}
+
+int LZ4_freeStreamDecode (LZ4_streamDecode_t* LZ4_stream)
+{
+ FREEMEM(LZ4_stream);
+ return 0;
+}
+
+/*
+ * LZ4_setStreamDecode
+ * Use this function to instruct where to find the dictionary
+ * This function is not necessary if previous data is still available where it was decoded.
+ * Loading a size of 0 is allowed (same effect as no dictionary).
+ * Return : 1 if OK, 0 if error
+ */
+int LZ4_setStreamDecode (LZ4_streamDecode_t* LZ4_streamDecode, const char* dictionary, int dictSize)
+{
+ LZ4_streamDecode_t_internal* lz4sd = (LZ4_streamDecode_t_internal*) LZ4_streamDecode;
+ lz4sd->prefixSize = (size_t) dictSize;
+ lz4sd->prefixEnd = (const BYTE*) dictionary + dictSize;
+ lz4sd->externalDict = NULL;
+ lz4sd->extDictSize = 0;
+ return 1;
+}
+
+/*
+*_continue() :
+ These decoding functions allow decompression of multiple blocks in "streaming" mode.
+ Previously decoded blocks must still be available at the memory position where they were decoded.
+ If it's not possible, save the relevant part of decoded data into a safe buffer,
+ and indicate where it stands using LZ4_setStreamDecode()
+*/
+int LZ4_decompress_safe_continue (LZ4_streamDecode_t* LZ4_streamDecode, const char* source, char* dest, int compressedSize, int maxOutputSize)
+{
+ LZ4_streamDecode_t_internal* lz4sd = (LZ4_streamDecode_t_internal*) LZ4_streamDecode;
+ int result;
+
+ if (lz4sd->prefixEnd == (BYTE*)dest)
+ {
+ result = LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize,
+ endOnInputSize, full, 0,
+ usingExtDict, lz4sd->prefixEnd - lz4sd->prefixSize, lz4sd->externalDict, lz4sd->extDictSize);
+ if (result <= 0) return result;
+ lz4sd->prefixSize += result;
+ lz4sd->prefixEnd += result;
+ }
+ else
+ {
+ lz4sd->extDictSize = lz4sd->prefixSize;
+ lz4sd->externalDict = lz4sd->prefixEnd - lz4sd->extDictSize;
+ result = LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize,
+ endOnInputSize, full, 0,
+ usingExtDict, (BYTE*)dest, lz4sd->externalDict, lz4sd->extDictSize);
+ if (result <= 0) return result;
+ lz4sd->prefixSize = result;
+ lz4sd->prefixEnd = (BYTE*)dest + result;
+ }
+
+ return result;
+}
+
+int LZ4_decompress_fast_continue (LZ4_streamDecode_t* LZ4_streamDecode, const char* source, char* dest, int originalSize)
+{
+ LZ4_streamDecode_t_internal* lz4sd = (LZ4_streamDecode_t_internal*) LZ4_streamDecode;
+ int result;
+
+ if (lz4sd->prefixEnd == (BYTE*)dest)
+ {
+ result = LZ4_decompress_generic(source, dest, 0, originalSize,
+ endOnOutputSize, full, 0,
+ usingExtDict, lz4sd->prefixEnd - lz4sd->prefixSize, lz4sd->externalDict, lz4sd->extDictSize);
+ if (result <= 0) return result;
+ lz4sd->prefixSize += originalSize;
+ lz4sd->prefixEnd += originalSize;
+ }
+ else
+ {
+ lz4sd->extDictSize = lz4sd->prefixSize;
+ lz4sd->externalDict = (BYTE*)dest - lz4sd->extDictSize;
+ result = LZ4_decompress_generic(source, dest, 0, originalSize,
+ endOnOutputSize, full, 0,
+ usingExtDict, (BYTE*)dest, lz4sd->externalDict, lz4sd->extDictSize);
+ if (result <= 0) return result;
+ lz4sd->prefixSize = originalSize;
+ lz4sd->prefixEnd = (BYTE*)dest + originalSize;
+ }
+
+ return result;
+}
+
+
+/*
+Advanced decoding functions :
+*_usingDict() :
+ These decoding functions work the same as "_continue" ones,
+ the dictionary must be explicitly provided within parameters
+*/
+
+FORCE_INLINE int LZ4_decompress_usingDict_generic(const char* source, char* dest, int compressedSize, int maxOutputSize, int safe, const char* dictStart, int dictSize)
+{
+ if (dictSize==0)
+ return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, safe, full, 0, noDict, (BYTE*)dest, NULL, 0);
+ if (dictStart+dictSize == dest)
+ {
+ if (dictSize >= (int)(64 KB - 1))
+ return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, safe, full, 0, withPrefix64k, (BYTE*)dest-64 KB, NULL, 0);
+ return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, safe, full, 0, noDict, (BYTE*)dest-dictSize, NULL, 0);
+ }
+ return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, safe, full, 0, usingExtDict, (BYTE*)dest, (const BYTE*)dictStart, dictSize);
+}
+
+int LZ4_decompress_safe_usingDict(const char* source, char* dest, int compressedSize, int maxOutputSize, const char* dictStart, int dictSize)
+{
+ return LZ4_decompress_usingDict_generic(source, dest, compressedSize, maxOutputSize, 1, dictStart, dictSize);
+}
+
+int LZ4_decompress_fast_usingDict(const char* source, char* dest, int originalSize, const char* dictStart, int dictSize)
+{
+ return LZ4_decompress_usingDict_generic(source, dest, 0, originalSize, 0, dictStart, dictSize);
+}
+
+/* debug function */
+int LZ4_decompress_safe_forceExtDict(const char* source, char* dest, int compressedSize, int maxOutputSize, const char* dictStart, int dictSize)
+{
+ return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, endOnInputSize, full, 0, usingExtDict, (BYTE*)dest, (const BYTE*)dictStart, dictSize);
+}
+
+
+/***************************************************
+* Obsolete Functions
+***************************************************/
+/* obsolete compression functions */
+int LZ4_compress_limitedOutput(const char* source, char* dest, int inputSize, int maxOutputSize) { return LZ4_compress_default(source, dest, inputSize, maxOutputSize); }
+int LZ4_compress(const char* source, char* dest, int inputSize) { return LZ4_compress_default(source, dest, inputSize, LZ4_compressBound(inputSize)); }
+int LZ4_compress_limitedOutput_withState (void* state, const char* src, char* dst, int srcSize, int dstSize) { return LZ4_compress_fast_extState(state, src, dst, srcSize, dstSize, 1); }
+int LZ4_compress_withState (void* state, const char* src, char* dst, int srcSize) { return LZ4_compress_fast_extState(state, src, dst, srcSize, LZ4_compressBound(srcSize), 1); }
+int LZ4_compress_limitedOutput_continue (LZ4_stream_t* LZ4_stream, const char* src, char* dst, int srcSize, int maxDstSize) { return LZ4_compress_fast_continue(LZ4_stream, src, dst, srcSize, maxDstSize, 1); }
+int LZ4_compress_continue (LZ4_stream_t* LZ4_stream, const char* source, char* dest, int inputSize) { return LZ4_compress_fast_continue(LZ4_stream, source, dest, inputSize, LZ4_compressBound(inputSize), 1); }
+
+/*
+These function names are deprecated and should no longer be used.
+They are only provided here for compatibility with older user programs.
+- LZ4_uncompress is totally equivalent to LZ4_decompress_fast
+- LZ4_uncompress_unknownOutputSize is totally equivalent to LZ4_decompress_safe
+*/
+int LZ4_uncompress (const char* source, char* dest, int outputSize) { return LZ4_decompress_fast(source, dest, outputSize); }
+int LZ4_uncompress_unknownOutputSize (const char* source, char* dest, int isize, int maxOutputSize) { return LZ4_decompress_safe(source, dest, isize, maxOutputSize); }
+
+
+/* Obsolete Streaming functions */
+
+int LZ4_sizeofStreamState() { return LZ4_STREAMSIZE; }
+
+static void LZ4_init(LZ4_stream_t_internal* lz4ds, BYTE* base)
+{
+ MEM_INIT(lz4ds, 0, LZ4_STREAMSIZE);
+ lz4ds->bufferStart = base;
+}
+
+int LZ4_resetStreamState(void* state, char* inputBuffer)
+{
+ if ((((size_t)state) & 3) != 0) return 1; /* Error : pointer is not aligned on 4-bytes boundary */
+ LZ4_init((LZ4_stream_t_internal*)state, (BYTE*)inputBuffer);
+ return 0;
+}
+
+void* LZ4_create (char* inputBuffer)
+{
+ void* lz4ds = ALLOCATOR(8, LZ4_STREAMSIZE_U64);
+ LZ4_init ((LZ4_stream_t_internal*)lz4ds, (BYTE*)inputBuffer);
+ return lz4ds;
+}
+
+char* LZ4_slideInputBuffer (void* LZ4_Data)
+{
+ LZ4_stream_t_internal* ctx = (LZ4_stream_t_internal*)LZ4_Data;
+ int dictSize = LZ4_saveDict((LZ4_stream_t*)LZ4_Data, (char*)ctx->bufferStart, 64 KB);
+ return (char*)(ctx->bufferStart + dictSize);
+}
+
+/* Obsolete streaming decompression functions */
+
+int LZ4_decompress_safe_withPrefix64k(const char* source, char* dest, int compressedSize, int maxOutputSize)
+{
+ return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, endOnInputSize, full, 0, withPrefix64k, (BYTE*)dest - 64 KB, NULL, 64 KB);
+}
+
+int LZ4_decompress_fast_withPrefix64k(const char* source, char* dest, int originalSize)
+{
+ return LZ4_decompress_generic(source, dest, 0, originalSize, endOnOutputSize, full, 0, withPrefix64k, (BYTE*)dest - 64 KB, NULL, 64 KB);
+}
+
+#endif /* LZ4_COMMONDEFS_ONLY */
+
+#endif /* NEED_COMPAT_LZ4 */
diff --git a/src/compat/compat-lz4.h b/src/compat/compat-lz4.h
new file mode 100644
index 0000000..3e74002
--- /dev/null
+++ b/src/compat/compat-lz4.h
@@ -0,0 +1,360 @@
+/*
+ LZ4 - Fast LZ compression algorithm
+ Header File
+ Copyright (C) 2011-2015, Yann Collet.
+
+ BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following disclaimer
+ in the documentation and/or other materials provided with the
+ distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ You can contact the author at :
+ - LZ4 source repository : https://github.com/Cyan4973/lz4
+ - LZ4 public forum : https://groups.google.com/forum/#!forum/lz4c
+*/
+#pragma once
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+/*
+ * lz4.h provides block compression functions, and gives full buffer control to programmer.
+ * If you need to generate inter-operable compressed data (respecting LZ4 frame specification),
+ * and can let the library handle its own memory, please use lz4frame.h instead.
+*/
+
+/**************************************
+* Version
+**************************************/
+#define LZ4_VERSION_MAJOR 1 /* for breaking interface changes */
+#define LZ4_VERSION_MINOR 7 /* for new (non-breaking) interface capabilities */
+#define LZ4_VERSION_RELEASE 1 /* for tweaks, bug-fixes, or development */
+#define LZ4_VERSION_NUMBER (LZ4_VERSION_MAJOR *100*100 + LZ4_VERSION_MINOR *100 + LZ4_VERSION_RELEASE)
+int LZ4_versionNumber (void);
+
+/**************************************
+* Tuning parameter
+**************************************/
+/*
+ * LZ4_MEMORY_USAGE :
+ * Memory usage formula : N->2^N Bytes (examples : 10 -> 1KB; 12 -> 4KB ; 16 -> 64KB; 20 -> 1MB; etc.)
+ * Increasing memory usage improves compression ratio
+ * Reduced memory usage can improve speed, due to cache effect
+ * Default value is 14, for 16KB, which nicely fits into Intel x86 L1 cache
+ */
+#define LZ4_MEMORY_USAGE 14
+
+
+/**************************************
+* Simple Functions
+**************************************/
+
+int LZ4_compress_default(const char* source, char* dest, int sourceSize, int maxDestSize);
+int LZ4_decompress_safe (const char* source, char* dest, int compressedSize, int maxDecompressedSize);
+
+/*
+LZ4_compress_default() :
+ Compresses 'sourceSize' bytes from buffer 'source'
+ into already allocated 'dest' buffer of size 'maxDestSize'.
+ Compression is guaranteed to succeed if 'maxDestSize' >= LZ4_compressBound(sourceSize).
+ It also runs faster, so it's a recommended setting.
+ If the function cannot compress 'source' into a more limited 'dest' budget,
+ compression stops *immediately*, and the function result is zero.
+ As a consequence, 'dest' content is not valid.
+ This function never writes outside 'dest' buffer, nor read outside 'source' buffer.
+ sourceSize : Max supported value is LZ4_MAX_INPUT_VALUE
+ maxDestSize : full or partial size of buffer 'dest' (which must be already allocated)
+ return : the number of bytes written into buffer 'dest' (necessarily <= maxOutputSize)
+ or 0 if compression fails
+
+LZ4_decompress_safe() :
+ compressedSize : is the precise full size of the compressed block.
+ maxDecompressedSize : is the size of destination buffer, which must be already allocated.
+ return : the number of bytes decompressed into destination buffer (necessarily <= maxDecompressedSize)
+ If destination buffer is not large enough, decoding will stop and output an error code (<0).
+ If the source stream is detected malformed, the function will stop decoding and return a negative result.
+ This function is protected against buffer overflow exploits, including malicious data packets.
+ It never writes outside output buffer, nor reads outside input buffer.
+*/
+
+
+/**************************************
+* Advanced Functions
+**************************************/
+#define LZ4_MAX_INPUT_SIZE 0x7E000000 /* 2 113 929 216 bytes */
+#define LZ4_COMPRESSBOUND(isize) ((unsigned)(isize) > (unsigned)LZ4_MAX_INPUT_SIZE ? 0 : (isize) + ((isize)/255) + 16)
+
+/*
+LZ4_compressBound() :
+ Provides the maximum size that LZ4 compression may output in a "worst case" scenario (input data not compressible)
+ This function is primarily useful for memory allocation purposes (destination buffer size).
+ Macro LZ4_COMPRESSBOUND() is also provided for compilation-time evaluation (stack memory allocation for example).
+ Note that LZ4_compress_default() compress faster when dest buffer size is >= LZ4_compressBound(srcSize)
+ inputSize : max supported value is LZ4_MAX_INPUT_SIZE
+ return : maximum output size in a "worst case" scenario
+ or 0, if input size is too large ( > LZ4_MAX_INPUT_SIZE)
+*/
+int LZ4_compressBound(int inputSize);
+
+/*
+LZ4_compress_fast() :
+ Same as LZ4_compress_default(), but allows to select an "acceleration" factor.
+ The larger the acceleration value, the faster the algorithm, but also the lesser the compression.
+ It's a trade-off. It can be fine tuned, with each successive value providing roughly +~3% to speed.
+ An acceleration value of "1" is the same as regular LZ4_compress_default()
+ Values <= 0 will be replaced by ACCELERATION_DEFAULT (see lz4.c), which is 1.
+*/
+int LZ4_compress_fast (const char* source, char* dest, int sourceSize, int maxDestSize, int acceleration);
+
+
+/*
+LZ4_compress_fast_extState() :
+ Same compression function, just using an externally allocated memory space to store compression state.
+ Use LZ4_sizeofState() to know how much memory must be allocated,
+ and allocate it on 8-bytes boundaries (using malloc() typically).
+ Then, provide it as 'void* state' to compression function.
+*/
+int LZ4_sizeofState(void);
+int LZ4_compress_fast_extState (void* state, const char* source, char* dest, int inputSize, int maxDestSize, int acceleration);
+
+
+/*
+LZ4_compress_destSize() :
+ Reverse the logic, by compressing as much data as possible from 'source' buffer
+ into already allocated buffer 'dest' of size 'targetDestSize'.
+ This function either compresses the entire 'source' content into 'dest' if it's large enough,
+ or fill 'dest' buffer completely with as much data as possible from 'source'.
+ *sourceSizePtr : will be modified to indicate how many bytes where read from 'source' to fill 'dest'.
+ New value is necessarily <= old value.
+ return : Nb bytes written into 'dest' (necessarily <= targetDestSize)
+ or 0 if compression fails
+*/
+int LZ4_compress_destSize (const char* source, char* dest, int* sourceSizePtr, int targetDestSize);
+
+
+/*
+LZ4_decompress_fast() :
+ originalSize : is the original and therefore uncompressed size
+ return : the number of bytes read from the source buffer (in other words, the compressed size)
+ If the source stream is detected malformed, the function will stop decoding and return a negative result.
+ Destination buffer must be already allocated. Its size must be a minimum of 'originalSize' bytes.
+ note : This function fully respect memory boundaries for properly formed compressed data.
+ It is a bit faster than LZ4_decompress_safe().
+ However, it does not provide any protection against intentionally modified data stream (malicious input).
+ Use this function in trusted environment only (data to decode comes from a trusted source).
+*/
+int LZ4_decompress_fast (const char* source, char* dest, int originalSize);
+
+/*
+LZ4_decompress_safe_partial() :
+ This function decompress a compressed block of size 'compressedSize' at position 'source'
+ into destination buffer 'dest' of size 'maxDecompressedSize'.
+ The function tries to stop decompressing operation as soon as 'targetOutputSize' has been reached,
+ reducing decompression time.
+ return : the number of bytes decoded in the destination buffer (necessarily <= maxDecompressedSize)
+ Note : this number can be < 'targetOutputSize' should the compressed block to decode be smaller.
+ Always control how many bytes were decoded.
+ If the source stream is detected malformed, the function will stop decoding and return a negative result.
+ This function never writes outside of output buffer, and never reads outside of input buffer. It is therefore protected against malicious data packets
+*/
+int LZ4_decompress_safe_partial (const char* source, char* dest, int compressedSize, int targetOutputSize, int maxDecompressedSize);
+
+
+/***********************************************
+* Streaming Compression Functions
+***********************************************/
+#define LZ4_STREAMSIZE_U64 ((1 << (LZ4_MEMORY_USAGE-3)) + 4)
+#define LZ4_STREAMSIZE (LZ4_STREAMSIZE_U64 * sizeof(long long))
+/*
+ * LZ4_stream_t
+ * information structure to track an LZ4 stream.
+ * important : init this structure content before first use !
+ * note : only allocated directly the structure if you are statically linking LZ4
+ * If you are using liblz4 as a DLL, please use below construction methods instead.
+ */
+typedef struct { long long table[LZ4_STREAMSIZE_U64]; } LZ4_stream_t;
+
+/*
+ * LZ4_resetStream
+ * Use this function to init an allocated LZ4_stream_t structure
+ */
+void LZ4_resetStream (LZ4_stream_t* streamPtr);
+
+/*
+ * LZ4_createStream will allocate and initialize an LZ4_stream_t structure
+ * LZ4_freeStream releases its memory.
+ * In the context of a DLL (liblz4), please use these methods rather than the static struct.
+ * They are more future proof, in case of a change of LZ4_stream_t size.
+ */
+LZ4_stream_t* LZ4_createStream(void);
+int LZ4_freeStream (LZ4_stream_t* streamPtr);
+
+/*
+ * LZ4_loadDict
+ * Use this function to load a static dictionary into LZ4_stream.
+ * Any previous data will be forgotten, only 'dictionary' will remain in memory.
+ * Loading a size of 0 is allowed.
+ * Return : dictionary size, in bytes (necessarily <= 64 KB)
+ */
+int LZ4_loadDict (LZ4_stream_t* streamPtr, const char* dictionary, int dictSize);
+
+/*
+ * LZ4_compress_fast_continue
+ * Compress buffer content 'src', using data from previously compressed blocks as dictionary to improve compression ratio.
+ * Important : Previous data blocks are assumed to still be present and unmodified !
+ * 'dst' buffer must be already allocated.
+ * If maxDstSize >= LZ4_compressBound(srcSize), compression is guaranteed to succeed, and runs faster.
+ * If not, and if compressed data cannot fit into 'dst' buffer size, compression stops, and function returns a zero.
+ */
+int LZ4_compress_fast_continue (LZ4_stream_t* streamPtr, const char* src, char* dst, int srcSize, int maxDstSize, int acceleration);
+
+/*
+ * LZ4_saveDict
+ * If previously compressed data block is not guaranteed to remain available at its memory location
+ * save it into a safer place (char* safeBuffer)
+ * Note : you don't need to call LZ4_loadDict() afterwards,
+ * dictionary is immediately usable, you can therefore call LZ4_compress_fast_continue()
+ * Return : saved dictionary size in bytes (necessarily <= dictSize), or 0 if error
+ */
+int LZ4_saveDict (LZ4_stream_t* streamPtr, char* safeBuffer, int dictSize);
+
+
+/************************************************
+* Streaming Decompression Functions
+************************************************/
+
+#define LZ4_STREAMDECODESIZE_U64 4
+#define LZ4_STREAMDECODESIZE (LZ4_STREAMDECODESIZE_U64 * sizeof(unsigned long long))
+typedef struct { unsigned long long table[LZ4_STREAMDECODESIZE_U64]; } LZ4_streamDecode_t;
+/*
+ * LZ4_streamDecode_t
+ * information structure to track an LZ4 stream.
+ * init this structure content using LZ4_setStreamDecode or memset() before first use !
+ *
+ * In the context of a DLL (liblz4) please prefer usage of construction methods below.
+ * They are more future proof, in case of a change of LZ4_streamDecode_t size in the future.
+ * LZ4_createStreamDecode will allocate and initialize an LZ4_streamDecode_t structure
+ * LZ4_freeStreamDecode releases its memory.
+ */
+LZ4_streamDecode_t* LZ4_createStreamDecode(void);
+int LZ4_freeStreamDecode (LZ4_streamDecode_t* LZ4_stream);
+
+/*
+ * LZ4_setStreamDecode
+ * Use this function to instruct where to find the dictionary.
+ * Setting a size of 0 is allowed (same effect as reset).
+ * Return : 1 if OK, 0 if error
+ */
+int LZ4_setStreamDecode (LZ4_streamDecode_t* LZ4_streamDecode, const char* dictionary, int dictSize);
+
+/*
+*_continue() :
+ These decoding functions allow decompression of multiple blocks in "streaming" mode.
+ Previously decoded blocks *must* remain available at the memory position where they were decoded (up to 64 KB)
+ In the case of a ring buffers, decoding buffer must be either :
+ - Exactly same size as encoding buffer, with same update rule (block boundaries at same positions)
+ In which case, the decoding & encoding ring buffer can have any size, including very small ones ( < 64 KB).
+ - Larger than encoding buffer, by a minimum of maxBlockSize more bytes.
+ maxBlockSize is implementation dependent. It's the maximum size you intend to compress into a single block.
+ In which case, encoding and decoding buffers do not need to be synchronized,
+ and encoding ring buffer can have any size, including small ones ( < 64 KB).
+ - _At least_ 64 KB + 8 bytes + maxBlockSize.
+ In which case, encoding and decoding buffers do not need to be synchronized,
+ and encoding ring buffer can have any size, including larger than decoding buffer.
+ Whenever these conditions are not possible, save the last 64KB of decoded data into a safe buffer,
+ and indicate where it is saved using LZ4_setStreamDecode()
+*/
+int LZ4_decompress_safe_continue (LZ4_streamDecode_t* LZ4_streamDecode, const char* source, char* dest, int compressedSize, int maxDecompressedSize);
+int LZ4_decompress_fast_continue (LZ4_streamDecode_t* LZ4_streamDecode, const char* source, char* dest, int originalSize);
+
+
+/*
+Advanced decoding functions :
+*_usingDict() :
+ These decoding functions work the same as
+ a combination of LZ4_setStreamDecode() followed by LZ4_decompress_x_continue()
+ They are stand-alone. They don't need nor update an LZ4_streamDecode_t structure.
+*/
+int LZ4_decompress_safe_usingDict (const char* source, char* dest, int compressedSize, int maxDecompressedSize, const char* dictStart, int dictSize);
+int LZ4_decompress_fast_usingDict (const char* source, char* dest, int originalSize, const char* dictStart, int dictSize);
+
+
+
+/**************************************
+* Obsolete Functions
+**************************************/
+/* Deprecate Warnings */
+/* Should these warnings messages be a problem,
+ it is generally possible to disable them,
+ with -Wno-deprecated-declarations for gcc
+ or _CRT_SECURE_NO_WARNINGS in Visual for example.
+ You can also define LZ4_DEPRECATE_WARNING_DEFBLOCK. */
+#ifndef LZ4_DEPRECATE_WARNING_DEFBLOCK
+# define LZ4_DEPRECATE_WARNING_DEFBLOCK
+# define LZ4_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
+# if (LZ4_GCC_VERSION >= 405) || defined(__clang__)
+# define LZ4_DEPRECATED(message) __attribute__((deprecated(message)))
+# elif (LZ4_GCC_VERSION >= 301)
+# define LZ4_DEPRECATED(message) __attribute__((deprecated))
+# elif defined(_MSC_VER)
+# define LZ4_DEPRECATED(message) __declspec(deprecated(message))
+# else
+# pragma message("WARNING: You need to implement LZ4_DEPRECATED for this compiler")
+# define LZ4_DEPRECATED(message)
+# endif
+#endif /* LZ4_DEPRECATE_WARNING_DEFBLOCK */
+
+/* Obsolete compression functions */
+/* These functions are planned to start generate warnings by r131 approximately */
+int LZ4_compress (const char* source, char* dest, int sourceSize);
+int LZ4_compress_limitedOutput (const char* source, char* dest, int sourceSize, int maxOutputSize);
+int LZ4_compress_withState (void* state, const char* source, char* dest, int inputSize);
+int LZ4_compress_limitedOutput_withState (void* state, const char* source, char* dest, int inputSize, int maxOutputSize);
+int LZ4_compress_continue (LZ4_stream_t* LZ4_streamPtr, const char* source, char* dest, int inputSize);
+int LZ4_compress_limitedOutput_continue (LZ4_stream_t* LZ4_streamPtr, const char* source, char* dest, int inputSize, int maxOutputSize);
+
+/* Obsolete decompression functions */
+/* These function names are completely deprecated and must no longer be used.
+ They are only provided here for compatibility with older programs.
+ - LZ4_uncompress is the same as LZ4_decompress_fast
+ - LZ4_uncompress_unknownOutputSize is the same as LZ4_decompress_safe
+ These function prototypes are now disabled; uncomment them only if you really need them.
+ It is highly recommended to stop using these prototypes and migrate to maintained ones */
+/* int LZ4_uncompress (const char* source, char* dest, int outputSize); */
+/* int LZ4_uncompress_unknownOutputSize (const char* source, char* dest, int isize, int maxOutputSize); */
+
+/* Obsolete streaming functions; use new streaming interface whenever possible */
+LZ4_DEPRECATED("use LZ4_createStream() instead") void* LZ4_create (char* inputBuffer);
+LZ4_DEPRECATED("use LZ4_createStream() instead") int LZ4_sizeofStreamState(void);
+LZ4_DEPRECATED("use LZ4_resetStream() instead") int LZ4_resetStreamState(void* state, char* inputBuffer);
+LZ4_DEPRECATED("use LZ4_saveDict() instead") char* LZ4_slideInputBuffer (void* state);
+
+/* Obsolete streaming decoding functions */
+LZ4_DEPRECATED("use LZ4_decompress_safe_usingDict() instead") int LZ4_decompress_safe_withPrefix64k (const char* src, char* dst, int compressedSize, int maxDstSize);
+LZ4_DEPRECATED("use LZ4_decompress_fast_usingDict() instead") int LZ4_decompress_fast_withPrefix64k (const char* src, char* dst, int originalSize);
+
+
+#if defined (__cplusplus)
+}
+#endif
diff --git a/src/compat/compat.vcxproj b/src/compat/compat.vcxproj
index 1dedb33..d2695e6 100644
--- a/src/compat/compat.vcxproj
+++ b/src/compat/compat.vcxproj
@@ -79,6 +79,7 @@
<ClCompile Include="compat-inet_ntop.c" />
<ClCompile Include="compat-inet_pton.c" />
<ClCompile Include="compat-daemon.c" />
+ <ClCompile Include="compat-lz4.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="compat.h" />
@@ -86,4 +87,4 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
-</Project> \ No newline at end of file
+</Project>
diff --git a/src/compat/compat.vcxproj.filters b/src/compat/compat.vcxproj.filters
index 00bb0ff..0f78e86 100644
--- a/src/compat/compat.vcxproj.filters
+++ b/src/compat/compat.vcxproj.filters
@@ -33,6 +33,9 @@
<ClCompile Include="compat-daemon.c">
<Filter>Source Files</Filter>
</ClCompile>
+ <ClCompile Include="compat-lz4.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="compat.h">
diff --git a/src/openvpn/Makefile.am b/src/openvpn/Makefile.am
index 6d02fea..4c18449 100644
--- a/src/openvpn/Makefile.am
+++ b/src/openvpn/Makefile.am
@@ -18,7 +18,7 @@ EXTRA_DIST = \
openvpn.vcxproj \
openvpn.vcxproj.filters
-INCLUDES = \
+AM_CPPFLAGS = \
-I$(top_srcdir)/include \
-I$(top_srcdir)/src/compat
@@ -26,6 +26,7 @@ AM_CFLAGS = \
$(TAP_CFLAGS) \
$(OPTIONAL_CRYPTO_CFLAGS) \
$(OPTIONAL_LZO_CFLAGS) \
+ $(OPTIONAL_LZ4_CFLAGS) \
$(OPTIONAL_PKCS11_HELPER_CFLAGS)
if WIN32
# we want unicode entry point but not the macro
@@ -35,15 +36,18 @@ endif
sbin_PROGRAMS = openvpn
openvpn_SOURCES = \
+ argv.c argv.h \
base64.c base64.h \
basic.h \
buffer.c buffer.h \
circ_list.h \
clinat.c clinat.h \
common.h \
+ comp.c comp.h compstub.c \
+ comp-lz4.c comp-lz4.h \
crypto.c crypto.h crypto_backend.h \
crypto_openssl.c crypto_openssl.h \
- crypto_polarssl.c crypto_polarssl.h \
+ crypto_mbedtls.c crypto_mbedtls.h \
dhcp.c dhcp.h \
errlevel.h \
error.c error.h \
@@ -65,7 +69,7 @@ openvpn_SOURCES = \
memdbg.h \
misc.c misc.h \
platform.c platform.h \
- console.c console.h \
+ console.c console.h console_builtin.c console_systemd.c \
mroute.c mroute.h \
mss.c mss.h \
mstats.c mstats.h \
@@ -77,7 +81,7 @@ openvpn_SOURCES = \
occ.c occ.h occ-inline.h \
pkcs11.c pkcs11.h pkcs11_backend.h \
pkcs11_openssl.c \
- pkcs11_polarssl.c \
+ pkcs11_mbedtls.c \
openvpn.c openvpn.h \
options.c options.h \
otime.c otime.h \
@@ -102,26 +106,28 @@ openvpn_SOURCES = \
socks.c socks.h \
ssl.c ssl.h ssl_backend.h \
ssl_openssl.c ssl_openssl.h \
- ssl_polarssl.c ssl_polarssl.h \
+ ssl_mbedtls.c ssl_mbedtls.h \
ssl_common.h \
ssl_verify.c ssl_verify.h ssl_verify_backend.h \
ssl_verify_openssl.c ssl_verify_openssl.h \
- ssl_verify_polarssl.c ssl_verify_polarssl.h \
+ ssl_verify_mbedtls.c ssl_verify_mbedtls.h \
status.c status.h \
syshead.h \
+ tls_crypt.c tls_crypt.h \
tun.c tun.h \
- win32.h win32_wfp.h win32.c \
+ win32.h win32.c \
cryptoapi.h cryptoapi.c
openvpn_LDADD = \
$(top_builddir)/src/compat/libcompat.la \
$(SOCKETS_LIBS) \
$(OPTIONAL_LZO_LIBS) \
+ $(OPTIONAL_LZ4_LIBS) \
$(OPTIONAL_PKCS11_HELPER_LIBS) \
$(OPTIONAL_CRYPTO_LIBS) \
$(OPTIONAL_SELINUX_LIBS) \
$(OPTIONAL_SYSTEMD_LIBS) \
$(OPTIONAL_DL_LIBS)
if WIN32
-openvpn_SOURCES += openvpn_win32_resources.rc
-openvpn_LDADD += -lgdi32 -lws2_32 -lwininet -lcrypt32 -liphlpapi -lrpcrt4 -lwinmm
+openvpn_SOURCES += openvpn_win32_resources.rc block_dns.c block_dns.h
+openvpn_LDADD += -lgdi32 -lws2_32 -lwininet -lcrypt32 -liphlpapi -lwinmm -lfwpuclnt -lrpcrt4
endif
diff --git a/src/openvpn/Makefile.in b/src/openvpn/Makefile.in
index 3691c96..ff15d6d 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.13.4 from Makefile.am.
# @configure_input@
-# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -37,17 +37,7 @@
# Required to build Windows resource file
VPATH = @srcdir@
-am__is_gnu_make = { \
- if test -z '$(MAKELEVEL)'; then \
- false; \
- elif test -n '$(MAKE_HOST)'; then \
- true; \
- elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
- true; \
- else \
- false; \
- fi; \
-}
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
am__make_running_with_option = \
case $${target_option-} in \
?) ;; \
@@ -110,11 +100,13 @@ PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
+DIST_COMMON = $(top_srcdir)/build/ltrc.inc $(srcdir)/Makefile.in \
+ $(srcdir)/Makefile.am $(top_srcdir)/depcomp
# we want unicode entry point but not the macro
@WIN32_TRUE@am__append_1 = -municode -UUNICODE
sbin_PROGRAMS = openvpn$(EXEEXT)
-@WIN32_TRUE@am__append_2 = openvpn_win32_resources.rc
-@WIN32_TRUE@am__append_3 = -lgdi32 -lws2_32 -lwininet -lcrypt32 -liphlpapi -lrpcrt4 -lwinmm
+@WIN32_TRUE@am__append_2 = openvpn_win32_resources.rc block_dns.c block_dns.h
+@WIN32_TRUE@am__append_3 = -lgdi32 -lws2_32 -lwininet -lcrypt32 -liphlpapi -lwinmm -lfwpuclnt -lrpcrt4
subdir = src/openvpn
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/ax_emptyarray.m4 \
@@ -126,63 +118,68 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_emptyarray.m4 \
$(top_srcdir)/compat.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
-DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
mkinstalldirs = $(install_sh) -d
-CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_HEADER = $(top_builddir)/config.h \
+ $(top_builddir)/include/openvpn-plugin.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
am__installdirs = "$(DESTDIR)$(sbindir)"
PROGRAMS = $(sbin_PROGRAMS)
-am__openvpn_SOURCES_DIST = base64.c base64.h basic.h buffer.c buffer.h \
- circ_list.h clinat.c clinat.h common.h crypto.c crypto.h \
- crypto_backend.h crypto_openssl.c crypto_openssl.h \
- crypto_polarssl.c crypto_polarssl.h dhcp.c dhcp.h errlevel.h \
+am__openvpn_SOURCES_DIST = argv.c argv.h base64.c base64.h basic.h \
+ buffer.c buffer.h circ_list.h clinat.c clinat.h common.h \
+ comp.c comp.h compstub.c comp-lz4.c comp-lz4.h crypto.c \
+ crypto.h crypto_backend.h crypto_openssl.c crypto_openssl.h \
+ crypto_mbedtls.c crypto_mbedtls.h dhcp.c dhcp.h errlevel.h \
error.c error.h event.c event.h fdmisc.c fdmisc.h forward.c \
forward.h forward-inline.h fragment.c fragment.h gremlin.c \
gremlin.h helper.c helper.h httpdigest.c httpdigest.h lladdr.c \
lladdr.h init.c init.h integer.h interval.c interval.h list.c \
list.h lzo.c lzo.h manage.c manage.h mbuf.c mbuf.h memdbg.h \
misc.c misc.h platform.c platform.h console.c console.h \
- mroute.c mroute.h mss.c mss.h mstats.c mstats.h mtcp.c mtcp.h \
- mtu.c mtu.h mudp.c mudp.h multi.c multi.h ntlm.c ntlm.h occ.c \
- occ.h occ-inline.h pkcs11.c pkcs11.h pkcs11_backend.h \
- pkcs11_openssl.c pkcs11_polarssl.c openvpn.c openvpn.h \
- options.c options.h otime.c otime.h packet_id.c packet_id.h \
- perf.c perf.h pf.c pf.h pf-inline.h ping.c ping.h \
- ping-inline.h plugin.c plugin.h pool.c pool.h proto.c proto.h \
- proxy.c proxy.h ps.c ps.h push.c push.h pushlist.h reliable.c \
- reliable.h route.c route.h schedule.c schedule.h session_id.c \
- session_id.h shaper.c shaper.h sig.c sig.h socket.c socket.h \
- socks.c socks.h ssl.c ssl.h ssl_backend.h ssl_openssl.c \
- ssl_openssl.h ssl_polarssl.c ssl_polarssl.h ssl_common.h \
- ssl_verify.c ssl_verify.h ssl_verify_backend.h \
- ssl_verify_openssl.c ssl_verify_openssl.h \
- ssl_verify_polarssl.c ssl_verify_polarssl.h status.c status.h \
- syshead.h tun.c tun.h win32.h win32_wfp.h win32.c cryptoapi.h \
- cryptoapi.c openvpn_win32_resources.rc
-@WIN32_TRUE@am__objects_1 = openvpn_win32_resources.$(OBJEXT)
-am_openvpn_OBJECTS = base64.$(OBJEXT) buffer.$(OBJEXT) \
- clinat.$(OBJEXT) crypto.$(OBJEXT) crypto_openssl.$(OBJEXT) \
- crypto_polarssl.$(OBJEXT) dhcp.$(OBJEXT) error.$(OBJEXT) \
+ console_builtin.c console_systemd.c mroute.c mroute.h mss.c \
+ mss.h mstats.c mstats.h mtcp.c mtcp.h mtu.c mtu.h mudp.c \
+ mudp.h multi.c multi.h ntlm.c ntlm.h occ.c occ.h occ-inline.h \
+ pkcs11.c pkcs11.h pkcs11_backend.h pkcs11_openssl.c \
+ pkcs11_mbedtls.c openvpn.c openvpn.h options.c options.h \
+ otime.c otime.h packet_id.c packet_id.h perf.c perf.h pf.c \
+ pf.h pf-inline.h ping.c ping.h ping-inline.h plugin.c plugin.h \
+ pool.c pool.h proto.c proto.h proxy.c proxy.h ps.c ps.h push.c \
+ push.h pushlist.h reliable.c reliable.h route.c route.h \
+ schedule.c schedule.h session_id.c session_id.h shaper.c \
+ shaper.h sig.c sig.h socket.c socket.h socks.c socks.h ssl.c \
+ ssl.h ssl_backend.h ssl_openssl.c ssl_openssl.h ssl_mbedtls.c \
+ ssl_mbedtls.h ssl_common.h ssl_verify.c ssl_verify.h \
+ ssl_verify_backend.h ssl_verify_openssl.c ssl_verify_openssl.h \
+ ssl_verify_mbedtls.c ssl_verify_mbedtls.h status.c status.h \
+ syshead.h tls_crypt.c tls_crypt.h tun.c tun.h win32.h win32.c \
+ cryptoapi.h cryptoapi.c openvpn_win32_resources.rc block_dns.c \
+ block_dns.h
+@WIN32_TRUE@am__objects_1 = openvpn_win32_resources.$(OBJEXT) \
+@WIN32_TRUE@ block_dns.$(OBJEXT)
+am_openvpn_OBJECTS = argv.$(OBJEXT) base64.$(OBJEXT) buffer.$(OBJEXT) \
+ clinat.$(OBJEXT) comp.$(OBJEXT) compstub.$(OBJEXT) \
+ comp-lz4.$(OBJEXT) crypto.$(OBJEXT) crypto_openssl.$(OBJEXT) \
+ crypto_mbedtls.$(OBJEXT) dhcp.$(OBJEXT) error.$(OBJEXT) \
event.$(OBJEXT) fdmisc.$(OBJEXT) forward.$(OBJEXT) \
fragment.$(OBJEXT) gremlin.$(OBJEXT) helper.$(OBJEXT) \
httpdigest.$(OBJEXT) lladdr.$(OBJEXT) init.$(OBJEXT) \
interval.$(OBJEXT) list.$(OBJEXT) lzo.$(OBJEXT) \
manage.$(OBJEXT) mbuf.$(OBJEXT) misc.$(OBJEXT) \
- platform.$(OBJEXT) console.$(OBJEXT) mroute.$(OBJEXT) \
- mss.$(OBJEXT) mstats.$(OBJEXT) mtcp.$(OBJEXT) mtu.$(OBJEXT) \
- mudp.$(OBJEXT) multi.$(OBJEXT) ntlm.$(OBJEXT) occ.$(OBJEXT) \
- pkcs11.$(OBJEXT) pkcs11_openssl.$(OBJEXT) \
- pkcs11_polarssl.$(OBJEXT) openvpn.$(OBJEXT) options.$(OBJEXT) \
- otime.$(OBJEXT) packet_id.$(OBJEXT) perf.$(OBJEXT) \
- pf.$(OBJEXT) ping.$(OBJEXT) plugin.$(OBJEXT) pool.$(OBJEXT) \
- proto.$(OBJEXT) proxy.$(OBJEXT) ps.$(OBJEXT) push.$(OBJEXT) \
- reliable.$(OBJEXT) route.$(OBJEXT) schedule.$(OBJEXT) \
- session_id.$(OBJEXT) shaper.$(OBJEXT) sig.$(OBJEXT) \
- socket.$(OBJEXT) socks.$(OBJEXT) ssl.$(OBJEXT) \
- ssl_openssl.$(OBJEXT) ssl_polarssl.$(OBJEXT) \
- ssl_verify.$(OBJEXT) ssl_verify_openssl.$(OBJEXT) \
- ssl_verify_polarssl.$(OBJEXT) status.$(OBJEXT) tun.$(OBJEXT) \
+ platform.$(OBJEXT) console.$(OBJEXT) console_builtin.$(OBJEXT) \
+ console_systemd.$(OBJEXT) mroute.$(OBJEXT) mss.$(OBJEXT) \
+ mstats.$(OBJEXT) mtcp.$(OBJEXT) mtu.$(OBJEXT) mudp.$(OBJEXT) \
+ multi.$(OBJEXT) ntlm.$(OBJEXT) occ.$(OBJEXT) pkcs11.$(OBJEXT) \
+ pkcs11_openssl.$(OBJEXT) pkcs11_mbedtls.$(OBJEXT) \
+ openvpn.$(OBJEXT) options.$(OBJEXT) otime.$(OBJEXT) \
+ packet_id.$(OBJEXT) perf.$(OBJEXT) pf.$(OBJEXT) ping.$(OBJEXT) \
+ plugin.$(OBJEXT) pool.$(OBJEXT) proto.$(OBJEXT) \
+ proxy.$(OBJEXT) ps.$(OBJEXT) push.$(OBJEXT) reliable.$(OBJEXT) \
+ route.$(OBJEXT) schedule.$(OBJEXT) session_id.$(OBJEXT) \
+ shaper.$(OBJEXT) sig.$(OBJEXT) socket.$(OBJEXT) \
+ socks.$(OBJEXT) ssl.$(OBJEXT) ssl_openssl.$(OBJEXT) \
+ ssl_mbedtls.$(OBJEXT) ssl_verify.$(OBJEXT) \
+ ssl_verify_openssl.$(OBJEXT) ssl_verify_mbedtls.$(OBJEXT) \
+ status.$(OBJEXT) tls_crypt.$(OBJEXT) tun.$(OBJEXT) \
win32.$(OBJEXT) cryptoapi.$(OBJEXT) $(am__objects_1)
openvpn_OBJECTS = $(am_openvpn_OBJECTS)
am__DEPENDENCIES_1 =
@@ -190,7 +187,8 @@ openvpn_DEPENDENCIES = $(top_builddir)/src/compat/libcompat.la \
$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
- $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1)
AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
am__v_lt_0 = --silent
@@ -207,7 +205,7 @@ AM_V_at = $(am__v_at_@AM_V@)
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
am__v_at_0 = @
am__v_at_1 =
-DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) -I$(top_builddir)/include
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
am__mv = mv -f
@@ -255,8 +253,6 @@ am__define_uniq_tagged_files = \
done | $(am__uniquify_input)`
ETAGS = etags
CTAGS = ctags
-am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/build/ltrc.inc \
- $(top_srcdir)/depcomp
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
@@ -270,6 +266,7 @@ AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
+CMAKE = @CMAKE@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
@@ -304,25 +301,31 @@ LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
-LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+LZ4_CFLAGS = @LZ4_CFLAGS@
+LZ4_LIBS = @LZ4_LIBS@
LZO_CFLAGS = @LZO_CFLAGS@
LZO_LIBS = @LZO_LIBS@
MAKEINFO = @MAKEINFO@
MAN2HTML = @MAN2HTML@
MANIFEST_TOOL = @MANIFEST_TOOL@
+MBEDTLS_CFLAGS = @MBEDTLS_CFLAGS@
+MBEDTLS_LIBS = @MBEDTLS_LIBS@
MKDIR_P = @MKDIR_P@
NETSTAT = @NETSTAT@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
-OPENSSL_CRYPTO_CFLAGS = @OPENSSL_CRYPTO_CFLAGS@
-OPENSSL_CRYPTO_LIBS = @OPENSSL_CRYPTO_LIBS@
-OPENSSL_SSL_CFLAGS = @OPENSSL_SSL_CFLAGS@
-OPENSSL_SSL_LIBS = @OPENSSL_SSL_LIBS@
+OPENSSL_CFLAGS = @OPENSSL_CFLAGS@
+OPENSSL_LIBS = @OPENSSL_LIBS@
+OPENVPN_VERSION_MAJOR = @OPENVPN_VERSION_MAJOR@
+OPENVPN_VERSION_MINOR = @OPENVPN_VERSION_MINOR@
+OPENVPN_VERSION_PATCH = @OPENVPN_VERSION_PATCH@
OPTIONAL_CRYPTO_CFLAGS = @OPTIONAL_CRYPTO_CFLAGS@
OPTIONAL_CRYPTO_LIBS = @OPTIONAL_CRYPTO_LIBS@
OPTIONAL_DL_LIBS = @OPTIONAL_DL_LIBS@
+OPTIONAL_LZ4_CFLAGS = @OPTIONAL_LZ4_CFLAGS@
+OPTIONAL_LZ4_LIBS = @OPTIONAL_LZ4_LIBS@
OPTIONAL_LZO_CFLAGS = @OPTIONAL_LZO_CFLAGS@
OPTIONAL_LZO_LIBS = @OPTIONAL_LZO_LIBS@
OPTIONAL_PKCS11_HELPER_CFLAGS = @OPTIONAL_PKCS11_HELPER_CFLAGS@
@@ -348,8 +351,6 @@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
PLUGIN_AUTH_PAM_CFLAGS = @PLUGIN_AUTH_PAM_CFLAGS@
PLUGIN_AUTH_PAM_LIBS = @PLUGIN_AUTH_PAM_LIBS@
-POLARSSL_CFLAGS = @POLARSSL_CFLAGS@
-POLARSSL_LIBS = @POLARSSL_LIBS@
RANLIB = @RANLIB@
RC = @RC@
ROUTE = @ROUTE@
@@ -364,6 +365,11 @@ TAP_CFLAGS = @TAP_CFLAGS@
TAP_WIN_COMPONENT_ID = @TAP_WIN_COMPONENT_ID@
TAP_WIN_MIN_MAJOR = @TAP_WIN_MIN_MAJOR@
TAP_WIN_MIN_MINOR = @TAP_WIN_MIN_MINOR@
+TEST_CFLAGS = @TEST_CFLAGS@
+TEST_LDFLAGS = @TEST_LDFLAGS@
+VENDOR_BUILD_ROOT = @VENDOR_BUILD_ROOT@
+VENDOR_DIST_ROOT = @VENDOR_DIST_ROOT@
+VENDOR_SRC_ROOT = @VENDOR_SRC_ROOT@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
@@ -432,42 +438,43 @@ EXTRA_DIST = \
openvpn.vcxproj \
openvpn.vcxproj.filters
-INCLUDES = \
+AM_CPPFLAGS = \
-I$(top_srcdir)/include \
-I$(top_srcdir)/src/compat
AM_CFLAGS = $(TAP_CFLAGS) $(OPTIONAL_CRYPTO_CFLAGS) \
- $(OPTIONAL_LZO_CFLAGS) $(OPTIONAL_PKCS11_HELPER_CFLAGS) \
- $(am__append_1)
-openvpn_SOURCES = base64.c base64.h basic.h buffer.c buffer.h \
- circ_list.h clinat.c clinat.h common.h crypto.c crypto.h \
+ $(OPTIONAL_LZO_CFLAGS) $(OPTIONAL_LZ4_CFLAGS) \
+ $(OPTIONAL_PKCS11_HELPER_CFLAGS) $(am__append_1)
+openvpn_SOURCES = argv.c argv.h base64.c base64.h basic.h buffer.c \
+ buffer.h circ_list.h clinat.c clinat.h common.h comp.c comp.h \
+ compstub.c comp-lz4.c comp-lz4.h crypto.c crypto.h \
crypto_backend.h crypto_openssl.c crypto_openssl.h \
- crypto_polarssl.c crypto_polarssl.h dhcp.c dhcp.h errlevel.h \
+ crypto_mbedtls.c crypto_mbedtls.h dhcp.c dhcp.h errlevel.h \
error.c error.h event.c event.h fdmisc.c fdmisc.h forward.c \
forward.h forward-inline.h fragment.c fragment.h gremlin.c \
gremlin.h helper.c helper.h httpdigest.c httpdigest.h lladdr.c \
lladdr.h init.c init.h integer.h interval.c interval.h list.c \
list.h lzo.c lzo.h manage.c manage.h mbuf.c mbuf.h memdbg.h \
misc.c misc.h platform.c platform.h console.c console.h \
- mroute.c mroute.h mss.c mss.h mstats.c mstats.h mtcp.c mtcp.h \
- mtu.c mtu.h mudp.c mudp.h multi.c multi.h ntlm.c ntlm.h occ.c \
- occ.h occ-inline.h pkcs11.c pkcs11.h pkcs11_backend.h \
- pkcs11_openssl.c pkcs11_polarssl.c openvpn.c openvpn.h \
- options.c options.h otime.c otime.h packet_id.c packet_id.h \
- perf.c perf.h pf.c pf.h pf-inline.h ping.c ping.h \
- ping-inline.h plugin.c plugin.h pool.c pool.h proto.c proto.h \
- proxy.c proxy.h ps.c ps.h push.c push.h pushlist.h reliable.c \
- reliable.h route.c route.h schedule.c schedule.h session_id.c \
- session_id.h shaper.c shaper.h sig.c sig.h socket.c socket.h \
- socks.c socks.h ssl.c ssl.h ssl_backend.h ssl_openssl.c \
- ssl_openssl.h ssl_polarssl.c ssl_polarssl.h ssl_common.h \
- ssl_verify.c ssl_verify.h ssl_verify_backend.h \
- ssl_verify_openssl.c ssl_verify_openssl.h \
- ssl_verify_polarssl.c ssl_verify_polarssl.h status.c status.h \
- syshead.h tun.c tun.h win32.h win32_wfp.h win32.c cryptoapi.h \
- cryptoapi.c $(am__append_2)
+ console_builtin.c console_systemd.c mroute.c mroute.h mss.c \
+ mss.h mstats.c mstats.h mtcp.c mtcp.h mtu.c mtu.h mudp.c \
+ mudp.h multi.c multi.h ntlm.c ntlm.h occ.c occ.h occ-inline.h \
+ pkcs11.c pkcs11.h pkcs11_backend.h pkcs11_openssl.c \
+ pkcs11_mbedtls.c openvpn.c openvpn.h options.c options.h \
+ otime.c otime.h packet_id.c packet_id.h perf.c perf.h pf.c \
+ pf.h pf-inline.h ping.c ping.h ping-inline.h plugin.c plugin.h \
+ pool.c pool.h proto.c proto.h proxy.c proxy.h ps.c ps.h push.c \
+ push.h pushlist.h reliable.c reliable.h route.c route.h \
+ schedule.c schedule.h session_id.c session_id.h shaper.c \
+ shaper.h sig.c sig.h socket.c socket.h socks.c socks.h ssl.c \
+ ssl.h ssl_backend.h ssl_openssl.c ssl_openssl.h ssl_mbedtls.c \
+ ssl_mbedtls.h ssl_common.h ssl_verify.c ssl_verify.h \
+ ssl_verify_backend.h ssl_verify_openssl.c ssl_verify_openssl.h \
+ ssl_verify_mbedtls.c ssl_verify_mbedtls.h status.c status.h \
+ syshead.h tls_crypt.c tls_crypt.h tun.c tun.h win32.h win32.c \
+ cryptoapi.h cryptoapi.c $(am__append_2)
openvpn_LDADD = $(top_builddir)/src/compat/libcompat.la \
- $(SOCKETS_LIBS) $(OPTIONAL_LZO_LIBS) \
+ $(SOCKETS_LIBS) $(OPTIONAL_LZO_LIBS) $(OPTIONAL_LZ4_LIBS) \
$(OPTIONAL_PKCS11_HELPER_LIBS) $(OPTIONAL_CRYPTO_LIBS) \
$(OPTIONAL_SELINUX_LIBS) $(OPTIONAL_SYSTEMD_LIBS) \
$(OPTIONAL_DL_LIBS) $(am__append_3)
@@ -487,6 +494,7 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(top_srcdir)/build/ltrc.inc $(am_
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/openvpn/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign src/openvpn/Makefile
+.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
@@ -495,7 +503,7 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
-$(top_srcdir)/build/ltrc.inc $(am__empty):
+$(top_srcdir)/build/ltrc.inc:
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
@@ -565,13 +573,20 @@ 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)/crypto_polarssl.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@
@@ -607,8 +622,8 @@ distclean-compile:
@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)/pkcs11_polarssl.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@
@@ -625,12 +640,13 @@ distclean-compile:
@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_polarssl.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)/ssl_verify_polarssl.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@
@@ -639,14 +655,14 @@ distclean-compile:
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $<
.c.obj:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'`
.c.lo:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@@ -868,8 +884,6 @@ uninstall-am: uninstall-sbinPROGRAMS
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
tags tags-am uninstall uninstall-am uninstall-sbinPROGRAMS
-.PRECIOUS: Makefile
-
.rc.lo:
$(LTRCCOMPILE) -i "$<" -o "$@"
diff --git a/src/openvpn/argv.c b/src/openvpn/argv.c
new file mode 100644
index 0000000..596e59c
--- /dev/null
+++ b/src/openvpn/argv.c
@@ -0,0 +1,315 @@
+/*
+ * OpenVPN -- An application to securely tunnel IP networks
+ * over a single TCP/UDP port, with support for SSL/TLS-based
+ * session authentication and key exchange,
+ * packet encryption, packet authentication, and
+ * packet compression.
+ *
+ * Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program (see the file COPYING included with this
+ * distribution); if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ *
+ * A printf-like function (that only recognizes a subset of standard printf
+ * format operators) that prints arguments to an argv list instead
+ * of a standard string. This is used to build up argv arrays for passing
+ * to execve.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#elif defined(_MSC_VER)
+#include "config-msvc.h"
+#endif
+
+#include "syshead.h"
+
+#include "argv.h"
+#include "options.h"
+
+static void
+argv_init (struct argv *a)
+{
+ a->capacity = 0;
+ a->argc = 0;
+ a->argv = NULL;
+}
+
+struct argv
+argv_new (void)
+{
+ struct argv ret;
+ argv_init (&ret);
+ return ret;
+}
+
+void
+argv_reset (struct argv *a)
+{
+ size_t i;
+ for (i = 0; i < a->argc; ++i)
+ free (a->argv[i]);
+ free (a->argv);
+ argv_init (a);
+}
+
+static void
+argv_extend (struct argv *a, const size_t newcap)
+{
+ if (newcap > a->capacity)
+ {
+ char **newargv;
+ size_t i;
+ ALLOC_ARRAY_CLEAR (newargv, char *, newcap);
+ for (i = 0; i < a->argc; ++i)
+ newargv[i] = a->argv[i];
+ free (a->argv);
+ a->argv = newargv;
+ a->capacity = newcap;
+ }
+}
+
+static void
+argv_grow (struct argv *a, const size_t add)
+{
+ const size_t newargc = a->argc + add + 1;
+ ASSERT (newargc > a->argc);
+ argv_extend (a, adjust_power_of_2 (newargc));
+}
+
+static void
+argv_append (struct argv *a, char *str) /* str must have been malloced or be NULL */
+{
+ argv_grow (a, 1);
+ a->argv[a->argc++] = str;
+}
+
+static struct argv
+argv_clone (const struct argv *a, const size_t headroom)
+{
+ struct argv r;
+ size_t i;
+
+ argv_init (&r);
+ for (i = 0; i < headroom; ++i)
+ argv_append (&r, NULL);
+ if (a)
+ {
+ for (i = 0; i < a->argc; ++i)
+ argv_append (&r, string_alloc (a->argv[i], NULL));
+ }
+ return r;
+}
+
+struct argv
+argv_insert_head (const struct argv *a, const char *head)
+{
+ struct argv r;
+ r = argv_clone (a, 1);
+ r.argv[0] = string_alloc (head, NULL);
+ return r;
+}
+
+static char *
+argv_term (const char **f)
+{
+ const char *p = *f;
+ const char *term = NULL;
+ size_t termlen = 0;
+
+ if (*p == '\0')
+ return NULL;
+
+ while (true)
+ {
+ const int c = *p;
+ if (c == '\0')
+ break;
+ if (term)
+ {
+ if (!isspace (c))
+ ++termlen;
+ else
+ break;
+ }
+ else
+ {
+ if (!isspace (c))
+ {
+ term = p;
+ termlen = 1;
+ }
+ }
+ ++p;
+ }
+ *f = p;
+
+ if (term)
+ {
+ char *ret;
+ ASSERT (termlen > 0);
+ ret = malloc (termlen + 1);
+ check_malloc_return (ret);
+ memcpy (ret, term, termlen);
+ ret[termlen] = '\0';
+ return ret;
+ }
+ else
+ return NULL;
+}
+
+const char *
+argv_str (const struct argv *a, struct gc_arena *gc, const unsigned int flags)
+{
+ if (a->argv)
+ return print_argv ((const char **)a->argv, gc, flags);
+ else
+ return "";
+}
+
+void
+argv_msg (const int msglev, const struct argv *a)
+{
+ struct gc_arena gc = gc_new ();
+ msg (msglev, "%s", argv_str (a, &gc, 0));
+ gc_free (&gc);
+}
+
+void
+argv_msg_prefix (const int msglev, const struct argv *a, const char *prefix)
+{
+ struct gc_arena gc = gc_new ();
+ msg (msglev, "%s: %s", prefix, argv_str (a, &gc, 0));
+ gc_free (&gc);
+}
+
+static void
+argv_printf_arglist (struct argv *a, const char *format, va_list arglist)
+{
+ char *term;
+ const char *f = format;
+
+ argv_extend (a, 1); /* ensure trailing NULL */
+
+ while ((term = argv_term (&f)) != NULL)
+ {
+ if (term[0] == '%')
+ {
+ if (!strcmp (term, "%s"))
+ {
+ char *s = va_arg (arglist, char *);
+ if (!s)
+ s = "";
+ argv_append (a, string_alloc (s, NULL));
+ }
+ else if (!strcmp (term, "%d"))
+ {
+ char numstr[64];
+ openvpn_snprintf (numstr, sizeof (numstr), "%d", va_arg (arglist, int));
+ argv_append (a, string_alloc (numstr, NULL));
+ }
+ else if (!strcmp (term, "%u"))
+ {
+ char numstr[64];
+ openvpn_snprintf (numstr, sizeof (numstr), "%u", va_arg (arglist, unsigned int));
+ argv_append (a, string_alloc (numstr, NULL));
+ }
+ else if (!strcmp (term, "%s/%d"))
+ {
+ char numstr[64];
+ char *s = va_arg (arglist, char *);
+
+ if (!s)
+ s = "";
+
+ openvpn_snprintf (numstr, sizeof (numstr), "%d", va_arg (arglist, int));
+
+ {
+ const size_t len = strlen(s) + strlen(numstr) + 2;
+ char *combined = (char *) malloc (len);
+ check_malloc_return (combined);
+
+ strcpy (combined, s);
+ strcat (combined, "/");
+ strcat (combined, numstr);
+ argv_append (a, combined);
+ }
+ }
+ else if (!strcmp (term, "%s%sc"))
+ {
+ char *s1 = va_arg (arglist, char *);
+ char *s2 = va_arg (arglist, char *);
+ char *combined;
+
+ if (!s1) s1 = "";
+ if (!s2) s2 = "";
+ combined = (char *) malloc (strlen(s1) + strlen(s2) + 1);
+ check_malloc_return (combined);
+ strcpy (combined, s1);
+ strcat (combined, s2);
+ argv_append (a, combined);
+ }
+ else
+ ASSERT (0);
+ free (term);
+ }
+ else
+ {
+ argv_append (a, term);
+ }
+ }
+}
+
+void
+argv_printf (struct argv *a, const char *format, ...)
+{
+ va_list arglist;
+ argv_reset (a);
+ va_start (arglist, format);
+ argv_printf_arglist (a, format, arglist);
+ va_end (arglist);
+ }
+
+void
+argv_printf_cat (struct argv *a, const char *format, ...)
+{
+ va_list arglist;
+ va_start (arglist, format);
+ argv_printf_arglist (a, format, arglist);
+ va_end (arglist);
+}
+
+void
+argv_parse_cmd (struct argv *a, const char *s)
+{
+ int nparms;
+ char *parms[MAX_PARMS + 1];
+ struct gc_arena gc = gc_new ();
+
+ argv_reset (a);
+ argv_extend (a, 1); /* ensure trailing NULL */
+
+ nparms = parse_line (s, parms, MAX_PARMS, "SCRIPT-ARGV", 0, D_ARGV_PARSE_CMD, &gc);
+ if (nparms)
+ {
+ int i;
+ for (i = 0; i < nparms; ++i)
+ argv_append (a, string_alloc (parms[i], NULL));
+ }
+ else
+ argv_append (a, string_alloc (s, NULL));
+
+ gc_free (&gc);
+}
diff --git a/src/openvpn/argv.h b/src/openvpn/argv.h
new file mode 100644
index 0000000..9aee641
--- /dev/null
+++ b/src/openvpn/argv.h
@@ -0,0 +1,70 @@
+/*
+ * OpenVPN -- An application to securely tunnel IP networks
+ * over a single TCP/UDP port, with support for SSL/TLS-based
+ * session authentication and key exchange,
+ * packet encryption, packet authentication, and
+ * packet compression.
+ *
+ * Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program (see the file COPYING included with this
+ * distribution); if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ *
+ * A printf-like function (that only recognizes a subset of standard printf
+ * format operators) that prints arguments to an argv list instead
+ * of a standard string. This is used to build up argv arrays for passing
+ * to execve.
+ */
+
+#ifndef ARGV_H
+#define ARGV_H
+
+#include "buffer.h"
+
+struct argv {
+ size_t capacity;
+ size_t argc;
+ char **argv;
+};
+
+struct argv argv_new (void);
+void argv_reset (struct argv *a);
+const char *argv_str (const struct argv *a, struct gc_arena *gc, const unsigned int flags);
+struct argv argv_insert_head (const struct argv *a, const char *head);
+void argv_msg (const int msglev, const struct argv *a);
+void argv_msg_prefix (const int msglev, const struct argv *a, const char *prefix);
+void argv_parse_cmd (struct argv *a, const char *s);
+
+void argv_printf (struct argv *a, const char *format, ...)
+#ifdef __GNUC__
+#if __USE_MINGW_ANSI_STDIO
+ __attribute__ ((format (gnu_printf, 2, 3)))
+#else
+ __attribute__ ((format (__printf__, 2, 3)))
+#endif
+#endif
+ ;
+
+void argv_printf_cat (struct argv *a, const char *format, ...)
+#ifdef __GNUC__
+#if __USE_MINGW_ANSI_STDIO
+ __attribute__ ((format (gnu_printf, 2, 3)))
+#else
+ __attribute__ ((format (__printf__, 2, 3)))
+#endif
+#endif
+ ;
+
+#endif
diff --git a/src/openvpn/base64.c b/src/openvpn/base64.c
index 7dccec2..258b258 100644
--- a/src/openvpn/base64.c
+++ b/src/openvpn/base64.c
@@ -39,8 +39,6 @@
#include "syshead.h"
-#if defined(ENABLE_HTTP_PROXY) || defined(ENABLE_PKCS11) || defined(ENABLE_CLIENT_CR) || defined(MANAGMENT_EXTERNAL_KEY)
-
#include "base64.h"
#include "memdbg.h"
@@ -163,7 +161,3 @@ openvpn_base64_decode(const char *str, void *data, int size)
}
return q - (unsigned char *) data;
}
-
-#else
-static void dummy(void) {}
-#endif /* ENABLE_HTTP_PROXY, ENABLE_PKCS11, ENABLE_CLIENT_CR */
diff --git a/src/openvpn/base64.h b/src/openvpn/base64.h
index 28a9677..92a195a 100644
--- a/src/openvpn/base64.h
+++ b/src/openvpn/base64.h
@@ -34,11 +34,7 @@
#ifndef _BASE64_H_
#define _BASE64_H_
-#if defined(ENABLE_HTTP_PROXY) || defined(ENABLE_PKCS11) || defined(ENABLE_CLIENT_CR) || defined(MANAGMENT_EXTERNAL_KEY)
-
int openvpn_base64_encode(const void *data, int size, char **str);
int openvpn_base64_decode(const char *str, void *data, int size);
#endif
-
-#endif
diff --git a/src/openvpn/block_dns.c b/src/openvpn/block_dns.c
new file mode 100644
index 0000000..cb3ce88
--- /dev/null
+++ b/src/openvpn/block_dns.c
@@ -0,0 +1,332 @@
+/*
+ * OpenVPN -- An application to securely tunnel IP networks
+ * over a single TCP/UDP port, with support for SSL/TLS-based
+ * session authentication and key exchange,
+ * packet encryption, packet authentication, and
+ * packet compression.
+ *
+ * Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net>
+ * 2015-2016 <iam@valdikss.org.ru>
+ * 2016 Selva Nair <selva.nair@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program (see the file COPYING included with this
+ * distribution); if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#elif defined(_MSC_VER)
+#include "config-msvc.h"
+#endif
+#ifdef HAVE_CONFIG_VERSION_H
+#include "config-version.h"
+#endif
+
+#include "syshead.h"
+
+#ifdef _WIN32
+
+#include <fwpmu.h>
+#include <initguid.h>
+#include <fwpmtypes.h>
+#include <winsock2.h>
+#include <ws2ipdef.h>
+#include <iphlpapi.h>
+#include "block_dns.h"
+
+/*
+ * WFP-related defines and GUIDs not in mingw32
+ */
+
+#ifndef FWPM_SESSION_FLAG_DYNAMIC
+#define FWPM_SESSION_FLAG_DYNAMIC 0x00000001
+#endif
+
+// c38d57d1-05a7-4c33-904f-7fbceee60e82
+DEFINE_GUID(
+ FWPM_LAYER_ALE_AUTH_CONNECT_V4,
+ 0xc38d57d1,
+ 0x05a7,
+ 0x4c33,
+ 0x90, 0x4f, 0x7f, 0xbc, 0xee, 0xe6, 0x0e, 0x82
+);
+
+// 4a72393b-319f-44bc-84c3-ba54dcb3b6b4
+DEFINE_GUID(
+ FWPM_LAYER_ALE_AUTH_CONNECT_V6,
+ 0x4a72393b,
+ 0x319f,
+ 0x44bc,
+ 0x84, 0xc3, 0xba, 0x54, 0xdc, 0xb3, 0xb6, 0xb4
+);
+
+// d78e1e87-8644-4ea5-9437-d809ecefc971
+DEFINE_GUID(
+ FWPM_CONDITION_ALE_APP_ID,
+ 0xd78e1e87,
+ 0x8644,
+ 0x4ea5,
+ 0x94, 0x37, 0xd8, 0x09, 0xec, 0xef, 0xc9, 0x71
+);
+
+// c35a604d-d22b-4e1a-91b4-68f674ee674b
+DEFINE_GUID(
+ FWPM_CONDITION_IP_REMOTE_PORT,
+ 0xc35a604d,
+ 0xd22b,
+ 0x4e1a,
+ 0x91, 0xb4, 0x68, 0xf6, 0x74, 0xee, 0x67, 0x4b
+);
+
+// 4cd62a49-59c3-4969-b7f3-bda5d32890a4
+DEFINE_GUID(
+ FWPM_CONDITION_IP_LOCAL_INTERFACE,
+ 0x4cd62a49,
+ 0x59c3,
+ 0x4969,
+ 0xb7, 0xf3, 0xbd, 0xa5, 0xd3, 0x28, 0x90, 0xa4
+);
+
+/* UUID of WFP sublayer used by all instances of openvpn
+ 2f660d7e-6a37-11e6-a181-001e8c6e04a2 */
+DEFINE_GUID(
+ OPENVPN_BLOCK_OUTSIDE_DNS_SUBLAYER,
+ 0x2f660d7e,
+ 0x6a37,
+ 0x11e6,
+ 0xa1, 0x81, 0x00, 0x1e, 0x8c, 0x6e, 0x04, 0xa2
+);
+
+static WCHAR *FIREWALL_NAME = L"OpenVPN";
+
+/*
+ * Default msg handler does nothing
+ */
+static inline void
+default_msg_handler (DWORD err, const char *msg)
+{
+ return;
+}
+
+#define CHECK_ERROR(err, msg) \
+ if (err) { msg_handler (err, msg); goto out; }
+
+/*
+ * Add a persistent sublayer with specified uuid.
+ */
+static DWORD
+add_sublayer (GUID uuid)
+{
+ FWPM_SESSION0 session;
+ HANDLE engine = NULL;
+ DWORD err = 0;
+ FWPM_SUBLAYER0 sublayer;
+
+ memset (&session, 0, sizeof(session));
+ memset (&sublayer, 0, sizeof(sublayer));
+
+ err = FwpmEngineOpen0 (NULL, RPC_C_AUTHN_WINNT, NULL, &session, &engine);
+ if (err != ERROR_SUCCESS)
+ goto out;
+
+ sublayer.subLayerKey = uuid;
+ sublayer.displayData.name = FIREWALL_NAME;
+ sublayer.displayData.description = FIREWALL_NAME;
+ sublayer.flags = 0;
+ sublayer.weight = 0x100;
+
+ /* Add sublayer to the session */
+ err = FwpmSubLayerAdd0 (engine, &sublayer, NULL);
+
+out:
+ if (engine)
+ FwpmEngineClose0 (engine);
+ return err;
+}
+
+/*
+ * Block outgoing port 53 traffic except for
+ * (i) adapter with the specified index
+ * OR
+ * (ii) processes with the specified executable path
+ * The firewall filters added here are automatically removed when the process exits or
+ * on calling delete_block_dns_filters().
+ * Arguments:
+ * engine_handle : On successful return contains the handle for a newly opened fwp session
+ * in which the filters are added.
+ * May be closed by passing to delete_block_dns_filters to remove the filters.
+ * index : The index of adapter for which traffic is permitted.
+ * exe_path : Path of executable for which traffic is permitted.
+ * msg_handler : An optional callback function for error reporting.
+ * Returns 0 on success, a non-zero status code of the last failed action on failure.
+ */
+
+DWORD
+add_block_dns_filters (HANDLE *engine_handle,
+ int index,
+ const WCHAR *exe_path,
+ block_dns_msg_handler_t msg_handler
+ )
+{
+ FWPM_SESSION0 session = {0};
+ FWPM_SUBLAYER0 *sublayer_ptr = NULL;
+ NET_LUID tapluid;
+ UINT64 filterid;
+ FWP_BYTE_BLOB *openvpnblob = NULL;
+ FWPM_FILTER0 Filter = {0};
+ FWPM_FILTER_CONDITION0 Condition[2] = {0};
+ DWORD err = 0;
+
+ if (!msg_handler)
+ msg_handler = default_msg_handler;
+
+ /* Add temporary filters which don't survive reboots or crashes. */
+ session.flags = FWPM_SESSION_FLAG_DYNAMIC;
+
+ *engine_handle = NULL;
+
+ err = FwpmEngineOpen0 (NULL, RPC_C_AUTHN_WINNT, NULL, &session, engine_handle);
+ CHECK_ERROR (err, "FwpEngineOpen: open fwp session failed");
+ msg_handler (0, "Block_DNS: WFP engine opened");
+
+ /* Check sublayer exists and add one if it does not. */
+ if (FwpmSubLayerGetByKey0 (*engine_handle, &OPENVPN_BLOCK_OUTSIDE_DNS_SUBLAYER, &sublayer_ptr)
+ == ERROR_SUCCESS)
+ {
+ msg_handler (0, "Block_DNS: Using existing sublayer");
+ FwpmFreeMemory0 ((void **)&sublayer_ptr);
+ }
+ else
+ { /* Add a new sublayer -- as another process may add it in the meantime,
+ do not treat "already exists" as an error */
+ err = add_sublayer (OPENVPN_BLOCK_OUTSIDE_DNS_SUBLAYER);
+
+ if (err == FWP_E_ALREADY_EXISTS || err == ERROR_SUCCESS)
+ msg_handler (0, "Block_DNS: Added a persistent sublayer with pre-defined UUID");
+ else
+ CHECK_ERROR (err, "add_sublayer: failed to add persistent sublayer");
+ }
+
+ err = ConvertInterfaceIndexToLuid (index, &tapluid);
+ CHECK_ERROR (err, "Convert interface index to luid failed");
+
+ err = FwpmGetAppIdFromFileName0 (exe_path, &openvpnblob);
+ CHECK_ERROR (err, "Get byte blob for openvpn executable name failed");
+
+ /* Prepare filter. */
+ Filter.subLayerKey = OPENVPN_BLOCK_OUTSIDE_DNS_SUBLAYER;
+ Filter.displayData.name = FIREWALL_NAME;
+ Filter.weight.type = FWP_UINT8;
+ Filter.weight.uint8 = 0xF;
+ Filter.filterCondition = Condition;
+ Filter.numFilterConditions = 2;
+
+ /* First filter. Permit IPv4 DNS queries from OpenVPN itself. */
+ Filter.layerKey = FWPM_LAYER_ALE_AUTH_CONNECT_V4;
+ Filter.action.type = FWP_ACTION_PERMIT;
+
+ Condition[0].fieldKey = FWPM_CONDITION_IP_REMOTE_PORT;
+ Condition[0].matchType = FWP_MATCH_EQUAL;
+ Condition[0].conditionValue.type = FWP_UINT16;
+ Condition[0].conditionValue.uint16 = 53;
+
+ Condition[1].fieldKey = FWPM_CONDITION_ALE_APP_ID;
+ Condition[1].matchType = FWP_MATCH_EQUAL;
+ Condition[1].conditionValue.type = FWP_BYTE_BLOB_TYPE;
+ Condition[1].conditionValue.byteBlob = openvpnblob;
+
+ err = FwpmFilterAdd0(*engine_handle, &Filter, NULL, &filterid);
+ CHECK_ERROR (err, "Add filter to permit IPv4 port 53 traffic from OpenVPN failed");
+
+ /* Second filter. Permit IPv6 DNS queries from OpenVPN itself. */
+ Filter.layerKey = FWPM_LAYER_ALE_AUTH_CONNECT_V6;
+
+ err = FwpmFilterAdd0(*engine_handle, &Filter, NULL, &filterid);
+ CHECK_ERROR (err, "Add filter to permit IPv6 port 53 traffic from OpenVPN failed");
+
+ msg_handler (0, "Block_DNS: Added permit filters for exe_path");
+
+ /* Third filter. Block all IPv4 DNS queries. */
+ Filter.layerKey = FWPM_LAYER_ALE_AUTH_CONNECT_V4;
+ Filter.action.type = FWP_ACTION_BLOCK;
+ Filter.weight.type = FWP_EMPTY;
+ Filter.numFilterConditions = 1;
+
+ err = FwpmFilterAdd0(*engine_handle, &Filter, NULL, &filterid);
+ CHECK_ERROR (err, "Add filter to block IPv4 DNS traffic failed");
+
+ /* Forth filter. Block all IPv6 DNS queries. */
+ Filter.layerKey = FWPM_LAYER_ALE_AUTH_CONNECT_V6;
+
+ err = FwpmFilterAdd0(*engine_handle, &Filter, NULL, &filterid);
+ CHECK_ERROR (err, "Add filter to block IPv6 DNS traffic failed");
+
+ msg_handler (0, "Block_DNS: Added block filters for all interfaces");
+
+ /* Fifth filter. Permit IPv4 DNS queries from TAP.
+ * Use a non-zero weight so that the permit filters get higher priority
+ * over the block filter added with automatic weighting */
+
+ Filter.weight.type = FWP_UINT8;
+ Filter.weight.uint8 = 0xE;
+ Filter.layerKey = FWPM_LAYER_ALE_AUTH_CONNECT_V4;
+ Filter.action.type = FWP_ACTION_PERMIT;
+ Filter.numFilterConditions = 2;
+
+ Condition[1].fieldKey = FWPM_CONDITION_IP_LOCAL_INTERFACE;
+ Condition[1].matchType = FWP_MATCH_EQUAL;
+ Condition[1].conditionValue.type = FWP_UINT64;
+ Condition[1].conditionValue.uint64 = &tapluid.Value;
+
+ err = FwpmFilterAdd0(*engine_handle, &Filter, NULL, &filterid);
+ CHECK_ERROR (err, "Add filter to permit IPv4 DNS traffic through TAP failed");
+
+ /* Sixth filter. Permit IPv6 DNS queries from TAP.
+ * Use same weight as IPv4 filter */
+ Filter.layerKey = FWPM_LAYER_ALE_AUTH_CONNECT_V6;
+
+ err = FwpmFilterAdd0(*engine_handle, &Filter, NULL, &filterid);
+ CHECK_ERROR (err, "Add filter to permit IPv6 DNS traffic through TAP failed");
+
+ msg_handler (0, "Block_DNS: Added permit filters for TAP interface");
+
+out:
+
+ if (openvpnblob)
+ FwpmFreeMemory0 ((void **)&openvpnblob);
+
+ if (err && *engine_handle)
+ {
+ FwpmEngineClose0 (*engine_handle);
+ *engine_handle = NULL;
+ }
+
+ return err;
+}
+
+DWORD
+delete_block_dns_filters (HANDLE engine_handle)
+{
+ DWORD err = 0;
+ /*
+ * For dynamic sessions closing the engine removes all filters added in the session
+ */
+ if (engine_handle)
+ {
+ err = FwpmEngineClose0(engine_handle);
+ }
+ return err;
+}
+
+#endif
diff --git a/src/openvpn/block_dns.h b/src/openvpn/block_dns.h
new file mode 100644
index 0000000..f8b6d4f
--- /dev/null
+++ b/src/openvpn/block_dns.h
@@ -0,0 +1,40 @@
+/*
+ * OpenVPN -- An application to securely tunnel IP networks
+ * over a single TCP/UDP port, with support for SSL/TLS-based
+ * session authentication and key exchange,
+ * packet encryption, packet authentication, and
+ * packet compression.
+ *
+ * Copyright (C) 2016 Selva Nair <selva.nair@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program (see the file COPYING included with this
+ * distribution); if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifdef _WIN32
+
+#ifndef OPENVPN_BLOCK_DNS_H
+#define OPENVPN_BLOCK_DNS_H
+
+typedef void (*block_dns_msg_handler_t) (DWORD err, const char *msg);
+
+DWORD
+delete_block_dns_filters (HANDLE engine);
+
+DWORD
+add_block_dns_filters (HANDLE *engine, int iface_index, const WCHAR *exe_path,
+ block_dns_msg_handler_t msg_handler_callback);
+
+#endif
+#endif
diff --git a/src/openvpn/buffer.c b/src/openvpn/buffer.c
index fb3b52d..52c6ab9 100644
--- a/src/openvpn/buffer.c
+++ b/src/openvpn/buffer.c
@@ -254,7 +254,7 @@ buf_puts(struct buffer *buf, const char *str)
*
* Return false on overflow.
*
- * This function is duplicated into service-win32/openvpnserv.c
+ * This functionality is duplicated in src/openvpnserv/common.c
* Any modifications here should be done to the other place as well.
*/
@@ -372,6 +372,44 @@ x_gc_free (struct gc_arena *a)
}
/*
+ * Functions to handle special objects in gc_entries
+ */
+
+void
+x_gc_freespecial (struct gc_arena *a)
+{
+ struct gc_entry_special *e;
+ e = a->list_special;
+ a->list_special = NULL;
+
+ while (e != NULL)
+ {
+ struct gc_entry_special *next = e->next;
+ e->free_fnc (e->addr);
+ free(e);
+ e = next;
+ }
+}
+
+void gc_addspecial (void *addr, void (free_function)(void*), struct gc_arena *a)
+{
+ ASSERT(a);
+ struct gc_entry_special *e;
+#ifdef DMALLOC
+ e = (struct gc_entry_special *) openvpn_dmalloc (file, line, sizeof (struct gc_entry_special));
+#else
+ e = (struct gc_entry_special *) malloc (sizeof (struct gc_entry_special));
+#endif
+ check_malloc_return (e);
+ e->free_fnc = free_function;
+ e->addr = addr;
+
+ e->next = a->list_special;
+ a->list_special = e;
+}
+
+
+/*
* Transfer src arena to dest, resetting src to an empty arena.
*/
void
@@ -397,18 +435,21 @@ gc_transfer (struct gc_arena *dest, struct gc_arena *src)
char *
format_hex_ex (const uint8_t *data, int size, int maxoutput,
- int space_break, const char* separator,
+ unsigned int space_break_flags, const char* separator,
struct gc_arena *gc)
{
struct buffer out = alloc_buf_gc (maxoutput ? maxoutput :
- ((size * 2) + (size / space_break) * (int) strlen (separator) + 2),
+ ((size * 2) + (size / (space_break_flags & FHE_SPACE_BREAK_MASK)) * (int) strlen (separator) + 2),
gc);
int i;
for (i = 0; i < size; ++i)
{
- if (separator && i && !(i % space_break))
+ if (separator && i && !(i % (space_break_flags & FHE_SPACE_BREAK_MASK)))
buf_printf (&out, "%s", separator);
- buf_printf (&out, "%02x", data[i]);
+ if (space_break_flags & FHE_CAPS)
+ buf_printf (&out, "%02X", data[i]);
+ else
+ buf_printf (&out, "%02x", data[i]);
}
buf_catrunc (&out, "[more...]");
return (char *)out.data;
@@ -938,9 +979,6 @@ valign4 (const struct buffer *buf, const char *file, const int line)
/*
* struct buffer_list
*/
-
-#ifdef ENABLE_BUFFER_LIST
-
struct buffer_list *
buffer_list_new (const int max_size)
{
@@ -1031,8 +1069,10 @@ buffer_list_peek (struct buffer_list *ol)
}
void
-buffer_list_aggregate (struct buffer_list *bl, const size_t max)
+buffer_list_aggregate_separator (struct buffer_list *bl, const size_t max, const char *sep)
{
+ int sep_len = strlen(sep);
+
if (bl->head)
{
struct buffer_entry *more = bl->head;
@@ -1040,7 +1080,7 @@ buffer_list_aggregate (struct buffer_list *bl, const size_t max)
int count = 0;
for (count = 0; more && size <= max; ++count)
{
- size += BLEN(&more->buf);
+ size += BLEN(&more->buf) + sep_len;
more = more->next;
}
@@ -1057,6 +1097,7 @@ buffer_list_aggregate (struct buffer_list *bl, const size_t max)
{
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;
@@ -1070,6 +1111,12 @@ buffer_list_aggregate (struct buffer_list *bl, const size_t max)
}
void
+buffer_list_aggregate (struct buffer_list *bl, const size_t max)
+{
+ buffer_list_aggregate_separator(bl, max, "");
+}
+
+void
buffer_list_pop (struct buffer_list *ol)
{
if (ol && ol->head)
@@ -1116,5 +1163,3 @@ buffer_list_file (const char *fn, int max_line_len)
}
return bl;
}
-
-#endif
diff --git a/src/openvpn/buffer.h b/src/openvpn/buffer.h
index 58f0601..8070439 100644
--- a/src/openvpn/buffer.h
+++ b/src/openvpn/buffer.h
@@ -91,6 +91,18 @@ struct gc_entry
* linked list. */
};
+/**
+ * Gargabe collection entry for a specially allocated structure that needs
+ * a custom free function to be freed like struct addrinfo
+ *
+ */
+struct gc_entry_special
+{
+ struct gc_entry_special *next;
+ void (*free_fnc)(void*);
+ void *addr;
+};
+
/**
* Garbage collection arena used to keep track of dynamically allocated
@@ -106,6 +118,7 @@ struct gc_arena
{
struct gc_entry *list; /**< First element of the linked list of
* \c gc_entry structures. */
+ struct gc_entry_special *list_special;
};
@@ -163,6 +176,9 @@ struct buffer string_alloc_buf (const char *str, struct gc_arena *gc);
#endif
+void gc_addspecial (void *addr, void (*free_function)(void*), struct gc_arena *a);
+
+
#ifdef BUF_INIT_TRACKING
#define buf_init(buf, offset) buf_init_debug (buf, offset, __FILE__, __LINE__)
bool buf_init_debug (struct buffer *buf, int offset, const char *file, int line);
@@ -172,6 +188,11 @@ bool buf_init_debug (struct buffer *buf, int offset, const char *file, int line)
/* inline functions */
+inline static void
+gc_freeaddrinfo_callback (void *addr)
+{
+ freeaddrinfo((struct addrinfo*) addr);
+}
static inline bool
buf_defined (const struct buffer *buf)
@@ -382,9 +403,11 @@ bool buf_parse (struct buffer *buf, const int delim, char *line, const int size)
/*
* Hex dump -- Output a binary buffer to a hex string and return it.
*/
+#define FHE_SPACE_BREAK_MASK 0xFF /* space_break parameter in lower 8 bits */
+#define FHE_CAPS 0x100 /* output hex in caps */
char *
format_hex_ex (const uint8_t *data, int size, int maxoutput,
- int space_break, const char* separator,
+ unsigned int space_break_flags, const char* separator,
struct gc_arena *gc);
static inline char *
@@ -781,6 +804,7 @@ void character_class_debug (void);
void gc_transfer (struct gc_arena *dest, struct gc_arena *src);
void x_gc_free (struct gc_arena *a);
+void x_gc_freespecial (struct gc_arena *a);
static inline bool
gc_defined (struct gc_arena *a)
@@ -792,6 +816,7 @@ static inline void
gc_init (struct gc_arena *a)
{
a->list = NULL;
+ a->list_special = NULL;
}
static inline void
@@ -804,7 +829,7 @@ static inline struct gc_arena
gc_new (void)
{
struct gc_arena ret;
- ret.list = NULL;
+ gc_init (&ret);
return ret;
}
@@ -813,6 +838,8 @@ gc_free (struct gc_arena *a)
{
if (a->list)
x_gc_free (a);
+ if (a->list_special)
+ x_gc_freespecial(a);
}
static inline void
@@ -882,9 +909,6 @@ check_malloc_return (const void *p)
/*
* Manage lists of buffers
*/
-
-#ifdef ENABLE_BUFFER_LIST
-
struct buffer_entry
{
struct buffer buf;
@@ -912,9 +936,7 @@ void buffer_list_advance (struct buffer_list *ol, int n);
void buffer_list_pop (struct buffer_list *ol);
void buffer_list_aggregate (struct buffer_list *bl, const size_t max);
+void buffer_list_aggregate_separator (struct buffer_list *bl, const size_t max, const char *sep);
struct buffer_list *buffer_list_file (const char *fn, int max_line_len);
-
-#endif
-
#endif /* BUFFER_H */
diff --git a/src/openvpn/clinat.c b/src/openvpn/clinat.c
index af75fc9..ddefe12 100644
--- a/src/openvpn/clinat.c
+++ b/src/openvpn/clinat.c
@@ -30,8 +30,6 @@
#include "syshead.h"
-#if defined(ENABLE_CLIENT_NAT)
-
#include "clinat.h"
#include "proto.h"
#include "socket.h"
@@ -265,5 +263,3 @@ client_nat_transform (const struct client_nat_option_list *list,
}
}
}
-
-#endif
diff --git a/src/openvpn/clinat.h b/src/openvpn/clinat.h
index d55a727..a5779e1 100644
--- a/src/openvpn/clinat.h
+++ b/src/openvpn/clinat.h
@@ -22,7 +22,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#if !defined(CLINAT_H) && defined(ENABLE_CLIENT_NAT)
+#if !defined(CLINAT_H)
#define CLINAT_H
#include "buffer.h"
diff --git a/src/openvpn/common.h b/src/openvpn/common.h
index 2f85bec..1134101 100644
--- a/src/openvpn/common.h
+++ b/src/openvpn/common.h
@@ -30,7 +30,7 @@
*/
#ifdef USE_64_BIT_COUNTERS
typedef unsigned long long int counter_type;
-# ifdef WIN32
+# ifdef _WIN32
# define counter_format "%I64u"
# else
# define counter_format "%llu"
diff --git a/src/openvpn/comp-lz4.c b/src/openvpn/comp-lz4.c
new file mode 100644
index 0000000..395f3d2
--- /dev/null
+++ b/src/openvpn/comp-lz4.c
@@ -0,0 +1,307 @@
+/*
+ * OpenVPN -- An application to securely tunnel IP networks
+ * over a single UDP port, with support for SSL/TLS-based
+ * session authentication and key exchange,
+ * packet encryption, packet authentication, and
+ * packet compression.
+ *
+ * Copyright (C) 2002-2012 OpenVPN Technologies, Inc. <sales@openvpn.net>
+ * Copyright (C) 2013 Gert Doering <gert@greenie.muc.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program (see the file COPYING included with this
+ * distribution); if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#elif defined(_MSC_VER)
+#include "config-msvc.h"
+#endif
+
+#include "syshead.h"
+
+#if defined(ENABLE_LZ4)
+
+#if defined(NEED_COMPAT_LZ4)
+#include "compat-lz4.h"
+#else
+#include "lz4.h"
+#endif
+
+#include "comp.h"
+#include "error.h"
+
+#include "memdbg.h"
+
+static void
+lz4_compress_init (struct compress_context *compctx)
+{
+ msg (D_INIT_MEDIUM, "LZ4 compression initializing");
+ ASSERT(compctx->flags & COMP_F_SWAP);
+}
+
+static void
+lz4v2_compress_init (struct compress_context *compctx)
+{
+ msg (D_INIT_MEDIUM, "LZ4v2 compression initializing");
+}
+
+static void
+lz4_compress_uninit (struct compress_context *compctx)
+{
+}
+
+static bool
+do_lz4_compress (struct buffer *buf,
+ struct buffer *work,
+ struct compress_context *compctx,
+ const struct frame* frame)
+{
+ /*
+ * In order to attempt compression, length must be at least COMPRESS_THRESHOLD.
+ */
+ if (buf->len >= COMPRESS_THRESHOLD)
+ {
+ const size_t ps = PAYLOAD_SIZE (frame);
+ int zlen_max = ps + COMP_EXTRA_BUFFER (ps);
+ int zlen;
+
+ ASSERT (buf_init (work, FRAME_HEADROOM (frame)));
+ ASSERT (buf_safe (work, zlen_max));
+
+ if (buf->len > ps)
+ {
+ dmsg (D_COMP_ERRORS, "LZ4 compression buffer overflow");
+ buf->len = 0;
+ return false;
+ }
+
+ zlen = LZ4_compress_limitedOutput((const char *)BPTR(buf), (char *)BPTR(work), BLEN(buf), zlen_max );
+
+ if (zlen <= 0)
+ {
+ dmsg (D_COMP_ERRORS, "LZ4 compression error");
+ buf->len = 0;
+ return false;
+ }
+
+ ASSERT (buf_safe (work, zlen));
+ work->len = zlen;
+
+
+ dmsg (D_COMP, "LZ4 compress %d -> %d", buf->len, work->len);
+ compctx->pre_compress += buf->len;
+ compctx->post_compress += work->len;
+ return true;
+ }
+ return false;
+}
+
+
+static void
+lz4_compress (struct buffer *buf, struct buffer work,
+ struct compress_context *compctx,
+ const struct frame* frame)
+{
+ bool compressed;
+ if (buf->len <= 0)
+ return;
+
+ compressed = do_lz4_compress(buf, &work, compctx, frame);
+
+ /* On error do_lz4_compress sets buf len to zero, just return */
+ if (buf->len == 0)
+ return;
+
+ /* did compression save us anything? */
+ {
+ uint8_t comp_head_byte = NO_COMPRESS_BYTE_SWAP;
+ if (compressed && work.len < buf->len)
+ {
+ *buf = work;
+ comp_head_byte = LZ4_COMPRESS_BYTE;
+ }
+
+ {
+ uint8_t *head = BPTR (buf);
+ uint8_t *tail = BEND (buf);
+ ASSERT (buf_safe (buf, 1));
+ ++buf->len;
+
+ /* move head byte of payload to tail */
+ *tail = *head;
+ *head = comp_head_byte;
+ }
+ }
+}
+
+
+static void
+lz4v2_compress (struct buffer *buf, struct buffer work,
+ struct compress_context *compctx,
+ const struct frame* frame)
+{
+ bool compressed;
+ if (buf->len <= 0)
+ return;
+
+ compressed = do_lz4_compress(buf, &work, compctx, frame);
+
+ /* On Error just return */
+ if (buf->len == 0)
+ return;
+
+ /* did compression save us anything? Include 2 byte compression header
+ in calculation */
+ if (compressed && work.len + 2 < buf->len)
+ {
+ ASSERT(buf_prepend(&work, 2));
+ uint8_t *head = BPTR (&work);
+ head[0] = COMP_ALGV2_INDICATOR_BYTE;
+ head[1] = COMP_ALGV2_LZ4_BYTE;
+ *buf = work;
+ }
+ else
+ {
+ compv2_escape_data_ifneeded(buf);
+ }
+}
+
+void
+do_lz4_decompress(size_t zlen_max,
+ struct buffer *work,
+ struct buffer *buf,
+ struct compress_context *compctx)
+{
+ int uncomp_len;
+ ASSERT (buf_safe (work, zlen_max));
+ uncomp_len = LZ4_decompress_safe((const char *)BPTR(buf), (char *)BPTR(work), (size_t)BLEN(buf), zlen_max);
+ if (uncomp_len <= 0)
+ {
+ dmsg (D_COMP_ERRORS, "LZ4 decompression error: %d", uncomp_len);
+ buf->len = 0;
+ return;
+ }
+
+ ASSERT (buf_safe (work, uncomp_len));
+ work->len = uncomp_len;
+
+ dmsg (D_COMP, "LZ4 decompress %d -> %d", buf->len, work->len);
+ compctx->pre_decompress += buf->len;
+ compctx->post_decompress += work->len;
+
+ *buf = *work;
+}
+
+static void
+lz4_decompress (struct buffer *buf, struct buffer work,
+ struct compress_context *compctx,
+ const struct frame* frame)
+{
+ size_t zlen_max = EXPANDED_SIZE (frame);
+ uint8_t c; /* flag indicating whether or not our peer compressed */
+
+ if (buf->len <= 0)
+ return;
+
+ ASSERT (buf_init (&work, FRAME_HEADROOM (frame)));
+
+ /* do unframing/swap (assumes buf->len > 0) */
+ {
+ uint8_t *head = BPTR (buf);
+ c = *head;
+ --buf->len;
+ *head = *BEND (buf);
+ }
+
+ if (c == LZ4_COMPRESS_BYTE) /* packet was compressed */
+ {
+ do_lz4_decompress(zlen_max, &work, buf, compctx);
+ }
+ else if (c == NO_COMPRESS_BYTE_SWAP) /* packet was not compressed */
+ {
+ ;
+ }
+ else
+ {
+ dmsg (D_COMP_ERRORS, "Bad LZ4 decompression header byte: %d", c);
+ buf->len = 0;
+ }
+}
+
+static void
+lz4v2_decompress (struct buffer *buf, struct buffer work,
+ struct compress_context *compctx,
+ const struct frame* frame)
+{
+ size_t zlen_max = EXPANDED_SIZE (frame);
+ uint8_t c; /* flag indicating whether or not our peer compressed */
+
+ if (buf->len <= 0)
+ return;
+
+ ASSERT (buf_init (&work, FRAME_HEADROOM (frame)));
+
+ /* do unframing/swap (assumes buf->len > 0) */
+ uint8_t *head = BPTR (buf);
+ c = *head;
+
+ /* Not compressed */
+ if (c != COMP_ALGV2_INDICATOR_BYTE) {
+ return;
+ }
+
+ /* Packet to short to make sense */
+ if (buf->len <= 1)
+ {
+ buf->len=0;
+ return;
+ }
+
+ c = head[1];
+ if (c == COMP_ALGV2_LZ4_BYTE) /* packet was compressed */
+ {
+ buf_advance(buf,2);
+ do_lz4_decompress(zlen_max, &work, buf, compctx);
+ }
+ else if (c == COMP_ALGV2_UNCOMPRESSED_BYTE)
+ {
+ buf_advance(buf,2);
+ }
+ else
+ {
+ dmsg (D_COMP_ERRORS, "Bad LZ4v2 decompression header byte: %d", c);
+ buf->len = 0;
+ }
+}
+
+const struct compress_alg lz4_alg = {
+ "lz4",
+ lz4_compress_init,
+ lz4_compress_uninit,
+ lz4_compress,
+ lz4_decompress
+};
+
+const struct compress_alg lz4v2_alg = {
+ "lz4v2",
+ lz4v2_compress_init,
+ lz4_compress_uninit,
+ lz4v2_compress,
+ lz4v2_decompress
+};
+
+#else
+static void dummy(void) {}
+#endif /* ENABLE_LZ4 */
diff --git a/src/openvpn/comp-lz4.h b/src/openvpn/comp-lz4.h
new file mode 100644
index 0000000..7774ca5
--- /dev/null
+++ b/src/openvpn/comp-lz4.h
@@ -0,0 +1,42 @@
+/*
+ * OpenVPN -- An application to securely tunnel IP networks
+ * over a single UDP port, with support for SSL/TLS-based
+ * session authentication and key exchange,
+ * packet encryption, packet authentication, and
+ * packet compression.
+ *
+ * Copyright (C) 2002-2012 OpenVPN Technologies, Inc. <sales@openvpn.net>
+ * Copyright (C) 2013 Gert Doering <gert@greenie.muc.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program (see the file COPYING included with this
+ * distribution); if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef OPENVPN_COMP_LZ4_H
+#define OPENVPN_COMP_LZ4_H
+
+#if defined(ENABLE_LZ4)
+
+#include "buffer.h"
+
+extern const struct compress_alg lz4_alg;
+extern const struct compress_alg lz4v2_alg;
+
+struct lz4_workspace
+{
+ int dummy;
+};
+
+#endif /* ENABLE_LZ4 */
+#endif
diff --git a/src/openvpn/comp.c b/src/openvpn/comp.c
new file mode 100644
index 0000000..499fef9
--- /dev/null
+++ b/src/openvpn/comp.c
@@ -0,0 +1,167 @@
+/*
+ * OpenVPN -- An application to securely tunnel IP networks
+ * over a single UDP port, with support for SSL/TLS-based
+ * session authentication and key exchange,
+ * packet encryption, packet authentication, and
+ * packet compression.
+ *
+ * Copyright (C) 2002-2012 OpenVPN Technologies, Inc. <sales@openvpn.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program (see the file COPYING included with this
+ * distribution); if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#elif defined(_MSC_VER)
+#include "config-msvc.h"
+#endif
+
+#include "syshead.h"
+
+#ifdef USE_COMP
+
+#include "comp.h"
+#include "error.h"
+#include "otime.h"
+
+#include "memdbg.h"
+
+struct compress_context *
+comp_init(const struct compress_options *opt)
+{
+ struct compress_context *compctx = NULL;
+ switch (opt->alg)
+ {
+ case COMP_ALG_STUB:
+ ALLOC_OBJ_CLEAR (compctx, struct compress_context);
+ compctx->flags = opt->flags;
+ compctx->alg = comp_stub_alg;
+ break;
+ case COMP_ALGV2_UNCOMPRESSED:
+ ALLOC_OBJ_CLEAR (compctx, struct compress_context);
+ compctx->flags = opt->flags;
+ compctx->alg = compv2_stub_alg;
+ break;
+#ifdef ENABLE_LZO
+ case COMP_ALG_LZO:
+ ALLOC_OBJ_CLEAR (compctx, struct compress_context);
+ compctx->flags = opt->flags;
+ compctx->alg = lzo_alg;
+ break;
+#endif
+#ifdef ENABLE_LZ4
+ case COMP_ALG_LZ4:
+ ALLOC_OBJ_CLEAR (compctx, struct compress_context);
+ compctx->flags = opt->flags;
+ compctx->alg = lz4_alg;
+ break;
+ case COMP_ALGV2_LZ4:
+ ALLOC_OBJ_CLEAR (compctx, struct compress_context);
+ compctx->flags = opt->flags;
+ compctx->alg = lz4v2_alg;
+ break;
+#endif
+ }
+ if (compctx)
+ (*compctx->alg.compress_init)(compctx);
+
+ return compctx;
+}
+
+/* In the v2 compression schemes, an uncompressed packet has
+ * has no opcode in front, unless the first byte is 0x50. In this
+ * case the packet needs to be escaped */
+void
+compv2_escape_data_ifneeded (struct buffer *buf)
+{
+ uint8_t *head = BPTR (buf);
+ if (head[0] != COMP_ALGV2_INDICATOR_BYTE)
+ return;
+
+ /* Header is 0x50 */
+ ASSERT(buf_prepend(buf, 2));
+
+ head = BPTR (buf);
+ head[0] = COMP_ALGV2_INDICATOR_BYTE;
+ head[1] = COMP_ALGV2_UNCOMPRESSED;
+}
+
+
+void
+comp_uninit(struct compress_context *compctx)
+{
+ if (compctx)
+ {
+ (*compctx->alg.compress_uninit)(compctx);
+ free(compctx);
+ }
+}
+
+void
+comp_add_to_extra_frame(struct frame *frame)
+{
+ /* Leave room for our one-byte compressed/didn't-compress prefix byte. */
+ frame_add_to_extra_frame (frame, COMP_PREFIX_LEN);
+}
+
+void
+comp_add_to_extra_buffer(struct frame *frame)
+{
+ /* Leave room for compression buffer to expand in worst case scenario
+ where data is totally uncompressible */
+ frame_add_to_extra_buffer (frame, COMP_EXTRA_BUFFER (EXPANDED_SIZE(frame)));
+}
+
+void
+comp_print_stats (const struct compress_context *compctx, struct status_output *so)
+{
+ if (compctx)
+ {
+ status_printf (so, "pre-compress bytes," counter_format, compctx->pre_compress);
+ status_printf (so, "post-compress bytes," counter_format, compctx->post_compress);
+ status_printf (so, "pre-decompress bytes," counter_format, compctx->pre_decompress);
+ status_printf (so, "post-decompress bytes," counter_format, compctx->post_decompress);
+ }
+}
+
+/*
+ * Tell our peer which compression algorithms we support.
+ */
+void
+comp_generate_peer_info_string(const struct compress_options *opt, struct buffer *out)
+{
+ if (opt)
+ {
+ bool lzo_avail = false;
+ if (!(opt->flags & COMP_F_ADVERTISE_STUBS_ONLY))
+ {
+#if defined(ENABLE_LZ4)
+ buf_printf (out, "IV_LZ4=1\n");
+ buf_printf (out, "IV_LZ4v2=1\n");
+#endif
+#if defined(ENABLE_LZO)
+ buf_printf (out, "IV_LZO=1\n");
+ lzo_avail = true;
+#endif
+ }
+ if (!lzo_avail)
+ buf_printf (out, "IV_LZO_STUB=1\n");
+ buf_printf (out, "IV_COMP_STUB=1\n");
+ buf_printf (out, "IV_COMP_STUBv2=1\n");
+ buf_printf (out, "IV_TCPNL=1\n");
+ }
+}
+
+#endif /* USE_COMP */
diff --git a/src/openvpn/comp.h b/src/openvpn/comp.h
new file mode 100644
index 0000000..9ed9532
--- /dev/null
+++ b/src/openvpn/comp.h
@@ -0,0 +1,198 @@
+/*
+ * OpenVPN -- An application to securely tunnel IP networks
+ * over a single UDP port, with support for SSL/TLS-based
+ * session authentication and key exchange,
+ * packet encryption, packet authentication, and
+ * packet compression.
+ *
+ * Copyright (C) 2002-2012 OpenVPN Technologies, Inc. <sales@openvpn.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program (see the file COPYING included with this
+ * distribution); if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * Generic compression support. Currently we support
+ * LZO 2 and LZ4.
+ */
+#ifndef OPENVPN_COMP_H
+#define OPENVPN_COMP_H
+
+#ifdef USE_COMP
+
+#include "buffer.h"
+#include "mtu.h"
+#include "common.h"
+#include "status.h"
+
+/* algorithms */
+#define COMP_ALG_UNDEF 0
+#define COMP_ALG_STUB 1 /* support compression command byte and framing without actual compression */
+#define COMP_ALG_LZO 2 /* LZO algorithm */
+#define COMP_ALG_SNAPPY 3 /* Snappy algorithm (no longer supported) */
+#define COMP_ALG_LZ4 4 /* LZ4 algorithm */
+
+
+/* algorithm v2 */
+#define COMP_ALGV2_UNCOMPRESSED 10
+#define COMP_ALGV2_LZ4 11
+/*
+#define COMP_ALGV2_LZO 12
+#define COMP_ALGV2_SNAPPY 13
+*/
+
+/* Compression flags */
+#define COMP_F_ADAPTIVE (1<<0) /* COMP_ALG_LZO only */
+#define COMP_F_ASYM (1<<1) /* only downlink is compressed, not uplink */
+#define COMP_F_SWAP (1<<2) /* initial command byte is swapped with last byte in buffer to preserve payload alignment */
+#define COMP_F_ADVERTISE_STUBS_ONLY (1<<3) /* tell server that we only support compression stubs */
+
+
+/*
+ * Length of prepended prefix on compressed packets
+ */
+#define COMP_PREFIX_LEN 1
+
+/*
+ * Prefix bytes
+ */
+
+/* V1 on wire codes */
+/* Initial command byte to tell our peer if we compressed */
+#define LZO_COMPRESS_BYTE 0x66
+#define LZ4_COMPRESS_BYTE 0x69
+#define NO_COMPRESS_BYTE 0xFA
+#define NO_COMPRESS_BYTE_SWAP 0xFB /* to maintain payload alignment, replace this byte with last byte of packet */
+
+/* V2 on wire code */
+#define COMP_ALGV2_INDICATOR_BYTE 0x50
+#define COMP_ALGV2_UNCOMPRESSED_BYTE 0
+#define COMP_ALGV2_LZ4_BYTE 1
+#define COMP_ALGV2_LZO_BYTE 2
+#define COMP_ALGV2_SNAPPY_BYTE 3
+
+/*
+ * Compress worst case size expansion (for any algorithm)
+ *
+ * LZO: len + len/8 + 128 + 3
+ * Snappy: len + len/6 + 32
+ * LZ4: len + len/255 + 16 (LZ4_COMPRESSBOUND(len))
+ */
+#define COMP_EXTRA_BUFFER(len) ((len)/6 + 128 + 3 + COMP_PREFIX_LEN)
+
+/*
+ * Don't try to compress any packet smaller than this.
+ */
+#define COMPRESS_THRESHOLD 100
+
+/* Forward declaration of compression context */
+struct compress_context;
+
+/*
+ * Virtual methods and other static info for each compression algorithm
+ */
+struct compress_alg
+{
+ const char *name;
+ void (*compress_init)(struct compress_context *compctx);
+ void (*compress_uninit)(struct compress_context *compctx);
+ void (*compress)(struct buffer *buf, struct buffer work,
+ struct compress_context *compctx,
+ const struct frame* frame);
+
+ void (*decompress)(struct buffer *buf, struct buffer work,
+ struct compress_context *compctx,
+ const struct frame* frame);
+};
+
+/*
+ * Headers for each compression implementation
+ */
+#ifdef ENABLE_LZO
+#include "lzo.h"
+#endif
+
+#ifdef ENABLE_LZ4
+#include "comp-lz4.h"
+#endif
+
+/*
+ * Information that basically identifies a compression
+ * algorithm and related flags.
+ */
+struct compress_options
+{
+ int alg;
+ unsigned int flags;
+};
+
+/*
+ * Workspace union of all supported compression algorithms
+ */
+union compress_workspace_union
+{
+#ifdef ENABLE_LZO
+ struct lzo_compress_workspace lzo;
+#endif
+#ifdef ENABLE_LZ4
+ struct lz4_workspace lz4;
+#endif
+};
+
+/*
+ * Context for active compression session
+ */
+struct compress_context
+{
+ unsigned int flags;
+ struct compress_alg alg;
+ union compress_workspace_union wu;
+
+ /* statistics */
+ counter_type pre_decompress;
+ counter_type post_decompress;
+ counter_type pre_compress;
+ counter_type post_compress;
+};
+
+extern const struct compress_alg comp_stub_alg;
+extern const struct compress_alg compv2_stub_alg;
+
+struct compress_context *comp_init(const struct compress_options *opt);
+
+void comp_uninit(struct compress_context *compctx);
+
+void comp_add_to_extra_frame(struct frame *frame);
+void comp_add_to_extra_buffer(struct frame *frame);
+
+void comp_print_stats (const struct compress_context *compctx, struct status_output *so);
+
+void comp_generate_peer_info_string(const struct compress_options *opt, struct buffer *out);
+
+void compv2_escape_data_ifneeded (struct buffer *buf);
+
+static inline bool
+comp_enabled(const struct compress_options *info)
+{
+ return info->alg != COMP_ALG_UNDEF;
+}
+
+static inline bool
+comp_unswapped_prefix(const struct compress_options *info)
+{
+ return !(info->flags & COMP_F_SWAP);
+}
+
+#endif /* USE_COMP */
+#endif
diff --git a/src/openvpn/compstub.c b/src/openvpn/compstub.c
new file mode 100644
index 0000000..9c6aad2
--- /dev/null
+++ b/src/openvpn/compstub.c
@@ -0,0 +1,169 @@
+/*
+ * OpenVPN -- An application to securely tunnel IP networks
+ * over a single UDP port, with support for SSL/TLS-based
+ * session authentication and key exchange,
+ * packet encryption, packet authentication, and
+ * packet compression.
+ *
+ * Copyright (C) 2002-2012 OpenVPN Technologies, Inc. <sales@openvpn.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program (see the file COPYING included with this
+ * distribution); if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#elif defined(_MSC_VER)
+#include "config-msvc.h"
+#endif
+
+#include "syshead.h"
+
+#if defined(USE_COMP)
+
+#include "comp.h"
+#include "error.h"
+#include "otime.h"
+
+#include "memdbg.h"
+
+static void
+stub_compress_init (struct compress_context *compctx)
+{
+}
+
+static void
+stub_compress_uninit (struct compress_context *compctx)
+{
+}
+
+static void
+stub_compress (struct buffer *buf, struct buffer work,
+ struct compress_context *compctx,
+ const struct frame* frame)
+{
+ if (buf->len <= 0)
+ return;
+ if (compctx->flags & COMP_F_SWAP)
+ {
+ uint8_t *head = BPTR (buf);
+ uint8_t *tail = BEND (buf);
+ ASSERT (buf_safe (buf, 1));
+ ++buf->len;
+
+ /* move head byte of payload to tail */
+ *tail = *head;
+ *head = NO_COMPRESS_BYTE_SWAP;
+ }
+ else
+ {
+ uint8_t *header = buf_prepend (buf, 1);
+ *header = NO_COMPRESS_BYTE;
+ }
+}
+
+static void
+stub_decompress (struct buffer *buf, struct buffer work,
+ struct compress_context *compctx,
+ const struct frame* frame)
+{
+ uint8_t c;
+ if (buf->len <= 0)
+ return;
+ if (compctx->flags & COMP_F_SWAP)
+ {
+ uint8_t *head = BPTR (buf);
+ c = *head;
+ --buf->len;
+ *head = *BEND (buf);
+ if (c != NO_COMPRESS_BYTE_SWAP)
+ {
+ dmsg (D_COMP_ERRORS, "Bad compression stub (swap) decompression header byte: %d", c);
+ buf->len = 0;
+ }
+ }
+ else
+ {
+ c = *BPTR (buf);
+ ASSERT (buf_advance (buf, 1));
+ if (c != NO_COMPRESS_BYTE)
+ {
+ dmsg (D_COMP_ERRORS, "Bad compression stub decompression header byte: %d", c);
+ buf->len = 0;
+ }
+ }
+}
+
+
+static void
+stubv2_compress (struct buffer *buf, struct buffer work,
+ struct compress_context *compctx,
+ const struct frame* frame)
+{
+ if (buf->len <= 0)
+ return;
+
+ compv2_escape_data_ifneeded (buf);
+}
+
+static void
+stubv2_decompress (struct buffer *buf, struct buffer work,
+ struct compress_context *compctx,
+ const struct frame* frame)
+{
+ if (buf->len <= 0)
+ return;
+
+ uint8_t *head = BPTR (buf);
+
+ /* no compression or packet to short*/
+ if (head[0] != COMP_ALGV2_INDICATOR_BYTE)
+ return;
+
+ /* compression header (0x50) is present */
+ buf_advance(buf, 1);
+
+ /* Packet buffer too short (only 1 byte) */
+ if (buf->len <= 0)
+ return;
+
+ head = BPTR (buf);
+ buf_advance(buf, 1);
+
+ if (head[0] != COMP_ALGV2_UNCOMPRESSED_BYTE) {
+ dmsg (D_COMP_ERRORS, "Bad compression stubv2 decompression header byte: %d", *head);
+ buf->len = 0;
+ return;
+ }
+}
+
+const struct compress_alg compv2_stub_alg = {
+ "stubv2",
+ stub_compress_init,
+ stub_compress_uninit,
+ stubv2_compress,
+ stubv2_decompress
+};
+
+const struct compress_alg comp_stub_alg = {
+ "stub",
+ stub_compress_init,
+ stub_compress_uninit,
+ stub_compress,
+ stub_decompress
+};
+
+#else
+static void dummy(void) {}
+#endif /* USE_STUB */
diff --git a/src/openvpn/console.c b/src/openvpn/console.c
index 86331a1..c3bb7c3 100644
--- a/src/openvpn/console.c
+++ b/src/openvpn/console.c
@@ -6,6 +6,8 @@
* packet compression.
*
* Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net>
+ * Copyright (C) 2014-2015 David Sommerseth <davids@redhat.com>
+ * Copyright (C) 2016 David Sommerseth <davids@openvpn.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
@@ -38,219 +40,43 @@
#include <systemd/sd-daemon.h>
#endif
-#ifdef WIN32
-#include "win32.h"
+struct _query_user query_user[QUERY_USER_NUMSLOTS]; /* GLOBAL */
-/*
- * Get input from console.
- *
- * Return false on input error, or if service
- * exit event is signaled.
- */
-
-static bool
-get_console_input_win32 (const char *prompt, const bool echo, char *input, const int capacity)
-{
- HANDLE in = INVALID_HANDLE_VALUE;
- HANDLE err = INVALID_HANDLE_VALUE;
- DWORD len = 0;
-
- ASSERT (prompt);
- ASSERT (input);
- ASSERT (capacity > 0);
-
- input[0] = '\0';
-
- in = GetStdHandle (STD_INPUT_HANDLE);
- err = get_orig_stderr ();
-
- if (in != INVALID_HANDLE_VALUE
- && err != INVALID_HANDLE_VALUE
- && !win32_service_interrupt (&win32_signal)
- && WriteFile (err, prompt, strlen (prompt), &len, NULL))
- {
- bool is_console = (GetFileType (in) == FILE_TYPE_CHAR);
- DWORD flags_save = 0;
- int status = 0;
- WCHAR *winput;
-
- if (is_console)
- {
- if (GetConsoleMode (in, &flags_save))
- {
- DWORD flags = ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT;
- if (echo)
- flags |= ENABLE_ECHO_INPUT;
- SetConsoleMode (in, flags);
- }
- else
- is_console = 0;
- }
-
- if (is_console)
- {
- winput = malloc (capacity * sizeof (WCHAR));
- if (winput == NULL)
- return false;
-
- status = ReadConsoleW (in, winput, capacity, &len, NULL);
- WideCharToMultiByte (CP_UTF8, 0, winput, len, input, capacity, NULL, NULL);
- free (winput);
- }
- else
- status = ReadFile (in, input, capacity, &len, NULL);
-
- string_null_terminate (input, (int)len, capacity);
- chomp (input);
-
- if (!echo)
- WriteFile (err, "\r\n", 2, &len, NULL);
- if (is_console)
- SetConsoleMode (in, flags_save);
- if (status && !win32_service_interrupt (&win32_signal))
- return true;
- }
-
- return false;
-}
-
-#endif
-
-#ifdef HAVE_GETPASS
-
-static FILE *
-open_tty (const bool write)
-{
- FILE *ret;
- ret = fopen ("/dev/tty", write ? "w" : "r");
- if (!ret)
- ret = write ? stderr : stdin;
- return ret;
-}
-
-static void
-close_tty (FILE *fp)
-{
- if (fp != stderr && fp != stdin)
- fclose (fp);
-}
-
-#endif
-#ifdef ENABLE_SYSTEMD
-
-/*
- * is systemd running
- */
-
-static bool
-check_systemd_running ()
+void query_user_clear()
{
- struct stat c;
-
- /* We simply test whether the systemd cgroup hierarchy is
- * mounted, as well as the systemd-ask-password executable
- * being available */
+ int i;
- return (sd_booted() > 0)
- && (stat(SYSTEMD_ASK_PASSWORD_PATH, &c) == 0);
-
-}
-
-static bool
-get_console_input_systemd (const char *prompt, const bool echo, char *input, const int capacity)
-{
- int std_out;
- bool ret = false;
- struct argv argv;
-
- argv_init (&argv);
- argv_printf (&argv, SYSTEMD_ASK_PASSWORD_PATH);
- argv_printf_cat (&argv, "%s", prompt);
-
- if ((std_out = openvpn_popen (&argv, NULL)) < 0) {
- return false;
- }
-
- memset (input, 0, capacity);
- if (read (std_out, input, capacity-1) > 0)
- {
- chomp (input);
- ret = true;
+ for( i = 0; i < QUERY_USER_NUMSLOTS; i++ ) {
+ CLEAR(query_user[i]);
}
- close (std_out);
-
- argv_reset (&argv);
-
- return ret;
}
-#endif
-
-/*
- * Get input from console
- */
-bool
-get_console_input (const char *prompt, const bool echo, char *input, const int capacity)
+void query_user_add(char *prompt, size_t prompt_len,
+ char *resp, size_t resp_len,
+ bool echo)
{
- bool ret = false;
- ASSERT (prompt);
- ASSERT (input);
- ASSERT (capacity > 0);
- input[0] = '\0';
-
-#ifdef ENABLE_SYSTEMD
- if (check_systemd_running ())
- return get_console_input_systemd (prompt, echo, input, capacity);
-#endif
+ int i;
-#if defined(WIN32)
- return get_console_input_win32 (prompt, echo, input, capacity);
-#elif defined(HAVE_GETPASS)
+ /* Ensure input is sane. All these must be present otherwise it is
+ * a programming error.
+ */
+ ASSERT( prompt_len > 0 && prompt != NULL && resp_len > 0 && resp != NULL );
- /* did we --daemon'ize before asking for passwords?
- * (in which case neither stdin or stderr are connected to a tty and
- * /dev/tty can not be open()ed anymore)
- */
- if ( !isatty(0) && !isatty(2) )
- {
- int fd = open( "/dev/tty", O_RDWR );
- if ( fd < 0 )
- { msg(M_FATAL, "neither stdin nor stderr are a tty device and you have neither a controlling tty nor systemd - can't ask for '%s'. If you used --daemon, you need to use --askpass to make passphrase-protected keys work, and you can not use --auth-nocache.", prompt ); }
- close(fd);
- }
-
- if (echo)
- {
- FILE *fp;
-
- fp = open_tty (true);
- fprintf (fp, "%s", prompt);
- fflush (fp);
- close_tty (fp);
-
- fp = open_tty (false);
- if (fgets (input, capacity, fp) != NULL)
- {
- chomp (input);
- ret = true;
+ /* Seek to the last unused slot */
+ for (i = 0; i < QUERY_USER_NUMSLOTS; i++) {
+ if( query_user[i].prompt == NULL ) {
+ break;
}
- close_tty (fp);
}
- else
- {
- char *gp = getpass (prompt);
- if (gp)
- {
- strncpynt (input, gp, capacity);
- memset (gp, 0, strlen (gp));
- ret = true;
- }
- }
-#else
- msg (M_FATAL, "Sorry, but I can't get console input on this OS (%s)", prompt);
-#endif
- return ret;
+ ASSERT( i < QUERY_USER_NUMSLOTS ); /* Unlikely, but we want to panic if it happens */
+
+ /* Save the information needed for the user interaction */
+ query_user[i].prompt = prompt;
+ query_user[i].prompt_len = prompt_len;
+ query_user[i].response = resp;
+ query_user[i].response_len = resp_len;
+ query_user[i].echo = echo;
}
diff --git a/src/openvpn/console.h b/src/openvpn/console.h
index 268f3fe..ec32cf6 100644
--- a/src/openvpn/console.h
+++ b/src/openvpn/console.h
@@ -6,6 +6,8 @@
* packet compression.
*
* Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net>
+ * Copyright (C) 2014-2015 David Sommerseth <davids@redhat.com>
+ * Copyright (C) 2016 David Sommerseth <davids@openvpn.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
@@ -27,7 +29,90 @@
#include "basic.h"
-bool
-get_console_input (const char *prompt, const bool echo, char *input, const int capacity);
+/**
+ * Configuration setup for declaring what kind of information to ask a user for
+ */
+struct _query_user {
+ char *prompt; /**< Prompt to present to the user */
+ size_t prompt_len; /**< Lenght of the prompt string */
+ char *response; /**< The user's response */
+ size_t response_len; /**< Lenght the of the user reposone */
+ bool echo; /**< True: The user should see what is being typed, otherwise mask it */
+};
+
+#define QUERY_USER_NUMSLOTS 10
+extern struct _query_user query_user[]; /**< Global variable, declared in console.c */
+
+/**
+ * Wipes all data put into all of the query_user structs
+ *
+ */
+void query_user_clear ();
+
+
+/**
+ * Adds an item to ask the user for
+ *
+ * @param prompt Prompt to display to the user
+ * @param prompt_len Length of the prompt string
+ * @param resp String containing the user response
+ * @param resp_len Lenght of the response string
+ * @param echo Should the user input be echoed to the user? If False, input will be masked
+ *
+ */
+void query_user_add (char *prompt, size_t prompt_len,
+ char *resp, size_t resp_len,
+ bool echo);
+
+
+/**
+ * Executes a configured setup, using the built-in method for querying the user.
+ * This method uses the console/TTY directly.
+ *
+ * @param setup Pointer to the setup defining what to ask the user
+ *
+ * @return True if executing all the defined steps completed successfully
+ */
+bool query_user_exec_builtin ();
+
+
+#if defined(ENABLE_SYSTEMD)
+/**
+ * Executes a configured setup, using the compiled method for querying the user
+ *
+ * @param setup Pointer to the setup defining what to ask the user
+ *
+ * @return True if executing all the defined steps completed successfully
+ */
+bool query_user_exec ();
+
+#else /* ENABLE_SYSTEMD not defined*/
+/**
+ * Wrapper function enabling query_user_exec() if no alternative methods have
+ * been enabled
+ *
+ */
+static bool query_user_exec ()
+{
+ return query_user_exec_builtin();
+}
+#endif /* defined(ENABLE_SYSTEMD) */
+
+
+/**
+ * A plain "make Gert happy" wrapper. Same arguments as @query_user_add
+ *
+ * FIXME/TODO: Remove this when refactoring the complete user query process
+ * to be called at start-up initialization of OpenVPN.
+ *
+ */
+static inline bool query_user_SINGLE (char *prompt, size_t prompt_len,
+ char *resp, size_t resp_len,
+ bool echo)
+{
+ query_user_clear();
+ query_user_add(prompt, prompt_len, resp, resp_len, echo);
+ return query_user_exec();
+}
#endif
diff --git a/src/openvpn/console_builtin.c b/src/openvpn/console_builtin.c
new file mode 100644
index 0000000..6b0211d
--- /dev/null
+++ b/src/openvpn/console_builtin.c
@@ -0,0 +1,261 @@
+/*
+ * OpenVPN -- An application to securely tunnel IP networks
+ * over a single UDP port, with support for SSL/TLS-based
+ * session authentication and key exchange,
+ * packet encryption, packet authentication, and
+ * packet compression.
+ *
+ * Copyright (C) 2002-2016 OpenVPN Technologies, Inc. <sales@openvpn.net>
+ * Copyright (C) 2014-2015 David Sommerseth <davids@redhat.com>
+ * Copyright (C) 2016 David Sommerseth <davids@openvpn.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program (see the file COPYING included with this
+ * distribution); if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * These functions covers handing user input/output using the default consoles
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#elif defined(_MSC_VER)
+#include "config-msvc.h"
+#endif
+
+#include "syshead.h"
+#include "console.h"
+#include "error.h"
+#include "buffer.h"
+#include "misc.h"
+
+#ifdef _WIN32
+
+#include "win32.h"
+
+/**
+ * Get input from a Windows console.
+ *
+ * @param prompt Prompt to display to the user
+ * @param echo Should the user input be displayed in the console
+ * @param input Pointer to the buffer the user input will be saved
+ * @param capacity Size of the buffer for the user input
+ *
+ * @return Return false on input error, or if service
+ * exit event is signaled.
+ */
+static bool get_console_input_win32 (const char *prompt, const bool echo, char *input, const int capacity)
+{
+ HANDLE in = INVALID_HANDLE_VALUE;
+ HANDLE err = INVALID_HANDLE_VALUE;
+ DWORD len = 0;
+
+ ASSERT (prompt);
+ ASSERT (input);
+ ASSERT (capacity > 0);
+
+ input[0] = '\0';
+
+ in = GetStdHandle (STD_INPUT_HANDLE);
+ err = get_orig_stderr ();
+
+ if (in != INVALID_HANDLE_VALUE
+ && err != INVALID_HANDLE_VALUE
+ && !win32_service_interrupt (&win32_signal)
+ && WriteFile (err, prompt, strlen (prompt), &len, NULL))
+ {
+ bool is_console = (GetFileType (in) == FILE_TYPE_CHAR);
+ DWORD flags_save = 0;
+ int status = 0;
+ WCHAR *winput;
+
+ if (is_console)
+ {
+ if (GetConsoleMode (in, &flags_save))
+ {
+ DWORD flags = ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT;
+ if (echo)
+ flags |= ENABLE_ECHO_INPUT;
+ SetConsoleMode (in, flags);
+ } else
+ is_console = 0;
+ }
+
+ if (is_console)
+ {
+ winput = malloc (capacity * sizeof (WCHAR));
+ if (winput == NULL)
+ return false;
+
+ status = ReadConsoleW (in, winput, capacity, &len, NULL);
+ WideCharToMultiByte (CP_UTF8, 0, winput, len, input, capacity, NULL, NULL);
+ free (winput);
+ } else
+ status = ReadFile (in, input, capacity, &len, NULL);
+
+ string_null_terminate (input, (int)len, capacity);
+ chomp (input);
+
+ if (!echo)
+ WriteFile (err, "\r\n", 2, &len, NULL);
+ if (is_console)
+ SetConsoleMode (in, flags_save);
+ if (status && !win32_service_interrupt (&win32_signal))
+ return true;
+ }
+
+ return false;
+}
+
+#endif /* _WIN32 */
+
+
+#ifdef HAVE_GETPASS
+
+/**
+ * Open the current console TTY for read/write operations
+ *
+ * @params write If true, the user wants to write to the console
+ * otherwise read from the console
+ *
+ * @returns Returns a FILE pointer to either the TTY in read or write mode
+ * or stdin/stderr, depending on the write flag
+ *
+ */
+static FILE * open_tty (const bool write)
+{
+ FILE *ret;
+ ret = fopen ("/dev/tty", write ? "w" : "r");
+ if (!ret)
+ ret = write ? stderr : stdin;
+ return ret;
+}
+
+/**
+ * Closes the TTY FILE pointer, but only if it is not a stdin/stderr FILE object.
+ *
+ * @params fp FILE pointer to close
+ *
+ */
+static void close_tty (FILE *fp)
+{
+ if (fp != stderr && fp != stdin)
+ fclose (fp);
+}
+
+#endif /* HAVE_GETPASS */
+
+
+/**
+ * Core function for getting input from console
+ *
+ * @params prompt The prompt to present to the user
+ * @params echo Should the user see what is being typed
+ * @params input Pointer to the buffer used to save the user input
+ * @params capacity Size of the input buffer
+ *
+ * @returns Returns True if user input was gathered
+ */
+static bool get_console_input (const char *prompt, const bool echo, char *input, const int capacity)
+{
+ bool ret = false;
+ ASSERT (prompt);
+ ASSERT (input);
+ ASSERT (capacity > 0);
+ input[0] = '\0';
+
+#if defined(_WIN32)
+ return get_console_input_win32 (prompt, echo, input, capacity);
+#elif defined(HAVE_GETPASS)
+
+ /* did we --daemon'ize before asking for passwords?
+ * (in which case neither stdin or stderr are connected to a tty and
+ * /dev/tty can not be open()ed anymore)
+ */
+ if ( !isatty(0) && !isatty(2) )
+ {
+ int fd = open( "/dev/tty", O_RDWR );
+ if ( fd < 0 )
+ {
+ msg(M_FATAL, "neither stdin nor stderr are a tty device and you have neither a "
+ "controlling tty nor systemd - can't ask for '%s'. If you used --daemon, "
+ "you need to use --askpass to make passphrase-protected keys work, and you "
+ "can not use --auth-nocache.", prompt );
+ }
+ close(fd);
+ }
+
+ if (echo)
+ {
+ FILE *fp;
+
+ fp = open_tty (true);
+ fprintf (fp, "%s", prompt);
+ fflush (fp);
+ close_tty (fp);
+
+ fp = open_tty (false);
+ if (fgets (input, capacity, fp) != NULL)
+ {
+ chomp (input);
+ ret = true;
+ }
+ close_tty (fp);
+ } else {
+ char *gp = getpass (prompt);
+ if (gp)
+ {
+ strncpynt (input, gp, capacity);
+ memset (gp, 0, strlen (gp));
+ ret = true;
+ }
+ }
+#else
+ msg (M_FATAL, "Sorry, but I can't get console input on this OS (%s)", prompt);
+#endif
+ return ret;
+}
+
+
+/**
+ * @copydoc query_user_exec()
+ *
+ * Default method for querying user using default stdin/stdout on a console.
+ * This needs to be available as a backup interface for the alternative
+ * implementations in case they cannot query through their implementation
+ * specific methods.
+ *
+ * If no alternative implementation is declared, a wrapper in console.h will ensure
+ * query_user_exec() will call this function instead.
+ *
+ */
+bool query_user_exec_builtin()
+{
+ bool ret = true; /* Presume everything goes okay */
+ int i;
+
+ /* Loop through configured query_user slots */
+ for (i = 0; i < QUERY_USER_NUMSLOTS && query_user[i].response != NULL; i++)
+ {
+ if (!get_console_input(query_user[i].prompt, query_user[i].echo,
+ query_user[i].response, query_user[i].response_len) )
+ {
+ /* Force the final result state to failed on failure */
+ ret = false;
+ }
+ }
+
+ return ret;
+}
diff --git a/src/openvpn/console_systemd.c b/src/openvpn/console_systemd.c
new file mode 100644
index 0000000..8a953c9
--- /dev/null
+++ b/src/openvpn/console_systemd.c
@@ -0,0 +1,122 @@
+/*
+ * OpenVPN -- An application to securely tunnel IP networks
+ * over a single UDP port, with support for SSL/TLS-based
+ * session authentication and key exchange,
+ * packet encryption, packet authentication, and
+ * packet compression.
+ *
+ * Copyright (C) 2014-2015 David Sommerseth <davids@redhat.com>
+ * Copyright (C) 2016 David Sommerseth <dazo@privateinternetaccess.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program (see the file COPYING included with this
+ * distribution); if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/**
+ * @file Alternative method to query for user input, using systemd
+ *
+ */
+
+#include "config.h"
+
+#ifdef ENABLE_SYSTEMD
+#include "syshead.h"
+#include "console.h"
+#include "misc.h"
+
+#include <systemd/sd-daemon.h>
+
+/*
+ * is systemd running
+ */
+
+static bool
+check_systemd_running ()
+{
+ struct stat c;
+
+ /* We simply test whether the systemd cgroup hierarchy is
+ * mounted, as well as the systemd-ask-password executable
+ * being available */
+
+ return (sd_booted() > 0)
+ && (stat(SYSTEMD_ASK_PASSWORD_PATH, &c) == 0);
+
+}
+
+static bool
+get_console_input_systemd (const char *prompt, const bool echo, char *input, const int capacity)
+{
+ int std_out;
+ bool ret = false;
+ struct argv argv = argv_new ();
+
+ argv_printf (&argv, SYSTEMD_ASK_PASSWORD_PATH);
+#ifdef SYSTEMD_NEWER_THAN_216
+ /* the --echo support arrived in upstream systemd 217 */
+ if( echo )
+ {
+ argv_printf_cat(&argv, "--echo");
+ }
+#endif
+ argv_printf_cat (&argv, "--icon network-vpn");
+ argv_printf_cat (&argv, "%s", prompt);
+
+ if ((std_out = openvpn_popen (&argv, NULL)) < 0) {
+ return false;
+ }
+ memset (input, 0, capacity);
+ if (read (std_out, input, capacity-1) != 0)
+ {
+ chomp (input);
+ ret = true;
+ }
+ close (std_out);
+
+ argv_reset (&argv);
+
+ return ret;
+}
+
+/**
+ * Systemd aware implementation of query_user_exec(). If systemd is not running
+ * it will fall back to use query_user_exec_builtin() instead.
+ *
+ */
+bool query_user_exec()
+{
+ bool ret = true; /* Presume everything goes okay */
+ int i;
+
+ /* If systemd is not available, use the default built-in mechanism */
+ if (!check_systemd_running())
+ {
+ return query_user_exec_builtin();
+ }
+
+ /* Loop through the complete query setup and when needed, collect the information */
+ for (i = 0; i < QUERY_USER_NUMSLOTS && query_user[i].response != NULL; i++)
+ {
+ if (!get_console_input_systemd(query_user[i].prompt, query_user[i].echo,
+ query_user[i].response, query_user[i].response_len) )
+ {
+ /* Force the final result state to failed on failure */
+ ret = false;
+ }
+ }
+
+ return ret;
+}
+
+#endif /* ENABLE_SYSTEMD */
diff --git a/src/openvpn/crypto.c b/src/openvpn/crypto.c
index 400bf11..05622ce 100644
--- a/src/openvpn/crypto.c
+++ b/src/openvpn/crypto.c
@@ -6,7 +6,7 @@
* packet compression.
*
* Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net>
- * Copyright (C) 2010 Fox Crypto B.V. <openvpn@fox-it.com>
+ * Copyright (C) 2010-2016 Fox Crypto B.V. <openvpn@fox-it.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
@@ -35,7 +35,8 @@
#include "crypto.h"
#include "error.h"
-#include "misc.h"
+#include "integer.h"
+#include "platform.h"
#include "memdbg.h"
@@ -62,38 +63,114 @@
* happen unless the frame parameters are wrong.
*/
-#define CRYPT_ERROR(format) \
- do { msg (D_CRYPT_ERRORS, "%s: " format, error_prefix); goto error_exit; } while (false)
+static void
+openvpn_encrypt_aead (struct buffer *buf, struct buffer work,
+ struct crypto_options *opt) {
+#ifdef HAVE_AEAD_CIPHER_MODES
+ struct gc_arena gc;
+ int outlen = 0;
+ const struct key_ctx *ctx = &opt->key_ctx_bi.encrypt;
+ uint8_t *mac_out = NULL;
+ const cipher_kt_t *cipher_kt = cipher_ctx_get_cipher_kt (ctx->cipher);
+ const int mac_len = cipher_kt_tag_size (cipher_kt);
+
+ /* IV, packet-ID and implicit IV required for this mode. */
+ ASSERT (ctx->cipher);
+ ASSERT (cipher_kt_mode_aead (cipher_kt));
+ ASSERT (opt->flags & CO_USE_IV);
+ ASSERT (packet_id_initialized(&opt->packet_id));
-/**
- * As memcmp(), but constant-time.
- * Returns 0 when data is equal, non-zero otherwise.
- */
-static int
-memcmp_constant_time (const void *a, const void *b, size_t size) {
- const uint8_t * a1 = a;
- const uint8_t * b1 = b;
- int ret = 0;
- size_t i;
-
- for (i = 0; i < size; i++) {
- ret |= *a1++ ^ *b1++;
+ gc_init (&gc);
+
+ /* Prepare IV */
+ {
+ struct buffer iv_buffer;
+ struct packet_id_net pin;
+ uint8_t iv[OPENVPN_MAX_IV_LENGTH];
+ const int iv_len = cipher_ctx_iv_length (ctx->cipher);
+
+ ASSERT (iv_len >= OPENVPN_AEAD_MIN_IV_LEN && iv_len <= OPENVPN_MAX_IV_LENGTH);
+
+ memset(iv, 0, sizeof(iv));
+ buf_set_write (&iv_buffer, iv, iv_len);
+
+ /* IV starts with packet id to make the IV unique for packet */
+ packet_id_alloc_outgoing (&opt->packet_id.send, &pin, false);
+ ASSERT (packet_id_write (&pin, &iv_buffer, false, false));
+
+ /* Remainder of IV consists of implicit part (unique per session) */
+ ASSERT (buf_write (&iv_buffer, ctx->implicit_iv, ctx->implicit_iv_len));
+ ASSERT (iv_buffer.len == iv_len);
+
+ /* Write explicit part of IV to work buffer */
+ ASSERT (buf_write(&work, iv, iv_len - ctx->implicit_iv_len));
+ dmsg (D_PACKET_CONTENT, "ENCRYPT IV: %s", format_hex (iv, iv_len, 0, &gc));
+
+ /* Init cipher_ctx with IV. key & keylen are already initialized */
+ ASSERT (cipher_ctx_reset(ctx->cipher, iv));
}
- return ret;
+ /* Reserve space for authentication tag */
+ mac_out = buf_write_alloc (&work, mac_len);
+ ASSERT (mac_out);
+
+ dmsg (D_PACKET_CONTENT, "ENCRYPT FROM: %s", format_hex (BPTR (buf), BLEN (buf), 80, &gc));
+
+ /* Buffer overflow check */
+ if (!buf_safe (&work, buf->len + cipher_ctx_block_size(ctx->cipher)))
+ {
+ msg (D_CRYPT_ERRORS,
+ "ENCRYPT: buffer size error, bc=%d bo=%d bl=%d wc=%d wo=%d wl=%d",
+ buf->capacity, buf->offset, buf->len, work.capacity, work.offset,
+ work.len);
+ goto err;
+ }
+
+ /* For AEAD ciphers, authenticate Additional Data, including opcode */
+ ASSERT (cipher_ctx_update_ad (ctx->cipher, BPTR (&work), BLEN (&work) - mac_len));
+ dmsg (D_PACKET_CONTENT, "ENCRYPT AD: %s",
+ format_hex (BPTR (&work), BLEN (&work) - mac_len, 0, &gc));
+
+ /* Encrypt packet ID, payload */
+ ASSERT (cipher_ctx_update (ctx->cipher, BEND (&work), &outlen, BPTR (buf), BLEN (buf)));
+ ASSERT (buf_inc_len (&work, outlen));
+
+ /* Flush the encryption buffer */
+ ASSERT (cipher_ctx_final (ctx->cipher, BEND (&work), &outlen));
+ ASSERT (buf_inc_len (&work, outlen));
+
+ /* Write authentication tag */
+ ASSERT (cipher_ctx_get_tag (ctx->cipher, mac_out, mac_len));
+
+ *buf = work;
+
+ dmsg (D_PACKET_CONTENT, "ENCRYPT TO: %s", format_hex (BPTR (buf), BLEN (buf), 80, &gc));
+
+ gc_free (&gc);
+ return;
+
+err:
+ crypto_clear_error();
+ buf->len = 0;
+ gc_free (&gc);
+ return;
+#else /* HAVE_AEAD_CIPHER_MODES */
+ ASSERT (0);
+#endif
}
-void
-openvpn_encrypt (struct buffer *buf, struct buffer work,
- const struct crypto_options *opt,
- const struct frame* frame)
+static void
+openvpn_encrypt_v1 (struct buffer *buf, struct buffer work,
+ struct crypto_options *opt)
{
struct gc_arena gc;
gc_init (&gc);
- if (buf->len > 0 && opt->key_ctx_bi)
+ if (buf->len > 0 && opt)
{
- struct key_ctx *ctx = &opt->key_ctx_bi->encrypt;
+ const struct key_ctx *ctx = &opt->key_ctx_bi.encrypt;
+ uint8_t *mac_out = NULL;
+ const uint8_t *hmac_start = NULL;
/* Do Encrypt from buf -> work */
if (ctx->cipher)
@@ -103,6 +180,14 @@ openvpn_encrypt (struct buffer *buf, struct buffer work,
const cipher_kt_t *cipher_kt = cipher_ctx_get_cipher_kt (ctx->cipher);
int outlen;
+ /* Reserve space for HMAC */
+ if (ctx->hmac)
+ {
+ mac_out = buf_write_alloc (&work, hmac_ctx_size(ctx->hmac));
+ ASSERT (mac_out);
+ hmac_start = BEND(&work);
+ }
+
if (cipher_kt_mode_cbc(cipher_kt))
{
CLEAR (iv_buf);
@@ -111,11 +196,11 @@ openvpn_encrypt (struct buffer *buf, struct buffer work,
if (opt->flags & CO_USE_IV)
prng_bytes (iv_buf, iv_size);
- /* Put packet ID in plaintext buffer or IV, depending on cipher mode */
- if (opt->packet_id)
+ /* Put packet ID in plaintext buffer */
+ if (packet_id_initialized(&opt->packet_id))
{
struct packet_id_net pin;
- packet_id_alloc_outgoing (&opt->packet_id->send, &pin, BOOL_CAST (opt->flags & CO_PACKET_ID_LONG_FORM));
+ packet_id_alloc_outgoing (&opt->packet_id.send, &pin, BOOL_CAST (opt->flags & CO_PACKET_ID_LONG_FORM));
ASSERT (packet_id_write (&pin, buf, BOOL_CAST (opt->flags & CO_PACKET_ID_LONG_FORM), true));
}
}
@@ -124,10 +209,11 @@ openvpn_encrypt (struct buffer *buf, struct buffer work,
struct packet_id_net pin;
struct buffer b;
- ASSERT (opt->flags & CO_USE_IV); /* IV and packet-ID required */
- ASSERT (opt->packet_id); /* for this mode. */
+ /* IV and packet-ID required for this mode. */
+ ASSERT (opt->flags & CO_USE_IV);
+ ASSERT (packet_id_initialized(&opt->packet_id));
- packet_id_alloc_outgoing (&opt->packet_id->send, &pin, true);
+ packet_id_alloc_outgoing (&opt->packet_id.send, &pin, true);
memset (iv_buf, 0, iv_size);
buf_set_write (&b, iv_buf, iv_size);
ASSERT (packet_id_write (&pin, &b, true, false));
@@ -137,12 +223,12 @@ openvpn_encrypt (struct buffer *buf, struct buffer work,
ASSERT (0);
}
- /* initialize work buffer with FRAME_HEADROOM bytes of prepend capacity */
- ASSERT (buf_init (&work, FRAME_HEADROOM (frame)));
-
/* set the IV pseudo-randomly */
if (opt->flags & CO_USE_IV)
- dmsg (D_PACKET_CONTENT, "ENCRYPT IV: %s", format_hex (iv_buf, iv_size, 0, &gc));
+ {
+ ASSERT (buf_write(&work, iv_buf, iv_size));
+ dmsg (D_PACKET_CONTENT, "ENCRYPT IV: %s", format_hex (iv_buf, iv_size, 0, &gc));
+ }
dmsg (D_PACKET_CONTENT, "ENCRYPT FROM: %s",
format_hex (BPTR (buf), BLEN (buf), 80, &gc));
@@ -165,52 +251,50 @@ openvpn_encrypt (struct buffer *buf, struct buffer work,
}
/* Encrypt packet ID, payload */
- ASSERT (cipher_ctx_update (ctx->cipher, BPTR (&work), &outlen, BPTR (buf), BLEN (buf)));
+ ASSERT (cipher_ctx_update (ctx->cipher, BEND (&work), &outlen, BPTR (buf), BLEN (buf)));
ASSERT (buf_inc_len(&work, outlen));
/* Flush the encryption buffer */
- ASSERT (cipher_ctx_final(ctx->cipher, BPTR (&work) + outlen, &outlen));
+ ASSERT (cipher_ctx_final(ctx->cipher, BEND (&work), &outlen));
ASSERT (buf_inc_len(&work, outlen));
/* For all CBC mode ciphers, check the last block is complete */
ASSERT (cipher_kt_mode (cipher_kt) != OPENVPN_MODE_CBC ||
outlen == iv_size);
-
- /* prepend the IV to the ciphertext */
- if (opt->flags & CO_USE_IV)
- {
- uint8_t *output = buf_prepend (&work, iv_size);
- ASSERT (output);
- memcpy (output, iv_buf, iv_size);
- }
-
- dmsg (D_PACKET_CONTENT, "ENCRYPT TO: %s",
- format_hex (BPTR (&work), BLEN (&work), 80, &gc));
}
else /* No Encryption */
{
- if (opt->packet_id)
+ if (packet_id_initialized(&opt->packet_id))
{
struct packet_id_net pin;
- packet_id_alloc_outgoing (&opt->packet_id->send, &pin, BOOL_CAST (opt->flags & CO_PACKET_ID_LONG_FORM));
+ packet_id_alloc_outgoing (&opt->packet_id.send, &pin, BOOL_CAST (opt->flags & CO_PACKET_ID_LONG_FORM));
ASSERT (packet_id_write (&pin, buf, BOOL_CAST (opt->flags & CO_PACKET_ID_LONG_FORM), true));
}
+ if (ctx->hmac)
+ {
+ hmac_start = BPTR(buf);
+ ASSERT (mac_out = buf_prepend (buf, hmac_ctx_size(ctx->hmac)));
+ }
+ if (BLEN(&work)) {
+ buf_write_prepend(buf, BPTR(&work), BLEN(&work));
+ }
work = *buf;
}
/* HMAC the ciphertext (or plaintext if !cipher) */
if (ctx->hmac)
{
- uint8_t *output = NULL;
-
hmac_ctx_reset (ctx->hmac);
- hmac_ctx_update (ctx->hmac, BPTR(&work), BLEN(&work));
- output = buf_prepend (&work, hmac_ctx_size(ctx->hmac));
- ASSERT (output);
- hmac_ctx_final (ctx->hmac, output);
+ hmac_ctx_update (ctx->hmac, hmac_start, BEND(&work) - hmac_start);
+ hmac_ctx_final (ctx->hmac, mac_out);
+ dmsg (D_PACKET_CONTENT, "ENCRYPT HMAC: %s",
+ format_hex (mac_out, hmac_ctx_size(ctx->hmac), 80, &gc));
}
*buf = work;
+
+ dmsg (D_PACKET_CONTENT, "ENCRYPT TO: %s",
+ format_hex (BPTR (&work), BLEN (&work), 80, &gc));
}
gc_free (&gc);
@@ -223,6 +307,47 @@ err:
return;
}
+void
+openvpn_encrypt (struct buffer *buf, struct buffer work,
+ struct crypto_options *opt)
+{
+ if (buf->len > 0 && opt)
+ {
+ const cipher_kt_t *cipher_kt =
+ cipher_ctx_get_cipher_kt(opt->key_ctx_bi.encrypt.cipher);
+
+ if (cipher_kt_mode_aead (cipher_kt))
+ openvpn_encrypt_aead(buf, work, opt);
+ else
+ openvpn_encrypt_v1(buf, work, opt);
+ }
+}
+
+bool crypto_check_replay(struct crypto_options *opt,
+ const struct packet_id_net *pin, const char *error_prefix,
+ struct gc_arena *gc) {
+ bool ret = false;
+ packet_id_reap_test (&opt->packet_id.rec);
+ if (packet_id_test (&opt->packet_id.rec, pin))
+ {
+ packet_id_add (&opt->packet_id.rec, pin);
+ if (opt->pid_persist && (opt->flags & CO_PACKET_ID_LONG_FORM))
+ packet_id_persist_save_obj (opt->pid_persist, &opt->packet_id);
+ ret = true;
+ }
+ else
+ {
+ if (!(opt->flags & CO_MUTE_REPLAY_WARNINGS))
+ {
+ msg (D_REPLAY_ERRORS, "%s: bad packet ID (may be a replay): %s -- "
+ "see the man page entry for --no-replay and --replay-window for "
+ "more info or silence this warning with --mute-replay-warnings",
+ error_prefix, packet_id_net_print (pin, true, gc));
+ }
+ }
+ return ret;
+}
+
/*
* If (opt->flags & CO_USE_IV) is not NULL, we will read an IV from the packet.
*
@@ -231,21 +356,169 @@ err:
* On success, buf is set to point to plaintext, true
* is returned.
*/
-bool
-openvpn_decrypt (struct buffer *buf, struct buffer work,
- const struct crypto_options *opt,
- const struct frame* frame)
+static bool
+openvpn_decrypt_aead (struct buffer *buf, struct buffer work,
+ struct crypto_options *opt, const struct frame* frame,
+ const uint8_t *ad_start)
+{
+#ifdef HAVE_AEAD_CIPHER_MODES
+ static const char error_prefix[] = "AEAD Decrypt error";
+ struct packet_id_net pin = { 0 };
+ const struct key_ctx *ctx = &opt->key_ctx_bi.decrypt;
+ const cipher_kt_t *cipher_kt = cipher_ctx_get_cipher_kt (ctx->cipher);
+ uint8_t *tag_ptr = NULL;
+ int tag_size = 0;
+ int outlen;
+ struct gc_arena gc;
+
+ gc_init (&gc);
+
+ ASSERT (opt);
+ ASSERT (frame);
+ ASSERT (buf->len > 0);
+ ASSERT (ctx->cipher);
+ ASSERT (cipher_kt_mode_aead (cipher_kt));
+
+ dmsg (D_PACKET_CONTENT, "DECRYPT FROM: %s",
+ format_hex (BPTR (buf), BLEN (buf), 80, &gc));
+
+ ASSERT (ad_start >= buf->data && ad_start <= BPTR (buf));
+
+ ASSERT (buf_init (&work, FRAME_HEADROOM_ADJ (frame, FRAME_HEADROOM_MARKER_DECRYPT)));
+
+ /* IV and Packet ID required for this mode */
+ ASSERT (packet_id_initialized (&opt->packet_id));
+ ASSERT (opt->flags & CO_USE_IV);
+
+ /* Combine IV from explicit part from packet and implicit part from context */
+ {
+ uint8_t iv[OPENVPN_MAX_IV_LENGTH] = { 0 };
+ const int iv_len = cipher_ctx_iv_length (ctx->cipher);
+ const size_t packet_iv_len = iv_len - ctx->implicit_iv_len;
+
+ ASSERT (ctx->implicit_iv_len <= iv_len);
+ if (buf->len + ctx->implicit_iv_len < iv_len)
+ CRYPT_ERROR ("missing IV info");
+
+ memcpy (iv, BPTR(buf), packet_iv_len);
+ memcpy (iv + packet_iv_len, ctx->implicit_iv, ctx->implicit_iv_len);
+
+ dmsg (D_PACKET_CONTENT, "DECRYPT IV: %s", format_hex (iv, iv_len, 0, &gc));
+
+ /* Load IV, ctx->cipher was already initialized with key & keylen */
+ if (!cipher_ctx_reset (ctx->cipher, iv))
+ {
+ CRYPT_ERROR ("cipher init failed");
+ }
+ }
+
+ /* Read packet ID from packet */
+ if (!packet_id_read (&pin, buf, false))
+ {
+ CRYPT_ERROR ("error reading packet-id");
+ }
+
+ /* keep the tag value to feed in later */
+ tag_size = cipher_kt_tag_size(cipher_kt);
+ if (buf->len < tag_size)
+ {
+ CRYPT_ERROR ("missing tag");
+ }
+ tag_ptr = BPTR(buf);
+ ASSERT (buf_advance (buf, tag_size));
+ dmsg (D_PACKET_CONTENT, "DECRYPT MAC: %s", format_hex (tag_ptr, tag_size, 0, &gc));
+#if defined(ENABLE_CRYPTO_OPENSSL) && OPENSSL_VERSION_NUMBER < 0x10001040L
+ /* OpenSSL <= 1.0.1c bug requires set tag before processing ciphertext */
+ if (!EVP_CIPHER_CTX_ctrl (ctx->cipher, EVP_CTRL_GCM_SET_TAG, tag_size, tag_ptr))
+ {
+ CRYPT_ERROR ("setting tag failed");
+ }
+#endif
+
+ if (buf->len < 1)
+ {
+ CRYPT_ERROR ("missing payload");
+ }
+
+ dmsg (D_PACKET_CONTENT, "DECRYPT FROM: %s", format_hex (BPTR(buf), BLEN(buf), 0, &gc));
+
+ /* Buffer overflow check (should never fail) */
+ if (!buf_safe (&work, buf->len + cipher_ctx_block_size(ctx->cipher)))
+ {
+ CRYPT_ERROR ("potential buffer overflow");
+ }
+
+ {
+ /* feed in tag and the authenticated data */
+ const int ad_size = BPTR (buf) - ad_start - tag_size;
+ ASSERT (cipher_ctx_update_ad (ctx->cipher, ad_start, ad_size));
+ dmsg (D_PACKET_CONTENT, "DECRYPT AD: %s",
+ format_hex (BPTR (buf) - ad_size - tag_size, ad_size, 0, &gc));
+ }
+
+ /* Decrypt and authenticate packet */
+ if (!cipher_ctx_update (ctx->cipher, BPTR (&work), &outlen, BPTR (buf),
+ BLEN (buf)))
+ {
+ CRYPT_ERROR ("cipher update failed");
+ }
+ ASSERT (buf_inc_len (&work, outlen));
+ if (!cipher_ctx_final_check_tag (ctx->cipher, BPTR (&work) + outlen,
+ &outlen, tag_ptr, tag_size))
+ {
+ CRYPT_ERROR ("cipher final failed");
+ }
+ ASSERT (buf_inc_len (&work, outlen));
+
+ dmsg (D_PACKET_CONTENT, "DECRYPT TO: %s",
+ format_hex (BPTR (&work), BLEN (&work), 80, &gc));
+
+ if (!crypto_check_replay (opt, &pin, error_prefix, &gc))
+ {
+ goto error_exit;
+ }
+
+ *buf = work;
+
+ gc_free (&gc);
+ return true;
+
+ error_exit:
+ crypto_clear_error();
+ buf->len = 0;
+ gc_free (&gc);
+ return false;
+#else /* HAVE_AEAD_CIPHER_MODES */
+ ASSERT (0);
+ return false;
+#endif
+}
+
+/*
+ * If (opt->flags & CO_USE_IV) is not NULL, we will read an IV from the packet.
+ *
+ * Set buf->len to 0 and return false on decrypt error.
+ *
+ * On success, buf is set to point to plaintext, true
+ * is returned.
+ */
+static bool
+openvpn_decrypt_v1 (struct buffer *buf, struct buffer work,
+ struct crypto_options *opt, const struct frame* frame)
{
static const char error_prefix[] = "Authenticate/Decrypt packet error";
struct gc_arena gc;
gc_init (&gc);
- if (buf->len > 0 && opt->key_ctx_bi)
+ if (buf->len > 0 && opt)
{
- struct key_ctx *ctx = &opt->key_ctx_bi->decrypt;
+ const struct key_ctx *ctx = &opt->key_ctx_bi.decrypt;
struct packet_id_net pin;
bool have_pin = false;
+ dmsg (D_PACKET_CONTENT, "DECRYPT FROM: %s",
+ format_hex (BPTR (buf), BLEN (buf), 80, &gc));
+
/* Verify the HMAC */
if (ctx->hmac)
{
@@ -325,7 +598,7 @@ openvpn_decrypt (struct buffer *buf, struct buffer work,
{
if (cipher_kt_mode_cbc(cipher_kt))
{
- if (opt->packet_id)
+ if (packet_id_initialized(&opt->packet_id))
{
if (!packet_id_read (&pin, &work, BOOL_CAST (opt->flags & CO_PACKET_ID_LONG_FORM)))
CRYPT_ERROR ("error reading CBC packet-id");
@@ -336,8 +609,9 @@ openvpn_decrypt (struct buffer *buf, struct buffer work,
{
struct buffer b;
- ASSERT (opt->flags & CO_USE_IV); /* IV and packet-ID required */
- ASSERT (opt->packet_id); /* for this mode. */
+ /* IV and packet-ID required for this mode. */
+ ASSERT (opt->flags & CO_USE_IV);
+ ASSERT (packet_id_initialized(&opt->packet_id));
buf_set_read (&b, iv_buf, iv_size);
if (!packet_id_read (&pin, &b, true))
@@ -353,7 +627,7 @@ openvpn_decrypt (struct buffer *buf, struct buffer work,
else
{
work = *buf;
- if (opt->packet_id)
+ if (packet_id_initialized(&opt->packet_id))
{
if (!packet_id_read (&pin, &work, BOOL_CAST (opt->flags & CO_PACKET_ID_LONG_FORM)))
CRYPT_ERROR ("error reading packet-id");
@@ -361,22 +635,9 @@ openvpn_decrypt (struct buffer *buf, struct buffer work,
}
}
- if (have_pin)
+ if (have_pin && !crypto_check_replay(opt, &pin, error_prefix, &gc))
{
- packet_id_reap_test (&opt->packet_id->rec);
- if (packet_id_test (&opt->packet_id->rec, &pin))
- {
- packet_id_add (&opt->packet_id->rec, &pin);
- if (opt->pid_persist && (opt->flags & CO_PACKET_ID_LONG_FORM))
- packet_id_persist_save_obj (opt->pid_persist, opt->packet_id);
- }
- else
- {
- if (!(opt->flags & CO_MUTE_REPLAY_WARNINGS))
- msg (D_REPLAY_ERRORS, "%s: bad packet ID (may be a replay): %s -- see the man page entry for --no-replay and --replay-window for more info or silence this warning with --mute-replay-warnings",
- error_prefix, packet_id_net_print (&pin, true, &gc));
- goto error_exit;
- }
+ goto error_exit;
}
*buf = work;
}
@@ -391,14 +652,36 @@ openvpn_decrypt (struct buffer *buf, struct buffer work,
return false;
}
-/*
- * How many bytes will we add to frame buffer for a given
- * set of crypto options?
- */
+
+bool
+openvpn_decrypt (struct buffer *buf, struct buffer work,
+ struct crypto_options *opt, const struct frame* frame,
+ const uint8_t *ad_start)
+{
+ bool ret = false;
+
+ if (buf->len > 0 && opt)
+ {
+ const struct key_ctx *ctx = &opt->key_ctx_bi.decrypt;
+ if (cipher_kt_mode_aead (cipher_ctx_get_cipher_kt (ctx->cipher)))
+ {
+ ret = openvpn_decrypt_aead (buf, work, opt, frame, ad_start);
+ }
+ else
+ {
+ ret = openvpn_decrypt_v1 (buf, work, opt, frame);
+ }
+ }
+ else
+ {
+ ret = true;
+ }
+ return ret;
+}
+
void
crypto_adjust_frame_parameters(struct frame *frame,
const struct key_type* kt,
- bool cipher_defined,
bool use_iv,
bool packet_id,
bool packet_id_long_form)
@@ -408,11 +691,14 @@ crypto_adjust_frame_parameters(struct frame *frame,
if (packet_id)
crypto_overhead += packet_id_size (packet_id_long_form);
- if (cipher_defined)
+ if (kt->cipher)
{
if (use_iv)
crypto_overhead += cipher_kt_iv_size (kt->cipher);
+ if (cipher_kt_mode_aead (kt->cipher))
+ crypto_overhead += cipher_kt_tag_size (kt->cipher);
+
/* extra block required by cipher_ctx_update() */
crypto_overhead += cipher_kt_block_size (kt->cipher);
}
@@ -421,8 +707,16 @@ 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 %zu bytes",
- __func__, crypto_overhead);
+ msg(D_MTU_DEBUG, "%s: Adjusting frame parameters for crypto by %u bytes",
+ __func__, (unsigned int) crypto_overhead);
+}
+
+size_t
+crypto_max_overhead(void)
+{
+ return packet_id_size(true) + OPENVPN_MAX_IV_LENGTH +
+ OPENVPN_MAX_CIPHER_BLOCK_SIZE +
+ max_int (OPENVPN_MAX_HMAC_SIZE, OPENVPN_AEAD_TAG_LENGTH);
}
/*
@@ -430,39 +724,55 @@ crypto_adjust_frame_parameters(struct frame *frame,
*/
void
init_key_type (struct key_type *kt, const char *ciphername,
- bool ciphername_defined, const char *authname,
- bool authname_defined, int keysize,
- bool cfb_ofb_allowed, bool warn)
+ const char *authname, int keysize, bool tls_mode, bool warn)
{
+ bool aead_cipher = false;
+
+ ASSERT(ciphername);
+ ASSERT(authname);
+
CLEAR (*kt);
- if (ciphername && ciphername_defined)
+ if (strcmp (ciphername, "none") != 0)
{
kt->cipher = cipher_kt_get (translate_cipher_name_from_openvpn(ciphername));
+ if (!kt->cipher)
+ {
+ msg (M_FATAL, "Cipher %s not supported", ciphername);
+ }
+
kt->cipher_length = cipher_kt_key_size (kt->cipher);
if (keysize > 0 && keysize <= MAX_CIPHER_KEY_LENGTH)
kt->cipher_length = keysize;
/* check legal cipher mode */
- {
- if (!(cipher_kt_mode_cbc(kt->cipher)
+ aead_cipher = cipher_kt_mode_aead(kt->cipher);
+ if (!(cipher_kt_mode_cbc(kt->cipher)
+ || (tls_mode && aead_cipher)
#ifdef ENABLE_OFB_CFB_MODE
- || (cfb_ofb_allowed && cipher_kt_mode_ofb_cfb(kt->cipher))
+ || (tls_mode && cipher_kt_mode_ofb_cfb(kt->cipher))
#endif
- ))
- msg (M_FATAL, "Cipher '%s' mode not supported", ciphername);
- }
+ ))
+ msg (M_FATAL, "Cipher '%s' mode not supported", ciphername);
+
+ if (OPENVPN_MAX_CIPHER_BLOCK_SIZE < cipher_kt_block_size(kt->cipher))
+ msg (M_FATAL, "Cipher '%s' not allowed: block size too big.", ciphername);
}
else
{
if (warn)
msg (M_WARN, "******* WARNING *******: null cipher specified, no encryption will be used");
}
- if (authname && authname_defined)
+ if (strcmp (authname, "none") != 0)
{
- kt->digest = md_kt_get (authname);
- kt->hmac_length = md_kt_size (kt->digest);
+ if (!aead_cipher) { /* Ignore auth for AEAD ciphers */
+ kt->digest = md_kt_get (authname);
+ kt->hmac_length = md_kt_size (kt->digest);
+
+ if (OPENVPN_MAX_HMAC_SIZE < kt->hmac_length)
+ msg (M_FATAL, "HMAC '%s' not allowed: digest size too big.", authname);
+ }
}
- else
+ else if (!aead_cipher)
{
if (warn)
msg (M_WARN, "******* WARNING *******: null MAC specified, no authentication will be used");
@@ -486,15 +796,21 @@ init_key_ctx (struct key_ctx *ctx, struct key *key,
msg (D_HANDSHAKE, "%s: Cipher '%s' initialized with %d bit key",
prefix,
- cipher_kt_name(kt->cipher),
+ translate_cipher_name_to_openvpn(cipher_kt_name(kt->cipher)),
kt->cipher_length *8);
dmsg (D_SHOW_KEYS, "%s: CIPHER KEY: %s", prefix,
format_hex (key->cipher, kt->cipher_length, 0, &gc));
dmsg (D_CRYPTO_DEBUG, "%s: CIPHER block_size=%d iv_size=%d",
- prefix,
- cipher_kt_block_size(kt->cipher),
- cipher_kt_iv_size(kt->cipher));
+ prefix, cipher_kt_block_size(kt->cipher),
+ cipher_kt_iv_size(kt->cipher));
+ if (cipher_kt_block_size(kt->cipher) < 128/8)
+ {
+ msg (M_WARN, "WARNING: INSECURE cipher with block size less than 128"
+ " bit (%d bit). This allows attacks like SWEET32. Mitigate by "
+ "using a --cipher with a larger block size (e.g. AES-256-CBC).",
+ cipher_kt_block_size(kt->cipher)*8);
+ }
}
if (kt->digest && kt->hmac_length > 0)
{
@@ -532,6 +848,7 @@ free_key_ctx (struct key_ctx *ctx)
free(ctx->hmac);
ctx->hmac = NULL;
}
+ ctx->implicit_iv_len = 0;
}
void
@@ -541,7 +858,6 @@ free_key_ctx_bi (struct key_ctx_bi *ctx)
free_key_ctx(&ctx->decrypt);
}
-
static bool
key_is_zero (struct key *key, const struct key_type *kt)
{
@@ -621,8 +937,10 @@ check_replay_iv_consistency (const struct key_type *kt, bool packet_id, bool use
{
ASSERT(kt);
- if (cipher_kt_mode_ofb_cfb(kt->cipher) && !(packet_id && use_iv))
- msg (M_FATAL, "--no-replay or --no-iv cannot be used with a CFB or OFB mode cipher");
+ if (!(packet_id && use_iv) && (cipher_kt_mode_ofb_cfb(kt->cipher) ||
+ cipher_kt_mode_aead(kt->cipher)))
+ msg (M_FATAL, "--no-replay or --no-iv cannot be used with a CFB, OFB or "
+ "AEAD mode cipher");
}
/*
@@ -688,7 +1006,7 @@ key2_print (const struct key2* k,
}
void
-test_crypto (const struct crypto_options *co, struct frame* frame)
+test_crypto (struct crypto_options *co, struct frame* frame)
{
int i, j;
struct gc_arena gc = gc_new ();
@@ -697,10 +1015,35 @@ test_crypto (const struct crypto_options *co, struct frame* frame)
struct buffer encrypt_workspace = alloc_buf_gc (BUF_SIZE (frame), &gc);
struct buffer decrypt_workspace = alloc_buf_gc (BUF_SIZE (frame), &gc);
struct buffer buf = clear_buf();
+ void *buf_p;
/* init work */
ASSERT (buf_init (&work, FRAME_HEADROOM (frame)));
+#ifdef HAVE_AEAD_CIPHER_MODES
+ /* init implicit IV */
+ {
+ const cipher_kt_t *cipher =
+ cipher_ctx_get_cipher_kt(co->key_ctx_bi.encrypt.cipher);
+
+ if (cipher_kt_mode_aead(cipher))
+ {
+ size_t impl_iv_len = cipher_kt_iv_size(cipher) - sizeof(packet_id_type);
+ ASSERT (cipher_kt_iv_size(cipher) <= OPENVPN_MAX_IV_LENGTH);
+ ASSERT (cipher_kt_iv_size(cipher) >= OPENVPN_AEAD_MIN_IV_LEN);
+
+ /* Generate dummy implicit IV */
+ ASSERT (rand_bytes(co->key_ctx_bi.encrypt.implicit_iv,
+ OPENVPN_MAX_IV_LENGTH));
+ co->key_ctx_bi.encrypt.implicit_iv_len = impl_iv_len;
+
+ memcpy(co->key_ctx_bi.decrypt.implicit_iv,
+ co->key_ctx_bi.encrypt.implicit_iv, OPENVPN_MAX_IV_LENGTH);
+ co->key_ctx_bi.decrypt.implicit_iv_len = impl_iv_len;
+ }
+ }
+#endif
+
msg (M_INFO, "Entering " PACKAGE_NAME " crypto self-test mode.");
for (i = 1; i <= TUN_MTU_SIZE (frame); ++i)
{
@@ -718,13 +1061,18 @@ test_crypto (const struct crypto_options *co, struct frame* frame)
/* copy source to input buf */
buf = work;
- memcpy (buf_write_alloc (&buf, BLEN (&src)), BPTR (&src), BLEN (&src));
+ buf_p = buf_write_alloc (&buf, BLEN (&src));
+ ASSERT(buf_p);
+ memcpy (buf_p, BPTR (&src), BLEN (&src));
+
+ /* initialize work buffer with FRAME_HEADROOM bytes of prepend capacity */
+ ASSERT (buf_init (&encrypt_workspace, FRAME_HEADROOM (frame)));
/* encrypt */
- openvpn_encrypt (&buf, encrypt_workspace, co, frame);
+ openvpn_encrypt (&buf, encrypt_workspace, co);
/* decrypt */
- openvpn_decrypt (&buf, decrypt_workspace, co, frame);
+ openvpn_decrypt (&buf, decrypt_workspace, co, frame, BPTR (&buf));
/* compare */
if (buf.len != src.len)
@@ -741,90 +1089,47 @@ test_crypto (const struct crypto_options *co, struct frame* frame)
gc_free (&gc);
}
-#ifdef ENABLE_SSL
-
void
-get_tls_handshake_key (const struct key_type *key_type,
- struct key_ctx_bi *ctx,
- const char *passphrase_file,
- const int key_direction,
- const unsigned int flags)
+crypto_read_openvpn_key (const struct key_type *key_type,
+ struct key_ctx_bi *ctx, const char *key_file, const char *key_inline,
+ const int key_direction, const char *key_name, const char *opt_name)
{
- if (passphrase_file && key_type->hmac_length)
- {
- struct key2 key2;
- struct key_type kt = *key_type;
- struct key_direction_state kds;
-
- /* for control channel we are only authenticating, not encrypting */
- kt.cipher_length = 0;
- kt.cipher = NULL;
-
- if (flags & GHK_INLINE)
- {
- /* key was specified inline, key text is in passphrase_file */
- read_key_file (&key2, passphrase_file, RKF_INLINE|RKF_MUST_SUCCEED);
-
- /* succeeded? */
- if (key2.n == 2)
- msg (M_INFO, "Control Channel Authentication: tls-auth using INLINE static key file");
- else
- msg (M_FATAL, "INLINE tls-auth file lacks the requisite 2 keys");
- }
- else
- {
- /* first try to parse as an OpenVPN static key file */
- read_key_file (&key2, passphrase_file, 0);
-
- /* succeeded? */
- if (key2.n == 2)
- {
- msg (M_INFO,
- "Control Channel Authentication: using '%s' as a " PACKAGE_NAME " static key file",
- passphrase_file);
- }
- else
- {
- int hash_size;
-
- CLEAR (key2);
-
- /* failed, now try to get hash from a freeform file */
- hash_size = read_passphrase_hash (passphrase_file,
- kt.digest,
- key2.keys[0].hmac,
- MAX_HMAC_KEY_LENGTH);
- ASSERT (hash_size == kt.hmac_length);
+ struct key2 key2;
+ struct key_direction_state kds;
+ char log_prefix[128] = { 0 };
- /* suceeded */
- key2.n = 1;
+ if (key_inline)
+ {
+ read_key_file (&key2, key_inline, RKF_MUST_SUCCEED|RKF_INLINE);
+ }
+ else
+ {
+ read_key_file (&key2, key_file, RKF_MUST_SUCCEED);
+ }
- msg (M_INFO,
- "Control Channel Authentication: using '%s' as a free-form passphrase file",
- passphrase_file);
- msg (M_WARN, "DEPRECATED OPTION: Using freeform files for tls-auth is deprecated and is not supported in OpenVPN 2.4 or newer versions");
- }
- }
- /* handle key direction */
+ if (key2.n != 2)
+ {
+ msg (M_ERR, "File '%s' does not have OpenVPN Static Key format. Using "
+ "free-form passphrase file is not supported anymore.", key_file);
+ }
- key_direction_state_init (&kds, key_direction);
- must_have_n_keys (passphrase_file, "tls-auth", &key2, kds.need_keys);
+ /* check for and fix highly unlikely key problems */
+ verify_fix_key2 (&key2, key_type, key_file);
- /* initialize hmac key in both directions */
+ /* handle key direction */
+ key_direction_state_init (&kds, key_direction);
+ must_have_n_keys (key_file, opt_name, &key2, kds.need_keys);
- init_key_ctx (&ctx->encrypt, &key2.keys[kds.out_key], &kt, OPENVPN_OP_ENCRYPT,
- "Outgoing Control Channel Authentication");
- init_key_ctx (&ctx->decrypt, &key2.keys[kds.in_key], &kt, OPENVPN_OP_DECRYPT,
- "Incoming Control Channel Authentication");
+ /* initialize key in both directions */
+ openvpn_snprintf (log_prefix, sizeof (log_prefix), "Outgoing %s", key_name);
+ init_key_ctx (&ctx->encrypt, &key2.keys[kds.out_key], key_type,
+ OPENVPN_OP_ENCRYPT, log_prefix);
+ openvpn_snprintf (log_prefix, sizeof (log_prefix), "Incoming %s", key_name);
+ init_key_ctx (&ctx->decrypt, &key2.keys[kds.in_key], key_type,
+ OPENVPN_OP_DECRYPT, log_prefix);
- CLEAR (key2);
- }
- else
- {
- CLEAR (*ctx);
- }
+ CLEAR (key2);
}
-#endif
/* header and footer for static key file */
static const char static_key_head[] = "-----BEGIN OpenVPN Static key V1-----";
@@ -1002,9 +1307,6 @@ read_key_file (struct key2 *key2, const char *file, const unsigned int flags)
if (!(flags & RKF_INLINE))
buf_clear (&in);
- if (key2->n)
- warn_if_group_others_accessible (error_filename);
-
#if 0
/* DEBUGGING */
{
@@ -1028,55 +1330,6 @@ read_key_file (struct key2 *key2, const char *file, const unsigned int flags)
gc_free (&gc);
}
-int
-read_passphrase_hash (const char *passphrase_file,
- const md_kt_t *digest,
- uint8_t *output,
- int len)
-{
- unsigned int outlen = 0;
- md_ctx_t md;
-
- ASSERT (len >= md_kt_size(digest));
- memset (output, 0, len);
-
- md_ctx_init(&md, digest);
-
- /* read passphrase file */
- {
- const int min_passphrase_size = 8;
- uint8_t buf[64];
- int total_size = 0;
- int fd = platform_open (passphrase_file, O_RDONLY, 0);
-
- if (fd == -1)
- msg (M_ERR, "Cannot open passphrase file: '%s'", passphrase_file);
-
- for (;;)
- {
- int size = read (fd, buf, sizeof (buf));
- if (size == 0)
- break;
- if (size == -1)
- msg (M_ERR, "Read error on passphrase file: '%s'",
- passphrase_file);
- md_ctx_update(&md, buf, size);
- total_size += size;
- }
- close (fd);
-
- warn_if_group_others_accessible (passphrase_file);
-
- if (total_size < min_passphrase_size)
- msg (M_FATAL,
- "Passphrase file '%s' is too small (must have at least %d characters)",
- passphrase_file, min_passphrase_size);
- }
- md_ctx_final(&md, output);
- md_ctx_cleanup(&md);
- return md_kt_size(digest);
-}
-
/*
* Write key to file, return number of random bits
* written.
@@ -1367,7 +1620,6 @@ prng_bytes (uint8_t *output, int len)
const int md_size = md_kt_size (nonce_md);
while (len > 0)
{
- unsigned int outlen = 0;
const int blen = min_int (len, md_size);
md_full(nonce_md, nonce_data, md_size + nonce_secret_len, nonce_data);
memcpy (output, nonce_data, blen);
@@ -1397,79 +1649,42 @@ get_random()
return l;
}
-#ifndef ENABLE_SSL
+static const cipher_name_pair *
+get_cipher_name_pair(const char *cipher_name) {
+ const cipher_name_pair *pair;
+ size_t i = 0;
-void
-init_ssl_lib (void)
-{
- crypto_init_lib ();
-}
+ /* Search for a cipher name translation */
+ for (; i < cipher_name_translation_table_count; i++)
+ {
+ pair = &cipher_name_translation_table[i];
+ if (0 == strcmp (cipher_name, pair->openvpn_name) ||
+ 0 == strcmp (cipher_name, pair->lib_name))
+ return pair;
+ }
-void
-free_ssl_lib (void)
-{
- crypto_uninit_lib ();
- prng_uninit();
+ /* Nothing found, return null */
+ return NULL;
}
-#endif /* ENABLE_SSL */
-
-/*
- * md5 functions
- */
-
const char *
-md5sum (uint8_t *buf, int len, int n_print_chars, struct gc_arena *gc)
-{
- uint8_t digest[MD5_DIGEST_LENGTH];
- const md_kt_t *md5_kt = md_kt_get("MD5");
-
- md_full(md5_kt, buf, len, digest);
-
- return format_hex (digest, MD5_DIGEST_LENGTH, n_print_chars, gc);
-}
-
-void
-md5_state_init (struct md5_state *s)
-{
- const md_kt_t *md5_kt = md_kt_get("MD5");
-
- md_ctx_init(&s->ctx, md5_kt);
-}
+translate_cipher_name_from_openvpn (const char *cipher_name) {
+ const cipher_name_pair *pair = get_cipher_name_pair(cipher_name);
-void
-md5_state_update (struct md5_state *s, void *data, size_t len)
-{
- md_ctx_update(&s->ctx, data, len);
-}
+ if (NULL == pair)
+ return cipher_name;
-void
-md5_state_final (struct md5_state *s, struct md5_digest *out)
-{
- md_ctx_final(&s->ctx, out->digest);
- md_ctx_cleanup(&s->ctx);
+ return pair->lib_name;
}
-void
-md5_digest_clear (struct md5_digest *digest)
-{
- CLEAR (*digest);
-}
+const char *
+translate_cipher_name_to_openvpn (const char *cipher_name) {
+ const cipher_name_pair *pair = get_cipher_name_pair(cipher_name);
-bool
-md5_digest_defined (const struct md5_digest *digest)
-{
- int i;
- for (i = 0; i < MD5_DIGEST_LENGTH; ++i)
- if (digest->digest[i])
- return true;
- return false;
-}
+ if (NULL == pair)
+ return cipher_name;
-bool
-md5_digest_equal (const struct md5_digest *d1, const struct md5_digest *d2)
-{
- return memcmp(d1->digest, d2->digest, MD5_DIGEST_LENGTH) == 0;
+ return pair->openvpn_name;
}
#endif /* ENABLE_CRYPTO */
diff --git a/src/openvpn/crypto.h b/src/openvpn/crypto.h
index e489827..ff90745 100644
--- a/src/openvpn/crypto.h
+++ b/src/openvpn/crypto.h
@@ -86,6 +86,30 @@
* <tt> [ HMAC ] [ - IV - ] [ * packet payload * ] </tt>
*
* @par
+ * <b>GCM data channel crypto format</b> \n
+ * GCM modes are only supported in TLS mode. In these modes, the IV consists of
+ * the 32-bit packet counter followed by data from the HMAC key. The HMAC key
+ * can be used as IV, since in GCM and CCM modes the HMAC key is not used for
+ * the HMAC. The packet counter may not roll over within a single TLS sessions.
+ * This results in a unique IV for each packet, as required by GCM.
+ *
+ * @par
+ * The HMAC key data is pre-shared during the connection setup, and thus can be
+ * omitted in on-the-wire packets, saving 8 bytes per packet (for GCM and CCM).
+ *
+ * @par
+ * In GCM mode, P_DATA_V2 headers (the opcode and peer-id) are also
+ * authenticated as Additional Data.
+ *
+ * @par
+ * <i>GCM IV format:</i> \n
+ * <tt> [ - packet ID - ] [ - HMAC key data - ] </tt>\n
+ * <i>P_DATA_V1 GCM data channel crypto format:</i> \n
+ * <tt> [ opcode ] [ - packet ID - ] [ TAG ] [ * packet payload * ] </tt>
+ * <i>P_DATA_V2 GCM data channel crypto format:</i> \n
+ * <tt> [ - opcode/peer-id - ] [ - packet ID - ] [ TAG ] [ * packet payload * ] </tt>
+ *
+ * @par
* <b>No-crypto data channel format</b> \n
* In no-crypto mode (\c \-\-cipher \c none is specified), both TLS-mode and
* static key mode are supported. No encryption will be performed on the packet,
@@ -108,6 +132,11 @@
#include "packet_id.h"
#include "mtu.h"
+/** Wrapper struct to pass around MD5 digests */
+struct md5_digest {
+ uint8_t digest[MD5_DIGEST_LENGTH];
+};
+
/*
* Defines a key type and key length for both cipher and HMAC.
*/
@@ -133,13 +162,16 @@ struct key
/**
- * Container for one set of OpenSSL cipher and/or HMAC contexts.
+ * Container for one set of cipher and/or HMAC contexts.
* @ingroup control_processor
*/
struct key_ctx
{
cipher_ctx_t *cipher; /**< Generic cipher %context. */
- hmac_ctx_t *hmac; /**< Generic HMAC %context. */
+ hmac_ctx_t *hmac; /**< Generic HMAC %context. */
+ uint8_t implicit_iv[OPENVPN_MAX_IV_LENGTH];
+ /**< The implicit part of the IV */
+ size_t implicit_iv_len; /**< The length of implicit_iv */
};
#define KEY_DIRECTION_BIDIRECTIONAL 0 /* same keys for both directions */
@@ -190,10 +222,11 @@ struct key_direction_state
*/
struct key_ctx_bi
{
- struct key_ctx encrypt; /**< OpenSSL cipher and/or HMAC contexts
- * for sending direction. */
- struct key_ctx decrypt; /**< OpenSSL cipher and/or HMAC contexts
- * for receiving direction. */
+ struct key_ctx encrypt; /**< Cipher and/or HMAC contexts for sending
+ * direction. */
+ struct key_ctx decrypt; /**< cipher and/or HMAC contexts for
+ * receiving direction. */
+ bool initialized;
};
/**
@@ -202,11 +235,11 @@ struct key_ctx_bi
*/
struct crypto_options
{
- struct key_ctx_bi *key_ctx_bi;
+ struct key_ctx_bi key_ctx_bi;
/**< OpenSSL cipher and HMAC contexts for
* both sending and receiving
* directions. */
- struct packet_id *packet_id; /**< Current packet ID state for both
+ struct packet_id packet_id; /**< Current packet ID state for both
* sending and receiving directions. */
struct packet_id_persist *pid_persist;
/**< Persistent packet ID state for
@@ -233,6 +266,15 @@ struct crypto_options
* security operation functions. */
};
+#define CRYPT_ERROR(format) \
+ do { msg (D_CRYPT_ERRORS, "%s: " format, error_prefix); goto error_exit; } while (false)
+
+/**
+ * Minimal IV length for AEAD mode ciphers (in bytes):
+ * 4-byte packet id + 8 bytes implicit IV.
+ */
+#define OPENVPN_AEAD_MIN_IV_LEN (sizeof (packet_id_type) + 8)
+
#define RKF_MUST_SUCCEED (1<<0)
#define RKF_INLINE (1<<1)
void read_key_file (struct key2 *key2, const char *file, const unsigned int flags);
@@ -257,9 +299,20 @@ bool write_key (const struct key *key, const struct key_type *kt,
int read_key (struct key *key, const struct key_type *kt, struct buffer *buf);
+/**
+ * Initialize a key_type structure with.
+ *
+ * @param kt The struct key_type to initialize
+ * @param ciphername The name of the cipher to use
+ * @param authname The name of the HMAC digest to use
+ * @param keysize The length of the cipher key to use, in bytes. Only valid
+ * for ciphers that support variable length keys.
+ * @param tls_mode Specifies wether we are running in TLS mode, which allows
+ * more ciphers than static key mode.
+ * @param warn Print warnings when null cipher / auth is used.
+ */
void init_key_type (struct key_type *kt, const char *ciphername,
- bool ciphername_defined, const char *authname, bool authname_defined,
- int keysize, bool cfb_ofb_allowed, bool warn);
+ const char *authname, int keysize, bool tls_mode, bool warn);
/*
* Key context functions
@@ -296,18 +349,16 @@ void free_key_ctx_bi (struct key_ctx_bi *ctx);
*
* @param buf - The %buffer containing the packet on which to
* perform security operations.
- * @param work - A working %buffer.
+ * @param work - An initialized working %buffer.
* @param opt - The security parameter state for this VPN tunnel.
- * @param frame - The packet geometry parameters for this VPN
- * tunnel.
+ *
* @return This function returns void.\n On return, the \a buf argument
* will point to the resulting %buffer. This %buffer will either
* contain the processed packet ready for sending, or be empty if an
* error occurred.
*/
void openvpn_encrypt (struct buffer *buf, struct buffer work,
- const struct crypto_options *opt,
- const struct frame* frame);
+ struct crypto_options *opt);
/**
@@ -333,6 +384,8 @@ void openvpn_encrypt (struct buffer *buf, struct buffer work,
* @param opt - The security parameter state for this VPN tunnel.
* @param frame - The packet geometry parameters for this VPN
* tunnel.
+ * @param ad_start - A pointer into buf, indicating from where to start
+ * authenticating additional data (AEAD mode only).
*
* @return
* @li True, if the packet was authenticated and decrypted successfully.
@@ -342,18 +395,35 @@ void openvpn_encrypt (struct buffer *buf, struct buffer work,
* an error occurred.
*/
bool openvpn_decrypt (struct buffer *buf, struct buffer work,
- const struct crypto_options *opt,
- const struct frame* frame);
+ struct crypto_options *opt, const struct frame* frame,
+ const uint8_t *ad_start);
/** @} name Functions for performing security operations on data channel packets */
+/**
+ * Check packet ID for replay, and perform replay administration.
+ *
+ * @param opt Crypto options for this packet, contains replay state.
+ * @param pin Packet ID read from packet.
+ * @param error_prefix Prefix to use when printing error messages.
+ * @param gc Garbage collector to use.
+ *
+ * @return true if packet ID is validated to be not a replay, false otherwise.
+ */
+bool crypto_check_replay(struct crypto_options *opt,
+ const struct packet_id_net *pin, const char *error_prefix,
+ struct gc_arena *gc);
+
+
+/** Calculate crypto overhead and adjust frame to account for that */
void crypto_adjust_frame_parameters(struct frame *frame,
const struct key_type* kt,
- bool cipher_defined,
bool use_iv,
bool packet_id,
bool packet_id_long_form);
+/** Return the worst-case OpenVPN crypto overhead (in bytes) */
+size_t crypto_max_overhead(void);
/* Minimum length of the nonce used by the PRNG */
#define NONCE_SECRET_LEN_MIN 16
@@ -392,7 +462,7 @@ void prng_bytes (uint8_t *output, int len);
void prng_uninit ();
-void test_crypto (const struct crypto_options *co, struct frame* f);
+void test_crypto (struct crypto_options *co, struct frame* f);
/* key direction functions */
@@ -413,45 +483,31 @@ void key2_print (const struct key2* k,
const char* prefix0,
const char* prefix1);
-#ifdef ENABLE_SSL
-
-#define GHK_INLINE (1<<0)
-void get_tls_handshake_key (const struct key_type *key_type,
- struct key_ctx_bi *ctx,
- const char *passphrase_file,
- const int key_direction,
- const unsigned int flags);
-
-#else
-
-void init_ssl_lib (void);
-void free_ssl_lib (void);
-
-#endif /* ENABLE_SSL */
+void crypto_read_openvpn_key (const struct key_type *key_type,
+ struct key_ctx_bi *ctx, const char *key_file, const char *key_inline,
+ const int key_direction, const char *key_name, const char *opt_name);
/*
- * md5 functions
+ * Inline functions
*/
-struct md5_state {
- md_ctx_t ctx;
-};
-
-struct md5_digest {
- uint8_t digest [MD5_DIGEST_LENGTH];
-};
-
-const char *md5sum(uint8_t *buf, int len, int n_print_chars, struct gc_arena *gc);
-void md5_state_init (struct md5_state *s);
-void md5_state_update (struct md5_state *s, void *data, size_t len);
-void md5_state_final (struct md5_state *s, struct md5_digest *out);
-void md5_digest_clear (struct md5_digest *digest);
-bool md5_digest_defined (const struct md5_digest *digest);
-bool md5_digest_equal (const struct md5_digest *d1, const struct md5_digest *d2);
-
-/*
- * Inline functions
+/**
+ * As memcmp(), but constant-time.
+ * Returns 0 when data is equal, non-zero otherwise.
*/
+static inline int
+memcmp_constant_time (const void *a, const void *b, size_t size) {
+ const uint8_t * a1 = a;
+ const uint8_t * b1 = b;
+ int ret = 0;
+ size_t i;
+
+ for (i = 0; i < size; i++) {
+ ret |= *a1++ ^ *b1++;
+ }
+
+ return ret;
+}
static inline bool
key_ctx_bi_defined(const struct key_ctx_bi* key)
diff --git a/src/openvpn/crypto_backend.h b/src/openvpn/crypto_backend.h
index 4c1ce9f..bf7d78c 100644
--- a/src/openvpn/crypto_backend.h
+++ b/src/openvpn/crypto_backend.h
@@ -33,11 +33,29 @@
#ifdef ENABLE_CRYPTO_OPENSSL
#include "crypto_openssl.h"
#endif
-#ifdef ENABLE_CRYPTO_POLARSSL
-#include "crypto_polarssl.h"
+#ifdef ENABLE_CRYPTO_MBEDTLS
+#include "crypto_mbedtls.h"
#endif
#include "basic.h"
+/* TLS uses a tag of 128 bytes, let's do the same for OpenVPN */
+#define OPENVPN_AEAD_TAG_LENGTH 16
+
+/* Maximum cipher block size (bytes) */
+#define OPENVPN_MAX_CIPHER_BLOCK_SIZE 32
+
+/* Maximum HMAC digest size (bytes) */
+#define OPENVPN_MAX_HMAC_SIZE 64
+
+/** Struct used in cipher name translation table */
+typedef struct {
+ const char *openvpn_name; /**< Cipher name used by OpenVPN */
+ const char *lib_name; /**< Cipher name used by crypto library */
+} cipher_name_pair;
+
+/** Cipher name translation table */
+extern const cipher_name_pair cipher_name_translation_table[];
+extern const size_t cipher_name_translation_table_count;
/*
* This routine should have additional OpenSSL crypto library initialisations
@@ -177,7 +195,8 @@ void cipher_des_encrypt_ecb (const unsigned char key[DES_KEY_LENGTH],
* \c AES-128-CBC).
*
* @return A statically allocated structure containing parameters
- * for the given cipher.
+ * for the given cipher, or NULL if no matching parameters
+ * were found.
*/
const cipher_kt_t * cipher_kt_get (const char *ciphername);
@@ -221,6 +240,16 @@ int cipher_kt_iv_size (const cipher_kt_t *cipher_kt);
int cipher_kt_block_size (const cipher_kt_t *cipher_kt);
/**
+ * Returns the MAC tag size of the cipher, in bytes.
+ *
+ * @param ctx Static cipher parameters.
+ *
+ * @return Tag size in bytes, or 0 if the tag size could not be
+ * determined.
+ */
+int cipher_kt_tag_size (const cipher_kt_t *cipher_kt);
+
+/**
* Returns the mode that the cipher runs in.
*
* @param cipher_kt Static cipher parameters. May not be NULL.
@@ -248,6 +277,15 @@ bool cipher_kt_mode_cbc(const cipher_kt_t *cipher);
*/
bool cipher_kt_mode_ofb_cfb(const cipher_kt_t *cipher);
+/**
+ * Check if the supplied cipher is a supported AEAD mode cipher.
+ *
+ * @param cipher Static cipher parameters.
+ *
+ * @return true iff the cipher is a AEAD mode cipher.
+ */
+bool cipher_kt_mode_aead(const cipher_kt_t *cipher);
+
/**
*
@@ -263,7 +301,7 @@ bool cipher_kt_mode_ofb_cfb(const cipher_kt_t *cipher);
* @param key_len Length of the key, in bytes
* @param kt Static cipher parameters to use
* @param enc Whether to encrypt or decrypt (either
- * \c POLARSSL_OP_ENCRYPT or \c POLARSSL_OP_DECRYPT).
+ * \c MBEDTLS_OP_ENCRYPT or \c MBEDTLS_OP_DECRYPT).
*/
void cipher_ctx_init (cipher_ctx_t *ctx, uint8_t *key, int key_len,
const cipher_kt_t *kt, int enc);
@@ -287,6 +325,15 @@ void cipher_ctx_cleanup (cipher_ctx_t *ctx);
int cipher_ctx_iv_length (const cipher_ctx_t *ctx);
/**
+ * Gets the computed message authenticated code (MAC) tag for this cipher.
+ *
+ * @param ctx The cipher's context
+ * @param tag The buffer to write computed tag in.
+ * @param tag_size The tag buffer size, in bytes.
+ */
+int cipher_ctx_get_tag (cipher_ctx_t *ctx, uint8_t* tag, int tag_len);
+
+/**
* Returns the block size of the cipher, in bytes.
*
* @param ctx The cipher's context
@@ -308,12 +355,12 @@ int cipher_ctx_mode (const cipher_ctx_t *ctx);
/**
* Returns the static cipher parameters for this context.
*
- * @param ctx Cipher's context. May not be NULL.
+ * @param ctx Cipher's context.
*
- * @return Static cipher parameters for the supplied context.
+ * @return Static cipher parameters for the supplied context, or
+ * NULL if unable to determine cipher parameters.
*/
-const cipher_kt_t *cipher_ctx_get_cipher_kt (const cipher_ctx_t *ctx)
- __attribute__((nonnull));
+const cipher_kt_t *cipher_ctx_get_cipher_kt (const cipher_ctx_t *ctx);
/**
* Resets the given cipher context, setting the IV to the specified value.
@@ -327,6 +374,18 @@ const cipher_kt_t *cipher_ctx_get_cipher_kt (const cipher_ctx_t *ctx)
int cipher_ctx_reset (cipher_ctx_t *ctx, uint8_t *iv_buf);
/**
+ * Updates the given cipher context, providing additional data (AD) for
+ * authenticated encryption with additional data (AEAD) cipher modes.
+ *
+ * @param ctx Cipher's context. May not be NULL.
+ * @param src Source buffer
+ * @param src_len Length of the source buffer, in bytes
+ *
+ * @return \c 0 on failure, \c 1 on success.
+ */
+int cipher_ctx_update_ad (cipher_ctx_t *ctx, const uint8_t *src, int src_len);
+
+/**
* Updates the given cipher context, encrypting data in the source buffer, and
* placing any complete blocks in the destination buffer.
*
@@ -358,6 +417,23 @@ int cipher_ctx_update (cipher_ctx_t *ctx, uint8_t *dst, int *dst_len,
*/
int cipher_ctx_final (cipher_ctx_t *ctx, uint8_t *dst, int *dst_len);
+/**
+ * Like \c cipher_ctx_final, but check the computed authentication tag against
+ * the supplied (expected) tag. This function reports failure when the tags
+ * don't match.
+ *
+ * @param ctx Cipher's context. May not be NULL.
+ * @param dst Destination buffer.
+ * @param dst_len Length of the destination buffer, in bytes.
+ * @param tag The expected authentication tag.
+ * @param tag_len The length of tag, in bytes.
+ *
+ * @return \c 0 on failure, \c 1 on success.
+ */
+int cipher_ctx_final_check_tag (cipher_ctx_t *ctx, uint8_t *dst, int *dst_len,
+ uint8_t *tag, size_t tag_len);
+
+
/*
*
* Generic message digest information functions
@@ -525,4 +601,24 @@ void hmac_ctx_update (hmac_ctx_t *ctx, const uint8_t *src, int src_len);
*/
void hmac_ctx_final (hmac_ctx_t *ctx, uint8_t *dst);
+/**
+ * Translate an OpenVPN cipher name to a crypto library cipher name.
+ *
+ * @param cipher_name An OpenVPN cipher name
+ *
+ * @return The corresponding crypto library cipher name, or NULL
+ * if no matching cipher name was found.
+ */
+const char * translate_cipher_name_from_openvpn (const char *cipher_name);
+
+/**
+ * Translate a crypto library cipher name to an OpenVPN cipher name.
+ *
+ * @param cipher_name A crypto library cipher name
+ *
+ * @return The corresponding OpenVPN cipher name, or NULL if no
+ * matching cipher name was found.
+ */
+const char * translate_cipher_name_to_openvpn (const char *cipher_name);
+
#endif /* CRYPTO_BACKEND_H_ */
diff --git a/src/openvpn/crypto_mbedtls.c b/src/openvpn/crypto_mbedtls.c
new file mode 100644
index 0000000..6ad5924
--- /dev/null
+++ b/src/openvpn/crypto_mbedtls.c
@@ -0,0 +1,785 @@
+/*
+ * OpenVPN -- An application to securely tunnel IP networks
+ * over a single TCP/UDP port, with support for SSL/TLS-based
+ * session authentication and key exchange,
+ * packet encryption, packet authentication, and
+ * packet compression.
+ *
+ * Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net>
+ * Copyright (C) 2010 Fox Crypto B.V. <openvpn@fox-it.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program (see the file COPYING included with this
+ * distribution); if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/**
+ * @file Data Channel Cryptography mbed TLS-specific backend interface
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#elif defined(_MSC_VER)
+#include "config-msvc.h"
+#endif
+
+#include "syshead.h"
+
+#if defined(ENABLE_CRYPTO) && defined(ENABLE_CRYPTO_MBEDTLS)
+
+#include "errlevel.h"
+#include "basic.h"
+#include "buffer.h"
+#include "integer.h"
+#include "crypto_backend.h"
+#include "otime.h"
+#include "misc.h"
+
+#include <mbedtls/des.h>
+#include <mbedtls/error.h>
+#include <mbedtls/md5.h>
+#include <mbedtls/cipher.h>
+#include <mbedtls/havege.h>
+
+#include <mbedtls/entropy.h>
+
+
+/*
+ *
+ * Hardware engine support. Allows loading/unloading of engines.
+ *
+ */
+
+void
+crypto_init_lib_engine (const char *engine_name)
+{
+ msg (M_WARN, "Note: mbed TLS hardware crypto engine functionality is not "
+ "available");
+}
+
+/*
+ *
+ * Functions related to the core crypto library
+ *
+ */
+
+void
+crypto_init_lib (void)
+{
+}
+
+void
+crypto_uninit_lib (void)
+{
+}
+
+void
+crypto_clear_error (void)
+{
+}
+
+bool mbed_log_err(unsigned int flags, int errval, const char *prefix)
+{
+ if (0 != errval)
+ {
+ char errstr[256];
+ mbedtls_strerror(errval, errstr, sizeof(errstr));
+
+ if (NULL == prefix) prefix = "mbed TLS error";
+ msg (flags, "%s: %s", prefix, errstr);
+ }
+
+ return 0 == errval;
+}
+
+bool mbed_log_func_line(unsigned int flags, int errval, const char *func,
+ int line)
+{
+ char prefix[256];
+
+ if (!openvpn_snprintf(prefix, sizeof(prefix), "%s:%d", func, line))
+ return mbed_log_err(flags, errval, func);
+
+ return mbed_log_err(flags, errval, prefix);
+}
+
+
+#ifdef DMALLOC
+void
+crypto_init_dmalloc (void)
+{
+ msg (M_ERR, "Error: dmalloc support is not available for mbed TLS.");
+}
+#endif /* DMALLOC */
+
+const cipher_name_pair cipher_name_translation_table[] = {
+ { "BF-CBC", "BLOWFISH-CBC" },
+ { "BF-CFB", "BLOWFISH-CFB64" },
+ { "CAMELLIA-128-CFB", "CAMELLIA-128-CFB128" },
+ { "CAMELLIA-192-CFB", "CAMELLIA-192-CFB128" },
+ { "CAMELLIA-256-CFB", "CAMELLIA-256-CFB128" }
+};
+const size_t cipher_name_translation_table_count =
+ sizeof (cipher_name_translation_table) / sizeof (*cipher_name_translation_table);
+
+static void print_cipher(const cipher_kt_t *info)
+{
+ if (info && (cipher_kt_mode_cbc(info)
+#ifdef HAVE_AEAD_CIPHER_MODES
+ || cipher_kt_mode_aead(info)
+#endif
+ ))
+ {
+ const char *ssl_only = cipher_kt_mode_cbc(info) ?
+ "" : ", TLS client/server mode only";
+ const char *var_key_size = info->flags & MBEDTLS_CIPHER_VARIABLE_KEY_LEN ?
+ " by default" : "";
+
+ printf ("%s (%d bit key%s, %d bit block%s)\n",
+ cipher_kt_name(info), cipher_kt_key_size(info) * 8, var_key_size,
+ cipher_kt_block_size(info) * 8, ssl_only);
+ }
+}
+
+void
+show_available_ciphers ()
+{
+ const int *ciphers = mbedtls_cipher_list();
+
+#ifndef ENABLE_SMALL
+ printf ("The following ciphers and cipher modes are available for use\n"
+ "with " PACKAGE_NAME ". Each cipher shown below may be used as a\n"
+ "parameter to the --cipher option. Using a CBC or GCM mode is\n"
+ "recommended. In static key mode only CBC mode is allowed.\n\n");
+#endif
+
+ while (*ciphers != 0)
+ {
+ const cipher_kt_t *info = mbedtls_cipher_info_from_type(*ciphers);
+ if (info && cipher_kt_block_size(info) >= 128/8)
+ {
+ print_cipher(info);
+ }
+ ciphers++;
+ }
+
+ printf ("\nThe following ciphers have a block size of less than 128 bits, \n"
+ "and are therefore deprecated. Do not use unless you have to.\n\n");
+ ciphers = mbedtls_cipher_list();
+ while (*ciphers != 0)
+ {
+ const cipher_kt_t *info = mbedtls_cipher_info_from_type(*ciphers);
+ if (info && cipher_kt_block_size(info) < 128/8)
+ {
+ print_cipher(info);
+ }
+ ciphers++;
+ }
+ printf ("\n");
+}
+
+void
+show_available_digests ()
+{
+ const int *digests = mbedtls_md_list();
+
+#ifndef ENABLE_SMALL
+ printf ("The following message digests are available for use with\n"
+ PACKAGE_NAME ". A message digest is used in conjunction with\n"
+ "the HMAC function, to authenticate received packets.\n"
+ "You can specify a message digest as parameter to\n"
+ "the --auth option.\n\n");
+#endif
+
+ while (*digests != 0)
+ {
+ const mbedtls_md_info_t *info = mbedtls_md_info_from_type(*digests);
+
+ if (info)
+ printf ("%s %d bit default key\n", mbedtls_md_get_name(info),
+ mbedtls_md_get_size(info) * 8);
+ digests++;
+ }
+ printf ("\n");
+}
+
+void
+show_available_engines ()
+{
+ printf ("Sorry, mbed TLS hardware crypto engine functionality is not "
+ "available\n");
+}
+
+/*
+ *
+ * Random number functions, used in cases where we want
+ * reasonably strong cryptographic random number generation
+ * without depleting our entropy pool. Used for random
+ * IV values and a number of other miscellaneous tasks.
+ *
+ */
+
+/*
+ * Initialise the given ctr_drbg context, using a personalisation string and an
+ * entropy gathering function.
+ */
+mbedtls_ctr_drbg_context * rand_ctx_get()
+{
+ static mbedtls_entropy_context ec = {0};
+ static mbedtls_ctr_drbg_context cd_ctx = {0};
+ static bool rand_initialised = false;
+
+ if (!rand_initialised)
+ {
+ struct gc_arena gc = gc_new();
+ struct buffer pers_string = alloc_buf_gc(100, &gc);
+
+ /*
+ * Personalisation string, should be as unique as possible (see NIST
+ * 800-90 section 8.7.1). We have very little information at this stage.
+ * Include Program Name, memory address of the context and PID.
+ */
+ buf_printf(&pers_string, "OpenVPN %0u %p %s", platform_getpid(), &cd_ctx, time_string(0, 0, 0, &gc));
+
+ /* Initialise mbed TLS RNG, and built-in entropy sources */
+ mbedtls_entropy_init(&ec);
+
+ mbedtls_ctr_drbg_init(&cd_ctx);
+ if (!mbed_ok(mbedtls_ctr_drbg_seed(&cd_ctx, mbedtls_entropy_func, &ec,
+ BPTR(&pers_string), BLEN(&pers_string))))
+ msg (M_FATAL, "Failed to initialize random generator");
+
+ gc_free(&gc);
+ rand_initialised = true;
+ }
+
+ return &cd_ctx;
+}
+
+#ifdef ENABLE_PREDICTION_RESISTANCE
+void rand_ctx_enable_prediction_resistance()
+{
+ mbedtls_ctr_drbg_context *cd_ctx = rand_ctx_get();
+
+ mbedtls_ctr_drbg_set_prediction_resistance(cd_ctx, 1);
+}
+#endif /* ENABLE_PREDICTION_RESISTANCE */
+
+int
+rand_bytes (uint8_t *output, int len)
+{
+ mbedtls_ctr_drbg_context *rng_ctx = rand_ctx_get();
+
+ while (len > 0)
+ {
+ const size_t blen = min_int (len, MBEDTLS_CTR_DRBG_MAX_REQUEST);
+ if (0 != mbedtls_ctr_drbg_random(rng_ctx, output, blen))
+ return 0;
+
+ output += blen;
+ len -= blen;
+ }
+
+ return 1;
+}
+
+/*
+ *
+ * Key functions, allow manipulation of keys.
+ *
+ */
+
+
+int
+key_des_num_cblocks (const mbedtls_cipher_info_t *kt)
+{
+ int ret = 0;
+ if (kt->type == MBEDTLS_CIPHER_DES_CBC)
+ ret = 1;
+ if (kt->type == MBEDTLS_CIPHER_DES_EDE_CBC)
+ ret = 2;
+ if (kt->type == MBEDTLS_CIPHER_DES_EDE3_CBC)
+ ret = 3;
+
+ dmsg (D_CRYPTO_DEBUG, "CRYPTO INFO: n_DES_cblocks=%d", ret);
+ return ret;
+}
+
+bool
+key_des_check (uint8_t *key, int key_len, int ndc)
+{
+ int i;
+ struct buffer b;
+
+ buf_set_read (&b, key, key_len);
+
+ for (i = 0; i < ndc; ++i)
+ {
+ unsigned char *key = buf_read_alloc(&b, MBEDTLS_DES_KEY_SIZE);
+ if (!key)
+ {
+ msg (D_CRYPT_ERRORS, "CRYPTO INFO: check_key_DES: insufficient key material");
+ goto err;
+ }
+ if (0 != mbedtls_des_key_check_weak(key))
+ {
+ msg (D_CRYPT_ERRORS, "CRYPTO INFO: check_key_DES: weak key detected");
+ goto err;
+ }
+ if (0 != mbedtls_des_key_check_key_parity(key))
+ {
+ msg (D_CRYPT_ERRORS, "CRYPTO INFO: check_key_DES: bad parity detected");
+ goto err;
+ }
+ }
+ return true;
+
+ err:
+ return false;
+}
+
+void
+key_des_fixup (uint8_t *key, int key_len, int ndc)
+{
+ int i;
+ struct buffer b;
+
+ buf_set_read (&b, key, key_len);
+ for (i = 0; i < ndc; ++i)
+ {
+ unsigned char *key = buf_read_alloc(&b, MBEDTLS_DES_KEY_SIZE);
+ if (!key)
+ {
+ msg (D_CRYPT_ERRORS, "CRYPTO INFO: fixup_key_DES: insufficient key material");
+ return;
+ }
+ mbedtls_des_key_set_parity(key);
+ }
+}
+
+/*
+ *
+ * Generic cipher key type functions
+ *
+ */
+
+
+const mbedtls_cipher_info_t *
+cipher_kt_get (const char *ciphername)
+{
+ const mbedtls_cipher_info_t *cipher = NULL;
+
+ ASSERT (ciphername);
+
+ cipher = mbedtls_cipher_info_from_string(ciphername);
+
+ if (NULL == cipher)
+ {
+ msg (D_LOW, "Cipher algorithm '%s' not found", ciphername);
+ return NULL;
+ }
+
+ if (cipher->key_bitlen/8 > MAX_CIPHER_KEY_LENGTH)
+ {
+ msg (D_LOW, "Cipher algorithm '%s' uses a default key size (%d bytes) "
+ "which is larger than " PACKAGE_NAME "'s current maximum key size "
+ "(%d bytes)", ciphername, cipher->key_bitlen/8, MAX_CIPHER_KEY_LENGTH);
+ return NULL;
+ }
+
+ return cipher;
+}
+
+const char *
+cipher_kt_name (const mbedtls_cipher_info_t *cipher_kt)
+{
+ if (NULL == cipher_kt)
+ return "[null-cipher]";
+
+ return translate_cipher_name_to_openvpn(cipher_kt->name);
+}
+
+int
+cipher_kt_key_size (const mbedtls_cipher_info_t *cipher_kt)
+{
+ if (NULL == cipher_kt)
+ return 0;
+
+ return cipher_kt->key_bitlen/8;
+}
+
+int
+cipher_kt_iv_size (const mbedtls_cipher_info_t *cipher_kt)
+{
+ if (NULL == cipher_kt)
+ return 0;
+ return cipher_kt->iv_size;
+}
+
+int
+cipher_kt_block_size (const mbedtls_cipher_info_t *cipher_kt)
+{
+ if (NULL == cipher_kt)
+ return 0;
+ return cipher_kt->block_size;
+}
+
+int
+cipher_kt_tag_size (const mbedtls_cipher_info_t *cipher_kt)
+{
+#ifdef HAVE_AEAD_CIPHER_MODES
+ if (cipher_kt && cipher_kt_mode_aead(cipher_kt))
+ return OPENVPN_AEAD_TAG_LENGTH;
+#endif
+ return 0;
+}
+
+int
+cipher_kt_mode (const mbedtls_cipher_info_t *cipher_kt)
+{
+ ASSERT(NULL != cipher_kt);
+ return cipher_kt->mode;
+}
+
+bool
+cipher_kt_mode_cbc(const cipher_kt_t *cipher)
+{
+ return cipher && cipher_kt_mode(cipher) == OPENVPN_MODE_CBC;
+}
+
+bool
+cipher_kt_mode_ofb_cfb(const cipher_kt_t *cipher)
+{
+ return cipher && (cipher_kt_mode(cipher) == OPENVPN_MODE_OFB ||
+ cipher_kt_mode(cipher) == OPENVPN_MODE_CFB);
+}
+
+bool
+cipher_kt_mode_aead(const cipher_kt_t *cipher)
+{
+ return cipher && cipher_kt_mode(cipher) == OPENVPN_MODE_GCM;
+}
+
+
+/*
+ *
+ * Generic cipher context functions
+ *
+ */
+
+
+void
+cipher_ctx_init (mbedtls_cipher_context_t *ctx, uint8_t *key, int key_len,
+ const mbedtls_cipher_info_t *kt, const mbedtls_operation_t operation)
+{
+ ASSERT(NULL != kt && NULL != ctx);
+
+ CLEAR (*ctx);
+
+ if (!mbed_ok(mbedtls_cipher_setup(ctx, kt)))
+ msg (M_FATAL, "mbed TLS cipher context init #1");
+
+ if (!mbed_ok(mbedtls_cipher_setkey(ctx, key, key_len*8, operation)))
+ msg (M_FATAL, "mbed TLS cipher set key");
+
+ /* make sure we used a big enough key */
+ ASSERT (ctx->key_bitlen <= key_len*8);
+}
+
+void cipher_ctx_cleanup (mbedtls_cipher_context_t *ctx)
+{
+ mbedtls_cipher_free(ctx);
+}
+
+int cipher_ctx_iv_length (const mbedtls_cipher_context_t *ctx)
+{
+ return mbedtls_cipher_get_iv_size(ctx);
+}
+
+int cipher_ctx_get_tag (cipher_ctx_t *ctx, uint8_t* tag, int tag_len)
+{
+#ifdef HAVE_AEAD_CIPHER_MODES
+ if (tag_len > SIZE_MAX)
+ return 0;
+
+ if (!mbed_ok (mbedtls_cipher_write_tag (ctx, (unsigned char *) tag, tag_len)))
+ return 0;
+
+ return 1;
+#else
+ ASSERT(0);
+#endif /* HAVE_AEAD_CIPHER_MODES */
+}
+
+int cipher_ctx_block_size(const mbedtls_cipher_context_t *ctx)
+{
+ return mbedtls_cipher_get_block_size(ctx);
+}
+
+int cipher_ctx_mode (const mbedtls_cipher_context_t *ctx)
+{
+ ASSERT(NULL != ctx);
+
+ return cipher_kt_mode(ctx->cipher_info);
+}
+
+const cipher_kt_t *
+cipher_ctx_get_cipher_kt (const cipher_ctx_t *ctx)
+{
+ return ctx ? ctx->cipher_info : NULL;
+}
+
+int cipher_ctx_reset (mbedtls_cipher_context_t *ctx, uint8_t *iv_buf)
+{
+ if (!mbed_ok(mbedtls_cipher_reset(ctx)))
+ return 0;
+
+ if (!mbed_ok(mbedtls_cipher_set_iv(ctx, iv_buf, ctx->cipher_info->iv_size)))
+ return 0;
+
+ return 1;
+}
+
+int cipher_ctx_update_ad (cipher_ctx_t *ctx, const uint8_t *src, int src_len)
+{
+#ifdef HAVE_AEAD_CIPHER_MODES
+ if (src_len > SIZE_MAX)
+ return 0;
+
+ if (!mbed_ok (mbedtls_cipher_update_ad (ctx, src, src_len)))
+ return 0;
+
+ return 1;
+#else
+ ASSERT(0);
+#endif /* HAVE_AEAD_CIPHER_MODES */
+}
+
+int cipher_ctx_update (mbedtls_cipher_context_t *ctx, uint8_t *dst,
+ int *dst_len, uint8_t *src, int src_len)
+{
+ size_t s_dst_len = *dst_len;
+
+ if (!mbed_ok(mbedtls_cipher_update(ctx, src, (size_t) src_len, dst,
+ &s_dst_len)))
+ return 0;
+
+ *dst_len = s_dst_len;
+
+ return 1;
+}
+
+int cipher_ctx_final (mbedtls_cipher_context_t *ctx, uint8_t *dst, int *dst_len)
+{
+ size_t s_dst_len = *dst_len;
+
+ if (!mbed_ok(mbedtls_cipher_finish(ctx, dst, &s_dst_len)))
+ return 0;
+
+ *dst_len = s_dst_len;
+
+ return 1;
+}
+
+int cipher_ctx_final_check_tag (mbedtls_cipher_context_t *ctx, uint8_t *dst,
+ int *dst_len, uint8_t *tag, size_t tag_len)
+{
+#ifdef HAVE_AEAD_CIPHER_MODES
+ size_t olen = 0;
+
+ if (MBEDTLS_DECRYPT != ctx->operation)
+ return 0;
+
+ if (tag_len > SIZE_MAX)
+ return 0;
+
+ if (!mbed_ok (mbedtls_cipher_finish (ctx, dst, &olen)))
+ {
+ msg (D_CRYPT_ERRORS, "%s: cipher_ctx_final() failed", __func__);
+ return 0;
+ }
+
+ if (olen > INT_MAX)
+ return 0;
+ *dst_len = olen;
+
+ if (!mbed_ok (mbedtls_cipher_check_tag (ctx, (const unsigned char *) tag,
+ tag_len)))
+ return 0;
+
+ return 1;
+#else
+ ASSERT(0);
+#endif /* HAVE_AEAD_CIPHER_MODES */
+}
+
+void
+cipher_des_encrypt_ecb (const unsigned char key[DES_KEY_LENGTH],
+ unsigned char *src,
+ unsigned char *dst)
+{
+ mbedtls_des_context ctx;
+
+ ASSERT (mbed_ok(mbedtls_des_setkey_enc(&ctx, key)));
+ ASSERT (mbed_ok(mbedtls_des_crypt_ecb(&ctx, src, dst)));
+}
+
+
+
+/*
+ *
+ * Generic message digest information functions
+ *
+ */
+
+
+const mbedtls_md_info_t *
+md_kt_get (const char *digest)
+{
+ const mbedtls_md_info_t *md = NULL;
+ ASSERT (digest);
+
+ md = mbedtls_md_info_from_string(digest);
+ if (!md)
+ msg (M_FATAL, "Message hash algorithm '%s' not found", digest);
+ if (mbedtls_md_get_size(md) > MAX_HMAC_KEY_LENGTH)
+ msg (M_FATAL, "Message hash algorithm '%s' uses a default hash size (%d bytes) which is larger than " PACKAGE_NAME "'s current maximum hash size (%d bytes)",
+ digest,
+ mbedtls_md_get_size(md),
+ MAX_HMAC_KEY_LENGTH);
+ return md;
+}
+
+const char *
+md_kt_name (const mbedtls_md_info_t *kt)
+{
+ if (NULL == kt)
+ return "[null-digest]";
+ return mbedtls_md_get_name (kt);
+}
+
+int
+md_kt_size (const mbedtls_md_info_t *kt)
+{
+ if (NULL == kt)
+ return 0;
+ return mbedtls_md_get_size(kt);
+}
+
+/*
+ *
+ * Generic message digest functions
+ *
+ */
+
+int
+md_full (const md_kt_t *kt, const uint8_t *src, int src_len, uint8_t *dst)
+{
+ return 0 == mbedtls_md(kt, src, src_len, dst);
+}
+
+
+void
+md_ctx_init (mbedtls_md_context_t *ctx, const mbedtls_md_info_t *kt)
+{
+ ASSERT(NULL != ctx && NULL != kt);
+
+ mbedtls_md_init(ctx);
+ ASSERT(0 == mbedtls_md_setup(ctx, kt, 0));
+ ASSERT(0 == mbedtls_md_starts(ctx));
+}
+
+void
+md_ctx_cleanup(mbedtls_md_context_t *ctx)
+{
+}
+
+int
+md_ctx_size (const mbedtls_md_context_t *ctx)
+{
+ if (NULL == ctx)
+ return 0;
+ return mbedtls_md_get_size(ctx->md_info);
+}
+
+void
+md_ctx_update (mbedtls_md_context_t *ctx, const uint8_t *src, int src_len)
+{
+ ASSERT(0 == mbedtls_md_update(ctx, src, src_len));
+}
+
+void
+md_ctx_final (mbedtls_md_context_t *ctx, uint8_t *dst)
+{
+ ASSERT(0 == mbedtls_md_finish(ctx, dst));
+ mbedtls_md_free(ctx);
+}
+
+
+/*
+ *
+ * Generic HMAC functions
+ *
+ */
+
+
+/*
+ * TODO: re-enable dmsg for crypto debug
+ */
+void
+hmac_ctx_init (mbedtls_md_context_t *ctx, const uint8_t *key, int key_len,
+ const mbedtls_md_info_t *kt)
+{
+ ASSERT(NULL != kt && NULL != ctx);
+
+ mbedtls_md_init(ctx);
+ ASSERT(0 == mbedtls_md_setup(ctx, kt, 1));
+ ASSERT(0 == mbedtls_md_hmac_starts(ctx, key, key_len));
+
+ /* make sure we used a big enough key */
+ ASSERT (mbedtls_md_get_size(kt) <= key_len);
+}
+
+void
+hmac_ctx_cleanup(mbedtls_md_context_t *ctx)
+{
+ mbedtls_md_free(ctx);
+}
+
+int
+hmac_ctx_size (const mbedtls_md_context_t *ctx)
+{
+ if (NULL == ctx)
+ return 0;
+ return mbedtls_md_get_size(ctx->md_info);
+}
+
+void
+hmac_ctx_reset (mbedtls_md_context_t *ctx)
+{
+ ASSERT(0 == mbedtls_md_hmac_reset(ctx));
+}
+
+void
+hmac_ctx_update (mbedtls_md_context_t *ctx, const uint8_t *src, int src_len)
+{
+ ASSERT(0 == mbedtls_md_hmac_update(ctx, src, src_len));
+}
+
+void
+hmac_ctx_final (mbedtls_md_context_t *ctx, uint8_t *dst)
+{
+ ASSERT(0 == mbedtls_md_hmac_finish(ctx, dst));
+}
+
+#endif /* ENABLE_CRYPTO && ENABLE_CRYPTO_MBEDTLS */
diff --git a/src/openvpn/crypto_polarssl.h b/src/openvpn/crypto_mbedtls.h
index 12b5146..574a63f 100644
--- a/src/openvpn/crypto_polarssl.h
+++ b/src/openvpn/crypto_mbedtls.h
@@ -24,48 +24,51 @@
*/
/**
- * @file Data Channel Cryptography PolarSSL-specific backend interface
+ * @file Data Channel Cryptography mbed TLS-specific backend interface
*/
-#ifndef CRYPTO_POLARSSL_H_
-#define CRYPTO_POLARSSL_H_
+#ifndef CRYPTO_MBEDTLS_H_
+#define CRYPTO_MBEDTLS_H_
-#include <polarssl/cipher.h>
-#include <polarssl/md.h>
-#include <polarssl/ctr_drbg.h>
+#include <mbedtls/cipher.h>
+#include <mbedtls/md.h>
+#include <mbedtls/ctr_drbg.h>
/** Generic cipher key type %context. */
-typedef cipher_info_t cipher_kt_t;
+typedef mbedtls_cipher_info_t cipher_kt_t;
/** Generic message digest key type %context. */
-typedef md_info_t md_kt_t;
+typedef mbedtls_md_info_t md_kt_t;
/** Generic cipher %context. */
-typedef cipher_context_t cipher_ctx_t;
+typedef mbedtls_cipher_context_t cipher_ctx_t;
/** Generic message digest %context. */
-typedef md_context_t md_ctx_t;
+typedef mbedtls_md_context_t md_ctx_t;
/** Generic HMAC %context. */
-typedef md_context_t hmac_ctx_t;
+typedef mbedtls_md_context_t hmac_ctx_t;
/** Maximum length of an IV */
-#define OPENVPN_MAX_IV_LENGTH POLARSSL_MAX_IV_LENGTH
+#define OPENVPN_MAX_IV_LENGTH MBEDTLS_MAX_IV_LENGTH
/** Cipher is in CBC mode */
-#define OPENVPN_MODE_CBC POLARSSL_MODE_CBC
+#define OPENVPN_MODE_CBC MBEDTLS_MODE_CBC
/** Cipher is in OFB mode */
-#define OPENVPN_MODE_OFB POLARSSL_MODE_OFB
+#define OPENVPN_MODE_OFB MBEDTLS_MODE_OFB
/** Cipher is in CFB mode */
-#define OPENVPN_MODE_CFB POLARSSL_MODE_CFB
+#define OPENVPN_MODE_CFB MBEDTLS_MODE_CFB
+
+/** Cipher is in GCM mode */
+#define OPENVPN_MODE_GCM MBEDTLS_MODE_GCM
/** Cipher should encrypt */
-#define OPENVPN_OP_ENCRYPT POLARSSL_ENCRYPT
+#define OPENVPN_OP_ENCRYPT MBEDTLS_ENCRYPT
/** Cipher should decrypt */
-#define OPENVPN_OP_DECRYPT POLARSSL_DECRYPT
+#define OPENVPN_OP_DECRYPT MBEDTLS_DECRYPT
#define MD4_DIGEST_LENGTH 16
#define MD5_DIGEST_LENGTH 16
@@ -73,16 +76,16 @@ typedef md_context_t hmac_ctx_t;
#define DES_KEY_LENGTH 8
/**
- * Returns a singleton instance of the PolarSSL random number generator.
+ * Returns a singleton instance of the mbed TLS random number generator.
*
- * For PolarSSL 1.1+, this is the CTR_DRBG random number generator. If it
+ * For PolarSSL/mbed TLS 1.1+, this is the CTR_DRBG random number generator. If it
* hasn't been initialised yet, the RNG will be initialised using the default
* entropy sources. Aside from the default platform entropy sources, an
* additional entropy source, the HAVEGE random number generator will also be
* added. During initialisation, a personalisation string will be added based
* on the time, the PID, and a pointer to the random context.
*/
-ctr_drbg_context * rand_ctx_get();
+mbedtls_ctr_drbg_context *rand_ctx_get();
#ifdef ENABLE_PREDICTION_RESISTANCE
/**
@@ -92,34 +95,34 @@ void rand_ctx_enable_prediction_resistance();
#endif
/**
- * Log the supplied PolarSSL error, prefixed by supplied prefix.
+ * Log the supplied mbed TLS error, prefixed by supplied prefix.
*
* @param flags Flags to indicate error type and priority.
- * @param errval PolarSSL error code to convert to error message.
- * @param prefix Prefix to PolarSSL error message.
+ * @param errval mbed TLS error code to convert to error message.
+ * @param prefix Prefix to mbed TLS error message.
*
* @returns true if no errors are detected, false otherwise.
*/
-bool polar_log_err(unsigned int flags, int errval, const char *prefix);
+bool mbed_log_err(unsigned int flags, int errval, const char *prefix);
/**
- * Log the supplied PolarSSL error, prefixed by function name and line number.
+ * Log the supplied mbed TLS error, prefixed by function name and line number.
*
* @param flags Flags to indicate error type and priority.
- * @param errval PolarSSL error code to convert to error message.
+ * @param errval mbed TLS error code to convert to error message.
* @param func Function name where error was reported.
* @param line Line number where error was reported.
*
* @returns true if no errors are detected, false otherwise.
*/
-bool polar_log_func_line(unsigned int flags, int errval, const char *func,
+bool mbed_log_func_line(unsigned int flags, int errval, const char *func,
int line);
-/** Wraps polar_log_func_line() to prevent function calls for non-errors */
-static inline bool polar_log_func_line_lite(unsigned int flags, int errval,
+/** Wraps mbed_log_func_line() to prevent function calls for non-errors */
+static inline bool mbed_log_func_line_lite(unsigned int flags, int errval,
const char *func, int line) {
if (errval) {
- return polar_log_func_line (flags, errval, func, line);
+ return mbed_log_func_line (flags, errval, func, line);
}
return true;
}
@@ -127,17 +130,17 @@ static inline bool polar_log_func_line_lite(unsigned int flags, int errval,
/**
* Check errval and log on error.
*
- * Convenience wrapper to put around polarssl library calls, e.g.
- * if (!polar_ok(polarssl_func())) return 0;
+ * Convenience wrapper to put around mbed TLS library calls, e.g.
+ * if (!mbed_ok (mbedtls_ssl_func())) return 0;
* or
- * ASSERT (polar_ok(polarssl_func()));
+ * ASSERT (mbed_ok (mbedtls_ssl_func()));
*
- * @param errval PolarSSL error code to convert to error message.
+ * @param errval mbed TLS error code to convert to error message.
*
* @returns true if no errors are detected, false otherwise.
*/
-#define polar_ok(errval) \
- polar_log_func_line_lite (D_CRYPT_ERRORS, errval, __func__, __LINE__)
+#define mbed_ok(errval) \
+ mbed_log_func_line_lite(D_CRYPT_ERRORS, errval, __func__, __LINE__)
-#endif /* CRYPTO_POLARSSL_H_ */
+#endif /* CRYPTO_MBEDTLS_H_ */
diff --git a/src/openvpn/crypto_openssl.c b/src/openvpn/crypto_openssl.c
index c147245..1ea06bb 100644
--- a/src/openvpn/crypto_openssl.c
+++ b/src/openvpn/crypto_openssl.c
@@ -42,9 +42,12 @@
#include "integer.h"
#include "crypto.h"
#include "crypto_backend.h"
-#include <openssl/objects.h>
-#include <openssl/evp.h>
+
#include <openssl/des.h>
+#include <openssl/err.h>
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/ssl.h>
/*
* Check for key size creepage.
@@ -58,41 +61,6 @@
#warning Some OpenSSL HMAC message digests now support key lengths greater than MAX_HMAC_KEY_LENGTH -- consider increasing MAX_HMAC_KEY_LENGTH
#endif
-/*
- *
- * Workarounds for incompatibilites between OpenSSL libraries.
- * Right now we accept OpenSSL libraries from 0.9.5 to 0.9.7.
- *
- */
-
-#if SSLEAY_VERSION_NUMBER < 0x00907000L
-
-/* Workaround: EVP_CIPHER_mode is defined wrong in OpenSSL 0.9.6 but is fixed in 0.9.7 */
-#undef EVP_CIPHER_mode
-#define EVP_CIPHER_mode(e) (((e)->flags) & EVP_CIPH_MODE)
-
-#define DES_cblock des_cblock
-#define DES_is_weak_key des_is_weak_key
-#define DES_check_key_parity des_check_key_parity
-#define DES_set_odd_parity des_set_odd_parity
-
-#define HMAC_CTX_init(ctx) CLEAR (*ctx)
-#define HMAC_Init_ex(ctx,sec,len,md,impl) HMAC_Init(ctx, sec, len, md)
-#define HMAC_CTX_cleanup(ctx) HMAC_cleanup(ctx)
-#define EVP_MD_CTX_cleanup(md) CLEAR (*md)
-
-#define INFO_CALLBACK_SSL_CONST
-
-#endif
-
-#ifndef EVP_CIPHER_name
-#define EVP_CIPHER_name(e) OBJ_nid2sn(EVP_CIPHER_nid(e))
-#endif
-
-#ifndef EVP_MD_name
-#define EVP_MD_name(e) OBJ_nid2sn(EVP_MD_type(e))
-#endif
-
#if HAVE_OPENSSL_ENGINE
#include <openssl/engine.h>
@@ -179,14 +147,6 @@ crypto_init_lib_engine (const char *engine_name)
void
crypto_init_lib (void)
{
-#ifndef ENABLE_SSL
- /* If SSL is enabled init is taken care of in ssl_openssl.c */
-#ifndef ENABLE_SMALL
- ERR_load_crypto_strings ();
-#endif
- OpenSSL_add_all_algorithms ();
-#endif
-
/*
* If you build the OpenSSL library and OpenVPN with
* CRYPTO_MDEBUG, you will get a listing of OpenSSL
@@ -201,14 +161,6 @@ crypto_init_lib (void)
void
crypto_uninit_lib (void)
{
-#ifndef ENABLE_SSL
- /* If SSL is enabled cleanup is taken care of in ssl_openssl.c */
- EVP_cleanup ();
-#ifndef ENABLE_SMALL
- ERR_free_strings ();
-#endif
-#endif
-
#ifdef CRYPTO_MDEBUG
FILE* fp = fopen ("sdlog", "w");
ASSERT (fp);
@@ -237,9 +189,21 @@ crypto_print_openssl_errors(const unsigned int flags) {
size_t err = 0;
while ((err = ERR_get_error ()))
- msg (flags, "OpenSSL: %s", ERR_error_string (err, NULL));
+ {
+ /* Be more clear about frequently occurring "no shared cipher" error */
+ if (err == ERR_PACK(ERR_LIB_SSL,SSL_F_SSL3_GET_CLIENT_HELLO,
+ SSL_R_NO_SHARED_CIPHER))
+ {
+ msg (D_CRYPT_ERRORS, "TLS error: The server has no TLS ciphersuites "
+ "in common with the client. Your --tls-cipher setting might be "
+ "too restrictive.");
+ }
+
+ msg (flags, "OpenSSL: %s", ERR_error_string (err, NULL));
+ }
}
+
/*
*
* OpenSSL memory debugging. If dmalloc debugging is enabled, tell
@@ -276,55 +240,97 @@ crypto_init_dmalloc (void)
}
#endif /* DMALLOC */
-const char *
-translate_cipher_name_from_openvpn (const char *cipher_name) {
- // OpenSSL doesn't require any translation
- return cipher_name;
+const cipher_name_pair cipher_name_translation_table[] = {
+ { "AES-128-GCM", "id-aes128-GCM" },
+ { "AES-192-GCM", "id-aes192-GCM" },
+ { "AES-256-GCM", "id-aes256-GCM" },
+};
+const size_t cipher_name_translation_table_count =
+ sizeof (cipher_name_translation_table) / sizeof (*cipher_name_translation_table);
+
+
+static int
+cipher_name_cmp(const void *a, const void *b)
+{
+ const EVP_CIPHER * const *cipher_a = a;
+ const EVP_CIPHER * const *cipher_b = b;
+
+ const char *cipher_name_a =
+ translate_cipher_name_to_openvpn(EVP_CIPHER_name(*cipher_a));
+ const char *cipher_name_b =
+ translate_cipher_name_to_openvpn(EVP_CIPHER_name(*cipher_b));
+
+ return strcmp(cipher_name_a, cipher_name_b);
}
-const char *
-translate_cipher_name_to_openvpn (const char *cipher_name) {
- // OpenSSL doesn't require any translation
- return cipher_name;
+static void
+print_cipher(const EVP_CIPHER *cipher)
+{
+ const char *var_key_size =
+ (EVP_CIPHER_flags (cipher) & EVP_CIPH_VARIABLE_LENGTH) ?
+ " by default" : "";
+ const char *ssl_only = cipher_kt_mode_cbc(cipher) ?
+ "" : ", TLS client/server mode only";
+
+ printf ("%s (%d bit key%s, %d bit block%s)\n",
+ translate_cipher_name_to_openvpn (EVP_CIPHER_name (cipher)),
+ EVP_CIPHER_key_length (cipher) * 8, var_key_size,
+ cipher_kt_block_size (cipher) * 8, ssl_only);
}
void
show_available_ciphers ()
{
int nid;
+ size_t i;
+ /* If we ever exceed this, we must be more selective */
+ const size_t cipher_list_len = 1000;
+ const EVP_CIPHER *cipher_list[cipher_list_len];
+ size_t num_ciphers = 0;
#ifndef ENABLE_SMALL
- printf ("The following ciphers and cipher modes are available\n"
- "for use with " PACKAGE_NAME ". Each cipher shown below may be\n"
- "used as a parameter to the --cipher option. The default\n"
- "key size is shown as well as whether or not it can be\n"
- "changed with the --keysize directive. Using a CBC mode\n"
- "is recommended. In static key mode only CBC mode is allowed.\n\n");
+ printf ("The following ciphers and cipher modes are available for use\n"
+ "with " PACKAGE_NAME ". Each cipher shown below may be use as a\n"
+ "parameter to the --cipher option. The default key size is\n"
+ "shown as well as whether or not it can be changed with the\n"
+ "--keysize directive. Using a CBC or GCM mode is recommended.\n"
+ "In static key mode only CBC mode is allowed.\n\n");
#endif
- for (nid = 0; nid < 10000; ++nid) /* is there a better way to get the size of the nid list? */
+ for (nid = 0; nid < 10000; ++nid)
{
- const EVP_CIPHER *cipher = EVP_get_cipherbynid (nid);
- if (cipher)
- {
- if (cipher_kt_mode_cbc(cipher)
+ const EVP_CIPHER *cipher = EVP_get_cipherbynid(nid);
+ if (cipher && (cipher_kt_mode_cbc(cipher)
#ifdef ENABLE_OFB_CFB_MODE
|| cipher_kt_mode_ofb_cfb(cipher)
#endif
- )
- {
- const char *var_key_size =
- (EVP_CIPHER_flags (cipher) & EVP_CIPH_VARIABLE_LENGTH) ?
- "variable" : "fixed";
- const char *ssl_only = cipher_kt_mode_ofb_cfb(cipher) ?
- " (TLS client/server mode)" : "";
-
- printf ("%s %d bit default key (%s)%s\n", OBJ_nid2sn (nid),
- EVP_CIPHER_key_length (cipher) * 8, var_key_size,
- ssl_only);
- }
+#ifdef HAVE_AEAD_CIPHER_MODES
+ || cipher_kt_mode_aead(cipher)
+#endif
+ ))
+ {
+ cipher_list[num_ciphers++] = cipher;
+ }
+ if (num_ciphers == cipher_list_len)
+ {
+ msg (M_WARN, "WARNING: Too many ciphers, not showing all");
+ break;
}
}
+
+ qsort (cipher_list, num_ciphers, sizeof(*cipher_list), cipher_name_cmp);
+
+ for (i = 0; i < num_ciphers; i++) {
+ if (cipher_kt_block_size(cipher_list[i]) >= 128/8)
+ print_cipher(cipher_list[i]);
+ }
+
+ printf ("\nThe following ciphers have a block size of less than 128 bits, \n"
+ "and are therefore deprecated. Do not use unless you have to.\n\n");
+ for (i = 0; i < num_ciphers; i++) {
+ if (cipher_kt_block_size(cipher_list[i]) < 128/8)
+ print_cipher(cipher_list[i]);
+ }
printf ("\n");
}
@@ -498,13 +504,20 @@ cipher_kt_get (const char *ciphername)
cipher = EVP_get_cipherbyname (ciphername);
if (NULL == cipher)
- crypto_msg (M_FATAL, "Cipher algorithm '%s' not found", ciphername);
+ {
+ crypto_msg (D_LOW, "Cipher algorithm '%s' not found", ciphername);
+ return NULL;
+ }
+
if (EVP_CIPHER_key_length (cipher) > MAX_CIPHER_KEY_LENGTH)
- msg (M_FATAL, "Cipher algorithm '%s' uses a default key size (%d bytes) which is larger than " PACKAGE_NAME "'s current maximum key size (%d bytes)",
- ciphername,
- EVP_CIPHER_key_length (cipher),
- MAX_CIPHER_KEY_LENGTH);
+ {
+ msg (D_LOW, "Cipher algorithm '%s' uses a default key size (%d bytes) "
+ "which is larger than " PACKAGE_NAME "'s current maximum key size "
+ "(%d bytes)", ciphername, EVP_CIPHER_key_length (cipher),
+ MAX_CIPHER_KEY_LENGTH);
+ return NULL;
+ }
return cipher;
}
@@ -530,9 +543,46 @@ cipher_kt_iv_size (const EVP_CIPHER *cipher_kt)
}
int
-cipher_kt_block_size (const EVP_CIPHER *cipher_kt)
+cipher_kt_block_size (const EVP_CIPHER *cipher) {
+ /* OpenSSL reports OFB/CFB/GCM cipher block sizes as '1 byte'. To work
+ * around that, try to replace the mode with 'CBC' and return the block size
+ * reported for that cipher, if possible. If that doesn't work, just return
+ * the value reported by OpenSSL.
+ */
+ char *name = NULL;
+ char *mode_str = NULL;
+ const char *orig_name = NULL;
+ const EVP_CIPHER *cbc_cipher = NULL;
+
+ int block_size = EVP_CIPHER_block_size(cipher);
+
+ orig_name = cipher_kt_name(cipher);
+ if (!orig_name)
+ goto cleanup;
+
+ name = string_alloc(translate_cipher_name_to_openvpn(orig_name), NULL);
+ mode_str = strrchr (name, '-');
+ if (!mode_str || strlen(mode_str) < 4)
+ goto cleanup;
+
+ strcpy (mode_str, "-CBC");
+
+ cbc_cipher = EVP_get_cipherbyname(translate_cipher_name_from_openvpn(name));
+ if (cbc_cipher)
+ block_size = EVP_CIPHER_block_size(cbc_cipher);
+
+cleanup:
+ free (name);
+ return block_size;
+}
+
+int
+cipher_kt_tag_size (const EVP_CIPHER *cipher_kt)
{
- return EVP_CIPHER_block_size (cipher_kt);
+ if (cipher_kt_mode_aead(cipher_kt))
+ return OPENVPN_AEAD_TAG_LENGTH;
+ else
+ return 0;
}
int
@@ -565,6 +615,16 @@ cipher_kt_mode_ofb_cfb(const cipher_kt_t *cipher)
;
}
+bool
+cipher_kt_mode_aead(const cipher_kt_t *cipher)
+{
+#ifdef HAVE_AEAD_CIPHER_MODES
+ return cipher && (cipher_kt_mode(cipher) == OPENVPN_MODE_GCM);
+#else
+ return false;
+#endif
+}
+
/*
*
* Generic cipher context functions
@@ -606,6 +666,15 @@ cipher_ctx_iv_length (const EVP_CIPHER_CTX *ctx)
return EVP_CIPHER_CTX_iv_length (ctx);
}
+int cipher_ctx_get_tag (EVP_CIPHER_CTX *ctx, uint8_t *tag_buf, int tag_size)
+{
+#ifdef HAVE_AEAD_CIPHER_MODES
+ return EVP_CIPHER_CTX_ctrl (ctx, EVP_CTRL_GCM_GET_TAG, tag_size, tag_buf);
+#else
+ ASSERT (0);
+#endif
+}
+
int
cipher_ctx_block_size(const EVP_CIPHER_CTX *ctx)
{
@@ -621,7 +690,7 @@ cipher_ctx_mode (const EVP_CIPHER_CTX *ctx)
const cipher_kt_t *
cipher_ctx_get_cipher_kt (const cipher_ctx_t *ctx)
{
- return EVP_CIPHER_CTX_cipher(ctx);
+ return ctx ? EVP_CIPHER_CTX_cipher(ctx) : NULL;
}
@@ -632,6 +701,19 @@ cipher_ctx_reset (EVP_CIPHER_CTX *ctx, uint8_t *iv_buf)
}
int
+cipher_ctx_update_ad (EVP_CIPHER_CTX *ctx, const uint8_t *src, int src_len)
+{
+#ifdef HAVE_AEAD_CIPHER_MODES
+ int len;
+ if (!EVP_CipherUpdate (ctx, NULL, &len, src, src_len))
+ crypto_msg(M_FATAL, "%s: EVP_CipherUpdate() failed", __func__);
+ return 1;
+#else
+ ASSERT (0);
+#endif
+}
+
+int
cipher_ctx_update (EVP_CIPHER_CTX *ctx, uint8_t *dst, int *dst_len,
uint8_t *src, int src_len)
{
@@ -646,6 +728,20 @@ cipher_ctx_final (EVP_CIPHER_CTX *ctx, uint8_t *dst, int *dst_len)
return EVP_CipherFinal (ctx, dst, dst_len);
}
+int
+cipher_ctx_final_check_tag (EVP_CIPHER_CTX *ctx, uint8_t *dst, int *dst_len,
+ uint8_t *tag, size_t tag_len)
+{
+#ifdef HAVE_AEAD_CIPHER_MODES
+ ASSERT (tag_len < SIZE_MAX);
+ if (!EVP_CIPHER_CTX_ctrl (ctx, EVP_CTRL_GCM_SET_TAG, tag_len, tag))
+ return 0;
+
+ return cipher_ctx_final (ctx, dst, dst_len);
+#else
+ ASSERT (0);
+#endif
+}
void
cipher_des_encrypt_ecb (const unsigned char key[DES_KEY_LENGTH],
diff --git a/src/openvpn/crypto_openssl.h b/src/openvpn/crypto_openssl.h
index 42c7e9a..f157041 100644
--- a/src/openvpn/crypto_openssl.h
+++ b/src/openvpn/crypto_openssl.h
@@ -61,6 +61,13 @@ typedef HMAC_CTX hmac_ctx_t;
/** Cipher is in CFB mode */
#define OPENVPN_MODE_CFB EVP_CIPH_CFB_MODE
+#ifdef HAVE_AEAD_CIPHER_MODES
+
+/** Cipher is in GCM mode */
+#define OPENVPN_MODE_GCM EVP_CIPH_GCM_MODE
+
+#endif /* HAVE_AEAD_CIPHER_MODES */
+
/** Cipher should encrypt */
#define OPENVPN_OP_ENCRYPT 1
diff --git a/src/openvpn/crypto_polarssl.c b/src/openvpn/crypto_polarssl.c
deleted file mode 100644
index 92fdb78..0000000
--- a/src/openvpn/crypto_polarssl.c
+++ /dev/null
@@ -1,712 +0,0 @@
-/*
- * OpenVPN -- An application to securely tunnel IP networks
- * over a single TCP/UDP port, with support for SSL/TLS-based
- * session authentication and key exchange,
- * packet encryption, packet authentication, and
- * packet compression.
- *
- * Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net>
- * Copyright (C) 2010 Fox Crypto B.V. <openvpn@fox-it.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program (see the file COPYING included with this
- * distribution); if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/**
- * @file Data Channel Cryptography PolarSSL-specific backend interface
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#elif defined(_MSC_VER)
-#include "config-msvc.h"
-#endif
-
-#include "syshead.h"
-
-#if defined(ENABLE_CRYPTO) && defined(ENABLE_CRYPTO_POLARSSL)
-
-#include "errlevel.h"
-#include "basic.h"
-#include "buffer.h"
-#include "integer.h"
-#include "crypto_backend.h"
-#include "otime.h"
-#include "misc.h"
-
-#include <polarssl/des.h>
-#include <polarssl/error.h>
-#include <polarssl/md5.h>
-#include <polarssl/cipher.h>
-#include <polarssl/havege.h>
-
-#include <polarssl/entropy.h>
-
-/*
- *
- * Hardware engine support. Allows loading/unloading of engines.
- *
- */
-
-void
-crypto_init_lib_engine (const char *engine_name)
-{
- msg (M_WARN, "Note: PolarSSL hardware crypto engine functionality is not "
- "available");
-}
-
-/*
- *
- * Functions related to the core crypto library
- *
- */
-
-void
-crypto_init_lib (void)
-{
-}
-
-void
-crypto_uninit_lib (void)
-{
-}
-
-void
-crypto_clear_error (void)
-{
-}
-
-bool polar_log_err(unsigned int flags, int errval, const char *prefix)
-{
- if (0 != errval)
- {
- char errstr[256];
- polarssl_strerror(errval, errstr, sizeof(errstr));
-
- if (NULL == prefix) prefix = "PolarSSL error";
- msg (flags, "%s: %s", prefix, errstr);
- }
-
- return 0 == errval;
-}
-
-bool polar_log_func_line(unsigned int flags, int errval, const char *func,
- int line)
-{
- char prefix[256];
-
- if (!openvpn_snprintf(prefix, sizeof(prefix), "%s:%d", func, line))
- return polar_log_err(flags, errval, func);
-
- return polar_log_err(flags, errval, prefix);
-}
-
-
-#ifdef DMALLOC
-void
-crypto_init_dmalloc (void)
-{
- msg (M_ERR, "Error: dmalloc support is not available for PolarSSL.");
-}
-#endif /* DMALLOC */
-
-typedef struct { const char * openvpn_name; const char * polarssl_name; } cipher_name_pair;
-cipher_name_pair cipher_name_translation_table[] = {
- { "BF-CBC", "BLOWFISH-CBC" },
- { "BF-CFB", "BLOWFISH-CFB64" },
- { "CAMELLIA-128-CFB", "CAMELLIA-128-CFB128" },
- { "CAMELLIA-192-CFB", "CAMELLIA-192-CFB128" },
- { "CAMELLIA-256-CFB", "CAMELLIA-256-CFB128" }
-};
-
-const cipher_name_pair *
-get_cipher_name_pair(const char *cipher_name) {
- cipher_name_pair *pair;
- size_t i = 0;
-
- /* Search for a cipher name translation */
- for (; i < sizeof (cipher_name_translation_table) / sizeof (*cipher_name_translation_table); i++)
- {
- pair = &cipher_name_translation_table[i];
- if (0 == strcmp (cipher_name, pair->openvpn_name) ||
- 0 == strcmp (cipher_name, pair->polarssl_name))
- return pair;
- }
-
- /* Nothing found, return null */
- return NULL;
-}
-
-const char *
-translate_cipher_name_from_openvpn (const char *cipher_name) {
- const cipher_name_pair *pair = get_cipher_name_pair(cipher_name);
-
- if (NULL == pair)
- return cipher_name;
-
- return pair->polarssl_name;
-}
-
-const char *
-translate_cipher_name_to_openvpn (const char *cipher_name) {
- const cipher_name_pair *pair = get_cipher_name_pair(cipher_name);
-
- if (NULL == pair)
- return cipher_name;
-
- return pair->openvpn_name;
-}
-
-void
-show_available_ciphers ()
-{
- const int *ciphers = cipher_list();
-
-#ifndef ENABLE_SMALL
- printf ("The following ciphers and cipher modes are available\n"
- "for use with " PACKAGE_NAME ". Each cipher shown below may be\n"
- "used as a parameter to the --cipher option. The default\n"
- "key size is shown as well as whether or not it can be\n"
- "changed with the --keysize directive. Using a CBC mode\n"
- "is recommended.\n\n");
-#endif
-
- while (*ciphers != 0)
- {
- const cipher_info_t *info = cipher_info_from_type(*ciphers);
-
- if (info && info->mode == POLARSSL_MODE_CBC)
- printf ("%s %d bit default key\n",
- cipher_kt_name(info), cipher_kt_key_size(info) * 8);
-
- ciphers++;
- }
- printf ("\n");
-}
-
-void
-show_available_digests ()
-{
- const int *digests = md_list();
-
-#ifndef ENABLE_SMALL
- printf ("The following message digests are available for use with\n"
- PACKAGE_NAME ". A message digest is used in conjunction with\n"
- "the HMAC function, to authenticate received packets.\n"
- "You can specify a message digest as parameter to\n"
- "the --auth option.\n\n");
-#endif
-
- while (*digests != 0)
- {
- const md_info_t *info = md_info_from_type(*digests);
-
- if (info)
- printf ("%s %d bit default key\n",
- info->name, info->size * 8);
- digests++;
- }
- printf ("\n");
-}
-
-void
-show_available_engines ()
-{
- printf ("Sorry, PolarSSL hardware crypto engine functionality is not "
- "available\n");
-}
-
-/*
- *
- * Random number functions, used in cases where we want
- * reasonably strong cryptographic random number generation
- * without depleting our entropy pool. Used for random
- * IV values and a number of other miscellaneous tasks.
- *
- */
-
-/*
- * Initialise the given ctr_drbg context, using a personalisation string and an
- * entropy gathering function.
- */
-ctr_drbg_context * rand_ctx_get()
-{
- static entropy_context ec = {0};
- static ctr_drbg_context cd_ctx = {0};
- static bool rand_initialised = false;
-
- if (!rand_initialised)
- {
- struct gc_arena gc = gc_new();
- struct buffer pers_string = alloc_buf_gc(100, &gc);
-
- /*
- * Personalisation string, should be as unique as possible (see NIST
- * 800-90 section 8.7.1). We have very little information at this stage.
- * Include Program Name, memory address of the context and PID.
- */
- buf_printf(&pers_string, "OpenVPN %0u %p %s", platform_getpid(), &cd_ctx, time_string(0, 0, 0, &gc));
-
- /* Initialise PolarSSL RNG, and built-in entropy sources */
- entropy_init(&ec);
-
- if (!polar_ok(ctr_drbg_init(&cd_ctx, entropy_func, &ec,
- BPTR(&pers_string), BLEN(&pers_string))))
- msg (M_FATAL, "Failed to initialize random generator");
-
- gc_free(&gc);
- rand_initialised = true;
- }
-
- return &cd_ctx;
-}
-
-#ifdef ENABLE_PREDICTION_RESISTANCE
-void rand_ctx_enable_prediction_resistance()
-{
- ctr_drbg_context *cd_ctx = rand_ctx_get();
-
- ctr_drbg_set_prediction_resistance(cd_ctx, 1);
-}
-#endif /* ENABLE_PREDICTION_RESISTANCE */
-
-int
-rand_bytes (uint8_t *output, int len)
-{
- ctr_drbg_context *rng_ctx = rand_ctx_get();
-
- while (len > 0)
- {
- const size_t blen = min_int (len, CTR_DRBG_MAX_REQUEST);
- if (0 != ctr_drbg_random(rng_ctx, output, blen))
- return 0;
-
- output += blen;
- len -= blen;
- }
-
- return 1;
-}
-
-/*
- *
- * Key functions, allow manipulation of keys.
- *
- */
-
-
-int
-key_des_num_cblocks (const cipher_info_t *kt)
-{
- int ret = 0;
- if (kt->type == POLARSSL_CIPHER_DES_CBC)
- ret = 1;
- if (kt->type == POLARSSL_CIPHER_DES_EDE_CBC)
- ret = 2;
- if (kt->type == POLARSSL_CIPHER_DES_EDE3_CBC)
- ret = 3;
-
- dmsg (D_CRYPTO_DEBUG, "CRYPTO INFO: n_DES_cblocks=%d", ret);
- return ret;
-}
-
-bool
-key_des_check (uint8_t *key, int key_len, int ndc)
-{
- int i;
- struct buffer b;
-
- buf_set_read (&b, key, key_len);
-
- for (i = 0; i < ndc; ++i)
- {
- unsigned char *key = buf_read_alloc(&b, DES_KEY_SIZE);
- if (!key)
- {
- msg (D_CRYPT_ERRORS, "CRYPTO INFO: check_key_DES: insufficient key material");
- goto err;
- }
- if (0 != des_key_check_weak(key))
- {
- msg (D_CRYPT_ERRORS, "CRYPTO INFO: check_key_DES: weak key detected");
- goto err;
- }
- if (0 != des_key_check_key_parity(key))
- {
- msg (D_CRYPT_ERRORS, "CRYPTO INFO: check_key_DES: bad parity detected");
- goto err;
- }
- }
- return true;
-
- err:
- return false;
-}
-
-void
-key_des_fixup (uint8_t *key, int key_len, int ndc)
-{
- int i;
- struct buffer b;
-
- buf_set_read (&b, key, key_len);
- for (i = 0; i < ndc; ++i)
- {
- unsigned char *key = buf_read_alloc(&b, DES_KEY_SIZE);
- if (!key)
- {
- msg (D_CRYPT_ERRORS, "CRYPTO INFO: fixup_key_DES: insufficient key material");
- return;
- }
- des_key_set_parity(key);
- }
-}
-
-/*
- *
- * Generic cipher key type functions
- *
- */
-
-
-const cipher_info_t *
-cipher_kt_get (const char *ciphername)
-{
- const cipher_info_t *cipher = NULL;
-
- ASSERT (ciphername);
-
- cipher = cipher_info_from_string(ciphername);
-
- if (NULL == cipher)
- msg (M_FATAL, "Cipher algorithm '%s' not found", ciphername);
-
- if (cipher->key_length/8 > MAX_CIPHER_KEY_LENGTH)
- msg (M_FATAL, "Cipher algorithm '%s' uses a default key size (%d bytes) which is larger than " PACKAGE_NAME "'s current maximum key size (%d bytes)",
- ciphername,
- cipher->key_length/8,
- MAX_CIPHER_KEY_LENGTH);
-
- return cipher;
-}
-
-const char *
-cipher_kt_name (const cipher_info_t *cipher_kt)
-{
- if (NULL == cipher_kt)
- return "[null-cipher]";
-
- return translate_cipher_name_to_openvpn(cipher_kt->name);
-}
-
-int
-cipher_kt_key_size (const cipher_info_t *cipher_kt)
-{
- if (NULL == cipher_kt)
- return 0;
- if (POLARSSL_CIPHER_ID_BLOWFISH == cipher_kt->base->cipher)
- return 128/8; /* Override PolarSSL 32 bit default key size with sane 128 bit default */
-
- return cipher_kt->key_length/8;
-}
-
-int
-cipher_kt_iv_size (const cipher_info_t *cipher_kt)
-{
- if (NULL == cipher_kt)
- return 0;
- return cipher_kt->iv_size;
-}
-
-int
-cipher_kt_block_size (const cipher_info_t *cipher_kt)
-{
- if (NULL == cipher_kt)
- return 0;
- return cipher_kt->block_size;
-}
-
-int
-cipher_kt_mode (const cipher_info_t *cipher_kt)
-{
- ASSERT(NULL != cipher_kt);
- return cipher_kt->mode;
-}
-
-bool
-cipher_kt_mode_cbc(const cipher_kt_t *cipher)
-{
- return cipher && cipher_kt_mode(cipher) == OPENVPN_MODE_CBC;
-}
-
-bool
-cipher_kt_mode_ofb_cfb(const cipher_kt_t *cipher)
-{
- return cipher && (cipher_kt_mode(cipher) == OPENVPN_MODE_OFB ||
- cipher_kt_mode(cipher) == OPENVPN_MODE_CFB);
-}
-
-
-/*
- *
- * Generic cipher context functions
- *
- */
-
-
-void
-cipher_ctx_init (cipher_context_t *ctx, uint8_t *key, int key_len,
- const cipher_info_t *kt, int enc)
-{
- ASSERT(NULL != kt && NULL != ctx);
-
- CLEAR (*ctx);
-
- if (!polar_ok(cipher_init_ctx(ctx, kt)))
- msg (M_FATAL, "PolarSSL cipher context init #1");
-
- if (!polar_ok(cipher_setkey(ctx, key, key_len*8, enc)))
- msg (M_FATAL, "PolarSSL cipher set key");
-
- /* make sure we used a big enough key */
- ASSERT (ctx->key_length <= key_len*8);
-}
-
-void cipher_ctx_cleanup (cipher_context_t *ctx)
-{
- cipher_free(ctx);
-}
-
-int cipher_ctx_iv_length (const cipher_context_t *ctx)
-{
- return cipher_get_iv_size(ctx);
-}
-
-int cipher_ctx_block_size(const cipher_context_t *ctx)
-{
- return cipher_get_block_size(ctx);
-}
-
-int cipher_ctx_mode (const cipher_context_t *ctx)
-{
- ASSERT(NULL != ctx);
-
- return cipher_kt_mode(ctx->cipher_info);
-}
-
-const cipher_kt_t *
-cipher_ctx_get_cipher_kt (const cipher_ctx_t *ctx)
-{
- ASSERT(NULL != ctx);
-
- return ctx->cipher_info;
-}
-
-int cipher_ctx_reset (cipher_context_t *ctx, uint8_t *iv_buf)
-{
- if (!polar_ok(cipher_reset(ctx)))
- return 0;
-
- if (!polar_ok(cipher_set_iv(ctx, iv_buf, ctx->cipher_info->iv_size)))
- return 0;
-
- return 1;
-}
-
-int cipher_ctx_update (cipher_context_t *ctx, uint8_t *dst, int *dst_len,
- uint8_t *src, int src_len)
-{
- size_t s_dst_len = *dst_len;
-
- if (!polar_ok(cipher_update(ctx, src, (size_t)src_len, dst, &s_dst_len)))
- return 0;
-
- *dst_len = s_dst_len;
-
- return 1;
-}
-
-int cipher_ctx_final (cipher_context_t *ctx, uint8_t *dst, int *dst_len)
-{
- size_t s_dst_len = *dst_len;
-
- if (!polar_ok(cipher_finish(ctx, dst, &s_dst_len)))
- return 0;
-
- *dst_len = s_dst_len;
-
- return 1;
-}
-
-void
-cipher_des_encrypt_ecb (const unsigned char key[DES_KEY_LENGTH],
- unsigned char *src,
- unsigned char *dst)
-{
- des_context ctx;
-
- ASSERT (polar_ok(des_setkey_enc(&ctx, key)));
- ASSERT (polar_ok(des_crypt_ecb(&ctx, src, dst)));
-}
-
-
-
-/*
- *
- * Generic message digest information functions
- *
- */
-
-
-const md_info_t *
-md_kt_get (const char *digest)
-{
- const md_info_t *md = NULL;
- ASSERT (digest);
-
- md = md_info_from_string(digest);
- if (!md)
- msg (M_FATAL, "Message hash algorithm '%s' not found", digest);
- if (md->size > MAX_HMAC_KEY_LENGTH)
- msg (M_FATAL, "Message hash algorithm '%s' uses a default hash size (%d bytes) which is larger than " PACKAGE_NAME "'s current maximum hash size (%d bytes)",
- digest,
- md->size,
- MAX_HMAC_KEY_LENGTH);
- return md;
-}
-
-const char *
-md_kt_name (const md_info_t *kt)
-{
- if (NULL == kt)
- return "[null-digest]";
- return md_get_name (kt);
-}
-
-int
-md_kt_size (const md_info_t *kt)
-{
- if (NULL == kt)
- return 0;
- return md_get_size(kt);
-}
-
-/*
- *
- * Generic message digest functions
- *
- */
-
-int
-md_full (const md_kt_t *kt, const uint8_t *src, int src_len, uint8_t *dst)
-{
- return 0 == md(kt, src, src_len, dst);
-}
-
-
-void
-md_ctx_init (md_context_t *ctx, const md_info_t *kt)
-{
- ASSERT(NULL != ctx && NULL != kt);
-
- CLEAR(*ctx);
-
- ASSERT(0 == md_init_ctx(ctx, kt));
- ASSERT(0 == md_starts(ctx));
-}
-
-void
-md_ctx_cleanup(md_context_t *ctx)
-{
-}
-
-int
-md_ctx_size (const md_context_t *ctx)
-{
- if (NULL == ctx)
- return 0;
- return md_get_size(ctx->md_info);
-}
-
-void
-md_ctx_update (md_context_t *ctx, const uint8_t *src, int src_len)
-{
- ASSERT(0 == md_update(ctx, src, src_len));
-}
-
-void
-md_ctx_final (md_context_t *ctx, uint8_t *dst)
-{
- ASSERT(0 == md_finish(ctx, dst));
- md_free(ctx);
-}
-
-
-/*
- *
- * Generic HMAC functions
- *
- */
-
-
-/*
- * TODO: re-enable dmsg for crypto debug
- */
-void
-hmac_ctx_init (md_context_t *ctx, const uint8_t *key, int key_len, const md_info_t *kt)
-{
- ASSERT(NULL != kt && NULL != ctx);
-
- CLEAR(*ctx);
-
- ASSERT(0 == md_init_ctx(ctx, kt));
- ASSERT(0 == md_hmac_starts(ctx, key, key_len));
-
- /* make sure we used a big enough key */
- ASSERT (md_get_size(kt) <= key_len);
-}
-
-void
-hmac_ctx_cleanup(md_context_t *ctx)
-{
- md_free(ctx);
-}
-
-int
-hmac_ctx_size (const md_context_t *ctx)
-{
- if (NULL == ctx)
- return 0;
- return md_get_size(ctx->md_info);
-}
-
-void
-hmac_ctx_reset (md_context_t *ctx)
-{
- ASSERT(0 == md_hmac_reset(ctx));
-}
-
-void
-hmac_ctx_update (md_context_t *ctx, const uint8_t *src, int src_len)
-{
- ASSERT(0 == md_hmac_update(ctx, src, src_len));
-}
-
-void
-hmac_ctx_final (md_context_t *ctx, uint8_t *dst)
-{
- ASSERT(0 == md_hmac_finish(ctx, dst));
-}
-
-#endif /* ENABLE_CRYPTO && ENABLE_CRYPTO_POLARSSL */
diff --git a/src/openvpn/cryptoapi.c b/src/openvpn/cryptoapi.c
index 853c07b..e107bd3 100644
--- a/src/openvpn/cryptoapi.c
+++ b/src/openvpn/cryptoapi.c
@@ -465,4 +465,4 @@ int SSL_CTX_use_CryptoAPI_certificate(SSL_CTX *ssl_ctx, const char *cert_prop)
#ifdef _MSC_VER /* Dummy function needed to avoid empty file compiler warning in Microsoft VC */
static void dummy (void) {}
#endif
-#endif /* WIN32 */
+#endif /* _WIN32 */
diff --git a/src/openvpn/errlevel.h b/src/openvpn/errlevel.h
index 3ee4ebc..9d56eb4 100644
--- a/src/openvpn/errlevel.h
+++ b/src/openvpn/errlevel.h
@@ -105,7 +105,6 @@
#define D_X509_ATTR LOGLEV(4, 59, 0) /* show x509-track attributes on connection */
#define D_INIT_MEDIUM LOGLEV(4, 60, 0) /* show medium frequency init messages */
#define D_MTU_INFO LOGLEV(4, 61, 0) /* show terse MTU info */
-#define D_SHOW_OCC_HASH LOGLEV(4, 62, 0) /* show MD5 hash of option compatibility string */
#define D_PID_DEBUG_LOW LOGLEV(4, 63, 0) /* show low-freq packet-id debugging info */
#define D_PID_DEBUG_MEDIUM LOGLEV(4, 64, 0) /* show medium-freq packet-id debugging info */
@@ -143,11 +142,12 @@
#define D_PS_PROXY_DEBUG LOGLEV(7, 70, M_DEBUG) /* port share proxy debug */
#define D_AUTO_USERID LOGLEV(7, 70, M_DEBUG) /* AUTO_USERID debugging */
#define D_TLS_KEYSELECT LOGLEV(7, 70, M_DEBUG) /* show information on key selection for data channel */
-#define D_ARGV_PARSE_CMD LOGLEV(7, 70, M_DEBUG) /* show parse_line() errors in argv_printf %sc */
+#define D_ARGV_PARSE_CMD LOGLEV(7, 70, M_DEBUG) /* show parse_line() errors in argv_parse_cmd */
#define D_CRYPTO_DEBUG LOGLEV(7, 70, M_DEBUG) /* show detailed info from crypto.c routines */
#define D_PID_DEBUG LOGLEV(7, 70, M_DEBUG) /* show packet-id debugging info */
#define D_PF_DROPPED_BCAST LOGLEV(7, 71, M_DEBUG) /* packet filter dropped a broadcast packet */
#define D_PF_DEBUG LOGLEV(7, 72, M_DEBUG) /* packet filter debugging, must also define PF_DEBUG in pf.h */
+#define D_PUSH_DEBUG LOGLEV(7, 73, M_DEBUG) /* show push/pull debugging info */
#define D_HANDSHAKE_VERBOSE LOGLEV(8, 70, M_DEBUG) /* show detailed description of each handshake */
#define D_TLS_DEBUG_MED LOGLEV(8, 70, M_DEBUG) /* limited info from tls_session routines */
diff --git a/src/openvpn/error.c b/src/openvpn/error.c
index 6ccdeae..425bc30 100644
--- a/src/openvpn/error.c
+++ b/src/openvpn/error.c
@@ -75,6 +75,10 @@ static bool std_redir; /* GLOBAL */
/* Should messages be written to the syslog? */
static bool use_syslog; /* GLOBAL */
+/* Should stdout/stderr be be parsable and always be prefixed with time
+ * and message flags */
+static bool machine_readable_output; /* GLOBAL */
+
/* Should timestamps be included on messages to stdout/stderr? */
static bool suppress_timestamps; /* GLOBAL */
@@ -148,10 +152,17 @@ set_suppress_timestamps (bool suppressed)
}
void
+set_machine_readable_output (bool parsable)
+{
+ machine_readable_output = parsable;
+}
+
+void
error_reset ()
{
use_syslog = std_redir = false;
suppress_timestamps = false;
+ machine_readable_output = false;
x_debug_level = 1;
mute_cutoff = 0;
mute_count = 0;
@@ -301,7 +312,22 @@ void x_msg_va (const unsigned int flags, const char *format, va_list arglist)
FILE *fp = msg_fp(flags);
const bool show_usec = check_debug_level (DEBUG_LEVEL_USEC_TIME);
- if ((flags & M_NOPREFIX) || suppress_timestamps)
+ if (machine_readable_output)
+ {
+ struct timeval tv;
+ gettimeofday (&tv, NULL);
+
+ fprintf (fp, "%lu.%06lu %x %s%s%s%s",
+ tv.tv_sec,
+ (unsigned long)tv.tv_usec,
+ flags,
+ prefix,
+ prefix_sep,
+ m1,
+ "\n");
+
+ }
+ else if ((flags & M_NOPREFIX) || suppress_timestamps)
{
fprintf (fp, "%s%s%s%s",
prefix,
@@ -427,7 +453,7 @@ close_syslog ()
#endif
}
-#ifdef WIN32
+#ifdef _WIN32
static HANDLE orig_stderr;
@@ -445,7 +471,7 @@ get_orig_stderr (void)
void
redirect_stdout_stderr (const char *file, bool append)
{
-#if defined(WIN32)
+#if defined(_WIN32)
if (!std_redir)
{
struct gc_arena gc = gc_new ();
@@ -577,7 +603,7 @@ x_check_status (int status,
const char *extended_msg = NULL;
msg (x_cs_verbose_level, "%s %s returned %d",
- sock ? proto2ascii (sock->info.proto, true) : "",
+ sock ? proto2ascii (sock->info.proto, sock->info.af, true) : "",
description,
status);
@@ -596,7 +622,7 @@ x_check_status (int status,
sock->info.mtu_changed = true;
}
}
-#elif defined(WIN32)
+#elif defined(_WIN32)
/* get possible driver error from TAP-Windows driver */
extended_msg = tap_win_getinfo (tt, &gc);
#endif
@@ -605,14 +631,14 @@ x_check_status (int status,
if (extended_msg)
msg (x_cs_info_level, "%s %s [%s]: %s (code=%d)",
description,
- sock ? proto2ascii (sock->info.proto, true) : "",
+ sock ? proto2ascii (sock->info.proto, sock->info.af, true) : "",
extended_msg,
strerror_ts (my_errno, &gc),
my_errno);
else
msg (x_cs_info_level, "%s %s: %s (code=%d)",
description,
- sock ? proto2ascii (sock->info.proto, true) : "",
+ sock ? proto2ascii (sock->info.proto, sock->info.af, true) : "",
strerror_ts (my_errno, &gc),
my_errno);
@@ -651,7 +677,7 @@ openvpn_exit (const int status)
tun_abort();
-#ifdef WIN32
+#ifdef _WIN32
uninit_win32 ();
#endif
@@ -711,7 +737,7 @@ crash (void)
}
#endif
-#ifdef WIN32
+#ifdef _WIN32
const char *
strerror_win32 (DWORD errnum, struct gc_arena *gc)
diff --git a/src/openvpn/error.h b/src/openvpn/error.h
index 4024e5e..f43bc38 100644
--- a/src/openvpn/error.h
+++ b/src/openvpn/error.h
@@ -27,6 +27,11 @@
#include "basic.h"
+#include <errno.h>
+#include <stdbool.h>
+
+#include <assert.h>
+
/* #define ABORT_ON_ERROR */
#ifdef ENABLE_PKCS11
@@ -66,7 +71,7 @@ struct gc_arena;
/* String and Error functions */
-#ifdef WIN32
+#ifdef _WIN32
# define openvpn_errno() GetLastError()
# define openvpn_strerror(e, gc) strerror_win32(e, gc)
const char *strerror_win32 (DWORD errnum, struct gc_arena *gc);
@@ -138,12 +143,6 @@ extern int x_msg_line_num;
/** Check muting filter */
bool dont_mute (unsigned int flags);
-/** Return true if flags represent an enabled, not muted log level */
-static inline bool msg_test (unsigned int flags)
-{
- return ((flags & M_DEBUG_LEVEL) <= x_debug_level) && dont_mute (flags);
-}
-
/* Macro to ensure (and teach static analysis tools) we exit on fatal errors */
#define EXIT_FATAL(flags) do { if ((flags) & M_FATAL) _exit(1); } while (false)
@@ -197,6 +196,8 @@ void error_reset (void);
void errors_to_stderr (void);
void set_suppress_timestamps (bool suppressed);
+void set_machine_readable_output (bool parsable);
+
#define SDL_CONSTRAIN (1<<0)
bool set_debug_level (const int level, const unsigned int flags);
@@ -223,6 +224,14 @@ FILE *msg_fp(const unsigned int flags);
void assert_failed (const char *filename, int line, const char *condition)
__attribute__((__noreturn__));
+/* Poor-man's static_assert() for when not supplied by assert.h, taken from
+ * Linux's sys/cdefs.h under GPLv2 */
+#ifndef static_assert
+#define static_assert(expr, diagnostic) \
+ extern int (*__OpenVPN_static_assert_function (void)) \
+ [!!sizeof (struct { int __error_if_negative: (expr) ? 2 : -1; })]
+#endif
+
#ifdef ENABLE_DEBUG
void crash (void); /* force a segfault (debugging only) */
#endif
@@ -235,6 +244,12 @@ check_debug_level (unsigned int level)
return (level & M_DEBUG_LEVEL) <= x_debug_level;
}
+/** Return true if flags represent an enabled, not muted log level */
+static inline bool msg_test (unsigned int flags)
+{
+ return check_debug_level (flags) && dont_mute (flags);
+}
+
/* Call if we forked */
void msg_forked (void);
@@ -246,7 +261,7 @@ void close_syslog ();
/* log file output */
void redirect_stdout_stderr (const char *file, bool append);
-#ifdef WIN32
+#ifdef _WIN32
/* get original stderr handle, even if redirected by --log/--log-append */
HANDLE get_orig_stderr (void);
#endif
@@ -341,7 +356,7 @@ static inline bool
ignore_sys_error (const int err)
{
/* I/O operation pending */
-#ifdef WIN32
+#ifdef _WIN32
if (err == WSAEWOULDBLOCK || err == WSAEINVAL)
return true;
#else
diff --git a/src/openvpn/event.c b/src/openvpn/event.c
index c642691..409ad13 100644
--- a/src/openvpn/event.c
+++ b/src/openvpn/event.c
@@ -49,7 +49,7 @@
/*
* All non-windows OSes are assumed to have select()
*/
-#ifdef WIN32
+#ifdef _WIN32
#define SELECT 0
#else
#define SELECT 1
@@ -74,7 +74,7 @@ tv_to_ms_timeout (const struct timeval *tv)
return max_int (tv->tv_sec * 1000 + (tv->tv_usec + 500) / 1000, 1);
}
-#ifdef WIN32
+#ifdef _WIN32
struct we_set
{
@@ -462,7 +462,7 @@ we_init (int *maxevents, unsigned int flags)
return (struct event_set *) wes;
}
-#endif /* WIN32 */
+#endif /* _WIN32 */
#if EPOLL
@@ -1007,7 +1007,7 @@ static struct event_set *
event_set_init_simple (int *maxevents, unsigned int flags)
{
struct event_set *ret = NULL;
-#ifdef WIN32
+#ifdef _WIN32
ret = we_init (maxevents, flags);
#elif POLL && SELECT
#if 0 /* Define to 1 if EVENT_METHOD_US_TIMEOUT should cause select to be favored over poll */
diff --git a/src/openvpn/event.h b/src/openvpn/event.h
index bd29fdc..565343d 100644
--- a/src/openvpn/event.h
+++ b/src/openvpn/event.h
@@ -42,7 +42,7 @@
#define EVENT_METHOD_US_TIMEOUT (1<<0)
#define EVENT_METHOD_FAST (1<<1)
-#ifdef WIN32
+#ifdef _WIN32
typedef const struct rw_handle *event_t;
@@ -137,7 +137,7 @@ event_set_return_init (struct event_set_return *esr)
esr->arg = NULL;
}
-#ifdef WIN32
+#ifdef _WIN32
static inline void
wait_signal (struct event_set *es, void *arg)
diff --git a/src/openvpn/fdmisc.c b/src/openvpn/fdmisc.c
index 7fe449c..ce01319 100644
--- a/src/openvpn/fdmisc.c
+++ b/src/openvpn/fdmisc.c
@@ -39,7 +39,7 @@
bool
set_nonblock_action (int fd)
{
-#ifdef WIN32
+#ifdef _WIN32
u_long arg = 1;
if (ioctlsocket (fd, FIONBIO, &arg))
return false;
@@ -54,7 +54,7 @@ set_nonblock_action (int fd)
bool
set_cloexec_action (int fd)
{
-#ifndef WIN32
+#ifndef _WIN32
if (fcntl (fd, F_SETFD, FD_CLOEXEC) < 0)
return false;
#endif
diff --git a/src/openvpn/fdmisc.h b/src/openvpn/fdmisc.h
index 13d6552..d34db9b 100644
--- a/src/openvpn/fdmisc.h
+++ b/src/openvpn/fdmisc.h
@@ -37,7 +37,7 @@ void set_cloexec (int fd);
static inline void openvpn_fd_set(int fd, fd_set *setp)
{
-#ifndef WIN32 /* The Windows FD_SET() implementation does not overflow */
+#ifndef _WIN32 /* The Windows FD_SET() implementation does not overflow */
ASSERT (fd >= 0 && fd < FD_SETSIZE);
#endif
FD_SET (fd, setp);
diff --git a/src/openvpn/forward-inline.h b/src/openvpn/forward-inline.h
index 5853ce2..5d4e308 100644
--- a/src/openvpn/forward-inline.h
+++ b/src/openvpn/forward-inline.h
@@ -35,7 +35,7 @@
static inline void
check_tls (struct context *c)
{
-#if defined(ENABLE_CRYPTO) && defined(ENABLE_SSL)
+#if defined(ENABLE_CRYPTO)
void check_tls_dowork (struct context *c);
if (c->c2.tls_multi)
check_tls_dowork (c);
@@ -49,7 +49,7 @@ check_tls (struct context *c)
static inline void
check_tls_errors (struct context *c)
{
-#if defined(ENABLE_CRYPTO) && defined(ENABLE_SSL)
+#if defined(ENABLE_CRYPTO)
void check_tls_errors_co (struct context *c);
void check_tls_errors_nco (struct context *c);
if (c->c2.tls_multi && c->c2.tls_exit_signal)
@@ -125,7 +125,7 @@ check_server_poll_timeout (struct context *c)
{
void check_server_poll_timeout_dowork (struct context *c);
- if (c->options.server_poll_timeout
+ if (c->options.ce.connect_timeout
&& event_timeout_trigger (&c->c2.server_poll_interval, &c->c2.timeval, ETT_DEFAULT))
check_server_poll_timeout_dowork (c);
}
diff --git a/src/openvpn/forward.c b/src/openvpn/forward.c
index d55fa3b..b50a2e0 100644
--- a/src/openvpn/forward.c
+++ b/src/openvpn/forward.c
@@ -39,6 +39,7 @@
#include "ps.h"
#include "dhcp.h"
#include "common.h"
+#include "ssl_verify.h"
#include "memdbg.h"
@@ -87,7 +88,7 @@ show_wait_status (struct context *c)
* traffic on the control-channel.
*
*/
-#if defined(ENABLE_CRYPTO) && defined(ENABLE_SSL)
+#ifdef ENABLE_CRYPTO
void
check_tls_dowork (struct context *c)
{
@@ -116,9 +117,6 @@ check_tls_dowork (struct context *c)
if (wakeup)
context_reschedule_sec (c, wakeup);
}
-#endif
-
-#if defined(ENABLE_CRYPTO) && defined(ENABLE_SSL)
void
check_tls_errors_co (struct context *c)
@@ -132,8 +130,7 @@ check_tls_errors_nco (struct context *c)
{
register_signal (c, c->c2.tls_exit_signal, "tls-error"); /* SOFT-SIGUSR1 -- TLS error */
}
-
-#endif
+#endif /* ENABLE_CRYPTO */
#if P2MP
@@ -211,12 +208,14 @@ check_connection_established_dowork (struct context *c)
management_set_state (management,
OPENVPN_STATE_GET_CONFIG,
NULL,
- 0,
- 0);
+ NULL,
+ NULL,
+ NULL,
+ NULL);
}
#endif
- /* send push request in 1 sec */
- event_timeout_init (&c->c2.push_request_interval, 1, now);
+ /* fire up push request right away (already 1s delayed) */
+ event_timeout_init (&c->c2.push_request_interval, 0, now);
reset_coarse_timers (c);
}
else
@@ -238,7 +237,7 @@ check_connection_established_dowork (struct context *c)
bool
send_control_channel_string (struct context *c, const char *str, int msglevel)
{
-#if defined(ENABLE_CRYPTO) && defined(ENABLE_SSL)
+#ifdef ENABLE_CRYPTO
if (c->c2.tls_multi) {
struct gc_arena gc = gc_new ();
bool stat;
@@ -263,7 +262,7 @@ send_control_channel_string (struct context *c, const char *str, int msglevel)
gc_free (&gc);
return stat;
}
-#endif
+#endif /* ENABLE_CRYPTO */
return true;
}
@@ -302,7 +301,7 @@ check_add_routes_dowork (struct context *c)
{
register_signal (c, SIGHUP, "ip-fail");
c->persist.restart_sleep_seconds = 10;
-#ifdef WIN32
+#ifdef _WIN32
show_routes (M_INFO|M_NOPREFIX);
show_adapters (M_INFO|M_NOPREFIX);
#endif
@@ -325,6 +324,13 @@ check_inactivity_timeout_dowork (struct context *c)
register_signal (c, SIGTERM, "inactive");
}
+int
+get_server_poll_remaining_time (struct event_timeout* server_poll_timeout)
+{
+ update_time();
+ int remaining = event_timeout_remaining(server_poll_timeout);
+ return max_int (0, remaining);
+}
#if P2MP
void
@@ -385,7 +391,7 @@ check_fragment_dowork (struct context *c)
struct link_socket_info *lsi = get_link_socket_info (c);
/* OS MTU Hint? */
- if (lsi->mtu_changed && c->c2.ipv4_tun)
+ if (lsi->mtu_changed)
{
frame_adjust_path_mtu (&c->c2.frame_fragment, c->c2.link_socket->mtu,
c->options.ce.proto);
@@ -433,6 +439,7 @@ encrypt_sign (struct context *c, bool comp_frag)
{
struct context_buffers *b = c->c2.buffers;
const uint8_t *orig_buf = c->c2.buf.data;
+ struct crypto_options *co = NULL;
#if P2MP_SERVER
/*
@@ -445,10 +452,10 @@ encrypt_sign (struct context *c, bool comp_frag)
if (comp_frag)
{
-#ifdef ENABLE_LZO
+#ifdef USE_COMP
/* Compress the packet. */
- if (lzo_defined (&c->c2.lzo_compwork))
- lzo_compress (&c->c2.buf, b->lzo_compress_buf, &c->c2.lzo_compwork, &c->c2.frame);
+ if (c->c2.comp_context)
+ (*c->c2.comp_context->alg.compress)(&c->c2.buf, b->compress_buf, c->c2.comp_context, &c->c2.frame);
#endif
#ifdef ENABLE_FRAGMENT
if (c->c2.fragment)
@@ -457,43 +464,41 @@ encrypt_sign (struct context *c, bool comp_frag)
}
#ifdef ENABLE_CRYPTO
-#ifdef ENABLE_SSL
- /*
- * If TLS mode, get the key we will use to encrypt
- * the packet.
- */
+ /* initialize work buffer with FRAME_HEADROOM bytes of prepend capacity */
+ ASSERT (buf_init (&b->encrypt_buf, FRAME_HEADROOM (&c->c2.frame)));
+
if (c->c2.tls_multi)
{
- tls_pre_encrypt (c->c2.tls_multi, &c->c2.buf, &c->c2.crypto_options);
+ /* Get the key we will use to encrypt the packet. */
+ tls_pre_encrypt (c->c2.tls_multi, &c->c2.buf, &co);
+ /* If using P_DATA_V2, prepend the 1-byte opcode and 3-byte peer-id to the
+ * packet before openvpn_encrypt(), so we can authenticate the opcode too.
+ */
+ if (c->c2.buf.len > 0 && !c->c2.tls_multi->opt.server && c->c2.tls_multi->use_peer_id)
+ tls_prepend_opcode_v2 (c->c2.tls_multi, &b->encrypt_buf);
+ }
+ else
+ {
+ co = &c->c2.crypto_options;
}
-#endif
- /*
- * Encrypt the packet and write an optional
- * HMAC signature.
- */
- openvpn_encrypt (&c->c2.buf, b->encrypt_buf, &c->c2.crypto_options, &c->c2.frame);
+ /* Encrypt and authenticate the packet */
+ openvpn_encrypt (&c->c2.buf, b->encrypt_buf, co);
+
+ /* Do packet administration */
+ if (c->c2.tls_multi)
+ {
+ if (c->c2.buf.len > 0 && (c->c2.tls_multi->opt.server || !c->c2.tls_multi->use_peer_id))
+ tls_prepend_opcode_v1(c->c2.tls_multi, &c->c2.buf);
+ tls_post_encrypt (c->c2.tls_multi, &c->c2.buf);
+ }
#endif
+
/*
* Get the address we will be sending the packet to.
*/
link_socket_get_outgoing_addr (&c->c2.buf, get_link_socket_info (c),
&c->c2.to_link_addr);
-#ifdef ENABLE_CRYPTO
-#ifdef ENABLE_SSL
- /*
- * In TLS mode, prepend the appropriate one-byte opcode
- * to the packet which identifies it as a data channel
- * packet and gives the low-permutation version of
- * the key-id to the recipient so it knows which
- * decrypt key to use.
- */
- if (c->c2.tls_multi)
- {
- tls_post_encrypt (c->c2.tls_multi, &c->c2.buf);
- }
-#endif
-#endif
/* if null encryption, copy result to read_tun_buf */
buffer_turnover (orig_buf, &c->c2.to_link, &c->c2.buf, &b->read_tun_buf);
@@ -540,13 +545,16 @@ process_coarse_timers (struct context *c)
return;
#if P2MP
- check_server_poll_timeout (c);
- if (c->sig->signal_received)
- return;
+ if (c->c2.tls_multi)
+ {
+ check_server_poll_timeout (c);
+ if (c->sig->signal_received)
+ return;
- check_scheduled_exit (c);
- if (c->sig->signal_received)
- return;
+ check_scheduled_exit (c);
+ if (c->sig->signal_received)
+ return;
+ }
#endif
#ifdef ENABLE_OCC
@@ -611,8 +619,6 @@ check_timeout_random_component (struct context *c)
tv_add (&c->c2.timeval, &c->c2.timeout_random_component);
}
-#ifdef ENABLE_SOCKS
-
/*
* Handle addition and removal of the 10-byte Socks5 header
* in UDP packets.
@@ -621,7 +627,7 @@ check_timeout_random_component (struct context *c)
static inline void
socks_postprocess_incoming_link (struct context *c)
{
- if (c->c2.link_socket->socks_proxy && c->c2.link_socket->info.proto == PROTO_UDPv4)
+ if (c->c2.link_socket->socks_proxy && c->c2.link_socket->info.proto == PROTO_UDP)
socks_process_incoming_udp (&c->c2.buf, &c->c2.from);
}
@@ -630,7 +636,7 @@ socks_preprocess_outgoing_link (struct context *c,
struct link_socket_actual **to_addr,
int *size_delta)
{
- if (c->c2.link_socket->socks_proxy && c->c2.link_socket->info.proto == PROTO_UDPv4)
+ if (c->c2.link_socket->socks_proxy && c->c2.link_socket->info.proto == PROTO_UDP)
{
*size_delta += socks_process_outgoing_udp (&c->c2.to_link, c->c2.to_link_addr);
*to_addr = &c->c2.link_socket->socks_relay;
@@ -650,7 +656,6 @@ link_socket_write_post_size_adjust (int *size,
*size = 0;
}
}
-#endif
/*
* Output: c->c2.buf
@@ -674,7 +679,6 @@ read_incoming_link (struct context *c)
status = link_socket_read (c->c2.link_socket,
&c->c2.buf,
- MAX_RW_SIZE_LINK (&c->c2.frame),
&c->c2.from);
if (socket_connection_reset (c->c2.link_socket, status))
@@ -719,28 +723,17 @@ read_incoming_link (struct context *c)
/* check recvfrom status */
check_status (status, "read", c->c2.link_socket, NULL);
-#ifdef ENABLE_SOCKS
/* Remove socks header if applicable */
socks_postprocess_incoming_link (c);
-#endif
perf_pop ();
}
-/*
- * Input: c->c2.buf
- * Output: c->c2.to_tun
- */
-
-void
-process_incoming_link (struct context *c)
+bool
+process_incoming_link_part1 (struct context *c, struct link_socket_info *lsi, bool floated)
{
struct gc_arena gc = gc_new ();
- bool decrypt_status;
- struct link_socket_info *lsi = get_link_socket_info (c);
- const uint8_t *orig_buf = c->c2.buf.data;
-
- perf_push (PERF_PROC_IN_LINK);
+ bool decrypt_status = false;
if (c->c2.buf.len > 0)
{
@@ -779,7 +772,7 @@ process_incoming_link (struct context *c)
fprintf (stderr, "R");
#endif
msg (D_LINK_RW, "%s READ [%d] from %s: %s",
- proto2ascii (lsi->proto, true),
+ proto2ascii (lsi->proto, lsi->af, true),
BLEN (&c->c2.buf),
print_link_socket_actual (&c->c2.from, &gc),
PROTO_DUMP (&c->c2.buf, &gc));
@@ -793,11 +786,12 @@ process_incoming_link (struct context *c)
*/
if (c->c2.buf.len > 0)
{
+ struct crypto_options *co = NULL;
+ const uint8_t *ad_start = NULL;
if (!link_socket_verify_incoming_addr (&c->c2.buf, lsi, &c->c2.from))
link_socket_bad_incoming_addr (&c->c2.buf, lsi, &c->c2.from);
#ifdef ENABLE_CRYPTO
-#ifdef ENABLE_SSL
if (c->c2.tls_multi)
{
/*
@@ -810,7 +804,8 @@ process_incoming_link (struct context *c)
* will load crypto_options with the correct encryption key
* and return false.
*/
- if (tls_pre_decrypt (c->c2.tls_multi, &c->c2.from, &c->c2.buf, &c->c2.crypto_options))
+ if (tls_pre_decrypt (c->c2.tls_multi, &c->c2.from, &c->c2.buf, &co,
+ floated, &ad_start))
{
interval_action (&c->c2.tmp_int);
@@ -819,6 +814,10 @@ process_incoming_link (struct context *c)
event_timeout_reset (&c->c2.ping_rec_interval);
}
}
+ else
+ {
+ co = &c->c2.crypto_options;
+ }
#if P2MP_SERVER
/*
* Drop non-TLS packet if client-connect script/plugin has not
@@ -827,30 +826,44 @@ process_incoming_link (struct context *c)
if (c->c2.context_auth != CAS_SUCCEEDED)
c->c2.buf.len = 0;
#endif
-#endif /* ENABLE_SSL */
/* authenticate and decrypt the incoming packet */
- decrypt_status = openvpn_decrypt (&c->c2.buf, c->c2.buffers->decrypt_buf, &c->c2.crypto_options, &c->c2.frame);
+ decrypt_status = openvpn_decrypt (&c->c2.buf, c->c2.buffers->decrypt_buf,
+ co, &c->c2.frame, ad_start);
if (!decrypt_status && link_socket_connection_oriented (c->c2.link_socket))
{
/* decryption errors are fatal in TCP mode */
register_signal (c, SIGUSR1, "decryption-error"); /* SOFT-SIGUSR1 -- decryption error in TCP mode */
msg (D_STREAM_ERRORS, "Fatal decryption error (process_incoming_link), restarting");
- goto done;
}
-
+#else /* ENABLE_CRYPTO */
+ decrypt_status = true;
#endif /* ENABLE_CRYPTO */
+ }
+ else
+ {
+ buf_reset (&c->c2.to_tun);
+ }
+ gc_free (&gc);
+
+ return decrypt_status;
+}
+void
+process_incoming_link_part2 (struct context *c, struct link_socket_info *lsi, const uint8_t *orig_buf)
+{
+ if (c->c2.buf.len > 0)
+ {
#ifdef ENABLE_FRAGMENT
if (c->c2.fragment)
fragment_incoming (c->c2.fragment, &c->c2.buf, &c->c2.frame_fragment);
#endif
-#ifdef ENABLE_LZO
+#ifdef USE_COMP
/* decompress the incoming packet */
- if (lzo_defined (&c->c2.lzo_compwork))
- lzo_decompress (&c->c2.buf, c->c2.buffers->lzo_decompress_buf, &c->c2.lzo_compwork, &c->c2.frame);
+ if (c->c2.comp_context)
+ (*c->c2.comp_context->alg.decompress)(&c->c2.buf, c->c2.buffers->decompress_buf, c->c2.comp_context, &c->c2.frame);
#endif
#ifdef PACKET_TRUNCATION_CHECK
@@ -908,9 +921,20 @@ process_incoming_link (struct context *c)
{
buf_reset (&c->c2.to_tun);
}
- done:
+}
+
+void
+process_incoming_link (struct context *c)
+{
+ perf_push (PERF_PROC_IN_LINK);
+
+ struct link_socket_info *lsi = get_link_socket_info (c);
+ const uint8_t *orig_buf = c->c2.buf.data;
+
+ process_incoming_link_part1(c, lsi, false);
+ process_incoming_link_part2(c, lsi, orig_buf);
+
perf_pop ();
- gc_free (&gc);
}
/*
@@ -969,6 +993,76 @@ read_incoming_tun (struct context *c)
perf_pop ();
}
+/**
+ * Drops UDP packets which OS decided to route via tun.
+ *
+ * On Windows and OS X when netwotk adapter is disabled or
+ * disconnected, platform starts to use tun as external interface.
+ * When packet is sent to tun, it comes to openvpn, encapsulated
+ * and sent to routing table, which sends it again to tun.
+ */
+static void
+drop_if_recursive_routing (struct context *c, struct buffer *buf)
+{
+ bool drop = false;
+ struct openvpn_sockaddr tun_sa;
+ int ip_hdr_offset = 0;
+
+ if (c->c2.to_link_addr == NULL) /* no remote addr known */
+ return;
+
+ tun_sa = c->c2.to_link_addr->dest;
+
+ int proto_ver = get_tun_ip_ver (TUNNEL_TYPE (c->c1.tuntap), &c->c2.buf, &ip_hdr_offset);
+
+ if (proto_ver == 4)
+ {
+ const struct openvpn_iphdr *pip;
+
+ /* make sure we got whole IP header */
+ if (BLEN (buf) < ((int) sizeof (struct openvpn_iphdr) + ip_hdr_offset))
+ return;
+
+ /* skip ipv4 packets for ipv6 tun */
+ if (tun_sa.addr.sa.sa_family != AF_INET)
+ return;
+
+ pip = (struct openvpn_iphdr *) (BPTR (buf) + ip_hdr_offset);
+
+ /* drop packets with same dest addr as gateway */
+ if (tun_sa.addr.in4.sin_addr.s_addr == pip->daddr)
+ drop = true;
+ }
+ else if (proto_ver == 6)
+ {
+ const struct openvpn_ipv6hdr *pip6;
+
+ /* make sure we got whole IPv6 header */
+ if (BLEN (buf) < ((int) sizeof (struct openvpn_ipv6hdr) + ip_hdr_offset))
+ return;
+
+ /* skip ipv6 packets for ipv4 tun */
+ if (tun_sa.addr.sa.sa_family != AF_INET6)
+ return;
+
+ /* drop packets with same dest addr as gateway */
+ pip6 = (struct openvpn_ipv6hdr *) (BPTR (buf) + ip_hdr_offset);
+ if (IN6_ARE_ADDR_EQUAL(&tun_sa.addr.in6.sin6_addr, &pip6->daddr))
+ drop = true;
+ }
+
+ if (drop)
+ {
+ struct gc_arena gc = gc_new ();
+
+ c->c2.buf.len = 0;
+
+ msg(D_LOW, "Recursive routing detected, drop tun packet to %s",
+ print_link_socket_actual(c->c2.to_link_addr, &gc));
+ gc_free (&gc);
+ }
+}
+
/*
* Input: c->c2.buf
* Output: c->c2.to_link
@@ -994,6 +1088,8 @@ process_incoming_tun (struct context *c)
if (c->c2.buf.len > 0)
{
+ if ((c->options.mode == MODE_POINT_TO_POINT) && (!c->options.allow_recursive_routing))
+ drop_if_recursive_routing (c, &c->c2.buf);
/*
* The --passtos and --mssfix options require
* us to examine the IP header (IPv4 or IPv6).
@@ -1028,6 +1124,8 @@ process_ip_header (struct context *c, unsigned int flags, struct buffer *buf)
if (!c->options.passtos)
flags &= ~PIPV4_PASSTOS;
#endif
+ if (!c->options.client_nat)
+ flags &= ~PIPV4_CLIENT_NAT;
if (!c->options.route_gateway_via_dhcp)
flags &= ~PIPV4_EXTRACT_DHCP_ROUTER;
@@ -1037,11 +1135,13 @@ process_ip_header (struct context *c, unsigned int flags, struct buffer *buf)
* The --passtos and --mssfix options require
* us to examine the IPv4 header.
*/
+
+ if (flags & (PIP_MSSFIX
#if PASSTOS_CAPABILITY
- if (flags & (PIPV4_PASSTOS|PIP_MSSFIX))
-#else
- if (flags & PIP_MSSFIX)
+ | PIPV4_PASSTOS
#endif
+ | PIPV4_CLIENT_NAT
+ ))
{
struct buffer ipbuf = *buf;
if (is_ipv4 (TUNNEL_TYPE (c->c1.tuntap), &ipbuf))
@@ -1056,14 +1156,12 @@ process_ip_header (struct context *c, unsigned int flags, struct buffer *buf)
if (flags & PIP_MSSFIX)
mss_fixup_ipv4 (&ipbuf, MTU_TO_MSS (TUN_MTU_SIZE_DYNAMIC (&c->c2.frame)));
-#ifdef ENABLE_CLIENT_NAT
/* possibly do NAT on packet */
if ((flags & PIPV4_CLIENT_NAT) && c->options.client_nat)
{
const int direction = (flags & PIPV4_OUTGOING) ? CN_INCOMING : CN_OUTGOING;
client_nat_transform (c->options.client_nat, &ipbuf, direction);
}
-#endif
/* possibly extract a DHCP router message */
if (flags & PIPV4_EXTRACT_DHCP_ROUTER)
{
@@ -1090,6 +1188,7 @@ void
process_outgoing_link (struct context *c)
{
struct gc_arena gc = gc_new ();
+ int error_code = 0;
perf_push (PERF_PROC_OUT_LINK);
@@ -1133,7 +1232,7 @@ process_outgoing_link (struct context *c)
fprintf (stderr, "W");
#endif
msg (D_LINK_RW, "%s WRITE [%d] to %s: %s",
- proto2ascii (c->c2.link_socket->info.proto, true),
+ proto2ascii (c->c2.link_socket->info.proto, c->c2.link_socket->info.af, true),
BLEN (&c->c2.to_link),
print_link_socket_actual (c->c2.to_link_addr, &gc),
PROTO_DUMP (&c->c2.to_link, &gc));
@@ -1141,23 +1240,18 @@ process_outgoing_link (struct context *c)
/* Packet send complexified by possible Socks5 usage */
{
struct link_socket_actual *to_addr = c->c2.to_link_addr;
-#ifdef ENABLE_SOCKS
int size_delta = 0;
-#endif
-#ifdef ENABLE_SOCKS
/* If Socks5 over UDP, prepend header */
socks_preprocess_outgoing_link (c, &to_addr, &size_delta);
-#endif
+
/* Send packet */
size = link_socket_write (c->c2.link_socket,
&c->c2.to_link,
to_addr);
-#ifdef ENABLE_SOCKS
/* Undo effect of prepend */
link_socket_write_post_size_adjust (&size, size_delta, &c->c2.to_link);
-#endif
}
if (size > 0)
@@ -1182,6 +1276,7 @@ process_outgoing_link (struct context *c)
}
/* Check return status */
+ error_code = openvpn_errno();
check_status (size, "write", c->c2.link_socket, NULL);
if (size > 0)
@@ -1198,6 +1293,17 @@ process_outgoing_link (struct context *c)
/* if not a ping/control message, indicate activity regarding --inactive parameter */
if (c->c2.buf.len > 0 )
register_activity (c, size);
+
+
+#ifdef ENABLE_CRYPTO
+ /* for unreachable network and "connecting" state switch to the next host */
+ if (size < 0 && ENETUNREACH == error_code && c->c2.tls_multi &&
+ !tls_initial_packet_received (c->c2.tls_multi) && c->options.mode == MODE_POINT_TO_POINT)
+ {
+ msg (M_INFO, "Network unreachable, restarting");
+ register_signal (c, SIGUSR1, "network-unreachable");
+ }
+#endif
}
else
{
@@ -1314,7 +1420,7 @@ pre_select (struct context *c)
c->c2.timeval.tv_sec = BIG_TIMEOUT;
c->c2.timeval.tv_usec = 0;
-#if defined(WIN32)
+#if defined(_WIN32)
if (check_debug_level (D_TAP_WIN_DEBUG))
{
c->c2.timeval.tv_sec = 1;
@@ -1373,6 +1479,9 @@ io_wait_dowork (struct context *c, const unsigned int flags)
#ifdef ENABLE_MANAGEMENT
static int management_shift = 6; /* depends on MANAGEMENT_READ and MANAGEMENT_WRITE */
#endif
+#ifdef ENABLE_ASYNC_PUSH
+ static int file_shift = 8; /* listening inotify events */
+#endif
/*
* Decide what kind of events we want to wait for.
@@ -1467,6 +1576,11 @@ io_wait_dowork (struct context *c, const unsigned int flags)
management_socket_set (management, c->c2.event_set, (void*)&management_shift, NULL);
#endif
+#ifdef ENABLE_ASYNC_PUSH
+ /* arm inotify watcher */
+ event_ctl (c->c2.event_set, c->c2.inotify_fd, EVENT_READ, (void*)&file_shift);
+#endif
+
/*
* Possible scenarios:
* (1) tcp/udp port has data available to read
diff --git a/src/openvpn/forward.h b/src/openvpn/forward.h
index 1830a00..0856aa7 100644
--- a/src/openvpn/forward.h
+++ b/src/openvpn/forward.h
@@ -103,7 +103,7 @@ void show_wait_status (struct context *c);
* once for each remaining fragment with this parameter set to false.
*/
void encrypt_sign (struct context *c, bool comp_frag);
-
+int get_server_poll_remaining_time (struct event_timeout* server_poll_timeout);
/**********************************************************************/
/**
@@ -127,12 +127,11 @@ void encrypt_sign (struct context *c, bool comp_frag);
*/
void read_incoming_link (struct context *c);
-
/**
- * Process a packet read from the external network interface.
+ * Starts processing a packet read from the external network interface.
* @ingroup external_multiplexer
*
- * This function controls the processing of a data channel packet which
+ * This function starts the processing of a data channel packet which
* has come out of a VPN tunnel. It's high-level structure is as follows:
* - Verify that a nonzero length packet has been received from a valid
* source address for the given context \a c.
@@ -146,6 +145,25 @@ void read_incoming_link (struct context *c);
* - Call \c openvpn_decrypt() of the \link data_crypto Data Channel
* Crypto module\endlink to authenticate and decrypt the packet using
* the security parameters loaded by \c tls_pre_decrypt() above.
+ *
+ * @param c - The context structure of the VPN tunnel associated with the
+ * packet.
+ * @param lsi - link_socket_info obtained from context before processing.
+ * @param floated - Flag indicates that peer has floated.
+ *
+ * @return true if packet is authenticated, false otherwise.
+ */
+bool process_incoming_link_part1 (struct context *c, struct link_socket_info *lsi, bool floated);
+
+/**
+ * Continues processing a packet read from the external network interface.
+ * @ingroup external_multiplexer
+ *
+ * This function continues the processing of a data channel packet which
+ * has come out of a VPN tunnel. It must be called after
+ * \c process_incoming_link_part1() function.
+ *
+ * It's high-level structure is as follows:
* - Call \c fragment_incoming() of the \link fragmentation Data Channel
* Fragmentation module\endlink to reassemble the packet if it's
* fragmented.
@@ -158,9 +176,11 @@ void read_incoming_link (struct context *c);
*
* @param c - The context structure of the VPN tunnel associated with the
* packet.
+ * @param lsi - link_socket_info obtained from context before processing.
+ * @param orig_buf - Pointer to a buffer data.
+ *
*/
-void process_incoming_link (struct context *c);
-
+void process_incoming_link_part2 (struct context *c, struct link_socket_info *lsi, const uint8_t *orig_buf);
/**
* Write a packet to the external network interface.
diff --git a/src/openvpn/helper.c b/src/openvpn/helper.c
index 62f88ec..229523d 100644
--- a/src/openvpn/helper.c
+++ b/src/openvpn/helper.c
@@ -200,8 +200,6 @@ helper_client_server (struct options *o)
add_in6_addr( o->server_network_ipv6, 0x1000 );
o->ifconfig_ipv6_pool_netbits = o->server_netbits_ipv6;
- o->tun_ipv6 = true;
-
push_option( o, "tun-ipv6", M_USAGE );
}
diff --git a/src/openvpn/init.c b/src/openvpn/init.c
index 2148777..470dc89 100644
--- a/src/openvpn/init.c
+++ b/src/openvpn/init.c
@@ -43,6 +43,9 @@
#include "lladdr.h"
#include "ping.h"
#include "mstats.h"
+#include "ssl_verify.h"
+#include "tls_crypt.h"
+#include "forward-inline.h"
#include "memdbg.h"
@@ -125,42 +128,25 @@ management_callback_proxy_cmd (void *arg, const char **p)
ret = true;
else if (p[2] && p[3])
{
- const int port = atoi(p[3]);
- if (!legal_ipv4_port (port))
- {
- msg (M_WARN, "Bad proxy port number: %s", p[3]);
- return false;
- }
-
if (streq (p[1], "HTTP"))
{
-#ifndef ENABLE_HTTP_PROXY
- msg (M_WARN, "HTTP proxy support is not available");
-#else
struct http_proxy_options *ho;
- if (ce->proto != PROTO_TCPv4 && ce->proto != PROTO_TCPv4_CLIENT &&
- ce->proto != PROTO_TCPv6 && ce->proto != PROTO_TCPv6_CLIENT)
+ if (ce->proto != PROTO_TCP && ce->proto != PROTO_TCP_CLIENT )
{
msg (M_WARN, "HTTP proxy support only works for TCP based connections");
return false;
}
ho = init_http_proxy_options_once (&ce->http_proxy_options, gc);
ho->server = string_alloc (p[2], gc);
- ho->port = port;
- ho->retry = true;
+ ho->port = string_alloc (p[3], gc);
ho->auth_retry = (p[4] && streq (p[4], "nct") ? PAR_NCT : PAR_ALL);
ret = true;
-#endif
}
else if (streq (p[1], "SOCKS"))
{
-#ifndef ENABLE_SOCKS
- msg (M_WARN, "SOCKS proxy support is not available");
-#else
ce->socks_proxy_server = string_alloc (p[2], gc);
- ce->socks_proxy_port = port;
+ ce->socks_proxy_port = p[3];
ret = true;
-#endif
}
}
else
@@ -227,8 +213,7 @@ management_callback_remote_cmd (void *arg, const char **p)
}
else if (!strcmp(p[1], "MOD") && p[2] && p[3])
{
- const int port = atoi(p[3]);
- if (strlen(p[2]) < RH_HOST_LEN && legal_ipv4_port(port))
+ if (strlen(p[2]) < RH_HOST_LEN && strlen(p[3]) < RH_PORT_LEN)
{
struct remote_host_store *rhs = c->options.rh_store;
if (!rhs)
@@ -237,8 +222,10 @@ management_callback_remote_cmd (void *arg, const char **p)
c->options.rh_store = rhs;
}
strncpynt(rhs->host, p[2], RH_HOST_LEN);
+ strncpynt(rhs->port, p[3], RH_PORT_LEN);
+
ce->remote = rhs->host;
- ce->remote_port = port;
+ ce->remote_port = rhs->port;
flags = CE_MAN_QUERY_REMOTE_MOD;
ret = true;
}
@@ -253,7 +240,7 @@ management_callback_remote_cmd (void *arg, const char **p)
}
static bool
-ce_management_query_remote (struct context *c, const char *remote_ip_hint)
+ce_management_query_remote (struct context *c)
{
struct gc_arena gc = gc_new ();
volatile struct connection_entry *ce = &c->options.ce;
@@ -262,7 +249,7 @@ ce_management_query_remote (struct context *c, const char *remote_ip_hint)
if (management)
{
struct buffer out = alloc_buf_gc (256, &gc);
- buf_printf (&out, ">REMOTE:%s,%d,%s", np(ce->remote), ce->remote_port, proto2ascii(ce->proto, false));
+ buf_printf (&out, ">REMOTE:%s,%s,%s", np(ce->remote), ce->remote_port, proto2ascii(ce->proto, ce->af, false));
management_notify_generic(management, BSTR (&out));
ce->flags &= ~(CE_MAN_QUERY_REMOTE_MASK<<CE_MAN_QUERY_REMOTE_SHIFT);
ce->flags |= (CE_MAN_QUERY_REMOTE_QUERY<<CE_MAN_QUERY_REMOTE_SHIFT);
@@ -278,8 +265,6 @@ ce_management_query_remote (struct context *c, const char *remote_ip_hint)
}
{
const int flags = ((ce->flags>>CE_MAN_QUERY_REMOTE_SHIFT) & CE_MAN_QUERY_REMOTE_MASK);
- if (flags == CE_MAN_QUERY_REMOTE_ACCEPT && remote_ip_hint)
- ce->remote = remote_ip_hint;
ret = (flags != CE_MAN_QUERY_REMOTE_SKIP);
}
gc_free (&gc);
@@ -294,95 +279,129 @@ static void
init_connection_list (struct context *c)
{
struct connection_list *l = c->options.connection_list;
- if (l)
+
+ l->current = -1;
+ if (c->options.remote_random)
{
- l->current = -1;
- if (c->options.remote_random)
- {
- int i;
- for (i = 0; i < l->len; ++i)
- {
- const int j = get_random () % l->len;
- if (i != j)
- {
- struct connection_entry *tmp;
- tmp = l->array[i];
- l->array[i] = l->array[j];
- l->array[j] = tmp;
- }
- }
- }
+ int i;
+ for (i = 0; i < l->len; ++i)
+ {
+ const int j = get_random () % l->len;
+ if (i != j)
+ {
+ struct connection_entry *tmp;
+ tmp = l->array[i];
+ l->array[i] = l->array[j];
+ l->array[j] = tmp;
+ }
+ }
}
}
/*
+ * Clear the remote address list
+ */
+static void clear_remote_addrlist (struct link_socket_addr *lsa, bool free)
+{
+ if (lsa->remote_list && free)
+ freeaddrinfo(lsa->remote_list);
+ lsa->remote_list = NULL;
+ lsa->current_remote = NULL;
+}
+
+/*
* Increment to next connection entry
*/
static void
next_connection_entry (struct context *c)
{
struct connection_list *l = c->options.connection_list;
- if (l)
- {
- bool ce_defined;
- struct connection_entry *ce;
- int n_cycles = 0;
-
- do {
- const char *remote_ip_hint = NULL;
- bool newcycle = false;
+ bool ce_defined;
+ struct connection_entry *ce;
+ int n_cycles = 0;
- ce_defined = true;
- if (l->no_advance && l->current >= 0)
- {
- l->no_advance = false;
- }
- else
- {
- if (++l->current >= l->len)
+ do {
+ ce_defined = true;
+ if (c->options.no_advance && l->current >= 0)
+ {
+ c->options.no_advance = false;
+ }
+ else
+ {
+ /* Check if there is another resolved address to try for
+ * the current connection */
+ if (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;
+ }
+ else
+ {
+ /* FIXME (schwabe) fix the persist-remote-ip option for real,
+ * this is broken probably ever since connection lists and multiple
+ * remote existed
+ */
+ if (!c->options.persist_remote_ip)
{
- l->current = 0;
- ++l->n_cycles;
- if (++n_cycles >= 2)
- msg (M_FATAL, "No usable connection profiles are present");
+ /* 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);
}
+ else
+ c->c1.link_socket_addr.current_remote =
+ c->c1.link_socket_addr.remote_list;
- if (l->current == 0)
- newcycle = true;
- }
+ /*
+ * Increase the number of connection attempts
+ * If this is connect-retry-max * size(l)
+ * OpenVPN will quit
+ */
- ce = l->array[l->current];
+ c->options.unsuccessful_attempts++;
- if (c->options.remote_ip_hint && !l->n_cycles)
- remote_ip_hint = c->options.remote_ip_hint;
+ if (++l->current >= l->len)
+ {
- if (ce->flags & CE_DISABLED)
- ce_defined = false;
+ l->current = 0;
+ if (++n_cycles >= 2)
+ msg (M_FATAL, "No usable connection profiles are present");
+ }
+ }
+ }
+
+ ce = l->array[l->current];
- c->options.ce = *ce;
+ if (ce->flags & CE_DISABLED)
+ ce_defined = false;
+
+ c->options.ce = *ce;
#ifdef ENABLE_MANAGEMENT
- if (ce_defined && management && management_query_remote_enabled(management))
- {
- /* allow management interface to override connection entry details */
- ce_defined = ce_management_query_remote(c, remote_ip_hint);
- if (IS_SIG (c))
- break;
- }
- else
+ if (ce_defined && management && management_query_remote_enabled(management))
+ {
+ /* allow management interface to override connection entry details */
+ ce_defined = ce_management_query_remote(c);
+ if (IS_SIG (c))
+ break;
+ }
+ else
#endif
- if (remote_ip_hint)
- c->options.ce.remote = remote_ip_hint;
#ifdef ENABLE_MANAGEMENT
- if (ce_defined && management && management_query_proxy_enabled (management))
- {
- ce_defined = ce_management_query_proxy (c);
- if (IS_SIG (c))
- break;
- }
+ if (ce_defined && management && management_query_proxy_enabled (management))
+ {
+ ce_defined = ce_management_query_proxy (c);
+ if (IS_SIG (c))
+ break;
+ }
#endif
- } while (!ce_defined);
- }
+ } while (!ce_defined);
+
+ /* Check if this connection attempt would bring us over the limit */
+ if (c->options.connect_retry_max > 0 &&
+ c->options.unsuccessful_attempts > (l->len * c->options.connect_retry_max))
+ msg(M_FATAL, "All connections have been connect-retry-max (%d) times unsuccessful, exiting",
+ c->options.connect_retry_max);
update_options_ce_post (&c->options);
}
@@ -392,7 +411,7 @@ next_connection_entry (struct context *c)
void
init_query_passwords (const struct context *c)
{
-#if defined(ENABLE_CRYPTO) && defined(ENABLE_SSL)
+#ifdef ENABLE_CRYPTO
/* Certificate password input */
if (c->options.key_pass_file)
pem_password_setup (c->options.key_pass_file);
@@ -415,47 +434,30 @@ init_query_passwords (const struct context *c)
* Initialize/Uninitialize HTTP or SOCKS proxy
*/
-#ifdef GENERAL_PROXY_SUPPORT
-
-static int
-proxy_scope (struct context *c)
-{
- return connection_list_defined (&c->options) ? 2 : 1;
-}
-
static void
uninit_proxy_dowork (struct context *c)
{
-#ifdef ENABLE_HTTP_PROXY
if (c->c1.http_proxy_owned && c->c1.http_proxy)
{
http_proxy_close (c->c1.http_proxy);
c->c1.http_proxy = NULL;
c->c1.http_proxy_owned = false;
}
-#endif
-#ifdef ENABLE_SOCKS
if (c->c1.socks_proxy_owned && c->c1.socks_proxy)
{
socks_proxy_close (c->c1.socks_proxy);
c->c1.socks_proxy = NULL;
c->c1.socks_proxy_owned = false;
}
-#endif
}
static void
init_proxy_dowork (struct context *c)
{
-#ifdef ENABLE_HTTP_PROXY
bool did_http = false;
-#else
- const bool did_http = false;
-#endif
uninit_proxy_dowork (c);
-#ifdef ENABLE_HTTP_PROXY
if (c->options.ce.http_proxy_options)
{
/* Possible HTTP proxy user/pass input */
@@ -466,51 +468,31 @@ init_proxy_dowork (struct context *c)
c->c1.http_proxy_owned = true;
}
}
-#endif
-#ifdef ENABLE_SOCKS
- if (!did_http && c->options.ce.socks_proxy_server)
+ if (!did_http && c->options.ce.socks_proxy_server)
{
c->c1.socks_proxy = socks_proxy_new (c->options.ce.socks_proxy_server,
c->options.ce.socks_proxy_port,
- c->options.ce.socks_proxy_authfile,
- c->options.ce.socks_proxy_retry);
+ c->options.ce.socks_proxy_authfile);
if (c->c1.socks_proxy)
{
c->c1.socks_proxy_owned = true;
}
}
-#endif
}
static void
-init_proxy (struct context *c, const int scope)
+init_proxy (struct context *c)
{
- if (scope == proxy_scope (c))
- init_proxy_dowork (c);
+ init_proxy_dowork (c);
}
static void
uninit_proxy (struct context *c)
{
- if (c->sig->signal_received != SIGUSR1 || proxy_scope (c) == 2)
- uninit_proxy_dowork (c);
-}
-
-#else
-
-static inline void
-init_proxy (struct context *c, const int scope)
-{
-}
-
-static inline void
-uninit_proxy (struct context *c)
-{
+ uninit_proxy_dowork (c);
}
-#endif
-
void
context_init_1 (struct context *c)
{
@@ -544,8 +526,6 @@ context_init_1 (struct context *c)
}
#endif
- /* initialize HTTP or SOCKS proxy object at scope level 1 */
- init_proxy (c, 1);
}
void
@@ -598,7 +578,7 @@ init_static (void)
error_reset (); /* initialize error.c */
reset_check_status (); /* initialize status check code in socket.c */
-#ifdef WIN32
+#ifdef _WIN32
init_win32 ();
#endif
@@ -659,8 +639,10 @@ init_static (void)
#ifdef TEST_GET_DEFAULT_GATEWAY
{
struct route_gateway_info rgi;
+ struct route_ipv6_gateway_info rgi6;
get_default_gateway(&rgi);
- print_default_gateway(M_INFO, &rgi);
+ get_default_gateway_ipv6(&rgi6, NULL);
+ print_default_gateway(M_INFO, &rgi, &rgi6);
return false;
}
#endif
@@ -810,7 +792,7 @@ uninit_static (void)
close_port_share ();
#endif
-#if defined(MEASURE_TLS_HANDSHAKE_STATS) && defined(ENABLE_CRYPTO) && defined(ENABLE_SSL)
+#if defined(MEASURE_TLS_HANDSHAKE_STATS) && defined(ENABLE_CRYPTO)
show_tls_performance_stats ();
#endif
}
@@ -853,10 +835,7 @@ print_openssl_info (const struct options *options)
*/
#ifdef ENABLE_CRYPTO
if (options->show_ciphers || options->show_digests || options->show_engines
-#ifdef ENABLE_SSL
- || options->show_tls_ciphers
-#endif
- )
+ || options->show_tls_ciphers || options->show_curves)
{
if (options->show_ciphers)
show_available_ciphers ();
@@ -864,10 +843,10 @@ print_openssl_info (const struct options *options)
show_available_digests ();
if (options->show_engines)
show_available_engines ();
-#ifdef ENABLE_SSL
if (options->show_tls_ciphers)
show_available_tls_ciphers (options->cipher_list);
-#endif
+ if (options->show_curves)
+ show_available_curves();
return true;
}
#endif
@@ -916,10 +895,8 @@ do_persist_tuntap (const struct options *options)
|| options->ifconfig_remote_netmask
#ifdef ENABLE_CRYPTO
|| options->shared_secret_file
-#ifdef ENABLE_SSL
|| options->tls_server || options->tls_client
#endif
-#endif
)
msg (M_FATAL|M_OPTERR,
"options --mktun or --rmtun should only be used together with --dev");
@@ -1036,7 +1013,7 @@ const char *
format_common_name (struct context *c, struct gc_arena *gc)
{
struct buffer out = alloc_buf_gc (256, gc);
-#if defined(ENABLE_CRYPTO) && defined(ENABLE_SSL)
+#ifdef ENABLE_CRYPTO
if (c->c2.tls_multi)
{
buf_printf (&out, "[%s] ", tls_common_name (c->c2.tls_multi, false));
@@ -1048,7 +1025,7 @@ format_common_name (struct context *c, struct gc_arena *gc)
void
pre_setup (const struct options *options)
{
-#ifdef WIN32
+#ifdef _WIN32
if (options->exit_event_name)
{
win32_signal_open (&win32_signal,
@@ -1080,6 +1057,19 @@ reset_coarse_timers (struct context *c)
}
/*
+ * Initialise the server poll timeout timer
+ * This timer is used in the http/socks proxy setup so it needs to be setup
+ * before
+ */
+static void
+do_init_server_poll_timeout (struct context *c)
+{
+ update_time ();
+ if (c->options.ce.connect_timeout)
+ event_timeout_init (&c->c2.server_poll_interval, c->options.ce.connect_timeout, now);
+}
+
+/*
* Initialize timers
*/
static void
@@ -1100,11 +1090,6 @@ do_init_timers (struct context *c, bool deferred)
if (c->options.ping_rec_timeout)
event_timeout_init (&c->c2.ping_rec_interval, c->options.ping_rec_timeout, now);
-#if P2MP
- if (c->options.server_poll_timeout)
- event_timeout_init (&c->c2.server_poll_interval, c->options.server_poll_timeout, now);
-#endif
-
if (!deferred)
{
/* initialize connection establishment timer */
@@ -1126,9 +1111,7 @@ do_init_timers (struct context *c, bool deferred)
#ifdef ENABLE_CRYPTO
if (c->options.packet_id_file)
event_timeout_init (&c->c2.packet_id_persist_interval, 60, now);
-#endif
-#if defined(ENABLE_CRYPTO) && defined(ENABLE_SSL)
/* initialize tmp_int optimization that limits the number of times we call
tls_multi_process in the main event loop */
interval_init (&c->c2.tmp_int, TLS_MULTI_HORIZON, TLS_MULTI_REFRESH);
@@ -1161,9 +1144,9 @@ static void
do_alloc_route_list (struct context *c)
{
if (!c->c1.route_list)
- c->c1.route_list = new_route_list (c->options.max_routes, &c->gc);
+ ALLOC_OBJ_CLEAR_GC (c->c1.route_list, struct route_list, &c->gc);
if (c->options.routes_ipv6 && !c->c1.route_ipv6_list)
- c->c1.route_ipv6_list = new_route_ipv6_list (c->options.max_routes, &c->gc);
+ ALLOC_OBJ_CLEAR_GC (c->c1.route_ipv6_list, struct route_ipv6_list, &c->gc);
}
@@ -1175,7 +1158,6 @@ static void
do_init_route_list (const struct options *options,
struct route_list *route_list,
const struct link_socket_info *link_socket_info,
- bool fatal,
struct env_set *es)
{
const char *gw = NULL;
@@ -1189,18 +1171,13 @@ do_init_route_list (const struct options *options,
if (options->route_default_metric)
metric = options->route_default_metric;
- if (!init_route_list (route_list,
+ if (init_route_list (route_list,
options->routes,
gw,
metric,
link_socket_current_remote (link_socket_info),
es))
{
- if (fatal)
- openvpn_exit (OPENVPN_EXIT_STATUS_ERROR); /* exit point */
- }
- else
- {
/* copy routes to environment */
setenv_routes (es, route_list);
}
@@ -1209,11 +1186,10 @@ do_init_route_list (const struct options *options,
static void
do_init_route_ipv6_list (const struct options *options,
struct route_ipv6_list *route_ipv6_list,
- bool fatal,
+ const struct link_socket_info *link_socket_info,
struct env_set *es)
{
const char *gw = NULL;
- int dev = dev_type_enum (options->dev, options->dev_type);
int metric = -1; /* no metric set */
gw = options->ifconfig_ipv6_remote; /* default GW = remote end */
@@ -1225,17 +1201,28 @@ do_init_route_ipv6_list (const struct options *options,
if (options->route_default_metric)
metric = options->route_default_metric;
- if (!init_route_ipv6_list (route_ipv6_list,
+ /* redirect (IPv6) gateway to VPN? if yes, add a few more specifics
+ */
+ if ( options->routes_ipv6->flags & RG_REROUTE_GW )
+ {
+ char *opt_list[] = { "::/3", "2000::/4", "3000::/4", "fc00::/7", NULL };
+ int i;
+
+ for (i=0; opt_list[i]; i++)
+ {
+ add_route_ipv6_to_option_list( options->routes_ipv6,
+ string_alloc (opt_list[i], options->routes_ipv6->gc),
+ NULL, NULL );
+ }
+ }
+
+ if (init_route_ipv6_list (route_ipv6_list,
options->routes_ipv6,
gw,
metric,
+ link_socket_current_remote_ipv6 (link_socket_info),
es))
{
- if (fatal)
- openvpn_exit (OPENVPN_EXIT_STATUS_ERROR); /* exit point */
- }
- else
- {
/* copy routes to environment */
setenv_routes_ipv6 (es, route_ipv6_list);
}
@@ -1250,13 +1237,16 @@ initialization_sequence_completed (struct context *c, const unsigned int flags)
{
static const char message[] = "Initialization Sequence Completed";
+ /* Reset the unsuccessful connection counter on complete initialisation */
+ c->options.unsuccessful_attempts=0;
+
/* If we delayed UID/GID downgrade or chroot, do it now */
do_uid_gid_chroot (c, true);
/* Test if errors */
if (flags & ISC_ERRORS)
{
-#ifdef WIN32
+#ifdef _WIN32
show_routes (M_INFO|M_NOPREFIX);
show_adapters (M_INFO|M_NOPREFIX);
msg (M_INFO, "%s With Errors ( see http://openvpn.net/faq.html#dhcpclientserv )", message);
@@ -1267,11 +1257,11 @@ initialization_sequence_completed (struct context *c, const unsigned int flags)
else
msg (M_INFO, "%s", message);
- /* Flag connection_list that we initialized */
- if ((flags & (ISC_ERRORS|ISC_SERVER)) == 0 && connection_list_defined (&c->options))
- connection_list_set_no_advance (&c->options);
+ /* Flag that we initialized */
+ if ((flags & (ISC_ERRORS|ISC_SERVER)) == 0)
+ c->options.no_advance=true;
-#ifdef WIN32
+#ifdef _WIN32
fork_register_dns_action (c->c1.tuntap);
#endif
@@ -1279,26 +1269,52 @@ initialization_sequence_completed (struct context *c, const unsigned int flags)
/* Tell management interface that we initialized */
if (management)
{
- in_addr_t tun_local = 0;
- in_addr_t tun_remote = 0; /* FKS */
+ in_addr_t *tun_local = NULL;
+ struct in6_addr *tun_local6 = NULL;
+ struct openvpn_sockaddr local, remote;
+ struct link_socket_actual *actual;
+ socklen_t sa_len = sizeof(local);
const char *detail = "SUCCESS";
- if (c->c1.tuntap)
- tun_local = c->c1.tuntap->local;
- /* TODO(jjo): for ipv6 this will convert some 32bits in the ipv6 addr
- * to a meaningless ipv4 address.
- * In any case, is somewhat inconsistent to send local tunnel
- * addr with remote _endpoint_ addr (?)
- */
- tun_remote = htonl (c->c1.link_socket_addr.actual.dest.addr.in4.sin_addr.s_addr);
if (flags & ISC_ERRORS)
- detail = "ERROR";
+ detail = "ERROR";
+
+ CLEAR (local);
+ actual = &get_link_socket_info(c)->lsa->actual;
+ remote = actual->dest;
+ getsockname(c->c2.link_socket->sd, &local.addr.sa, &sa_len);
+#if ENABLE_IP_PKTINFO
+ if (!addr_defined(&local))
+ {
+ switch (local.addr.sa.sa_family)
+ {
+ case AF_INET:
+#if defined(HAVE_IN_PKTINFO) && defined(HAVE_IPI_SPEC_DST)
+ local.addr.in4.sin_addr = actual->pi.in4.ipi_spec_dst;
+#else
+ local.addr.in4.sin_addr = actual->pi.in4;
+#endif
+ break;
+ case AF_INET6:
+ local.addr.in6.sin6_addr = actual->pi.in6.ipi6_addr;
+ break;
+ }
+ }
+#endif
+
+ if (c->c1.tuntap)
+ {
+ tun_local = &c->c1.tuntap->local;
+ tun_local6 = &c->c1.tuntap->local_ipv6;
+ }
management_set_state (management,
OPENVPN_STATE_CONNECTED,
detail,
tun_local,
- tun_remote);
+ tun_local6,
+ &local,
+ &remote);
if (tun_local)
- management_post_tunnel_open (management, tun_local);
+ management_post_tunnel_open (management, *tun_local);
}
#endif
}
@@ -1335,12 +1351,12 @@ do_route (const struct options *options,
{
struct argv argv = argv_new ();
setenv_str (es, "script_type", "route-up");
- argv_printf (&argv, "%sc", options->route_script);
+ argv_parse_cmd (&argv, options->route_script);
openvpn_run_script (&argv, es, 0, "--route-up");
argv_reset (&argv);
}
-#ifdef WIN32
+#ifdef _WIN32
if (options->show_net_up)
{
show_routes (M_INFO|M_NOPREFIX);
@@ -1355,21 +1371,6 @@ do_route (const struct options *options,
}
/*
- * Save current pulled options string in the c1 context store, so we can
- * compare against it after possible future restarts.
- */
-#if P2MP
-static void
-save_pulled_options_digest (struct context *c, const struct md5_digest *newdigest)
-{
- if (newdigest)
- c->c1.pulled_options_digest_save = *newdigest;
- else
- md5_digest_clear (&c->c1.pulled_options_digest_save);
-}
-#endif
-
-/*
* initialize tun/tap device object
*/
static void
@@ -1383,14 +1384,11 @@ do_init_tun (struct context *c)
c->options.ifconfig_ipv6_local,
c->options.ifconfig_ipv6_netbits,
c->options.ifconfig_ipv6_remote,
- addr_host (&c->c1.link_socket_addr.local),
- addr_host (&c->c1.link_socket_addr.remote),
+ c->c1.link_socket_addr.bind_local,
+ c->c1.link_socket_addr.remote_list,
!c->options.ifconfig_nowarn,
c->c2.es);
- /* flag tunnel for IPv6 config if --tun-ipv6 is set */
- c->c1.tuntap->ipv6 = c->options.tun_ipv6;
-
init_tun_post (c->c1.tuntap,
&c->c2.frame,
&c->options.tuntap_options);
@@ -1408,22 +1406,39 @@ do_open_tun (struct context *c)
struct gc_arena gc = gc_new ();
bool ret = false;
- c->c2.ipv4_tun = (!c->options.tun_ipv6
- && is_dev_type (c->options.dev, c->options.dev_type, "tun"));
-
+#ifndef TARGET_ANDROID
if (!c->c1.tuntap)
{
+#endif
+
+#ifdef TARGET_ANDROID
+ /* If we emulate persist-tun on android we still have to open a new tun and
+ * then close the old */
+ int oldtunfd=-1;
+ if (c->c1.tuntap)
+ oldtunfd = c->c1.tuntap->fd;
+#endif
+
/* initialize (but do not open) tun/tap object */
do_init_tun (c);
+#ifdef _WIN32
+ /* store (hide) interactive service handle in tuntap_options */
+ c->c1.tuntap->options.msg_channel = c->options.msg_channel;
+ msg (D_ROUTE, "interactive service msg_channel=%u", (unsigned int) c->options.msg_channel);
+#endif
+
/* allocate route list structure */
do_alloc_route_list (c);
/* parse and resolve the route option list */
- if (c->options.routes && c->c1.route_list && c->c2.link_socket)
- do_init_route_list (&c->options, c->c1.route_list, &c->c2.link_socket->info, false, c->c2.es);
- if (c->options.routes_ipv6 && c->c1.route_ipv6_list )
- do_init_route_ipv6_list (&c->options, c->c1.route_ipv6_list, false, c->c2.es);
+ ASSERT(c->c2.link_socket);
+ if (c->options.routes && c->c1.route_list)
+ do_init_route_list (&c->options, c->c1.route_list,
+ &c->c2.link_socket->info, c->c2.es);
+ if (c->options.routes_ipv6 && c->c1.route_ipv6_list)
+ do_init_route_ipv6_list (&c->options, c->c1.route_ipv6_list,
+ &c->c2.link_socket->info, c->c2.es);
/* do ifconfig */
if (!c->options.ifconfig_noexec
@@ -1438,6 +1453,16 @@ do_open_tun (struct context *c)
do_ifconfig (c->c1.tuntap, guess, TUN_MTU_SIZE (&c->c2.frame), c->c2.es);
}
+ /* possibly add routes */
+ if (route_order() == ROUTE_BEFORE_TUN) {
+ /* Ignore route_delay, would cause ROUTE_BEFORE_TUN to be ignored */
+ do_route (&c->options, c->c1.route_list, c->c1.route_ipv6_list,
+ c->c1.tuntap, c->plugins, c->c2.es);
+ }
+#ifdef TARGET_ANDROID
+ /* Store the old fd inside the fd so open_tun can use it */
+ c->c1.tuntap->fd = oldtunfd;
+#endif
/* open the tun device */
open_tun (c->options.dev, c->options.dev_type, c->options.dev_node,
c->c1.tuntap);
@@ -1458,7 +1483,7 @@ do_open_tun (struct context *c)
c->plugins,
OPENVPN_PLUGIN_UP,
c->c1.tuntap->actual_name,
-#ifdef WIN32
+#ifdef _WIN32
c->c1.tuntap->adapter_index,
#endif
dev_type_string (c->options.dev, c->options.dev_type),
@@ -1471,17 +1496,17 @@ do_open_tun (struct context *c)
"up",
c->c2.es);
-#ifdef WIN32
+#if defined(_WIN32)
if (c->options.block_outside_dns)
{
dmsg (D_LOW, "Blocking outside DNS");
- if (!win_wfp_block_dns(c->c1.tuntap->adapter_index))
+ if (!win_wfp_block_dns(c->c1.tuntap->adapter_index, c->options.msg_channel))
msg (M_FATAL, "Blocking DNS failed!");
}
#endif
/* possibly add routes */
- if (!c->options.route_delay_defined)
+ if ((route_order() == ROUTE_AFTER_TUN) && (!c->options.route_delay_defined))
do_route (&c->options, c->c1.route_list, c->c1.route_ipv6_list,
c->c1.tuntap, c->plugins, c->c2.es);
@@ -1495,6 +1520,7 @@ do_open_tun (struct context *c)
ret = true;
static_context = c;
+#ifndef TARGET_ANDROID
}
else
{
@@ -1510,7 +1536,7 @@ do_open_tun (struct context *c)
c->plugins,
OPENVPN_PLUGIN_UP,
c->c1.tuntap->actual_name,
-#ifdef WIN32
+#ifdef _WIN32
c->c1.tuntap->adapter_index,
#endif
dev_type_string (c->options.dev, c->options.dev_type),
@@ -1522,7 +1548,17 @@ do_open_tun (struct context *c)
NULL,
"up",
c->c2.es);
+#if defined(_WIN32)
+ if (c->options.block_outside_dns)
+ {
+ dmsg (D_LOW, "Blocking outside DNS");
+ if (!win_wfp_block_dns(c->c1.tuntap->adapter_index, c->options.msg_channel))
+ msg (M_FATAL, "Blocking DNS failed!");
+ }
+#endif
+
}
+#endif
gc_free (&gc);
return ret;
}
@@ -1539,7 +1575,7 @@ do_close_tun_simple (struct context *c)
c->c1.tuntap = NULL;
c->c1.tuntap_owned = false;
#if P2MP
- save_pulled_options_digest (c, NULL); /* delete C1-saved pulled_options_digest */
+ CLEAR (c->c1.pulled_options_digest_save);
#endif
}
@@ -1550,7 +1586,7 @@ do_close_tun (struct context *c, bool force)
if (c->c1.tuntap && c->c1.tuntap_owned)
{
const char *tuntap_actual = string_alloc (c->c1.tuntap->actual_name, &gc);
-#ifdef WIN32
+#ifdef _WIN32
DWORD adapter_index = c->c1.tuntap->adapter_index;
#endif
const in_addr_t local = c->c1.tuntap->local;
@@ -1571,12 +1607,12 @@ do_close_tun (struct context *c, bool force)
/* delete any routes we added */
if (c->c1.route_list || c->c1.route_ipv6_list )
- {
+ {
run_up_down (c->options.route_predown_script,
c->plugins,
OPENVPN_PLUGIN_ROUTE_PREDOWN,
tuntap_actual,
-#ifdef WIN32
+#ifdef _WIN32
adapter_index,
#endif
NULL,
@@ -1604,7 +1640,7 @@ do_close_tun (struct context *c, bool force)
c->plugins,
OPENVPN_PLUGIN_DOWN,
tuntap_actual,
-#ifdef WIN32
+#ifdef _WIN32
adapter_index,
#endif
NULL,
@@ -1618,10 +1654,10 @@ do_close_tun (struct context *c, bool force)
"down",
c->c2.es);
-#ifdef WIN32
+#if defined(_WIN32)
if (c->options.block_outside_dns)
{
- if (!win_wfp_uninit())
+ if (!win_wfp_uninit(c->options.msg_channel))
msg (M_FATAL, "Uninitialising WFP failed!");
}
#endif
@@ -1638,7 +1674,7 @@ do_close_tun (struct context *c, bool force)
c->plugins,
OPENVPN_PLUGIN_DOWN,
tuntap_actual,
-#ifdef WIN32
+#ifdef _WIN32
adapter_index,
#endif
NULL,
@@ -1651,6 +1687,15 @@ do_close_tun (struct context *c, bool force)
c->sig->signal_text),
"down",
c->c2.es);
+
+#if defined(_WIN32)
+ if (c->options.block_outside_dns)
+ {
+ if (!win_wfp_uninit(c->options.msg_channel))
+ msg (M_FATAL, "Uninitialising WFP failed!");
+ }
+#endif
+
}
}
gc_free (&gc);
@@ -1671,7 +1716,22 @@ tun_abort()
* Handle delayed tun/tap interface bringup due to --up-delay or --pull
*/
-void
+#if P2MP
+/**
+ * Helper for do_up(). Take two option hashes and return true if they are not
+ * equal, or either one is all-zeroes.
+ */
+static bool
+options_hash_changed_or_zero(const struct md5_digest *a,
+ const struct md5_digest *b)
+{
+ const struct md5_digest zero = {{0}};
+ return memcmp (a, b, sizeof(struct md5_digest)) ||
+ !memcmp (a, &zero, sizeof(struct md5_digest));
+}
+#endif /* P2MP */
+
+bool
do_up (struct context *c, bool pulled_options, unsigned int option_types_found)
{
if (!c->c2.do_up_ran)
@@ -1679,7 +1739,13 @@ do_up (struct context *c, bool pulled_options, unsigned int option_types_found)
reset_coarse_timers (c);
if (pulled_options && option_types_found)
- do_deferred_options (c, option_types_found);
+ {
+ if (!do_deferred_options (c, option_types_found))
+ {
+ msg (D_PUSH_ERRORS, "ERROR: Failed to apply push options");
+ return false;
+ }
+ }
/* if --up-delay specified, open tun, do ifconfig, and run up script now */
if (c->options.up_delay || PULL_DEFINED (&c->options))
@@ -1695,8 +1761,8 @@ do_up (struct context *c, bool pulled_options, unsigned int option_types_found)
if (!c->c2.did_open_tun
&& PULL_DEFINED (&c->options)
&& c->c1.tuntap
- && (!md5_digest_defined (&c->c1.pulled_options_digest_save) || !md5_digest_defined (&c->c2.pulled_options_digest)
- || !md5_digest_equal (&c->c1.pulled_options_digest_save, &c->c2.pulled_options_digest)))
+ && options_hash_changed_or_zero (&c->c1.pulled_options_digest_save,
+ &c->c2.pulled_options_digest))
{
/* if so, close tun, delete routes, then reinitialize tun and add routes */
msg (M_INFO, "NOTE: Pulled options changed on restart, will need to close and reopen TUN/TAP device.");
@@ -1711,11 +1777,11 @@ do_up (struct context *c, bool pulled_options, unsigned int option_types_found)
if (c->c2.did_open_tun)
{
#if P2MP
- save_pulled_options_digest (c, &c->c2.pulled_options_digest);
+ c->c1.pulled_options_digest_save = c->c2.pulled_options_digest;
#endif
/* if --route-delay was specified, start timer */
- if (c->options.route_delay_defined)
+ if ((route_order() == ROUTE_AFTER_TUN) && c->options.route_delay_defined)
{
event_timeout_init (&c->c2.route_wakeup, c->options.route_delay, now);
event_timeout_init (&c->c2.route_wakeup_expire, c->options.route_delay + c->options.route_delay_window, now);
@@ -1734,6 +1800,7 @@ do_up (struct context *c, bool pulled_options, unsigned int option_types_found)
c->c2.do_up_ran = true;
}
+ return true;
}
/*
@@ -1761,13 +1828,18 @@ pull_permission_mask (const struct context *c)
if (!c->options.route_nopull)
flags |= (OPT_P_ROUTE | OPT_P_IPWIN32);
+#ifdef ENABLE_CRYPTO
+ if (c->options.ncp_enabled)
+ flags |= OPT_P_NCP;
+#endif
+
return flags;
}
/*
* Handle non-tun-related pulled options.
*/
-void
+bool
do_deferred_options (struct context *c, const unsigned int found)
{
if (found & OPT_P_MESSAGES)
@@ -1794,14 +1866,12 @@ do_deferred_options (struct context *c, const unsigned int found)
}
#endif
-#ifdef ENABLE_LZO
+#ifdef USE_COMP
if (found & OPT_P_COMP)
{
- if (lzo_defined (&c->c2.lzo_compwork))
- {
- msg (D_PUSH, "OPTIONS IMPORT: LZO parms modified");
- lzo_modify_flags (&c->c2.lzo_compwork, c->options.lzo);
- }
+ msg (D_PUSH, "OPTIONS IMPORT: compression parms modified");
+ comp_uninit (c->c2.comp_context);
+ c->c2.comp_context = comp_init (&c->options.comp);
}
#endif
@@ -1836,7 +1906,7 @@ do_deferred_options (struct context *c, const unsigned int found)
if (found & OPT_P_SETENV)
msg (D_PUSH, "OPTIONS IMPORT: environment modified");
-#ifdef ENABLE_SSL
+#ifdef ENABLE_CRYPTO
if (found & OPT_P_PEER_ID)
{
msg (D_PUSH, "OPTIONS IMPORT: peer-id set");
@@ -1856,20 +1926,37 @@ do_deferred_options (struct context *c, const unsigned int found)
" MTU problems", TUN_MTU_SIZE(&c->c2.frame) );
}
}
+
+ /* process (potentially pushed) crypto options */
+ if (c->options.pull)
+ {
+ struct tls_session *session = &c->c2.tls_multi->session[TM_ACTIVE];
+ if (found & OPT_P_NCP)
+ msg (D_PUSH, "OPTIONS IMPORT: data channel crypto options modified");
+ /* Do not regenerate keys if server sends an extra push request */
+ if (!session->key[KS_PRIMARY].crypto_options.key_ctx_bi.initialized &&
+ !tls_session_update_crypto_params(session, &c->options, &c->c2.frame))
+ {
+ msg (D_TLS_ERRORS, "OPTIONS ERROR: failed to import crypto options");
+ return false;
+ }
+ }
#endif
+ return true;
}
/*
- * Possible hold on initialization
+ * Possible hold on initialization, holdtime is the
+ * time OpenVPN would wait without management
*/
static bool
-do_hold (void)
+do_hold (int holdtime)
{
#ifdef ENABLE_MANAGEMENT
if (management)
{
/* block until management hold is released */
- if (management_hold (management))
+ if (management_hold (management, holdtime))
return true;
}
#endif
@@ -1882,31 +1969,16 @@ do_hold (void)
static void
socket_restart_pause (struct context *c)
{
- bool proxy = false;
int sec = 2;
-
-#ifdef ENABLE_HTTP_PROXY
- if (c->options.ce.http_proxy_options)
- proxy = true;
-#endif
-#ifdef ENABLE_SOCKS
- if (c->options.ce.socks_proxy_server)
- proxy = true;
-#endif
+ int backoff = 0;
switch (c->options.ce.proto)
{
- case PROTO_UDPv4:
- case PROTO_UDPv6:
- if (proxy)
- sec = c->options.ce.connect_retry_seconds;
- break;
- case PROTO_TCPv4_SERVER:
- case PROTO_TCPv6_SERVER:
+ case PROTO_TCP_SERVER:
sec = 1;
break;
- case PROTO_TCPv4_CLIENT:
- case PROTO_TCPv6_CLIENT:
+ case PROTO_UDP:
+ case PROTO_TCP_CLIENT:
sec = c->options.ce.connect_retry_seconds;
break;
}
@@ -1919,13 +1991,22 @@ socket_restart_pause (struct context *c)
#if P2MP
if (auth_retry_get () == AR_NOINTERACT)
sec = 10;
-
-#if 0 /* not really needed because of c->persist.restart_sleep_seconds */
- if (c->options.server_poll_timeout && sec > 1)
- sec = 1;
-#endif
#endif
+ /* Slow down reconnection after 5 retries per remote -- for tcp only in client mode */
+ if (c->options.ce.proto != PROTO_TCP_SERVER)
+ {
+ backoff = (c->options.unsuccessful_attempts / c->options.connection_list->len) - 4;
+ if (backoff > 0)
+ {
+ /* sec is less than 2^16; we can left shift it by up to 15 bits without overflow */
+ sec = max_int (sec, 1) << min_int (backoff, 15);
+ }
+
+ if (sec > c->options.ce.connect_retry_seconds_max)
+ sec = c->options.ce.connect_retry_seconds_max;
+ }
+
if (c->persist.restart_sleep_seconds > 0 && c->persist.restart_sleep_seconds > sec)
sec = c->persist.restart_sleep_seconds;
else if (c->persist.restart_sleep_seconds == -1)
@@ -1933,8 +2014,10 @@ socket_restart_pause (struct context *c)
c->persist.restart_sleep_seconds = 0;
/* do managment hold on context restart, i.e. second, third, fourth, etc. initialization */
- if (do_hold ())
+ if (do_hold (sec))
+ {
sec = 0;
+ }
if (sec)
{
@@ -1952,7 +2035,7 @@ do_startup_pause (struct context *c)
if (!c->first_time)
socket_restart_pause (c);
else
- do_hold (); /* do management hold on first context initialization */
+ do_hold (0); /* do management hold on first context initialization */
}
/*
@@ -1977,6 +2060,7 @@ frame_finalize_options (struct context *c, const struct options *o)
|FRAME_HEADROOM_MARKER_READ_STREAM);
}
+ frame_add_to_extra_buffer (&c->c2.frame, PAYLOAD_ALIGN);
frame_finalize (&c->c2.frame,
o->ce.link_mtu_defined,
o->ce.link_mtu,
@@ -1992,13 +2076,11 @@ key_schedule_free (struct key_schedule *ks, bool free_ssl_ctx)
{
#ifdef ENABLE_CRYPTO
free_key_ctx_bi (&ks->static_key);
-#ifdef ENABLE_SSL
if (tls_ctx_initialised(&ks->ssl_ctx) && free_ssl_ctx)
{
tls_ctx_free (&ks->ssl_ctx);
- free_key_ctx_bi (&ks->tls_auth_key);
+ free_key_ctx_bi (&ks->tls_wrap_key);
}
-#endif /* ENABLE_SSL */
#endif /* ENABLE_CRYPTO */
CLEAR (*ks);
}
@@ -2018,14 +2100,6 @@ init_crypto_pre (struct context *c, const unsigned int flags)
packet_id_persist_load (&c->c1.pid_persist, c->options.packet_id_file);
}
- /* Initialize crypto options */
-
- if (c->options.use_iv)
- c->c2.crypto_options.flags |= CO_USE_IV;
-
- if (c->options.mute_replay_warnings)
- c->c2.crypto_options.flags |= CO_MUTE_REPLAY_WARNINGS;
-
#ifdef ENABLE_PREDICTION_RESISTANCE
if (c->options.use_prediction_resistance)
rand_ctx_enable_prediction_resistance();
@@ -2044,60 +2118,38 @@ do_init_crypto_static (struct context *c, const unsigned int flags)
init_crypto_pre (c, flags);
+ /* Initialize flags */
+ if (c->options.use_iv)
+ c->c2.crypto_options.flags |= CO_USE_IV;
+
+ if (c->options.mute_replay_warnings)
+ c->c2.crypto_options.flags |= CO_MUTE_REPLAY_WARNINGS;
+
/* Initialize packet ID tracking */
if (options->replay)
{
- packet_id_init (&c->c2.packet_id,
- link_socket_proto_connection_oriented (options->ce.proto),
+ packet_id_init (&c->c2.crypto_options.packet_id,
options->replay_window,
options->replay_time,
"STATIC", 0);
- c->c2.crypto_options.packet_id = &c->c2.packet_id;
c->c2.crypto_options.pid_persist = &c->c1.pid_persist;
c->c2.crypto_options.flags |= CO_PACKET_ID_LONG_FORM;
packet_id_persist_load_obj (&c->c1.pid_persist,
- c->c2.crypto_options.packet_id);
+ &c->c2.crypto_options.packet_id);
}
if (!key_ctx_bi_defined (&c->c1.ks.static_key))
{
- struct key2 key2;
- struct key_direction_state kds;
-
/* Get cipher & hash algorithms */
- init_key_type (&c->c1.ks.key_type, options->ciphername,
- options->ciphername_defined, options->authname,
- options->authname_defined, options->keysize,
- options->test_crypto, true);
+ init_key_type (&c->c1.ks.key_type, options->ciphername, options->authname,
+ options->keysize, options->test_crypto, true);
/* Read cipher and hmac keys from shared secret file */
- {
- unsigned int rkf_flags = RKF_MUST_SUCCEED;
- const char *rkf_file = options->shared_secret_file;
-
- if (options->shared_secret_file_inline)
- {
- rkf_file = options->shared_secret_file_inline;
- rkf_flags |= RKF_INLINE;
- }
- read_key_file (&key2, rkf_file, rkf_flags);
- }
-
- /* Check for and fix highly unlikely key problems */
- verify_fix_key2 (&key2, &c->c1.ks.key_type,
- options->shared_secret_file);
-
- /* Initialize OpenSSL key objects */
- key_direction_state_init (&kds, options->key_direction);
- must_have_n_keys (options->shared_secret_file, "secret", &key2,
- kds.need_keys);
- init_key_ctx (&c->c1.ks.static_key.encrypt, &key2.keys[kds.out_key],
- &c->c1.ks.key_type, OPENVPN_OP_ENCRYPT, "Static Encrypt");
- init_key_ctx (&c->c1.ks.static_key.decrypt, &key2.keys[kds.in_key],
- &c->c1.ks.key_type, OPENVPN_OP_DECRYPT, "Static Decrypt");
-
- /* Erase the temporary copy of key */
- CLEAR (key2);
+ crypto_read_openvpn_key (&c->c1.ks.key_type, &c->c1.ks.static_key,
+ options->shared_secret_file,
+ options->shared_secret_file_inline,
+ options->key_direction, "Static Key Encryption",
+ "secret");
}
else
{
@@ -2105,12 +2157,11 @@ do_init_crypto_static (struct context *c, const unsigned int flags)
}
/* Get key schedule */
- c->c2.crypto_options.key_ctx_bi = &c->c1.ks.static_key;
+ c->c2.crypto_options.key_ctx_bi = c->c1.ks.static_key;
/* Compute MTU parameters */
crypto_adjust_frame_parameters (&c->c2.frame,
&c->c1.ks.key_type,
- options->ciphername_defined,
options->use_iv, options->replay, true);
/* Sanity check on IV, sequence number, and cipher mode options */
@@ -2118,8 +2169,6 @@ do_init_crypto_static (struct context *c, const unsigned int flags)
options->use_iv);
}
-#ifdef ENABLE_SSL
-
/*
* Initialize the persistent component of OpenVPN's TLS mode,
* which is preserved across SIGUSR1 resets.
@@ -2160,9 +2209,8 @@ do_init_crypto_tls_c1 (struct context *c)
}
/* Get cipher & hash algorithms */
- init_key_type (&c->c1.ks.key_type, options->ciphername,
- options->ciphername_defined, options->authname,
- options->authname_defined, options->keysize, true, true);
+ init_key_type (&c->c1.ks.key_type, options->ciphername, options->authname,
+ options->keysize, true, true);
/* Initialize PRNG with config-specified digest */
prng_init (options->prng_hash, options->prng_nonce_secret_len);
@@ -2170,21 +2218,36 @@ do_init_crypto_tls_c1 (struct context *c)
/* TLS handshake authentication (--tls-auth) */
if (options->tls_auth_file)
{
- unsigned int flags = 0;
- const char *file = options->tls_auth_file;
-
- if (options->tls_auth_file_inline)
+ /* Initialize key_type for tls-auth with auth only */
+ CLEAR (c->c1.ks.tls_auth_key_type);
+ if (!streq (options->authname, "none"))
{
- flags |= GHK_INLINE;
- file = options->tls_auth_file_inline;
+ c->c1.ks.tls_auth_key_type.digest = md_kt_get (options->authname);
+ c->c1.ks.tls_auth_key_type.hmac_length =
+ md_kt_size (c->c1.ks.tls_auth_key_type.digest);
}
- get_tls_handshake_key (&c->c1.ks.key_type,
- &c->c1.ks.tls_auth_key,
- file,
- options->key_direction,
- flags);
+ else
+ {
+ msg (M_FATAL, "ERROR: tls-auth enabled, but no valid --auth "
+ "algorithm specified ('%s')", options->authname);
+ }
+
+ crypto_read_openvpn_key (&c->c1.ks.tls_auth_key_type,
+ &c->c1.ks.tls_wrap_key, options->tls_auth_file,
+ options->tls_auth_file_inline, options->key_direction,
+ "Control Channel Authentication", "tls-auth");
}
+ /* TLS handshake encryption+authentication (--tls-crypt) */
+ if (options->tls_crypt_file) {
+ tls_crypt_init_key (&c->c1.ks.tls_wrap_key, options->tls_crypt_file,
+ 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)
{
@@ -2196,6 +2259,11 @@ 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;
}
}
@@ -2226,17 +2294,28 @@ do_init_crypto_tls (struct context *c, const unsigned int flags)
/* In short form, unique datagram identifier is 32 bits, in long form 64 bits */
packet_id_long_form = cipher_kt_mode_ofb_cfb (c->c1.ks.key_type.cipher);
- /* Compute MTU parameters */
- crypto_adjust_frame_parameters (&c->c2.frame,
- &c->c1.ks.key_type,
- options->ciphername_defined,
- options->use_iv,
- options->replay, packet_id_long_form);
+ /* Compute MTU parameters (postpone if we push/pull options) */
+ if (c->options.pull || c->options.mode == MODE_SERVER)
+ {
+ /* Account for worst-case crypto overhead before allocating buffers */
+ frame_add_to_extra_frame (&c->c2.frame, crypto_max_overhead());
+ }
+ else
+ {
+ crypto_adjust_frame_parameters(&c->c2.frame, &c->c1.ks.key_type,
+ options->use_iv, options->replay, packet_id_long_form);
+ }
tls_adjust_frame_parameters (&c->c2.frame);
/* Set all command-line TLS-related options */
CLEAR (to);
+ if (options->use_iv)
+ to.crypto_flags |= CO_USE_IV;
+
+ if (options->mute_replay_warnings)
+ to.crypto_flags |= CO_MUTE_REPLAY_WARNINGS;
+
to.crypto_flags_and = ~(CO_PACKET_ID_LONG_FORM);
if (packet_id_long_form)
to.crypto_flags_or = CO_PACKET_ID_LONG_FORM;
@@ -2249,6 +2328,9 @@ do_init_crypto_tls (struct context *c, const unsigned int flags)
to.replay_window = options->replay_window;
to.replay_time = options->replay_time;
to.tcp_mode = link_socket_proto_connection_oriented (options->ce.proto);
+ to.config_ciphername = c->c1.ciphername;
+ to.config_authname = c->c1.authname;
+ to.ncp_enabled = options->ncp_enabled;
to.transition_window = options->transition_window;
to.handshake_window = options->handshake_window;
to.packet_timeout = options->tls_timeout;
@@ -2256,6 +2338,8 @@ do_init_crypto_tls (struct context *c, const unsigned int flags)
to.renegotiate_packets = options->renegotiate_packets;
to.renegotiate_seconds = options->renegotiate_seconds;
to.single_session = options->single_session;
+ to.mode = options->mode;
+ to.pull = options->pull;
#ifdef ENABLE_PUSH_PEER_INFO
if (options->push_peer_info) /* all there is */
to.push_peer_info_detail = 2;
@@ -2267,7 +2351,7 @@ do_init_crypto_tls (struct context *c, const unsigned int flags)
/* should we not xmit any packets until we get an initial
response from client? */
- if (to.server && options->ce.proto == PROTO_TCPv4_SERVER)
+ if (to.server && options->ce.proto == PROTO_TCP_SERVER)
to.xmit_hold = true;
#ifdef ENABLE_OCC
@@ -2279,6 +2363,7 @@ do_init_crypto_tls (struct context *c, const unsigned int flags)
to.verify_x509_type = (options->verify_x509_type & 0xff);
to.verify_x509_name = options->verify_x509_name;
to.crl_file = options->crl_file;
+ to.crl_file_inline = options->crl_file_inline;
to.ssl_flags = options->ssl_flags;
to.ns_cert_type = options->ns_cert_type;
memmove (to.remote_cert_ku, options->remote_cert_ku, sizeof (to.remote_cert_ku));
@@ -2308,11 +2393,11 @@ do_init_crypto_tls (struct context *c, const unsigned int flags)
if (options->ccd_exclusive)
to.client_config_dir_exclusive = options->client_config_dir;
to.auth_user_pass_file = options->auth_user_pass_file;
+ to.auth_token_generate = options->auth_token_generate;
+ to.auth_token_lifetime = options->auth_token_lifetime;
#endif
-#ifdef ENABLE_X509_TRACK
to.x509_track = options->x509_track;
-#endif
#if P2MP
#ifdef ENABLE_CLIENT_CR
@@ -2320,15 +2405,46 @@ do_init_crypto_tls (struct context *c, const unsigned int flags)
#endif
#endif
+#ifdef USE_COMP
+ to.comp_options = options->comp;
+#endif
+
+#if defined(ENABLE_CRYPTO_OPENSSL) && OPENSSL_VERSION_NUMBER >= 0x10001000
+ if (options->keying_material_exporter_label)
+ {
+ to.ekm_size = options->keying_material_exporter_length;
+ if (to.ekm_size < 16 || to.ekm_size > 4095)
+ to.ekm_size = 0;
+
+ to.ekm_label = options->keying_material_exporter_label;
+ to.ekm_label_size = strlen(to.ekm_label);
+ }
+ else
+ {
+ to.ekm_size = 0;
+ }
+#endif
+
/* TLS handshake authentication (--tls-auth) */
if (options->tls_auth_file)
{
- to.tls_auth_key = c->c1.ks.tls_auth_key;
- to.tls_auth.pid_persist = &c->c1.pid_persist;
- to.tls_auth.flags |= CO_PACKET_ID_LONG_FORM;
+ to.tls_wrap.mode = TLS_WRAP_AUTH;
+ to.tls_wrap.opt.key_ctx_bi = c->c1.ks.tls_wrap_key;
+ to.tls_wrap.opt.pid_persist = &c->c1.pid_persist;
+ to.tls_wrap.opt.flags |= CO_PACKET_ID_LONG_FORM;
crypto_adjust_frame_parameters (&to.frame,
- &c->c1.ks.key_type,
- false, false, true, true);
+ &c->c1.ks.tls_auth_key_type,
+ false, true, true);
+ }
+
+ /* TLS handshake encryption (--tls-crypt) */
+ if (options->tls_crypt_file)
+ {
+ to.tls_wrap.mode = TLS_WRAP_CRYPT;
+ to.tls_wrap.opt.key_ctx_bi = c->c1.ks.tls_wrap_key;
+ to.tls_wrap.opt.pid_persist = &c->c1.pid_persist;
+ to.tls_wrap.opt.flags |= CO_PACKET_ID_LONG_FORM;
+ tls_crypt_adjust_frame_parameters (&to.frame);
}
/* If we are running over TCP, allow for
@@ -2364,10 +2480,6 @@ do_init_finalize_tls_frame (struct context *c)
}
}
-#endif /* ENABLE_SSL */
-#endif /* ENABLE_CRYPTO */
-
-#ifdef ENABLE_CRYPTO
/*
* No encryption or authentication.
*/
@@ -2386,54 +2498,70 @@ do_init_crypto (struct context *c, const unsigned int flags)
#ifdef ENABLE_CRYPTO
if (c->options.shared_secret_file)
do_init_crypto_static (c, flags);
-#ifdef ENABLE_SSL
else if (c->options.tls_server || c->options.tls_client)
do_init_crypto_tls (c, flags);
-#endif
else /* no encryption or authentication. */
do_init_crypto_none (c);
#else /* ENABLE_CRYPTO */
msg (M_WARN,
"******* WARNING *******: " PACKAGE_NAME
- " built without OpenSSL -- encryption and authentication features disabled -- all data will be tunnelled as cleartext");
+ " built without crypto library -- encryption and authentication features disabled -- all data will be tunnelled as cleartext");
#endif /* ENABLE_CRYPTO */
}
static void
do_init_frame (struct context *c)
{
-#ifdef ENABLE_LZO
+#ifdef USE_COMP
/*
- * Initialize LZO compression library.
+ * modify frame parameters if compression is enabled
*/
- if (c->options.lzo & LZO_SELECTED)
+ if (comp_enabled(&c->options.comp))
{
- lzo_adjust_frame_parameters (&c->c2.frame);
+ comp_add_to_extra_frame (&c->c2.frame);
+#if !defined(ENABLE_LZ4)
/*
- * LZO usage affects buffer alignment.
+ * Compression usage affects buffer alignment when non-swapped algs
+ * such as LZO is used.
+ * Newer algs like LZ4 and comp-stub with COMP_F_SWAP don't need
+ * any special alignment because of the control-byte swap approach.
+ * LZO alignment (on the other hand) is problematic because
+ * the presence of the control byte means that either the output of
+ * decryption must be written to an unaligned buffer, or the input
+ * to compression (or packet dispatch if packet is uncompressed)
+ * must be read from an unaligned buffer.
+ * This code tries to align the input to compression (or packet
+ * dispatch if packet is uncompressed) at the cost of requiring
+ * decryption output to be written to an unaligned buffer, so
+ * it's more of a tradeoff than an optimal solution and we don't
+ * include it when we are doing a modern build with LZ4.
+ * Strictly speaking, on the server it would be better to execute
+ * this code for every connection after we decide the compression
+ * method, but currently the frame code doesn't appear to be
+ * flexible enough for this, since the frame is already established
+ * before it is known which compression options will be pushed.
*/
- if (CIPHER_ENABLED (c))
+ if (comp_unswapped_prefix (&c->options.comp) && CIPHER_ENABLED (c))
{
- frame_add_to_align_adjust (&c->c2.frame, LZO_PREFIX_LEN);
+ frame_add_to_align_adjust (&c->c2.frame, COMP_PREFIX_LEN);
frame_or_align_flags (&c->c2.frame,
FRAME_HEADROOM_MARKER_FRAGMENT
|FRAME_HEADROOM_MARKER_DECRYPT);
}
+#endif
#ifdef ENABLE_FRAGMENT
- lzo_adjust_frame_parameters (&c->c2.frame_fragment_omit); /* omit LZO frame delta from final frame_fragment */
+ comp_add_to_extra_frame (&c->c2.frame_fragment_omit); /* omit compression frame delta from final frame_fragment */
#endif
}
-#endif /* ENABLE_LZO */
+#endif /* USE_COMP */
-#ifdef ENABLE_SOCKS
/*
* Adjust frame size for UDP Socks support.
*/
if (c->options.ce.socks_proxy_server)
socks_adjust_frame_parameters (&c->c2.frame, c->options.ce.proto);
-#endif
/*
* Adjust frame size based on the --tun-mtu-extra parameter.
@@ -2454,16 +2582,27 @@ do_init_frame (struct context *c)
*/
frame_finalize_options (c, NULL);
+#ifdef USE_COMP
+ /*
+ * Modify frame parameters if compression is compiled in.
+ * Should be called after frame_finalize_options.
+ */
+ comp_add_to_extra_buffer (&c->c2.frame);
+#ifdef ENABLE_FRAGMENT
+ comp_add_to_extra_buffer (&c->c2.frame_fragment_omit); /* omit compression frame delta from final frame_fragment */
+#endif
+#endif /* USE_COMP */
+
/* packets with peer-id (P_DATA_V2) need 3 extra bytes in frame (on client)
* and need link_mtu+3 bytes on socket reception (on server).
*
- * accomodate receive path in f->extra_link
- * send path in f->extra_buffer (+leave room for alignment)
+ * accomodate receive path in f->extra_link, which has the side effect of
+ * also increasing send buffers (BUF_SIZE() macro), which need to be
+ * allocated big enough before receiving peer-id option from server.
*
* f->extra_frame is adjusted when peer-id option is push-received
*/
frame_add_to_extra_link(&c->c2.frame, 3);
- frame_add_to_extra_buffer(&c->c2.frame, 8);
#ifdef ENABLE_FRAGMENT
/*
@@ -2546,7 +2685,6 @@ do_option_warnings (struct context *c)
if (!o->use_iv)
msg (M_WARN, "WARNING: You have disabled Crypto IVs (--no-iv) which may make " PACKAGE_NAME " less secure");
-#ifdef ENABLE_SSL
if (o->tls_server)
warn_on_use_of_common_subnets ();
if (o->tls_client
@@ -2556,12 +2694,6 @@ do_option_warnings (struct context *c)
&& !o->remote_cert_eku)
msg (M_WARN, "WARNING: No server certificate verification method has been enabled. See http://openvpn.net/howto.html#mitm for more info.");
#endif
-#endif
-
-#ifndef CONNECT_NONBLOCK
- if (o->ce.connect_timeout_defined)
- msg (M_WARN, "NOTE: --connect-timeout option is not supported on this OS");
-#endif
/* If a script is used, print appropiate warnings */
if (o->user_script_used)
@@ -2578,7 +2710,7 @@ do_option_warnings (struct context *c)
static void
do_init_frame_tls (struct context *c)
{
-#if defined(ENABLE_CRYPTO) && defined(ENABLE_SSL)
+#ifdef ENABLE_CRYPTO
do_init_finalize_tls_frame (c);
#endif
}
@@ -2600,9 +2732,9 @@ init_context_buffers (const struct frame *frame)
b->decrypt_buf = alloc_buf (BUF_SIZE (frame));
#endif
-#ifdef ENABLE_LZO
- b->lzo_compress_buf = alloc_buf (BUF_SIZE (frame));
- b->lzo_decompress_buf = alloc_buf (BUF_SIZE (frame));
+#ifdef USE_COMP
+ b->compress_buf = alloc_buf (BUF_SIZE (frame));
+ b->decompress_buf = alloc_buf (BUF_SIZE (frame));
#endif
return b;
@@ -2617,9 +2749,9 @@ free_context_buffers (struct context_buffers *b)
free_buf (&b->read_tun_buf);
free_buf (&b->aux_buf);
-#ifdef ENABLE_LZO
- free_buf (&b->lzo_compress_buf);
- free_buf (&b->lzo_decompress_buf);
+#ifdef USE_COMP
+ free_buf (&b->compress_buf);
+ free_buf (&b->decompress_buf);
#endif
#ifdef ENABLE_CRYPTO
@@ -2658,19 +2790,6 @@ do_init_fragment (struct context *c)
#endif
/*
- * Set the --mssfix option.
- */
-static void
-do_init_mssfix (struct context *c)
-{
- if (c->options.ce.mssfix)
- {
- frame_set_mtu_dynamic (&c->c2.frame,
- c->options.ce.mssfix, SET_MTU_UPPER_BOUND);
- }
-}
-
-/*
* Allocate our socket object.
*/
static void
@@ -2695,20 +2814,18 @@ do_init_socket_1 (struct context *c, const int mode)
#endif
link_socket_init_phase1 (c->c2.link_socket,
- connection_list_defined (&c->options),
c->options.ce.local,
c->options.ce.local_port,
c->options.ce.remote,
c->options.ce.remote_port,
+ c->c1.dns_cache,
c->options.ce.proto,
+ c->options.ce.af,
+ c->options.ce.bind_ipv6_only,
mode,
c->c2.accept_from,
-#ifdef ENABLE_HTTP_PROXY
c->c1.http_proxy,
-#endif
-#ifdef ENABLE_SOCKS
c->c1.socks_proxy,
-#endif
#ifdef ENABLE_DEBUG
c->options.gremlin,
#endif
@@ -2719,13 +2836,11 @@ do_init_socket_1 (struct context *c, const int mode)
c->options.ipchange,
c->plugins,
c->options.resolve_retry_seconds,
- c->options.ce.connect_retry_seconds,
- c->options.ce.connect_timeout,
- c->options.ce.connect_retry_max,
c->options.ce.mtu_discover_type,
c->options.rcvbuf,
c->options.sndbuf,
c->options.mark,
+ &c->c2.server_poll_interval,
sockflags);
}
@@ -2736,7 +2851,7 @@ static void
do_init_socket_2 (struct context *c)
{
link_socket_init_phase2 (c->c2.link_socket, &c->c2.frame,
- &c->sig->signal_received);
+ c->sig);
}
/*
@@ -2767,22 +2882,14 @@ do_compute_occ_strings (struct context *c)
c->c2.options_string_remote =
options_string (&c->options, &c->c2.frame, c->c1.tuntap, true, &gc);
- msg (D_SHOW_OCC, "Local Options String: '%s'", c->c2.options_string_local);
- msg (D_SHOW_OCC, "Expected Remote Options String: '%s'",
- c->c2.options_string_remote);
+ msg (D_SHOW_OCC, "Local Options String (VER=%s): '%s'",
+ options_string_version (c->c2.options_string_local, &gc),
+ c->c2.options_string_local);
+ msg (D_SHOW_OCC, "Expected Remote Options String (VER=%s): '%s'",
+ options_string_version (c->c2.options_string_remote, &gc),
+ c->c2.options_string_remote);
#ifdef ENABLE_CRYPTO
- msg (D_SHOW_OCC_HASH, "Local Options hash (VER=%s): '%s'",
- options_string_version (c->c2.options_string_local, &gc),
- md5sum ((uint8_t*)c->c2.options_string_local,
- strlen (c->c2.options_string_local), 9, &gc));
- msg (D_SHOW_OCC_HASH, "Expected Remote Options hash (VER=%s): '%s'",
- options_string_version (c->c2.options_string_remote, &gc),
- md5sum ((uint8_t*)c->c2.options_string_remote,
- strlen (c->c2.options_string_remote), 9, &gc));
-#endif
-
-#if defined(ENABLE_CRYPTO) && defined(ENABLE_SSL)
if (c->c2.tls_multi)
tls_multi_init_set_options (c->c2.tls_multi,
c->c2.options_string_local,
@@ -2859,7 +2966,7 @@ do_close_free_buf (struct context *c)
static void
do_close_tls (struct context *c)
{
-#if defined(ENABLE_CRYPTO) && defined(ENABLE_SSL)
+#ifdef ENABLE_CRYPTO
if (c->c2.tls_multi)
{
tls_multi_free (c->c2.tls_multi, true);
@@ -2899,14 +3006,31 @@ do_close_link_socket (struct context *c)
c->c2.link_socket = NULL;
}
- if (!(c->sig->signal_received == SIGUSR1 && c->options.persist_remote_ip))
- {
- CLEAR (c->c1.link_socket_addr.remote);
+
+ /* Preserve the resolved list of remote if the user request to or if we want
+ * reconnect to the same host again or there are still addresses that need
+ * to be tried */
+ if (!(c->sig->signal_received == SIGUSR1 &&
+ ( (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->options.no_advance))
+ )))
+ {
+ clear_remote_addrlist(&c->c1.link_socket_addr, !c->options.resolve_in_advance);
+ }
+
+ /* Clear the remote actual address when persist_remote_ip is not in use */
+ if (!(c->sig->signal_received == SIGUSR1 && c->options.persist_remote_ip))
CLEAR (c->c1.link_socket_addr.actual);
- }
- if (!(c->sig->signal_received == SIGUSR1 && c->options.persist_local_ip))
- CLEAR (c->c1.link_socket_addr.local);
+ if (!(c->sig->signal_received == SIGUSR1 && c->options.persist_local_ip)) {
+ if (c->c1.link_socket_addr.bind_local && !c->options.resolve_in_advance)
+ freeaddrinfo(c->c1.link_socket_addr.bind_local);
+
+ c->c1.link_socket_addr.bind_local=NULL;
+ }
}
/*
@@ -2916,7 +3040,7 @@ static void
do_close_packet_id (struct context *c)
{
#ifdef ENABLE_CRYPTO
- packet_id_free (&c->c2.packet_id);
+ packet_id_free (&c->c2.crypto_options.packet_id);
packet_id_persist_save (&c->c1.pid_persist);
if (!(c->sig->signal_received == SIGUSR1))
packet_id_persist_close (&c->c1.pid_persist);
@@ -3070,7 +3194,7 @@ do_setup_fast_io (struct context *c)
{
if (c->options.fast_io)
{
-#ifdef WIN32
+#ifdef _WIN32
msg (M_INFO, "NOTE: --fast-io is disabled since we are running on Windows");
#else
if (!proto_is_udp(c->options.ce.proto))
@@ -3093,7 +3217,7 @@ do_setup_fast_io (struct context *c)
static void
do_signal_on_tls_errors (struct context *c)
{
-#if defined(ENABLE_CRYPTO) && defined(ENABLE_SSL)
+#ifdef ENABLE_CRYPTO
if (c->options.tls_exit)
c->c2.tls_exit_signal = SIGTERM;
else
@@ -3183,7 +3307,7 @@ management_callback_status_p2p (void *arg, const int version, struct status_outp
void
management_show_net_callback (void *arg, const int msglevel)
{
-#ifdef WIN32
+#ifdef _WIN32
show_routes (msglevel);
show_adapters (msglevel);
msg (msglevel, "END");
@@ -3192,6 +3316,37 @@ management_show_net_callback (void *arg, const int msglevel)
#endif
}
+#ifdef TARGET_ANDROID
+int
+management_callback_network_change (void *arg, bool samenetwork)
+{
+ /* Check if the client should translate the network change to a SIGUSR1 to
+ reestablish the connection or just reprotect the socket
+
+ At the moment just assume that, for all settings that use pull (not
+ --static) and are not using peer-id reestablishing the connection is
+ required (unless the network is the same)
+
+ The function returns -1 on invalid fd and -2 if the socket cannot be
+ reused. On the -2 return value the man_network_change function triggers
+ a SIGUSR1 to force a reconnect.
+ */
+
+ int socketfd=-1;
+ struct context *c = (struct context *) arg;
+ if (!c->c2.link_socket)
+ return -1;
+ if (c->c2.link_socket->sd == SOCKET_UNDEFINED)
+ return -1;
+
+ socketfd = c->c2.link_socket->sd;
+ if (!c->options.pull || c->c2.tls_multi->use_peer_id || samenetwork)
+ return socketfd;
+ else
+ return -2;
+}
+#endif
+
#endif
void
@@ -3207,6 +3362,9 @@ init_management_callback_p2p (struct context *c)
cb.show_net = management_show_net_callback;
cb.proxy_cmd = management_callback_proxy_cmd;
cb.remote_cmd = management_callback_remote_cmd;
+#ifdef TARGET_ANDROID
+ cb.network_change = management_callback_network_change;
+#endif
management_set_callback (management, &cb);
}
#endif
@@ -3248,12 +3406,14 @@ open_management (struct context *c)
management_set_state (management,
OPENVPN_STATE_CONNECTING,
NULL,
- (in_addr_t)0,
- (in_addr_t)0);
+ NULL,
+ NULL,
+ NULL,
+ NULL);
}
/* initial management hold, called early, before first context initialization */
- do_hold ();
+ do_hold (0);
if (IS_SIG (c))
{
msg (M_WARN, "Signal received from management interface, exiting");
@@ -3326,10 +3486,14 @@ init_instance (struct context *c, const struct env_set *env, const unsigned int
/* init garbage collection level */
gc_init (&c->c2.gc);
+ /* inherit environmental variables */
+ if (env)
+ do_inherit_env (c, env);
+
/* signals caught here will abort */
c->sig->signal_received = 0;
c->sig->signal_text = NULL;
- c->sig->hard = false;
+ c->sig->source = SIG_SOURCE_SOFT;
if (c->mode == CM_P2P)
init_management_callback_p2p (c);
@@ -3342,14 +3506,20 @@ init_instance (struct context *c, const struct env_set *env, const unsigned int
goto sig;
}
+ if (c->options.resolve_in_advance)
+ {
+ do_preresolve (c);
+ if (IS_SIG (c))
+ goto sig;
+ }
+
/* map in current connection entry */
next_connection_entry (c);
/* link_socket_mode allows CM_CHILD_TCP
instances to inherit acceptable fds
from a top-level parent */
- if (c->options.ce.proto == PROTO_TCPv4_SERVER
- || c->options.ce.proto == PROTO_TCPv6_SERVER)
+ if (c->options.ce.proto == PROTO_TCP_SERVER)
{
if (c->mode == CM_TOP)
link_socket_mode = LS_MODE_TCP_LISTEN;
@@ -3378,10 +3548,6 @@ init_instance (struct context *c, const struct env_set *env, const unsigned int
if (c->mode == CM_P2P || c->mode == CM_TOP)
do_option_warnings (c);
- /* inherit environmental variables */
- if (env)
- do_inherit_env (c, env);
-
#ifdef ENABLE_PLUGIN
/* initialize plugins */
if (c->mode == CM_P2P || c->mode == CM_TOP)
@@ -3416,7 +3582,7 @@ init_instance (struct context *c, const struct env_set *env, const unsigned int
do_event_set_init (c, false);
/* initialize HTTP or SOCKS proxy object at scope level 2 */
- init_proxy (c, 2);
+ init_proxy (c);
/* allocate our socket object */
if (c->mode == CM_P2P || c->mode == CM_TOP || c->mode == CM_CHILD_TCP)
@@ -3442,10 +3608,10 @@ init_instance (struct context *c, const struct env_set *env, const unsigned int
goto sig;
}
-#ifdef ENABLE_LZO
- /* initialize LZO compression library. */
- if ((options->lzo & LZO_SELECTED) && (c->mode == CM_P2P || child))
- lzo_compress_init (&c->c2.lzo_compwork, options->lzo);
+#ifdef USE_COMP
+ /* initialize compression library. */
+ if (comp_enabled(&options->comp) && (c->mode == CM_P2P || child))
+ c->c2.comp_context = comp_init (&options->comp);
#endif
/* initialize MTU variables */
@@ -3465,7 +3631,7 @@ init_instance (struct context *c, const struct env_set *env, const unsigned int
#endif
/* initialize dynamic MTU variable */
- do_init_mssfix (c);
+ frame_init_mssfix (&c->c2.frame, &c->options);
/* bind the TCP/UDP socket */
if (c->mode == CM_P2P || c->mode == CM_TOP || c->mode == CM_CHILD_TCP)
@@ -3498,16 +3664,19 @@ init_instance (struct context *c, const struct env_set *env, const unsigned int
open_plugins (c, false, OPENVPN_PLUGIN_INIT_POST_DAEMON);
#endif
+ /* initialise connect timeout timer */
+ do_init_server_poll_timeout(c);
+
+ /* finalize the TCP/UDP socket */
+ if (c->mode == CM_P2P || c->mode == CM_TOP || c->mode == CM_CHILD_TCP)
+ do_init_socket_2 (c);
+
/*
* Actually do UID/GID downgrade, and chroot, if requested.
* May be delayed by --client, --pull, or --up-delay.
*/
do_uid_gid_chroot (c, c->c2.did_open_tun);
- /* finalize the TCP/UDP socket */
- if (c->mode == CM_P2P || c->mode == CM_TOP || c->mode == CM_CHILD_TCP)
- do_init_socket_2 (c);
-
/* initialize timers */
if (c->mode == CM_P2P || child)
do_init_timers (c, false);
@@ -3559,9 +3728,12 @@ close_instance (struct context *c)
/* if xinetd/inetd mode, don't allow restart */
do_close_check_if_restart_permitted (c);
-#ifdef ENABLE_LZO
- if (lzo_defined (&c->c2.lzo_compwork))
- lzo_compress_uninit (&c->c2.lzo_compwork);
+#ifdef USE_COMP
+ if (c->c2.comp_context)
+ {
+ comp_uninit (c->c2.comp_context);
+ c->c2.comp_context = NULL;
+ }
#endif
/* free buffers */
@@ -3636,11 +3808,14 @@ inherit_context_child (struct context *dest,
#ifdef ENABLE_CRYPTO
dest->c1.ks.key_type = src->c1.ks.key_type;
-#ifdef ENABLE_SSL
/* inherit SSL context */
dest->c1.ks.ssl_ctx = src->c1.ks.ssl_ctx;
- dest->c1.ks.tls_auth_key = src->c1.ks.tls_auth_key;
-#endif
+ dest->c1.ks.tls_wrap_key = src->c1.ks.tls_wrap_key;
+ dest->c1.ks.tls_auth_key_type = src->c1.ks.tls_auth_key_type;
+ /* inherit pre-NCP ciphers */
+ dest->c1.ciphername = src->c1.ciphername;
+ dest->c1.authname = src->c1.authname;
+ dest->c1.keysize = src->c1.keysize;
#endif
/* options */
@@ -3713,7 +3888,7 @@ inherit_context_top (struct context *dest,
/* detach plugins */
dest->plugins_owned = false;
-#if defined(ENABLE_CRYPTO) && defined(ENABLE_SSL)
+#ifdef ENABLE_CRYPTO
dest->c2.tls_multi = NULL;
#endif
@@ -3733,6 +3908,10 @@ inherit_context_top (struct context *dest,
dest->c2.event_set = NULL;
if (proto_is_dgram(src->options.ce.proto))
do_event_set_init (dest, false);
+
+#ifdef USE_COMP
+ dest->c2.comp_context = NULL;
+#endif
}
void
@@ -3747,8 +3926,11 @@ close_context (struct context *c, int sig, unsigned int flags)
if (c->sig->signal_received == SIGUSR1)
{
if ((flags & CC_USR1_TO_HUP)
- || (c->sig->hard && (flags & CC_HARD_USR1_TO_HUP)))
- c->sig->signal_received = SIGHUP;
+ || (c->sig->source == SIG_SOURCE_HARD && (flags & CC_HARD_USR1_TO_HUP)))
+ {
+ c->sig->signal_received = SIGHUP;
+ c->sig->signal_text = "close_context usr1 to hup";
+ }
}
if (!(flags & CC_NO_CLOSE))
@@ -3773,6 +3955,7 @@ test_crypto_thread (void *arg)
ASSERT (options->test_crypto);
init_verb_mute (c, IVM_LEVEL_1);
context_init_1 (c);
+ next_connection_entry(c);
do_init_crypto_static (c, 0);
frame_finalize_options (c, options);
@@ -3780,13 +3963,13 @@ test_crypto_thread (void *arg)
test_crypto (&c->c2.crypto_options, &c->c2.frame);
key_schedule_free (&c->c1.ks, true);
- packet_id_free (&c->c2.packet_id);
+ packet_id_free (&c->c2.crypto_options.packet_id);
context_gc_free (c);
return NULL;
}
-#endif
+#endif /* ENABLE_CRYPTO */
bool
do_test_crypto (const struct options *o)
diff --git a/src/openvpn/init.h b/src/openvpn/init.h
index a819bd2..524bc64 100644
--- a/src/openvpn/init.h
+++ b/src/openvpn/init.h
@@ -81,7 +81,7 @@ bool do_test_crypto (const struct options *o);
void context_gc_free (struct context *c);
-void do_up (struct context *c,
+bool do_up (struct context *c,
bool pulled_options,
unsigned int option_types_found);
@@ -91,7 +91,7 @@ const char *format_common_name (struct context *c, struct gc_arena *gc);
void reset_coarse_timers (struct context *c);
-void do_deferred_options (struct context *c, const unsigned int found);
+bool do_deferred_options (struct context *c, const unsigned int found);
void inherit_context_child (struct context *dest,
const struct context *src);
diff --git a/src/openvpn/interval.h b/src/openvpn/interval.h
index 4814ec9..59eb1f6 100644
--- a/src/openvpn/interval.h
+++ b/src/openvpn/interval.h
@@ -186,6 +186,15 @@ event_timeout_modify_wakeup (struct event_timeout* et, interval_t n)
}
/*
+ * Will return the time left for a timeout, this function does not check
+ * if the timeout is actually valid
+ */
+static inline interval_t event_timeout_remaining (struct event_timeout* et)
+{
+ return (int) et->last + et->n - now;
+}
+
+/*
* This is the principal function for testing and triggering recurring
* timers and will return true on a timer signal event.
* If et_const_retry == ETT_DEFAULT and a signal occurs,
diff --git a/src/openvpn/lzo.c b/src/openvpn/lzo.c
index 195b819..25a839b 100644
--- a/src/openvpn/lzo.c
+++ b/src/openvpn/lzo.c
@@ -34,15 +34,14 @@
#include "syshead.h"
-#ifdef ENABLE_LZO
+#if defined(ENABLE_LZO)
-#include "lzo.h"
+#include "comp.h"
#include "error.h"
#include "otime.h"
#include "memdbg.h"
-#ifndef ENABLE_LZO_STUB
/**
* Perform adaptive compression housekeeping.
*
@@ -97,101 +96,69 @@ lzo_adaptive_compress_data (struct lzo_adaptive_compress *ac, int n_total, int n
ac->n_comp += n_comp;
}
-#endif /* ENABLE_LZO_STUB */
-
-void lzo_adjust_frame_parameters (struct frame *frame)
-{
- /* Leave room for our one-byte compressed/didn't-compress prefix byte. */
- frame_add_to_extra_frame (frame, LZO_PREFIX_LEN);
-
- /* Leave room for compression buffer to expand in worst case scenario
- where data is totally uncompressible */
- frame_add_to_extra_buffer (frame, LZO_EXTRA_BUFFER (EXPANDED_SIZE(frame)));
-}
-
-void
-lzo_compress_init (struct lzo_compress_workspace *lzowork, unsigned int flags)
+static void
+lzo_compress_init (struct compress_context *compctx)
{
- CLEAR (*lzowork);
-
- lzowork->flags = flags;
-#ifndef ENABLE_LZO_STUB
- lzowork->wmem_size = LZO_WORKSPACE;
-
+ msg (D_INIT_MEDIUM, "LZO compression initializing");
+ ASSERT(!(compctx->flags & COMP_F_SWAP));
+ compctx->wu.lzo.wmem_size = LZO_WORKSPACE;
if (lzo_init () != LZO_E_OK)
msg (M_FATAL, "Cannot initialize LZO compression library");
- lzowork->wmem = (lzo_voidp) lzo_malloc (lzowork->wmem_size);
- check_malloc_return (lzowork->wmem);
- msg (D_INIT_MEDIUM, "LZO compression initialized");
-#else
- msg (D_INIT_MEDIUM, "LZO stub compression initialized");
-#endif
- lzowork->defined = true;
+ compctx->wu.lzo.wmem = (lzo_voidp) lzo_malloc (compctx->wu.lzo.wmem_size);
+ check_malloc_return (compctx->wu.lzo.wmem);
}
-void
-lzo_compress_uninit (struct lzo_compress_workspace *lzowork)
+static void
+lzo_compress_uninit (struct compress_context *compctx)
{
- if (lzowork)
- {
- ASSERT (lzowork->defined);
-#ifndef ENABLE_LZO_STUB
- lzo_free (lzowork->wmem);
- lzowork->wmem = NULL;
-#endif
- lzowork->defined = false;
- }
+ lzo_free (compctx->wu.lzo.wmem);
+ compctx->wu.lzo.wmem = NULL;
}
static inline bool
-lzo_compression_enabled (struct lzo_compress_workspace *lzowork)
+lzo_compression_enabled (struct compress_context *compctx)
{
-#ifndef ENABLE_LZO_STUB
- if ((lzowork->flags & (LZO_SELECTED|LZO_ON)) == (LZO_SELECTED|LZO_ON))
+ if (compctx->flags & COMP_F_ASYM)
+ return false;
+ else
{
- if (lzowork->flags & LZO_ADAPTIVE)
- return lzo_adaptive_compress_test (&lzowork->ac);
+ if (compctx->flags & COMP_F_ADAPTIVE)
+ return lzo_adaptive_compress_test (&compctx->wu.lzo.ac);
else
return true;
}
-#endif
- return false;
}
-void
+static void
lzo_compress (struct buffer *buf, struct buffer work,
- struct lzo_compress_workspace *lzowork,
+ struct compress_context *compctx,
const struct frame* frame)
{
-#ifndef ENABLE_LZO_STUB
lzo_uint zlen = 0;
int err;
bool compressed = false;
-#endif
-
- ASSERT (lzowork->defined);
if (buf->len <= 0)
return;
-#ifndef ENABLE_LZO_STUB
/*
* In order to attempt compression, length must be at least COMPRESS_THRESHOLD,
* and our adaptive level must give the OK.
*/
- if (buf->len >= COMPRESS_THRESHOLD && lzo_compression_enabled (lzowork))
+ if (buf->len >= COMPRESS_THRESHOLD && lzo_compression_enabled (compctx))
{
+ const size_t ps = PAYLOAD_SIZE (frame);
ASSERT (buf_init (&work, FRAME_HEADROOM (frame)));
- ASSERT (buf_safe (&work, LZO_EXTRA_BUFFER (PAYLOAD_SIZE (frame))));
+ ASSERT (buf_safe (&work, ps + COMP_EXTRA_BUFFER (ps)));
- if (!(buf->len <= PAYLOAD_SIZE (frame)))
+ if (buf->len > ps)
{
dmsg (D_COMP_ERRORS, "LZO compression buffer overflow");
buf->len = 0;
return;
}
- err = LZO_COMPRESS (BPTR (buf), BLEN (buf), BPTR (&work), &zlen, lzowork->wmem);
+ err = LZO_COMPRESS (BPTR (buf), BLEN (buf), BPTR (&work), &zlen, compctx->wu.lzo.wmem);
if (err != LZO_E_OK)
{
dmsg (D_COMP_ERRORS, "LZO compression error: %d", err);
@@ -203,43 +170,38 @@ lzo_compress (struct buffer *buf, struct buffer work,
work.len = zlen;
compressed = true;
- dmsg (D_COMP, "compress %d -> %d", buf->len, work.len);
- lzowork->pre_compress += buf->len;
- lzowork->post_compress += work.len;
+ dmsg (D_COMP, "LZO compress %d -> %d", buf->len, work.len);
+ compctx->pre_compress += buf->len;
+ compctx->post_compress += work.len;
/* tell adaptive level about our success or lack thereof in getting any size reduction */
- if (lzowork->flags & LZO_ADAPTIVE)
- lzo_adaptive_compress_data (&lzowork->ac, buf->len, work.len);
+ if (compctx->flags & COMP_F_ADAPTIVE)
+ lzo_adaptive_compress_data (&compctx->wu.lzo.ac, buf->len, work.len);
}
/* did compression save us anything ? */
if (compressed && work.len < buf->len)
{
uint8_t *header = buf_prepend (&work, 1);
- *header = YES_COMPRESS;
+ *header = LZO_COMPRESS_BYTE;
*buf = work;
}
else
-#endif
{
uint8_t *header = buf_prepend (buf, 1);
- *header = NO_COMPRESS;
+ *header = NO_COMPRESS_BYTE;
}
}
-void
+static void
lzo_decompress (struct buffer *buf, struct buffer work,
- struct lzo_compress_workspace *lzowork,
+ struct compress_context *compctx,
const struct frame* frame)
{
-#ifndef ENABLE_LZO_STUB
lzo_uint zlen = EXPANDED_SIZE (frame);
int err;
-#endif
uint8_t c; /* flag indicating whether or not our peer compressed */
- ASSERT (lzowork->defined);
-
if (buf->len <= 0)
return;
@@ -248,12 +210,11 @@ lzo_decompress (struct buffer *buf, struct buffer work,
c = *BPTR (buf);
ASSERT (buf_advance (buf, 1));
- if (c == YES_COMPRESS) /* packet was compressed */
+ if (c == LZO_COMPRESS_BYTE) /* packet was compressed */
{
-#ifndef ENABLE_LZO_STUB
ASSERT (buf_safe (&work, zlen));
err = LZO_DECOMPRESS (BPTR (buf), BLEN (buf), BPTR (&work), &zlen,
- lzowork->wmem);
+ compctx->wu.lzo.wmem);
if (err != LZO_E_OK)
{
dmsg (D_COMP_ERRORS, "LZO decompression error: %d", err);
@@ -264,18 +225,13 @@ lzo_decompress (struct buffer *buf, struct buffer work,
ASSERT (buf_safe (&work, zlen));
work.len = zlen;
- dmsg (D_COMP, "decompress %d -> %d", buf->len, work.len);
- lzowork->pre_decompress += buf->len;
- lzowork->post_decompress += work.len;
+ dmsg (D_COMP, "LZO decompress %d -> %d", buf->len, work.len);
+ compctx->pre_decompress += buf->len;
+ compctx->post_decompress += work.len;
*buf = work;
-#else
- dmsg (D_COMP_ERRORS, "LZO decompression error: LZO capability not compiled");
- buf->len = 0;
- return;
-#endif
}
- else if (c == NO_COMPRESS) /* packet was not compressed */
+ else if (c == NO_COMPRESS_BYTE) /* packet was not compressed */
{
;
}
@@ -286,24 +242,13 @@ lzo_decompress (struct buffer *buf, struct buffer work,
}
}
-void
-lzo_modify_flags (struct lzo_compress_workspace *lzowork, unsigned int flags)
-{
- ASSERT (lzowork->defined);
- lzowork->flags = flags;
-}
-
-void lzo_print_stats (const struct lzo_compress_workspace *lzo_compwork, struct status_output *so)
-{
- ASSERT (lzo_compwork->defined);
-
-#ifndef ENABLE_LZO_STUB
- status_printf (so, "pre-compress bytes," counter_format, lzo_compwork->pre_compress);
- status_printf (so, "post-compress bytes," counter_format, lzo_compwork->post_compress);
- status_printf (so, "pre-decompress bytes," counter_format, lzo_compwork->pre_decompress);
- status_printf (so, "post-decompress bytes," counter_format, lzo_compwork->post_decompress);
-#endif
-}
+const struct compress_alg lzo_alg = {
+ "lzo",
+ lzo_compress_init,
+ lzo_compress_uninit,
+ lzo_compress,
+ lzo_decompress
+};
#else
static void dummy(void) {}
diff --git a/src/openvpn/lzo.h b/src/openvpn/lzo.h
index 472204d..f33e587 100644
--- a/src/openvpn/lzo.h
+++ b/src/openvpn/lzo.h
@@ -32,14 +32,13 @@
*/
-#ifdef ENABLE_LZO
+#if defined(ENABLE_LZO)
/**
* @addtogroup compression
* @{
*/
-#ifndef ENABLE_LZO_STUB
#if defined(HAVE_LZO_LZOUTIL_H)
#include "lzo/lzoutil.h"
#elif defined(HAVE_LZOUTIL_H)
@@ -50,28 +49,16 @@
#elif defined(HAVE_LZO1X_H)
#include "lzo1x.h"
#endif
-#endif
#include "buffer.h"
#include "mtu.h"
#include "common.h"
#include "status.h"
-/**************************************************************************/
-/** @name Bit-flags which control data channel packet compression *//******/
-/** @{ */
-#define LZO_SELECTED (1<<0) /**< Bit-flag indicating that compression
- * of data channel packets is enabled. */
-#define LZO_ON (1<<1) /**< Bit-flag indicating that compression
- * of data channel packets is active. */
-#define LZO_ADAPTIVE (1<<2) /**< Bit-flag indicating that adaptive
- * compression of data channel packets
- * has been selected. */
-/** @} name Bit-flags which control data channel packet compression *//****/
+extern const struct compress_alg lzo_alg;
/**************************************************************************/
/** @name LZO library interface defines *//** @{ *//***********************/
-#ifndef ENABLE_LZO_STUB
#define LZO_COMPRESS lzo1x_1_15_compress
/**< LZO library compression function.
*
@@ -93,36 +80,11 @@
* verify the integrity of incoming
* packets, you might want to consider
* using the non-safe version. */
-#endif /* ENABLE_LZO_STUB */
/** @} name LZO library interface *//**************************************/
/**************************************************************************/
-/** @name Miscellaneous compression defines *//** @{ *//*******************/
-#define LZO_EXTRA_BUFFER(len) ((len)/8 + 128 + 3)
- /**< LZO 2.0 worst-case size expansion. */
-#ifndef ENABLE_LZO_STUB
-#define COMPRESS_THRESHOLD 100 /**< Minimum packet size to attempt
- * compression. */
-#endif /* ENABLE_LZO_STUB */
-/** @} name Miscellaneous compression defines *//**************************/
-
-
-/**************************************************************************/
-/** @name Compression header defines *//** @{ *//**************************/
-#define LZO_PREFIX_LEN 1 /**< Length in bytes of prepended
- * compression header. */
-#define YES_COMPRESS 0x66 /**< Single-byte compression header
- * indicating this packet has been
- * compressed. */
-#define NO_COMPRESS 0xFA /**< Single-byte compression header
- * indicating this packet has not been
- * compressed. */
-/** @} name Compression header defines *//*********************************/
-
-/**************************************************************************/
/** @name Adaptive compression defines *//** @{ *//************************/
-#ifndef ENABLE_LZO_STUB
#define AC_SAMP_SEC 2 /**< Number of seconds in a sample period. */
#define AC_MIN_BYTES 1000 /**< Minimum number of bytes a sample
* period must contain for it to be
@@ -132,11 +94,8 @@
* turned off. */
#define AC_OFF_SEC 60 /**< Seconds to wait after compression has
* been turned off before retesting. */
-#endif /* ENABLE_LZO_STUB */
/** @} name Adaptive compression defines *//*******************************/
-#ifndef ENABLE_LZO_STUB
-
/**
* Adaptive compression state.
*/
@@ -147,8 +106,6 @@ struct lzo_adaptive_compress {
int n_comp;
};
-#endif /* ENABLE_LZO_STUB */
-
/**
* State for the compression and decompression routines.
@@ -162,186 +119,13 @@ struct lzo_adaptive_compress {
*/
struct lzo_compress_workspace
{
- bool defined;
- unsigned int flags;
-#ifndef ENABLE_LZO_STUB
lzo_voidp wmem;
int wmem_size;
struct lzo_adaptive_compress ac;
-
- /* statistics */
- counter_type pre_decompress;
- counter_type post_decompress;
- counter_type pre_compress;
- counter_type post_compress;
-#endif
};
-
-/**************************************************************************/
-/** @name Functions for initialization and cleanup *//** @{ *//************/
-
-/**
- * Adjust %frame parameters for data channel payload compression.
- *
- * Data channel packet compression requires a single-byte header to
- * indicate whether a packet has been compressed or not. The packet
- * handling buffers must also allow for worst-case payload compression
- * where the compressed content size is actually larger than the original
- * content size. This function adjusts the parameters of a given frame
- * structure to include the header and allow for worst-case compression
- * expansion.
- *
- * @param frame - The frame structure to adjust.
- */
-void lzo_adjust_frame_parameters(struct frame *frame);
-
-/**
- * Initialize a compression workspace structure.
- *
- * This function initializes the given workspace structure \a lzowork.
- * This includes allocating a work buffer for internal use and setting its
- * flags to the given value of \a flags.
- *
- * This function also initializes the lzo library.
- *
- * @param lzowork - A pointer to the workspace structure to
- * initialize.
- * @param flags - The initial flags to set in the workspace
- * structure.
- */
-void lzo_compress_init (struct lzo_compress_workspace *lzowork, unsigned int flags);
-
-/**
- * Cleanup a compression workspace structure.
- *
- * This function cleans up the given workspace structure \a lzowork. This
- * includes freeing the structure's internal work buffer.
- *
- * @param lzowork - A pointer to the workspace structure to clean up.
- */
-void lzo_compress_uninit (struct lzo_compress_workspace *lzowork);
-
-/**
- * Set a workspace structure's flags.
- *
- * @param lzowork - The workspace structure of which to modify the
- * flags.
- * @param flags - The new value to assign to the workspace
- * structure's flags.
- */
-void lzo_modify_flags (struct lzo_compress_workspace *lzowork, unsigned int flags);
-
-/** @} name Functions for initialization and cleanup *//*******************/
-
-
-/**************************************************************************/
-/** @name Function for packets to be sent to a remote OpenVPN peer *//*****/
-/** @{ */
-
-/**
- * Process an outgoing packet according to a VPN tunnel's settings.
- * @ingroup compression
- *
- * This function processes the packet contained in \a buf. Its behavior
- * depends on the settings contained within \a lzowork. If compression is
- * enabled and active, this function compresses the packet. After
- * compression, the size of the uncompressed and compressed packets are
- * compared, and the smallest is used.
- *
- * This function prepends a one-byte header indicating whether the packet
- * was or was not compressed, so as to let the peer know how to handle the
- * packet.
- *
- * If an error occurs during processing, an error message is logged and
- * the length of \a buf is set to zero.
- *
- * @param buf - A pointer to the buffer containing the outgoing
- * packet. This pointer will be modified to point
- * to the processed packet on return.
- * @param work - A preallocated working buffer.
- * @param lzowork - The compression workspace structure associated
- * with this VPN tunnel.
- * @param frame - The frame parameters of this tunnel.
- *
- * @return Void.\n On return, \a buf will point to a buffer containing
- * the processed, possibly compressed, packet data with a compression
- * header prepended.
- */
-void lzo_compress (struct buffer *buf, struct buffer work,
- struct lzo_compress_workspace *lzowork,
- const struct frame* frame);
-
-/** @} name Function for packets to be sent to a remote OpenVPN peer *//***/
-
-
-/**************************************************************************/
-/** @name Function for packets received from a remote OpenVPN peer *//*****/
-/** @{ */
-
-/**
- * Inspect an incoming packet and decompress if it is compressed.
- *
- * This function inspects the incoming packet contained in \a buf. If its
- * one-byte compression header indicates that it was compressed (i.e. \c
- * YES_COMPRESS), then it will be decompressed. If its header indicates
- * that it was not compressed (i.e. \c NO_COMPRESS), then the buffer is
- * not modified except for removing the compression header.
- *
- * If an error occurs during processing, for example if the compression
- * header has a value other than \c YES_COMPRESS or \c NO_COMPRESS, then
- * the error is logged and the length of \a buf is set to zero.
- *
- * @param buf - A pointer to the buffer containing the incoming
- * packet. This pointer will be modified to point
- * to the processed packet on return.
- * @param work - A preallocated working buffer.
- * @param lzowork - The compression workspace structure associated
- * with this VPN tunnel.
- * @param frame - The frame parameters of this tunnel.
- *
- * @return Void.\n On return, \a buf will point to a buffer containing
- * the uncompressed packet data and the one-byte compression header
- * will have been removed.
- */
-void lzo_decompress (struct buffer *buf, struct buffer work,
- struct lzo_compress_workspace *lzowork,
- const struct frame* frame);
-
-/** @} name Function for packets received from a remote OpenVPN peer *//***/
-
-
-/**************************************************************************/
-/** @name Utility functions *//** @{ *//***********************************/
-
-/**
- * Print statistics on compression and decompression performance.
- *
- * @param lzo_compwork - The workspace structure from which to get the
- * statistics.
- * @param so - The status output structure to which to write the
- * statistics.
- */
-void lzo_print_stats (const struct lzo_compress_workspace *lzo_compwork, struct status_output *so);
-
-/**
- * Check whether compression is enabled for a workspace structure.
- *
- * @param lzowork - The workspace structure to check.
- *
- * @return true if compression is enabled; false otherwise.
- */
-static inline bool
-lzo_defined (const struct lzo_compress_workspace *lzowork)
-{
- return lzowork->defined;
-}
-
-/** @} name Utility functions *//******************************************/
-
-
/** @} addtogroup compression */
-#endif /* ENABLE_LZO */
+#endif /* ENABLE_LZO && USE_COMP */
#endif
diff --git a/src/openvpn/manage.c b/src/openvpn/manage.c
index 0a4542a..77a8006 100644
--- a/src/openvpn/manage.c
+++ b/src/openvpn/manage.c
@@ -113,6 +113,8 @@ man_help ()
#ifdef MANAGMENT_EXTERNAL_KEY
msg (M_CLIENT, "rsa-sig : Enter an RSA signature in response to >RSA_SIGN challenge");
msg (M_CLIENT, " Enter signature base64 on subsequent lines followed by END");
+ msg (M_CLIENT, "certificate : Enter a client certificate in response to >NEED-CERT challenge");
+ msg (M_CLIENT, " Enter certificate base64 on subsequent lines followed by END");
#endif
msg (M_CLIENT, "signal s : Send signal s to daemon,");
msg (M_CLIENT, " s = SIGHUP|SIGTERM|SIGUSR1|SIGUSR2.");
@@ -268,7 +270,7 @@ man_delete_unix_socket (struct management *man)
static void
man_close_socket (struct management *man, const socket_descriptor_t sd)
{
-#ifndef WIN32
+#ifndef _WIN32
/*
* Windows doesn't need this because the ne32 event is permanently
* enabled at struct management scope.
@@ -701,7 +703,7 @@ man_query_need_str (struct management *man, const char *type, const char *action
static void
man_forget_passwords (struct management *man)
{
-#if defined(ENABLE_CRYPTO) && defined(ENABLE_SSL)
+#ifdef ENABLE_CRYPTO
ssl_purge_auth (false);
msg (M_CLIENT, "SUCCESS: Passwords were forgotten");
#endif
@@ -868,6 +870,12 @@ in_extra_dispatch (struct management *man)
man->connection.ext_key_input = man->connection.in_extra;
man->connection.in_extra = NULL;
return;
+ case IEC_CERTIFICATE:
+ man->connection.ext_cert_state = EKS_READY;
+ buffer_list_free (man->connection.ext_cert_input);
+ man->connection.ext_cert_input = man->connection.in_extra;
+ man->connection.in_extra = NULL;
+ return;
#endif
}
in_extra_reset (&man->connection, IER_RESET);
@@ -1030,6 +1038,20 @@ man_rsa_sig (struct management *man)
msg (M_CLIENT, "ERROR: The rsa-sig command is not currently available");
}
+static void
+man_certificate (struct management *man)
+{
+ struct man_connection *mc = &man->connection;
+ if (mc->ext_cert_state == EKS_SOLICIT)
+ {
+ mc->ext_cert_state = EKS_INPUT;
+ mc->in_extra_cmd = IEC_CERTIFICATE;
+ in_extra_reset (mc, IER_NEW);
+ }
+ else
+ msg (M_CLIENT, "ERROR: The certificate command is not currently available");
+}
+
#endif
static void
@@ -1105,6 +1127,27 @@ man_remote (struct management *man, const char **p)
}
}
+#ifdef TARGET_ANDROID
+static void
+man_network_change (struct management *man, bool samenetwork)
+{
+ /* Called to signal the OpenVPN that the network configuration has changed and
+ the client should either float or reconnect.
+
+ The code is currently only used by ics-openvpn
+ */
+ if (man->persist.callback.network_change)
+ {
+ int fd = (*man->persist.callback.network_change)
+ (man->persist.callback.arg, samenetwork);
+ man->connection.fdtosend = fd;
+ msg (M_CLIENT, "PROTECTFD: fd '%d' sent to be protected", fd);
+ if (fd == -2)
+ man_signal (man, "SIGUSR1");
+ }
+}
+#endif
+
static void
man_dispatch_command (struct management *man, struct status_output *so, const char **p, const int nparms)
{
@@ -1148,6 +1191,16 @@ man_dispatch_command (struct management *man, struct status_output *so, const ch
if (man_need (man, p, 1, 0))
man_signal (man, p[1]);
}
+#ifdef TARGET_ANDROID
+ else if (streq (p[0], "network-change"))
+ {
+ bool samenetwork = false;
+ if (p[1] && streq(p[1], "samenetwork"))
+ samenetwork = true;
+
+ man_network_change(man, samenetwork);
+ }
+#endif
else if (streq (p[0], "load-stats"))
{
man_load_stats (man);
@@ -1311,6 +1364,10 @@ man_dispatch_command (struct management *man, struct status_output *so, const ch
{
man_rsa_sig (man);
}
+ else if (streq (p[0], "certificate"))
+ {
+ man_certificate (man);
+ }
#endif
#ifdef ENABLE_PKCS11
else if (streq (p[0], "pkcs11-id-count"))
@@ -1356,7 +1413,7 @@ man_dispatch_command (struct management *man, struct status_output *so, const ch
gc_free (&gc);
}
-#ifdef WIN32
+#ifdef _WIN32
static void
man_start_ne32 (struct management *man)
@@ -1446,7 +1503,7 @@ man_new_connection_post (struct management *man, const char *description)
man_connection_settings_reset (man);
-#ifdef WIN32
+#ifdef _WIN32
man_start_ne32 (man);
#endif
@@ -1461,7 +1518,7 @@ man_new_connection_post (struct management *man, const char *description)
#endif
msg (D_MANAGEMENT, "MANAGEMENT: %s %s",
description,
- print_sockaddr (&man->settings.local, &gc));
+ print_sockaddr (man->settings.local->ai_addr, &gc));
buffer_list_reset (man->connection.out);
@@ -1533,7 +1590,7 @@ man_accept (struct management *man)
if (socket_defined (man->connection.sd_top))
{
-#ifdef WIN32
+#ifdef _WIN32
man_stop_ne32 (man);
#endif
}
@@ -1568,8 +1625,9 @@ man_listen (struct management *man)
else
#endif
{
- man->connection.sd_top = create_socket_tcp (AF_INET);
- socket_bind (man->connection.sd_top, &man->settings.local, "MANAGEMENT");
+ man->connection.sd_top = create_socket_tcp (man->settings.local);
+ socket_bind (man->connection.sd_top, man->settings.local,
+ man->settings.local->ai_family, "MANAGEMENT", false);
}
/*
@@ -1593,10 +1651,10 @@ man_listen (struct management *man)
else
#endif
msg (D_MANAGEMENT, "MANAGEMENT: TCP Socket listening on %s",
- print_sockaddr (&man->settings.local, &gc));
+ print_sockaddr (man->settings.local->ai_addr, &gc));
}
-#ifdef WIN32
+#ifdef _WIN32
man_start_ne32 (man);
#endif
@@ -1634,9 +1692,9 @@ man_connect (struct management *man)
else
#endif
{
- man->connection.sd_cli = create_socket_tcp (AF_INET);
+ man->connection.sd_cli = create_socket_tcp (man->settings.local);
status = openvpn_connect (man->connection.sd_cli,
- &man->settings.local,
+ man->settings.local->ai_addr,
5,
&signal_received);
}
@@ -1661,7 +1719,7 @@ man_connect (struct management *man)
#endif
msg (D_LINK_ERRORS,
"MANAGEMENT: connect to %s failed: %s",
- print_sockaddr (&man->settings.local, &gc),
+ print_sockaddr (man->settings.local->ai_addr, &gc),
strerror_ts (status, &gc));
throw_signal_soft (SIGTERM, "management-connect-failed");
goto done;
@@ -1679,7 +1737,7 @@ man_reset_client_socket (struct management *man, const bool exiting)
{
if (socket_defined (man->connection.sd_cli))
{
-#ifdef WIN32
+#ifdef _WIN32
man_stop_ne32 (man);
#endif
man_close_socket (man, man->connection.sd_cli);
@@ -1694,7 +1752,7 @@ man_reset_client_socket (struct management *man, const bool exiting)
}
if (!exiting)
{
-#if defined(ENABLE_CRYPTO) && defined(ENABLE_SSL)
+#ifdef ENABLE_CRYPTO
if (man->settings.flags & MF_FORGET_DISCONNECT)
ssl_purge_auth (false);
#endif
@@ -1779,6 +1837,120 @@ man_io_error (struct management *man, const char *prefix)
return false;
}
+#ifdef TARGET_ANDROID
+static ssize_t man_send_with_fd (int fd, void *ptr, size_t nbytes, int flags, int sendfd)
+{
+ struct msghdr msg;
+ struct iovec iov[1];
+
+ union {
+ struct cmsghdr cm;
+ char control[CMSG_SPACE(sizeof(int))];
+ } control_un;
+ struct cmsghdr *cmptr;
+
+ msg.msg_control = control_un.control;
+ msg.msg_controllen = sizeof(control_un.control);
+
+ cmptr = CMSG_FIRSTHDR(&msg);
+ cmptr->cmsg_len = CMSG_LEN(sizeof(int));
+ cmptr->cmsg_level = SOL_SOCKET;
+ cmptr->cmsg_type = SCM_RIGHTS;
+ *((int *) CMSG_DATA(cmptr)) = sendfd;
+
+ msg.msg_name = NULL;
+ msg.msg_namelen = 0;
+
+ iov[0].iov_base = ptr;
+ iov[0].iov_len = nbytes;
+ msg.msg_iov = iov;
+ msg.msg_iovlen = 1;
+
+ return (sendmsg(fd, &msg, flags));
+}
+
+static ssize_t man_recv_with_fd (int fd, void *ptr, size_t nbytes, int flags, int *recvfd)
+{
+ struct msghdr msghdr;
+ struct iovec iov[1];
+ ssize_t n;
+
+ union {
+ struct cmsghdr cm;
+ char control[CMSG_SPACE(sizeof (int))];
+ } control_un;
+ struct cmsghdr *cmptr;
+
+ msghdr.msg_control = control_un.control;
+ msghdr.msg_controllen = sizeof(control_un.control);
+
+ msghdr.msg_name = NULL;
+ msghdr.msg_namelen = 0;
+
+ iov[0].iov_base = ptr;
+ iov[0].iov_len = nbytes;
+ msghdr.msg_iov = iov;
+ msghdr.msg_iovlen = 1;
+
+ if ( (n = recvmsg(fd, &msghdr, flags)) <= 0)
+ return (n);
+
+ if ( (cmptr = CMSG_FIRSTHDR(&msghdr)) != NULL &&
+ cmptr->cmsg_len == CMSG_LEN(sizeof(int))) {
+ if (cmptr->cmsg_level != SOL_SOCKET)
+ msg (M_ERR, "control level != SOL_SOCKET");
+ if (cmptr->cmsg_type != SCM_RIGHTS)
+ msg (M_ERR, "control type != SCM_RIGHTS");
+ *recvfd = *((int *) CMSG_DATA(cmptr));
+ } else
+ *recvfd = -1; /* descriptor was not passed */
+
+ return (n);
+}
+
+/*
+ * The android control method will instruct the GUI part of openvpn to do
+ * the route/ifconfig/open tun command. See doc/android.txt for details.
+ */
+bool management_android_control (struct management *man, const char *command, const char *msg)
+{
+ struct user_pass up;
+ CLEAR(up);
+ strncpy (up.username, msg, sizeof(up.username)-1);
+
+ management_query_user_pass(management, &up , command, GET_USER_PASS_NEED_OK,(void*) 0);
+ return strcmp ("ok", up.password)==0;
+}
+
+/*
+ * In Android 4.4 it is not possible to open a new tun device and then close the
+ * old tun device without breaking the whole VPNService stack until the device
+ * is rebooted. This management method ask the UI what method should be taken to
+ * ensure the optimal solution for the situation
+ */
+int managment_android_persisttun_action (struct management *man)
+{
+ struct user_pass up;
+ CLEAR(up);
+ strcpy(up.username,"tunmethod");
+ management_query_user_pass(management, &up , "PERSIST_TUN_ACTION",
+ GET_USER_PASS_NEED_OK,(void*) 0);
+ if (!strcmp("NOACTION", up.password))
+ return ANDROID_KEEP_OLD_TUN;
+ else if (!strcmp ("OPEN_AFTER_CLOSE", up.password))
+ return ANDROID_OPEN_AFTER_CLOSE;
+ else if (!strcmp ("OPEN_BEFORE_CLOSE", up.password))
+ return ANDROID_OPEN_BEFORE_CLOSE;
+ else
+ msg (M_ERR, "Got unrecognised '%s' from management for PERSIST_TUN_ACTION query", up.password);
+
+ ASSERT(0);
+ return ANDROID_OPEN_AFTER_CLOSE;
+}
+
+
+#endif
+
static int
man_read (struct management *man)
{
@@ -1788,7 +1960,15 @@ man_read (struct management *man)
unsigned char buf[256];
int len = 0;
+#ifdef TARGET_ANDROID
+ int fd;
+ len = man_recv_with_fd (man->connection.sd_cli, buf, sizeof (buf), MSG_NOSIGNAL, &fd);
+ if(fd >= 0)
+ man->connection.lastfdreceived = fd;
+#else
len = recv (man->connection.sd_cli, buf, sizeof (buf), MSG_NOSIGNAL);
+#endif
+
if (len == 0)
{
man_reset_client_socket (man, false);
@@ -1865,6 +2045,13 @@ man_write (struct management *man)
if (buf && BLEN (buf))
{
const int len = min_int (size_hint, BLEN (buf));
+#ifdef TARGET_ANDROID
+ if (man->connection.fdtosend > 0)
+ {
+ sent = man_send_with_fd (man->connection.sd_cli, BPTR (buf), len, MSG_NOSIGNAL,man->connection.fdtosend);
+ man->connection.fdtosend = -1;
+ } else
+#endif
sent = send (man->connection.sd_cli, BPTR (buf), len, MSG_NOSIGNAL);
if (sent >= 0)
{
@@ -1957,7 +2144,7 @@ man_persist_close (struct man_persist *mp)
static void
man_settings_init (struct man_settings *ms,
const char *addr,
- const int port,
+ const char *port,
const char *pass_file,
const char *client_user,
const char *client_group,
@@ -2010,12 +2197,6 @@ man_settings_init (struct man_settings *ms,
else
#endif
{
- /*
- * Initialize socket address
- */
- ms->local.addr.in4.sin_family = AF_INET;
- ms->local.addr.in4.sin_addr.s_addr = 0;
- ms->local.addr.in4.sin_port = htons (port);
/*
* Run management over tunnel, or
@@ -2027,8 +2208,15 @@ man_settings_init (struct man_settings *ms,
}
else
{
- ms->local.addr.in4.sin_addr.s_addr = getaddr
- (GETADDR_RESOLVE|GETADDR_WARN_ON_SIGNAL|GETADDR_FATAL, addr, 0, NULL, NULL);
+ int status;
+ int resolve_flags = GETADDR_RESOLVE|GETADDR_WARN_ON_SIGNAL|GETADDR_FATAL;
+
+ if (! (flags & MF_CONNECT_AS_CLIENT))
+ resolve_flags |= GETADDR_PASSIVE;
+
+ status = openvpn_getaddrinfo (resolve_flags, addr, port, 0,
+ NULL, AF_UNSPEC, &ms->local);
+ ASSERT(status==0);
}
}
@@ -2054,6 +2242,8 @@ man_settings_init (struct man_settings *ms,
static void
man_settings_close (struct man_settings *ms)
{
+ if (ms->local)
+ freeaddrinfo(ms->local);
free (ms->write_peer_info_file);
CLEAR (*ms);
}
@@ -2064,7 +2254,7 @@ man_connection_init (struct management *man)
{
if (man->connection.state == MS_INITIAL)
{
-#ifdef WIN32
+#ifdef _WIN32
/*
* This object is a sort of TCP/IP helper
* for Windows.
@@ -2105,7 +2295,7 @@ man_connection_close (struct management *man)
if (mc->es)
event_free (mc->es);
-#ifdef WIN32
+#ifdef _WIN32
net_event_win32_close (&mc->ne32);
#endif
if (socket_defined (mc->sd_top))
@@ -2147,7 +2337,7 @@ management_init (void)
bool
management_open (struct management *man,
const char *addr,
- const int port,
+ const char *port,
const char *pass_file,
const char *client_user,
const char *client_group,
@@ -2232,8 +2422,10 @@ void
management_set_state (struct management *man,
const int state,
const char *detail,
- const in_addr_t tun_local_ip,
- const in_addr_t tun_remote_ip)
+ const in_addr_t *tun_local_ip,
+ const struct in6_addr *tun_local_ip6,
+ const struct openvpn_sockaddr *local,
+ const struct openvpn_sockaddr *remote)
{
if (man->persist.state && (!(man->settings.flags & MF_SERVER) || state < OPENVPN_STATE_CLIENT_BASE))
{
@@ -2246,9 +2438,15 @@ management_set_state (struct management *man,
e.timestamp = now;
e.u.state = state;
e.string = detail;
- e.local_ip = tun_local_ip;
- e.remote_ip = tun_remote_ip;
-
+ if (tun_local_ip)
+ e.local_ip = *tun_local_ip;
+ if (tun_local_ip6)
+ e.local_ip6 = *tun_local_ip6;
+ if (local)
+ e.local_sock = *local;
+ if (remote)
+ e.remote_sock = *remote;
+
log_history_add (man->persist.state, &e);
if (man->connection.state_realtime)
@@ -2361,33 +2559,6 @@ management_notify_generic (struct management *man, const char *str)
#ifdef MANAGEMENT_DEF_AUTH
-static bool
-validate_peer_info_line(const char *line)
-{
- uint8_t c;
- int state = 0;
- while ((c=*line++))
- {
- switch (state)
- {
- case 0:
- case 1:
- if (c == '=' && state == 1)
- state = 2;
- else if (isalnum(c) || c == '_')
- state = 1;
- else
- return false;
- case 2:
- if (isprint(c))
- ;
- else
- return false;
- }
- }
- return (state == 2);
-}
-
static void
man_output_peer_info_env (struct management *man, struct man_def_auth_context *mdac)
{
@@ -2426,7 +2597,8 @@ management_notify_client_needing_auth (struct management *management,
mode = "REAUTH";
msg (M_CLIENT, ">CLIENT:%s,%lu,%u", mode, mdac->cid, mda_key_id);
man_output_extra_env (management, "CLIENT");
- man_output_peer_info_env(management, mdac);
+ if (management->connection.env_filter_level>0)
+ man_output_peer_info_env(management, mdac);
man_output_env (es, true, management->connection.env_filter_level, "CLIENT");
mdac->flags |= DAF_INITIAL_AUTH;
}
@@ -2513,7 +2685,13 @@ management_post_tunnel_open (struct management *man, const in_addr_t tun_local_i
&& man->connection.state == MS_INITIAL)
{
/* listen on our local TUN/TAP IP address */
- man->settings.local.addr.in4.sin_addr.s_addr = htonl (tun_local_ip);
+ struct in_addr ia;
+ int ret;
+
+ ia.s_addr = htonl(tun_local_ip);
+ ret = openvpn_getaddrinfo(GETADDR_PASSIVE, inet_ntoa(ia), NULL, 0, NULL,
+ AF_INET, &man->settings.local);
+ ASSERT (ret==0);
man_connection_init (man);
}
@@ -2553,7 +2731,7 @@ man_persist_state (unsigned int *persistent, const int n)
return true;
}
-#ifdef WIN32
+#ifdef _WIN32
void
management_socket_set (struct management *man,
@@ -2845,7 +3023,8 @@ management_event_loop_n_seconds (struct management *man, int sec)
man_check_for_signals (&signal_received);
if (signal_received)
return;
- } while (expire);
+ update_time();
+ } while (expire && expire > now);
/* revert state */
man->persist.standalone_disabled = standalone_disabled_save;
@@ -2984,15 +3163,14 @@ management_query_user_pass (struct management *man,
#ifdef MANAGMENT_EXTERNAL_KEY
-char * /* returns allocated base64 signature */
-management_query_rsa_sig (struct management *man,
- const char *b64_data)
+int
+management_query_multiline (struct management *man,
+ const char *b64_data, const char *prompt, const char *cmd, int *state, struct buffer_list **input)
{
struct gc_arena gc = gc_new ();
- char *ret = NULL;
+ int ret = 0;
volatile int signal_received = 0;
struct buffer alert_msg = clear_buf();
- struct buffer *buf;
const bool standalone_disabled_save = man->persist.standalone_disabled;
struct man_connection *mc = &man->connection;
@@ -3001,10 +3179,15 @@ management_query_rsa_sig (struct management *man,
man->persist.standalone_disabled = false; /* This is so M_CLIENT messages will be correctly passed through msg() */
man->persist.special_state_msg = NULL;
- mc->ext_key_state = EKS_SOLICIT;
+ *state = EKS_SOLICIT;
- alert_msg = alloc_buf_gc (strlen(b64_data)+64, &gc);
- buf_printf (&alert_msg, ">RSA_SIGN:%s", b64_data);
+ if (b64_data) {
+ alert_msg = alloc_buf_gc (strlen(b64_data)+strlen(prompt)+3, &gc);
+ buf_printf (&alert_msg, ">%s:%s", prompt, b64_data);
+ } else {
+ alert_msg = alloc_buf_gc (strlen(prompt)+3, &gc);
+ buf_printf (&alert_msg, ">%s", prompt);
+ }
man_wait_for_client_connection (man, &signal_received, 0, MWCC_OTHER_WAIT);
@@ -3022,40 +3205,107 @@ management_query_rsa_sig (struct management *man,
man_check_for_signals (&signal_received);
if (signal_received)
goto done;
- } while (mc->ext_key_state != EKS_READY);
+ } while (*state != EKS_READY);
- if (buffer_list_defined(mc->ext_key_input))
- {
- buffer_list_aggregate (mc->ext_key_input, 2048);
- buf = buffer_list_peek (mc->ext_key_input);
- if (buf && BLEN(buf) > 0)
- {
- ret = (char *) malloc(BLEN(buf)+1);
- check_malloc_return(ret);
- memcpy(ret, buf->data, BLEN(buf));
- ret[BLEN(buf)] = '\0';
- }
- }
+ ret = 1;
}
done:
- if (mc->ext_key_state == EKS_READY && ret)
- msg (M_CLIENT, "SUCCESS: rsa-sig command succeeded");
- else if (mc->ext_key_state == EKS_INPUT || mc->ext_key_state == EKS_READY)
- msg (M_CLIENT, "ERROR: rsa-sig command failed");
+ if (*state == EKS_READY && ret)
+ msg (M_CLIENT, "SUCCESS: %s command succeeded", cmd);
+ else if (*state == EKS_INPUT || *state == EKS_READY)
+ msg (M_CLIENT, "ERROR: %s command failed", cmd);
/* revert state */
man->persist.standalone_disabled = standalone_disabled_save;
man->persist.special_state_msg = NULL;
in_extra_reset (mc, IER_RESET);
- mc->ext_key_state = EKS_UNDEF;
- buffer_list_free (mc->ext_key_input);
- mc->ext_key_input = NULL;
+ *state = EKS_UNDEF;
gc_free (&gc);
return ret;
}
+char * /* returns allocated base64 signature */
+management_query_multiline_flatten_newline (struct management *man,
+ const char *b64_data, const char *prompt, const char *cmd, int *state, struct buffer_list **input)
+{
+ int ok;
+ char *result = NULL;
+ struct buffer *buf;
+
+ ok = management_query_multiline(man, b64_data, prompt, cmd, state, input);
+ if (ok && buffer_list_defined(*input))
+ {
+ buffer_list_aggregate_separator (*input, 10000, "\n");
+ buf = buffer_list_peek (*input);
+ if (buf && BLEN(buf) > 0)
+ {
+ result = (char *) malloc(BLEN(buf)+1);
+ check_malloc_return(result);
+ memcpy(result, buf->data, BLEN(buf));
+ result[BLEN(buf)] = '\0';
+ }
+ }
+
+ buffer_list_free (*input);
+ *input = NULL;
+
+ return result;
+}
+
+char * /* returns allocated base64 signature */
+management_query_multiline_flatten (struct management *man,
+ const char *b64_data, const char *prompt, const char *cmd, int *state, struct buffer_list **input)
+{
+ int ok;
+ char *result = NULL;
+ struct buffer *buf;
+
+ ok = management_query_multiline(man, b64_data, prompt, cmd, state, input);
+ if (ok && buffer_list_defined(*input))
+ {
+ buffer_list_aggregate (*input, 2048);
+ buf = buffer_list_peek (*input);
+ if (buf && BLEN(buf) > 0)
+ {
+ result = (char *) malloc(BLEN(buf)+1);
+ check_malloc_return(result);
+ memcpy(result, buf->data, BLEN(buf));
+ result[BLEN(buf)] = '\0';
+ }
+ }
+
+ buffer_list_free (*input);
+ *input = NULL;
+
+ return result;
+}
+
+char * /* returns allocated base64 signature */
+management_query_rsa_sig (struct management *man,
+ const char *b64_data)
+{
+ return management_query_multiline_flatten(man, b64_data, "RSA_SIGN", "rsa-sign",
+ &man->connection.ext_key_state, &man->connection.ext_key_input);
+}
+
+
+char* management_query_cert (struct management *man, const char *cert_name)
+{
+ const char prompt_1[] = "NEED-CERTIFICATE:";
+ struct buffer buf_prompt = alloc_buf(strlen(cert_name) + 20);
+ buf_write(&buf_prompt, prompt_1, strlen(prompt_1));
+ buf_write(&buf_prompt, cert_name, strlen(cert_name)+1); // +1 for \0
+
+ char *result;
+ result = management_query_multiline_flatten_newline(management,
+ NULL, (char*)buf_bptr(&buf_prompt), "certificate",
+ &man->connection.ext_cert_state, &man->connection.ext_cert_input);
+ free_buf(&buf_prompt);
+ return result;
+}
+
#endif
/*
@@ -3082,12 +3332,13 @@ management_should_daemonize (struct management *man)
* Return true if the caller should not sleep for an additional time interval.
*/
bool
-management_hold (struct management *man)
+management_hold (struct management *man, int holdtime)
{
if (management_would_hold (man))
{
volatile int signal_received = 0;
const bool standalone_disabled_save = man->persist.standalone_disabled;
+ struct gc_arena gc = gc_new ();
man->persist.standalone_disabled = false; /* This is so M_CLIENT messages will be correctly passed through msg() */
man->persist.special_state_msg = NULL;
@@ -3097,7 +3348,9 @@ management_hold (struct management *man)
if (!signal_received)
{
- man->persist.special_state_msg = ">HOLD:Waiting for hold release";
+ struct buffer out = alloc_buf_gc (128, &gc);
+ buf_printf (&out, ">HOLD:Waiting for hold release:%d", holdtime);
+ man->persist.special_state_msg = BSTR (&out);
msg (M_CLIENT, "%s", man->persist.special_state_msg);
/* run command processing event loop until we get our username/password */
@@ -3116,6 +3369,7 @@ management_hold (struct management *man)
man->persist.special_state_msg = NULL;
man->settings.mansig &= ~MANSIG_IGNORE_USR1_HUP;
+ gc_free (&gc);
return true;
}
return false;
@@ -3218,7 +3472,14 @@ log_entry_print (const struct log_entry *e, unsigned int flags, struct gc_arena
if (flags & LOG_PRINT_LOCAL_IP)
buf_printf (&out, ",%s", print_in_addr_t (e->local_ip, IA_EMPTY_IF_UNDEF, gc));
if (flags & LOG_PRINT_REMOTE_IP)
- buf_printf (&out, ",%s", print_in_addr_t (e->remote_ip, IA_EMPTY_IF_UNDEF, gc));
+ {
+ buf_printf (&out, ",%s", (!addr_defined (&e->remote_sock) ? "," :
+ print_sockaddr_ex (&e->remote_sock.addr.sa, ",", PS_DONT_SHOW_FAMILY|PS_SHOW_PORT, gc)));
+ buf_printf (&out, ",%s", (!addr_defined (&e->local_sock) ? "," :
+ print_sockaddr_ex (&e->local_sock.addr.sa, ",", PS_DONT_SHOW_FAMILY|PS_SHOW_PORT, gc)));
+ }
+ if (flags & LOG_PRINT_LOCAL_IP && !IN6_IS_ADDR_UNSPECIFIED(&e->local_ip6))
+ buf_printf (&out, ",%s", print_in6_addr (e->local_ip6, IA_EMPTY_IF_UNDEF, gc));
if (flags & LOG_ECHO_TO_LOG)
msg (D_MANAGEMENT, "MANAGEMENT: %s", BSTR (&out));
if (flags & LOG_PRINT_CRLF)
diff --git a/src/openvpn/manage.h b/src/openvpn/manage.h
index 28da69f..3ffced0 100644
--- a/src/openvpn/manage.h
+++ b/src/openvpn/manage.h
@@ -88,7 +88,9 @@ struct log_entry
time_t timestamp;
const char *string;
in_addr_t local_ip;
- in_addr_t remote_ip;
+ struct in6_addr local_ip6;
+ struct openvpn_sockaddr local_sock;
+ struct openvpn_sockaddr remote_sock;
union log_entry_union u;
};
@@ -173,6 +175,9 @@ struct management_callback
#endif
bool (*proxy_cmd) (void *arg, const char **p);
bool (*remote_cmd) (void *arg, const char **p);
+#ifdef TARGET_ANDROID
+ int (*network_change) (void *arg, bool samenetwork);
+#endif
};
/*
@@ -212,7 +217,7 @@ struct man_persist {
struct man_settings {
bool defined;
unsigned int flags; /* MF_x flags */
- struct openvpn_sockaddr local;
+ struct addrinfo* local;
#if UNIX_SOCK_SUPPORT
struct sockaddr_un local_unix;
#endif
@@ -252,7 +257,7 @@ struct man_connection {
socket_descriptor_t sd_cli;
struct openvpn_sockaddr remote;
-#ifdef WIN32
+#ifdef _WIN32
struct net_event_win32 ne32;
#endif
@@ -268,6 +273,7 @@ struct man_connection {
# define IEC_CLIENT_AUTH 1
# define IEC_CLIENT_PF 2
# define IEC_RSA_SIGN 3
+# define IEC_CERTIFICATE 4
int in_extra_cmd;
struct buffer_list *in_extra;
#ifdef MANAGEMENT_DEF_AUTH
@@ -281,6 +287,8 @@ struct man_connection {
# define EKS_READY 3
int ext_key_state;
struct buffer_list *ext_key_input;
+ int ext_cert_state;
+ struct buffer_list *ext_cert_input;
#endif
#endif
struct event_set *es;
@@ -299,6 +307,10 @@ struct man_connection {
#ifdef MANAGMENT_EXTERNAL_KEY
struct buffer_list *rsa_sig;
#endif
+#ifdef TARGET_ANDROID
+ int fdtosend;
+ int lastfdreceived;
+#endif
};
struct management
@@ -334,10 +346,11 @@ struct management *management_init (void);
#define MF_UP_DOWN (1<<10)
#define MF_QUERY_REMOTE (1<<11)
#define MF_QUERY_PROXY (1<<12)
+#define MF_EXTERNAL_CERT (1<<13)
bool management_open (struct management *man,
const char *addr,
- const int port,
+ const char *port,
const char *pass_file,
const char *client_user,
const char *client_group,
@@ -372,9 +385,18 @@ bool management_query_user_pass (struct management *man,
const unsigned int flags,
const char *static_challenge);
+#ifdef TARGET_ANDROID
+bool management_android_control (struct management *man, const char *command, const char *msg);
+
+#define ANDROID_KEEP_OLD_TUN 1
+#define ANDROID_OPEN_AFTER_CLOSE 2
+#define ANDROID_OPEN_BEFORE_CLOSE 3
+int managment_android_persisttun_action (struct management *man);
+#endif
+
bool management_should_daemonize (struct management *man);
bool management_would_hold (struct management *man);
-bool management_hold (struct management *man);
+bool management_hold (struct management *man, int holdtime);
void management_event_loop_n_seconds (struct management *man, int sec);
@@ -407,6 +429,7 @@ void management_learn_addr (struct management *management,
#ifdef MANAGMENT_EXTERNAL_KEY
char *management_query_rsa_sig (struct management *man, const char *b64_data);
+char* management_query_cert (struct management *man, const char *cert_name);
#endif
@@ -475,8 +498,10 @@ management_enable_def_auth (const struct management *man)
void management_set_state (struct management *man,
const int state,
const char *detail,
- const in_addr_t tun_local_ip,
- const in_addr_t tun_remote_ip);
+ const in_addr_t *tun_local_ip,
+ const struct in6_addr *tun_local_ip6,
+ const struct openvpn_sockaddr *local_addr,
+ const struct openvpn_sockaddr *remote_addr);
/*
* The management object keeps track of OpenVPN --echo
diff --git a/src/openvpn/misc.c b/src/openvpn/misc.c
index 48ca0d5..56d43e0 100644
--- a/src/openvpn/misc.c
+++ b/src/openvpn/misc.c
@@ -6,6 +6,8 @@
* packet compression.
*
* Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net>
+ * Copyright (C) 2014-2015 David Sommerseth <davids@redhat.com>
+ * Copyright (C) 2016 David Sommerseth <davids@openvpn.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
@@ -62,7 +64,7 @@ run_up_down (const char *command,
const struct plugin_list *plugins,
int plugin_type,
const char *arg,
-#ifdef WIN32
+#ifdef _WIN32
DWORD adapter_index,
#endif
const char *dev_type,
@@ -85,7 +87,7 @@ run_up_down (const char *command,
setenv_str (es, "dev", arg);
if (dev_type)
setenv_str (es, "dev_type", dev_type);
-#ifdef WIN32
+#ifdef _WIN32
setenv_int (es, "dev_idx", adapter_index);
#endif
@@ -118,13 +120,9 @@ run_up_down (const char *command,
struct argv argv = argv_new ();
ASSERT (arg);
setenv_str (es, "script_type", script_type);
- argv_printf (&argv,
- "%sc %s %d %d %s %s %s",
- command,
- arg,
- tun_mtu, link_mtu,
- ifconfig_local, ifconfig_remote,
- context);
+ argv_parse_cmd (&argv, command);
+ argv_printf_cat (&argv, "%s %d %d %s %s %s", arg, tun_mtu, link_mtu,
+ ifconfig_local, ifconfig_remote, context);
argv_msg (M_INFO, &argv);
openvpn_run_script (&argv, es, S_FATAL, "--up/--down");
argv_reset (&argv);
@@ -192,38 +190,13 @@ save_inetd_socket_descriptor (void)
}
/*
- * Warn if a given file is group/others accessible.
- */
-void
-warn_if_group_others_accessible (const char* filename)
-{
-#ifndef WIN32
-#ifdef HAVE_STAT
- if (strcmp (filename, INLINE_FILE_TAG))
- {
- struct stat st;
- if (stat (filename, &st))
- {
- msg (M_WARN | M_ERRNO, "WARNING: cannot stat file '%s'", filename);
- }
- else
- {
- if (st.st_mode & (S_IRWXG|S_IRWXO))
- msg (M_WARN, "WARNING: file '%s' is group or others accessible", filename);
- }
- }
-#endif
-#endif
-}
-
-/*
* Print an error message based on the status code returned by system().
*/
const char *
system_error_message (int stat, struct gc_arena *gc)
{
struct buffer out = alloc_buf_gc (256, gc);
-#ifdef WIN32
+#ifdef _WIN32
if (stat == -1)
buf_printf (&out, "external program did not execute -- ");
buf_printf (&out, "returned error code %d", stat);
@@ -279,7 +252,7 @@ openvpn_execve_allowed (const unsigned int flags)
}
-#ifndef WIN32
+#ifndef _WIN32
/*
* Run execve() inside a fork(). Designed to replicate the semantics of system() but
* in a safer way that doesn't require the invocation of a shell or the risks
@@ -362,27 +335,29 @@ openvpn_popen (const struct argv *a, const struct env_set *es)
pid = fork ();
if (pid == (pid_t)0) /* child side */
{
- close (pipe_stdout[0]);
+ close (pipe_stdout[0]); /* Close read end */
dup2 (pipe_stdout[1],1);
execve (cmd, argv, envp);
exit (127);
}
- else if (pid < (pid_t)0) /* fork failed */
- {
- msg (M_ERR, "openvpn_popen: unable to fork");
- }
- else /* parent side */
+ else if (pid > (pid_t)0) /* parent side */
{
int status = 0;
+ close (pipe_stdout[1]); /* Close write end */
waitpid(pid, &status, 0);
ret = pipe_stdout[0];
+ }
+ else /* fork failed */
+ {
+ close (pipe_stdout[0]);
close (pipe_stdout[1]);
+ msg (M_ERR, "openvpn_popen: unable to fork %s", cmd);
}
}
else {
- msg (M_WARN, "openvpn_popen: unable to create stdout pipe");
- ret = -1;
+ msg (M_WARN, "openvpn_popen: unable to create stdout pipe for %s", cmd);
+ ret = -1;
}
}
else if (!warn_shown && (script_security < SSEC_SCRIPTS))
@@ -611,6 +586,16 @@ env_set_add (struct env_set *es, const char *str)
env_set_add_nolock (es, str);
}
+const char*
+env_set_get (const struct env_set *es, const char *name)
+{
+ const struct env_item *item = es->list;
+ while (item && !env_string_equal(item->string, name)) {
+ item = item->next;
+ }
+ return item ? item->string : NULL;
+}
+
void
env_set_print (int msglevel, const struct env_set *es)
{
@@ -701,14 +686,6 @@ env_set_remove_from_environment (const struct env_set *es)
}
}
-#ifdef HAVE_PUTENV
-
-/* companion functions to putenv */
-
-static struct env_item *global_env = NULL; /* GLOBAL */
-
-#endif
-
/* add/modify/delete environmental strings */
void
@@ -753,6 +730,28 @@ setenv_str_safe (struct env_set *es, const char *name, const char *value)
msg (M_WARN, "setenv_str_safe: name overflow");
}
+void setenv_str_incr(struct env_set *es, const char *name, const char *value)
+{
+ unsigned int counter = 1;
+ const size_t tmpname_len = strlen(name) + 5; /* 3 digits counter max */
+ char *tmpname = gc_malloc(tmpname_len, true, NULL);
+ strcpy(tmpname, name);
+ while (NULL != env_set_get(es, tmpname) && counter < 1000)
+ {
+ ASSERT (openvpn_snprintf (tmpname, tmpname_len, "%s_%u", name, counter));
+ counter++;
+ }
+ if (counter < 1000)
+ {
+ setenv_str (es, tmpname, value);
+ }
+ else
+ {
+ msg (D_TLS_DEBUG_MED, "Too many same-name env variables, ignoring: %s", name);
+ }
+ free (tmpname);
+}
+
void
setenv_del (struct env_set *es, const char *name)
{
@@ -830,32 +829,6 @@ setenv_str_i (struct env_set *es, const char *name, const char *value, const int
gc_free (&gc);
}
-/*
- * taken from busybox networking/ifupdown.c
- */
-unsigned int
-count_bits(unsigned int a)
-{
- unsigned int result;
- result = (a & 0x55) + ((a >> 1) & 0x55);
- result = (result & 0x33) + ((result >> 2) & 0x33);
- return((result & 0x0F) + ((result >> 4) & 0x0F));
-}
-
-int
-count_netmask_bits(const char *dotted_quad)
-{
- unsigned int result, a, b, c, d;
- /* Found a netmask... Check if it is dotted quad */
- if (sscanf(dotted_quad, "%u.%u.%u.%u", &a, &b, &c, &d) != 4)
- return -1;
- result = count_bits(a);
- result += count_bits(b);
- result += count_bits(c);
- result += count_bits(d);
- return ((int)result);
-}
-
/* return true if filename can be opened for read */
bool
test_file (const char *filename)
@@ -977,7 +950,7 @@ hostname_randomize(const char *hostname, struct gc_arena *gc)
const char *
gen_path (const char *directory, const char *filename, struct gc_arena *gc)
{
-#if WIN32
+#ifdef _WIN32
const int CC_PATH_RESERVED = CC_LESS_THAN|CC_GREATER_THAN|CC_COLON|
CC_DOUBLE_QUOTE|CC_SLASH|CC_BACKSLASH|CC_PIPE|CC_QUESTION_MARK|CC_ASTERISK;
#else
@@ -988,7 +961,7 @@ gen_path (const char *directory, const char *filename, struct gc_arena *gc)
if (safe_filename
&& strcmp (safe_filename, ".")
&& strcmp (safe_filename, "..")
-#ifdef WIN32
+#ifdef _WIN32
&& win_safe_filename (safe_filename)
#endif
)
@@ -1016,7 +989,7 @@ absolute_pathname (const char *pathname)
if (pathname)
{
const int c = pathname[0];
-#ifdef WIN32
+#ifdef _WIN32
return c == '\\' || (isalpha(c) && pathname[1] == ':' && pathname[2] == '\\');
#else
return c == '/';
@@ -1085,13 +1058,23 @@ get_user_pass_cr (struct user_pass *up,
struct buffer user_prompt = alloc_buf_gc (128, &gc);
buf_printf (&user_prompt, "NEED-OK|%s|%s:", prefix, up->username);
-
- if (!get_console_input (BSTR (&user_prompt), true, up->password, USER_PASS_LEN))
- msg (M_FATAL, "ERROR: could not read %s ok-confirmation from stdin", prefix);
+ if (!query_user_SINGLE (BSTR(&user_prompt), BLEN(&user_prompt),
+ up->password, USER_PASS_LEN, false))
+ {
+ msg (M_FATAL, "ERROR: could not read %s ok-confirmation from stdin", prefix);
+ }
if (!strlen (up->password))
strcpy (up->password, "ok");
}
+ else if (flags & GET_USER_PASS_INLINE_CREDS)
+ {
+ struct buffer buf;
+ buf_set_read (&buf, (uint8_t*) auth_file, strlen (auth_file) + 1);
+ if (!(flags & GET_USER_PASS_PASSWORD_ONLY))
+ buf_parse (&buf, '\n', up->username, USER_PASS_LEN);
+ buf_parse (&buf, '\n', up->password, USER_PASS_LEN);
+ }
/*
* Read from auth file unless this is a dynamic challenge request.
*/
@@ -1103,8 +1086,6 @@ get_user_pass_cr (struct user_pass *up,
FILE *fp;
char password_buf[USER_PASS_LEN] = { '\0' };
- warn_if_group_others_accessible (auth_file);
-
fp = platform_fopen (auth_file, "r");
if (!fp)
msg (M_ERR, "Error opening '%s' auth file: %s", prefix, auth_file);
@@ -1155,13 +1136,17 @@ get_user_pass_cr (struct user_pass *up,
if (ac)
{
char *response = (char *) gc_malloc (USER_PASS_LEN, false, &gc);
- struct buffer packed_resp;
+ struct buffer packed_resp, challenge;
+ challenge = alloc_buf_gc (14+strlen(ac->challenge_text), &gc);
+ buf_printf (&challenge, "CHALLENGE: %s", ac->challenge_text);
buf_set_write (&packed_resp, (uint8_t*)up->password, USER_PASS_LEN);
- msg (M_INFO|M_NOPREFIX, "CHALLENGE: %s", ac->challenge_text);
- if (!get_console_input (ac->challenge_text, BOOL_CAST(ac->flags&CR_ECHO),
- response, USER_PASS_LEN))
- msg (M_FATAL, "ERROR: could not read challenge response from stdin");
+
+ if (!query_user_SINGLE (BSTR(&challenge), BLEN(&challenge),
+ response, USER_PASS_LEN, BOOL_CAST(ac->flags&CR_ECHO)))
+ {
+ msg (M_FATAL, "ERROR: could not read challenge response from stdin");
+ }
strncpynt (up->username, ac->user, USER_PASS_LEN);
buf_printf (&packed_resp, "CRV1::%s::%s", ac->state_id, response);
}
@@ -1176,32 +1161,49 @@ get_user_pass_cr (struct user_pass *up,
struct buffer user_prompt = alloc_buf_gc (128, &gc);
struct buffer pass_prompt = alloc_buf_gc (128, &gc);
+ query_user_clear ();
buf_printf (&user_prompt, "Enter %s Username:", prefix);
buf_printf (&pass_prompt, "Enter %s Password:", prefix);
if (username_from_stdin && !(flags & GET_USER_PASS_PASSWORD_ONLY))
{
- if (!get_console_input (BSTR (&user_prompt), true, up->username, USER_PASS_LEN))
- msg (M_FATAL, "ERROR: could not read %s username from stdin", prefix);
+ query_user_add (BSTR(&user_prompt), BLEN(&user_prompt),
+ up->username, USER_PASS_LEN, true);
+ }
+
+ if (password_from_stdin)
+ {
+ query_user_add (BSTR(&pass_prompt), BLEN(&pass_prompt),
+ up->password, USER_PASS_LEN, false);
+ }
+
+ if( !query_user_exec () )
+ {
+ msg(M_FATAL, "ERROR: Failed retrieving username or password");
+ }
+
+ if (!(flags & GET_USER_PASS_PASSWORD_ONLY))
+ {
if (strlen (up->username) == 0)
msg (M_FATAL, "ERROR: %s username is empty", prefix);
}
- if (password_from_stdin && !get_console_input (BSTR (&pass_prompt), false, up->password, USER_PASS_LEN))
- msg (M_FATAL, "ERROR: could not not read %s password from stdin", prefix);
-
#ifdef ENABLE_CLIENT_CR
if (auth_challenge && (flags & GET_USER_PASS_STATIC_CHALLENGE) && response_from_stdin)
{
char *response = (char *) gc_malloc (USER_PASS_LEN, false, &gc);
- struct buffer packed_resp;
+ struct buffer packed_resp, challenge;
char *pw64=NULL, *resp64=NULL;
- msg (M_INFO|M_NOPREFIX, "CHALLENGE: %s", auth_challenge);
+ challenge = alloc_buf_gc (14+strlen(auth_challenge), &gc);
+ buf_printf (&challenge, "CHALLENGE: %s", auth_challenge);
- if (!get_console_input (auth_challenge, BOOL_CAST(flags & GET_USER_PASS_STATIC_CHALLENGE_ECHO),
- response, USER_PASS_LEN))
- msg (M_FATAL, "ERROR: could not read static challenge response from stdin");
+ if (!query_user_SINGLE (BSTR(&challenge), BLEN(&challenge),
+ response, USER_PASS_LEN,
+ BOOL_CAST(flags & GET_USER_PASS_STATIC_CHALLENGE_ECHO)))
+ {
+ msg (M_FATAL, "ERROR: could not retrieve static challenge response");
+ }
if (openvpn_base64_encode(up->password, strlen(up->password), &pw64) == -1
|| openvpn_base64_encode(response, strlen(response), &resp64) == -1)
msg (M_FATAL, "ERROR: could not base64-encode password/static_response");
@@ -1555,465 +1557,6 @@ adjust_power_of_2 (size_t u)
}
/*
- * A printf-like function (that only recognizes a subset of standard printf
- * format operators) that prints arguments to an argv list instead
- * of a standard string. This is used to build up argv arrays for passing
- * to execve.
- */
-
-void
-argv_init (struct argv *a)
-{
- a->capacity = 0;
- a->argc = 0;
- a->argv = NULL;
- a->system_str = NULL;
-}
-
-struct argv
-argv_new (void)
-{
- struct argv ret;
- argv_init (&ret);
- return ret;
-}
-
-void
-argv_reset (struct argv *a)
-{
- size_t i;
- for (i = 0; i < a->argc; ++i)
- free (a->argv[i]);
- free (a->argv);
- free (a->system_str);
- argv_init (a);
-}
-
-static void
-argv_extend (struct argv *a, const size_t newcap)
-{
- if (newcap > a->capacity)
- {
- char **newargv;
- size_t i;
- ALLOC_ARRAY_CLEAR (newargv, char *, newcap);
- for (i = 0; i < a->argc; ++i)
- newargv[i] = a->argv[i];
- free (a->argv);
- a->argv = newargv;
- a->capacity = newcap;
- }
-}
-
-static void
-argv_grow (struct argv *a, const size_t add)
-{
- const size_t newargc = a->argc + add + 1;
- ASSERT (newargc > a->argc);
- argv_extend (a, adjust_power_of_2 (newargc));
-}
-
-static void
-argv_append (struct argv *a, char *str) /* str must have been malloced or be NULL */
-{
- argv_grow (a, 1);
- a->argv[a->argc++] = str;
-}
-
-static void
-argv_system_str_append (struct argv *a, const char *str, const bool enquote)
-{
- if (str)
- {
- char *newstr;
-
- /* compute length of new system_str */
- size_t l = strlen (str) + 1; /* space for new string plus trailing '\0' */
- if (a->system_str)
- l += strlen (a->system_str) + 1; /* space for existing string + space (" ") separator */
- if (enquote)
- l += 2; /* space for two quotes */
-
- /* build new system_str */
- newstr = (char *) malloc (l);
- newstr[0] = '\0';
- check_malloc_return (newstr);
- if (a->system_str)
- {
- strcpy (newstr, a->system_str);
- strcat (newstr, " ");
- }
- if (enquote)
- strcat (newstr, "\"");
- strcat (newstr, str);
- if (enquote)
- strcat (newstr, "\"");
- free (a->system_str);
- a->system_str = newstr;
- }
-}
-
-static char *
-argv_extract_cmd_name (const char *path)
-{
- char *ret = NULL;
- if (path)
- {
- char *path_cp = string_alloc(path, NULL); /* POSIX basename() implementaions may modify its arguments */
- const char *bn = basename (path_cp);
- if (bn)
- {
- char *dot = NULL;
- ret = string_alloc (bn, NULL);
- dot = strrchr (ret, '.');
- if (dot)
- *dot = '\0';
- free(path_cp);
- if (ret[0] == '\0')
- {
- free(ret);
- ret = NULL;
- }
- }
- }
- return ret;
-}
-
-const char *
-argv_system_str (const struct argv *a)
-{
- return a->system_str;
-}
-
-struct argv
-argv_clone (const struct argv *a, const size_t headroom)
-{
- struct argv r;
- size_t i;
-
- argv_init (&r);
- for (i = 0; i < headroom; ++i)
- argv_append (&r, NULL);
- if (a)
- {
- for (i = 0; i < a->argc; ++i)
- argv_append (&r, string_alloc (a->argv[i], NULL));
- r.system_str = string_alloc (a->system_str, NULL);
- }
- return r;
-}
-
-struct argv
-argv_insert_head (const struct argv *a, const char *head)
-{
- struct argv r;
- char *s;
-
- r = argv_clone (a, 1);
- r.argv[0] = string_alloc (head, NULL);
- s = r.system_str;
- r.system_str = string_alloc (head, NULL);
- if (s)
- {
- argv_system_str_append (&r, s, false);
- free (s);
- }
- return r;
-}
-
-char *
-argv_term (const char **f)
-{
- const char *p = *f;
- const char *term = NULL;
- size_t termlen = 0;
-
- if (*p == '\0')
- return NULL;
-
- while (true)
- {
- const int c = *p;
- if (c == '\0')
- break;
- if (term)
- {
- if (!isspace (c))
- ++termlen;
- else
- break;
- }
- else
- {
- if (!isspace (c))
- {
- term = p;
- termlen = 1;
- }
- }
- ++p;
- }
- *f = p;
-
- if (term)
- {
- char *ret;
- ASSERT (termlen > 0);
- ret = malloc (termlen + 1);
- check_malloc_return (ret);
- memcpy (ret, term, termlen);
- ret[termlen] = '\0';
- return ret;
- }
- else
- return NULL;
-}
-
-const char *
-argv_str (const struct argv *a, struct gc_arena *gc, const unsigned int flags)
-{
- if (a->argv)
- return print_argv ((const char **)a->argv, gc, flags);
- else
- return "";
-}
-
-void
-argv_msg (const int msglev, const struct argv *a)
-{
- struct gc_arena gc = gc_new ();
- msg (msglev, "%s", argv_str (a, &gc, 0));
- gc_free (&gc);
-}
-
-void
-argv_msg_prefix (const int msglev, const struct argv *a, const char *prefix)
-{
- struct gc_arena gc = gc_new ();
- msg (msglev, "%s: %s", prefix, argv_str (a, &gc, 0));
- gc_free (&gc);
-}
-
-void
-argv_printf (struct argv *a, const char *format, ...)
-{
- va_list arglist;
- va_start (arglist, format);
- argv_printf_arglist (a, format, 0, arglist);
- va_end (arglist);
- }
-
-void
-argv_printf_cat (struct argv *a, const char *format, ...)
-{
- va_list arglist;
- va_start (arglist, format);
- argv_printf_arglist (a, format, APA_CAT, arglist);
- va_end (arglist);
-}
-
-void
-argv_printf_arglist (struct argv *a, const char *format, const unsigned int flags, va_list arglist)
-{
- struct gc_arena gc = gc_new ();
- char *term;
- const char *f = format;
-
- if (!(flags & APA_CAT))
- argv_reset (a);
- argv_extend (a, 1); /* ensure trailing NULL */
-
- while ((term = argv_term (&f)) != NULL)
- {
- if (term[0] == '%')
- {
- if (!strcmp (term, "%s"))
- {
- char *s = va_arg (arglist, char *);
- if (!s)
- s = "";
- argv_append (a, string_alloc (s, NULL));
- argv_system_str_append (a, s, true);
- }
- else if (!strcmp (term, "%sc"))
- {
- char *s = va_arg (arglist, char *);
- if (s)
- {
- int nparms;
- char *parms[MAX_PARMS+1];
- int i;
-
- nparms = parse_line (s, parms, MAX_PARMS, "SCRIPT-ARGV", 0, D_ARGV_PARSE_CMD, &gc);
- if (nparms)
- {
- for (i = 0; i < nparms; ++i)
- argv_append (a, string_alloc (parms[i], NULL));
- }
- else
- argv_append (a, string_alloc (s, NULL));
-
- argv_system_str_append (a, s, false);
- }
- else
- {
- argv_append (a, string_alloc ("", NULL));
- argv_system_str_append (a, "echo", false);
- }
- }
- else if (!strcmp (term, "%d"))
- {
- char numstr[64];
- openvpn_snprintf (numstr, sizeof (numstr), "%d", va_arg (arglist, int));
- argv_append (a, string_alloc (numstr, NULL));
- argv_system_str_append (a, numstr, false);
- }
- else if (!strcmp (term, "%u"))
- {
- char numstr[64];
- openvpn_snprintf (numstr, sizeof (numstr), "%u", va_arg (arglist, unsigned int));
- argv_append (a, string_alloc (numstr, NULL));
- argv_system_str_append (a, numstr, false);
- }
- else if (!strcmp (term, "%s/%d"))
- {
- char numstr[64];
- char *s = va_arg (arglist, char *);
-
- if (!s)
- s = "";
-
- openvpn_snprintf (numstr, sizeof (numstr), "%d", va_arg (arglist, int));
-
- {
- const size_t len = strlen(s) + strlen(numstr) + 2;
- char *combined = (char *) malloc (len);
- check_malloc_return (combined);
-
- strcpy (combined, s);
- strcat (combined, "/");
- strcat (combined, numstr);
- argv_append (a, combined);
- argv_system_str_append (a, combined, false);
- }
- }
- else if (!strcmp (term, "%s%sc"))
- {
- char *s1 = va_arg (arglist, char *);
- char *s2 = va_arg (arglist, char *);
- char *combined;
- char *cmd_name;
-
- if (!s1) s1 = "";
- if (!s2) s2 = "";
- combined = (char *) malloc (strlen(s1) + strlen(s2) + 1);
- check_malloc_return (combined);
- strcpy (combined, s1);
- strcat (combined, s2);
- argv_append (a, combined);
-
- cmd_name = argv_extract_cmd_name (combined);
- if (cmd_name)
- {
- argv_system_str_append (a, cmd_name, false);
- free (cmd_name);
- }
- }
- else
- ASSERT (0);
- free (term);
- }
- else
- {
- argv_append (a, term);
- argv_system_str_append (a, term, false);
- }
- }
- gc_free (&gc);
-}
-
-#ifdef ARGV_TEST
-void
-argv_test (void)
-{
- struct gc_arena gc = gc_new ();
- const char *s;
-
- struct argv a;
-
- argv_init (&a);
- argv_printf (&a, "%sc foo bar %s", "c:\\\\src\\\\test\\\\jyargs.exe", "foo bar");
- argv_msg_prefix (M_INFO, &a, "ARGV");
- msg (M_INFO, "ARGV-S: %s", argv_system_str(&a));
- /*openvpn_execve_check (&a, NULL, 0, "command failed");*/
-
- argv_printf (&a, "%sc %s %s", "c:\\\\src\\\\test files\\\\batargs.bat", "foo", "bar");
- argv_msg_prefix (M_INFO, &a, "ARGV");
- msg (M_INFO, "ARGV-S: %s", argv_system_str(&a));
- /*openvpn_execve_check (&a, NULL, 0, "command failed");*/
-
- argv_printf (&a, "%s%sc foo bar %s %s/%d %d %u", "/foo", "/bar.exe", "one two", "1.2.3.4", 24, -69, 96);
- argv_msg_prefix (M_INFO, &a, "ARGV");
- msg (M_INFO, "ARGV-S: %s", argv_system_str(&a));
- /*openvpn_execve_check (&a, NULL, 0, "command failed");*/
-
- argv_printf (&a, "this is a %s test of int %d unsigned %u", "FOO", -69, 42);
- s = argv_str (&a, &gc, PA_BRACKET);
- printf ("PF: %s\n", s);
- printf ("PF-S: %s\n", argv_system_str(&a));
-
- {
- struct argv b = argv_insert_head (&a, "MARK");
- s = argv_str (&b, &gc, PA_BRACKET);
- printf ("PF: %s\n", s);
- printf ("PF-S: %s\n", argv_system_str(&b));
- argv_reset (&b);
- }
-
- argv_printf (&a, "%sc foo bar %d", "\"multi term\" command following \\\"spaces", 99);
- s = argv_str (&a, &gc, PA_BRACKET);
- printf ("PF: %s\n", s);
- printf ("PF-S: %s\n", argv_system_str(&a));
- argv_reset (&a);
-
- s = argv_str (&a, &gc, PA_BRACKET);
- printf ("PF: %s\n", s);
- printf ("PF-S: %s\n", argv_system_str(&a));
- argv_reset (&a);
-
- argv_printf (&a, "foo bar %d", 99);
- argv_printf_cat (&a, "bar %d foo %sc", 42, "nonesuch");
- argv_printf_cat (&a, "cool %s %d u %s/%d end", "frood", 4, "hello", 7);
- s = argv_str (&a, &gc, PA_BRACKET);
- printf ("PF: %s\n", s);
- printf ("PF-S: %s\n", argv_system_str(&a));
- argv_reset (&a);
-
-#if 0
- {
- char line[512];
- while (fgets (line, sizeof(line), stdin) != NULL)
- {
- char *term;
- const char *f = line;
- int i = 0;
-
- while ((term = argv_term (&f)) != NULL)
- {
- printf ("[%d] '%s'\n", i, term);
- ++i;
- free (term);
- }
- }
- }
-#endif
-
- argv_reset (&a);
- gc_free (&gc);
-}
-#endif
-
-/*
* Remove security-sensitive strings from control message
* so that they will not be output to log file.
*/
@@ -2040,6 +1583,15 @@ sanitize_control_message(const char *src, struct gc_arena *gc)
skip = 4;
redact = true;
}
+ else if (!check_debug_level(D_SHOW_KEYS)
+ && (c == 'a' && !strncmp(src, "auth-token ", 11)))
+ {
+ /* Unless --verb is 7 or higher (D_SHOW_KEYS), hide
+ * the auth-token value coming in the src string
+ */
+ skip = 10;
+ redact = true;
+ }
if (c == ',') /* end of redacted item? */
{
@@ -2084,3 +1636,59 @@ compat_flag (unsigned int flag)
return (compat_flags & (flag >> 1));
}
+
+#if P2MP_SERVER
+
+/* helper to parse peer_info received from multi client, validate
+ * (this is untrusted data) and put into environment
+ */
+bool
+validate_peer_info_line(char *line)
+{
+ uint8_t c;
+ int state = 0;
+ while (*line)
+ {
+ c = *line;
+ switch (state)
+ {
+ case 0:
+ case 1:
+ if (c == '=' && state == 1)
+ state = 2;
+ else if (isalnum(c) || c == '_')
+ state = 1;
+ else
+ return false;
+ case 2:
+ /* after the '=', replace non-printable or shell meta with '_' */
+ if (!isprint(c) || isspace(c) ||
+ c == '$' || c == '(' || c == '`' )
+ *line = '_';
+ }
+ line++;
+ }
+ return (state == 2);
+}
+
+void
+output_peer_info_env (struct env_set *es, const char * peer_info)
+{
+ char line[256];
+ struct buffer buf;
+ buf_set_read (&buf, (const uint8_t *) peer_info, strlen(peer_info));
+ while (buf_parse (&buf, '\n', line, sizeof (line)))
+ {
+ chomp (line);
+ if (validate_peer_info_line(line) &&
+ (strncmp(line, "IV_", 3) == 0 || strncmp(line, "UV_", 3) == 0) )
+ {
+ msg (M_INFO, "peer info: %s", line);
+ env_set_add(es, line);
+ }
+ else
+ msg (M_WARN, "validation failed on peer_info line received from client");
+ }
+}
+
+#endif /* P2MP_SERVER */
diff --git a/src/openvpn/misc.h b/src/openvpn/misc.h
index c1942b6..b8bbaa7 100644
--- a/src/openvpn/misc.h
+++ b/src/openvpn/misc.h
@@ -25,6 +25,7 @@
#ifndef MISC_H
#define MISC_H
+#include "argv.h"
#include "basic.h"
#include "common.h"
#include "integer.h"
@@ -37,14 +38,6 @@
/* forward declarations */
struct plugin_list;
-/* used by argv_x functions */
-struct argv {
- size_t capacity;
- size_t argc;
- char **argv;
- char *system_str;
-};
-
/*
* Handle environmental variable lists
*/
@@ -63,7 +56,7 @@ void run_up_down (const char *command,
const struct plugin_list *plugins,
int plugin_type,
const char *arg,
-#ifdef WIN32
+#ifdef _WIN32
DWORD adapter_index,
#endif
const char *dev_type,
@@ -78,9 +71,6 @@ void run_up_down (const char *command,
void write_pid (const char *filename);
-/* check file protections */
-void warn_if_group_others_accessible(const char* filename);
-
/* system flags */
#define S_SCRIPT (1<<0)
#define S_FATAL (1<<1)
@@ -136,6 +126,12 @@ void setenv_str (struct env_set *es, const char *name, const char *value);
void setenv_str_safe (struct env_set *es, const char *name, const char *value);
void setenv_del (struct env_set *es, const char *name);
+/**
+ * Store the supplied name value pair in the env_set. If the variable with the
+ * supplied name already exists, append _N to the name, starting at N=1.
+ */
+void setenv_str_incr(struct env_set *es, const char *name, const char *value);
+
void setenv_int_i (struct env_set *es, const char *name, const int value, const int i);
void setenv_str_i (struct env_set *es, const char *name, const char *value, const int i);
@@ -145,6 +141,7 @@ struct env_set *env_set_create (struct gc_arena *gc);
void env_set_destroy (struct env_set *es);
bool env_set_del (struct env_set *es, const char *str);
void env_set_add (struct env_set *es, const char *str);
+const char* env_set_get (const struct env_set *es, const char *name);
void env_set_print (int msglevel, const struct env_set *es);
@@ -162,10 +159,6 @@ const char **make_env_array (const struct env_set *es,
const char **make_arg_array (const char *first, const char *parms, struct gc_arena *gc);
const char **make_extended_arg_array (char **p, struct gc_arena *gc);
-/* convert netmasks for iproute2 */
-int count_netmask_bits(const char *);
-unsigned int count_bits(unsigned int );
-
/* an analogue to the random() function, but use OpenSSL functions if available */
#ifdef ENABLE_CRYPTO
long int get_random(void);
@@ -253,6 +246,8 @@ struct static_challenge_info {};
#define GET_USER_PASS_STATIC_CHALLENGE (1<<8) /* SCRV1 protocol -- static challenge */
#define GET_USER_PASS_STATIC_CHALLENGE_ECHO (1<<9) /* SCRV1 protocol -- echo response */
+#define GET_USER_PASS_INLINE_CREDS (1<<10) /* indicates that auth_file is actually inline creds */
+
bool get_user_pass_cr (struct user_pass *up,
const char *auth_file,
const char *prefix,
@@ -320,49 +315,17 @@ extern int script_security; /* GLOBAL */
/* return the next largest power of 2 */
size_t adjust_power_of_2 (size_t u);
-/*
- * A printf-like function (that only recognizes a subset of standard printf
- * format operators) that prints arguments to an argv list instead
- * of a standard string. This is used to build up argv arrays for passing
- * to execve.
- */
-void argv_init (struct argv *a);
-struct argv argv_new (void);
-void argv_reset (struct argv *a);
-char *argv_term (const char **f);
-const char *argv_str (const struct argv *a, struct gc_arena *gc, const unsigned int flags);
-struct argv argv_insert_head (const struct argv *a, const char *head);
-void argv_msg (const int msglev, const struct argv *a);
-void argv_msg_prefix (const int msglev, const struct argv *a, const char *prefix);
-const char *argv_system_str (const struct argv *a);
-
-#define APA_CAT (1<<0) /* concatentate onto existing struct argv list */
-void argv_printf_arglist (struct argv *a, const char *format, const unsigned int flags, va_list arglist);
-
-void argv_printf (struct argv *a, const char *format, ...)
-#ifdef __GNUC__
-#if __USE_MINGW_ANSI_STDIO
- __attribute__ ((format (gnu_printf, 2, 3)))
-#else
- __attribute__ ((format (__printf__, 2, 3)))
-#endif
-#endif
- ;
-
-void argv_printf_cat (struct argv *a, const char *format, ...)
-#ifdef __GNUC__
-#if __USE_MINGW_ANSI_STDIO
- __attribute__ ((format (gnu_printf, 2, 3)))
-#else
- __attribute__ ((format (__printf__, 2, 3)))
-#endif
-#endif
- ;
-
#define COMPAT_FLAG_QUERY 0 /** compat_flags operator: Query for a flag */
#define COMPAT_FLAG_SET (1<<0) /** compat_flags operator: Set a compat flag */
#define COMPAT_NAMES (1<<1) /** compat flag: --compat-names set */
#define COMPAT_NO_NAME_REMAPPING (1<<2) /** compat flag: --compat-names without char remapping */
bool compat_flag (unsigned int flag);
+#if P2MP_SERVER
+/* helper to parse peer_info received from multi client, validate
+ * (this is untrusted data) and put into environment */
+bool validate_peer_info_line(char *line);
+void output_peer_info_env (struct env_set *es, const char * peer_info);
+#endif /* P2MP_SERVER */
+
#endif
diff --git a/src/openvpn/mroute.c b/src/openvpn/mroute.c
index 850e336..c905af7 100644
--- a/src/openvpn/mroute.c
+++ b/src/openvpn/mroute.c
@@ -58,7 +58,8 @@ is_mac_mcast_addr (const uint8_t *mac)
static inline bool
is_mac_mcast_maddr (const struct mroute_addr *addr)
{
- return (addr->type & MR_ADDR_MASK) == MR_ADDR_ETHER && is_mac_mcast_addr (addr->addr);
+ return (addr->type & MR_ADDR_MASK) == MR_ADDR_ETHER &&
+ is_mac_mcast_addr (addr->eth_addr);
}
/*
@@ -73,7 +74,7 @@ mroute_learnable_address (const struct mroute_addr *addr)
for (i = 0; i < addr->len; ++i)
{
- int b = addr->addr[i];
+ int b = addr->raw_addr[i];
if (b != 0x00)
not_all_zeros = true;
if (b != 0xFF)
@@ -90,7 +91,7 @@ mroute_get_in_addr_t (struct mroute_addr *ma, const in_addr_t src, unsigned int
ma->type = MR_ADDR_IPV4 | mask;
ma->netbits = 0;
ma->len = 4;
- *(in_addr_t*)ma->addr = src;
+ ma->v4.addr = src;
}
}
@@ -102,7 +103,7 @@ mroute_get_in6_addr (struct mroute_addr *ma, const struct in6_addr src, unsigned
ma->type = MR_ADDR_IPV6 | mask;
ma->netbits = 0;
ma->len = 16;
- *(struct in6_addr *)ma->addr = src;
+ ma->v6.addr = src;
}
}
@@ -226,14 +227,14 @@ mroute_extract_addr_ether (struct mroute_addr *src,
src->type = MR_ADDR_ETHER;
src->netbits = 0;
src->len = 6;
- memcpy (src->addr, eth->source, 6);
+ memcpy (src->eth_addr, eth->source, sizeof(dest->eth_addr));
}
if (dest)
{
dest->type = MR_ADDR_ETHER;
dest->netbits = 0;
dest->len = 6;
- memcpy (dest->addr, eth->dest, 6);
+ memcpy (dest->eth_addr, eth->dest, sizeof(dest->eth_addr));
/* ethernet broadcast/multicast packet? */
if (is_mac_mcast_addr (eth->dest))
@@ -281,15 +282,15 @@ bool mroute_extract_openvpn_sockaddr (struct mroute_addr *addr,
addr->type = MR_ADDR_IPV4 | MR_WITH_PORT;
addr->netbits = 0;
addr->len = 6;
- memcpy (addr->addr, &osaddr->addr.in4.sin_addr.s_addr, 4);
- memcpy (addr->addr + 4, &osaddr->addr.in4.sin_port, 2);
+ addr->v4.addr = osaddr->addr.in4.sin_addr.s_addr;
+ addr->v4.port = osaddr->addr.in4.sin_port;
}
else
{
addr->type = MR_ADDR_IPV4;
addr->netbits = 0;
addr->len = 4;
- memcpy (addr->addr, &osaddr->addr.in4.sin_addr.s_addr, 4);
+ addr->v4.addr = osaddr->addr.in4.sin_addr.s_addr;
}
return true;
}
@@ -299,15 +300,15 @@ bool mroute_extract_openvpn_sockaddr (struct mroute_addr *addr,
addr->type = MR_ADDR_IPV6 | MR_WITH_PORT;
addr->netbits = 0;
addr->len = 18;
- memcpy (addr->addr, &osaddr->addr.in6.sin6_addr, 16);
- memcpy (addr->addr + 16, &osaddr->addr.in6.sin6_port, 2);
+ addr->v6.addr = osaddr->addr.in6.sin6_addr;
+ addr->v6.port = osaddr->addr.in6.sin6_port;
}
else
{
addr->type = MR_ADDR_IPV6;
addr->netbits = 0;
addr->len = 16;
- memcpy (addr->addr, &osaddr->addr.in6.sin6_addr, 16);
+ addr->v6.addr = osaddr->addr.in6.sin6_addr;
}
return true;
}
@@ -326,23 +327,29 @@ bool mroute_extract_openvpn_sockaddr (struct mroute_addr *addr,
void
mroute_addr_mask_host_bits (struct mroute_addr *ma)
{
- in_addr_t addr = ntohl(*(in_addr_t*)ma->addr);
if ((ma->type & MR_ADDR_MASK) == MR_ADDR_IPV4)
{
+ in_addr_t addr = ntohl (ma->v4.addr);
addr &= netbits_to_netmask (ma->netbits);
- *(in_addr_t*)ma->addr = htonl (addr);
+ ma->v4.addr = htonl (addr);
}
else if ((ma->type & MR_ADDR_MASK) == MR_ADDR_IPV6)
{
- int byte = ma->len-1; /* rightmost byte in address */
+ int byte = sizeof (ma->v6.addr) - 1; /* rightmost byte in address */
int bits_to_clear = 128 - ma->netbits;
while( byte >= 0 && bits_to_clear > 0 )
{
if ( bits_to_clear >= 8 )
- { ma->addr[byte--] = 0; bits_to_clear -= 8; }
+ {
+ ma->v6.addr.s6_addr[byte--] = 0;
+ bits_to_clear -= 8;
+ }
else
- { ma->addr[byte--] &= (IPV4_NETMASK_HOST << bits_to_clear); bits_to_clear = 0; }
+ {
+ ma->v6.addr.s6_addr[byte--] &= (IPV4_NETMASK_HOST << bits_to_clear);
+ bits_to_clear = 0;
+ }
}
ASSERT( bits_to_clear == 0 );
}
@@ -390,44 +397,42 @@ mroute_addr_print_ex (const struct mroute_addr *ma,
switch (maddr.type & MR_ADDR_MASK)
{
case MR_ADDR_ETHER:
- buf_printf (&out, "%s", format_hex_ex (ma->addr, 6, 0, 1, ":", gc));
+ buf_printf (&out, "%s", format_hex_ex (ma->eth_addr,
+ sizeof(ma->eth_addr), 0, 1, ":", gc));
break;
case MR_ADDR_IPV4:
{
- struct buffer buf;
- in_addr_t addr;
- int port;
- bool status;
- buf_set_read (&buf, maddr.addr, maddr.len);
- addr = buf_read_u32 (&buf, &status);
- if (status)
+ if ((flags & MAPF_SHOW_ARP) && (maddr.type & MR_ARP))
+ buf_printf (&out, "ARP/");
+ buf_printf (&out, "%s", print_in_addr_t (ntohl (maddr.v4.addr),
+ (flags & MAPF_IA_EMPTY_IF_UNDEF) ? IA_EMPTY_IF_UNDEF : 0, gc));
+ if (maddr.type & MR_WITH_NETBITS)
{
- if ((flags & MAPF_SHOW_ARP) && (maddr.type & MR_ARP))
- buf_printf (&out, "ARP/");
- buf_printf (&out, "%s", print_in_addr_t (addr, (flags & MAPF_IA_EMPTY_IF_UNDEF) ? IA_EMPTY_IF_UNDEF : 0, gc));
- if (maddr.type & MR_WITH_NETBITS)
+ if (flags & MAPF_SUBNET)
{
- if (flags & MAPF_SUBNET)
- {
- const in_addr_t netmask = netbits_to_netmask (maddr.netbits);
- buf_printf (&out, "/%s", print_in_addr_t (netmask, 0, gc));
- }
- else
- buf_printf (&out, "/%d", maddr.netbits);
+ const in_addr_t netmask = netbits_to_netmask (maddr.netbits);
+ buf_printf (&out, "/%s", print_in_addr_t (netmask, 0, gc));
}
+ else
+ buf_printf (&out, "/%d", maddr.netbits);
}
if (maddr.type & MR_WITH_PORT)
{
- port = buf_read_u16 (&buf);
- if (port >= 0)
- buf_printf (&out, ":%d", port);
+ buf_printf (&out, ":%d", ntohs (maddr.v4.port));
}
}
break;
case MR_ADDR_IPV6:
{
- buf_printf (&out, "%s",
- print_in6_addr( *(struct in6_addr*)&maddr.addr, 0, gc));
+ if ( IN6_IS_ADDR_V4MAPPED( &maddr.v6.addr ) )
+ {
+ buf_printf (&out, "%s", print_in_addr_t (maddr.v4mappedv6.addr,
+ IA_NET_ORDER, gc));
+ }
+ else
+ {
+ buf_printf (&out, "%s", print_in6_addr (maddr.v6.addr, 0, gc));
+ }
if (maddr.type & MR_WITH_NETBITS)
{
buf_printf (&out, "/%d", maddr.netbits);
@@ -487,62 +492,28 @@ mroute_helper_regenerate (struct mroute_helper *mh)
}
void
-mroute_helper_add_iroute (struct mroute_helper *mh, const struct iroute *ir)
-{
- if (ir->netbits >= 0)
- {
- ASSERT (ir->netbits < MR_HELPER_NET_LEN);
- ++mh->cache_generation;
- ++mh->net_len_refcount[ir->netbits];
- if (mh->net_len_refcount[ir->netbits] == 1)
- mroute_helper_regenerate (mh);
- }
-}
-
-void
-mroute_helper_del_iroute (struct mroute_helper *mh, const struct iroute *ir)
-{
- if (ir->netbits >= 0)
- {
- ASSERT (ir->netbits < MR_HELPER_NET_LEN);
- ++mh->cache_generation;
- --mh->net_len_refcount[ir->netbits];
- ASSERT (mh->net_len_refcount[ir->netbits] >= 0);
- if (!mh->net_len_refcount[ir->netbits])
- mroute_helper_regenerate (mh);
- }
-}
-
-/* this is a bit inelegant, we really should have a helper to that
- * is only passed the netbits value, and not the whole struct iroute *
- * - thus one helper could do IPv4 and IPv6. For the sake of "not change
- * code unrelated to IPv4" this is left for later cleanup, for now.
- */
-void
-mroute_helper_add_iroute6 (struct mroute_helper *mh,
- const struct iroute_ipv6 *ir6)
+mroute_helper_add_iroute46 (struct mroute_helper *mh, int netbits)
{
- if (ir6->netbits >= 0)
+ if (netbits >= 0)
{
- ASSERT (ir6->netbits < MR_HELPER_NET_LEN);
+ ASSERT (netbits < MR_HELPER_NET_LEN);
++mh->cache_generation;
- ++mh->net_len_refcount[ir6->netbits];
- if (mh->net_len_refcount[ir6->netbits] == 1)
+ ++mh->net_len_refcount[netbits];
+ if (mh->net_len_refcount[netbits] == 1)
mroute_helper_regenerate (mh);
}
}
void
-mroute_helper_del_iroute6 (struct mroute_helper *mh,
- const struct iroute_ipv6 *ir6)
+mroute_helper_del_iroute46 (struct mroute_helper *mh, int netbits)
{
- if (ir6->netbits >= 0)
+ if (netbits >= 0)
{
- ASSERT (ir6->netbits < MR_HELPER_NET_LEN);
+ ASSERT (netbits < MR_HELPER_NET_LEN);
++mh->cache_generation;
- --mh->net_len_refcount[ir6->netbits];
- ASSERT (mh->net_len_refcount[ir6->netbits] >= 0);
- if (!mh->net_len_refcount[ir6->netbits])
+ --mh->net_len_refcount[netbits];
+ ASSERT (mh->net_len_refcount[netbits] >= 0);
+ if (!mh->net_len_refcount[netbits])
mroute_helper_regenerate (mh);
}
}
diff --git a/src/openvpn/mroute.h b/src/openvpn/mroute.h
index b72b5ff..8f7a064 100644
--- a/src/openvpn/mroute.h
+++ b/src/openvpn/mroute.h
@@ -31,6 +31,8 @@
#include "list.h"
#include "route.h"
+#include <stddef.h>
+
#define IP_MCAST_SUBNET_MASK ((in_addr_t)240<<24)
#define IP_MCAST_NETWORK ((in_addr_t)224<<24)
@@ -79,9 +81,45 @@ struct mroute_addr {
uint8_t type; /* MR_ADDR/MR_WITH flags */
uint8_t netbits; /* number of bits in network part of address,
valid if MR_WITH_NETBITS is set */
- uint8_t addr[MR_MAX_ADDR_LEN]; /* actual address */
+ union {
+ uint8_t raw_addr[MR_MAX_ADDR_LEN]; /* actual address */
+ uint8_t eth_addr[OPENVPN_ETH_ALEN];
+ struct {
+ in_addr_t addr; /* _network order_ IPv4 address */
+ in_port_t port; /* _network order_ TCP/UDP port */
+ } v4;
+ struct {
+ struct in6_addr addr;
+ in_port_t port; /* _network order_ TCP/UDP port */
+ } v6;
+ struct {
+ uint8_t prefix[12];
+ in_addr_t addr; /* _network order_ IPv4 address */
+ } v4mappedv6;
+ }
+#ifndef HAVE_ANONYMOUS_UNION_SUPPORT
+/* Wrappers to support compilers that do not grok anonymous unions */
+ mroute_union
+#define raw_addr mroute_union.raw_addr
+#define eth_addr mroute_union.eth_addr
+#define v4 mroute_union.v4
+#define v6 mroute_union.v6
+#define v4mappedv6 mroute_union.v4mappedv6
+#endif
+ ;
};
+/* Double-check that struct packing works as expected */
+static_assert (offsetof(struct mroute_addr, v4.port) ==
+ offsetof(struct mroute_addr, v4) + 4,
+ "Unexpected struct packing of v4");
+static_assert (offsetof(struct mroute_addr, v6.port) ==
+ offsetof(struct mroute_addr, v6) + 16,
+ "Unexpected struct packing of v6");
+static_assert (offsetof(struct mroute_addr, v4mappedv6.addr) ==
+ offsetof(struct mroute_addr, v4mappedv6) + 12,
+ "Unexpected struct packing of v4mappedv6");
+
/*
* Number of bits in an address. Should be raised for IPv6.
*/
@@ -125,10 +163,8 @@ void mroute_addr_mask_host_bits (struct mroute_addr *ma);
struct mroute_helper *mroute_helper_init (int ageable_ttl_secs);
void mroute_helper_free (struct mroute_helper *mh);
-void mroute_helper_add_iroute (struct mroute_helper *mh, const struct iroute *ir);
-void mroute_helper_del_iroute (struct mroute_helper *mh, const struct iroute *ir);
-void mroute_helper_add_iroute6 (struct mroute_helper *mh, const struct iroute_ipv6 *ir6);
-void mroute_helper_del_iroute6 (struct mroute_helper *mh, const struct iroute_ipv6 *ir6);
+void mroute_helper_add_iroute46 (struct mroute_helper *mh, int netbits);
+void mroute_helper_del_iroute46 (struct mroute_helper *mh, int netbits);
/*
* Given a raw packet in buf, return the src and dest
@@ -169,7 +205,7 @@ mroute_addr_equal (const struct mroute_addr *a1, const struct mroute_addr *a2)
return false;
if (a1->len != a2->len)
return false;
- return memcmp (a1->addr, a2->addr, a1->len) == 0;
+ return memcmp (a1->raw_addr, a2->raw_addr, a1->len) == 0;
}
static inline const uint8_t *
@@ -191,16 +227,17 @@ mroute_extract_in_addr_t (struct mroute_addr *dest, const in_addr_t src)
dest->type = MR_ADDR_IPV4;
dest->netbits = 0;
dest->len = 4;
- *(in_addr_t*)dest->addr = htonl (src);
+ dest->v4.addr = htonl (src);
}
static inline in_addr_t
in_addr_t_from_mroute_addr (const struct mroute_addr *addr)
{
- if ((addr->type & MR_ADDR_MASK) == MR_ADDR_IPV4 && addr->netbits == 0 && addr->len == 4)
- return ntohl(*(in_addr_t*)addr->addr);
- else
+ if ((addr->type & MR_ADDR_MASK) == MR_ADDR_IPV4 && addr->netbits == 0 && addr->len == 4) {
+ return ntohl(addr->v4.addr);
+ } else {
return 0;
+ }
}
static inline void
diff --git a/src/openvpn/mtcp.c b/src/openvpn/mtcp.c
index dc15f09..78e5ccd 100644
--- a/src/openvpn/mtcp.c
+++ b/src/openvpn/mtcp.c
@@ -37,6 +37,10 @@
#include "memdbg.h"
+#ifdef HAVE_SYS_INOTIFY_H
+#include <sys/inotify.h>
+#endif
+
/*
* TCP States
*/
@@ -62,6 +66,10 @@
# define MTCP_MANAGEMENT ((void*)4)
#endif
+#ifdef ENABLE_ASYNC_PUSH
+#define MTCP_FILE_CLOSE_WRITE ((void*)5)
+#endif
+
#define MTCP_N ((void*)16) /* upper bound on MTCP_x */
struct ta_iow_flags
@@ -245,6 +253,12 @@ multi_tcp_wait (const struct context *c,
if (management)
management_socket_set (management, mtcp->es, MTCP_MANAGEMENT, &mtcp->management_persist_flags);
#endif
+
+#ifdef ENABLE_ASYNC_PUSH
+ /* arm inotify watcher */
+ event_ctl (mtcp->es, c->c2.inotify_fd, EVENT_READ, MTCP_FILE_CLOSE_WRITE);
+#endif
+
status = event_wait (mtcp->es, &c->c2.timeval, mtcp->esr, mtcp->maxevents);
update_time ();
mtcp->n_esr = 0;
@@ -636,6 +650,12 @@ multi_tcp_process_io (struct multi_context *m)
{
get_signal (&m->top.sig->signal_received);
}
+#ifdef ENABLE_ASYNC_PUSH
+ else if (e->arg == MTCP_FILE_CLOSE_WRITE)
+ {
+ multi_process_file_closed (m, MPP_PRE_SELECT | MPP_RECORD_TOUCH);
+ }
+#endif
}
if (IS_SIG (&m->top))
break;
@@ -676,7 +696,7 @@ tunnel_server_tcp (struct context *top)
multi_init (&multi, top, true, MC_SINGLE_THREADED);
/* initialize our cloned top object */
- multi_top_init (&multi, top, true);
+ multi_top_init (&multi, top);
/* initialize management interface */
init_management_callback_multi (&multi);
@@ -684,6 +704,14 @@ tunnel_server_tcp (struct context *top)
/* finished with initialization */
initialization_sequence_completed (top, ISC_SERVER); /* --mode server --proto tcp-server */
+#ifdef ENABLE_ASYNC_PUSH
+ multi.top.c2.inotify_fd = inotify_init();
+ if (multi.top.c2.inotify_fd < 0)
+ {
+ msg (D_MULTI_ERRORS, "MULTI: inotify_init error: %s", strerror(errno));
+ }
+#endif
+
/* per-packet event loop */
while (true)
{
@@ -712,6 +740,10 @@ tunnel_server_tcp (struct context *top)
perf_pop ();
}
+#ifdef ENABLE_ASYNC_PUSH
+ close(top->c2.inotify_fd);
+#endif
+
/* shut down management interface */
uninit_management_callback_multi (&multi);
diff --git a/src/openvpn/mtu.c b/src/openvpn/mtu.c
index 13f3f6c..8cbaa86 100644
--- a/src/openvpn/mtu.c
+++ b/src/openvpn/mtu.c
@@ -35,6 +35,7 @@
#include "error.h"
#include "integer.h"
#include "mtu.h"
+#include "options.h"
#include "memdbg.h"
@@ -78,8 +79,6 @@ frame_finalize (struct frame *frame,
}
frame->link_mtu_dynamic = frame->link_mtu;
-
- frame->extra_buffer += PAYLOAD_ALIGN;
}
/*
@@ -127,6 +126,15 @@ frame_subtract_extra (struct frame *frame, const struct frame *src)
}
void
+frame_init_mssfix (struct frame *frame, const struct options *options)
+{
+ if (options->ce.mssfix)
+ {
+ frame_set_mtu_dynamic (frame, options->ce.mssfix, SET_MTU_UPPER_BOUND);
+ }
+}
+
+void
frame_print (const struct frame *frame,
int level,
const char *prefix)
@@ -153,18 +161,32 @@ frame_print (const struct frame *frame,
#define MTUDISC_NOT_SUPPORTED_MSG "--mtu-disc is not supported on this OS"
void
-set_mtu_discover_type (int sd, int mtu_type)
+set_mtu_discover_type (int sd, int mtu_type, sa_family_t proto_af)
{
if (mtu_type >= 0)
{
-#if defined(HAVE_SETSOCKOPT) && defined(SOL_IP) && defined(IP_MTU_DISCOVER)
- if (setsockopt
- (sd, SOL_IP, IP_MTU_DISCOVER, &mtu_type, sizeof (mtu_type)))
- msg (M_ERR, "Error setting IP_MTU_DISCOVER type=%d on TCP/UDP socket",
- mtu_type);
-#else
- msg (M_FATAL, MTUDISC_NOT_SUPPORTED_MSG);
+ switch (proto_af)
+ {
+#if defined(HAVE_SETSOCKOPT) && defined(IP_MTU_DISCOVER)
+ case AF_INET:
+ if (setsockopt
+ (sd, IPPROTO_IP, IP_MTU_DISCOVER, &mtu_type, sizeof (mtu_type)))
+ msg (M_ERR, "Error setting IP_MTU_DISCOVER type=%d on TCP/UDP socket",
+ mtu_type);
+ break;
+#endif
+#if defined(HAVE_SETSOCKOPT) && defined(IPV6_MTU_DISCOVER)
+ case AF_INET6:
+ if (setsockopt
+ (sd, IPPROTO_IPV6, IPV6_MTU_DISCOVER, &mtu_type, sizeof (mtu_type)))
+ msg (M_ERR, "Error setting IPV6_MTU_DISCOVER type=%d on TCP6/UDP6 socket",
+ mtu_type);
+ break;
#endif
+ default:
+ msg (M_FATAL, MTUDISC_NOT_SUPPORTED_MSG);
+ break;
+ }
}
}
@@ -288,7 +310,7 @@ void
set_sock_extended_error_passing (int sd)
{
int on = 1;
- if (setsockopt (sd, SOL_IP, IP_RECVERR, &on, sizeof (on)))
+ if (setsockopt (sd, SOL_IP, IP_RECVERR, (void *) &on, sizeof (on)))
msg (M_WARN | M_ERRNO,
"Note: enable extended error passing on TCP/UDP socket failed (IP_RECVERR)");
}
diff --git a/src/openvpn/mtu.h b/src/openvpn/mtu.h
index bccd681..0320545 100644
--- a/src/openvpn/mtu.h
+++ b/src/openvpn/mtu.h
@@ -135,6 +135,9 @@ struct frame {
int align_adjust;
};
+/* Forward declarations, to prevent includes */
+struct options;
+
/* Routines which read struct frame should use the macros below */
/*
@@ -207,7 +210,7 @@ void frame_print (const struct frame *frame,
int level,
const char *prefix);
-void set_mtu_discover_type (int sd, int mtu_type);
+void set_mtu_discover_type (int sd, int mtu_type, sa_family_t proto_af);
int translate_mtu_discover_type_name (const char *name);
/*
@@ -227,6 +230,9 @@ void alloc_buf_sock_tun (struct buffer *buf,
const bool tuntap_buffer,
const unsigned int align_mask);
+/** Set the --mssfix option. */
+void frame_init_mssfix (struct frame *frame, const struct options *options);
+
/*
* EXTENDED_SOCKET_ERROR_CAPABILITY functions -- print extra error info
* on socket errors, such as PMTU size. As of 2003.05.11, only works
diff --git a/src/openvpn/mudp.c b/src/openvpn/mudp.c
index 3468dab..fec5e8d 100644
--- a/src/openvpn/mudp.c
+++ b/src/openvpn/mudp.c
@@ -33,10 +33,15 @@
#if P2MP_SERVER
#include "multi.h"
+#include <inttypes.h>
#include "forward-inline.h"
#include "memdbg.h"
+#ifdef HAVE_SYS_INOTIFY_H
+#include <sys/inotify.h>
+#endif
+
/*
* Get a client instance based on real address. If
* the instance doesn't exist, create it while
@@ -44,26 +49,54 @@
*/
struct multi_instance *
-multi_get_create_instance_udp (struct multi_context *m)
+multi_get_create_instance_udp (struct multi_context *m, bool *floated)
{
struct gc_arena gc = gc_new ();
struct mroute_addr real;
struct multi_instance *mi = NULL;
struct hash *hash = m->hash;
- if (mroute_extract_openvpn_sockaddr (&real, &m->top.c2.from.dest, true))
+ if (mroute_extract_openvpn_sockaddr (&real, &m->top.c2.from.dest, true) &&
+ m->top.c2.buf.len > 0)
{
struct hash_element *he;
const uint32_t hv = hash_value (hash, &real);
struct hash_bucket *bucket = hash_bucket (hash, hv);
-
- he = hash_lookup_fast (hash, bucket, &real, hv);
+ uint8_t* ptr = BPTR(&m->top.c2.buf);
+ uint8_t op = ptr[0] >> P_OPCODE_SHIFT;
+ bool v2 = (op == P_DATA_V2) && (m->top.c2.buf.len >= (1 + 3));
+ bool peer_id_disabled = false;
- if (he)
+ /* make sure buffer has enough length to read opcode (1 byte) and peer-id (3 bytes) */
+ if (v2)
{
- mi = (struct multi_instance *) he->value;
+ uint32_t peer_id = ntohl(*(uint32_t*)ptr) & 0xFFFFFF;
+ peer_id_disabled = (peer_id == MAX_PEER_ID);
+
+ if (!peer_id_disabled && (peer_id < m->max_clients) && (m->instances[peer_id]))
+ {
+ mi = m->instances[peer_id];
+
+ *floated = !link_socket_actual_match(&mi->context.c2.from, &m->top.c2.from);
+
+ if (*floated)
+ {
+ /* reset prefix, since here we are not sure peer is the one it claims to be */
+ ungenerate_prefix(mi);
+ msg (D_MULTI_MEDIUM, "Float requested for peer %" PRIu32 " to %s", peer_id,
+ mroute_addr_print (&real, &gc));
+ }
+ }
}
- else
+ if (!v2 || peer_id_disabled)
+ {
+ he = hash_lookup_fast (hash, bucket, &real, hv);
+ if (he)
+ {
+ mi = (struct multi_instance *) he->value;
+ }
+ }
+ if (!mi)
{
if (!m->top.c2.tls_auth_standalone
|| tls_pre_decrypt_lite (m->top.c2.tls_auth_standalone, &m->top.c2.from, &m->top.c2.buf))
@@ -73,8 +106,27 @@ multi_get_create_instance_udp (struct multi_context *m)
mi = multi_create_instance (m, &real);
if (mi)
{
+ int i;
+
hash_add_fast (hash, bucket, &mi->real, hv, mi);
mi->did_real_hash = true;
+
+ /* max_clients must be less then max peer-id value */
+ ASSERT(m->max_clients < MAX_PEER_ID);
+
+ for (i = 0; i < m->max_clients; ++i)
+ {
+ if (!m->instances[i])
+ {
+ mi->context.c2.tls_multi->peer_id = i;
+ m->instances[i] = mi;
+ break;
+ }
+ }
+
+ /* should not really end up here, since multi_create_instance returns null
+ * if amount of clients exceeds max_clients */
+ ASSERT(i < m->max_clients);
}
}
else
@@ -89,15 +141,8 @@ multi_get_create_instance_udp (struct multi_context *m)
#ifdef ENABLE_DEBUG
if (check_debug_level (D_MULTI_DEBUG))
{
- const char *status;
-
- if (he && mi)
- status = "[succeeded]";
- else if (!he && mi)
- status = "[created]";
- else
- status = "[failed]";
-
+ const char *status = mi ? "[ok]" : "[failed]";
+
dmsg (D_MULTI_DEBUG, "GET INST BY REAL: %s %s",
mroute_addr_print (&real, &gc),
status);
@@ -143,6 +188,10 @@ multi_process_io_udp (struct multi_context *m)
strcat (buf, "TR/");
else if (status & TUN_WRITE)
strcat (buf, "TW/");
+#ifdef ENABLE_ASYNC_PUSH
+ else if (status & FILE_CLOSED)
+ strcat (buf, "FC/");
+#endif
printf ("IO %s\n", buf);
#endif
@@ -168,7 +217,6 @@ multi_process_io_udp (struct multi_context *m)
else if (status & SOCKET_READ)
{
read_incoming_link (&m->top);
- multi_release_io_lock (m);
if (!IS_SIG (&m->top))
multi_process_incoming_link (m, NULL, mpp_flags);
}
@@ -176,10 +224,16 @@ multi_process_io_udp (struct multi_context *m)
else if (status & TUN_READ)
{
read_incoming_tun (&m->top);
- multi_release_io_lock (m);
if (!IS_SIG (&m->top))
multi_process_incoming_tun (m, mpp_flags);
}
+#ifdef ENABLE_ASYNC_PUSH
+ /* INOTIFY callback */
+ else if (status & FILE_CLOSED)
+ {
+ multi_process_file_closed(m, mpp_flags);
+ }
+#endif
}
/*
@@ -234,7 +288,7 @@ tunnel_server_udp_single_threaded (struct context *top)
multi_init (&multi, top, false, MC_SINGLE_THREADED);
/* initialize our cloned top object */
- multi_top_init (&multi, top, true);
+ multi_top_init (&multi, top);
/* initialize management interface */
init_management_callback_multi (&multi);
@@ -242,6 +296,14 @@ tunnel_server_udp_single_threaded (struct context *top)
/* finished with initialization */
initialization_sequence_completed (top, ISC_SERVER); /* --mode server --proto udp */
+#ifdef ENABLE_ASYNC_PUSH
+ multi.top.c2.inotify_fd = inotify_init();
+ if (multi.top.c2.inotify_fd < 0)
+ {
+ msg (D_MULTI_ERRORS, "MULTI: inotify_init error: %s", strerror(errno));
+ }
+#endif
+
/* per-packet event loop */
while (true)
{
@@ -270,6 +332,10 @@ tunnel_server_udp_single_threaded (struct context *top)
perf_pop ();
}
+#ifdef ENABLE_ASYNC_PUSH
+ close(top->c2.inotify_fd);
+#endif
+
/* shut down management interface */
uninit_management_callback_multi (&multi);
diff --git a/src/openvpn/mudp.h b/src/openvpn/mudp.h
index 97f961b..1f15d9d 100644
--- a/src/openvpn/mudp.h
+++ b/src/openvpn/mudp.h
@@ -65,7 +65,7 @@ void tunnel_server_udp (struct context *top);
* packet's source address or if one was a newly created successfully.
* NULL if one did not yet exist and a new one was not created.
*/
-struct multi_instance *multi_get_create_instance_udp (struct multi_context *m);
+struct multi_instance *multi_get_create_instance_udp (struct multi_context *m, bool *floated);
#endif
#endif
diff --git a/src/openvpn/multi.c b/src/openvpn/multi.c
index 577c5d3..8f3d34e 100644
--- a/src/openvpn/multi.c
+++ b/src/openvpn/multi.c
@@ -28,6 +28,11 @@
#include "config-msvc.h"
#endif
+#ifdef HAVE_SYS_INOTIFY_H
+#include <sys/inotify.h>
+#define INOTIFY_EVENT_BUFFER_SIZE 16384
+#endif
+
#include "syshead.h"
#if P2MP_SERVER
@@ -38,6 +43,8 @@
#include "otime.h"
#include "gremlin.h"
#include "mstats.h"
+#include "ssl_verify.h"
+#include <inttypes.h>
#include "memdbg.h"
@@ -119,10 +126,8 @@ learn_address_script (const struct multi_context *m,
{
struct argv argv = argv_new ();
setenv_str (es, "script_type", "learn-address");
- argv_printf (&argv, "%sc %s %s",
- m->top.options.learn_address_script,
- op,
- mroute_addr_print (addr, &gc));
+ argv_parse_cmd (&argv, m->top.options.learn_address_script);
+ argv_printf_cat (&argv, "%s %s", op, mroute_addr_print (addr, &gc));
if (mi)
argv_printf_cat (&argv, "%s", tls_common_name (mi->context.c2.tls_multi, false));
if (!openvpn_run_script (&argv, es, 0, "--learn-address"))
@@ -241,6 +246,23 @@ cid_compare_function (const void *key1, const void *key2)
#endif
+#ifdef ENABLE_ASYNC_PUSH
+static uint32_t
+/*
+ * inotify watcher descriptors are used as hash value
+ */
+int_hash_function (const void *key, uint32_t iv)
+{
+ return (unsigned long)key;
+}
+
+static bool
+int_compare_function (const void *key1, const void *key2)
+{
+ return (unsigned long)key1 == (unsigned long)key2;
+}
+#endif
+
/*
* Main initialization function, init multi_context object.
*/
@@ -302,6 +324,17 @@ multi_init (struct multi_context *m, struct context *t, bool tcp_mode, int threa
cid_compare_function);
#endif
+#ifdef ENABLE_ASYNC_PUSH
+ /*
+ * Mapping between inotify watch descriptors and
+ * multi_instances.
+ */
+ m->inotify_watchers = hash_init (t->options.real_hash_size,
+ get_random(),
+ int_hash_function,
+ int_compare_function);
+#endif
+
/*
* This is our scheduler, for time-based wakeup
* events.
@@ -372,6 +405,8 @@ multi_init (struct multi_context *m, struct context *t, bool tcp_mode, int threa
*/
m->max_clients = t->options.max_clients;
+ m->instances = calloc(m->max_clients, sizeof(struct multi_instance*));
+
/*
* Initialize multi-socket TCP I/O wait object
*/
@@ -392,6 +427,8 @@ multi_init (struct multi_context *m, struct context *t, bool tcp_mode, int threa
t->options.stale_routes_check_interval, t->options.stale_routes_ageing_time);
event_timeout_init (&m->stale_routes_check_et, t->options.stale_routes_check_interval, 0);
}
+
+ m->deferred_shutdown_signal.signal_received = 0;
}
const char *
@@ -399,7 +436,7 @@ multi_instance_string (const struct multi_instance *mi, bool null, struct gc_are
{
if (mi)
{
- struct buffer out = alloc_buf_gc (256, gc);
+ struct buffer out = alloc_buf_gc (MULTI_PREFIX_MAX_LENGTH, gc);
const char *cn = tls_common_name (mi->context.c2.tls_multi, true);
if (cn)
@@ -416,21 +453,27 @@ multi_instance_string (const struct multi_instance *mi, bool null, struct gc_are
void
generate_prefix (struct multi_instance *mi)
{
- mi->msg_prefix = multi_instance_string (mi, true, &mi->gc);
+ struct gc_arena gc = gc_new();
+ const char *prefix = multi_instance_string (mi, true, &gc);
+ if (prefix)
+ strncpynt(mi->msg_prefix, prefix, sizeof(mi->msg_prefix));
+ else
+ mi->msg_prefix[0] = '\0';
set_prefix (mi);
+ gc_free(&gc);
}
void
ungenerate_prefix (struct multi_instance *mi)
{
- mi->msg_prefix = NULL;
+ mi->msg_prefix[0] = '\0';
set_prefix (mi);
}
static const char *
mi_prefix (const struct multi_instance *mi)
{
- if (mi && mi->msg_prefix)
+ if (mi && mi->msg_prefix[0])
return mi->msg_prefix;
else
return "UNDEF_I";
@@ -450,10 +493,10 @@ multi_del_iroutes (struct multi_context *m,
if (TUNNEL_TYPE (mi->context.c1.tuntap) == DEV_TYPE_TUN)
{
for (ir = mi->context.options.iroutes; ir != NULL; ir = ir->next)
- mroute_helper_del_iroute (m->route_helper, ir);
+ mroute_helper_del_iroute46 (m->route_helper, ir->netbits);
for ( ir6 = mi->context.options.iroutes_ipv6; ir6 != NULL; ir6 = ir6->next )
- mroute_helper_del_iroute6 (m->route_helper, ir6);
+ mroute_helper_del_iroute46 (m->route_helper, ir6->netbits);
}
}
@@ -500,7 +543,7 @@ multi_client_disconnect_script (struct multi_context *m,
{
struct argv argv = argv_new ();
setenv_str (mi->context.c2.es, "script_type", "client-disconnect");
- argv_printf (&argv, "%sc", mi->context.options.client_disconnect_script);
+ argv_parse_cmd (&argv, mi->context.options.client_disconnect_script);
openvpn_run_script (&argv, mi->context.c2.es, 0, "--client-disconnect");
argv_reset (&argv);
}
@@ -552,6 +595,17 @@ multi_close_instance (struct multi_context *m,
}
#endif
+#ifdef ENABLE_ASYNC_PUSH
+ if (mi->inotify_watch != -1)
+ {
+ hash_remove(m->inotify_watchers, (void*) (unsigned long)mi->inotify_watch);
+ mi->inotify_watch = -1;
+ }
+#endif
+
+ if (mi->context.c2.tls_multi->peer_id != MAX_PEER_ID)
+ m->instances[mi->context.c2.tls_multi->peer_id] = NULL;
+
schedule_remove_entry (m->schedule, (struct schedule_entry *) mi);
ifconfig_pool_release (m->ifconfig_pool, mi->vaddr_handle, false);
@@ -628,6 +682,13 @@ multi_uninit (struct multi_context *m)
#endif
m->hash = NULL;
+ free(m->instances);
+
+#ifdef ENABLE_ASYNC_PUSH
+ hash_free (m->inotify_watchers);
+ m->inotify_watchers = NULL;
+#endif
+
schedule_free (m->schedule);
mbuf_free (m->mbuf);
ifconfig_pool_free (m->ifconfig_pool);
@@ -704,6 +765,11 @@ multi_create_instance (struct multi_context *m, const struct mroute_addr *real)
mi->context.c2.push_reply_deferred = true;
+#ifdef ENABLE_ASYNC_PUSH
+ mi->context.c2.push_request_received = false;
+ mi->inotify_watch = -1;
+#endif
+
if (!multi_process_post (m, mi, MPP_PRE_SELECT))
{
msg (D_MULTI_ERRORS, "MULTI: signal occurred during client instance initialization");
@@ -807,8 +873,8 @@ multi_print_status (struct multi_context *m, struct status_output *so, const int
*/
status_printf (so, "TITLE%c%s", sep, title_string);
status_printf (so, "TIME%c%s%c%u", sep, time_string (now, 0, false, &gc_top), sep, (unsigned int)now);
- status_printf (so, "HEADER%cCLIENT_LIST%cCommon Name%cReal Address%cVirtual Address%cBytes Received%cBytes Sent%cConnected Since%cConnected Since (time_t)%cUsername",
- sep, sep, sep, sep, sep, sep, sep, sep, sep);
+ status_printf (so, "HEADER%cCLIENT_LIST%cCommon Name%cReal Address%cVirtual Address%cVirtual IPv6 Address%cBytes Received%cBytes Sent%cConnected Since%cConnected Since (time_t)%cUsername%cClient ID%cPeer ID",
+ sep, sep, sep, sep, sep, sep, sep, sep, sep, sep, sep, sep);
hash_iterator_init (m->hash, &hi);
while ((he = hash_iterator_next (&hi)))
{
@@ -817,15 +883,28 @@ multi_print_status (struct multi_context *m, struct status_output *so, const int
if (!mi->halt)
{
- status_printf (so, "CLIENT_LIST%c%s%c%s%c%s%c" counter_format "%c" counter_format "%c%s%c%u%c%s",
+ status_printf (so, "CLIENT_LIST%c%s%c%s%c%s%c%s%c" counter_format "%c" counter_format "%c%s%c%u%c%s%c"
+#ifdef MANAGEMENT_DEF_AUTH
+ "%lu"
+#else
+ ""
+#endif
+ "%c%"PRIu32,
sep, tls_common_name (mi->context.c2.tls_multi, false),
sep, mroute_addr_print (&mi->real, &gc),
sep, print_in_addr_t (mi->reporting_addr, IA_EMPTY_IF_UNDEF, &gc),
+ sep, print_in6_addr (mi->reporting_addr_ipv6, IA_EMPTY_IF_UNDEF, &gc),
sep, mi->context.c2.link_read_bytes,
sep, mi->context.c2.link_write_bytes,
sep, time_string (mi->created, 0, false, &gc),
sep, (unsigned int)mi->created,
- sep, tls_username (mi->context.c2.tls_multi, false));
+ sep, tls_username (mi->context.c2.tls_multi, false),
+#ifdef MANAGEMENT_DEF_AUTH
+ sep, mi->context.c2.mda_context.cid,
+#else
+ sep,
+#endif
+ sep, mi->context.c2.tls_multi ? mi->context.c2.tls_multi->peer_id : UINT32_MAX);
}
gc_free (&gc);
}
@@ -896,6 +975,13 @@ multi_print_status (struct multi_context *m, struct status_output *so, const int
status_flush (so);
gc_free (&gc_top);
}
+
+#ifdef ENABLE_ASYNC_PUSH
+ if (m->inotify_watchers)
+ {
+ msg (D_MULTI_DEBUG, "inotify watchers count: %d\n", hash_n_elements(m->inotify_watchers));
+ }
+#endif
}
/*
@@ -1113,7 +1199,7 @@ multi_learn_in6_addr (struct multi_context *m,
addr.len = 16;
addr.type = MR_ADDR_IPV6;
addr.netbits = 0;
- memcpy( &addr.addr, &a6, sizeof(a6) );
+ addr.v6.addr = a6;
if (netbits >= 0)
{
@@ -1158,23 +1244,18 @@ multi_add_iroutes (struct multi_context *m,
print_in_addr_t (ir->network, 0, &gc),
multi_instance_string (mi, false, &gc));
- mroute_helper_add_iroute (m->route_helper, ir);
+ mroute_helper_add_iroute46 (m->route_helper, ir->netbits);
multi_learn_in_addr_t (m, mi, ir->network, ir->netbits, false);
}
for ( ir6 = mi->context.options.iroutes_ipv6; ir6 != NULL; ir6 = ir6->next )
{
- if (ir6->netbits >= 0)
- msg (D_MULTI_LOW, "MULTI: internal route %s/%d -> %s",
+ msg (D_MULTI_LOW, "MULTI: internal route %s/%d -> %s",
print_in6_addr (ir6->network, 0, &gc),
ir6->netbits,
multi_instance_string (mi, false, &gc));
- else
- msg (D_MULTI_LOW, "MULTI: internal route %s -> %s",
- print_in6_addr (ir6->network, 0, &gc),
- multi_instance_string (mi, false, &gc));
- mroute_helper_add_iroute6 (m->route_helper, ir6);
+ mroute_helper_add_iroute46 (m->route_helper, ir6->netbits);
multi_learn_in6_addr (m, mi, ir6->network, ir6->netbits, false);
}
@@ -1289,16 +1370,13 @@ multi_select_virtual_addr (struct multi_context *m, struct multi_instance *mi)
mi->context.c2.push_ifconfig_defined = true;
mi->context.c2.push_ifconfig_local = mi->context.options.push_ifconfig_local;
mi->context.c2.push_ifconfig_remote_netmask = mi->context.options.push_ifconfig_remote_netmask;
-#ifdef ENABLE_CLIENT_NAT
mi->context.c2.push_ifconfig_local_alias = mi->context.options.push_ifconfig_local_alias;
-#endif
/* the current implementation does not allow "static IPv4, pool IPv6",
* (see below) so issue a warning if that happens - don't break the
* session, though, as we don't even know if this client WANTS IPv6
*/
- if ( mi->context.c1.tuntap->ipv6 &&
- mi->context.options.ifconfig_ipv6_pool_defined &&
+ if ( mi->context.options.ifconfig_ipv6_pool_defined &&
! mi->context.options.push_ifconfig_ipv6_defined )
{
msg( M_INFO, "MULTI_sva: WARNING: if --ifconfig-push is used for IPv4, automatic IPv6 assignment from --ifconfig-ipv6-pool does not work. Use --ifconfig-ipv6-push for IPv6 then." );
@@ -1351,10 +1429,10 @@ multi_select_virtual_addr (struct multi_context *m, struct multi_instance *mi)
if ( mi->context.options.ifconfig_ipv6_pool_defined )
{
mi->context.c2.push_ifconfig_ipv6_local = remote_ipv6;
- mi->context.c2.push_ifconfig_ipv6_remote =
+ mi->context.c2.push_ifconfig_ipv6_remote =
mi->context.c1.tuntap->local_ipv6;
- mi->context.c2.push_ifconfig_ipv6_netbits =
- mi->context.options.ifconfig_ipv6_pool_netbits;
+ mi->context.c2.push_ifconfig_ipv6_netbits =
+ mi->context.options.ifconfig_ipv6_netbits;
mi->context.c2.push_ifconfig_ipv6_defined = true;
}
}
@@ -1371,8 +1449,7 @@ multi_select_virtual_addr (struct multi_context *m, struct multi_instance *mi)
* way round ("dynamic IPv4, static IPv6") or "both static" makes sense
* -> and so it's implemented right now
*/
- if ( mi->context.c1.tuntap->ipv6 &&
- mi->context.options.push_ifconfig_ipv6_defined )
+ if ( mi->context.options.push_ifconfig_ipv6_defined )
{
mi->context.c2.push_ifconfig_ipv6_local =
mi->context.options.push_ifconfig_ipv6_local;
@@ -1430,7 +1507,7 @@ multi_set_virtual_addr_env (struct multi_context *m, struct multi_instance *mi)
setenv_del (mi->context.c2.es, "ifconfig_pool_remote_ip6");
setenv_del (mi->context.c2.es, "ifconfig_pool_ip6_netbits");
- if (mi->context.c1.tuntap->ipv6 && mi->context.c2.push_ifconfig_ipv6_defined)
+ if (mi->context.c2.push_ifconfig_ipv6_defined)
{
setenv_in6_addr (mi->context.c2.es,
"ifconfig_pool_remote",
@@ -1755,9 +1832,8 @@ multi_connection_established (struct multi_context *m, struct multi_instance *mi
goto script_failed;
}
- argv_printf (&argv, "%sc %s",
- mi->context.options.client_connect_script,
- dc_file);
+ argv_parse_cmd (&argv, mi->context.options.client_connect_script);
+ argv_printf_cat (&argv, "%s", dc_file);
if (openvpn_run_script (&argv, mi->context.c2.es, 0, "--client-connect"))
{
@@ -1868,9 +1944,18 @@ multi_connection_established (struct multi_context *m, struct multi_instance *mi
/* set our client's VPN endpoint for status reporting purposes */
mi->reporting_addr = mi->context.c2.push_ifconfig_local;
+ mi->reporting_addr_ipv6 = mi->context.c2.push_ifconfig_ipv6_local;
/* set context-level authentication flag */
mi->context.c2.context_auth = CAS_SUCCEEDED;
+
+#ifdef ENABLE_ASYNC_PUSH
+ /* authentication complete, send push reply */
+ if (mi->context.c2.push_request_received)
+ {
+ process_incoming_push_request(&mi->context);
+ }
+#endif
}
else
{
@@ -1900,6 +1985,58 @@ multi_connection_established (struct multi_context *m, struct multi_instance *mi
mi->context.c2.push_reply_deferred = false;
}
+#ifdef ENABLE_ASYNC_PUSH
+/*
+ * Called when inotify event is fired, which happens when acf file is closed or deleted.
+ * Continues authentication and sends push_reply.
+ */
+void
+multi_process_file_closed (struct multi_context *m, const unsigned int mpp_flags)
+{
+ char buffer[INOTIFY_EVENT_BUFFER_SIZE];
+ size_t buffer_i = 0;
+ int r = read (m->top.c2.inotify_fd, buffer, INOTIFY_EVENT_BUFFER_SIZE);
+
+ while (buffer_i < r)
+ {
+ /* parse inotify events */
+ struct inotify_event *pevent = (struct inotify_event *) &buffer[buffer_i];
+ size_t event_size = sizeof (struct inotify_event) + pevent->len;
+ buffer_i += event_size;
+
+ msg(D_MULTI_DEBUG, "MULTI: modified fd %d, mask %d", pevent->wd, pevent->mask);
+
+ struct multi_instance* mi = hash_lookup(m->inotify_watchers, (void*) (unsigned long) pevent->wd);
+
+ if (pevent->mask & IN_CLOSE_WRITE)
+ {
+ if (mi)
+ {
+ /* continue authentication and send push_reply */
+ multi_process_post (m, mi, mpp_flags);
+ }
+ else
+ {
+ msg(D_MULTI_ERRORS, "MULTI: multi_instance not found!");
+ }
+ }
+ else if (pevent->mask & IN_IGNORED)
+ {
+ /* this event is _always_ fired when watch is removed or file is deleted */
+ if (mi)
+ {
+ hash_remove(m->inotify_watchers, (void*) (unsigned long) pevent->wd);
+ mi->inotify_watch = -1;
+ }
+ }
+ else
+ {
+ msg(D_MULTI_ERRORS, "MULTI: unknown mask %d", pevent->mask);
+ }
+ }
+}
+#endif
+
/*
* Add a mbuf buffer to a particular
* instance.
@@ -2060,19 +2197,50 @@ multi_process_post (struct multi_context *m, struct multi_instance *mi, const un
if (!IS_SIG (&mi->context) && ((flags & MPP_PRE_SELECT) || ((flags & MPP_CONDITIONAL_PRE_SELECT) && !ANY_OUT (&mi->context))))
{
+#if defined(ENABLE_ASYNC_PUSH) && defined(ENABLE_DEF_AUTH)
+ bool was_authenticated = false;
+ struct key_state *ks = NULL;
+ if (mi->context.c2.tls_multi)
+ {
+ ks = &mi->context.c2.tls_multi->session[TM_ACTIVE].key[KS_PRIMARY];
+ was_authenticated = ks->authenticated;
+ }
+#endif
+
/* figure timeouts and fetch possible outgoing
to_link packets (such as ping or TLS control) */
pre_select (&mi->context);
- if (!IS_SIG (&mi->context))
+#if defined(ENABLE_ASYNC_PUSH) && defined(ENABLE_DEF_AUTH)
+ if (ks && ks->auth_control_file && ks->auth_deferred && !was_authenticated)
{
- /* tell scheduler to wake us up at some point in the future */
- multi_schedule_context_wakeup(m, mi);
+ /* watch acf file */
+ long watch_descriptor = inotify_add_watch(m->top.c2.inotify_fd, ks->auth_control_file, IN_CLOSE_WRITE | IN_ONESHOT);
+ if (watch_descriptor >= 0)
+ {
+ if (mi->inotify_watch != -1)
+ {
+ hash_remove(m->inotify_watchers, (void*) (unsigned long)mi->inotify_watch);
+ }
+ hash_add (m->inotify_watchers, (const uintptr_t*)watch_descriptor, mi, true);
+ mi->inotify_watch = watch_descriptor;
+ }
+ else
+ {
+ msg(M_NONFATAL, "MULTI: inotify_add_watch error: %s", strerror(errno));
+ }
+ }
+#endif
+ if (!IS_SIG (&mi->context))
+ {
/* connection is "established" when SSL/TLS key negotiation succeeds
and (if specified) auth user/pass succeeds */
if (!mi->connection_established_flag && CONNECTION_ESTABLISHED (&mi->context))
multi_connection_established (m, mi);
+
+ /* tell scheduler to wake us up at some point in the future */
+ multi_schedule_context_wakeup(m, mi);
}
}
@@ -2107,6 +2275,72 @@ multi_process_post (struct multi_context *m, struct multi_instance *mi, const un
return ret;
}
+void multi_process_float (struct multi_context* m, struct multi_instance* mi)
+{
+ struct mroute_addr real;
+ struct hash *hash = m->hash;
+ struct gc_arena gc = gc_new ();
+
+ if (!mroute_extract_openvpn_sockaddr (&real, &m->top.c2.from.dest, true))
+ goto done;
+
+ const uint32_t hv = hash_value (hash, &real);
+ struct hash_bucket *bucket = hash_bucket (hash, hv);
+
+ /* make sure that we don't float to an address taken by another client */
+ struct hash_element *he = hash_lookup_fast (hash, bucket, &real, hv);
+ if (he)
+ {
+ struct multi_instance *ex_mi = (struct multi_instance *) he->value;
+
+ struct tls_multi *m1 = mi->context.c2.tls_multi;
+ struct tls_multi *m2 = ex_mi->context.c2.tls_multi;
+
+ /* do not float if target address is taken by client with another cert */
+ if (!cert_hash_compare(m1->locked_cert_hash_set, m2->locked_cert_hash_set))
+ {
+ msg (D_MULTI_LOW, "Disallow float to an address taken by another client %s",
+ multi_instance_string (ex_mi, false, &gc));
+
+ mi->context.c2.buf.len = 0;
+
+ goto done;
+ }
+
+ msg (D_MULTI_MEDIUM, "closing instance %s", multi_instance_string (ex_mi, false, &gc));
+ multi_close_instance(m, ex_mi, false);
+ }
+
+ msg (D_MULTI_MEDIUM, "peer %" PRIu32 " (%s) floated from %s to %s",
+ mi->context.c2.tls_multi->peer_id,
+ tls_common_name (mi->context.c2.tls_multi, false),
+ mroute_addr_print (&mi->real, &gc),
+ print_link_socket_actual (&m->top.c2.from, &gc));
+
+ /* change external network address of the remote peer */
+ mi->real = real;
+ generate_prefix (mi);
+
+ mi->context.c2.from = m->top.c2.from;
+ mi->context.c2.to_link_addr = &mi->context.c2.from;
+
+ /* inherit parent link_socket and link_socket_info */
+ mi->context.c2.link_socket = m->top.c2.link_socket;
+ mi->context.c2.link_socket_info->lsa->actual = m->top.c2.from;
+
+ tls_update_remote_addr (mi->context.c2.tls_multi, &mi->context.c2.from);
+
+ ASSERT (hash_add (m->hash, &mi->real, mi, true));
+ ASSERT (hash_add (m->iter, &mi->real, mi, true));
+
+#ifdef MANAGEMENT_DEF_AUTH
+ ASSERT (hash_add (m->cid_hash, &mi->context.c2.mda_context.cid, mi, true));
+#endif
+
+done:
+ gc_free (&gc);
+}
+
/*
* Process packets in the TCP/UDP socket -> TUN/TAP interface direction,
* i.e. client -> server direction.
@@ -2121,6 +2355,7 @@ multi_process_incoming_link (struct multi_context *m, struct multi_instance *ins
unsigned int mroute_flags;
struct multi_instance *mi;
bool ret = true;
+ bool floated = false;
if (m->pending)
return true;
@@ -2130,7 +2365,7 @@ multi_process_incoming_link (struct multi_context *m, struct multi_instance *ins
#ifdef MULTI_DEBUG_EVENT_LOOP
printf ("TCP/UDP -> TUN [%d]\n", BLEN (&m->top.c2.buf));
#endif
- multi_set_pending (m, multi_get_create_instance_udp (m));
+ multi_set_pending (m, multi_get_create_instance_udp (m, &floated));
}
else
multi_set_pending (m, instance);
@@ -2148,13 +2383,30 @@ multi_process_incoming_link (struct multi_context *m, struct multi_instance *ins
c->c2.buf = m->top.c2.buf;
/* transfer from-addr from top-level context buffer to instance */
- c->c2.from = m->top.c2.from;
+ if (!floated)
+ c->c2.from = m->top.c2.from;
}
if (BLEN (&c->c2.buf) > 0)
{
+ struct link_socket_info *lsi;
+ const uint8_t *orig_buf;
+
/* decrypt in instance context */
- process_incoming_link (c);
+
+ perf_push (PERF_PROC_IN_LINK);
+ lsi = get_link_socket_info (c);
+ orig_buf = c->c2.buf.data;
+ if (process_incoming_link_part1(c, lsi, floated))
+ {
+ if (floated)
+ {
+ multi_process_float (m, m->pending);
+ }
+
+ process_incoming_link_part2(c, lsi, orig_buf);
+ }
+ perf_pop ();
if (TUNNEL_TYPE (m->top.c1.tuntap) == DEV_TYPE_TUN)
{
@@ -2176,7 +2428,7 @@ multi_process_incoming_link (struct multi_context *m, struct multi_instance *ins
{
/* IPv6 link-local address (fe80::xxx)? */
if ( (src.type & MR_ADDR_MASK) == MR_ADDR_IPV6 &&
- src.addr[0] == 0xfe && src.addr[1] == 0x80 )
+ IN6_IS_ADDR_LINKLOCAL (&src.v6.addr) )
{
/* do nothing, for now. TODO: add address learning */
}
@@ -2478,10 +2730,18 @@ multi_process_timeout (struct multi_context *m, const unsigned int mpp_flags)
/* instance marked for wakeup? */
if (m->earliest_wakeup)
{
- set_prefix (m->earliest_wakeup);
- ret = multi_process_post (m, m->earliest_wakeup, mpp_flags);
+ if (m->earliest_wakeup == (struct multi_instance*)&m->deferred_shutdown_signal)
+ {
+ schedule_remove_entry(m->schedule, (struct schedule_entry*) &m->deferred_shutdown_signal);
+ throw_signal(m->deferred_shutdown_signal.signal_received);
+ }
+ else
+ {
+ set_prefix (m->earliest_wakeup);
+ ret = multi_process_post (m, m->earliest_wakeup, mpp_flags);
+ clear_prefix ();
+ }
m->earliest_wakeup = NULL;
- clear_prefix ();
}
return ret;
}
@@ -2591,12 +2851,10 @@ multi_process_per_second_timers_dowork (struct multi_context *m)
}
void
-multi_top_init (struct multi_context *m, const struct context *top, const bool alloc_buffers)
+multi_top_init (struct multi_context *m, const struct context *top)
{
inherit_context_top (&m->top, top);
- m->top.c2.buffers = NULL;
- if (alloc_buffers)
- m->top.c2.buffers = init_context_buffers (&top->c2.frame);
+ m->top.c2.buffers = init_context_buffers (&top->c2.frame);
}
void
@@ -2606,6 +2864,48 @@ multi_top_free (struct multi_context *m)
free_context_buffers (m->top.c2.buffers);
}
+static bool
+is_exit_restart(int sig)
+{
+ return (sig == SIGUSR1 || sig == SIGTERM || sig == SIGHUP || sig == SIGINT);
+}
+
+static void
+multi_push_restart_schedule_exit(struct multi_context *m, bool next_server)
+{
+ struct hash_iterator hi;
+ struct hash_element *he;
+ struct timeval tv;
+
+ /* tell all clients to restart */
+ hash_iterator_init (m->iter, &hi);
+ while ((he = hash_iterator_next (&hi)))
+ {
+ struct multi_instance *mi = (struct multi_instance *) he->value;
+ if (!mi->halt)
+ {
+ send_control_channel_string (&mi->context, next_server ? "RESTART,[N]" : "RESTART", D_PUSH);
+ multi_schedule_context_wakeup(m, mi);
+ }
+ }
+ hash_iterator_free (&hi);
+
+ /* reschedule signal */
+ ASSERT (!openvpn_gettimeofday (&m->deferred_shutdown_signal.wakeup, NULL));
+ tv.tv_sec = 2;
+ tv.tv_usec = 0;
+ tv_add (&m->deferred_shutdown_signal.wakeup, &tv);
+
+ m->deferred_shutdown_signal.signal_received = m->top.sig->signal_received;
+
+ schedule_add_entry (m->schedule,
+ (struct schedule_entry *) &m->deferred_shutdown_signal,
+ &m->deferred_shutdown_signal.wakeup,
+ compute_wakeup_sigma (&m->deferred_shutdown_signal.wakeup));
+
+ m->top.sig->signal_received = 0;
+}
+
/*
* Return true if event loop should break,
* false if it should continue.
@@ -2621,6 +2921,14 @@ multi_process_signal (struct multi_context *m)
m->top.sig->signal_received = 0;
return false;
}
+ else if (proto_is_dgram(m->top.options.ce.proto) &&
+ is_exit_restart(m->top.sig->signal_received) &&
+ (m->deferred_shutdown_signal.signal_received == 0) &&
+ m->top.options.ce.explicit_exit_notification != 0)
+ {
+ multi_push_restart_schedule_exit(m, m->top.options.ce.explicit_exit_notification == 2);
+ return false;
+ }
return true;
}
diff --git a/src/openvpn/multi.h b/src/openvpn/multi.h
index 2bc0c8a..0d369f3 100644
--- a/src/openvpn/multi.h
+++ b/src/openvpn/multi.h
@@ -42,6 +42,8 @@
#include "mtcp.h"
#include "perf.h"
+#define MULTI_PREFIX_MAX_LENGTH 256
+
/*
* Walk (don't run) through the routing table,
* deleting old entries, and possibly multi_instance
@@ -55,6 +57,13 @@ struct multi_reap
};
+struct deferred_signal_schedule_entry
+{
+ struct schedule_entry se;
+ int signal_received;
+ struct timeval wakeup;
+};
+
/**
* Server-mode state structure for one single VPN tunnel.
*
@@ -80,7 +89,7 @@ struct multi_instance {
struct mroute_addr real; /**< External network address of the
* remote peer. */
ifconfig_pool_handle vaddr_handle;
- const char *msg_prefix;
+ char msg_prefix[MULTI_PREFIX_MAX_LENGTH];
/* queued outgoing data in Server/TCP mode */
unsigned int tcp_rwflags;
@@ -88,6 +97,7 @@ struct multi_instance {
bool socket_set_called;
in_addr_t reporting_addr; /* IP address shown in status listing */
+ struct in6_addr reporting_addr_ipv6; /* IPv6 address in status listing */
bool did_open_context;
bool did_real_hash;
@@ -102,6 +112,10 @@ struct multi_instance {
struct context context; /**< The context structure storing state
* for this VPN tunnel. */
+
+#ifdef ENABLE_ASYNC_PUSH
+ int inotify_watch; /* watch descriptor for acf */
+#endif
};
@@ -124,6 +138,9 @@ struct multi_context {
# define MC_WORK_THREAD (MC_MULTI_THREADED_WORKER|MC_MULTI_THREADED_SCHEDULER)
int thread_mode;
+ struct multi_instance** instances; /**< Array of multi_instances. An instance can be
+ * accessed using peer-id as an index. */
+
struct hash *hash; /**< VPN tunnel instances indexed by real
* address of the remote peer. */
struct hash *vhash; /**< VPN tunnel instances indexed by
@@ -166,6 +183,13 @@ struct multi_context {
* Timer object for stale route check
*/
struct event_timeout stale_routes_check_et;
+
+#ifdef ENABLE_ASYNC_PUSH
+ /* mapping between inotify watch descriptors and multi_instances */
+ struct hash *inotify_watchers;
+#endif
+
+ struct deferred_signal_schedule_entry deferred_shutdown_signal;
};
/*
@@ -209,7 +233,7 @@ const char *multi_instance_string (const struct multi_instance *mi, bool null, s
void multi_init (struct multi_context *m, struct context *t, bool tcp_mode, int thread_mode);
void multi_uninit (struct multi_context *m);
-void multi_top_init (struct multi_context *m, const struct context *top, const bool alloc_buffers);
+void multi_top_init (struct multi_context *m, const struct context *top);
void multi_top_free (struct multi_context *m);
struct multi_instance *multi_create_instance (struct multi_context *m, const struct mroute_addr *real);
@@ -217,6 +241,16 @@ void multi_close_instance (struct multi_context *m, struct multi_instance *mi, b
bool multi_process_timeout (struct multi_context *m, const unsigned int mpp_flags);
+/**
+ * Handles peer floating.
+ *
+ * If peer is floated to a taken address, either drops packet
+ * (if peer that owns address has different CN) or disconnects
+ * existing peer. Updates multi_instance with new address,
+ * updates hashtables in multi_context.
+ */
+void multi_process_float (struct multi_context* m, struct multi_instance* mi);
+
#define MPP_PRE_SELECT (1<<0)
#define MPP_CONDITIONAL_PRE_SELECT (1<<1)
#define MPP_CLOSE_ON_SIGNAL (1<<2)
@@ -311,6 +345,18 @@ void multi_close_instance_on_signal (struct multi_context *m, struct multi_insta
void init_management_callback_multi (struct multi_context *m);
void uninit_management_callback_multi (struct multi_context *m);
+
+#ifdef ENABLE_ASYNC_PUSH
+/**
+ * Called when inotify event is fired, which happens when acf file is closed or deleted.
+ * Continues authentication and sends push_repl
+ *
+ * @param m multi_context
+ * @param mpp_flags
+ */
+void multi_process_file_closed (struct multi_context *m, const unsigned int mpp_flags);
+#endif
+
/*
* Return true if our output queue is not full
*/
@@ -418,6 +464,12 @@ multi_route_defined (const struct multi_context *m,
}
/*
+ * Takes prefix away from multi_instance.
+ */
+void
+ungenerate_prefix (struct multi_instance *mi);
+
+/*
* Set a msg() function prefix with our current client instance ID.
*/
@@ -425,10 +477,10 @@ static inline void
set_prefix (struct multi_instance *mi)
{
#ifdef MULTI_DEBUG_EVENT_LOOP
- if (mi->msg_prefix)
+ if (mi->msg_prefix[0])
printf ("[%s]\n", mi->msg_prefix);
#endif
- msg_set_prefix (mi->msg_prefix);
+ msg_set_prefix (mi->msg_prefix[0] ? mi->msg_prefix : NULL);
}
static inline void
@@ -573,10 +625,5 @@ multi_set_pending (struct multi_context *m, struct multi_instance *mi)
m->pending = mi;
}
-static inline void
-multi_release_io_lock (struct multi_context *m)
-{
-}
-
#endif /* P2MP_SERVER */
#endif /* MULTI_H */
diff --git a/src/openvpn/occ.c b/src/openvpn/occ.c
index ff48706..d71381d 100644
--- a/src/openvpn/occ.c
+++ b/src/openvpn/occ.c
@@ -379,7 +379,7 @@ process_received_occ_msg (struct context *c)
&& c->c2.max_send_size_local > TUN_MTU_MIN
&& (c->c2.max_recv_size_remote < c->c2.max_send_size_local
|| c->c2.max_recv_size_local < c->c2.max_send_size_remote))
- msg (M_INFO, "NOTE: This connection is unable to accomodate a UDP packet size of %d. Consider using --fragment or --mssfix options as a workaround.",
+ msg (M_INFO, "NOTE: This connection is unable to accommodate a UDP packet size of %d. Consider using --fragment or --mssfix options as a workaround.",
c->c2.max_send_size_local);
}
event_timeout_clear (&c->c2.occ_mtu_load_test_interval);
diff --git a/src/openvpn/openvpn.c b/src/openvpn/openvpn.c
index 823c3dd..5fb2fd9 100644
--- a/src/openvpn/openvpn.c
+++ b/src/openvpn/openvpn.c
@@ -138,7 +138,7 @@ openvpn_main (int argc, char *argv[])
return 1;
#endif
-#ifdef WIN32
+#ifdef _WIN32
SetConsoleOutputCP (CP_UTF8);
#endif
@@ -172,7 +172,7 @@ openvpn_main (int argc, char *argv[])
/* initialize environmental variable store */
c.es = env_set_create (NULL);
-#ifdef WIN32
+#ifdef _WIN32
set_win_sys_path_via_env (c.es);
#endif
@@ -220,7 +220,7 @@ openvpn_main (int argc, char *argv[])
/* print version number */
msg (M_INFO, "%s", title_string);
-#ifdef WIN32
+#ifdef _WIN32
show_windows_version(M_INFO);
#endif
show_library_versions(M_INFO);
@@ -312,7 +312,7 @@ openvpn_main (int argc, char *argv[])
return 0; /* NOTREACHED */
}
-#ifdef WIN32
+#ifdef _WIN32
int
wmain (int argc, wchar_t *wargv[]) {
char **argv;
diff --git a/src/openvpn/openvpn.h b/src/openvpn/openvpn.h
index 36c3100..fa5cc1d 100644
--- a/src/openvpn/openvpn.h
+++ b/src/openvpn/openvpn.h
@@ -31,7 +31,7 @@
#include "crypto.h"
#include "ssl.h"
#include "packet_id.h"
-#include "lzo.h"
+#include "comp.h"
#include "tun.h"
#include "interval.h"
#include "status.h"
@@ -62,14 +62,12 @@ struct key_schedule
/* pre-shared static key, read from a file */
struct key_ctx_bi static_key;
-#ifdef ENABLE_SSL
/* our global SSL context */
struct tls_root_ctx ssl_ctx;
- /* optional authentication HMAC key for TLS control channel */
- struct key_ctx_bi tls_auth_key;
-
-#endif /* ENABLE_SSL */
+ /* optional TLS control channel wrapping */
+ struct key_type tls_auth_key_type;
+ struct key_ctx_bi tls_wrap_key;
#else /* ENABLE_CRYPTO */
int dummy;
#endif /* ENABLE_CRYPTO */
@@ -104,10 +102,10 @@ struct context_buffers
struct buffer decrypt_buf;
#endif
- /* workspace buffers for LZO compression */
-#ifdef ENABLE_LZO
- struct buffer lzo_compress_buf;
- struct buffer lzo_decompress_buf;
+ /* workspace buffers for compression */
+#ifdef USE_COMP
+ struct buffer compress_buf;
+ struct buffer decompress_buf;
#endif
/*
@@ -165,6 +163,9 @@ struct context_1
/* tunnel session keys */
struct key_schedule ks;
+ /* preresolved and cached host names */
+ struct cached_dns_entry *dns_cache;
+
/* persist crypto sequence number to/from file */
struct packet_id_persist pid_persist;
@@ -184,17 +185,13 @@ struct context_1
struct status_output *status_output;
bool status_output_owned;
-#ifdef ENABLE_HTTP_PROXY
/* HTTP proxy object */
struct http_proxy_info *http_proxy;
bool http_proxy_owned;
-#endif
-#ifdef ENABLE_SOCKS
/* SOCKS proxy object */
struct socks_proxy_info *socks_proxy;
bool socks_proxy_owned;
-#endif
#if P2MP
@@ -213,6 +210,10 @@ struct context_1
struct user_pass *auth_user_pass;
/**< Username and password for
* authentication. */
+
+ const char *ciphername; /**< Data channel cipher from config file */
+ const char *authname; /**< Data channel auth from config file */
+ int keysize; /**< Data channel keysize from config file */
#endif
};
@@ -247,6 +248,9 @@ struct context_2
# define MANAGEMENT_READ (1<<6)
# define MANAGEMENT_WRITE (1<<7)
# endif
+#ifdef ENABLE_ASYNC_PUSH
+# define FILE_CLOSED (1<<8)
+#endif
unsigned int event_set_status;
@@ -335,8 +339,6 @@ struct context_2
/*
* TLS-mode crypto objects.
*/
-#ifdef ENABLE_SSL
-
struct tls_multi *tls_multi; /**< TLS state structure for this VPN
* tunnel. */
@@ -357,23 +359,19 @@ struct context_2
/* throw this signal on TLS errors */
int tls_exit_signal;
-#endif /* ENABLE_SSL */
-
struct crypto_options crypto_options;
/**< Security parameters and crypto state
* used by the \link data_crypto Data
* Channel Crypto module\endlink to
* process data channel packet. */
- /* used to keep track of data channel packet sequence numbers */
- struct packet_id packet_id;
struct event_timeout packet_id_persist_interval;
#endif /* ENABLE_CRYPTO */
-#ifdef ENABLE_LZO
- struct lzo_compress_workspace lzo_compwork;
- /**< Compression workspace used by the
+#ifdef USE_COMP
+ struct compress_context *comp_context;
+ /**< Compression context used by the
* \link compression Data Channel
* Compression module\endlink. */
#endif
@@ -393,11 +391,6 @@ struct context_2
struct buffer to_tun;
struct buffer to_link;
- /*
- * IPv4 TUN device?
- */
- bool ipv4_tun;
-
/* should we print R|W|r|w to console on packet transfers? */
bool log_rw;
@@ -423,6 +416,10 @@ struct context_2
time_t update_timeout_random_component;
struct timeval timeout_random_component;
+ /* Timer for everything up to the first packet from the *OpenVPN* server
+ * socks, http proxy, and tcp packets do not count */
+ struct event_timeout server_poll_interval;
+
/* indicates that the do_up_delay function has run */
bool do_up_ran;
@@ -446,13 +443,14 @@ struct context_2
#if P2MP_SERVER
/* --ifconfig endpoints to be pushed to client */
bool push_reply_deferred;
+#ifdef ENABLE_ASYNC_PUSH
+ bool push_request_received;
+#endif
bool push_ifconfig_defined;
time_t sent_push_reply_expiry;
in_addr_t push_ifconfig_local;
in_addr_t push_ifconfig_remote_netmask;
-#ifdef ENABLE_CLIENT_NAT
in_addr_t push_ifconfig_local_alias;
-#endif
bool push_ifconfig_ipv6_defined;
struct in6_addr push_ifconfig_ipv6_local;
@@ -474,11 +472,9 @@ struct context_2
/* hash of pulled options, so we can compare when options change */
bool pulled_options_md5_init_done;
- struct md5_state pulled_options_state;
+ md_ctx_t pulled_options_state;
struct md5_digest pulled_options_digest;
- struct event_timeout server_poll_interval;
-
struct event_timeout scheduled_exit;
int scheduled_exit_signal;
#endif
@@ -491,6 +487,10 @@ struct context_2
#ifdef MANAGEMENT_DEF_AUTH
struct man_def_auth_context mda_context;
#endif
+
+#ifdef ENABLE_ASYNC_PUSH
+ int inotify_fd; /* descriptor for monitoring file changes */
+#endif
};
@@ -566,7 +566,7 @@ struct context
* have been compiled in.
*/
-#if defined(ENABLE_CRYPTO) && defined(ENABLE_SSL)
+#ifdef ENABLE_CRYPTO
#define TLS_MODE(c) ((c)->c2.tls_multi != NULL)
#define PROTO_DUMP_FLAGS (check_debug_level (D_LINK_RW_VERBOSE) ? (PD_SHOW_DATA|PD_VERBOSE) : 0)
#define PROTO_DUMP(buf, gc) protocol_dump((buf), \
@@ -591,4 +591,7 @@ struct context
#define CIPHER_ENABLED(c) (false)
#endif
+/* this represents "disabled peer-id" */
+#define MAX_PEER_ID 0xFFFFFF
+
#endif
diff --git a/src/openvpn/openvpn.vcxproj b/src/openvpn/openvpn.vcxproj
index d691500..8dfbea5 100644
--- a/src/openvpn/openvpn.vcxproj
+++ b/src/openvpn/openvpn.vcxproj
@@ -64,7 +64,7 @@
<AdditionalIncludeDirectories>$(SOURCEBASE);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ResourceCompile>
<Link>
- <AdditionalDependencies>libeay32.lib;ssleay32.lib;lzo2.lib;pkcs11-helper.dll.lib;gdi32.lib;ws2_32.lib;wininet.lib;crypt32.lib;iphlpapi.lib;winmm.lib;rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalDependencies>libeay32.lib;ssleay32.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>
<AdditionalLibraryDirectories>$(OPENSSL_HOME)/lib;$(LZO_HOME)/lib;$(PKCS11H_HOME)/lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
@@ -89,7 +89,7 @@
<AdditionalIncludeDirectories>$(SOURCEBASE);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ResourceCompile>
<Link>
- <AdditionalDependencies>libeay32.lib;ssleay32.lib;lzo2.lib;pkcs11-helper.dll.lib;gdi32.lib;ws2_32.lib;wininet.lib;crypt32.lib;iphlpapi.lib;winmm.lib;rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalDependencies>libeay32.lib;ssleay32.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>
<AdditionalLibraryDirectories>$(OPENSSL_HOME)/lib;$(LZO_HOME)/lib;$(PKCS11H_HOME)/lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
@@ -102,6 +102,9 @@
<ClCompile Include="base64.c" />
<ClCompile Include="buffer.c" />
<ClCompile Include="clinat.c" />
+ <ClCompile Include="comp-lz4.c" />
+ <ClCompile Include="comp.c" />
+ <ClCompile Include="compstub.c" />
<ClCompile Include="console.c" />
<ClCompile Include="crypto.c" />
<ClCompile Include="crypto_openssl.c" />
@@ -171,6 +174,9 @@
<ClInclude Include="circ_list.h" />
<ClInclude Include="clinat.h" />
<ClInclude Include="common.h" />
+ <ClInclude Include="comp-lz4.h" />
+ <ClInclude Include="comp.h" />
+ <ClInclude Include="compstub.h" />
<ClInclude Include="console.h" />
<ClInclude Include="crypto.h" />
<ClInclude Include="crypto_backend.h" />
@@ -262,4 +268,4 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
-</Project> \ No newline at end of file
+</Project>
diff --git a/src/openvpn/openvpn.vcxproj.filters b/src/openvpn/openvpn.vcxproj.filters
index dbed3cd..8b6a269 100644
--- a/src/openvpn/openvpn.vcxproj.filters
+++ b/src/openvpn/openvpn.vcxproj.filters
@@ -207,6 +207,15 @@
<ClCompile Include="win32.c">
<Filter>Source Files</Filter>
</ClCompile>
+ <ClCompile Include="comp.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="compstub.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="comp-lz4.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="base64.h">
@@ -227,6 +236,12 @@
<ClInclude Include="common.h">
<Filter>Header Files</Filter>
</ClInclude>
+ <ClInclude Include="comp.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="comp-lz4.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
<ClInclude Include="console.h">
<Filter>Header Files</Filter>
</ClInclude>
@@ -449,9 +464,6 @@
<ClInclude Include="win32.h">
<Filter>Header Files</Filter>
</ClInclude>
- <ClInclude Include="win32_wfp.h">
- <Filter>Header Files</Filter>
- </ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="openvpn_win32_resources.rc">
diff --git a/src/openvpn/options.c b/src/openvpn/options.c
index a49a4fb..7f128c3 100644
--- a/src/openvpn/options.c
+++ b/src/openvpn/options.c
@@ -56,39 +56,38 @@
#include "helper.h"
#include "manage.h"
#include "forward.h"
+#include "ssl_verify.h"
+#include "platform.h"
#include <ctype.h>
#include "memdbg.h"
const char title_string[] =
PACKAGE_STRING
+#ifdef CONFIGURE_GIT_REVISION
+ " [git:" CONFIGURE_GIT_REVISION CONFIGURE_GIT_FLAGS "]"
+#endif
" " TARGET_ALIAS
#ifdef ENABLE_CRYPTO
-#ifdef ENABLE_SSL
-#if defined(ENABLE_CRYPTO_POLARSSL)
- " [SSL (PolarSSL)]"
+#if defined(ENABLE_CRYPTO_MBEDTLS)
+ " [SSL (mbed TLS)]"
#elif defined(ENABLE_CRYPTO_OPENSSL)
" [SSL (OpenSSL)]"
#else
" [SSL]"
-#endif /* defined(ENABLE_CRYPTO_POLARSSL) */
-#else /* ! ENABLE_SSL */
-#if defined(ENABLE_CRYPTO_POLARSSL)
- " [CRYPTO (PolarSSL)]"
-#elif defined(ENABLE_CRYPTO_OPENSSL)
- " [CRYPTO (OpenSSL)]"
-#else
- " [CRYPTO]"
-#endif /* defined(ENABLE_CRYPTO_POLARSSL) */
-#endif /* ENABLE_SSL */
+#endif /* defined(ENABLE_CRYPTO_MBEDTLS) */
#endif /* ENABLE_CRYPTO */
+#ifdef USE_COMP
#ifdef ENABLE_LZO
-#ifdef ENABLE_LZO_STUB
- " [LZO (STUB)]"
-#else
" [LZO]"
#endif
+#ifdef ENABLE_LZ4
+ " [LZ4]"
+#endif
+#ifdef ENABLE_COMP_STUB
+ " [COMP_STUB]"
#endif
+#endif /* USE_COMP */
#if EPOLL
" [EPOLL]"
#endif
@@ -99,9 +98,15 @@ const char title_string[] =
" [PKCS11]"
#endif
#if ENABLE_IP_PKTINFO
- " [MH]"
+# if defined(HAVE_IN_PKTINFO) && defined(HAVE_IPI_SPEC_DST)
+ " [MH/PKTINFO]"
+# elif defined(IP_RECVDSTADDR)
+ " [MH/RECVDA]"
+# endif
+#endif
+#ifdef HAVE_AEAD_CIPHER_MODES
+ " [AEAD]"
#endif
- " [IPv6]"
" built on " __DATE__
;
@@ -125,11 +130,11 @@ static const char usage_message[] =
" p = udp (default), tcp-server, or tcp-client\n"
"--proto-force p : only consider protocol p in list of connection profiles.\n"
" p = udp6, tcp6-server, or tcp6-client (ipv6)\n"
- "--connect-retry n : For --proto tcp-client, number of seconds to wait\n"
- " between connection retries (default=%d).\n"
- "--connect-timeout n : For --proto tcp-client, connection timeout (in seconds).\n"
+ "--connect-retry n [m] : For client, number of seconds to wait between\n"
+ " connection retries (default=%d). On repeated retries\n"
+ " the wait time is exponentially increased to a maximum of m\n"
+ " (default=%d).\n"
"--connect-retry-max n : Maximum connection attempt retries, default infinite.\n"
-#ifdef ENABLE_HTTP_PROXY
"--http-proxy s p [up] [auth] : Connect to remote host\n"
" through an HTTP proxy at address s and port p.\n"
" If proxy authentication is required,\n"
@@ -139,21 +144,16 @@ static const char usage_message[] =
"--http-proxy s p 'auto[-nct]' : Like the above directive, but automatically\n"
" determine auth method and query for username/password\n"
" if needed. auto-nct disables weak proxy auth methods.\n"
- "--http-proxy-retry : Retry indefinitely on HTTP proxy errors.\n"
- "--http-proxy-timeout n : Proxy timeout in seconds, default=5.\n"
"--http-proxy-option type [parm] : Set extended HTTP proxy options.\n"
" Repeat to set multiple options.\n"
" VERSION version (default=1.0)\n"
" AGENT user-agent\n"
-#endif
-#ifdef ENABLE_SOCKS
"--socks-proxy s [p] [up] : Connect to remote host through a Socks5 proxy at\n"
" address s and port p (default port = 1080).\n"
" If proxy authentication is required,\n"
" up is a file containing username/password on 2 lines, or\n"
" 'stdin' to prompt for console.\n"
"--socks-proxy-retry : Retry indefinitely on Socks proxy errors.\n"
-#endif
"--resolv-retry n: If hostname resolve fails for --remote, retry\n"
" resolve for n seconds before failing (disabled by default).\n"
" Set n=\"infinite\" to retry indefinitely.\n"
@@ -162,16 +162,12 @@ static const char usage_message[] =
"--ipchange cmd : Run command cmd on remote ip address initial\n"
" setting or change -- execute as: cmd ip-address port#\n"
"--port port : TCP/UDP port # for both local and remote.\n"
- "--lport port : TCP/UDP port # for local (default=%d). Implies --bind.\n"
- "--rport port : TCP/UDP port # for remote (default=%d).\n"
+ "--lport port : TCP/UDP port # for local (default=%s). Implies --bind.\n"
+ "--rport port : TCP/UDP port # for remote (default=%s).\n"
"--bind : Bind to local address and port. (This is the default unless\n"
" --proto tcp-client"
-#ifdef ENABLE_HTTP_PROXY
" or --http-proxy"
-#endif
-#ifdef ENABLE_SOCKS
" or --socks-proxy"
-#endif
" is used).\n"
"--nobind : Do not bind to local address and port.\n"
"--dev tunX|tapX : tun/tap device (X can be omitted for dynamic device.\n"
@@ -182,7 +178,6 @@ static const char usage_message[] =
" /dev/net/tun, /dev/tun, /dev/tap, etc.\n"
"--lladdr hw : Set the link layer address of the tap device.\n"
"--topology t : Set --dev tun topology: 'net30', 'p2p', or 'subnet'.\n"
- "--tun-ipv6 : Build tun link capable of forwarding IPv6 traffic.\n"
#ifdef ENABLE_IPROUTE
"--iproute cmd : Use this command instead of default " IPROUTE_PATH ".\n"
#endif
@@ -207,9 +202,7 @@ static const char usage_message[] =
"--route-ipv6 network/bits [gateway] [metric] :\n"
" Add IPv6 route to routing table after connection\n"
" is established. Multiple routes can be specified.\n"
- " gateway default: taken from --route-ipv6-gateway or --ifconfig\n"
- "--max-routes n : Specify the maximum number of routes that may be defined\n"
- " or pulled from a server.\n"
+ " gateway default: taken from 'remote' in --ifconfig-ipv6\n"
"--route-gateway gw|'dhcp' : Specify a default gateway for use with --route.\n"
"--route-metric m : Specify a default metric for use with --route.\n"
"--route-delay n [w] : Delay n seconds after connection initiation before\n"
@@ -234,9 +227,7 @@ static const char usage_message[] =
" Add 'bypass-dns' flag to similarly bypass tunnel for DNS.\n"
"--redirect-private [flags]: Like --redirect-gateway, but omit actually changing\n"
" the default gateway. Useful when pushing private subnets.\n"
-#ifdef ENABLE_CLIENT_NAT
"--client-nat snat|dnat network netmask alias : on client add 1-to-1 NAT rule.\n"
-#endif
#ifdef ENABLE_PUSH_PEER_INFO
"--push-peer-info : (client only) push client info to server.\n"
#endif
@@ -335,6 +326,7 @@ static const char usage_message[] =
"--log file : Output log to file which is created/truncated on open.\n"
"--log-append file : Append log to file, or create file if nonexistent.\n"
"--suppress-timestamps : Don't log timestamps to stdout/stderr.\n"
+ "--machine-readable-output : Always log timestamp, message flags to stdout/stderr.\n"
"--writepid file : Write main process ID to file.\n"
"--nice n : Change process priority (>0 = lower, <0 = higher).\n"
"--echo [parms ...] : Echo parameters to log output.\n"
@@ -359,12 +351,15 @@ static const char usage_message[] =
#ifdef ENABLE_DEBUG
"--gremlin mask : Special stress testing mode (for debugging only).\n"
#endif
-#ifdef ENABLE_LZO
- "--comp-lzo : Use fast LZO compression -- may add up to 1 byte per\n"
+#if defined(USE_COMP)
+ "--compress alg : Use compression algorithm alg\n"
+#if defined(ENABLE_LZO)
+ "--comp-lzo : Use LZO compression -- may add up to 1 byte per\n"
" packet for uncompressible data.\n"
"--comp-noadapt : Don't use adaptive compression when --comp-lzo\n"
" is specified.\n"
#endif
+#endif
#ifdef ENABLE_MANAGEMENT
"--management ip port [pass] : Enable a TCP server on ip:port to handle\n"
" management functions. pass is a password file\n"
@@ -442,6 +437,9 @@ static const char usage_message[] =
" Only valid in a client-specific config file.\n"
"--client-cert-not-required : Don't require client certificate, client\n"
" will authenticate using username/password.\n"
+ "--verify-client-cert [none|optional|require] : perform no, optional or\n"
+ " mandatory client certificate verification.\n"
+ " Default is to require the client to supply a certificate.\n"
"--username-as-common-name : For auth-user-pass authentication, use\n"
" the authenticated username as the common name,\n"
" rather than the common name from the client cert.\n"
@@ -449,6 +447,11 @@ static const char usage_message[] =
" run command cmd to verify. If method='via-env', pass\n"
" user/pass via environment, if method='via-file', pass\n"
" user/pass via temporary file.\n"
+ "--auth-gen-token [lifetime] Generate a random authentication token which is pushed\n"
+ " to each client, replacing the password. Usefull when\n"
+ " OTP based two-factor auth mechanisms are in use and\n"
+ " --reneg-* options are enabled. Optionally a lifetime in seconds\n"
+ " for generated tokens can be set.\n"
"--opt-verify : Clients that connect with options that are incompatible\n"
" with those of the server will be disconnected.\n"
"--auth-user-pass-optional : Allow connections by clients that don't\n"
@@ -476,6 +479,9 @@ static const char usage_message[] =
"--stale-routes-check n [t] : Remove routes with a last activity timestamp\n"
" older than n seconds. Run this check every t\n"
" seconds (defaults to n).\n"
+ "--explicit-exit-notify [n] : In UDP server mode send [RESTART] command on exit/restart to connected\n"
+ " clients. n = 1 - reconnect to same server,\n"
+ " 2 - advance to next server, default=1.\n"
#if PORT_SHARE
"--port-share host port [dir] : When run in TCP mode, proxy incoming HTTPS\n"
" sessions to a web server at host:port. dir specifies an\n"
@@ -493,13 +499,20 @@ static const char usage_message[] =
"--pull : Accept certain config file options from the peer as if they\n"
" were part of the local config file. Must be specified\n"
" when connecting to a '--mode server' remote host.\n"
+ "--pull-filter accept|ignore|reject t : Filter each option received from the\n"
+ " server if it starts with the text t. The action flag accept,\n"
+ " ignore or reject causes the option to be allowed, removed or\n"
+ " rejected with error. May be specified multiple times, and\n"
+ " each filter is applied in the order of appearance.\n"
"--auth-retry t : How to handle auth failures. Set t to\n"
" none (default), interact, or nointeract.\n"
"--static-challenge t e : Enable static challenge/response protocol using\n"
" challenge text t, with e indicating echo flag (0|1)\n"
- "--server-poll-timeout n : when polling possible remote servers to connect to\n"
+ "--connect-timeout n : when polling possible remote servers to connect to\n"
" in a round-robin fashion, spend no more than n seconds\n"
" waiting for a response before trying the next server.\n"
+ "--allow-recursive-routing : When this option is set, OpenVPN will not drop\n"
+ " incoming tun packets with same destination as host.\n"
#endif
#ifdef ENABLE_OCC
"--explicit-exit-notify [n] : On exit/restart, send exit signal to\n"
@@ -522,13 +535,15 @@ static const char usage_message[] =
"--cipher alg : Encrypt packets with cipher algorithm alg\n"
" (default=%s).\n"
" Set alg=none to disable encryption.\n"
+ "--ncp-ciphers list : List of ciphers that are allowed to be negotiated.\n"
+ "--ncp-disable : Disable cipher negotiation.\n"
"--prng alg [nsl] : For PRNG, use digest algorithm alg, and\n"
" nonce_secret_len=nsl. Set alg=none to disable PRNG.\n"
#ifdef HAVE_EVP_CIPHER_CTX_SET_KEY_LENGTH
"--keysize n : Size of cipher key in bits (optional).\n"
" If unspecified, defaults to cipher-specific default.\n"
#endif
-#ifndef ENABLE_CRYPTO_POLARSSL
+#ifndef ENABLE_CRYPTO_MBEDTLS
"--engine [name] : Enable OpenSSL hardware crypto engine functionality.\n"
#endif
"--no-replay : Disable replay protection.\n"
@@ -545,7 +560,6 @@ static const char usage_message[] =
"--use-prediction-resistance: Enable prediction resistance on the random\n"
" number generator.\n"
#endif
-#ifdef ENABLE_SSL
"\n"
"TLS Key Negotiation Options:\n"
"(These options are meaningful only for TLS-mode)\n"
@@ -555,15 +569,10 @@ static const char usage_message[] =
" number, such as 1 (default), 2, etc.\n"
"--ca file : Certificate authority file in .pem format containing\n"
" root certificate.\n"
-#ifndef ENABLE_CRYPTO_POLARSSL
+#ifndef ENABLE_CRYPTO_MBEDTLS
"--capath dir : A directory of trusted certificates (CAs"
-#if OPENSSL_VERSION_NUMBER >= 0x00907000L
" and CRLs).\n"
-#else /* OPENSSL_VERSION_NUMBER >= 0x00907000L */
- ").\n"
- " WARNING: no support of CRL available with this version.\n"
-#endif /* OPENSSL_VERSION_NUMBER >= 0x00907000L */
-#endif /* ENABLE_CRYPTO_POLARSSL */
+#endif /* ENABLE_CRYPTO_MBEDTLS */
"--dh file : File containing Diffie Hellman parameters\n"
" in .pem format (for --tls-server only).\n"
" Use \"openssl dhparam -out dh1024.pem 1024\" to generate.\n"
@@ -575,7 +584,7 @@ static const char usage_message[] =
" will accept from the peer. If version is unrecognized and 'or-highest'\n"
" is specified, require max TLS version supported by SSL implementation.\n"
"--tls-version-max <version> : sets the maximum TLS version we will use.\n"
-#ifndef ENABLE_CRYPTO_POLARSSL
+#ifndef ENABLE_CRYPTO_MBEDTLS
"--pkcs12 file : PKCS#12 file containing local private key, local certificate\n"
" and optionally the root CA certificate.\n"
#endif
@@ -584,7 +593,7 @@ static const char usage_message[] =
" Default is CN in the Subject field.\n"
#endif
"--verify-hash : Specify SHA1 fingerprint for level-1 cert.\n"
-#ifdef WIN32
+#ifdef _WIN32
"--cryptoapicert select-string : Load the certificate and private key from the\n"
" Windows Certificate System Store.\n"
#endif
@@ -602,10 +611,17 @@ static const char usage_message[] =
"--single-session: Allow only one session (reset state on restart).\n"
"--tls-exit : Exit on TLS negotiation failure.\n"
"--tls-auth f [d]: Add an additional layer of authentication on top of the TLS\n"
- " control channel to protect against DoS attacks.\n"
- " f (required) is a shared-secret passphrase file.\n"
+ " control channel to protect against attacks on the TLS stack\n"
+ " and DoS attacks.\n"
+ " f (required) is a shared-secret key file.\n"
" The optional d parameter controls key directionality,\n"
" see --secret option for more info.\n"
+ "--tls-crypt key : Add an additional layer of authenticated encryption on top\n"
+ " of the TLS control channel to hide the TLS certificate,\n"
+ " provide basic post-quantum security and protect against\n"
+ " attacks on the TLS stack and DoS attacks.\n"
+ " key (required) provides the pre-shared key file.\n"
+ " see --secret option for more info.\n"
"--askpass [file]: Get PEM password from controlling tty before we daemonize.\n"
"--auth-nocache : Don't cache --askpass or --auth-user-pass passwords.\n"
"--crl-verify crl ['dir']: Check peer certificate against a CRL.\n"
@@ -622,11 +638,12 @@ static const char usage_message[] =
" of verification.\n"
"--ns-cert-type t: Require that peer certificate was signed with an explicit\n"
" nsCertType designation t = 'client' | 'server'.\n"
-#ifdef ENABLE_X509_TRACK
"--x509-track x : Save peer X509 attribute x in environment for use by\n"
" plugins and management interface.\n"
+#if defined(ENABLE_CRYPTO_OPENSSL) && OPENSSL_VERSION_NUMBER >= 0x10001000
+ "--keying-material-exporter label len : Save Exported Keying Material (RFC5705)\n"
+ " of len bytes (min. 16 bytes) using label in environment for use by plugins.\n"
#endif
-#if OPENSSL_VERSION_NUMBER >= 0x00907000L || ENABLE_CRYPTO_POLARSSL
"--remote-cert-ku v ... : Require that the peer certificate was signed with\n"
" explicit key usage, you can specify more than one value.\n"
" value should be given in hex format.\n"
@@ -636,8 +653,6 @@ static const char usage_message[] =
"--remote-cert-tls t: Require that peer certificate was signed with explicit\n"
" key usage and extended key usage based on RFC3280 TLS rules.\n"
" t = 'client' | 'server'.\n"
-#endif /* OPENSSL_VERSION_NUMBER || ENABLE_CRYPTO_POLARSSL */
-#endif /* ENABLE_SSL */
#ifdef ENABLE_PKCS11
"\n"
"PKCS#11 Options:\n"
@@ -662,10 +677,8 @@ static const char usage_message[] =
"--show-ciphers : Show cipher algorithms to use with --cipher option.\n"
"--show-digests : Show message digest algorithms to use with --auth option.\n"
"--show-engines : Show hardware crypto accelerator engines (if available).\n"
-#ifdef ENABLE_SSL
"--show-tls : Show all TLS ciphers (TLS used only as a control channel).\n"
-#endif
-#ifdef WIN32
+#ifdef _WIN32
"\n"
"Windows Specific:\n"
"--win-sys path : Pathname of Windows system directory. Default is the pathname\n"
@@ -715,7 +728,9 @@ static const char usage_message[] =
" optional parameter controls the initial state of ex.\n"
"--show-net-up : Show " PACKAGE_NAME "'s view of routing table and net adapter list\n"
" after TAP adapter is up and routes have been added.\n"
+#ifdef _WIN32
"--block-outside-dns : Block DNS on other network adapters to prevent DNS leaks\n"
+#endif
"Windows Standalone Options:\n"
"\n"
"--show-adapters : Show all TAP-Windows adapters.\n"
@@ -775,10 +790,13 @@ init_options (struct options *o, const bool init_gc)
}
o->mode = MODE_POINT_TO_POINT;
o->topology = TOP_NET30;
- o->ce.proto = PROTO_UDPv4;
+ o->ce.proto = PROTO_UDP;
+ o->ce.af = AF_UNSPEC;
+ o->ce.bind_ipv6_only = false;
o->ce.connect_retry_seconds = 5;
- o->ce.connect_timeout = 10;
- o->ce.connect_retry_max = 0;
+ o->ce.connect_retry_seconds_max = 300;
+ o->ce.connect_timeout = 120;
+ o->connect_retry_max = 0;
o->ce.local_port = o->ce.remote_port = OPENVPN_PORT;
o->verbosity = 1;
o->status_file_update_freq = 60;
@@ -789,8 +807,8 @@ init_options (struct options *o, const bool init_gc)
o->ce.mtu_discover_type = -1;
o->ce.mssfix = MSSFIX_DEFAULT;
o->route_delay_window = 30;
- o->max_routes = MAX_ROUTES_DEFAULT;
o->resolve_retry_seconds = RESOLV_RETRY_INFINITE;
+ o->resolve_in_advance = false;
o->proto_force = -1;
#ifdef ENABLE_OCC
o->occ = true;
@@ -806,7 +824,7 @@ init_options (struct options *o, const bool init_gc)
#ifdef TARGET_LINUX
o->tuntap_options.txqueuelen = 100;
#endif
-#ifdef WIN32
+#ifdef _WIN32
#if 0
o->tuntap_options.ip_win32_type = IPW32_SET_ADAPTIVE;
#else
@@ -829,13 +847,16 @@ init_options (struct options *o, const bool init_gc)
#endif
#if P2MP
o->scheduled_exit_interval = 5;
- o->server_poll_timeout = 0;
#endif
#ifdef ENABLE_CRYPTO
o->ciphername = "BF-CBC";
- o->ciphername_defined = true;
+#ifdef HAVE_AEAD_CIPHER_MODES /* IV_NCP=2 requires GCM support */
+ o->ncp_enabled = true;
+#else
+ o->ncp_enabled = false;
+#endif
+ o->ncp_ciphers = "AES-256-GCM:AES-128-GCM";
o->authname = "SHA1";
- o->authname_defined = true;
o->prng_hash = "SHA1";
o->prng_nonce_secret_len = 16;
o->replay = true;
@@ -846,25 +867,27 @@ init_options (struct options *o, const bool init_gc)
#ifdef ENABLE_PREDICTION_RESISTANCE
o->use_prediction_resistance = false;
#endif
-#ifdef ENABLE_SSL
o->key_method = 2;
o->tls_timeout = 2;
+ o->renegotiate_bytes = -1;
o->renegotiate_seconds = 3600;
o->handshake_window = 60;
o->transition_window = 3600;
+ o->ecdh_curve = NULL;
#ifdef ENABLE_X509ALTUSERNAME
o->x509_username_field = X509_USERNAME_FIELD_DEFAULT;
#endif
-#endif /* ENABLE_SSL */
#endif /* ENABLE_CRYPTO */
#ifdef ENABLE_PKCS11
o->pkcs11_pin_cache_period = -1;
#endif /* ENABLE_PKCS11 */
-/* tmp is only used in P2MP server context */
+/* P2MP server context features */
#if P2MP_SERVER
+ o->auth_token_generate = false;
+
/* Set default --tmp-dir */
-#ifdef WIN32
+#ifdef _WIN32
/* On Windows, find temp dir via enviroment variables */
o->tmp_dir = win_get_tempdir();
#else
@@ -873,8 +896,9 @@ init_options (struct options *o, const bool init_gc)
if( !o->tmp_dir ) {
o->tmp_dir = "/tmp";
}
-#endif /* WIN32 */
+#endif /* _WIN32 */
#endif /* P2MP_SERVER */
+ o->allow_recursive_routing = false;
}
void
@@ -886,6 +910,37 @@ uninit_options (struct options *o)
}
}
+struct pull_filter
+{
+# define PUF_TYPE_UNDEF 0 /** undefined filter type */
+# define PUF_TYPE_ACCEPT 1 /** filter type to accept a matching option */
+# define PUF_TYPE_IGNORE 2 /** filter type to ignore a matching option */
+# define PUF_TYPE_REJECT 3 /** filter type to reject and trigger SIGUSR1 */
+ int type;
+ int size;
+ char *pattern;
+ struct pull_filter *next;
+};
+
+struct pull_filter_list
+{
+ struct pull_filter *head;
+ struct pull_filter *tail;
+};
+
+static const char *
+pull_filter_type_name (int type)
+{
+ if (type == PUF_TYPE_ACCEPT)
+ return "accept";
+ if (type == PUF_TYPE_IGNORE)
+ return "ignore";
+ if (type == PUF_TYPE_REJECT)
+ return "reject";
+ else
+ return "???";
+}
+
#ifndef ENABLE_SMALL
#define SHOW_PARM(name, value, format) msg(D_SHOW_PARMS, " " #name " = " format, (value))
@@ -902,26 +957,22 @@ setenv_connection_entry (struct env_set *es,
const struct connection_entry *e,
const int i)
{
- setenv_str_i (es, "proto", proto2ascii (e->proto, false), i);
+ setenv_str_i (es, "proto", proto2ascii (e->proto, e->af, false), i);
setenv_str_i (es, "local", e->local, i);
- setenv_int_i (es, "local_port", e->local_port, i);
+ setenv_str_i (es, "local_port", e->local_port, i);
setenv_str_i (es, "remote", e->remote, i);
- setenv_int_i (es, "remote_port", e->remote_port, i);
+ setenv_str_i (es, "remote_port", e->remote_port, i);
-#ifdef ENABLE_HTTP_PROXY
if (e->http_proxy_options)
{
setenv_str_i (es, "http_proxy_server", e->http_proxy_options->server, i);
- setenv_int_i (es, "http_proxy_port", e->http_proxy_options->port, i);
+ setenv_str_i (es, "http_proxy_port", e->http_proxy_options->port, i);
}
-#endif
-#ifdef ENABLE_SOCKS
if (e->socks_proxy_server)
{
setenv_str_i (es, "socks_proxy_server", e->socks_proxy_server, i);
- setenv_int_i (es, "socks_proxy_port", e->socks_proxy_port, i);
+ setenv_str_i (es, "socks_proxy_port", e->socks_proxy_port, i);
}
-#endif
}
void
@@ -1064,7 +1115,7 @@ string_substitute (const char *src, int from, int to, struct gc_arena *gc)
return ret;
}
-#ifdef ENABLE_SSL
+#ifdef ENABLE_CRYPTO
static uint8_t *
parse_hash_fingerprint(const char *str, int nbytes, int msglevel, struct gc_arena *gc)
{
@@ -1098,7 +1149,7 @@ parse_hash_fingerprint(const char *str, int nbytes, int msglevel, struct gc_aren
}
#endif
-#ifdef WIN32
+#ifdef _WIN32
#ifndef ENABLE_SMALL
@@ -1141,7 +1192,9 @@ show_tuntap_options (const struct tuntap_options *o)
}
#endif
+#endif
+#if defined(_WIN32) || defined(TARGET_ANDROID)
static void
dhcp_option_address_parse (const char *name, const char *parm, in_addr_t *array, int *len, int msglevel)
{
@@ -1231,9 +1284,11 @@ show_p2mp_parms (const struct options *o)
SHOW_INT (max_routes_per_client);
SHOW_STR (auth_user_pass_verify_script);
SHOW_BOOL (auth_user_pass_verify_script_via_file);
+ SHOW_BOOL (auth_token_generate);
+ SHOW_INT (auth_token_lifetime);
#if PORT_SHARE
SHOW_STR (port_share_host);
- SHOW_INT (port_share_port);
+ SHOW_STR (port_share_port);
#endif
#endif /* P2MP_SERVER */
@@ -1298,19 +1353,27 @@ option_iroute_ipv6 (struct options *o,
#endif /* P2MP_SERVER */
#endif /* P2MP */
-#if defined(ENABLE_HTTP_PROXY) && !defined(ENABLE_SMALL)
+#ifndef ENABLE_SMALL
static void
show_http_proxy_options (const struct http_proxy_options *o)
{
+ int i;
msg (D_SHOW_PARMS, "BEGIN http_proxy");
SHOW_STR (server);
- SHOW_INT (port);
+ SHOW_STR (port);
SHOW_STR (auth_method_string);
SHOW_STR (auth_file);
- SHOW_BOOL (retry);
- SHOW_INT (timeout);
SHOW_STR (http_version);
SHOW_STR (user_agent);
+ for (i=0; i < MAX_CUSTOM_HTTP_HEADER && o->custom_headers[i].name;i++)
+ {
+ if (o->custom_headers[i].content)
+ msg (D_SHOW_PARMS, " custom_header[%d] = %s: %s", i,
+ o->custom_headers[i].name, o->custom_headers[i].content);
+ else
+ msg (D_SHOW_PARMS, " custom_header[%d] = %s", i,
+ o->custom_headers[i].name);
+ }
msg (D_SHOW_PARMS, "END http_proxy");
}
#endif
@@ -1320,9 +1383,7 @@ options_detach (struct options *o)
{
gc_detach (&o->gc);
o->routes = NULL;
-#ifdef ENABLE_CLIENT_NAT
o->client_nat = NULL;
-#endif
#if P2MP_SERVER
clone_push_list(o);
#endif
@@ -1332,50 +1393,43 @@ void
rol_check_alloc (struct options *options)
{
if (!options->routes)
- options->routes = new_route_option_list (options->max_routes, &options->gc);
+ options->routes = new_route_option_list (&options->gc);
}
void
rol6_check_alloc (struct options *options)
{
if (!options->routes_ipv6)
- options->routes_ipv6 = new_route_ipv6_option_list (options->max_routes, &options->gc);
+ options->routes_ipv6 = new_route_ipv6_option_list (&options->gc);
}
-#ifdef ENABLE_CLIENT_NAT
static void
cnol_check_alloc (struct options *options)
{
if (!options->client_nat)
options->client_nat = new_client_nat_list (&options->gc);
}
-#endif
#ifndef ENABLE_SMALL
static void
show_connection_entry (const struct connection_entry *o)
{
- msg (D_SHOW_PARMS, " proto = %s", proto2ascii (o->proto, false));
+ msg (D_SHOW_PARMS, " proto = %s", proto2ascii (o->proto, o->af, false));
SHOW_STR (local);
- SHOW_INT (local_port);
+ SHOW_STR (local_port);
SHOW_STR (remote);
- SHOW_INT (remote_port);
+ SHOW_STR (remote_port);
SHOW_BOOL (remote_float);
SHOW_BOOL (bind_defined);
SHOW_BOOL (bind_local);
+ SHOW_BOOL (bind_ipv6_only);
SHOW_INT (connect_retry_seconds);
SHOW_INT (connect_timeout);
- SHOW_INT (connect_retry_max);
-#ifdef ENABLE_HTTP_PROXY
if (o->http_proxy_options)
show_http_proxy_options (o->http_proxy_options);
-#endif
-#ifdef ENABLE_SOCKS
SHOW_STR (socks_proxy_server);
- SHOW_INT (socks_proxy_port);
- SHOW_BOOL (socks_proxy_retry);
-#endif
+ SHOW_STR (socks_proxy_port);
SHOW_INT (tun_mtu);
SHOW_BOOL (tun_mtu_defined);
SHOW_INT (link_mtu);
@@ -1399,8 +1453,6 @@ show_connection_entry (const struct connection_entry *o)
static void
show_connection_entries (const struct options *o)
{
- msg (D_SHOW_PARMS, "Connection profiles [default]:");
- show_connection_entry (&o->ce);
if (o->connection_list)
{
const struct connection_list *l = o->connection_list;
@@ -1411,9 +1463,28 @@ show_connection_entries (const struct options *o)
show_connection_entry (l->array[i]);
}
}
+ else
+ {
+ msg (D_SHOW_PARMS, "Connection profiles [default]:");
+ show_connection_entry (&o->ce);
+ }
msg (D_SHOW_PARMS, "Connection profiles END");
}
+static void
+show_pull_filter_list (const struct pull_filter_list *l)
+{
+ struct pull_filter *f;
+ if (!l)
+ return;
+
+ msg (D_SHOW_PARMS, " Pull filters:");
+ for (f = l->head; f; f = f->next)
+ {
+ msg (D_SHOW_PARMS, " %s \"%s\"", pull_filter_type_name(f->type), f->pattern);
+ }
+}
+
#endif
void
@@ -1436,12 +1507,11 @@ show_settings (const struct options *o)
SHOW_BOOL (show_digests);
SHOW_BOOL (show_engines);
SHOW_BOOL (genkey);
-#ifdef ENABLE_SSL
SHOW_STR (key_pass_file);
SHOW_BOOL (show_tls_ciphers);
#endif
-#endif
+ SHOW_INT (connect_retry_max);
show_connection_entries (o);
SHOW_BOOL (remote_random);
@@ -1452,7 +1522,6 @@ show_settings (const struct options *o)
SHOW_STR (dev_node);
SHOW_STR (lladdr);
SHOW_INT (topology);
- SHOW_BOOL (tun_ipv6);
SHOW_STR (ifconfig_local);
SHOW_STR (ifconfig_remote_netmask);
SHOW_BOOL (ifconfig_noexec);
@@ -1488,6 +1557,7 @@ show_settings (const struct options *o)
#endif
SHOW_INT (resolve_retry_seconds);
+ SHOW_BOOL (resolve_in_advance);
SHOW_STR (username);
SHOW_STR (groupname);
@@ -1506,6 +1576,7 @@ show_settings (const struct options *o)
SHOW_INT (inetd);
SHOW_BOOL (log);
SHOW_BOOL (suppress_timestamps);
+ SHOW_BOOL (machine_readable_output);
SHOW_INT (nice);
SHOW_INT (verbosity);
SHOW_INT (mute);
@@ -1528,8 +1599,9 @@ show_settings (const struct options *o)
SHOW_BOOL (fast_io);
-#ifdef ENABLE_LZO
- SHOW_INT (lzo);
+#ifdef USE_COMP
+ SHOW_INT (comp.alg);
+ SHOW_INT (comp.flags);
#endif
SHOW_STR (route_script);
@@ -1541,19 +1613,18 @@ show_settings (const struct options *o)
SHOW_BOOL (route_delay_defined);
SHOW_BOOL (route_nopull);
SHOW_BOOL (route_gateway_via_dhcp);
- SHOW_INT (max_routes);
SHOW_BOOL (allow_pull_fqdn);
+ show_pull_filter_list (o->pull_filter_list);
+
if (o->routes)
print_route_options (o->routes, D_SHOW_PARMS);
-
-#ifdef ENABLE_CLIENT_NAT
+
if (o->client_nat)
print_client_nat_list(o->client_nat, D_SHOW_PARMS);
-#endif
#ifdef ENABLE_MANAGEMENT
SHOW_STR (management_addr);
- SHOW_INT (management_port);
+ SHOW_STR (management_port);
SHOW_STR (management_user_pass);
SHOW_INT (management_log_history_cache);
SHOW_INT (management_echo_buffer_size);
@@ -1570,16 +1641,14 @@ show_settings (const struct options *o)
#ifdef ENABLE_CRYPTO
SHOW_STR (shared_secret_file);
SHOW_INT (key_direction);
- SHOW_BOOL (ciphername_defined);
SHOW_STR (ciphername);
- SHOW_BOOL (authname_defined);
SHOW_STR (authname);
SHOW_STR (prng_hash);
SHOW_INT (prng_nonce_secret_len);
SHOW_INT (keysize);
-#ifndef ENABLE_CRYPTO_POLARSSL
+#ifndef ENABLE_CRYPTO_MBEDTLS
SHOW_BOOL (engine);
-#endif /* ENABLE_CRYPTO_POLARSSL */
+#endif /* ENABLE_CRYPTO_MBEDTLS */
SHOW_BOOL (replay);
SHOW_BOOL (mute_replay_warnings);
SHOW_INT (replay_window);
@@ -1591,13 +1660,17 @@ show_settings (const struct options *o)
SHOW_BOOL (use_prediction_resistance);
#endif
-#ifdef ENABLE_SSL
SHOW_BOOL (tls_server);
SHOW_BOOL (tls_client);
SHOW_INT (key_method);
SHOW_STR (ca_file);
SHOW_STR (ca_path);
SHOW_STR (dh_file);
+#ifdef MANAGMENT_EXTERNAL_KEY
+ if((o->management_flags & MF_EXTERNAL_CERT))
+ SHOW_PARM ("cert_file","EXTERNAL_CERT","%s");
+ else
+#endif
SHOW_STR (cert_file);
SHOW_STR (extra_certs_file);
@@ -1607,7 +1680,7 @@ show_settings (const struct options *o)
else
#endif
SHOW_STR (priv_key_file);
-#ifndef ENABLE_CRYPTO_POLARSSL
+#ifndef ENABLE_CRYPTO_MBEDTLS
SHOW_STR (pkcs12_file);
#endif
#ifdef ENABLE_CRYPTOAPI
@@ -1644,8 +1717,8 @@ show_settings (const struct options *o)
SHOW_BOOL (tls_exit);
SHOW_STR (tls_auth_file);
-#endif
-#endif
+ SHOW_STR (tls_crypt_file);
+#endif /* ENABLE_CRYPTO */
#ifdef ENABLE_PKCS11
{
@@ -1677,7 +1750,7 @@ show_settings (const struct options *o)
show_p2mp_parms (o);
#endif
-#ifdef WIN32
+#ifdef _WIN32
SHOW_BOOL (show_net_up);
SHOW_INT (route_method);
SHOW_BOOL (block_outside_dns);
@@ -1691,7 +1764,7 @@ show_settings (const struct options *o)
#undef SHOW_INT
#undef SHOW_BOOL
-#if HTTP_PROXY_OVERRIDE
+#ifdef ENABLE_MANAGEMENT
static struct http_proxy_options *
parse_http_proxy_override (const char *server,
@@ -1703,19 +1776,9 @@ parse_http_proxy_override (const char *server,
if (server && port)
{
struct http_proxy_options *ho;
- const int int_port = atoi(port);
-
- if (!legal_ipv4_port (int_port))
- {
- msg (msglevel, "Bad http-proxy port number: %s", port);
- return NULL;
- }
-
ALLOC_OBJ_CLEAR_GC (ho, struct http_proxy_options, gc);
ho->server = string_alloc(server, gc);
- ho->port = int_port;
- ho->retry = true;
- ho->timeout = 5;
+ ho->port = port;
if (flags && !strcmp(flags, "nct"))
ho->auth_retry = PAR_NCT;
else
@@ -1732,32 +1795,31 @@ void
options_postprocess_http_proxy_override (struct options *o)
{
const struct connection_list *l = o->connection_list;
- if (l)
+ int i;
+ bool succeed = false;
+ for (i = 0; i < l->len; ++i)
+ {
+ struct connection_entry *ce = l->array[i];
+ if (ce->proto == PROTO_TCP_CLIENT || ce->proto == PROTO_TCP)
+ {
+ ce->http_proxy_options = o->http_proxy_override;
+ succeed = true;
+ }
+ }
+ if (succeed)
{
- int i;
- bool succeed = false;
for (i = 0; i < l->len; ++i)
- {
- struct connection_entry *ce = l->array[i];
- if (ce->proto == PROTO_TCPv4_CLIENT || ce->proto == PROTO_TCPv4)
- {
- ce->http_proxy_options = o->http_proxy_override;
- succeed = true;
- }
- }
- if (succeed)
- {
- for (i = 0; i < l->len; ++i)
- {
- struct connection_entry *ce = l->array[i];
- if (ce->proto == PROTO_UDPv4)
- {
- ce->flags |= CE_DISABLED;
- }
- }
- }
- else
- msg (M_WARN, "Note: option http-proxy-override ignored because no TCP-based connection profiles are defined");
+ {
+ struct connection_entry *ce = l->array[i];
+ if (ce->proto == PROTO_UDP)
+ {
+ ce->flags |= CE_DISABLED;
+ }
+ }
+ }
+ else
+ {
+ msg (M_WARN, "Note: option http-proxy-override ignored because no TCP-based connection profiles are defined");
}
}
@@ -1811,15 +1873,46 @@ alloc_remote_entry (struct options *options, const int msglevel)
return e;
}
+static struct pull_filter_list *
+alloc_pull_filter_list (struct options *o)
+{
+ if (!o->pull_filter_list)
+ ALLOC_OBJ_CLEAR_GC (o->pull_filter_list, struct pull_filter_list, &o->gc);
+ return o->pull_filter_list;
+}
+
+static struct pull_filter *
+alloc_pull_filter (struct options *o, const int msglevel)
+{
+ struct pull_filter_list *l = alloc_pull_filter_list (o);
+ struct pull_filter *f;
+
+ ALLOC_OBJ_CLEAR_GC (f, struct pull_filter, &o->gc);
+ if (l->head)
+ {
+ ASSERT (l->tail);
+ l->tail->next = f;
+ }
+ else
+ {
+ ASSERT (!l->tail);
+ l->head = f;
+ }
+ l->tail = f;
+ return f;
+}
+
void
connection_entry_load_re (struct connection_entry *ce, const struct remote_entry *re)
{
if (re->remote)
ce->remote = re->remote;
- if (re->remote_port >= 0)
+ if (re->remote_port)
ce->remote_port = re->remote_port;
if (re->proto >= 0)
ce->proto = re->proto;
+ if (re->af > 0)
+ ce->af = re->af;
}
static void
@@ -1849,10 +1942,8 @@ options_postprocess_verify_ce (const struct options *options, const struct conne
* If "proto tcp" is specified, make sure we know whether it is
* tcp-client or tcp-server.
*/
- if (ce->proto == PROTO_TCPv4)
+ if (ce->proto == PROTO_TCP)
msg (M_USAGE, "--proto tcp is ambiguous in this context. Please specify --proto tcp-server or --proto tcp-client");
- if (ce->proto == PROTO_TCPv6)
- msg (M_USAGE, "--proto tcp6 is ambiguous in this context. Please specify --proto tcp6-server or --proto tcp6-client");
/*
* Sanity check on daemon/inetd modes
@@ -1864,14 +1955,14 @@ options_postprocess_verify_ce (const struct options *options, const struct conne
if (options->inetd && (ce->local || ce->remote))
msg (M_USAGE, "--local or --remote cannot be used with --inetd");
- if (options->inetd && ce->proto == PROTO_TCPv4_CLIENT)
+ if (options->inetd && ce->proto == PROTO_TCP_CLIENT)
msg (M_USAGE, "--proto tcp-client cannot be used with --inetd");
- if (options->inetd == INETD_NOWAIT && ce->proto != PROTO_TCPv4_SERVER)
+ if (options->inetd == INETD_NOWAIT && ce->proto != PROTO_TCP_SERVER)
msg (M_USAGE, "--inetd nowait can only be used with --proto tcp-server");
if (options->inetd == INETD_NOWAIT
-#if defined(ENABLE_CRYPTO) && defined(ENABLE_SSL)
+#ifdef ENABLE_CRYPTO
&& !(options->tls_server || options->tls_client)
#endif
)
@@ -1885,20 +1976,6 @@ options_postprocess_verify_ce (const struct options *options, const struct conne
msg (M_USAGE, "--lladdr can only be used in --dev tap mode");
/*
- * Sanity check on TCP mode options
- */
-
- if (ce->connect_retry_defined && ce->proto != PROTO_TCPv4_CLIENT
- && ce->proto != PROTO_TCPv6_CLIENT)
- msg (M_USAGE, "--connect-retry doesn't make sense unless also used with "
- "--proto tcp-client or tcp6-client");
-
- if (ce->connect_timeout_defined && ce->proto != PROTO_TCPv4_CLIENT
- && ce->proto != PROTO_TCPv6_CLIENT)
- msg (M_USAGE, "--connect-timeout doesn't make sense unless also used with "
- "--proto tcp-client or tcp6-client");
-
- /*
* Sanity check on MTU parameters
*/
if (options->ce.tun_mtu_defined && options->ce.link_mtu_defined)
@@ -1920,7 +1997,7 @@ options_postprocess_verify_ce (const struct options *options, const struct conne
if (proto_is_net(ce->proto)
&& string_defined_equal (ce->local, ce->remote)
- && ce->local_port == ce->remote_port)
+ && string_defined_equal (ce->local_port, ce->remote_port))
msg (M_USAGE, "--remote and --local addresses are the same");
if (string_defined_equal (ce->remote, options->ifconfig_local)
@@ -1965,7 +2042,7 @@ options_postprocess_verify_ce (const struct options *options, const struct conne
* Windows-specific options.
*/
-#ifdef WIN32
+#ifdef _WIN32
if (dev == DEV_TYPE_TUN && !(pull || (options->ifconfig_local && options->ifconfig_remote_netmask)))
msg (M_USAGE, "On Windows, --ifconfig is required when --dev tun is used");
@@ -1993,29 +2070,21 @@ options_postprocess_verify_ce (const struct options *options, const struct conne
msg (M_USAGE, "--explicit-exit-notify can only be used with --proto udp");
#endif
- if (!ce->remote && (ce->proto == PROTO_TCPv4_CLIENT
- || ce->proto == PROTO_TCPv6_CLIENT))
+ if (!ce->remote && ce->proto == PROTO_TCP_CLIENT)
msg (M_USAGE, "--remote MUST be used in TCP Client mode");
-#ifdef ENABLE_HTTP_PROXY
- if ((ce->http_proxy_options) && ce->proto != PROTO_TCPv4_CLIENT)
+ 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)");
if ((ce->http_proxy_options) && !ce->http_proxy_options->server)
msg (M_USAGE, "--http-proxy not specified but other http proxy options present");
-#endif
-#if defined(ENABLE_HTTP_PROXY) && defined(ENABLE_SOCKS)
if (ce->http_proxy_options && ce->socks_proxy_server)
msg (M_USAGE, "--http-proxy can not be used together with --socks-proxy");
-#endif
-#ifdef ENABLE_SOCKS
- if (ce->socks_proxy_server && ce->proto == PROTO_TCPv4_SERVER)
+ if (ce->socks_proxy_server && ce->proto == PROTO_TCP_SERVER)
msg (M_USAGE, "--socks-proxy can not be used in TCP Server mode");
-#endif
- if ((ce->proto == PROTO_TCPv4_SERVER || ce->proto == PROTO_TCPv6_SERVER)
- && connection_list_defined (options))
+ if (ce->proto == PROTO_TCP_SERVER && (options->connection_list->len > 1))
msg (M_USAGE, "TCP server mode allows at most one --remote address");
#if P2MP_SERVER
@@ -2029,13 +2098,14 @@ options_postprocess_verify_ce (const struct options *options, const struct conne
msg (M_USAGE, "--mode server only works with --dev tun or --dev tap");
if (options->pull)
msg (M_USAGE, "--pull cannot be used with --mode server");
- if (!(proto_is_udp(ce->proto) || ce->proto == PROTO_TCPv4_SERVER
- || ce->proto == PROTO_TCPv6_SERVER))
+ if (options->pull_filter_list)
+ msg (M_USAGE, "--pull-filter cannot be used with --mode server");
+ if (!(proto_is_udp(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");
#if PORT_SHARE
if ((options->port_share_host || options->port_share_port) &&
- (ce->proto != PROTO_TCPv4_SERVER && ce->proto != PROTO_TCPv6_SERVER))
+ (ce->proto != PROTO_TCP_SERVER))
msg (M_USAGE, "--port-share only works in TCP server mode "
"(--proto tcp-server or tcp6-server)");
#endif
@@ -2045,38 +2115,29 @@ options_postprocess_verify_ce (const struct options *options, const struct conne
msg (M_USAGE, "--remote cannot be used with --mode server");
if (!ce->bind_local)
msg (M_USAGE, "--nobind cannot be used with --mode server");
-#ifdef ENABLE_HTTP_PROXY
if (ce->http_proxy_options)
msg (M_USAGE, "--http-proxy cannot be used with --mode server");
-#endif
-#ifdef ENABLE_SOCKS
if (ce->socks_proxy_server)
msg (M_USAGE, "--socks-proxy cannot be used with --mode server");
-#endif
- if (options->connection_list)
- msg (M_USAGE, "<connection> cannot be used with --mode server");
-#if 0
- if (options->tun_ipv6)
- msg (M_USAGE, "--tun-ipv6 cannot be used with --mode server");
-#endif
+ /* <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)
+ msg (M_USAGE, "<connection> cannot be used with --mode server");
+
if (options->shaper)
msg (M_USAGE, "--shaper cannot be used with --mode server");
if (options->inetd)
msg (M_USAGE, "--inetd cannot be used with --mode server");
if (options->ipchange)
msg (M_USAGE, "--ipchange cannot be used with --mode server (use --client-connect instead)");
- if (!(proto_is_dgram(ce->proto) || ce->proto == PROTO_TCPv4_SERVER
- || ce->proto == PROTO_TCPv6_SERVER))
+ 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");
if (!proto_is_udp(ce->proto) && (options->cf_max || options->cf_per))
msg (M_USAGE, "--connect-freq only works with --mode server --proto udp. Try --max-clients instead.");
if (!(dev == DEV_TYPE_TAP || (dev == DEV_TYPE_TUN && options->topology == TOP_SUBNET)) && options->ifconfig_pool_netmask)
msg (M_USAGE, "The third parameter to --ifconfig-pool (netmask) is only valid in --dev tap mode");
-#ifdef ENABLE_OCC
- if (ce->explicit_exit_notification)
- msg (M_USAGE, "--explicit-exit-notify cannot be used with --mode server");
-#endif
if (options->routes && (options->routes->flags & RG_ENABLE))
msg (M_USAGE, "--redirect-gateway cannot be used with --mode server (however --push \"redirect-gateway\" is fine)");
if (options->route_delay_defined)
@@ -2087,9 +2148,8 @@ options_postprocess_verify_ce (const struct options *options, const struct conne
msg (M_USAGE, "--ifconfig-pool-persist must be used with --ifconfig-pool");
if (options->ifconfig_ipv6_pool_defined && !options->ifconfig_ipv6_local )
msg (M_USAGE, "--ifconfig-ipv6-pool needs --ifconfig-ipv6");
- if (options->ifconfig_ipv6_local && !options->tun_ipv6 )
- msg (M_INFO, "Warning: --ifconfig-ipv6 without --tun-ipv6 will not do IPv6");
-
+ if (options->allow_recursive_routing)
+ msg (M_USAGE, "--allow-recursive-routing cannot be used with --mode server");
if (options->auth_user_pass_file)
msg (M_USAGE, "--auth-user-pass cannot be used with --mode server (it should be used on the client side only)");
if (options->ccd_exclusive && !options->client_config_dir)
@@ -2102,8 +2162,8 @@ options_postprocess_verify_ce (const struct options *options, const struct conne
|| PLUGIN_OPTION_LIST (options)
|| MAN_CLIENT_AUTH_ENABLED (options));
const char *postfix = "must be used with --management-client-auth, an --auth-user-pass-verify script, or plugin";
- if ((options->ssl_flags & SSLF_CLIENT_CERT_NOT_REQUIRED) && !ccnr)
- msg (M_USAGE, "--client-cert-not-required %s", postfix);
+ if ((options->ssl_flags & (SSLF_CLIENT_CERT_NOT_REQUIRED|SSLF_CLIENT_CERT_OPTIONAL)) && !ccnr)
+ msg (M_USAGE, "--verify-client-cert none|optional %s", postfix);
if ((options->ssl_flags & SSLF_USERNAME_AS_COMMON_NAME) && !ccnr)
msg (M_USAGE, "--username-as-common-name %s", postfix);
if ((options->ssl_flags & SSLF_AUTH_USER_PASS_OPTIONAL) && !ccnr)
@@ -2137,8 +2197,8 @@ options_postprocess_verify_ce (const struct options *options, const struct conne
msg (M_USAGE, "--duplicate-cn requires --mode server");
if (options->cf_max || options->cf_per)
msg (M_USAGE, "--connect-freq requires --mode server");
- if (options->ssl_flags & SSLF_CLIENT_CERT_NOT_REQUIRED)
- msg (M_USAGE, "--client-cert-not-required requires --mode server");
+ if (options->ssl_flags & (SSLF_CLIENT_CERT_NOT_REQUIRED|SSLF_CLIENT_CERT_OPTIONAL))
+ msg (M_USAGE, "--client-cert-not-required and --verify-client-cert require --mode server");
if (options->ssl_flags & SSLF_USERNAME_AS_COMMON_NAME)
msg (M_USAGE, "--username-as-common-name requires --mode server");
if (options->ssl_flags & SSLF_AUTH_USER_PASS_OPTIONAL)
@@ -2151,6 +2211,8 @@ options_postprocess_verify_ce (const struct options *options, const struct conne
"tcp-nodelay in the server configuration instead.");
if (options->auth_user_pass_verify_script)
msg (M_USAGE, "--auth-user-pass-verify requires --mode server");
+ if (options->auth_token_generate)
+ msg (M_USAGE, "--auth-gen-token requires --mode server");
#if PORT_SHARE
if (options->port_share_host || options->port_share_port)
msg (M_USAGE, "--port-share requires TCP server mode (--mode server --proto tcp-server)");
@@ -2165,14 +2227,14 @@ options_postprocess_verify_ce (const struct options *options, const struct conne
#ifdef ENABLE_CRYPTO
+ if (options->ncp_enabled && !tls_check_ncp_cipher_list(options->ncp_ciphers))
+ {
+ msg (M_USAGE, "NCP cipher list contains unsupported ciphers.");
+ }
+
/*
* Check consistency of replay options
*/
- if ((!proto_is_udp(ce->proto))
- && (options->replay_window != defaults.replay_window
- || options->replay_time != defaults.replay_time))
- msg (M_USAGE, "--replay-window only makes sense with --proto udp");
-
if (!options->replay
&& (options->replay_window != defaults.replay_window
|| options->replay_time != defaults.replay_time))
@@ -2181,16 +2243,24 @@ options_postprocess_verify_ce (const struct options *options, const struct conne
/*
* SSL/TLS mode sanity checks.
*/
-
-#ifdef ENABLE_SSL
if (options->tls_server + options->tls_client +
(options->shared_secret_file != NULL) > 1)
msg (M_USAGE, "specify only one of --tls-server, --tls-client, or --secret");
- if (options->tls_server)
+ if (options->ssl_flags & (SSLF_CLIENT_CERT_NOT_REQUIRED|SSLF_CLIENT_CERT_OPTIONAL))
+ {
+ msg (M_WARN, "WARNING: POTENTIALLY DANGEROUS OPTION "
+ "--verify-client-cert none|optional (or --client-cert-not-required) "
+ "may accept clients which do not present a certificate");
+ }
+
+ if (options->key_method == 1)
{
- notnull (options->dh_file, "DH file (--dh)");
+ msg (M_WARN, "WARNING: --key-method 1 is deprecated and will be removed "
+ "in OpenVPN 2.5. By default --key-method 2 will be used if not set "
+ "in the configuration file, which is the recommended approach.");
}
+
if (options->tls_server || options->tls_client)
{
#ifdef ENABLE_PKCS11
@@ -2209,6 +2279,8 @@ options_postprocess_verify_ce (const struct options *options, const struct conne
#ifdef MANAGMENT_EXTERNAL_KEY
if (options->management_flags & MF_EXTERNAL_KEY)
msg(M_USAGE, "Parameter --management-external-key cannot be used when --pkcs11-provider is also specified.");
+ if (options->management_flags & MF_EXTERNAL_CERT)
+ msg(M_USAGE, "Parameter --management-external-cert cannot be used when --pkcs11-provider is also specified.");
#endif
if (options->pkcs12_file)
msg(M_USAGE, "Parameter --pkcs12 cannot be used when --pkcs11-provider is also specified.");
@@ -2224,6 +2296,13 @@ options_postprocess_verify_ce (const struct options *options, const struct conne
{
msg (M_USAGE, "--key and --management-external-key are mutually exclusive");
}
+ else if((options->management_flags & MF_EXTERNAL_CERT))
+ {
+ if (options->cert_file)
+ msg (M_USAGE, "--cert and --management-external-cert are mutually exclusive");
+ else if(!(options->management_flags & MF_EXTERNAL_KEY))
+ msg (M_USAGE, "--management-external-cert must be used with --management-external-key");
+ }
else
#endif
#ifdef ENABLE_CRYPTOAPI
@@ -2240,14 +2319,16 @@ options_postprocess_verify_ce (const struct options *options, const struct conne
#ifdef MANAGMENT_EXTERNAL_KEY
if (options->management_flags & MF_EXTERNAL_KEY)
msg(M_USAGE, "Parameter --management-external-key cannot be used when --cryptoapicert is also specified.");
+ if (options->management_flags & MF_EXTERNAL_CERT)
+ msg(M_USAGE, "Parameter --management-external-cert cannot be used when --cryptoapicert is also specified.");
#endif
}
else
#endif
if (options->pkcs12_file)
{
-#ifdef ENABLE_CRYPTO_POLARSSL
- msg(M_USAGE, "Parameter --pkcs12 cannot be used with the PolarSSL version version of OpenVPN.");
+#ifdef ENABLE_CRYPTO_MBEDTLS
+ msg(M_USAGE, "Parameter --pkcs12 cannot be used with the mbed TLS version version of OpenVPN.");
#else
if (options->ca_path)
msg(M_USAGE, "Parameter --capath cannot be used when --pkcs12 is also specified.");
@@ -2257,17 +2338,19 @@ options_postprocess_verify_ce (const struct options *options, const struct conne
msg(M_USAGE, "Parameter --key cannot be used when --pkcs12 is also specified.");
#ifdef MANAGMENT_EXTERNAL_KEY
if (options->management_flags & MF_EXTERNAL_KEY)
- msg(M_USAGE, "Parameter --external-management-key cannot be used when --pkcs12 is also specified.");
+ msg(M_USAGE, "Parameter --management-external-key cannot be used when --pkcs12 is also specified.");
+ if (options->management_flags & MF_EXTERNAL_CERT)
+ msg(M_USAGE, "Parameter --management-external-cert cannot be used when --pkcs12 is also specified.");
#endif
#endif
}
else
{
-#ifdef ENABLE_CRYPTO_POLARSSL
+#ifdef ENABLE_CRYPTO_MBEDTLS
if (!(options->ca_file))
msg(M_USAGE, "You must define CA file (--ca)");
if (options->ca_path)
- msg(M_USAGE, "Parameter --capath cannot be used with the PolarSSL version version of OpenVPN.");
+ msg(M_USAGE, "Parameter --capath cannot be used with the mbed TLS version version of OpenVPN.");
#else
if ((!(options->ca_file)) && (!(options->ca_path)))
msg(M_USAGE, "You must define CA file (--ca) or CA path (--capath)");
@@ -2275,14 +2358,14 @@ options_postprocess_verify_ce (const struct options *options, const struct conne
if (pull)
{
- const int sum = (options->cert_file != NULL) +
+ const int sum =
#ifdef MANAGMENT_EXTERNAL_KEY
- ((options->priv_key_file != NULL) || (options->management_flags & MF_EXTERNAL_KEY));
+ ((options->cert_file != NULL) || (options->management_flags & MF_EXTERNAL_CERT)) +
+ ((options->priv_key_file != NULL) || (options->management_flags & MF_EXTERNAL_KEY));
#else
- (options->priv_key_file != NULL);
+ (options->cert_file != NULL) + (options->priv_key_file != NULL);
#endif
-
if (sum == 0)
{
#if P2MP
@@ -2299,6 +2382,9 @@ options_postprocess_verify_ce (const struct options *options, const struct conne
}
else
{
+#ifdef MANAGMENT_EXTERNAL_KEY
+ if (!(options->management_flags & MF_EXTERNAL_CERT))
+#endif
notnull (options->cert_file, "certificate file (--cert) or PKCS#12 file (--pkcs12)");
#ifdef MANAGMENT_EXTERNAL_KEY
if (!(options->management_flags & MF_EXTERNAL_KEY))
@@ -2306,6 +2392,10 @@ options_postprocess_verify_ce (const struct options *options, const struct conne
notnull (options->priv_key_file, "private key file (--key) or PKCS#12 file (--pkcs12)");
}
}
+ if (options->tls_auth_file && options->tls_crypt_file)
+ {
+ msg (M_USAGE, "--tls-auth and --tls-crypt are mutually exclusive");
+ }
}
else
{
@@ -2323,7 +2413,7 @@ options_postprocess_verify_ce (const struct options *options, const struct conne
MUST_BE_UNDEF (dh_file);
MUST_BE_UNDEF (cert_file);
MUST_BE_UNDEF (priv_key_file);
-#ifndef ENABLE_CRYPTO_POLARSSL
+#ifndef ENABLE_CRYPTO_MBEDTLS
MUST_BE_UNDEF (pkcs12_file);
#endif
MUST_BE_UNDEF (cipher_list);
@@ -2337,6 +2427,7 @@ options_postprocess_verify_ce (const struct options *options, const struct conne
MUST_BE_UNDEF (handshake_window);
MUST_BE_UNDEF (transition_window);
MUST_BE_UNDEF (tls_auth_file);
+ MUST_BE_UNDEF (tls_crypt_file);
MUST_BE_UNDEF (single_session);
#ifdef ENABLE_PUSH_PEER_INFO
MUST_BE_UNDEF (push_peer_info);
@@ -2353,16 +2444,12 @@ options_postprocess_verify_ce (const struct options *options, const struct conne
MUST_BE_UNDEF (pkcs11_id);
MUST_BE_UNDEF (pkcs11_id_management);
#endif
-#if P2MP
- MUST_BE_UNDEF (server_poll_timeout);
-#endif
if (pull)
msg (M_USAGE, err, "--pull");
}
#undef MUST_BE_UNDEF
#endif /* ENABLE_CRYPTO */
-#endif /* ENABLE_SSL */
#if P2MP
if (options->auth_user_pass_file && !options->pull)
@@ -2380,35 +2467,29 @@ options_postprocess_mutate_ce (struct options *o, struct connection_entry *ce)
#if P2MP_SERVER
if (o->server_defined || o->server_bridge_defined || o->server_bridge_proxy_dhcp)
{
- if (ce->proto == PROTO_TCPv4)
- ce->proto = PROTO_TCPv4_SERVER;
- else if (ce->proto == PROTO_TCPv6)
- ce->proto = PROTO_TCPv6_SERVER;
+ if (ce->proto == PROTO_TCP)
+ ce->proto = PROTO_TCP_SERVER;
}
#endif
#if P2MP
if (o->client)
{
- if (ce->proto == PROTO_TCPv4)
- ce->proto = PROTO_TCPv4_CLIENT;
- else if (ce->proto == PROTO_TCPv6)
- ce->proto = PROTO_TCPv6_CLIENT;
+ if (ce->proto == PROTO_TCP)
+ ce->proto = PROTO_TCP_CLIENT;
}
#endif
- if (ce->proto == PROTO_TCPv4_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;
-#ifdef ENABLE_SOCKS
- if (ce->proto == PROTO_UDPv4 && 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;
-#endif
if (!ce->bind_local)
- ce->local_port = 0;
+ ce->local_port = NULL;
/* if protocol forcing is enabled, disable all protocols except for the forced one */
- if (o->proto_force >= 0 && proto_is_tcp(o->proto_force) != proto_is_tcp(ce->proto))
+ if (o->proto_force >= 0 && o->proto_force != ce->proto)
ce->flags |= CE_DISABLED;
/*
@@ -2445,7 +2526,9 @@ options_postprocess_mutate_ce (struct options *o, struct connection_entry *ce)
static void
options_postprocess_mutate_invariant (struct options *options)
{
+#ifdef _WIN32
const int dev = dev_type_enum (options->dev, options->dev_type);
+#endif
/*
* In forking TCP server mode, you don't need to ifconfig
@@ -2454,7 +2537,7 @@ options_postprocess_mutate_invariant (struct options *options)
if (options->inetd == INETD_NOWAIT)
options->ifconfig_noexec = true;
-#ifdef WIN32
+#ifdef _WIN32
if ((dev == DEV_TYPE_TUN || dev == DEV_TYPE_TAP) && !options->route_delay_defined)
{
if (options->mode == MODE_POINT_TO_POINT)
@@ -2477,7 +2560,7 @@ options_postprocess_mutate_invariant (struct options *options)
*/
if (options->mode == MODE_SERVER)
{
-#ifdef WIN32
+#ifdef _WIN32
/*
* We need to explicitly set --tap-sleep because
* we do not schedule event timers in the top-level context.
@@ -2516,6 +2599,7 @@ options_postprocess_verify (const struct options *o)
static void
options_postprocess_mutate (struct options *o)
{
+ int i;
/*
* Process helper-type options which map to other, more complex
* sequences of options.
@@ -2529,48 +2613,57 @@ options_postprocess_mutate (struct options *o)
if (o->remote_list && !o->connection_list)
{
/*
- * For compatibility with 2.0.x, map multiple --remote options
- * into connection list (connection lists added in 2.1).
+ * Convert remotes into connection list
*/
- if (o->remote_list->len > 1 || o->force_connection_list)
- {
- const struct remote_list *rl = o->remote_list;
- int i;
- for (i = 0; i < rl->len; ++i)
- {
- const struct remote_entry *re = rl->array[i];
- struct connection_entry ce = o->ce;
- struct connection_entry *ace;
-
- ASSERT (re->remote);
- connection_entry_load_re (&ce, re);
- ace = alloc_connection_entry (o, M_USAGE);
- ASSERT (ace);
- *ace = ce;
- }
- }
- else if (o->remote_list->len == 1) /* one --remote option specified */
- {
- connection_entry_load_re (&o->ce, o->remote_list->array[0]);
- }
- else
- {
- ASSERT (0);
- }
+ const struct remote_list *rl = o->remote_list;
+ for (i = 0; i < rl->len; ++i)
+ {
+ const struct remote_entry *re = rl->array[i];
+ struct connection_entry ce = o->ce;
+ struct connection_entry *ace;
+
+ ASSERT (re->remote);
+ connection_entry_load_re (&ce, re);
+ ace = alloc_connection_entry (o, M_USAGE);
+ ASSERT (ace);
+ *ace = ce;
+ }
}
- if (o->connection_list)
+ else if(!o->remote_list && !o->connection_list)
{
- int i;
- for (i = 0; i < o->connection_list->len; ++i)
+ struct connection_entry *ace;
+ ace = alloc_connection_entry (o, M_USAGE);
+ ASSERT (ace);
+ *ace = o->ce;
+ }
+
+ ASSERT (o->connection_list);
+ for (i = 0; i < o->connection_list->len; ++i)
options_postprocess_mutate_ce (o, o->connection_list->array[i]);
-#if HTTP_PROXY_OVERRIDE
- if (o->http_proxy_override)
+#ifdef ENABLE_CRYPTO
+ if (o->tls_server)
+ {
+ /* Check that DH file is specified, or explicitly disabled */
+ notnull (o->dh_file, "DH file (--dh)");
+ if (streq (o->dh_file, "none"))
+ o->dh_file = NULL;
+ }
+
+ /* cipher negotiation (NCP) currently assumes --pull or --mode server */
+ if ( o->ncp_enabled &&
+ ! (o->pull || o->mode == MODE_SERVER) )
+ {
+ msg( M_WARN, "disabling NCP mode (--ncp-disable) because not "
+ "in P2MP client or server mode" );
+ o->ncp_enabled = false;
+ }
+#endif
+
+#if ENABLE_MANAGEMENT
+ if (o->http_proxy_override)
options_postprocess_http_proxy_override(o);
#endif
- }
- else
- options_postprocess_mutate_ce (o, &o->ce);
#ifdef ENABLE_CRYPTOAPI
if (o->cryptoapi_cert)
@@ -2609,6 +2702,7 @@ options_postprocess_mutate (struct options *o)
#define CHKACC_FILEXSTWR (1<<2) /** If file exists, is it writable? */
#define CHKACC_INLINE (1<<3) /** File is present if it's an inline file */
#define CHKACC_ACPTSTDIN (1<<4) /** If filename is stdin, it's allowed and "exists" */
+#define CHKACC_PRIVATE (1<<5) /** Warn if this (private) file is group/others accessible */
static bool
check_file_access(const int type, const char *file, const int mode, const char *opt)
@@ -2649,6 +2743,23 @@ check_file_access(const int type, const char *file, const int mode, const char *
if (platform_access (file, W_OK) != 0)
errcode = errno;
+ /* Warn if a given private file is group/others accessible. */
+ if (type & CHKACC_PRIVATE)
+ {
+ platform_stat_t st;
+ if (platform_stat (file, &st))
+ {
+ msg (M_WARN | M_ERRNO, "WARNING: cannot stat file '%s'", file);
+ }
+#ifndef _WIN32
+ else
+ {
+ if (st.st_mode & (S_IRWXG|S_IRWXO))
+ msg (M_WARN, "WARNING: file '%s' is group or others accessible", file);
+ }
+#endif
+ }
+
/* Scream if an error is found */
if( errcode > 0 )
msg (M_NOPREFIX|M_OPTERR, "%s fails with '%s': %s",
@@ -2724,7 +2835,7 @@ check_cmd_access(const char *command, const char *opt, const char *chroot)
/* Extract executable path and arguments */
argv = argv_new ();
- argv_printf (&argv, "%sc", command);
+ argv_parse_cmd (&argv, command);
/* if an executable is specified then check it; otherwise, complain */
if (argv.argv[0])
@@ -2754,8 +2865,8 @@ options_postprocess_filechecks (struct options *options)
{
bool errs = false;
+#ifdef ENABLE_CRYPTO
/* ** SSL/TLS/crypto related files ** */
-#ifdef ENABLE_SSL
errs |= check_file_access (CHKACC_FILE|CHKACC_INLINE, options->dh_file, R_OK, "--dh");
errs |= check_file_access (CHKACC_FILE|CHKACC_INLINE, options->ca_file, R_OK, "--ca");
errs |= check_file_access_chroot (options->chroot_dir, CHKACC_FILE, options->ca_path, R_OK, "--capath");
@@ -2765,41 +2876,40 @@ options_postprocess_filechecks (struct options *options)
#ifdef MANAGMENT_EXTERNAL_KEY
if(!(options->management_flags & MF_EXTERNAL_KEY))
#endif
- errs |= check_file_access (CHKACC_FILE|CHKACC_INLINE, options->priv_key_file, R_OK,
- "--key");
- errs |= check_file_access (CHKACC_FILE|CHKACC_INLINE, options->pkcs12_file, R_OK,
- "--pkcs12");
+ {
+ errs |= check_file_access (CHKACC_FILE|CHKACC_INLINE|CHKACC_PRIVATE,
+ options->priv_key_file, R_OK, "--key");
+ }
+ errs |= check_file_access (CHKACC_FILE|CHKACC_INLINE|CHKACC_PRIVATE,
+ options->pkcs12_file, R_OK, "--pkcs12");
if (options->ssl_flags & SSLF_CRL_VERIFY_DIR)
errs |= check_file_access_chroot (options->chroot_dir, CHKACC_FILE, options->crl_file, R_OK|X_OK,
"--crl-verify directory");
else
- errs |= check_file_access_chroot (options->chroot_dir, CHKACC_FILE, options->crl_file, R_OK,
- "--crl-verify");
-
- errs |= check_file_access (CHKACC_FILE|CHKACC_INLINE, options->tls_auth_file, R_OK,
- "--tls-auth");
-#endif /* ENABLE_SSL */
-#ifdef ENABLE_CRYPTO
- errs |= check_file_access (CHKACC_FILE|CHKACC_INLINE, options->shared_secret_file, R_OK,
- "--secret");
+ errs |= check_file_access_chroot (options->chroot_dir, CHKACC_FILE|CHKACC_INLINE,
+ options->crl_file, R_OK, "--crl-verify");
+
+ errs |= check_file_access (CHKACC_FILE|CHKACC_INLINE|CHKACC_PRIVATE,
+ options->tls_auth_file, R_OK, "--tls-auth");
+ errs |= check_file_access (CHKACC_FILE|CHKACC_INLINE|CHKACC_PRIVATE,
+ options->tls_crypt_file, R_OK, "--tls-crypt");
+ errs |= check_file_access (CHKACC_FILE|CHKACC_INLINE|CHKACC_PRIVATE,
+ options->shared_secret_file, R_OK, "--secret");
errs |= check_file_access (CHKACC_DIRPATH|CHKACC_FILEXSTWR,
- options->packet_id_file, R_OK|W_OK, "--replay-persist");
-#endif /* ENABLE_CRYPTO */
-
+ options->packet_id_file, R_OK|W_OK, "--replay-persist");
/* ** Password files ** */
-#ifdef ENABLE_SSL
- errs |= check_file_access (CHKACC_FILE|CHKACC_ACPTSTDIN,
- options->key_pass_file, R_OK, "--askpass");
-#endif /* ENABLE_SSL */
+ errs |= check_file_access (CHKACC_FILE|CHKACC_ACPTSTDIN|CHKACC_PRIVATE,
+ options->key_pass_file, R_OK, "--askpass");
+#endif /* ENABLE_CRYPTO */
#ifdef ENABLE_MANAGEMENT
- errs |= check_file_access (CHKACC_FILE|CHKACC_ACPTSTDIN,
+ errs |= check_file_access (CHKACC_FILE|CHKACC_ACPTSTDIN|CHKACC_PRIVATE,
options->management_user_pass, R_OK,
"--management user/password file");
#endif /* ENABLE_MANAGEMENT */
#if P2MP
- errs |= check_file_access (CHKACC_FILE|CHKACC_ACPTSTDIN,
+ errs |= check_file_access (CHKACC_FILE|CHKACC_ACPTSTDIN|CHKACC_PRIVATE,
options->auth_user_pass_file, R_OK,
"--auth-user-pass");
#endif /* P2MP */
@@ -2815,10 +2925,10 @@ options_postprocess_filechecks (struct options *options)
R_OK|W_OK, "--status");
/* ** Config related ** */
-#ifdef ENABLE_SSL
+#ifdef ENABLE_CRYPTO
errs |= check_file_access_chroot (options->chroot_dir, CHKACC_FILE, options->tls_export_cert,
R_OK|W_OK|X_OK, "--tls-export-cert");
-#endif /* ENABLE_SSL */
+#endif /* ENABLE_CRYPTO */
#if P2MP_SERVER
errs |= check_file_access_chroot (options->chroot_dir, CHKACC_FILE, options->client_config_dir,
R_OK|X_OK, "--client-config-dir");
@@ -2872,18 +2982,16 @@ pre_pull_save (struct options *o)
o->pre_pull->routes_ipv6 = clone_route_ipv6_option_list(o->routes_ipv6, &o->gc);
o->pre_pull->routes_ipv6_defined = true;
}
-#ifdef ENABLE_CLIENT_NAT
if (o->client_nat)
{
o->pre_pull->client_nat = clone_client_nat_option_list(o->client_nat, &o->gc);
o->pre_pull->client_nat_defined = true;
}
-#endif
}
}
void
-pre_pull_restore (struct options *o)
+pre_pull_restore (struct options *o, struct gc_arena *gc)
{
const struct options_pre_pull *pp = o->pre_pull;
if (pp)
@@ -2895,7 +3003,7 @@ pre_pull_restore (struct options *o)
if (pp->routes_defined)
{
rol_check_alloc (o);
- copy_route_option_list (o->routes, pp->routes);
+ copy_route_option_list (o->routes, pp->routes, gc);
}
else
o->routes = NULL;
@@ -2903,12 +3011,11 @@ pre_pull_restore (struct options *o)
if (pp->routes_ipv6_defined)
{
rol6_check_alloc (o);
- copy_route_ipv6_option_list (o->routes_ipv6, pp->routes_ipv6);
+ copy_route_ipv6_option_list (o->routes_ipv6, pp->routes_ipv6, gc);
}
else
o->routes_ipv6 = NULL;
-#ifdef ENABLE_CLIENT_NAT
if (pp->client_nat_defined)
{
cnol_check_alloc (o);
@@ -2916,7 +3023,6 @@ pre_pull_restore (struct options *o)
}
else
o->client_nat = NULL;
-#endif
o->foreign_option_index = pp->foreign_option_index;
}
@@ -2929,6 +3035,37 @@ pre_pull_restore (struct options *o)
#ifdef ENABLE_OCC
+/**
+ * Calculate the link-mtu to advertise to our peer. The actual value is not
+ * relevant, because we will possibly perform data channel cipher negotiation
+ * after this, but older clients will log warnings if we do not supply them the
+ * value they expect. This assumes that the traditional cipher/auth directives
+ * in the config match the config of the peer.
+ */
+static size_t
+calc_options_string_link_mtu(const struct options *o, const struct frame *frame)
+{
+ size_t link_mtu = EXPANDED_SIZE (frame);
+#ifdef ENABLE_CRYPTO
+ if (o->pull || o->mode == MODE_SERVER)
+ {
+ struct frame fake_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()));
+ 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,
+ o->ce.tun_mtu_defined, o->ce.tun_mtu);
+ msg (D_MTU_DEBUG, "%s: link-mtu %u -> %d", __func__, (unsigned int) link_mtu,
+ EXPANDED_SIZE (&fake_frame));
+ link_mtu = EXPANDED_SIZE (&fake_frame);
+ }
+#endif
+ return link_mtu;
+}
+
/*
* Build an options string to represent data channel encryption options.
* This string must match exactly between peers. The keysize is checked
@@ -2953,6 +3090,7 @@ pre_pull_restore (struct options *o)
* the other end of the connection]
*
* --comp-lzo
+ * --compress alg
* --fragment
*
* Crypto Options:
@@ -2972,7 +3110,6 @@ pre_pull_restore (struct options *o)
* --tls-server [matched with --tls-client on
* the other end of the connection]
*/
-
char *
options_string (const struct options *o,
const struct frame *frame,
@@ -2990,14 +3127,14 @@ options_string (const struct options *o,
*/
buf_printf (&out, ",dev-type %s", dev_type_string (o->dev, o->dev_type));
- buf_printf (&out, ",link-mtu %d", EXPANDED_SIZE (frame));
+ buf_printf (&out, ",link-mtu %u", (unsigned int) calc_options_string_link_mtu(o, frame));
buf_printf (&out, ",tun-mtu %d", PAYLOAD_SIZE (frame));
- buf_printf (&out, ",proto %s", proto2ascii (proto_remote (o->ce.proto, remote), true));
+ buf_printf (&out, ",proto %s", proto_remote (o->ce.proto, remote));
/* send tun_ipv6 only in peer2peer mode - in client/server mode, it
* is usually pushed by the server, triggering a non-helpful warning
*/
- if (o->tun_ipv6 && o->mode == MODE_POINT_TO_POINT && !PULL_DEFINED(o))
+ if (o->ifconfig_ipv6_local && o->mode == MODE_POINT_TO_POINT && !PULL_DEFINED(o))
buf_printf (&out, ",tun-ipv6");
/*
@@ -3014,8 +3151,8 @@ options_string (const struct options *o,
o->ifconfig_ipv6_local,
o->ifconfig_ipv6_netbits,
o->ifconfig_ipv6_remote,
- (in_addr_t)0,
- (in_addr_t)0,
+ NULL,
+ NULL,
false,
NULL);
if (tt)
@@ -3034,9 +3171,9 @@ options_string (const struct options *o,
tt = NULL;
}
-#ifdef ENABLE_LZO
- if (o->lzo & LZO_SELECTED)
- buf_printf (&out, ",comp-lzo");
+#ifdef USE_COMP
+ if (o->comp.alg != COMP_ALG_UNDEF)
+ buf_printf (&out, ",comp-lzo"); /* for compatibility, this simply indicates that compression context is active, not necessarily LZO per-se */
#endif
#ifdef ENABLE_FRAGMENT
@@ -3046,13 +3183,8 @@ options_string (const struct options *o,
#ifdef ENABLE_CRYPTO
-#ifdef ENABLE_SSL
#define TLS_CLIENT (o->tls_client)
#define TLS_SERVER (o->tls_server)
-#else
-#define TLS_CLIENT (false)
-#define TLS_SERVER (false)
-#endif
/*
* Key direction
@@ -3075,11 +3207,11 @@ options_string (const struct options *o,
+ (TLS_SERVER == true)
<= 1);
- init_key_type (&kt, o->ciphername, o->ciphername_defined,
- o->authname, o->authname_defined,
- o->keysize, true, false);
+ init_key_type (&kt, o->ciphername, o->authname, o->keysize, true,
+ false);
- buf_printf (&out, ",cipher %s", cipher_kt_name (kt.cipher));
+ buf_printf (&out, ",cipher %s",
+ translate_cipher_name_to_openvpn(cipher_kt_name (kt.cipher)));
buf_printf (&out, ",auth %s", md_kt_name (kt.digest));
buf_printf (&out, ",keysize %d", kt.cipher_length * 8);
if (o->shared_secret_file)
@@ -3095,7 +3227,6 @@ options_string (const struct options *o,
#endif
}
-#ifdef ENABLE_SSL
/*
* SSL Options
*/
@@ -3104,6 +3235,9 @@ options_string (const struct options *o,
{
if (o->tls_auth_file)
buf_printf (&out, ",tls-auth");
+ /* Not adding tls-crypt here, because we won't reach this code if
+ * tls-auth/tls-crypt does not match. Removing tls-auth here would
+ * break stuff, so leaving that in place. */
if (o->key_method > 1)
buf_printf (&out, ",key-method %d", o->key_method);
@@ -3124,7 +3258,6 @@ options_string (const struct options *o,
buf_printf (&out, ",tls-server");
}
}
-#endif /* ENABLE_SSL */
#undef TLS_CLIENT
#undef TLS_SERVER
@@ -3447,10 +3580,11 @@ usage (void)
struct options o;
init_options (&o, true);
-#if defined(ENABLE_CRYPTO) && defined(ENABLE_SSL)
+#ifdef ENABLE_CRYPTO
fprintf (fp, usage_message,
title_string,
o.ce.connect_retry_seconds,
+ o.ce.connect_retry_seconds_max,
o.ce.local_port, o.ce.remote_port,
TUN_MTU_DEFAULT, TAP_MTU_EXTRA_DEFAULT,
o.verbosity,
@@ -3458,15 +3592,6 @@ usage (void)
o.replay_window, o.replay_time,
o.tls_timeout, o.renegotiate_seconds,
o.handshake_window, o.transition_window);
-#elif defined(ENABLE_CRYPTO)
- fprintf (fp, usage_message,
- title_string,
- o.ce.connect_retry_seconds,
- o.ce.local_port, o.ce.remote_port,
- TUN_MTU_DEFAULT, TAP_MTU_EXTRA_DEFAULT,
- o.verbosity,
- o.authname, o.ciphername,
- o.replay_window, o.replay_time);
#else
fprintf (fp, usage_message,
title_string,
@@ -3489,7 +3614,7 @@ usage_small (void)
openvpn_exit (OPENVPN_EXIT_STATUS_USAGE); /* exit point */
}
-#ifdef WIN32
+#ifdef _WIN32
void show_windows_version(const unsigned int flags)
{
struct gc_arena gc = gc_new ();
@@ -3501,7 +3626,7 @@ void show_windows_version(const unsigned int flags)
void
show_library_versions(const unsigned int flags)
{
-#ifdef ENABLE_SSL
+#ifdef ENABLE_CRYPTO
#define SSL_LIB_VER_STR get_ssl_library_version()
#else
#define SSL_LIB_VER_STR ""
@@ -3523,7 +3648,7 @@ usage_version (void)
{
msg (M_INFO|M_NOPREFIX, "%s", title_string);
show_library_versions( M_INFO|M_NOPREFIX );
-#ifdef WIN32
+#ifdef _WIN32
show_windows_version( M_INFO|M_NOPREFIX );
#endif
msg (M_INFO|M_NOPREFIX, "Originally developed by James Yonan");
@@ -3535,9 +3660,6 @@ usage_version (void)
#ifdef CONFIGURE_SPECIAL_BUILD
msg (M_INFO|M_NOPREFIX, "special build: %s", CONFIGURE_SPECIAL_BUILD);
#endif
-#ifdef CONFIGURE_GIT_REVISION
- msg (M_INFO|M_NOPREFIX, "git revision: %s", CONFIGURE_GIT_REVISION);
-#endif
#endif
openvpn_exit (OPENVPN_EXIT_STATUS_USAGE); /* exit point */
}
@@ -3573,7 +3695,7 @@ positive_atoi (const char *str)
return i < 0 ? 0 : i;
}
-#ifdef WIN32 /* This function is only used when compiling on Windows */
+#ifdef _WIN32 /* This function is only used when compiling on Windows */
static unsigned int
atou (const char *str)
{
@@ -3809,7 +3931,7 @@ read_inline_file (struct in_src *is, const char *close_tag, struct gc_arena *gc)
buf_printf (&buf, "%s", line);
}
if (!endtagfound)
- msg (M_WARN, "WARNING: Endtag %s missing", close_tag);
+ msg (M_FATAL, "ERROR: Endtag %s missing", close_tag);
ret = string_alloc (BSTR (&buf), gc);
buf_clear (&buf);
free_buf (&buf);
@@ -4019,6 +4141,45 @@ parse_argv (struct options *options,
}
}
+/**
+ * Filter an option line by all pull filters.
+ *
+ * If a match is found, the line is modified depending on
+ * the filter type, and returns true. If the filter type is
+ * reject, SIGUSR1 is triggered and the return value is false.
+ * In that case the caller must end the push processing.
+ */
+static bool
+apply_pull_filter (const struct options *o, char *line)
+{
+ struct pull_filter *f;
+
+ if (!o->pull_filter_list) return true;
+
+ for (f = o->pull_filter_list->head; f; f = f->next)
+ {
+ if (f->type == PUF_TYPE_ACCEPT && strncmp (line, f->pattern, f->size) == 0)
+ {
+ msg (D_LOW, "Pushed option accepted by filter: '%s'", line);
+ return true;
+ }
+ else if (f->type == PUF_TYPE_IGNORE && strncmp (line, f->pattern, f->size) == 0)
+ {
+ msg (D_PUSH, "Pushed option removed by filter: '%s'", line);
+ *line = '\0';
+ return true;
+ }
+ else if (f->type == PUF_TYPE_REJECT && strncmp (line, f->pattern, f->size) == 0)
+ {
+ msg (M_WARN, "Pushed option rejected by filter: '%s'. Restarting.", line);
+ *line = '\0';
+ throw_signal_soft (SIGUSR1, "Offending option received from server");
+ return false;
+ }
+ }
+ return true;
+}
+
bool
apply_push_options (struct options *options,
struct buffer *buf,
@@ -4036,6 +4197,10 @@ apply_push_options (struct options *options,
char *p[MAX_PARMS];
CLEAR (p);
++line_num;
+ if (!apply_pull_filter(options, line))
+ {
+ return false; /* Cause push/pull error and stop push processing */
+ }
if (parse_line (line, p, SIZE (p), file, line_num, msglevel, &options->gc))
{
add_option (options, p, file, line_num, 0, msglevel, permission_mask, option_types_found, es);
@@ -4222,13 +4387,18 @@ add_option (struct options *options,
{
VERIFY_PERMISSION (OPT_P_GENERAL);
usage ();
+ if (p[1])
+ {
+ msg (msglevel, "--help does not accept any parameters");
+ goto err;
+ }
}
- if (streq (p[0], "version"))
+ if (streq (p[0], "version") && !p[1])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
usage_version ();
}
- else if (streq (p[0], "config") && p[1])
+ else if (streq (p[0], "config") && p[1] && !p[2])
{
VERIFY_PERMISSION (OPT_P_CONFIG);
@@ -4239,12 +4409,17 @@ add_option (struct options *options,
read_config_file (options, p[1], level, file, line, msglevel, permission_mask, option_types_found, es);
}
#if defined(ENABLE_DEBUG) && !defined(ENABLE_SMALL)
- else if (streq (p[0], "show-gateway"))
+ else if (streq (p[0], "show-gateway") && !p[2])
{
struct route_gateway_info rgi;
+ struct route_ipv6_gateway_info rgi6;
+ struct in6_addr remote = IN6ADDR_ANY_INIT;
VERIFY_PERMISSION (OPT_P_GENERAL);
+ if (p[1])
+ get_ipv6_addr (p[1], &remote, NULL, M_WARN);
get_default_gateway(&rgi);
- print_default_gateway(M_INFO, &rgi);
+ get_default_gateway_ipv6(&rgi6, &remote);
+ print_default_gateway(M_INFO, &rgi, &rgi6);
openvpn_exit (OPENVPN_EXIT_STATUS_GOOD); /* exit point */
}
#endif
@@ -4289,10 +4464,8 @@ add_option (struct options *options,
msg (M_WARN, "echo/parameter option overflow");
}
#ifdef ENABLE_MANAGEMENT
- else if (streq (p[0], "management") && p[1] && p[2])
+ else if (streq (p[0], "management") && p[1] && p[2] && !p[4])
{
- int port = 0;
-
VERIFY_PERMISSION (OPT_P_GENERAL);
if (streq (p[2], "unix"))
{
@@ -4303,104 +4476,93 @@ add_option (struct options *options,
goto err;
#endif
}
- else
- {
- port = atoi (p[2]);
- if (!legal_ipv4_port (port))
- {
- msg (msglevel, "port number associated with --management directive is out of range");
- goto err;
- }
- }
options->management_addr = p[1];
- options->management_port = port;
+ options->management_port = p[2];
if (p[3])
{
options->management_user_pass = p[3];
}
}
- else if (streq (p[0], "management-client-user") && p[1])
+ else if (streq (p[0], "management-client-user") && p[1] && !p[2])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->management_client_user = p[1];
}
- else if (streq (p[0], "management-client-group") && p[1])
+ else if (streq (p[0], "management-client-group") && p[1] && !p[2])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->management_client_group = p[1];
}
- else if (streq (p[0], "management-query-passwords"))
+ else if (streq (p[0], "management-query-passwords") && !p[1])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->management_flags |= MF_QUERY_PASSWORDS;
}
- else if (streq (p[0], "management-query-remote"))
+ else if (streq (p[0], "management-query-remote") && !p[1])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->management_flags |= MF_QUERY_REMOTE;
}
- else if (streq (p[0], "management-query-proxy"))
+ else if (streq (p[0], "management-query-proxy") && !p[1])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->management_flags |= MF_QUERY_PROXY;
- options->force_connection_list = true;
}
- else if (streq (p[0], "management-hold"))
+ else if (streq (p[0], "management-hold") && !p[1])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->management_flags |= MF_HOLD;
}
- else if (streq (p[0], "management-signal"))
+ else if (streq (p[0], "management-signal") && !p[1])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->management_flags |= MF_SIGNAL;
}
- else if (streq (p[0], "management-forget-disconnect"))
+ else if (streq (p[0], "management-forget-disconnect") && !p[1])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->management_flags |= MF_FORGET_DISCONNECT;
}
- else if (streq (p[0], "management-up-down"))
+ else if (streq (p[0], "management-up-down") && !p[1])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->management_flags |= MF_UP_DOWN;
}
- else if (streq (p[0], "management-client"))
+ else if (streq (p[0], "management-client") && !p[2])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->management_flags |= MF_CONNECT_AS_CLIENT;
options->management_write_peer_info_file = p[1];
}
#ifdef MANAGMENT_EXTERNAL_KEY
- else if (streq (p[0], "management-external-key"))
+ else if (streq (p[0], "management-external-key") && !p[1])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->management_flags |= MF_EXTERNAL_KEY;
}
-#endif
-#ifdef MANAGEMENT_DEF_AUTH
- else if (streq (p[0], "management-client-auth"))
+ else if (streq (p[0], "management-external-cert") && p[1] && !p[2])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
- options->management_flags |= MF_CLIENT_AUTH;
+ options->management_flags |= MF_EXTERNAL_CERT;
+ options->management_certificate = p[1];
}
#endif
-#ifdef ENABLE_X509_TRACK
- else if (streq (p[0], "x509-track") && p[1])
+#ifdef MANAGEMENT_DEF_AUTH
+ else if (streq (p[0], "management-client-auth") && !p[1])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
- x509_track_add (&options->x509_track, p[1], msglevel, &options->gc);
+ options->management_flags |= MF_CLIENT_AUTH;
}
#endif
#ifdef MANAGEMENT_PF
- else if (streq (p[0], "management-client-pf"))
+ else if (streq (p[0], "management-client-pf") && !p[1])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->management_flags |= (MF_CLIENT_PF | MF_CLIENT_AUTH);
}
#endif
- else if (streq (p[0], "management-log-cache") && p[1])
+ else if (streq (p[0], "management-log-cache") && p[1] && !p[2])
{
int cache;
@@ -4415,7 +4577,7 @@ add_option (struct options *options,
}
#endif
#ifdef ENABLE_PLUGIN
- else if (streq (p[0], "plugin") && p[1])
+ else if (streq (p[0], "plugin") && p[1] && !p[3])
{
VERIFY_PERMISSION (OPT_P_PLUGIN);
if (!options->plugin_list)
@@ -4427,7 +4589,7 @@ add_option (struct options *options,
}
}
#endif
- else if (streq (p[0], "mode") && p[1])
+ else if (streq (p[0], "mode") && p[1] && !p[2])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
if (streq (p[1], "p2p"))
@@ -4442,22 +4604,22 @@ add_option (struct options *options,
goto err;
}
}
- else if (streq (p[0], "dev") && p[1])
+ else if (streq (p[0], "dev") && p[1] && !p[2])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->dev = p[1];
}
- else if (streq (p[0], "dev-type") && p[1])
+ else if (streq (p[0], "dev-type") && p[1] && !p[2])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->dev_type = p[1];
}
- else if (streq (p[0], "dev-node") && p[1])
+ else if (streq (p[0], "dev-node") && p[1] && !p[2])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->dev_node = p[1];
}
- else if (streq (p[0], "lladdr") && p[1])
+ else if (streq (p[0], "lladdr") && p[1] && !p[2])
{
VERIFY_PERMISSION (OPT_P_UP);
if (mac_addr_safe (p[1])) /* MAC address only */
@@ -4468,24 +4630,24 @@ add_option (struct options *options,
goto err;
}
}
- else if (streq (p[0], "topology") && p[1])
+ else if (streq (p[0], "topology") && p[1] && !p[2])
{
VERIFY_PERMISSION (OPT_P_UP);
options->topology = parse_topology (p[1], msglevel);
}
- else if (streq (p[0], "tun-ipv6"))
+ else if (streq (p[0], "tun-ipv6") && !p[1])
{
VERIFY_PERMISSION (OPT_P_UP);
- options->tun_ipv6 = true;
+ msg (M_WARN, "Note: option tun-ipv6 is ignored because modern operating systems do not need special IPv6 tun handling anymore.");
}
#ifdef ENABLE_IPROUTE
- else if (streq (p[0], "iproute") && p[1])
+ else if (streq (p[0], "iproute") && p[1] && !p[2])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
iproute_path = p[1];
}
#endif
- else if (streq (p[0], "ifconfig") && p[1] && p[2])
+ else if (streq (p[0], "ifconfig") && p[1] && p[2] && !p[3])
{
VERIFY_PERMISSION (OPT_P_UP);
if (ip_or_dns_addr_safe (p[1], options->allow_pull_fqdn) && ip_or_dns_addr_safe (p[2], options->allow_pull_fqdn)) /* FQDN -- may be DNS name */
@@ -4499,7 +4661,7 @@ add_option (struct options *options,
goto err;
}
}
- else if (streq (p[0], "ifconfig-ipv6") && p[1] && p[2] )
+ else if (streq (p[0], "ifconfig-ipv6") && p[1] && p[2] && !p[3])
{
unsigned int netbits;
@@ -4523,27 +4685,27 @@ add_option (struct options *options,
goto err;
}
}
- else if (streq (p[0], "ifconfig-noexec"))
+ else if (streq (p[0], "ifconfig-noexec") && !p[1])
{
VERIFY_PERMISSION (OPT_P_UP);
options->ifconfig_noexec = true;
}
- else if (streq (p[0], "ifconfig-nowarn"))
+ else if (streq (p[0], "ifconfig-nowarn") && !p[1])
{
VERIFY_PERMISSION (OPT_P_UP);
options->ifconfig_nowarn = true;
}
- else if (streq (p[0], "local") && p[1])
+ else if (streq (p[0], "local") && p[1] && !p[2])
{
VERIFY_PERMISSION (OPT_P_GENERAL|OPT_P_CONNECTION);
options->ce.local = p[1];
}
- else if (streq (p[0], "remote-random"))
+ else if (streq (p[0], "remote-random") && !p[1])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->remote_random = true;
}
- else if (streq (p[0], "connection") && p[1])
+ else if (streq (p[0], "connection") && p[1] && !p[3])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
if (streq (p[1], INLINE_FILE_TAG) && p[2])
@@ -4605,47 +4767,38 @@ add_option (struct options *options,
options->ignore_unknown_option[i] = NULL;
}
- else if (streq (p[0], "remote-ip-hint") && p[1])
- {
- VERIFY_PERMISSION (OPT_P_GENERAL);
- options->remote_ip_hint = p[1];
- }
-#if HTTP_PROXY_OVERRIDE
- else if (streq (p[0], "http-proxy-override") && p[1] && p[2])
+#if ENABLE_MANAGEMENT
+ else if (streq (p[0], "http-proxy-override") && p[1] && p[2] && !p[4])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->http_proxy_override = parse_http_proxy_override(p[1], p[2], p[3], msglevel, &options->gc);
if (!options->http_proxy_override)
goto err;
- options->force_connection_list = true;
}
#endif
- else if (streq (p[0], "remote") && p[1])
+ else if (streq (p[0], "remote") && p[1] && !p[4])
{
struct remote_entry re;
- re.remote = NULL;
- re.remote_port = re.proto = -1;
+ re.remote = re.remote_port= NULL;
+ re.proto = -1;
+ re.af=0;
VERIFY_PERMISSION (OPT_P_GENERAL|OPT_P_CONNECTION);
re.remote = p[1];
if (p[2])
{
- const int port = atoi (p[2]);
- if (!legal_ipv4_port (port))
- {
- msg (msglevel, "remote: port number associated with host %s is out of range", p[1]);
- goto err;
- }
- re.remote_port = port;
+ re.remote_port = p[2];
if (p[3])
{
const int proto = ascii2proto (p[3]);
+ 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]);
goto err;
}
re.proto = proto;
+ re.af = af;
}
}
if (permission_mask & OPT_P_GENERAL)
@@ -4660,7 +4813,7 @@ add_option (struct options *options,
connection_entry_load_re (&options->ce, &re);
}
}
- else if (streq (p[0], "resolv-retry") && p[1])
+ else if (streq (p[0], "resolv-retry") && p[1] && !p[2])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
if (streq (p[1], "infinite"))
@@ -4668,22 +4821,44 @@ add_option (struct options *options,
else
options->resolve_retry_seconds = positive_atoi (p[1]);
}
- else if (streq (p[0], "connect-retry") && p[1])
+ else if ((streq (p[0], "preresolve") || streq (p[0], "ip-remote-hint")) && !p[2])
+ {
+ VERIFY_PERMISSION (OPT_P_GENERAL);
+ options->resolve_in_advance = true;
+ /* Note the ip-remote-hint and the argument p[1] are for
+ backward compatibility */
+ if (p[1])
+ options->ip_remote_hint=p[1];
+ }
+ else if (streq (p[0], "connect-retry") && p[1] && !p[3])
{
VERIFY_PERMISSION (OPT_P_GENERAL|OPT_P_CONNECTION);
options->ce.connect_retry_seconds = positive_atoi (p[1]);
- options->ce.connect_retry_defined = true;
+ /*
+ * Limit the base value of retry wait interval to 16 bits to avoid
+ * overflow when scaled up for exponential backoff
+ */
+ if (options->ce.connect_retry_seconds > 0xFFFF)
+ {
+ options->ce.connect_retry_seconds = 0xFFFF;
+ msg (M_WARN, "connect retry wait interval truncated to %d",
+ options->ce.connect_retry_seconds);
+ }
+
+ if (p[2])
+ options->ce.connect_retry_seconds_max =
+ max_int (positive_atoi (p[2]), options->ce.connect_retry_seconds);
}
- else if (streq (p[0], "connect-timeout") && p[1])
+ else if ((streq (p[0], "connect-timeout") || streq (p[0], "server-poll-timeout"))
+ && p[1] && !p[2])
{
VERIFY_PERMISSION (OPT_P_GENERAL|OPT_P_CONNECTION);
options->ce.connect_timeout = positive_atoi (p[1]);
- options->ce.connect_timeout_defined = true;
}
- else if (streq (p[0], "connect-retry-max") && p[1])
+ else if (streq (p[0], "connect-retry-max") && p[1] && !p[2])
{
VERIFY_PERMISSION (OPT_P_GENERAL|OPT_P_CONNECTION);
- options->ce.connect_retry_max = positive_atoi (p[1]);
+ options->connect_retry_max = positive_atoi (p[1]);
}
else if (streq (p[0], "ipchange") && p[1])
{
@@ -4695,24 +4870,24 @@ add_option (struct options *options,
string_substitute (p[1], ',', ' ', &options->gc),
"ipchange", true);
}
- else if (streq (p[0], "float"))
+ else if (streq (p[0], "float") && !p[1])
{
VERIFY_PERMISSION (OPT_P_GENERAL|OPT_P_CONNECTION);
options->ce.remote_float = true;
}
#ifdef ENABLE_DEBUG
- else if (streq (p[0], "gremlin") && p[1])
+ else if (streq (p[0], "gremlin") && p[1] && !p[2])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->gremlin = positive_atoi (p[1]);
}
#endif
- else if (streq (p[0], "chroot") && p[1])
+ else if (streq (p[0], "chroot") && p[1] && !p[2])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->chroot_dir = p[1];
}
- else if (streq (p[0], "cd") && p[1])
+ else if (streq (p[0], "cd") && p[1] && !p[2])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
if (platform_chdir (p[1]))
@@ -4723,13 +4898,13 @@ add_option (struct options *options,
options->cd_dir = p[1];
}
#ifdef ENABLE_SELINUX
- else if (streq (p[0], "setcon") && p[1])
+ else if (streq (p[0], "setcon") && p[1] && !p[2])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->selinux_context = p[1];
}
#endif
- else if (streq (p[0], "writepid") && p[1])
+ else if (streq (p[0], "writepid") && p[1] && !p[2])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->writepid = p[1];
@@ -4748,27 +4923,27 @@ add_option (struct options *options,
goto err;
set_user_script (options, &options->down_script, p[1], "down", true);
}
- else if (streq (p[0], "down-pre"))
+ else if (streq (p[0], "down-pre") && !p[1])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->down_pre = true;
}
- else if (streq (p[0], "up-delay"))
+ else if (streq (p[0], "up-delay") && !p[1])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->up_delay = true;
}
- else if (streq (p[0], "up-restart"))
+ else if (streq (p[0], "up-restart") && !p[1])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->up_restart = true;
}
- else if (streq (p[0], "syslog"))
+ else if (streq (p[0], "syslog") && !p[2])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
open_syslog (p[1], false);
}
- else if (streq (p[0], "daemon"))
+ else if (streq (p[0], "daemon") && !p[2])
{
bool didit = false;
VERIFY_PERMISSION (OPT_P_GENERAL);
@@ -4786,7 +4961,7 @@ add_option (struct options *options,
}
}
}
- else if (streq (p[0], "inetd"))
+ else if (streq (p[0], "inetd") && !p[3])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
if (!options->inetd)
@@ -4841,44 +5016,50 @@ add_option (struct options *options,
open_syslog (name, true);
}
}
- else if (streq (p[0], "log") && p[1])
+ else if (streq (p[0], "log") && p[1] && !p[2])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->log = true;
redirect_stdout_stderr (p[1], false);
}
- else if (streq (p[0], "suppress-timestamps"))
+ else if (streq (p[0], "suppress-timestamps") && !p[1])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->suppress_timestamps = true;
set_suppress_timestamps(true);
}
- else if (streq (p[0], "log-append") && p[1])
+ else if (streq (p[0], "machine-readable-output") && !p[1])
+ {
+ VERIFY_PERMISSION (OPT_P_GENERAL);
+ options->machine_readable_output = true;
+ set_machine_readable_output(true);
+ }
+ else if (streq (p[0], "log-append") && p[1] && !p[2])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->log = true;
redirect_stdout_stderr (p[1], true);
}
#ifdef ENABLE_MEMSTATS
- else if (streq (p[0], "memstats") && p[1])
+ else if (streq (p[0], "memstats") && p[1] && !p[2])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->memstats_fn = p[1];
}
#endif
- else if (streq (p[0], "mlock"))
+ else if (streq (p[0], "mlock") && !p[1])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->mlock = true;
}
#if ENABLE_IP_PKTINFO
- else if (streq (p[0], "multihome"))
+ else if (streq (p[0], "multihome") && !p[1])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->sockflags |= SF_USE_IP_PKTINFO;
}
#endif
- else if (streq (p[0], "verb") && p[1])
+ else if (streq (p[0], "verb") && p[1] && !p[2])
{
VERIFY_PERMISSION (OPT_P_MESSAGES);
options->verbosity = positive_atoi (p[1]);
@@ -4889,17 +5070,17 @@ add_option (struct options *options,
options->verbosity);
#endif
}
- else if (streq (p[0], "mute") && p[1])
+ else if (streq (p[0], "mute") && p[1] && !p[2])
{
VERIFY_PERMISSION (OPT_P_MESSAGES);
options->mute = positive_atoi (p[1]);
}
- else if (streq (p[0], "errors-to-stderr"))
+ else if (streq (p[0], "errors-to-stderr") && !p[1])
{
VERIFY_PERMISSION (OPT_P_MESSAGES);
errors_to_stderr();
}
- else if (streq (p[0], "status") && p[1])
+ else if (streq (p[0], "status") && p[1] && !p[3])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->status_file = p[1];
@@ -4908,7 +5089,7 @@ add_option (struct options *options,
options->status_file_update_freq = positive_atoi (p[2]);
}
}
- else if (streq (p[0], "status-version") && p[1])
+ else if (streq (p[0], "status-version") && p[1] && !p[2])
{
int version;
@@ -4921,7 +5102,7 @@ add_option (struct options *options,
}
options->status_file_version = version;
}
- else if (streq (p[0], "remap-usr1") && p[1])
+ else if (streq (p[0], "remap-usr1") && p[1] && !p[2])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
if (streq (p[1], "SIGHUP"))
@@ -4934,19 +5115,19 @@ add_option (struct options *options,
goto err;
}
}
- else if ((streq (p[0], "link-mtu") || streq (p[0], "udp-mtu")) && p[1])
+ else if ((streq (p[0], "link-mtu") || streq (p[0], "udp-mtu")) && p[1] && !p[2])
{
VERIFY_PERMISSION (OPT_P_MTU|OPT_P_CONNECTION);
options->ce.link_mtu = positive_atoi (p[1]);
options->ce.link_mtu_defined = true;
}
- else if (streq (p[0], "tun-mtu") && p[1])
+ else if (streq (p[0], "tun-mtu") && p[1] && !p[2])
{
VERIFY_PERMISSION (OPT_P_MTU|OPT_P_CONNECTION);
options->ce.tun_mtu = positive_atoi (p[1]);
options->ce.tun_mtu_defined = true;
}
- else if (streq (p[0], "tun-mtu-extra") && p[1])
+ else if (streq (p[0], "tun-mtu-extra") && p[1] && !p[2])
{
VERIFY_PERMISSION (OPT_P_MTU|OPT_P_CONNECTION);
options->ce.tun_mtu_extra = positive_atoi (p[1]);
@@ -4959,41 +5140,41 @@ add_option (struct options *options,
msg (msglevel, "--mtu-dynamic has been replaced by --fragment");
goto err;
}
- else if (streq (p[0], "fragment") && p[1])
+ else if (streq (p[0], "fragment") && p[1] && !p[2])
{
/* VERIFY_PERMISSION (OPT_P_MTU); */
VERIFY_PERMISSION (OPT_P_MTU|OPT_P_CONNECTION);
options->ce.fragment = positive_atoi (p[1]);
}
#endif
- else if (streq (p[0], "mtu-disc") && p[1])
+ else if (streq (p[0], "mtu-disc") && p[1] && !p[2])
{
VERIFY_PERMISSION (OPT_P_MTU|OPT_P_CONNECTION);
options->ce.mtu_discover_type = translate_mtu_discover_type_name (p[1]);
}
#ifdef ENABLE_OCC
- else if (streq (p[0], "mtu-test"))
+ else if (streq (p[0], "mtu-test") && !p[1])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->mtu_test = true;
}
#endif
- else if (streq (p[0], "nice") && p[1])
+ else if (streq (p[0], "nice") && p[1] && !p[2])
{
VERIFY_PERMISSION (OPT_P_NICE);
options->nice = atoi (p[1]);
}
- else if (streq (p[0], "rcvbuf") && p[1])
+ else if (streq (p[0], "rcvbuf") && p[1] && !p[2])
{
VERIFY_PERMISSION (OPT_P_SOCKBUF);
options->rcvbuf = positive_atoi (p[1]);
}
- else if (streq (p[0], "sndbuf") && p[1])
+ else if (streq (p[0], "sndbuf") && p[1] && !p[2])
{
VERIFY_PERMISSION (OPT_P_SOCKBUF);
options->sndbuf = positive_atoi (p[1]);
}
- else if (streq (p[0], "mark") && p[1])
+ else if (streq (p[0], "mark") && p[1] && !p[2])
{
#if defined(TARGET_LINUX) && HAVE_DECL_SO_MARK
VERIFY_PERMISSION (OPT_P_GENERAL);
@@ -5012,7 +5193,7 @@ add_option (struct options *options,
msg (msglevel, "unknown socket flag: %s", p[j]);
}
}
- else if (streq (p[0], "txqueuelen") && p[1])
+ else if (streq (p[0], "txqueuelen") && p[1] && !p[2])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
#ifdef TARGET_LINUX
@@ -5022,7 +5203,7 @@ add_option (struct options *options,
goto err;
#endif
}
- else if (streq (p[0], "shaper") && p[1])
+ else if (streq (p[0], "shaper") && p[1] && !p[2])
{
#ifdef ENABLE_FEATURE_SHAPER
int shaper;
@@ -5042,73 +5223,54 @@ add_option (struct options *options,
goto err;
#endif /* ENABLE_FEATURE_SHAPER */
}
- else if (streq (p[0], "port") && p[1])
+ else if (streq (p[0], "port") && p[1] && !p[2])
{
- int port;
-
VERIFY_PERMISSION (OPT_P_GENERAL|OPT_P_CONNECTION);
- port = atoi (p[1]);
- if (!legal_ipv4_port (port))
- {
- msg (msglevel, "Bad port number: %s", p[1]);
- goto err;
- }
- options->ce.local_port = options->ce.remote_port = port;
+ options->ce.local_port = options->ce.remote_port = p[1];
}
- else if (streq (p[0], "lport") && p[1])
+ else if (streq (p[0], "lport") && p[1] && !p[2])
{
- int port;
-
VERIFY_PERMISSION (OPT_P_GENERAL|OPT_P_CONNECTION);
- port = atoi (p[1]);
- if ((port != 0) && !legal_ipv4_port (port))
- {
- msg (msglevel, "Bad local port number: %s", p[1]);
- goto err;
- }
options->ce.local_port_defined = true;
- options->ce.local_port = port;
+ options->ce.local_port = p[1];
}
- else if (streq (p[0], "rport") && p[1])
+ else if (streq (p[0], "rport") && p[1] && !p[2])
{
- int port;
-
VERIFY_PERMISSION (OPT_P_GENERAL|OPT_P_CONNECTION);
- port = atoi (p[1]);
- if (!legal_ipv4_port (port))
- {
- msg (msglevel, "Bad remote port number: %s", p[1]);
- goto err;
- }
- options->ce.remote_port = port;
+ options->ce.remote_port = p[1];
}
- else if (streq (p[0], "bind"))
+ else if (streq (p[0], "bind") && !p[1])
{
VERIFY_PERMISSION (OPT_P_GENERAL|OPT_P_CONNECTION);
options->ce.bind_defined = true;
+ if (p[1] && streq (p[1], "ipv6only"))
+ options->ce.bind_ipv6_only=true;
+
}
- else if (streq (p[0], "nobind"))
+ else if (streq (p[0], "nobind") && !p[1])
{
VERIFY_PERMISSION (OPT_P_GENERAL|OPT_P_CONNECTION);
options->ce.bind_local = false;
}
- else if (streq (p[0], "fast-io"))
+ else if (streq (p[0], "fast-io") && !p[1])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->fast_io = true;
}
- else if (streq (p[0], "inactive") && p[1])
+ else if (streq (p[0], "inactive") && p[1] && !p[3])
{
VERIFY_PERMISSION (OPT_P_TIMER);
options->inactivity_timeout = positive_atoi (p[1]);
if (p[2])
options->inactivity_minimum_bytes = positive_atoi (p[2]);
}
- else if (streq (p[0], "proto") && p[1])
+ else if (streq (p[0], "proto") && p[1] && !p[2])
{
int proto;
+ sa_family_t af;
VERIFY_PERMISSION (OPT_P_GENERAL|OPT_P_CONNECTION);
proto = ascii2proto (p[1]);
+ af = ascii2af(p[1]);
if (proto < 0)
{
msg (msglevel, "Bad protocol: '%s'. Allowed protocols with --proto option: %s",
@@ -5117,8 +5279,9 @@ add_option (struct options *options,
goto err;
}
options->ce.proto = proto;
+ options->ce.af = af;
}
- else if (streq (p[0], "proto-force") && p[1])
+ else if (streq (p[0], "proto-force") && p[1] && !p[2])
{
int proto_force;
VERIFY_PERMISSION (OPT_P_GENERAL);
@@ -5129,33 +5292,24 @@ add_option (struct options *options,
goto err;
}
options->proto_force = proto_force;
- options->force_connection_list = true;
}
-#ifdef ENABLE_HTTP_PROXY
- else if (streq (p[0], "http-proxy") && p[1])
+ else if (streq (p[0], "http-proxy") && p[1] && !p[5])
{
struct http_proxy_options *ho;
VERIFY_PERMISSION (OPT_P_GENERAL|OPT_P_CONNECTION);
{
- int port;
if (!p[2])
{
msg (msglevel, "http-proxy port number not defined");
goto err;
}
- port = atoi (p[2]);
- if (!legal_ipv4_port (port))
- {
- msg (msglevel, "Bad http-proxy port number: %s", p[2]);
- goto err;
- }
ho = init_http_proxy_options_once (&options->ce.http_proxy_options, &options->gc);
ho->server = p[1];
- ho->port = port;
+ ho->port = p[2];
}
if (p[3])
@@ -5183,101 +5337,124 @@ add_option (struct options *options,
ho->auth_method_string = "none";
}
}
- else if (streq (p[0], "http-proxy-retry"))
+ else if (streq (p[0], "http-proxy-user-pass") && p[1])
{
struct http_proxy_options *ho;
- VERIFY_PERMISSION (OPT_P_GENERAL|OPT_P_CONNECTION);
+ VERIFY_PERMISSION (OPT_P_GENERAL);
ho = init_http_proxy_options_once (&options->ce.http_proxy_options, &options->gc);
- ho->retry = true;
+ if (streq (p[1], INLINE_FILE_TAG) && p[2])
+ {
+ ho->auth_file = p[2];
+ ho->inline_creds = true;
+ }
+ else
+ ho->auth_file = p[1];
}
- else if (streq (p[0], "http-proxy-timeout") && p[1])
+ else if (streq (p[0], "http-proxy-retry") || streq (p[0], "socks-proxy-retry"))
{
- struct http_proxy_options *ho;
-
VERIFY_PERMISSION (OPT_P_GENERAL|OPT_P_CONNECTION);
- ho = init_http_proxy_options_once (&options->ce.http_proxy_options, &options->gc);
- ho->timeout = positive_atoi (p[1]);
+ msg (M_WARN, "DEPRECATED OPTION: http-proxy-retry and socks-proxy-retry: "
+ "In OpenVPN 2.4 proxy connection retries are handled like regular connections. "
+ "Use connect-retry-max 1 to get a similar behavior as before.");
}
- else if (streq (p[0], "http-proxy-option") && p[1])
+ else if (streq (p[0], "http-proxy-timeout") && p[1] && !p[2])
+ {
+ VERIFY_PERMISSION (OPT_P_GENERAL|OPT_P_CONNECTION);
+ msg (M_WARN, "DEPRECATED OPTION: http-proxy-timeout: In OpenVPN 2.4 the timeout until a connection to a "
+ "server is established is managed with a single timeout set by connect-timeout");
+ }
+ else if (streq (p[0], "http-proxy-option") && p[1] && !p[4])
{
struct http_proxy_options *ho;
VERIFY_PERMISSION (OPT_P_GENERAL|OPT_P_CONNECTION);
ho = init_http_proxy_options_once (&options->ce.http_proxy_options, &options->gc);
- if (streq (p[1], "VERSION") && p[2])
+ if (streq (p[1], "VERSION") && p[2] && !p[3])
{
ho->http_version = p[2];
}
- else if (streq (p[1], "AGENT") && p[2])
+ else if (streq (p[1], "AGENT") && p[2] && !p[3])
{
ho->user_agent = p[2];
}
+ else if ((streq (p[1], "EXT1") || streq(p[1], "EXT2") || streq(p[1], "CUSTOM-HEADER"))
+ && p[2])
+ {
+ /* In the wild patched versions use both EXT1/2 and CUSTOM-HEADER
+ * with either two argument or one */
+
+ struct http_custom_header *custom_header = NULL;
+ int i;
+ /* Find the first free header */
+ for (i=0; i < MAX_CUSTOM_HTTP_HEADER; i++) {
+ if (!ho->custom_headers[i].name) {
+ custom_header = &ho->custom_headers[i];
+ break;
+ }
+ }
+ if (!custom_header)
+ {
+ msg (msglevel, "Cannot use more than %d http-proxy-option CUSTOM-HEADER : '%s'", MAX_CUSTOM_HTTP_HEADER, p[1]);
+ }
+ else
+ {
+ /* We will save p[2] and p[3], the proxy code will detect if
+ * p[3] is NULL */
+ custom_header->name = p[2];
+ custom_header->content = p[3];
+ }
+ }
else
{
- msg (msglevel, "Bad http-proxy-option or missing parameter: '%s'", p[1]);
+ msg (msglevel, "Bad http-proxy-option or missing or extra parameter: '%s'", p[1]);
}
}
-#endif
-#ifdef ENABLE_SOCKS
- else if (streq (p[0], "socks-proxy") && p[1])
+ else if (streq (p[0], "socks-proxy") && p[1] && !p[4])
{
VERIFY_PERMISSION (OPT_P_GENERAL|OPT_P_CONNECTION);
if (p[2])
- {
- int port;
- port = atoi (p[2]);
- if (!legal_ipv4_port (port))
- {
- msg (msglevel, "Bad socks-proxy port number: %s", p[2]);
- goto err;
- }
- options->ce.socks_proxy_port = port;
+ {
+ options->ce.socks_proxy_port = p[2];
}
else
{
- options->ce.socks_proxy_port = 1080;
+ options->ce.socks_proxy_port = "1080";
}
options->ce.socks_proxy_server = p[1];
options->ce.socks_proxy_authfile = p[3]; /* might be NULL */
}
- else if (streq (p[0], "socks-proxy-retry"))
- {
- VERIFY_PERMISSION (OPT_P_GENERAL|OPT_P_CONNECTION);
- options->ce.socks_proxy_retry = true;
- }
-#endif
- else if (streq (p[0], "keepalive") && p[1] && p[2])
+ else if (streq (p[0], "keepalive") && p[1] && p[2] && !p[3])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->keepalive_ping = atoi (p[1]);
options->keepalive_timeout = atoi (p[2]);
}
- else if (streq (p[0], "ping") && p[1])
+ else if (streq (p[0], "ping") && p[1] && !p[2])
{
VERIFY_PERMISSION (OPT_P_TIMER);
options->ping_send_timeout = positive_atoi (p[1]);
}
- else if (streq (p[0], "ping-exit") && p[1])
+ else if (streq (p[0], "ping-exit") && p[1] && !p[2])
{
VERIFY_PERMISSION (OPT_P_TIMER);
options->ping_rec_timeout = positive_atoi (p[1]);
options->ping_rec_timeout_action = PING_EXIT;
}
- else if (streq (p[0], "ping-restart") && p[1])
+ else if (streq (p[0], "ping-restart") && p[1] && !p[2])
{
VERIFY_PERMISSION (OPT_P_TIMER);
options->ping_rec_timeout = positive_atoi (p[1]);
options->ping_rec_timeout_action = PING_RESTART;
}
- else if (streq (p[0], "ping-timer-rem"))
+ else if (streq (p[0], "ping-timer-rem") && !p[1])
{
VERIFY_PERMISSION (OPT_P_TIMER);
options->ping_timer_remote = true;
}
#ifdef ENABLE_OCC
- else if (streq (p[0], "explicit-exit-notify"))
+ else if (streq (p[0], "explicit-exit-notify") && !p[2])
{
VERIFY_PERMISSION (OPT_P_GENERAL|OPT_P_CONNECTION|OPT_P_EXPLICIT_NOTIFY);
if (p[1])
@@ -5290,35 +5467,33 @@ add_option (struct options *options,
}
}
#endif
- else if (streq (p[0], "persist-tun"))
+ else if (streq (p[0], "persist-tun") && !p[1])
{
VERIFY_PERMISSION (OPT_P_PERSIST);
options->persist_tun = true;
}
- else if (streq (p[0], "persist-key"))
+ else if (streq (p[0], "persist-key") && !p[1])
{
VERIFY_PERMISSION (OPT_P_PERSIST);
options->persist_key = true;
}
- else if (streq (p[0], "persist-local-ip"))
+ else if (streq (p[0], "persist-local-ip") && !p[1])
{
VERIFY_PERMISSION (OPT_P_PERSIST_IP);
options->persist_local_ip = true;
}
- else if (streq (p[0], "persist-remote-ip"))
+ else if (streq (p[0], "persist-remote-ip") && !p[1])
{
VERIFY_PERMISSION (OPT_P_PERSIST_IP);
options->persist_remote_ip = true;
}
-#ifdef ENABLE_CLIENT_NAT
- else if (streq (p[0], "client-nat") && p[1] && p[2] && p[3] && p[4])
+ else if (streq (p[0], "client-nat") && p[1] && p[2] && p[3] && p[4] && !p[5])
{
VERIFY_PERMISSION (OPT_P_ROUTE);
cnol_check_alloc (options);
add_client_nat_to_option_list(options->client_nat, p[1], p[2], p[3], p[4], msglevel);
}
-#endif
- else if (streq (p[0], "route") && p[1])
+ else if (streq (p[0], "route") && p[1] && !p[5])
{
VERIFY_PERMISSION (OPT_P_ROUTE);
rol_check_alloc (options);
@@ -5342,7 +5517,7 @@ add_option (struct options *options,
}
add_route_to_option_list (options->routes, p[1], p[2], p[3], p[4]);
}
- else if (streq (p[0], "route-ipv6") && p[1])
+ else if (streq (p[0], "route-ipv6") && p[1] && !p[4])
{
VERIFY_PERMISSION (OPT_P_ROUTE);
rol6_check_alloc (options);
@@ -5362,25 +5537,14 @@ add_option (struct options *options,
}
add_route_ipv6_to_option_list (options->routes_ipv6, p[1], p[2], p[3]);
}
- else if (streq (p[0], "max-routes") && p[1])
+ else if (streq (p[0], "max-routes") && !p[2])
{
- int max_routes;
-
- VERIFY_PERMISSION (OPT_P_GENERAL);
- max_routes = atoi (p[1]);
- if (max_routes < 0 || max_routes > 100000000)
- {
- msg (msglevel, "--max-routes parameter is out of range");
- goto err;
- }
- if (options->routes || options->routes_ipv6)
- {
- msg (msglevel, "--max-routes must to be specifed before any route/route-ipv6/redirect-gateway option");
- goto err;
- }
- options->max_routes = max_routes;
+ msg (M_WARN, "DEPRECATED OPTION: --max-routes option ignored."
+ "The number of routes is unlimited as of version 2.4. "
+ "This option will be removed in a future version, "
+ "please remove it from your configuration.");
}
- else if (streq (p[0], "route-gateway") && p[1])
+ else if (streq (p[0], "route-gateway") && p[1] && !p[2])
{
VERIFY_PERMISSION (OPT_P_ROUTE_EXTRAS);
if (streq (p[1], "dhcp"))
@@ -5400,12 +5564,12 @@ add_option (struct options *options,
}
}
}
- else if (streq (p[0], "route-metric") && p[1])
+ else if (streq (p[0], "route-metric") && p[1] && !p[2])
{
VERIFY_PERMISSION (OPT_P_ROUTE);
options->route_default_metric = positive_atoi (p[1]);
}
- else if (streq (p[0], "route-delay"))
+ else if (streq (p[0], "route-delay") && !p[3])
{
VERIFY_PERMISSION (OPT_P_ROUTE_EXTRAS);
options->route_delay_defined = true;
@@ -5439,17 +5603,37 @@ add_option (struct options *options,
p[1],
"route-pre-down", true);
}
- else if (streq (p[0], "route-noexec"))
+ else if (streq (p[0], "route-noexec") && !p[1])
{
VERIFY_PERMISSION (OPT_P_SCRIPT);
options->route_noexec = true;
}
- else if (streq (p[0], "route-nopull"))
+ else if (streq (p[0], "route-nopull") && !p[1])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->route_nopull = true;
}
- else if (streq (p[0], "allow-pull-fqdn"))
+ else if (streq (p[0], "pull-filter") && p[1] && p[2] && !p[3])
+ {
+ struct pull_filter *f;
+ VERIFY_PERMISSION (OPT_P_GENERAL)
+ f = alloc_pull_filter (options, msglevel);
+
+ if (strcmp ("accept", p[1]) == 0)
+ f->type = PUF_TYPE_ACCEPT;
+ else if (strcmp ("ignore", p[1]) == 0)
+ f->type = PUF_TYPE_IGNORE;
+ else if (strcmp ("reject", p[1]) == 0)
+ f->type = PUF_TYPE_REJECT;
+ else
+ {
+ msg (msglevel, "Unknown --pull-filter type: %s", p[1]);
+ goto err;
+ }
+ f->pattern = p[2];
+ f->size = strlen(p[2]);
+ }
+ else if (streq (p[0], "allow-pull-fqdn") && !p[1])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->allow_pull_fqdn = true;
@@ -5475,6 +5659,13 @@ add_option (struct options *options,
options->routes->flags |= RG_BYPASS_DNS;
else if (streq (p[j], "block-local"))
options->routes->flags |= RG_BLOCK_LOCAL;
+ else if (streq (p[j], "ipv6"))
+ {
+ rol6_check_alloc (options);
+ options->routes_ipv6->flags |= RG_REROUTE_GW;
+ }
+ else if (streq (p[j], "!ipv4"))
+ options->routes->flags &= ~RG_REROUTE_GW;
else
{
msg (msglevel, "unknown --%s flag: %s", p[0], p[j]);
@@ -5483,15 +5674,15 @@ add_option (struct options *options,
}
options->routes->flags |= RG_ENABLE;
}
- else if (streq (p[0], "remote-random-hostname"))
+ else if (streq (p[0], "remote-random-hostname") && !p[1])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->sockflags |= SF_HOST_RANDOMIZE;
}
- else if (streq (p[0], "setenv") && p[1])
+ else if (streq (p[0], "setenv") && p[1] && !p[3])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
- if (streq (p[1], "REMOTE_RANDOM_HOSTNAME"))
+ if (streq (p[1], "REMOTE_RANDOM_HOSTNAME") && !p[2])
{
options->sockflags |= SF_HOST_RANDOMIZE;
}
@@ -5501,17 +5692,15 @@ add_option (struct options *options,
goto err;
}
#ifdef ENABLE_PUSH_PEER_INFO
- else if (streq (p[1], "PUSH_PEER_INFO"))
+ else if (streq (p[1], "PUSH_PEER_INFO") && !p[2])
{
options->push_peer_info = true;
}
#endif
-#if P2MP
else if (streq (p[1], "SERVER_POLL_TIMEOUT") && p[2])
{
- options->server_poll_timeout = positive_atoi(p[2]);
+ options->ce.connect_timeout = positive_atoi(p[2]);
}
-#endif
else
{
if (streq (p[1], "FORWARD_COMPATIBLE") && p[2] && streq (p[2], "1"))
@@ -5522,17 +5711,17 @@ add_option (struct options *options,
setenv_str (es, p[1], p[2] ? p[2] : "");
}
}
- else if (streq (p[0], "setenv-safe") && p[1])
+ else if (streq (p[0], "setenv-safe") && p[1] && !p[3])
{
VERIFY_PERMISSION (OPT_P_SETENV);
setenv_str_safe (es, p[1], p[2] ? p[2] : "");
}
- else if (streq (p[0], "script-security") && p[1])
+ else if (streq (p[0], "script-security") && p[1] && !p[2])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
script_security = atoi (p[1]);
}
- else if (streq (p[0], "mssfix"))
+ else if (streq (p[0], "mssfix") && !p[2])
{
VERIFY_PERMISSION (OPT_P_GENERAL|OPT_P_CONNECTION);
if (p[1])
@@ -5544,7 +5733,7 @@ add_option (struct options *options,
}
#ifdef ENABLE_OCC
- else if (streq (p[0], "disable-occ"))
+ else if (streq (p[0], "disable-occ") && !p[1])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->occ = false;
@@ -5552,7 +5741,7 @@ add_option (struct options *options,
#endif
#if P2MP
#if P2MP_SERVER
- else if (streq (p[0], "server") && p[1] && p[2])
+ else if (streq (p[0], "server") && p[1] && p[2] && !p[4])
{
const int lev = M_WARN;
bool error = false;
@@ -5581,7 +5770,7 @@ add_option (struct options *options,
}
}
}
- else if (streq (p[0], "server-ipv6") && p[1] )
+ else if (streq (p[0], "server-ipv6") && p[1] && !p[3])
{
const int lev = M_WARN;
struct in6_addr network;
@@ -5608,7 +5797,7 @@ add_option (struct options *options,
goto err;
}
}
- else if (streq (p[0], "server-bridge") && p[1] && p[2] && p[3] && p[4])
+ else if (streq (p[0], "server-bridge") && p[1] && p[2] && p[3] && p[4] && !p[5])
{
const int lev = M_WARN;
bool error = false;
@@ -5630,7 +5819,7 @@ add_option (struct options *options,
options->server_bridge_pool_start = pool_start;
options->server_bridge_pool_end = pool_end;
}
- else if (streq (p[0], "server-bridge") && p[1] && streq (p[1], "nogw"))
+ else if (streq (p[0], "server-bridge") && p[1] && streq (p[1], "nogw") && !p[2])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->server_bridge_proxy_dhcp = true;
@@ -5641,17 +5830,23 @@ add_option (struct options *options,
VERIFY_PERMISSION (OPT_P_GENERAL);
options->server_bridge_proxy_dhcp = true;
}
- else if (streq (p[0], "push") && p[1])
+ else if (streq (p[0], "push") && p[1] && !p[2])
{
VERIFY_PERMISSION (OPT_P_PUSH);
push_options (options, &p[1], msglevel, &options->gc);
}
- else if (streq (p[0], "push-reset"))
+ else if (streq (p[0], "push-reset") && !p[1])
{
VERIFY_PERMISSION (OPT_P_INSTANCE);
push_reset (options);
}
- else if (streq (p[0], "ifconfig-pool") && p[1] && p[2])
+ else if (streq (p[0], "push-remove") && p[1] && !p[2])
+ {
+ VERIFY_PERMISSION (OPT_P_INSTANCE);
+ msg (D_PUSH, "PUSH_REMOVE '%s'", p[1]);
+ push_remove_option (options,p[1]);
+ }
+ else if (streq (p[0], "ifconfig-pool") && p[1] && p[2] && !p[4])
{
const int lev = M_WARN;
bool error = false;
@@ -5678,7 +5873,7 @@ add_option (struct options *options,
if (netmask)
options->ifconfig_pool_netmask = netmask;
}
- else if (streq (p[0], "ifconfig-pool-persist") && p[1])
+ else if (streq (p[0], "ifconfig-pool-persist") && p[1] && !p[3])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->ifconfig_pool_persist_filename = p[1];
@@ -5687,12 +5882,12 @@ add_option (struct options *options,
options->ifconfig_pool_persist_refresh_freq = positive_atoi (p[2]);
}
}
- else if (streq (p[0], "ifconfig-pool-linear"))
+ else if (streq (p[0], "ifconfig-pool-linear") && !p[1])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->topology = TOP_P2P;
}
- else if (streq (p[0], "ifconfig-ipv6-pool") && p[1] )
+ else if (streq (p[0], "ifconfig-ipv6-pool") && p[1] && !p[2])
{
const int lev = M_WARN;
struct in6_addr network;
@@ -5714,7 +5909,7 @@ add_option (struct options *options,
options->ifconfig_ipv6_pool_base = network;
options->ifconfig_ipv6_pool_netbits = netbits;
}
- else if (streq (p[0], "hash-size") && p[1] && p[2])
+ else if (streq (p[0], "hash-size") && p[1] && p[2] && !p[3])
{
int real, virtual;
@@ -5729,7 +5924,7 @@ add_option (struct options *options,
options->real_hash_size = real;
options->virtual_hash_size = real;
}
- else if (streq (p[0], "connect-freq") && p[1] && p[2])
+ else if (streq (p[0], "connect-freq") && p[1] && p[2] && !p[3])
{
int cf_max, cf_per;
@@ -5744,7 +5939,7 @@ add_option (struct options *options,
options->cf_max = cf_max;
options->cf_per = cf_per;
}
- else if (streq (p[0], "max-clients") && p[1])
+ else if (streq (p[0], "max-clients") && p[1] && !p[2])
{
int max_clients;
@@ -5755,29 +5950,55 @@ add_option (struct options *options,
msg (msglevel, "--max-clients must be at least 1");
goto err;
}
+ if (max_clients >= MAX_PEER_ID) /* max peer-id value */
+ {
+ msg (msglevel, "--max-clients must be less than %d", MAX_PEER_ID);
+ goto err;
+ }
options->max_clients = max_clients;
}
- else if (streq (p[0], "max-routes-per-client") && p[1])
+ else if (streq (p[0], "max-routes-per-client") && p[1] && !p[2])
{
VERIFY_PERMISSION (OPT_P_INHERIT);
options->max_routes_per_client = max_int (atoi (p[1]), 1);
}
- else if (streq (p[0], "client-cert-not-required"))
+ else if (streq (p[0], "client-cert-not-required") && !p[1])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->ssl_flags |= SSLF_CLIENT_CERT_NOT_REQUIRED;
+ msg (M_WARN, "DEPRECATED OPTION: --client-cert-not-required, use --verify-client-cert instead");
+ }
+ else if (streq (p[0], "verify-client-cert") && !p[2])
+ {
+ VERIFY_PERMISSION (OPT_P_GENERAL);
+
+ /* Reset any existing flags */
+ options->ssl_flags &= ~SSLF_CLIENT_CERT_OPTIONAL;
+ options->ssl_flags &= ~SSLF_CLIENT_CERT_NOT_REQUIRED;
+ if (p[1])
+ {
+ if (streq (p[1], "none"))
+ options->ssl_flags |= SSLF_CLIENT_CERT_NOT_REQUIRED;
+ else if (streq (p[1], "optional"))
+ options->ssl_flags |= SSLF_CLIENT_CERT_OPTIONAL;
+ else if (!streq (p[1], "require"))
+ {
+ msg (msglevel, "parameter to --verify-client-cert must be 'none', 'optional' or 'require'");
+ goto err;
+ }
+ }
}
- else if (streq (p[0], "username-as-common-name"))
+ else if (streq (p[0], "username-as-common-name") && !p[1])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->ssl_flags |= SSLF_USERNAME_AS_COMMON_NAME;
}
- else if (streq (p[0], "auth-user-pass-optional"))
+ else if (streq (p[0], "auth-user-pass-optional") && !p[1])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->ssl_flags |= SSLF_AUTH_USER_PASS_OPTIONAL;
}
- else if (streq (p[0], "opt-verify"))
+ else if (streq (p[0], "opt-verify") && !p[1])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->ssl_flags |= SSLF_OPT_VERIFY;
@@ -5808,6 +6029,12 @@ add_option (struct options *options,
&options->auth_user_pass_verify_script,
p[1], "auth-user-pass-verify", true);
}
+ else if (streq (p[0], "auth-gen-token"))
+ {
+ VERIFY_PERMISSION (OPT_P_GENERAL);
+ options->auth_token_generate = true;
+ options->auth_token_lifetime = p[1] ? positive_atoi (p[1]) : 0;
+ }
else if (streq (p[0], "client-connect") && p[1])
{
VERIFY_PERMISSION (OPT_P_SCRIPT);
@@ -5832,22 +6059,22 @@ add_option (struct options *options,
set_user_script (options, &options->learn_address_script,
p[1], "learn-address", true);
}
- else if (streq (p[0], "tmp-dir") && p[1])
+ else if (streq (p[0], "tmp-dir") && p[1] && !p[2])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->tmp_dir = p[1];
}
- else if (streq (p[0], "client-config-dir") && p[1])
+ else if (streq (p[0], "client-config-dir") && p[1] && !p[2])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->client_config_dir = p[1];
}
- else if (streq (p[0], "ccd-exclusive"))
+ else if (streq (p[0], "ccd-exclusive") && !p[1])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->ccd_exclusive = true;
}
- else if (streq (p[0], "bcast-buffers") && p[1])
+ else if (streq (p[0], "bcast-buffers") && p[1] && !p[2])
{
int n_bcast_buf;
@@ -5857,7 +6084,7 @@ add_option (struct options *options,
msg (msglevel, "--bcast-buffers parameter must be > 0");
options->n_bcast_buf = n_bcast_buf;
}
- else if (streq (p[0], "tcp-queue-limit") && p[1])
+ else if (streq (p[0], "tcp-queue-limit") && p[1] && !p[2])
{
int tcp_queue_limit;
@@ -5868,34 +6095,25 @@ add_option (struct options *options,
options->tcp_queue_limit = tcp_queue_limit;
}
#if PORT_SHARE
- else if (streq (p[0], "port-share") && p[1] && p[2])
+ else if (streq (p[0], "port-share") && p[1] && p[2] && !p[4])
{
- int port;
-
VERIFY_PERMISSION (OPT_P_GENERAL);
- port = atoi (p[2]);
- if (!legal_ipv4_port (port))
- {
- msg (msglevel, "port number associated with --port-share directive is out of range");
- goto err;
- }
-
options->port_share_host = p[1];
- options->port_share_port = port;
+ options->port_share_port = p[2];
options->port_share_journal_dir = p[3];
}
#endif
- else if (streq (p[0], "client-to-client"))
+ else if (streq (p[0], "client-to-client") && !p[1])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->enable_c2c = true;
}
- else if (streq (p[0], "duplicate-cn"))
+ else if (streq (p[0], "duplicate-cn") && !p[1])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->duplicate_cn = true;
}
- else if (streq (p[0], "iroute") && p[1])
+ else if (streq (p[0], "iroute") && p[1] && !p[3])
{
const char *netmask = NULL;
@@ -5906,12 +6124,12 @@ add_option (struct options *options,
}
option_iroute (options, p[1], netmask, msglevel);
}
- else if (streq (p[0], "iroute-ipv6") && p[1])
+ else if (streq (p[0], "iroute-ipv6") && p[1] && !p[2])
{
VERIFY_PERMISSION (OPT_P_INSTANCE);
option_iroute_ipv6 (options, p[1], msglevel);
}
- else if (streq (p[0], "ifconfig-push") && p[1] && p[2])
+ else if (streq (p[0], "ifconfig-push") && p[1] && p[2] && !p[4])
{
in_addr_t local, remote_netmask;
@@ -5923,10 +6141,8 @@ add_option (struct options *options,
options->push_ifconfig_defined = true;
options->push_ifconfig_local = local;
options->push_ifconfig_remote_netmask = remote_netmask;
-#ifdef ENABLE_CLIENT_NAT
if (p[3])
options->push_ifconfig_local_alias = getaddr (GETADDR_HOST_ORDER|GETADDR_RESOLVE, p[3], 0, NULL, NULL);
-#endif
}
else
{
@@ -5934,7 +6150,7 @@ add_option (struct options *options,
goto err;
}
}
- else if (streq (p[0], "ifconfig-push-constraint") && p[1] && p[2])
+ else if (streq (p[0], "ifconfig-push-constraint") && p[1] && p[2] && !p[3])
{
in_addr_t network, netmask;
@@ -5953,7 +6169,7 @@ add_option (struct options *options,
goto err;
}
}
- else if (streq (p[0], "ifconfig-ipv6-push") && p[1] )
+ else if (streq (p[0], "ifconfig-ipv6-push") && p[1] && !p[3])
{
struct in6_addr local, remote;
unsigned int netbits;
@@ -5989,18 +6205,19 @@ add_option (struct options *options,
options->push_ifconfig_ipv6_local = local;
options->push_ifconfig_ipv6_netbits = netbits;
options->push_ifconfig_ipv6_remote = remote;
+ options->push_ifconfig_ipv6_blocked = false;
}
- else if (streq (p[0], "disable"))
+ else if (streq (p[0], "disable") && !p[1])
{
VERIFY_PERMISSION (OPT_P_INSTANCE);
options->disable = true;
}
- else if (streq (p[0], "tcp-nodelay"))
+ else if (streq (p[0], "tcp-nodelay") && !p[1])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->server_flags |= SF_TCP_NODELAY_HELPER;
}
- else if (streq (p[0], "stale-routes-check") && p[1])
+ else if (streq (p[0], "stale-routes-check") && p[1] && !p[3])
{
int ageing_time, check_interval;
@@ -6021,27 +6238,22 @@ add_option (struct options *options,
}
#endif /* P2MP_SERVER */
- else if (streq (p[0], "client"))
+ else if (streq (p[0], "client") && !p[1])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->client = true;
}
- else if (streq (p[0], "pull"))
+ else if (streq (p[0], "pull") && !p[1])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->pull = true;
}
- else if (streq (p[0], "push-continuation") && p[1])
+ else if (streq (p[0], "push-continuation") && p[1] && !p[2])
{
VERIFY_PERMISSION (OPT_P_PULL_MODE);
options->push_continuation = atoi(p[1]);
}
- else if (streq (p[0], "server-poll-timeout") && p[1])
- {
- VERIFY_PERMISSION (OPT_P_GENERAL);
- options->server_poll_timeout = positive_atoi(p[1]);
- }
- else if (streq (p[0], "auth-user-pass"))
+ else if (streq (p[0], "auth-user-pass") && !p[2])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
if (p[1])
@@ -6051,13 +6263,13 @@ add_option (struct options *options,
else
options->auth_user_pass_file = "stdin";
}
- else if (streq (p[0], "auth-retry") && p[1])
+ else if (streq (p[0], "auth-retry") && p[1] && !p[2])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
auth_retry_set (msglevel, p[1]);
}
#ifdef ENABLE_CLIENT_CR
- else if (streq (p[0], "static-challenge") && p[1] && p[2])
+ else if (streq (p[0], "static-challenge") && p[1] && p[2] && !p[3])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->sc_info.challenge_text = p[1];
@@ -6066,8 +6278,26 @@ add_option (struct options *options,
}
#endif
#endif
-#ifdef WIN32
- else if (streq (p[0], "win-sys") && p[1])
+ else if (streq (p[0], "msg-channel") && p[1])
+ {
+#ifdef _WIN32
+ VERIFY_PERMISSION (OPT_P_GENERAL);
+ HANDLE process = GetCurrentProcess ();
+ HANDLE handle = (HANDLE) atoi (p[1]);
+ if (!DuplicateHandle (process, handle, process, &options->msg_channel, 0,
+ FALSE, DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS))
+ {
+ msg (msglevel, "could not duplicate service pipe handle");
+ goto err;
+ }
+ options->route_method = ROUTE_METHOD_SERVICE;
+#else
+ msg (msglevel, "--msg-channel is only supported on Windows");
+ goto err;
+#endif
+ }
+#ifdef _WIN32
+ else if (streq (p[0], "win-sys") && p[1] && !p[2])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
if (streq (p[1], "env"))
@@ -6077,7 +6307,7 @@ add_option (struct options *options,
else
set_win_sys_path (p[1], es);
}
- else if (streq (p[0], "route-method") && p[1])
+ else if (streq (p[0], "route-method") && p[1] && !p[2])
{
VERIFY_PERMISSION (OPT_P_ROUTE_EXTRAS);
if (streq (p[1], "adaptive"))
@@ -6092,7 +6322,7 @@ add_option (struct options *options,
goto err;
}
}
- else if (streq (p[0], "ip-win32") && p[1])
+ else if (streq (p[0], "ip-win32") && p[1] && !p[4])
{
const int index = ascii2ipset (p[1]);
struct tuntap_options *to = &options->tuntap_options;
@@ -6146,7 +6376,9 @@ add_option (struct options *options,
to->ip_win32_type = index;
to->ip_win32_defined = true;
}
- else if (streq (p[0], "dhcp-option") && p[1])
+#endif
+#if defined(_WIN32) || defined(TARGET_ANDROID)
+ else if (streq (p[0], "dhcp-option") && p[1] && !p[3])
{
struct tuntap_options *o = &options->tuntap_options;
VERIFY_PERMISSION (OPT_P_IPWIN32);
@@ -6186,36 +6418,38 @@ add_option (struct options *options,
{
dhcp_option_address_parse ("NBDD", p[2], o->nbdd, &o->nbdd_len, msglevel);
}
- else if (streq (p[1], "DISABLE-NBT"))
+ else if (streq (p[1], "DISABLE-NBT") && !p[2])
{
o->disable_nbt = 1;
}
else
{
- msg (msglevel, "--dhcp-option: unknown option type '%s' or missing parameter", p[1]);
+ msg (msglevel, "--dhcp-option: unknown option type '%s' or missing or unknown parameter", p[1]);
goto err;
}
o->dhcp_options = true;
}
- else if (streq (p[0], "show-adapters"))
+#endif
+#ifdef _WIN32
+ else if (streq (p[0], "show-adapters") && !p[1])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
show_tap_win_adapters (M_INFO|M_NOPREFIX, M_WARN|M_NOPREFIX);
openvpn_exit (OPENVPN_EXIT_STATUS_GOOD); /* exit point */
}
- else if (streq (p[0], "show-net"))
+ else if (streq (p[0], "show-net") && !p[1])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
show_routes (M_INFO|M_NOPREFIX);
show_adapters (M_INFO|M_NOPREFIX);
openvpn_exit (OPENVPN_EXIT_STATUS_GOOD); /* exit point */
}
- else if (streq (p[0], "show-net-up"))
+ else if (streq (p[0], "show-net-up") && !p[1])
{
VERIFY_PERMISSION (OPT_P_UP);
options->show_net_up = true;
}
- else if (streq (p[0], "tap-sleep") && p[1])
+ else if (streq (p[0], "tap-sleep") && p[1] && !p[2])
{
int s;
VERIFY_PERMISSION (OPT_P_IPWIN32);
@@ -6227,22 +6461,22 @@ add_option (struct options *options,
}
options->tuntap_options.tap_sleep = s;
}
- else if (streq (p[0], "dhcp-renew"))
+ else if (streq (p[0], "dhcp-renew") && !p[1])
{
VERIFY_PERMISSION (OPT_P_IPWIN32);
options->tuntap_options.dhcp_renew = true;
}
- else if (streq (p[0], "dhcp-pre-release"))
+ else if (streq (p[0], "dhcp-pre-release") && !p[1])
{
VERIFY_PERMISSION (OPT_P_IPWIN32);
options->tuntap_options.dhcp_pre_release = true;
}
- else if (streq (p[0], "dhcp-release"))
+ else if (streq (p[0], "dhcp-release") && !p[1])
{
VERIFY_PERMISSION (OPT_P_IPWIN32);
options->tuntap_options.dhcp_release = true;
}
- else if (streq (p[0], "dhcp-internal") && p[1]) /* standalone method for internal use */
+ else if (streq (p[0], "dhcp-internal") && p[1] && !p[2]) /* standalone method for internal use */
{
unsigned int adapter_index;
VERIFY_PERMISSION (OPT_P_GENERAL);
@@ -6255,28 +6489,17 @@ add_option (struct options *options,
dhcp_renew_by_adapter_index (adapter_index);
openvpn_exit (OPENVPN_EXIT_STATUS_GOOD); /* exit point */
}
- else if (streq (p[0], "register-dns"))
+ else if (streq (p[0], "register-dns") && !p[1])
{
VERIFY_PERMISSION (OPT_P_IPWIN32);
options->tuntap_options.register_dns = true;
}
-#ifdef WIN32
else if (streq (p[0], "block-outside-dns") && !p[1])
{
VERIFY_PERMISSION (OPT_P_IPWIN32);
- if (win_wfp_init_funcs())
- {
- options->block_outside_dns = true;
- }
- else
- {
- msg (msglevel_fc, "Failed to enable --block-outside-dns. "
- "Maybe WFP is not supported on your system?");
- goto err;
- }
+ options->block_outside_dns = true;
}
-#endif
- else if (streq (p[0], "rdns-internal"))
+ else if (streq (p[0], "rdns-internal") && !p[1])
/* standalone method for internal use
*
* (if --register-dns is set, openvpn needs to call itself in a
@@ -6290,18 +6513,18 @@ add_option (struct options *options,
ipconfig_register_dns (NULL);
openvpn_exit (OPENVPN_EXIT_STATUS_GOOD); /* exit point */
}
- else if (streq (p[0], "show-valid-subnets"))
+ else if (streq (p[0], "show-valid-subnets") && !p[1])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
show_valid_win32_tun_subnets ();
openvpn_exit (OPENVPN_EXIT_STATUS_GOOD); /* exit point */
}
- else if (streq (p[0], "pause-exit"))
+ else if (streq (p[0], "pause-exit") && !p[1])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
set_pause_exit_win32 ();
}
- else if (streq (p[0], "service") && p[1])
+ else if (streq (p[0], "service") && p[1] && !p[3])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->exit_event_name = p[1];
@@ -6310,62 +6533,75 @@ add_option (struct options *options,
options->exit_event_initial_state = (atoi(p[2]) != 0);
}
}
- else if (streq (p[0], "allow-nonadmin"))
+ else if (streq (p[0], "allow-nonadmin") && !p[2])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
tap_allow_nonadmin_access (p[1]);
openvpn_exit (OPENVPN_EXIT_STATUS_GOOD); /* exit point */
}
- else if (streq (p[0], "user") && p[1])
+ else if (streq (p[0], "user") && p[1] && !p[2])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
msg (M_WARN, "NOTE: --user option is not implemented on Windows");
}
- else if (streq (p[0], "group") && p[1])
+ else if (streq (p[0], "group") && p[1] && !p[2])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
msg (M_WARN, "NOTE: --group option is not implemented on Windows");
}
#else
- else if (streq (p[0], "user") && p[1])
+ else if (streq (p[0], "user") && p[1] && !p[2])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->username = p[1];
}
- else if (streq (p[0], "group") && p[1])
+ else if (streq (p[0], "group") && p[1] && !p[2])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->groupname = p[1];
}
- else if (streq (p[0], "dhcp-option") && p[1])
+ else if (streq (p[0], "dhcp-option") && p[1] && !p[3])
{
VERIFY_PERMISSION (OPT_P_IPWIN32);
foreign_option (options, p, 3, es);
}
- else if (streq (p[0], "route-method") && p[1]) /* ignore when pushed to non-Windows OS */
+ else if (streq (p[0], "route-method") && p[1] && !p[2]) /* ignore when pushed to non-Windows OS */
{
VERIFY_PERMISSION (OPT_P_ROUTE_EXTRAS);
}
#endif
#if PASSTOS_CAPABILITY
- else if (streq (p[0], "passtos"))
+ else if (streq (p[0], "passtos") && !p[1])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->passtos = true;
}
#endif
-#ifdef ENABLE_LZO
- else if (streq (p[0], "comp-lzo"))
+#if defined(USE_COMP)
+ else if (streq (p[0], "comp-lzo") && !p[2])
{
VERIFY_PERMISSION (OPT_P_COMP);
- if (p[1])
+
+#if defined(ENABLE_LZO)
+ if (p[1] && streq (p[1], "no"))
+#endif
+ {
+ options->comp.alg = COMP_ALG_STUB;
+ options->comp.flags = 0;
+ }
+#if defined(ENABLE_LZO)
+ else if (p[1])
{
if (streq (p[1], "yes"))
- options->lzo = LZO_SELECTED|LZO_ON;
- else if (streq (p[1], "no"))
- options->lzo = LZO_SELECTED;
+ {
+ options->comp.alg = COMP_ALG_LZO;
+ options->comp.flags = 0;
+ }
else if (streq (p[1], "adaptive"))
- options->lzo = LZO_SELECTED|LZO_ON|LZO_ADAPTIVE;
+ {
+ options->comp.alg = COMP_ALG_LZO;
+ options->comp.flags = COMP_F_ADAPTIVE;
+ }
else
{
msg (msglevel, "bad comp-lzo option: %s -- must be 'yes', 'no', or 'adaptive'", p[1]);
@@ -6373,31 +6609,81 @@ add_option (struct options *options,
}
}
else
- options->lzo = LZO_SELECTED|LZO_ON|LZO_ADAPTIVE;
+ {
+ options->comp.alg = COMP_ALG_LZO;
+ options->comp.flags = COMP_F_ADAPTIVE;
+ }
+#endif
+ }
+ else if (streq (p[0], "comp-noadapt") && !p[1])
+ {
+ VERIFY_PERMISSION (OPT_P_COMP);
+ options->comp.flags &= ~COMP_F_ADAPTIVE;
}
- else if (streq (p[0], "comp-noadapt"))
+ else if (streq (p[0], "compress") && !p[2])
{
VERIFY_PERMISSION (OPT_P_COMP);
- options->lzo &= ~LZO_ADAPTIVE;
+ if (p[1])
+ {
+ if (streq (p[1], "stub"))
+ {
+ options->comp.alg = COMP_ALG_STUB;
+ options->comp.flags = (COMP_F_SWAP|COMP_F_ADVERTISE_STUBS_ONLY);
+ }
+ else if (streq(p[1], "stub-v2"))
+ {
+ options->comp.alg = COMP_ALGV2_UNCOMPRESSED;
+ options->comp.flags = COMP_F_ADVERTISE_STUBS_ONLY;
+ }
+#if defined(ENABLE_LZO)
+ else if (streq (p[1], "lzo"))
+ {
+ options->comp.alg = COMP_ALG_LZO;
+ options->comp.flags = 0;
+ }
+#endif
+#if defined(ENABLE_LZ4)
+ else if (streq (p[1], "lz4"))
+ {
+ options->comp.alg = COMP_ALG_LZ4;
+ options->comp.flags = COMP_F_SWAP;
+ }
+ else if (streq (p[1], "lz4-v2"))
+ {
+ options->comp.alg = COMP_ALGV2_LZ4;
+ options->comp.flags = 0;
+ }
+#endif
+ else
+ {
+ msg (msglevel, "bad comp option: %s", p[1]);
+ goto err;
+ }
+ }
+ else
+ {
+ options->comp.alg = COMP_ALG_STUB;
+ options->comp.flags = COMP_F_SWAP;
+ }
}
-#endif /* ENABLE_LZO */
+#endif /* USE_COMP */
#ifdef ENABLE_CRYPTO
- else if (streq (p[0], "show-ciphers"))
+ else if (streq (p[0], "show-ciphers") && !p[1])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->show_ciphers = true;
}
- else if (streq (p[0], "show-digests"))
+ else if (streq (p[0], "show-digests") && !p[1])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->show_digests = true;
}
- else if (streq (p[0], "show-engines"))
+ else if (streq (p[0], "show-engines") && !p[1])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->show_engines = true;
}
- else if (streq (p[0], "key-direction") && p[1])
+ else if (streq (p[0], "key-direction") && p[1] && !p[2])
{
int key_direction;
@@ -6407,7 +6693,7 @@ add_option (struct options *options,
else
goto err;
}
- else if (streq (p[0], "secret") && p[1])
+ else if (streq (p[0], "secret") && p[1] && !p[3])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
if (streq (p[1], INLINE_FILE_TAG) && p[2])
@@ -6427,46 +6713,34 @@ add_option (struct options *options,
}
options->shared_secret_file = p[1];
}
- else if (streq (p[0], "genkey"))
+ else if (streq (p[0], "genkey") && !p[1])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->genkey = true;
}
- else if (streq (p[0], "auth") && p[1])
+ else if (streq (p[0], "auth") && p[1] && !p[2])
{
- VERIFY_PERMISSION (OPT_P_CRYPTO);
- options->authname_defined = true;
+ VERIFY_PERMISSION (OPT_P_GENERAL);
options->authname = p[1];
- if (streq (options->authname, "none"))
- {
- options->authname_defined = false;
- options->authname = NULL;
- }
}
- else if (streq (p[0], "auth"))
+ else if (streq (p[0], "cipher") && p[1] && !p[2])
{
- VERIFY_PERMISSION (OPT_P_CRYPTO);
- options->authname_defined = true;
+ VERIFY_PERMISSION (OPT_P_NCP);
+ options->ciphername = p[1];
}
- else if (streq (p[0], "cipher") && p[1])
+ else if (streq (p[0], "ncp-ciphers") && p[1] && !p[2])
{
- VERIFY_PERMISSION (OPT_P_CRYPTO);
- options->ciphername_defined = true;
- options->ciphername = p[1];
- if (streq (options->ciphername, "none"))
- {
- options->ciphername_defined = false;
- options->ciphername = NULL;
- }
+ VERIFY_PERMISSION (OPT_P_GENERAL|OPT_P_INSTANCE);
+ options->ncp_ciphers = p[1];
}
- else if (streq (p[0], "cipher"))
+ else if (streq (p[0], "ncp-disable") && !p[1])
{
- VERIFY_PERMISSION (OPT_P_CRYPTO);
- options->ciphername_defined = true;
+ VERIFY_PERMISSION (OPT_P_GENERAL|OPT_P_INSTANCE);
+ options->ncp_enabled = false;
}
- else if (streq (p[0], "prng") && p[1])
+ else if (streq (p[0], "prng") && p[1] && !p[3])
{
- VERIFY_PERMISSION (OPT_P_CRYPTO);
+ VERIFY_PERMISSION (OPT_P_GENERAL);
if (streq (p[1], "none"))
options->prng_hash = NULL;
else
@@ -6486,14 +6760,14 @@ add_option (struct options *options,
}
}
}
- else if (streq (p[0], "no-replay"))
+ else if (streq (p[0], "no-replay") && !p[1])
{
- VERIFY_PERMISSION (OPT_P_CRYPTO);
+ VERIFY_PERMISSION (OPT_P_GENERAL);
options->replay = false;
}
- else if (streq (p[0], "replay-window"))
+ else if (streq (p[0], "replay-window") && !p[3])
{
- VERIFY_PERMISSION (OPT_P_CRYPTO);
+ VERIFY_PERMISSION (OPT_P_GENERAL);
if (p[1])
{
int replay_window;
@@ -6531,28 +6805,28 @@ add_option (struct options *options,
goto err;
}
}
- else if (streq (p[0], "mute-replay-warnings"))
+ else if (streq (p[0], "mute-replay-warnings") && !p[1])
{
- VERIFY_PERMISSION (OPT_P_CRYPTO);
+ VERIFY_PERMISSION (OPT_P_GENERAL);
options->mute_replay_warnings = true;
}
- else if (streq (p[0], "no-iv"))
+ else if (streq (p[0], "no-iv") && !p[1])
{
- VERIFY_PERMISSION (OPT_P_CRYPTO);
+ VERIFY_PERMISSION (OPT_P_GENERAL);
options->use_iv = false;
}
- else if (streq (p[0], "replay-persist") && p[1])
+ else if (streq (p[0], "replay-persist") && p[1] && !p[2])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->packet_id_file = p[1];
}
- else if (streq (p[0], "test-crypto"))
+ else if (streq (p[0], "test-crypto") && !p[1])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->test_crypto = true;
}
-#ifndef ENABLE_CRYPTO_POLARSSL
- else if (streq (p[0], "engine"))
+#ifndef ENABLE_CRYPTO_MBEDTLS
+ else if (streq (p[0], "engine") && !p[2])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
if (p[1])
@@ -6562,13 +6836,13 @@ add_option (struct options *options,
else
options->engine = "auto";
}
-#endif /* ENABLE_CRYPTO_POLARSSL */
+#endif /* ENABLE_CRYPTO_MBEDTLS */
#ifdef HAVE_EVP_CIPHER_CTX_SET_KEY_LENGTH
- else if (streq (p[0], "keysize") && p[1])
+ else if (streq (p[0], "keysize") && p[1] && !p[2])
{
int keysize;
- VERIFY_PERMISSION (OPT_P_CRYPTO);
+ VERIFY_PERMISSION (OPT_P_NCP);
keysize = atoi (p[1]) / 8;
if (keysize < 0 || keysize > MAX_CIPHER_KEY_LENGTH)
{
@@ -6579,29 +6853,38 @@ add_option (struct options *options,
}
#endif
#ifdef ENABLE_PREDICTION_RESISTANCE
- else if (streq (p[0], "use-prediction-resistance"))
+ else if (streq (p[0], "use-prediction-resistance") && !p[1])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->use_prediction_resistance = true;
}
#endif
-#ifdef ENABLE_SSL
- else if (streq (p[0], "show-tls"))
+ else if (streq (p[0], "show-tls") && !p[1])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->show_tls_ciphers = true;
}
- else if (streq (p[0], "tls-server"))
+ else if (streq (p[0], "show-curves") && !p[1])
+ {
+ VERIFY_PERMISSION (OPT_P_GENERAL);
+ options->show_curves = true;
+ }
+ else if (streq (p[0], "ecdh-curve") && p[1] && !p[2])
+ {
+ VERIFY_PERMISSION (OPT_P_GENERAL);
+ options->ecdh_curve= p[1];
+ }
+ else if (streq (p[0], "tls-server") && !p[1])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->tls_server = true;
}
- else if (streq (p[0], "tls-client"))
+ else if (streq (p[0], "tls-client") && !p[1])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->tls_client = true;
}
- else if (streq (p[0], "ca") && p[1])
+ else if (streq (p[0], "ca") && p[1] && ((streq (p[1], INLINE_FILE_TAG) && p[2]) || !p[2]) && !p[3])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->ca_file = p[1];
@@ -6610,14 +6893,14 @@ add_option (struct options *options,
options->ca_file_inline = p[2];
}
}
-#ifndef ENABLE_CRYPTO_POLARSSL
- else if (streq (p[0], "capath") && p[1])
+#ifndef ENABLE_CRYPTO_MBEDTLS
+ else if (streq (p[0], "capath") && p[1] && !p[2])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->ca_path = p[1];
}
-#endif /* ENABLE_CRYPTO_POLARSSL */
- else if (streq (p[0], "dh") && p[1])
+#endif /* ENABLE_CRYPTO_MBEDTLS */
+ else if (streq (p[0], "dh") && p[1] && ((streq (p[1], INLINE_FILE_TAG) && p[2]) || !p[2]) && !p[3])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->dh_file = p[1];
@@ -6626,7 +6909,7 @@ add_option (struct options *options,
options->dh_file_inline = p[2];
}
}
- else if (streq (p[0], "cert") && p[1])
+ else if (streq (p[0], "cert") && p[1] && ((streq (p[1], INLINE_FILE_TAG) && p[2]) || !p[2]) && !p[3])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->cert_file = p[1];
@@ -6635,7 +6918,7 @@ add_option (struct options *options,
options->cert_file_inline = p[2];
}
}
- else if (streq (p[0], "extra-certs") && p[1])
+ else if (streq (p[0], "extra-certs") && p[1] && ((streq (p[1], INLINE_FILE_TAG) && p[2]) || !p[2]) && !p[3])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->extra_certs_file = p[1];
@@ -6644,19 +6927,19 @@ add_option (struct options *options,
options->extra_certs_file_inline = p[2];
}
}
- else if (streq (p[0], "verify-hash") && p[1])
+ else if (streq (p[0], "verify-hash") && p[1] && !p[2])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->verify_hash = parse_hash_fingerprint(p[1], SHA_DIGEST_LENGTH, msglevel, &options->gc);
}
#ifdef ENABLE_CRYPTOAPI
- else if (streq (p[0], "cryptoapicert") && p[1])
+ else if (streq (p[0], "cryptoapicert") && p[1] && !p[2])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->cryptoapi_cert = p[1];
}
#endif
- else if (streq (p[0], "key") && p[1])
+ else if (streq (p[0], "key") && p[1] && ((streq (p[1], INLINE_FILE_TAG) && p[2]) || !p[2]) && !p[3])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->priv_key_file = p[1];
@@ -6665,7 +6948,7 @@ add_option (struct options *options,
options->priv_key_file_inline = p[2];
}
}
- else if (streq (p[0], "tls-version-min") && p[1])
+ else if (streq (p[0], "tls-version-min") && p[1] && !p[3])
{
int ver;
VERIFY_PERMISSION (OPT_P_GENERAL);
@@ -6679,7 +6962,7 @@ add_option (struct options *options,
~(SSLF_TLS_VERSION_MIN_MASK << SSLF_TLS_VERSION_MIN_SHIFT);
options->ssl_flags |= (ver << SSLF_TLS_VERSION_MIN_SHIFT);
}
- else if (streq (p[0], "tls-version-max") && p[1])
+ else if (streq (p[0], "tls-version-max") && p[1] && !p[2])
{
int ver;
VERIFY_PERMISSION (OPT_P_GENERAL);
@@ -6693,8 +6976,8 @@ add_option (struct options *options,
~(SSLF_TLS_VERSION_MAX_MASK << SSLF_TLS_VERSION_MAX_SHIFT);
options->ssl_flags |= (ver << SSLF_TLS_VERSION_MAX_SHIFT);
}
-#ifndef ENABLE_CRYPTO_POLARSSL
- else if (streq (p[0], "pkcs12") && p[1])
+#ifndef ENABLE_CRYPTO_MBEDTLS
+ else if (streq (p[0], "pkcs12") && p[1] && ((streq (p[1], INLINE_FILE_TAG) && p[2]) || !p[2]) && !p[3])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->pkcs12_file = p[1];
@@ -6703,8 +6986,8 @@ add_option (struct options *options,
options->pkcs12_file_inline = p[2];
}
}
-#endif /* ENABLE_CRYPTO_POLARSSL */
- else if (streq (p[0], "askpass"))
+#endif /* ENABLE_CRYPTO_MBEDTLS */
+ else if (streq (p[0], "askpass") && !p[2])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
if (p[1])
@@ -6714,12 +6997,12 @@ add_option (struct options *options,
else
options->key_pass_file = "stdin";
}
- else if (streq (p[0], "auth-nocache"))
+ else if (streq (p[0], "auth-nocache") && !p[1])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
ssl_set_auth_nocache ();
}
- else if (streq (p[0], "auth-token") && p[1])
+ else if (streq (p[0], "auth-token") && p[1] && !p[2])
{
VERIFY_PERMISSION (OPT_P_ECHO);
ssl_set_auth_token(p[1]);
@@ -6728,34 +7011,39 @@ add_option (struct options *options,
management_auth_token (management, p[1]);
#endif
}
- else if (streq (p[0], "single-session"))
+ else if (streq (p[0], "single-session") && !p[1])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->single_session = true;
}
#ifdef ENABLE_PUSH_PEER_INFO
- else if (streq (p[0], "push-peer-info"))
+ else if (streq (p[0], "push-peer-info") && !p[1])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->push_peer_info = true;
}
#endif
- else if (streq (p[0], "tls-exit"))
+ else if (streq (p[0], "tls-exit") && !p[1])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->tls_exit = true;
}
- else if (streq (p[0], "tls-cipher") && p[1])
+ else if (streq (p[0], "tls-cipher") && p[1] && !p[2])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->cipher_list = p[1];
}
- else if (streq (p[0], "crl-verify") && 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])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
if (p[2] && streq(p[2], "dir"))
options->ssl_flags |= SSLF_CRL_VERIFY_DIR;
options->crl_file = p[1];
+ if (streq (p[1], INLINE_FILE_TAG) && p[2])
+ {
+ options->crl_file_inline = p[2];
+ }
}
else if (streq (p[0], "tls-verify") && p[1])
{
@@ -6766,85 +7054,48 @@ add_option (struct options *options,
string_substitute (p[1], ',', ' ', &options->gc),
"tls-verify", true);
}
-#ifndef ENABLE_CRYPTO_POLARSSL
- else if (streq (p[0], "tls-export-cert") && p[1])
+#ifndef ENABLE_CRYPTO_MBEDTLS
+ else if (streq (p[0], "tls-export-cert") && p[1] && !p[2])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->tls_export_cert = p[1];
}
#endif
- else if (streq (p[0], "compat-names"))
+#if P2MP_SERVER
+ else if (streq (p[0], "compat-names") && ((p[1] && streq (p[1], "no-remapping")) || !p[1]) && !p[2])
+#else
+ else if (streq (p[0], "compat-names") && !p[1])
+#endif
{
VERIFY_PERMISSION (OPT_P_GENERAL);
- if (options->verify_x509_type != VERIFY_X509_NONE &&
- options->verify_x509_type != TLS_REMOTE_SUBJECT_DN &&
- options->verify_x509_type != TLS_REMOTE_SUBJECT_RDN_PREFIX)
+ if (options->verify_x509_type != VERIFY_X509_NONE)
{
msg (msglevel, "you cannot use --compat-names with --verify-x509-name");
goto err;
}
- msg (M_WARN, "DEPRECATED OPTION: --compat-names, please update your configuration");
+ msg (M_WARN, "DEPRECATED OPTION: --compat-names, please update your configuration. This will be removed in OpenVPN v2.5.");
compat_flag (COMPAT_FLAG_SET | COMPAT_NAMES);
#if P2MP_SERVER
if (p[1] && streq (p[1], "no-remapping"))
compat_flag (COMPAT_FLAG_SET | COMPAT_NO_NAME_REMAPPING);
}
- else if (streq (p[0], "no-name-remapping"))
+ else if (streq (p[0], "no-name-remapping") && !p[1])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
- if (options->verify_x509_type != VERIFY_X509_NONE &&
- options->verify_x509_type != TLS_REMOTE_SUBJECT_DN &&
- options->verify_x509_type != TLS_REMOTE_SUBJECT_RDN_PREFIX)
+ if (options->verify_x509_type != VERIFY_X509_NONE)
{
msg (msglevel, "you cannot use --no-name-remapping with --verify-x509-name");
goto err;
}
- msg (M_WARN, "DEPRECATED OPTION: --no-name-remapping, please update your configuration");
+ msg (M_WARN, "DEPRECATED OPTION: --no-name-remapping, please update your configuration. This will be removed in OpenVPN v2.5.");
compat_flag (COMPAT_FLAG_SET | COMPAT_NAMES);
compat_flag (COMPAT_FLAG_SET | COMPAT_NO_NAME_REMAPPING);
#endif
}
- else if (streq (p[0], "tls-remote") && p[1])
- {
- VERIFY_PERMISSION (OPT_P_GENERAL);
-
- if (options->verify_x509_type != VERIFY_X509_NONE &&
- options->verify_x509_type != TLS_REMOTE_SUBJECT_DN &&
- options->verify_x509_type != TLS_REMOTE_SUBJECT_RDN_PREFIX)
- {
- msg (msglevel, "you cannot use --tls-remote with --verify-x509-name");
- goto err;
- }
- msg (M_WARN, "DEPRECATED OPTION: --tls-remote, please update your configuration");
-
- if (strlen (p[1]))
- {
- int is_username = (!strchr (p[1], '=') || !strstr (p[1], ", "));
- int type = TLS_REMOTE_SUBJECT_DN;
- if (p[1][0] != '/' && is_username)
- type = TLS_REMOTE_SUBJECT_RDN_PREFIX;
-
- /*
- * Enable legacy openvpn format for DNs that have not been converted
- * yet and --x509-username-field (not containing an '=' or ', ')
- */
- if (p[1][0] == '/' || is_username)
- compat_flag (COMPAT_FLAG_SET | COMPAT_NAMES);
-
- options->verify_x509_type = type;
- options->verify_x509_name = p[1];
- }
- }
- else if (streq (p[0], "verify-x509-name") && p[1] && strlen (p[1]))
+ else if (streq (p[0], "verify-x509-name") && p[1] && strlen (p[1]) && !p[3])
{
int type = VERIFY_X509_SUBJECT_DN;
VERIFY_PERMISSION (OPT_P_GENERAL);
- if (options->verify_x509_type == TLS_REMOTE_SUBJECT_DN ||
- options->verify_x509_type == TLS_REMOTE_SUBJECT_RDN_PREFIX)
- {
- msg (msglevel, "you cannot use --verify-x509-name with --tls-remote");
- goto err;
- }
if (compat_flag (COMPAT_FLAG_QUERY | COMPAT_NAMES))
{
msg (msglevel, "you cannot use --verify-x509-name with "
@@ -6868,7 +7119,7 @@ add_option (struct options *options,
options->verify_x509_type = type;
options->verify_x509_name = p[1];
}
- else if (streq (p[0], "ns-cert-type") && p[1])
+ else if (streq (p[0], "ns-cert-type") && p[1] && !p[2])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
if (streq (p[1], "server"))
@@ -6881,7 +7132,6 @@ add_option (struct options *options,
goto err;
}
}
-#if OPENSSL_VERSION_NUMBER >= 0x00907000L || ENABLE_CRYPTO_POLARSSL
else if (streq (p[0], "remote-cert-ku"))
{
int j;
@@ -6891,12 +7141,12 @@ add_option (struct options *options,
for (j = 1; j < MAX_PARMS && p[j] != NULL; ++j)
sscanf (p[j], "%x", &(options->remote_cert_ku[j-1]));
}
- else if (streq (p[0], "remote-cert-eku") && p[1])
+ else if (streq (p[0], "remote-cert-eku") && p[1] && !p[2])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->remote_cert_eku = p[1];
}
- else if (streq (p[0], "remote-cert-tls") && p[1])
+ else if (streq (p[0], "remote-cert-tls") && p[1] && !p[2])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
@@ -6919,38 +7169,37 @@ add_option (struct options *options,
goto err;
}
}
-#endif /* OPENSSL_VERSION_NUMBER */
- else if (streq (p[0], "tls-timeout") && p[1])
+ else if (streq (p[0], "tls-timeout") && p[1] && !p[2])
{
VERIFY_PERMISSION (OPT_P_TLS_PARMS);
options->tls_timeout = positive_atoi (p[1]);
}
- else if (streq (p[0], "reneg-bytes") && p[1])
+ else if (streq (p[0], "reneg-bytes") && p[1] && !p[2])
{
VERIFY_PERMISSION (OPT_P_TLS_PARMS);
options->renegotiate_bytes = positive_atoi (p[1]);
}
- else if (streq (p[0], "reneg-pkts") && p[1])
+ else if (streq (p[0], "reneg-pkts") && p[1] && !p[2])
{
VERIFY_PERMISSION (OPT_P_TLS_PARMS);
options->renegotiate_packets = positive_atoi (p[1]);
}
- else if (streq (p[0], "reneg-sec") && p[1])
+ else if (streq (p[0], "reneg-sec") && p[1] && !p[2])
{
VERIFY_PERMISSION (OPT_P_TLS_PARMS);
options->renegotiate_seconds = positive_atoi (p[1]);
}
- else if (streq (p[0], "hand-window") && p[1])
+ else if (streq (p[0], "hand-window") && p[1] && !p[2])
{
VERIFY_PERMISSION (OPT_P_TLS_PARMS);
options->handshake_window = positive_atoi (p[1]);
}
- else if (streq (p[0], "tran-window") && p[1])
+ else if (streq (p[0], "tran-window") && p[1] && !p[2])
{
VERIFY_PERMISSION (OPT_P_TLS_PARMS);
options->transition_window = positive_atoi (p[1]);
}
- else if (streq (p[0], "tls-auth") && p[1])
+ else if (streq (p[0], "tls-auth") && p[1] && !p[3])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
if (streq (p[1], INLINE_FILE_TAG) && p[2])
@@ -6970,7 +7219,16 @@ add_option (struct options *options,
}
options->tls_auth_file = p[1];
}
- else if (streq (p[0], "key-method") && p[1])
+ else if (streq (p[0], "tls-crypt") && p[1] && !p[3])
+ {
+ VERIFY_PERMISSION (OPT_P_GENERAL);
+ if (streq (p[1], INLINE_FILE_TAG) && p[2])
+ {
+ options->tls_crypt_inline = p[2];
+ }
+ options->tls_crypt_file = p[1];
+ }
+ else if (streq (p[0], "key-method") && p[1] && !p[2])
{
int key_method;
@@ -6986,8 +7244,13 @@ add_option (struct options *options,
}
options->key_method = key_method;
}
+ else if (streq (p[0], "x509-track") && p[1] && !p[2])
+ {
+ VERIFY_PERMISSION (OPT_P_GENERAL);
+ x509_track_add (&options->x509_track, p[1], msglevel, &options->gc);
+ }
#ifdef ENABLE_X509ALTUSERNAME
- else if (streq (p[0], "x509-username-field") && p[1])
+ else if (streq (p[0], "x509-username-field") && p[1] && !p[2])
{
/* This option used to automatically upcase the fieldname passed as the
* option argument, e.g., "ou" became "OU". Now, this "helpfulness" is
@@ -7014,10 +7277,9 @@ add_option (struct options *options,
options->x509_username_field = p[1];
}
#endif /* ENABLE_X509ALTUSERNAME */
-#endif /* ENABLE_SSL */
#endif /* ENABLE_CRYPTO */
#ifdef ENABLE_PKCS11
- else if (streq (p[0], "show-pkcs11-ids"))
+ else if (streq (p[0], "show-pkcs11-ids") && !p[3])
{
char *provider = p[1];
bool cert_private = (p[2] == NULL ? false : ( atoi (p[2]) != 0 ));
@@ -7087,40 +7349,68 @@ add_option (struct options *options,
for (j = 1; j < MAX_PARMS && p[j] != NULL; ++j)
options->pkcs11_cert_private[j-1] = atoi (p[j]) != 0 ? 1 : 0;
}
- else if (streq (p[0], "pkcs11-pin-cache") && p[1])
+ else if (streq (p[0], "pkcs11-pin-cache") && p[1] && !p[2])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->pkcs11_pin_cache_period = atoi (p[1]);
}
- else if (streq (p[0], "pkcs11-id") && p[1])
+ else if (streq (p[0], "pkcs11-id") && p[1] && !p[2])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->pkcs11_id = p[1];
}
- else if (streq (p[0], "pkcs11-id-management"))
+ else if (streq (p[0], "pkcs11-id-management") && !p[1])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->pkcs11_id_management = true;
}
#endif
- else if (streq (p[0], "rmtun"))
+ else if (streq (p[0], "rmtun") && !p[1])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->persist_config = true;
options->persist_mode = 0;
}
- else if (streq (p[0], "mktun"))
+ else if (streq (p[0], "mktun") && !p[1])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->persist_config = true;
options->persist_mode = 1;
}
- else if (streq (p[0], "peer-id") && p[1])
+ else if (streq (p[0], "peer-id") && p[1] && !p[2])
{
VERIFY_PERMISSION (OPT_P_PEER_ID);
options->use_peer_id = true;
options->peer_id = atoi(p[1]);
}
+#if defined(ENABLE_CRYPTO_OPENSSL) && OPENSSL_VERSION_NUMBER >= 0x10001000
+ else if (streq (p[0], "keying-material-exporter") && p[1] && p[2])
+ {
+ int ekm_length = positive_atoi (p[2]);
+
+ VERIFY_PERMISSION (OPT_P_GENERAL);
+
+ if (strncmp(p[1], "EXPORTER", 8))
+ {
+ msg (msglevel, "Keying material exporter label must begin with "
+ "\"EXPORTER\"");
+ goto err;
+ }
+ if (ekm_length < 16 || ekm_length > 4095)
+ {
+ msg (msglevel, "Invalid keying material exporter length");
+ goto err;
+ }
+
+ options->keying_material_exporter_label = p[1];
+ options->keying_material_exporter_length = ekm_length;
+ }
+#endif
+ else if (streq (p[0], "allow-recursive-routing") && !p[1])
+ {
+ VERIFY_PERMISSION (OPT_P_GENERAL);
+ options->allow_recursive_routing = true;
+ }
else
{
int i;
@@ -7136,9 +7426,9 @@ add_option (struct options *options,
}
}
if (file)
- msg (msglevel, "Unrecognized option or missing parameter(s) in %s:%d: %s (%s)", file, line, p[0], PACKAGE_VERSION);
+ msg (msglevel, "Unrecognized option or missing or extra parameter(s) in %s:%d: %s (%s)", file, line, p[0], PACKAGE_VERSION);
else
- msg (msglevel, "Unrecognized option or missing parameter(s): --%s (%s)", p[0], PACKAGE_VERSION);
+ msg (msglevel, "Unrecognized option or missing or extra parameter(s): --%s (%s)", p[0], PACKAGE_VERSION);
}
err:
gc_free (&gc);
diff --git a/src/openvpn/options.h b/src/openvpn/options.h
index 26b09ea..a028556 100644
--- a/src/openvpn/options.h
+++ b/src/openvpn/options.h
@@ -39,7 +39,7 @@
#include "plugin.h"
#include "manage.h"
#include "proxy.h"
-#include "lzo.h"
+#include "comp.h"
#include "pushlist.h"
#include "clinat.h"
@@ -71,44 +71,37 @@ struct options_pre_pull
bool routes_ipv6_defined;
struct route_ipv6_option_list *routes_ipv6;
-#ifdef ENABLE_CLIENT_NAT
bool client_nat_defined;
struct client_nat_option_list *client_nat;
-#endif
int foreign_option_index;
};
#endif
-#if defined(ENABLE_CRYPTO) && !defined(ENABLE_CRYPTO_OPENSSL) && !defined(ENABLE_CRYPTO_POLARSSL)
-# error "At least one of OpenSSL or PolarSSL needs to be defined."
+#if defined(ENABLE_CRYPTO) && !defined(ENABLE_CRYPTO_OPENSSL) && !defined(ENABLE_CRYPTO_MBEDTLS)
+# error "At least one of OpenSSL or mbed TLS needs to be defined."
#endif
struct connection_entry
{
int proto;
- int local_port;
+ sa_family_t af;
+ const char* local_port;
bool local_port_defined;
- int remote_port;
+ const char *remote_port;
const char *local;
const char *remote;
bool remote_float;
bool bind_defined;
+ bool bind_ipv6_only;
bool bind_local;
int connect_retry_seconds;
- bool connect_retry_defined;
- int connect_retry_max;
+ int connect_retry_seconds_max;
int connect_timeout;
- bool connect_timeout_defined;
-#ifdef ENABLE_HTTP_PROXY
struct http_proxy_options *http_proxy_options;
-#endif
-#ifdef ENABLE_SOCKS
const char *socks_proxy_server;
- int socks_proxy_port;
+ const char *socks_proxy_port;
const char *socks_proxy_authfile;
- bool socks_proxy_retry;
-#endif
int tun_mtu; /* MTU of tun device */
bool tun_mtu_defined; /* true if user overriding parm with command line option */
@@ -124,9 +117,7 @@ struct connection_entry
int mssfix; /* Upper bound on TCP MSS */
bool mssfix_default; /* true if --mssfix was supplied without a parameter */
-#ifdef ENABLE_OCC
- int explicit_exit_notification; /* Explicitly tell peer when we are exiting via OCC_EXIT message */
-#endif
+ int explicit_exit_notification; /* Explicitly tell peer when we are exiting via OCC_EXIT or [RESTART] message */
# define CE_DISABLED (1<<0)
# define CE_MAN_QUERY_PROXY (1<<1)
@@ -143,8 +134,9 @@ struct connection_entry
struct remote_entry
{
const char *remote;
- int remote_port;
+ const char *remote_port;
int proto;
+ sa_family_t af;
};
#define CONNECTION_LIST_SIZE 64
@@ -153,8 +145,6 @@ struct connection_list
{
int len;
int current;
- int n_cycles;
- bool no_advance;
struct connection_entry *array[CONNECTION_LIST_SIZE];
};
@@ -168,6 +158,8 @@ struct remote_host_store
{
# define RH_HOST_LEN 80
char host[RH_HOST_LEN];
+#define RH_PORT_LEN 20
+ char port[RH_PORT_LEN];
};
/* Command line options */
@@ -198,20 +190,23 @@ struct options
bool show_ciphers;
bool show_digests;
bool show_engines;
-#ifdef ENABLE_SSL
bool show_tls_ciphers;
-#endif
+ bool show_curves;
bool genkey;
#endif
/* Networking parms */
+ int connect_retry_max;
struct connection_entry ce;
- char *remote_ip_hint;
struct connection_list *connection_list;
+
struct remote_list *remote_list;
- bool force_connection_list;
+ /* Do not advanced the connection or remote addr list*/
+ bool no_advance;
+ /* Counts the number of unsuccessful connection attempts */
+ unsigned int unsuccessful_attempts;
-#if HTTP_PROXY_OVERRIDE
+#if ENABLE_MANAGEMENT
struct http_proxy_options *http_proxy_override;
#endif
@@ -256,7 +251,6 @@ struct options
int ping_send_timeout; /* Send a TCP/UDP ping to remote every n seconds */
int ping_rec_timeout; /* Expect a TCP/UDP ping from remote at least once every n seconds */
bool ping_timer_remote; /* Run ping timer only if we have a remote address */
- bool tun_ipv6; /* Build tun dev that supports IPv6 */
# define PING_UNDEF 0
# define PING_EXIT 1
@@ -273,6 +267,8 @@ struct options
#endif
int resolve_retry_seconds; /* If hostname resolve fails, retry for n seconds */
+ bool resolve_in_advance;
+ const char *ip_remote_hint;
struct tuntap_options tuntap_options;
@@ -300,6 +296,7 @@ struct options
bool log;
bool suppress_timestamps;
+ bool machine_readable_output;
int nice;
int verbosity;
int mute;
@@ -315,9 +312,8 @@ struct options
/* optimize TUN/TAP/UDP writes */
bool fast_io;
-#ifdef ENABLE_LZO
- /* LZO_x flags from lzo.h */
- unsigned int lzo;
+#ifdef USE_COMP
+ struct compress_options comp;
#endif
/* buffer sizes */
@@ -339,16 +335,12 @@ struct options
int route_delay;
int route_delay_window;
bool route_delay_defined;
- int max_routes;
struct route_option_list *routes;
struct route_ipv6_option_list *routes_ipv6; /* IPv6 */
bool route_nopull;
bool route_gateway_via_dhcp;
bool allow_pull_fqdn; /* as a client, allow server to push a FQDN for certain parameters */
-
-#ifdef ENABLE_CLIENT_NAT
struct client_nat_option_list *client_nat;
-#endif
#ifdef ENABLE_OCC
/* Enable options consistency check between peers */
@@ -357,7 +349,7 @@ struct options
#ifdef ENABLE_MANAGEMENT
const char *management_addr;
- int management_port;
+ const char *management_port;
const char *management_user_pass;
int management_log_history_cache;
int management_echo_buffer_size;
@@ -369,6 +361,7 @@ struct options
/* Mask of MF_ values of manage.h */
unsigned int management_flags;
+ const char *management_certificate;
#endif
#ifdef ENABLE_PLUGIN
@@ -429,9 +422,7 @@ struct options
bool push_ifconfig_defined;
in_addr_t push_ifconfig_local;
in_addr_t push_ifconfig_remote_netmask;
-#ifdef ENABLE_CLIENT_NAT
in_addr_t push_ifconfig_local_alias;
-#endif
bool push_ifconfig_constraint_defined;
in_addr_t push_ifconfig_constraint_network;
in_addr_t push_ifconfig_constraint_netmask;
@@ -439,6 +430,7 @@ struct options
struct in6_addr push_ifconfig_ipv6_local; /* IPv6 */
int push_ifconfig_ipv6_netbits; /* IPv6 */
struct in6_addr push_ifconfig_ipv6_remote; /* IPv6 */
+ bool push_ifconfig_ipv6_blocked; /* IPv6 */
bool enable_c2c;
bool duplicate_cn;
int cf_max;
@@ -450,9 +442,11 @@ struct options
const char *auth_user_pass_verify_script;
bool auth_user_pass_verify_script_via_file;
+ bool auth_token_generate;
+ unsigned int auth_token_lifetime;
#if PORT_SHARE
char *port_share_host;
- int port_share_port;
+ char *port_share_port;
const char *port_share_journal_dir;
#endif
#endif
@@ -464,8 +458,6 @@ struct options
const char *auth_user_pass_file;
struct options_pre_pull *pre_pull;
- int server_poll_timeout;
-
int scheduled_exit_interval;
#ifdef ENABLE_CLIENT_CR
@@ -478,9 +470,9 @@ struct options
const char *shared_secret_file;
const char *shared_secret_file_inline;
int key_direction;
- bool ciphername_defined;
const char *ciphername;
- bool authname_defined;
+ bool ncp_enabled;
+ const char *ncp_ciphers;
const char *authname;
int keysize;
const char *prng_hash;
@@ -497,7 +489,6 @@ struct options
bool use_prediction_resistance;
#endif
-#ifdef ENABLE_SSL
/* TLS (control channel) parms */
bool tls_server;
bool tls_client;
@@ -509,6 +500,7 @@ struct options
const char *priv_key_file;
const char *pkcs12_file;
const char *cipher_list;
+ const char *ecdh_curve;
const char *tls_verify;
int verify_x509_type;
const char *verify_x509_name;
@@ -518,6 +510,7 @@ struct options
const char *ca_file_inline;
const char *cert_file_inline;
const char *extra_certs_file_inline;
+ const char *crl_file_inline;
char *priv_key_file_inline;
const char *dh_file_inline;
const char *pkcs12_file_inline; /* contains the base64 encoding of pkcs12 file */
@@ -565,10 +558,14 @@ struct options
/* Old key allowed to live n seconds after new key goes active */
int transition_window;
- /* Special authentication MAC for TLS control channel */
- const char *tls_auth_file; /* shared secret */
+ /* Shared secret used for TLS control channel authentication */
+ const char *tls_auth_file;
const char *tls_auth_file_inline;
+ /* Shared secret used for TLS control channel authenticated encryption */
+ const char *tls_crypt_file;
+ const char *tls_crypt_inline;
+
/* Allow only one session */
bool single_session;
@@ -578,17 +575,15 @@ struct options
bool tls_exit;
-#endif /* ENABLE_SSL */
#endif /* ENABLE_CRYPTO */
-#ifdef ENABLE_X509_TRACK
const struct x509_track *x509_track;
-#endif
/* special state parms */
int foreign_option_index;
-#ifdef WIN32
+#ifdef _WIN32
+ HANDLE msg_channel;
const char *exit_event_name;
bool exit_event_initial_state;
bool show_net_up;
@@ -598,6 +593,18 @@ struct options
bool use_peer_id;
uint32_t peer_id;
+
+#if defined(ENABLE_CRYPTO_OPENSSL) && OPENSSL_VERSION_NUMBER >= 0x10001000
+ /* Keying Material Exporters [RFC 5705] */
+ const char *keying_material_exporter_label;
+ int keying_material_exporter_length;
+#endif
+
+ struct pull_filter_list *pull_filter_list;
+
+ /* Useful when packets sent by openvpn itself are not subject
+ to the routing tables that would move packets into the tunnel. */
+ bool allow_recursive_routing;
};
#define streq(x, y) (!strcmp((x), (y)))
@@ -617,7 +624,7 @@ struct options
#define OPT_P_PERSIST_IP (1<<9)
#define OPT_P_COMP (1<<10) /* TODO */
#define OPT_P_MESSAGES (1<<11)
-#define OPT_P_CRYPTO (1<<12) /* TODO */
+#define OPT_P_NCP (1<<12) /**< Negotiable crypto parameters */
#define OPT_P_TLS_PARMS (1<<13) /* TODO */
#define OPT_P_MTU (1<<14) /* TODO */
#define OPT_P_NICE (1<<15)
@@ -652,7 +659,7 @@ struct options
#define PUSH_DEFINED(opt) (false)
#endif
-#ifdef WIN32
+#ifdef _WIN32
#define ROUTE_OPTION_FLAGS(o) ((o)->route_method & ROUTE_METHOD_MASK)
#else
#define ROUTE_OPTION_FLAGS(o) (0)
@@ -690,7 +697,7 @@ void usage_small (void);
void show_library_versions(const unsigned int flags);
-#ifdef WIN32
+#ifdef _WIN32
void show_windows_version(const unsigned int flags);
#endif
@@ -722,7 +729,7 @@ void options_warning (char *actual, const char *expected);
void options_postprocess (struct options *options);
void pre_pull_save (struct options *o);
-void pre_pull_restore (struct options *o);
+void pre_pull_restore (struct options *o, struct gc_arena *gc);
bool apply_push_options (struct options *options,
struct buffer *buf,
@@ -784,20 +791,5 @@ void options_string_import (struct options *options,
bool get_ipv6_addr( const char * prefix_str, struct in6_addr *network,
unsigned int * netbits, int msglevel );
-/*
- * inline functions
- */
-static inline bool
-connection_list_defined (const struct options *o)
-{
- return o->connection_list != NULL;
-}
-
-static inline void
-connection_list_set_no_advance (struct options *o)
-{
- if (o->connection_list)
- o->connection_list->no_advance = true;
-}
#endif
diff --git a/src/openvpn/otime.h b/src/openvpn/otime.h
index 4ca1032..c0b0f38 100644
--- a/src/openvpn/otime.h
+++ b/src/openvpn/otime.h
@@ -76,8 +76,8 @@ openvpn_gettimeofday (struct timeval *tv, void *tz)
static inline void
update_time (void)
{
-#ifdef WIN32
- /* on WIN32, gettimeofday is faster than time(NULL) */
+#ifdef _WIN32
+ /* on _WIN32, gettimeofday is faster than time(NULL) */
struct timeval tv;
openvpn_gettimeofday (&tv, NULL);
#else
@@ -90,8 +90,8 @@ update_time (void)
static inline void
update_time (void)
{
-#if defined(WIN32)
- /* on WIN32, gettimeofday is faster than time(NULL) */
+#if defined(_WIN32)
+ /* on _WIN32, gettimeofday is faster than time(NULL) */
struct timeval tv;
if (!gettimeofday (&tv, NULL))
{
diff --git a/src/openvpn/packet_id.c b/src/openvpn/packet_id.c
index baa4966..9874519 100644
--- a/src/openvpn/packet_id.c
+++ b/src/openvpn/packet_id.c
@@ -76,10 +76,9 @@ packet_id_debug (int msglevel,
}
void
-packet_id_init (struct packet_id *p, bool tcp_mode, int seq_backtrack, int time_backtrack, const char *name, int unit)
+packet_id_init (struct packet_id *p, int seq_backtrack, int time_backtrack, const char *name, int unit)
{
- dmsg (D_PID_DEBUG, "PID packet_id_init tcp_mode=%d seq_backtrack=%d time_backtrack=%d",
- tcp_mode,
+ dmsg (D_PID_DEBUG, "PID packet_id_init seq_backtrack=%d time_backtrack=%d",
seq_backtrack,
time_backtrack);
@@ -88,7 +87,7 @@ packet_id_init (struct packet_id *p, bool tcp_mode, int seq_backtrack, int time_
p->rec.name = name;
p->rec.unit = unit;
- if (seq_backtrack && !tcp_mode)
+ if (seq_backtrack)
{
ASSERT (MIN_SEQ_BACKTRACK <= seq_backtrack && seq_backtrack <= MAX_SEQ_BACKTRACK);
ASSERT (MIN_TIME_BACKTRACK <= time_backtrack && time_backtrack <= MAX_TIME_BACKTRACK);
diff --git a/src/openvpn/packet_id.h b/src/openvpn/packet_id.h
index 3ddaab6..fb059b7 100644
--- a/src/openvpn/packet_id.h
+++ b/src/openvpn/packet_id.h
@@ -210,7 +210,7 @@ struct packet_id
struct packet_id_rec rec;
};
-void packet_id_init (struct packet_id *p, bool tcp_mode, int seq_backtrack, int time_backtrack, const char *name, int unit);
+void packet_id_init (struct packet_id *p, int seq_backtrack, int time_backtrack, const char *name, int unit);
void packet_id_free (struct packet_id *p);
/* should we accept an incoming packet id ? */
@@ -258,6 +258,12 @@ bool packet_id_write (const struct packet_id_net *pin, struct buffer *buf, bool
* Inline functions.
*/
+/** Is this struct packet_id initialized? */
+static inline bool packet_id_initialized (const struct packet_id *pid)
+{
+ return pid->rec.initialized;
+}
+
/* are we in enabled state? */
static inline bool
packet_id_persist_enabled (const struct packet_id_persist *p)
diff --git a/src/openvpn/pf.c b/src/openvpn/pf.c
index 461beed..a3208db 100644
--- a/src/openvpn/pf.c
+++ b/src/openvpn/pf.c
@@ -35,8 +35,8 @@
#if defined(ENABLE_PF)
#include "init.h"
-
#include "memdbg.h"
+#include "ssl_verify.h"
#include "pf-inline.h"
diff --git a/src/openvpn/pkcs11.c b/src/openvpn/pkcs11.c
index a1f13c5..2621058 100644
--- a/src/openvpn/pkcs11.c
+++ b/src/openvpn/pkcs11.c
@@ -744,9 +744,10 @@ _pkcs11_openvpn_show_pkcs11_ids_pin_prompt (
ASSERT (token!=NULL);
buf_printf (&pass_prompt, "Please enter '%s' token PIN or 'cancel': ", token->display);
-
- if (!get_console_input (BSTR (&pass_prompt), false, pin, pin_max)) {
- msg (M_FATAL, "Cannot read password from stdin");
+ if (!query_user_SINGLE(BSTR(&pass_prompt), BLEN(&pass_prompt),
+ pin, pin_max, false))
+ {
+ msg (M_FATAL, "Could not retrieve the PIN");
}
gc_free (&gc);
diff --git a/src/openvpn/pkcs11_polarssl.c b/src/openvpn/pkcs11_mbedtls.c
index a58beef..e208b61 100644
--- a/src/openvpn/pkcs11_polarssl.c
+++ b/src/openvpn/pkcs11_mbedtls.c
@@ -24,7 +24,7 @@
*/
/**
- * @file PKCS #11 PolarSSL backend
+ * @file PKCS #11 mbed TLS backend
*/
#ifdef HAVE_CONFIG_H
@@ -35,12 +35,12 @@
#include "syshead.h"
-#if defined(ENABLE_PKCS11) && defined(ENABLE_CRYPTO_POLARSSL)
+#if defined(ENABLE_PKCS11) && defined(ENABLE_CRYPTO_MBEDTLS)
#include "errlevel.h"
#include "pkcs11_backend.h"
-#include <polarssl/pkcs11.h>
-#include <polarssl/x509.h>
+#include <mbedtls/pkcs11.h>
+#include <mbedtls/x509.h>
int
pkcs11_init_tls_session(pkcs11h_certificate_t certificate,
@@ -50,21 +50,22 @@ pkcs11_init_tls_session(pkcs11h_certificate_t certificate,
ASSERT (NULL != ssl_ctx);
- ALLOC_OBJ_CLEAR (ssl_ctx->crt_chain, x509_crt);
- if (pkcs11_x509_cert_init(ssl_ctx->crt_chain, certificate)) {
- msg (M_FATAL, "PKCS#11: Cannot retrieve PolarSSL certificate object");
+ ALLOC_OBJ_CLEAR (ssl_ctx->crt_chain, mbedtls_x509_crt);
+ if (mbedtls_pkcs11_x509_cert_bind(ssl_ctx->crt_chain, certificate)) {
+ msg (M_FATAL, "PKCS#11: Cannot retrieve mbed TLS certificate object");
goto cleanup;
}
- ALLOC_OBJ_CLEAR (ssl_ctx->priv_key_pkcs11, pkcs11_context);
- if (pkcs11_priv_key_init(ssl_ctx->priv_key_pkcs11, certificate)) {
- msg (M_FATAL, "PKCS#11: Cannot initialize PolarSSL private key object");
+ ALLOC_OBJ_CLEAR (ssl_ctx->priv_key_pkcs11, mbedtls_pkcs11_context);
+ if (mbedtls_pkcs11_priv_key_bind(ssl_ctx->priv_key_pkcs11, certificate)) {
+ msg (M_FATAL, "PKCS#11: Cannot initialize mbed TLS private key object");
goto cleanup;
}
- ALLOC_OBJ_CLEAR (ssl_ctx->priv_key, pk_context);
- if (0 != pk_init_ctx_rsa_alt(ssl_ctx->priv_key, ssl_ctx->priv_key_pkcs11,
- ssl_pkcs11_decrypt, ssl_pkcs11_sign, ssl_pkcs11_key_len)) {
+ ALLOC_OBJ_CLEAR (ssl_ctx->priv_key, mbedtls_pk_context);
+ if (!mbed_ok(mbedtls_pk_setup_rsa_alt(ssl_ctx->priv_key,
+ ssl_ctx->priv_key_pkcs11, mbedtls_ssl_pkcs11_decrypt,
+ mbedtls_ssl_pkcs11_sign, mbedtls_ssl_pkcs11_key_len))) {
goto cleanup;
}
@@ -80,22 +81,22 @@ pkcs11_certificate_dn (pkcs11h_certificate_t cert, struct gc_arena *gc)
char *ret = NULL;
char dn[1024] = {0};
- x509_crt polar_cert = {0};
+ mbedtls_x509_crt mbed_crt = {0};
- if (pkcs11_x509_cert_init(&polar_cert, cert)) {
- msg (M_FATAL, "PKCS#11: Cannot retrieve PolarSSL certificate object");
+ if (mbedtls_pkcs11_x509_cert_bind(&mbed_crt, cert)) {
+ msg (M_FATAL, "PKCS#11: Cannot retrieve mbed TLS certificate object");
goto cleanup;
}
- if (-1 == x509_dn_gets (dn, sizeof(dn), &polar_cert.subject)) {
- msg (M_FATAL, "PKCS#11: PolarSSL cannot parse subject");
+ if (-1 == mbedtls_x509_dn_gets (dn, sizeof(dn), &mbed_crt.subject)) {
+ msg (M_FATAL, "PKCS#11: mbed TLS cannot parse subject");
goto cleanup;
}
ret = string_alloc(dn, gc);
cleanup:
- x509_crt_free(&polar_cert);
+ mbedtls_x509_crt_free(&mbed_crt);
return ret;
}
@@ -106,23 +107,23 @@ pkcs11_certificate_serial (pkcs11h_certificate_t cert, char *serial,
{
int ret = 1;
- x509_crt polar_cert = {0};
+ mbedtls_x509_crt mbed_crt = {0};
- if (pkcs11_x509_cert_init(&polar_cert, cert)) {
- msg (M_FATAL, "PKCS#11: Cannot retrieve PolarSSL certificate object");
+ if (mbedtls_pkcs11_x509_cert_bind(&mbed_crt, cert)) {
+ msg (M_FATAL, "PKCS#11: Cannot retrieve mbed TLS certificate object");
goto cleanup;
}
- if (-1 == x509_serial_gets (serial, serial_len, &polar_cert.serial)) {
- msg (M_FATAL, "PKCS#11: PolarSSL cannot parse serial");
+ if (-1 == mbedtls_x509_serial_gets (serial, serial_len, &mbed_crt.serial)) {
+ msg (M_FATAL, "PKCS#11: mbed TLS cannot parse serial");
goto cleanup;
}
ret = 0;
cleanup:
- x509_crt_free(&polar_cert);
+ mbedtls_x509_crt_free(&mbed_crt);
return ret;
}
-#endif /* defined(ENABLE_PKCS11) && defined(ENABLE_CRYPTO_POLARSSL) */
+#endif /* defined(ENABLE_PKCS11) && defined(ENABLE_CRYPTO_MBEDTLS) */
diff --git a/src/openvpn/platform.c b/src/openvpn/platform.c
index 16d4dac..6343647 100644
--- a/src/openvpn/platform.c
+++ b/src/openvpn/platform.c
@@ -158,7 +158,7 @@ platform_nice (int niceval)
unsigned int
platform_getpid ()
{
-#ifdef WIN32
+#ifdef _WIN32
return (unsigned int) GetCurrentProcessId ();
#else
#ifdef HAVE_GETPID
@@ -190,7 +190,7 @@ int
platform_chdir (const char* dir)
{
#ifdef HAVE_CHDIR
-#ifdef WIN32
+#ifdef _WIN32
int res;
struct gc_arena gc = gc_new ();
res = _wchdir (wide_string (dir, &gc));
@@ -210,7 +210,7 @@ platform_chdir (const char* dir)
bool
platform_system_ok (int stat)
{
-#ifdef WIN32
+#ifdef _WIN32
return stat == 0;
#else
return stat != -1 && WIFEXITED (stat) && WEXITSTATUS (stat) == 0;
@@ -220,7 +220,7 @@ platform_system_ok (int stat)
int
platform_access (const char *path, int mode)
{
-#ifdef WIN32
+#ifdef _WIN32
struct gc_arena gc = gc_new ();
int ret = _waccess (wide_string (path, &gc), mode & ~X_OK);
gc_free (&gc);
@@ -236,7 +236,7 @@ platform_access (const char *path, int mode)
void
platform_sleep_milliseconds (unsigned int n)
{
-#ifdef WIN32
+#ifdef _WIN32
Sleep (n);
#else
struct timeval tv;
@@ -252,7 +252,7 @@ platform_sleep_milliseconds (unsigned int n)
void
platform_sleep_until_signal (void)
{
-#ifdef WIN32
+#ifdef _WIN32
ASSERT (0);
#else
select (0, NULL, NULL, NULL, NULL);
@@ -263,7 +263,7 @@ platform_sleep_until_signal (void)
bool
platform_unlink (const char *filename)
{
-#if defined(WIN32)
+#if defined(_WIN32)
struct gc_arena gc = gc_new ();
BOOL ret = DeleteFileW (wide_string (filename, &gc));
gc_free (&gc);
@@ -278,7 +278,7 @@ platform_unlink (const char *filename)
FILE *
platform_fopen (const char *path, const char *mode)
{
-#ifdef WIN32
+#ifdef _WIN32
struct gc_arena gc = gc_new ();
FILE *f = _wfopen (wide_string (path, &gc), wide_string (mode, &gc));
gc_free (&gc);
@@ -291,7 +291,7 @@ platform_fopen (const char *path, const char *mode)
int
platform_open (const char *path, int flags, int mode)
{
-#ifdef WIN32
+#ifdef _WIN32
struct gc_arena gc = gc_new ();
int fd = _wopen (wide_string (path, &gc), flags, mode);
gc_free (&gc);
@@ -304,7 +304,7 @@ platform_open (const char *path, int flags, int mode)
int
platform_stat (const char *path, platform_stat_t *buf)
{
-#ifdef WIN32
+#ifdef _WIN32
struct gc_arena gc = gc_new ();
int res = _wstat (wide_string (path, &gc), buf);
gc_free (&gc);
diff --git a/src/openvpn/platform.h b/src/openvpn/platform.h
index 7c0a4d7..fe2685a 100644
--- a/src/openvpn/platform.h
+++ b/src/openvpn/platform.h
@@ -130,7 +130,7 @@ int platform_putenv (char *string);
FILE *platform_fopen (const char *path, const char *mode);
int platform_open (const char *path, int flags, int mode);
-#ifdef WIN32
+#ifdef _WIN32
typedef struct _stat platform_stat_t;
#else
typedef struct stat platform_stat_t;
diff --git a/src/openvpn/plugin.c b/src/openvpn/plugin.c
index 4e5e6ce..2443438 100644
--- a/src/openvpn/plugin.c
+++ b/src/openvpn/plugin.c
@@ -27,6 +27,9 @@
#elif defined(_MSC_VER)
#include "config-msvc.h"
#endif
+#ifdef HAVE_CONFIG_VERSION_H
+#include "config-version.h"
+#endif
#include "syshead.h"
@@ -172,7 +175,7 @@ plugin_option_list_print (const struct plugin_option_list *list, int msglevel)
}
#endif
-#ifndef WIN32
+#ifndef _WIN32
static void
libdl_resolve_symbol (void *handle, void **dest, const char *symbol, const char *plugin_name, const unsigned int flags)
@@ -203,7 +206,7 @@ plugin_init_item (struct plugin *p, const struct plugin_option *o)
p->so_pathname = o->so_pathname;
p->plugin_type_mask = plugin_supported_types ();
-#ifndef WIN32
+#ifndef _WIN32
p->handle = NULL;
#if defined(PLUGIN_LIBDIR)
@@ -347,6 +350,17 @@ static struct openvpn_plugin_callbacks callbacks = {
plugin_vlog
};
+
+/* Provide a wrapper macro for a version patch level string to plug-ins.
+ * This is located here purely to not make the code too messy with #ifndef
+ * inside a struct declaration
+ */
+#ifndef CONFIGURE_GIT_REVISION
+# define _OPENVPN_PATCH_LEVEL OPENVPN_VERSION_PATCH
+#else
+# define _OPENVPN_PATCH_LEVEL "git:" CONFIGURE_GIT_REVISION CONFIGURE_GIT_FLAGS
+#endif
+
static void
plugin_open_item (struct plugin *p,
const struct plugin_option *o,
@@ -375,7 +389,12 @@ plugin_open_item (struct plugin *p,
(const char ** const) o->argv,
(const char ** const) envp,
&callbacks,
- SSLAPI };
+ SSLAPI,
+ PACKAGE_VERSION,
+ OPENVPN_VERSION_MAJOR,
+ OPENVPN_VERSION_MINOR,
+ _OPENVPN_PATCH_LEVEL
+ };
struct openvpn_plugin_args_open_return retargs;
CLEAR(retargs);
@@ -420,7 +439,7 @@ plugin_call_item (const struct plugin *p,
const struct argv *av,
struct openvpn_plugin_string_list **retlist,
const char **envp
-#ifdef ENABLE_SSL
+#ifdef ENABLE_CRYPTO
, int certdepth,
openvpn_x509_cert_t *current_cert
#endif
@@ -449,7 +468,7 @@ plugin_call_item (const struct plugin *p,
(const char ** const) envp,
p->plugin_handle,
per_client_context,
-#ifdef ENABLE_SSL
+#ifdef ENABLE_CRYPTO
(current_cert ? certdepth : -1),
current_cert
#else
@@ -500,10 +519,10 @@ plugin_close_item (struct plugin *p)
if (p->plugin_handle)
(*p->close)(p->plugin_handle);
-#ifndef WIN32
+#ifndef _WIN32
if (dlclose (p->handle))
msg (M_WARN, "PLUGIN_CLOSE: dlclose() failed on plugin: %s", p->so_pathname);
-#elif defined(WIN32)
+#elif defined(_WIN32)
if (!FreeLibrary (p->module))
msg (M_WARN, "PLUGIN_CLOSE: FreeLibrary() failed on plugin: %s", p->so_pathname);
#endif
@@ -659,7 +678,7 @@ plugin_call_ssl (const struct plugin_list *pl,
const struct argv *av,
struct plugin_return *pr,
struct env_set *es
-#ifdef ENABLE_SSL
+#ifdef ENABLE_CRYPTO
, int certdepth,
openvpn_x509_cert_t *current_cert
#endif
@@ -689,7 +708,7 @@ plugin_call_ssl (const struct plugin_list *pl,
av,
pr ? &pr->list[i] : NULL,
envp
-#ifdef ENABLE_SSL
+#ifdef ENABLE_CRYPTO
,certdepth,
current_cert
#endif
diff --git a/src/openvpn/plugin.h b/src/openvpn/plugin.h
index 2f8416b..b1e0458 100644
--- a/src/openvpn/plugin.h
+++ b/src/openvpn/plugin.h
@@ -32,8 +32,8 @@
#ifdef ENABLE_CRYPTO_OPENSSL
#include "ssl_verify_openssl.h"
#endif
-#ifdef ENABLE_CRYPTO_POLARSSL
-#include "ssl_verify_polarssl.h"
+#ifdef ENABLE_CRYPTO_MBEDTLS
+#include "ssl_verify_mbedtls.h"
#endif
#include "openvpn-plugin.h"
@@ -59,7 +59,7 @@ struct plugin {
unsigned int plugin_type_mask;
int requested_initialization_point;
-#ifndef WIN32
+#ifndef _WIN32
void *handle;
#else
HMODULE module;
@@ -127,7 +127,7 @@ int plugin_call_ssl (const struct plugin_list *pl,
const struct argv *av,
struct plugin_return *pr,
struct env_set *es
-#ifdef ENABLE_SSL
+#ifdef ENABLE_CRYPTO
, int current_cert_depth,
openvpn_x509_cert_t *current_cert
#endif
@@ -183,7 +183,7 @@ plugin_call_ssl (const struct plugin_list *pl,
const struct argv *av,
struct plugin_return *pr,
struct env_set *es
-#ifdef ENABLE_SSL
+#ifdef ENABLE_CRYPTO
, int current_cert_depth,
openvpn_x509_cert_t *current_cert
#endif
@@ -202,7 +202,7 @@ plugin_call(const struct plugin_list *pl,
struct env_set *es)
{
return plugin_call_ssl(pl, type, av, pr, es
-#ifdef ENABLE_SSL
+#ifdef ENABLE_CRYPTO
, -1, NULL
#endif
);
diff --git a/src/openvpn/proto.h b/src/openvpn/proto.h
index f91e787..07612c8 100644
--- a/src/openvpn/proto.h
+++ b/src/openvpn/proto.h
@@ -219,6 +219,45 @@ struct ip_tcp_udp_hdr {
- sizeof(struct openvpn_tcphdr))
/*
+ * This returns an ip protocol version of packet inside tun
+ * and offset of IP header (via parameter).
+ */
+inline static int get_tun_ip_ver(int tunnel_type, struct buffer *buf, int *ip_hdr_offset)
+{
+ int ip_ver = -1;
+
+ /* for tun get ip version from ip header */
+ if (tunnel_type == DEV_TYPE_TUN)
+ {
+ *ip_hdr_offset = 0;
+ if (likely(BLEN (buf) >= (int) sizeof (struct openvpn_iphdr)))
+ {
+ ip_ver = OPENVPN_IPH_GET_VER (*BPTR(buf));
+ }
+ }
+ else if (tunnel_type == DEV_TYPE_TAP)
+ {
+ *ip_hdr_offset = (int)(sizeof (struct openvpn_ethhdr));
+ /* for tap get ip version from eth header */
+ if (likely(BLEN (buf) >= *ip_hdr_offset))
+ {
+ const struct openvpn_ethhdr *eh = (const struct openvpn_ethhdr *) BPTR (buf);
+ uint16_t proto = ntohs (eh->proto);
+ if (proto == OPENVPN_ETH_P_IPV6)
+ {
+ ip_ver = 6;
+ }
+ else if (proto == OPENVPN_ETH_P_IPV4)
+ {
+ ip_ver = 4;
+ }
+ }
+ }
+
+ return ip_ver;
+}
+
+/*
* If raw tunnel packet is IPv4 or IPv6, return true and increment
* buffer offset to start of IP header.
*/
diff --git a/src/openvpn/proxy.c b/src/openvpn/proxy.c
index 89989d1..0f78020 100644
--- a/src/openvpn/proxy.c
+++ b/src/openvpn/proxy.c
@@ -41,8 +41,7 @@
#include "httpdigest.h"
#include "ntlm.h"
#include "memdbg.h"
-
-#ifdef ENABLE_HTTP_PROXY
+#include "forward.h"
#define UP_TYPE_PROXY "HTTP Proxy"
@@ -54,7 +53,6 @@ init_http_proxy_options_once (struct http_proxy_options **hpo,
{
ALLOC_OBJ_CLEAR_GC (*hpo, struct http_proxy_options, gc);
/* http proxy defaults */
- (*hpo)->timeout = 5;
(*hpo)->http_version = "1.0";
}
return *hpo;
@@ -243,6 +241,8 @@ get_user_pass_http (struct http_proxy_info *p, const bool force)
unsigned int flags = GET_USER_PASS_MANAGEMENT;
if (p->queried_creds)
flags |= GET_USER_PASS_PREVIOUS_CREDS_FAILED;
+ if (p->options.inline_creds)
+ flags |= GET_USER_PASS_INLINE_CREDS;
get_user_pass (&static_proxy_user_pass,
p->options.auth_file,
UP_TYPE_PROXY,
@@ -257,6 +257,8 @@ clear_user_pass_http (void)
purge_user_pass (&static_proxy_user_pass, true);
}
+#if 0
+/* function only used in #if 0 debug statement */
static void
dump_residual (socket_descriptor_t sd,
int timeout,
@@ -271,6 +273,7 @@ dump_residual (socket_descriptor_t sd,
msg (D_PROXY, "PROXY HEADER: '%s'", buf);
}
}
+#endif
/*
* Extract the Proxy-Authenticate header from the stream.
@@ -439,12 +442,11 @@ struct http_proxy_info *
http_proxy_new (const struct http_proxy_options *o)
{
struct http_proxy_info *p;
- struct http_proxy_options opt;
if (!o || !o->server)
msg (M_FATAL, "HTTP_PROXY: server not specified");
- ASSERT (legal_ipv4_port (o->port));
+ ASSERT ( o->port);
ALLOC_OBJ_CLEAR (p, struct http_proxy_info);
p->options = *o;
@@ -490,10 +492,72 @@ http_proxy_close (struct http_proxy_info *hp)
}
bool
+add_proxy_headers (struct http_proxy_info *p,
+ socket_descriptor_t sd, /* already open to proxy */
+ const char *host, /* openvpn server remote */
+ const char* port /* openvpn server port */
+ )
+{
+ char buf[512];
+ int i;
+ bool host_header_sent=false;
+
+ /*
+ * Send custom headers if provided
+ * If content is NULL the whole header is in name
+ * Also remember if we already sent a Host: header
+ */
+ for (i=0; i < MAX_CUSTOM_HTTP_HEADER && p->options.custom_headers[i].name;i++)
+ {
+ if (p->options.custom_headers[i].content)
+ {
+ openvpn_snprintf (buf, sizeof(buf), "%s: %s",
+ p->options.custom_headers[i].name,
+ p->options.custom_headers[i].content);
+ if (!strcasecmp(p->options.custom_headers[i].name, "Host"))
+ host_header_sent=true;
+ }
+ else
+ {
+ openvpn_snprintf (buf, sizeof(buf), "%s",
+ p->options.custom_headers[i].name);
+ if (!strncasecmp(p->options.custom_headers[i].name, "Host:", 5))
+ host_header_sent=true;
+ }
+
+ msg (D_PROXY, "Send to HTTP proxy: '%s'", buf);
+ if (!send_line_crlf (sd, buf))
+ return false;
+ }
+
+ if (!host_header_sent)
+ {
+ openvpn_snprintf (buf, sizeof(buf), "Host: %s", host);
+ msg (D_PROXY, "Send to HTTP proxy: '%s'", buf);
+ if (!send_line_crlf(sd, buf))
+ return false;
+ }
+
+ /* send User-Agent string if provided */
+ if (p->options.user_agent)
+ {
+ openvpn_snprintf (buf, sizeof(buf), "User-Agent: %s",
+ p->options.user_agent);
+ msg (D_PROXY, "Send to HTTP proxy: '%s'", buf);
+ if (!send_line_crlf (sd, buf))
+ return false;
+ }
+
+ return true;
+}
+
+
+bool
establish_http_proxy_passthru (struct http_proxy_info *p,
socket_descriptor_t sd, /* already open to proxy */
const char *host, /* openvpn server remote */
- const int port, /* openvpn server port */
+ const char *port, /* openvpn server port */
+ struct event_timeout* server_poll_timeout,
struct buffer *lookahead,
volatile int *signal_received)
{
@@ -521,7 +585,7 @@ establish_http_proxy_passthru (struct http_proxy_info *p,
else
{
/* format HTTP CONNECT message */
- openvpn_snprintf (buf, sizeof(buf), "CONNECT %s:%d HTTP/%s",
+ openvpn_snprintf (buf, sizeof(buf), "CONNECT %s:%s HTTP/%s",
host,
port,
p->options.http_version);
@@ -532,18 +596,8 @@ establish_http_proxy_passthru (struct http_proxy_info *p,
if (!send_line_crlf (sd, buf))
goto error;
- openvpn_snprintf(buf, sizeof(buf), "Host: %s", host);
- if (!send_line_crlf(sd, buf))
- goto error;
-
- /* send User-Agent string if provided */
- if (p->options.user_agent)
- {
- openvpn_snprintf (buf, sizeof(buf), "User-Agent: %s",
- p->options.user_agent);
- if (!send_line_crlf (sd, buf))
- goto error;
- }
+ if (!add_proxy_headers (p, sd, host, port))
+ goto error;
/* auth specified? */
switch (p->auth_method)
@@ -586,7 +640,7 @@ establish_http_proxy_passthru (struct http_proxy_info *p,
goto error;
/* receive reply from proxy */
- if (!recv_line (sd, buf, sizeof(buf), p->options.timeout, true, NULL, signal_received))
+ if (!recv_line (sd, buf, sizeof(buf), get_server_poll_remaining_time (server_poll_timeout), true, NULL, signal_received))
goto error;
/* remove trailing CR, LF */
@@ -615,7 +669,7 @@ establish_http_proxy_passthru (struct http_proxy_info *p,
while (true)
{
- if (!recv_line (sd, buf, sizeof(buf), p->options.timeout, true, NULL, signal_received))
+ if (!recv_line (sd, buf, sizeof(buf), get_server_poll_remaining_time (server_poll_timeout), true, NULL, signal_received))
goto error;
chomp (buf);
msg (D_PROXY, "HTTP proxy returned: '%s'", buf);
@@ -642,7 +696,7 @@ establish_http_proxy_passthru (struct http_proxy_info *p,
/* now send the phase 3 reply */
/* format HTTP CONNECT message */
- openvpn_snprintf (buf, sizeof(buf), "CONNECT %s:%d HTTP/%s",
+ openvpn_snprintf (buf, sizeof(buf), "CONNECT %s:%s HTTP/%s",
host,
port,
p->options.http_version);
@@ -658,14 +712,11 @@ establish_http_proxy_passthru (struct http_proxy_info *p,
if (!send_line_crlf (sd, buf))
goto error;
-
/* send HOST etc, */
- openvpn_snprintf (buf, sizeof(buf), "Host: %s", host);
- msg (D_PROXY, "Send to HTTP proxy: '%s'", buf);
- if (!send_line_crlf (sd, buf))
- goto error;
+ if (!add_proxy_headers (p, sd, host, port))
+ goto error;
- msg (D_PROXY, "Attempting NTLM Proxy-Authorization phase 3");
+ msg (D_PROXY, "Attempting NTLM Proxy-Authorization phase 3");
{
const char *np3 = ntlm_phase_3 (p, buf2, &gc);
if (!np3)
@@ -685,7 +736,7 @@ establish_http_proxy_passthru (struct http_proxy_info *p,
goto error;
/* receive reply from proxy */
- if (!recv_line (sd, buf, sizeof(buf), p->options.timeout, true, NULL, signal_received))
+ if (!recv_line (sd, buf, sizeof(buf), get_server_poll_remaining_time (server_poll_timeout), true, NULL, signal_received))
goto error;
/* remove trailing CR, LF */
@@ -730,7 +781,7 @@ establish_http_proxy_passthru (struct http_proxy_info *p,
/* build the digest response */
- openvpn_snprintf (uri, sizeof(uri), "%s:%d",
+ openvpn_snprintf (uri, sizeof(uri), "%s:%s",
host,
port);
@@ -771,9 +822,7 @@ establish_http_proxy_passthru (struct http_proxy_info *p,
goto error;
/* send HOST etc, */
- openvpn_snprintf (buf, sizeof(buf), "Host: %s", host);
- msg (D_PROXY, "Send to HTTP proxy: '%s'", buf);
- if (!send_line_crlf (sd, buf))
+ if (!add_proxy_headers (p, sd, host, port))
goto error;
/* send digest response */
@@ -795,7 +844,7 @@ establish_http_proxy_passthru (struct http_proxy_info *p,
goto error;
/* receive reply from proxy */
- if (!recv_line (sd, buf, sizeof(buf), p->options.timeout, true, NULL, signal_received))
+ if (!recv_line (sd, buf, sizeof(buf), get_server_poll_remaining_time (server_poll_timeout), true, NULL, signal_received))
goto error;
/* remove trailing CR, LF */
@@ -819,7 +868,7 @@ establish_http_proxy_passthru (struct http_proxy_info *p,
/* figure out what kind of authentication the proxy needs */
char *pa = NULL;
const int method = get_proxy_authenticate(sd,
- p->options.timeout,
+ get_server_poll_remaining_time (server_poll_timeout),
&pa,
NULL,
signal_received);
@@ -863,7 +912,7 @@ establish_http_proxy_passthru (struct http_proxy_info *p,
msg (D_LINK_ERRORS, "HTTP proxy returned bad status");
#if 0
/* DEBUGGING -- show a multi-line HTTP error response */
- dump_residual(sd, p->options.timeout, signal_received);
+ dump_residual(sd, get_server_poll_remaining_time (server_poll_timeout), signal_received);
#endif
goto error;
}
@@ -871,7 +920,7 @@ establish_http_proxy_passthru (struct http_proxy_info *p,
/* SUCCESS */
/* receive line from proxy and discard */
- if (!recv_line (sd, NULL, 0, p->options.timeout, true, NULL, signal_received))
+ if (!recv_line (sd, NULL, 0, get_server_poll_remaining_time (server_poll_timeout), true, NULL, signal_received))
goto error;
/*
@@ -894,14 +943,8 @@ establish_http_proxy_passthru (struct http_proxy_info *p,
return ret;
error:
- /* on error, should we exit or restart? */
if (!*signal_received)
- *signal_received = (p->options.retry ? SIGUSR1 : SIGTERM); /* SOFT-SIGUSR1 -- HTTP proxy error */
+ *signal_received = SIGUSR1; /* SOFT-SIGUSR1 -- HTTP proxy error */
gc_free (&gc);
return ret;
}
-
-#else
-static void dummy(void) {}
-#endif /* ENABLE_HTTP_PROXY */
-
diff --git a/src/openvpn/proxy.h b/src/openvpn/proxy.h
index 5e476f1..7d2581c 100644
--- a/src/openvpn/proxy.h
+++ b/src/openvpn/proxy.h
@@ -28,8 +28,6 @@
#include "buffer.h"
#include "misc.h"
-#ifdef ENABLE_HTTP_PROXY
-
/* HTTP CONNECT authentication methods */
#define HTTP_AUTH_NONE 0
#define HTTP_AUTH_BASIC 1
@@ -38,11 +36,15 @@
#define HTTP_AUTH_NTLM2 4
#define HTTP_AUTH_N 5 /* number of HTTP_AUTH methods */
+struct http_custom_header {
+ const char *name;
+ const char *content;
+};
+
+#define MAX_CUSTOM_HTTP_HEADER 10
struct http_proxy_options {
const char *server;
- int port;
- bool retry;
- int timeout;
+ const char *port;
# define PAR_NO 0 /* don't support any auth retries */
# define PAR_ALL 1 /* allow all proxy auth protocols */
@@ -53,11 +55,13 @@ struct http_proxy_options {
const char *auth_file;
const char *http_version;
const char *user_agent;
+ struct http_custom_header custom_headers[MAX_CUSTOM_HTTP_HEADER];
+ bool inline_creds;
};
struct http_proxy_options_simple {
const char *server;
- int port;
+ const char *port;
int auth_retry;
};
@@ -80,13 +84,12 @@ void http_proxy_close (struct http_proxy_info *hp);
bool establish_http_proxy_passthru (struct http_proxy_info *p,
socket_descriptor_t sd, /* already open to proxy */
const char *host, /* openvpn server remote */
- const int port, /* openvpn server port */
+ const char *port, /* openvpn server port */
+ struct event_timeout* server_poll_timeout,
struct buffer *lookahead,
volatile int *signal_received);
uint8_t *make_base64_string2 (const uint8_t *str, int str_len, struct gc_arena *gc);
uint8_t *make_base64_string (const uint8_t *str, struct gc_arena *gc);
-#endif /* ENABLE_HTTP_PROXY */
-
#endif /* PROXY_H */
diff --git a/src/openvpn/ps.c b/src/openvpn/ps.c
index 6495dc7..2cb68f1 100644
--- a/src/openvpn/ps.c
+++ b/src/openvpn/ps.c
@@ -223,12 +223,12 @@ port_share_sendmsg (const socket_descriptor_t sd,
if (socket_defined (sd_send))
{
- *((socket_descriptor_t*)CMSG_DATA(h)) = sd_send;
+ memcpy (CMSG_DATA(h), &sd_send, sizeof (sd_send));
}
else
{
socketpair (PF_UNIX, SOCK_DGRAM, 0, sd_null);
- *((socket_descriptor_t*)CMSG_DATA(h)) = sd_null[0];
+ memcpy (CMSG_DATA(h), &sd_null[0], sizeof (sd_null[0]));
}
status = sendmsg (sd, &mesg, MSG_NOSIGNAL);
@@ -330,8 +330,8 @@ journal_add (const char *journal_dir, struct proxy_connection *pc, struct proxy_
if (!getpeername (pc->sd, (struct sockaddr *) &from.addr.sa, &slen)
&& !getsockname (cp->sd, (struct sockaddr *) &to.addr.sa, &dlen))
{
- const char *f = print_sockaddr_ex (&from, ":", PS_SHOW_PORT, &gc);
- const char *t = print_sockaddr_ex (&to, ":", PS_SHOW_PORT, &gc);
+ const char *f = print_openvpn_sockaddr (&from, &gc);
+ const char *t = print_openvpn_sockaddr (&to, &gc);
fnlen = strlen(journal_dir) + strlen(t) + 2;
jfn = (char *) malloc(fnlen);
check_malloc_return (jfn);
@@ -340,7 +340,8 @@ journal_add (const char *journal_dir, struct proxy_connection *pc, struct proxy_
fd = platform_open (jfn, O_CREAT | O_TRUNC | O_WRONLY, S_IRUSR | S_IWUSR | S_IRGRP);
if (fd != -1)
{
- write(fd, f, strlen(f));
+ if (write(fd, f, strlen(f)) != strlen(f))
+ msg(M_WARN, "PORT SHARE: writing to journal file (%s) failed", jfn);
close (fd);
cp->jfn = jfn;
}
@@ -371,17 +372,6 @@ proxy_list_close (struct proxy_connection **list)
}
}
-static void
-sock_addr_set (struct openvpn_sockaddr *osaddr,
- const in_addr_t addr,
- const int port)
-{
- CLEAR (*osaddr);
- osaddr->addr.in4.sin_family = AF_INET;
- osaddr->addr.in4.sin_addr.s_addr = htonl (addr);
- osaddr->addr.in4.sin_port = htons (port);
-}
-
static inline void
proxy_connection_io_requeue (struct proxy_connection *pc, const int rwflags_new, struct event_set *es)
{
@@ -403,26 +393,23 @@ proxy_connection_io_requeue (struct proxy_connection *pc, const int rwflags_new,
static bool
proxy_entry_new (struct proxy_connection **list,
struct event_set *es,
- const in_addr_t server_addr,
- const int server_port,
+ const struct sockaddr_in server_addr,
const socket_descriptor_t sd_client,
struct buffer *initial_data,
const char *journal_dir)
{
- struct openvpn_sockaddr osaddr;
socket_descriptor_t sd_server;
int status;
struct proxy_connection *pc;
struct proxy_connection *cp;
/* connect to port share server */
- sock_addr_set (&osaddr, server_addr, server_port);
if ((sd_server = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
{
msg (M_WARN|M_ERRNO, "PORT SHARE PROXY: cannot create socket");
return false;
}
- status = openvpn_connect (sd_server, &osaddr, 5, NULL);
+ status = openvpn_connect (sd_server,(const struct sockaddr*) &server_addr, 5, NULL);
if (status)
{
msg (M_WARN, "PORT SHARE PROXY: connect to port-share server failed");
@@ -482,8 +469,7 @@ static bool
control_message_from_parent (const socket_descriptor_t sd_control,
struct proxy_connection **list,
struct event_set *es,
- const in_addr_t server_addr,
- const int server_port,
+ const struct sockaddr_in server_addr,
const int max_initial_buf,
const char *journal_dir)
{
@@ -516,7 +502,8 @@ control_message_from_parent (const socket_descriptor_t sd_control,
h->cmsg_len = CMSG_LEN(sizeof(socket_descriptor_t));
h->cmsg_level = SOL_SOCKET;
h->cmsg_type = SCM_RIGHTS;
- *((socket_descriptor_t*)CMSG_DATA(h)) = SOCKET_UNDEFINED;
+ static const socket_descriptor_t socket_undefined = SOCKET_UNDEFINED;
+ memcpy (CMSG_DATA(h), &socket_undefined, sizeof(socket_undefined));
status = recvmsg (sd_control, &mesg, MSG_NOSIGNAL);
if (status != -1)
@@ -530,7 +517,8 @@ control_message_from_parent (const socket_descriptor_t sd_control,
}
else
{
- const socket_descriptor_t received_fd = *((socket_descriptor_t*)CMSG_DATA(h));
+ socket_descriptor_t received_fd;
+ memcpy (&received_fd, CMSG_DATA(h), sizeof(received_fd));
dmsg (D_PS_PROXY_DEBUG, "PORT SHARE PROXY: RECEIVED sd=%d", (int)received_fd);
if (status >= 2 && command == COMMAND_REDIRECT)
@@ -539,7 +527,6 @@ control_message_from_parent (const socket_descriptor_t sd_control,
if (proxy_entry_new (list,
es,
server_addr,
- server_port,
received_fd,
&buf,
journal_dir))
@@ -716,8 +703,7 @@ proxy_connection_io_dispatch (struct proxy_connection *pc,
* This is the main function for the port share proxy background process.
*/
static void
-port_share_proxy (const in_addr_t hostaddr,
- const int port,
+port_share_proxy (const struct sockaddr_in hostaddr,
const socket_descriptor_t sd_control,
const int max_initial_buf,
const char *journal_dir)
@@ -754,7 +740,7 @@ port_share_proxy (const in_addr_t hostaddr,
const struct event_set_return *e = &esr[i];
if (e->arg == sd_control_marker)
{
- if (!control_message_from_parent (sd_control, &list, es, hostaddr, port, max_initial_buf, journal_dir))
+ if (!control_message_from_parent (sd_control, &list, es, hostaddr, max_initial_buf, journal_dir))
goto done;
}
else
@@ -789,14 +775,16 @@ port_share_proxy (const in_addr_t hostaddr,
*/
struct port_share *
port_share_open (const char *host,
- const int port,
+ const char *port,
const int max_initial_buf,
const char *journal_dir)
{
pid_t pid;
socket_descriptor_t fd[2];
- in_addr_t hostaddr;
+ struct sockaddr_in hostaddr;
struct port_share *ps;
+ int status;
+ struct addrinfo* ai;
ALLOC_OBJ_CLEAR (ps, struct port_share);
ps->foreground_fd = -1;
@@ -805,7 +793,12 @@ port_share_open (const char *host,
/*
* Get host's IP address
*/
- hostaddr = getaddr (GETADDR_RESOLVE|GETADDR_HOST_ORDER|GETADDR_FATAL, host, 0, NULL, NULL);
+
+ status = openvpn_getaddrinfo (GETADDR_RESOLVE|GETADDR_FATAL,
+ host, port, 0, NULL, AF_INET, &ai);
+ ASSERT (status==0);
+ hostaddr = *((struct sockaddr_in*) ai->ai_addr);
+ freeaddrinfo(ai);
/*
* Make a socket for foreground and background processes
@@ -881,7 +874,7 @@ port_share_open (const char *host,
prng_init (NULL, 0);
/* execute the event loop */
- port_share_proxy (hostaddr, port, fd[1], max_initial_buf, journal_dir);
+ port_share_proxy (hostaddr, fd[1], max_initial_buf, journal_dir);
openvpn_close_socket (fd[1]);
diff --git a/src/openvpn/ps.h b/src/openvpn/ps.h
index 4280635..e8919d4 100644
--- a/src/openvpn/ps.h
+++ b/src/openvpn/ps.h
@@ -44,7 +44,7 @@ struct port_share {
extern struct port_share *port_share;
struct port_share *port_share_open (const char *host,
- const int port,
+ const char *port,
const int max_initial_buf,
const char *journal_dir);
diff --git a/src/openvpn/push.c b/src/openvpn/push.c
index 71f39c1..f86bdd3 100644
--- a/src/openvpn/push.c
+++ b/src/openvpn/push.c
@@ -33,12 +33,40 @@
#include "push.h"
#include "options.h"
#include "ssl.h"
+#include "ssl_verify.h"
#include "manage.h"
#include "memdbg.h"
#if P2MP
+static char push_reply_cmd[] = "PUSH_REPLY";
+
+/**
+ * Add an option to the given push list by providing a format string.
+ *
+ * The string added to the push options is allocated in o->gc, so the caller
+ * does not have to preserve anything.
+ *
+ * @param gc GC arena where options are allocated
+ * @param push_list Push list containing options
+ * @param msglevel The message level to use when printing errors
+ * @param fmt Format string for the option
+ * @param ... Format string arguments
+ *
+ * @return true on success, false on failure.
+ */
+static bool push_option_fmt(struct gc_arena *gc, struct push_list *push_list,
+ int msglevel, const char *fmt, ...)
+#ifdef __GNUC__
+#if __USE_MINGW_ANSI_STDIO
+ __attribute__ ((format (gnu_printf, 4, 5)))
+#else
+ __attribute__ ((format (__printf__, 4, 5)))
+#endif
+#endif
+ ;
+
/*
* Auth username/password
*
@@ -49,7 +77,8 @@ void
receive_auth_failed (struct context *c, const struct buffer *buffer)
{
msg (M_VERB0, "AUTH: Received control message: %s", BSTR(buffer));
- connection_list_set_no_advance(&c->options);
+ c->options.no_advance=true;
+
if (c->options.pull)
{
switch (auth_retry_get ())
@@ -120,8 +149,7 @@ server_pushed_signal (struct context *c, const struct buffer *buffer, const bool
else if (m[i] == 'N')
{
/* next server? */
- if (c->options.connection_list)
- c->options.connection_list->no_advance = false;
+ c->options.no_advance = false;
}
}
}
@@ -214,11 +242,37 @@ incoming_push_message (struct context *c, const struct buffer *buffer)
{
c->options.push_option_types_found |= option_types_found;
+ /* delay bringing tun/tap up until --push parms received from remote */
if (status == PUSH_MSG_REPLY)
- do_up (c, true, c->options.push_option_types_found ); /* delay bringing tun/tap up until --push parms received from remote */
+ {
+ if (!do_up (c, true, c->options.push_option_types_found))
+ {
+ msg (D_PUSH_ERRORS, "Failed to open tun/tap interface");
+ goto error;
+ }
+ }
event_timeout_clear (&c->c2.push_request_interval);
}
+ else if (status == PUSH_MSG_REQUEST)
+ {
+ if (c->options.mode == MODE_SERVER)
+ {
+ struct tls_session *session = &c->c2.tls_multi->session[TM_ACTIVE];
+ /* Do not regenerate keys if client send a second push request */
+ if (!session->key[KS_PRIMARY].crypto_options.key_ctx_bi.initialized &&
+ !tls_session_update_crypto_params (session, &c->options,
+ &c->c2.frame))
+ {
+ msg (D_TLS_ERRORS, "TLS Error: server generate_key_expansion failed");
+ goto error;
+ }
+ }
+ }
+ goto cleanup;
+error:
+ register_signal (c, SIGUSR1, "process-push-msg-failed");
+cleanup:
gc_free (&gc);
}
@@ -241,79 +295,158 @@ send_push_request (struct context *c)
#if P2MP_SERVER
-bool
-send_push_reply (struct context *c)
+/**
+ * Prepare push options, based on local options and available peer info.
+ *
+ * @param context context structure storing data for VPN tunnel
+ * @param gc gc arena for allocating push options
+ * @param push_list push list to where options are added
+ *
+ * @return true on success, false on failure.
+ */
+static bool
+prepare_push_reply (struct context *c, struct gc_arena *gc,
+ struct push_list *push_list)
{
- struct gc_arena gc = gc_new ();
- struct buffer buf = alloc_buf_gc (PUSH_BUNDLE_SIZE, &gc);
- struct push_entry *e = c->options.push_list.head;
- bool multi_push = false;
- static char cmd[] = "PUSH_REPLY";
- const int extra = 84; /* extra space for possible trailing ifconfig and push-continuation */
- const int safe_cap = BCAP (&buf) - extra;
- bool push_sent = false;
+ const char *optstr = NULL;
+ struct tls_multi *tls_multi = c->c2.tls_multi;
+ const char * const peer_info = tls_multi->peer_info;
+ struct options *o = &c->options;
- msg( M_INFO, "send_push_reply(): safe_cap=%d", safe_cap );
+ /* ipv6 */
+ if (c->c2.push_ifconfig_ipv6_defined && !o->push_ifconfig_ipv6_blocked)
+ {
+ push_option_fmt (gc, push_list, M_USAGE, "ifconfig-ipv6 %s/%d %s",
+ print_in6_addr (c->c2.push_ifconfig_ipv6_local, 0, gc),
+ c->c2.push_ifconfig_ipv6_netbits,
+ print_in6_addr (c->c2.push_ifconfig_ipv6_remote,
+ 0, gc));
+ }
- buf_printf (&buf, "%s", cmd);
+ /* ipv4 */
+ if (c->c2.push_ifconfig_defined && c->c2.push_ifconfig_local &&
+ c->c2.push_ifconfig_remote_netmask)
+ {
+ in_addr_t ifconfig_local = c->c2.push_ifconfig_local;
+ if (c->c2.push_ifconfig_local_alias)
+ ifconfig_local = c->c2.push_ifconfig_local_alias;
+ push_option_fmt (gc, push_list, M_USAGE, "ifconfig %s %s",
+ print_in_addr_t (ifconfig_local, 0, gc),
+ print_in_addr_t (c->c2.push_ifconfig_remote_netmask,
+ 0, gc));
+ }
+
+ /* Send peer-id if client supports it */
+ optstr = peer_info ? strstr(peer_info, "IV_PROTO=") : NULL;
+ if (optstr)
+ {
+ int proto = 0;
+ int r = sscanf(optstr, "IV_PROTO=%d", &proto);
+ if ((r == 1) && (proto >= 2))
+ {
+ push_option_fmt(gc, push_list, M_USAGE, "peer-id %d",
+ tls_multi->peer_id);
+ }
+ }
- if ( c->c2.push_ifconfig_ipv6_defined )
+ /* Push cipher if client supports Negotiable Crypto Parameters */
+ if (tls_peer_info_ncp_ver (peer_info) >= 2 && o->ncp_enabled)
{
- /* IPv6 is put into buffer first, could be lengthy */
- buf_printf( &buf, ",ifconfig-ipv6 %s/%d %s",
- print_in6_addr( c->c2.push_ifconfig_ipv6_local, 0, &gc),
- c->c2.push_ifconfig_ipv6_netbits,
- print_in6_addr( c->c2.push_ifconfig_ipv6_remote, 0, &gc) );
- if (BLEN (&buf) >= safe_cap)
+ /* if we have already created our key, we cannot change our own
+ * cipher, so disable NCP and warn = explain why
+ */
+ const struct tls_session *session = &tls_multi->session[TM_ACTIVE];
+ if ( session->key[KS_PRIMARY].crypto_options.key_ctx_bi.initialized )
+ {
+ msg( M_INFO, "PUSH: client wants to negotiate cipher (NCP), but "
+ "server has already generated data channel keys, "
+ "ignoring client request" );
+ }
+ else
{
- msg (M_WARN, "--push ifconfig-ipv6 option is too long");
- goto fail;
+ /* Push the first cipher from --ncp-ciphers to the client.
+ * TODO: actual negotiation, instead of server dictatorship. */
+ char *push_cipher = string_alloc(o->ncp_ciphers, &o->gc);
+ o->ciphername = strtok (push_cipher, ":");
+ push_option_fmt(gc, push_list, M_USAGE, "cipher %s", o->ciphername);
}
}
+ /* If server uses --auth-gen-token and we have an auth token
+ * to send to the client
+ */
+ if (false == tls_multi->auth_token_sent && NULL != tls_multi->auth_token)
+ {
+ push_option_fmt(gc, push_list, M_USAGE,
+ "auth-token %s", tls_multi->auth_token);
+ tls_multi->auth_token_sent = true;
+ }
+ return true;
+}
+
+static bool
+send_push_options (struct context *c, struct buffer *buf,
+ struct push_list *push_list, int safe_cap,
+ bool *push_sent, bool *multi_push)
+{
+ struct push_entry *e = push_list->head;
+
while (e)
{
if (e->enable)
{
const int l = strlen (e->option);
- if (BLEN (&buf) + l >= safe_cap)
+ if (BLEN (buf) + l >= safe_cap)
{
- buf_printf (&buf, ",push-continuation 2");
- {
- const bool status = send_control_channel_string (c, BSTR (&buf), D_PUSH);
- if (!status)
- goto fail;
- push_sent = true;
- multi_push = true;
- buf_reset_len (&buf);
- buf_printf (&buf, "%s", cmd);
- }
+ buf_printf (buf, ",push-continuation 2");
+ {
+ const bool status = send_control_channel_string (c, BSTR (buf), D_PUSH);
+ if (!status)
+ return false;
+ *push_sent = true;
+ *multi_push = true;
+ buf_reset_len (buf);
+ buf_printf (buf, "%s", push_reply_cmd);
+ }
}
- if (BLEN (&buf) + l >= safe_cap)
+ if (BLEN (buf) + l >= safe_cap)
{
msg (M_WARN, "--push option is too long");
- goto fail;
+ return false;
}
- buf_printf (&buf, ",%s", e->option);
+ buf_printf (buf, ",%s", e->option);
}
e = e->next;
}
+ return true;
+}
+
+static bool
+send_push_reply (struct context *c, struct push_list *per_client_push_list)
+{
+ struct gc_arena gc = gc_new ();
+ struct buffer buf = alloc_buf_gc (PUSH_BUNDLE_SIZE, &gc);
+ bool multi_push = false;
+ const int extra = 84; /* extra space for possible trailing ifconfig and push-continuation */
+ const int safe_cap = BCAP (&buf) - extra;
+ bool push_sent = false;
+
+ buf_printf (&buf, "%s", push_reply_cmd);
+
+ /* send options which are common to all clients */
+ if (!send_push_options (c, &buf, &c->options.push_list, safe_cap,
+ &push_sent, &multi_push))
+ goto fail;
+
+ /* send client-specific options */
+ if (!send_push_options (c, &buf, per_client_push_list, safe_cap,
+ &push_sent, &multi_push))
+ goto fail;
- if (c->c2.push_ifconfig_defined && c->c2.push_ifconfig_local && c->c2.push_ifconfig_remote_netmask)
- {
- in_addr_t ifconfig_local = c->c2.push_ifconfig_local;
-#ifdef ENABLE_CLIENT_NAT
- if (c->c2.push_ifconfig_local_alias)
- ifconfig_local = c->c2.push_ifconfig_local_alias;
-#endif
- buf_printf (&buf, ",ifconfig %s %s",
- print_in_addr_t (ifconfig_local, 0, &gc),
- print_in_addr_t (c->c2.push_ifconfig_remote_netmask, 0, &gc));
- }
if (multi_push)
buf_printf (&buf, ",push-continuation 1");
- if (BLEN (&buf) > sizeof(cmd)-1)
+ if (BLEN (&buf) > sizeof(push_reply_cmd)-1)
{
const bool status = send_control_channel_string (c, BSTR (&buf), D_PUSH);
if (!status)
@@ -329,7 +462,7 @@ send_push_reply (struct context *c)
bool status = false;
buf_reset_len (&buf);
- buf_printf (&buf, "%s", cmd);
+ buf_printf (&buf, "%s", push_reply_cmd);
status = send_control_channel_string (c, BSTR(&buf), D_PUSH);
if (!status)
goto fail;
@@ -344,7 +477,8 @@ send_push_reply (struct context *c)
}
static void
-push_option_ex (struct options *o, const char *opt, bool enable, int msglevel)
+push_option_ex (struct gc_arena *gc, struct push_list *push_list,
+ const char *opt, bool enable, int msglevel)
{
if (!string_class (opt, CC_ANY, CC_COMMA))
{
@@ -353,20 +487,20 @@ push_option_ex (struct options *o, const char *opt, bool enable, int msglevel)
else
{
struct push_entry *e;
- ALLOC_OBJ_CLEAR_GC (e, struct push_entry, &o->gc);
+ ALLOC_OBJ_CLEAR_GC (e, struct push_entry, gc);
e->enable = true;
e->option = opt;
- if (o->push_list.head)
+ if (push_list->head)
{
- ASSERT(o->push_list.tail);
- o->push_list.tail->next = e;
- o->push_list.tail = e;
+ ASSERT(push_list->tail);
+ push_list->tail->next = e;
+ push_list->tail = e;
}
else
{
- ASSERT(!o->push_list.tail);
- o->push_list.head = e;
- o->push_list.tail = e;
+ ASSERT(!push_list->tail);
+ push_list->head = e;
+ push_list->tail = e;
}
}
}
@@ -374,7 +508,7 @@ push_option_ex (struct options *o, const char *opt, bool enable, int msglevel)
void
push_option (struct options *o, const char *opt, int msglevel)
{
- push_option_ex (o, opt, true, msglevel);
+ push_option_ex (&o->gc, &o->push_list, opt, true, msglevel);
}
void
@@ -386,7 +520,8 @@ clone_push_list (struct options *o)
push_reset (o);
while (e)
{
- push_option_ex (o, string_alloc (e->option, &o->gc), true, M_FATAL);
+ push_option_ex (&o->gc, &o->push_list,
+ string_alloc (e->option, &o->gc), true, M_FATAL);
e = e->next;
}
}
@@ -400,55 +535,137 @@ push_options (struct options *o, char **p, int msglevel, struct gc_arena *gc)
push_option (o, opt, msglevel);
}
+static bool push_option_fmt(struct gc_arena *gc, struct push_list *push_list,
+ int msglevel, const char *format, ...)
+{
+ va_list arglist;
+ char tmp[256] = {0};
+ int len;
+ va_start (arglist, format);
+ len = vsnprintf (tmp, sizeof(tmp), format, arglist);
+ va_end (arglist);
+ if (len > sizeof(tmp)-1)
+ return false;
+ push_option_ex (gc, push_list, string_alloc (tmp, gc), true, msglevel);
+ return true;
+}
+
void
push_reset (struct options *o)
{
CLEAR (o->push_list);
}
+
+void
+push_remove_option (struct options *o, const char *p)
+{
+ msg (D_PUSH_DEBUG, "PUSH_REMOVE searching for: '%s'", p);
+
+ /* ifconfig-ipv6 is special, as not part of the push list */
+ if ( streq( p, "ifconfig-ipv6" ))
+ {
+ o->push_ifconfig_ipv6_blocked = true;
+ return;
+ }
+
+ if (o && o->push_list.head )
+ {
+ struct push_entry *e = o->push_list.head;
+
+ /* cycle through the push list */
+ while (e)
+ {
+ if ( e->enable &&
+ strncmp( e->option, p, strlen(p) ) == 0 )
+ {
+ msg (D_PUSH_DEBUG, "PUSH_REMOVE removing: '%s'", e->option);
+ e->enable = false;
+ }
+
+ e = e->next;
+ }
+ }
+}
#endif
+#if P2MP_SERVER
int
-process_incoming_push_msg (struct context *c,
- const struct buffer *buffer,
- bool honor_received_options,
- unsigned int permission_mask,
- unsigned int *option_types_found)
+process_incoming_push_request (struct context *c)
{
int ret = PUSH_MSG_ERROR;
- struct buffer buf = *buffer;
-#if P2MP_SERVER
- if (buf_string_compare_advance (&buf, "PUSH_REQUEST"))
+#ifdef ENABLE_ASYNC_PUSH
+ c->c2.push_request_received = true;
+#endif
+ if (tls_authentication_status (c->c2.tls_multi, 0) == TLS_AUTHENTICATION_FAILED || c->c2.context_auth == CAS_FAILED)
{
- if (tls_authentication_status (c->c2.tls_multi, 0) == TLS_AUTHENTICATION_FAILED || c->c2.context_auth == CAS_FAILED)
+ const char *client_reason = tls_client_reason (c->c2.tls_multi);
+ send_auth_failed (c, client_reason);
+ ret = PUSH_MSG_AUTH_FAILURE;
+ }
+ else if (!c->c2.push_reply_deferred && c->c2.context_auth == CAS_SUCCEEDED)
+ {
+ time_t now;
+
+ openvpn_time (&now);
+ if (c->c2.sent_push_reply_expiry > now)
{
- const char *client_reason = tls_client_reason (c->c2.tls_multi);
- send_auth_failed (c, client_reason);
- ret = PUSH_MSG_AUTH_FAILURE;
+ ret = PUSH_MSG_ALREADY_REPLIED;
}
- else if (!c->c2.push_reply_deferred && c->c2.context_auth == CAS_SUCCEEDED)
+ else
{
- time_t now;
+ /* per-client push options - peer-id, cipher, ifconfig, ipv6-ifconfig */
+ struct push_list push_list;
+ struct gc_arena gc = gc_new ();
- openvpn_time(&now);
- if (c->c2.sent_push_reply_expiry > now)
+ CLEAR (push_list);
+ if (prepare_push_reply (c, &gc, &push_list) &&
+ send_push_reply (c, &push_list))
{
- ret = PUSH_MSG_ALREADY_REPLIED;
- }
- else
- {
- if (send_push_reply (c))
- {
- ret = PUSH_MSG_REQUEST;
- c->c2.sent_push_reply_expiry = now + 30;
- }
+ ret = PUSH_MSG_REQUEST;
+ c->c2.sent_push_reply_expiry = now + 30;
}
+ gc_free(&gc);
}
- else
+ }
+ else
+ {
+ ret = PUSH_MSG_REQUEST_DEFERRED;
+ }
+
+ return ret;
+}
+#endif
+
+static void
+push_update_digest(md_ctx_t *ctx, struct buffer *buf)
+{
+ char line[OPTION_PARM_SIZE];
+ while (buf_parse (buf, ',', line, sizeof (line)))
+ {
+ /* peer-id might change on restart and this should not trigger reopening tun */
+ if (strstr (line, "peer-id ") != line)
{
- ret = PUSH_MSG_REQUEST_DEFERRED;
+ md_ctx_update (ctx, (const uint8_t *) line, strlen(line));
}
}
+}
+
+int
+process_incoming_push_msg (struct context *c,
+ const struct buffer *buffer,
+ bool honor_received_options,
+ unsigned int permission_mask,
+ unsigned int *option_types_found)
+{
+ int ret = PUSH_MSG_ERROR;
+ struct buffer buf = *buffer;
+
+#if P2MP_SERVER
+ if (buf_string_compare_advance (&buf, "PUSH_REQUEST"))
+ {
+ ret = process_incoming_push_request(c);
+ }
else
#endif
@@ -460,12 +677,12 @@ process_incoming_push_msg (struct context *c,
struct buffer buf_orig = buf;
if (!c->c2.pulled_options_md5_init_done)
{
- md5_state_init (&c->c2.pulled_options_state);
+ md_ctx_init(&c->c2.pulled_options_state, md_kt_get("MD5"));
c->c2.pulled_options_md5_init_done = true;
}
if (!c->c2.did_pre_pull_restore)
{
- pre_pull_restore (&c->options);
+ pre_pull_restore (&c->options, &c->c2.gc);
c->c2.did_pre_pull_restore = true;
}
if (apply_push_options (&c->options,
@@ -473,20 +690,22 @@ process_incoming_push_msg (struct context *c,
permission_mask,
option_types_found,
c->c2.es))
- switch (c->options.push_continuation)
- {
- case 0:
- case 1:
- md5_state_update (&c->c2.pulled_options_state, BPTR(&buf_orig), BLEN(&buf_orig));
- md5_state_final (&c->c2.pulled_options_state, &c->c2.pulled_options_digest);
- c->c2.pulled_options_md5_init_done = false;
- ret = PUSH_MSG_REPLY;
- break;
- case 2:
- md5_state_update (&c->c2.pulled_options_state, BPTR(&buf_orig), BLEN(&buf_orig));
- ret = PUSH_MSG_CONTINUATION;
- break;
- }
+ {
+ push_update_digest (&c->c2.pulled_options_state, &buf_orig);
+ switch (c->options.push_continuation)
+ {
+ case 0:
+ case 1:
+ md_ctx_final (&c->c2.pulled_options_state, c->c2.pulled_options_digest.digest);
+ md_ctx_cleanup (&c->c2.pulled_options_state);
+ c->c2.pulled_options_md5_init_done = false;
+ ret = PUSH_MSG_REPLY;
+ break;
+ case 2:
+ ret = PUSH_MSG_CONTINUATION;
+ break;
+ }
+ }
}
else if (ch == '\0')
{
@@ -518,7 +737,8 @@ remove_iroutes_from_push_route_list (struct options *o)
/* parse the push item */
CLEAR (p);
- if (parse_line (e->option, p, SIZE (p), "[PUSH_ROUTE_REMOVE]", 1, D_ROUTE_DEBUG, &gc))
+ if ( e->enable &&
+ parse_line (e->option, p, SIZE (p), "[PUSH_ROUTE_REMOVE]", 1, D_ROUTE_DEBUG, &gc))
{
/* is the push item a route directive? */
if (p[0] && !strcmp (p[0], "route") && !p[3])
@@ -544,12 +764,12 @@ remove_iroutes_from_push_route_list (struct options *o)
}
}
}
- }
- /* should we copy the push item? */
- e->enable = enable;
- if (!enable)
- msg (D_PUSH, "REMOVE PUSH ROUTE: '%s'", e->option);
+ /* should we copy the push item? */
+ e->enable = enable;
+ if (!enable)
+ msg (D_PUSH, "REMOVE PUSH ROUTE: '%s'", e->option);
+ }
e = e->next;
}
diff --git a/src/openvpn/push.h b/src/openvpn/push.h
index 8c3f157..d6cb4b1 100644
--- a/src/openvpn/push.h
+++ b/src/openvpn/push.h
@@ -37,8 +37,7 @@
#define PUSH_MSG_CONTINUATION 5
#define PUSH_MSG_ALREADY_REPLIED 6
-void incoming_push_message (struct context *c,
- const struct buffer *buffer);
+int process_incoming_push_request (struct context *c);
int process_incoming_push_msg (struct context *c,
const struct buffer *buffer,
@@ -54,14 +53,15 @@ void server_pushed_signal (struct context *c, const struct buffer *buffer, const
#if P2MP_SERVER
+void incoming_push_message (struct context *c, const struct buffer *buffer);
+
void clone_push_list (struct options *o);
void push_option (struct options *o, const char *opt, int msglevel);
void push_options (struct options *o, char **p, int msglevel, struct gc_arena *gc);
void push_reset (struct options *o);
-
-bool send_push_reply (struct context *c);
+void push_remove_option (struct options *o, const char *p);
void remove_iroutes_from_push_route_list (struct options *o);
diff --git a/src/openvpn/reliable.c b/src/openvpn/reliable.c
index 763169e..22883a7 100644
--- a/src/openvpn/reliable.c
+++ b/src/openvpn/reliable.c
@@ -35,7 +35,7 @@
#include "syshead.h"
-#if defined(ENABLE_CRYPTO) && defined(ENABLE_SSL)
+#ifdef ENABLE_CRYPTO
#include "buffer.h"
#include "error.h"
@@ -754,4 +754,4 @@ reliable_debug_print (const struct reliable *rel, char *desc)
#else
static void dummy(void) {}
-#endif /* ENABLE_CRYPTO && ENABLE_SSL*/
+#endif /* ENABLE_CRYPTO */
diff --git a/src/openvpn/reliable.h b/src/openvpn/reliable.h
index 594ab82..828dcd3 100644
--- a/src/openvpn/reliable.h
+++ b/src/openvpn/reliable.h
@@ -29,7 +29,7 @@
*/
-#if defined(ENABLE_CRYPTO) && defined(ENABLE_SSL)
+#ifdef ENABLE_CRYPTO
#ifndef RELIABLE_H
#define RELIABLE_H
@@ -477,4 +477,4 @@ void reliable_ack_debug_print (const struct reliable_ack *ack, char *desc);
#endif /* RELIABLE_H */
-#endif /* ENABLE_CRYPTO && ENABLE_SSL */
+#endif /* ENABLE_CRYPTO */
diff --git a/src/openvpn/route.c b/src/openvpn/route.c
index 827bd79..fec12c1 100644
--- a/src/openvpn/route.c
+++ b/src/openvpn/route.c
@@ -42,12 +42,21 @@
#include "manage.h"
#include "win32.h"
#include "options.h"
-#include "win32.h"
#include "memdbg.h"
-#ifdef WIN32
+#if defined(TARGET_LINUX) || defined(TARGET_ANDROID)
+#include <linux/rtnetlink.h> /* RTM_GETROUTE etc. */
+#endif
+
+#ifdef _WIN32
+#include "openvpn-msg.h"
+
#define METRIC_NOT_USED ((DWORD)-1)
+static bool add_route_service (const struct route_ipv4 *, const struct tuntap *);
+static bool del_route_service (const struct route_ipv4 *, const struct tuntap *);
+static bool add_route_ipv6_service (const struct route_ipv6 *, const struct tuntap *);
+static bool del_route_ipv6_service (const struct route_ipv6 *, const struct tuntap *);
#endif
static void delete_route (struct route_ipv4 *r, const struct tuntap *tt, unsigned int flags, const struct route_gateway_info *rgi, const struct env_set *es);
@@ -93,76 +102,62 @@ add_bypass_address (struct route_bypass *rb, const in_addr_t a)
}
struct route_option_list *
-new_route_option_list (const int max_routes, struct gc_arena *a)
+new_route_option_list (struct gc_arena *a)
{
struct route_option_list *ret;
- ALLOC_VAR_ARRAY_CLEAR_GC (ret, struct route_option_list, struct route_option, max_routes, a);
- ret->capacity = max_routes;
+ ALLOC_OBJ_CLEAR_GC (ret, struct route_option_list, a);
+ ret->gc = a;
return ret;
}
struct route_ipv6_option_list *
-new_route_ipv6_option_list (const int max_routes, struct gc_arena *a)
+new_route_ipv6_option_list (struct gc_arena *a)
{
struct route_ipv6_option_list *ret;
- ALLOC_VAR_ARRAY_CLEAR_GC (ret, struct route_ipv6_option_list, struct route_ipv6_option, max_routes, a);
- ret->capacity = max_routes;
+ ALLOC_OBJ_CLEAR_GC (ret, struct route_ipv6_option_list, a);
+ ret->gc = a;
return ret;
}
+/*
+ * NOTE: structs are cloned/copied shallow by design.
+ * The routes list from src will stay intact since it is allocated using
+ * the options->gc. The cloned/copied lists will share this common tail
+ * to avoid copying the data around between pulls. Pulled routes use
+ * the c2->gc so they get freed immediately after a reconnect.
+ */
struct route_option_list *
clone_route_option_list (const struct route_option_list *src, struct gc_arena *a)
{
- const size_t rl_size = array_mult_safe (sizeof(struct route_option), src->capacity, sizeof(struct route_option_list));
- struct route_option_list *ret = gc_malloc (rl_size, false, a);
- memcpy (ret, src, rl_size);
+ struct route_option_list *ret;
+ ALLOC_OBJ_GC (ret, struct route_option_list, a);
+ *ret = *src;
return ret;
}
struct route_ipv6_option_list *
clone_route_ipv6_option_list (const struct route_ipv6_option_list *src, struct gc_arena *a)
{
- const size_t rl_size = array_mult_safe (sizeof(struct route_ipv6_option), src->capacity, sizeof(struct route_ipv6_option_list));
- struct route_ipv6_option_list *ret = gc_malloc (rl_size, false, a);
- memcpy (ret, src, rl_size);
+ struct route_ipv6_option_list *ret;
+ ALLOC_OBJ_GC (ret, struct route_ipv6_option_list, a);
+ *ret = *src;
return ret;
}
void
-copy_route_option_list (struct route_option_list *dest, const struct route_option_list *src)
+copy_route_option_list (struct route_option_list *dest, const struct route_option_list *src, struct gc_arena *a)
{
- const size_t src_size = array_mult_safe (sizeof(struct route_option), src->capacity, sizeof(struct route_option_list));
- if (src->capacity > dest->capacity)
- msg (M_FATAL, PACKAGE_NAME " ROUTE: (copy) number of route options in src (%d) is greater than route list capacity in dest (%d)", src->capacity, dest->capacity);
- memcpy (dest, src, src_size);
+ *dest = *src;
+ dest->gc = a;
}
void
copy_route_ipv6_option_list (struct route_ipv6_option_list *dest,
- const struct route_ipv6_option_list *src)
+ const struct route_ipv6_option_list *src,
+ struct gc_arena *a)
{
- const size_t src_size = array_mult_safe (sizeof(struct route_ipv6_option), src->capacity, sizeof(struct route_ipv6_option_list));
- if (src->capacity > dest->capacity)
- msg (M_FATAL, PACKAGE_NAME " ROUTE: (copy) number of route options in src (%d) is greater than route list capacity in dest (%d)", src->capacity, dest->capacity);
- memcpy (dest, src, src_size);
-}
-
-struct route_list *
-new_route_list (const int max_routes, struct gc_arena *a)
-{
- struct route_list *ret;
- ALLOC_VAR_ARRAY_CLEAR_GC (ret, struct route_list, struct route_ipv4, max_routes, a);
- ret->capacity = max_routes;
- return ret;
-}
-
-struct route_ipv6_list *
-new_route_ipv6_list (const int max_routes, struct gc_arena *a)
-{
- struct route_ipv6_list *ret;
- ALLOC_VAR_ARRAY_CLEAR_GC (ret, struct route_ipv6_list, struct route_ipv6, max_routes, a);
- ret->capacity = max_routes;
- return ret;
+ *dest = *src;
+ dest->gc = a;
}
static const char *
@@ -292,15 +287,15 @@ init_route (struct route_ipv4 *r,
/* get_special_addr replaces specialaddr with a special ip addr
like gw. getaddrinfo is called to convert a a addrinfo struct */
- if(get_special_addr (rl, ro->network, &special.s_addr, &status))
+ if(get_special_addr (rl, ro->network, (in_addr_t *) &special.s_addr, &status))
{
special.s_addr = htonl(special.s_addr);
- ret = openvpn_getaddrinfo(0, inet_ntoa(special), 0, NULL,
+ ret = openvpn_getaddrinfo(0, inet_ntoa(special), NULL, 0, NULL,
AF_INET, network_list);
}
else
ret = openvpn_getaddrinfo(GETADDR_RESOLVE | GETADDR_WARN_ON_SIGNAL,
- ro->network, 0, NULL, AF_INET, network_list);
+ ro->network, NULL, 0, NULL, AF_INET, network_list);
status = (ret == 0);
@@ -389,7 +384,7 @@ init_route_ipv6 (struct route_ipv6 *r6,
const struct route_ipv6_option *r6o,
const struct route_ipv6_list *rl6 )
{
- r6->defined = false;
+ CLEAR (*r6);
if ( !get_ipv6_addr( r6o->prefix, &r6->network, &r6->netbits, M_WARN ))
goto fail;
@@ -402,7 +397,7 @@ init_route_ipv6 (struct route_ipv6 *r6,
msg( M_WARN, PACKAGE_NAME "ROUTE6: cannot parse gateway spec '%s'", r6o->gateway );
}
}
- else if (rl6->remote_endpoint_defined)
+ else if (rl6->spec_flags & RTSA_REMOTE_ENDPOINT)
{
r6->gateway = rl6->remote_endpoint_ipv6;
}
@@ -414,7 +409,6 @@ init_route_ipv6 (struct route_ipv6 *r6,
/* metric */
- r6->metric_defined = false;
r6->metric = -1;
if (is_route_parm_defined (r6o->metric))
{
@@ -426,22 +420,21 @@ init_route_ipv6 (struct route_ipv6 *r6,
r6o->metric);
goto fail;
}
- r6->metric_defined = true;
+ r6->flags |= RT_METRIC_DEFINED;
}
- else if (rl6->default_metric_defined)
+ else if (rl6->spec_flags & RTSA_DEFAULT_METRIC)
{
r6->metric = rl6->default_metric;
- r6->metric_defined = true;
+ r6->flags |= RT_METRIC_DEFINED;
}
- r6->defined = true;
+ r6->flags |= RT_DEFINED;
return true;
fail:
msg (M_WARN, PACKAGE_NAME " ROUTE: failed to parse/resolve route for host/network: %s",
r6o->prefix);
- r6->defined = false;
return false;
}
@@ -453,15 +446,14 @@ add_route_to_option_list (struct route_option_list *l,
const char *metric)
{
struct route_option *ro;
- if (l->n >= l->capacity)
- msg (M_FATAL, PACKAGE_NAME " ROUTE: cannot add more than %d routes -- please increase the max-routes option in the client configuration file",
- l->capacity);
- ro = &l->routes[l->n];
+ ALLOC_OBJ_GC (ro, struct route_option, l->gc);
ro->network = network;
ro->netmask = netmask;
ro->gateway = gateway;
ro->metric = metric;
- ++l->n;
+ ro->next = l->routes;
+ l->routes = ro;
+
}
void
@@ -471,32 +463,26 @@ add_route_ipv6_to_option_list (struct route_ipv6_option_list *l,
const char *metric)
{
struct route_ipv6_option *ro;
- if (l->n >= l->capacity)
- msg (M_FATAL, PACKAGE_NAME " ROUTE: cannot add more than %d IPv6 routes -- please increase the max-routes option in the client configuration file",
- l->capacity);
- ro = &l->routes_ipv6[l->n];
+ ALLOC_OBJ_GC (ro, struct route_ipv6_option, l->gc);
ro->prefix = prefix;
ro->gateway = gateway;
ro->metric = metric;
- ++l->n;
+ ro->next = l->routes_ipv6;
+ l->routes_ipv6 = ro;
}
void
clear_route_list (struct route_list *rl)
{
- const int capacity = rl->capacity;
- const size_t rl_size = array_mult_safe (sizeof(struct route_ipv4), capacity, sizeof(struct route_list));
- memset(rl, 0, rl_size);
- rl->capacity = capacity;
+ gc_free (&rl->gc);
+ CLEAR (*rl);
}
void
clear_route_ipv6_list (struct route_ipv6_list *rl6)
{
- const int capacity = rl6->capacity;
- const size_t rl6_size = array_mult_safe (sizeof(struct route_ipv6), capacity, sizeof(struct route_ipv6_list));
- memset(rl6, 0, rl6_size);
- rl6->capacity = capacity;
+ gc_free (&rl6->gc);
+ CLEAR (*rl6);
}
void
@@ -517,22 +503,27 @@ add_block_local_item (struct route_list *rl,
{
const int rgi_needed = (RGI_ADDR_DEFINED|RGI_NETMASK_DEFINED);
if ((rl->rgi.flags & rgi_needed) == rgi_needed
- && rl->rgi.gateway.netmask < 0xFFFFFFFF
- && (rl->n)+2 <= rl->capacity)
+ && rl->rgi.gateway.netmask < 0xFFFFFFFF)
{
- struct route_ipv4 r;
+ struct route_ipv4 *r1, *r2;
unsigned int l2;
+ ALLOC_OBJ_GC (r1, struct route_ipv4, &rl->gc);
+ ALLOC_OBJ_GC (r2, struct route_ipv4, &rl->gc);
+
/* split a route into two smaller blocking routes, and direct them to target */
- CLEAR(r);
- r.flags = RT_DEFINED;
- r.gateway = target;
- r.network = gateway->addr & gateway->netmask;
l2 = ((~gateway->netmask)+1)>>1;
- r.netmask = ~(l2-1);
- rl->routes[rl->n++] = r;
- r.network += l2;
- rl->routes[rl->n++] = r;
+ r1->flags = RT_DEFINED;
+ r1->gateway = target;
+ r1->network = gateway->addr & gateway->netmask;
+ r1->netmask = ~(l2-1);
+ r1->next = rl->routes;
+ rl->routes = r1;
+
+ *r2 = *r1;
+ r2->network += l2;
+ r2->next = rl->routes;
+ rl->routes = r2;
}
}
@@ -547,8 +538,10 @@ add_block_local (struct route_list *rl)
{
size_t i;
+#ifndef TARGET_ANDROID
/* add bypass for gateway addr */
add_bypass_address (&rl->spec.bypass, rl->rgi.gateway.addr);
+#endif
/* block access to local subnet */
add_block_local_item (rl, &rl->rgi.gateway, rl->spec.remote_endpoint);
@@ -597,7 +590,7 @@ init_route_list (struct route_list *rl,
{
setenv_route_addr (es, "net_gateway", rl->rgi.gateway.addr, -1);
#if defined(ENABLE_DEBUG) && !defined(ENABLE_SMALL)
- print_default_gateway (D_ROUTE, &rl->rgi);
+ print_default_gateway (D_ROUTE, &rl->rgi, NULL);
#endif
}
else
@@ -644,72 +637,108 @@ init_route_list (struct route_list *rl,
/* parse the routes from opt to rl */
{
- int i = 0;
- int j = rl->n;
- bool warned = false;
- for (i = 0; i < opt->n; ++i)
+ struct route_option *ro;
+ for (ro = opt->routes; ro; ro = ro->next)
{
struct addrinfo* netlist = NULL;
struct route_ipv4 r;
- if (!init_route (&r,
- &netlist,
- &opt->routes[i],
- rl))
+ if (!init_route (&r, &netlist, ro, rl))
ret = false;
else
{
struct addrinfo* curele;
for (curele = netlist; curele; curele = curele->ai_next)
{
- if (j < rl->capacity)
- {
- r.network = ntohl(((struct sockaddr_in*)(curele)->ai_addr)->sin_addr.s_addr);
- rl->routes[j++] = r;
- }
- else
- {
- if (!warned)
- {
- msg (M_WARN, PACKAGE_NAME " ROUTE: routes dropped because number of expanded routes is greater than route list capacity (%d)", rl->capacity);
- warned = true;
- }
- }
+ struct route_ipv4 *new;
+ ALLOC_OBJ_GC (new, struct route_ipv4, &rl->gc);
+ *new = r;
+ new->network = ntohl (((struct sockaddr_in*)curele->ai_addr)->sin_addr.s_addr);
+ new->next = rl->routes;
+ rl->routes = new;
}
}
if (netlist)
- freeaddrinfo(netlist);
+ gc_addspecial(netlist, &gc_freeaddrinfo_callback, &gc);
}
- rl->n = j;
}
gc_free (&gc);
return ret;
}
+/* check whether an IPv6 host address is covered by a given route_ipv6
+ * (not the most beautiful implementation in the world, but portable and
+ * "good enough")
+ */
+static bool
+route_ipv6_match_host( const struct route_ipv6 *r6,
+ const struct in6_addr *host )
+{
+ unsigned int bits = r6->netbits;
+ int i;
+ unsigned int mask;
+
+ if ( bits>128 )
+ return false;
+
+ for( i=0; bits >= 8; i++, bits -= 8 )
+ {
+ if ( r6->network.s6_addr[i] != host->s6_addr[i] )
+ return false;
+ }
+
+ if ( bits == 0 )
+ return true;
+
+ mask = 0xff << (8-bits);
+
+ if ( (r6->network.s6_addr[i] & mask) == (host->s6_addr[i] & mask ))
+ return true;
+
+ return false;
+}
+
bool
init_route_ipv6_list (struct route_ipv6_list *rl6,
const struct route_ipv6_option_list *opt6,
const char *remote_endpoint,
int default_metric,
+ const struct in6_addr *remote_host_ipv6,
struct env_set *es)
{
struct gc_arena gc = gc_new ();
bool ret = true;
+ bool need_remote_ipv6_route;
clear_route_ipv6_list (rl6);
rl6->flags = opt6->flags;
+ if (remote_host_ipv6)
+ {
+ rl6->remote_host_ipv6 = *remote_host_ipv6;
+ rl6->spec_flags |= RTSA_REMOTE_HOST;
+ }
+
if (default_metric >= 0 )
{
rl6->default_metric = default_metric;
- rl6->default_metric_defined = true;
+ rl6->spec_flags |= RTSA_DEFAULT_METRIC;
}
- /* "default_gateway" is stuff for "redirect-gateway", which we don't
- * do for IPv6 yet -> TODO
- */
+ msg (D_ROUTE, "GDG6: remote_host_ipv6=%s",
+ remote_host_ipv6? print_in6_addr (*remote_host_ipv6, 0, &gc): "n/a" );
+
+ get_default_gateway_ipv6 (&rl6->rgi6, remote_host_ipv6);
+ if (rl6->rgi6.flags & RGI_ADDR_DEFINED)
+ {
+ setenv_str (es, "net_gateway_ipv6", print_in6_addr (rl6->rgi6.gateway.addr_ipv6, 0, &gc));
+#if defined(ENABLE_DEBUG) && !defined(ENABLE_SMALL)
+ print_default_gateway (D_ROUTE, NULL, &rl6->rgi6);
+#endif
+ }
+ else
{
dmsg (D_ROUTE, "ROUTE6: default_gateway=UNDEF");
}
@@ -719,36 +748,81 @@ init_route_ipv6_list (struct route_ipv6_list *rl6,
if ( inet_pton( AF_INET6, remote_endpoint,
&rl6->remote_endpoint_ipv6) == 1 )
{
- rl6->remote_endpoint_defined = true;
+ rl6->spec_flags |= RTSA_REMOTE_ENDPOINT;
}
else
{
- msg (M_WARN, PACKAGE_NAME " ROUTE: failed to parse/resolve default gateway: %s", remote_endpoint);
+ msg (M_WARN, PACKAGE_NAME " ROUTE: failed to parse/resolve VPN endpoint: %s", remote_endpoint);
ret = false;
}
}
- else
- rl6->remote_endpoint_defined = false;
+ /* parse the routes from opt6 to rl6
+ * discovering potential overlaps with remote_host_ipv6 in the process
+ */
+ need_remote_ipv6_route = false;
- if (!(opt6->n >= 0 && opt6->n <= rl6->capacity))
- msg (M_FATAL, PACKAGE_NAME " ROUTE6: (init) number of route options (%d) is greater than route list capacity (%d)", opt6->n, rl6->capacity);
-
- /* parse the routes from opt to rl6 */
{
- int i, j = 0;
- for (i = 0; i < opt6->n; ++i)
+ struct route_ipv6_option *ro6;
+ for (ro6 = opt6->routes_ipv6; ro6; ro6 = ro6->next)
{
- if (!init_route_ipv6 (&rl6->routes_ipv6[j],
- &opt6->routes_ipv6[i],
- rl6 ))
+ struct route_ipv6 *r6;
+ ALLOC_OBJ_GC (r6, struct route_ipv6, &rl6->gc);
+ if (!init_route_ipv6 (r6, ro6, rl6))
ret = false;
else
- ++j;
+ {
+ r6->next = rl6->routes_ipv6;
+ rl6->routes_ipv6 = r6;
+
+#ifndef TARGET_ANDROID
+ /* On Android the VPNService protect function call will take of
+ * avoiding routing loops, so ignore this part and let
+ * need_remote_ipv6_route always evaluate to false
+ */
+ if ( remote_host_ipv6 &&
+ route_ipv6_match_host( r6, remote_host_ipv6 ) )
+ {
+ need_remote_ipv6_route = true;
+ msg (D_ROUTE, "ROUTE6: %s/%d overlaps IPv6 remote %s, adding host route to VPN endpoint",
+ print_in6_addr (r6->network, 0, &gc), r6->netbits,
+ print_in6_addr (*remote_host_ipv6, 0, &gc));
+ }
+#endif
+ }
}
- rl6->n = j;
}
+ /* add VPN server host route if needed */
+ if ( need_remote_ipv6_route )
+ {
+ if ( (rl6->rgi6.flags & (RGI_ADDR_DEFINED|RGI_IFACE_DEFINED) ) ==
+ (RGI_ADDR_DEFINED|RGI_IFACE_DEFINED) )
+ {
+ struct route_ipv6 *r6;
+ ALLOC_OBJ_CLEAR_GC (r6, struct route_ipv6, &rl6->gc);
+
+ r6->network = *remote_host_ipv6;
+ r6->netbits = 128;
+ if ( !(rl6->rgi6.flags & RGI_ON_LINK) )
+ { r6->gateway = rl6->rgi6.gateway.addr_ipv6; }
+ r6->metric = 1;
+#ifdef _WIN32
+ r6->adapter_index = rl6->rgi6.adapter_index;
+#else
+ r6->iface = rl6->rgi6.iface;
+#endif
+ r6->flags = RT_DEFINED | RT_METRIC_DEFINED;
+
+ r6->next = rl6->routes_ipv6;
+ rl6->routes_ipv6 = r6;
+ }
+ else
+ {
+ msg (M_WARN, "ROUTE6: IPv6 route overlaps with IPv6 remote address, but could not determine IPv6 gateway address + interface, expect failure\n" );
+ }
+ }
+
gc_free (&gc);
return ret;
}
@@ -854,6 +928,7 @@ redirect_default_route_to_vpn (struct route_list *rl, const struct tuntap *tt, u
}
else
{
+#ifndef TARGET_ANDROID
bool local = BOOL_CAST(rl->flags & RG_LOCAL);
if (rl->flags & RG_AUTO_LOCAL) {
const int tla = rl->spec.remote_host_local;
@@ -886,6 +961,7 @@ redirect_default_route_to_vpn (struct route_list *rl, const struct tuntap *tt, u
dmsg (D_ROUTE, "ROUTE remote_host protocol differs from tunneled");
}
}
+#endif
/* route DHCP/DNS server traffic through original default gateway */
add_bypass_routes (&rl->spec.bypass, rl->rgi.gateway.addr, tt, flags, &rl->rgi, es);
@@ -1015,22 +1091,23 @@ add_routes (struct route_list *rl, struct route_ipv6_list *rl6, const struct tun
redirect_default_route_to_vpn (rl, tt, flags, es);
if ( rl && !(rl->iflags & RL_ROUTES_ADDED) )
{
- int i;
+ struct route_ipv4 *r;
#ifdef ENABLE_MANAGEMENT
- if (management && rl->n)
+ if (management && rl->routes)
{
management_set_state (management,
OPENVPN_STATE_ADD_ROUTES,
NULL,
- 0,
- 0);
+ NULL,
+ NULL,
+ NULL,
+ NULL);
}
#endif
-
- for (i = 0; i < rl->n; ++i)
+
+ for (r = rl->routes; r; r = r->next)
{
- struct route_ipv4 *r = &rl->routes[i];
check_subnet_conflict (r->network, r->netmask, "route");
if (flags & ROUTE_DELETE_FIRST)
delete_route (r, tt, flags, &rl->rgi, es);
@@ -1038,18 +1115,16 @@ add_routes (struct route_list *rl, struct route_ipv6_list *rl6, const struct tun
}
rl->iflags |= RL_ROUTES_ADDED;
}
- if (rl6 && !rl6->routes_added)
+ if (rl6 && !(rl6->iflags & RL_ROUTES_ADDED) )
{
- int i;
-
- for (i = 0; i < rl6->n; ++i)
+ struct route_ipv6 *r;
+ for (r = rl6->routes_ipv6; r; r = r->next)
{
- struct route_ipv6 *r = &rl6->routes_ipv6[i];
if (flags & ROUTE_DELETE_FIRST)
delete_route_ipv6 (r, tt, flags, es);
add_route_ipv6 (r, tt, flags, es);
}
- rl6->routes_added = true;
+ rl6->iflags |= RL_ROUTES_ADDED;
}
}
@@ -1059,10 +1134,9 @@ delete_routes (struct route_list *rl, struct route_ipv6_list *rl6,
{
if ( rl && rl->iflags & RL_ROUTES_ADDED )
{
- int i;
- for (i = rl->n - 1; i >= 0; --i)
+ struct route_ipv4 *r;
+ for (r = rl->routes; r; r = r->next)
{
- struct route_ipv4 * r = &rl->routes[i];
delete_route (r, tt, flags, &rl->rgi, es);
}
rl->iflags &= ~RL_ROUTES_ADDED;
@@ -1075,15 +1149,14 @@ delete_routes (struct route_list *rl, struct route_ipv6_list *rl6,
clear_route_list (rl);
}
- if ( rl6 && rl6->routes_added )
+ if ( rl6 && (rl6->iflags & RL_ROUTES_ADDED) )
{
- int i;
- for (i = rl6->n - 1; i >= 0; --i)
+ struct route_ipv6 *r6;
+ for (r6 = rl6->routes_ipv6; r6; r6 = r6->next)
{
- const struct route_ipv6 *r6 = &rl6->routes_ipv6[i];
delete_route_ipv6 (r6, tt, flags, es);
}
- rl6->routes_added = false;
+ rl6->iflags &= ~RL_ROUTES_ADDED;
}
if ( rl6 )
@@ -1098,7 +1171,7 @@ static const char *
show_opt (const char *option)
{
if (!option)
- return "nil";
+ return "default (not set)";
else
return option;
}
@@ -1117,19 +1190,21 @@ void
print_route_options (const struct route_option_list *rol,
int level)
{
- int i;
+ struct route_option *ro;
if (rol->flags & RG_ENABLE)
msg (level, " [redirect_default_gateway local=%d]",
(rol->flags & RG_LOCAL) != 0);
- for (i = 0; i < rol->n; ++i)
- print_route_option (&rol->routes[i], level);
+ for (ro = rol->routes; ro; ro = ro->next)
+ print_route_option (ro, level);
}
void
-print_default_gateway(const int msglevel, const struct route_gateway_info *rgi)
+print_default_gateway(const int msglevel,
+ const struct route_gateway_info *rgi,
+ const struct route_ipv6_gateway_info *rgi6)
{
struct gc_arena gc = gc_new ();
- if (rgi->flags & RGI_ADDR_DEFINED)
+ if (rgi && (rgi->flags & RGI_ADDR_DEFINED))
{
struct buffer out = alloc_buf_gc (256, &gc);
buf_printf (&out, "ROUTE_GATEWAY");
@@ -1139,7 +1214,7 @@ print_default_gateway(const int msglevel, const struct route_gateway_info *rgi)
buf_printf (&out, " %s", print_in_addr_t (rgi->gateway.addr, 0, &gc));
if (rgi->flags & RGI_NETMASK_DEFINED)
buf_printf (&out, "/%s", print_in_addr_t (rgi->gateway.netmask, 0, &gc));
-#ifdef WIN32
+#ifdef _WIN32
if (rgi->flags & RGI_IFACE_DEFINED)
buf_printf (&out, " I=%u", (unsigned int)rgi->adapter_index);
#else
@@ -1150,6 +1225,27 @@ print_default_gateway(const int msglevel, const struct route_gateway_info *rgi)
buf_printf (&out, " HWADDR=%s", format_hex_ex (rgi->hwaddr, 6, 0, 1, ":", &gc));
msg (msglevel, "%s", BSTR (&out));
}
+
+ if (rgi6 && (rgi6->flags & RGI_ADDR_DEFINED))
+ {
+ struct buffer out = alloc_buf_gc (256, &gc);
+ buf_printf (&out, "ROUTE6_GATEWAY");
+ buf_printf (&out, " %s", print_in6_addr (rgi6->gateway.addr_ipv6, 0, &gc));
+ if (rgi6->flags & RGI_ON_LINK)
+ buf_printf (&out, " ON_LINK");
+ if (rgi6->flags & RGI_NETMASK_DEFINED)
+ buf_printf (&out, "/%d", rgi6->gateway.netbits_ipv6);
+#ifdef _WIN32
+ if (rgi6->flags & RGI_IFACE_DEFINED)
+ buf_printf (&out, " I=%u", (unsigned int)rgi6->adapter_index);
+#else
+ if (rgi6->flags & RGI_IFACE_DEFINED)
+ buf_printf (&out, " IFACE=%s", rgi6->iface);
+#endif
+ if (rgi6->flags & RGI_HWADDR_DEFINED)
+ buf_printf (&out, " HWADDR=%s", format_hex_ex (rgi6->hwaddr, 6, 0, 1, ":", &gc));
+ msg (msglevel, "%s", BSTR (&out));
+ }
gc_free (&gc);
}
@@ -1167,9 +1263,9 @@ print_route (const struct route_ipv4 *r, int level)
void
print_routes (const struct route_list *rl, int level)
{
- int i;
- for (i = 0; i < rl->n; ++i)
- print_route (&rl->routes[i], level);
+ struct route_ipv4 *r;
+ for (r = rl->routes; r; r = r->next)
+ print_route (r, level);
}
static void
@@ -1195,16 +1291,17 @@ setenv_route (struct env_set *es, const struct route_ipv4 *r, int i)
void
setenv_routes (struct env_set *es, const struct route_list *rl)
{
- int i;
- for (i = 0; i < rl->n; ++i)
- setenv_route (es, &rl->routes[i], i + 1);
+ int i = 1;
+ struct route_ipv4 *r;
+ for (r = rl->routes; r; r = r->next)
+ setenv_route (es, r, i++);
}
static void
setenv_route_ipv6 (struct env_set *es, const struct route_ipv6 *r6, int i)
{
struct gc_arena gc = gc_new ();
- if (r6->defined)
+ if (r6->flags & RT_DEFINED)
{
struct buffer name1 = alloc_buf_gc( 256, &gc );
struct buffer val = alloc_buf_gc( 256, &gc );
@@ -1223,9 +1320,10 @@ setenv_route_ipv6 (struct env_set *es, const struct route_ipv6 *r6, int i)
void
setenv_routes_ipv6 (struct env_set *es, const struct route_ipv6_list *rl6)
{
- int i;
- for (i = 0; i < rl6->n; ++i)
- setenv_route_ipv6 (es, &rl6->routes_ipv6[i], i + 1);
+ int i = 1;
+ struct route_ipv6 *r6;
+ for (r6 = rl6->routes_ipv6; r6; r6 = r6->next)
+ setenv_route_ipv6 (es, r6, i++);
}
/*
@@ -1297,7 +1395,7 @@ add_route (struct route_ipv4 *r,
const struct env_set *es)
{
struct gc_arena gc;
- struct argv argv;
+ struct argv argv = argv_new ();
const char *network;
const char *netmask;
const char *gateway;
@@ -1308,7 +1406,6 @@ add_route (struct route_ipv4 *r,
return;
gc_init (&gc);
- argv_init (&argv);
network = print_in_addr_t (r->network, 0, &gc);
netmask = print_in_addr_t (r->netmask, 0, &gc);
@@ -1323,7 +1420,7 @@ add_route (struct route_ipv4 *r,
argv_printf (&argv, "%s route add %s/%d",
iproute_path,
network,
- count_netmask_bits(netmask));
+ netmask_to_netbits2(r->netmask));
if (r->flags & RT_METRIC_DEFINED)
argv_printf_cat (&argv, "metric %d", r->metric);
@@ -1348,7 +1445,16 @@ add_route (struct route_ipv4 *r,
argv_msg (D_ROUTE, &argv);
status = openvpn_execve_check (&argv, es, 0, "ERROR: Linux route add command failed");
-#elif defined (WIN32)
+#elif defined (TARGET_ANDROID)
+ struct buffer out = alloc_buf_gc (128, &gc);
+
+ if (rgi)
+ buf_printf (&out, "%s %s %s dev %s", network, netmask, gateway, rgi->iface);
+ else
+ buf_printf (&out, "%s %s %s", network, netmask, gateway);
+ management_android_control (management, "ROUTE", buf_bptr(&out));
+
+#elif defined (_WIN32)
{
DWORD ai = TUN_ADAPTER_INDEX_INVALID;
argv_printf (&argv, "%s%sc ADD %s MASK %s %s",
@@ -1367,7 +1473,12 @@ add_route (struct route_ipv4 *r,
argv_msg (D_ROUTE, &argv);
- if ((flags & ROUTE_METHOD_MASK) == ROUTE_METHOD_IPAPI)
+ if ((flags & ROUTE_METHOD_MASK) == ROUTE_METHOD_SERVICE)
+ {
+ status = add_route_service (r, tt);
+ msg (D_ROUTE, "Route addition via service %s", status ? "succeeded" : "failed");
+ }
+ else if ((flags & ROUTE_METHOD_MASK) == ROUTE_METHOD_IPAPI)
{
status = add_route_ipapi (r, tt, ai);
msg (D_ROUTE, "Route addition via IPAPI %s", status ? "succeeded" : "failed");
@@ -1511,6 +1622,17 @@ add_route (struct route_ipv4 *r,
argv_msg (D_ROUTE, &argv);
status = openvpn_execve_check (&argv, es, 0, "ERROR: OpenBSD/NetBSD route add command failed");
+#elif defined(TARGET_AIX)
+
+ {
+ int netbits = netmask_to_netbits2(r->netmask);
+ argv_printf (&argv, "%s add -net %s/%d %s",
+ ROUTE_PATH,
+ network, netbits, gateway);
+ argv_msg (D_ROUTE, &argv);
+ status = openvpn_execve_check (&argv, es, 0, "ERROR: AIX route add command failed");
+ }
+
#else
msg (M_FATAL, "Sorry, but I don't know how to do 'route' commands on this operating system. Try putting your routes in a --route-up script");
#endif
@@ -1525,33 +1647,30 @@ add_route (struct route_ipv4 *r,
}
-static const char *
-print_in6_addr_netbits_only( struct in6_addr network_copy, int netbits,
- struct gc_arena * gc)
+static void
+route_ipv6_clear_host_bits( struct route_ipv6 *r6 )
{
/* clear host bit parts of route
* (needed if routes are specified improperly, or if we need to
* explicitely setup/clear the "connected" network routes on some OSes)
*/
int byte = 15;
- int bits_to_clear = 128 - netbits;
+ int bits_to_clear = 128 - r6->netbits;
while( byte >= 0 && bits_to_clear > 0 )
{
if ( bits_to_clear >= 8 )
- { network_copy.s6_addr[byte--] = 0; bits_to_clear -= 8; }
+ { r6->network.s6_addr[byte--] = 0; bits_to_clear -= 8; }
else
- { network_copy.s6_addr[byte--] &= (0xff << bits_to_clear); bits_to_clear = 0; }
+ { r6->network.s6_addr[byte--] &= (0xff << bits_to_clear); bits_to_clear = 0; }
}
-
- return print_in6_addr( network_copy, 0, gc);
}
void
add_route_ipv6 (struct route_ipv6 *r6, const struct tuntap *tt, unsigned int flags, const struct env_set *es)
{
struct gc_arena gc;
- struct argv argv;
+ struct argv argv = argv_new ();
const char *network;
const char *gateway;
@@ -1560,19 +1679,48 @@ add_route_ipv6 (struct route_ipv6 *r6, const struct tuntap *tt, unsigned int fla
bool gateway_needed = false;
- if (!r6->defined)
+ if (! (r6->flags & RT_DEFINED) )
return;
+#ifndef _WIN32
+ if ( r6->iface != NULL ) /* vpn server special route */
+ {
+ device = r6->iface;
+ if ( !IN6_IS_ADDR_UNSPECIFIED(&r6->gateway) )
+ gateway_needed = true;
+ }
+#endif
+
gc_init (&gc);
- argv_init (&argv);
- network = print_in6_addr_netbits_only( r6->network, r6->netbits, &gc);
+ route_ipv6_clear_host_bits (r6);
+
+ network = print_in6_addr( r6->network, 0, &gc);
gateway = print_in6_addr( r6->gateway, 0, &gc);
- if ( !tt->ipv6 )
+#if defined(TARGET_DARWIN) || \
+ defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY) || \
+ defined(TARGET_OPENBSD) || defined(TARGET_NETBSD)
+
+ /* the BSD platforms cannot specify gateway and interface independently,
+ * but for link-local destinations, we MUST specify the interface, so
+ * we build a combined "$gateway%$interface" gateway string
+ */
+ if ( r6->iface != NULL && gateway_needed &&
+ IN6_IS_ADDR_LINKLOCAL(&r6->gateway) ) /* fe80::...%intf */
{
- msg( M_INFO, "add_route_ipv6(): not adding %s/%d, no IPv6 on if %s",
- network, r6->netbits, device );
+ int len = strlen(gateway) + 1 + strlen(r6->iface)+1;
+ char * tmp = gc_malloc( len, true, &gc );
+ snprintf( tmp, len, "%s%%%s", gateway, r6->iface );
+ gateway = tmp;
+ }
+#endif
+
+ if (!tt->did_ifconfig_ipv6_setup)
+ {
+ msg( M_INFO, "add_route_ipv6(): not adding %s/%d: "
+ "no IPv6 address been configured on interface %s",
+ network, r6->netbits, device);
return;
}
@@ -1591,7 +1739,7 @@ add_route_ipv6 (struct route_ipv6 *r6, const struct tuntap *tt, unsigned int fla
* gateway unless the route is to be an on-link network
*/
if ( tt->type == DEV_TYPE_TAP &&
- !(r6->metric_defined && r6->metric == 0 ) )
+ !( (r6->flags & RT_METRIC_DEFINED) && r6->metric == 0 ) )
{
gateway_needed = true;
}
@@ -1605,7 +1753,7 @@ add_route_ipv6 (struct route_ipv6 *r6, const struct tuntap *tt, unsigned int fla
device);
if (gateway_needed)
argv_printf_cat (&argv, "via %s", gateway);
- if (r6->metric_defined && r6->metric > 0 )
+ if ( (r6->flags & RT_METRIC_DEFINED) && r6->metric > 0 )
argv_printf_cat (&argv, " metric %d", r6->metric);
#else
@@ -1616,70 +1764,95 @@ add_route_ipv6 (struct route_ipv6 *r6, const struct tuntap *tt, unsigned int fla
device);
if (gateway_needed)
argv_printf_cat (&argv, "gw %s", gateway);
- if (r6->metric_defined && r6->metric > 0 )
+ if ( (r6->flags & RT_METRIC_DEFINED) && r6->metric > 0 )
argv_printf_cat (&argv, " metric %d", r6->metric);
#endif /*ENABLE_IPROUTE*/
argv_msg (D_ROUTE, &argv);
status = openvpn_execve_check (&argv, es, 0, "ERROR: Linux route -6/-A inet6 add command failed");
-#elif defined (WIN32)
+#elif defined (TARGET_ANDROID)
+ struct buffer out = alloc_buf_gc (64, &gc);
+
+ buf_printf (&out, "%s/%d %s", network, r6->netbits, device);
+
+ management_android_control (management, "ROUTE6", buf_bptr(&out));
+
+#elif defined (_WIN32)
- if (win32_version_info() != WIN_XP)
+ if (tt->options.msg_channel)
+ status = add_route_ipv6_service (r6, tt);
+ else
{
struct buffer out = alloc_buf_gc (64, &gc);
- buf_printf (&out, "interface=%d", tt->adapter_index );
+ if ( r6->adapter_index ) /* vpn server special route */
+ {
+ buf_printf (&out, "interface=%d", r6->adapter_index );
+ gateway_needed = true;
+ }
+ else
+ {
+ buf_printf (&out, "interface=%d", tt->adapter_index );
+ }
device = buf_bptr(&out);
- }
- /* netsh interface ipv6 add route 2001:db8::/32 MyTunDevice */
- argv_printf (&argv, "%s%sc interface ipv6 add route %s/%d %s",
- get_win_sys_path(),
- NETSH_PATH_SUFFIX,
- network,
- r6->netbits,
- device);
-
- /* next-hop depends on TUN or TAP mode:
- * - in TAP mode, we use the "real" next-hop
- * - in TUN mode we use a special-case link-local address that the tapdrvr
- * knows about and will answer ND (neighbor discovery) packets for
- */
- if ( tt->type == DEV_TYPE_TUN )
- argv_printf_cat( &argv, " %s", "fe80::8" );
- else
- argv_printf_cat( &argv, " %s", gateway );
+ /* netsh interface ipv6 add route 2001:db8::/32 MyTunDevice */
+ argv_printf (&argv, "%s%sc interface ipv6 add route %s/%d %s",
+ get_win_sys_path(),
+ NETSH_PATH_SUFFIX,
+ network,
+ r6->netbits,
+ device);
+
+ /* next-hop depends on TUN or TAP mode:
+ * - in TAP mode, we use the "real" next-hop
+ * - in TUN mode we use a special-case link-local address that the tapdrvr
+ * knows about and will answer ND (neighbor discovery) packets for
+ */
+ if ( tt->type == DEV_TYPE_TUN && !gateway_needed )
+ argv_printf_cat( &argv, " %s", "fe80::8" );
+ else if ( !IN6_IS_ADDR_UNSPECIFIED(&r6->gateway) )
+ argv_printf_cat( &argv, " %s", gateway );
#if 0
- if (r->metric_defined)
- argv_printf_cat (&argv, " METRIC %d", r->metric);
+ if (r6->flags & RT_METRIC_DEFINED)
+ argv_printf_cat (&argv, " METRIC %d", r->metric);
#endif
- /* in some versions of Windows, routes are persistent across reboots by
- * default, unless "store=active" is set (pointed out by Tony Lim, thanks)
- */
- argv_printf_cat( &argv, " store=active" );
+ /* in some versions of Windows, routes are persistent across reboots by
+ * default, unless "store=active" is set (pointed out by Tony Lim, thanks)
+ */
+ argv_printf_cat( &argv, " store=active" );
- argv_msg (D_ROUTE, &argv);
+ argv_msg (D_ROUTE, &argv);
- netcmd_semaphore_lock ();
- status = openvpn_execve_check (&argv, es, 0, "ERROR: Windows route add ipv6 command failed");
- netcmd_semaphore_release ();
+ netcmd_semaphore_lock ();
+ status = openvpn_execve_check (&argv, es, 0, "ERROR: Windows route add ipv6 command failed");
+ netcmd_semaphore_release ();
+ }
#elif defined (TARGET_SOLARIS)
/* example: route add -inet6 2001:db8::/32 somegateway 0 */
- /* for some weird reason, this does not work for me unless I set
+ /* for some reason, routes to tun/tap do not work for me unless I set
* "metric 0" - otherwise, the routes will be nicely installed, but
- * packets will just disappear somewhere. So we use "0" now...
+ * packets will just disappear somewhere. So we always use "0" now,
+ * unless the route points to "gateway on other interface"...
+ *
+ * (Note: OpenSolaris can not specify host%interface gateways, so we just
+ * use the GW addresses - it seems to still work for fe80:: addresses,
+ * however this is done internally. NUD maybe?)
*/
-
- argv_printf (&argv, "%s add -inet6 %s/%d %s 0",
+ argv_printf (&argv, "%s add -inet6 %s/%d %s",
ROUTE_PATH,
network,
r6->netbits,
gateway );
+ /* on tun/tap, not "elsewhere"? -> metric 0 */
+ if ( !r6->iface )
+ argv_printf_cat (&argv, "0");
+
argv_msg (D_ROUTE, &argv);
status = openvpn_execve_check (&argv, es, 0, "ERROR: Solaris route add -inet6 command failed");
@@ -1730,11 +1903,22 @@ add_route_ipv6 (struct route_ipv6 *r6, const struct tuntap *tt, unsigned int fla
argv_msg (D_ROUTE, &argv);
status = openvpn_execve_check (&argv, es, 0, "ERROR: NetBSD route add -inet6 command failed");
+#elif defined(TARGET_AIX)
+
+ argv_printf (&argv, "%s add -inet6 %s/%d %s",
+ ROUTE_PATH,
+ network, r6->netbits, gateway);
+ argv_msg (D_ROUTE, &argv);
+ status = openvpn_execve_check (&argv, es, 0, "ERROR: AIX route add command failed");
+
#else
msg (M_FATAL, "Sorry, but I don't know how to do 'route ipv6' commands on this operating system. Try putting your routes in a --route-up script");
#endif
- r6->defined = status;
+ if (status)
+ r6->flags |= RT_ADDED;
+ else
+ r6->flags &= ~RT_ADDED;
argv_reset (&argv);
gc_free (&gc);
}
@@ -1747,7 +1931,7 @@ delete_route (struct route_ipv4 *r,
const struct env_set *es)
{
struct gc_arena gc;
- struct argv argv;
+ struct argv argv = argv_new ();
const char *network;
const char *netmask;
const char *gateway;
@@ -1757,7 +1941,6 @@ delete_route (struct route_ipv4 *r,
return;
gc_init (&gc);
- argv_init (&argv);
network = print_in_addr_t (r->network, 0, &gc);
netmask = print_in_addr_t (r->netmask, 0, &gc);
@@ -1772,7 +1955,7 @@ delete_route (struct route_ipv4 *r,
argv_printf (&argv, "%s route del %s/%d",
iproute_path,
network,
- count_netmask_bits(netmask));
+ netmask_to_netbits2(r->netmask));
#else
argv_printf (&argv, "%s del -net %s netmask %s",
ROUTE_PATH,
@@ -1784,7 +1967,7 @@ delete_route (struct route_ipv4 *r,
argv_msg (D_ROUTE, &argv);
openvpn_execve_check (&argv, es, 0, "ERROR: Linux route delete command failed");
-#elif defined (WIN32)
+#elif defined (_WIN32)
argv_printf (&argv, "%s%sc DELETE %s MASK %s %s",
get_win_sys_path(),
@@ -1795,7 +1978,12 @@ delete_route (struct route_ipv4 *r,
argv_msg (D_ROUTE, &argv);
- if ((flags & ROUTE_METHOD_MASK) == ROUTE_METHOD_IPAPI)
+ if ((flags & ROUTE_METHOD_MASK) == ROUTE_METHOD_SERVICE)
+ {
+ const bool status = del_route_service (r, tt);
+ msg (D_ROUTE, "Route deletion via service %s", status ? "succeeded" : "failed");
+ }
+ else if ((flags & ROUTE_METHOD_MASK) == ROUTE_METHOD_IPAPI)
{
const bool status = del_route_ipapi (r, tt);
msg (D_ROUTE, "Route deletion via IPAPI %s", status ? "succeeded" : "failed");
@@ -1889,6 +2077,20 @@ delete_route (struct route_ipv4 *r,
argv_msg (D_ROUTE, &argv);
openvpn_execve_check (&argv, es, 0, "ERROR: OpenBSD/NetBSD route delete command failed");
+#elif defined(TARGET_ANDROID)
+ msg (M_NONFATAL, "Sorry, deleting routes on Android is not possible. The VpnService API allows routes to be set on connect only.");
+
+#elif defined(TARGET_AIX)
+
+ {
+ int netbits = netmask_to_netbits2(r->netmask);
+ argv_printf (&argv, "%s delete -net %s/%d %s",
+ ROUTE_PATH,
+ network, netbits, gateway);
+ argv_msg (D_ROUTE, &argv);
+ openvpn_execve_check (&argv, es, 0, "ERROR: AIX route delete command failed");
+ }
+
#else
msg (M_FATAL, "Sorry, but I don't know how to do 'route' commands on this operating system. Try putting your routes in a --route-up script");
#endif
@@ -1903,27 +2105,45 @@ void
delete_route_ipv6 (const struct route_ipv6 *r6, const struct tuntap *tt, unsigned int flags, const struct env_set *es)
{
struct gc_arena gc;
- struct argv argv;
+ struct argv argv = argv_new ();
const char *network;
const char *gateway;
const char *device = tt->actual_name;
bool gateway_needed = false;
- if (!r6->defined)
+ if ((r6->flags & (RT_DEFINED|RT_ADDED)) != (RT_DEFINED|RT_ADDED))
return;
+#ifndef _WIN32
+ if ( r6->iface != NULL ) /* vpn server special route */
+ {
+ device = r6->iface;
+ gateway_needed = true;
+ }
+#endif
+
gc_init (&gc);
- argv_init (&argv);
- network = print_in6_addr_netbits_only( r6->network, r6->netbits, &gc);
+ network = print_in6_addr( r6->network, 0, &gc);
gateway = print_in6_addr( r6->gateway, 0, &gc);
- if ( !tt->ipv6 )
+#if defined(TARGET_DARWIN) || \
+ defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY) || \
+ defined(TARGET_OPENBSD) || defined(TARGET_NETBSD)
+
+ /* the BSD platforms cannot specify gateway and interface independently,
+ * but for link-local destinations, we MUST specify the interface, so
+ * we build a combined "$gateway%$interface" gateway string
+ */
+ if ( r6->iface != NULL && gateway_needed &&
+ IN6_IS_ADDR_LINKLOCAL(&r6->gateway) ) /* fe80::...%intf */
{
- msg( M_INFO, "delete_route_ipv6(): not deleting %s/%d, no IPv6 on if %s",
- network, r6->netbits, device );
- return;
+ int len = strlen(gateway) + 1 + strlen(r6->iface)+1;
+ char * tmp = gc_malloc( len, true, &gc );
+ snprintf( tmp, len, "%s%%%s", gateway, r6->iface );
+ gateway = tmp;
}
+#endif
msg( M_INFO, "delete_route_ipv6(%s/%d)", network, r6->netbits );
@@ -1931,7 +2151,7 @@ delete_route_ipv6 (const struct route_ipv6 *r6, const struct tuntap *tt, unsigne
* delete, otherwise some OSes will refuse to delete the route
*/
if ( tt->type == DEV_TYPE_TAP &&
- !(r6->metric_defined && r6->metric == 0 ) )
+ !( (r6->flags & RT_METRIC_DEFINED) && r6->metric == 0 ) )
{
gateway_needed = true;
}
@@ -1954,61 +2174,70 @@ delete_route_ipv6 (const struct route_ipv6 *r6, const struct tuntap *tt, unsigne
device);
if (gateway_needed)
argv_printf_cat (&argv, "gw %s", gateway);
- if (r6->metric_defined && r6->metric > 0 )
+ if ( (r6->flags & RT_METRIC_DEFINED) && r6->metric > 0 )
argv_printf_cat (&argv, " metric %d", r6->metric);
#endif /*ENABLE_IPROUTE*/
argv_msg (D_ROUTE, &argv);
openvpn_execve_check (&argv, es, 0, "ERROR: Linux route -6/-A inet6 del command failed");
-#elif defined (WIN32)
+#elif defined (_WIN32)
- if (win32_version_info() != WIN_XP)
+ if (tt->options.msg_channel)
+ del_route_ipv6_service (r6, tt);
+ else
{
struct buffer out = alloc_buf_gc (64, &gc);
- buf_printf (&out, "interface=%d", tt->adapter_index );
+ if ( r6->adapter_index ) /* vpn server special route */
+ {
+ buf_printf (&out, "interface=%d", r6->adapter_index );
+ gateway_needed = true;
+ }
+ else
+ {
+ buf_printf (&out, "interface=%d", tt->adapter_index );
+ }
device = buf_bptr(&out);
- }
- /* netsh interface ipv6 delete route 2001:db8::/32 MyTunDevice */
- argv_printf (&argv, "%s%sc interface ipv6 delete route %s/%d %s",
- get_win_sys_path(),
- NETSH_PATH_SUFFIX,
- network,
- r6->netbits,
- device);
-
- /* next-hop depends on TUN or TAP mode:
- * - in TAP mode, we use the "real" next-hop
- * - in TUN mode we use a special-case link-local address that the tapdrvr
- * knows about and will answer ND (neighbor discovery) packets for
- * (and "route deletion without specifying next-hop" does not work...)
- */
- if ( tt->type == DEV_TYPE_TUN )
- argv_printf_cat( &argv, " %s", "fe80::8" );
- else
- argv_printf_cat( &argv, " %s", gateway );
+ /* netsh interface ipv6 delete route 2001:db8::/32 MyTunDevice */
+ argv_printf (&argv, "%s%sc interface ipv6 delete route %s/%d %s",
+ get_win_sys_path(),
+ NETSH_PATH_SUFFIX,
+ network,
+ r6->netbits,
+ device);
+
+ /* next-hop depends on TUN or TAP mode:
+ * - in TAP mode, we use the "real" next-hop
+ * - in TUN mode we use a special-case link-local address that the tapdrvr
+ * knows about and will answer ND (neighbor discovery) packets for
+ * (and "route deletion without specifying next-hop" does not work...)
+ */
+ if ( tt->type == DEV_TYPE_TUN && !gateway_needed )
+ argv_printf_cat( &argv, " %s", "fe80::8" );
+ else if ( !IN6_IS_ADDR_UNSPECIFIED(&r6->gateway) )
+ argv_printf_cat( &argv, " %s", gateway );
#if 0
- if (r->metric_defined)
- argv_printf_cat (&argv, "METRIC %d", r->metric);
+ if (r6->flags & RT_METRIC_DEFINED)
+ argv_printf_cat (&argv, "METRIC %d", r->metric);
#endif
- /* Windows XP to 7 "just delete" routes, wherever they came from, but
- * in Windows 8(.1?), if you create them with "store=active", this is
- * how you should delete them as well (pointed out by Cedric Tabary)
- */
- argv_printf_cat( &argv, " store=active" );
+ /* Windows XP to 7 "just delete" routes, wherever they came from, but
+ * in Windows 8(.1?), if you create them with "store=active", this is
+ * how you should delete them as well (pointed out by Cedric Tabary)
+ */
+ argv_printf_cat( &argv, " store=active" );
- argv_msg (D_ROUTE, &argv);
+ argv_msg (D_ROUTE, &argv);
- netcmd_semaphore_lock ();
- openvpn_execve_check (&argv, es, 0, "ERROR: Windows route delete ipv6 command failed");
- netcmd_semaphore_release ();
+ netcmd_semaphore_lock ();
+ openvpn_execve_check (&argv, es, 0, "ERROR: Windows route delete ipv6 command failed");
+ netcmd_semaphore_release ();
+ }
#elif defined (TARGET_SOLARIS)
/* example: route delete -inet6 2001:db8::/32 somegateway */
- /* GERT-TODO: this is untested, but should work */
argv_printf (&argv, "%s delete -inet6 %s/%d %s",
ROUTE_PATH,
@@ -2066,6 +2295,14 @@ delete_route_ipv6 (const struct route_ipv6 *r6, const struct tuntap *tt, unsigne
argv_msg (D_ROUTE, &argv);
openvpn_execve_check (&argv, es, 0, "ERROR: NetBSD route delete -inet6 command failed");
+#elif defined(TARGET_AIX)
+
+ argv_printf (&argv, "%s delete -inet6 %s/%d %s",
+ ROUTE_PATH,
+ network, r6->netbits, gateway);
+ argv_msg (D_ROUTE, &argv);
+ openvpn_execve_check (&argv, es, 0, "ERROR: AIX route add command failed");
+
#else
msg (M_FATAL, "Sorry, but I don't know how to do 'route ipv6' commands on this operating system. Try putting your routes in a --route-down script");
#endif
@@ -2079,7 +2316,7 @@ delete_route_ipv6 (const struct route_ipv6 *r6, const struct tuntap *tt, unsigne
* to get the current default gateway.
*/
-#if defined(WIN32)
+#if defined(_WIN32)
static const MIB_IPFORWARDTABLE *
get_windows_routing_table (struct gc_arena *gc)
@@ -2148,6 +2385,7 @@ test_routes (const struct route_list *rl, const struct tuntap *tt)
int count = 0;
int good = 0;
int ambig = 0;
+ int len = -1;
bool adapter_up = false;
if (is_adapter_up (tt, adapters))
@@ -2157,9 +2395,9 @@ test_routes (const struct route_list *rl, const struct tuntap *tt)
if (rl)
{
- int i;
- for (i = 0; i < rl->n; ++i)
- test_route_helper (&ret, &count, &good, &ambig, adapters, rl->routes[i].gateway);
+ struct route_ipv4 *r;
+ for (r = rl->routes, len = 0; r; r = r->next, ++len)
+ test_route_helper (&ret, &count, &good, &ambig, adapters, r->gateway);
if ((rl->flags & RG_ENABLE) && (rl->spec.flags & RTSA_REMOTE_ENDPOINT))
test_route_helper (&ret, &count, &good, &ambig, adapters, rl->spec.remote_endpoint);
@@ -2169,7 +2407,7 @@ test_routes (const struct route_list *rl, const struct tuntap *tt)
msg (D_ROUTE, "TEST ROUTES: %d/%d succeeded len=%d ret=%d a=%d u/d=%s",
good,
count,
- rl ? rl->n : -1,
+ len,
(int)ret,
ambig,
adapter_up ? "up" : "down");
@@ -2301,6 +2539,81 @@ windows_route_find_if_index (const struct route_ipv4 *r, const struct tuntap *tt
return ret;
}
+/* IPv6 implementation using GetBestRoute2()
+ * (TBD: dynamic linking so the binary can still run on XP?)
+ * https://msdn.microsoft.com/en-us/library/windows/desktop/aa365922(v=vs.85).aspx
+ * https://msdn.microsoft.com/en-us/library/windows/desktop/aa814411(v=vs.85).aspx
+ */
+void
+get_default_gateway_ipv6(struct route_ipv6_gateway_info *rgi6,
+ const struct in6_addr *dest)
+{
+ struct gc_arena gc = gc_new ();
+ MIB_IPFORWARD_ROW2 BestRoute;
+ SOCKADDR_INET DestinationAddress, BestSourceAddress;
+ DWORD BestIfIndex;
+ DWORD status;
+ NET_LUID InterfaceLuid;
+
+ CLEAR(*rgi6);
+ CLEAR(InterfaceLuid); // cleared = not used for lookup
+ CLEAR(DestinationAddress);
+
+ DestinationAddress.si_family = AF_INET6;
+ if ( dest )
+ {
+ DestinationAddress.Ipv6.sin6_addr = *dest;
+ }
+
+ status = GetBestInterfaceEx( &DestinationAddress, &BestIfIndex );
+
+ if (status != NO_ERROR)
+ {
+ msg (D_ROUTE, "NOTE: GetBestInterfaceEx returned error: %s (code=%u)",
+ strerror_win32 (status, &gc),
+ (unsigned int)status);
+ goto done;
+ }
+
+ msg( D_ROUTE, "GetBestInterfaceEx() returned if=%d", (int) BestIfIndex );
+
+ status = GetBestRoute2( &InterfaceLuid, BestIfIndex, NULL,
+ &DestinationAddress, 0,
+ &BestRoute, &BestSourceAddress );
+
+ if (status != NO_ERROR)
+ {
+ msg (D_ROUTE, "NOTE: GetIpForwardEntry2 returned error: %s (code=%u)",
+ strerror_win32 (status, &gc),
+ (unsigned int)status);
+ goto done;
+ }
+
+ msg( D_ROUTE, "GDG6: II=%d DP=%s/%d NH=%s",
+ BestRoute.InterfaceIndex,
+ print_in6_addr( BestRoute.DestinationPrefix.Prefix.Ipv6.sin6_addr, 0, &gc),
+ BestRoute.DestinationPrefix.PrefixLength,
+ print_in6_addr( BestRoute.NextHop.Ipv6.sin6_addr, 0, &gc) );
+ msg( D_ROUTE, "GDG6: Metric=%d, Loopback=%d, AA=%d, I=%d",
+ (int) BestRoute.Metric,
+ (int) BestRoute.Loopback,
+ (int) BestRoute.AutoconfigureAddress,
+ (int) BestRoute.Immortal );
+
+ rgi6->gateway.addr_ipv6 = BestRoute.NextHop.Ipv6.sin6_addr;
+ rgi6->adapter_index = BestRoute.InterfaceIndex;
+ rgi6->flags |= RGI_ADDR_DEFINED | RGI_IFACE_DEFINED;
+
+ /* on-link is signalled by receiving an empty (::) NextHop */
+ if ( IN6_IS_ADDR_UNSPECIFIED(&BestRoute.NextHop.Ipv6.sin6_addr) )
+ {
+ rgi6->flags |= RGI_ON_LINK;
+ }
+
+ done:
+ gc_free (&gc);
+}
+
bool
add_route_ipapi (const struct route_ipv4 *r, const struct tuntap *tt, DWORD adapter_index)
{
@@ -2407,6 +2720,126 @@ del_route_ipapi (const struct route_ipv4 *r, const struct tuntap *tt)
return ret;
}
+static bool
+do_route_service (const bool add, const route_message_t *rt, const size_t size, HANDLE pipe)
+{
+ DWORD len;
+ bool ret = false;
+ ack_message_t ack;
+ struct gc_arena gc = gc_new ();
+
+ if (!WriteFile (pipe, rt, size, &len, NULL) ||
+ !ReadFile (pipe, &ack, sizeof (ack), &len, NULL))
+ {
+ msg (M_WARN, "ROUTE: could not talk to service: %s [%lu]",
+ strerror_win32 (GetLastError (), &gc), GetLastError ());
+ goto out;
+ }
+
+ if (ack.error_number != NO_ERROR)
+ {
+ msg (M_WARN, "ROUTE: route %s failed using service: %s [status=%u if_index=%lu]",
+ (add ? "addition" : "deletion"), strerror_win32 (ack.error_number, &gc),
+ ack.error_number, rt->iface.index);
+ goto out;
+ }
+
+ ret = true;
+
+out:
+ gc_free (&gc);
+ return ret;
+}
+
+static bool
+do_route_ipv4_service (const bool add, const struct route_ipv4 *r, const struct tuntap *tt)
+{
+ DWORD if_index = windows_route_find_if_index (r, tt);
+ if (if_index == ~0)
+ return false;
+
+ route_message_t msg = {
+ .header = {
+ (add ? msg_add_route : msg_del_route),
+ sizeof (route_message_t),
+ 0 },
+ .family = AF_INET,
+ .prefix.ipv4.s_addr = htonl(r->network),
+ .gateway.ipv4.s_addr = htonl(r->gateway),
+ .iface = { .index = if_index, .name = "" },
+ .metric = (r->flags & RT_METRIC_DEFINED ? r->metric : -1)
+ };
+
+ netmask_to_netbits (r->network, r->netmask, &msg.prefix_len);
+ if (msg.prefix_len == -1)
+ msg.prefix_len = 32;
+
+ return do_route_service (add, &msg, sizeof (msg), tt->options.msg_channel);
+}
+
+static bool
+do_route_ipv6_service (const bool add, const struct route_ipv6 *r, const struct tuntap *tt)
+{
+ bool status;
+ route_message_t msg = {
+ .header = {
+ (add ? msg_add_route : msg_del_route),
+ sizeof (route_message_t),
+ 0 },
+ .family = AF_INET6,
+ .prefix.ipv6 = r->network,
+ .prefix_len = r->netbits,
+ .gateway.ipv6 = r->gateway,
+ .iface = { .index = tt->adapter_index, .name = "" },
+ .metric = ( (r->flags & RT_METRIC_DEFINED) ? r->metric : -1)
+ };
+
+ if ( r->adapter_index ) /* vpn server special route */
+ msg.iface.index = r->adapter_index;
+
+ /* In TUN mode we use a special link-local address as the next hop.
+ * The tapdrvr knows about it and will answer neighbor discovery packets.
+ */
+ if (tt->type == DEV_TYPE_TUN)
+ inet_pton (AF_INET6, "fe80::8", &msg.gateway.ipv6);
+
+ if (msg.iface.index == TUN_ADAPTER_INDEX_INVALID)
+ {
+ strncpy (msg.iface.name, tt->actual_name, sizeof (msg.iface.name));
+ msg.iface.name[sizeof (msg.iface.name) - 1] = '\0';
+ }
+
+ status = do_route_service (add, &msg, sizeof (msg), tt->options.msg_channel);
+ msg (D_ROUTE, "IPv6 route %s via service %s",
+ add ? "addition" : "deletion",
+ status ? "succeeded" : "failed");
+ return status;
+}
+
+static bool
+add_route_service (const struct route_ipv4 *r, const struct tuntap *tt)
+{
+ return do_route_ipv4_service (true, r, tt);
+}
+
+static bool
+del_route_service (const struct route_ipv4 *r, const struct tuntap *tt)
+{
+ return do_route_ipv4_service (false, r, tt);
+}
+
+static bool
+add_route_ipv6_service (const struct route_ipv6 *r, const struct tuntap *tt)
+{
+ return do_route_ipv6_service (true, r, tt);
+}
+
+static bool
+del_route_ipv6_service (const struct route_ipv6 *r, const struct tuntap *tt)
+{
+ return do_route_ipv6_service (false, r, tt);
+}
+
static const char *
format_route_entry (const MIB_IPFORWARDROW *r, struct gc_arena *gc)
{
@@ -2451,7 +2884,7 @@ show_routes (int msglev)
gc_free (&gc);
}
-#elif defined(TARGET_LINUX)
+#elif defined(TARGET_LINUX) || defined(TARGET_ANDROID)
void
get_default_gateway (struct route_gateway_info *rgi)
@@ -2463,6 +2896,7 @@ get_default_gateway (struct route_gateway_info *rgi)
CLEAR(*rgi);
+#ifndef TARGET_ANDROID
/* get default gateway IP addr */
{
FILE *fp = fopen ("/proc/net/route", "r");
@@ -2519,6 +2953,19 @@ get_default_gateway (struct route_gateway_info *rgi)
}
}
}
+#else
+ /* Android, set some pseudo GW, addr is in host byte order,
+ * Determining the default GW on Android 5.0+ is non trivial
+ * and serves almost no purpose since OpenVPN only uses the
+ * default GW address to add routes for networks that should
+ * NOT be routed over the VPN. Using a well known address
+ * (127.'d'.'g'.'w') for the default GW make detecting
+ * these routes easier from the controlling app.
+ */
+ rgi->gateway.addr = 127 << 24 | 'd' << 16 | 'g' << 8 | 'w';
+ rgi->flags |= RGI_ADDR_DEFINED;
+ strcpy(best_name, "android-gw");
+#endif
/* scan adapter list */
if (rgi->flags & RGI_ADDR_DEFINED)
@@ -2617,136 +3064,149 @@ get_default_gateway (struct route_gateway_info *rgi)
gc_free (&gc);
}
-#elif defined(TARGET_FREEBSD)||defined(TARGET_DRAGONFLY)||defined(TARGET_SOLARIS)
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <net/route.h>
-
-struct {
- struct rt_msghdr m_rtm;
- char m_space[512];
-} m_rtmsg;
-
-#define ROUNDUP(a) \
- ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
-
-/*
- * FIXME -- add support for netmask, hwaddr, and iface
+/* IPv6 implementation using netlink
+ * http://www.linuxjournal.com/article/7356
+ * netlink(3), netlink(7), rtnetlink(7)
+ * http://www.virtualbox.org/svn/vbox/trunk/src/VBox/NetworkServices/NAT/rtmon_linux.c
*/
-void
-get_default_gateway (struct route_gateway_info *rgi)
-{
- struct gc_arena gc = gc_new ();
- int s, seq, l, pid, rtm_addrs;
- unsigned int i;
- struct sockaddr so_dst, so_mask;
- char *cp = m_rtmsg.m_space;
- struct sockaddr *gate = NULL, *sa;
- struct rt_msghdr *rtm_aux;
-
-#if defined(TARGET_FREEBSD)||defined(TARGET_DRAGONFLY)
-
-#define NEXTADDR(w, u) \
- if (rtm_addrs & (w)) {\
- l = ROUNDUP(u.sa_len); memmove(cp, &(u), l); cp += l;\
- }
-
-#define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len))
-
-#else /* TARGET_SOLARIS */
-
-#define NEXTADDR(w, u) \
- if (rtm_addrs & (w)) {\
- l = ROUNDUP(sizeof(struct sockaddr_in)); memmove(cp, &(u), l); cp += l;\
- }
-
-#define ADVANCE(x, n) (x += ROUNDUP(sizeof(struct sockaddr_in)))
+struct rtreq {
+ struct nlmsghdr nh;
+ struct rtmsg rtm;
+ char attrbuf[512];
+};
-#endif
+void
+get_default_gateway_ipv6(struct route_ipv6_gateway_info *rgi6,
+ const struct in6_addr *dest)
+{
+ int nls = -1;
+ struct rtreq rtreq;
+ struct rtattr *rta;
+
+ char rtbuf[2000];
+ ssize_t ssize;
+
+ CLEAR(*rgi6);
+
+ nls = socket( PF_NETLINK, SOCK_RAW, NETLINK_ROUTE );
+ if ( nls < 0 )
+ { msg(M_WARN|M_ERRNO, "GDG6: socket() failed" ); goto done; }
+
+ /* bind() is not needed, no unsolicited msgs coming in */
+
+ /* request best matching route, see netlink(7) for explanations
+ */
+ CLEAR(rtreq);
+ rtreq.nh.nlmsg_type = RTM_GETROUTE;
+ rtreq.nh.nlmsg_flags = NLM_F_REQUEST; /* best match only */
+ rtreq.rtm.rtm_family = AF_INET6;
+ rtreq.rtm.rtm_src_len = 0; /* not source dependent */
+ rtreq.rtm.rtm_dst_len = 128; /* exact dst */
+ rtreq.rtm.rtm_table = RT_TABLE_MAIN;
+ rtreq.rtm.rtm_protocol = RTPROT_UNSPEC;
+ rtreq.nh.nlmsg_len = NLMSG_SPACE(sizeof(rtreq.rtm));
+
+ /* set RTA_DST for target IPv6 address we want */
+ rta = (struct rtattr *)(((char *) &rtreq)+NLMSG_ALIGN(rtreq.nh.nlmsg_len));
+ rta->rta_type = RTA_DST;
+ rta->rta_len = RTA_LENGTH(16);
+ rtreq.nh.nlmsg_len = NLMSG_ALIGN(rtreq.nh.nlmsg_len) +
+ RTA_LENGTH(16);
+
+ if ( dest == NULL ) /* ::, unspecified */
+ memset( RTA_DATA(rta), 0, 16 ); /* :: = all-zero */
+ else
+ memcpy( RTA_DATA(rta), (void *)dest, 16 );
+ /* send and receive reply */
+ if ( send( nls, &rtreq, rtreq.nh.nlmsg_len, 0 ) < 0 )
+ { msg(M_WARN|M_ERRNO, "GDG6: send() failed" ); goto done; }
-#define rtm m_rtmsg.m_rtm
+ ssize = recv(nls, rtbuf, sizeof(rtbuf), MSG_TRUNC);
- CLEAR(*rgi);
+ if (ssize < 0)
+ { msg(M_WARN|M_ERRNO, "GDG6: recv() failed" ); goto done; }
- pid = getpid();
- seq = 0;
- rtm_addrs = RTA_DST | RTA_NETMASK;
+ if (ssize > sizeof(rtbuf))
+ {
+ msg(M_WARN, "get_default_gateway_ipv6: returned message too big for buffer (%d>%d)", (int)ssize, (int)sizeof(rtbuf) );
+ goto done;
+ }
- bzero(&so_dst, sizeof(so_dst));
- bzero(&so_mask, sizeof(so_mask));
- bzero(&rtm, sizeof(struct rt_msghdr));
+ struct nlmsghdr *nh;
- rtm.rtm_type = RTM_GET;
- rtm.rtm_flags = RTF_UP | RTF_GATEWAY;
- rtm.rtm_version = RTM_VERSION;
- rtm.rtm_seq = ++seq;
- rtm.rtm_addrs = rtm_addrs;
+ for (nh = (struct nlmsghdr *)rtbuf;
+ NLMSG_OK(nh, ssize);
+ nh = NLMSG_NEXT(nh, ssize))
+ {
+ struct rtmsg *rtm;
+ int attrlen;
- so_dst.sa_family = AF_INET;
- so_mask.sa_family = AF_INET;
+ if (nh->nlmsg_type == NLMSG_DONE) { break; }
-#if defined(TARGET_FREEBSD)||defined(TARGET_DRAGONFLY)
- so_dst.sa_len = sizeof(struct sockaddr_in);
- so_mask.sa_len = sizeof(struct sockaddr_in);
-#endif
+ if (nh->nlmsg_type == NLMSG_ERROR) {
+ struct nlmsgerr *ne = (struct nlmsgerr *)NLMSG_DATA(nh);
+ msg(M_WARN, "GDG6: NLSMG_ERROR: error %d\n", ne->error);
+ break;
+ }
- NEXTADDR(RTA_DST, so_dst);
- NEXTADDR(RTA_NETMASK, so_mask);
+ if (nh->nlmsg_type != RTM_NEWROUTE) {
+ /* shouldn't happen */
+ msg(M_WARN, "GDG6: unexpected msg_type %d", nh->nlmsg_type );
+ continue;
+ }
- rtm.rtm_msglen = l = cp - (char *)&m_rtmsg;
+ rtm = (struct rtmsg *)NLMSG_DATA(nh);
+ attrlen = RTM_PAYLOAD(nh);
- s = socket(PF_ROUTE, SOCK_RAW, 0);
+ /* we're only looking for routes in the main table, as "we have
+ * no IPv6" will lead to a lookup result in "Local" (::/0 reject)
+ */
+ if (rtm->rtm_family != AF_INET6 ||
+ rtm->rtm_table != RT_TABLE_MAIN)
+ { continue; } /* we're not interested */
- if (write(s, (char *)&m_rtmsg, l) < 0)
- {
- msg(M_WARN|M_ERRNO, "Could not retrieve default gateway from route socket:");
- gc_free (&gc);
- close(s);
- return;
+ for (rta = RTM_RTA(rtm);
+ RTA_OK(rta, attrlen);
+ rta = RTA_NEXT(rta, attrlen))
+ {
+ if (rta->rta_type == RTA_GATEWAY) {
+ if ( RTA_PAYLOAD(rta) != sizeof(struct in6_addr) )
+ { msg(M_WARN, "GDG6: RTA_GW size mismatch"); continue; }
+ rgi6->gateway.addr_ipv6 = *(struct in6_addr*) RTA_DATA(rta);
+ rgi6->flags |= RGI_ADDR_DEFINED;
+ }
+ else if (rta->rta_type == RTA_OIF) {
+ char ifname[IF_NAMESIZE+1];
+ int oif;
+ if ( RTA_PAYLOAD(rta) != sizeof(oif) )
+ { msg(M_WARN, "GDG6: oif size mismatch"); continue; }
+
+ memcpy(&oif, RTA_DATA(rta), sizeof(oif));
+ if_indextoname(oif,ifname);
+ strncpy( rgi6->iface, ifname, sizeof(rgi6->iface)-1 );
+ rgi6->flags |= RGI_IFACE_DEFINED;
+ }
+ }
}
- do {
- l = read(s, (char *)&m_rtmsg, sizeof(m_rtmsg));
- } while (l > 0 && (rtm.rtm_seq != seq || rtm.rtm_pid != pid));
-
- close(s);
-
- rtm_aux = &rtm;
-
- cp = ((char *)(rtm_aux + 1));
- if (rtm_aux->rtm_addrs) {
- for (i = 1; i; i <<= 1)
- if (i & rtm_aux->rtm_addrs) {
- sa = (struct sockaddr *)cp;
- if (i == RTA_GATEWAY )
- gate = sa;
- ADVANCE(cp, sa);
- }
- }
- else
+ /* if we have an interface but no gateway, the destination is on-link */
+ if ( ( rgi6->flags & (RGI_IFACE_DEFINED|RGI_ADDR_DEFINED) ) ==
+ RGI_IFACE_DEFINED )
{
- gc_free (&gc);
- return;
+ rgi6->flags |= (RGI_ADDR_DEFINED | RGI_ON_LINK);
+ if ( dest )
+ rgi6->gateway.addr_ipv6 = *dest;
}
-
- if (gate != NULL )
- {
- rgi->gateway.addr = ntohl(((struct sockaddr_in *)gate)->sin_addr.s_addr);
- rgi->flags |= RGI_ADDR_DEFINED;
-
- gc_free (&gc);
- }
- else
- {
- gc_free (&gc);
- }
+ done:
+ if (nls >= 0)
+ close (nls);
}
-#elif defined(TARGET_DARWIN)
+#elif defined(TARGET_DARWIN) || defined(TARGET_SOLARIS) || \
+ defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY) || \
+ defined(TARGET_OPENBSD) || defined(TARGET_NETBSD)
#include <sys/types.h>
#include <sys/socket.h>
@@ -2759,15 +3219,41 @@ struct rtmsg {
char m_space[512];
};
-#define ROUNDUP(a) \
+/* 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
+ * 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
+ *
+ * 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
+ */
+
+#if defined(TARGET_DARWIN)
+# define ROUNDUP(a) \
((a) > 0 ? (1 + (((a) - 1) | (sizeof(uint32_t) - 1))) : sizeof(uint32_t))
+#else
+# define ROUNDUP(a) \
+ ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
+#endif
+
+#if defined(TARGET_SOLARIS)
+#define NEXTADDR(w, u) \
+ if (rtm_addrs & (w)) {\
+ l = ROUNDUP(sizeof(u)); memmove(cp, &(u), l); cp += l;\
+ }
+#define ADVANCE(x, n) (x += ROUNDUP(sizeof(struct sockaddr_in)))
+#else
#define NEXTADDR(w, u) \
if (rtm_addrs & (w)) {\
- l = ROUNDUP(u.sa_len); memmove(cp, &(u), l); cp += l;\
+ l = ROUNDUP( ((struct sockaddr *)&(u))->sa_len); memmove(cp, &(u), l); cp += l;\
}
#define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len))
+#endif
#define max(a,b) ((a) > (b) ? (a) : (b))
@@ -2805,9 +3291,12 @@ get_default_gateway (struct route_gateway_info *rgi)
rtm.rtm_addrs = rtm_addrs;
so_dst.sa_family = AF_INET;
- so_dst.sa_len = sizeof(struct sockaddr_in);
so_mask.sa_family = AF_INET;
+
+#ifndef TARGET_SOLARIS
+ so_dst.sa_len = sizeof(struct sockaddr_in);
so_mask.sa_len = sizeof(struct sockaddr_in);
+#endif
NEXTADDR(RTA_DST, so_dst);
NEXTADDR(RTA_NETMASK, so_mask);
@@ -2865,7 +3354,6 @@ get_default_gateway (struct route_gateway_info *rgi)
{
/* get interface name */
const struct sockaddr_dl *adl = (struct sockaddr_dl *) ifp;
- int len = adl->sdl_nlen;
if (adl->sdl_nlen && adl->sdl_nlen < sizeof(rgi->iface))
{
memcpy (rgi->iface, adl->sdl_data, adl->sdl_nlen);
@@ -2932,7 +3420,12 @@ get_default_gateway (struct route_gateway_info *rgi)
for (cp = buffer; cp <= buffer + ifc.ifc_len - sizeof(struct ifreq); )
{
ifr = (struct ifreq *)cp;
+#if defined(TARGET_SOLARIS)
+ const size_t len = sizeof(ifr->ifr_name) + sizeof(ifr->ifr_addr);
+#else
const size_t len = sizeof(ifr->ifr_name) + max(sizeof(ifr->ifr_addr), ifr->ifr_addr.sa_len);
+#endif
+
if (!ifr->ifr_addr.sa_family)
break;
if (!strncmp(ifr->ifr_name, rgi->iface, IFNAMSIZ))
@@ -2954,121 +3447,162 @@ get_default_gateway (struct route_gateway_info *rgi)
gc_free (&gc);
}
-#undef max
-
-#elif defined(TARGET_OPENBSD) || defined(TARGET_NETBSD)
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <net/route.h>
-
-struct {
- struct rt_msghdr m_rtm;
- char m_space[512];
-} m_rtmsg;
-
-#define ROUNDUP(a) \
- ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
+/* BSD implementation using routing socket (as does IPv4)
+ * (the code duplication is somewhat unavoidable if we want this to
+ * work on OpenSolaris as well. *sigh*)
+ */
-/*
- * FIXME -- add support for netmask, hwaddr, and iface
+/* Solaris has no length field - this is ugly, but less #ifdef in total
*/
+#if defined(TARGET_SOLARIS)
+# undef ADVANCE
+# define ADVANCE(x, n) (x += ROUNDUP(sizeof(struct sockaddr_in6)))
+#endif
+
void
-get_default_gateway (struct route_gateway_info *rgi)
+get_default_gateway_ipv6(struct route_ipv6_gateway_info *rgi6,
+ const struct in6_addr *dest)
{
- struct gc_arena gc = gc_new ();
- int s, seq, l, rtm_addrs;
- unsigned int i;
- pid_t pid;
- struct sockaddr so_dst, so_mask;
- char *cp = m_rtmsg.m_space;
- struct sockaddr *gate = NULL, *sa;
- struct rt_msghdr *rtm_aux;
-#define NEXTADDR(w, u) \
- if (rtm_addrs & (w)) {\
- l = ROUNDUP(u.sa_len); memmove(cp, &(u), l); cp += l;\
- }
+ struct rtmsg m_rtmsg;
+ int sockfd = -1;
+ int seq, l, pid, rtm_addrs;
+ unsigned int i;
+ struct sockaddr_in6 so_dst, so_mask;
+ char *cp = m_rtmsg.m_space;
+ struct sockaddr *gate = NULL, *ifp = NULL, *sa;
+ struct rt_msghdr *rtm_aux;
-#define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len))
+ CLEAR(*rgi6);
-#define rtm m_rtmsg.m_rtm
+ /* setup data to send to routing socket */
+ pid = getpid();
+ seq = 0;
+ rtm_addrs = RTA_DST | RTA_NETMASK | RTA_IFP;
- CLEAR(*rgi);
+ bzero(&m_rtmsg, sizeof(m_rtmsg));
+ bzero(&so_dst, sizeof(so_dst));
+ bzero(&so_mask, sizeof(so_mask));
+ bzero(&rtm, sizeof(struct rt_msghdr));
- pid = getpid();
- seq = 0;
- rtm_addrs = RTA_DST | RTA_NETMASK;
+ rtm.rtm_type = RTM_GET;
+ rtm.rtm_flags = RTF_UP;
+ rtm.rtm_version = RTM_VERSION;
+ rtm.rtm_seq = ++seq;
- bzero(&so_dst, sizeof(so_dst));
- bzero(&so_mask, sizeof(so_mask));
- bzero(&rtm, sizeof(struct rt_msghdr));
+ so_dst.sin6_family = AF_INET6;
+ so_mask.sin6_family = AF_INET6;
- rtm.rtm_type = RTM_GET;
- rtm.rtm_flags = RTF_UP | RTF_GATEWAY;
- rtm.rtm_version = RTM_VERSION;
- rtm.rtm_seq = ++seq;
- rtm.rtm_addrs = rtm_addrs;
+ if ( dest != NULL && /* specific host? */
+ !IN6_IS_ADDR_UNSPECIFIED(dest) )
+ {
+ so_dst.sin6_addr = *dest;
+ /* :: needs /0 "netmask", host route wants "no netmask */
+ rtm_addrs &= ~RTA_NETMASK;
+ }
- so_dst.sa_family = AF_INET;
- so_dst.sa_len = sizeof(struct sockaddr_in);
- so_mask.sa_family = AF_INET;
- so_mask.sa_len = sizeof(struct sockaddr_in);
+ rtm.rtm_addrs = rtm_addrs;
- NEXTADDR(RTA_DST, so_dst);
- NEXTADDR(RTA_NETMASK, so_mask);
+#ifndef TARGET_SOLARIS
+ so_dst.sin6_len = sizeof(struct sockaddr_in6);
+ so_mask.sin6_len = sizeof(struct sockaddr_in6);
+#endif
- rtm.rtm_msglen = l = cp - (char *)&m_rtmsg;
+ NEXTADDR(RTA_DST, so_dst);
+ NEXTADDR(RTA_NETMASK, so_mask);
- s = socket(PF_ROUTE, SOCK_RAW, 0);
+ rtm.rtm_msglen = l = cp - (char *)&m_rtmsg;
- if (write(s, (char *)&m_rtmsg, l) < 0)
+ /* transact with routing socket */
+ sockfd = socket(PF_ROUTE, SOCK_RAW, 0);
+ if (sockfd < 0)
{
- msg(M_WARN|M_ERRNO, "Could not retrieve default gateway from route socket:");
- gc_free (&gc);
- close(s);
- return;
+ msg (M_WARN, "GDG6: socket #1 failed");
+ goto done;
+ }
+ if (write(sockfd, (char *)&m_rtmsg, l) < 0)
+ {
+ msg (M_WARN, "GDG6: problem writing to routing socket");
+ goto done;
}
- do {
- l = read(s, (char *)&m_rtmsg, sizeof(m_rtmsg));
- } while (l > 0 && (rtm.rtm_seq != seq || rtm.rtm_pid != pid));
-
- close(s);
-
- rtm_aux = &rtm;
-
- cp = ((char *)(rtm_aux + 1));
- if (rtm_aux->rtm_addrs) {
- for (i = 1; i; i <<= 1)
- if (i & rtm_aux->rtm_addrs) {
- sa = (struct sockaddr *)cp;
- if (i == RTA_GATEWAY )
- gate = sa;
- ADVANCE(cp, sa);
- }
- }
- else
+ do
{
- gc_free (&gc);
- return;
+ l = read(sockfd, (char *)&m_rtmsg, sizeof(m_rtmsg));
}
+ while (l > 0 && (rtm.rtm_seq != seq || rtm.rtm_pid != pid));
+ close(sockfd);
+ sockfd = -1;
- if (gate != NULL )
+ /* extract return data from routing socket */
+ rtm_aux = &rtm;
+ cp = ((char *)(rtm_aux + 1));
+ if (rtm_aux->rtm_addrs)
{
- rgi->gateway.addr = ntohl(((struct sockaddr_in *)gate)->sin_addr.s_addr);
- rgi->flags |= RGI_ADDR_DEFINED;
-
- gc_free (&gc);
+ for (i = 1; i; i <<= 1)
+ {
+ if (i & rtm_aux->rtm_addrs)
+ {
+ sa = (struct sockaddr *)cp;
+ if (i == RTA_GATEWAY )
+ gate = sa;
+ else if (i == RTA_IFP)
+ ifp = sa;
+ ADVANCE(cp, sa);
+ }
+ }
}
- else
+ else
+ goto done;
+
+ /* get gateway addr and interface name */
+ if (gate != NULL )
{
- gc_free (&gc);
+ struct sockaddr_in6 * s6 = (struct sockaddr_in6 *)gate;
+ struct in6_addr gw = s6->sin6_addr;
+
+#ifndef TARGET_SOLARIS
+ /* You do not really want to know... from FreeBSD's route.c
+ * (KAME encodes the 16 bit scope_id in s6_addr[2] + [3],
+ * but for a correct link-local address these must be :0000: )
+ */
+ if ( gate->sa_len == sizeof(struct sockaddr_in6) &&
+ IN6_IS_ADDR_LINKLOCAL(&gw) )
+ {
+ gw.s6_addr[2] = gw.s6_addr[3] = 0;
+ }
+
+ if ( gate->sa_len != sizeof(struct sockaddr_in6) ||
+ IN6_IS_ADDR_UNSPECIFIED(&gw) )
+ {
+ rgi6->flags |= RGI_ON_LINK;
+ }
+ else
+#endif
+
+ rgi6->gateway.addr_ipv6 = gw;
+ rgi6->flags |= RGI_ADDR_DEFINED;
+
+ if (ifp)
+ {
+ /* get interface name */
+ const struct sockaddr_dl *adl = (struct sockaddr_dl *) ifp;
+ if (adl->sdl_nlen && adl->sdl_nlen < sizeof(rgi6->iface))
+ {
+ memcpy (rgi6->iface, adl->sdl_data, adl->sdl_nlen);
+ rgi6->flags |= RGI_IFACE_DEFINED;
+ }
+ }
}
+
+ done:
+ if (sockfd >= 0)
+ close(sockfd);
}
+#undef max
+
#else
/*
@@ -3100,6 +3634,13 @@ get_default_gateway (struct route_gateway_info *rgi)
{
CLEAR(*rgi);
}
+void
+get_default_gateway_ipv6(struct route_ipv6_gateway_info *rgi6,
+ const struct in6_addr *dest)
+{
+ msg(D_ROUTE, "no support for get_default_gateway_ipv6() on this system");
+ CLEAR(*rgi6);
+}
#endif
@@ -3127,13 +3668,33 @@ netmask_to_netbits (const in_addr_t network, const in_addr_t netmask, int *netbi
return false;
}
+/* similar to netmask_to_netbits(), but don't mess with base address
+ * etc., just convert to netbits - non-mappable masks are returned as "-1"
+ */
+int netmask_to_netbits2 (in_addr_t netmask)
+{
+ int i;
+ const int addrlen = sizeof (in_addr_t) * 8;
+
+ for (i = 0; i <= addrlen; ++i)
+ {
+ in_addr_t mask = netbits_to_netmask (i);
+ if (mask == netmask)
+ {
+ return i;
+ }
+ }
+ return -1;
+}
+
+
/*
* get_bypass_addresses() is used by the redirect-gateway bypass-x
* functions to build a route bypass to selected DHCP/DNS servers,
* so that outgoing packets to these servers don't end up in the tunnel.
*/
-#if defined(WIN32)
+#if defined(_WIN32)
static void
add_host_route_if_nonlocal (struct route_bypass *rb, const in_addr_t addr)
@@ -3207,7 +3768,7 @@ get_bypass_addresses (struct route_bypass *rb, const unsigned int flags) /* PLA
* Used by redirect-gateway autolocal feature
*/
-#if defined(WIN32)
+#if defined(_WIN32)
int
test_local_addr (const in_addr_t addr, const struct route_gateway_info *rgi)
diff --git a/src/openvpn/route.h b/src/openvpn/route.h
index fe9b461..c358681 100644
--- a/src/openvpn/route.h
+++ b/src/openvpn/route.h
@@ -33,15 +33,14 @@
#include "tun.h"
#include "misc.h"
-#define MAX_ROUTES_DEFAULT 100
-
-#ifdef WIN32
+#ifdef _WIN32
/*
* Windows route methods
*/
#define ROUTE_METHOD_ADAPTIVE 0 /* try IP helper first then route.exe */
#define ROUTE_METHOD_IPAPI 1 /* use IP helper API */
#define ROUTE_METHOD_EXE 2 /* use route.exe */
+#define ROUTE_METHOD_SERVICE 3 /* use the privileged Windows service */
#define ROUTE_METHOD_MASK 3
#endif
@@ -74,6 +73,7 @@ struct route_special_addr
};
struct route_option {
+ struct route_option *next;
const char *network;
const char *netmask;
const char *gateway;
@@ -92,28 +92,28 @@ struct route_option {
struct route_option_list {
unsigned int flags; /* RG_x flags */
- int capacity;
- int n;
- struct route_option routes[EMPTY_ARRAY_SIZE];
+ struct route_option *routes;
+ struct gc_arena *gc;
};
struct route_ipv6_option {
+ struct route_ipv6_option *next;
const char *prefix; /* e.g. "2001:db8:1::/64" */
const char *gateway; /* e.g. "2001:db8:0::2" */
const char *metric; /* e.g. "5" */
};
struct route_ipv6_option_list {
- unsigned int flags;
- int capacity;
- int n;
- struct route_ipv6_option routes_ipv6[EMPTY_ARRAY_SIZE];
+ unsigned int flags; /* RG_x flags, see route_option-list */
+ struct route_ipv6_option *routes_ipv6;
+ struct gc_arena *gc;
};
struct route_ipv4 {
# define RT_DEFINED (1<<0)
# define RT_ADDED (1<<1)
# define RT_METRIC_DEFINED (1<<2)
+ struct route_ipv4 *next;
unsigned int flags;
const struct route_option *option;
in_addr_t network;
@@ -123,26 +123,18 @@ struct route_ipv4 {
};
struct route_ipv6 {
- bool defined;
+ struct route_ipv6 *next;
+ unsigned int flags; /* RT_ flags, see route_ipv4 */
struct in6_addr network;
unsigned int netbits;
struct in6_addr gateway;
- bool metric_defined;
int metric;
-};
-
-struct route_ipv6_list {
- bool routes_added;
- unsigned int flags;
- int default_metric;
- bool default_metric_defined;
- struct in6_addr remote_endpoint_ipv6;
- bool remote_endpoint_defined;
- bool did_redirect_default_gateway; /* TODO (?) */
- bool did_local; /* TODO (?) */
- int capacity;
- int n;
- struct route_ipv6 routes_ipv6[EMPTY_ARRAY_SIZE];
+ /* gateway interface */
+# ifdef _WIN32
+ DWORD adapter_index; /* interface or ~0 if undefined */
+#else
+ char * iface; /* interface name (null terminated) */
+#endif
};
@@ -161,7 +153,7 @@ struct route_gateway_info {
unsigned int flags;
/* gateway interface */
-# ifdef WIN32
+# ifdef _WIN32
DWORD adapter_index; /* interface or ~0 if undefined */
#else
char iface[16]; /* interface name (null terminated), may be empty */
@@ -179,6 +171,34 @@ struct route_gateway_info {
struct route_gateway_address addrs[RGI_N_ADDRESSES]; /* local addresses attached to iface */
};
+struct route_ipv6_gateway_address {
+ struct in6_addr addr_ipv6;
+ int netbits_ipv6;
+};
+
+struct route_ipv6_gateway_info {
+/* RGI_ flags used as in route_gateway_info */
+ unsigned int flags;
+
+ /* gateway interface */
+# ifdef _WIN32
+ DWORD adapter_index; /* interface or ~0 if undefined */
+#else
+ char iface[16]; /* interface name (null terminated), may be empty */
+#endif
+
+ /* gateway interface hardware address */
+ uint8_t hwaddr[6];
+
+ /* gateway/router address */
+ struct route_ipv6_gateway_address gateway;
+
+ /* address/netmask pairs bound to interface */
+# define RGI_N_ADDRESSES 8
+ int n_addrs; /* len of addrs, may be 0 */
+ struct route_ipv6_gateway_address addrs[RGI_N_ADDRESSES]; /* local addresses attached to iface */
+};
+
struct route_list {
# define RL_DID_REDIRECT_DEFAULT_GATEWAY (1<<0)
# define RL_DID_LOCAL (1<<1)
@@ -188,9 +208,22 @@ struct route_list {
struct route_special_addr spec;
struct route_gateway_info rgi;
unsigned int flags; /* RG_x flags */
- int capacity;
- int n;
- struct route_ipv4 routes[EMPTY_ARRAY_SIZE];
+ struct route_ipv4 *routes;
+ struct gc_arena gc;
+};
+
+struct route_ipv6_list {
+ unsigned int iflags; /* RL_ flags, see route_list */
+
+ unsigned int spec_flags; /* RTSA_ flags, route_special_addr */
+ struct in6_addr remote_endpoint_ipv6; /* inside tun */
+ struct in6_addr remote_host_ipv6; /* --remote address */
+ int default_metric;
+
+ struct route_ipv6_gateway_info rgi6;
+ unsigned int flags; /* RG_x flags, see route_option_list */
+ struct route_ipv6 *routes_ipv6;
+ struct gc_arena gc;
};
#if P2MP
@@ -208,17 +241,15 @@ struct iroute_ipv6 {
};
#endif
-struct route_option_list *new_route_option_list (const int max_routes, struct gc_arena *a);
-struct route_ipv6_option_list *new_route_ipv6_option_list (const int max_routes, struct gc_arena *a);
+struct route_option_list *new_route_option_list (struct gc_arena *a);
+struct route_ipv6_option_list *new_route_ipv6_option_list (struct gc_arena *a);
struct route_option_list *clone_route_option_list (const struct route_option_list *src, struct gc_arena *a);
struct route_ipv6_option_list *clone_route_ipv6_option_list (const struct route_ipv6_option_list *src, struct gc_arena *a);
-void copy_route_option_list (struct route_option_list *dest, const struct route_option_list *src);
+void copy_route_option_list (struct route_option_list *dest, const struct route_option_list *src, struct gc_arena *a);
void copy_route_ipv6_option_list (struct route_ipv6_option_list *dest,
- const struct route_ipv6_option_list *src);
-
-struct route_list *new_route_list (const int max_routes, struct gc_arena *a);
-struct route_ipv6_list *new_route_ipv6_list (const int max_routes, struct gc_arena *a);
+ const struct route_ipv6_option_list *src,
+ struct gc_arena *a);
void add_route_ipv6 (struct route_ipv6 *r, const struct tuntap *tt, unsigned int flags, const struct env_set *es);
void delete_route_ipv6 (const struct route_ipv6 *r, const struct tuntap *tt, unsigned int flags, const struct env_set *es);
@@ -251,6 +282,7 @@ bool init_route_ipv6_list (struct route_ipv6_list *rl6,
const struct route_ipv6_option_list *opt6,
const char *remote_endpoint,
int default_metric,
+ const struct in6_addr *remote_host,
struct env_set *es);
void route_list_add_vpn_gateway (struct route_list *rl,
@@ -277,7 +309,11 @@ void setenv_routes_ipv6 (struct env_set *es, const struct route_ipv6_list *rl6);
bool is_special_addr (const char *addr_str);
void get_default_gateway (struct route_gateway_info *rgi);
-void print_default_gateway(const int msglevel, const struct route_gateway_info *rgi);
+void get_default_gateway_ipv6 (struct route_ipv6_gateway_info *rgi,
+ const struct in6_addr *dest);
+void print_default_gateway(const int msglevel,
+ const struct route_gateway_info *rgi,
+ const struct route_ipv6_gateway_info *rgi6);
/*
* Test if addr is reachable via a local interface (return ILA_LOCAL),
@@ -297,7 +333,7 @@ void print_route_options (const struct route_option_list *rol,
void print_routes (const struct route_list *rl, int level);
-#ifdef WIN32
+#ifdef _WIN32
void show_routes (int msglev);
bool test_routes (const struct route_list *rl, const struct tuntap *tt);
@@ -309,6 +345,7 @@ static inline bool test_routes (const struct route_list *rl, const struct tuntap
#endif
bool netmask_to_netbits (const in_addr_t network, const in_addr_t netmask, int *netbits);
+int netmask_to_netbits2 (in_addr_t netmask);
static inline in_addr_t
netbits_to_netmask (const int netbits)
diff --git a/src/openvpn/session_id.c b/src/openvpn/session_id.c
index 2e07b54..0ebff65 100644
--- a/src/openvpn/session_id.c
+++ b/src/openvpn/session_id.c
@@ -39,7 +39,7 @@
#include "syshead.h"
-#if defined(ENABLE_CRYPTO) && defined(ENABLE_SSL)
+#ifdef ENABLE_CRYPTO
#include "error.h"
#include "common.h"
@@ -64,4 +64,4 @@ session_id_print (const struct session_id *sid, struct gc_arena *gc)
#else
static void dummy(void) {}
-#endif /* ENABLE_CRYPTO && ENABLE_SSL*/
+#endif /* ENABLE_CRYPTO */
diff --git a/src/openvpn/session_id.h b/src/openvpn/session_id.h
index 33909dd..2a1f41f 100644
--- a/src/openvpn/session_id.h
+++ b/src/openvpn/session_id.h
@@ -30,7 +30,7 @@
* negotiated).
*/
-#if defined(ENABLE_CRYPTO) && defined(ENABLE_SSL)
+#ifdef ENABLE_CRYPTO
#ifndef SESSION_ID_H
#define SESSION_ID_H
@@ -83,4 +83,4 @@ void session_id_random (struct session_id *sid);
const char *session_id_print (const struct session_id *sid, struct gc_arena *gc);
#endif /* SESSION_ID_H */
-#endif /* ENABLE_CRYPTO && ENABLE_SSL */
+#endif /* ENABLE_CRYPTO */
diff --git a/src/openvpn/shaper.h b/src/openvpn/shaper.h
index afeb9c3..fa132c4 100644
--- a/src/openvpn/shaper.h
+++ b/src/openvpn/shaper.h
@@ -75,7 +75,7 @@ bool shaper_soonest_event (struct timeval *tv, int delay);
static inline void
shaper_reset (struct shaper *s, int bytes_per_second)
{
- s->bytes_per_second = bytes_per_second ? constrain_int (bytes_per_second, SHAPER_MIN, SHAPER_MAX) : 0;
+ s->bytes_per_second = constrain_int (bytes_per_second, SHAPER_MIN, SHAPER_MAX);
#ifdef SHAPER_USE_FP
s->factor = 1000000.0 / (double)s->bytes_per_second;
diff --git a/src/openvpn/sig.c b/src/openvpn/sig.c
index 0ebde24..0ff1437 100644
--- a/src/openvpn/sig.c
+++ b/src/openvpn/sig.c
@@ -97,14 +97,14 @@ void
throw_signal (const int signum)
{
siginfo_static.signal_received = signum;
- siginfo_static.hard = true;
+ siginfo_static.source = SIG_SOURCE_HARD;
}
void
throw_signal_soft (const int signum, const char *signal_text)
{
siginfo_static.signal_received = signum;
- siginfo_static.hard = false;
+ siginfo_static.source = SIG_SOURCE_SOFT;
siginfo_static.signal_text = signal_text;
}
@@ -115,7 +115,7 @@ signal_reset (struct signal_info *si)
{
si->signal_received = 0;
si->signal_text = NULL;
- si->hard = false;
+ si->source = SIG_SOURCE_SOFT;
}
}
@@ -124,9 +124,23 @@ print_signal (const struct signal_info *si, const char *title, int msglevel)
{
if (si)
{
- const char *hs = (si->hard ? "hard" : "soft");
const char *type = (si->signal_text ? si->signal_text : "");
const char *t = (title ? title : "process");
+ const char *hs = NULL;
+ switch (si->source)
+ {
+ case SIG_SOURCE_SOFT:
+ hs= "soft";
+ break;
+ case SIG_SOURCE_HARD:
+ hs = "hard";
+ break;
+ case SIG_SOURCE_CONNECTION_FAILED:
+ hs = "connection failed(soft)";
+ break;
+ default:
+ ASSERT(0);
+ }
switch (si->signal_received)
{
@@ -175,8 +189,10 @@ signal_restart_status (const struct signal_info *si)
management_set_state (management,
state,
si->signal_text ? si->signal_text : signal_name (si->signal_received, true),
- (in_addr_t)0,
- (in_addr_t)0);
+ NULL,
+ NULL,
+ NULL,
+ NULL);
}
#endif
}
@@ -205,7 +221,7 @@ static int signal_mode; /* GLOBAL */
void
pre_init_signal_catch (void)
{
-#ifndef WIN32
+#ifndef _WIN32
#ifdef HAVE_SIGNAL_H
signal_mode = SM_PRE_INIT;
signal (SIGINT, signal_handler);
@@ -215,13 +231,13 @@ pre_init_signal_catch (void)
signal (SIGUSR2, SIG_IGN);
signal (SIGPIPE, SIG_IGN);
#endif /* HAVE_SIGNAL_H */
-#endif /* WIN32 */
+#endif /* _WIN32 */
}
void
post_init_signal_catch (void)
{
-#ifndef WIN32
+#ifndef _WIN32
#ifdef HAVE_SIGNAL_H
signal_mode = SM_POST_INIT;
signal (SIGINT, signal_handler);
@@ -265,9 +281,9 @@ print_status (const struct context *c, struct status_output *so)
status_printf (so, "TCP/UDP read bytes," counter_format, c->c2.link_read_bytes);
status_printf (so, "TCP/UDP write bytes," counter_format, c->c2.link_write_bytes);
status_printf (so, "Auth read bytes," counter_format, c->c2.link_read_bytes_auth);
-#ifdef ENABLE_LZO
- if (lzo_defined (&c->c2.lzo_compwork))
- lzo_print_stats (&c->c2.lzo_compwork, so);
+#ifdef USE_COMP
+ if (c->c2.comp_context)
+ comp_print_stats (c->c2.comp_context, so);
#endif
#ifdef PACKET_TRUNCATION_CHECK
status_printf (so, "TUN read truncations," counter_format, c->c2.n_trunc_tun_read);
@@ -275,7 +291,7 @@ print_status (const struct context *c, struct status_output *so)
status_printf (so, "Pre-encrypt truncations," counter_format, c->c2.n_trunc_pre_encrypt);
status_printf (so, "Post-decrypt truncations," counter_format, c->c2.n_trunc_post_decrypt);
#endif
-#ifdef WIN32
+#ifdef _WIN32
if (tuntap_defined (c->c1.tuntap))
status_printf (so, "TAP-WIN32 driver status,\"%s\"",
tap_win_getinfo (c->c1.tuntap, &gc));
@@ -360,12 +376,35 @@ process_sigterm (struct context *c)
return ret;
}
+/**
+ * If a restart signal is received during exit-notification, reset the
+ * signal and return true.
+ */
+static bool
+ignore_restart_signals (struct context *c)
+{
+ bool ret = false;
+#ifdef ENABLE_OCC
+ if ( (c->sig->signal_received == SIGUSR1 || c->sig->signal_received == SIGHUP) &&
+ event_timeout_defined(&c->c2.explicit_exit_notification_interval) )
+ {
+ msg (M_INFO, "Ignoring %s received during exit notification",
+ signal_name(c->sig->signal_received, true));
+ signal_reset (c->sig);
+ ret = true;
+ }
+#endif
+ return ret;
+}
+
bool
process_signal (struct context *c)
{
bool ret = true;
- if (c->sig->signal_received == SIGTERM || c->sig->signal_received == SIGINT)
+ if (ignore_restart_signals (c))
+ ret = false;
+ else if (c->sig->signal_received == SIGTERM || c->sig->signal_received == SIGINT)
{
ret = process_sigterm (c);
}
diff --git a/src/openvpn/sig.h b/src/openvpn/sig.h
index 987efef..2875a4c 100644
--- a/src/openvpn/sig.h
+++ b/src/openvpn/sig.h
@@ -28,6 +28,15 @@
#include "status.h"
#include "win32.h"
+
+
+#define SIG_SOURCE_SOFT 0
+#define SIG_SOURCE_HARD 1
+/* CONNECTION_FAILED is also a "soft" status,
+ * It is thrown if a connection attempt fails
+ */
+#define SIG_SOURCE_CONNECTION_FAILED 2
+
/*
* Signal information, including signal code
* and descriptive text.
@@ -35,7 +44,7 @@
struct signal_info
{
volatile int signal_received;
- volatile bool hard;
+ volatile int source;
const char *signal_text;
};
@@ -70,7 +79,7 @@ void register_signal (struct context *c, int sig, const char *text);
void process_explicit_exit_notification_timer_wakeup (struct context *c);
#endif
-#ifdef WIN32
+#ifdef _WIN32
static inline void
get_signal (volatile int *sig)
diff --git a/src/openvpn/socket.c b/src/openvpn/socket.c
index b7ac339..c233f2b 100644
--- a/src/openvpn/socket.c
+++ b/src/openvpn/socket.c
@@ -38,6 +38,9 @@
#include "ps.h"
#include "manage.h"
#include "misc.h"
+#include "manage.h"
+#include "openvpn.h"
+#include "forward.h"
#include "memdbg.h"
@@ -69,23 +72,6 @@ sf2gaf(const unsigned int getaddr_flags,
* Functions related to the translation of DNS names to IP addresses.
*/
-static const char*
-h_errno_msg(int h_errno_err)
-{
- switch (h_errno_err)
- {
- case HOST_NOT_FOUND:
- return "[HOST_NOT_FOUND] The specified host is unknown.";
- case NO_DATA:
- return "[NO_DATA] The requested name is valid but does not have an IP address.";
- case NO_RECOVERY:
- return "[NO_RECOVERY] A non-recoverable name server error occurred.";
- case TRY_AGAIN:
- return "[TRY_AGAIN] A temporary error occurred on an authoritative name server.";
- }
- return "[unknown h_errno value]";
-}
-
/*
* Translate IP addr or hostname to in_addr_t.
* If resolve error, try again for
@@ -100,8 +86,8 @@ getaddr (unsigned int flags,
{
struct addrinfo *ai;
int status;
- status = openvpn_getaddrinfo(flags, hostname, resolve_retry_seconds,
- signal_received, AF_INET, &ai);
+ status = openvpn_getaddrinfo (flags & ~GETADDR_HOST_ORDER, hostname, NULL,
+ resolve_retry_seconds, signal_received, AF_INET, &ai);
if(status==0) {
struct in_addr ia;
if(succeeded)
@@ -116,6 +102,178 @@ getaddr (unsigned int flags,
}
}
+static inline bool
+streqnull (const char* a, const char* b)
+{
+ if (a == NULL && b == NULL)
+ return true;
+ else if (a == NULL || b == NULL)
+ return false;
+ else
+ return streq (a, b);
+}
+
+/*
+ get_cached_dns_entry return 0 on success and -1
+ otherwise. (like getaddrinfo)
+ */
+static int
+get_cached_dns_entry (struct cached_dns_entry* dns_cache,
+ const char* hostname,
+ const char* servname,
+ int ai_family,
+ int resolve_flags,
+ struct addrinfo **ai)
+{
+ struct cached_dns_entry *ph;
+ int flags;
+
+ /* Only use flags that are relevant for the structure */
+ flags = resolve_flags & GETADDR_CACHE_MASK;
+
+ for (ph = dns_cache; ph ; ph = ph->next)
+ {
+ if (streqnull (ph->hostname, hostname) &&
+ streqnull (ph->servname, servname) &&
+ ph->ai_family == ai_family &&
+ ph->flags == flags)
+ {
+ *ai = ph->ai;
+ return 0;
+ }
+ }
+ return -1;
+}
+
+
+static int
+do_preresolve_host (struct context *c,
+ const char *hostname,
+ const char *servname,
+ const int af,
+ const int flags)
+{
+ struct addrinfo *ai;
+ int status;
+
+ if (get_cached_dns_entry(c->c1.dns_cache,
+ hostname,
+ servname,
+ af,
+ flags,
+ &ai) == 0 )
+ {
+ /* entry already cached, return success */
+ return 0;
+ }
+
+ status = openvpn_getaddrinfo (flags, hostname, servname,
+ c->options.resolve_retry_seconds, NULL,
+ af, &ai);
+ if (status == 0)
+ {
+ struct cached_dns_entry *ph;
+
+ ALLOC_OBJ_CLEAR_GC (ph, struct cached_dns_entry, &c->gc);
+ ph->ai = ai;
+ ph->hostname = hostname;
+ ph->servname = servname;
+ ph->flags = flags & GETADDR_CACHE_MASK;
+
+ if (!c->c1.dns_cache)
+ c->c1.dns_cache = ph;
+ else
+ {
+ struct cached_dns_entry *prev = c->c1.dns_cache;
+ while (prev->next)
+ prev = prev->next;
+ prev->next = ph;
+ }
+
+ gc_addspecial (ai, &gc_freeaddrinfo_callback, &c->gc);
+
+ }
+ return status;
+}
+
+void
+do_preresolve (struct context *c)
+{
+ int i;
+ struct connection_list *l = c->options.connection_list;
+ const unsigned int preresolve_flags = GETADDR_RESOLVE|
+ GETADDR_UPDATE_MANAGEMENT_STATE|
+ GETADDR_MENTION_RESOLVE_RETRY|
+ GETADDR_FATAL;
+
+
+ for (i = 0; i < l->len; ++i)
+ {
+ int status;
+ const char *remote;
+ int flags = preresolve_flags;
+
+ struct connection_entry* ce = c->options.connection_list->array[i];
+
+ if (proto_is_dgram(ce->proto))
+ flags |= GETADDR_DATAGRAM;
+
+ if (c->options.sockflags & SF_HOST_RANDOMIZE)
+ flags |= GETADDR_RANDOMIZE;
+
+ if (c->options.ip_remote_hint)
+ remote = c->options.ip_remote_hint;
+ else
+ remote = ce->remote;
+
+ /* 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);
+ if (status != 0)
+ goto err;
+ }
+
+ /* Preresolve proxy */
+ if (ce->http_proxy_options)
+ {
+ status = do_preresolve_host (c,
+ ce->http_proxy_options->server,
+ ce->http_proxy_options->port,
+ ce->af,
+ preresolve_flags);
+
+ if (status != 0)
+ goto err;
+ }
+
+ if (ce->socks_proxy_server)
+ {
+ status = do_preresolve_host (c,
+ ce->socks_proxy_server,
+ ce->socks_proxy_port,
+ ce->af,
+ flags);
+ if (status != 0)
+ goto err;
+ }
+
+ if (ce->bind_local)
+ {
+ flags |= GETADDR_PASSIVE;
+ flags &= ~GETADDR_RANDOMIZE;
+ status = do_preresolve_host (c, ce->local, ce->local_port, ce->af, flags);
+ if (status != 0)
+ goto err;
+
+ }
+
+ }
+ return;
+
+ err:
+ throw_signal_soft (SIGHUP, "Preresolving failed");
+}
/*
* Translate IPv4/IPv6 addr or hostname into struct addrinfo
@@ -124,6 +282,7 @@ getaddr (unsigned int flags,
int
openvpn_getaddrinfo (unsigned int flags,
const char *hostname,
+ const char *servname,
int resolve_retry_seconds,
volatile int *signal_received,
int ai_family,
@@ -134,15 +293,27 @@ openvpn_getaddrinfo (unsigned int flags,
int sigrec = 0;
int msglevel = (flags & GETADDR_FATAL) ? M_FATAL : D_RESOLVE_ERRORS;
struct gc_arena gc = gc_new ();
+ const char *print_hostname;
+ const char *print_servname;
ASSERT(res);
- if (!hostname)
- hostname = "::";
+ ASSERT (hostname || servname);
+ ASSERT (!(flags & GETADDR_HOST_ORDER));
- if (flags & GETADDR_RANDOMIZE)
+ if (hostname && (flags & GETADDR_RANDOMIZE))
hostname = hostname_randomize(hostname, &gc);
+ if(hostname)
+ print_hostname = hostname;
+ else
+ print_hostname = "undefined";
+
+ if(servname)
+ print_servname = servname;
+ else
+ print_servname = "";
+
if (flags & GETADDR_MSG_VIRT_OUT)
msglevel |= M_MSG_VIRT_OUT;
@@ -154,25 +325,35 @@ openvpn_getaddrinfo (unsigned int flags,
CLEAR(hints);
hints.ai_family = ai_family;
hints.ai_flags = AI_NUMERICHOST;
- hints.ai_socktype = SOCK_STREAM;
- status = getaddrinfo(hostname, NULL, &hints, res);
+ if(flags & GETADDR_PASSIVE)
+ hints.ai_flags |= AI_PASSIVE;
+
+ if(flags & GETADDR_DATAGRAM)
+ hints.ai_socktype = SOCK_DGRAM;
+ else
+ hints.ai_socktype = SOCK_STREAM;
+
+ status = getaddrinfo(hostname, servname, &hints, res);
if (status != 0) /* parse as numeric address failed? */
{
const int fail_wait_interval = 5; /* seconds */
- int resolve_retries = (flags & GETADDR_TRY_ONCE) ? 1 : (resolve_retry_seconds / fail_wait_interval);
+ /* Add +4 to cause integer division rounding up (1 + 4) = 5, (0+4)/5=0 */
+ int resolve_retries = (flags & GETADDR_TRY_ONCE) ? 1 :
+ ((resolve_retry_seconds + 4)/ fail_wait_interval);
const char *fmt;
int level = 0;
- fmt = "RESOLVE: Cannot resolve host address: %s: %s";
+ fmt = "RESOLVE: Cannot resolve host address: %s:%s (%s)";
if ((flags & GETADDR_MENTION_RESOLVE_RETRY)
&& !resolve_retry_seconds)
- fmt = "RESOLVE: Cannot resolve host address: %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)
{
- msg (msglevel, "RESOLVE: Cannot parse IP address: %s", hostname);
+ msg (msglevel, "RESOLVE: Cannot parse IP address: %s:%s (%s)",
+ print_hostname,print_servname, gai_strerror(status));
goto done;
}
@@ -183,8 +364,10 @@ openvpn_getaddrinfo (unsigned int flags,
management_set_state (management,
OPENVPN_STATE_RESOLVE,
NULL,
- (in_addr_t)0,
- (in_addr_t)0);
+ NULL,
+ NULL,
+ NULL,
+ NULL);
}
#endif
@@ -193,14 +376,14 @@ openvpn_getaddrinfo (unsigned int flags,
*/
while (true)
{
-#ifndef WIN32
+#ifndef _WIN32
res_init ();
#endif
/* try hostname lookup */
- hints.ai_flags = 0;
+ hints.ai_flags &= ~AI_NUMERICHOST;
dmsg (D_SOCKET_DEBUG, "GETADDRINFO flags=0x%04x ai_family=%d ai_socktype=%d",
flags, hints.ai_family, hints.ai_socktype);
- status = getaddrinfo(hostname, NULL, &hints, res);
+ status = getaddrinfo(hostname, servname, &hints, res);
if (signal_received)
{
@@ -239,7 +422,8 @@ openvpn_getaddrinfo (unsigned int flags,
msg (level,
fmt,
- hostname,
+ print_hostname,
+ print_servname,
gai_strerror(status));
if (--resolve_retries <= 0)
@@ -252,7 +436,8 @@ openvpn_getaddrinfo (unsigned int flags,
/* hostname resolve succeeded */
- /* Do not chose an IP Addresse by random or change the order *
+ /*
+ * Do not choose an IP Addresse by random or change the order *
* of IP addresses, doing so will break RFC 3484 address selection *
*/
}
@@ -422,59 +607,6 @@ mac_addr_safe (const char *mac_addr)
return true;
}
-static void
-update_remote (const char* host,
- struct openvpn_sockaddr *addr,
- bool *changed,
- const unsigned int sockflags)
-{
- switch(addr->addr.sa.sa_family)
- {
- case AF_INET:
- if (host && addr)
- {
- const in_addr_t new_addr = getaddr (
- sf2gaf(GETADDR_RESOLVE|GETADDR_UPDATE_MANAGEMENT_STATE, sockflags),
- host,
- 1,
- NULL,
- NULL);
- if (new_addr && addr->addr.in4.sin_addr.s_addr != new_addr)
- {
- addr->addr.in4.sin_addr.s_addr = new_addr;
- *changed = true;
- }
- }
- break;
- case AF_INET6:
- if (host && addr)
- {
- int status;
- struct addrinfo* ai;
-
- status = openvpn_getaddrinfo(sf2gaf(GETADDR_RESOLVE|GETADDR_UPDATE_MANAGEMENT_STATE, sockflags), host, 1, NULL, AF_INET6, &ai);
-
- if ( status ==0 )
- {
- struct sockaddr_in6 sin6;
- CLEAR(sin6);
- sin6 = *((struct sockaddr_in6*)ai->ai_addr);
- if (!IN6_ARE_ADDR_EQUAL(&sin6.sin6_addr, &addr->addr.in6.sin6_addr))
- {
- int port = addr->addr.in6.sin6_port;
- /* ipv6 requires also eg. sin6_scope_id => easier to fully copy and override port */
- addr->addr.in6 = sin6;
- addr->addr.in6.sin6_port = port;
- }
- freeaddrinfo(ai);
- }
- }
- break;
- default:
- ASSERT(0);
- }
-}
-
static int
socket_get_sndbuf (int sd)
{
@@ -558,7 +690,7 @@ socket_set_buffers (int fd, const struct socket_buffer_size *sbs)
static bool
socket_set_tcp_nodelay (int sd, int state)
{
-#if defined(WIN32) || (defined(HAVE_SETSOCKOPT) && defined(IPPROTO_TCP) && defined(TCP_NODELAY))
+#if defined(_WIN32) || (defined(HAVE_SETSOCKOPT) && defined(IPPROTO_TCP) && defined(TCP_NODELAY))
if (setsockopt (sd, IPPROTO_TCP, TCP_NODELAY, (void *) &state, sizeof (state)) != 0)
{
msg (M_WARN, "NOTE: setsockopt TCP_NODELAY=%d failed", state);
@@ -579,7 +711,7 @@ static inline void
socket_set_mark (int sd, int mark)
{
#if defined(TARGET_LINUX) && HAVE_DECL_SO_MARK
- if (mark && setsockopt (sd, SOL_SOCKET, SO_MARK, &mark, sizeof (mark)) != 0)
+ if (mark && setsockopt (sd, SOL_SOCKET, SO_MARK, (void *) &mark, sizeof (mark)) != 0)
msg (M_WARN, "NOTE: setsockopt SO_MARK=%d failed", mark);
#endif
}
@@ -619,14 +751,17 @@ link_socket_update_buffer_sizes (struct link_socket *ls, int rcvbuf, int sndbuf)
*/
socket_descriptor_t
-create_socket_tcp (int af)
+create_socket_tcp (struct addrinfo* addrinfo)
{
socket_descriptor_t sd;
- if ((sd = socket (af, SOCK_STREAM, IPPROTO_TCP)) < 0)
+ ASSERT (addrinfo);
+ ASSERT (addrinfo->ai_socktype == SOCK_STREAM);
+
+ if ((sd = socket (addrinfo->ai_family, addrinfo->ai_socktype, addrinfo->ai_protocol)) < 0)
msg (M_ERR, "Cannot create TCP socket");
-#ifndef WIN32 /* using SO_REUSEADDR on Windows will cause bind to succeed on port conflicts! */
+#ifndef _WIN32 /* using SO_REUSEADDR on Windows will cause bind to succeed on port conflicts! */
/* set SO_REUSEADDR on socket */
{
int on = 1;
@@ -640,106 +775,134 @@ create_socket_tcp (int af)
}
static socket_descriptor_t
-create_socket_udp (const unsigned int flags)
+create_socket_udp (struct addrinfo* addrinfo, const unsigned int flags)
{
socket_descriptor_t sd;
- if ((sd = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
- msg (M_ERR, "UDP: Cannot create UDP socket");
+ ASSERT (addrinfo);
+ ASSERT (addrinfo->ai_socktype == SOCK_DGRAM);
+
+ if ((sd = socket (addrinfo->ai_family, addrinfo->ai_socktype, addrinfo->ai_protocol)) < 0)
+ msg (M_ERR, "UDP: Cannot create UDP/UDP6 socket");
#if ENABLE_IP_PKTINFO
else if (flags & SF_USE_IP_PKTINFO)
{
int pad = 1;
-#ifdef IP_PKTINFO
- if (setsockopt (sd, SOL_IP, IP_PKTINFO,
- (void*)&pad, sizeof(pad)) < 0)
- msg(M_ERR, "UDP: failed setsockopt for IP_PKTINFO");
+ if(addrinfo->ai_family == AF_INET)
+ {
+#if defined(HAVE_IN_PKTINFO) && defined(HAVE_IPI_SPEC_DST)
+ if (setsockopt (sd, SOL_IP, IP_PKTINFO,
+ (void*)&pad, sizeof(pad)) < 0)
+ msg(M_ERR, "UDP: failed setsockopt for IP_PKTINFO");
#elif defined(IP_RECVDSTADDR)
- if (setsockopt (sd, IPPROTO_IP, IP_RECVDSTADDR,
- (void*)&pad, sizeof(pad)) < 0)
- msg(M_ERR, "UDP: failed setsockopt for IP_RECVDSTADDR");
+ if (setsockopt (sd, IPPROTO_IP, IP_RECVDSTADDR,
+ (void*)&pad, sizeof(pad)) < 0)
+ msg(M_ERR, "UDP: failed setsockopt for IP_RECVDSTADDR");
#else
#error ENABLE_IP_PKTINFO is set without IP_PKTINFO xor IP_RECVDSTADDR (fix syshead.h)
#endif
- }
-#endif
- return sd;
-}
-
-static socket_descriptor_t
-create_socket_udp6 (const unsigned int flags)
-{
- socket_descriptor_t sd;
-
- if ((sd = socket (PF_INET6, SOCK_DGRAM, IPPROTO_UDP)) < 0)
- msg (M_ERR, "UDP: Cannot create UDP6 socket");
-#if ENABLE_IP_PKTINFO
- else if (flags & SF_USE_IP_PKTINFO)
- {
- int pad = 1;
+ }
+ else if (addrinfo->ai_family == AF_INET6 )
+ {
#ifndef IPV6_RECVPKTINFO /* Some older Darwin platforms require this */
- if (setsockopt (sd, IPPROTO_IPV6, IPV6_PKTINFO,
- (void*)&pad, sizeof(pad)) < 0)
+ if (setsockopt (sd, IPPROTO_IPV6, IPV6_PKTINFO,
+ (void*)&pad, sizeof(pad)) < 0)
#else
- if (setsockopt (sd, IPPROTO_IPV6, IPV6_RECVPKTINFO,
- (void*)&pad, sizeof(pad)) < 0)
+ if (setsockopt (sd, IPPROTO_IPV6, IPV6_RECVPKTINFO,
+ (void*)&pad, sizeof(pad)) < 0)
#endif
- msg(M_ERR, "UDP: failed setsockopt for IPV6_RECVPKTINFO");
+ msg(M_ERR, "UDP: failed setsockopt for IPV6_RECVPKTINFO");
+ }
}
#endif
return sd;
}
+static void bind_local (struct link_socket *sock, const sa_family_t ai_family)
+{
+ /* bind to local address/port */
+ if (sock->bind_local)
+ {
+ if (sock->socks_proxy && sock->info.proto == PROTO_UDP)
+ socket_bind (sock->ctrl_sd, sock->info.lsa->bind_local,
+ ai_family, "SOCKS", false);
+ else
+ socket_bind (sock->sd, sock->info.lsa->bind_local,
+ ai_family,
+ "TCP/UDP", sock->info.bind_ipv6_only);
+ }
+}
+
static void
-create_socket (struct link_socket *sock)
+create_socket (struct link_socket* sock, struct addrinfo* addr)
{
- /* create socket */
- if (sock->info.proto == PROTO_UDPv4)
+ if (addr->ai_protocol == IPPROTO_UDP || addr->ai_socktype == SOCK_DGRAM)
{
- sock->sd = create_socket_udp (sock->sockflags);
+ sock->sd = create_socket_udp (addr, sock->sockflags);
sock->sockflags |= SF_GETADDRINFO_DGRAM;
-#ifdef ENABLE_SOCKS
+ /* Assume that control socket and data socket to the socks proxy
+ * are using the same IP family */
if (sock->socks_proxy)
- sock->ctrl_sd = create_socket_tcp (AF_INET);
-#endif
- }
- else if (sock->info.proto == PROTO_TCPv4_SERVER
- || sock->info.proto == PROTO_TCPv4_CLIENT)
- {
- sock->sd = create_socket_tcp (AF_INET);
- }
- else if (sock->info.proto == PROTO_TCPv6_SERVER
- || sock->info.proto == PROTO_TCPv6_CLIENT)
- {
- sock->sd = create_socket_tcp (AF_INET6);
+ {
+ /* Construct a temporary addrinfo to create the socket,
+ * currently resolve two remote addresses is not supported,
+ * TODO: Rewrite the whole resolve_remote */
+ struct addrinfo addrinfo_tmp = *addr;
+ addrinfo_tmp.ai_socktype = SOCK_STREAM;
+ addrinfo_tmp.ai_protocol = IPPROTO_TCP;
+ sock->ctrl_sd = create_socket_tcp (&addrinfo_tmp);
+ }
}
- else if (sock->info.proto == PROTO_UDPv6)
+ else if (addr->ai_protocol == IPPROTO_TCP || addr->ai_socktype == SOCK_STREAM)
{
- sock->sd = create_socket_udp6 (sock->sockflags);
- sock->sockflags |= SF_GETADDRINFO_DGRAM;
+ sock->sd = create_socket_tcp (addr);
}
else
{
ASSERT (0);
}
+ /* set socket buffers based on --sndbuf and --rcvbuf options */
+ socket_set_buffers (sock->sd, &sock->socket_buffer_sizes);
+
+ /* set socket to --mark packets with given value */
+ socket_set_mark (sock->sd, sock->mark);
+
+ bind_local (sock, addr->ai_family);
+}
+
+#ifdef TARGET_ANDROID
+static void protect_fd_nonlocal (int fd, const struct sockaddr* addr)
+{
+ /* pass socket FD to management interface to pass on to VPNService API
+ * as "protected socket" (exempt from being routed into tunnel)
+ */
+ if (addr_local (addr)) {
+ msg(D_SOCKET_DEBUG, "Address is local, not protecting socket fd %d", fd);
+ return;
+ }
+
+ msg(D_SOCKET_DEBUG, "Protecting socket fd %d", fd);
+ management->connection.fdtosend = fd;
+ management_android_control (management, "PROTECTFD", __func__);
}
+#endif
/*
* Functions used for establishing a TCP stream connection.
*/
-
static void
socket_do_listen (socket_descriptor_t sd,
- const struct openvpn_sockaddr *local,
+ const struct addrinfo *local,
bool do_listen,
bool do_set_nonblock)
{
struct gc_arena gc = gc_new ();
if (do_listen)
{
+ ASSERT(local);
msg (M_INFO, "Listening for incoming TCP connection on %s",
- print_sockaddr (local, &gc));
+ print_sockaddr (local->ai_addr, &gc));
if (listen (sd, 1))
msg (M_ERR, "TCP: listen() failed");
}
@@ -821,8 +984,7 @@ static int
socket_listen_accept (socket_descriptor_t sd,
struct link_socket_actual *act,
const char *remote_dynamic,
- bool *remote_changed,
- const struct openvpn_sockaddr *local,
+ const struct addrinfo *local,
bool do_listen,
bool nowait,
volatile int *signal_received)
@@ -868,18 +1030,26 @@ socket_listen_accept (socket_descriptor_t sd,
if (socket_defined (new_sd))
{
- update_remote (remote_dynamic, &remote_verify, remote_changed, 0);
- if (addr_defined (&remote_verify)
- && !addr_match (&remote_verify, &act->dest))
- {
- msg (M_WARN,
- "TCP NOTE: Rejected connection attempt from %s due to --remote setting",
- print_link_socket_actual (act, &gc));
- if (openvpn_close_socket (new_sd))
- msg (M_ERR, "TCP: close socket failed (new_sd)");
- }
+ struct addrinfo* ai = NULL;
+ if(remote_dynamic)
+ openvpn_getaddrinfo(0, remote_dynamic, NULL, 1, NULL,
+ remote_verify.addr.sa.sa_family, &ai);
+
+ if(ai && !addrlist_match(&remote_verify, ai))
+ {
+ msg (M_WARN,
+ "TCP NOTE: Rejected connection attempt from %s due to --remote setting",
+ print_link_socket_actual (act, &gc));
+ if (openvpn_close_socket (new_sd))
+ msg (M_ERR, "TCP: close socket failed (new_sd)");
+ freeaddrinfo(ai);
+ }
else
- break;
+ {
+ if(ai)
+ freeaddrinfo(ai);
+ break;
+ }
}
openvpn_sleep (1);
}
@@ -893,19 +1063,61 @@ socket_listen_accept (socket_descriptor_t sd,
return new_sd;
}
+/* older mingw versions and WinXP do not have this define,
+ * but Vista and up support the functionality - just define it here
+ */
+#ifdef _WIN32
+# ifndef IPV6_V6ONLY
+# define IPV6_V6ONLY 27
+# endif
+#endif
void
socket_bind (socket_descriptor_t sd,
- struct openvpn_sockaddr *local,
- const char *prefix)
+ struct addrinfo *local,
+ int ai_family,
+ const char *prefix,
+ bool ipv6only)
{
struct gc_arena gc = gc_new ();
- if (bind (sd, &local->addr.sa, af_addr_size(local->addr.sa.sa_family)))
+ /* FIXME (schwabe)
+ * getaddrinfo for the bind address might return multiple AF_INET/AF_INET6
+ * entries for the requested protocol.
+ * For example if an address has multiple A records
+ * What is the correct way to deal with it?
+ */
+
+ struct addrinfo* cur;
+
+ ASSERT(local);
+
+
+ /* find the first addrinfo with correct ai_family */
+ for (cur = local; cur; cur=cur->ai_next)
+ {
+ if(cur->ai_family == ai_family)
+ break;
+ }
+ if (!cur)
+ msg (M_FATAL, "%s: Socket bind failed: Addr to bind has no %s record",
+ prefix, addr_family_name(ai_family));
+
+ if (ai_family == AF_INET6)
+ {
+ int v6only = ipv6only ? 1: 0; /* setsockopt must have an "int" */
+
+ msg (M_INFO, "setsockopt(IPV6_V6ONLY=%d)", v6only);
+ if (setsockopt (sd, IPPROTO_IPV6, IPV6_V6ONLY, (void *) &v6only, sizeof(v6only)))
+ {
+ msg (M_NONFATAL|M_ERRNO, "Setting IPV6_V6ONLY=%d failed", v6only);
+ }
+ }
+ if (bind (sd, cur->ai_addr, cur->ai_addrlen))
{
const int errnum = openvpn_errno ();
msg (M_FATAL, "%s: Socket bind failed on local address %s: %s",
prefix,
- print_sockaddr (local, &gc),
+ print_sockaddr_ex (local->ai_addr, ":", PS_SHOW_PORT, &gc),
strerror_ts (errnum, &gc));
}
gc_free (&gc);
@@ -913,19 +1125,23 @@ socket_bind (socket_descriptor_t sd,
int
openvpn_connect (socket_descriptor_t sd,
- struct openvpn_sockaddr *remote,
+ const struct sockaddr *remote,
int connect_timeout,
volatile int *signal_received)
{
int status = 0;
+#ifdef TARGET_ANDROID
+ protect_fd_nonlocal(sd, remote);
+#endif
+
#ifdef CONNECT_NONBLOCK
set_nonblock (sd);
- status = connect (sd, &remote->addr.sa, af_addr_size(remote->addr.sa.sa_family));
+ status = connect (sd, remote, af_addr_size(remote->sa_family));
if (status)
status = openvpn_errno ();
if (
-#ifdef WIN32
+#ifdef _WIN32
status == WSAEWOULDBLOCK
#else
status == EINPROGRESS
@@ -968,7 +1184,7 @@ openvpn_connect (socket_descriptor_t sd,
{
if (--connect_timeout < 0)
{
-#ifdef WIN32
+#ifdef _WIN32
status = WSAETIMEDOUT;
#else
status = ETIMEDOUT;
@@ -995,7 +1211,7 @@ openvpn_connect (socket_descriptor_t sd,
}
}
#else
- status = connect (sd, &remote->addr.sa, af_addr_size(remote->addr.sa.sa_family));
+ status = connect (sd, remote, af_addr_size(remote->sa_family));
if (status)
status = openvpn_errno ();
#endif
@@ -1003,85 +1219,72 @@ openvpn_connect (socket_descriptor_t sd,
return status;
}
+void set_actual_address (struct link_socket_actual* actual, struct addrinfo* ai)
+{
+ CLEAR (*actual);
+ ASSERT (ai);
+
+ if (ai->ai_family == AF_INET)
+ actual->dest.addr.in4 =
+ *((struct sockaddr_in*) ai->ai_addr);
+ else if (ai->ai_family == AF_INET6)
+ actual->dest.addr.in6 =
+ *((struct sockaddr_in6*) ai->ai_addr);
+ else
+ ASSERT(0);
+
+}
+
void
-socket_connect (socket_descriptor_t *sd,
- struct openvpn_sockaddr *local,
- bool bind_local,
- struct openvpn_sockaddr *remote,
- const bool connection_profiles_defined,
- const char *remote_dynamic,
- bool *remote_changed,
- const int connect_retry_seconds,
- const int connect_timeout,
- const int connect_retry_max,
- const unsigned int sockflags,
- volatile int *signal_received)
+socket_connect (socket_descriptor_t* sd,
+ const struct sockaddr* dest,
+ const int connect_timeout,
+ struct signal_info* sig_info)
{
struct gc_arena gc = gc_new ();
- int retry = 0;
+ int status;
#ifdef CONNECT_NONBLOCK
- msg (M_INFO, "Attempting to establish TCP connection with %s [nonblock]",
- print_sockaddr (remote, &gc));
+ msg (M_INFO, "Attempting to establish TCP connection with %s [nonblock]",
+ print_sockaddr (dest, &gc));
#else
- msg (M_INFO, "Attempting to establish TCP connection with %s",
- print_sockaddr (remote, &gc));
+ msg (M_INFO, "Attempting to establish TCP connection with %s",
+ print_sockaddr (dest, &gc));
#endif
- while (true)
- {
- int status;
-
#ifdef ENABLE_MANAGEMENT
- if (management)
+ if (management)
management_set_state (management,
OPENVPN_STATE_TCP_CONNECT,
NULL,
- (in_addr_t)0,
- (in_addr_t)0);
+ NULL,
+ NULL,
+ NULL,
+ NULL);
#endif
- status = openvpn_connect (*sd, remote, connect_timeout, signal_received);
+ /* Set the actual address */
+ status = openvpn_connect (*sd, dest, connect_timeout, &sig_info->signal_received);
- get_signal (signal_received);
- if (*signal_received)
+ get_signal (&sig_info->signal_received);
+ if (sig_info->signal_received)
goto done;
- if (!status)
- break;
+ if (status) {
- msg (D_LINK_ERRORS,
- "TCP: connect to %s failed, will try again in %d seconds: %s",
- print_sockaddr (remote, &gc),
- connect_retry_seconds,
- strerror_ts (status, &gc));
+ msg (D_LINK_ERRORS,
+ "TCP: connect to %s failed: %s",
+ print_sockaddr (dest, &gc),
+ strerror_ts (status, &gc));
- gc_reset (&gc);
-
- openvpn_close_socket (*sd);
- *sd = SOCKET_UNDEFINED;
-
- if ((connect_retry_max > 0 && ++retry >= connect_retry_max) || connection_profiles_defined)
- {
- *signal_received = SIGUSR1;
- goto done;
- }
-
- openvpn_sleep (connect_retry_seconds);
-
- get_signal (signal_received);
- if (*signal_received)
- goto done;
-
- *sd = create_socket_tcp (local->addr.sa.sa_family);
-
- if (bind_local)
- socket_bind (*sd, local, "TCP Client");
- update_remote (remote_dynamic, remote, remote_changed, sockflags);
- }
-
- msg (M_INFO, "TCP connection established with %s",
- print_sockaddr (remote, &gc));
+ openvpn_close_socket (*sd);
+ *sd = SOCKET_UNDEFINED;
+ sig_info->signal_received = SIGUSR1;
+ sig_info->source = SIG_SOURCE_CONNECTION_FAILED;
+ } else {
+ msg (M_INFO, "TCP connection established with %s",
+ print_sockaddr (dest, &gc));
+ }
done:
gc_free (&gc);
@@ -1093,7 +1296,7 @@ socket_connect (socket_descriptor_t *sd,
static void
socket_frame_init (const struct frame *frame, struct link_socket *sock)
{
-#ifdef WIN32
+#ifdef _WIN32
overlapped_io_init (&sock->reads, frame, FALSE, false);
overlapped_io_init (&sock->writes, frame, TRUE, false);
sock->rw_handle.read = sock->reads.overlapped.hEvent;
@@ -1102,7 +1305,7 @@ socket_frame_init (const struct frame *frame, struct link_socket *sock)
if (link_socket_connection_oriented (sock))
{
-#ifdef WIN32
+#ifdef _WIN32
stream_buf_init (&sock->stream_buf,
&sock->reads.buf_init,
sock->sockflags,
@@ -1132,70 +1335,39 @@ frame_adjust_path_mtu (struct frame *frame, int pmtu, int proto)
}
static void
-resolve_bind_local (struct link_socket *sock)
+resolve_bind_local (struct link_socket *sock, const sa_family_t af)
{
struct gc_arena gc = gc_new ();
/* resolve local address if undefined */
- if (!addr_defined (&sock->info.lsa->local))
- {
- /* may return AF_{INET|INET6} guessed from local_host */
- switch(addr_guess_family(sock->info.proto, sock->local_host))
- {
- case AF_INET:
- sock->info.lsa->local.addr.in4.sin_family = AF_INET;
- sock->info.lsa->local.addr.in4.sin_addr.s_addr =
- (sock->local_host ? getaddr (GETADDR_RESOLVE | GETADDR_WARN_ON_SIGNAL | GETADDR_FATAL,
- sock->local_host,
- 0,
- NULL,
- NULL)
- : htonl (INADDR_ANY));
- sock->info.lsa->local.addr.in4.sin_port = htons (sock->local_port);
- break;
- case AF_INET6:
- {
- int status;
- CLEAR(sock->info.lsa->local.addr.in6);
- if (sock->local_host)
- {
- struct addrinfo *ai;
-
- status = openvpn_getaddrinfo(GETADDR_RESOLVE | GETADDR_WARN_ON_SIGNAL | GETADDR_FATAL,
- sock->local_host, 0, NULL, AF_INET6, &ai);
- if(status ==0) {
- sock->info.lsa->local.addr.in6 = *((struct sockaddr_in6*)(ai->ai_addr));
- freeaddrinfo(ai);
- }
- }
- else
- {
- sock->info.lsa->local.addr.in6.sin6_family = AF_INET6;
- sock->info.lsa->local.addr.in6.sin6_addr = in6addr_any;
- status = 0;
- }
- if (!status == 0)
- {
- msg (M_FATAL, "getaddr6() failed for local \"%s\": %s",
- sock->local_host,
- gai_strerror(status));
- }
- sock->info.lsa->local.addr.in6.sin6_port = htons (sock->local_port);
- }
- break;
- }
- }
-
- /* bind to local address/port */
- if (sock->bind_local)
+ if (!sock->info.lsa->bind_local)
{
-#ifdef ENABLE_SOCKS
- if (sock->socks_proxy && sock->info.proto == PROTO_UDPv4)
- socket_bind (sock->ctrl_sd, &sock->info.lsa->local, "SOCKS");
- else
-#endif
- socket_bind (sock->sd, &sock->info.lsa->local, "TCP/UDP");
+ int flags = GETADDR_RESOLVE | GETADDR_WARN_ON_SIGNAL |
+ GETADDR_FATAL | GETADDR_PASSIVE;
+ int status;
+
+ if(proto_is_dgram(sock->info.proto))
+ flags |= GETADDR_DATAGRAM;
+
+ /* will return AF_{INET|INET6}from local_host */
+ status = get_cached_dns_entry (sock->dns_cache,
+ sock->local_host,
+ sock->local_port,
+ af,
+ flags,
+ &sock->info.lsa->bind_local);
+
+ if (status)
+ status = openvpn_getaddrinfo(flags, sock->local_host, sock->local_port, 0,
+ NULL, af, &sock->info.lsa->bind_local);
+
+ if(status !=0) {
+ msg (M_FATAL, "getaddrinfo() failed for local \"%s:%s\": %s",
+ sock->local_host, sock->local_port,
+ gai_strerror(status));
+ }
}
+
gc_free (&gc);
}
@@ -1206,132 +1378,113 @@ resolve_remote (struct link_socket *sock,
volatile int *signal_received)
{
struct gc_arena gc = gc_new ();
- int af;
- if (!sock->did_resolve_remote)
+ /* resolve remote address if undefined */
+ if (!sock->info.lsa->remote_list)
{
- /* resolve remote address if undefined */
- if (!addr_defined (&sock->info.lsa->remote))
+ if (sock->remote_host)
{
- af = addr_guess_family(sock->info.proto, sock->remote_host);
- switch(af)
- {
- case AF_INET:
- sock->info.lsa->remote.addr.in4.sin_family = AF_INET;
- sock->info.lsa->remote.addr.in4.sin_addr.s_addr = 0;
- break;
- case AF_INET6:
- CLEAR(sock->info.lsa->remote.addr.in6);
- sock->info.lsa->remote.addr.in6.sin6_family = AF_INET6;
- sock->info.lsa->remote.addr.in6.sin6_addr = in6addr_any;
- break;
- }
-
- if (sock->remote_host)
+ unsigned int flags = sf2gaf(GETADDR_RESOLVE|GETADDR_UPDATE_MANAGEMENT_STATE, sock->sockflags);
+ int retry = 0;
+ int status = -1;
+ struct addrinfo* ai;
+ if (proto_is_dgram(sock->info.proto))
+ flags |= GETADDR_DATAGRAM;
+
+ if (sock->resolve_retry_seconds == RESOLV_RETRY_INFINITE)
{
- unsigned int flags = sf2gaf(GETADDR_RESOLVE|GETADDR_UPDATE_MANAGEMENT_STATE, sock->sockflags);
- int retry = 0;
- int status = -1;
- struct addrinfo* ai;
-
- if (sock->connection_profiles_defined && sock->resolve_retry_seconds == RESOLV_RETRY_INFINITE)
+ if (phase == 2)
+ flags |= (GETADDR_TRY_ONCE | GETADDR_FATAL);
+ retry = 0;
+ }
+ else if (phase == 1)
+ {
+ if (sock->resolve_retry_seconds)
{
- if (phase == 2)
- flags |= (GETADDR_TRY_ONCE | GETADDR_FATAL);
retry = 0;
}
- else if (phase == 1)
+ else
{
- if (sock->resolve_retry_seconds)
- {
- retry = 0;
- }
- else
- {
- flags |= (GETADDR_FATAL | GETADDR_MENTION_RESOLVE_RETRY);
- retry = 0;
- }
+ flags |= (GETADDR_FATAL | GETADDR_MENTION_RESOLVE_RETRY);
+ retry = 0;
}
- else if (phase == 2)
+ }
+ else if (phase == 2)
+ {
+ if (sock->resolve_retry_seconds)
{
- if (sock->resolve_retry_seconds)
- {
- flags |= GETADDR_FATAL;
- retry = sock->resolve_retry_seconds;
- }
- else
- {
- ASSERT (0);
- }
+ flags |= GETADDR_FATAL;
+ retry = sock->resolve_retry_seconds;
}
else
{
ASSERT (0);
}
+ }
+ else
+ {
+ ASSERT (0);
+ }
- /* Temporary fix, this need to be changed for dual stack */
- status = openvpn_getaddrinfo(flags, sock->remote_host, retry,
- signal_received, af, &ai);
- if(status == 0)
- {
- if ( ai->ai_family == AF_INET6 )
- sock->info.lsa->remote.addr.in6 = *((struct sockaddr_in6*)(ai->ai_addr));
- else
- sock->info.lsa->remote.addr.in4 = *((struct sockaddr_in*)(ai->ai_addr));
- freeaddrinfo(ai);
-
- dmsg (D_SOCKET_DEBUG, "RESOLVE_REMOTE flags=0x%04x phase=%d rrs=%d sig=%d status=%d",
- flags,
- phase,
- retry,
- signal_received ? *signal_received : -1,
- status);
- }
- if (signal_received)
- {
- if (*signal_received)
- goto done;
- }
+
+ status = get_cached_dns_entry (sock->dns_cache,
+ sock->remote_host,
+ sock->remote_port,
+ sock->info.af,
+ flags, &ai);
+ if (status)
+ status = openvpn_getaddrinfo (flags, sock->remote_host, sock->remote_port,
+ retry, signal_received, sock->info.af, &ai);
+
+ if(status == 0) {
+ 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",
+ flags,
+ phase,
+ retry,
+ signal_received ? *signal_received : -1,
+ status);
+ }
+ if (signal_received)
+ {
+ if (*signal_received)
+ goto done;
+ }
if (status!=0)
{
if (signal_received)
*signal_received = SIGUSR1;
goto done;
}
- }
- switch(af)
- {
- case AF_INET:
- sock->info.lsa->remote.addr.in4.sin_port = htons (sock->remote_port);
- break;
- case AF_INET6:
- sock->info.lsa->remote.addr.in6.sin6_port = htons (sock->remote_port);
- break;
- }
}
+ }
- /* should we re-use previous active remote address? */
- if (link_socket_actual_defined (&sock->info.lsa->actual))
- {
- msg (M_INFO, "TCP/UDP: Preserving recently used remote address: %s",
- print_link_socket_actual (&sock->info.lsa->actual, &gc));
- if (remote_dynamic)
- *remote_dynamic = NULL;
- }
- else
+ /* should we re-use previous active remote address? */
+ if (link_socket_actual_defined (&sock->info.lsa->actual))
+ {
+ msg (M_INFO, "TCP/UDP: Preserving recently used remote address: %s",
+ print_link_socket_actual (&sock->info.lsa->actual, &gc));
+ if (remote_dynamic)
+ *remote_dynamic = NULL;
+ }
+ else
+ {
+ CLEAR (sock->info.lsa->actual);
+ if(sock->info.lsa->current_remote)
{
- CLEAR (sock->info.lsa->actual);
- sock->info.lsa->actual.dest = sock->info.lsa->remote;
+ set_actual_address (&sock->info.lsa->actual,
+ sock->info.lsa->current_remote);
}
-
- /* remember that we finished */
- sock->did_resolve_remote = true;
}
done:
gc_free (&gc);
}
+
+
struct link_socket *
link_socket_new (void)
{
@@ -1339,29 +1492,24 @@ link_socket_new (void)
ALLOC_OBJ_CLEAR (sock, struct link_socket);
sock->sd = SOCKET_UNDEFINED;
-#ifdef ENABLE_SOCKS
sock->ctrl_sd = SOCKET_UNDEFINED;
-#endif
return sock;
}
-/* bind socket if necessary */
void
link_socket_init_phase1 (struct link_socket *sock,
- const bool connection_profiles_defined,
const char *local_host,
- int local_port,
+ const char *local_port,
const char *remote_host,
- int remote_port,
+ const char *remote_port,
+ struct cached_dns_entry *dns_cache,
int proto,
+ sa_family_t af,
+ bool bind_ipv6_only,
int mode,
const struct link_socket *accept_from,
-#ifdef ENABLE_HTTP_PROXY
struct http_proxy_info *http_proxy,
-#endif
-#ifdef ENABLE_SOCKS
struct socks_proxy_info *socks_proxy,
-#endif
#ifdef ENABLE_DEBUG
int gremlin,
#endif
@@ -1372,38 +1520,25 @@ link_socket_init_phase1 (struct link_socket *sock,
const char *ipchange_command,
const struct plugin_list *plugins,
int resolve_retry_seconds,
- int connect_retry_seconds,
- int connect_timeout,
- int connect_retry_max,
int mtu_discover_type,
int rcvbuf,
int sndbuf,
int mark,
+ struct event_timeout* server_poll_timeout,
unsigned int sockflags)
{
ASSERT (sock);
- sock->connection_profiles_defined = connection_profiles_defined;
-
sock->local_host = local_host;
sock->local_port = local_port;
sock->remote_host = remote_host;
sock->remote_port = remote_port;
-
-#ifdef ENABLE_HTTP_PROXY
+ sock->dns_cache = dns_cache;
sock->http_proxy = http_proxy;
-#endif
-
-#ifdef ENABLE_SOCKS
sock->socks_proxy = socks_proxy;
-#endif
-
sock->bind_local = bind_local;
sock->inetd = inetd;
sock->resolve_retry_seconds = resolve_retry_seconds;
- sock->connect_retry_seconds = connect_retry_seconds;
- sock->connect_timeout = connect_timeout;
- sock->connect_retry_max = connect_retry_max;
sock->mtu_discover_type = mtu_discover_type;
#ifdef ENABLE_DEBUG
@@ -1414,31 +1549,30 @@ link_socket_init_phase1 (struct link_socket *sock,
sock->socket_buffer_sizes.sndbuf = sndbuf;
sock->sockflags = sockflags;
+ sock->mark = mark;
sock->info.proto = proto;
+ sock->info.af = af;
sock->info.remote_float = remote_float;
sock->info.lsa = lsa;
+ sock->info.bind_ipv6_only = bind_ipv6_only;
sock->info.ipchange_command = ipchange_command;
sock->info.plugins = plugins;
+ sock->server_poll_timeout = server_poll_timeout;
sock->mode = mode;
if (mode == LS_MODE_TCP_ACCEPT_FROM)
{
ASSERT (accept_from);
- ASSERT (sock->info.proto == PROTO_TCPv4_SERVER
- || sock->info.proto == PROTO_TCPv6_SERVER
- );
+ ASSERT (sock->info.proto == PROTO_TCP_SERVER);
ASSERT (!sock->inetd);
sock->sd = accept_from->sd;
}
- if (false)
- ;
-#ifdef ENABLE_HTTP_PROXY
/* are we running in HTTP proxy mode? */
- else if (sock->http_proxy)
+ if (sock->http_proxy)
{
- ASSERT (sock->info.proto == PROTO_TCPv4_CLIENT);
+ ASSERT (sock->info.proto == PROTO_TCP_CLIENT);
ASSERT (!sock->inetd);
/* the proxy server */
@@ -1449,12 +1583,9 @@ link_socket_init_phase1 (struct link_socket *sock,
sock->proxy_dest_host = remote_host;
sock->proxy_dest_port = remote_port;
}
-#endif
-#ifdef ENABLE_SOCKS
/* or in Socks proxy mode? */
else if (sock->socks_proxy)
{
- ASSERT (sock->info.proto == PROTO_TCPv4_CLIENT || sock->info.proto == PROTO_UDPv4);
ASSERT (!sock->inetd);
/* the proxy server */
@@ -1465,7 +1596,6 @@ link_socket_init_phase1 (struct link_socket *sock,
sock->proxy_dest_host = remote_host;
sock->proxy_dest_port = remote_port;
}
-#endif
else
{
sock->remote_host = remote_host;
@@ -1473,7 +1603,7 @@ link_socket_init_phase1 (struct link_socket *sock,
}
/* bind behavior for TCP server vs. client */
- if (sock->info.proto == PROTO_TCPv4_SERVER)
+ if (sock->info.proto == PROTO_TCP_SERVER)
{
if (sock->mode == LS_MODE_TCP_ACCEPT_FROM)
sock->bind_local = false;
@@ -1484,43 +1614,255 @@ link_socket_init_phase1 (struct link_socket *sock,
/* were we started by inetd or xinetd? */
if (sock->inetd)
{
- ASSERT (sock->info.proto != PROTO_TCPv4_CLIENT
- && sock->info.proto != PROTO_TCPv6_CLIENT);
+ ASSERT (sock->info.proto != PROTO_TCP_CLIENT);
ASSERT (socket_defined (inetd_socket_descriptor));
sock->sd = inetd_socket_descriptor;
}
else if (mode != LS_MODE_TCP_ACCEPT_FROM)
{
- create_socket (sock);
+ if (sock->bind_local) {
+ resolve_bind_local (sock, sock->info.af);
+ }
+ resolve_remote (sock, 1, NULL, NULL);
+ }
+}
- /* set socket buffers based on --sndbuf and --rcvbuf options */
- socket_set_buffers (sock->sd, &sock->socket_buffer_sizes);
+static
+void phase2_inetd (struct link_socket* sock, const struct frame *frame,
+ const char *remote_dynamic, volatile int *signal_received)
+{
+ bool remote_changed = false;
- /* set socket to --mark packets with given value */
- socket_set_mark (sock->sd, mark);
+ if (sock->info.proto == PROTO_TCP_SERVER) {
+ /* AF_INET as default (and fallback) for inetd */
+ sock->info.lsa->actual.dest.addr.sa.sa_family = AF_INET;
+#ifdef HAVE_GETSOCKNAME
+ {
+ /* inetd: hint family type for dest = local's */
+ struct openvpn_sockaddr local_addr;
+ socklen_t addrlen = sizeof(local_addr);
+ if (getsockname (sock->sd, &local_addr.addr.sa, &addrlen) == 0) {
+ sock->info.lsa->actual.dest.addr.sa.sa_family = local_addr.addr.sa.sa_family;
+ dmsg (D_SOCKET_DEBUG, "inetd(%s): using sa_family=%d from getsockname(%d)",
+ proto2ascii(sock->info.proto, sock->info.af, false),
+ local_addr.addr.sa.sa_family, sock->sd);
+ } else
+ msg (M_WARN, "inetd(%s): getsockname(%d) failed, using AF_INET",
+ proto2ascii(sock->info.proto, sock->info.af, false), sock->sd);
+ }
+#else
+ msg (M_WARN, "inetd(%s): this OS does not provide the getsockname() "
+ "function, using AF_INET",
+ proto2ascii(sock->info.proto, false));
+#endif
+ sock->sd =
+ socket_listen_accept (sock->sd,
+ &sock->info.lsa->actual,
+ remote_dynamic,
+ sock->info.lsa->bind_local,
+ false,
+ sock->inetd == INETD_NOWAIT,
+ signal_received);
- resolve_bind_local (sock);
- resolve_remote (sock, 1, NULL, NULL);
+ }
+ ASSERT (!remote_changed);
+}
+
+static void
+phase2_set_socket_flags (struct link_socket* sock)
+{
+ /* set misc socket parameters */
+ socket_set_flags (sock->sd, sock->sockflags);
+
+ /* set socket to non-blocking mode */
+ set_nonblock (sock->sd);
+
+ /* set socket file descriptor to not pass across execs, so that
+ scripts don't have access to it */
+ set_cloexec (sock->sd);
+
+ if (socket_defined (sock->ctrl_sd))
+ set_cloexec (sock->ctrl_sd);
+
+ /* set Path MTU discovery options on the socket */
+ set_mtu_discover_type (sock->sd, sock->mtu_discover_type, sock->info.af);
+
+#if EXTENDED_SOCKET_ERROR_CAPABILITY
+ /* if the OS supports it, enable extended error passing on the socket */
+ set_sock_extended_error_passing (sock->sd);
+#endif
+}
+
+
+static void
+linksock_print_addr (struct link_socket *sock)
+{
+ struct gc_arena gc = gc_new ();
+ const int msglevel = (sock->mode == LS_MODE_TCP_ACCEPT_FROM) ? D_INIT_MEDIUM : M_INFO;
+
+ /* print local address */
+ if (sock->inetd)
+ msg (msglevel, "%s link local: [inetd]", proto2ascii (sock->info.proto, sock->info.af, true));
+ else if (sock->bind_local)
+ {
+ sa_family_t ai_family = sock->info.lsa->actual.dest.addr.sa.sa_family;
+ /* Socket is always bound on the first matching address,
+ * For bound sockets with no remote addr this is the element of
+ * the list */
+ struct addrinfo *cur;
+ for (cur = sock->info.lsa->bind_local; cur; cur=cur->ai_next)
+ {
+ if(!ai_family || ai_family == cur->ai_family)
+ break;
+ }
+ ASSERT (cur);
+ msg (msglevel, "%s link local (bound): %s",
+ proto2ascii (sock->info.proto, sock->info.af, true),
+ print_sockaddr(cur->ai_addr,&gc));
}
+ else
+ msg (msglevel, "%s link local: (not bound)",
+ proto2ascii (sock->info.proto, sock->info.af, true));
+
+ /* print active remote address */
+ msg (msglevel, "%s link remote: %s",
+ proto2ascii (sock->info.proto, sock->info.af, true),
+ print_link_socket_actual_ex (&sock->info.lsa->actual,
+ ":",
+ PS_SHOW_PORT_IF_DEFINED,
+ &gc));
+ gc_free(&gc);
+}
+
+static void
+phase2_tcp_server (struct link_socket *sock, const char *remote_dynamic,
+ volatile int *signal_received)
+{
+ switch (sock->mode)
+ {
+ case LS_MODE_DEFAULT:
+ sock->sd = socket_listen_accept (sock->sd,
+ &sock->info.lsa->actual,
+ remote_dynamic,
+ sock->info.lsa->bind_local,
+ true,
+ false,
+ signal_received);
+ break;
+ case LS_MODE_TCP_LISTEN:
+ socket_do_listen (sock->sd,
+ sock->info.lsa->bind_local,
+ true,
+ false);
+ break;
+ case LS_MODE_TCP_ACCEPT_FROM:
+ sock->sd = socket_do_accept (sock->sd,
+ &sock->info.lsa->actual,
+ false);
+ if (!socket_defined (sock->sd))
+ {
+ *signal_received = SIGTERM;
+ return;
+ }
+ tcp_connection_established (&sock->info.lsa->actual);
+ break;
+ default:
+ ASSERT (0);
+ }
+}
+
+
+static void
+phase2_tcp_client (struct link_socket *sock, struct signal_info *sig_info)
+{
+ bool proxy_retry = false;
+ do {
+ socket_connect (&sock->sd,
+ sock->info.lsa->current_remote->ai_addr,
+ get_server_poll_remaining_time (sock->server_poll_timeout),
+ sig_info);
+
+ if (sig_info->signal_received)
+ return;
+
+ if (sock->http_proxy)
+ {
+ proxy_retry = establish_http_proxy_passthru (sock->http_proxy,
+ sock->sd,
+ sock->proxy_dest_host,
+ sock->proxy_dest_port,
+ sock->server_poll_timeout,
+ &sock->stream_buf.residual,
+ &sig_info->signal_received);
+ }
+ else if (sock->socks_proxy)
+ {
+ establish_socks_proxy_passthru (sock->socks_proxy,
+ sock->sd,
+ sock->proxy_dest_host,
+ sock->proxy_dest_port,
+ &sig_info->signal_received);
+ }
+ if (proxy_retry)
+ {
+ openvpn_close_socket (sock->sd);
+ sock->sd = create_socket_tcp (sock->info.lsa->current_remote);
+ }
+
+ } while (proxy_retry);
+
+}
+
+static void
+phase2_socks_client (struct link_socket *sock, struct signal_info *sig_info)
+{
+ socket_connect (&sock->ctrl_sd,
+ sock->info.lsa->current_remote->ai_addr,
+ get_server_poll_remaining_time (sock->server_poll_timeout),
+ sig_info);
+
+ if (sig_info->signal_received)
+ return;
+
+ establish_socks_proxy_udpassoc (sock->socks_proxy,
+ sock->ctrl_sd,
+ sock->sd,
+ &sock->socks_relay.dest,
+ &sig_info->signal_received);
+
+ if (sig_info->signal_received)
+ return;
+
+ sock->remote_host = sock->proxy_dest_host;
+ sock->remote_port = sock->proxy_dest_port;
+
+ addr_zero_host(&sock->info.lsa->actual.dest);
+ if (sock->info.lsa->remote_list)
+ {
+ freeaddrinfo(sock->info.lsa->remote_list);
+ sock->info.lsa->current_remote = NULL;
+ sock->info.lsa->remote_list = NULL;
+ }
+
+ resolve_remote (sock, 1, NULL, &sig_info->signal_received);
}
/* finalize socket initialization */
void
link_socket_init_phase2 (struct link_socket *sock,
const struct frame *frame,
- volatile int *signal_received)
+ struct signal_info *sig_info)
{
- struct gc_arena gc = gc_new ();
const char *remote_dynamic = NULL;
- bool remote_changed = false;
int sig_save = 0;
ASSERT (sock);
+ ASSERT (sig_info);
- if (signal_received && *signal_received)
+ if (sig_info->signal_received)
{
- sig_save = *signal_received;
- *signal_received = 0;
+ sig_save = sig_info->signal_received;
+ sig_info->signal_received = 0;
}
/* initialize buffers */
@@ -1537,246 +1879,83 @@ link_socket_init_phase2 (struct link_socket *sock,
/* were we started by inetd or xinetd? */
if (sock->inetd)
{
- if (sock->info.proto == PROTO_TCPv4_SERVER
- || sock->info.proto == PROTO_TCPv6_SERVER) {
- /* AF_INET as default (and fallback) for inetd */
- sock->info.lsa->actual.dest.addr.sa.sa_family = AF_INET;
-#ifdef HAVE_GETSOCKNAME
- {
- /* inetd: hint family type for dest = local's */
- struct openvpn_sockaddr local_addr;
- socklen_t addrlen = sizeof(local_addr);
- if (getsockname (sock->sd, (struct sockaddr *)&local_addr, &addrlen) == 0) {
- sock->info.lsa->actual.dest.addr.sa.sa_family = local_addr.addr.sa.sa_family;
- dmsg (D_SOCKET_DEBUG, "inetd(%s): using sa_family=%d from getsockname(%d)",
- proto2ascii(sock->info.proto, false), local_addr.addr.sa.sa_family,
- sock->sd);
- } else
- msg (M_WARN, "inetd(%s): getsockname(%d) failed, using AF_INET",
- proto2ascii(sock->info.proto, false), sock->sd);
- }
-#else
- msg (M_WARN, "inetd(%s): this OS does not provide the getsockname() "
- "function, using AF_INET",
- proto2ascii(sock->info.proto, false));
-#endif
- sock->sd =
- socket_listen_accept (sock->sd,
- &sock->info.lsa->actual,
- remote_dynamic,
- &remote_changed,
- &sock->info.lsa->local,
- false,
- sock->inetd == INETD_NOWAIT,
- signal_received);
- }
- ASSERT (!remote_changed);
- if (*signal_received)
+ phase2_inetd (sock, frame, remote_dynamic, &sig_info->signal_received);
+ if (sig_info->signal_received)
goto done;
+
}
else
{
- resolve_remote (sock, 2, &remote_dynamic, signal_received);
+ /* Second chance to resolv/create socket */
+ resolve_remote (sock, 2, &remote_dynamic, &sig_info->signal_received);
- if (*signal_received)
- goto done;
+ /* If a valid remote has been found, create the socket with its addrinfo */
+ if (sock->info.lsa->current_remote)
+ create_socket (sock, sock->info.lsa->current_remote);
- /* TCP client/server */
- if (sock->info.proto == PROTO_TCPv4_SERVER
- ||sock->info.proto == PROTO_TCPv6_SERVER)
+ /* If socket has not already been created create it now */
+ if (sock->sd == SOCKET_UNDEFINED)
{
- switch (sock->mode)
+ /* If we have no --remote and have still not figured out the
+ * protocol family to use we will use the first of the bind */
+
+ if (sock->bind_local && !sock->remote_host && sock->info.lsa->bind_local)
{
- case LS_MODE_DEFAULT:
- sock->sd = socket_listen_accept (sock->sd,
- &sock->info.lsa->actual,
- remote_dynamic,
- &remote_changed,
- &sock->info.lsa->local,
- true,
- false,
- signal_received);
- break;
- case LS_MODE_TCP_LISTEN:
- socket_do_listen (sock->sd,
- &sock->info.lsa->local,
- true,
- false);
- break;
- case LS_MODE_TCP_ACCEPT_FROM:
- sock->sd = socket_do_accept (sock->sd,
- &sock->info.lsa->actual,
- false);
- if (!socket_defined (sock->sd))
- {
- *signal_received = SIGTERM;
- goto done;
+ /* Warn if this is because neither v4 or v6 was specified
+ * and we should not connect a remote */
+ if (sock->info.af == AF_UNSPEC)
+ {
+ msg (M_WARN, "Could not determine IPv4/IPv6 protocol. Using %s",
+ addr_family_name(sock->info.lsa->bind_local->ai_family));
+ sock->info.af = sock->info.lsa->bind_local->ai_family;
}
- tcp_connection_established (&sock->info.lsa->actual);
- break;
- default:
- ASSERT (0);
+
+ create_socket (sock, sock->info.lsa->bind_local);
}
}
- else if (sock->info.proto == PROTO_TCPv4_CLIENT
- ||sock->info.proto == PROTO_TCPv6_CLIENT)
- {
-#ifdef GENERAL_PROXY_SUPPORT
- bool proxy_retry = false;
-#else
- const bool proxy_retry = false;
-#endif
- do {
- socket_connect (&sock->sd,
- &sock->info.lsa->local,
- sock->bind_local,
- &sock->info.lsa->actual.dest,
- sock->connection_profiles_defined,
- remote_dynamic,
- &remote_changed,
- sock->connect_retry_seconds,
- sock->connect_timeout,
- sock->connect_retry_max,
- sock->sockflags,
- signal_received);
-
- if (*signal_received)
- goto done;
-
- if (false)
- ;
-#ifdef ENABLE_HTTP_PROXY
- else if (sock->http_proxy)
- {
- proxy_retry = establish_http_proxy_passthru (sock->http_proxy,
- sock->sd,
- sock->proxy_dest_host,
- sock->proxy_dest_port,
- &sock->stream_buf.residual,
- signal_received);
- }
-#endif
-#ifdef ENABLE_SOCKS
- else if (sock->socks_proxy)
- {
- establish_socks_proxy_passthru (sock->socks_proxy,
- sock->sd,
- sock->proxy_dest_host,
- sock->proxy_dest_port,
- signal_received);
- }
-#endif
- if (proxy_retry)
- {
- openvpn_close_socket (sock->sd);
- sock->sd = create_socket_tcp (AF_INET);
- }
- } while (proxy_retry);
- }
-#ifdef ENABLE_SOCKS
- else if (sock->info.proto == PROTO_UDPv4 && sock->socks_proxy)
+ /* Socket still undefined, give a warning and abort connection */
+ if (sock->sd == SOCKET_UNDEFINED)
{
- socket_connect (&sock->ctrl_sd,
- &sock->info.lsa->local,
- sock->bind_local,
- &sock->info.lsa->actual.dest,
- sock->connection_profiles_defined,
- remote_dynamic,
- &remote_changed,
- sock->connect_retry_seconds,
- sock->connect_timeout,
- sock->connect_retry_max,
- sock->sockflags,
- signal_received);
-
- if (*signal_received)
- goto done;
-
- establish_socks_proxy_udpassoc (sock->socks_proxy,
- sock->ctrl_sd,
- sock->sd,
- &sock->socks_relay.dest,
- signal_received);
-
- if (*signal_received)
- goto done;
-
- sock->remote_host = sock->proxy_dest_host;
- sock->remote_port = sock->proxy_dest_port;
- sock->did_resolve_remote = false;
-
- addr_zero_host(&sock->info.lsa->actual.dest);
- addr_zero_host(&sock->info.lsa->remote);
-
- resolve_remote (sock, 1, NULL, signal_received);
-
- if (*signal_received)
- goto done;
+ msg (M_WARN, "Could not determine IPv4/IPv6 protocol");
+ sig_info->signal_received = SIGUSR1;
+ goto done;
}
-#endif
- if (*signal_received)
+ if (sig_info->signal_received)
goto done;
- if (remote_changed)
+ if (sock->info.proto == PROTO_TCP_SERVER)
{
- msg (M_INFO, "TCP/UDP: Dynamic remote address changed during TCP connection establishment");
- addr_copy_host(&sock->info.lsa->remote, &sock->info.lsa->actual.dest);
+ phase2_tcp_server (sock, remote_dynamic,
+ &sig_info->signal_received);
}
- }
-
- /* set misc socket parameters */
- socket_set_flags (sock->sd, sock->sockflags);
-
- /* set socket to non-blocking mode */
- set_nonblock (sock->sd);
-
- /* set socket file descriptor to not pass across execs, so that
- scripts don't have access to it */
- set_cloexec (sock->sd);
-
-#ifdef ENABLE_SOCKS
- if (socket_defined (sock->ctrl_sd))
- set_cloexec (sock->ctrl_sd);
-#endif
-
- /* set Path MTU discovery options on the socket */
- set_mtu_discover_type (sock->sd, sock->mtu_discover_type);
+ else if (sock->info.proto == PROTO_TCP_CLIENT)
+ {
+ phase2_tcp_client (sock, sig_info);
-#if EXTENDED_SOCKET_ERROR_CAPABILITY
- /* if the OS supports it, enable extended error passing on the socket */
- set_sock_extended_error_passing (sock->sd);
+ }
+ else if (sock->info.proto == PROTO_UDP && sock->socks_proxy)
+ {
+ phase2_socks_client (sock, sig_info);
+ }
+#ifdef TARGET_ANDROID
+ if (sock->sd != -1)
+ protect_fd_nonlocal (sock->sd, &sock->info.lsa->actual.dest.addr.sa);
#endif
+ if (sig_info->signal_received)
+ goto done;
+ }
- /* print local address */
- {
- const int msglevel = (sock->mode == LS_MODE_TCP_ACCEPT_FROM) ? D_INIT_MEDIUM : M_INFO;
-
- if (sock->inetd)
- msg (msglevel, "%s link local: [inetd]", proto2ascii (sock->info.proto, true));
- else
- msg (msglevel, "%s link local%s: %s",
- proto2ascii (sock->info.proto, true),
- (sock->bind_local ? " (bound)" : ""),
- print_sockaddr_ex (&sock->info.lsa->local, ":", sock->bind_local ? PS_SHOW_PORT : 0, &gc));
-
- /* print active remote address */
- msg (msglevel, "%s link remote: %s",
- proto2ascii (sock->info.proto, true),
- print_link_socket_actual_ex (&sock->info.lsa->actual,
- ":",
- PS_SHOW_PORT_IF_DEFINED,
- &gc));
- }
+ phase2_set_socket_flags(sock);
+ linksock_print_addr(sock);
done:
- if (sig_save && signal_received)
+ if (sig_save)
{
- if (!*signal_received)
- *signal_received = sig_save;
+ if (!sig_info->signal_received)
+ sig_info->signal_received = sig_save;
}
- gc_free (&gc);
}
void
@@ -1792,7 +1971,7 @@ link_socket_close (struct link_socket *sock)
if (socket_defined (sock->sd))
{
-#ifdef WIN32
+#ifdef _WIN32
close_net_event_win32 (&sock->listen_handle, sock->sd, 0);
#endif
if (!gremlin)
@@ -1802,7 +1981,7 @@ link_socket_close (struct link_socket *sock)
msg (M_WARN | M_ERRNO, "TCP/UDP: Close Socket failed");
}
sock->sd = SOCKET_UNDEFINED;
-#ifdef WIN32
+#ifdef _WIN32
if (!gremlin)
{
overlapped_io_close (&sock->reads);
@@ -1811,14 +1990,12 @@ link_socket_close (struct link_socket *sock)
#endif
}
-#ifdef ENABLE_SOCKS
if (socket_defined (sock->ctrl_sd))
{
if (openvpn_close_socket (sock->ctrl_sd))
msg (M_WARN | M_ERRNO, "TCP/UDP: Close Socket (ctrl_sd) failed");
sock->ctrl_sd = SOCKET_UNDEFINED;
}
-#endif
stream_buf_close (&sock->stream_buf);
free_buf (&sock->stream_buf_data);
@@ -1844,17 +2021,15 @@ setenv_trusted (struct env_set *es, const struct link_socket_info *info)
static void
ipchange_fmt (const bool include_cmd, struct argv *argv, const struct link_socket_info *info, struct gc_arena *gc)
{
- const char *ip = print_sockaddr_ex (&info->lsa->actual.dest, NULL, 0, gc);
- const char *port = print_sockaddr_ex (&info->lsa->actual.dest, NULL, PS_DONT_SHOW_ADDR|PS_SHOW_PORT, gc);
+ const char *host = print_sockaddr_ex (&info->lsa->actual.dest.addr.sa, " ", PS_SHOW_PORT , gc);
if (include_cmd)
- argv_printf (argv, "%sc %s %s",
- info->ipchange_command,
- ip,
- port);
+ {
+ argv_parse_cmd (argv, info->ipchange_command);
+ argv_printf_cat (argv, "%s", host);
+ }
else
- argv_printf (argv, "%s %s",
- ip,
- port);
+ argv_printf (argv, "%s", host);
+
}
void
@@ -1911,6 +2086,7 @@ link_socket_bad_incoming_addr (struct buffer *buf,
const struct link_socket_actual *from_addr)
{
struct gc_arena gc = gc_new ();
+ struct addrinfo* ai;
switch(from_addr->dest.addr.sa.sa_family)
{
@@ -1920,7 +2096,12 @@ link_socket_bad_incoming_addr (struct buffer *buf,
"TCP/UDP: Incoming packet rejected from %s[%d], expected peer address: %s (allow this incoming source address/port by removing --remote or adding --float)",
print_link_socket_actual (from_addr, &gc),
(int)from_addr->dest.addr.sa.sa_family,
- print_sockaddr (&info->lsa->remote, &gc));
+ print_sockaddr_ex (info->lsa->remote_list->ai_addr,":" ,PS_SHOW_PORT, &gc));
+ /* print additional remote addresses */
+ for(ai=info->lsa->remote_list->ai_next;ai;ai=ai->ai_next) {
+ msg(D_LINK_ERRORS,"or from peer address: %s",
+ print_sockaddr_ex(ai->ai_addr,":",PS_SHOW_PORT, &gc));
+ }
break;
}
buf->len = 0;
@@ -1945,18 +2126,43 @@ link_socket_current_remote (const struct link_socket_info *info)
* Maybe in the future consider PF_INET6 endpoints also ...
* by now just ignore it
*
+ * For --remote entries with multiple addresses this
+ * only return the actual endpoint we have sucessfully connected to
*/
if (lsa->actual.dest.addr.sa.sa_family != AF_INET)
return IPV4_INVALID_ADDR;
if (link_socket_actual_defined (&lsa->actual))
return ntohl (lsa->actual.dest.addr.in4.sin_addr.s_addr);
- else if (addr_defined (&lsa->remote))
- return ntohl (lsa->remote.addr.in4.sin_addr.s_addr);
+ else if (lsa->current_remote)
+ return ntohl (((struct sockaddr_in*)lsa->current_remote->ai_addr)
+ ->sin_addr.s_addr);
else
return 0;
}
+const struct in6_addr *
+link_socket_current_remote_ipv6 (const struct link_socket_info *info)
+{
+ const struct link_socket_addr *lsa = info->lsa;
+
+/* This logic supports "redirect-gateway" semantic,
+ * for PF_INET6 routes over PF_INET6 endpoints
+ *
+ * For --remote entries with multiple addresses this
+ * only return the actual endpoint we have sucessfully connected to
+ */
+ if (lsa->actual.dest.addr.sa.sa_family != AF_INET6)
+ return NULL;
+
+ if (link_socket_actual_defined (&lsa->actual))
+ return &(lsa->actual.dest.addr.in6.sin6_addr);
+ else if (lsa->current_remote)
+ return &(((struct sockaddr_in6*)lsa->current_remote->ai_addr) ->sin6_addr);
+ else
+ return NULL;
+}
+
/*
* Return a status string describing socket state.
*/
@@ -1970,7 +2176,7 @@ socket_stat (const struct link_socket *s, unsigned int rwflags, struct gc_arena
{
buf_printf (&out, "S%s",
(s->rwflags_debug & EVENT_READ) ? "R" : "r");
-#ifdef WIN32
+#ifdef _WIN32
buf_printf (&out, "%s",
overlapped_io_state_ascii (&s->reads));
#endif
@@ -1979,7 +2185,7 @@ socket_stat (const struct link_socket *s, unsigned int rwflags, struct gc_arena
{
buf_printf (&out, "S%s",
(s->rwflags_debug & EVENT_WRITE) ? "W" : "w");
-#ifdef WIN32
+#ifdef _WIN32
buf_printf (&out, "%s",
overlapped_io_state_ascii (&s->writes));
#endif
@@ -2019,7 +2225,7 @@ stream_buf_init (struct stream_buf *sb,
sb->residual = alloc_buf (sb->maxlen);
sb->error = false;
#if PORT_SHARE
- sb->port_share_state = ((sockflags & SF_PORT_SHARE) && (proto == PROTO_TCPv4_SERVER))
+ sb->port_share_state = ((sockflags & SF_PORT_SHARE) && (proto == PROTO_TCP_SERVER))
? PS_ENABLED
: PS_DISABLED;
#endif
@@ -2154,7 +2360,7 @@ stream_buf_close (struct stream_buf* sb)
event_t
socket_listen_event_handle (struct link_socket *s)
{
-#ifdef WIN32
+#ifdef _WIN32
if (!defined_net_event_win32 (&s->listen_handle))
init_net_event_win32 (&s->listen_handle, FD_ACCEPT, s->sd, 0);
return &s->listen_handle;
@@ -2168,67 +2374,65 @@ socket_listen_event_handle (struct link_socket *s)
*/
const char *
-print_sockaddr (const struct openvpn_sockaddr *addr, struct gc_arena *gc)
-{
- return print_sockaddr_ex (addr, ":", PS_SHOW_PORT, gc);
-}
-
-const char *
-print_sockaddr_ex (const struct openvpn_sockaddr *addr,
- const char* separator,
- const unsigned int flags,
- struct gc_arena *gc)
+print_sockaddr_ex (const struct sockaddr *sa,
+ const char* separator,
+ const unsigned int flags,
+ struct gc_arena *gc)
{
struct buffer out = alloc_buf_gc (128, gc);
- bool addr_is_defined;
- addr_is_defined = addr_defined (addr);
- if (!addr_is_defined) {
- return "[undef]";
- }
- switch(addr->addr.sa.sa_family)
+ bool addr_is_defined = false;
+ char hostaddr[NI_MAXHOST] = "";
+ char servname[NI_MAXSERV] = "";
+ int status;
+
+ socklen_t salen = 0;
+ switch(sa->sa_family)
{
case AF_INET:
- {
- const int port= ntohs (addr->addr.in4.sin_port);
- buf_puts (&out, "[AF_INET]");
-
- if (!(flags & PS_DONT_SHOW_ADDR))
- buf_printf (&out, "%s", (addr_defined (addr) ? inet_ntoa (addr->addr.in4.sin_addr) : "[undef]"));
-
- if (((flags & PS_SHOW_PORT) || (addr_defined (addr) && (flags & PS_SHOW_PORT_IF_DEFINED)))
- && port)
- {
- if (separator)
- buf_printf (&out, "%s", separator);
-
- buf_printf (&out, "%d", port);
- }
- }
+ if (!(flags & PS_DONT_SHOW_FAMILY))
+ buf_puts (&out, "[AF_INET]");
+ salen = sizeof (struct sockaddr_in);
+ addr_is_defined = ((struct sockaddr_in*) sa)->sin_addr.s_addr != 0;
break;
case AF_INET6:
- {
- const int port= ntohs (addr->addr.in6.sin6_port);
- char buf[INET6_ADDRSTRLEN] = "";
- buf_puts (&out, "[AF_INET6]");
- if (addr_is_defined)
- {
- getnameinfo(&addr->addr.sa, sizeof (struct sockaddr_in6),
- buf, sizeof (buf), NULL, 0, NI_NUMERICHOST);
- buf_puts (&out, buf);
- }
- if (((flags & PS_SHOW_PORT) || (addr_is_defined && (flags & PS_SHOW_PORT_IF_DEFINED)))
- && port)
- {
- if (separator)
- buf_puts (&out, separator);
-
- buf_printf (&out, "%d", port);
- }
- }
+ if (!(flags & PS_DONT_SHOW_FAMILY))
+ buf_puts (&out, "[AF_INET6]");
+ salen = sizeof (struct sockaddr_in6);
+ addr_is_defined = !IN6_IS_ADDR_UNSPECIFIED(&((struct sockaddr_in6*) sa)->sin6_addr);
break;
+ case AF_UNSPEC:
+ if (!(flags & PS_DONT_SHOW_FAMILY))
+ return "[AF_UNSPEC]";
+ else
+ return "";
default:
ASSERT(0);
}
+
+ status = getnameinfo(sa, salen, hostaddr, sizeof (hostaddr),
+ servname, sizeof(servname), NI_NUMERICHOST | NI_NUMERICSERV);
+
+ if(status!=0) {
+ buf_printf(&out,"[nameinfo() err: %s]",gai_strerror(status));
+ return BSTR(&out);
+ }
+
+ if (!(flags & PS_DONT_SHOW_ADDR))
+ {
+ if (addr_is_defined)
+ buf_puts (&out, hostaddr);
+ else
+ buf_puts (&out, "[undef]");
+ }
+
+ if ((flags & PS_SHOW_PORT) || (flags & PS_SHOW_PORT_IF_DEFINED))
+ {
+ if (separator)
+ buf_puts (&out, separator);
+
+ buf_puts (&out, servname);
+ }
+
return BSTR (&out);
}
@@ -2252,7 +2456,7 @@ print_link_socket_actual_ex (const struct link_socket_actual *act,
{
char ifname[IF_NAMESIZE] = "[undef]";
struct buffer out = alloc_buf_gc (128, gc);
- buf_printf (&out, "%s", print_sockaddr_ex (&act->dest, separator, flags, gc));
+ buf_printf (&out, "%s", print_sockaddr_ex (&act->dest.addr.sa, separator, flags, gc));
#if ENABLE_IP_PKTINFO
if ((flags & PS_SHOW_PKTINFO) && addr_defined_ipi(act))
{
@@ -2263,7 +2467,7 @@ print_link_socket_actual_ex (const struct link_socket_actual *act,
struct openvpn_sockaddr sa;
CLEAR (sa);
sa.addr.in4.sin_family = AF_INET;
-#ifdef IP_PKTINFO
+#if defined(HAVE_IN_PKTINFO) && defined(HAVE_IPI_SPEC_DST)
sa.addr.in4.sin_addr = act->pi.in4.ipi_spec_dst;
if_indextoname(act->pi.in4.ipi_ifindex, ifname);
#elif defined(IP_RECVDSTADDR)
@@ -2273,7 +2477,7 @@ print_link_socket_actual_ex (const struct link_socket_actual *act,
#error ENABLE_IP_PKTINFO is set without IP_PKTINFO xor IP_RECVDSTADDR (fix syshead.h)
#endif
buf_printf (&out, " (via %s%%%s)",
- print_sockaddr_ex (&sa, separator, 0, gc),
+ print_sockaddr_ex (&sa.addr.sa, separator, 0, gc),
ifname);
}
break;
@@ -2392,9 +2596,20 @@ setenv_sockaddr (struct env_set *es, const char *name_prefix, const struct openv
}
break;
case AF_INET6:
- openvpn_snprintf (name_buf, sizeof (name_buf), "%s_ip6", name_prefix);
- getnameinfo(&addr->addr.sa, sizeof (struct sockaddr_in6),
- buf, sizeof(buf), NULL, 0, NI_NUMERICHOST);
+ if ( IN6_IS_ADDR_V4MAPPED( &addr->addr.in6.sin6_addr ))
+ {
+ struct in_addr ia;
+ memcpy (&ia.s_addr, &addr->addr.in6.sin6_addr.s6_addr[12],
+ sizeof (ia.s_addr));
+ openvpn_snprintf (name_buf, sizeof (name_buf), "%s_ip", name_prefix);
+ openvpn_snprintf (buf, sizeof(buf), "%s", inet_ntoa(ia) );
+ }
+ else
+ {
+ openvpn_snprintf (name_buf, sizeof (name_buf), "%s_ip6", name_prefix);
+ getnameinfo(&addr->addr.sa, sizeof (struct sockaddr_in6),
+ buf, sizeof(buf), NULL, 0, NI_NUMERICHOST);
+ }
setenv_str (es, name_buf, buf);
if ((flags & SA_IP_PORT) && addr->addr.in6.sin6_port)
@@ -2451,22 +2666,28 @@ setenv_link_socket_actual (struct env_set *es,
struct proto_names {
const char *short_form;
const char *display_form;
- bool is_dgram;
- bool is_net;
- unsigned short proto_af;
+ sa_family_t proto_af;
+ int proto;
};
/* Indexed by PROTO_x */
-static const struct proto_names proto_names[PROTO_N] = {
- {"proto-uninitialized", "proto-NONE",0,0, AF_UNSPEC},
- {"udp", "UDPv4",1,1, AF_INET},
- {"tcp-server", "TCPv4_SERVER",0,1, AF_INET},
- {"tcp-client", "TCPv4_CLIENT",0,1, AF_INET},
- {"tcp", "TCPv4",0,1, AF_INET},
- {"udp6" ,"UDPv6",1,1, AF_INET6},
- {"tcp6-server","TCPv6_SERVER",0,1, AF_INET6},
- {"tcp6-client","TCPv6_CLIENT",0,1, AF_INET6},
- {"tcp6" ,"TCPv6",0,1, AF_INET6},
+static const struct proto_names proto_names[] = {
+ {"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},
+ /* 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},
+ /* 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},
};
bool
@@ -2474,59 +2695,66 @@ proto_is_net(int proto)
{
if (proto < 0 || proto >= PROTO_N)
ASSERT(0);
- return proto_names[proto].is_net;
+ return proto != PROTO_NONE;
}
bool
proto_is_dgram(int proto)
{
- if (proto < 0 || proto >= PROTO_N)
- ASSERT(0);
- return proto_names[proto].is_dgram;
+ return proto_is_udp(proto);
}
+
bool
proto_is_udp(int proto)
{
if (proto < 0 || proto >= PROTO_N)
ASSERT(0);
- return proto_names[proto].is_dgram&&proto_names[proto].is_net;
+ return proto == PROTO_UDP;
}
+
bool
proto_is_tcp(int proto)
{
if (proto < 0 || proto >= PROTO_N)
ASSERT(0);
- return (!proto_names[proto].is_dgram)&&proto_names[proto].is_net;
-}
-
-unsigned short
-proto_sa_family(int proto)
-{
- if (proto < 0 || proto >= PROTO_N)
- ASSERT(0);
- return proto_names[proto].proto_af;
+ return proto == PROTO_TCP_CLIENT || proto == PROTO_TCP_SERVER;
}
int
ascii2proto (const char* proto_name)
{
int i;
- ASSERT (PROTO_N == SIZE (proto_names));
- for (i = 0; i < PROTO_N; ++i)
+ for (i = 0; i < SIZE (proto_names); ++i)
if (!strcmp (proto_name, proto_names[i].short_form))
- return i;
+ return proto_names[i].proto;
return -1;
}
+sa_family_t
+ascii2af (const char* proto_name)
+{
+ int i;
+ for (i = 0; i < SIZE (proto_names); ++i)
+ if (!strcmp (proto_name, proto_names[i].short_form))
+ return proto_names[i].proto_af;
+ return 0;
+}
+
const char *
-proto2ascii (int proto, bool display_form)
+proto2ascii (int proto, sa_family_t af, bool display_form)
{
- ASSERT (PROTO_N == SIZE (proto_names));
- if (proto < 0 || proto >= PROTO_N)
- return "[unknown protocol]";
- else if (display_form)
- return proto_names[proto].display_form;
- else
- return proto_names[proto].short_form;
+ unsigned int i;
+ for (i = 0; i < SIZE (proto_names); ++i)
+ {
+ if(proto_names[i].proto_af == af && proto_names[i].proto == proto)
+ {
+ if(display_form)
+ return proto_names[i].display_form;
+ else
+ return proto_names[i].short_form;
+ }
+ }
+
+ return "[unknown protocol]";
}
const char *
@@ -2535,40 +2763,15 @@ proto2ascii_all (struct gc_arena *gc)
struct buffer out = alloc_buf_gc (256, gc);
int i;
- ASSERT (PROTO_N == SIZE (proto_names));
- for (i = 0; i < PROTO_N; ++i)
+ for (i = 0; i < SIZE (proto_names); ++i)
{
if (i)
buf_printf(&out, " ");
- buf_printf(&out, "[%s]", proto2ascii(i, false));
+ buf_printf(&out, "[%s]", proto_names[i].short_form);
}
return BSTR (&out);
}
-int
-addr_guess_family(int proto, const char *name)
-{
- unsigned short ret;
- if (proto)
- {
- return proto_sa_family(proto); /* already stamped */
- }
- else
- {
- struct addrinfo hints , *ai;
- int err;
- CLEAR(hints);
- hints.ai_flags = AI_NUMERICHOST;
- err = getaddrinfo(name, NULL, &hints, &ai);
- if ( 0 == err )
- {
- ret=ai->ai_family;
- freeaddrinfo(ai);
- return ret;
- }
- }
- return AF_INET; /* default */
-}
const char *
addr_family_name (int af)
{
@@ -2592,31 +2795,22 @@ addr_family_name (int af)
* has always sent UDPv4, TCPv4 over the wire. Keep these
* strings for backward compatbility
*/
-int
+const char*
proto_remote (int proto, bool remote)
{
ASSERT (proto >= 0 && proto < PROTO_N);
- if (remote)
- {
- switch (proto)
- {
- case PROTO_TCPv4_SERVER: return PROTO_TCPv4_CLIENT;
- case PROTO_TCPv4_CLIENT: return PROTO_TCPv4_SERVER;
- case PROTO_TCPv6_SERVER: return PROTO_TCPv4_CLIENT;
- case PROTO_TCPv6_CLIENT: return PROTO_TCPv4_SERVER;
- case PROTO_UDPv6: return PROTO_UDPv4;
- }
- }
- else
- {
- switch (proto)
- {
- case PROTO_TCPv6_SERVER: return PROTO_TCPv4_SERVER;
- case PROTO_TCPv6_CLIENT: return PROTO_TCPv4_CLIENT;
- case PROTO_UDPv6: return PROTO_UDPv4;
- }
- }
- return proto;
+ if (proto == PROTO_UDP)
+ return "UDPv4";
+
+ if ( (remote && proto == PROTO_TCP_CLIENT) ||
+ (!remote && proto == PROTO_TCP_SERVER))
+ return "TCPv4_SERVER";
+ if ( (remote && proto == PROTO_TCP_SERVER) ||
+ (!remote && proto == PROTO_TCP_CLIENT))
+ return "TCPv4_CLIENT";
+
+ ASSERT (0);
+ return ""; /* Make the compiler happy */
}
/*
@@ -2643,7 +2837,7 @@ link_socket_read_tcp (struct link_socket *sock,
if (!sock->stream_buf.residual_fully_formed)
{
-#ifdef WIN32
+#ifdef _WIN32
len = socket_finalize (sock->sd, &sock->reads, buf, NULL);
#else
struct buffer frag;
@@ -2668,51 +2862,39 @@ link_socket_read_tcp (struct link_socket *sock,
return buf->len = 0; /* no error, but packet is still incomplete */
}
-#ifndef WIN32
+#ifndef _WIN32
#if ENABLE_IP_PKTINFO
-#pragma pack(1) /* needed to keep structure size consistent for 32 vs. 64-bit architectures */
-struct openvpn_in4_pktinfo
-{
- struct cmsghdr cmsghdr;
-#ifdef HAVE_IN_PKTINFO
- struct in_pktinfo pi4;
-#elif defined(IP_RECVDSTADDR)
- struct in_addr pi4;
+/* make the buffer large enough to handle ancilliary socket data for
+ * both IPv4 and IPv6 destination addresses, plus padding (see RFC 2292)
+ */
+#if defined(HAVE_IN_PKTINFO) && defined(HAVE_IPI_SPEC_DST)
+#define PKTINFO_BUF_SIZE max_int( CMSG_SPACE(sizeof (struct in6_pktinfo)), \
+ CMSG_SPACE(sizeof (struct in_pktinfo)) )
+#else
+#define PKTINFO_BUF_SIZE max_int( CMSG_SPACE(sizeof (struct in6_pktinfo)), \
+ CMSG_SPACE(sizeof (struct in_addr)) )
#endif
-};
-struct openvpn_in6_pktinfo
-{
- struct cmsghdr cmsghdr;
- struct in6_pktinfo pi6;
-};
-
-union openvpn_pktinfo {
- struct openvpn_in4_pktinfo msgpi4;
- struct openvpn_in6_pktinfo msgpi6;
-};
-#pragma pack()
static socklen_t
link_socket_read_udp_posix_recvmsg (struct link_socket *sock,
struct buffer *buf,
- int maxsize,
struct link_socket_actual *from)
{
struct iovec iov;
- union openvpn_pktinfo opi;
+ uint8_t pktinfo_buf[PKTINFO_BUF_SIZE];
struct msghdr mesg;
socklen_t fromlen = sizeof (from->dest.addr);
iov.iov_base = BPTR (buf);
- iov.iov_len = maxsize;
+ iov.iov_len = buf_forward_capacity_total (buf);
mesg.msg_iov = &iov;
mesg.msg_iovlen = 1;
mesg.msg_name = &from->dest.addr;
mesg.msg_namelen = fromlen;
- mesg.msg_control = &opi;
- mesg.msg_controllen = sizeof opi;
+ mesg.msg_control = pktinfo_buf;
+ mesg.msg_controllen = sizeof pktinfo_buf;
buf->len = recvmsg (sock->sd, &mesg, 0);
if (buf->len >= 0)
{
@@ -2721,18 +2903,19 @@ link_socket_read_udp_posix_recvmsg (struct link_socket *sock,
cmsg = CMSG_FIRSTHDR (&mesg);
if (cmsg != NULL
&& CMSG_NXTHDR (&mesg, cmsg) == NULL
-#ifdef IP_PKTINFO
+#if defined(HAVE_IN_PKTINFO) && defined(HAVE_IPI_SPEC_DST)
&& cmsg->cmsg_level == SOL_IP
&& cmsg->cmsg_type == IP_PKTINFO
+ && cmsg->cmsg_len >= CMSG_LEN(sizeof(struct in_pktinfo)) )
#elif defined(IP_RECVDSTADDR)
&& cmsg->cmsg_level == IPPROTO_IP
&& cmsg->cmsg_type == IP_RECVDSTADDR
+ && cmsg->cmsg_len >= CMSG_LEN(sizeof(struct in_addr)) )
#else
#error ENABLE_IP_PKTINFO is set without IP_PKTINFO xor IP_RECVDSTADDR (fix syshead.h)
#endif
- && cmsg->cmsg_len >= sizeof (struct openvpn_in4_pktinfo))
{
-#ifdef IP_PKTINFO
+#if defined(HAVE_IN_PKTINFO) && defined(HAVE_IPI_SPEC_DST)
struct in_pktinfo *pkti = (struct in_pktinfo *) CMSG_DATA (cmsg);
from->pi.in4.ipi_ifindex = pkti->ipi_ifindex;
from->pi.in4.ipi_spec_dst = pkti->ipi_spec_dst;
@@ -2746,13 +2929,18 @@ link_socket_read_udp_posix_recvmsg (struct link_socket *sock,
&& CMSG_NXTHDR (&mesg, cmsg) == NULL
&& cmsg->cmsg_level == IPPROTO_IPV6
&& cmsg->cmsg_type == IPV6_PKTINFO
- && cmsg->cmsg_len >= sizeof (struct openvpn_in6_pktinfo))
+ && cmsg->cmsg_len >= CMSG_LEN(sizeof(struct in6_pktinfo)) )
{
struct in6_pktinfo *pkti6 = (struct in6_pktinfo *) CMSG_DATA (cmsg);
from->pi.in6.ipi6_ifindex = pkti6->ipi6_ifindex;
from->pi.in6.ipi6_addr = pkti6->ipi6_addr;
}
+ else if (cmsg != NULL)
+ {
+ msg(M_WARN, "CMSG received that cannot be parsed (cmsg_level=%d, cmsg_type=%d, cmsg=len=%d)", (int)cmsg->cmsg_level, (int)cmsg->cmsg_type, (int)cmsg->cmsg_len );
+ }
}
+
return fromlen;
}
#endif
@@ -2760,21 +2948,20 @@ link_socket_read_udp_posix_recvmsg (struct link_socket *sock,
int
link_socket_read_udp_posix (struct link_socket *sock,
struct buffer *buf,
- int maxsize,
struct link_socket_actual *from)
{
socklen_t fromlen = sizeof (from->dest.addr);
- socklen_t expectedlen = af_addr_size(proto_sa_family(sock->info.proto));
+ socklen_t expectedlen = af_addr_size(sock->info.af);
addr_zero_host(&from->dest);
- ASSERT (buf_safe (buf, maxsize));
#if ENABLE_IP_PKTINFO
/* Both PROTO_UDPv4 and PROTO_UDPv6 */
- if (proto_is_udp(sock->info.proto) && sock->sockflags & SF_USE_IP_PKTINFO)
- fromlen = link_socket_read_udp_posix_recvmsg (sock, buf, maxsize, from);
+ if (sock->info.proto == PROTO_UDP && sock->sockflags & SF_USE_IP_PKTINFO)
+ fromlen = link_socket_read_udp_posix_recvmsg (sock, buf, from);
else
#endif
- buf->len = recvfrom (sock->sd, BPTR (buf), maxsize, 0,
+ buf->len = recvfrom (sock->sd, BPTR (buf), buf_forward_capacity(buf), 0,
&from->dest.addr.sa, &fromlen);
+ /* FIXME: won't do anything when sock->info.af == AF_UNSPEC */
if (buf->len >= 0 && expectedlen && fromlen != expectedlen)
bad_address_length (fromlen, expectedlen);
return buf->len;
@@ -2796,7 +2983,7 @@ link_socket_write_tcp (struct link_socket *sock,
ASSERT (len <= sock->stream_buf.maxlen);
len = htonps (len);
ASSERT (buf_write_prepend (buf, &len, sizeof (len)));
-#ifdef WIN32
+#ifdef _WIN32
return link_socket_write_win32 (sock, buf, to);
#else
return link_socket_write_tcp_posix (sock, buf, to);
@@ -2805,7 +2992,7 @@ link_socket_write_tcp (struct link_socket *sock,
#if ENABLE_IP_PKTINFO
-int
+size_t
link_socket_write_udp_posix_sendmsg (struct link_socket *sock,
struct buffer *buf,
struct link_socket_actual *to)
@@ -2813,24 +3000,24 @@ link_socket_write_udp_posix_sendmsg (struct link_socket *sock,
struct iovec iov;
struct msghdr mesg;
struct cmsghdr *cmsg;
- union openvpn_pktinfo opi;
+ uint8_t pktinfo_buf[PKTINFO_BUF_SIZE];
iov.iov_base = BPTR (buf);
iov.iov_len = BLEN (buf);
mesg.msg_iov = &iov;
mesg.msg_iovlen = 1;
- switch (sock->info.lsa->remote.addr.sa.sa_family)
+ switch (to->dest.addr.sa.sa_family)
{
case AF_INET:
{
mesg.msg_name = &to->dest.addr.sa;
mesg.msg_namelen = sizeof (struct sockaddr_in);
- mesg.msg_control = &opi;
+ mesg.msg_control = pktinfo_buf;
mesg.msg_flags = 0;
-#ifdef HAVE_IN_PKTINFO
- mesg.msg_controllen = sizeof (struct openvpn_in4_pktinfo);
+#if defined(HAVE_IN_PKTINFO) && defined(HAVE_IPI_SPEC_DST)
+ mesg.msg_controllen = CMSG_SPACE(sizeof (struct in_pktinfo));
cmsg = CMSG_FIRSTHDR (&mesg);
- cmsg->cmsg_len = sizeof (struct openvpn_in4_pktinfo);
+ cmsg->cmsg_len = CMSG_LEN(sizeof (struct in_pktinfo));
cmsg->cmsg_level = SOL_IP;
cmsg->cmsg_type = IP_PKTINFO;
{
@@ -2841,7 +3028,7 @@ link_socket_write_udp_posix_sendmsg (struct link_socket *sock,
pkti->ipi_addr.s_addr = 0;
}
#elif defined(IP_RECVDSTADDR)
- ASSERT( CMSG_SPACE(sizeof (struct in_addr)) <= sizeof(opi) );
+ ASSERT( CMSG_SPACE(sizeof (struct in_addr)) <= sizeof(pktinfo_buf) );
mesg.msg_controllen = CMSG_SPACE(sizeof (struct in_addr));
cmsg = CMSG_FIRSTHDR (&mesg);
cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_addr));
@@ -2858,13 +3045,16 @@ link_socket_write_udp_posix_sendmsg (struct link_socket *sock,
struct in6_pktinfo *pkti6;
mesg.msg_name = &to->dest.addr.sa;
mesg.msg_namelen = sizeof (struct sockaddr_in6);
- mesg.msg_control = &opi;
- mesg.msg_controllen = sizeof (struct openvpn_in6_pktinfo);
+
+ ASSERT( CMSG_SPACE(sizeof (struct in6_pktinfo)) <= sizeof(pktinfo_buf) );
+ mesg.msg_control = pktinfo_buf;
+ mesg.msg_controllen = CMSG_SPACE(sizeof (struct in6_pktinfo));
mesg.msg_flags = 0;
cmsg = CMSG_FIRSTHDR (&mesg);
- cmsg->cmsg_len = sizeof (struct openvpn_in6_pktinfo);
+ cmsg->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));
cmsg->cmsg_level = IPPROTO_IPV6;
cmsg->cmsg_type = IPV6_PKTINFO;
+
pkti6 = (struct in6_pktinfo *) CMSG_DATA (cmsg);
pkti6->ipi6_ifindex = to->pi.in6.ipi6_ifindex;
pkti6->ipi6_addr = to->pi.in6.ipi6_addr;
@@ -2881,7 +3071,7 @@ link_socket_write_udp_posix_sendmsg (struct link_socket *sock,
* Win32 overlapped socket I/O functions.
*/
-#ifdef WIN32
+#ifdef _WIN32
int
socket_recv_queue (struct link_socket *sock, int maxsize)
@@ -2919,10 +3109,7 @@ socket_recv_queue (struct link_socket *sock, int maxsize)
if (proto_is_udp(sock->info.proto))
{
sock->reads.addr_defined = true;
- if (sock->info.proto == PROTO_UDPv6)
- sock->reads.addrlen = sizeof (sock->reads.addr6);
- else
- sock->reads.addrlen = sizeof (sock->reads.addr);
+ sock->reads.addrlen = sizeof (sock->reads.addr6);
status = WSARecvFrom(
sock->sd,
wsabuf,
@@ -2954,9 +3141,10 @@ socket_recv_queue (struct link_socket *sock, int maxsize)
if (!status) /* operation completed immediately? */
{
- int addrlen = af_addr_size(sock->info.lsa->local.addr.sa.sa_family);
- if (sock->reads.addr_defined && sock->reads.addrlen != addrlen)
- bad_address_length (sock->reads.addrlen, addrlen);
+ /* FIXME: won't do anything when sock->info.af == AF_UNSPEC */
+ int af_len = af_addr_size (sock->info.af);
+ if (sock->reads.addr_defined && af_len && sock->reads.addrlen != af_len)
+ bad_address_length (sock->reads.addrlen, af_len);
sock->reads.iostate = IOSTATE_IMMEDIATE_RETURN;
/* since we got an immediate return, we must signal the event object ourselves */
@@ -3018,7 +3206,7 @@ socket_send_queue (struct link_socket *sock, struct buffer *buf, const struct li
{
/* set destination address for UDP writes */
sock->writes.addr_defined = true;
- if (sock->info.proto == PROTO_UDPv6)
+ if (to->dest.addr.sa.sa_family == AF_INET6)
{
sock->writes.addr6 = to->dest.addr.in6;
sock->writes.addrlen = sizeof (sock->writes.addr6);
@@ -3191,7 +3379,7 @@ socket_finalize (SOCKET s,
case sizeof(struct sockaddr_in):
case sizeof(struct sockaddr_in6):
/* TODO(jjo): for some reason (?) I'm getting 24,28 for AF_INET6
- * under WIN32*/
+ * under _WIN32*/
case sizeof(struct sockaddr_in6)-4:
break;
default:
@@ -3217,7 +3405,7 @@ socket_finalize (SOCKET s,
return ret;
}
-#endif /* WIN32 */
+#endif /* _WIN32 */
/*
* Socket event notification
@@ -3238,7 +3426,7 @@ socket_set (struct link_socket *s,
rwflags &= ~EVENT_READ;
}
-#ifdef WIN32
+#ifdef _WIN32
if (rwflags & EVENT_READ)
socket_recv_queue (s, 0);
#endif
diff --git a/src/openvpn/socket.h b/src/openvpn/socket.h
index b7a4e01..2a82d88 100644
--- a/src/openvpn/socket.h
+++ b/src/openvpn/socket.h
@@ -39,7 +39,7 @@
/*
* OpenVPN's default port number as assigned by IANA.
*/
-#define OPENVPN_PORT 1194
+#define OPENVPN_PORT "1194"
/*
* Number of seconds that "resolv-retry infinite"
@@ -72,14 +72,25 @@ struct openvpn_sockaddr
} addr;
};
+/* struct to hold preresolved host names */
+struct cached_dns_entry {
+ const char *hostname;
+ const char *servname;
+ int ai_family;
+ int flags;
+ struct addrinfo *ai;
+ struct cached_dns_entry *next;
+};
+
/* actual address of remote, based on source address of received packets */
struct link_socket_actual
{
/*int dummy;*/ /* add offset to force a bug if dest not explicitly dereferenced */
+
struct openvpn_sockaddr dest;
#if ENABLE_IP_PKTINFO
union {
-#ifdef HAVE_IN_PKTINFO
+#if defined(HAVE_IN_PKTINFO) && defined(HAVE_IPI_SPEC_DST)
struct in_pktinfo in4;
#elif defined(IP_RECVDSTADDR)
struct in_addr in4;
@@ -92,8 +103,10 @@ struct link_socket_actual
/* IP addresses which are persistant across SIGUSR1s */
struct link_socket_addr
{
- struct openvpn_sockaddr local;
- struct openvpn_sockaddr remote; /* initial remote */
+ struct addrinfo* bind_local;
+ struct addrinfo* remote_list; /* complete remote list */
+ struct addrinfo* current_remote; /* remote used in the
+ current connection attempt */
struct link_socket_actual actual; /* reply to this address */
};
@@ -105,6 +118,8 @@ struct link_socket_info
const struct plugin_list *plugins;
bool remote_float;
int proto; /* Protocol (PROTO_x defined below) */
+ sa_family_t af; /* Address family like AF_INET, AF_INET6 or AF_UNSPEC*/
+ bool bind_ipv6_only;
int mtu_changed; /* Set to true when mtu value is changed */
};
@@ -152,12 +167,9 @@ struct link_socket
struct link_socket_info info;
socket_descriptor_t sd;
-
-#ifdef ENABLE_SOCKS
socket_descriptor_t ctrl_sd; /* only used for UDP over Socks */
-#endif
-#ifdef WIN32
+#ifdef _WIN32
struct overlapped_io reads;
struct overlapped_io writes;
struct rw_handle rw_handle;
@@ -170,13 +182,11 @@ struct link_socket
/* used for long-term queueing of pre-accepted socket listen */
bool listen_persistent_queued;
- /* Does config file contain any <connection> ... </connection> blocks? */
- bool connection_profiles_defined;
-
const char *remote_host;
- int remote_port;
+ const char *remote_port;
const char *local_host;
- int local_port;
+ const char *local_port;
+ struct cached_dns_entry *dns_cache;
bool bind_local;
# define INETD_NONE 0
@@ -190,45 +200,39 @@ struct link_socket
int mode;
int resolve_retry_seconds;
- int connect_retry_seconds;
- int connect_timeout;
- int connect_retry_max;
int mtu_discover_type;
struct socket_buffer_size socket_buffer_sizes;
int mtu; /* OS discovered MTU, or 0 if unknown */
- bool did_resolve_remote;
-
# define SF_USE_IP_PKTINFO (1<<0)
# define SF_TCP_NODELAY (1<<1)
# define SF_PORT_SHARE (1<<2)
# define SF_HOST_RANDOMIZE (1<<3)
# define SF_GETADDRINFO_DGRAM (1<<4)
unsigned int sockflags;
+ int mark;
/* for stream sockets */
struct stream_buf stream_buf;
struct buffer stream_buf_data;
bool stream_reset;
-#ifdef ENABLE_HTTP_PROXY
/* HTTP proxy */
struct http_proxy_info *http_proxy;
-#endif
-#ifdef ENABLE_SOCKS
/* Socks proxy */
struct socks_proxy_info *socks_proxy;
struct link_socket_actual socks_relay; /* Socks UDP relay address */
-#endif
-#if defined(ENABLE_HTTP_PROXY) || defined(ENABLE_SOCKS)
/* The OpenVPN server we will use the proxy to connect to */
const char *proxy_dest_host;
- int proxy_dest_port;
-#endif
+ const char *proxy_dest_port;
+
+ /* Pointer to the server-poll to trigger the timeout in function which have
+ * their own loop instead of using the main oop */
+ struct event_timeout* server_poll_timeout;
#if PASSTOS_CAPABILITY
/* used to get/set TOS. */
@@ -253,7 +257,7 @@ struct link_socket
#define MSG_NOSIGNAL 0
#endif
-#ifdef WIN32
+#ifdef _WIN32
#define openvpn_close_socket(s) closesocket(s)
@@ -278,34 +282,36 @@ int socket_finalize (
struct link_socket *link_socket_new (void);
void socket_bind (socket_descriptor_t sd,
- struct openvpn_sockaddr *local,
- const char *prefix);
+ struct addrinfo *local,
+ int af_family,
+ const char *prefix,
+ bool ipv6only);
int openvpn_connect (socket_descriptor_t sd,
- struct openvpn_sockaddr *remote,
+ const struct sockaddr *remote,
int connect_timeout,
volatile int *signal_received);
+
+
/*
* Initialize link_socket object.
*/
void
link_socket_init_phase1 (struct link_socket *sock,
- const bool connection_profiles_defined,
const char *local_host,
- int local_port,
+ const char *local_port,
const char *remote_host,
- int remote_port,
+ const char *remote_port,
+ struct cached_dns_entry *dns_cache,
int proto,
+ sa_family_t af,
+ bool bind_ipv6_only,
int mode,
const struct link_socket *accept_from,
-#ifdef ENABLE_HTTP_PROXY
struct http_proxy_info *http_proxy,
-#endif
-#ifdef ENABLE_SOCKS
struct socks_proxy_info *socks_proxy,
-#endif
#ifdef ENABLE_DEBUG
int gremlin,
#endif
@@ -316,18 +322,18 @@ link_socket_init_phase1 (struct link_socket *sock,
const char *ipchange_command,
const struct plugin_list *plugins,
int resolve_retry_seconds,
- int connect_retry_seconds,
- int connect_timeout,
- int connect_retry_max,
int mtu_discover_type,
int rcvbuf,
int sndbuf,
int mark,
+ struct event_timeout* server_poll_timeout,
unsigned int sockflags);
void link_socket_init_phase2 (struct link_socket *sock,
const struct frame *frame,
- volatile int *signal_received);
+ struct signal_info *sig_info);
+
+void do_preresolve(struct context *c);
void socket_adjust_frame_parameters (struct frame *frame, int proto);
@@ -341,15 +347,37 @@ void sd_close (socket_descriptor_t *sd);
#define PS_SHOW_PORT (1<<1)
#define PS_SHOW_PKTINFO (1<<2)
#define PS_DONT_SHOW_ADDR (1<<3)
+#define PS_DONT_SHOW_FAMILY (1<<4)
-const char *print_sockaddr_ex (const struct openvpn_sockaddr *addr,
+const char *print_sockaddr_ex (const struct sockaddr *addr,
const char* separator,
const unsigned int flags,
struct gc_arena *gc);
+static inline
+const char *print_openvpn_sockaddr_ex (const struct openvpn_sockaddr *addr,
+ const char* separator,
+ const unsigned int flags,
+ struct gc_arena *gc)
+{
+ return print_sockaddr_ex(&addr->addr.sa, separator, flags, gc);
+}
+
+static inline
+const char *print_openvpn_sockaddr (const struct openvpn_sockaddr *addr,
+ struct gc_arena *gc)
+{
+ return print_sockaddr_ex (&addr->addr.sa, ":", PS_SHOW_PORT, gc);
+}
+
+static inline
+const char *print_sockaddr (const struct sockaddr *addr,
+ struct gc_arena *gc)
+{
+ return print_sockaddr_ex (addr, ":", PS_SHOW_PORT, gc);
+}
+
-const char *print_sockaddr (const struct openvpn_sockaddr *addr,
- struct gc_arena *gc);
const char *print_link_socket_actual_ex (const struct link_socket_actual *act,
const char* separator,
@@ -395,6 +423,8 @@ void bad_address_length (int actual, int expected);
*/
#define IPV4_INVALID_ADDR 0xffffffff
in_addr_t link_socket_current_remote (const struct link_socket_info *info);
+const struct in6_addr * link_socket_current_remote_ipv6
+ (const struct link_socket_info *info);
void link_socket_connection_initiated (const struct buffer *buf,
struct link_socket_info *info,
@@ -406,6 +436,9 @@ void link_socket_bad_incoming_addr (struct buffer *buf,
const struct link_socket_info *info,
const struct link_socket_actual *from_addr);
+void set_actual_address (struct link_socket_actual* actual,
+ struct addrinfo* ai);
+
void link_socket_bad_outgoing_addr (void);
void setenv_trusted (struct env_set *es, const struct link_socket_info *info);
@@ -429,7 +462,7 @@ bool ip_or_dns_addr_safe (const char *addr, const bool allow_fqdn);
bool mac_addr_safe (const char *mac_addr);
bool ipv6_addr_safe (const char *ipv6_text_addr);
-socket_descriptor_t create_socket_tcp (int af);
+socket_descriptor_t create_socket_tcp (struct addrinfo*);
socket_descriptor_t socket_do_accept (socket_descriptor_t sd,
struct link_socket_actual *act,
@@ -481,6 +514,10 @@ bool unix_socket_get_peer_uid_gid (const socket_descriptor_t sd, int *uid, int *
#define GETADDR_TRY_ONCE (1<<7)
#define GETADDR_UPDATE_MANAGEMENT_STATE (1<<8)
#define GETADDR_RANDOMIZE (1<<9)
+#define GETADDR_PASSIVE (1<<10)
+#define GETADDR_DATAGRAM (1<<11)
+
+#define GETADDR_CACHE_MASK (GETADDR_DATAGRAM|GETADDR_PASSIVE)
in_addr_t getaddr (unsigned int flags,
const char *hostname,
@@ -490,6 +527,7 @@ in_addr_t getaddr (unsigned int flags,
int openvpn_getaddrinfo (unsigned int flags,
const char *hostname,
+ const char *servname,
int resolve_retry_seconds,
volatile int *signal_received,
int ai_family,
@@ -505,21 +543,18 @@ int openvpn_getaddrinfo (unsigned int flags,
*/
enum proto_num {
PROTO_NONE, /* catch for uninitialized */
- PROTO_UDPv4,
- PROTO_TCPv4_SERVER,
- PROTO_TCPv4_CLIENT,
- PROTO_TCPv4,
- PROTO_UDPv6,
- PROTO_TCPv6_SERVER,
- PROTO_TCPv6_CLIENT,
- PROTO_TCPv6,
+ PROTO_UDP,
+ PROTO_TCP,
+ PROTO_TCP_SERVER,
+ PROTO_TCP_CLIENT,
PROTO_N
};
int ascii2proto (const char* proto_name);
-const char *proto2ascii (int proto, bool display_form);
+sa_family_t ascii2af (const char* proto_name);
+const char *proto2ascii (int proto, sa_family_t af, bool display_form);
const char *proto2ascii_all (struct gc_arena *gc);
-int proto_remote (int proto, bool remote);
+const char *proto_remote (int proto, bool remote);
const char *addr_family_name(int af);
/*
@@ -544,12 +579,6 @@ datagram_overhead (int proto)
*/
static inline bool
-legal_ipv4_port (int port)
-{
- return port > 0 && port < 65536;
-}
-
-static inline bool
link_socket_proto_connection_oriented (int proto)
{
return !proto_is_dgram(proto);
@@ -574,13 +603,30 @@ addr_defined (const struct openvpn_sockaddr *addr)
default: return 0;
}
}
+
+static inline bool
+addr_local (const struct sockaddr *addr)
+{
+ if (!addr)
+ return false;
+ switch (addr->sa_family) {
+ case AF_INET:
+ return ((const struct sockaddr_in*)addr)->sin_addr.s_addr == htonl(INADDR_LOOPBACK);
+ case AF_INET6:
+ return IN6_IS_ADDR_LOOPBACK(&((const struct sockaddr_in6*)addr)->sin6_addr);
+ default:
+ return false;
+ }
+}
+
+
static inline bool
addr_defined_ipi (const struct link_socket_actual *lsa)
{
#if ENABLE_IP_PKTINFO
if (!lsa) return 0;
switch (lsa->dest.addr.sa.sa_family) {
-#ifdef HAVE_IN_PKTINFO
+#if defined(HAVE_IN_PKTINFO) && defined(HAVE_IPI_SPEC_DST)
case AF_INET: return lsa->pi.in4.ipi_spec_dst.s_addr != 0;
#elif defined(IP_RECVDSTADDR)
case AF_INET: return lsa->pi.in4.s_addr != 0;
@@ -613,6 +659,29 @@ addr_match (const struct openvpn_sockaddr *a1, const struct openvpn_sockaddr *a2
return false;
}
+static inline bool
+addrlist_match (const struct openvpn_sockaddr *a1, const struct addrinfo *addrlist)
+{
+ const struct addrinfo *curele;
+ for (curele = addrlist; curele; curele=curele->ai_next)
+ {
+ switch(a1->addr.sa.sa_family)
+ {
+ case AF_INET:
+ if (a1->addr.in4.sin_addr.s_addr == ((struct sockaddr_in*)curele->ai_addr)->sin_addr.s_addr)
+ return true;
+ break;
+ case AF_INET6:
+ if (IN6_ARE_ADDR_EQUAL(&a1->addr.in6.sin6_addr, &((struct sockaddr_in6*) curele->ai_addr)->sin6_addr))
+ return true;
+ break;
+ default:
+ ASSERT(0);
+ }
+ }
+ return false;
+}
+
static inline in_addr_t
addr_host (const struct openvpn_sockaddr *addr)
{
@@ -626,6 +695,36 @@ addr_host (const struct openvpn_sockaddr *addr)
return ntohl (addr->addr.in4.sin_addr.s_addr);
}
+
+static inline bool
+addrlist_port_match (const struct openvpn_sockaddr *a1, const struct addrinfo *a2)
+{
+ const struct addrinfo *curele;
+ for(curele=a2;curele;curele = curele->ai_next)
+ {
+ switch(a1->addr.sa.sa_family)
+ {
+ case AF_INET:
+ if (curele->ai_family == AF_INET
+ && a1->addr.in4.sin_addr.s_addr == ((struct sockaddr_in*)curele->ai_addr)->sin_addr.s_addr
+ && a1->addr.in4.sin_port == ((struct sockaddr_in*)curele->ai_addr)->sin_port)
+ return true;
+ break;
+ case AF_INET6:
+ if (curele->ai_family == AF_INET6
+ && IN6_ARE_ADDR_EQUAL(&a1->addr.in6.sin6_addr, &((struct sockaddr_in6*) curele->ai_addr)->sin6_addr)
+ && a1->addr.in6.sin6_port == ((struct sockaddr_in6*) curele->ai_addr)->sin6_port)
+ return true;
+ break;
+ default:
+ ASSERT(0);
+ }
+ }
+ return false;
+}
+
+
+
static inline bool
addr_port_match (const struct openvpn_sockaddr *a1, const struct openvpn_sockaddr *a2)
{
@@ -634,7 +733,7 @@ addr_port_match (const struct openvpn_sockaddr *a1, const struct openvpn_sockadd
return a1->addr.in4.sin_addr.s_addr == a2->addr.in4.sin_addr.s_addr
&& a1->addr.in4.sin_port == a2->addr.in4.sin_port;
case AF_INET6:
- return IN6_ARE_ADDR_EQUAL(&a1->addr.in6.sin6_addr, &a2->addr.in6.sin6_addr)
+ return IN6_ARE_ADDR_EQUAL(&a1->addr.in6.sin6_addr, &a2->addr.in6.sin6_addr)
&& a1->addr.in6.sin6_port == a2->addr.in6.sin6_port;
}
ASSERT(0);
@@ -651,6 +750,17 @@ addr_match_proto (const struct openvpn_sockaddr *a1,
: addr_port_match (a1, a2);
}
+
+static inline bool
+addrlist_match_proto (const struct openvpn_sockaddr *a1,
+ struct addrinfo *addr_list,
+ const int proto)
+{
+ return link_socket_proto_connection_oriented (proto)
+ ? addrlist_match (a1, addr_list)
+ : addrlist_port_match (a1, addr_list);
+}
+
static inline void
addr_zero_host(struct openvpn_sockaddr *addr)
{
@@ -670,28 +780,15 @@ addr_copy_sa(struct openvpn_sockaddr *dst, const struct openvpn_sockaddr *src)
dst->addr = src->addr;
}
-static inline void
-addr_copy_host(struct openvpn_sockaddr *dst, const struct openvpn_sockaddr *src)
-{
- switch(src->addr.sa.sa_family) {
- case AF_INET:
- dst->addr.in4.sin_addr.s_addr = src->addr.in4.sin_addr.s_addr;
- break;
- case AF_INET6:
- dst->addr.in6.sin6_addr = src->addr.in6.sin6_addr;
- break;
- }
-}
-
static inline bool
addr_inet4or6(struct sockaddr *addr)
{
return addr->sa_family == AF_INET || addr->sa_family == AF_INET6;
}
-int addr_guess_family(int proto, const char *name);
+int addr_guess_family(sa_family_t af,const char *name);
static inline int
-af_addr_size(unsigned short af)
+af_addr_size(sa_family_t af)
{
switch(af) {
case AF_INET: return sizeof (struct sockaddr_in);
@@ -745,7 +842,7 @@ socket_connection_reset (const struct link_socket *sock, int status)
else if (status < 0)
{
const int err = openvpn_errno ();
-#ifdef WIN32
+#ifdef _WIN32
return err == WSAECONNRESET || err == WSAECONNABORTED;
#else
return err == ECONNRESET;
@@ -767,9 +864,9 @@ link_socket_verify_incoming_addr (struct buffer *buf,
case AF_INET:
if (!link_socket_actual_defined (from_addr))
return false;
- if (info->remote_float || !addr_defined (&info->lsa->remote))
+ if (info->remote_float || (!info->lsa->remote_list))
return true;
- if (addr_match_proto (&from_addr->dest, &info->lsa->remote, info->proto))
+ if (addrlist_match_proto (&from_addr->dest, info->lsa->remote_list, info->proto))
return true;
}
}
@@ -806,13 +903,15 @@ link_socket_set_outgoing_addr (const struct buffer *buf,
{
struct link_socket_addr *lsa = info->lsa;
if (
- /* new or changed address? */
- (!info->connection_established
- || !addr_match_proto (&act->dest, &lsa->actual.dest, info->proto))
- /* address undef or address == remote or --float */
- && (info->remote_float
- || !addr_defined (&lsa->remote)
- || addr_match_proto (&act->dest, &lsa->remote, info->proto))
+ /* new or changed address? */
+ (!info->connection_established
+ || !addr_match_proto (&act->dest, &lsa->actual.dest, info->proto)
+ )
+ &&
+ /* address undef or address == remote or --float */
+ (info->remote_float ||
+ (!lsa->remote_list || addrlist_match_proto (&act->dest, lsa->remote_list, info->proto))
+ )
)
{
link_socket_connection_initiated (buf, info, act, common_name, es);
@@ -851,7 +950,7 @@ stream_buf_read_setup (struct link_socket* sock)
int link_socket_read_tcp (struct link_socket *sock,
struct buffer *buf);
-#ifdef WIN32
+#ifdef _WIN32
static inline int
link_socket_read_udp_win32 (struct link_socket *sock,
@@ -865,7 +964,6 @@ link_socket_read_udp_win32 (struct link_socket *sock,
int link_socket_read_udp_posix (struct link_socket *sock,
struct buffer *buf,
- int maxsize,
struct link_socket_actual *from);
#endif
@@ -874,17 +972,16 @@ int link_socket_read_udp_posix (struct link_socket *sock,
static inline int
link_socket_read (struct link_socket *sock,
struct buffer *buf,
- int maxsize,
struct link_socket_actual *from)
{
if (proto_is_udp(sock->info.proto)) /* unified UDPv4 and UDPv6 */
{
int res;
-#ifdef WIN32
+#ifdef _WIN32
res = link_socket_read_udp_win32 (sock, buf, from);
#else
- res = link_socket_read_udp_posix (sock, buf, maxsize, from);
+ res = link_socket_read_udp_posix (sock, buf, from);
#endif
return res;
}
@@ -909,7 +1006,7 @@ int link_socket_write_tcp (struct link_socket *sock,
struct buffer *buf,
struct link_socket_actual *to);
-#ifdef WIN32
+#ifdef _WIN32
static inline int
link_socket_write_win32 (struct link_socket *sock,
@@ -936,13 +1033,13 @@ link_socket_write_win32 (struct link_socket *sock,
#else
-static inline int
+static inline size_t
link_socket_write_udp_posix (struct link_socket *sock,
struct buffer *buf,
struct link_socket_actual *to)
{
#if ENABLE_IP_PKTINFO
- int link_socket_write_udp_posix_sendmsg (struct link_socket *sock,
+ size_t link_socket_write_udp_posix_sendmsg (struct link_socket *sock,
struct buffer *buf,
struct link_socket_actual *to);
@@ -956,7 +1053,7 @@ link_socket_write_udp_posix (struct link_socket *sock,
(socklen_t) af_addr_size(to->dest.addr.sa.sa_family));
}
-static inline int
+static inline size_t
link_socket_write_tcp_posix (struct link_socket *sock,
struct buffer *buf,
struct link_socket_actual *to)
@@ -966,12 +1063,12 @@ link_socket_write_tcp_posix (struct link_socket *sock,
#endif
-static inline int
+static inline size_t
link_socket_write_udp (struct link_socket *sock,
struct buffer *buf,
struct link_socket_actual *to)
{
-#ifdef WIN32
+#ifdef _WIN32
return link_socket_write_win32 (sock, buf, to);
#else
return link_socket_write_udp_posix (sock, buf, to);
@@ -1041,7 +1138,7 @@ socket_read_residual (const struct link_socket *s)
static inline event_t
socket_event_handle (const struct link_socket *s)
{
-#ifdef WIN32
+#ifdef _WIN32
return &s->rw_handle;
#else
return s->sd;
@@ -1072,7 +1169,7 @@ socket_set_listen_persistent (struct link_socket *s,
static inline void
socket_reset_listen_persistent (struct link_socket *s)
{
-#ifdef WIN32
+#ifdef _WIN32
reset_net_event_win32 (&s->listen_handle, s->sd);
#endif
}
diff --git a/src/openvpn/socks.c b/src/openvpn/socks.c
index 57dc02a..5a9ea6c 100644
--- a/src/openvpn/socks.c
+++ b/src/openvpn/socks.c
@@ -38,8 +38,6 @@
#include "syshead.h"
-#ifdef ENABLE_SOCKS
-
#include "common.h"
#include "misc.h"
#include "win32.h"
@@ -55,22 +53,21 @@
void
socks_adjust_frame_parameters (struct frame *frame, int proto)
{
- if (proto == PROTO_UDPv4)
+ if (proto == PROTO_UDP)
frame_add_to_extra_link (frame, 10);
}
struct socks_proxy_info *
socks_proxy_new (const char *server,
- int port,
- const char *authfile,
- bool retry)
+ const char *port,
+ const char *authfile)
{
struct socks_proxy_info *p;
ALLOC_OBJ_CLEAR (p, struct socks_proxy_info);
ASSERT (server);
- ASSERT (legal_ipv4_port (port));
+ ASSERT (port);
strncpynt (p->server, server, sizeof (p->server));
p->port = port;
@@ -80,7 +77,6 @@ socks_proxy_new (const char *server,
else
p->authfile[0] = 0;
- p->retry = retry;
p->defined = true;
return p;
@@ -404,11 +400,27 @@ recv_socks_reply (socket_descriptor_t sd,
return true;
}
+static int
+port_from_servname(const char* servname)
+{
+ int port =0;
+ port = atoi(servname);
+ if(port >0 && port < 65536)
+ return port;
+
+ struct servent* service;
+ service = getservbyname(servname, NULL);
+ if(service)
+ return service->s_port;
+
+ return 0;
+}
+
void
establish_socks_proxy_passthru (struct socks_proxy_info *p,
socket_descriptor_t sd, /* already open to proxy */
const char *host, /* openvpn server remote */
- const int port, /* openvpn server port */
+ const char *servname, /* openvpn server port */
volatile int *signal_received)
{
char buf[128];
@@ -429,6 +441,13 @@ establish_socks_proxy_passthru (struct socks_proxy_info *p,
buf[4] = (char) len;
memcpy(buf + 5, host, len);
+ int port = port_from_servname (servname);
+ if (port ==0)
+ {
+ msg (D_LINK_ERRORS, "establish_socks_proxy_passthrough: Cannot convert %s to port number", servname);
+ goto error;
+ }
+
buf[5 + len] = (char) (port >> 8);
buf[5 + len + 1] = (char) (port & 0xff);
@@ -441,6 +460,7 @@ establish_socks_proxy_passthru (struct socks_proxy_info *p,
}
}
+
/* receive reply from Socks proxy and discard */
if (!recv_socks_reply (sd, NULL, signal_received))
goto error;
@@ -448,9 +468,8 @@ establish_socks_proxy_passthru (struct socks_proxy_info *p,
return;
error:
- /* on error, should we exit or restart? */
if (!*signal_received)
- *signal_received = (p->retry ? SIGUSR1 : SIGTERM); /* SOFT-SIGUSR1 -- socks error */
+ *signal_received = SIGUSR1; /* SOFT-SIGUSR1 -- socks error */
return;
}
@@ -486,9 +505,8 @@ establish_socks_proxy_udpassoc (struct socks_proxy_info *p,
return;
error:
- /* on error, should we exit or restart? */
if (!*signal_received)
- *signal_received = (p->retry ? SIGUSR1 : SIGTERM); /* SOFT-SIGUSR1 -- socks error */
+ *signal_received = SIGUSR1; /* SOFT-SIGUSR1 -- socks error */
return;
}
@@ -553,7 +571,3 @@ socks_process_outgoing_udp (struct buffer *buf,
return 10;
}
-
-#else
-static void dummy(void) {}
-#endif /* ENABLE_SOCKS */
diff --git a/src/openvpn/socks.h b/src/openvpn/socks.h
index b55ff6f..a2843b9 100644
--- a/src/openvpn/socks.h
+++ b/src/openvpn/socks.h
@@ -30,8 +30,6 @@
#ifndef SOCKS_H
#define SOCKS_H
-#ifdef ENABLE_SOCKS
-
#include "buffer.h"
struct openvpn_sockaddr;
@@ -39,26 +37,24 @@ struct link_socket_actual;
struct socks_proxy_info {
bool defined;
- bool retry;
char server[128];
- int port;
+ const char *port;
char authfile[256];
};
void socks_adjust_frame_parameters (struct frame *frame, int proto);
struct socks_proxy_info *socks_proxy_new (const char *server,
- int port,
- const char *authfile,
- bool retry);
+ const char *port,
+ const char *authfile);
void socks_proxy_close (struct socks_proxy_info *sp);
void establish_socks_proxy_passthru (struct socks_proxy_info *p,
socket_descriptor_t sd, /* already open to proxy */
const char *host, /* openvpn server remote */
- const int port, /* openvpn server port */
+ const char *servname, /* openvpn server port */
volatile int *signal_received);
void establish_socks_proxy_udpassoc (struct socks_proxy_info *p,
@@ -74,4 +70,3 @@ int socks_process_outgoing_udp (struct buffer *buf,
const struct link_socket_actual *to);
#endif
-#endif
diff --git a/src/openvpn/ssl.c b/src/openvpn/ssl.c
index 9e31c3c..dc06350 100644
--- a/src/openvpn/ssl.c
+++ b/src/openvpn/ssl.c
@@ -35,7 +35,6 @@
* Both the TLS session and the data channel are multiplexed
* over the same TCP/UDP port.
*/
-
#ifdef HAVE_CONFIG_H
#include "config.h"
#elif defined(_MSC_VER)
@@ -45,11 +44,10 @@
#include "syshead.h"
#include "win32.h"
-#if defined(ENABLE_CRYPTO) && defined(ENABLE_SSL)
+#if defined(ENABLE_CRYPTO)
#include "error.h"
#include "common.h"
-#include "integer.h"
#include "socket.h"
#include "misc.h"
#include "fdmisc.h"
@@ -58,9 +56,8 @@
#include "status.h"
#include "gremlin.h"
#include "pkcs11.h"
-#include "list.h"
-#include "base64.h"
#include "route.h"
+#include "tls_crypt.h"
#include "ssl.h"
#include "ssl_verify.h"
@@ -150,6 +147,7 @@ static const tls_cipher_name_pair tls_cipher_name_translation_table[] = {
{"DHE-RSA-CAMELLIA128-SHA", "TLS-DHE-RSA-WITH-CAMELLIA-128-CBC-SHA"},
{"DHE-RSA-CAMELLIA256-SHA256", "TLS-DHE-RSA-WITH-CAMELLIA-256-CBC-SHA256"},
{"DHE-RSA-CAMELLIA256-SHA", "TLS-DHE-RSA-WITH-CAMELLIA-256-CBC-SHA"},
+ {"DHE-RSA-CHACHA20-POLY1305", "TLS-DHE-RSA-WITH-CHACHA20-POLY1305-SHA256"},
{"DHE-RSA-SEED-SHA", "TLS-DHE-RSA-WITH-SEED-CBC-SHA"},
{"DH-RSA-SEED-SHA", "TLS-DH-RSA-WITH-SEED-CBC-SHA"},
{"ECDH-ECDSA-AES128-GCM-SHA256", "TLS-ECDH-ECDSA-WITH-AES-128-GCM-SHA256"},
@@ -178,6 +176,7 @@ static const tls_cipher_name_pair tls_cipher_name_translation_table[] = {
{"ECDHE-ECDSA-CAMELLIA128-SHA", "TLS-ECDHE-ECDSA-WITH-CAMELLIA-128-CBC-SHA"},
{"ECDHE-ECDSA-CAMELLIA256-SHA256", "TLS-ECDHE-ECDSA-WITH-CAMELLIA-256-CBC-SHA256"},
{"ECDHE-ECDSA-CAMELLIA256-SHA", "TLS-ECDHE-ECDSA-WITH-CAMELLIA-256-CBC-SHA"},
+ {"ECDHE-ECDSA-CHACHA20-POLY1305", "TLS-ECDHE-ECDSA-WITH-CHACHA20-POLY1305-SHA256"},
{"ECDHE-ECDSA-DES-CBC3-SHA", "TLS-ECDHE-ECDSA-WITH-3DES-EDE-CBC-SHA"},
{"ECDHE-ECDSA-DES-CBC-SHA", "TLS-ECDHE-ECDSA-WITH-DES-CBC-SHA"},
{"ECDHE-ECDSA-RC4-SHA", "TLS-ECDHE-ECDSA-WITH-RC4-128-SHA"},
@@ -193,6 +192,7 @@ static const tls_cipher_name_pair tls_cipher_name_translation_table[] = {
{"ECDHE-RSA-CAMELLIA128-SHA", "TLS-ECDHE-RSA-WITH-CAMELLIA-128-CBC-SHA"},
{"ECDHE-RSA-CAMELLIA256-SHA256", "TLS-ECDHE-RSA-WITH-CAMELLIA-256-CBC-SHA256"},
{"ECDHE-RSA-CAMELLIA256-SHA", "TLS-ECDHE-RSA-WITH-CAMELLIA-256-CBC-SHA"},
+ {"ECDHE-RSA-CHACHA20-POLY1305", "TLS-ECDHE-RSA-WITH-CHACHA20-POLY1305-SHA256"},
{"ECDHE-RSA-DES-CBC3-SHA", "TLS-ECDHE-RSA-WITH-3DES-EDE-CBC-SHA"},
{"ECDHE-RSA-DES-CBC-SHA", "TLS-ECDHE-RSA-WITH-DES-CBC-SHA"},
{"ECDHE-RSA-RC4-SHA", "TLS-ECDHE-RSA-WITH-RC4-128-SHA"},
@@ -237,21 +237,37 @@ static const tls_cipher_name_pair tls_cipher_name_translation_table[] = {
{"SRP-RSA-AES-128-CBC-SHA", "TLS-SRP-SHA-RSA-WITH-AES-128-CBC-SHA"},
{"SRP-RSA-AES-256-CBC-SHA", "TLS-SRP-SHA-RSA-WITH-AES-256-CBC-SHA"},
#ifdef ENABLE_CRYPTO_OPENSSL
+ /* OpenSSL-specific group names */
{"DEFAULT", "DEFAULT"},
{"ALL", "ALL"},
- {"HIGH", "HIGH"},
- {"MEDIUM", "MEDIUM"},
- {"LOW", "LOW"},
- {"ECDH", "ECDH"},
- {"ECDSA", "ECDSA"},
- {"EDH", "EDH"},
- {"EXP", "EXP"},
- {"RSA", "RSA"},
- {"SRP", "SRP"},
+ {"HIGH", "HIGH"}, {"!HIGH", "!HIGH"},
+ {"MEDIUM", "MEDIUM"}, {"!MEDIUM", "!MEDIUM"},
+ {"LOW", "LOW"}, {"!LOW", "!LOW"},
+ {"ECDH", "ECDH"}, {"!ECDH", "!ECDH"},
+ {"ECDSA", "ECDSA"}, {"!ECDSA", "!ECDSA"},
+ {"EDH", "EDH"}, {"!EDH", "!EDH"},
+ {"EXP", "EXP"}, {"!EXP", "!EXP"},
+ {"RSA", "RSA"}, {"!RSA", "!RSA"},
+ {"kRSA", "kRSA"}, {"!kRSA", "!kRSA"},
+ {"SRP", "SRP"}, {"!SRP", "!SRP"},
#endif
{NULL, NULL}
};
+/**
+ * Update the implicit IV for a key_ctx_bi based on TLS session ids and cipher
+ * used.
+ *
+ * Note that the implicit IV is based on the HMAC key, but only in AEAD modes
+ * where the HMAC key is not used for an actual HMAC.
+ *
+ * @param ctx Encrypt/decrypt key context
+ * @param key HMAC key, used to calculate implicit IV
+ * @param key_len HMAC key length
+ */
+static void
+key_ctx_update_implicit_iv(struct key_ctx *ctx, uint8_t *key, size_t key_len);
+
const tls_cipher_name_pair *
tls_get_cipher_name_pair (const char * cipher_name, size_t len) {
const tls_cipher_name_pair * pair = tls_cipher_name_translation_table;
@@ -268,6 +284,27 @@ tls_get_cipher_name_pair (const char * cipher_name, size_t len) {
return NULL;
}
+/**
+ * Limit the reneg_bytes value when using a small-block (<128 bytes) cipher.
+ *
+ * @param cipher The current cipher (may be NULL).
+ * @param reneg_bytes Pointer to the current reneg_bytes, updated if needed.
+ * May *not* be NULL.
+ */
+static void
+tls_limit_reneg_bytes (const cipher_kt_t *cipher, int *reneg_bytes)
+{
+ if (cipher && (cipher_kt_block_size(cipher) < 128/8))
+ {
+ if (*reneg_bytes == -1) /* Not user-specified */
+ {
+ msg (M_WARN, "WARNING: cipher with small block size in use, "
+ "reducing reneg-bytes to 64MB to mitigate SWEET32 attacks.");
+ *reneg_bytes = 64 * 1024 * 1024;
+ }
+ }
+}
+
/*
* Max number of bytes we will add
* for data structures common to both
@@ -488,12 +525,15 @@ init_ssl (const struct options *options, struct tls_root_ctx *new_ctx)
if (options->tls_server)
{
- tls_ctx_server_new(new_ctx, options->ssl_flags);
- tls_ctx_load_dh_params(new_ctx, options->dh_file, options->dh_file_inline);
+ tls_ctx_server_new(new_ctx);
+
+ if (options->dh_file)
+ tls_ctx_load_dh_params(new_ctx, options->dh_file,
+ options->dh_file_inline);
}
else /* if client */
{
- tls_ctx_client_new(new_ctx, options->ssl_flags);
+ tls_ctx_client_new(new_ctx);
}
tls_ctx_set_options(new_ctx, options->ssl_flags);
@@ -522,10 +562,19 @@ init_ssl (const struct options *options, struct tls_root_ctx *new_ctx)
}
#endif
#ifdef MANAGMENT_EXTERNAL_KEY
- else if ((options->management_flags & MF_EXTERNAL_KEY) && options->cert_file)
- {
- tls_ctx_use_external_private_key(new_ctx, options->cert_file,
- options->cert_file_inline);
+ else if ((options->management_flags & MF_EXTERNAL_KEY) &&
+ (options->cert_file || options->management_flags & MF_EXTERNAL_CERT))
+ {
+ if (options->cert_file) {
+ tls_ctx_use_external_private_key(new_ctx, options->cert_file,
+ options->cert_file_inline);
+ } else {
+ char *external_certificate = management_query_cert(management,
+ options->management_certificate);
+ tls_ctx_use_external_private_key(new_ctx, INLINE_FILE_TAG,
+ external_certificate);
+ free(external_certificate);
+ }
}
#endif
else
@@ -552,7 +601,7 @@ init_ssl (const struct options *options, struct tls_root_ctx *new_ctx)
/* Load extra certificates that are part of our own certificate
chain but shouldn't be included in the verify chain */
- if (options->extra_certs_file || options->extra_certs_file_inline)
+ if (options->extra_certs_file)
{
tls_ctx_load_extra_certs(new_ctx, options->extra_certs_file, options->extra_certs_file_inline);
}
@@ -560,10 +609,20 @@ init_ssl (const struct options *options, struct tls_root_ctx *new_ctx)
/* Check certificate notBefore and notAfter */
tls_ctx_check_cert_time(new_ctx);
+ /* Read CRL */
+ if (options->crl_file && !(options->ssl_flags & SSLF_CRL_VERIFY_DIR))
+ {
+ tls_ctx_reload_crl(new_ctx, options->crl_file, options->crl_file_inline);
+ }
+
+ /* Once keys and cert are loaded, load ECDH parameters */
+ if (options->tls_server)
+ tls_ctx_load_ecdh_params(new_ctx, options->ecdh_curve);
+
/* Allowable ciphers */
tls_ctx_restrict_ciphers(new_ctx, options->cipher_list);
-#ifdef ENABLE_CRYPTO_POLARSSL
+#ifdef ENABLE_CRYPTO_MBEDTLS
/* Personalise the random by mixing in the certificate */
tls_ctx_personalise_random (new_ctx);
#endif
@@ -766,11 +825,17 @@ key_state_init (struct tls_session *session, struct key_state *ks)
reliable_set_timeout (ks->send_reliable, session->opt->packet_timeout);
/* init packet ID tracker */
- packet_id_init (&ks->packet_id,
- session->opt->tcp_mode,
- session->opt->replay_window,
- session->opt->replay_time,
- "SSL", ks->key_id);
+ if (session->opt->replay)
+ {
+ packet_id_init (&ks->crypto_options.packet_id,
+ session->opt->replay_window, session->opt->replay_time, "SSL",
+ ks->key_id);
+ }
+
+ ks->crypto_options.pid_persist = NULL;
+ ks->crypto_options.flags = session->opt->crypto_flags;
+ ks->crypto_options.flags &= session->opt->crypto_flags_and;
+ ks->crypto_options.flags |= session->opt->crypto_flags_or;
#ifdef MANAGEMENT_DEF_AUTH
ks->mda_key_id = session->opt->mda_context->mda_key_id_counter++;
@@ -798,7 +863,7 @@ key_state_free (struct key_state *ks, bool clear)
key_state_ssl_free(&ks->ks_ssl);
- free_key_ctx_bi (&ks->key);
+ free_key_ctx_bi (&ks->crypto_options.key_ctx_bi);
free_buf (&ks->plaintext_read_buf);
free_buf (&ks->plaintext_write_buf);
free_buf (&ks->ack_write_buf);
@@ -822,7 +887,7 @@ key_state_free (struct key_state *ks, bool clear)
if (ks->key_src)
free (ks->key_src);
- packet_id_free (&ks->packet_id);
+ packet_id_free (&ks->crypto_options.packet_id);
#ifdef PLUGIN_DEF_AUTH
key_state_rm_auth_control_file (ks);
@@ -837,11 +902,23 @@ key_state_free (struct key_state *ks, bool clear)
/** @} addtogroup control_processor */
-/*
- * Must be called if we move a tls_session in memory.
+/**
+ * Returns whether or not the server should check for username/password
+ *
+ * @param session The current TLS session
+ *
+ * @return true if username and password verification is enabled,
+ * false if not.
*/
-static inline void tls_session_set_self_referential_pointers (struct tls_session* session) {
- session->tls_auth.packet_id = &session->tls_auth_pid;
+static inline bool
+tls_session_user_pass_enabled(struct tls_session *session)
+{
+ return (session->opt->auth_user_pass_verify_script
+ || plugin_defined (session->opt->plugins, OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY)
+#ifdef MANAGEMENT_DEF_AUTH
+ || management_enable_def_auth (management)
+#endif
+ );
}
@@ -895,20 +972,18 @@ tls_session_init (struct tls_multi *multi, struct tls_session *session)
}
/* Initialize control channel authentication parameters */
- session->tls_auth = session->opt->tls_auth;
-
- /* Set session internal pointers (also called if session object is moved in memory) */
- tls_session_set_self_referential_pointers (session);
+ session->tls_wrap = session->opt->tls_wrap;
+ session->tls_wrap.work = alloc_buf (TLS_CHANNEL_BUF_SIZE);
/* initialize packet ID replay window for --tls-auth */
- packet_id_init (session->tls_auth.packet_id,
- session->opt->tcp_mode,
+ packet_id_init (&session->tls_wrap.opt.packet_id,
session->opt->replay_window,
session->opt->replay_time,
- "TLS_AUTH", session->key_id);
+ "TLS_WRAP", session->key_id);
/* load most recent packet-id to replay protect on --tls-auth */
- packet_id_persist_load_obj (session->tls_auth.pid_persist, session->tls_auth.packet_id);
+ packet_id_persist_load_obj (session->tls_wrap.opt.pid_persist,
+ &session->tls_wrap.opt.packet_id);
key_state_init (session, &session->key[KS_PRIMARY]);
@@ -935,8 +1010,10 @@ tls_session_free (struct tls_session *session, bool clear)
{
int i;
- if (session->tls_auth.packet_id)
- packet_id_free (session->tls_auth.packet_id);
+ if (packet_id_initialized(&session->tls_wrap.opt.packet_id))
+ packet_id_free (&session->tls_wrap.opt.packet_id);
+
+ free_buf (&session->tls_wrap.work);
for (i = 0; i < KS_SIZE; ++i)
key_state_free (&session->key[i], false);
@@ -967,7 +1044,6 @@ move_session (struct tls_multi* multi, int dest, int src, bool reinit_src)
ASSERT (dest >= 0 && dest < TM_SIZE);
tls_session_free (&multi->session[dest], false);
multi->session[dest] = multi->session[src];
- tls_session_set_self_referential_pointers (&multi->session[dest]);
if (reinit_src)
tls_session_init (multi, &multi->session[src]);
@@ -984,22 +1060,6 @@ reset_session (struct tls_multi *multi, struct tls_session *session)
tls_session_init (multi, session);
}
-#if 0
-/*
- * Transmit a TLS reset on our untrusted channel.
- */
-static void
-initiate_untrusted_session (struct tls_multi *multi, struct sockaddr_in *to)
-{
- struct tls_session *session = &multi->session[TM_UNTRUSTED];
- struct key_state *ks = &session->key[KS_PRIMARY];
-
- reset_session (multi, session);
- ks->remote_addr = *to;
- msg (D_TLS_DEBUG_LOW, "TLS: initiate_untrusted_session: addr=%s", print_sockaddr (to));
-}
-#endif
-
/*
* Used to determine in how many seconds we should be
* called again.
@@ -1048,9 +1108,6 @@ tls_multi_init (struct tls_options *tls_options)
/* get command line derived options */
ret->opt = *tls_options;
- /* set up pointer to HMAC object for TLS packet authentication */
- ret->opt.tls_auth.key_ctx_bi = &ret->opt.tls_auth_key;
-
/* set up list of keys to be scanned by data channel encrypt and decrypt routines */
ASSERT (SIZE (ret->key_scan) == 3);
ret->key_scan[0] = &ret->session[TM_ACTIVE].key[KS_PRIMARY];
@@ -1088,10 +1145,14 @@ tls_auth_standalone_init (struct tls_options *tls_options,
ALLOC_OBJ_CLEAR_GC (tas, struct tls_auth_standalone, gc);
- /* set up pointer to HMAC object for TLS packet authentication */
- tas->tls_auth_key = tls_options->tls_auth_key;
- tas->tls_auth_options.key_ctx_bi = &tas->tls_auth_key;
- tas->tls_auth_options.flags |= CO_PACKET_ID_LONG_FORM;
+ tas->tls_wrap = tls_options->tls_wrap;
+
+ /*
+ * Standalone tls-auth is in read-only mode with respect to TLS
+ * control channel state. After we build a new client instance
+ * object, we will process this session-initiating packet for real.
+ */
+ tas->tls_wrap.opt.flags |= CO_IGNORE_PACKET_ID;
/* get initial frame parms, still need to finalize */
tas->frame = tls_options->frame;
@@ -1136,6 +1197,8 @@ tls_multi_free (struct tls_multi *multi, bool clear)
#ifdef MANAGEMENT_DEF_AUTH
man_def_auth_set_client_reason(multi, NULL);
+#endif
+#if P2MP_SERVER
free (multi->peer_info);
#endif
@@ -1147,6 +1210,12 @@ tls_multi_free (struct tls_multi *multi, bool clear)
cert_hash_free (multi->locked_cert_hash_set);
+ if (multi->auth_token)
+ {
+ memset (multi->auth_token, 0, AUTH_TOKEN_SIZE);
+ free (multi->auth_token);
+ }
+
for (i = 0; i < TM_SIZE; ++i)
tls_session_free (&multi->session[i], false);
@@ -1171,11 +1240,11 @@ tls_multi_free (struct tls_multi *multi, bool clear)
static bool
swap_hmac (struct buffer *buf, const struct crypto_options *co, bool incoming)
{
- struct key_ctx *ctx;
+ const struct key_ctx *ctx;
ASSERT (co);
- ctx = (incoming ? &co->key_ctx_bi->decrypt : &co->key_ctx_bi->encrypt);
+ ctx = (incoming ? &co->key_ctx_bi.decrypt : &co->key_ctx_bi.encrypt);
ASSERT (ctx->hmac);
{
@@ -1230,20 +1299,34 @@ write_control_auth (struct tls_session *session,
int max_ack,
bool prepend_ack)
{
- uint8_t *header;
+ uint8_t header = ks->key_id | (opcode << P_OPCODE_SHIFT);
struct buffer null = clear_buf ();
ASSERT (link_socket_actual_defined (&ks->remote_addr));
ASSERT (reliable_ack_write
(ks->rec_ack, buf, &ks->session_id_remote, max_ack, prepend_ack));
- ASSERT (session_id_write_prepend (&session->session_id, buf));
- ASSERT (header = buf_prepend (buf, 1));
- *header = ks->key_id | (opcode << P_OPCODE_SHIFT);
- if (session->tls_auth.key_ctx_bi->encrypt.hmac)
+
+ if (session->tls_wrap.mode == TLS_WRAP_AUTH ||
+ session->tls_wrap.mode == TLS_WRAP_NONE)
+ {
+ ASSERT (session_id_write_prepend (&session->session_id, buf));
+ ASSERT (buf_write_prepend (buf, &header, sizeof(header)));
+ }
+ if (session->tls_wrap.mode == TLS_WRAP_AUTH)
{
/* no encryption, only write hmac */
- openvpn_encrypt (buf, null, &session->tls_auth, NULL);
- ASSERT (swap_hmac (buf, &session->tls_auth, false));
+ openvpn_encrypt (buf, null, &session->tls_wrap.opt);
+ ASSERT (swap_hmac (buf, &session->tls_wrap.opt, false));
+ }
+ else if (session->tls_wrap.mode == TLS_WRAP_CRYPT)
+ {
+ buf_init (&session->tls_wrap.work, buf->offset);
+ ASSERT (buf_write (&session->tls_wrap.work, &header, sizeof(header)));
+ ASSERT (session_id_write (&session->session_id, &session->tls_wrap.work));
+ ASSERT (tls_crypt_wrap (buf, &session->tls_wrap.work, &session->tls_wrap.opt));
+ /* Don't change the original data in buf, it's used by the reliability
+ * layer to resend on failure. */
+ *buf = session->tls_wrap.work;
}
*to_link_addr = &ks->remote_addr;
}
@@ -1253,17 +1336,18 @@ write_control_auth (struct tls_session *session,
*/
static bool
read_control_auth (struct buffer *buf,
- const struct crypto_options *co,
+ struct tls_wrap_ctx *ctx,
const struct link_socket_actual *from)
{
struct gc_arena gc = gc_new ();
+ bool ret = false;
- if (co->key_ctx_bi->decrypt.hmac)
+ if (ctx->mode == TLS_WRAP_AUTH)
{
struct buffer null = clear_buf ();
/* move the hmac record to the front of the packet */
- if (!swap_hmac (buf, co, true))
+ if (!swap_hmac (buf, &ctx->opt, true))
{
msg (D_TLS_ERRORS,
"TLS Error: cannot locate HMAC in incoming packet from %s",
@@ -1274,24 +1358,41 @@ read_control_auth (struct buffer *buf,
/* authenticate only (no decrypt) and remove the hmac record
from the head of the buffer */
- openvpn_decrypt (buf, null, co, NULL);
+ openvpn_decrypt (buf, null, &ctx->opt, NULL, BPTR (buf));
if (!buf->len)
{
msg (D_TLS_ERRORS,
"TLS Error: incoming packet authentication failed from %s",
print_link_socket_actual (from, &gc));
- gc_free (&gc);
- return false;
+ goto cleanup;
}
}
+ else if (ctx->mode == TLS_WRAP_CRYPT)
+ {
+ struct buffer tmp = alloc_buf (buf_forward_capacity_total (buf));
+ if (!tls_crypt_unwrap (buf, &tmp, &ctx->opt))
+ {
+ msg (D_TLS_ERRORS, "TLS Error: tls-crypt unwrapping failed from %s",
+ print_link_socket_actual (from, &gc));
+ goto cleanup;
+ }
+ ASSERT (buf_init (buf, buf->offset));
+ ASSERT (buf_copy (buf, &tmp));
+ free_buf (&tmp);
+ }
- /* advance buffer pointer past opcode & session_id since our caller
- already read it */
- buf_advance (buf, SID_SIZE + 1);
+ if (ctx->mode == TLS_WRAP_NONE || ctx->mode == TLS_WRAP_AUTH)
+ {
+ /* advance buffer pointer past opcode & session_id since our caller
+ already read it */
+ buf_advance (buf, SID_SIZE + 1);
+ }
+ ret = true;
+cleanup:
gc_free (&gc);
- return true;
+ return ret;
}
/*
@@ -1352,7 +1453,7 @@ tls1_P_hash(const md_kt_t *md_kt,
int olen)
{
struct gc_arena gc = gc_new ();
- int chunk,n;
+ int chunk;
hmac_ctx_t ctx;
hmac_ctx_t ctx_tmp;
uint8_t A1[MAX_HMAC_KEY_LENGTH];
@@ -1378,7 +1479,6 @@ tls1_P_hash(const md_kt_t *md_kt,
hmac_ctx_update(&ctx,seed,seed_len);
hmac_ctx_final(&ctx, A1);
- n=0;
for (;;)
{
hmac_ctx_reset(&ctx);
@@ -1429,7 +1529,7 @@ tls1_P_hash(const md_kt_t *md_kt,
* (2) The pre-master secret is generated by the client.
*/
static void
-tls1_PRF(uint8_t *label,
+tls1_PRF(const uint8_t *label,
int label_len,
const uint8_t *sec,
int slen,
@@ -1581,6 +1681,13 @@ generate_key_expansion (struct key_ctx_bi *key,
OPENVPN_OP_DECRYPT,
"Data Channel Decrypt");
+ /* Initialize implicit IVs */
+ key_ctx_update_implicit_iv (&key->encrypt, key2.keys[(int)server].hmac,
+ MAX_HMAC_KEY_LENGTH);
+ key_ctx_update_implicit_iv (&key->decrypt, key2.keys[1-(int)server].hmac,
+ MAX_HMAC_KEY_LENGTH);
+
+ key->initialized = true;
ret = true;
exit:
@@ -1590,6 +1697,96 @@ generate_key_expansion (struct key_ctx_bi *key,
return ret;
}
+static void
+key_ctx_update_implicit_iv(struct key_ctx *ctx, uint8_t *key, size_t key_len) {
+ const cipher_kt_t *cipher_kt = cipher_ctx_get_cipher_kt (ctx->cipher);
+
+ /* Only use implicit IV in AEAD cipher mode, where HMAC key is not used */
+ if (cipher_kt_mode_aead (cipher_kt))
+ {
+ size_t impl_iv_len = 0;
+ ASSERT (cipher_kt_iv_size (cipher_kt) >= OPENVPN_AEAD_MIN_IV_LEN);
+ impl_iv_len = cipher_kt_iv_size (cipher_kt) - sizeof (packet_id_type);
+ ASSERT (impl_iv_len <= OPENVPN_MAX_IV_LENGTH);
+ ASSERT (impl_iv_len <= key_len);
+ memcpy (ctx->implicit_iv, key, impl_iv_len);
+ ctx->implicit_iv_len = impl_iv_len;
+ }
+}
+
+static bool
+item_in_list(const char *item, const char *list)
+{
+ char *tmp_ciphers = string_alloc (list, NULL);
+ char *tmp_ciphers_orig = tmp_ciphers;
+
+ const char *token = strtok (tmp_ciphers, ":");
+ while(token)
+ {
+ if (0 == strcmp (token, item))
+ break;
+ token = strtok (NULL, ":");
+ }
+ free(tmp_ciphers_orig);
+
+ return token != NULL;
+}
+
+bool
+tls_session_update_crypto_params(struct tls_session *session,
+ const struct options *options, struct frame *frame)
+{
+ bool ret = false;
+ struct key_state *ks = &session->key[KS_PRIMARY]; /* primary key */
+
+ ASSERT (ks->authenticated);
+
+ if (!session->opt->server &&
+ 0 != strcmp(options->ciphername, session->opt->config_ciphername) &&
+ !item_in_list(options->ciphername, options->ncp_ciphers))
+ {
+ msg (D_TLS_ERRORS, "Error: pushed cipher not allowed - %s not in %s or %s",
+ options->ciphername, session->opt->config_ciphername,
+ options->ncp_ciphers);
+ return false;
+ }
+
+ init_key_type (&session->opt->key_type, options->ciphername,
+ options->authname, options->keysize, true, true);
+
+ bool packet_id_long_form = cipher_kt_mode_ofb_cfb (session->opt->key_type.cipher);
+ session->opt->crypto_flags_and &= ~(CO_PACKET_ID_LONG_FORM);
+ if (packet_id_long_form)
+ session->opt->crypto_flags_and = CO_PACKET_ID_LONG_FORM;
+
+ /* Update frame parameters: undo worst-case overhead, add actual overhead */
+ frame_add_to_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,
+ options->ce.tun_mtu_defined, options->ce.tun_mtu);
+ frame_init_mssfix(frame, options);
+ frame_print (frame, D_MTU_INFO, "Data Channel MTU parms");
+
+ const struct session_id *client_sid = session->opt->server ?
+ &ks->session_id_remote : &session->session_id;
+ const struct session_id *server_sid = !session->opt->server ?
+ &ks->session_id_remote : &session->session_id;
+ if (!generate_key_expansion (&ks->crypto_options.key_ctx_bi,
+ &session->opt->key_type, ks->key_src, client_sid, server_sid,
+ session->opt->server))
+ {
+ msg (D_TLS_ERRORS, "TLS Error: server generate_key_expansion failed");
+ goto cleanup;
+ }
+ tls_limit_reneg_bytes (session->opt->key_type.cipher,
+ &session->opt->renegotiate_bytes);
+ ret = true;
+cleanup:
+ CLEAR (*ks->key_src);
+ return ret;
+}
+
static bool
random_bytes_to_buf (struct buffer *buf,
uint8_t *out,
@@ -1762,7 +1959,6 @@ key_method_1_write (struct buffer *buf, struct tls_session *session)
{
struct key key;
struct key_state *ks = &session->key[KS_PRIMARY]; /* primary key */
- struct key_state *ks_lame = &session->key[KS_LAME_DUCK]; /* retiring key */
ASSERT (session->opt->key_method == 1);
ASSERT (buf_init (buf, 0));
@@ -1780,8 +1976,9 @@ key_method_1_write (struct buffer *buf, struct tls_session *session)
return false;
}
- init_key_ctx (&ks->key.encrypt, &key, &session->opt->key_type,
- OPENVPN_OP_ENCRYPT, "Data Channel Encrypt");
+ init_key_ctx (&ks->crypto_options.key_ctx_bi.encrypt, &key,
+ &session->opt->key_type, OPENVPN_OP_ENCRYPT,
+ "Data Channel Encrypt");
CLEAR (key);
/* send local options string */
@@ -1827,17 +2024,30 @@ push_peer_info(struct buffer *buf, struct tls_session *session)
buf_printf (&out, "IV_PLAT=netbsd\n");
#elif defined(TARGET_FREEBSD)
buf_printf (&out, "IV_PLAT=freebsd\n");
-#elif defined(WIN32)
+#elif defined(TARGET_ANDROID)
+ buf_printf (&out, "IV_PLAT=android\n");
+#elif defined(_WIN32)
buf_printf (&out, "IV_PLAT=win\n");
#endif
- /* push LZO status */
-#ifdef ENABLE_LZO_STUB
- buf_printf (&out, "IV_LZO_STUB=1\n");
-#endif
/* support for P_DATA_V2 */
buf_printf(&out, "IV_PROTO=2\n");
+ /* support for Negotiable Crypto Paramters */
+ if (session->opt->ncp_enabled &&
+ (session->opt->mode == MODE_SERVER || session->opt->pull))
+ {
+ buf_printf(&out, "IV_NCP=2\n");
+ }
+
+ /* push compression status */
+#ifdef USE_COMP
+ comp_generate_peer_info_string(&session->opt->comp_options, &out);
+#endif
+
+ /* support for redirecting IPv6 gateway */
+ buf_printf(&out, "IV_RGI6=1\n");
+
if (session->opt->push_peer_info_detail >= 2)
{
/* push mac addr */
@@ -1846,17 +2056,19 @@ push_peer_info(struct buffer *buf, struct tls_session *session)
if (rgi.flags & RGI_HWADDR_DEFINED)
buf_printf (&out, "IV_HWADDR=%s\n", format_hex_ex (rgi.hwaddr, 6, 0, 1, ":", &gc));
buf_printf (&out, "IV_SSL=%s\n", get_ssl_library_version() );
-#if defined(WIN32)
+#if defined(_WIN32)
buf_printf (&out, "IV_PLAT_VER=%s\n", win32_version_string (&gc, false));
#endif
}
- /* push env vars that begin with UV_ and IV_GUI_VER */
+ /* push env vars that begin with UV_, IV_PLAT_VER and IV_GUI_VER */
for (e=es->list; e != NULL; e=e->next)
{
if (e->string)
{
- if (((strncmp(e->string, "UV_", 3)==0 && session->opt->push_peer_info_detail >= 2)
+ if ((((strncmp(e->string, "UV_", 3)==0 ||
+ strncmp(e->string, "IV_PLAT_VER=", sizeof("IV_PLAT_VER=")-1)==0)
+ && session->opt->push_peer_info_detail >= 2)
|| (strncmp(e->string,"IV_GUI_VER=",sizeof("IV_GUI_VER=")-1)==0))
&& buf_safe(&out, strlen(e->string)+1))
buf_printf (&out, "%s\n", e->string);
@@ -1883,7 +2095,6 @@ static bool
key_method_2_write (struct buffer *buf, struct tls_session *session)
{
struct key_state *ks = &session->key[KS_PRIMARY]; /* primary key */
- struct key_state *ks_lame = &session->key[KS_LAME_DUCK]; /* retiring key */
ASSERT (session->opt->key_method == 2);
ASSERT (buf_init (buf, 0));
@@ -1931,14 +2142,17 @@ key_method_2_write (struct buffer *buf, struct tls_session *session)
if (!push_peer_info (buf, session))
goto error;
- /*
- * generate tunnel keys if server
+ /* Generate tunnel keys if we're a TLS server.
+ * If we're a p2mp server and IV_NCP >= 2 is negotiated, the first key
+ * generation is postponed until after the pull/push, so we can process pushed
+ * cipher directives.
*/
- if (session->opt->server)
+ if (session->opt->server && !(session->opt->ncp_enabled &&
+ session->opt->mode == MODE_SERVER && ks->key_id <= 0))
{
if (ks->authenticated)
{
- if (!generate_key_expansion (&ks->key,
+ if (!generate_key_expansion (&ks->crypto_options.key_ctx_bi,
&session->opt->key_type,
ks->key_src,
&ks->session_id_remote,
@@ -1951,6 +2165,8 @@ key_method_2_write (struct buffer *buf, struct tls_session *session)
}
CLEAR (*ks->key_src);
+ tls_limit_reneg_bytes (session->opt->key_type.cipher,
+ &session->opt->renegotiate_bytes);
}
return true;
@@ -1967,7 +2183,6 @@ key_method_1_read (struct buffer *buf, struct tls_session *session)
int status;
struct key key;
struct key_state *ks = &session->key[KS_PRIMARY]; /* primary key */
- struct key_state *ks_lame = &session->key[KS_LAME_DUCK]; /* retiring key */
ASSERT (session->opt->key_method == 1);
@@ -2010,8 +2225,9 @@ key_method_1_read (struct buffer *buf, struct tls_session *session)
buf_clear (buf);
- init_key_ctx (&ks->key.decrypt, &key, &session->opt->key_type,
- OPENVPN_OP_DECRYPT, "Data Channel Decrypt");
+ init_key_ctx (&ks->crypto_options.key_ctx_bi.decrypt, &key,
+ &session->opt->key_type, OPENVPN_OP_DECRYPT,
+ "Data Channel Decrypt");
CLEAR (key);
ks->authenticated = true;
return true;
@@ -2026,13 +2242,13 @@ static bool
key_method_2_read (struct buffer *buf, struct tls_multi *multi, struct tls_session *session)
{
struct key_state *ks = &session->key[KS_PRIMARY]; /* primary key */
- struct key_state *ks_lame = &session->key[KS_LAME_DUCK]; /* retiring key */
int key_method_flags;
bool username_status, password_status;
struct gc_arena gc = gc_new ();
char *options;
+ struct user_pass *up;
/* allocate temporary objects */
ALLOC_ARRAY_CLEAR_GC (options, char, TLS_OPTIONS_LEN, &gc);
@@ -2072,15 +2288,31 @@ key_method_2_read (struct buffer *buf, struct tls_multi *multi, struct tls_sessi
ks->authenticated = false;
- if (verify_user_pass_enabled(session))
- {
- /* Perform username/password authentication */
- struct user_pass *up;
+ /* always extract username + password fields from buf, even if not
+ * authenticating for it, because otherwise we can't get at the
+ * peer_info data which follows behind
+ */
+ ALLOC_OBJ_CLEAR_GC (up, struct user_pass, &gc);
+ username_status = read_string (buf, up->username, USER_PASS_LEN);
+ password_status = read_string (buf, up->password, USER_PASS_LEN);
+
+#if P2MP_SERVER
+ /* get peer info from control channel */
+ free (multi->peer_info);
+ multi->peer_info = read_string_alloc (buf);
+ if ( multi->peer_info )
+ output_peer_info_env (session->opt->es, multi->peer_info);
- ALLOC_OBJ_CLEAR_GC (up, struct user_pass, &gc);
- username_status = read_string (buf, up->username, USER_PASS_LEN);
- password_status = read_string (buf, up->password, USER_PASS_LEN);
+ if (tls_peer_info_ncp_ver (multi->peer_info) < 2)
+ {
+ /* Peer does not support NCP */
+ session->opt->ncp_enabled = false;
+ }
+#endif
+ if (tls_session_user_pass_enabled(session))
+ {
+ /* Perform username/password authentication */
if (!username_status || !password_status)
{
CLEAR (*up);
@@ -2091,14 +2323,7 @@ key_method_2_read (struct buffer *buf, struct tls_multi *multi, struct tls_sessi
}
}
-#ifdef MANAGEMENT_DEF_AUTH
- /* get peer info from control channel */
- free (multi->peer_info);
- multi->peer_info = read_string_alloc (buf);
-#endif
-
verify_user_pass(up, multi, session);
- CLEAR (*up);
}
else
{
@@ -2112,6 +2337,9 @@ key_method_2_read (struct buffer *buf, struct tls_multi *multi, struct tls_sessi
ks->authenticated = true;
}
+ /* clear username and password from memory */
+ CLEAR (*up);
+
/* Perform final authentication checks */
if (ks->authenticated)
{
@@ -2140,16 +2368,22 @@ key_method_2_read (struct buffer *buf, struct tls_multi *multi, struct tls_sessi
*/
if (ks->authenticated && plugin_defined (session->opt->plugins, OPENVPN_PLUGIN_TLS_FINAL))
{
+ key_state_export_keying_material(&ks->ks_ssl, session);
+
if (plugin_call (session->opt->plugins, OPENVPN_PLUGIN_TLS_FINAL, NULL, NULL, session->opt->es) != OPENVPN_PLUGIN_FUNC_SUCCESS)
ks->authenticated = false;
+
+ setenv_del (session->opt->es, "exported_keying_material");
}
/*
- * Generate tunnel keys if client
+ * Generate tunnel keys if we're a client.
+ * If --pull is enabled, the first key generation is postponed until after the
+ * pull/push, so we can process pushed cipher directives.
*/
- if (!session->opt->server)
+ if (!session->opt->server && (!session->opt->pull || ks->key_id > 0))
{
- if (!generate_key_expansion (&ks->key,
+ if (!generate_key_expansion (&ks->crypto_options.key_ctx_bi,
&session->opt->key_type,
ks->key_src,
&session->session_id,
@@ -2159,8 +2393,10 @@ key_method_2_read (struct buffer *buf, struct tls_multi *multi, struct tls_sessi
msg (D_TLS_ERRORS, "TLS Error: client generate_key_expansion failed");
goto error;
}
-
+
CLEAR (*ks->key_src);
+ tls_limit_reneg_bytes (session->opt->key_type.cipher,
+ &session->opt->renegotiate_bytes);
}
gc_free (&gc);
@@ -2217,11 +2453,11 @@ tls_process (struct tls_multi *multi,
if (ks->state >= S_ACTIVE &&
((session->opt->renegotiate_seconds
&& now >= ks->established + session->opt->renegotiate_seconds)
- || (session->opt->renegotiate_bytes
+ || (session->opt->renegotiate_bytes > 0
&& ks->n_bytes >= session->opt->renegotiate_bytes)
|| (session->opt->renegotiate_packets
&& ks->n_packets >= session->opt->renegotiate_packets)
- || (packet_id_close_to_wrapping (&ks->packet_id.send))))
+ || (packet_id_close_to_wrapping (&ks->crypto_options.packet_id.send))))
{
msg (D_TLS_DEBUG_LOW,
"TLS: soft reset sec=%d bytes=" counter_format "/%d pkts=" counter_format "/%d",
@@ -2257,269 +2493,274 @@ tls_process (struct tls_multi *multi,
* CHANGED with 2.0 -> now we may send tunnel configuration
* info over the control channel.
*/
- if (true)
+
+ /* Initial handshake */
+ if (ks->state == S_INITIAL)
{
- /* Initial handshake */
- if (ks->state == S_INITIAL)
+ buf = reliable_get_buf_output_sequenced (ks->send_reliable);
+ if (buf)
{
- buf = reliable_get_buf_output_sequenced (ks->send_reliable);
- if (buf)
- {
- ks->must_negotiate = now + session->opt->handshake_window;
- ks->auth_deferred_expire = now + auth_deferred_expire_window (session->opt);
+ ks->must_negotiate = now + session->opt->handshake_window;
+ ks->auth_deferred_expire = now + auth_deferred_expire_window (session->opt);
- /* null buffer */
- reliable_mark_active_outgoing (ks->send_reliable, buf, ks->initial_opcode);
- INCR_GENERATED;
+ /* null buffer */
+ reliable_mark_active_outgoing (ks->send_reliable, buf, ks->initial_opcode);
+ INCR_GENERATED;
- ks->state = S_PRE_START;
- state_change = true;
- dmsg (D_TLS_DEBUG, "TLS: Initial Handshake, sid=%s",
- session_id_print (&session->session_id, &gc));
+ ks->state = S_PRE_START;
+ state_change = true;
+ dmsg (D_TLS_DEBUG, "TLS: Initial Handshake, sid=%s",
+ session_id_print (&session->session_id, &gc));
#ifdef ENABLE_MANAGEMENT
- if (management && ks->initial_opcode != P_CONTROL_SOFT_RESET_V1)
- {
- management_set_state (management,
- OPENVPN_STATE_WAIT,
- NULL,
- 0,
- 0);
- }
-#endif
+ if (management && ks->initial_opcode != P_CONTROL_SOFT_RESET_V1)
+ {
+ management_set_state (management,
+ OPENVPN_STATE_WAIT,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL);
}
+#endif
}
+ }
- /* Are we timed out on receive? */
- if (now >= ks->must_negotiate)
+ /* Are we timed out on receive? */
+ if (now >= ks->must_negotiate)
+ {
+ if (ks->state < S_ACTIVE)
{
- if (ks->state < S_ACTIVE)
- {
- msg (D_TLS_ERRORS,
- "TLS Error: TLS key negotiation failed to occur within %d seconds (check your network connectivity)",
- session->opt->handshake_window);
- goto error;
- }
- else /* assume that ks->state == S_ACTIVE */
- {
- dmsg (D_TLS_DEBUG_MED, "STATE S_NORMAL_OP");
- ks->state = S_NORMAL_OP;
- ks->must_negotiate = 0;
- }
+ msg (D_TLS_ERRORS,
+ "TLS Error: TLS key negotiation failed to occur within %d seconds (check your network connectivity)",
+ session->opt->handshake_window);
+ goto error;
}
+ else /* assume that ks->state == S_ACTIVE */
+ {
+ dmsg (D_TLS_DEBUG_MED, "STATE S_NORMAL_OP");
+ ks->state = S_NORMAL_OP;
+ ks->must_negotiate = 0;
+ }
+ }
- /* Wait for Initial Handshake ACK */
- if (ks->state == S_PRE_START && FULL_SYNC)
+ /* Wait for Initial Handshake ACK */
+ if (ks->state == S_PRE_START && FULL_SYNC)
+ {
+ ks->state = S_START;
+ state_change = true;
+
+ /* Reload the CRL before TLS negotiation */
+ if (session->opt->crl_file &&
+ !(session->opt->ssl_flags & SSLF_CRL_VERIFY_DIR))
{
- ks->state = S_START;
- state_change = true;
- dmsg (D_TLS_DEBUG_MED, "STATE S_START");
+ tls_ctx_reload_crl(&session->opt->ssl_ctx,
+ session->opt->crl_file, session->opt->crl_file_inline);
}
- /* Wait for ACK */
- if (((ks->state == S_GOT_KEY && !session->opt->server) ||
- (ks->state == S_SENT_KEY && session->opt->server)))
+ dmsg (D_TLS_DEBUG_MED, "STATE S_START");
+ }
+
+ /* Wait for ACK */
+ if (((ks->state == S_GOT_KEY && !session->opt->server) ||
+ (ks->state == S_SENT_KEY && session->opt->server)))
+ {
+ if (FULL_SYNC)
{
- if (FULL_SYNC)
- {
- ks->established = now;
- dmsg (D_TLS_DEBUG_MED, "STATE S_ACTIVE");
- if (check_debug_level (D_HANDSHAKE))
- print_details (&ks->ks_ssl, "Control Channel:");
- state_change = true;
- ks->state = S_ACTIVE;
- INCR_SUCCESS;
+ ks->established = now;
+ dmsg (D_TLS_DEBUG_MED, "STATE S_ACTIVE");
+ if (check_debug_level (D_HANDSHAKE))
+ print_details (&ks->ks_ssl, "Control Channel:");
+ state_change = true;
+ ks->state = S_ACTIVE;
+ INCR_SUCCESS;
- /* Set outgoing address for data channel packets */
- link_socket_set_outgoing_addr (NULL, to_link_socket_info, &ks->remote_addr, session->common_name, session->opt->es);
+ /* Set outgoing address for data channel packets */
+ link_socket_set_outgoing_addr (NULL, to_link_socket_info, &ks->remote_addr, session->common_name, session->opt->es);
- /* Flush any payload packets that were buffered before our state transitioned to S_ACTIVE */
- flush_payload_buffer (ks);
+ /* Flush any payload packets that were buffered before our state transitioned to S_ACTIVE */
+ flush_payload_buffer (ks);
#ifdef MEASURE_TLS_HANDSHAKE_STATS
- show_tls_performance_stats();
+ show_tls_performance_stats();
#endif
- }
}
+ }
- /* Reliable buffer to outgoing TCP/UDP (send up to CONTROL_SEND_ACK_MAX ACKs
- for previously received packets) */
- if (!to_link->len && reliable_can_send (ks->send_reliable))
- {
- int opcode;
- struct buffer b;
-
- buf = reliable_send (ks->send_reliable, &opcode);
- ASSERT (buf);
- b = *buf;
- INCR_SENT;
-
- write_control_auth (session, ks, &b, to_link_addr, opcode,
- CONTROL_SEND_ACK_MAX, true);
- *to_link = b;
- active = true;
- state_change = true;
- dmsg (D_TLS_DEBUG, "Reliable -> TCP/UDP");
- break;
- }
+ /* Reliable buffer to outgoing TCP/UDP (send up to CONTROL_SEND_ACK_MAX ACKs
+ for previously received packets) */
+ if (!to_link->len && reliable_can_send (ks->send_reliable))
+ {
+ int opcode;
+ struct buffer b;
+
+ buf = reliable_send (ks->send_reliable, &opcode);
+ ASSERT (buf);
+ b = *buf;
+ INCR_SENT;
+
+ write_control_auth (session, ks, &b, to_link_addr, opcode,
+ CONTROL_SEND_ACK_MAX, true);
+ *to_link = b;
+ active = true;
+ state_change = true;
+ dmsg (D_TLS_DEBUG, "Reliable -> TCP/UDP");
+ break;
+ }
#ifndef TLS_AGGREGATE_ACK
- /* Send 1 or more ACKs (each received control packet gets one ACK) */
- if (!to_link->len && !reliable_ack_empty (ks->rec_ack))
- {
- buf = &ks->ack_write_buf;
- ASSERT (buf_init (buf, FRAME_HEADROOM (&multi->opt.frame)));
- write_control_auth (session, ks, buf, to_link_addr, P_ACK_V1,
- RELIABLE_ACK_SIZE, false);
- *to_link = *buf;
- active = true;
- state_change = true;
- dmsg (D_TLS_DEBUG, "Dedicated ACK -> TCP/UDP");
- break;
- }
+ /* Send 1 or more ACKs (each received control packet gets one ACK) */
+ if (!to_link->len && !reliable_ack_empty (ks->rec_ack))
+ {
+ buf = &ks->ack_write_buf;
+ ASSERT (buf_init (buf, FRAME_HEADROOM (&multi->opt.frame)));
+ write_control_auth (session, ks, buf, to_link_addr, P_ACK_V1,
+ RELIABLE_ACK_SIZE, false);
+ *to_link = *buf;
+ active = true;
+ state_change = true;
+ dmsg (D_TLS_DEBUG, "Dedicated ACK -> TCP/UDP");
+ break;
+ }
#endif
- /* Write incoming ciphertext to TLS object */
- buf = reliable_get_buf_sequenced (ks->rec_reliable);
- if (buf)
- {
- int status = 0;
- if (buf->len)
- {
- status = key_state_write_ciphertext (&ks->ks_ssl, buf);
- if (status == -1)
- {
- msg (D_TLS_ERRORS,
- "TLS Error: Incoming Ciphertext -> TLS object write error");
- goto error;
- }
- }
- else
- {
- status = 1;
- }
- if (status == 1)
- {
- reliable_mark_deleted (ks->rec_reliable, buf, true);
- state_change = true;
- dmsg (D_TLS_DEBUG, "Incoming Ciphertext -> TLS");
- }
- }
-
- /* Read incoming plaintext from TLS object */
- buf = &ks->plaintext_read_buf;
- if (!buf->len)
+ /* Write incoming ciphertext to TLS object */
+ buf = reliable_get_buf_sequenced (ks->rec_reliable);
+ if (buf)
+ {
+ int status = 0;
+ if (buf->len)
{
- int status;
-
- ASSERT (buf_init (buf, 0));
- status = key_state_read_plaintext (&ks->ks_ssl, buf, TLS_CHANNEL_BUF_SIZE);
- update_time ();
+ status = key_state_write_ciphertext (&ks->ks_ssl, buf);
if (status == -1)
{
- msg (D_TLS_ERRORS, "TLS Error: TLS object -> incoming plaintext read error");
+ msg (D_TLS_ERRORS,
+ "TLS Error: Incoming Ciphertext -> TLS object write error");
goto error;
}
- if (status == 1)
- {
- state_change = true;
- dmsg (D_TLS_DEBUG, "TLS -> Incoming Plaintext");
- }
-#if 0 /* show null plaintext reads */
- if (!status)
- msg (M_INFO, "TLS plaintext read -> NULL return");
-#endif
}
-
- /* Send Key */
- buf = &ks->plaintext_write_buf;
- if (!buf->len && ((ks->state == S_START && !session->opt->server) ||
- (ks->state == S_GOT_KEY && session->opt->server)))
+ else
{
- if (session->opt->key_method == 1)
- {
- if (!key_method_1_write (buf, session))
- goto error;
- }
- else if (session->opt->key_method == 2)
- {
- if (!key_method_2_write (buf, session))
- goto error;
- }
- else
- {
- ASSERT (0);
- }
+ status = 1;
+ }
+ if (status == 1)
+ {
+ reliable_mark_deleted (ks->rec_reliable, buf, true);
+ state_change = true;
+ dmsg (D_TLS_DEBUG, "Incoming Ciphertext -> TLS");
+ }
+ }
+
+ /* Read incoming plaintext from TLS object */
+ buf = &ks->plaintext_read_buf;
+ if (!buf->len)
+ {
+ int status;
+ ASSERT (buf_init (buf, 0));
+ status = key_state_read_plaintext (&ks->ks_ssl, buf, TLS_CHANNEL_BUF_SIZE);
+ update_time ();
+ if (status == -1)
+ {
+ msg (D_TLS_ERRORS, "TLS Error: TLS object -> incoming plaintext read error");
+ goto error;
+ }
+ if (status == 1)
+ {
state_change = true;
- dmsg (D_TLS_DEBUG_MED, "STATE S_SENT_KEY");
- ks->state = S_SENT_KEY;
+ dmsg (D_TLS_DEBUG, "TLS -> Incoming Plaintext");
}
+ }
- /* Receive Key */
- buf = &ks->plaintext_read_buf;
- if (buf->len
- && ((ks->state == S_SENT_KEY && !session->opt->server)
- || (ks->state == S_START && session->opt->server)))
+ /* Send Key */
+ buf = &ks->plaintext_write_buf;
+ if (!buf->len && ((ks->state == S_START && !session->opt->server) ||
+ (ks->state == S_GOT_KEY && session->opt->server)))
+ {
+ if (session->opt->key_method == 1)
{
- if (session->opt->key_method == 1)
- {
- if (!key_method_1_read (buf, session))
- goto error;
- }
- else if (session->opt->key_method == 2)
- {
- if (!key_method_2_read (buf, multi, session))
- goto error;
- }
- else
- {
- ASSERT (0);
- }
+ if (!key_method_1_write (buf, session))
+ goto error;
+ }
+ else if (session->opt->key_method == 2)
+ {
+ if (!key_method_2_write (buf, session))
+ goto error;
+ }
+ else
+ {
+ ASSERT (0);
+ }
+
+ state_change = true;
+ dmsg (D_TLS_DEBUG_MED, "STATE S_SENT_KEY");
+ ks->state = S_SENT_KEY;
+ }
+ /* Receive Key */
+ buf = &ks->plaintext_read_buf;
+ if (buf->len
+ && ((ks->state == S_SENT_KEY && !session->opt->server)
+ || (ks->state == S_START && session->opt->server)))
+ {
+ if (session->opt->key_method == 1)
+ {
+ if (!key_method_1_read (buf, session))
+ goto error;
+ }
+ else if (session->opt->key_method == 2)
+ {
+ if (!key_method_2_read (buf, multi, session))
+ goto error;
+ }
+ else
+ {
+ ASSERT (0);
+ }
+
+ state_change = true;
+ dmsg (D_TLS_DEBUG_MED, "STATE S_GOT_KEY");
+ ks->state = S_GOT_KEY;
+ }
+
+ /* Write outgoing plaintext to TLS object */
+ buf = &ks->plaintext_write_buf;
+ if (buf->len)
+ {
+ int status = key_state_write_plaintext (&ks->ks_ssl, buf);
+ if (status == -1)
+ {
+ msg (D_TLS_ERRORS,
+ "TLS ERROR: Outgoing Plaintext -> TLS object write error");
+ goto error;
+ }
+ if (status == 1)
+ {
state_change = true;
- dmsg (D_TLS_DEBUG_MED, "STATE S_GOT_KEY");
- ks->state = S_GOT_KEY;
+ dmsg (D_TLS_DEBUG, "Outgoing Plaintext -> TLS");
}
+ }
- /* Write outgoing plaintext to TLS object */
- buf = &ks->plaintext_write_buf;
- if (buf->len)
+ /* Outgoing Ciphertext to reliable buffer */
+ if (ks->state >= S_START)
+ {
+ buf = reliable_get_buf_output_sequenced (ks->send_reliable);
+ if (buf)
{
- int status = key_state_write_plaintext (&ks->ks_ssl, buf);
+ int status = key_state_read_ciphertext (&ks->ks_ssl, buf, PAYLOAD_SIZE_DYNAMIC (&multi->opt.frame));
if (status == -1)
{
msg (D_TLS_ERRORS,
- "TLS ERROR: Outgoing Plaintext -> TLS object write error");
+ "TLS Error: Ciphertext -> reliable TCP/UDP transport read error");
goto error;
}
if (status == 1)
{
+ reliable_mark_active_outgoing (ks->send_reliable, buf, P_CONTROL_V1);
+ INCR_GENERATED;
state_change = true;
- dmsg (D_TLS_DEBUG, "Outgoing Plaintext -> TLS");
- }
- }
-
- /* Outgoing Ciphertext to reliable buffer */
- if (ks->state >= S_START)
- {
- buf = reliable_get_buf_output_sequenced (ks->send_reliable);
- if (buf)
- {
- int status = key_state_read_ciphertext (&ks->ks_ssl, buf, PAYLOAD_SIZE_DYNAMIC (&multi->opt.frame));
- if (status == -1)
- {
- msg (D_TLS_ERRORS,
- "TLS Error: Ciphertext -> reliable TCP/UDP transport read error");
- goto error;
- }
- if (status == 1)
- {
- reliable_mark_active_outgoing (ks->send_reliable, buf, P_CONTROL_V1);
- INCR_GENERATED;
- state_change = true;
- dmsg (D_TLS_DEBUG, "Outgoing Ciphertext -> Reliable");
- }
+ dmsg (D_TLS_DEBUG, "Outgoing Ciphertext -> Reliable");
}
}
}
@@ -2532,11 +2773,11 @@ tls_process (struct tls_multi *multi,
/* Send 1 or more ACKs (each received control packet gets one ACK) */
if (!to_link->len && !reliable_ack_empty (ks->rec_ack))
{
- buf = &ks->ack_write_buf;
- ASSERT (buf_init (buf, FRAME_HEADROOM (&multi->opt.frame)));
- write_control_auth (session, ks, buf, to_link_addr, P_ACK_V1,
+ struct buffer buf = ks->ack_write_buf;
+ ASSERT (buf_init (&buf, FRAME_HEADROOM (&multi->opt.frame)));
+ write_control_auth (session, ks, &buf, to_link_addr, P_ACK_V1,
RELIABLE_ACK_SIZE, false);
- *to_link = *buf;
+ *to_link = buf;
active = true;
state_change = true;
dmsg (D_TLS_DEBUG, "Dedicated ACK -> TCP/UDP");
@@ -2775,7 +3016,9 @@ bool
tls_pre_decrypt (struct tls_multi *multi,
const struct link_socket_actual *from,
struct buffer *buf,
- struct crypto_options *opt)
+ struct crypto_options **opt,
+ bool floated,
+ const uint8_t **ad_start)
{
struct gc_arena gc = gc_new ();
bool ret = false;
@@ -2819,18 +3062,29 @@ tls_pre_decrypt (struct tls_multi *multi,
#ifdef ENABLE_DEF_AUTH
&& !ks->auth_deferred
#endif
- && link_socket_actual_match (from, &ks->remote_addr))
+ && (floated || link_socket_actual_match (from, &ks->remote_addr)))
{
- /* return appropriate data channel decrypt key in opt */
- opt->key_ctx_bi = &ks->key;
- opt->packet_id = multi->opt.replay ? &ks->packet_id : NULL;
- opt->pid_persist = NULL;
- opt->flags &= multi->opt.crypto_flags_and;
- opt->flags |= multi->opt.crypto_flags_or;
+ if (!ks->crypto_options.key_ctx_bi.initialized)
+ {
+ msg (D_TLS_DEBUG_LOW,
+ "Key %s [%d] not initialized (yet), dropping packet.",
+ print_link_socket_actual (from, &gc), key_id);
+ goto error_lite;
+ }
- ASSERT (buf_advance (buf, 1));
+ /* return appropriate data channel decrypt key in opt */
+ *opt = &ks->crypto_options;
if (op == P_DATA_V2)
{
+ *ad_start = BPTR(buf);
+ }
+ ASSERT (buf_advance (buf, 1));
+ if (op == P_DATA_V1)
+ {
+ *ad_start = BPTR(buf);
+ }
+ else if (op == P_DATA_V2)
+ {
if (buf->len < 4)
{
msg (D_TLS_ERRORS, "Protocol error: received P_DATA_V2 from %s but length is < 4",
@@ -2848,23 +3102,6 @@ tls_pre_decrypt (struct tls_multi *multi,
gc_free (&gc);
return ret;
}
-#if 0 /* keys out of sync? */
- else
- {
- dmsg (D_TLS_ERRORS, "TLS_PRE_DECRYPT: [%d] dken=%d rkid=%d lkid=%d auth=%d def=%d match=%d",
- i,
- DECRYPT_KEY_ENABLED (multi, ks),
- key_id,
- ks->key_id,
- ks->authenticated,
-#ifdef ENABLE_DEF_AUTH
- ks->auth_deferred,
-#else
- -1,
-#endif
- link_socket_actual_match (from, &ks->remote_addr));
- }
-#endif
}
msg (D_TLS_ERRORS,
@@ -2991,8 +3228,10 @@ tls_pre_decrypt (struct tls_multi *multi,
management_set_state (management,
OPENVPN_STATE_AUTH,
NULL,
- 0,
- 0);
+ NULL,
+ NULL,
+ NULL,
+ NULL);
}
#endif
@@ -3036,7 +3275,7 @@ tls_pre_decrypt (struct tls_multi *multi,
goto error;
}
- if (!read_control_auth (buf, &session->tls_auth, from))
+ if (!read_control_auth (buf, &session->tls_wrap, from))
goto error;
/*
@@ -3087,7 +3326,7 @@ tls_pre_decrypt (struct tls_multi *multi,
if (op == P_CONTROL_SOFT_RESET_V1
&& DECRYPT_KEY_ENABLED (multi, ks))
{
- if (!read_control_auth (buf, &session->tls_auth, from))
+ if (!read_control_auth (buf, &session->tls_wrap, from))
goto error;
key_state_soft_reset (session);
@@ -3104,7 +3343,7 @@ tls_pre_decrypt (struct tls_multi *multi,
if (op == P_CONTROL_SOFT_RESET_V1)
do_burst = true;
- if (!read_control_auth (buf, &session->tls_auth, from))
+ if (!read_control_auth (buf, &session->tls_wrap, from))
goto error;
dmsg (D_TLS_DEBUG,
@@ -3215,10 +3454,7 @@ tls_pre_decrypt (struct tls_multi *multi,
done:
buf->len = 0;
- opt->key_ctx_bi = NULL;
- opt->packet_id = NULL;
- opt->pid_persist = NULL;
- opt->flags &= multi->opt.crypto_flags_and;
+ *opt = NULL;
gc_free (&gc);
return ret;
@@ -3297,18 +3533,11 @@ tls_pre_decrypt_lite (const struct tls_auth_standalone *tas,
{
struct buffer newbuf = clone_buf (buf);
- struct crypto_options co = tas->tls_auth_options;
+ struct tls_wrap_ctx tls_wrap_tmp = tas->tls_wrap;
bool status;
- /*
- * We are in read-only mode at this point with respect to TLS
- * control channel state. After we build a new client instance
- * object, we will process this session-initiating packet for real.
- */
- co.flags |= CO_IGNORE_PACKET_ID;
-
/* HMAC test, if --tls-auth was specified */
- status = read_control_auth (&newbuf, &co, from);
+ status = read_control_auth (&newbuf, &tls_wrap_tmp, from);
free_buf (&newbuf);
if (!status)
goto error;
@@ -3344,7 +3573,7 @@ tls_pre_decrypt_lite (const struct tls_auth_standalone *tas,
/* Choose the key with which to encrypt a data packet */
void
tls_pre_encrypt (struct tls_multi *multi,
- struct buffer *buf, struct crypto_options *opt)
+ struct buffer *buf, struct crypto_options **opt)
{
multi->save_ks = NULL;
if (buf->len > 0)
@@ -3356,6 +3585,7 @@ tls_pre_encrypt (struct tls_multi *multi,
struct key_state *ks = multi->key_scan[i];
if (ks->state >= S_ACTIVE
&& ks->authenticated
+ && ks->crypto_options.key_ctx_bi.initialized
#ifdef ENABLE_DEF_AUTH
&& !ks->auth_deferred
#endif
@@ -3373,11 +3603,7 @@ tls_pre_encrypt (struct tls_multi *multi,
if (ks_select)
{
- opt->key_ctx_bi = &ks_select->key;
- opt->packet_id = multi->opt.replay ? &ks_select->packet_id : NULL;
- opt->pid_persist = NULL;
- opt->flags &= multi->opt.crypto_flags_and;
- opt->flags |= multi->opt.crypto_flags_or;
+ *opt = &ks_select->crypto_options;
multi->save_ks = ks_select;
dmsg (D_TLS_KEYSELECT, "TLS: tls_pre_encrypt: key_id=%d", ks_select->key_id);
return;
@@ -3392,36 +3618,48 @@ tls_pre_encrypt (struct tls_multi *multi,
}
buf->len = 0;
- opt->key_ctx_bi = NULL;
- opt->packet_id = NULL;
- opt->pid_persist = NULL;
- opt->flags &= multi->opt.crypto_flags_and;
+ *opt = NULL;
}
-/* Prepend the appropriate opcode to encrypted buffer prior to TCP/UDP send */
void
-tls_post_encrypt (struct tls_multi *multi, struct buffer *buf)
+tls_prepend_opcode_v1 (const struct tls_multi *multi, struct buffer *buf)
{
- struct key_state *ks;
- uint8_t *op;
+ struct key_state *ks = multi->save_ks;
+ uint8_t op;
+
+ msg (D_TLS_DEBUG, __func__);
+
+ ASSERT (ks);
+
+ op = (P_DATA_V1 << P_OPCODE_SHIFT) | ks->key_id;
+ ASSERT (buf_write_prepend (buf, &op, 1));
+}
+
+void
+tls_prepend_opcode_v2 (const struct tls_multi *multi, struct buffer *buf)
+{
+ struct key_state *ks = multi->save_ks;
uint32_t peer;
- ks = multi->save_ks;
+ msg (D_TLS_DEBUG, __func__);
+
+ ASSERT (ks);
+
+ peer = htonl(((P_DATA_V2 << P_OPCODE_SHIFT) | ks->key_id) << 24
+ | (multi->peer_id & 0xFFFFFF));
+ ASSERT (buf_write_prepend (buf, &peer, 4));
+}
+
+void
+tls_post_encrypt (struct tls_multi *multi, struct buffer *buf)
+{
+ struct key_state *ks = multi->save_ks;
multi->save_ks = NULL;
+
if (buf->len > 0)
{
ASSERT (ks);
- if (!multi->opt.server && multi->use_peer_id)
- {
- peer = htonl(((P_DATA_V2 << P_OPCODE_SHIFT) | ks->key_id) << 24 | (multi->peer_id & 0xFFFFFF));
- ASSERT (buf_write_prepend (buf, &peer, 4));
- }
- else
- {
- ASSERT (op = buf_prepend (buf, 1));
- *op = (P_DATA_V1 << P_OPCODE_SHIFT) | ks->key_id;
- }
++ks->n_packets;
ks->n_bytes += buf->len;
}
@@ -3494,6 +3732,70 @@ tls_rec_payload (struct tls_multi *multi,
return ret;
}
+void
+tls_update_remote_addr (struct tls_multi *multi, const struct link_socket_actual *addr)
+{
+ struct gc_arena gc = gc_new ();
+ int i, j;
+
+ for (i = 0; i < TM_SIZE; ++i)
+ {
+ struct tls_session *session = &multi->session[i];
+
+ for (j = 0; j < KS_SIZE; ++j)
+ {
+ struct key_state *ks = &session->key[j];
+
+ if (!link_socket_actual_defined(&ks->remote_addr) ||
+ link_socket_actual_match (addr, &ks->remote_addr))
+ continue;
+
+ dmsg (D_TLS_KEYSELECT, "TLS: tls_update_remote_addr from IP=%s to IP=%s",
+ print_link_socket_actual (&ks->remote_addr, &gc),
+ print_link_socket_actual (addr, &gc));
+
+ ks->remote_addr = *addr;
+ }
+ }
+ gc_free (&gc);
+}
+
+int
+tls_peer_info_ncp_ver(const char *peer_info)
+{
+ const char *ncpstr = peer_info ? strstr (peer_info, "IV_NCP=") : NULL;
+ if (ncpstr)
+ {
+ int ncp = 0;
+ int r = sscanf(ncpstr, "IV_NCP=%d", &ncp);
+ if (r == 1)
+ return ncp;
+ }
+ return 0;
+}
+
+bool
+tls_check_ncp_cipher_list(const char *list) {
+ bool unsupported_cipher_found = false;
+
+ ASSERT (list);
+
+ char * const tmp_ciphers = string_alloc (list, NULL);
+ const char *token = strtok (tmp_ciphers, ":");
+ while (token)
+ {
+ if (!cipher_kt_get (translate_cipher_name_from_openvpn (token)))
+ {
+ msg (M_WARN, "Unsupported cipher in --ncp-ciphers: %s", token);
+ unsupported_cipher_found = true;
+ }
+ token = strtok (NULL, ":");
+ }
+ free (tmp_ciphers);
+
+ return 0 < strlen(list) && !unsupported_cipher_found;
+}
+
/*
* Dump a human-readable rendition of an openvpn packet
* into a garbage collectable string which is returned.
@@ -3594,4 +3896,4 @@ done:
#else
static void dummy(void) {}
-#endif /* ENABLE_CRYPTO && ENABLE_SSL*/
+#endif /* ENABLE_CRYPTO */
diff --git a/src/openvpn/ssl.h b/src/openvpn/ssl.h
index 6a14768..777b621 100644
--- a/src/openvpn/ssl.h
+++ b/src/openvpn/ssl.h
@@ -30,7 +30,7 @@
#ifndef OPENVPN_SSL_H
#define OPENVPN_SSL_H
-#if defined(ENABLE_CRYPTO) && defined(ENABLE_SSL)
+#if defined(ENABLE_CRYPTO)
#include "basic.h"
#include "common.h"
@@ -44,7 +44,6 @@
#include "plugin.h"
#include "ssl_common.h"
-#include "ssl_verify.h"
#include "ssl_backend.h"
/* Used in the TLS PRF function */
@@ -137,8 +136,7 @@
*/
struct tls_auth_standalone
{
- struct key_ctx_bi tls_auth_key;
- struct crypto_options tls_auth_options;
+ struct tls_wrap_ctx tls_wrap;
struct frame frame;
};
@@ -294,9 +292,10 @@ int tls_multi_process (struct tls_multi *multi,
* of this packet.
* @param from - The source address of the packet.
* @param buf - A buffer structure containing the incoming packet.
- * @param opt - A crypto options structure that will be loaded with the
- * appropriate security parameters to handle the packet if it is a
- * data channel packet.
+ * @param opt - Returns a crypto options structure with the appropriate security
+ * parameters to handle the packet if it is a data channel packet.
+ * @param ad_start - Returns a pointer to the start of the authenticated data of
+ * of this packet
*
* @return
* @li True if the packet is a control channel packet that has been
@@ -307,7 +306,9 @@ int tls_multi_process (struct tls_multi *multi,
bool tls_pre_decrypt (struct tls_multi *multi,
const struct link_socket_actual *from,
struct buffer *buf,
- struct crypto_options *opt);
+ struct crypto_options **opt,
+ bool floated,
+ const uint8_t **ad_start);
/**************************************************************************/
@@ -356,20 +357,53 @@ bool tls_pre_decrypt_lite (const struct tls_auth_standalone *tas,
* @ingroup data_crypto
*
* If no appropriate security parameters can be found, or if some other
- * error occurs, then the buffer is set to empty.
+ * error occurs, then the buffer is set to empty, and the parameters to a NULL
+ * pointer.
*
* @param multi - The TLS state for this packet's destination VPN tunnel.
* @param buf - The buffer containing the outgoing packet.
- * @param opt - The crypto options structure into which the appropriate
- * security parameters should be loaded.
+ * @param opt - Returns a crypto options structure with the security parameters.
*/
void tls_pre_encrypt (struct tls_multi *multi,
- struct buffer *buf, struct crypto_options *opt);
+ struct buffer *buf, struct crypto_options **opt);
/**
- * Prepend the one-byte OpenVPN header to the packet, and perform some
- * accounting for the key state used.
+ * Prepend a one-byte OpenVPN data channel P_DATA_V1 opcode to the packet.
+ *
+ * The opcode identifies the packet as a V1 data channel packet and gives the
+ * low-permutation version of the key-id to the recipient, so it knows which
+ * decrypt key to use.
+ *
+ * @param multi - The TLS state for this packet's destination VPN tunnel.
+ * @param buf - The buffer to write the header to.
+ *
+ * @ingroup data_crypto
+ */
+void
+tls_prepend_opcode_v1 (const struct tls_multi *multi, struct buffer *buf);
+
+/**
+ * Prepend an OpenVPN data channel P_DATA_V2 header to the packet. The
+ * P_DATA_V2 header consists of a 1-byte opcode, followed by a 3-byte peer-id.
+ *
+ * The opcode identifies the packet as a V2 data channel packet and gives the
+ * low-permutation version of the key-id to the recipient, so it knows which
+ * decrypt key to use.
+ *
+ * The peer-id is sent by clients to servers to help the server determine to
+ * select the decrypt key when the client is roaming between addresses/ports.
+ *
+ * @param multi - The TLS state for this packet's destination VPN tunnel.
+ * @param buf - The buffer to write the header to.
+ *
+ * @ingroup data_crypto
+ */
+void
+tls_prepend_opcode_v2 (const struct tls_multi *multi, struct buffer *buf);
+
+/**
+ * Perform some accounting for the key state used.
* @ingroup data_crypto
*
* @param multi - The TLS state for this packet's destination VPN tunnel.
@@ -432,6 +466,29 @@ bool tls_send_payload (struct tls_multi *multi,
bool tls_rec_payload (struct tls_multi *multi,
struct buffer *buf);
+/**
+ * Updates remote address in TLS sessions.
+ *
+ * @param multi - Tunnel to update
+ * @param addr - new address
+ */
+void tls_update_remote_addr (struct tls_multi *multi,
+ const struct link_socket_actual *addr);
+
+/**
+ * Update TLS session crypto parameters (cipher and auth) and derive data
+ * channel keys based on the supplied options.
+ *
+ * @param session The TLS session to update.
+ * @param options The options to use when updating session.
+ * @param frame The frame options for this session (frame overhead is
+ * adjusted based on the selected cipher/auth).
+ *
+ * @return true if updating succeeded, false otherwise.
+ */
+bool tls_session_update_crypto_params(struct tls_session *session,
+ const struct options *options, struct frame *frame);
+
#ifdef MANAGEMENT_DEF_AUTH
static inline char *
tls_get_peer_info(const struct tls_multi *multi)
@@ -440,6 +497,21 @@ tls_get_peer_info(const struct tls_multi *multi)
}
#endif
+/**
+ * Return the Negotiable Crypto Parameters version advertised in the peer info
+ * string, or 0 if none specified.
+ */
+int tls_peer_info_ncp_ver(const char *peer_info);
+
+/**
+ * Check whether the ciphers in the supplied list are supported.
+ *
+ * @param list Colon-separated list of ciphers
+ *
+ * @returns true iff all ciphers in list are supported.
+ */
+bool tls_check_ncp_cipher_list(const char *list);
+
/*
* inline functions
*/
@@ -503,6 +575,6 @@ void show_tls_performance_stats(void);
/*#define EXTRACT_X509_FIELD_TEST*/
void extract_x509_field_test (void);
-#endif /* ENABLE_CRYPTO && ENABLE_SSL */
+#endif /* ENABLE_CRYPTO */
#endif
diff --git a/src/openvpn/ssl_backend.h b/src/openvpn/ssl_backend.h
index 4b35e51..0777c61 100644
--- a/src/openvpn/ssl_backend.h
+++ b/src/openvpn/ssl_backend.h
@@ -38,10 +38,10 @@
#include "ssl_verify_openssl.h"
#define SSLAPI SSLAPI_OPENSSL
#endif
-#ifdef ENABLE_CRYPTO_POLARSSL
-#include "ssl_polarssl.h"
-#include "ssl_verify_polarssl.h"
-#define SSLAPI SSLAPI_POLARSSL
+#ifdef ENABLE_CRYPTO_MBEDTLS
+#include "ssl_mbedtls.h"
+#include "ssl_verify_mbedtls.h"
+#define SSLAPI SSLAPI_MBEDTLS
#endif
/* Ensure that SSLAPI got a sane value if SSL is disabled or unknown */
@@ -124,21 +124,21 @@ int tls_version_parse(const char *vstr, const char *extra);
*/
int tls_version_max(void);
+#ifdef ENABLE_CRYPTO
+
/**
* Initialise a library-specific TLS context for a server.
*
* @param ctx TLS context to initialise
- * @param ssl_flags SSLF_x flags from ssl_common.h
*/
-void tls_ctx_server_new(struct tls_root_ctx *ctx, unsigned int ssl_flags);
+void tls_ctx_server_new(struct tls_root_ctx *ctx);
/**
* Initialises a library-specific TLS context for a client.
*
* @param ctx TLS context to initialise
- * @param ssl_flags SSLF_x flags from ssl_common.h
*/
-void tls_ctx_client_new(struct tls_root_ctx *ctx, unsigned int ssl_flags);
+void tls_ctx_client_new(struct tls_root_ctx *ctx);
/**
* Frees the library-specific TLSv1 context
@@ -170,8 +170,9 @@ void 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.
*
- * @param ctx TLS context to restrict
- * @param ciphers String containing : delimited cipher names.
+ * @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(struct tls_root_ctx *ctx, const char *ciphers);
@@ -197,6 +198,16 @@ void tls_ctx_load_dh_params(struct tls_root_ctx *ctx, const char *dh_file,
const char *dh_file_inline);
/**
+ * Load Elliptic Curve Parameters, and load them into the library-specific
+ * TLS context.
+ *
+ * @param ctx TLS context to use
+ * @param curve_name The name of the elliptic curve to load.
+ */
+void tls_ctx_load_ecdh_params(struct tls_root_ctx *ctx, const char *curve_name
+ );
+
+/**
* Load PKCS #12 file for key, cert and (optionally) CA certs, and add to
* library-specific TLS context.
*
@@ -221,7 +232,7 @@ int tls_ctx_load_pkcs12(struct tls_root_ctx *ctx, const char *pkcs12_file,
*/
#ifdef ENABLE_CRYPTOAPI
void tls_ctx_load_cryptoapi(struct tls_root_ctx *ctx, const char *cryptoapi_cert);
-#endif /* WIN32 */
+#endif /* _WIN32 */
/**
* Load certificate file into the given TLS context. If the given certificate
@@ -299,9 +310,9 @@ void tls_ctx_load_extra_certs (struct tls_root_ctx *ctx, const char *extra_certs
const char *extra_certs_file_inline
);
-#ifdef ENABLE_CRYPTO_POLARSSL
+#ifdef ENABLE_CRYPTO_MBEDTLS
/**
- * Add a personalisation string to the PolarSSL RNG, based on the certificate
+ * Add a personalisation string to the mbed TLS RNG, based on the certificate
* loaded into the given context.
*
* @param ctx TLS context to use
@@ -334,6 +345,30 @@ void key_state_ssl_init(struct key_state_ssl *ks_ssl,
*/
void key_state_ssl_free(struct key_state_ssl *ks_ssl);
+/**
+ * Reload the Certificate Revocation List for the SSL channel
+ *
+ * @param ssl_ctx The TLS context to use when reloading the CRL
+ * @param crl_file The file name to load the CRL from, or
+ * "[[INLINE]]" in the case of inline files.
+ * @param crl_inline A string containing the CRL
+ */
+void tls_ctx_reload_crl(struct tls_root_ctx *ssl_ctx,
+ const char *crl_file, const char *crl_inline);
+
+/**
+ * Keying Material Exporters [RFC 5705] allows additional keying material to be
+ * derived from existing TLS channel. This exported keying material can then be
+ * used for a variety of purposes.
+ *
+ * @param ks_ssl The SSL channel's state info
+ * @param session The session associated with the given key_state
+ */
+
+void
+key_state_export_keying_material(struct key_state_ssl *ks_ssl,
+ struct tls_session *session) __attribute__((nonnull));
+
/**************************************************************************/
/** @addtogroup control_tls
* @{ */
@@ -472,6 +507,11 @@ void print_details (struct key_state_ssl * ks_ssl, const char *prefix);
void show_available_tls_ciphers (const char *tls_ciphers);
/*
+ * Show the available elliptic curves in the crypto library
+ */
+void show_available_curves (void);
+
+/*
* The OpenSSL library has a notion of preference in TLS ciphers. Higher
* preference == more secure. Return the highest preference cipher.
*/
@@ -483,4 +523,5 @@ void get_highest_preference_tls_cipher (char *buf, int size);
*/
const char * get_ssl_library_version(void);
+#endif /* ENABLE_CRYPTO */
#endif /* SSL_BACKEND_H_ */
diff --git a/src/openvpn/ssl_common.h b/src/openvpn/ssl_common.h
index 449172d..28702af 100644
--- a/src/openvpn/ssl_common.h
+++ b/src/openvpn/ssl_common.h
@@ -149,7 +149,12 @@ struct key_source2 {
struct key_state
{
int state;
- int key_id; /* inherited from struct tls_session below */
+
+ /**
+ * Key id for this key_state, inherited from struct tls_session.
+ * @see tls_session::key_id.
+ */
+ int key_id;
struct key_state_ssl ks_ssl; /* contains SSL object and BIOs for the control channel */
@@ -160,9 +165,8 @@ struct key_state
int initial_opcode; /* our initial P_ opcode */
struct session_id session_id_remote; /* peer's random session ID */
struct link_socket_actual remote_addr; /* peer's IP addr */
- struct packet_id packet_id; /* for data channel, to prevent replay attacks */
- struct key_ctx_bi key; /* data channel keys for encrypt/decrypt/hmac */
+ struct crypto_options crypto_options;/* data channel crypto options */
struct key_source2 *key_src; /* source entropy for key expansion */
@@ -200,6 +204,18 @@ struct key_state
#endif
};
+/** Control channel wrapping (--tls-auth/--tls-crypt) context */
+struct tls_wrap_ctx
+{
+ enum {
+ TLS_WRAP_NONE = 0, /**< No control channel wrapping */
+ TLS_WRAP_AUTH, /**< Control channel authentication */
+ TLS_WRAP_CRYPT, /**< Control channel encryption and authentication */
+ } mode; /**< Control channel wrapping mode */
+ struct crypto_options opt; /**< Crypto state */
+ struct buffer work; /**< Work buffer (only for --tls-crypt) */
+};
+
/*
* Our const options, obtained directly or derived from
* command line options.
@@ -232,6 +248,8 @@ struct tls_options
#ifdef ENABLE_OCC
bool disable_occ;
#endif
+ int mode;
+ bool pull;
#ifdef ENABLE_PUSH_PEER_INFO
int push_peer_info_detail;
#endif
@@ -248,6 +266,7 @@ struct tls_options
int verify_x509_type;
const char *verify_x509_name;
const char *crl_file;
+ const char *crl_file_inline;
int ns_cert_type;
unsigned remote_cert_ku[MAX_PARMS];
const char *remote_cert_eku;
@@ -259,6 +278,7 @@ struct tls_options
bool pass_config_info;
/* struct crypto_option flags */
+ unsigned int crypto_flags;
unsigned int crypto_flags_and;
unsigned int crypto_flags_or;
@@ -266,9 +286,12 @@ struct tls_options
int replay_time; /* --replay-window parm */
bool tcp_mode;
- /* packet authentication for TLS handshake */
- struct crypto_options tls_auth;
- struct key_ctx_bi tls_auth_key;
+ const char *config_ciphername;
+ const char *config_authname;
+ bool ncp_enabled;
+
+ /** TLS handshake wrapping state */
+ struct tls_wrap_ctx tls_wrap;
/* frame parameters for TLS control channel */
struct frame frame;
@@ -278,6 +301,9 @@ struct tls_options
bool auth_user_pass_verify_script_via_file;
const char *tmp_dir;
const char *auth_user_pass_file;
+ bool auth_token_generate; /**< Generate auth-tokens on successful user/pass auth,
+ * set via options->auth_token_generate. */
+ unsigned int auth_token_lifetime;
/* use the client-config-dir as a positive authenticator */
const char *client_config_dir_exclusive;
@@ -286,10 +312,16 @@ struct tls_options
struct env_set *es;
const struct plugin_list *plugins;
+ /* compression parms */
+#ifdef USE_COMP
+ struct compress_options comp_options;
+#endif
+
/* configuration file SSL-related boolean and low-permutation options */
# define SSLF_CLIENT_CERT_NOT_REQUIRED (1<<0)
-# define SSLF_USERNAME_AS_COMMON_NAME (1<<1)
-# define SSLF_AUTH_USER_PASS_OPTIONAL (1<<2)
+# define SSLF_CLIENT_CERT_OPTIONAL (1<<1)
+# define SSLF_USERNAME_AS_COMMON_NAME (1<<2)
+# define SSLF_AUTH_USER_PASS_OPTIONAL (1<<3)
# define SSLF_OPT_VERIFY (1<<4)
# define SSLF_CRL_VERIFY_DIR (1<<5)
# define SSLF_TLS_VERSION_MIN_SHIFT 6
@@ -302,9 +334,7 @@ struct tls_options
struct man_def_auth_context *mda_context;
#endif
-#ifdef ENABLE_X509_TRACK
const struct x509_track *x509_track;
-#endif
#ifdef ENABLE_CLIENT_CR
const struct static_challenge_info *sci;
@@ -312,6 +342,11 @@ struct tls_options
/* --gremlin bits */
int gremlin;
+
+ /* Keying Material Exporter [RFC 5705] parameters */
+ const char *ekm_label;
+ size_t ekm_label_size;
+ size_t ekm_size;
};
/** @addtogroup control_processor
@@ -328,6 +363,9 @@ struct tls_options
/** @} name Index of key_state objects within a tls_session structure */
/** @} addtogroup control_processor */
+#define AUTH_TOKEN_SIZE 32 /**< Size of server side generated auth tokens.
+ * 32 bytes == 256 bits
+ */
/**
* Security parameter state of a single session within a VPN tunnel.
@@ -354,12 +392,17 @@ struct tls_session
bool burst;
/* authenticate control packets */
- struct crypto_options tls_auth;
- struct packet_id tls_auth_pid;
+ struct tls_wrap_ctx tls_wrap;
int initial_opcode; /* our initial P_ opcode */
struct session_id session_id; /* our random session ID */
- int key_id; /* increments with each soft reset (for key renegotiation) */
+
+ /**
+ * The current active key id, used to keep track of renegotiations.
+ * key_id increments with each soft reset to KEY_ID_MASK then recycles back
+ * to 1. This way you know that if key_id is 0, it is the first key.
+ */
+ int key_id;
int limit_next; /* used for traffic shaping on the control channel */
@@ -481,20 +524,29 @@ struct tls_multi
*/
char *client_reason;
+ /* Time of last call to tls_authentication_status */
+ time_t tas_last;
+#endif
+
+#if P2MP_SERVER
/*
* A multi-line string of general-purpose info received from peer
* over control channel.
*/
char *peer_info;
-
- /* Time of last call to tls_authentication_status */
- time_t tas_last;
#endif
/* For P_DATA_V2 */
uint32_t peer_id;
bool use_peer_id;
+ char *auth_token; /**< If server sends a generated auth-token,
+ * this is the token to use for future
+ * user/pass authentications in this session.
+ */
+ time_t auth_token_tstamp; /**< timestamp of the generated token */
+ bool auth_token_sent; /**< If server uses --auth-gen-token and
+ * token has been sent to client */
/*
* Our session objects.
*/
diff --git a/src/openvpn/ssl_polarssl.c b/src/openvpn/ssl_mbedtls.c
index 1f58369..7fa35a7 100644
--- a/src/openvpn/ssl_polarssl.c
+++ b/src/openvpn/ssl_mbedtls.c
@@ -25,7 +25,7 @@
*/
/**
- * @file Control Channel PolarSSL Backend
+ * @file Control Channel mbed TLS Backend
*/
#ifdef HAVE_CONFIG_H
@@ -36,7 +36,7 @@
#include "syshead.h"
-#if defined(ENABLE_SSL) && defined(ENABLE_CRYPTO_POLARSSL)
+#if defined(ENABLE_CRYPTO) && defined(ENABLE_CRYPTO_MBEDTLS)
#include "errlevel.h"
#include "ssl_backend.h"
@@ -46,15 +46,16 @@
#include "manage.h"
#include "ssl_common.h"
-#include <polarssl/havege.h>
+#include <mbedtls/havege.h>
-#include "ssl_verify_polarssl.h"
-#include <polarssl/debug.h>
-#include <polarssl/error.h>
-#include <polarssl/oid.h>
-#include <polarssl/pem.h>
-#include <polarssl/sha256.h>
-#include <polarssl/version.h>
+#include "ssl_verify_mbedtls.h"
+#include <mbedtls/debug.h>
+#include <mbedtls/error.h>
+#include <mbedtls/net.h>
+#include <mbedtls/oid.h>
+#include <mbedtls/pem.h>
+#include <mbedtls/sha256.h>
+#include <mbedtls/version.h>
void
tls_init_lib()
@@ -72,29 +73,29 @@ tls_clear_error()
}
void
-tls_ctx_server_new(struct tls_root_ctx *ctx, unsigned int ssl_flags)
+tls_ctx_server_new(struct tls_root_ctx *ctx)
{
ASSERT(NULL != ctx);
CLEAR(*ctx);
- ALLOC_OBJ_CLEAR(ctx->dhm_ctx, dhm_context);
+ ALLOC_OBJ_CLEAR(ctx->dhm_ctx, mbedtls_dhm_context);
- ALLOC_OBJ_CLEAR(ctx->ca_chain, x509_crt);
+ ALLOC_OBJ_CLEAR(ctx->ca_chain, mbedtls_x509_crt);
- ctx->endpoint = SSL_IS_SERVER;
+ ctx->endpoint = MBEDTLS_SSL_IS_SERVER;
ctx->initialised = true;
}
void
-tls_ctx_client_new(struct tls_root_ctx *ctx, unsigned int ssl_flags)
+tls_ctx_client_new(struct tls_root_ctx *ctx)
{
ASSERT(NULL != ctx);
CLEAR(*ctx);
- ALLOC_OBJ_CLEAR(ctx->dhm_ctx, dhm_context);
- ALLOC_OBJ_CLEAR(ctx->ca_chain, x509_crt);
+ ALLOC_OBJ_CLEAR(ctx->dhm_ctx, mbedtls_dhm_context);
+ ALLOC_OBJ_CLEAR(ctx->ca_chain, mbedtls_x509_crt);
- ctx->endpoint = SSL_IS_CLIENT;
+ ctx->endpoint = MBEDTLS_SSL_IS_CLIENT;
ctx->initialised = true;
}
@@ -103,25 +104,31 @@ tls_ctx_free(struct tls_root_ctx *ctx)
{
if (ctx)
{
- pk_free(ctx->priv_key);
+ mbedtls_pk_free(ctx->priv_key);
if (ctx->priv_key)
free(ctx->priv_key);
- x509_crt_free(ctx->ca_chain);
+ mbedtls_x509_crt_free(ctx->ca_chain);
if (ctx->ca_chain)
free(ctx->ca_chain);
- x509_crt_free(ctx->crt_chain);
+ mbedtls_x509_crt_free(ctx->crt_chain);
if (ctx->crt_chain)
free(ctx->crt_chain);
- dhm_free(ctx->dhm_ctx);
+ mbedtls_dhm_free(ctx->dhm_ctx);
if (ctx->dhm_ctx)
free(ctx->dhm_ctx);
+ mbedtls_x509_crl_free(ctx->crl);
+ if (ctx->crl)
+ {
+ free(ctx->crl);
+ }
+
#if defined(ENABLE_PKCS11)
if (ctx->priv_key_pkcs11 != NULL) {
- pkcs11_priv_key_free(ctx->priv_key_pkcs11);
+ mbedtls_pkcs11_priv_key_free(ctx->priv_key_pkcs11);
free(ctx->priv_key_pkcs11);
}
#endif
@@ -148,6 +155,12 @@ tls_ctx_initialised(struct tls_root_ctx *ctx)
}
void
+key_state_export_keying_material(struct key_state_ssl *ssl,
+ struct tls_session *session)
+{
+}
+
+void
tls_ctx_set_options (struct tls_root_ctx *ctx, unsigned int ssl_flags)
{
}
@@ -176,7 +189,12 @@ tls_ctx_restrict_ciphers(struct tls_root_ctx *ctx, const char *ciphers)
{
char *tmp_ciphers, *tmp_ciphers_orig, *token;
int i, cipher_count;
- int ciphers_len = strlen (ciphers);
+ int ciphers_len;
+
+ if (NULL == ciphers)
+ return; /* Nothing to do */
+
+ ciphers_len = strlen (ciphers);
ASSERT (NULL != ctx);
ASSERT (0 != ciphers_len);
@@ -196,7 +214,7 @@ tls_ctx_restrict_ciphers(struct tls_root_ctx *ctx, const char *ciphers)
token = strtok (tmp_ciphers, ":");
while(token)
{
- ctx->allowed_ciphers[i] = ssl_get_ciphersuite_id (
+ ctx->allowed_ciphers[i] = mbedtls_ssl_get_ciphersuite_id (
tls_translate_cipher_name (token));
if (0 != ctx->allowed_ciphers[i])
i++;
@@ -214,12 +232,12 @@ tls_ctx_check_cert_time (const struct tls_root_ctx *ctx)
return; /* Nothing to check if there is no certificate */
}
- if (x509_time_future (&ctx->crt_chain->valid_from))
+ if (mbedtls_x509_time_is_future (&ctx->crt_chain->valid_from))
{
msg (M_WARN, "WARNING: Your certificate is not yet valid!");
}
- if (x509_time_expired (&ctx->crt_chain->valid_to))
+ if (mbedtls_x509_time_is_past (&ctx->crt_chain->valid_to))
{
msg (M_WARN, "WARNING: Your certificate has expired!");
}
@@ -232,18 +250,27 @@ tls_ctx_load_dh_params (struct tls_root_ctx *ctx, const char *dh_file,
{
if (!strcmp (dh_file, INLINE_FILE_TAG) && dh_inline)
{
- if (!polar_ok(dhm_parse_dhm(ctx->dhm_ctx,
- (const unsigned char *) dh_inline, strlen(dh_inline))))
+ if (!mbed_ok(mbedtls_dhm_parse_dhm(ctx->dhm_ctx,
+ (const unsigned char *) dh_inline, strlen(dh_inline)+1)))
msg (M_FATAL, "Cannot read inline DH parameters");
}
else
{
- if (!polar_ok(dhm_parse_dhmfile(ctx->dhm_ctx, dh_file)))
+ if (!mbed_ok(mbedtls_dhm_parse_dhmfile(ctx->dhm_ctx, dh_file)))
msg (M_FATAL, "Cannot read DH parameters from file %s", dh_file);
}
msg (D_TLS_DEBUG_LOW, "Diffie-Hellman initialized with " counter_format " bit key",
- (counter_type) 8 * mpi_size(&ctx->dhm_ctx->P));
+ (counter_type) 8 * mbedtls_mpi_size(&ctx->dhm_ctx->P));
+}
+
+void
+tls_ctx_load_ecdh_params (struct tls_root_ctx *ctx, const char *curve_name
+ )
+{
+ if (NULL != curve_name)
+ msg(M_WARN, "WARNING: mbed TLS builds do not support specifying an ECDH "
+ "curve, using default curves.");
}
int
@@ -252,7 +279,7 @@ tls_ctx_load_pkcs12(struct tls_root_ctx *ctx, const char *pkcs12_file,
bool load_ca_file
)
{
- msg(M_FATAL, "PKCS #12 files not yet supported for PolarSSL.");
+ msg(M_FATAL, "PKCS #12 files not yet supported for mbed TLS.");
return 0;
}
@@ -260,9 +287,9 @@ tls_ctx_load_pkcs12(struct tls_root_ctx *ctx, const char *pkcs12_file,
void
tls_ctx_load_cryptoapi(struct tls_root_ctx *ctx, const char *cryptoapi_cert)
{
- msg(M_FATAL, "Windows CryptoAPI not yet supported for PolarSSL.");
+ msg(M_FATAL, "Windows CryptoAPI not yet supported for mbed TLS.");
}
-#endif /* WIN32 */
+#endif /* _WIN32 */
void
tls_ctx_load_cert_file (struct tls_root_ctx *ctx, const char *cert_file,
@@ -273,18 +300,18 @@ tls_ctx_load_cert_file (struct tls_root_ctx *ctx, const char *cert_file,
if (!ctx->crt_chain)
{
- ALLOC_OBJ_CLEAR(ctx->crt_chain, x509_crt);
+ ALLOC_OBJ_CLEAR(ctx->crt_chain, mbedtls_x509_crt);
}
if (!strcmp (cert_file, INLINE_FILE_TAG) && cert_inline)
{
- if (!polar_ok(x509_crt_parse(ctx->crt_chain,
- (const unsigned char *) cert_inline, strlen(cert_inline))))
+ if (!mbed_ok(mbedtls_x509_crt_parse(ctx->crt_chain,
+ (const unsigned char *) cert_inline, strlen(cert_inline)+1)))
msg (M_FATAL, "Cannot load inline certificate file");
}
else
{
- if (!polar_ok(x509_crt_parse_file(ctx->crt_chain, cert_file)))
+ if (!mbed_ok(mbedtls_x509_crt_parse_file(ctx->crt_chain, cert_file)))
{
msg (M_FATAL, "Cannot load certificate file %s", cert_file);
}
@@ -301,51 +328,51 @@ tls_ctx_load_priv_file (struct tls_root_ctx *ctx, const char *priv_key_file,
if (!ctx->priv_key)
{
- ALLOC_OBJ_CLEAR(ctx->priv_key, pk_context);
+ ALLOC_OBJ_CLEAR(ctx->priv_key, mbedtls_pk_context);
}
if (!strcmp (priv_key_file, INLINE_FILE_TAG) && priv_key_inline)
{
- status = pk_parse_key(ctx->priv_key,
- (const unsigned char *) priv_key_inline, strlen(priv_key_inline),
+ status = mbedtls_pk_parse_key(ctx->priv_key,
+ (const unsigned char *) priv_key_inline, strlen(priv_key_inline)+1,
NULL, 0);
- if (POLARSSL_ERR_PK_PASSWORD_REQUIRED == status)
+ if (MBEDTLS_ERR_PK_PASSWORD_REQUIRED == status)
{
char passbuf[512] = {0};
pem_password_callback(passbuf, 512, 0, NULL);
- status = pk_parse_key(ctx->priv_key,
- (const unsigned char *) priv_key_inline, strlen(priv_key_inline),
- (unsigned char *) passbuf, strlen(passbuf));
+ status = mbedtls_pk_parse_key(ctx->priv_key,
+ (const unsigned char *) priv_key_inline,
+ strlen(priv_key_inline)+1, (unsigned char *) passbuf,
+ strlen(passbuf));
}
}
else
{
- status = pk_parse_keyfile(ctx->priv_key, priv_key_file, NULL);
- if (POLARSSL_ERR_PK_PASSWORD_REQUIRED == status)
+ status = mbedtls_pk_parse_keyfile(ctx->priv_key, priv_key_file, NULL);
+ if (MBEDTLS_ERR_PK_PASSWORD_REQUIRED == status)
{
char passbuf[512] = {0};
pem_password_callback(passbuf, 512, 0, NULL);
- status = pk_parse_keyfile(ctx->priv_key, priv_key_file, passbuf);
+ status = mbedtls_pk_parse_keyfile(ctx->priv_key, priv_key_file, passbuf);
}
}
- if (!polar_ok(status))
+ if (!mbed_ok(status))
{
#ifdef ENABLE_MANAGEMENT
- if (management && (POLARSSL_ERR_PK_PASSWORD_MISMATCH == status))
+ if (management && (MBEDTLS_ERR_PK_PASSWORD_MISMATCH == status))
management_auth_failure (management, UP_TYPE_PRIVATE_KEY, NULL);
#endif
msg (M_WARN, "Cannot load private key file %s", priv_key_file);
return 1;
}
- warn_if_group_others_accessible (priv_key_file);
+ if (!mbed_ok(mbedtls_pk_check_pair(&ctx->crt_chain->pk, ctx->priv_key)))
+ {
+ msg (M_WARN, "Private key does not match the certificate");
+ return 1;
+ }
- /* TODO: Check Private Key */
-#if 0
- if (!SSL_CTX_check_private_key (ctx))
- msg (M_SSLERR, "Private key does not match the certificate");
-#endif
return 0;
}
@@ -357,7 +384,7 @@ struct external_context {
};
/**
- * external_pkcs1_sign implements a PolarSSL rsa_sign_func callback, that uses
+ * external_pkcs1_sign implements a mbed TLS rsa_sign_func callback, that uses
* the management interface to request an RSA signature for the supplied hash.
*
* @param ctx_voidptr Management external key context.
@@ -366,18 +393,18 @@ struct external_context {
* @param mode RSA mode (should be RSA_PRIVATE).
* @param md_alg Message digest ('hash') algorithm type.
* @param hashlen Length of hash (overridden by length specified by md_alg
- * if md_alg != POLARSSL_MD_NONE).
+ * if md_alg != MBEDTLS_MD_NONE).
* @param hash The digest ('hash') to sign. Should have a size
- * matching the length of md_alg (if != POLARSSL_MD_NONE),
+ * matching the length of md_alg (if != MBEDTLS_MD_NONE),
* or hashlen otherwise.
* @param sig Buffer that returns the signature. Should be at least of
* size ctx->signature_length.
*
- * @return 0 on success, non-zero polarssl error code on failure.
+ * @return 0 on success, non-zero mbed TLS error code on failure.
*/
static inline int external_pkcs1_sign( void *ctx_voidptr,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, int mode,
- md_type_t md_alg, unsigned int hashlen, const unsigned char *hash,
+ mbedtls_md_type_t md_alg, unsigned int hashlen, const unsigned char *hash,
unsigned char *sig )
{
struct external_context * const ctx = ctx_voidptr;
@@ -389,35 +416,35 @@ static inline int external_pkcs1_sign( void *ctx_voidptr,
const char *oid = NULL;
if( NULL == ctx )
- return POLARSSL_ERR_RSA_BAD_INPUT_DATA;
+ return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
- if( RSA_PRIVATE != mode )
- return POLARSSL_ERR_RSA_BAD_INPUT_DATA;
+ if( MBEDTLS_RSA_PRIVATE != mode )
+ return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
/*
* Support a wide range of hashes. TLSv1.1 and before only need SIG_RSA_RAW,
* but TLSv1.2 needs the full suite of hashes.
*
- * This code has been taken from PolarSSL pkcs11_sign(), under the GPLv2.0+.
+ * This code has been taken from mbed TLS pkcs11_sign(), under the GPLv2.0+.
*/
- if( md_alg != POLARSSL_MD_NONE )
+ if( md_alg != MBEDTLS_MD_NONE )
{
- const md_info_t *md_info = md_info_from_type( md_alg );
+ const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( md_alg );
if( md_info == NULL )
- return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
+ return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
- if (!polar_ok(oid_get_oid_by_md( md_alg, &oid, &oid_size )))
- return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
+ if (!mbed_ok(mbedtls_oid_get_oid_by_md( md_alg, &oid, &oid_size )))
+ return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
- hashlen = md_get_size( md_info );
+ hashlen = mbedtls_md_get_size( md_info );
asn_len = 10 + oid_size;
}
sig_len = ctx->signature_length;
if ( (SIZE_MAX - hashlen) < asn_len || (hashlen + asn_len) > sig_len )
- return POLARSSL_ERR_RSA_BAD_INPUT_DATA;
+ return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
- if( md_alg != POLARSSL_MD_NONE )
+ if( md_alg != MBEDTLS_MD_NONE )
{
/*
* DigestInfo ::= SEQUENCE {
@@ -428,17 +455,17 @@ static inline int external_pkcs1_sign( void *ctx_voidptr,
*
* Digest ::= OCTET STRING
*/
- *p++ = ASN1_SEQUENCE | ASN1_CONSTRUCTED;
+ *p++ = MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED;
*p++ = (unsigned char) ( 0x08 + oid_size + hashlen );
- *p++ = ASN1_SEQUENCE | ASN1_CONSTRUCTED;
+ *p++ = MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED;
*p++ = (unsigned char) ( 0x04 + oid_size );
- *p++ = ASN1_OID;
+ *p++ = MBEDTLS_ASN1_OID;
*p++ = oid_size & 0xFF;
memcpy( p, oid, oid_size );
p += oid_size;
- *p++ = ASN1_NULL;
+ *p++ = MBEDTLS_ASN1_NULL;
*p++ = 0x00;
- *p++ = ASN1_OCTET_STRING;
+ *p++ = MBEDTLS_ASN1_OCTET_STRING;
*p++ = hashlen;
/* Determine added ASN length */
@@ -451,7 +478,7 @@ static inline int external_pkcs1_sign( void *ctx_voidptr,
/* convert 'from' to base64 */
if (openvpn_base64_encode (sig, asn_len + hashlen, &in_b64) <= 0)
{
- rv = POLARSSL_ERR_RSA_BAD_INPUT_DATA;
+ rv = MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
goto done;
}
@@ -460,7 +487,7 @@ static inline int external_pkcs1_sign( void *ctx_voidptr,
out_b64 = management_query_rsa_sig (management, in_b64);
if (!out_b64)
{
- rv = POLARSSL_ERR_RSA_PRIVATE_FAILED;
+ rv = MBEDTLS_ERR_RSA_PRIVATE_FAILED;
goto done;
}
@@ -468,7 +495,7 @@ static inline int external_pkcs1_sign( void *ctx_voidptr,
if ( openvpn_base64_decode (out_b64, sig, ctx->signature_length) !=
ctx->signature_length )
{
- rv = POLARSSL_ERR_RSA_PRIVATE_FAILED;
+ rv = MBEDTLS_ERR_RSA_PRIVATE_FAILED;
goto done;
}
@@ -501,10 +528,10 @@ tls_ctx_use_external_private_key (struct tls_root_ctx *ctx,
return 0;
ALLOC_OBJ_CLEAR (ctx->external_key, struct external_context);
- ctx->external_key->signature_length = pk_get_len(&ctx->crt_chain->pk);
+ ctx->external_key->signature_length = mbedtls_pk_get_len (&ctx->crt_chain->pk);
- ALLOC_OBJ_CLEAR (ctx->priv_key, pk_context);
- if (!polar_ok (pk_init_ctx_rsa_alt(ctx->priv_key, ctx->external_key,
+ ALLOC_OBJ_CLEAR (ctx->priv_key, mbedtls_pk_context);
+ if (!mbed_ok (mbedtls_pk_setup_rsa_alt (ctx->priv_key, ctx->external_key,
NULL, external_pkcs1_sign, external_key_len)))
return 0;
@@ -513,21 +540,22 @@ tls_ctx_use_external_private_key (struct tls_root_ctx *ctx,
#endif
void tls_ctx_load_ca (struct tls_root_ctx *ctx, const char *ca_file,
- const char *ca_inline, const char *ca_path, bool tls_server)
+ const char *ca_inline, const char *ca_path, bool tls_server
+ )
{
if (ca_path)
- msg(M_FATAL, "ERROR: PolarSSL cannot handle the capath directive");
+ msg(M_FATAL, "ERROR: mbed TLS cannot handle the capath directive");
if (ca_file && !strcmp (ca_file, INLINE_FILE_TAG) && ca_inline)
{
- if (!polar_ok(x509_crt_parse(ctx->ca_chain,
- (const unsigned char *) ca_inline, strlen(ca_inline))))
+ if (!mbed_ok (mbedtls_x509_crt_parse (ctx->ca_chain,
+ (const unsigned char *) ca_inline, strlen(ca_inline)+1)))
msg (M_FATAL, "Cannot load inline CA certificates");
}
else
{
/* Load CA file for verifying peer supplied certificate */
- if (!polar_ok(x509_crt_parse_file(ctx->ca_chain, ca_file)))
+ if (!mbed_ok (mbedtls_x509_crt_parse_file (ctx->ca_chain, ca_file)))
msg (M_FATAL, "Cannot load CA certificate file %s", ca_file);
}
}
@@ -541,19 +569,19 @@ tls_ctx_load_extra_certs (struct tls_root_ctx *ctx, const char *extra_certs_file
if (!ctx->crt_chain)
{
- ALLOC_OBJ_CLEAR (ctx->crt_chain, x509_crt);
+ ALLOC_OBJ_CLEAR (ctx->crt_chain, mbedtls_x509_crt);
}
if (!strcmp (extra_certs_file, INLINE_FILE_TAG) && extra_certs_inline)
{
- if (!polar_ok(x509_crt_parse(ctx->crt_chain,
+ if (!mbed_ok(mbedtls_x509_crt_parse(ctx->crt_chain,
(const unsigned char *) extra_certs_inline,
- strlen(extra_certs_inline))))
+ strlen(extra_certs_inline)+1)))
msg (M_FATAL, "Cannot load inline extra-certs file");
}
else
{
- if (!polar_ok(x509_crt_parse_file(ctx->crt_chain, extra_certs_file)))
+ if (!mbed_ok(mbedtls_x509_crt_parse_file(ctx->crt_chain, extra_certs_file)))
msg (M_FATAL, "Cannot load extra-certs file: %s", extra_certs_file);
}
}
@@ -588,13 +616,12 @@ static void buf_free_entries(endless_buffer *buf)
buf->last_block = NULL;
}
-static int endless_buf_read( void * ctx, unsigned char * out, size_t out_len )
+static int endless_buf_read( endless_buffer *in, unsigned char * out, size_t out_len )
{
- endless_buffer *in = (endless_buffer *) ctx;
size_t read_len = 0;
if (in->first_block == NULL)
- return POLARSSL_ERR_NET_WANT_READ;
+ return MBEDTLS_ERR_SSL_WANT_READ;
while (in->first_block != NULL && read_len < out_len)
{
@@ -627,18 +654,17 @@ static int endless_buf_read( void * ctx, unsigned char * out, size_t out_len )
return read_len;
}
-static int endless_buf_write( void *ctx, const unsigned char *in, size_t len )
+static int endless_buf_write( endless_buffer *out, const unsigned char *in, size_t len )
{
- endless_buffer *out = (endless_buffer *) ctx;
buffer_entry *new_block = malloc(sizeof(buffer_entry));
if (NULL == new_block)
- return POLARSSL_ERR_NET_SEND_FAILED;
+ return MBEDTLS_ERR_NET_SEND_FAILED;
new_block->data = malloc(len);
if (NULL == new_block->data)
{
free(new_block);
- return POLARSSL_ERR_NET_SEND_FAILED;
+ return MBEDTLS_ERR_NET_SEND_FAILED;
}
new_block->length = len;
@@ -657,10 +683,23 @@ static int endless_buf_write( void *ctx, const unsigned char *in, size_t len )
return len;
}
-static void my_debug( void *ctx, int level, const char *str )
+static int ssl_bio_read( void *ctx, unsigned char *out, size_t out_len)
+{
+ bio_ctx *my_ctx = (bio_ctx *) ctx;
+ return endless_buf_read (&my_ctx->in, out, out_len);
+}
+
+static int ssl_bio_write( void *ctx, const unsigned char *in, size_t in_len)
+{
+ bio_ctx *my_ctx = (bio_ctx *) ctx;
+ return endless_buf_write (&my_ctx->out, in, in_len);
+}
+
+static void my_debug( void *ctx, int level, const char *file, int line,
+ const char *str )
{
int my_loglevel = (level < 3) ? D_TLS_DEBUG_MED : D_TLS_DEBUG;
- msg (my_loglevel, "PolarSSL msg: %s", str);
+ msg (my_loglevel, "mbed TLS msg (%s:%d): %s", file, line, str);
}
/*
@@ -670,16 +709,16 @@ void tls_ctx_personalise_random(struct tls_root_ctx *ctx)
{
static char old_sha256_hash[32] = {0};
unsigned char sha256_hash[32] = {0};
- ctr_drbg_context *cd_ctx = rand_ctx_get();
+ mbedtls_ctr_drbg_context *cd_ctx = rand_ctx_get();
if (NULL != ctx->crt_chain)
{
- x509_crt *cert = ctx->crt_chain;
+ mbedtls_x509_crt *cert = ctx->crt_chain;
- sha256(cert->tbs.p, cert->tbs.len, sha256_hash, false);
+ mbedtls_sha256(cert->tbs.p, cert->tbs.len, sha256_hash, false);
if ( 0 != memcmp(old_sha256_hash, sha256_hash, sizeof(sha256_hash)))
{
- ctr_drbg_update(cd_ctx, sha256_hash, 32);
+ mbedtls_ctr_drbg_update(cd_ctx, sha256_hash, 32);
memcpy(old_sha256_hash, sha256_hash, sizeof(old_sha256_hash));
}
}
@@ -688,9 +727,9 @@ void tls_ctx_personalise_random(struct tls_root_ctx *ctx)
int
tls_version_max(void)
{
-#if defined(SSL_MAJOR_VERSION_3) && defined(SSL_MINOR_VERSION_3)
+#if defined(MBEDTLS_SSL_MAJOR_VERSION_3) && defined(MBEDTLS_SSL_MINOR_VERSION_3)
return TLS_VER_1_2;
-#elif defined(SSL_MAJOR_VERSION_3) && defined(SSL_MINOR_VERSION_2)
+#elif defined(MBEDTLS_SSL_MAJOR_VERSION_3) && defined(MBEDTLS_SSL_MINOR_VERSION_2)
return TLS_VER_1_1;
#else
return TLS_VER_1_0;
@@ -698,13 +737,13 @@ tls_version_max(void)
}
/**
- * Convert an OpenVPN tls-version variable to PolarSSl format (i.e. a major and
+ * Convert an OpenVPN tls-version variable to mbed TLS format (i.e. a major and
* minor ssl version number).
*
* @param tls_ver The tls-version variable to convert.
- * @param major Returns the TLS major version in polarssl format.
+ * @param major Returns the TLS major version in mbed TLS format.
* Must be a valid pointer.
- * @param minor Returns the TLS minor version in polarssl format.
+ * @param minor Returns the TLS minor version in mbed TLS format.
* Must be a valid pointer.
*/
static void tls_version_to_major_minor(int tls_ver, int *major, int *minor) {
@@ -714,16 +753,16 @@ static void tls_version_to_major_minor(int tls_ver, int *major, int *minor) {
switch (tls_ver)
{
case TLS_VER_1_0:
- *major = SSL_MAJOR_VERSION_3;
- *minor = SSL_MINOR_VERSION_1;
+ *major = MBEDTLS_SSL_MAJOR_VERSION_3;
+ *minor = MBEDTLS_SSL_MINOR_VERSION_1;
break;
case TLS_VER_1_1:
- *major = SSL_MAJOR_VERSION_3;
- *minor = SSL_MINOR_VERSION_2;
+ *major = MBEDTLS_SSL_MAJOR_VERSION_3;
+ *minor = MBEDTLS_SSL_MINOR_VERSION_2;
break;
case TLS_VER_1_2:
- *major = SSL_MAJOR_VERSION_3;
- *minor = SSL_MINOR_VERSION_3;
+ *major = MBEDTLS_SSL_MAJOR_VERSION_3;
+ *minor = MBEDTLS_SSL_MINOR_VERSION_3;
break;
default:
msg(M_FATAL, "%s: invalid TLS version %d", __func__, tls_ver);
@@ -731,6 +770,41 @@ static void tls_version_to_major_minor(int tls_ver, int *major, int *minor) {
}
}
+void
+tls_ctx_reload_crl(struct tls_root_ctx *ctx, const char *crl_file,
+ const char *crl_inline)
+{
+ ASSERT (crl_file);
+
+ if (ctx->crl == NULL)
+ {
+ ALLOC_OBJ_CLEAR(ctx->crl, mbedtls_x509_crl);
+ }
+ mbedtls_x509_crl_free(ctx->crl);
+
+ if (!strcmp (crl_file, INLINE_FILE_TAG) && crl_inline)
+ {
+ if (!mbed_ok(mbedtls_x509_crl_parse(ctx->crl,
+ (const unsigned char *)crl_inline, strlen(crl_inline)+1)))
+ {
+ msg (M_WARN, "CRL: cannot parse inline CRL");
+ goto err;
+ }
+ }
+ else
+ {
+ if (!mbed_ok(mbedtls_x509_crl_parse_file(ctx->crl, crl_file)))
+ {
+ msg (M_WARN, "CRL: cannot read CRL from file %s", crl_file);
+ goto err;
+ }
+ }
+ return;
+
+err:
+ mbedtls_x509_crl_free(ctx->crl);
+}
+
void key_state_ssl_init(struct key_state_ssl *ks_ssl,
const struct tls_root_ctx *ssl_ctx, bool is_server, struct tls_session *session)
{
@@ -738,88 +812,92 @@ void key_state_ssl_init(struct key_state_ssl *ks_ssl,
ASSERT(ks_ssl);
CLEAR(*ks_ssl);
- ALLOC_OBJ_CLEAR(ks_ssl->ctx, ssl_context);
- if (polar_ok(ssl_init(ks_ssl->ctx)))
+ /* Initialise SSL config */
+ mbedtls_ssl_config_init(&ks_ssl->ssl_config);
+ mbedtls_ssl_config_defaults(&ks_ssl->ssl_config, ssl_ctx->endpoint,
+ MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT);
+#ifdef MBEDTLS_DEBUG_C
+ mbedtls_debug_set_threshold(3);
+#endif
+ mbedtls_ssl_conf_dbg (&ks_ssl->ssl_config, my_debug, NULL);
+ mbedtls_ssl_conf_rng (&ks_ssl->ssl_config, mbedtls_ctr_drbg_random,
+ rand_ctx_get());
+
+ if (ssl_ctx->allowed_ciphers)
+ mbedtls_ssl_conf_ciphersuites (&ks_ssl->ssl_config, ssl_ctx->allowed_ciphers);
+
+ /* Disable record splitting (for now). OpenVPN assumes records are sent
+ * unfragmented, and changing that will require thorough review and
+ * testing. Since OpenVPN is not susceptible to BEAST, we can just
+ * disable record splitting as a quick fix. */
+#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING)
+ mbedtls_ssl_conf_cbc_record_splitting (&ks_ssl->ssl_config,
+ MBEDTLS_SSL_CBC_RECORD_SPLITTING_DISABLED);
+#endif /* MBEDTLS_SSL_CBC_RECORD_SPLITTING */
+
+ /* Initialise authentication information */
+ if (is_server)
+ mbed_ok (mbedtls_ssl_conf_dh_param_ctx(&ks_ssl->ssl_config,
+ ssl_ctx->dhm_ctx));
+
+ mbed_ok (mbedtls_ssl_conf_own_cert(&ks_ssl->ssl_config, ssl_ctx->crt_chain,
+ ssl_ctx->priv_key));
+
+ /* Initialise SSL verification */
+#if P2MP_SERVER
+ if (session->opt->ssl_flags & SSLF_CLIENT_CERT_OPTIONAL)
{
- /* Initialise SSL context */
- debug_set_threshold(3);
- ssl_set_dbg (ks_ssl->ctx, my_debug, NULL);
- ssl_set_endpoint (ks_ssl->ctx, ssl_ctx->endpoint);
-
- ssl_set_rng (ks_ssl->ctx, ctr_drbg_random, rand_ctx_get());
+ mbedtls_ssl_conf_authmode(&ks_ssl->ssl_config, MBEDTLS_SSL_VERIFY_OPTIONAL);
+ }
+ else if (!(session->opt->ssl_flags & SSLF_CLIENT_CERT_NOT_REQUIRED))
+#endif
+ {
+ mbedtls_ssl_conf_authmode (&ks_ssl->ssl_config, MBEDTLS_SSL_VERIFY_REQUIRED);
+ }
+ mbedtls_ssl_conf_verify (&ks_ssl->ssl_config, verify_callback, session);
- if (ssl_ctx->allowed_ciphers)
- ssl_set_ciphersuites (ks_ssl->ctx, ssl_ctx->allowed_ciphers);
+ /* TODO: mbed TLS does not currently support sending the CA chain to the client */
+ mbedtls_ssl_conf_ca_chain (&ks_ssl->ssl_config, ssl_ctx->ca_chain, ssl_ctx->crl);
- /* Disable record splitting (for now). OpenVPN assumes records are sent
- * unfragmented, and changing that will require thorough review and
- * testing. Since OpenVPN is not susceptible to BEAST, we can just
- * disable record splitting as a quick fix. */
-#if defined(POLARSSL_SSL_CBC_RECORD_SPLITTING)
- ssl_set_cbc_record_splitting (ks_ssl->ctx, SSL_CBC_RECORD_SPLITTING_DISABLED);
-#endif /* POLARSSL_SSL_CBC_RECORD_SPLITTING */
+ /* Initialize minimum TLS version */
+ {
+ const int tls_version_min =
+ (session->opt->ssl_flags >> SSLF_TLS_VERSION_MIN_SHIFT) &
+ SSLF_TLS_VERSION_MIN_MASK;
- /* Initialise authentication information */
- if (is_server)
- polar_ok (ssl_set_dh_param_ctx (ks_ssl->ctx, ssl_ctx->dhm_ctx));
+ /* default to TLS 1.0 */
+ int major = MBEDTLS_SSL_MAJOR_VERSION_3;
+ int minor = MBEDTLS_SSL_MINOR_VERSION_1;
- polar_ok (ssl_set_own_cert (ks_ssl->ctx, ssl_ctx->crt_chain,
- ssl_ctx->priv_key));
+ if (tls_version_min > TLS_VER_UNSPEC)
+ tls_version_to_major_minor(tls_version_min, &major, &minor);
- /* Initialise SSL verification */
-#if P2MP_SERVER
- if (session->opt->ssl_flags & SSLF_CLIENT_CERT_NOT_REQUIRED)
- {
- msg (M_WARN, "WARNING: POTENTIALLY DANGEROUS OPTION "
- "--client-cert-not-required may accept clients which do not present "
- "a certificate");
- }
- else
-#endif
- {
- ssl_set_authmode (ks_ssl->ctx, SSL_VERIFY_REQUIRED);
- ssl_set_verify (ks_ssl->ctx, verify_callback, session);
- }
+ mbedtls_ssl_conf_min_version(&ks_ssl->ssl_config, major, minor);
+ }
- /* TODO: PolarSSL does not currently support sending the CA chain to the client */
- ssl_set_ca_chain (ks_ssl->ctx, ssl_ctx->ca_chain, NULL, NULL );
+ /* Initialize maximum TLS version */
+ {
+ const int tls_version_max =
+ (session->opt->ssl_flags >> SSLF_TLS_VERSION_MAX_SHIFT) &
+ SSLF_TLS_VERSION_MAX_MASK;
- /* Initialize minimum TLS version */
+ if (tls_version_max > TLS_VER_UNSPEC)
{
- const int tls_version_min =
- (session->opt->ssl_flags >> SSLF_TLS_VERSION_MIN_SHIFT) &
- SSLF_TLS_VERSION_MIN_MASK;
-
- /* default to TLS 1.0 */
- int major = SSL_MAJOR_VERSION_3;
- int minor = SSL_MINOR_VERSION_1;
-
- if (tls_version_min > TLS_VER_UNSPEC)
- tls_version_to_major_minor(tls_version_min, &major, &minor);
-
- ssl_set_min_version(ks_ssl->ctx, major, minor);
+ int major, minor;
+ tls_version_to_major_minor(tls_version_max, &major, &minor);
+ mbedtls_ssl_conf_max_version(&ks_ssl->ssl_config, major, minor);
}
+ }
- /* Initialize maximum TLS version */
- {
- const int tls_version_max =
- (session->opt->ssl_flags >> SSLF_TLS_VERSION_MAX_SHIFT) &
- SSLF_TLS_VERSION_MAX_MASK;
-
- if (tls_version_max > TLS_VER_UNSPEC)
- {
- int major, minor;
- tls_version_to_major_minor(tls_version_max, &major, &minor);
- ssl_set_max_version(ks_ssl->ctx, major, minor);
- }
- }
+ /* Initialise SSL context */
+ ALLOC_OBJ_CLEAR(ks_ssl->ctx, mbedtls_ssl_context);
+ mbedtls_ssl_init(ks_ssl->ctx);
+ mbedtls_ssl_setup(ks_ssl->ctx, &ks_ssl->ssl_config);
- /* Initialise BIOs */
- ALLOC_OBJ_CLEAR (ks_ssl->ct_in, endless_buffer);
- ALLOC_OBJ_CLEAR (ks_ssl->ct_out, endless_buffer);
- ssl_set_bio (ks_ssl->ctx, endless_buf_read, ks_ssl->ct_in,
- endless_buf_write, ks_ssl->ct_out);
- }
+ /* Initialise BIOs */
+ CLEAR (ks_ssl->bio_ctx);
+ mbedtls_ssl_set_bio (ks_ssl->ctx, &ks_ssl->bio_ctx, ssl_bio_write,
+ ssl_bio_read, NULL);
}
void
@@ -828,17 +906,12 @@ key_state_ssl_free(struct key_state_ssl *ks_ssl)
if (ks_ssl) {
if (ks_ssl->ctx)
{
- ssl_free(ks_ssl->ctx);
+ mbedtls_ssl_free(ks_ssl->ctx);
free(ks_ssl->ctx);
}
- if (ks_ssl->ct_in) {
- buf_free_entries(ks_ssl->ct_in);
- free(ks_ssl->ct_in);
- }
- if (ks_ssl->ct_out) {
- buf_free_entries(ks_ssl->ct_out);
- free(ks_ssl->ct_out);
- }
+ mbedtls_ssl_config_free(&ks_ssl->ssl_config);
+ buf_free_entries(&ks_ssl->bio_ctx.in);
+ buf_free_entries(&ks_ssl->bio_ctx.out);
CLEAR(*ks_ssl);
}
}
@@ -847,46 +920,18 @@ int
key_state_write_plaintext (struct key_state_ssl *ks, struct buffer *buf)
{
int retval = 0;
- perf_push (PERF_BIO_WRITE_PLAINTEXT);
- ASSERT (NULL != ks);
ASSERT (buf);
- ASSERT (buf->len >= 0);
- if (0 == buf->len)
- {
- perf_pop ();
- return 0;
- }
-
- retval = ssl_write(ks->ctx, BPTR(buf), buf->len);
-
- if (retval < 0)
- {
- perf_pop ();
- if (POLARSSL_ERR_NET_WANT_WRITE == retval || POLARSSL_ERR_NET_WANT_READ == retval)
- return 0;
- msg (D_TLS_ERRORS, "TLS ERROR: write tls_write_plaintext error");
- return -1;
- }
+ retval = key_state_write_plaintext_const(ks, BPTR(buf), BLEN(buf));
- if (retval != buf->len)
+ if (1 == retval)
{
- msg (D_TLS_ERRORS,
- "TLS ERROR: write tls_write_plaintext incomplete %d/%d",
- retval, buf->len);
- perf_pop ();
- return -1;
+ memset (BPTR (buf), 0, BLEN (buf)); /* erase data just written */
+ buf->len = 0;
}
- /* successful write */
- dmsg (D_HANDSHAKE_VERBOSE, "write tls_write_plaintext %d bytes", retval);
-
- memset (BPTR (buf), 0, BLEN (buf)); /* erase data just written */
- buf->len = 0;
-
- perf_pop ();
- return 1;
+ return retval;
}
int
@@ -906,14 +951,14 @@ key_state_write_plaintext_const (struct key_state_ssl *ks, const uint8_t *data,
ASSERT (data);
- retval = ssl_write(ks->ctx, data, len);
+ retval = mbedtls_ssl_write(ks->ctx, data, len);
if (retval < 0)
{
perf_pop ();
- if (POLARSSL_ERR_NET_WANT_WRITE == retval || POLARSSL_ERR_NET_WANT_READ == retval)
+ if (MBEDTLS_ERR_SSL_WANT_WRITE == retval || MBEDTLS_ERR_SSL_WANT_READ == retval)
return 0;
- polar_log_err (D_TLS_ERRORS, retval,
+ mbed_log_err (D_TLS_ERRORS, retval,
"TLS ERROR: write tls_write_plaintext_const error");
return -1;
}
@@ -957,15 +1002,15 @@ key_state_read_ciphertext (struct key_state_ssl *ks, struct buffer *buf,
if (maxlen < len)
len = maxlen;
- retval = endless_buf_read(ks->ct_out, BPTR(buf), len);
+ retval = endless_buf_read(&ks->bio_ctx.out, BPTR(buf), len);
/* Error during read, check for retry error */
if (retval < 0)
{
perf_pop ();
- if (POLARSSL_ERR_NET_WANT_WRITE == retval || POLARSSL_ERR_NET_WANT_READ == retval)
+ if (MBEDTLS_ERR_SSL_WANT_WRITE == retval || MBEDTLS_ERR_SSL_WANT_READ == retval)
return 0;
- polar_log_err (D_TLS_ERRORS, retval, "TLS_ERROR: read tls_read_ciphertext error");
+ mbed_log_err (D_TLS_ERRORS, retval, "TLS_ERROR: read tls_read_ciphertext error");
buf->len = 0;
return -1;
}
@@ -1000,15 +1045,15 @@ key_state_write_ciphertext (struct key_state_ssl *ks, struct buffer *buf)
return 0;
}
- retval = endless_buf_write(ks->ct_in, BPTR(buf), buf->len);
+ retval = endless_buf_write(&ks->bio_ctx.in, BPTR(buf), buf->len);
if (retval < 0)
{
perf_pop ();
- if (POLARSSL_ERR_NET_WANT_WRITE == retval || POLARSSL_ERR_NET_WANT_READ == retval)
+ if (MBEDTLS_ERR_SSL_WANT_WRITE == retval || MBEDTLS_ERR_SSL_WANT_READ == retval)
return 0;
- polar_log_err (D_TLS_ERRORS, retval,
+ mbed_log_err (D_TLS_ERRORS, retval,
"TLS ERROR: write tls_write_ciphertext error");
return -1;
}
@@ -1054,14 +1099,14 @@ key_state_read_plaintext (struct key_state_ssl *ks, struct buffer *buf,
if (maxlen < len)
len = maxlen;
- retval = ssl_read(ks->ctx, BPTR(buf), len);
+ retval = mbedtls_ssl_read(ks->ctx, BPTR(buf), len);
/* Error during read, check for retry error */
if (retval < 0)
{
- if (POLARSSL_ERR_NET_WANT_WRITE == retval || POLARSSL_ERR_NET_WANT_READ == retval)
+ if (MBEDTLS_ERR_SSL_WANT_WRITE == retval || MBEDTLS_ERR_SSL_WANT_READ == retval)
return 0;
- polar_log_err (D_TLS_ERRORS, retval, "TLS_ERROR: read tls_read_plaintext error");
+ mbed_log_err (D_TLS_ERRORS, retval, "TLS_ERROR: read tls_read_plaintext error");
buf->len = 0;
perf_pop ();
return -1;
@@ -1092,20 +1137,21 @@ key_state_read_plaintext (struct key_state_ssl *ks, struct buffer *buf,
void
print_details (struct key_state_ssl * ks_ssl, const char *prefix)
{
- const x509_crt *cert;
+ const mbedtls_x509_crt *cert;
char s1[256];
char s2[256];
s1[0] = s2[0] = 0;
openvpn_snprintf (s1, sizeof (s1), "%s %s, cipher %s",
prefix,
- ssl_get_version (ks_ssl->ctx),
- ssl_get_ciphersuite(ks_ssl->ctx));
+ mbedtls_ssl_get_version (ks_ssl->ctx),
+ mbedtls_ssl_get_ciphersuite (ks_ssl->ctx));
- cert = ssl_get_peer_cert(ks_ssl->ctx);
+ cert = mbedtls_ssl_get_peer_cert (ks_ssl->ctx);
if (cert != NULL)
{
- openvpn_snprintf (s2, sizeof (s2), ", %zu bit key", pk_get_size(&cert->pk));
+ openvpn_snprintf (s2, sizeof (s2), ", %u bit key",
+ (unsigned int) mbedtls_pk_get_bitlen (&cert->pk));
}
msg (D_HANDSHAKE, "%s%s", s1, s2);
@@ -1115,12 +1161,13 @@ void
show_available_tls_ciphers (const char *cipher_list)
{
struct tls_root_ctx tls_ctx;
- const int *ciphers = ssl_list_ciphersuites();
+ const int *ciphers = mbedtls_ssl_list_ciphersuites ();
- if (cipher_list) {
- tls_ctx_restrict_ciphers(&tls_ctx, cipher_list);
+ tls_ctx_server_new(&tls_ctx);
+ tls_ctx_restrict_ciphers(&tls_ctx, cipher_list);
+
+ if (tls_ctx.allowed_ciphers)
ciphers = tls_ctx.allowed_ciphers;
- }
#ifndef ENABLE_SMALL
printf ("Available TLS Ciphers,\n");
@@ -1129,32 +1176,51 @@ show_available_tls_ciphers (const char *cipher_list)
while (*ciphers != 0)
{
- printf ("%s\n", ssl_get_ciphersuite_name(*ciphers));
+ printf ("%s\n", mbedtls_ssl_get_ciphersuite_name (*ciphers));
ciphers++;
}
printf ("\n" SHOW_TLS_CIPHER_LIST_WARNING);
+
+ tls_ctx_free(&tls_ctx);
+}
+
+void
+show_available_curves (void)
+{
+ const mbedtls_ecp_curve_info *pcurve = mbedtls_ecp_curve_list ();
+
+ if (NULL == pcurve)
+ msg (M_FATAL, "Cannot retrieve curve list from mbed TLS");
+
+ /* Print curve list */
+ printf ("Available Elliptic curves, listed in order of preference:\n\n");
+ while (MBEDTLS_ECP_DP_NONE != pcurve->grp_id)
+ {
+ printf("%s\n", pcurve->name);
+ pcurve++;
+ }
}
void
get_highest_preference_tls_cipher (char *buf, int size)
{
const char *cipher_name;
- const int *ciphers = ssl_list_ciphersuites();
+ const int *ciphers = mbedtls_ssl_list_ciphersuites();
if (*ciphers == 0)
msg (M_FATAL, "Cannot retrieve list of supported SSL ciphers.");
- cipher_name = ssl_get_ciphersuite_name(*ciphers);
+ cipher_name = mbedtls_ssl_get_ciphersuite_name(*ciphers);
strncpynt (buf, cipher_name, size);
}
const char *
get_ssl_library_version(void)
{
- static char polar_version[30];
- unsigned int pv = version_get_number();
- sprintf( polar_version, "PolarSSL %d.%d.%d",
+ static char mbedtls_version[30];
+ unsigned int pv = mbedtls_version_get_number();
+ sprintf( mbedtls_version, "mbed TLS %d.%d.%d",
(pv>>24)&0xff, (pv>>16)&0xff, (pv>>8)&0xff );
- return polar_version;
+ return mbedtls_version;
}
-#endif /* defined(ENABLE_SSL) && defined(ENABLE_CRYPTO_POLARSSL) */
+#endif /* defined(ENABLE_CRYPTO) && defined(ENABLE_CRYPTO_MBEDTLS) */
diff --git a/src/openvpn/ssl_polarssl.h b/src/openvpn/ssl_mbedtls.h
index b80a509..3edeedc 100644
--- a/src/openvpn/ssl_polarssl.h
+++ b/src/openvpn/ssl_mbedtls.h
@@ -24,19 +24,19 @@
*/
/**
- * @file Control Channel PolarSSL Backend
+ * @file Control Channel mbed TLS Backend
*/
-#ifndef SSL_POLARSSL_H_
-#define SSL_POLARSSL_H_
+#ifndef SSL_MBEDTLS_H_
+#define SSL_MBEDTLS_H_
#include "syshead.h"
-#include <polarssl/ssl.h>
-#include <polarssl/x509_crt.h>
+#include <mbedtls/ssl.h>
+#include <mbedtls/x509_crt.h>
#if defined(ENABLE_PKCS11)
-#include <polarssl/pkcs11.h>
+#include <mbedtls/pkcs11.h>
#endif
typedef struct _buffer_entry buffer_entry;
@@ -53,6 +53,11 @@ typedef struct {
buffer_entry *last_block;
} endless_buffer;
+typedef struct {
+ endless_buffer in;
+ endless_buffer out;
+} bio_ctx;
+
/**
* Structure that wraps the TLS context. Contents differ depending on the
* SSL library used.
@@ -64,12 +69,13 @@ struct tls_root_ctx {
int endpoint; /**< Whether or not this is a server or a client */
- dhm_context *dhm_ctx; /**< Diffie-Helmann-Merkle context */
- x509_crt *crt_chain; /**< Local Certificate chain */
- x509_crt *ca_chain; /**< CA chain for remote verification */
- pk_context *priv_key; /**< Local private key */
+ mbedtls_dhm_context *dhm_ctx; /**< Diffie-Helmann-Merkle context */
+ mbedtls_x509_crt *crt_chain; /**< Local Certificate chain */
+ mbedtls_x509_crt *ca_chain; /**< CA chain for remote verification */
+ mbedtls_pk_context *priv_key; /**< Local private key */
+ mbedtls_x509_crl *crl; /**< Certificate Revocation List */
#if defined(ENABLE_PKCS11)
- pkcs11_context *priv_key_pkcs11; /**< PKCS11 private key */
+ mbedtls_pkcs11_context *priv_key_pkcs11; /**< PKCS11 private key */
#endif
#ifdef MANAGMENT_EXTERNAL_KEY
struct external_context *external_key; /**< Management external key */
@@ -78,10 +84,10 @@ struct tls_root_ctx {
};
struct key_state_ssl {
- ssl_context *ctx;
- endless_buffer *ct_in;
- endless_buffer *ct_out;
+ mbedtls_ssl_config ssl_config; /**< mbedTLS global ssl config */
+ mbedtls_ssl_context *ctx; /**< mbedTLS connection context */
+ bio_ctx bio_ctx;
};
-#endif /* SSL_POLARSSL_H_ */
+#endif /* SSL_MBEDTLS_H_ */
diff --git a/src/openvpn/ssl_openssl.c b/src/openvpn/ssl_openssl.c
index 1dfbb23..51669fc 100644
--- a/src/openvpn/ssl_openssl.c
+++ b/src/openvpn/ssl_openssl.c
@@ -35,7 +35,7 @@
#include "syshead.h"
-#if defined(ENABLE_SSL) && defined(ENABLE_CRYPTO_OPENSSL)
+#if defined(ENABLE_CRYPTO) && defined(ENABLE_CRYPTO_OPENSSL)
#include "errlevel.h"
#include "buffer.h"
@@ -56,6 +56,9 @@
#include <openssl/pkcs12.h>
#include <openssl/x509.h>
#include <openssl/crypto.h>
+#ifndef OPENSSL_NO_EC
+#include <openssl/ec.h>
+#endif
/*
* Allocate space in SSL objects in which to store a struct tls_session
@@ -93,62 +96,23 @@ tls_clear_error()
ERR_clear_error ();
}
-/*
- * OpenSSL callback to get a temporary RSA key, mostly
- * used for export ciphers.
- */
-static RSA *
-tmp_rsa_cb (SSL * s, int is_export, int keylength)
-{
- static RSA *rsa_tmp = NULL;
- if (rsa_tmp == NULL)
- {
- int ret = -1;
- BIGNUM *bn = BN_new();
- rsa_tmp = RSA_new();
-
- msg (D_HANDSHAKE, "Generating temp (%d bit) RSA key", keylength);
-
- if(!bn || !BN_set_word(bn, RSA_F4) ||
- !RSA_generate_key_ex(rsa_tmp, keylength, bn, NULL))
- crypto_msg(M_FATAL, "Failed to generate temp RSA key");
-
- if (bn) BN_free( bn );
- }
- return (rsa_tmp);
-}
-
void
-tls_ctx_server_new(struct tls_root_ctx *ctx, unsigned int ssl_flags)
+tls_ctx_server_new(struct tls_root_ctx *ctx)
{
- const int tls_version_max =
- (ssl_flags >> SSLF_TLS_VERSION_MAX_SHIFT) & SSLF_TLS_VERSION_MAX_MASK;
-
ASSERT(NULL != ctx);
- if (tls_version_max == TLS_VER_1_0)
- ctx->ctx = SSL_CTX_new (TLSv1_server_method ());
- else
- ctx->ctx = SSL_CTX_new (SSLv23_server_method ());
+ ctx->ctx = SSL_CTX_new (SSLv23_server_method ());
if (ctx->ctx == NULL)
crypto_msg (M_FATAL, "SSL_CTX_new SSLv23_server_method");
-
- SSL_CTX_set_tmp_rsa_callback (ctx->ctx, tmp_rsa_cb);
}
void
-tls_ctx_client_new(struct tls_root_ctx *ctx, unsigned int ssl_flags)
+tls_ctx_client_new(struct tls_root_ctx *ctx)
{
- const int tls_version_max =
- (ssl_flags >> SSLF_TLS_VERSION_MAX_SHIFT) & SSLF_TLS_VERSION_MAX_MASK;
-
ASSERT(NULL != ctx);
- if (tls_version_max == TLS_VER_1_0)
- ctx->ctx = SSL_CTX_new (TLSv1_client_method ());
- else
- ctx->ctx = SSL_CTX_new (SSLv23_client_method ());
+ ctx->ctx = SSL_CTX_new (SSLv23_client_method ());
if (ctx->ctx == NULL)
crypto_msg (M_FATAL, "SSL_CTX_new SSLv23_client_method");
@@ -169,6 +133,38 @@ bool tls_ctx_initialised(struct tls_root_ctx *ctx)
return NULL != ctx->ctx;
}
+void
+key_state_export_keying_material(struct key_state_ssl *ssl,
+ struct tls_session *session)
+{
+ if (session->opt->ekm_size > 0)
+ {
+#if (OPENSSL_VERSION_NUMBER >= 0x10001000)
+ unsigned int size = session->opt->ekm_size;
+ struct gc_arena gc = gc_new();
+ unsigned char* ekm = (unsigned char*) gc_malloc(size, true, &gc);
+
+ if (SSL_export_keying_material(ssl->ssl, ekm, size,
+ session->opt->ekm_label, session->opt->ekm_label_size, NULL, 0, 0))
+ {
+ unsigned int len = (size * 2) + 2;
+
+ const char *key = format_hex_ex (ekm, size, len, 0, NULL, &gc);
+ setenv_str (session->opt->es, "exported_keying_material", key);
+
+ dmsg(D_TLS_DEBUG_MED, "%s: exported keying material: %s",
+ __func__, key);
+ }
+ else
+ {
+ msg (M_WARN, "WARNING: Export keying material failed!");
+ setenv_del (session->opt->es, "exported_keying_material");
+ }
+ gc_free(&gc);
+#endif
+ }
+}
+
/*
* Print debugging information on SSL/TLS session negotiation.
*/
@@ -217,14 +213,18 @@ tls_ctx_set_options (struct tls_root_ctx *ctx, unsigned int ssl_flags)
{
ASSERT(NULL != ctx);
+ /* default certificate verification flags */
+ int flags = SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
+
/* process SSL options including minimum TLS version we will accept from peer */
{
long sslopt = SSL_OP_SINGLE_DH_USE | SSL_OP_NO_TICKET | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3;
+ int tls_ver_max = TLS_VER_UNSPEC;
const int tls_ver_min =
(ssl_flags >> SSLF_TLS_VERSION_MIN_SHIFT) & SSLF_TLS_VERSION_MIN_MASK;
- int tls_ver_max =
- (ssl_flags >> SSLF_TLS_VERSION_MAX_SHIFT) & SSLF_TLS_VERSION_MAX_MASK;
+ tls_ver_max =
+ (ssl_flags >> SSLF_TLS_VERSION_MAX_SHIFT) & SSLF_TLS_VERSION_MAX_MASK;
if (tls_ver_max <= TLS_VER_UNSPEC)
tls_ver_max = tls_version_max();
@@ -245,6 +245,9 @@ tls_ctx_set_options (struct tls_root_ctx *ctx, unsigned int ssl_flags)
SSL_CTX_set_options (ctx->ctx, sslopt);
}
+#ifdef SSL_MODE_RELEASE_BUFFERS
+ SSL_CTX_set_mode (ctx->ctx, SSL_MODE_RELEASE_BUFFERS);
+#endif
SSL_CTX_set_session_cache_mode (ctx->ctx, SSL_SESS_CACHE_OFF);
SSL_CTX_set_default_passwd_cb (ctx->ctx, pem_password_callback);
@@ -252,14 +255,14 @@ tls_ctx_set_options (struct tls_root_ctx *ctx, unsigned int ssl_flags)
#if P2MP_SERVER
if (ssl_flags & SSLF_CLIENT_CERT_NOT_REQUIRED)
{
- msg (M_WARN, "WARNING: POTENTIALLY DANGEROUS OPTION "
- "--client-cert-not-required may accept clients which do not present "
- "a certificate");
+ flags = 0;
+ }
+ else if (ssl_flags & SSLF_CLIENT_CERT_OPTIONAL)
+ {
+ flags = SSL_VERIFY_PEER;
}
- else
#endif
- SSL_CTX_set_verify (ctx->ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
- verify_callback);
+ SSL_CTX_set_verify (ctx->ctx, flags, verify_callback);
SSL_CTX_set_info_callback (ctx->ctx, info_callback);
}
@@ -275,12 +278,17 @@ tls_ctx_restrict_ciphers(struct tls_root_ctx *ctx, const char *ciphers)
"DEFAULT"
/* Disable export ciphers and openssl's 'low' and 'medium' ciphers */
":!EXP:!LOW:!MEDIUM"
+ /* Disable static (EC)DH keys (no forward secrecy) */
+ ":!kDH:!kECDH"
+ /* Disable DSA private keys */
+ ":!DSS"
/* Disable unsupported TLS modes */
":!PSK:!SRP:!kRSA"))
crypto_msg (M_FATAL, "Failed to set default TLS cipher list.");
return;
}
+ /* Parse supplied cipher list and pass on to OpenSSL */
size_t begin_of_cipher, end_of_cipher;
const char *current_cipher;
@@ -309,8 +317,8 @@ tls_ctx_restrict_ciphers(struct tls_root_ctx *ctx, const char *ciphers)
// Issue warning on missing translation
// %.*s format specifier expects length of type int, so guarantee
// that length is small enough and cast to int.
- msg (M_WARN, "No valid translation found for TLS cipher '%.*s'",
- (int) MIN(current_cipher_len, 256), current_cipher);
+ msg (D_LOW, "No valid translation found for TLS cipher '%.*s'",
+ constrain_int(current_cipher_len, 0, 256), current_cipher);
}
else
{
@@ -319,7 +327,8 @@ tls_ctx_restrict_ciphers(struct tls_root_ctx *ctx, const char *ciphers)
current_cipher_len = strlen(current_cipher);
if (end_of_cipher - begin_of_cipher == current_cipher_len &&
- 0 == memcmp (&ciphers[begin_of_cipher], cipher_pair->openssl_name, end_of_cipher - begin_of_cipher))
+ 0 != memcmp (&ciphers[begin_of_cipher], cipher_pair->iana_name,
+ end_of_cipher - begin_of_cipher))
{
// Non-IANA name used, show warning
msg (M_WARN, "Deprecated TLS cipher name '%s', please use IANA name '%s'", cipher_pair->openssl_name, cipher_pair->iana_name);
@@ -436,6 +445,78 @@ tls_ctx_load_dh_params (struct tls_root_ctx *ctx, const char *dh_file,
DH_free (dh);
}
+void
+tls_ctx_load_ecdh_params (struct tls_root_ctx *ctx, const char *curve_name
+ )
+{
+#ifndef OPENSSL_NO_EC
+ int nid = NID_undef;
+ EC_KEY *ecdh = NULL;
+ const char *sname = NULL;
+
+ /* Generate a new ECDH key for each SSL session (for non-ephemeral ECDH) */
+ SSL_CTX_set_options(ctx->ctx, SSL_OP_SINGLE_ECDH_USE);
+#if OPENSSL_VERSION_NUMBER >= 0x10002000L
+ /* OpenSSL 1.0.2 and newer can automatically handle ECDH parameter loading */
+ if (NULL == curve_name) {
+ SSL_CTX_set_ecdh_auto(ctx->ctx, 1);
+ return;
+ }
+#endif
+ /* For older OpenSSL, we'll have to do the parameter loading on our own */
+ if (curve_name != NULL)
+ {
+ /* Use user supplied curve if given */
+ msg (D_TLS_DEBUG, "Using user specified ECDH curve (%s)", curve_name);
+ nid = OBJ_sn2nid(curve_name);
+ }
+ else
+ {
+ /* Extract curve from key */
+ EC_KEY *eckey = NULL;
+ const EC_GROUP *ecgrp = NULL;
+ EVP_PKEY *pkey = NULL;
+
+ /* Little hack to get private key ref from SSL_CTX, yay OpenSSL... */
+ SSL ssl;
+ ssl.cert = ctx->ctx->cert;
+ pkey = SSL_get_privatekey(&ssl);
+
+ msg (D_TLS_DEBUG, "Extracting ECDH curve from private key");
+
+ if (pkey != NULL && (eckey = EVP_PKEY_get1_EC_KEY(pkey)) != NULL &&
+ (ecgrp = EC_KEY_get0_group(eckey)) != NULL)
+ nid = EC_GROUP_get_curve_name(ecgrp);
+ }
+
+ /* Translate NID back to name , just for kicks */
+ sname = OBJ_nid2sn(nid);
+ if (sname == NULL) sname = "(Unknown)";
+
+ /* Create new EC key and set as ECDH key */
+ if (NID_undef == nid || NULL == (ecdh = EC_KEY_new_by_curve_name(nid)))
+ {
+ /* Creating key failed, fall back on sane default */
+ ecdh = EC_KEY_new_by_curve_name(NID_secp384r1);
+ const char *source = (NULL == curve_name) ?
+ "extract curve from certificate" : "use supplied curve";
+ msg (D_TLS_DEBUG_LOW,
+ "Failed to %s (%s), using secp384r1 instead.", source, sname);
+ sname = OBJ_nid2sn(NID_secp384r1);
+ }
+
+ if (!SSL_CTX_set_tmp_ecdh(ctx->ctx, ecdh))
+ crypto_msg (M_FATAL, "SSL_CTX_set_tmp_ecdh: cannot add curve");
+
+ msg (D_TLS_DEBUG_LOW, "ECDH curve %s added", sname);
+
+ EC_KEY_free(ecdh);
+#else
+ msg (M_DEBUG, "Your OpenSSL library was built without elliptic curve support."
+ " Skipping ECDH parameter loading.");
+#endif /* OPENSSL_NO_EC */
+}
+
int
tls_ctx_load_pkcs12(struct tls_root_ctx *ctx, const char *pkcs12_file,
const char *pkcs12_file_inline,
@@ -501,7 +582,6 @@ tls_ctx_load_pkcs12(struct tls_root_ctx *ctx, const char *pkcs12_file,
/* Load Private Key */
if (!SSL_CTX_use_PrivateKey (ctx->ctx, pkey))
crypto_msg (M_FATAL, "Cannot use private key");
- warn_if_group_others_accessible (pkcs12_file);
/* Check Private Key */
if (!SSL_CTX_check_private_key (ctx->ctx))
@@ -552,7 +632,7 @@ tls_ctx_load_cryptoapi(struct tls_root_ctx *ctx, const char *cryptoapi_cert)
if (!SSL_CTX_use_CryptoAPI_certificate (ctx->ctx, cryptoapi_cert))
crypto_msg (M_FATAL, "Cannot load certificate \"%s\" from Microsoft Certificate Store", cryptoapi_cert);
}
-#endif /* WIN32 */
+#endif /* ENABLE_CRYPTOAPI */
static void
tls_ctx_add_extra_certs (struct tls_root_ctx *ctx, BIO *bio)
@@ -645,7 +725,6 @@ tls_ctx_load_priv_file (struct tls_root_ctx *ctx, const char *priv_key_file,
const char *priv_key_file_inline
)
{
- int status;
SSL_CTX *ssl_ctx = NULL;
BIO *in = NULL;
EVP_PKEY *pkey = NULL;
@@ -678,7 +757,6 @@ tls_ctx_load_priv_file (struct tls_root_ctx *ctx, const char *priv_key_file,
crypto_msg (M_WARN, "Cannot load private key file %s", priv_key_file);
goto end;
}
- warn_if_group_others_accessible (priv_key_file);
/* Check Private Key */
if (!SSL_CTX_check_private_key (ssl_ctx))
@@ -693,6 +771,64 @@ end:
return ret;
}
+void
+tls_ctx_reload_crl(struct tls_root_ctx *ssl_ctx, const char *crl_file,
+ const char *crl_inline)
+{
+ X509_CRL *crl = NULL;
+ BIO *in = NULL;
+
+ X509_STORE *store = SSL_CTX_get_cert_store(ssl_ctx->ctx);
+ if (!store)
+ crypto_msg (M_FATAL, "Cannot get certificate store");
+
+ /* Always start with a cleared CRL list, for that we
+ * we need to manually find the CRL object from the stack
+ * and remove it */
+ for (int i = 0; i < sk_X509_OBJECT_num(store->objs); i++)
+ {
+ X509_OBJECT* obj = sk_X509_OBJECT_value(store->objs, i);
+ ASSERT(obj);
+ if (obj->type == X509_LU_CRL)
+ {
+ sk_X509_OBJECT_delete(store->objs, i);
+ X509_OBJECT_free_contents(obj);
+ OPENSSL_free(obj);
+ }
+ }
+
+ X509_STORE_set_flags (store, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL);
+
+ if (!strcmp (crl_file, INLINE_FILE_TAG) && crl_inline)
+ in = BIO_new_mem_buf ((char *)crl_inline, -1);
+ else
+ in = BIO_new_file (crl_file, "r");
+
+ if (in == NULL)
+ {
+ msg (M_WARN, "CRL: cannot read: %s", crl_file);
+ goto end;
+ }
+
+ crl = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL);
+ if (crl == NULL)
+ {
+ msg (M_WARN, "CRL: cannot read CRL from file %s", crl_file);
+ goto end;
+ }
+
+ if (!X509_STORE_add_crl(store, crl))
+ {
+ msg (M_WARN, "CRL: cannot add %s to store", crl_file);
+ goto end;
+ }
+
+end:
+ X509_CRL_free(crl);
+ BIO_free(in);
+}
+
+
#ifdef MANAGMENT_EXTERNAL_KEY
/* encrypt */
@@ -780,10 +916,11 @@ tls_ctx_use_external_private_key (struct tls_root_ctx *ctx,
X509 *cert = NULL;
ASSERT (NULL != ctx);
- ASSERT (NULL != cert);
tls_ctx_load_cert_file_and_copy (ctx, cert_file, cert_file_inline, &cert);
+ ASSERT (NULL != cert);
+
/* allocate custom RSA method object */
ALLOC_OBJ_CLEAR (rsa_meth, RSA_METHOD);
rsa_meth->name = "OpenVPN external private key RSA Method";
@@ -965,11 +1102,7 @@ tls_ctx_load_ca (struct tls_root_ctx *ctx, const char *ca_file,
msg(M_WARN, "WARNING: experimental option --capath %s", ca_path);
else
crypto_msg (M_FATAL, "Cannot add lookup at --capath %s", ca_path);
-#if OPENSSL_VERSION_NUMBER >= 0x00907000L
X509_STORE_set_flags (store, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL);
-#else
- msg(M_WARN, "WARNING: this version of OpenSSL cannot handle CRL files in capath");
-#endif
}
}
@@ -1385,7 +1518,6 @@ show_available_tls_ciphers (const char *cipher_list)
struct tls_root_ctx tls_ctx;
SSL *ssl;
const char *cipher_name;
- const char *print_name;
const tls_cipher_name_pair *pair;
int priority = 0;
@@ -1419,6 +1551,43 @@ show_available_tls_ciphers (const char *cipher_list)
SSL_CTX_free (tls_ctx.ctx);
}
+/*
+ * Show the Elliptic curves that are available for us to use
+ * in the OpenSSL library.
+ */
+void
+show_available_curves()
+{
+#ifndef OPENSSL_NO_EC
+ EC_builtin_curve *curves = NULL;
+ size_t crv_len = 0;
+ size_t n = 0;
+
+ crv_len = EC_get_builtin_curves(NULL, 0);
+ ALLOC_ARRAY(curves, EC_builtin_curve, crv_len);
+ if (EC_get_builtin_curves(curves, crv_len))
+ {
+ printf ("Available Elliptic curves:\n");
+ for (n = 0; n < crv_len; n++)
+ {
+ const char *sname;
+ sname = OBJ_nid2sn(curves[n].nid);
+ if (sname == NULL) sname = "";
+
+ printf("%s\n", sname);
+ }
+ }
+ else
+ {
+ crypto_msg (M_FATAL, "Cannot get list of builtin curves");
+ }
+ free(curves);
+#else
+ msg (M_WARN, "Your OpenSSL library was built without elliptic curve support. "
+ "No curves available.");
+#endif
+}
+
void
get_highest_preference_tls_cipher (char *buf, int size)
{
@@ -1446,4 +1615,4 @@ get_ssl_library_version(void)
return SSLeay_version(SSLEAY_VERSION);
}
-#endif /* defined(ENABLE_SSL) && defined(ENABLE_CRYPTO_OPENSSL) */
+#endif /* defined(ENABLE_CRYPTO) && defined(ENABLE_CRYPTO_OPENSSL) */
diff --git a/src/openvpn/ssl_openssl.h b/src/openvpn/ssl_openssl.h
index 73a6c49..97dc742 100644
--- a/src/openvpn/ssl_openssl.h
+++ b/src/openvpn/ssl_openssl.h
@@ -35,15 +35,14 @@
/**
* SSL_OP_NO_TICKET tells OpenSSL to disable "stateless session resumption",
* as this is something we do not want nor need, but could potentially be
- * used for a future attack. For compatibility reasons, in the 2.3.x
- * series, we keep building if the OpenSSL version is too old to support
- * this. 2.4 requires it and will fail configure if not present.
+ * used for a future attack. For compatibility reasons we keep building if the
+ * OpenSSL version is too old (pre-0.9.8f) to support stateless session
+ * resumption (and the accompanying SSL_OP_NO_TICKET flag).
*/
#ifndef SSL_OP_NO_TICKET
# define SSL_OP_NO_TICKET 0
#endif
-
/**
* Structure that wraps the TLS context. Contents differ depending on the
* SSL library used.
diff --git a/src/openvpn/ssl_verify.c b/src/openvpn/ssl_verify.c
index ca69b41..a099776 100644
--- a/src/openvpn/ssl_verify.c
+++ b/src/openvpn/ssl_verify.c
@@ -35,10 +35,12 @@
#include "syshead.h"
-#if defined(ENABLE_CRYPTO) && defined(ENABLE_SSL)
+#ifdef ENABLE_CRYPTO
#include "misc.h"
#include "manage.h"
+#include "otime.h"
+#include "base64.h"
#include "ssl_verify.h"
#include "ssl_verify_backend.h"
@@ -191,40 +193,25 @@ tls_username (const struct tls_multi *multi, const bool null)
}
void
-cert_hash_remember (struct tls_session *session, const int error_depth, const unsigned char *sha1_hash)
+cert_hash_remember (struct tls_session *session, const int error_depth,
+ const struct buffer *cert_hash)
{
if (error_depth >= 0 && error_depth < MAX_CERT_DEPTH)
{
if (!session->cert_hash_set)
- ALLOC_OBJ_CLEAR (session->cert_hash_set, struct cert_hash_set);
+ {
+ ALLOC_OBJ_CLEAR (session->cert_hash_set, struct cert_hash_set);
+ }
if (!session->cert_hash_set->ch[error_depth])
- ALLOC_OBJ (session->cert_hash_set->ch[error_depth], struct cert_hash);
- {
- struct cert_hash *ch = session->cert_hash_set->ch[error_depth];
- memcpy (ch->sha1_hash, sha1_hash, SHA_DIGEST_LENGTH);
- }
- }
-}
-
-#if 0
-static void
-cert_hash_print (const struct cert_hash_set *chs, int msglevel)
-{
- struct gc_arena gc = gc_new ();
- msg (msglevel, "CERT_HASH");
- if (chs)
- {
- int i;
- for (i = 0; i < MAX_CERT_DEPTH; ++i)
{
- const struct cert_hash *ch = chs->ch[i];
- if (ch)
- msg (msglevel, "%d:%s", i, format_hex(ch->sha1_hash, SHA_DIGEST_LENGTH, 0, &gc));
+ ALLOC_OBJ (session->cert_hash_set->ch[error_depth], struct cert_hash);
}
+
+ struct cert_hash *ch = session->cert_hash_set->ch[error_depth];
+ ASSERT (sizeof (ch->sha256_hash) == BLEN (cert_hash));
+ memcpy (ch->sha256_hash, BPTR (cert_hash), sizeof (ch->sha256_hash));
}
- gc_free (&gc);
}
-#endif
void
cert_hash_free (struct cert_hash_set *chs)
@@ -238,7 +225,7 @@ cert_hash_free (struct cert_hash_set *chs)
}
}
-static bool
+bool
cert_hash_compare (const struct cert_hash_set *chs1, const struct cert_hash_set *chs2)
{
if (chs1 && chs2)
@@ -251,7 +238,8 @@ cert_hash_compare (const struct cert_hash_set *chs1, const struct cert_hash_set
if (!ch1 && !ch2)
continue;
- else if (ch1 && ch2 && !memcmp (ch1->sha1_hash, ch2->sha1_hash, SHA_DIGEST_LENGTH))
+ else if (ch1 && ch2 && !memcmp (ch1->sha256_hash, ch2->sha256_hash,
+ sizeof(ch1->sha256_hash)))
continue;
else
return false;
@@ -278,7 +266,8 @@ cert_hash_copy (const struct cert_hash_set *chs)
if (ch)
{
ALLOC_OBJ (dest->ch[i], struct cert_hash);
- memcpy (dest->ch[i]->sha1_hash, ch->sha1_hash, SHA_DIGEST_LENGTH);
+ memcpy (dest->ch[i]->sha256_hash, ch->sha256_hash,
+ sizeof(dest->ch[i]->sha256_hash));
}
}
}
@@ -337,8 +326,6 @@ verify_peer_cert(const struct tls_options *opt, openvpn_x509_cert_t *peer_cert,
}
}
-#if OPENSSL_VERSION_NUMBER >= 0x00907000L || ENABLE_CRYPTO_POLARSSL
-
/* verify certificate ku */
if (opt->remote_cert_ku[0] != 0)
{
@@ -367,8 +354,6 @@ verify_peer_cert(const struct tls_options *opt, openvpn_x509_cert_t *peer_cert,
}
}
-#endif /* OPENSSL_VERSION_NUMBER */
-
/* verify X509 name or username against --verify-x509-[user]name */
if (opt->verify_x509_type != VERIFY_X509_NONE)
{
@@ -397,22 +382,17 @@ verify_peer_cert(const struct tls_options *opt, openvpn_x509_cert_t *peer_cert,
*/
static void
verify_cert_set_env(struct env_set *es, openvpn_x509_cert_t *peer_cert, int cert_depth,
- const char *subject, const char *common_name
-#ifdef ENABLE_X509_TRACK
- , const struct x509_track *x509_track
-#endif
- )
+ const char *subject, const char *common_name,
+ const struct x509_track *x509_track)
{
char envname[64];
char *serial = NULL;
struct gc_arena gc = gc_new ();
/* Save X509 fields in environment */
-#ifdef ENABLE_X509_TRACK
if (x509_track)
x509_setenv_track (x509_track, es, cert_depth, peer_cert);
else
-#endif
x509_setenv (es, cert_depth, peer_cert);
/* export subject name string as environmental variable */
@@ -425,13 +405,19 @@ verify_cert_set_env(struct env_set *es, openvpn_x509_cert_t *peer_cert, int cert
setenv_str (es, envname, common_name);
#endif
- /* export X509 cert SHA1 fingerprint */
+ /* export X509 cert fingerprints */
{
- unsigned char *sha1_hash = x509_get_sha1_hash(peer_cert, &gc);
+ struct buffer sha1 = x509_get_sha1_fingerprint(peer_cert, &gc);
+ struct buffer sha256 = x509_get_sha256_fingerprint(peer_cert, &gc);
openvpn_snprintf (envname, sizeof(envname), "tls_digest_%d", cert_depth);
- setenv_str (es, envname, format_hex_ex(sha1_hash, SHA_DIGEST_LENGTH, 0, 1,
- ":", &gc));
+ setenv_str (es, envname,
+ format_hex_ex(BPTR(&sha1), BLEN(&sha1), 0, 1, ":", &gc));
+
+ openvpn_snprintf (envname, sizeof(envname), "tls_digest_sha256_%d",
+ cert_depth);
+ setenv_str (es, envname,
+ format_hex_ex(BPTR(&sha256), BLEN(&sha256), 0, 1, ":", &gc));
}
/* export serial number as environmental variable */
@@ -530,7 +516,8 @@ verify_cert_call_command(const char *verify_command, struct env_set *es,
}
}
- argv_printf (&argv, "%sc %d %s", verify_command, cert_depth, subject);
+ argv_parse_cmd (&argv, verify_command);
+ argv_printf_cat (&argv, "%d %s", cert_depth, subject);
argv_msg_prefix (D_TLS_DEBUG, &argv, "TLS: executing verify command");
ret = openvpn_run_script (&argv, es, 0, "--tls-verify script");
@@ -647,8 +634,8 @@ verify_cert(struct tls_session *session, openvpn_x509_cert_t *cert, int cert_dep
/* verify level 1 cert, i.e. the CA that signed our leaf cert */
if (cert_depth == 1 && opt->verify_hash)
{
- unsigned char *sha1_hash = x509_get_sha1_hash(cert, &gc);
- if (memcmp (sha1_hash, opt->verify_hash, SHA_DIGEST_LENGTH))
+ struct buffer sha1_hash = x509_get_sha1_fingerprint(cert, &gc);
+ if (memcmp (BPTR (&sha1_hash), opt->verify_hash, BLEN(&sha1_hash)))
{
msg (D_TLS_ERRORS, "TLS Error: level-1 certificate hash verification failed");
goto cleanup;
@@ -662,11 +649,8 @@ verify_cert(struct tls_session *session, openvpn_x509_cert_t *cert, int cert_dep
session->verify_maxlevel = max_int (session->verify_maxlevel, cert_depth);
/* export certificate values to the environment */
- verify_cert_set_env(opt->es, cert, cert_depth, subject, common_name
-#ifdef ENABLE_X509_TRACK
- , opt->x509_track
-#endif
- );
+ verify_cert_set_env(opt->es, cert, cert_depth, subject, common_name,
+ opt->x509_track);
/* export current untrusted IP */
setenv_untrusted (session);
@@ -688,15 +672,18 @@ verify_cert(struct tls_session *session, openvpn_x509_cert_t *cert, int cert_dep
if (opt->crl_file)
{
if (opt->ssl_flags & SSLF_CRL_VERIFY_DIR)
- {
- if (SUCCESS != verify_check_crl_dir(opt->crl_file, cert))
- goto cleanup;
- }
+ {
+ if (SUCCESS != verify_check_crl_dir(opt->crl_file, cert))
+ goto cleanup;
+ }
else
- {
- if (SUCCESS != x509_verify_crl(opt->crl_file, cert, subject))
- goto cleanup;
- }
+ {
+ if (tls_verify_crl_missing (opt))
+ {
+ msg (D_TLS_ERRORS, "VERIFY ERROR: CRL not loaded");
+ goto cleanup;
+ }
+ }
}
msg (D_HANDSHAKE, "VERIFY OK: depth=%d, %s", cert_depth, subject);
@@ -1000,7 +987,8 @@ verify_user_pass_script (struct tls_session *session, const struct user_pass *up
setenv_untrusted (session);
/* format command line */
- argv_printf (&argv, "%sc %s", session->opt->auth_user_pass_verify_script, tmp_file);
+ 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,
@@ -1030,7 +1018,9 @@ static int
verify_user_pass_plugin (struct tls_session *session, const struct user_pass *up, const char *raw_username)
{
int retval = OPENVPN_PLUGIN_FUNC_ERROR;
+#ifdef PLUGIN_DEF_AUTH
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))
@@ -1154,6 +1144,63 @@ verify_user_pass(struct user_pass *up, struct tls_multi *multi,
string_mod_remap_name (up->username, COMMON_NAME_CHAR_CLASS);
string_mod (up->password, CC_PRINT, CC_CRLF, '_');
+ /* If server is configured with --auth-gen-token and we have an
+ * authentication token for this client, this authentication
+ * round will be done internally using the token instead of
+ * calling any external authentication modules.
+ */
+ if (session->opt->auth_token_generate && multi->auth_token_sent
+ && NULL != multi->auth_token)
+ {
+ unsigned int ssl_flags = session->opt->ssl_flags;
+
+ /* Ensure that the username has not changed */
+ if (!tls_lock_username(multi, up->username))
+ {
+ ks->authenticated = false;
+ goto done;
+ }
+
+ /* If auth-token lifetime has been enabled,
+ * ensure the token has not expired
+ */
+ if (session->opt->auth_token_lifetime > 0
+ && (multi->auth_token_tstamp + session->opt->auth_token_lifetime) < now)
+ {
+ msg (D_HANDSHAKE, "Auth-token for client expired\n");
+ ks->authenticated = false;
+ goto done;
+ }
+
+ /* The core authentication of the token itself */
+ if (memcmp_constant_time(multi->auth_token, up->password,
+ strlen(multi->auth_token)) != 0)
+ {
+ memset (multi->auth_token, 0, AUTH_TOKEN_SIZE);
+ free (multi->auth_token);
+ multi->auth_token = NULL;
+ multi->auth_token_sent = false;
+ ks->authenticated = false;
+ tls_deauthenticate (multi);
+
+ msg (D_TLS_ERRORS, "TLS Auth Error: Auth-token verification "
+ "failed for username '%s' %s", up->username,
+ (ssl_flags & SSLF_USERNAME_AS_COMMON_NAME) ? "[CN SET]" : "");
+ }
+ else
+ {
+ ks->authenticated = true;
+
+ if (ssl_flags & SSLF_USERNAME_AS_COMMON_NAME)
+ set_common_name (session, up->username);
+ msg (D_HANDSHAKE, "TLS: Username/auth-token authentication "
+ "succeeded for username '%s' %s",
+ up->username,
+ (ssl_flags & SSLF_USERNAME_AS_COMMON_NAME) ? "[CN SET]" : "");
+ }
+ goto done;
+ }
+
/* call plugin(s) and/or script */
#ifdef MANAGEMENT_DEF_AUTH
if (man_def_auth == KMDA_DEF)
@@ -1191,6 +1238,43 @@ verify_user_pass(struct user_pass *up, struct tls_multi *multi,
if (man_def_auth != KMDA_UNDEF)
ks->auth_deferred = true;
#endif
+
+ if ((session->opt->auth_token_generate) && (NULL == multi->auth_token))
+ {
+ /* Server is configured with --auth-gen-token but no token has yet
+ * been generated for this client. Generate one and save it.
+ */
+ uint8_t tok[AUTH_TOKEN_SIZE];
+
+ if (!rand_bytes(tok, AUTH_TOKEN_SIZE))
+ {
+ msg( M_FATAL, "Failed to get enough randomness for "
+ "authentication token");
+ }
+
+ /* The token should be longer than the input when
+ * being base64 encoded
+ */
+ if( openvpn_base64_encode(tok, AUTH_TOKEN_SIZE,
+ &multi->auth_token) < AUTH_TOKEN_SIZE)
+ {
+ msg(D_TLS_ERRORS, "BASE64 encoding of token failed. "
+ "No auth-token will be activated now");
+ if (multi->auth_token)
+ {
+ memset (multi->auth_token, 0, AUTH_TOKEN_SIZE);
+ free (multi->auth_token);
+ multi->auth_token = NULL;
+ }
+ }
+ else
+ {
+ multi->auth_token_tstamp = now;
+ dmsg (D_SHOW_KEYS, "Generated token for client: %s",
+ multi->auth_token);
+ }
+ }
+
if ((session->opt->ssl_flags & SSLF_USERNAME_AS_COMMON_NAME))
set_common_name (session, up->username);
#ifdef ENABLE_DEF_AUTH
@@ -1210,6 +1294,7 @@ verify_user_pass(struct user_pass *up, struct tls_multi *multi,
msg (D_TLS_ERRORS, "TLS Auth Error: Auth Username/Password verification failed for peer");
}
+ done:
gc_free (&gc);
}
@@ -1270,4 +1355,4 @@ verify_final_auth_checks(struct tls_multi *multi, struct tls_session *session)
gc_free (&gc);
}
}
-#endif /* defined(ENABLE_CRYPTO) && defined(ENABLE_SSL) */
+#endif /* ENABLE_CRYPTO */
diff --git a/src/openvpn/ssl_verify.h b/src/openvpn/ssl_verify.h
index e0bcba4..98312fd 100644
--- a/src/openvpn/ssl_verify.h
+++ b/src/openvpn/ssl_verify.h
@@ -30,17 +30,18 @@
#ifndef SSL_VERIFY_H_
#define SSL_VERIFY_H_
+#ifdef ENABLE_CRYPTO
+
#include "syshead.h"
#include "misc.h"
-#include "manage.h"
#include "ssl_common.h"
/* Include OpenSSL-specific code */
#ifdef ENABLE_CRYPTO_OPENSSL
#include "ssl_verify_openssl.h"
#endif
-#ifdef ENABLE_CRYPTO_POLARSSL
-#include "ssl_verify_polarssl.h"
+#ifdef ENABLE_CRYPTO_MBEDTLS
+#include "ssl_verify_mbedtls.h"
#endif
#include "ssl_verify_backend.h"
@@ -54,7 +55,7 @@
/** Structure containing the hash for a single certificate */
struct cert_hash {
- unsigned char sha1_hash[SHA_DIGEST_LENGTH]; /**< The SHA1 hash for a certificate */
+ unsigned char sha256_hash[256/8];
};
/** Structure containing the hashes for a full certificate chain */
@@ -66,8 +67,6 @@ struct cert_hash_set {
#define VERIFY_X509_SUBJECT_DN 1
#define VERIFY_X509_SUBJECT_RDN 2
#define VERIFY_X509_SUBJECT_RDN_PREFIX 3
-#define TLS_REMOTE_SUBJECT_DN 1 + 0x100
-#define TLS_REMOTE_SUBJECT_RDN_PREFIX 3 + 0x100
#define TLS_AUTHENTICATION_SUCCEEDED 0
#define TLS_AUTHENTICATION_FAILED 1
@@ -136,6 +135,14 @@ const char *tls_common_name (const struct tls_multi* multi, const bool null);
*/
const char *tls_username (const struct tls_multi *multi, const bool null);
+/**
+ * Compares certificates hashes, returns true if hashes are equal.
+ *
+ * @param chs1 cert 1 hash set
+ * @param chs2 cert 2 hash set
+ */
+bool cert_hash_compare (const struct cert_hash_set *chs1, const struct cert_hash_set *chs2);
+
#ifdef ENABLE_PF
/**
@@ -166,25 +173,6 @@ tls_common_name_hash (const struct tls_multi *multi, const char **cn, uint32_t *
#endif
/**
- * Returns whether or not the server should check for username/password
- *
- * @param session The current TLS session
- *
- * @return true if username and password verification is enabled,
- * false if not.
- *
- */
-static inline bool verify_user_pass_enabled(struct tls_session *session)
-{
- return (session->opt->auth_user_pass_verify_script
- || plugin_defined (session->opt->plugins, OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY)
-#ifdef MANAGEMENT_DEF_AUTH
- || management_enable_def_auth (management)
-#endif
- );
-}
-
-/**
* Verify the given username and password, using either an external script, a
* plugin, or the management interface.
*
@@ -211,8 +199,6 @@ void verify_user_pass(struct user_pass *up, struct tls_multi *multi,
*/
void verify_final_auth_checks(struct tls_multi *multi, struct tls_session *session);
-#ifdef ENABLE_X509_TRACK
-
struct x509_track
{
const struct x509_track *next;
@@ -222,10 +208,6 @@ struct x509_track
int nid;
};
-void x509_track_add (const struct x509_track **ll_head, const char *name, int msglevel, struct gc_arena *gc);
-
-#endif
-
/*
* Certificate checking for verify_nsCertType
*/
@@ -254,5 +236,6 @@ tls_client_reason (struct tls_multi *multi)
#endif
}
-#endif /* SSL_VERIFY_H_ */
+#endif /* ENABLE_CRYPTO */
+#endif /* SSL_VERIFY_H_ */
diff --git a/src/openvpn/ssl_verify_backend.h b/src/openvpn/ssl_verify_backend.h
index 01e453e..de304b9 100644
--- a/src/openvpn/ssl_verify_backend.h
+++ b/src/openvpn/ssl_verify_backend.h
@@ -66,10 +66,10 @@ result_t verify_cert(struct tls_session *session, openvpn_x509_cert_t *cert, int
*
* @param session TLS Session associated with this tunnel
* @param cert_depth Depth of the current certificate
- * @param sha1_hash Hash of the current certificate
+ * @param cert_hash Hash of the current certificate
*/
void cert_hash_remember (struct tls_session *session, const int cert_depth,
- const unsigned char *sha1_hash);
+ const struct buffer *cert_hash);
/*
* Library-specific functions.
@@ -87,14 +87,27 @@ void cert_hash_remember (struct tls_session *session, const int cert_depth,
*/
char *x509_get_subject (openvpn_x509_cert_t *cert, struct gc_arena *gc);
-/* Retrieve the certificate's SHA1 hash.
+/**
+ * Retrieve the certificate's SHA1 fingerprint.
*
- * @param cert Certificate to retrieve the hash from.
+ * @param cert Certificate to retrieve the fingerprint from.
* @param gc Garbage collection arena to use when allocating string.
*
- * @return a string containing the SHA1 hash of the certificate
+ * @return a string containing the certificate fingerprint
*/
-unsigned char *x509_get_sha1_hash (openvpn_x509_cert_t *cert, struct gc_arena *gc);
+struct buffer x509_get_sha1_fingerprint (openvpn_x509_cert_t *cert,
+ struct gc_arena *gc);
+
+/**
+ * Retrieve the certificate's SHA256 fingerprint.
+ *
+ * @param cert Certificate to retrieve the fingerprint from.
+ * @param gc Garbage collection arena to use when allocating string.
+ *
+ * @return a string containing the certificate fingerprint
+ */
+struct buffer x509_get_sha256_fingerprint (openvpn_x509_cert_t *cert,
+ struct gc_arena *gc);
/*
* Retrieve the certificate's username from the specified field.
@@ -150,8 +163,6 @@ char *backend_x509_get_serial_hex (openvpn_x509_cert_t *cert,
*/
void x509_setenv (struct env_set *es, int cert_depth, openvpn_x509_cert_t *cert);
-#ifdef ENABLE_X509_TRACK
-
/*
* Start tracking the given attribute.
*
@@ -189,8 +200,6 @@ void x509_track_add (const struct x509_track **ll_head, const char *name,
void x509_setenv_track (const struct x509_track *xt, struct env_set *es,
const int depth, openvpn_x509_cert_t *x509);
-#endif
-
/*
* Check X.509 Netscape certificate type field, if available.
*
@@ -204,8 +213,6 @@ void x509_setenv_track (const struct x509_track *xt, struct env_set *es,
*/
result_t x509_verify_ns_cert_type(const openvpn_x509_cert_t *cert, const int usage);
-#if OPENSSL_VERSION_NUMBER >= 0x00907000L || ENABLE_CRYPTO_POLARSSL
-
/*
* Verify X.509 key usage extension field.
*
@@ -234,8 +241,6 @@ result_t x509_verify_cert_ku (openvpn_x509_cert_t *x509, const unsigned * const
*/
result_t x509_verify_cert_eku (openvpn_x509_cert_t *x509, const char * const expected_oid);
-#endif
-
/*
* Store the given certificate in pem format in a temporary file in tmp_dir
*
@@ -247,18 +252,12 @@ result_t x509_verify_cert_eku (openvpn_x509_cert_t *x509, const char * const exp
*/
result_t x509_write_pem(FILE *peercert_file, openvpn_x509_cert_t *peercert);
-/*
- * Check the certificate against a CRL file.
- *
- * @param crl_file File name of the CRL file
- * @param cert Certificate to verify
- * @param subject Subject of the given certificate
- *
- * @return \c SUCCESS if the CRL was not signed by the issuer of the
- * certificate or does not contain an entry for it.
- * \c FAILURE otherwise.
+/**
+ * Return true iff a CRL is configured, but is not loaded. This can be caused
+ * by e.g. a CRL parsing error, a missing CRL file or CRL file permission
+ * errors. (These conditions are checked upon startup, but the CRL might be
+ * updated and reloaded during runtime.)
*/
-result_t x509_verify_crl(const char *crl_file, openvpn_x509_cert_t *cert,
- const char *subject);
+bool tls_verify_crl_missing(const struct tls_options *opt);
#endif /* SSL_VERIFY_BACKEND_H_ */
diff --git a/src/openvpn/ssl_verify_mbedtls.c b/src/openvpn/ssl_verify_mbedtls.c
new file mode 100644
index 0000000..332f04b
--- /dev/null
+++ b/src/openvpn/ssl_verify_mbedtls.c
@@ -0,0 +1,511 @@
+/*
+ * OpenVPN -- An application to securely tunnel IP networks
+ * over a single TCP/UDP port, with support for SSL/TLS-based
+ * session authentication and key exchange,
+ * packet encryption, packet authentication, and
+ * packet compression.
+ *
+ * Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net>
+ * Copyright (C) 2010 Fox Crypto B.V. <openvpn@fox-it.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program (see the file COPYING included with this
+ * distribution); if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/**
+ * @file Control Channel Verification Module mbed TLS backend
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#elif defined(_MSC_VER)
+#include "config-msvc.h"
+#endif
+
+#include "syshead.h"
+
+#if defined(ENABLE_CRYPTO) && defined(ENABLE_CRYPTO_MBEDTLS)
+
+#include "crypto_mbedtls.h"
+#include "ssl_verify.h"
+#include <mbedtls/asn1.h>
+#include <mbedtls/error.h>
+#include <mbedtls/bignum.h>
+#include <mbedtls/oid.h>
+#include <mbedtls/sha1.h>
+
+#define MAX_SUBJECT_LENGTH 256
+
+int
+verify_callback (void *session_obj, mbedtls_x509_crt *cert, int cert_depth,
+ uint32_t *flags)
+{
+ struct tls_session *session = (struct tls_session *) session_obj;
+ struct gc_arena gc = gc_new();
+
+ ASSERT (cert);
+ ASSERT (session);
+
+ session->verified = false;
+
+ /* Remember certificate hash */
+ struct buffer cert_fingerprint = x509_get_sha256_fingerprint (cert, &gc);
+ cert_hash_remember (session, cert_depth, &cert_fingerprint);
+
+ /* did peer present cert which was signed by our root cert? */
+ if (*flags != 0)
+ {
+ int ret = 0;
+ char errstr[512] = { 0 };
+ char *subject = x509_get_subject(cert, &gc);
+
+ ret = mbedtls_x509_crt_verify_info (errstr, sizeof(errstr)-1, "", *flags);
+ if (ret <= 0 && !openvpn_snprintf(errstr, sizeof(errstr),
+ "Could not retrieve error string, flags=%"PRIx32, *flags))
+ {
+ errstr[0] = '\0';
+ }
+ else
+ {
+ chomp(errstr);
+ }
+
+ if (subject)
+ {
+ msg (D_TLS_ERRORS, "VERIFY ERROR: depth=%d, subject=%s: %s",
+ cert_depth, subject, errstr);
+ }
+ else
+ {
+ msg (D_TLS_ERRORS, "VERIFY ERROR: depth=%d, (could not extract X509 "
+ "subject string from certificate): %s", cert_depth, errstr);
+ }
+
+ /* Leave flags set to non-zero to indicate that the cert is not ok */
+ }
+ else if (SUCCESS != verify_cert(session, cert, cert_depth))
+ {
+ *flags |= MBEDTLS_X509_BADCERT_OTHER;
+ }
+
+ gc_free(&gc);
+
+ /*
+ * PolarSSL/mbed TLS-1.2.0+ expects 0 on anything except fatal errors.
+ */
+ return 0;
+}
+
+#ifdef ENABLE_X509ALTUSERNAME
+# warning "X509 alt user name not yet supported for mbed TLS"
+#endif
+
+result_t
+backend_x509_get_username (char *cn, int cn_len,
+ char *x509_username_field, mbedtls_x509_crt *cert)
+{
+ mbedtls_x509_name *name;
+
+ ASSERT( cn != NULL );
+
+ name = &cert->subject;
+
+ /* Find common name */
+ while( name != NULL )
+ {
+ if (0 == memcmp (name->oid.p, MBEDTLS_OID_AT_CN,
+ MBEDTLS_OID_SIZE (MBEDTLS_OID_AT_CN)))
+ break;
+
+ name = name->next;
+ }
+
+ /* Not found, return an error if this is the peer's certificate */
+ if( name == NULL )
+ return FAILURE;
+
+ /* Found, extract CN */
+ if (cn_len > name->val.len)
+ {
+ memcpy( cn, name->val.p, name->val.len );
+ cn[name->val.len] = '\0';
+ }
+ else
+ {
+ memcpy( cn, name->val.p, cn_len);
+ cn[cn_len-1] = '\0';
+ }
+
+ return SUCCESS;
+}
+
+char *
+backend_x509_get_serial (mbedtls_x509_crt *cert, struct gc_arena *gc)
+{
+ char *buf = NULL;
+ size_t buflen = 0;
+ mbedtls_mpi serial_mpi = { 0 };
+
+ /* Transform asn1 integer serial into mbed TLS MPI */
+ mbedtls_mpi_init(&serial_mpi);
+ if (!mbed_ok(mbedtls_mpi_read_binary(&serial_mpi, cert->serial.p,
+ cert->serial.len)))
+ {
+ msg(M_WARN, "Failed to retrieve serial from certificate.");
+ goto end;
+ }
+
+ /* Determine decimal representation length, allocate buffer */
+ mbedtls_mpi_write_string(&serial_mpi, 10, NULL, 0, &buflen);
+ buf = gc_malloc(buflen, true, gc);
+
+ /* Write MPI serial as decimal string into buffer */
+ if (!mbed_ok(mbedtls_mpi_write_string(&serial_mpi, 10, buf, buflen, &buflen)))
+ {
+ msg(M_WARN, "Failed to write serial to string.");
+ buf = NULL;
+ goto end;
+ }
+
+end:
+ mbedtls_mpi_free(&serial_mpi);
+ return buf;
+}
+
+char *
+backend_x509_get_serial_hex (mbedtls_x509_crt *cert, struct gc_arena *gc)
+{
+ char *buf = NULL;
+ size_t len = cert->serial.len * 3 + 1;
+
+ buf = gc_malloc(len, true, gc);
+
+ if(mbedtls_x509_serial_gets(buf, len-1, &cert->serial) < 0)
+ buf = NULL;
+
+ return buf;
+}
+
+static struct buffer
+x509_get_fingerprint (const mbedtls_md_info_t *md_info, mbedtls_x509_crt *cert,
+ struct gc_arena *gc)
+{
+ const size_t md_size = mbedtls_md_get_size (md_info);
+ struct buffer fingerprint = alloc_buf_gc (md_size, gc);
+ mbedtls_md(md_info, cert->raw.p, cert->tbs.len, BPTR (&fingerprint));
+ ASSERT (buf_inc_len(&fingerprint, md_size));
+ return fingerprint;
+}
+
+struct buffer
+x509_get_sha1_fingerprint (mbedtls_x509_crt *cert, struct gc_arena *gc)
+{
+ return x509_get_fingerprint(mbedtls_md_info_from_type(MBEDTLS_MD_SHA1),
+ cert, gc);
+}
+
+struct buffer
+x509_get_sha256_fingerprint (mbedtls_x509_crt *cert, struct gc_arena *gc)
+{
+ return x509_get_fingerprint(mbedtls_md_info_from_type(MBEDTLS_MD_SHA256),
+ cert, gc);
+}
+
+char *
+x509_get_subject(mbedtls_x509_crt *cert, struct gc_arena *gc)
+{
+ char tmp_subject[MAX_SUBJECT_LENGTH] = {0};
+ char *subject = NULL;
+
+ int ret = 0;
+
+ ret = mbedtls_x509_dn_gets( tmp_subject, MAX_SUBJECT_LENGTH-1, &cert->subject );
+ if (ret > 0)
+ {
+ /* Allocate the required space for the subject */
+ subject = string_alloc(tmp_subject, gc);
+ }
+
+ return subject;
+}
+
+static void
+do_setenv_x509 (struct env_set *es, const char *name, char *value, int depth)
+{
+ char *name_expand;
+ size_t name_expand_size;
+
+ string_mod (value, CC_ANY, CC_CRLF, '?');
+ msg (D_X509_ATTR, "X509 ATTRIBUTE name='%s' value='%s' depth=%d", name, value, depth);
+ name_expand_size = 64 + strlen (name);
+ name_expand = (char *) malloc (name_expand_size);
+ check_malloc_return (name_expand);
+ openvpn_snprintf (name_expand, name_expand_size, "X509_%d_%s", depth, name);
+ setenv_str (es, name_expand, value);
+ free (name_expand);
+}
+
+static char *
+asn1_buf_to_c_string(const mbedtls_asn1_buf *orig, struct gc_arena *gc)
+{
+ size_t i;
+ char *val;
+
+ for (i = 0; i < orig->len; ++i)
+ if (orig->p[i] == '\0')
+ return "ERROR: embedded null value";
+ val = gc_malloc(orig->len+1, false, gc);
+ memcpy(val, orig->p, orig->len);
+ val[orig->len] = '\0';
+ return val;
+}
+
+static void
+do_setenv_name(struct env_set *es, const struct x509_track *xt,
+ const mbedtls_x509_crt *cert, int depth, struct gc_arena *gc)
+{
+ const mbedtls_x509_name *xn;
+ for (xn = &cert->subject; xn != NULL; xn = xn->next)
+ {
+ const char *xn_short_name = NULL;
+ if (0 == mbedtls_oid_get_attr_short_name (&xn->oid, &xn_short_name) &&
+ 0 == strcmp (xt->name, xn_short_name))
+ {
+ char *val_str = asn1_buf_to_c_string (&xn->val, gc);
+ do_setenv_x509 (es, xt->name, val_str, depth);
+ }
+ }
+}
+
+void
+x509_track_add (const struct x509_track **ll_head, const char *name, int msglevel, struct gc_arena *gc)
+{
+ struct x509_track *xt;
+ ALLOC_OBJ_CLEAR_GC (xt, struct x509_track, gc);
+ if (*name == '+')
+ {
+ xt->flags |= XT_FULL_CHAIN;
+ ++name;
+ }
+ xt->name = name;
+ xt->next = *ll_head;
+ *ll_head = xt;
+}
+
+void
+x509_setenv_track (const struct x509_track *xt, struct env_set *es,
+ const int depth, mbedtls_x509_crt *cert)
+{
+ struct gc_arena gc = gc_new();
+ while (xt)
+ {
+ if (depth == 0 || (xt->flags & XT_FULL_CHAIN))
+ {
+ if (0 == strcmp(xt->name, "SHA1") || 0 == strcmp(xt->name, "SHA256"))
+ {
+ /* Fingerprint is not part of X509 structure */
+ struct buffer cert_hash;
+ char *fingerprint;
+
+ if (0 == strcmp(xt->name, "SHA1"))
+ cert_hash = x509_get_sha1_fingerprint(cert, &gc);
+ else
+ cert_hash = x509_get_sha256_fingerprint(cert, &gc);
+
+ fingerprint = format_hex_ex(BPTR(&cert_hash),
+ BLEN(&cert_hash), 0, 1 | FHE_CAPS, ":", &gc);
+ do_setenv_x509(es, xt->name, fingerprint, depth);
+ }
+ else
+ {
+ do_setenv_name(es, xt, cert, depth, &gc);
+ }
+ }
+ xt = xt->next;
+ }
+ gc_free(&gc);
+}
+
+/*
+ * Save X509 fields to environment, using the naming convention:
+ *
+ * X509_{cert_depth}_{name}={value}
+ */
+void
+x509_setenv (struct env_set *es, int cert_depth, mbedtls_x509_crt *cert)
+{
+ int i;
+ unsigned char c;
+ const mbedtls_x509_name *name;
+ char s[128];
+
+ name = &cert->subject;
+
+ memset( s, 0, sizeof( s ) );
+
+ while( name != NULL )
+ {
+ char name_expand[64+8];
+ const char *shortname;
+
+ if( 0 == mbedtls_oid_get_attr_short_name(&name->oid, &shortname) )
+ {
+ openvpn_snprintf (name_expand, sizeof(name_expand), "X509_%d_%s",
+ cert_depth, shortname);
+ }
+ else
+ {
+ openvpn_snprintf (name_expand, sizeof(name_expand), "X509_%d_\?\?",
+ cert_depth);
+ }
+
+ for( i = 0; i < name->val.len; i++ )
+ {
+ if( i >= (int) sizeof( s ) - 1 )
+ break;
+
+ c = name->val.p[i];
+ if( c < 32 || c == 127 || ( c > 128 && c < 160 ) )
+ s[i] = '?';
+ else s[i] = c;
+ }
+ s[i] = '\0';
+
+ /* Check both strings, set environment variable */
+ string_mod (name_expand, CC_PRINT, CC_CRLF, '_');
+ string_mod ((char*)s, CC_PRINT, CC_CRLF, '_');
+ setenv_str_incr (es, name_expand, (char*)s);
+
+ name = name->next;
+ }
+}
+
+result_t
+x509_verify_ns_cert_type(const mbedtls_x509_crt *cert, const int usage)
+{
+ if (usage == NS_CERT_CHECK_NONE)
+ return SUCCESS;
+ if (usage == NS_CERT_CHECK_CLIENT)
+ return ((cert->ext_types & MBEDTLS_X509_EXT_NS_CERT_TYPE)
+ && (cert->ns_cert_type & MBEDTLS_X509_NS_CERT_TYPE_SSL_CLIENT)) ?
+ SUCCESS : FAILURE;
+ if (usage == NS_CERT_CHECK_SERVER)
+ return ((cert->ext_types & MBEDTLS_X509_EXT_NS_CERT_TYPE)
+ && (cert->ns_cert_type & MBEDTLS_X509_NS_CERT_TYPE_SSL_SERVER)) ?
+ SUCCESS : FAILURE;
+
+ return FAILURE;
+}
+
+result_t
+x509_verify_cert_ku (mbedtls_x509_crt *cert, const unsigned * const expected_ku,
+ int expected_len)
+{
+ result_t fFound = FAILURE;
+
+ if(!(cert->ext_types & MBEDTLS_X509_EXT_KEY_USAGE))
+ {
+ msg (D_HANDSHAKE, "Certificate does not have key usage extension");
+ }
+ else
+ {
+ int i;
+ unsigned nku = cert->key_usage;
+
+ msg (D_HANDSHAKE, "Validating certificate key usage");
+ for (i=0; SUCCESS != fFound && i<expected_len; i++)
+ {
+ if (expected_ku[i] != 0)
+ {
+ msg (D_HANDSHAKE, "++ Certificate has key usage %04x, expects "
+ "%04x", nku, expected_ku[i]);
+
+ if (nku == expected_ku[i])
+ {
+ fFound = SUCCESS;
+ }
+ }
+ }
+ }
+ return fFound;
+}
+
+result_t
+x509_verify_cert_eku (mbedtls_x509_crt *cert, const char * const expected_oid)
+{
+ result_t fFound = FAILURE;
+
+ if (!(cert->ext_types & MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE))
+ {
+ msg (D_HANDSHAKE, "Certificate does not have extended key usage extension");
+ }
+ else
+ {
+ mbedtls_x509_sequence *oid_seq = &(cert->ext_key_usage);
+
+ msg (D_HANDSHAKE, "Validating certificate extended key usage");
+ while (oid_seq != NULL)
+ {
+ mbedtls_x509_buf *oid = &oid_seq->buf;
+ char oid_num_str[1024];
+ const char *oid_str;
+
+ if (0 == mbedtls_oid_get_extended_key_usage( oid, &oid_str ))
+ {
+ msg (D_HANDSHAKE, "++ Certificate has EKU (str) %s, expects %s",
+ oid_str, expected_oid);
+ if (!strcmp (expected_oid, oid_str))
+ {
+ fFound = SUCCESS;
+ break;
+ }
+ }
+
+ if (0 < mbedtls_oid_get_numeric_string( oid_num_str,
+ sizeof (oid_num_str), oid))
+ {
+ msg (D_HANDSHAKE, "++ Certificate has EKU (oid) %s, expects %s",
+ oid_num_str, expected_oid);
+ if (!strcmp (expected_oid, oid_num_str))
+ {
+ fFound = SUCCESS;
+ break;
+ }
+ }
+ oid_seq = oid_seq->next;
+ }
+ }
+
+ return fFound;
+}
+
+result_t
+x509_write_pem(FILE *peercert_file, mbedtls_x509_crt *peercert)
+{
+ msg (M_WARN, "mbed TLS does not support writing peer certificate in PEM format");
+ return FAILURE;
+}
+
+bool
+tls_verify_crl_missing(const struct tls_options *opt)
+{
+ if (opt->crl_file && !(opt->ssl_flags & SSLF_CRL_VERIFY_DIR)
+ && (opt->ssl_ctx.crl == NULL || opt->ssl_ctx.crl->version == 0))
+ {
+ return true;
+ }
+ return false;
+}
+
+#endif /* #if defined(ENABLE_CRYPTO) && defined(ENABLE_CRYPTO_MBEDTLS) */
diff --git a/src/openvpn/ssl_verify_polarssl.h b/src/openvpn/ssl_verify_mbedtls.h
index b5157ed..e26d08f 100644
--- a/src/openvpn/ssl_verify_polarssl.h
+++ b/src/openvpn/ssl_verify_mbedtls.h
@@ -24,20 +24,18 @@
*/
/**
- * @file Control Channel Verification Module PolarSSL backend
+ * @file Control Channel Verification Module mbed TLS backend
*/
-#ifndef SSL_VERIFY_POLARSSL_H_
-#define SSL_VERIFY_POLARSSL_H_
+#ifndef SSL_VERIFY_MBEDTLS_H_
+#define SSL_VERIFY_MBEDTLS_H_
#include "syshead.h"
-#include "misc.h"
-#include "manage.h"
-#include <polarssl/x509_crt.h>
+#include <mbedtls/x509_crt.h>
#ifndef __OPENVPN_X509_CERT_T_DECLARED
#define __OPENVPN_X509_CERT_T_DECLARED
-typedef x509_crt openvpn_x509_cert_t;
+typedef mbedtls_x509_crt openvpn_x509_cert_t;
#endif
/** @name Function for authenticating a new connection from a remote OpenVPN peer
@@ -52,7 +50,7 @@ typedef x509_crt openvpn_x509_cert_t;
* determine whether the remote OpenVPN peer's certificate is allowed to
* connect. It is called for once for every certificate in the chain. The
* callback functionality is configured in the \c init_ssl() function, which
- * calls the PolarSSL library's \c ssl_set_verify_callback() function with \c
+ * calls the mbed TLS library's \c ssl_set_verify_callback() function with \c
* verify_callback() as its callback argument.
*
* It checks *flags and registers the certificate hash. If these steps succeed,
@@ -61,7 +59,7 @@ typedef x509_crt openvpn_x509_cert_t;
*
* @param session_obj - The OpenVPN \c tls_session associated with this object,
* as set during SSL session setup.
- * @param cert - The certificate used by PolarSSL.
+ * @param cert - The certificate used by mbed TLS.
* @param cert_depth - The depth of the current certificate in the chain, with
* 0 being the actual certificate.
* @param flags - Whether the remote OpenVPN peer's certificate
@@ -72,9 +70,9 @@ typedef x509_crt openvpn_x509_cert_t;
*
* @return The return value is 0 unless a fatal error occurred.
*/
-int verify_callback (void *session_obj, x509_crt *cert, int cert_depth,
- int *flags);
+int verify_callback (void *session_obj, mbedtls_x509_crt *cert, int cert_depth,
+ uint32_t *flags);
/** @} name Function for authenticating a new connection from a remote OpenVPN peer */
-#endif /* SSL_VERIFY_POLARSSL_H_ */
+#endif /* SSL_VERIFY_MBEDTLS_H_ */
diff --git a/src/openvpn/ssl_verify_openssl.c b/src/openvpn/ssl_verify_openssl.c
index 4750f02..3d1c85e 100644
--- a/src/openvpn/ssl_verify_openssl.c
+++ b/src/openvpn/ssl_verify_openssl.c
@@ -35,11 +35,15 @@
#include "syshead.h"
-#if defined(ENABLE_SSL) && defined(ENABLE_CRYPTO_OPENSSL)
+#if defined(ENABLE_CRYPTO) && defined(ENABLE_CRYPTO_OPENSSL)
+#include "ssl_verify_openssl.h"
+
+#include "error.h"
+#include "ssl_openssl.h"
#include "ssl_verify.h"
#include "ssl_verify_backend.h"
-#include "ssl_openssl.h"
+
#include <openssl/x509v3.h>
#include <openssl/err.h>
@@ -57,8 +61,8 @@ verify_callback (int preverify_ok, X509_STORE_CTX * ctx)
session = (struct tls_session *) SSL_get_ex_data (ssl, mydata_index);
ASSERT (session);
- cert_hash_remember (session, ctx->error_depth,
- x509_get_sha1_hash(ctx->current_cert, &gc));
+ struct buffer cert_hash = x509_get_sha256_fingerprint(ctx->current_cert, &gc);
+ cert_hash_remember (session, ctx->error_depth, &cert_hash);
/* did peer present cert which was signed by our root cert? */
if (!preverify_ok)
@@ -66,15 +70,28 @@ verify_callback (int preverify_ok, X509_STORE_CTX * ctx)
/* get the X509 name */
char *subject = x509_get_subject(ctx->current_cert, &gc);
- if (subject)
+ if (!subject)
+ {
+ subject = "(Failed to retrieve certificate subject)";
+ }
+
+ /* Log and ignore missing CRL errors */
+ if (ctx->error == X509_V_ERR_UNABLE_TO_GET_CRL)
{
- /* Remote site specified a certificate, but it's not correct */
- msg (D_TLS_ERRORS, "VERIFY ERROR: depth=%d, error=%s: %s",
- ctx->error_depth,
- X509_verify_cert_error_string (ctx->error),
- subject);
+ msg (D_TLS_DEBUG_LOW, "VERIFY WARNING: depth=%d, %s: %s",
+ ctx->error_depth,
+ X509_verify_cert_error_string (ctx->error),
+ subject);
+ ret = 1;
+ goto cleanup;
}
+ /* Remote site specified a certificate, but it's not correct */
+ msg (D_TLS_ERRORS, "VERIFY ERROR: depth=%d, error=%s: %s",
+ ctx->error_depth,
+ X509_verify_cert_error_string (ctx->error),
+ subject);
+
ERR_clear_error();
session->verified = false;
@@ -134,8 +151,8 @@ bool extract_x509_extension(X509 *cert, char *fieldname, char *out, int size)
}
break;
default:
- msg (D_TLS_ERRORS, "ASN1 ERROR: can not handle field type %i",
- name->type);
+ msg (D_TLS_DEBUG, "%s: ignoring general name field type %i",
+ __func__, name->type);
break;
}
}
@@ -165,8 +182,8 @@ extract_x509_field_ssl (X509_NAME *x509, const char *field_name, char *out,
int tmp = -1;
X509_NAME_ENTRY *x509ne = 0;
ASN1_STRING *asn1 = 0;
- unsigned char *buf = (unsigned char *)1; /* bug in OpenSSL 0.9.6b ASN1_STRING_to_UTF8 requires this workaround */
- int nid = OBJ_txt2nid((char *)field_name);
+ unsigned char *buf = NULL;
+ int nid = OBJ_txt2nid(field_name);
ASSERT (size > 0);
*out = '\0';
@@ -244,11 +261,21 @@ backend_x509_get_serial_hex (openvpn_x509_cert_t *cert, struct gc_arena *gc)
return format_hex_ex(asn1_i->data, asn1_i->length, 0, 1, ":", gc);
}
-unsigned char *
-x509_get_sha1_hash (X509 *cert, struct gc_arena *gc)
+struct buffer
+x509_get_sha1_fingerprint (X509 *cert, struct gc_arena *gc)
+{
+ struct buffer hash = alloc_buf_gc(sizeof(cert->sha1_hash), gc);
+ memcpy(BPTR(&hash), cert->sha1_hash, sizeof(cert->sha1_hash));
+ ASSERT (buf_inc_len(&hash, sizeof (cert->sha1_hash)));
+ return hash;
+}
+
+struct buffer
+x509_get_sha256_fingerprint (X509 *cert, struct gc_arena *gc)
{
- unsigned char *hash = gc_malloc(SHA_DIGEST_LENGTH, false, gc);
- memcpy(hash, cert->sha1_hash, SHA_DIGEST_LENGTH);
+ struct buffer hash = alloc_buf_gc((EVP_sha256())->md_size, gc);
+ X509_digest(cert, EVP_sha256(), BPTR(&hash), NULL);
+ ASSERT (buf_inc_len(&hash, (EVP_sha256())->md_size));
return hash;
}
@@ -299,7 +326,26 @@ err:
}
-#ifdef ENABLE_X509_TRACK
+/*
+ * x509-track implementation -- save X509 fields to environment,
+ * using the naming convention:
+ *
+ * X509_{cert_depth}_{name}={value}
+ *
+ * This function differs from x509_setenv below in the following ways:
+ *
+ * (1) Only explicitly named attributes in xt are saved, per usage
+ * of "x509-track" program options.
+ * (2) Only the level 0 cert info is saved unless the XT_FULL_CHAIN
+ * flag is set in xt->flags (corresponds with prepending a '+'
+ * to the name when specified by "x509-track" program option).
+ * (3) This function supports both X509 subject name fields as
+ * well as X509 V3 extensions.
+ * (4) This function can return the SHA1 fingerprint of a cert, e.g.
+ * x509-track "+SHA1"
+ * will return the SHA1 fingerprint for each certificate in the
+ * peer chain.
+ */
void
x509_track_add (const struct x509_track **ll_head, const char *name, int msglevel, struct gc_arena *gc)
@@ -342,60 +388,82 @@ do_setenv_x509 (struct env_set *es, const char *name, char *value, int depth)
void
x509_setenv_track (const struct x509_track *xt, struct env_set *es, const int depth, X509 *x509)
{
+ struct gc_arena gc = gc_new();
X509_NAME *x509_name = X509_get_subject_name (x509);
const char nullc = '\0';
- int i;
while (xt)
{
if (depth == 0 || (xt->flags & XT_FULL_CHAIN))
{
- i = X509_NAME_get_index_by_NID(x509_name, xt->nid, -1);
- if (i >= 0)
- {
- X509_NAME_ENTRY *ent = X509_NAME_get_entry(x509_name, i);
- if (ent)
- {
- ASN1_STRING *val = X509_NAME_ENTRY_get_data (ent);
- unsigned char *buf;
- buf = (unsigned char *)1; /* bug in OpenSSL 0.9.6b ASN1_STRING_to_UTF8 requires this workaround */
- if (ASN1_STRING_to_UTF8 (&buf, val) > 0)
- {
- do_setenv_x509(es, xt->name, (char *)buf, depth);
- OPENSSL_free (buf);
- }
- }
- }
- else
+ switch (xt->nid)
{
- i = X509_get_ext_by_NID(x509, xt->nid, -1);
- if (i >= 0)
- {
- X509_EXTENSION *ext = X509_get_ext(x509, i);
- if (ext)
- {
- BIO *bio = BIO_new(BIO_s_mem());
- if (bio)
- {
- if (X509V3_EXT_print(bio, ext, 0, 0))
- {
- if (BIO_write(bio, &nullc, 1) == 1)
- {
- char *str;
- BIO_get_mem_data(bio, &str);
- do_setenv_x509(es, xt->name, str, depth);
- }
- }
- BIO_free(bio);
- }
- }
- }
+ case NID_sha1:
+ case NID_sha256:
+ {
+ struct buffer fp_buf;
+ char *fp_str = NULL;
+
+ if (xt->nid == NID_sha1)
+ fp_buf = x509_get_sha1_fingerprint(x509, &gc);
+ else
+ fp_buf = x509_get_sha256_fingerprint(x509, &gc);
+
+ fp_str = format_hex_ex(BPTR(&fp_buf), BLEN(&fp_buf), 0,
+ 1 | FHE_CAPS, ":", &gc);
+ do_setenv_x509(es, xt->name, fp_str, depth);
+ }
+ break;
+ default:
+ {
+ int i = X509_NAME_get_index_by_NID(x509_name, xt->nid, -1);
+ if (i >= 0)
+ {
+ X509_NAME_ENTRY *ent = X509_NAME_get_entry(x509_name, i);
+ if (ent)
+ {
+ ASN1_STRING *val = X509_NAME_ENTRY_get_data (ent);
+ unsigned char *buf;
+ buf = (unsigned char *)1; /* bug in OpenSSL 0.9.6b ASN1_STRING_to_UTF8 requires this workaround */
+ if (ASN1_STRING_to_UTF8 (&buf, val) > 0)
+ {
+ do_setenv_x509(es, xt->name, (char *)buf, depth);
+ OPENSSL_free (buf);
+ }
+ }
+ }
+ else
+ {
+ i = X509_get_ext_by_NID(x509, xt->nid, -1);
+ if (i >= 0)
+ {
+ X509_EXTENSION *ext = X509_get_ext(x509, i);
+ if (ext)
+ {
+ BIO *bio = BIO_new(BIO_s_mem());
+ if (bio)
+ {
+ if (X509V3_EXT_print(bio, ext, 0, 0))
+ {
+ if (BIO_write(bio, &nullc, 1) == 1)
+ {
+ char *str;
+ BIO_get_mem_data(bio, &str);
+ do_setenv_x509(es, xt->name, str, depth);
+ }
+ }
+ BIO_free(bio);
+ }
+ }
+ }
+ }
+ }
}
}
xt = xt->next;
}
+ gc_free(&gc);
}
-#endif
/*
* Save X509 fields to environment, using the naming convention:
@@ -444,7 +512,7 @@ x509_setenv (struct env_set *es, int cert_depth, openvpn_x509_cert_t *peer_cert)
objbuf);
string_mod (name_expand, CC_PRINT, CC_CRLF, '_');
string_mod ((char*)buf, CC_PRINT, CC_CRLF, '_');
- setenv_str (es, name_expand, (char*)buf);
+ setenv_str_incr (es, name_expand, (char*)buf);
free (name_expand);
OPENSSL_free (buf);
}
@@ -465,8 +533,6 @@ x509_verify_ns_cert_type(const openvpn_x509_cert_t *peer_cert, const int usage)
return FAILURE;
}
-#if OPENSSL_VERSION_NUMBER >= 0x00907000L
-
result_t
x509_verify_cert_ku (X509 *x509, const unsigned * const expected_ku,
int expected_len)
@@ -572,61 +638,28 @@ x509_write_pem(FILE *peercert_file, X509 *peercert)
return SUCCESS;
}
-#endif /* OPENSSL_VERSION_NUMBER */
-
-/*
- * check peer cert against CRL
- */
-result_t
-x509_verify_crl(const char *crl_file, X509 *peer_cert, const char *subject)
+bool
+tls_verify_crl_missing(const struct tls_options *opt)
{
- X509_CRL *crl=NULL;
- X509_REVOKED *revoked;
- BIO *in=NULL;
- int n,i;
- result_t retval = FAILURE;
- struct gc_arena gc = gc_new();
- char *serial;
-
- in = BIO_new_file (crl_file, "r");
-
- if (in == NULL) {
- msg (M_WARN, "CRL: cannot read: %s", crl_file);
- goto end;
- }
- crl=PEM_read_bio_X509_CRL(in,NULL,NULL,NULL);
- if (crl == NULL) {
- msg (M_WARN, "CRL: cannot read CRL from file %s", crl_file);
- goto end;
- }
-
- if (X509_NAME_cmp(X509_CRL_get_issuer(crl), X509_get_issuer_name(peer_cert)) != 0) {
- msg (M_WARN, "CRL: CRL %s is from a different issuer than the issuer of "
- "certificate %s", crl_file, subject);
- retval = SUCCESS;
- goto end;
- }
-
- n = sk_X509_REVOKED_num(X509_CRL_get_REVOKED(crl));
- for (i = 0; i < n; i++) {
- revoked = (X509_REVOKED *)sk_X509_REVOKED_value(X509_CRL_get_REVOKED(crl), i);
- if (ASN1_INTEGER_cmp(revoked->serialNumber, X509_get_serialNumber(peer_cert)) == 0) {
- serial = backend_x509_get_serial_hex(peer_cert, &gc);
- msg (D_HANDSHAKE, "CRL CHECK FAILED: %s (serial %s) is REVOKED", subject, (serial ? serial : "NOT AVAILABLE"));
- goto end;
+ if (!opt->crl_file || (opt->ssl_flags & SSLF_CRL_VERIFY_DIR))
+ {
+ return false;
}
- }
-
- retval = SUCCESS;
- msg (D_HANDSHAKE, "CRL CHECK OK: %s",subject);
-end:
- gc_free(&gc);
- BIO_free(in);
- if (crl)
- X509_CRL_free (crl);
+ X509_STORE *store = SSL_CTX_get_cert_store(opt->ssl_ctx.ctx);
+ if (!store)
+ crypto_msg (M_FATAL, "Cannot get certificate store");
- return retval;
+ for (int i = 0; i < sk_X509_OBJECT_num(store->objs); i++)
+ {
+ X509_OBJECT* obj = sk_X509_OBJECT_value(store->objs, i);
+ ASSERT(obj);
+ if (obj->type == X509_LU_CRL)
+ {
+ return false;
+ }
+ }
+ return true;
}
-#endif /* defined(ENABLE_SSL) && defined(ENABLE_CRYPTO_OPENSSL) */
+#endif /* defined(ENABLE_CRYPTO) && defined(ENABLE_CRYPTO_OPENSSL) */
diff --git a/src/openvpn/ssl_verify_polarssl.c b/src/openvpn/ssl_verify_polarssl.c
deleted file mode 100644
index 7ed87d6..0000000
--- a/src/openvpn/ssl_verify_polarssl.c
+++ /dev/null
@@ -1,397 +0,0 @@
-/*
- * OpenVPN -- An application to securely tunnel IP networks
- * over a single TCP/UDP port, with support for SSL/TLS-based
- * session authentication and key exchange,
- * packet encryption, packet authentication, and
- * packet compression.
- *
- * Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net>
- * Copyright (C) 2010 Fox Crypto B.V. <openvpn@fox-it.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program (see the file COPYING included with this
- * distribution); if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/**
- * @file Control Channel Verification Module PolarSSL backend
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#elif defined(_MSC_VER)
-#include "config-msvc.h"
-#endif
-
-#include "syshead.h"
-
-#if defined(ENABLE_SSL) && defined(ENABLE_CRYPTO_POLARSSL)
-
-#include "ssl_verify.h"
-#include <polarssl/bignum.h>
-#include <polarssl/error.h>
-#include <polarssl/oid.h>
-#include <polarssl/sha1.h>
-
-#define MAX_SUBJECT_LENGTH 256
-
-int
-verify_callback (void *session_obj, x509_crt *cert, int cert_depth,
- int *flags)
-{
- struct tls_session *session = (struct tls_session *) session_obj;
- struct gc_arena gc = gc_new();
-
- ASSERT (cert);
- ASSERT (session);
-
- session->verified = false;
-
- /* Remember certificate hash */
- cert_hash_remember (session, cert_depth, x509_get_sha1_hash(cert, &gc));
-
- /* did peer present cert which was signed by our root cert? */
- if (*flags != 0)
- {
- char *subject = x509_get_subject(cert, &gc);
-
- if (subject)
- msg (D_TLS_ERRORS, "VERIFY ERROR: depth=%d, flags=%x, %s", cert_depth, *flags, subject);
- else
- msg (D_TLS_ERRORS, "VERIFY ERROR: depth=%d, flags=%x, could not extract X509 "
- "subject string from certificate", *flags, cert_depth);
-
- /* Leave flags set to non-zero to indicate that the cert is not ok */
- }
- else if (SUCCESS != verify_cert(session, cert, cert_depth))
- {
- *flags |= BADCERT_OTHER;
- }
-
- gc_free(&gc);
-
- /*
- * PolarSSL-1.2.0+ expects 0 on anything except fatal errors.
- */
- return 0;
-}
-
-#ifdef ENABLE_X509ALTUSERNAME
-# warning "X509 alt user name not yet supported for PolarSSL"
-#endif
-
-result_t
-backend_x509_get_username (char *cn, int cn_len,
- char *x509_username_field, x509_crt *cert)
-{
- x509_name *name;
-
- ASSERT( cn != NULL );
-
- name = &cert->subject;
-
- /* Find common name */
- while( name != NULL )
- {
- if( memcmp( name->oid.p, OID_AT_CN, OID_SIZE(OID_AT_CN) ) == 0)
- break;
-
- name = name->next;
- }
-
- /* Not found, return an error if this is the peer's certificate */
- if( name == NULL )
- return FAILURE;
-
- /* Found, extract CN */
- if (cn_len > name->val.len)
- memcpy( cn, name->val.p, name->val.len );
- else
- {
- memcpy( cn, name->val.p, cn_len);
- cn[cn_len-1] = '\0';
- }
-
- return SUCCESS;
-}
-
-char *
-backend_x509_get_serial (openvpn_x509_cert_t *cert, struct gc_arena *gc)
-{
- char *buf = NULL;
- size_t buflen = 0;
- mpi serial_mpi = { 0 };
-
- /* Transform asn1 integer serial into PolarSSL MPI */
- mpi_init(&serial_mpi);
- if (!polar_ok(mpi_read_binary(&serial_mpi, cert->serial.p, cert->serial.len)))
- {
- msg(M_WARN, "Failed to retrieve serial from certificate.");
- return NULL;
- }
-
- /* Determine decimal representation length, allocate buffer */
- mpi_write_string(&serial_mpi, 10, buf, &buflen);
- buf = gc_malloc(buflen, true, gc);
-
- /* Write MPI serial as decimal string into buffer */
- if (!polar_ok(mpi_write_string(&serial_mpi, 10, buf, &buflen)))
- {
- msg(M_WARN, "Failed to write serial to string.");
- return NULL;
- }
-
- return buf;
-}
-
-char *
-backend_x509_get_serial_hex (openvpn_x509_cert_t *cert, struct gc_arena *gc)
-{
- char *buf = NULL;
- size_t len = cert->serial.len * 3 + 1;
-
- buf = gc_malloc(len, true, gc);
-
- if(x509_serial_gets(buf, len-1, &cert->serial) < 0)
- buf = NULL;
-
- return buf;
-}
-
-unsigned char *
-x509_get_sha1_hash (x509_crt *cert, struct gc_arena *gc)
-{
- unsigned char *sha1_hash = gc_malloc(SHA_DIGEST_LENGTH, false, gc);
- sha1(cert->tbs.p, cert->tbs.len, sha1_hash);
- return sha1_hash;
-}
-
-char *
-x509_get_subject(x509_crt *cert, struct gc_arena *gc)
-{
- char tmp_subject[MAX_SUBJECT_LENGTH] = {0};
- char *subject = NULL;
-
- int ret = 0;
-
- ret = x509_dn_gets( tmp_subject, MAX_SUBJECT_LENGTH-1, &cert->subject );
- if (ret > 0)
- {
- /* Allocate the required space for the subject */
- subject = string_alloc(tmp_subject, gc);
- }
-
- return subject;
-}
-
-/*
- * Save X509 fields to environment, using the naming convention:
- *
- * X509_{cert_depth}_{name}={value}
- */
-void
-x509_setenv (struct env_set *es, int cert_depth, openvpn_x509_cert_t *cert)
-{
- int i;
- unsigned char c;
- const x509_name *name;
- char s[128];
-
- name = &cert->subject;
-
- memset( s, 0, sizeof( s ) );
-
- while( name != NULL )
- {
- char name_expand[64+8];
- const char *shortname;
-
- if( 0 == oid_get_attr_short_name(&name->oid, &shortname) )
- {
- openvpn_snprintf (name_expand, sizeof(name_expand), "X509_%d_%s",
- cert_depth, shortname);
- }
- else
- {
- openvpn_snprintf (name_expand, sizeof(name_expand), "X509_%d_\?\?",
- cert_depth);
- }
-
- for( i = 0; i < name->val.len; i++ )
- {
- if( i >= (int) sizeof( s ) - 1 )
- break;
-
- c = name->val.p[i];
- if( c < 32 || c == 127 || ( c > 128 && c < 160 ) )
- s[i] = '?';
- else s[i] = c;
- }
- s[i] = '\0';
-
- /* Check both strings, set environment variable */
- string_mod (name_expand, CC_PRINT, CC_CRLF, '_');
- string_mod ((char*)s, CC_PRINT, CC_CRLF, '_');
- setenv_str (es, name_expand, (char*)s);
-
- name = name->next;
- }
-}
-
-result_t
-x509_verify_ns_cert_type(const x509_crt *cert, const int usage)
-{
- if (usage == NS_CERT_CHECK_NONE)
- return SUCCESS;
- if (usage == NS_CERT_CHECK_CLIENT)
- return ((cert->ext_types & EXT_NS_CERT_TYPE)
- && (cert->ns_cert_type & NS_CERT_TYPE_SSL_CLIENT)) ? SUCCESS : FAILURE;
- if (usage == NS_CERT_CHECK_SERVER)
- return ((cert->ext_types & EXT_NS_CERT_TYPE)
- && (cert->ns_cert_type & NS_CERT_TYPE_SSL_SERVER)) ? SUCCESS : FAILURE;
-
- return FAILURE;
-}
-
-result_t
-x509_verify_cert_ku (x509_crt *cert, const unsigned * const expected_ku,
- int expected_len)
-{
- result_t fFound = FAILURE;
-
- if(!(cert->ext_types & EXT_KEY_USAGE))
- {
- msg (D_HANDSHAKE, "Certificate does not have key usage extension");
- }
- else
- {
- int i;
- unsigned nku = cert->key_usage;
-
- msg (D_HANDSHAKE, "Validating certificate key usage");
- for (i=0; SUCCESS != fFound && i<expected_len; i++)
- {
- if (expected_ku[i] != 0)
- {
- msg (D_HANDSHAKE, "++ Certificate has key usage %04x, expects "
- "%04x", nku, expected_ku[i]);
-
- if (nku == expected_ku[i])
- {
- fFound = SUCCESS;
- }
- }
- }
- }
- return fFound;
-}
-
-result_t
-x509_verify_cert_eku (x509_crt *cert, const char * const expected_oid)
-{
- result_t fFound = FAILURE;
-
- if (!(cert->ext_types & EXT_EXTENDED_KEY_USAGE))
- {
- msg (D_HANDSHAKE, "Certificate does not have extended key usage extension");
- }
- else
- {
- x509_sequence *oid_seq = &(cert->ext_key_usage);
-
- msg (D_HANDSHAKE, "Validating certificate extended key usage");
- while (oid_seq != NULL)
- {
- x509_buf *oid = &oid_seq->buf;
- char oid_num_str[1024];
- const char *oid_str;
-
- if (0 == oid_get_extended_key_usage( oid, &oid_str ))
- {
- msg (D_HANDSHAKE, "++ Certificate has EKU (str) %s, expects %s",
- oid_str, expected_oid);
- if (!strcmp (expected_oid, oid_str))
- {
- fFound = SUCCESS;
- break;
- }
- }
-
- if (0 < oid_get_numeric_string( oid_num_str,
- sizeof (oid_num_str), oid))
- {
- msg (D_HANDSHAKE, "++ Certificate has EKU (oid) %s, expects %s",
- oid_num_str, expected_oid);
- if (!strcmp (expected_oid, oid_num_str))
- {
- fFound = SUCCESS;
- break;
- }
- }
- oid_seq = oid_seq->next;
- }
- }
-
- return fFound;
-}
-
-result_t
-x509_write_pem(FILE *peercert_file, x509_crt *peercert)
-{
- msg (M_WARN, "PolarSSL does not support writing peer certificate in PEM format");
- return FAILURE;
-}
-
-/*
- * check peer cert against CRL
- */
-result_t
-x509_verify_crl(const char *crl_file, x509_crt *cert, const char *subject)
-{
- result_t retval = FAILURE;
- x509_crl crl = {0};
- struct gc_arena gc = gc_new();
- char *serial;
-
- if (!polar_ok(x509_crl_parse_file(&crl, crl_file)))
- {
- msg (M_WARN, "CRL: cannot read CRL from file %s", crl_file);
- goto end;
- }
-
- if(cert->issuer_raw.len != crl.issuer_raw.len ||
- memcmp(crl.issuer_raw.p, cert->issuer_raw.p, crl.issuer_raw.len) != 0)
- {
- msg (M_WARN, "CRL: CRL %s is from a different issuer than the issuer of "
- "certificate %s", crl_file, subject);
- retval = SUCCESS;
- goto end;
- }
-
- if (!polar_ok(x509_crt_revoked(cert, &crl)))
- {
- serial = backend_x509_get_serial_hex(cert, &gc);
- msg (D_HANDSHAKE, "CRL CHECK FAILED: %s (serial %s) is REVOKED", subject, (serial ? serial : "NOT AVAILABLE"));
- goto end;
- }
-
- retval = SUCCESS;
- msg (D_HANDSHAKE, "CRL CHECK OK: %s",subject);
-
-end:
- gc_free(&gc);
- x509_crl_free(&crl);
- return retval;
-}
-
-#endif /* #if defined(ENABLE_SSL) && defined(ENABLE_CRYPTO_POLARSSL) */
diff --git a/src/openvpn/syshead.h b/src/openvpn/syshead.h
index 24926ae..8de7d87 100644
--- a/src/openvpn/syshead.h
+++ b/src/openvpn/syshead.h
@@ -37,7 +37,7 @@
# define unlikely(x) (x)
#endif
-#ifdef WIN32
+#ifdef _WIN32
#include <windows.h>
#include <winsock2.h>
#define sleep(x) Sleep((x)*1000)
@@ -64,7 +64,7 @@
# include <sys/wait.h>
#endif
-#ifndef WIN32
+#ifndef _WIN32
#ifndef WEXITSTATUS
# define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8)
#endif
@@ -217,7 +217,7 @@
#include <net/if_tap.h>
#endif
-#ifdef TARGET_LINUX
+#if defined(TARGET_LINUX) || defined (TARGET_ANDROID)
#ifdef HAVE_LINUX_IF_TUN_H
#include <linux/if_tun.h>
@@ -358,9 +358,14 @@
#endif /* TARGET_DARWIN */
-#ifdef WIN32
-#include <iphlpapi.h>
+#ifdef _WIN32
+ // Missing declarations for MinGW 32.
+ // #if !defined(__MINGW64_VERSION_MAJOR) || __MINGW64_VERSION_MAJOR < 2
+ typedef int MIB_TCP_STATE;
+ // #endif
+#include <naptypes.h>
#include <ntddndis.h>
+#include <iphlpapi.h>
#include <wininet.h>
#include <shellapi.h>
/* The following two headers are needed of PF_INET6 */
@@ -379,16 +384,13 @@
* Pedantic mode is meant to accomplish lint-style program checking,
* not to build a working executable.
*/
-#ifdef __STRICT_ANSI__
-# define PEDANTIC 1
+#ifdef PEDANTIC
# undef HAVE_CPP_VARARG_MACRO_GCC
# undef HAVE_CPP_VARARG_MACRO_ISO
# undef EMPTY_ARRAY_SIZE
# define EMPTY_ARRAY_SIZE 1
# undef inline
# define inline
-#else
-# define PEDANTIC 0
#endif
/*
@@ -403,18 +405,11 @@
/*
* Do we have nanoseconds gettimeofday?
*/
-#if defined(HAVE_GETTIMEOFDAY) || defined(WIN32)
+#if defined(HAVE_GETTIMEOFDAY) || defined(_WIN32)
#define HAVE_GETTIMEOFDAY_NANOSECONDS 1
#endif
/*
- * do we have the MIN() macro?
- */
-#ifndef MIN
-#define MIN(a,b) (((a)<(b))?(a):(b))
-#endif
-
-/*
* Do we have the capability to report extended socket errors?
*/
#if defined(HAVE_LINUX_TYPES_H) && defined(HAVE_LINUX_ERRQUEUE_H) && defined(HAVE_SOCK_EXTENDED_ERR) && defined(HAVE_MSGHDR) && defined(HAVE_CMSGHDR) && defined(CMSG_FIRSTHDR) && defined(CMSG_NXTHDR) && defined(IP_RECVERR) && defined(MSG_ERRQUEUE) && defined(SOL_IP) && defined(HAVE_IOVEC)
@@ -442,6 +437,13 @@
#endif
/*
+ * Define type sa_family_t if it isn't defined in the socket headers
+ */
+#ifndef HAVE_SA_FAMILY_T
+typedef unsigned short sa_family_t;
+#endif
+
+/*
* Disable ESEC
*/
#if 0
@@ -468,26 +470,16 @@
/*
* Directory separation char
*/
-#ifdef WIN32
+#ifdef _WIN32
#define OS_SPECIFIC_DIRSEP '\\'
#else
#define OS_SPECIFIC_DIRSEP '/'
#endif
/*
- * Define a boolean value based
- * on Win32 status.
- */
-#ifdef WIN32
-#define WIN32_0_1 1
-#else
-#define WIN32_0_1 0
-#endif
-
-/*
* Our socket descriptor type.
*/
-#ifdef WIN32
+#ifdef _WIN32
#define SOCKET_UNDEFINED (INVALID_SOCKET)
typedef SOCKET socket_descriptor_t;
#else
@@ -518,7 +510,7 @@ socket_defined (const socket_descriptor_t sd)
* Do we have point-to-multipoint capability?
*/
-#if defined(ENABLE_CLIENT_SERVER) && defined(ENABLE_CRYPTO) && defined(ENABLE_SSL) && defined(HAVE_GETTIMEOFDAY_NANOSECONDS)
+#if defined(ENABLE_CLIENT_SERVER) && defined(ENABLE_CRYPTO) && defined(HAVE_GETTIMEOFDAY_NANOSECONDS)
#define P2MP 1
#else
#define P2MP 0
@@ -555,14 +547,14 @@ socket_defined (const socket_descriptor_t sd)
/*
* Enable external private key
*/
-#if defined(ENABLE_MANAGEMENT) && defined(ENABLE_SSL)
+#if defined(ENABLE_MANAGEMENT) && defined(ENABLE_CRYPTO)
#define MANAGMENT_EXTERNAL_KEY
#endif
-/* Enable PolarSSL RNG prediction resistance support */
-#ifdef ENABLE_CRYPTO_POLARSSL
+/* Enable mbed TLS RNG prediction resistance support */
+#ifdef ENABLE_CRYPTO_MBEDTLS
#define ENABLE_PREDICTION_RESISTANCE
-#endif /* ENABLE_CRYPTO_POLARSSL */
+#endif /* ENABLE_CRYPTO_MBEDTLS */
/*
* MANAGEMENT_IN_EXTRA allows the management interface to
@@ -588,18 +580,13 @@ socket_defined (const socket_descriptor_t sd)
/*
* Do we support Unix domain sockets?
*/
-#if defined(PF_UNIX) && !defined(WIN32)
+#if defined(PF_UNIX) && !defined(_WIN32)
#define UNIX_SOCK_SUPPORT 1
#else
#define UNIX_SOCK_SUPPORT 0
#endif
/*
- * Compile the struct buffer_list code
- */
-#define ENABLE_BUFFER_LIST
-
-/*
* Should we include OCC (options consistency check) code?
*/
#ifndef ENABLE_SMALL
@@ -609,7 +596,7 @@ socket_defined (const socket_descriptor_t sd)
/*
* Should we include NTLM proxy functionality
*/
-#if defined(ENABLE_CRYPTO) && defined(ENABLE_HTTP_PROXY)
+#if defined(ENABLE_CRYPTO)
#define NTLM 1
#else
#define NTLM 0
@@ -618,34 +605,20 @@ socket_defined (const socket_descriptor_t sd)
/*
* Should we include proxy digest auth functionality
*/
-#if defined(ENABLE_CRYPTO) && defined(ENABLE_HTTP_PROXY)
+#if defined(ENABLE_CRYPTO)
#define PROXY_DIGEST_AUTH 1
#else
#define PROXY_DIGEST_AUTH 0
#endif
/*
- * Should we include code common to all proxy methods?
- */
-#if defined(ENABLE_HTTP_PROXY) || defined(ENABLE_SOCKS)
-#define GENERAL_PROXY_SUPPORT
-#endif
-
-/*
* Do we have CryptoAPI capability?
*/
-#if defined(WIN32) && defined(ENABLE_CRYPTO) && defined(ENABLE_SSL) && defined(ENABLE_CRYPTO_OPENSSL)
+#if defined(_WIN32) && defined(ENABLE_CRYPTO) && defined(ENABLE_CRYPTO_OPENSSL)
#define ENABLE_CRYPTOAPI
#endif
/*
- * Enable x509-track feature?
- */
-#if defined(ENABLE_CRYPTO) && defined(ENABLE_SSL) && defined (ENABLE_CRYPTO_OPENSSL)
-#define ENABLE_X509_TRACK
-#endif
-
-/*
* Is poll available on this platform?
*/
#if defined(HAVE_POLL) && defined(HAVE_SYS_POLL_H)
@@ -670,15 +643,6 @@ socket_defined (const socket_descriptor_t sd)
#endif
/*
- * Should we include http proxy override functionality
- */
-#if defined(ENABLE_MANAGEMENT) && defined(ENABLE_HTTP_PROXY)
-#define HTTP_PROXY_OVERRIDE 1
-#else
-#define HTTP_PROXY_OVERRIDE 0
-#endif
-
-/*
* Reduce sensitivity to system clock instability
* and backtracks.
*/
@@ -719,14 +683,17 @@ socket_defined (const socket_descriptor_t sd)
/*
* Do we support pushing peer info?
*/
-#if defined(ENABLE_CRYPTO) && defined(ENABLE_SSL)
+#if defined(ENABLE_CRYPTO)
#define ENABLE_PUSH_PEER_INFO
#endif
/*
- * Do we support internal client-side NAT?
+ * Compression support
*/
-#define ENABLE_CLIENT_NAT
+#if defined(ENABLE_LZO) || defined(ENABLE_LZ4) || \
+ defined(ENABLE_COMP_STUB)
+#define USE_COMP
+#endif
/*
* Enable --memstats option
diff --git a/src/openvpn/tls_crypt.c b/src/openvpn/tls_crypt.c
new file mode 100644
index 0000000..d40532e
--- /dev/null
+++ b/src/openvpn/tls_crypt.c
@@ -0,0 +1,254 @@
+/*
+ * OpenVPN -- An application to securely tunnel IP networks
+ * over a single TCP/UDP port, with support for SSL/TLS-based
+ * session authentication and key exchange,
+ * packet encryption, packet authentication, and
+ * packet compression.
+ *
+ * Copyright (C) 2016 Fox Crypto B.V. <openvpn@fox-it.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program (see the file COPYING included with this
+ * distribution); if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#elif defined(_MSC_VER)
+#include "config-msvc.h"
+#endif
+
+#include "syshead.h"
+
+#ifdef ENABLE_CRYPTO
+#include "crypto.h"
+#include "session_id.h"
+
+#include "tls_crypt.h"
+
+int tls_crypt_buf_overhead(void)
+{
+ return packet_id_size (true) + TLS_CRYPT_TAG_SIZE + TLS_CRYPT_BLOCK_SIZE;
+}
+
+void
+tls_crypt_init_key (struct key_ctx_bi *key, const char *key_file,
+ const char *key_inline, bool tls_server) {
+ const int key_direction = tls_server ?
+ KEY_DIRECTION_NORMAL : KEY_DIRECTION_INVERSE;
+
+ struct key_type kt;
+ kt.cipher = cipher_kt_get ("AES-256-CTR");
+ kt.cipher_length = cipher_kt_key_size (kt.cipher);
+ kt.digest = md_kt_get ("SHA256");
+ kt.hmac_length = md_kt_size (kt.digest);
+
+ if (!kt.cipher)
+ {
+ msg (M_FATAL, "ERROR: --tls-crypt requires AES-256-CTR support.");
+ }
+ if (!kt.digest)
+ {
+ msg (M_FATAL, "ERROR: --tls-crypt requires HMAC-SHA-256 support.");
+ }
+
+ crypto_read_openvpn_key (&kt, key, key_file, key_inline, key_direction,
+ "Control Channel Encryption", "tls-crypt");
+}
+
+void
+tls_crypt_adjust_frame_parameters(struct frame *frame)
+{
+ frame_add_to_extra_frame (frame, tls_crypt_buf_overhead());
+
+ msg(D_MTU_DEBUG, "%s: Adjusting frame parameters for tls-crypt by %i bytes",
+ __func__, tls_crypt_buf_overhead());
+}
+
+
+bool
+tls_crypt_wrap (const struct buffer *src, struct buffer *dst,
+ struct crypto_options *opt) {
+ const struct key_ctx *ctx = &opt->key_ctx_bi.encrypt;
+ struct gc_arena gc;
+
+ /* IV, packet-ID and implicit IV required for this mode. */
+ ASSERT (ctx->cipher);
+ ASSERT (ctx->hmac);
+ ASSERT (packet_id_initialized(&opt->packet_id));
+ ASSERT (hmac_ctx_size(ctx->hmac) == 256/8);
+
+ gc_init (&gc);
+
+ dmsg (D_PACKET_CONTENT, "TLS-CRYPT WRAP FROM: %s",
+ format_hex (BPTR (src), BLEN (src), 80, &gc));
+
+ /* Get packet ID */
+ {
+ struct packet_id_net pin;
+ packet_id_alloc_outgoing (&opt->packet_id.send, &pin, true);
+ packet_id_write (&pin, dst, true, false);
+ }
+
+ dmsg (D_PACKET_CONTENT, "TLS-CRYPT WRAP AD: %s",
+ format_hex (BPTR (dst), BLEN (dst), 0, &gc));
+
+ /* Buffer overflow check */
+ if (!buf_safe (dst, BLEN (src) + TLS_CRYPT_BLOCK_SIZE + TLS_CRYPT_TAG_SIZE))
+ {
+ msg (D_CRYPT_ERRORS, "TLS-CRYPT WRAP: buffer size error, "
+ "sc=%d so=%d sl=%d dc=%d do=%d dl=%d", src->capacity, src->offset,
+ src->len, dst->capacity, dst->offset, dst->len);
+ goto err;
+ }
+
+ /* Calculate auth tag and synthetic IV */
+ {
+ uint8_t *tag = NULL;
+ hmac_ctx_reset (ctx->hmac);
+ hmac_ctx_update (ctx->hmac, BPTR (dst), BLEN (dst));
+ hmac_ctx_update (ctx->hmac, BPTR (src), BLEN (src));
+
+ ASSERT (tag = buf_write_alloc (dst, TLS_CRYPT_TAG_SIZE));
+ hmac_ctx_final (ctx->hmac, tag);
+
+ dmsg (D_PACKET_CONTENT, "TLS-CRYPT WRAP TAG: %s",
+ format_hex (tag, TLS_CRYPT_TAG_SIZE, 0, &gc));
+
+ /* Use the 128 most significant bits of the tag as IV */
+ ASSERT (cipher_ctx_reset (ctx->cipher, tag));
+ }
+
+ /* Encrypt src */
+ {
+ int outlen = 0;
+ ASSERT (cipher_ctx_update (ctx->cipher, BEND (dst), &outlen,
+ BPTR (src), BLEN(src)));
+ ASSERT (buf_inc_len (dst, outlen));
+ ASSERT (cipher_ctx_final (ctx->cipher, BPTR (dst), &outlen));
+ ASSERT (buf_inc_len (dst, outlen));
+ }
+
+ dmsg (D_PACKET_CONTENT, "TLS-CRYPT WRAP TO: %s",
+ format_hex (BPTR (dst), BLEN (dst), 80, &gc));
+
+ gc_free (&gc);
+ return true;
+
+err:
+ crypto_clear_error();
+ dst->len = 0;
+ gc_free (&gc);
+ return false;
+}
+
+bool
+tls_crypt_unwrap (const struct buffer *src, struct buffer *dst,
+ struct crypto_options *opt)
+{
+ static const char error_prefix[] = "tls-crypt unwrap error";
+ const struct key_ctx *ctx = &opt->key_ctx_bi.decrypt;
+ struct gc_arena gc;
+
+ gc_init (&gc);
+
+ ASSERT (opt);
+ ASSERT (src->len > 0);
+ ASSERT (ctx->cipher);
+ ASSERT (packet_id_initialized (&opt->packet_id) ||
+ (opt->flags & CO_IGNORE_PACKET_ID));
+
+ dmsg (D_PACKET_CONTENT, "TLS-CRYPT UNWRAP FROM: %s",
+ format_hex (BPTR (src), BLEN (src), 80, &gc));
+
+ if (buf_len (src) < TLS_CRYPT_OFF_CT)
+ {
+ CRYPT_ERROR ("packet too short");
+ }
+
+ /* Decrypt cipher text */
+ {
+ int outlen = 0;
+
+ /* Buffer overflow check (should never fail) */
+ if (!buf_safe (dst, BLEN (src) - TLS_CRYPT_OFF_CT + TLS_CRYPT_BLOCK_SIZE))
+ {
+ CRYPT_ERROR ("potential buffer overflow");
+ }
+
+ if (!cipher_ctx_reset (ctx->cipher, BPTR (src) + TLS_CRYPT_OFF_TAG))
+ {
+ CRYPT_ERROR ("cipher reset failed");
+ }
+ if (!cipher_ctx_update (ctx->cipher, BPTR (dst), &outlen,
+ BPTR (src) + TLS_CRYPT_OFF_CT, BLEN (src) - TLS_CRYPT_OFF_CT))
+ {
+ CRYPT_ERROR ("cipher update failed");
+ }
+ ASSERT (buf_inc_len (dst, outlen));
+ if (!cipher_ctx_final (ctx->cipher, BPTR(dst), &outlen))
+ {
+ CRYPT_ERROR ("cipher final failed");
+ }
+ ASSERT (buf_inc_len (dst, outlen));
+ }
+
+ /* Check authentication */
+ {
+ const uint8_t *tag = BPTR (src) + TLS_CRYPT_OFF_TAG;
+ uint8_t tag_check[TLS_CRYPT_TAG_SIZE] = { 0 };
+
+ dmsg (D_PACKET_CONTENT, "TLS-CRYPT UNWRAP AD: %s",
+ format_hex (BPTR (src), TLS_CRYPT_OFF_TAG, 0, &gc));
+ dmsg (D_PACKET_CONTENT, "TLS-CRYPT UNWRAP TO: %s",
+ format_hex (BPTR (dst), BLEN (dst), 80, &gc));
+
+ hmac_ctx_reset (ctx->hmac);
+ hmac_ctx_update (ctx->hmac, BPTR (src), TLS_CRYPT_OFF_TAG);
+ hmac_ctx_update (ctx->hmac, BPTR (dst), BLEN (dst));
+ hmac_ctx_final (ctx->hmac, tag_check);
+
+ if (memcmp_constant_time (tag, tag_check, sizeof(tag_check)))
+ {
+ dmsg (D_CRYPTO_DEBUG, "tag : %s",
+ format_hex (tag, sizeof(tag_check), 0, &gc));
+ dmsg (D_CRYPTO_DEBUG, "tag_check: %s",
+ format_hex (tag_check, sizeof(tag_check), 0, &gc));
+ CRYPT_ERROR ("packet authentication failed");
+ }
+ }
+
+ /* Check replay */
+ if (!(opt->flags & CO_IGNORE_PACKET_ID))
+ {
+ struct packet_id_net pin;
+ struct buffer tmp = *src;
+ ASSERT (buf_advance (&tmp, TLS_CRYPT_OFF_PID));
+ ASSERT (packet_id_read (&pin, &tmp, true));
+ if (!crypto_check_replay (opt, &pin, error_prefix, &gc))
+ {
+ CRYPT_ERROR ("packet replay");
+ }
+ }
+
+ gc_free (&gc);
+ return true;
+
+ error_exit:
+ crypto_clear_error();
+ dst->len = 0;
+ gc_free (&gc);
+ return false;
+}
+
+#endif /* EMABLE_CRYPTO */
diff --git a/src/openvpn/tls_crypt.h b/src/openvpn/tls_crypt.h
new file mode 100644
index 0000000..d1962c9
--- /dev/null
+++ b/src/openvpn/tls_crypt.h
@@ -0,0 +1,144 @@
+/*
+ * OpenVPN -- An application to securely tunnel IP networks
+ * over a single TCP/UDP port, with support for SSL/TLS-based
+ * session authentication and key exchange,
+ * packet encryption, packet authentication, and
+ * packet compression.
+ *
+ * Copyright (C) 2016 Fox Crypto B.V. <openvpn@fox-it.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program (see the file COPYING included with this
+ * distribution); if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/**
+ * @defgroup tls_crypt Control channel encryption (--tls-crypt)
+ * @ingroup control_tls
+ * @{
+ *
+ * @par
+ * Control channel encryption uses a pre-shared static key (like the --tls-auth
+ * key) to encrypt control channel packets.
+ *
+ * @par
+ * Encrypting control channel packets has three main advantages:
+ * - It provides more privacy by hiding the certificate used for the TLS
+ * connection.
+ * - It is harder to identify OpenVPN traffic as such.
+ * - It provides "poor-man's" post-quantum security, against attackers who
+ * will never know the pre-shared key (i.e. no forward secrecy).
+ *
+ * @par Specification
+ * Control channel encryption is based on the SIV construction [0], to achieve
+ * nonce misuse-resistant authenticated encryption:
+ *
+ * @par
+ * \code{.unparsed}
+ * msg = control channel plaintext
+ * header = opcode (1 byte) || session_id (8 bytes) || packet_id (8 bytes)
+ * Ka = authentication key (256 bits)
+ * Ke = encryption key (256 bits)
+ * (Ka and Ke are pre-shared keys, like with --tls-auth)
+ *
+ * auth_tag = HMAC-SHA256(Ka, header || msg)
+ * IV = 128 most-significant bits of auth_tag
+ * ciph = AES256-CTR(Ke, IV, msg)
+ *
+ * output = Header || Tag || Ciph
+ * \endcode
+ *
+ * @par
+ * This boils down to the following on-the-wire packet format:
+ *
+ * @par
+ * \code{.unparsed}
+ * - opcode - || - session_id - || - packet_id - || auth_tag || * payload *
+ * \endcode
+ *
+ * @par
+ * Where
+ * <tt>- XXX -</tt> means authenticated, and
+ * <tt>* XXX *</tt> means authenticated and encrypted.
+ */
+
+#ifndef TLSCRYPT_H
+#define TLSCRYPT_H
+
+#include "buffer.h"
+#include "crypto.h"
+#include "session_id.h"
+
+#define TLS_CRYPT_TAG_SIZE (256/8)
+#define TLS_CRYPT_PID_SIZE (sizeof (packet_id_type) + sizeof (net_time_t))
+#define TLS_CRYPT_BLOCK_SIZE (128/8)
+
+#define TLS_CRYPT_OFF_PID (1 + SID_SIZE)
+#define TLS_CRYPT_OFF_TAG (TLS_CRYPT_OFF_PID + TLS_CRYPT_PID_SIZE)
+#define TLS_CRYPT_OFF_CT (TLS_CRYPT_OFF_TAG + TLS_CRYPT_TAG_SIZE)
+
+/**
+ * Initialize a key_ctx_bi structure for use with --tls-crypt.
+ *
+ * @param key The key context to initialize
+ * @param key_file The file to read the key from (or the inline tag to
+ * indicate and inline key).
+ * @param key_inline Array containing (zero-terminated) inline key, or NULL
+ * if not used.
+ * @param tls_server Must be set to true is this is a TLS server instance.
+ */
+void tls_crypt_init_key (struct key_ctx_bi *key, const char *key_file,
+ const char *key_inline, bool tls_server);
+
+/**
+ * Returns the maximum overhead (in bytes) added to the destination buffer by
+ * tls_crypt_wrap().
+ */
+int tls_crypt_buf_overhead(void);
+
+/**
+ * Adjust frame parameters for --tls-crypt overhead.
+ */
+void tls_crypt_adjust_frame_parameters(struct frame *frame);
+
+/**
+ * Wrap a control channel packet (both authenticates and encrypts the data).
+ *
+ * @param src Data to authenticate and encrypt.
+ * @param dst Any data present in this buffer is first authenticated, then
+ * the wrapped packet id and data from the src buffer are appended.
+ * Must have at least tls_crypt_buf_overhead()+BLEN(src) headroom.
+ * @param opt The crypto state for this --tls-crypt instance.
+ *
+ * @returns true iff wrapping succeeded.
+ */
+bool tls_crypt_wrap (const struct buffer *src, struct buffer *dst,
+ struct crypto_options *opt);
+
+/**
+ * Unwrap a control channel packet (decrypts, authenticates and performs
+ * replay checks).
+ *
+ * @param src Data to decrypt and authenticate.
+ * @param dst Returns the decrypted data, if unwrapping was successful.
+ * @param opt The crypto state for this --tls-crypt instance.
+ *
+ * @returns true iff unwrapping succeeded (data authenticated correctly and was
+ * no replay).
+ */
+bool tls_crypt_unwrap (const struct buffer *src, struct buffer *dst,
+ struct crypto_options *opt);
+
+/** @} */
+
+#endif /* TLSCRYPT_H */
diff --git a/src/openvpn/tun.c b/src/openvpn/tun.c
index b70410d..77ae72f 100644
--- a/src/openvpn/tun.c
+++ b/src/openvpn/tun.c
@@ -49,7 +49,13 @@
#include "memdbg.h"
-#ifdef WIN32
+#ifdef _WIN32
+#include "openvpn-msg.h"
+#endif
+
+#include <string.h>
+
+#ifdef _WIN32
/* #define SIMULATE_DHCP_FAILED */ /* simulate bad DHCP negotiation */
@@ -62,12 +68,70 @@ static void netsh_ifconfig (const struct tuntap_options *to,
const in_addr_t ip,
const in_addr_t netmask,
const unsigned int flags);
-static void netsh_command (const struct argv *a, int n);
+static void netsh_command (const struct argv *a, int n, int msglevel);
static const char *netsh_get_id (const char *dev_node, struct gc_arena *gc);
static DWORD get_adapter_index_flexible (const char *name);
+static bool
+do_address_service (const bool add, const short family, 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;
+
+ address_message_t addr = {
+ .header = {
+ (add ? msg_add_address : msg_del_address),
+ sizeof (address_message_t),
+ 0 },
+ .family = family,
+ .iface = { .index = tt->adapter_index, .name = "" }
+ };
+
+ if (addr.iface.index == TUN_ADAPTER_INDEX_INVALID)
+ {
+ strncpy (addr.iface.name, tt->actual_name, sizeof (addr.iface.name));
+ addr.iface.name[sizeof (addr.iface.name) - 1] = '\0';
+ }
+
+ if (addr.family == AF_INET)
+ {
+ addr.address.ipv4.s_addr = tt->local;
+ addr.prefix_len = 32;
+ }
+ else
+ {
+ addr.address.ipv6 = tt->local_ipv6;
+ addr.prefix_len = tt->netbits_ipv6;
+ }
+
+ if (!WriteFile (pipe, &addr, sizeof (addr), &len, NULL) ||
+ !ReadFile (pipe, &ack, sizeof (ack), &len, NULL))
+ {
+ msg (M_WARN, "TUN: could not talk to service: %s [%lu]",
+ strerror_win32 (GetLastError (), &gc), GetLastError ());
+ goto out;
+ }
+
+ if (ack.error_number != NO_ERROR)
+ {
+ msg (M_WARN, "TUN: %s address failed using service: %s [status=%u if_index=%lu]",
+ (add ? "adding" : "deleting"), strerror_win32 (ack.error_number, &gc),
+ ack.error_number, addr.iface.index);
+ goto out;
+ }
+
+ ret = true;
+
+out:
+ gc_free (&gc);
+ return ret;
+}
+
#endif
#ifdef TARGET_SOLARIS
@@ -134,7 +198,7 @@ guess_tuntap_dev (const char *dev,
const char *dev_node,
struct gc_arena *gc)
{
-#ifdef WIN32
+#ifdef _WIN32
const int dt = dev_type_enum (dev, dev_type);
if (dt == DEV_TYPE_TUN || dt == DEV_TYPE_TAP)
{
@@ -357,7 +421,7 @@ tun_stat (const struct tuntap *tt, unsigned int rwflags, struct gc_arena *gc)
{
buf_printf (&out, "T%s",
(tt->rwflags_debug & EVENT_READ) ? "R" : "r");
-#ifdef WIN32
+#ifdef _WIN32
buf_printf (&out, "%s",
overlapped_io_state_ascii (&tt->reads));
#endif
@@ -366,7 +430,7 @@ tun_stat (const struct tuntap *tt, unsigned int rwflags, struct gc_arena *gc)
{
buf_printf (&out, "T%s",
(tt->rwflags_debug & EVENT_WRITE) ? "W" : "w");
-#ifdef WIN32
+#ifdef _WIN32
buf_printf (&out, "%s",
overlapped_io_state_ascii (&tt->writes));
#endif
@@ -455,8 +519,8 @@ init_tun (const char *dev, /* --dev option */
const char *ifconfig_ipv6_local_parm, /* --ifconfig parm 1 IPv6 */
int ifconfig_ipv6_netbits_parm,
const char *ifconfig_ipv6_remote_parm, /* --ifconfig parm 2 IPv6 */
- in_addr_t local_public,
- in_addr_t remote_public,
+ struct addrinfo *local_public,
+ struct addrinfo *remote_public,
const bool strict_warn,
struct env_set *es)
{
@@ -507,6 +571,7 @@ init_tun (const char *dev, /* --dev option */
*/
if (strict_warn)
{
+ struct addrinfo *curele;
ifconfig_sanity_check (tt->type == DEV_TYPE_TUN, tt->remote_netmask, tt->topology);
/*
@@ -514,17 +579,23 @@ init_tun (const char *dev, /* --dev option */
* make sure they do not clash with our virtual subnet.
*/
- check_addr_clash ("local",
+ for(curele=local_public;curele;curele=curele->ai_next) {
+ if(curele->ai_family == AF_INET)
+ check_addr_clash ("local",
tt->type,
- local_public,
+ ((struct sockaddr_in*)curele->ai_addr)->sin_addr.s_addr,
tt->local,
tt->remote_netmask);
+ }
- check_addr_clash ("remote",
- tt->type,
- remote_public,
- tt->local,
- tt->remote_netmask);
+ for (curele=remote_public;curele;curele=curele->ai_next) {
+ if (curele->ai_family == AF_INET)
+ check_addr_clash ("remote",
+ tt->type,
+ ((struct sockaddr_in*)curele->ai_addr)->sin_addr.s_addr,
+ tt->local,
+ tt->remote_netmask);
+ }
if (tt->type == DEV_TYPE_TAP || (tt->type == DEV_TYPE_TUN && tt->topology == TOP_SUBNET))
check_subnet_conflict (tt->local, tt->remote_netmask, "TUN/TAP adapter");
@@ -540,6 +611,21 @@ init_tun (const char *dev, /* --dev option */
tt->broadcast = generate_ifconfig_broadcast_addr (tt->local, tt->remote_netmask);
}
+#ifdef _WIN32
+ /*
+ * Make sure that both ifconfig addresses are part of the
+ * same .252 subnet.
+ */
+ if (tun)
+ {
+ verify_255_255_255_252 (tt->local, tt->remote_netmask);
+ tt->adapter_netmask = ~3;
+ }
+ else
+ {
+ tt->adapter_netmask = tt->remote_netmask;
+ }
+#endif
tt->did_ifconfig_setup = true;
}
@@ -579,7 +665,7 @@ init_tun_post (struct tuntap *tt,
const struct tuntap_options *options)
{
tt->options = *options;
-#ifdef WIN32
+#ifdef _WIN32
overlapped_io_init (&tt->reads, frame, FALSE, true);
overlapped_io_init (&tt->writes, frame, TRUE, true);
tt->rw_handle.read = tt->reads.overlapped.hEvent;
@@ -588,7 +674,7 @@ init_tun_post (struct tuntap *tt,
#endif
}
-#if defined(WIN32) || \
+#if defined(_WIN32) || \
defined(TARGET_DARWIN) || defined(TARGET_NETBSD) || defined(TARGET_OPENBSD)
/* some of the platforms will auto-add a "network route" pointing
@@ -601,12 +687,12 @@ void add_route_connected_v6_net(struct tuntap * tt,
{
struct route_ipv6 r6;
- r6.defined = true;
+ CLEAR(r6);
r6.network = tt->local_ipv6;
r6.netbits = tt->netbits_ipv6;
r6.gateway = tt->local_ipv6;
r6.metric = 0; /* connected route */
- r6.metric_defined = true;
+ r6.flags = RT_DEFINED | RT_METRIC_DEFINED;
add_route_ipv6 (&r6, tt, 0, es);
}
@@ -615,17 +701,18 @@ void delete_route_connected_v6_net(struct tuntap * tt,
{
struct route_ipv6 r6;
- r6.defined = true;
+ CLEAR(r6);
r6.network = tt->local_ipv6;
r6.netbits = tt->netbits_ipv6;
r6.gateway = tt->local_ipv6;
r6.metric = 0; /* connected route */
- r6.metric_defined = true;
+ r6.flags = RT_DEFINED | RT_ADDED | RT_METRIC_DEFINED;
delete_route_ipv6 (&r6, tt, 0, es);
}
#endif
-#if defined(TARGET_FREEBSD)||defined(TARGET_DRAGONFLY)
+#if defined(TARGET_FREEBSD)||defined(TARGET_DRAGONFLY)||\
+ 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"
@@ -635,8 +722,8 @@ void delete_route_connected_v6_net(struct tuntap * tt,
* is still point to point and no layer 2 resolution is done...
*/
-const char *
-create_arbitrary_remote( struct tuntap *tt, struct gc_arena * gc )
+in_addr_t
+create_arbitrary_remote( struct tuntap *tt )
{
in_addr_t remote;
@@ -644,7 +731,7 @@ create_arbitrary_remote( struct tuntap *tt, struct gc_arena * gc )
if ( remote == tt->local ) remote ++;
- return print_in_addr_t (remote, 0, gc);
+ return remote;
}
#endif
@@ -664,14 +751,11 @@ do_ifconfig (struct tuntap *tt,
const char *ifconfig_remote_netmask = NULL;
const char *ifconfig_broadcast = NULL;
const char *ifconfig_ipv6_local = NULL;
- const char *ifconfig_ipv6_remote = NULL;
bool do_ipv6 = false;
- struct argv argv;
-
- argv_init (&argv);
+ struct argv argv = argv_new ();
- msg( M_INFO, "do_ifconfig, tt->ipv6=%d, tt->did_ifconfig_ipv6_setup=%d",
- tt->ipv6, tt->did_ifconfig_ipv6_setup );
+ msg( M_DEBUG, "do_ifconfig, tt->did_ifconfig_ipv6_setup=%d",
+ tt->did_ifconfig_ipv6_setup );
/*
* We only handle TUN/TAP devices here, not --dev null devices.
@@ -684,10 +768,9 @@ do_ifconfig (struct tuntap *tt,
ifconfig_local = print_in_addr_t (tt->local, 0, &gc);
ifconfig_remote_netmask = print_in_addr_t (tt->remote_netmask, 0, &gc);
- if ( tt->ipv6 && tt->did_ifconfig_ipv6_setup )
+ if (tt->did_ifconfig_ipv6_setup )
{
ifconfig_ipv6_local = print_in6_addr (tt->local_ipv6, 0, &gc);
- ifconfig_ipv6_remote = print_in6_addr (tt->remote_ipv6, 0, &gc);
do_ipv6 = true;
}
@@ -703,8 +786,10 @@ do_ifconfig (struct tuntap *tt,
management_set_state (management,
OPENVPN_STATE_ASSIGN_IP,
NULL,
- tt->local,
- 0);
+ &tt->local,
+ &tt->local_ipv6,
+ NULL,
+ NULL);
}
#endif
@@ -743,7 +828,7 @@ do_ifconfig (struct tuntap *tt,
iproute_path,
actual,
ifconfig_local,
- count_netmask_bits(ifconfig_remote_netmask),
+ netmask_to_netbits2(tt->remote_netmask),
ifconfig_broadcast
);
argv_msg (M_INFO, &argv);
@@ -799,8 +884,35 @@ do_ifconfig (struct tuntap *tt,
tt->did_ifconfig = true;
#endif /*ENABLE_IPROUTE*/
-#elif defined(TARGET_SOLARIS)
+#elif defined(TARGET_ANDROID)
+
+ if (do_ipv6) {
+ struct buffer out6 = alloc_buf_gc (64, &gc);
+ buf_printf (&out6, "%s/%d", ifconfig_ipv6_local,tt->netbits_ipv6);
+ management_android_control(management, "IFCONFIG6",buf_bptr(&out6));
+ }
+
+ struct buffer out = alloc_buf_gc (64, &gc);
+
+ char* top;
+ switch(tt->topology) {
+ case TOP_NET30:
+ top="net30";
+ break;
+ case TOP_P2P:
+ top="p2p";
+ break;
+ case TOP_SUBNET:
+ top="subnet";
+ break;
+ default:
+ top="undef";
+ }
+
+ buf_printf (&out, "%s %s %d %s", ifconfig_local, ifconfig_remote_netmask, tun_mtu, top);
+ management_android_control (management, "IFCONFIG", buf_bptr(&out));
+#elif defined(TARGET_SOLARIS)
/* Solaris 2.6 (and 7?) cannot set all parameters in one go...
* example:
* ifconfig tun2 10.2.0.2 10.2.0.1 mtu 1450 up
@@ -862,6 +974,9 @@ do_ifconfig (struct tuntap *tt,
if ( tt->type == DEV_TYPE_TUN )
{
+ const char *ifconfig_ipv6_remote =
+ print_in6_addr (tt->remote_ipv6, 0, &gc);
+
argv_printf (&argv,
"%s %s inet6 plumb %s/%d %s up",
IFCONFIG_PATH,
@@ -916,6 +1031,8 @@ do_ifconfig (struct tuntap *tt,
#elif defined(TARGET_OPENBSD)
+ in_addr_t remote_end; /* for "virtual" subnet topology */
+
/*
* On OpenBSD, tun interfaces are persistent if created with
* "ifconfig tunX create", and auto-destroyed if created by
@@ -935,12 +1052,13 @@ do_ifconfig (struct tuntap *tt,
else
if ( tt->topology == TOP_SUBNET )
{
+ remote_end = create_arbitrary_remote( tt );
argv_printf (&argv,
"%s %s %s %s mtu %d netmask %s up -link0",
IFCONFIG_PATH,
actual,
ifconfig_local,
- ifconfig_local,
+ print_in_addr_t (remote_end, 0, &gc),
tun_mtu,
ifconfig_remote_netmask
);
@@ -957,6 +1075,19 @@ do_ifconfig (struct tuntap *tt,
);
argv_msg (M_INFO, &argv);
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)
+ {
+ 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,
@@ -976,13 +1107,6 @@ do_ifconfig (struct tuntap *tt,
#elif defined(TARGET_NETBSD)
-/* whether or not NetBSD can do IPv6 can be seen by the availability of
- * the TUNSIFHEAD ioctl() - see next TARGET_NETBSD block for more details
- */
-#ifdef TUNSIFHEAD
-# define NETBSD_MULTI_AF
-#endif
-
if (tun)
argv_printf (&argv,
"%s %s %s %s mtu %d netmask 255.255.255.255 up",
@@ -1025,7 +1149,6 @@ do_ifconfig (struct tuntap *tt,
if ( do_ipv6 )
{
-#ifdef NETBSD_MULTI_AF
argv_printf (&argv,
"%s %s inet6 %s/%d",
IFCONFIG_PATH,
@@ -1038,10 +1161,6 @@ do_ifconfig (struct tuntap *tt,
/* and, hooray, we explicitely need to add a route... */
add_route_connected_v6_net(tt, es);
-#else
- msg( M_INFO, "no IPv6 support for tun interfaces on NetBSD before 4.0 (if your system is newer, recompile openvpn)" );
- tt->ipv6 = false;
-#endif
}
tt->did_ifconfig = true;
@@ -1126,6 +1245,8 @@ do_ifconfig (struct tuntap *tt,
#elif defined(TARGET_FREEBSD)||defined(TARGET_DRAGONFLY)
+ in_addr_t remote_end; /* for "virtual" subnet topology */
+
/* example: ifconfig tun2 10.2.0.2 10.2.0.1 mtu 1450 netmask 255.255.255.255 up */
if (tun)
argv_printf (&argv,
@@ -1138,12 +1259,13 @@ do_ifconfig (struct tuntap *tt,
);
else if ( 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,
- create_arbitrary_remote( tt, &gc ),
+ print_in_addr_t (remote_end, 0, &gc),
tun_mtu,
ifconfig_remote_netmask
);
@@ -1170,7 +1292,7 @@ do_ifconfig (struct tuntap *tt,
r.flags = RT_DEFINED;
r.network = tt->local & tt->remote_netmask;
r.netmask = tt->remote_netmask;
- r.gateway = tt->local;
+ r.gateway = remote_end;
add_route (&r, tt, 0, NULL, es);
}
@@ -1187,21 +1309,46 @@ do_ifconfig (struct tuntap *tt,
openvpn_execve_check (&argv, es, S_FATAL, "FreeBSD ifconfig inet6 failed");
}
-#elif defined (WIN32)
+#elif defined(TARGET_AIX)
{
- /*
- * Make sure that both ifconfig addresses are part of the
- * same .252 subnet.
- */
+ /* AIX ifconfig will complain if it can't find ODM path in env */
+ struct env_set *aix_es = env_set_create (NULL);
+ env_set_add( aix_es, "ODMDIR=/etc/objrepos" );
+
if (tun)
+ msg(M_FATAL, "no tun support on AIX (canthappen)");
+
+ /* example: ifconfig tap0 172.30.1.1 netmask 255.255.254.0 up */
+ argv_printf (&argv,
+ "%s %s %s netmask %s mtu %d up",
+ IFCONFIG_PATH,
+ actual,
+ ifconfig_local,
+ ifconfig_remote_netmask,
+ tun_mtu
+ );
+
+ argv_msg (M_INFO, &argv);
+ openvpn_execve_check (&argv, aix_es, S_FATAL, "AIX ifconfig failed");
+ tt->did_ifconfig = true;
+
+ if ( do_ipv6 )
{
- verify_255_255_255_252 (tt->local, tt->remote_netmask);
- tt->adapter_netmask = ~3;
- }
- else
- {
- tt->adapter_netmask = tt->remote_netmask;
+ argv_printf (&argv,
+ "%s %s inet6 %s/%d",
+ IFCONFIG_PATH,
+ actual,
+ ifconfig_ipv6_local,
+ tt->netbits_ipv6
+ );
+ argv_msg (M_INFO, &argv);
+ openvpn_execve_check (&argv, aix_es, S_FATAL, "AIX ifconfig inet6 failed");
}
+ env_set_destroy (aix_es);
+ }
+#elif defined (_WIN32)
+ {
+ ASSERT (actual != NULL);
switch (tt->options.ip_win32_type)
{
@@ -1212,9 +1359,6 @@ do_ifconfig (struct tuntap *tt,
print_in_addr_t (tt->adapter_netmask, 0, &gc));
break;
case IPW32_SET_NETSH:
- if (!strcmp (actual, "NULL"))
- msg (M_FATAL, "Error: When using --ip-win32 netsh, if you have more than one TAP-Windows adapter, you must also specify --dev-node");
-
netsh_ifconfig (&tt->options,
actual,
tt->local,
@@ -1226,39 +1370,28 @@ do_ifconfig (struct tuntap *tt,
tt->did_ifconfig = true;
}
- /* IPv6 always uses "netsh" interface */
if ( do_ipv6 )
{
- char * saved_actual;
- char iface[64];
- DWORD idx;
-
- if (!strcmp (actual, "NULL"))
- msg (M_FATAL, "Error: When using --tun-ipv6, if you have more than one TAP-Windows adapter, you must also specify --dev-node");
-
- idx = get_adapter_index_flexible(actual);
- openvpn_snprintf(iface, sizeof(iface), "interface=%lu", idx);
-
- /* example: netsh interface ipv6 set address interface=42 2001:608:8003::d store=active */
- argv_printf (&argv,
- "%s%sc interface ipv6 set address %s %s store=active",
- get_win_sys_path(),
- NETSH_PATH_SUFFIX,
- win32_version_info() == WIN_XP ? actual : iface,
- ifconfig_ipv6_local);
- netsh_command (&argv, 4);
+ if (tt->options.msg_channel)
+ {
+ do_address_service (true, AF_INET6, tt);
+ }
+ else
+ {
+ /* example: netsh interface ipv6 set address interface=42 2001:608:8003::d store=active */
+ char iface[64];
+ openvpn_snprintf(iface, sizeof(iface), "interface=%lu", tt->adapter_index );
+ argv_printf (&argv,
+ "%s%sc interface ipv6 set address %s %s store=active",
+ get_win_sys_path(),
+ NETSH_PATH_SUFFIX,
+ iface,
+ ifconfig_ipv6_local );
+ netsh_command (&argv, 4, M_FATAL);
+ }
/* explicit route needed */
- /* on windows, OpenVPN does ifconfig first, open_tun later, so
- * tt->actual_name might not yet be initialized, but routing code
- * needs to know interface name - point to "actual", restore later
- */
- saved_actual = tt->actual_name;
- tt->actual_name = (char*) actual;
- /* we use adapter_index in add_route_ipv6 */
- tt->adapter_index = idx;
add_route_connected_v6_net(tt, es);
- tt->actual_name = saved_actual;
}
#else
msg (M_FATAL, "Sorry, but I don't know how to do 'ifconfig' commands on this operating system. You should ifconfig your TUN/TAP device manually or use an --up script.");
@@ -1272,7 +1405,7 @@ static void
clear_tuntap (struct tuntap *tuntap)
{
CLEAR (*tuntap);
-#ifdef WIN32
+#ifdef _WIN32
tuntap->hand = NULL;
#else
tuntap->fd = -1;
@@ -1280,7 +1413,6 @@ clear_tuntap (struct tuntap *tuntap)
#ifdef TARGET_SOLARIS
tuntap->ip_fd = -1;
#endif
- tuntap->ipv6 = false;
}
static void
@@ -1333,7 +1465,7 @@ write_tun_header (struct tuntap* tt, uint8_t *buf, int len)
iph = (struct ip *) buf;
- if (tt->ipv6 && iph->ip_v == 6)
+ if (iph->ip_v == 6)
type = htonl (AF_INET6);
else
type = htonl (AF_INET);
@@ -1370,20 +1502,15 @@ read_tun_header (struct tuntap* tt, uint8_t *buf, int len)
#endif
-#ifndef WIN32
+#if !(defined(_WIN32) || defined(TARGET_LINUX))
static void
open_tun_generic (const char *dev, const char *dev_type, const char *dev_node,
- bool ipv6_explicitly_supported, bool dynamic,
- struct tuntap *tt)
+ bool dynamic, struct tuntap *tt)
{
char tunname[256];
char dynamic_name[256];
bool dynamic_opened = false;
-
- if ( tt->ipv6 && ! ipv6_explicitly_supported )
- msg (M_WARN, "NOTE: explicit support for IPv6 tun devices is not provided for this OS");
-
if (tt->type == DEV_TYPE_NULL)
{
open_null (tt);
@@ -1477,7 +1604,9 @@ open_tun_generic (const char *dev, const char *dev_type, const char *dev_node,
tt->actual_name = string_alloc (dynamic_opened ? dynamic_name : dev, NULL);
}
}
+#endif /* !_WIN32 && !TARGET_LINUX */
+#if !defined(_WIN32)
static void
close_tun_generic (struct tuntap *tt)
{
@@ -1487,12 +1616,83 @@ close_tun_generic (struct tuntap *tt)
free (tt->actual_name);
clear_tuntap (tt);
}
+#endif /* !_WIN32 */
-#endif
+#if defined (TARGET_ANDROID)
+void
+open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt)
+{
+#define ANDROID_TUNNAME "vpnservice-tun"
+ int i;
+ struct user_pass up;
+ struct gc_arena gc = gc_new ();
+ bool opentun;
-#if defined(TARGET_LINUX)
+ int oldtunfd = tt->fd;
+
+ for (i = 0; i < tt->options.dns_len; ++i) {
+ management_android_control (management, "DNSSERVER",
+ print_in_addr_t(tt->options.dns[i], 0, &gc));
+ }
-#ifdef HAVE_LINUX_IF_TUN_H /* New driver support */
+ if(tt->options.domain)
+ management_android_control (management, "DNSDOMAIN", tt->options.domain);
+
+ int android_method = managment_android_persisttun_action (management);
+
+ /* Android 4.4 workaround */
+ if (oldtunfd >=0 && android_method == ANDROID_OPEN_AFTER_CLOSE)
+ {
+ close(oldtunfd);
+ openvpn_sleep(2);
+ }
+
+ if (oldtunfd >=0 && android_method == ANDROID_KEEP_OLD_TUN) {
+ /* keep the old fd */
+ opentun = true;
+ } else {
+ opentun = management_android_control (management, "OPENTUN", dev);
+ /* Pick up the fd from management interface after calling the
+ * OPENTUN command */
+ tt->fd = management->connection.lastfdreceived;
+ management->connection.lastfdreceived=-1;
+ }
+
+ if (oldtunfd>=0 && android_method == ANDROID_OPEN_BEFORE_CLOSE)
+ close(oldtunfd);
+
+ /* Set the actual name to a dummy name */
+ tt->actual_name = string_alloc (ANDROID_TUNNAME, NULL);
+
+ if ((tt->fd < 0) || !opentun)
+ msg (M_ERR, "ERROR: Cannot open TUN");
+
+ gc_free (&gc);
+}
+
+void
+close_tun (struct tuntap *tt)
+{
+ if (tt)
+ {
+ close_tun_generic (tt);
+ free (tt);
+ }
+}
+
+int
+write_tun (struct tuntap* tt, uint8_t *buf, int len)
+{
+ return write (tt->fd, buf, len);
+}
+
+int
+read_tun (struct tuntap* tt, uint8_t *buf, int len)
+{
+ return read (tt->fd, buf, len);
+}
+
+#elif defined(TARGET_LINUX)
#ifndef HAVE_LINUX_SOCKIOS_H
#error header file linux/sockios.h required
@@ -1533,8 +1733,7 @@ open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tu
* Process --tun-ipv6
*/
CLEAR (ifr);
- if (!tt->ipv6)
- ifr.ifr_flags = IFF_NO_PI;
+ ifr.ifr_flags = IFF_NO_PI;
#if defined(IFF_ONE_QUEUE) && defined(SIOCSIFTXQLEN)
ifr.ifr_flags |= IFF_ONE_QUEUE;
@@ -1615,32 +1814,10 @@ open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tu
ASSERT (0);
}
-#endif
-
-#else
-
-void
-open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt)
-{
- open_tun_generic (dev, dev_type, dev_node, false, true, tt);
-}
-
-#endif /* HAVE_LINUX_IF_TUN_H */
+#endif /* !PENDANTIC */
#ifdef ENABLE_FEATURE_TUN_PERSIST
-/*
- * This can be removed in future
- * when all systems will use newer
- * linux-headers
- */
-#ifndef TUNSETOWNER
-#define TUNSETOWNER _IOW('T', 204, int)
-#endif
-#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, const struct tuntap_options *options)
{
@@ -1686,9 +1863,8 @@ close_tun (struct tuntap *tt)
{
if (tt->type != DEV_TYPE_NULL && tt->did_ifconfig)
{
- struct argv argv;
+ struct argv argv = argv_new ();
struct gc_arena gc = gc_new ();
- argv_init (&argv);
#ifdef ENABLE_IPROUTE
if (is_tun_p2p (tt))
@@ -1708,7 +1884,7 @@ close_tun (struct tuntap *tt)
iproute_path,
tt->actual_name,
print_in_addr_t (tt->local, 0, &gc),
- count_netmask_bits(print_in_addr_t (tt->remote_netmask, 0, &gc))
+ netmask_to_netbits2(tt->remote_netmask)
);
}
#else
@@ -1722,7 +1898,7 @@ close_tun (struct tuntap *tt)
argv_msg (M_INFO, &argv);
openvpn_execve_check (&argv, NULL, 0, "Linux ip addr del failed");
- if (tt->ipv6 && tt->did_ifconfig_ipv6_setup)
+ if (tt->did_ifconfig_ipv6_setup)
{
const char * ifconfig_ipv6_local = print_in6_addr (tt->local_ipv6, 0, &gc);
@@ -1759,53 +1935,13 @@ close_tun (struct tuntap *tt)
int
write_tun (struct tuntap* tt, uint8_t *buf, int len)
{
- if (tt->ipv6)
- {
- struct tun_pi pi;
- struct iphdr *iph;
- struct iovec vect[2];
- int ret;
-
- iph = (struct iphdr *)buf;
-
- pi.flags = 0;
-
- if(iph->version == 6)
- pi.proto = htons(OPENVPN_ETH_P_IPV6);
- else
- pi.proto = htons(OPENVPN_ETH_P_IPV4);
-
- vect[0].iov_len = sizeof(pi);
- vect[0].iov_base = &pi;
- vect[1].iov_len = len;
- vect[1].iov_base = buf;
-
- ret = writev(tt->fd, vect, 2);
- return(ret - sizeof(pi));
- }
- else
- return write (tt->fd, buf, len);
+ return write (tt->fd, buf, len);
}
int
read_tun (struct tuntap* tt, uint8_t *buf, int len)
{
- if (tt->ipv6)
- {
- struct iovec vect[2];
- struct tun_pi pi;
- int ret;
-
- vect[0].iov_len = sizeof(pi);
- vect[0].iov_base = &pi;
- vect[1].iov_len = len;
- vect[1].iov_base = buf;
-
- ret = readv(tt->fd, vect, 2);
- return(ret - sizeof(pi));
- }
- else
- return read (tt->fd, buf, len);
+ return read (tt->fd, buf, len);
}
#elif defined(TARGET_SOLARIS)
@@ -2009,10 +2145,9 @@ solaris_close_tun (struct tuntap *tt)
if (tt)
{
/* IPv6 interfaces need to be 'manually' de-configured */
- if ( tt->ipv6 && tt->did_ifconfig_ipv6_setup )
+ if ( tt->did_ifconfig_ipv6_setup )
{
- struct argv argv;
- argv_init (&argv);
+ struct argv argv = argv_new ();
argv_printf( &argv, "%s %s inet6 unplumb",
IFCONFIG_PATH, tt->actual_name );
argv_msg (M_INFO, &argv);
@@ -2075,8 +2210,7 @@ static void
solaris_error_close (struct tuntap *tt, const struct env_set *es,
const char *actual, bool unplumb_inet6 )
{
- struct argv argv;
- argv_init (&argv);
+ struct argv argv = argv_new ();
if (unplumb_inet6)
{
@@ -2123,7 +2257,7 @@ read_tun (struct tuntap* tt, uint8_t *buf, int len)
void
open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt)
{
- open_tun_generic (dev, dev_type, dev_node, true, true, tt);
+ open_tun_generic (dev, dev_type, dev_node, true, tt);
/* Enable multicast on the interface */
if (tt->fd >= 0)
@@ -2168,12 +2302,11 @@ close_tun (struct tuntap* tt)
else if (tt)
{
struct gc_arena gc = gc_new ();
- struct argv argv;
+ struct argv argv = argv_new ();
/* setup command, close tun dev (clears tt->actual_name!), run command
*/
- argv_init (&argv);
argv_printf (&argv, "%s %s destroy",
IFCONFIG_PATH, tt->actual_name);
@@ -2217,11 +2350,7 @@ read_tun (struct tuntap *tt, uint8_t *buf, int len)
void
open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt)
{
-#ifdef NETBSD_MULTI_AF
- open_tun_generic (dev, dev_type, dev_node, true, true, tt);
-#else
- open_tun_generic (dev, dev_type, dev_node, false, true, tt);
-#endif
+ open_tun_generic (dev, dev_type, dev_node, true, tt);
if (tt->fd >= 0)
{
@@ -2230,7 +2359,6 @@ open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tu
i = 0;
ioctl (tt->fd, TUNSLMODE, &i); /* link layer mode off */
-#ifdef NETBSD_MULTI_AF
if ( tt->type == DEV_TYPE_TUN )
{
i = 1;
@@ -2239,7 +2367,6 @@ open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tu
msg (M_WARN | M_ERRNO, "ioctl(TUNSIFHEAD): %s", strerror(errno));
}
}
-#endif
}
}
@@ -2260,12 +2387,11 @@ close_tun (struct tuntap *tt)
else if (tt)
{
struct gc_arena gc = gc_new ();
- struct argv argv;
+ struct argv argv = argv_new ();
/* setup command, close tun dev (clears tt->actual_name!), run command
*/
- argv_init (&argv);
argv_printf (&argv, "%s %s destroy",
IFCONFIG_PATH, tt->actual_name);
@@ -2278,8 +2404,6 @@ close_tun (struct tuntap *tt)
}
}
-#ifdef NETBSD_MULTI_AF
-
static inline int
netbsd_modify_read_write_return (int len)
{
@@ -2300,7 +2424,7 @@ write_tun (struct tuntap* tt, uint8_t *buf, int len)
iph = (struct openvpn_iphdr *) buf;
- if (tt->ipv6 && OPENVPN_IPH_GET_VER(iph->version_len) == 6)
+ if (OPENVPN_IPH_GET_VER(iph->version_len) == 6)
type = htonl (AF_INET6);
else
type = htonl (AF_INET);
@@ -2335,21 +2459,6 @@ read_tun (struct tuntap* tt, uint8_t *buf, int len)
return read (tt->fd, buf, len);
}
-#else /* not NETBSD_MULTI_AF -> older code, IPv4 only */
-
-int
-write_tun (struct tuntap* tt, uint8_t *buf, int len)
-{
- return write (tt->fd, buf, len);
-}
-
-int
-read_tun (struct tuntap* tt, uint8_t *buf, int len)
-{
- return read (tt->fd, buf, len);
-}
-#endif /* NETBSD_MULTI_AF */
-
#elif defined(TARGET_FREEBSD)
static inline int
@@ -2364,7 +2473,7 @@ freebsd_modify_read_write_return (int len)
void
open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt)
{
- open_tun_generic (dev, dev_type, dev_node, true, true, tt);
+ open_tun_generic (dev, dev_type, dev_node, true, tt);
if (tt->fd >= 0 && tt->type == DEV_TYPE_TUN)
{
@@ -2397,12 +2506,11 @@ close_tun (struct tuntap *tt)
}
else if (tt) /* close and destroy */
{
- struct argv argv;
+ struct argv argv = argv_new ();
/* setup command, close tun dev (clears tt->actual_name!), run command
*/
- argv_init (&argv);
argv_printf (&argv, "%s %s destroy",
IFCONFIG_PATH, tt->actual_name);
@@ -2426,7 +2534,7 @@ write_tun (struct tuntap* tt, uint8_t *buf, int len)
iph = (struct ip *) buf;
- if (tt->ipv6 && iph->ip_v == 6)
+ if (iph->ip_v == 6)
type = htonl (AF_INET6);
else
type = htonl (AF_INET);
@@ -2475,7 +2583,7 @@ dragonfly_modify_read_write_return (int len)
void
open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt)
{
- open_tun_generic (dev, dev_type, dev_node, true, true, tt);
+ open_tun_generic (dev, dev_type, dev_node, true, tt);
if (tt->fd >= 0)
{
@@ -2509,7 +2617,7 @@ write_tun (struct tuntap* tt, uint8_t *buf, int len)
iph = (struct ip *) buf;
- if (tt->ipv6 && iph->ip_v == 6)
+ if (iph->ip_v == 6)
type = htonl (AF_INET6);
else
type = htonl (AF_INET);
@@ -2702,7 +2810,7 @@ open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tu
{
/* No explicit utun and utun failed, try the generic way) */
msg (M_INFO, "Failed to open utun device. Falling back to /dev/tun device");
- open_tun_generic (dev, dev_type, NULL, true, true, tt);
+ open_tun_generic (dev, dev_type, NULL, true, tt);
}
else
{
@@ -2723,7 +2831,7 @@ open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tu
if (dev_node && strcmp (dev_node, "tun")==0)
dev_node=NULL;
- open_tun_generic (dev, dev_type, dev_node, true, true, tt);
+ open_tun_generic (dev, dev_type, dev_node, true, tt);
}
}
@@ -2733,10 +2841,9 @@ close_tun (struct tuntap* tt)
if (tt)
{
struct gc_arena gc = gc_new ();
- struct argv argv;
- argv_init (&argv);
+ struct argv argv = argv_new ();
- if ( tt->ipv6 && tt->did_ifconfig_ipv6_setup )
+ if (tt->did_ifconfig_ipv6_setup )
{
const char * ifconfig_ipv6_local =
print_in6_addr (tt->local_ipv6, 0, &gc);
@@ -2776,7 +2883,137 @@ read_tun (struct tuntap* tt, uint8_t *buf, int len)
return read (tt->fd, buf, len);
}
-#elif defined(WIN32)
+#elif defined(TARGET_AIX)
+
+void
+open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt)
+{
+ char tunname[256];
+ char dynamic_name[20];
+ const char *p;
+
+ if (tt->type == DEV_TYPE_NULL)
+ {
+ open_null (tt);
+ return;
+ }
+
+ if ( tt->type == DEV_TYPE_TUN)
+ {
+ msg(M_FATAL, "no support for 'tun' devices on AIX" );
+ }
+
+ if ( strncmp( dev, "tap", 3 ) != 0 || dev_node )
+ {
+ msg(M_FATAL, "'--dev %s' and/or '--dev-node' not supported on AIX, use '--dev tap0', 'tap1', etc.", dev );
+ }
+
+ if ( strcmp( dev, "tap" ) == 0 ) /* find first free tap dev */
+ { /* (= no /dev/tapN node) */
+ int i;
+ for (i=0; i<99; i++ )
+ {
+ openvpn_snprintf (tunname, sizeof (tunname), "/dev/tap%d", i);
+ if ( access( tunname, F_OK ) < 0 && errno == ENOENT )
+ { break; }
+ }
+ if ( i >= 99 )
+ msg( M_FATAL, "cannot find unused tap device" );
+
+ openvpn_snprintf( dynamic_name, sizeof(dynamic_name), "tap%d", i );
+ dev = dynamic_name;
+ }
+ else /* name given, sanity check */
+ {
+ /* ensure that dev name is "tap+<digits>" *only* */
+ p = &dev[3];
+ while( isdigit(*p) ) p++;
+ if ( *p != '\0' )
+ msg( M_FATAL, "TAP device name must be '--dev tapNNNN'" );
+
+ openvpn_snprintf (tunname, sizeof (tunname), "/dev/%s", dev);
+ }
+
+ /* pre-existing device?
+ */
+ if ( access( tunname, F_OK ) < 0 && errno == ENOENT )
+ {
+
+ /* tunnel device must be created with 'ifconfig tapN create'
+ */
+ struct argv argv = argv_new ();
+ struct env_set *es = env_set_create (NULL);
+ argv_printf (&argv, "%s %s create", IFCONFIG_PATH, dev);
+ argv_msg (M_INFO, &argv);
+ env_set_add( es, "ODMDIR=/etc/objrepos" );
+ openvpn_execve_check (&argv, es, S_FATAL, "AIX 'create tun interface' failed");
+ env_set_destroy (es);
+ }
+ else
+ {
+ /* we didn't make it, we're not going to break it */
+ tt->persistent_if = TRUE;
+ }
+
+ if ((tt->fd = open (tunname, O_RDWR)) < 0)
+ {
+ msg (M_ERR, "Cannot open TAP device '%s'", tunname);
+ }
+
+ set_nonblock (tt->fd);
+ set_cloexec (tt->fd); /* don't pass fd to scripts */
+ msg (M_INFO, "TUN/TAP device %s opened", tunname);
+
+ /* tt->actual_name is passed to up and down scripts and used as the ifconfig dev name */
+ tt->actual_name = string_alloc(dev, NULL);
+}
+
+/* tap devices need to be manually destroyed on AIX
+ */
+void
+close_tun (struct tuntap* tt)
+{
+ struct gc_arena gc = gc_new ();
+ struct argv argv = argv_new ();
+ struct env_set *es = env_set_create (NULL);
+
+ if (!tt) return;
+
+ /* persistent devices need IP address unconfig, others need destroyal
+ */
+ if (tt->persistent_if)
+ {
+ argv_printf (&argv, "%s %s 0.0.0.0 down",
+ IFCONFIG_PATH, tt->actual_name);
+ }
+ else
+ {
+ argv_printf (&argv, "%s %s destroy",
+ IFCONFIG_PATH, tt->actual_name);
+ }
+
+ close_tun_generic (tt);
+ argv_msg (M_INFO, &argv);
+ env_set_add( es, "ODMDIR=/etc/objrepos" );
+ openvpn_execve_check (&argv, es, 0, "AIX 'destroy tap interface' failed (non-critical)");
+
+ free(tt);
+ env_set_destroy (es);
+}
+
+int
+write_tun (struct tuntap* tt, uint8_t *buf, int len)
+{
+ return write (tt->fd, buf, len);
+}
+
+int
+read_tun (struct tuntap* tt, uint8_t *buf, int len)
+{
+ return read (tt->fd, buf, len);
+}
+
+#elif defined(_WIN32)
int
tun_read_queue (struct tuntap *tt, int maxsize)
@@ -4246,7 +4483,7 @@ dhcp_renew (const struct tuntap *tt)
*/
static void
-netsh_command (const struct argv *a, int n)
+netsh_command (const struct argv *a, int n, int msglevel)
{
int i;
for (i = 0; i < n; ++i)
@@ -4261,21 +4498,19 @@ netsh_command (const struct argv *a, int n)
return;
openvpn_sleep (4);
}
- msg (M_FATAL, "NETSH: command failed");
+ msg (msglevel, "NETSH: command failed");
}
void
ipconfig_register_dns (const struct env_set *es)
{
- struct argv argv;
+ struct argv argv = argv_new ();
bool status;
const char err[] = "ERROR: Windows ipconfig command failed";
msg (D_TUNTAP_INFO, "Start net commands...");
netcmd_semaphore_lock ();
- argv_init (&argv);
-
argv_printf (&argv, "%s%sc stop dnscache",
get_win_sys_path(),
WIN_NET_PATH_SUFFIX);
@@ -4411,7 +4646,7 @@ netsh_ifconfig_options (const char *type,
NETSH_PATH_SUFFIX,
type,
flex_name);
- netsh_command (&argv, 2);
+ netsh_command (&argv, 2, M_FATAL);
}
/* add new DNS/WINS settings to TAP interface */
@@ -4432,7 +4667,7 @@ netsh_ifconfig_options (const char *type,
type,
flex_name,
print_in_addr_t (addr_list[i], 0, &gc));
- netsh_command (&argv, 2);
+ netsh_command (&argv, 2, M_FATAL);
++count;
}
@@ -4507,7 +4742,7 @@ netsh_ifconfig (const struct tuntap_options *to,
print_in_addr_t (ip, 0, &gc),
print_in_addr_t (netmask, 0, &gc));
- netsh_command (&argv, 4);
+ netsh_command (&argv, 4, M_FATAL);
}
}
@@ -4543,8 +4778,7 @@ static void
netsh_enable_dhcp (const struct tuntap_options *to,
const char *actual_name)
{
- struct argv argv;
- argv_init (&argv);
+ struct argv argv = argv_new ();
/* example: netsh interface ip set address my-tap dhcp */
argv_printf (&argv,
@@ -4553,7 +4787,7 @@ netsh_enable_dhcp (const struct tuntap_options *to,
NETSH_PATH_SUFFIX,
actual_name);
- netsh_command (&argv, 4);
+ netsh_command (&argv, 4, M_FATAL);
argv_reset (&argv);
}
@@ -4750,10 +4984,43 @@ fork_dhcp_action (struct tuntap *tt)
}
}
+static void
+register_dns_service (const struct tuntap *tt)
+{
+ DWORD len;
+ HANDLE msg_channel = tt->options.msg_channel;
+ ack_message_t ack;
+ struct gc_arena gc = gc_new ();
+
+ message_header_t rdns = { msg_register_dns, sizeof(message_header_t), 0 };
+
+ if (!WriteFile (msg_channel, &rdns, sizeof (rdns), &len, NULL) ||
+ !ReadFile (msg_channel, &ack, sizeof (ack), &len, NULL))
+ {
+ msg (M_WARN, "Register_dns: could not talk to service: %s [status=0x%lx]",
+ strerror_win32 (GetLastError (), &gc), GetLastError ());
+ }
+
+ else if (ack.error_number != NO_ERROR)
+ {
+ msg (M_WARN, "Register_dns failed using service: %s [status=0x%x]",
+ strerror_win32 (ack.error_number, &gc), ack.error_number);
+ }
+
+ else
+ msg (M_INFO, "Register_dns request sent to the service");
+
+ gc_free (&gc);
+}
+
void
fork_register_dns_action (struct tuntap *tt)
{
- if (tt && tt->options.register_dns)
+ if (tt && tt->options.register_dns && tt->options.msg_channel)
+ {
+ register_dns_service (tt);
+ }
+ else if (tt && tt->options.register_dns)
{
struct gc_arena gc = gc_new ();
struct buffer cmd = alloc_buf_gc (256, &gc);
@@ -4798,7 +5065,7 @@ open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tu
/*netcmd_semaphore_lock ();*/
- msg( M_INFO, "open_tun, tt->ipv6=%d", tt->ipv6 );
+ msg( M_INFO, "open_tun");
if (tt->type == DEV_TYPE_NULL)
{
@@ -4924,11 +5191,10 @@ open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tu
/* usage of numeric constants is ugly, but this is really tied to
* *this* version of the driver
*/
- if ( tt->ipv6 && tt->type == DEV_TYPE_TUN &&
+ if (tt->type == DEV_TYPE_TUN &&
info[0] == 9 && info[1] < 8)
{
- msg( M_INFO, "WARNING: Tap-Win32 driver version %d.%d does not support IPv6 in TUN mode. IPv6 will be disabled. Upgrade to Tap-Win32 9.8 (2.2-beta3 release or later) or use TAP mode to get IPv6", (int) info[0], (int) info[1] );
- tt->ipv6 = false;
+ msg( M_INFO, "WARNING: Tap-Win32 driver version %d.%d does not support IPv6 in TUN mode. IPv6 will not work. Upgrade your Tap-Win32 driver.", (int) info[0], (int) info[1] );
}
/* tap driver 9.8 (2.2.0 and 2.2.1 release) is buggy
@@ -4936,7 +5202,7 @@ open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tu
if ( tt->type == DEV_TYPE_TUN &&
info[0] == 9 && info[1] == 8)
{
- msg( M_FATAL, "ERROR: Tap-Win32 driver version %d.%d is buggy regarding small IPv4 packets in TUN mode. Upgrade to Tap-Win32 9.9 (2.2.2 release or later) or use TAP mode", (int) info[0], (int) info[1] );
+ msg( M_FATAL, "ERROR: Tap-Win32 driver version %d.%d is buggy regarding small IPv4 packets in TUN mode. Upgrade your Tap-Win32 driver.", (int) info[0], (int) info[1] );
}
}
@@ -5122,13 +5388,35 @@ open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tu
/* flush arp cache */
if (index != TUN_ADAPTER_INDEX_INVALID)
{
- DWORD status;
+ DWORD status = -1;
+
+ if (tt->options.msg_channel)
+ {
+ ack_message_t ack;
+ flush_neighbors_message_t msg = {
+ .header = {
+ msg_flush_neighbors,
+ sizeof (flush_neighbors_message_t),
+ 0 },
+ .family = AF_INET,
+ .iface = { .index = index, .name = "" }
+ };
+
+ if (!WriteFile (tt->options.msg_channel, &msg, sizeof (msg), &len, NULL) ||
+ !ReadFile (tt->options.msg_channel, &ack, sizeof (ack), &len, NULL))
+ msg (M_WARN, "TUN: could not talk to service: %s [%lu]",
+ strerror_win32 (GetLastError (), &gc), GetLastError ());
+
+ status = ack.error_number;
+ }
+ else
+ status = FlushIpNetTable (index);
- if ((status = FlushIpNetTable (index)) == NO_ERROR)
+ if (status == NO_ERROR)
msg (M_INFO, "Successful ARP Flush on interface [%u] %s",
(unsigned int)index,
device_guid);
- else
+ else if (status != -1)
msg (D_TUNTAP_INFO, "NOTE: FlushIpNetTable failed on interface [%u] %s (status=%u) : %s",
(unsigned int)index,
device_guid,
@@ -5247,30 +5535,36 @@ close_tun (struct tuntap *tt)
if (tt)
{
- if ( tt->ipv6 && tt->did_ifconfig_ipv6_setup )
+ if ( tt->did_ifconfig_ipv6_setup )
{
- const char *ifconfig_ipv6_local;
- struct argv argv;
- argv_init (&argv);
-
- /* remove route pointing to interface */
- delete_route_connected_v6_net(tt, NULL);
-
- /* "store=active" is needed in Windows 8(.1) to delete the
- * address we added (pointed out by Cedric Tabary).
- */
-
- /* netsh interface ipv6 delete address \"%s\" %s */
- ifconfig_ipv6_local = print_in6_addr (tt->local_ipv6, 0, &gc);
- argv_printf (&argv,
- "%s%sc interface ipv6 delete address %s %s store=active",
- get_win_sys_path(),
- NETSH_PATH_SUFFIX,
- tt->actual_name,
- ifconfig_ipv6_local );
-
- netsh_command (&argv, 1);
- argv_reset (&argv);
+ if (tt->options.msg_channel)
+ {
+ do_address_service (false, AF_INET6, tt);
+ }
+ else
+ {
+ const char *ifconfig_ipv6_local;
+ struct argv argv = argv_new ();
+
+ /* remove route pointing to interface */
+ delete_route_connected_v6_net(tt, NULL);
+
+ /* "store=active" is needed in Windows 8(.1) to delete the
+ * address we added (pointed out by Cedric Tabary).
+ */
+
+ /* netsh interface ipv6 delete address \"%s\" %s */
+ ifconfig_ipv6_local = print_in6_addr (tt->local_ipv6, 0, &gc);
+ argv_printf (&argv,
+ "%s%sc interface ipv6 delete address %s %s store=active",
+ get_win_sys_path(),
+ NETSH_PATH_SUFFIX,
+ tt->actual_name,
+ ifconfig_ipv6_local);
+
+ netsh_command (&argv, 1, M_WARN);
+ argv_reset (&argv);
+ }
}
#if 1
if (tt->ipapi_context_defined)
@@ -5377,7 +5671,7 @@ ipset2ascii_all (struct gc_arena *gc)
void
open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt)
{
- open_tun_generic (dev, dev_type, dev_node, false, true, tt);
+ open_tun_generic (dev, dev_type, dev_node, true, tt);
}
void
diff --git a/src/openvpn/tun.h b/src/openvpn/tun.h
index 7089f7c..dedd915 100644
--- a/src/openvpn/tun.h
+++ b/src/openvpn/tun.h
@@ -25,7 +25,7 @@
#ifndef TUN_H
#define TUN_H
-#ifdef WIN32
+#ifdef _WIN32
#include <winioctl.h>
#include <tap-windows.h>
#endif
@@ -38,7 +38,7 @@
#include "proto.h"
#include "misc.h"
-#ifdef WIN32
+#if defined(_WIN32) || defined(TARGET_ANDROID)
#define TUN_ADAPTER_INDEX_INVALID ((DWORD)-1)
@@ -58,6 +58,10 @@ struct tuntap_options {
# define IPW32_SET_N 5
int ip_win32_type;
+#ifdef _WIN32
+ HANDLE msg_channel;
+#endif
+
/* --ip-win32 dynamic options */
bool dhcp_masq_custom_offset;
int dhcp_masq_offset;
@@ -135,8 +139,6 @@ struct tuntap
bool did_ifconfig_ipv6_setup;
bool did_ifconfig;
- bool ipv6;
-
bool persistent_if; /* if existed before, keep on program end */
struct tuntap_options options; /* options set on command line */
@@ -155,7 +157,7 @@ struct tuntap
struct in6_addr remote_ipv6;
int netbits_ipv6;
-#ifdef WIN32
+#ifdef _WIN32
HANDLE hand;
struct overlapped_io reads;
struct overlapped_io writes;
@@ -195,7 +197,7 @@ struct tuntap
static inline bool
tuntap_defined (const struct tuntap *tt)
{
-#ifdef WIN32
+#ifdef _WIN32
return tt && tt->hand != NULL;
#else
return tt && tt->fd >= 0;
@@ -232,8 +234,8 @@ struct tuntap *init_tun (const char *dev, /* --dev option */
const char *ifconfig_ipv6_local_parm, /* --ifconfig parm 1 / IPv6 */
int ifconfig_ipv6_netbits_parm, /* --ifconfig parm 1 / bits */
const char *ifconfig_ipv6_remote_parm, /* --ifconfig parm 2 / IPv6 */
- in_addr_t local_public,
- in_addr_t remote_public,
+ struct addrinfo *local_public,
+ struct addrinfo *remote_public,
const bool strict_warn,
struct env_set *es);
@@ -296,14 +298,31 @@ ifconfig_order(void)
return IFCONFIG_AFTER_TUN_OPEN;
#elif defined(TARGET_NETBSD)
return IFCONFIG_AFTER_TUN_OPEN;
-#elif defined(WIN32)
+#elif defined(_WIN32)
+ return IFCONFIG_AFTER_TUN_OPEN;
+#elif defined(TARGET_ANDROID)
return IFCONFIG_BEFORE_TUN_OPEN;
#else
return IFCONFIG_DEFAULT;
#endif
}
-#ifdef WIN32
+#define ROUTE_BEFORE_TUN 0
+#define ROUTE_AFTER_TUN 1
+#define ROUTE_ORDER_DEFAULT ROUTE_AFTER_TUN
+
+static inline int
+route_order(void)
+{
+#if defined(TARGET_ANDROID)
+ return ROUTE_BEFORE_TUN;
+#else
+ return ROUTE_ORDER_DEFAULT;
+#endif
+}
+
+
+#ifdef _WIN32
#define TUN_PASS_BUFFER
@@ -457,7 +476,7 @@ tun_standby (struct tuntap *tt)
static inline event_t
tun_event_handle (const struct tuntap *tt)
{
-#ifdef WIN32
+#ifdef _WIN32
return &tt->rw_handle;
#else
return tt->fd;
@@ -480,7 +499,7 @@ tun_set (struct tuntap *tt,
if (persistent)
*persistent = rwflags;
}
-#ifdef WIN32
+#ifdef _WIN32
if (rwflags & EVENT_READ)
tun_read_queue (tt, 0);
#endif
diff --git a/src/openvpn/win32.c b/src/openvpn/win32.c
index e17cca1..00bc7ac 100644
--- a/src/openvpn/win32.c
+++ b/src/openvpn/win32.c
@@ -35,7 +35,7 @@
#include "syshead.h"
-#ifdef WIN32
+#ifdef _WIN32
#include "buffer.h"
#include "error.h"
@@ -43,34 +43,20 @@
#include "sig.h"
#include "win32.h"
#include "misc.h"
+#include "openvpn-msg.h"
#include "memdbg.h"
-#include "win32_wfp.h"
-
#ifdef HAVE_VERSIONHELPERS_H
#include <versionhelpers.h>
#else
#include "compat-versionhelpers.h"
#endif
-/* WFP function pointers. Initialized in win_wfp_init_funcs() */
-func_ConvertInterfaceIndexToLuid ConvertInterfaceIndexToLuid = NULL;
-func_FwpmEngineOpen0 FwpmEngineOpen0 = NULL;
-func_FwpmEngineClose0 FwpmEngineClose0 = NULL;
-func_FwpmFilterAdd0 FwpmFilterAdd0 = NULL;
-func_FwpmSubLayerAdd0 FwpmSubLayerAdd0 = NULL;
-func_FwpmSubLayerDeleteByKey0 FwpmSubLayerDeleteByKey0 = NULL;
-func_FwpmFreeMemory0 FwpmFreeMemory0 = NULL;
-func_FwpmGetAppIdFromFileName0 FwpmGetAppIdFromFileName0 = NULL;
-
-/*
- * WFP firewall name.
- */
-WCHAR * FIREWALL_NAME = L"OpenVPN"; /* GLOBAL */
+#include "block_dns.h"
/*
- * WFP handle and GUID.
+ * WFP handle
*/
static HANDLE m_hEngineHandle = NULL; /* GLOBAL */
@@ -119,7 +105,6 @@ init_win32 (void)
}
window_title_clear (&window_title);
win32_signal_clear (&win32_signal);
- netcmd_semaphore_init ();
}
void
@@ -598,7 +583,7 @@ win32_signal_get (struct win32_signal *ws)
if (ret)
{
siginfo_static.signal_received = ret;
- siginfo_static.hard = true;
+ siginfo_static.source = SIG_SOURCE_HARD;
}
}
return ret;
@@ -765,6 +750,10 @@ void
netcmd_semaphore_lock (void)
{
const int timeout_seconds = 600;
+
+ if (!netcmd_semaphore.hand)
+ netcmd_semaphore_init ();
+
if (!semaphore_lock (&netcmd_semaphore, timeout_seconds * 1000))
msg (M_FATAL, "Cannot lock net command semaphore");
}
@@ -773,6 +762,8 @@ void
netcmd_semaphore_release (void)
{
semaphore_release (&netcmd_semaphore);
+ /* netcmd_semaphore has max count of 1 - safe to close after release */
+ semaphore_close (&netcmd_semaphore);
}
/*
@@ -1106,211 +1097,109 @@ win_get_tempdir()
return tmpdir;
}
-bool
-win_wfp_init_funcs ()
+static bool
+win_block_dns_service (bool add, int index, const HANDLE pipe)
{
- /* Initialize all WFP-related function pointers */
- HMODULE iphlpapiHandle;
- HMODULE fwpuclntHandle;
-
- iphlpapiHandle = LoadLibrary("iphlpapi.dll");
- if (iphlpapiHandle == NULL)
- {
- msg (M_NONFATAL, "Can't load iphlpapi.dll");
- return false;
- }
+ DWORD len;
+ bool ret = false;
+ ack_message_t ack;
+ struct gc_arena gc = gc_new ();
- fwpuclntHandle = LoadLibrary("fwpuclnt.dll");
- if (fwpuclntHandle == NULL)
- {
- msg (M_NONFATAL, "Can't load fwpuclnt.dll");
- return false;
- }
-
- ConvertInterfaceIndexToLuid = (func_ConvertInterfaceIndexToLuid)GetProcAddress(iphlpapiHandle, "ConvertInterfaceIndexToLuid");
- FwpmFilterAdd0 = (func_FwpmFilterAdd0)GetProcAddress(fwpuclntHandle, "FwpmFilterAdd0");
- FwpmEngineOpen0 = (func_FwpmEngineOpen0)GetProcAddress(fwpuclntHandle, "FwpmEngineOpen0");
- FwpmEngineClose0 = (func_FwpmEngineClose0)GetProcAddress(fwpuclntHandle, "FwpmEngineClose0");
- FwpmSubLayerAdd0 = (func_FwpmSubLayerAdd0)GetProcAddress(fwpuclntHandle, "FwpmSubLayerAdd0");
- FwpmSubLayerDeleteByKey0 = (func_FwpmSubLayerDeleteByKey0)GetProcAddress(fwpuclntHandle, "FwpmSubLayerDeleteByKey0");
- FwpmFreeMemory0 = (func_FwpmFreeMemory0)GetProcAddress(fwpuclntHandle, "FwpmFreeMemory0");
- FwpmGetAppIdFromFileName0 = (func_FwpmGetAppIdFromFileName0)GetProcAddress(fwpuclntHandle, "FwpmGetAppIdFromFileName0");
-
- if (!ConvertInterfaceIndexToLuid ||
- !FwpmFilterAdd0 ||
- !FwpmEngineOpen0 ||
- !FwpmEngineClose0 ||
- !FwpmSubLayerAdd0 ||
- !FwpmSubLayerDeleteByKey0 ||
- !FwpmFreeMemory0 ||
- !FwpmGetAppIdFromFileName0)
- {
- msg (M_NONFATAL, "Can't get address for all WFP-related procedures.");
- return false;
- }
+ block_dns_message_t data = {
+ .header = {
+ (add ? msg_add_block_dns : msg_del_block_dns),
+ sizeof (block_dns_message_t),
+ 0 },
+ .iface = { .index = index, .name = "" }
+ };
- return true;
-}
+ if (!WriteFile (pipe, &data, sizeof (data), &len, NULL) ||
+ !ReadFile (pipe, &ack, sizeof (ack), &len, NULL))
+ {
+ msg (M_WARN, "Block_DNS: could not talk to service: %s [%lu]",
+ strerror_win32 (GetLastError (), &gc), GetLastError ());
+ goto out;
+ }
-bool
-win_wfp_add_filter (HANDLE engineHandle,
- const FWPM_FILTER0 *filter,
- PSECURITY_DESCRIPTOR sd,
- UINT64 *id)
-{
- if (FwpmFilterAdd0(engineHandle, filter, sd, id) != ERROR_SUCCESS)
+ if (ack.error_number != NO_ERROR)
{
- msg (M_NONFATAL, "Can't add WFP filter");
- return false;
+ msg (M_WARN, "Block_DNS: %s block dns filters using service failed: %s [status=0x%x if_index=%d]",
+ (add ? "adding" : "deleting"), strerror_win32 (ack.error_number, &gc),
+ ack.error_number, data.iface.index);
+ goto out;
}
- return true;
+
+ ret = true;
+ msg (M_INFO, "%s outside dns using service succeeded.", (add ? "Blocking" : "Unblocking"));
+out:
+ gc_free (&gc);
+ return ret;
}
-bool
-win_wfp_block_dns (const NET_IFINDEX index)
+static void
+block_dns_msg_handler (DWORD err, const char *msg)
{
- FWPM_SESSION0 session = {0};
- FWPM_SUBLAYER0 SubLayer = {0};
- NET_LUID tapluid;
- UINT64 filterid;
- WCHAR openvpnpath[MAX_PATH];
- FWP_BYTE_BLOB *openvpnblob = NULL;
- FWPM_FILTER0 Filter = {0};
- FWPM_FILTER_CONDITION0 Condition[2] = {0};
-
- /* Add temporary filters which don't survive reboots or crashes. */
- session.flags = FWPM_SESSION_FLAG_DYNAMIC;
-
- dmsg (D_LOW, "Opening WFP engine");
+ struct gc_arena gc = gc_new ();
- if (FwpmEngineOpen0(NULL, RPC_C_AUTHN_WINNT, NULL, &session, &m_hEngineHandle) != ERROR_SUCCESS)
+ if (err == 0)
{
- msg (M_NONFATAL, "Can't open WFP engine");
- return false;
+ msg (M_INFO, "%s", msg);
+ }
+ else
+ {
+ msg (M_WARN, "Error in add_block_dns_filters(): %s : %s [status=0x%lx]",
+ msg, strerror_win32 (err, &gc), err);
}
- if (UuidCreate(&SubLayer.subLayerKey) != NO_ERROR)
- return false;
+ gc_free (&gc);
+}
- /* Populate packet filter layer information. */
- SubLayer.displayData.name = FIREWALL_NAME;
- SubLayer.displayData.description = FIREWALL_NAME;
- SubLayer.flags = 0;
- SubLayer.weight = 0x100;
+bool
+win_wfp_block_dns (const NET_IFINDEX index, const HANDLE msg_channel)
+{
+ WCHAR openvpnpath[MAX_PATH];
+ bool ret = false;
+ DWORD status;
- /* Add packet filter to our interface. */
- dmsg (D_LOW, "Adding WFP sublayer");
- if (FwpmSubLayerAdd0(m_hEngineHandle, &SubLayer, NULL) != ERROR_SUCCESS)
+ if (msg_channel)
{
- msg (M_NONFATAL, "Can't add WFP sublayer");
- return false;
+ dmsg (D_LOW, "Using service to add block dns filters");
+ ret = win_block_dns_service (true, index, msg_channel);
+ goto out;
}
- dmsg (D_LOW, "Blocking DNS using WFP");
- if (ConvertInterfaceIndexToLuid(index, &tapluid) != NO_ERROR)
+ status = GetModuleFileNameW (NULL, openvpnpath, sizeof(openvpnpath));
+ if (status == 0 || status == sizeof(openvpnpath))
{
- msg (M_NONFATAL, "Can't convert interface index to LUID");
- return false;
+ msg (M_WARN|M_ERRNO, "block_dns: cannot get executable path");
+ goto out;
}
- dmsg (D_LOW, "Tap Luid: %I64d", tapluid.Value);
-
- /* Get OpenVPN path. */
- GetModuleFileNameW(NULL, openvpnpath, MAX_PATH);
-
- if (FwpmGetAppIdFromFileName0(openvpnpath, &openvpnblob) != ERROR_SUCCESS)
- return false;
-
- /* Prepare filter. */
- Filter.subLayerKey = SubLayer.subLayerKey;
- Filter.displayData.name = FIREWALL_NAME;
- Filter.weight.type = FWP_UINT8;
- Filter.weight.uint8 = 0xF;
- Filter.filterCondition = Condition;
- Filter.numFilterConditions = 2;
-
- /* First filter. Permit IPv4 DNS queries from OpenVPN itself. */
- Filter.layerKey = FWPM_LAYER_ALE_AUTH_CONNECT_V4;
- Filter.action.type = FWP_ACTION_PERMIT;
-
- Condition[0].fieldKey = FWPM_CONDITION_IP_REMOTE_PORT;
- Condition[0].matchType = FWP_MATCH_EQUAL;
- Condition[0].conditionValue.type = FWP_UINT16;
- Condition[0].conditionValue.uint16 = 53;
-
- Condition[1].fieldKey = FWPM_CONDITION_ALE_APP_ID;
- Condition[1].matchType = FWP_MATCH_EQUAL;
- Condition[1].conditionValue.type = FWP_BYTE_BLOB_TYPE;
- Condition[1].conditionValue.byteBlob = openvpnblob;
-
- /* Add filter condition to our interface. */
- if (!win_wfp_add_filter(m_hEngineHandle, &Filter, NULL, &filterid))
- goto err;
- dmsg (D_LOW, "Filter (Permit OpenVPN IPv4 DNS) added with ID=%I64d", filterid);
-
- /* Second filter. Permit IPv6 DNS queries from OpenVPN itself. */
- Filter.layerKey = FWPM_LAYER_ALE_AUTH_CONNECT_V6;
-
- /* Add filter condition to our interface. */
- if (!win_wfp_add_filter(m_hEngineHandle, &Filter, NULL, &filterid))
- goto err;
- dmsg (D_LOW, "Filter (Permit OpenVPN IPv6 DNS) added with ID=%I64d", filterid);
-
- /* Third filter. Block all IPv4 DNS queries. */
- Filter.layerKey = FWPM_LAYER_ALE_AUTH_CONNECT_V4;
- Filter.action.type = FWP_ACTION_BLOCK;
- Filter.weight.type = FWP_EMPTY;
- Filter.numFilterConditions = 1;
-
- if (!win_wfp_add_filter(m_hEngineHandle, &Filter, NULL, &filterid))
- goto err;
- dmsg (D_LOW, "Filter (Block IPv4 DNS) added with ID=%I64d", filterid);
-
- /* Forth filter. Block all IPv6 DNS queries. */
- Filter.layerKey = FWPM_LAYER_ALE_AUTH_CONNECT_V6;
-
- if (!win_wfp_add_filter(m_hEngineHandle, &Filter, NULL, &filterid))
- goto err;
- dmsg (D_LOW, "Filter (Block IPv6 DNS) added with ID=%I64d", filterid);
-
- /* Fifth filter. Permit IPv4 DNS queries from TAP. */
- Filter.layerKey = FWPM_LAYER_ALE_AUTH_CONNECT_V4;
- Filter.action.type = FWP_ACTION_PERMIT;
- Filter.numFilterConditions = 2;
-
- Condition[1].fieldKey = FWPM_CONDITION_IP_LOCAL_INTERFACE;
- Condition[1].matchType = FWP_MATCH_EQUAL;
- Condition[1].conditionValue.type = FWP_UINT64;
- Condition[1].conditionValue.uint64 = &tapluid.Value;
-
- /* Add filter condition to our interface. */
- if (!win_wfp_add_filter(m_hEngineHandle, &Filter, NULL, &filterid))
- goto err;
- dmsg (D_LOW, "Filter (Permit IPv4 DNS queries from TAP) added with ID=%I64d", filterid);
-
- /* Sixth filter. Permit IPv6 DNS queries from TAP. */
- Filter.layerKey = FWPM_LAYER_ALE_AUTH_CONNECT_V6;
-
- /* Add filter condition to our interface. */
- if (!win_wfp_add_filter(m_hEngineHandle, &Filter, NULL, &filterid))
- goto err;
- dmsg (D_LOW, "Filter (Permit IPv6 DNS queries from TAP) added with ID=%I64d", filterid);
-
- FwpmFreeMemory0((void **)&openvpnblob);
- return true;
- err:
- FwpmFreeMemory0((void **)&openvpnblob);
- return false;
+ status = add_block_dns_filters (&m_hEngineHandle, index, openvpnpath,
+ block_dns_msg_handler);
+ ret = (status == 0);
+
+out:
+
+ return ret;
}
bool
-win_wfp_uninit()
+win_wfp_uninit(const HANDLE msg_channel)
{
dmsg (D_LOW, "Uninitializing WFP");
- if (m_hEngineHandle) {
- FwpmEngineClose0(m_hEngineHandle);
+
+ if (msg_channel)
+ {
+ msg (D_LOW, "Using service to delete block dns filters");
+ win_block_dns_service (false, -1, msg_channel);
+ }
+ else
+ {
+ delete_block_dns_filters (m_hEngineHandle);
m_hEngineHandle = NULL;
- }
+ }
+
return true;
}
diff --git a/src/openvpn/win32.h b/src/openvpn/win32.h
index 0990182..11e42f4 100644
--- a/src/openvpn/win32.h
+++ b/src/openvpn/win32.h
@@ -22,7 +22,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#ifdef WIN32
+#ifdef _WIN32
#ifndef OPENVPN_WIN32_H
#define OPENVPN_WIN32_H
@@ -271,9 +271,8 @@ const char *win_get_tempdir();
/* Convert a string from UTF-8 to UCS-2 */
WCHAR *wide_string (const char* utf8, struct gc_arena *gc);
-bool win_wfp_init_funcs();
-bool win_wfp_block_dns(const NET_IFINDEX index);
-bool win_wfp_uninit();
+bool win_wfp_block_dns(const NET_IFINDEX index, const HANDLE msg_channel);
+bool win_wfp_uninit(const HANDLE msg_channel);
#define WIN_XP 0
#define WIN_VISTA 1
diff --git a/src/openvpn/win32_wfp.h b/src/openvpn/win32_wfp.h
deleted file mode 100644
index 7559e5b..0000000
--- a/src/openvpn/win32_wfp.h
+++ /dev/null
@@ -1,359 +0,0 @@
-/*
- This Software is provided under the Zope Public License (ZPL) Version 2.1.
-
- Copyright (c) 2009, 2010 by the mingw-w64 project
-
- See the AUTHORS file for the list of contributors to the mingw-w64 project.
-
- This license has been certified as open source. It has also been designated
- as GPL compatible by the Free Software Foundation (FSF).
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
-
- 1. Redistributions in source code must retain the accompanying copyright
- notice, this list of conditions, and the following disclaimer.
- 2. Redistributions in binary form must reproduce the accompanying
- copyright notice, this list of conditions, and the following disclaimer
- in the documentation and/or other materials provided with the
- distribution.
- 3. Names of the copyright holders must not be used to endorse or promote
- products derived from this software without prior written permission
- from the copyright holders.
- 4. The right to distribute this software or to use it for any purpose does
- not give you the right to use Servicemarks (sm) or Trademarks (tm) of
- the copyright holders. Use of them is covered by separate agreement
- with the copyright holders.
- 5. If any files are modified, you must cause the modified files to carry
- prominent notices stating that you changed the files and the date of
- any change.
-
- Disclaimer
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY EXPRESSED
- OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT,
- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-/*
- * Windows Filtering Platform (WFP) related prototypes, mostly stripped out of
- * mingw-w64.
- */
-
-/*
- * WFP-related defines and GUIDs.
- */
-
-#ifndef WIN32_WFP_H
-#define WIN32_WFP_H
-
-#include <initguid.h>
-#include <iphlpapi.h>
-#include <rpc.h>
-#include <rpcdce.h>
-
-#ifndef FWPM_SESSION_FLAG_DYNAMIC
-#define FWPM_SESSION_FLAG_DYNAMIC 0x00000001
-#endif
-
-// c38d57d1-05a7-4c33-904f-7fbceee60e82
-DEFINE_GUID(
- FWPM_LAYER_ALE_AUTH_CONNECT_V4,
- 0xc38d57d1,
- 0x05a7,
- 0x4c33,
- 0x90, 0x4f, 0x7f, 0xbc, 0xee, 0xe6, 0x0e, 0x82
-);
-
-// 4a72393b-319f-44bc-84c3-ba54dcb3b6b4
-DEFINE_GUID(
- FWPM_LAYER_ALE_AUTH_CONNECT_V6,
- 0x4a72393b,
- 0x319f,
- 0x44bc,
- 0x84, 0xc3, 0xba, 0x54, 0xdc, 0xb3, 0xb6, 0xb4
-);
-
-// d78e1e87-8644-4ea5-9437-d809ecefc971
-DEFINE_GUID(
- FWPM_CONDITION_ALE_APP_ID,
- 0xd78e1e87,
- 0x8644,
- 0x4ea5,
- 0x94, 0x37, 0xd8, 0x09, 0xec, 0xef, 0xc9, 0x71
-);
-
-// c35a604d-d22b-4e1a-91b4-68f674ee674b
-DEFINE_GUID(
- FWPM_CONDITION_IP_REMOTE_PORT,
- 0xc35a604d,
- 0xd22b,
- 0x4e1a,
- 0x91, 0xb4, 0x68, 0xf6, 0x74, 0xee, 0x67, 0x4b
-);
-
-// 4cd62a49-59c3-4969-b7f3-bda5d32890a4
-DEFINE_GUID(
- FWPM_CONDITION_IP_LOCAL_INTERFACE,
- 0x4cd62a49,
- 0x59c3,
- 0x4969,
- 0xb7, 0xf3, 0xbd, 0xa5, 0xd3, 0x28, 0x90, 0xa4
-);
-
-/* From fwptypes.h */
-
-#define FWP_ACTION_FLAG_TERMINATING (0x00001000)
-#define FWP_ACTION_FLAG_NON_TERMINATING (0x00002000)
-
-#define FWP_ACTION_BLOCK (0x1 | FWP_ACTION_FLAG_TERMINATING)
-#define FWP_ACTION_PERMIT (0x2 | FWP_ACTION_FLAG_TERMINATING)
-
-typedef UINT32 FWP_ACTION_TYPE;
-
-typedef enum FWP_DATA_TYPE_ {
- FWP_EMPTY = 0,
- FWP_UINT8 = 1,
- FWP_UINT16 = 2,
- FWP_UINT32 = 3,
- FWP_UINT64 = 4,
- FWP_INT8 = 5,
- FWP_INT16 = 6,
- FWP_INT32 = 7,
- FWP_INT64 = 8,
- FWP_FLOAT = 9,
- FWP_DOUBLE = 10,
- FWP_BYTE_ARRAY16_TYPE = 11,
- FWP_BYTE_BLOB_TYPE = 12,
- FWP_SID = 13,
- FWP_SECURITY_DESCRIPTOR_TYPE = 14,
- FWP_TOKEN_INFORMATION_TYPE = 15,
- FWP_TOKEN_ACCESS_INFORMATION_TYPE = 16,
- FWP_UNICODE_STRING_TYPE = 17,
- FWP_BYTE_ARRAY6_TYPE = 18,
- FWP_SINGLE_DATA_TYPE_MAX = 0xff,
- FWP_V4_ADDR_MASK = 0x100,
- FWP_V6_ADDR_MASK = 0x101,
- FWP_RANGE_TYPE = 0x102,
- FWP_DATA_TYPE_MAX = 0x103
-} FWP_DATA_TYPE;
-
-typedef enum FWP_MATCH_TYPE_ {
- FWP_MATCH_EQUAL = 0,
- FWP_MATCH_GREATER = 1,
- FWP_MATCH_LESS = 2,
- FWP_MATCH_GREATER_OR_EQUAL = 3,
- FWP_MATCH_LESS_OR_EQUAL = 4,
- FWP_MATCH_RANGE = 5,
- FWP_MATCH_FLAGS_ALL_SET = 6,
- FWP_MATCH_FLAGS_ANY_SET = 7,
- FWP_MATCH_FLAGS_NONE_SET = 8,
- FWP_MATCH_EQUAL_CASE_INSENSITIVE = 9,
- FWP_MATCH_NOT_EQUAL = 10,
- FWP_MATCH_TYPE_MAX = 11
-} FWP_MATCH_TYPE;
-
-typedef struct FWP_BYTE_ARRAY6_ {
- UINT8 byteArray6[6];
-} FWP_BYTE_ARRAY6;
-
-typedef struct FWP_BYTE_ARRAY16_ {
- UINT8 byteArray16[16];
-} FWP_BYTE_ARRAY16;
-
-typedef struct FWP_BYTE_BLOB_ {
- UINT32 size;
- UINT8 *data;
-} FWP_BYTE_BLOB;
-
-typedef struct FWP_TOKEN_INFORMATION_ {
- ULONG sidCount;
- PSID_AND_ATTRIBUTES sids;
- ULONG restrictedSidCount;
- PSID_AND_ATTRIBUTES restrictedSids;
-} FWP_TOKEN_INFORMATION;
-
-typedef struct FWP_VALUE0_ {
- FWP_DATA_TYPE type;
- union {
- UINT8 uint8;
- UINT16 uint16;
- UINT32 uint32;
- UINT64 *uint64;
- INT8 int8;
- INT16 int16;
- INT32 int32;
- INT64 *int64;
- float float32;
- double *double64;
- FWP_BYTE_ARRAY16 *byteArray16;
- FWP_BYTE_BLOB *byteBlob;
- SID *sid;
- FWP_BYTE_BLOB *sd;
- FWP_TOKEN_INFORMATION *tokenInformation;
- FWP_BYTE_BLOB *tokenAccessInformation;
- LPWSTR unicodeString;
- FWP_BYTE_ARRAY6 *byteArray6;
- };
-} FWP_VALUE0;
-
-typedef struct FWP_V4_ADDR_AND_MASK_ {
- UINT32 addr;
- UINT32 mask;
-} FWP_V4_ADDR_AND_MASK;
-
-typedef struct FWP_V6_ADDR_AND_MASK_ {
- UINT8 addr[16];
- UINT8 prefixLength;
-} FWP_V6_ADDR_AND_MASK;
-
-typedef struct FWP_RANGE0_ {
- FWP_VALUE0 valueLow;
- FWP_VALUE0 valueHigh;
-} FWP_RANGE0;
-
-typedef struct FWP_CONDITION_VALUE0_ {
- FWP_DATA_TYPE type;
- union {
- UINT8 uint8;
- UINT16 uint16;
- UINT32 uint32;
- UINT64 *uint64;
- INT8 int8;
- INT16 int16;
- INT32 int32;
- INT64 *int64;
- float float32;
- double *double64;
- FWP_BYTE_ARRAY16 *byteArray16;
- FWP_BYTE_BLOB *byteBlob;
- SID *sid;
- FWP_BYTE_BLOB *sd;
- FWP_TOKEN_INFORMATION *tokenInformation;
- FWP_BYTE_BLOB *tokenAccessInformation;
- LPWSTR unicodeString;
- FWP_BYTE_ARRAY6 *byteArray6;
- FWP_V4_ADDR_AND_MASK *v4AddrMask;
- FWP_V6_ADDR_AND_MASK *v6AddrMask;
- FWP_RANGE0 *rangeValue;
- };
-} FWP_CONDITION_VALUE0;
-
-typedef struct FWPM_DISPLAY_DATA0_ {
- wchar_t *name;
- wchar_t *description;
-} FWPM_DISPLAY_DATA0;
-
-/* From fwpmtypes.h */
-
-typedef struct FWPM_ACTION0_ {
- FWP_ACTION_TYPE type;
- union {
- GUID filterType;
- GUID calloutKey;
- };
-} FWPM_ACTION0;
-
-typedef struct FWPM_SESSION0_ {
- GUID sessionKey;
- FWPM_DISPLAY_DATA0 displayData;
- UINT32 flags;
- UINT32 txnWaitTimeoutInMSec;
- DWORD processId;
- SID *sid;
- wchar_t *username;
- BOOL kernelMode;
-} FWPM_SESSION0;
-
-typedef struct FWPM_SUBLAYER0_ {
- GUID subLayerKey;
- FWPM_DISPLAY_DATA0 displayData;
- UINT16 flags;
- GUID *providerKey;
- FWP_BYTE_BLOB providerData;
- UINT16 weight;
-} FWPM_SUBLAYER0;
-
-typedef struct FWPM_FILTER_CONDITION0_ {
- GUID fieldKey;
- FWP_MATCH_TYPE matchType;
- FWP_CONDITION_VALUE0 conditionValue;
-} FWPM_FILTER_CONDITION0;
-
-typedef struct FWPM_FILTER0_ {
- GUID filterKey;
- FWPM_DISPLAY_DATA0 displayData;
- UINT32 flags;
- GUID *providerKey;
- FWP_BYTE_BLOB providerData;
- GUID layerKey;
- GUID subLayerKey;
- FWP_VALUE0 weight;
- UINT32 numFilterConditions;
- FWPM_FILTER_CONDITION0 *filterCondition;
- FWPM_ACTION0 action;
- union {
- UINT64 rawContext;
- GUID providerContextKey;
- };
- GUID *reserved;
- UINT64 filterId;
- FWP_VALUE0 effectiveWeight;
-} FWPM_FILTER0;
-
-/* Typedefs of WFP functions */
-
-#define NETIO_STATUS DWORD
-
-typedef NETIO_STATUS *(WINAPI *func_ConvertInterfaceIndexToLuid)(
- NET_IFINDEX InterfaceIndex,
- PNET_LUID InterfaceLuid
-);
-
-typedef DWORD *(WINAPI *func_FwpmEngineOpen0)(
- const wchar_t *serverName,
- UINT32 authnService,
- SEC_WINNT_AUTH_IDENTITY_W *authIdentity,
- const FWPM_SESSION0 *session,
- HANDLE *engineHandle
-);
-
-typedef DWORD *(WINAPI *func_FwpmEngineClose0)(
- HANDLE engineHandle
-);
-
-typedef DWORD *(WINAPI *func_FwpmFilterAdd0)(
- HANDLE engineHandle,
- const FWPM_FILTER0 *filter,
- PSECURITY_DESCRIPTOR sd,
- UINT64 *id
-);
-
-typedef DWORD *(WINAPI *func_FwpmSubLayerAdd0)(
- HANDLE engineHandle,
- const FWPM_SUBLAYER0 *subLayer,
- PSECURITY_DESCRIPTOR sd
-);
-
-typedef DWORD *(WINAPI *func_FwpmSubLayerDeleteByKey0)(
- HANDLE engineHandle,
- const GUID *key
-);
-
-typedef void *(WINAPI *func_FwpmFreeMemory0)(
- void **p
-);
-
-typedef DWORD *(WINAPI *func_FwpmGetAppIdFromFileName0)(
- const wchar_t *fileName,
- FWP_BYTE_BLOB **appId
-);
-
-#endif
diff --git a/src/openvpnserv/Makefile.am b/src/openvpnserv/Makefile.am
index a989c25..3521a34 100644
--- a/src/openvpnserv/Makefile.am
+++ b/src/openvpnserv/Makefile.am
@@ -17,11 +17,23 @@ EXTRA_DIST = \
openvpnserv.vcxproj \
openvpnserv.vcxproj.filters
+AM_CPPFLAGS = \
+ -I$(top_srcdir)/include -I$(top_srcdir)/src/openvpn -I$(top_srcdir)/src/compat
+
if WIN32
sbin_PROGRAMS = openvpnserv
+openvpnserv_CFLAGS = \
+ -municode -D_UNICODE \
+ -UNTDDI_VERSION -U_WIN32_WINNT \
+ -D_WIN32_WINNT=_WIN32_WINNT_VISTA
+openvpnserv_LDADD = -ladvapi32 -luserenv -liphlpapi -lfwpuclnt -lrpcrt4 -lshlwapi -lnetapi32 -lws2_32
endif
openvpnserv_SOURCES = \
- openvpnserv.c \
- service.h service.c \
+ common.c \
+ automatic.c \
+ interactive.c \
+ service.c service.h \
+ validate.c validate.h \
+ $(top_srcdir)/src/openvpn/block_dns.c $(top_srcdir)/src/openvpn/block_dns.h \
openvpnserv_resources.rc
diff --git a/src/openvpnserv/Makefile.in b/src/openvpnserv/Makefile.in
index ed1ee90..74a802b 100644
--- a/src/openvpnserv/Makefile.in
+++ b/src/openvpnserv/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.15 from Makefile.am.
+# Makefile.in generated by automake 1.13.4 from Makefile.am.
# @configure_input@
-# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -37,17 +37,7 @@
# Required to build Windows resource file
VPATH = @srcdir@
-am__is_gnu_make = { \
- if test -z '$(MAKELEVEL)'; then \
- false; \
- elif test -n '$(MAKE_HOST)'; then \
- true; \
- elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
- true; \
- else \
- false; \
- fi; \
-}
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
am__make_running_with_option = \
case $${target_option-} in \
?) ;; \
@@ -110,6 +100,8 @@ PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
+DIST_COMMON = $(top_srcdir)/build/ltrc.inc $(srcdir)/Makefile.in \
+ $(srcdir)/Makefile.am $(top_srcdir)/depcomp
@WIN32_TRUE@sbin_PROGRAMS = openvpnserv$(EXEEXT)
subdir = src/openvpnserv
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
@@ -122,21 +114,28 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_emptyarray.m4 \
$(top_srcdir)/compat.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
-DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
mkinstalldirs = $(install_sh) -d
-CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_HEADER = $(top_builddir)/config.h \
+ $(top_builddir)/include/openvpn-plugin.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
am__installdirs = "$(DESTDIR)$(sbindir)"
PROGRAMS = $(sbin_PROGRAMS)
-am_openvpnserv_OBJECTS = openvpnserv.$(OBJEXT) service.$(OBJEXT) \
+am_openvpnserv_OBJECTS = openvpnserv-common.$(OBJEXT) \
+ openvpnserv-automatic.$(OBJEXT) \
+ openvpnserv-interactive.$(OBJEXT) \
+ openvpnserv-service.$(OBJEXT) openvpnserv-validate.$(OBJEXT) \
+ openvpnserv-block_dns.$(OBJEXT) \
openvpnserv_resources.$(OBJEXT)
openvpnserv_OBJECTS = $(am_openvpnserv_OBJECTS)
-openvpnserv_LDADD = $(LDADD)
+openvpnserv_DEPENDENCIES =
AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
am__v_lt_0 = --silent
am__v_lt_1 =
+openvpnserv_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(openvpnserv_CFLAGS) \
+ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
am__v_P_0 = false
@@ -149,7 +148,7 @@ AM_V_at = $(am__v_at_@AM_V@)
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
am__v_at_0 = @
am__v_at_1 =
-DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) -I$(top_builddir)/include
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
am__mv = mv -f
@@ -197,8 +196,6 @@ am__define_uniq_tagged_files = \
done | $(am__uniquify_input)`
ETAGS = etags
CTAGS = ctags
-am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/build/ltrc.inc \
- $(top_srcdir)/depcomp
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
@@ -212,6 +209,7 @@ AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
+CMAKE = @CMAKE@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
@@ -246,25 +244,31 @@ LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
-LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+LZ4_CFLAGS = @LZ4_CFLAGS@
+LZ4_LIBS = @LZ4_LIBS@
LZO_CFLAGS = @LZO_CFLAGS@
LZO_LIBS = @LZO_LIBS@
MAKEINFO = @MAKEINFO@
MAN2HTML = @MAN2HTML@
MANIFEST_TOOL = @MANIFEST_TOOL@
+MBEDTLS_CFLAGS = @MBEDTLS_CFLAGS@
+MBEDTLS_LIBS = @MBEDTLS_LIBS@
MKDIR_P = @MKDIR_P@
NETSTAT = @NETSTAT@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
-OPENSSL_CRYPTO_CFLAGS = @OPENSSL_CRYPTO_CFLAGS@
-OPENSSL_CRYPTO_LIBS = @OPENSSL_CRYPTO_LIBS@
-OPENSSL_SSL_CFLAGS = @OPENSSL_SSL_CFLAGS@
-OPENSSL_SSL_LIBS = @OPENSSL_SSL_LIBS@
+OPENSSL_CFLAGS = @OPENSSL_CFLAGS@
+OPENSSL_LIBS = @OPENSSL_LIBS@
+OPENVPN_VERSION_MAJOR = @OPENVPN_VERSION_MAJOR@
+OPENVPN_VERSION_MINOR = @OPENVPN_VERSION_MINOR@
+OPENVPN_VERSION_PATCH = @OPENVPN_VERSION_PATCH@
OPTIONAL_CRYPTO_CFLAGS = @OPTIONAL_CRYPTO_CFLAGS@
OPTIONAL_CRYPTO_LIBS = @OPTIONAL_CRYPTO_LIBS@
OPTIONAL_DL_LIBS = @OPTIONAL_DL_LIBS@
+OPTIONAL_LZ4_CFLAGS = @OPTIONAL_LZ4_CFLAGS@
+OPTIONAL_LZ4_LIBS = @OPTIONAL_LZ4_LIBS@
OPTIONAL_LZO_CFLAGS = @OPTIONAL_LZO_CFLAGS@
OPTIONAL_LZO_LIBS = @OPTIONAL_LZO_LIBS@
OPTIONAL_PKCS11_HELPER_CFLAGS = @OPTIONAL_PKCS11_HELPER_CFLAGS@
@@ -290,8 +294,6 @@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
PLUGIN_AUTH_PAM_CFLAGS = @PLUGIN_AUTH_PAM_CFLAGS@
PLUGIN_AUTH_PAM_LIBS = @PLUGIN_AUTH_PAM_LIBS@
-POLARSSL_CFLAGS = @POLARSSL_CFLAGS@
-POLARSSL_LIBS = @POLARSSL_LIBS@
RANLIB = @RANLIB@
RC = @RC@
ROUTE = @ROUTE@
@@ -306,6 +308,11 @@ TAP_CFLAGS = @TAP_CFLAGS@
TAP_WIN_COMPONENT_ID = @TAP_WIN_COMPONENT_ID@
TAP_WIN_MIN_MAJOR = @TAP_WIN_MIN_MAJOR@
TAP_WIN_MIN_MINOR = @TAP_WIN_MIN_MINOR@
+TEST_CFLAGS = @TEST_CFLAGS@
+TEST_LDFLAGS = @TEST_LDFLAGS@
+VENDOR_BUILD_ROOT = @VENDOR_BUILD_ROOT@
+VENDOR_DIST_ROOT = @VENDOR_DIST_ROOT@
+VENDOR_SRC_ROOT = @VENDOR_SRC_ROOT@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
@@ -372,9 +379,22 @@ EXTRA_DIST = \
openvpnserv.vcxproj \
openvpnserv.vcxproj.filters
+AM_CPPFLAGS = \
+ -I$(top_srcdir)/include -I$(top_srcdir)/src/openvpn -I$(top_srcdir)/src/compat
+
+@WIN32_TRUE@openvpnserv_CFLAGS = \
+@WIN32_TRUE@ -municode -D_UNICODE \
+@WIN32_TRUE@ -UNTDDI_VERSION -U_WIN32_WINNT \
+@WIN32_TRUE@ -D_WIN32_WINNT=_WIN32_WINNT_VISTA
+
+@WIN32_TRUE@openvpnserv_LDADD = -ladvapi32 -luserenv -liphlpapi -lfwpuclnt -lrpcrt4 -lshlwapi -lnetapi32 -lws2_32
openvpnserv_SOURCES = \
- openvpnserv.c \
- service.h service.c \
+ common.c \
+ automatic.c \
+ interactive.c \
+ service.c service.h \
+ validate.c validate.h \
+ $(top_srcdir)/src/openvpn/block_dns.c $(top_srcdir)/src/openvpn/block_dns.h \
openvpnserv_resources.rc
all: all-am
@@ -393,6 +413,7 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(top_srcdir)/build/ltrc.inc $(am_
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/openvpnserv/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign src/openvpnserv/Makefile
+.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
@@ -401,7 +422,7 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
-$(top_srcdir)/build/ltrc.inc $(am__empty):
+$(top_srcdir)/build/ltrc.inc:
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
@@ -463,7 +484,7 @@ clean-sbinPROGRAMS:
openvpnserv$(EXEEXT): $(openvpnserv_OBJECTS) $(openvpnserv_DEPENDENCIES) $(EXTRA_openvpnserv_DEPENDENCIES)
@rm -f openvpnserv$(EXEEXT)
- $(AM_V_CCLD)$(LINK) $(openvpnserv_OBJECTS) $(openvpnserv_LDADD) $(LIBS)
+ $(AM_V_CCLD)$(openvpnserv_LINK) $(openvpnserv_OBJECTS) $(openvpnserv_LDADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
@@ -471,22 +492,26 @@ mostlyclean-compile:
distclean-compile:
-rm -f *.tab.c
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openvpnserv.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/service.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openvpnserv-automatic.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openvpnserv-block_dns.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openvpnserv-common.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openvpnserv-interactive.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openvpnserv-service.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openvpnserv-validate.Po@am__quote@
.c.o:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $<
.c.obj:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'`
.c.lo:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@@ -495,6 +520,90 @@ distclean-compile:
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+openvpnserv-common.o: common.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(openvpnserv_CFLAGS) $(CFLAGS) -MT openvpnserv-common.o -MD -MP -MF $(DEPDIR)/openvpnserv-common.Tpo -c -o openvpnserv-common.o `test -f 'common.c' || echo '$(srcdir)/'`common.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/openvpnserv-common.Tpo $(DEPDIR)/openvpnserv-common.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='common.c' object='openvpnserv-common.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(openvpnserv_CFLAGS) $(CFLAGS) -c -o openvpnserv-common.o `test -f 'common.c' || echo '$(srcdir)/'`common.c
+
+openvpnserv-common.obj: common.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(openvpnserv_CFLAGS) $(CFLAGS) -MT openvpnserv-common.obj -MD -MP -MF $(DEPDIR)/openvpnserv-common.Tpo -c -o openvpnserv-common.obj `if test -f 'common.c'; then $(CYGPATH_W) 'common.c'; else $(CYGPATH_W) '$(srcdir)/common.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/openvpnserv-common.Tpo $(DEPDIR)/openvpnserv-common.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='common.c' object='openvpnserv-common.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(openvpnserv_CFLAGS) $(CFLAGS) -c -o openvpnserv-common.obj `if test -f 'common.c'; then $(CYGPATH_W) 'common.c'; else $(CYGPATH_W) '$(srcdir)/common.c'; fi`
+
+openvpnserv-automatic.o: automatic.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(openvpnserv_CFLAGS) $(CFLAGS) -MT openvpnserv-automatic.o -MD -MP -MF $(DEPDIR)/openvpnserv-automatic.Tpo -c -o openvpnserv-automatic.o `test -f 'automatic.c' || echo '$(srcdir)/'`automatic.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/openvpnserv-automatic.Tpo $(DEPDIR)/openvpnserv-automatic.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='automatic.c' object='openvpnserv-automatic.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(openvpnserv_CFLAGS) $(CFLAGS) -c -o openvpnserv-automatic.o `test -f 'automatic.c' || echo '$(srcdir)/'`automatic.c
+
+openvpnserv-automatic.obj: automatic.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(openvpnserv_CFLAGS) $(CFLAGS) -MT openvpnserv-automatic.obj -MD -MP -MF $(DEPDIR)/openvpnserv-automatic.Tpo -c -o openvpnserv-automatic.obj `if test -f 'automatic.c'; then $(CYGPATH_W) 'automatic.c'; else $(CYGPATH_W) '$(srcdir)/automatic.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/openvpnserv-automatic.Tpo $(DEPDIR)/openvpnserv-automatic.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='automatic.c' object='openvpnserv-automatic.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(openvpnserv_CFLAGS) $(CFLAGS) -c -o openvpnserv-automatic.obj `if test -f 'automatic.c'; then $(CYGPATH_W) 'automatic.c'; else $(CYGPATH_W) '$(srcdir)/automatic.c'; fi`
+
+openvpnserv-interactive.o: interactive.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(openvpnserv_CFLAGS) $(CFLAGS) -MT openvpnserv-interactive.o -MD -MP -MF $(DEPDIR)/openvpnserv-interactive.Tpo -c -o openvpnserv-interactive.o `test -f 'interactive.c' || echo '$(srcdir)/'`interactive.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/openvpnserv-interactive.Tpo $(DEPDIR)/openvpnserv-interactive.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='interactive.c' object='openvpnserv-interactive.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(openvpnserv_CFLAGS) $(CFLAGS) -c -o openvpnserv-interactive.o `test -f 'interactive.c' || echo '$(srcdir)/'`interactive.c
+
+openvpnserv-interactive.obj: interactive.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(openvpnserv_CFLAGS) $(CFLAGS) -MT openvpnserv-interactive.obj -MD -MP -MF $(DEPDIR)/openvpnserv-interactive.Tpo -c -o openvpnserv-interactive.obj `if test -f 'interactive.c'; then $(CYGPATH_W) 'interactive.c'; else $(CYGPATH_W) '$(srcdir)/interactive.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/openvpnserv-interactive.Tpo $(DEPDIR)/openvpnserv-interactive.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='interactive.c' object='openvpnserv-interactive.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(openvpnserv_CFLAGS) $(CFLAGS) -c -o openvpnserv-interactive.obj `if test -f 'interactive.c'; then $(CYGPATH_W) 'interactive.c'; else $(CYGPATH_W) '$(srcdir)/interactive.c'; fi`
+
+openvpnserv-service.o: service.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(openvpnserv_CFLAGS) $(CFLAGS) -MT openvpnserv-service.o -MD -MP -MF $(DEPDIR)/openvpnserv-service.Tpo -c -o openvpnserv-service.o `test -f 'service.c' || echo '$(srcdir)/'`service.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/openvpnserv-service.Tpo $(DEPDIR)/openvpnserv-service.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='service.c' object='openvpnserv-service.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(openvpnserv_CFLAGS) $(CFLAGS) -c -o openvpnserv-service.o `test -f 'service.c' || echo '$(srcdir)/'`service.c
+
+openvpnserv-service.obj: service.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(openvpnserv_CFLAGS) $(CFLAGS) -MT openvpnserv-service.obj -MD -MP -MF $(DEPDIR)/openvpnserv-service.Tpo -c -o openvpnserv-service.obj `if test -f 'service.c'; then $(CYGPATH_W) 'service.c'; else $(CYGPATH_W) '$(srcdir)/service.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/openvpnserv-service.Tpo $(DEPDIR)/openvpnserv-service.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='service.c' object='openvpnserv-service.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(openvpnserv_CFLAGS) $(CFLAGS) -c -o openvpnserv-service.obj `if test -f 'service.c'; then $(CYGPATH_W) 'service.c'; else $(CYGPATH_W) '$(srcdir)/service.c'; fi`
+
+openvpnserv-validate.o: validate.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(openvpnserv_CFLAGS) $(CFLAGS) -MT openvpnserv-validate.o -MD -MP -MF $(DEPDIR)/openvpnserv-validate.Tpo -c -o openvpnserv-validate.o `test -f 'validate.c' || echo '$(srcdir)/'`validate.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/openvpnserv-validate.Tpo $(DEPDIR)/openvpnserv-validate.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='validate.c' object='openvpnserv-validate.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(openvpnserv_CFLAGS) $(CFLAGS) -c -o openvpnserv-validate.o `test -f 'validate.c' || echo '$(srcdir)/'`validate.c
+
+openvpnserv-validate.obj: validate.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(openvpnserv_CFLAGS) $(CFLAGS) -MT openvpnserv-validate.obj -MD -MP -MF $(DEPDIR)/openvpnserv-validate.Tpo -c -o openvpnserv-validate.obj `if test -f 'validate.c'; then $(CYGPATH_W) 'validate.c'; else $(CYGPATH_W) '$(srcdir)/validate.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/openvpnserv-validate.Tpo $(DEPDIR)/openvpnserv-validate.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='validate.c' object='openvpnserv-validate.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(openvpnserv_CFLAGS) $(CFLAGS) -c -o openvpnserv-validate.obj `if test -f 'validate.c'; then $(CYGPATH_W) 'validate.c'; else $(CYGPATH_W) '$(srcdir)/validate.c'; fi`
+
+openvpnserv-block_dns.o: $(top_srcdir)/src/openvpn/block_dns.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(openvpnserv_CFLAGS) $(CFLAGS) -MT openvpnserv-block_dns.o -MD -MP -MF $(DEPDIR)/openvpnserv-block_dns.Tpo -c -o openvpnserv-block_dns.o `test -f '$(top_srcdir)/src/openvpn/block_dns.c' || echo '$(srcdir)/'`$(top_srcdir)/src/openvpn/block_dns.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/openvpnserv-block_dns.Tpo $(DEPDIR)/openvpnserv-block_dns.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(top_srcdir)/src/openvpn/block_dns.c' object='openvpnserv-block_dns.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(openvpnserv_CFLAGS) $(CFLAGS) -c -o openvpnserv-block_dns.o `test -f '$(top_srcdir)/src/openvpn/block_dns.c' || echo '$(srcdir)/'`$(top_srcdir)/src/openvpn/block_dns.c
+
+openvpnserv-block_dns.obj: $(top_srcdir)/src/openvpn/block_dns.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(openvpnserv_CFLAGS) $(CFLAGS) -MT openvpnserv-block_dns.obj -MD -MP -MF $(DEPDIR)/openvpnserv-block_dns.Tpo -c -o openvpnserv-block_dns.obj `if test -f '$(top_srcdir)/src/openvpn/block_dns.c'; then $(CYGPATH_W) '$(top_srcdir)/src/openvpn/block_dns.c'; else $(CYGPATH_W) '$(srcdir)/$(top_srcdir)/src/openvpn/block_dns.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/openvpnserv-block_dns.Tpo $(DEPDIR)/openvpnserv-block_dns.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(top_srcdir)/src/openvpn/block_dns.c' object='openvpnserv-block_dns.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(openvpnserv_CFLAGS) $(CFLAGS) -c -o openvpnserv-block_dns.obj `if test -f '$(top_srcdir)/src/openvpn/block_dns.c'; then $(CYGPATH_W) '$(top_srcdir)/src/openvpn/block_dns.c'; else $(CYGPATH_W) '$(srcdir)/$(top_srcdir)/src/openvpn/block_dns.c'; fi`
+
mostlyclean-libtool:
-rm -f *.lo
@@ -708,8 +817,6 @@ uninstall-am: uninstall-sbinPROGRAMS
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
tags tags-am uninstall uninstall-am uninstall-sbinPROGRAMS
-.PRECIOUS: Makefile
-
.rc.lo:
$(LTRCCOMPILE) -i "$<" -o "$@"
diff --git a/src/openvpnserv/automatic.c b/src/openvpnserv/automatic.c
new file mode 100644
index 0000000..aa7618f
--- /dev/null
+++ b/src/openvpnserv/automatic.c
@@ -0,0 +1,415 @@
+/*
+ * OpenVPN -- An application to securely tunnel IP networks
+ * over a single TCP/UDP port, with support for SSL/TLS-based
+ * session authentication and key exchange,
+ * packet encryption, packet authentication, and
+ * packet compression.
+ *
+ * Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program (see the file COPYING included with this
+ * distribution); if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * This program allows one or more OpenVPN processes to be started
+ * as a service. To build, you must get the service sample from the
+ * Platform SDK and replace Simple.c with this file.
+ *
+ * You should also apply service.patch to
+ * service.c and service.h from the Platform SDK service sample.
+ *
+ * This code is designed to be built with the mingw compiler.
+ */
+
+#include "service.h"
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <process.h>
+
+/* bool definitions */
+#define bool int
+#define true 1
+#define false 0
+
+static SERVICE_STATUS_HANDLE service;
+static SERVICE_STATUS status;
+
+openvpn_service_t automatic_service = {
+ automatic,
+ TEXT(PACKAGE_NAME "ServiceLegacy"),
+ TEXT(PACKAGE_NAME " Legacy Service"),
+ TEXT(SERVICE_DEPENDENCIES),
+ SERVICE_DEMAND_START
+};
+
+struct security_attributes
+{
+ SECURITY_ATTRIBUTES sa;
+ SECURITY_DESCRIPTOR sd;
+};
+
+/*
+ * Which registry key in HKLM should
+ * we get config info from?
+ */
+#define REG_KEY "SOFTWARE\\" PACKAGE_NAME
+
+static HANDLE exit_event = NULL;
+
+/* clear an object */
+#define CLEAR(x) memset(&(x), 0, sizeof(x))
+
+
+bool
+init_security_attributes_allow_all (struct security_attributes *obj)
+{
+ CLEAR (*obj);
+
+ obj->sa.nLength = sizeof (SECURITY_ATTRIBUTES);
+ obj->sa.lpSecurityDescriptor = &obj->sd;
+ obj->sa.bInheritHandle = TRUE;
+ if (!InitializeSecurityDescriptor (&obj->sd, SECURITY_DESCRIPTOR_REVISION))
+ return false;
+ if (!SetSecurityDescriptorDacl (&obj->sd, TRUE, NULL, FALSE))
+ return false;
+ return true;
+}
+
+/*
+ * This event is initially created in the non-signaled
+ * state. It will transition to the signaled state when
+ * we have received a terminate signal from the Service
+ * Control Manager which will cause an asynchronous call
+ * of ServiceStop below.
+ */
+#define EXIT_EVENT_NAME TEXT(PACKAGE "_exit_1")
+
+HANDLE
+create_event (LPCTSTR name, bool allow_all, bool initial_state, bool manual_reset)
+{
+ if (allow_all)
+ {
+ struct security_attributes sa;
+ if (!init_security_attributes_allow_all (&sa))
+ return NULL;
+ return CreateEvent (&sa.sa, (BOOL)manual_reset, (BOOL)initial_state, name);
+ }
+ else
+ return CreateEvent (NULL, (BOOL)manual_reset, (BOOL)initial_state, name);
+}
+
+void
+close_if_open (HANDLE h)
+{
+ if (h != NULL)
+ CloseHandle (h);
+}
+
+static bool
+match (const WIN32_FIND_DATA *find, LPCTSTR ext)
+{
+ int i;
+
+ if (find->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+ return false;
+
+ if (!_tcslen (ext))
+ return true;
+
+ i = _tcslen (find->cFileName) - _tcslen (ext) - 1;
+ if (i < 1)
+ return false;
+
+ return find->cFileName[i] == '.' && !_tcsicmp (find->cFileName + i + 1, ext);
+}
+
+/*
+ * Modify the extension on a filename.
+ */
+static bool
+modext (LPTSTR dest, int size, LPCTSTR src, LPCTSTR newext)
+{
+ int i;
+
+ if (size > 0 && (_tcslen (src) + 1) <= size)
+ {
+ _tcscpy (dest, src);
+ dest [size - 1] = TEXT('\0');
+ i = _tcslen (dest);
+ while (--i >= 0)
+ {
+ if (dest[i] == TEXT('\\'))
+ break;
+ if (dest[i] == TEXT('.'))
+ {
+ dest[i] = TEXT('\0');
+ break;
+ }
+ }
+ if (_tcslen (dest) + _tcslen(newext) + 2 <= size)
+ {
+ _tcscat (dest, TEXT("."));
+ _tcscat (dest, newext);
+ return true;
+ }
+ dest[0] = TEXT('\0');
+ }
+ return false;
+}
+
+static DWORD WINAPI
+ServiceCtrlAutomatic (DWORD ctrl_code, DWORD event, LPVOID data, LPVOID ctx)
+{
+ SERVICE_STATUS *status = ctx;
+ switch (ctrl_code)
+ {
+ case SERVICE_CONTROL_STOP:
+ status->dwCurrentState = SERVICE_STOP_PENDING;
+ ReportStatusToSCMgr (service, status);
+ if (exit_event)
+ SetEvent (exit_event);
+ return NO_ERROR;
+
+ case SERVICE_CONTROL_INTERROGATE:
+ return NO_ERROR;
+
+ default:
+ return ERROR_CALL_NOT_IMPLEMENTED;
+ }
+}
+
+
+VOID WINAPI
+ServiceStartAutomatic (DWORD dwArgc, LPTSTR *lpszArgv)
+{
+ DWORD error = NO_ERROR;
+ settings_t settings;
+
+ service = RegisterServiceCtrlHandlerEx (automatic_service.name, ServiceCtrlAutomatic, &status);
+ if (!service)
+ return;
+
+ status.dwServiceType = SERVICE_WIN32_SHARE_PROCESS;
+ status.dwCurrentState = SERVICE_START_PENDING;
+ status.dwServiceSpecificExitCode = NO_ERROR;
+ status.dwWin32ExitCode = NO_ERROR;
+ status.dwWaitHint = 3000;
+
+ if (!ReportStatusToSCMgr(service, &status))
+ {
+ MsgToEventLog (M_ERR, TEXT("ReportStatusToSCMgr #1 failed"));
+ goto finish;
+ }
+
+ /*
+ * Create our exit event
+ */
+ exit_event = create_event (EXIT_EVENT_NAME, false, false, true);
+ if (!exit_event)
+ {
+ MsgToEventLog (M_ERR, TEXT("CreateEvent failed"));
+ goto finish;
+ }
+
+ /*
+ * If exit event is already signaled, it means we were not
+ * shut down properly.
+ */
+ if (WaitForSingleObject (exit_event, 0) != WAIT_TIMEOUT)
+ {
+ MsgToEventLog (M_ERR, TEXT("Exit event is already signaled -- we were not shut down properly"));
+ goto finish;
+ }
+
+ if (!ReportStatusToSCMgr(service, &status))
+ {
+ MsgToEventLog (M_ERR, TEXT("ReportStatusToSCMgr #2 failed"));
+ goto finish;
+ }
+
+ /*
+ * Read info from registry in key HKLM\SOFTWARE\OpenVPN
+ */
+ error = GetOpenvpnSettings (&settings);
+ if (error != ERROR_SUCCESS)
+ goto finish;
+
+ /*
+ * Instantiate an OpenVPN process for each configuration
+ * file found.
+ */
+ {
+ WIN32_FIND_DATA find_obj;
+ HANDLE find_handle;
+ BOOL more_files;
+ TCHAR find_string[MAX_PATH];
+
+ openvpn_sntprintf (find_string, MAX_PATH, TEXT("%s\\*"), settings.config_dir);
+
+ find_handle = FindFirstFile (find_string, &find_obj);
+ if (find_handle == INVALID_HANDLE_VALUE)
+ {
+ MsgToEventLog (M_ERR, TEXT("Cannot get configuration file list using: %s"), find_string);
+ goto finish;
+ }
+
+ /*
+ * Loop over each config file
+ */
+ do {
+ HANDLE log_handle = NULL;
+ STARTUPINFO start_info;
+ PROCESS_INFORMATION proc_info;
+ struct security_attributes sa;
+ TCHAR log_file[MAX_PATH];
+ TCHAR log_path[MAX_PATH];
+ TCHAR command_line[256];
+
+ CLEAR (start_info);
+ CLEAR (proc_info);
+ CLEAR (sa);
+
+ if (!ReportStatusToSCMgr(service, &status))
+ {
+ MsgToEventLog (M_ERR, TEXT("ReportStatusToSCMgr #3 failed"));
+ FindClose (find_handle);
+ goto finish;
+ }
+
+ /* does file have the correct type and extension? */
+ if (match (&find_obj, settings.ext_string))
+ {
+ /* get log file pathname */
+ if (!modext (log_file, _countof (log_file), find_obj.cFileName, TEXT("log")))
+ {
+ MsgToEventLog (M_ERR, TEXT("Cannot construct logfile name based on: %s"), find_obj.cFileName);
+ FindClose (find_handle);
+ goto finish;
+ }
+ openvpn_sntprintf (log_path, _countof (log_path),
+ TEXT("%s\\%s"), settings.log_dir, log_file);
+
+ /* construct command line */
+ openvpn_sntprintf (command_line, _countof (command_line), TEXT(PACKAGE " --service %s 1 --config \"%s\""),
+ EXIT_EVENT_NAME,
+ find_obj.cFileName);
+
+ /* Make security attributes struct for logfile handle so it can
+ be inherited. */
+ if (!init_security_attributes_allow_all (&sa))
+ {
+ error = MsgToEventLog (M_SYSERR, TEXT("InitializeSecurityDescriptor start_" PACKAGE " failed"));
+ goto finish;
+ }
+
+ /* open logfile as stdout/stderr for soon-to-be-spawned subprocess */
+ log_handle = CreateFile (log_path,
+ GENERIC_WRITE,
+ FILE_SHARE_READ,
+ &sa.sa,
+ settings.append ? OPEN_ALWAYS : CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+
+ if (log_handle == INVALID_HANDLE_VALUE)
+ {
+ error = MsgToEventLog (M_SYSERR, TEXT("Cannot open logfile: %s"), log_path);
+ FindClose (find_handle);
+ goto finish;
+ }
+
+ /* append to logfile? */
+ if (settings.append)
+ {
+ if (SetFilePointer (log_handle, 0, NULL, FILE_END) == INVALID_SET_FILE_POINTER)
+ {
+ error = MsgToEventLog (M_SYSERR, TEXT("Cannot seek to end of logfile: %s"), log_path);
+ FindClose (find_handle);
+ goto finish;
+ }
+ }
+
+ /* fill in STARTUPINFO struct */
+ GetStartupInfo(&start_info);
+ start_info.cb = sizeof(start_info);
+ start_info.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
+ start_info.wShowWindow = SW_HIDE;
+ start_info.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
+ start_info.hStdOutput = start_info.hStdError = log_handle;
+
+ /* create an OpenVPN process for one config file */
+ if (!CreateProcess(settings.exe_path,
+ command_line,
+ NULL,
+ NULL,
+ TRUE,
+ settings.priority | CREATE_NEW_CONSOLE,
+ NULL,
+ settings.config_dir,
+ &start_info,
+ &proc_info))
+ {
+ error = MsgToEventLog (M_SYSERR, TEXT("CreateProcess failed, exe='%s' cmdline='%s' dir='%s'"),
+ settings.exe_path,
+ command_line,
+ settings.config_dir);
+
+ FindClose (find_handle);
+ CloseHandle (log_handle);
+ goto finish;
+ }
+
+ /* close unneeded handles */
+ Sleep (1000); /* try to prevent race if we close logfile
+ handle before child process DUPs it */
+ if (!CloseHandle (proc_info.hProcess)
+ || !CloseHandle (proc_info.hThread)
+ || !CloseHandle (log_handle))
+ {
+ error = MsgToEventLog (M_SYSERR, TEXT("CloseHandle failed"));
+ goto finish;
+ }
+ }
+
+ /* more files to process? */
+ more_files = FindNextFile (find_handle, &find_obj);
+
+ } while (more_files);
+
+ FindClose (find_handle);
+ }
+
+ /* we are now fully started */
+ status.dwCurrentState = SERVICE_RUNNING;
+ status.dwWaitHint = 0;
+ if (!ReportStatusToSCMgr(service, &status))
+ {
+ MsgToEventLog (M_ERR, TEXT("ReportStatusToSCMgr SERVICE_RUNNING failed"));
+ goto finish;
+ }
+
+ /* wait for our shutdown signal */
+ if (WaitForSingleObject (exit_event, INFINITE) != WAIT_OBJECT_0)
+ MsgToEventLog (M_ERR, TEXT("wait for shutdown signal failed"));
+
+finish:
+ if (exit_event)
+ CloseHandle (exit_event);
+
+ status.dwCurrentState = SERVICE_STOPPED;
+ status.dwWin32ExitCode = error;
+ ReportStatusToSCMgr (service, &status);
+}
diff --git a/src/openvpnserv/common.c b/src/openvpnserv/common.c
new file mode 100644
index 0000000..dba4724
--- /dev/null
+++ b/src/openvpnserv/common.c
@@ -0,0 +1,218 @@
+/*
+ * OpenVPN -- An application to securely tunnel IP networks
+ * over a single TCP/UDP port, with support for SSL/TLS-based
+ * session authentication and key exchange,
+ * packet encryption, packet authentication, and
+ * packet compression.
+ *
+ * Copyright (C) 2011 Heiko Hund <heiko.hund@sophos.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program (see the file COPYING included with this
+ * distribution); if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <service.h>
+#include <validate.h>
+/*
+ * These are necessary due to certain buggy implementations of (v)snprintf,
+ * that don't guarantee null termination for size > 0.
+ */
+int
+openvpn_vsntprintf (LPTSTR str, size_t size, LPCTSTR format, va_list arglist)
+{
+ int len = -1;
+ if (size > 0)
+ {
+ len = _vsntprintf (str, size, format, arglist);
+ str[size - 1] = 0;
+ }
+ return (len >= 0 && len < size);
+}
+int
+openvpn_sntprintf (LPTSTR str, size_t size, LPCTSTR format, ...)
+{
+ va_list arglist;
+ int len = -1;
+ if (size > 0)
+ {
+ va_start (arglist, format);
+ len = openvpn_vsntprintf (str, size, format, arglist);
+ va_end (arglist);
+ }
+ return len;
+}
+
+#define REG_KEY TEXT("SOFTWARE\\" PACKAGE_NAME)
+
+static DWORD
+GetRegString (HKEY key, LPCTSTR value, LPTSTR data, DWORD size)
+{
+ DWORD type;
+ LONG status = RegQueryValueEx (key, value, NULL, &type, (LPBYTE) data, &size);
+
+ if (status == ERROR_SUCCESS && type != REG_SZ)
+ status = ERROR_DATATYPE_MISMATCH;
+
+ if (status != ERROR_SUCCESS)
+ {
+ SetLastError (status);
+ return MsgToEventLog (M_SYSERR, TEXT("Error querying registry value: HKLM\\%s\\%s"), REG_KEY, value);
+ }
+
+ return ERROR_SUCCESS;
+}
+
+
+DWORD
+GetOpenvpnSettings (settings_t *s)
+{
+ TCHAR priority[64];
+ TCHAR append[2];
+ DWORD error;
+ HKEY key;
+
+ LONG status = RegOpenKeyEx (HKEY_LOCAL_MACHINE, REG_KEY, 0, KEY_READ, &key);
+ if (status != ERROR_SUCCESS)
+ {
+ SetLastError (status);
+ return MsgToEventLog (M_SYSERR, TEXT("Could not open Registry key HKLM\\%s not found"), REG_KEY);
+ }
+
+ error = GetRegString (key, TEXT("exe_path"), s->exe_path, sizeof (s->exe_path));
+ if (error != ERROR_SUCCESS)
+ goto out;
+
+ error = GetRegString (key, TEXT("config_dir"), s->config_dir, sizeof (s->config_dir));
+ if (error != ERROR_SUCCESS)
+ goto out;
+
+ error = GetRegString (key, TEXT("config_ext"), s->ext_string, sizeof (s->ext_string));
+ if (error != ERROR_SUCCESS)
+ goto out;
+
+ error = GetRegString (key, TEXT("log_dir"), s->log_dir, sizeof (s->log_dir));
+ if (error != ERROR_SUCCESS)
+ goto out;
+
+ error = GetRegString (key, TEXT("priority"), priority, sizeof (priority));
+ if (error != ERROR_SUCCESS)
+ goto out;
+
+ error = GetRegString (key, TEXT("log_append"), append, sizeof (append));
+ if (error != ERROR_SUCCESS)
+ goto out;
+
+ /* read if present, else use default */
+ error = GetRegString (key, TEXT("ovpn_admin_group"), s->ovpn_admin_group, sizeof (s->ovpn_admin_group));
+ if (error != ERROR_SUCCESS)
+ {
+ openvpn_sntprintf(s->ovpn_admin_group, _countof(s->ovpn_admin_group), OVPN_ADMIN_GROUP);
+ error = 0; /* this error is not fatal */
+ }
+ /* set process priority */
+ if (!_tcsicmp (priority, TEXT("IDLE_PRIORITY_CLASS")))
+ s->priority = IDLE_PRIORITY_CLASS;
+ else if (!_tcsicmp (priority, TEXT("BELOW_NORMAL_PRIORITY_CLASS")))
+ s->priority = BELOW_NORMAL_PRIORITY_CLASS;
+ else if (!_tcsicmp (priority, TEXT("NORMAL_PRIORITY_CLASS")))
+ s->priority = NORMAL_PRIORITY_CLASS;
+ else if (!_tcsicmp (priority, TEXT("ABOVE_NORMAL_PRIORITY_CLASS")))
+ s->priority = ABOVE_NORMAL_PRIORITY_CLASS;
+ else if (!_tcsicmp (priority, TEXT("HIGH_PRIORITY_CLASS")))
+ s->priority = HIGH_PRIORITY_CLASS;
+ else
+ {
+ SetLastError (ERROR_INVALID_DATA);
+ error = MsgToEventLog (M_SYSERR, TEXT("Unknown priority name: %s"), priority);
+ goto out;
+ }
+
+ /* set log file append/truncate flag */
+ if (append[0] == TEXT('0'))
+ s->append = FALSE;
+ else if (append[0] == TEXT('1'))
+ s->append = TRUE;
+ else
+ {
+ SetLastError (ERROR_INVALID_DATA);
+ error = MsgToEventLog (M_ERR, TEXT("Log file append flag (given as '%s') must be '0' or '1'"), append);
+ goto out;
+ }
+
+out:
+ RegCloseKey (key);
+ return error;
+}
+
+
+LPCTSTR
+GetLastErrorText ()
+{
+ static TCHAR buf[256];
+ DWORD len;
+ LPTSTR tmp = NULL;
+
+ len = FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ARGUMENT_ARRAY,
+ NULL, GetLastError(), LANG_NEUTRAL, (LPTSTR)&tmp, 0, NULL);
+
+ if (len == 0 || (long) _countof (buf) < (long) len + 14)
+ buf[0] = TEXT('\0');
+ else
+ {
+ tmp[_tcslen (tmp) - 2] = TEXT('\0'); /* remove CR/LF characters */
+ openvpn_sntprintf (buf, _countof (buf), TEXT("%s (0x%x)"), tmp, GetLastError());
+ }
+
+ if (tmp)
+ LocalFree (tmp);
+
+ return buf;
+}
+
+
+DWORD
+MsgToEventLog (DWORD flags, LPCTSTR format, ...)
+{
+ HANDLE hEventSource;
+ TCHAR msg[2][256];
+ DWORD error = 0;
+ LPCTSTR err_msg = TEXT("");
+ va_list arglist;
+
+ if (flags & MSG_FLAGS_SYS_CODE)
+ {
+ error = GetLastError ();
+ err_msg = GetLastErrorText ();
+ }
+
+ hEventSource = RegisterEventSource (NULL, APPNAME);
+ if (hEventSource != NULL)
+ {
+ openvpn_sntprintf (msg[0], _countof (msg[0]),
+ TEXT("%s%s: %s"), APPNAME,
+ (flags & MSG_FLAGS_ERROR) ? TEXT(" error") : TEXT(""), err_msg);
+
+ va_start (arglist, format);
+ openvpn_vsntprintf (msg[1], _countof (msg[1]), format, arglist);
+ va_end (arglist);
+
+ const TCHAR *mesg[] = { msg[0], msg[1] };
+ ReportEvent (hEventSource, flags & MSG_FLAGS_ERROR ?
+ EVENTLOG_ERROR_TYPE : EVENTLOG_INFORMATION_TYPE,
+ 0, 0, NULL, 2, 0, mesg, NULL);
+ DeregisterEventSource (hEventSource);
+ }
+
+ return error;
+}
diff --git a/src/openvpnserv/interactive.c b/src/openvpnserv/interactive.c
new file mode 100644
index 0000000..ffaa171
--- /dev/null
+++ b/src/openvpnserv/interactive.c
@@ -0,0 +1,1652 @@
+/*
+ * OpenVPN -- An application to securely tunnel IP networks
+ * over a single TCP/UDP port, with support for SSL/TLS-based
+ * session authentication and key exchange,
+ * packet encryption, packet authentication, and
+ * packet compression.
+ *
+ * Copyright (C) 2012 Heiko Hund <heiko.hund@sophos.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program (see the file COPYING included with this
+ * distribution); if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#include "service.h"
+
+#include <winsock2.h>
+#include <ws2tcpip.h>
+#include <iphlpapi.h>
+#include <userenv.h>
+#include <accctrl.h>
+#include <aclapi.h>
+#include <stdio.h>
+#include <sddl.h>
+#include <shellapi.h>
+
+#include "openvpn-msg.h"
+#include "validate.h"
+#include "block_dns.h"
+
+#define IO_TIMEOUT 2000 /*ms*/
+
+#define ERROR_OPENVPN_STARTUP 0x20000000
+#define ERROR_STARTUP_DATA 0x20000001
+#define ERROR_MESSAGE_DATA 0x20000002
+#define ERROR_MESSAGE_TYPE 0x20000003
+
+static SERVICE_STATUS_HANDLE service;
+static SERVICE_STATUS status;
+static HANDLE exit_event = NULL;
+static settings_t settings;
+static HANDLE rdns_semaphore = NULL;
+#define RDNS_TIMEOUT 600 /* seconds to wait for the semaphore */
+
+
+openvpn_service_t interactive_service = {
+ interactive,
+ TEXT(PACKAGE_NAME "ServiceInteractive"),
+ TEXT(PACKAGE_NAME " Interactive Service"),
+ TEXT(SERVICE_DEPENDENCIES),
+ SERVICE_AUTO_START
+};
+
+
+typedef struct {
+ WCHAR *directory;
+ WCHAR *options;
+ WCHAR *std_input;
+} STARTUP_DATA;
+
+
+/* Datatype for linked lists */
+typedef struct _list_item {
+ struct _list_item *next;
+ LPVOID data;
+} list_item_t;
+
+
+/* Datatypes for undo information */
+typedef enum {
+ address,
+ route,
+ block_dns,
+ _undo_type_max
+} undo_type_t;
+typedef list_item_t* undo_lists_t[_undo_type_max];
+
+
+static DWORD
+AddListItem (list_item_t **pfirst, LPVOID data)
+{
+ list_item_t *new_item = malloc (sizeof (list_item_t));
+ if (new_item == NULL)
+ return ERROR_OUTOFMEMORY;
+
+ new_item->next = *pfirst;
+ new_item->data = data;
+
+ *pfirst = new_item;
+ return NO_ERROR;
+}
+
+typedef BOOL (*match_fn_t) (LPVOID item, LPVOID ctx);
+
+static LPVOID
+RemoveListItem (list_item_t **pfirst, match_fn_t match, LPVOID ctx)
+{
+ LPVOID data = NULL;
+ list_item_t **pnext;
+
+ for (pnext = pfirst; *pnext; pnext = &(*pnext)->next)
+ {
+ list_item_t *item = *pnext;
+ if (!match (item->data, ctx))
+ continue;
+
+ /* Found item, remove from the list and free memory */
+ *pnext = item->next;
+ data = item->data;
+ free (item);
+ break;
+ }
+ return data;
+}
+
+
+static HANDLE
+CloseHandleEx (LPHANDLE handle)
+{
+ if (handle && *handle && *handle != INVALID_HANDLE_VALUE)
+ {
+ CloseHandle (*handle);
+ *handle = INVALID_HANDLE_VALUE;
+ }
+ return INVALID_HANDLE_VALUE;
+}
+
+
+static HANDLE
+InitOverlapped (LPOVERLAPPED overlapped)
+{
+ ZeroMemory (overlapped, sizeof (OVERLAPPED));
+ overlapped->hEvent = CreateEvent (NULL, TRUE, FALSE, NULL);
+ return overlapped->hEvent;
+}
+
+
+static BOOL
+ResetOverlapped (LPOVERLAPPED overlapped)
+{
+ HANDLE io_event = overlapped->hEvent;
+ if (!ResetEvent (io_event))
+ return FALSE;
+ ZeroMemory (overlapped, sizeof (OVERLAPPED));
+ overlapped->hEvent = io_event;
+ return TRUE;
+}
+
+
+typedef enum {
+ peek,
+ read,
+ write
+} async_op_t;
+
+static DWORD
+AsyncPipeOp (async_op_t op, HANDLE pipe, LPVOID buffer, DWORD size, DWORD count, LPHANDLE events)
+{
+ int i;
+ BOOL success;
+ HANDLE io_event;
+ DWORD res, bytes = 0;
+ OVERLAPPED overlapped;
+ LPHANDLE handles = NULL;
+
+ io_event = InitOverlapped (&overlapped);
+ if (!io_event)
+ goto out;
+
+ handles = malloc ((count + 1) * sizeof (HANDLE));
+ if (!handles)
+ goto out;
+
+ if (op == write)
+ success = WriteFile (pipe, buffer, size, NULL, &overlapped);
+ else
+ success = ReadFile (pipe, buffer, size, NULL, &overlapped);
+ if (!success && GetLastError () != ERROR_IO_PENDING && GetLastError () != ERROR_MORE_DATA)
+ goto out;
+
+ handles[0] = io_event;
+ for (i = 0; i < count; i++)
+ handles[i + 1] = events[i];
+
+ res = WaitForMultipleObjects (count + 1, handles, FALSE,
+ op == peek ? INFINITE : IO_TIMEOUT);
+ if (res != WAIT_OBJECT_0)
+ {
+ CancelIo (pipe);
+ goto out;
+ }
+
+ if (op == peek)
+ PeekNamedPipe (pipe, NULL, 0, NULL, &bytes, NULL);
+ else
+ GetOverlappedResult (pipe, &overlapped, &bytes, TRUE);
+
+out:
+ CloseHandleEx (&io_event);
+ free (handles);
+ return bytes;
+}
+
+static DWORD
+PeekNamedPipeAsync (HANDLE pipe, DWORD count, LPHANDLE events)
+{
+ return AsyncPipeOp (peek, pipe, NULL, 0, count, events);
+}
+
+static DWORD
+ReadPipeAsync (HANDLE pipe, LPVOID buffer, DWORD size, DWORD count, LPHANDLE events)
+{
+ return AsyncPipeOp (read, pipe, buffer, size, count, events);
+}
+
+static DWORD
+WritePipeAsync (HANDLE pipe, LPVOID data, DWORD size, DWORD count, LPHANDLE events)
+{
+ return AsyncPipeOp (write, pipe, data, size, count, events);
+}
+
+static VOID
+ReturnProcessId (HANDLE pipe, DWORD pid, DWORD count, LPHANDLE events)
+{
+ const WCHAR msg[] = L"Process ID";
+ WCHAR buf[22 + _countof(msg)]; /* 10 chars each for error and PID and 2 for line breaks */
+
+ /*
+ * Same format as error messages (3 line string) with error = 0 in
+ * 0x%08x format, PID on line 2 and a description "Process ID" on line 3
+ */
+ _snwprintf (buf, _countof(buf), L"0x%08x\n0x%08x\n%s", 0, pid, msg);
+ buf[_countof(buf) - 1] = '\0';
+
+ WritePipeAsync (pipe, buf, wcslen (buf) * 2, count, events);
+}
+
+static VOID
+ReturnError (HANDLE pipe, DWORD error, LPCWSTR func, DWORD count, LPHANDLE events)
+{
+ DWORD result_len;
+ LPWSTR result = L"0xffffffff\nFormatMessage failed\nCould not return result";
+ DWORD_PTR args[] = {
+ (DWORD_PTR) error,
+ (DWORD_PTR) func,
+ (DWORD_PTR) ""
+ };
+
+ if (error != ERROR_OPENVPN_STARTUP)
+ {
+ FormatMessageW (FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_IGNORE_INSERTS,
+ 0, error, 0, (LPWSTR) &args[2], 0, NULL);
+ }
+
+ result_len = FormatMessageW (FORMAT_MESSAGE_FROM_STRING |
+ FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_ARGUMENT_ARRAY,
+ L"0x%1!08x!\n%2!s!\n%3!s!", 0, 0,
+ (LPWSTR) &result, 0, (va_list*) args);
+
+ WritePipeAsync (pipe, result, wcslen (result) * 2, count, events);
+#ifdef UNICODE
+ MsgToEventLog (MSG_FLAGS_ERROR, result);
+#else
+ MsgToEventLog (MSG_FLAGS_ERROR, "%S", result);
+#endif
+
+ if (error != ERROR_OPENVPN_STARTUP)
+ LocalFree ((LPVOID) args[2]);
+ if (result_len)
+ LocalFree (result);
+}
+
+
+static VOID
+ReturnLastError (HANDLE pipe, LPCWSTR func)
+{
+ ReturnError (pipe, GetLastError (), func, 1, &exit_event);
+}
+
+
+static VOID
+ReturnOpenvpnOutput (HANDLE pipe, HANDLE ovpn_output, DWORD count, LPHANDLE events)
+{
+ WCHAR *wide_output = NULL;
+ CHAR output[512];
+ DWORD size;
+
+ ReadFile (ovpn_output, output, sizeof (output), &size, NULL);
+ if (size == 0)
+ return;
+
+ wide_output = malloc ((size) * sizeof (WCHAR));
+ if (wide_output)
+ {
+ MultiByteToWideChar (CP_UTF8, 0, output, size, wide_output, size);
+ wide_output[size - 1] = 0;
+ }
+
+ ReturnError (pipe, ERROR_OPENVPN_STARTUP, wide_output, count, events);
+ free (wide_output);
+}
+
+/*
+ * Validate options against a white list. Also check the config_file is
+ * inside the config_dir. The white list is defined in validate.c
+ * Returns true on success
+ */
+static BOOL
+ValidateOptions (HANDLE pipe, const WCHAR *workdir, const WCHAR *options)
+{
+ WCHAR **argv;
+ int argc;
+ WCHAR buf[256];
+ BOOL ret = FALSE;
+ int i;
+ const WCHAR *msg1 = L"You have specified a config file location (%s relative to %s)"
+ " that requires admin approval. This error may be avoided"
+ " by adding your account to the \"%s\" group";
+
+ const WCHAR *msg2 = L"You have specified an option (%s) that may be used"
+ " only with admin approval. This error may be avoided"
+ " by adding your account to the \"%s\" group";
+
+ argv = CommandLineToArgvW (options, &argc);
+
+ if (!argv)
+ {
+ ReturnLastError (pipe, L"CommandLineToArgvW");
+ ReturnError (pipe, ERROR_STARTUP_DATA, L"Cannot validate options", 1, &exit_event);
+ goto out;
+ }
+
+ /* Note: argv[0] is the first option */
+ if (argc < 1) /* no options */
+ {
+ ret = TRUE;
+ goto out;
+ }
+
+ /*
+ * If only one argument, it is the config file
+ */
+ if (argc == 1)
+ {
+ WCHAR *argv_tmp[2] = { L"--config", argv[0] };
+
+ if (!CheckOption (workdir, 2, argv_tmp, &settings))
+ {
+ snwprintf (buf, _countof(buf), msg1, argv[0], workdir,
+ settings.ovpn_admin_group);
+ buf[_countof(buf) - 1] = L'\0';
+ ReturnError (pipe, ERROR_STARTUP_DATA, buf, 1, &exit_event);
+ }
+ goto out;
+ }
+
+ for (i = 0; i < argc; ++i)
+ {
+ if (!IsOption(argv[i]))
+ continue;
+
+ if (!CheckOption (workdir, argc-i, &argv[i], &settings))
+ {
+ if (wcscmp(L"--config", argv[i]) == 0 && argc-i > 1)
+ {
+ snwprintf (buf, _countof(buf), msg1, argv[i+1], workdir,
+ settings.ovpn_admin_group);
+ buf[_countof(buf) - 1] = L'\0';
+ ReturnError (pipe, ERROR_STARTUP_DATA, buf, 1, &exit_event);
+ }
+ else
+ {
+ snwprintf (buf, _countof(buf), msg2, argv[i],
+ settings.ovpn_admin_group);
+ buf[_countof(buf) - 1] = L'\0';
+ ReturnError (pipe, ERROR_STARTUP_DATA, buf, 1, &exit_event);
+ }
+ goto out;
+ }
+ }
+
+ /* all options passed */
+ ret = TRUE;
+
+out:
+ if (argv)
+ LocalFree (argv);
+ return ret;
+}
+
+static BOOL
+GetStartupData (HANDLE pipe, STARTUP_DATA *sud)
+{
+ size_t len;
+ BOOL ret = FALSE;
+ WCHAR *data = NULL;
+ DWORD size, bytes, read;
+
+ bytes = PeekNamedPipeAsync (pipe, 1, &exit_event);
+ if (bytes == 0)
+ {
+ MsgToEventLog (M_SYSERR, TEXT("PeekNamedPipeAsync failed"));
+ ReturnLastError (pipe, L"PeekNamedPipeAsync");
+ goto out;
+ }
+
+ size = bytes / sizeof (*data);
+ data = malloc (bytes);
+ if (data == NULL)
+ {
+ MsgToEventLog (M_SYSERR, TEXT("malloc failed"));
+ ReturnLastError (pipe, L"malloc");
+ goto out;
+ }
+
+ read = ReadPipeAsync (pipe, data, bytes, 1, &exit_event);
+ if (bytes != read)
+ {
+ MsgToEventLog (M_SYSERR, TEXT("ReadPipeAsync failed"));
+ ReturnLastError (pipe, L"ReadPipeAsync");
+ goto out;
+ }
+
+ if (data[size - 1] != 0)
+ {
+ MsgToEventLog (M_ERR, TEXT("Startup data is not NULL terminated"));
+ ReturnError (pipe, ERROR_STARTUP_DATA, L"GetStartupData", 1, &exit_event);
+ goto out;
+ }
+
+ sud->directory = data;
+ len = wcslen (sud->directory) + 1;
+ size -= len;
+ if (size <= 0)
+ {
+ MsgToEventLog (M_ERR, TEXT("Startup data ends at working directory"));
+ ReturnError (pipe, ERROR_STARTUP_DATA, L"GetStartupData", 1, &exit_event);
+ goto out;
+ }
+
+ sud->options = sud->directory + len;
+ len = wcslen (sud->options) + 1;
+ size -= len;
+ if (size <= 0)
+ {
+ MsgToEventLog (M_ERR, TEXT("Startup data ends at command line options"));
+ ReturnError (pipe, ERROR_STARTUP_DATA, L"GetStartupData", 1, &exit_event);
+ goto out;
+ }
+
+ sud->std_input = sud->options + len;
+ data = NULL; /* don't free data */
+ ret = TRUE;
+
+out:
+ free (data);
+ return ret;
+}
+
+
+static VOID
+FreeStartupData (STARTUP_DATA *sud)
+{
+ free (sud->directory);
+}
+
+
+static SOCKADDR_INET
+sockaddr_inet (short family, inet_address_t *addr)
+{
+ SOCKADDR_INET sa_inet;
+ ZeroMemory (&sa_inet, sizeof (sa_inet));
+ sa_inet.si_family = family;
+ if (family == AF_INET)
+ sa_inet.Ipv4.sin_addr = addr->ipv4;
+ else if (family == AF_INET6)
+ sa_inet.Ipv6.sin6_addr = addr->ipv6;
+ return sa_inet;
+}
+
+static DWORD
+InterfaceLuid (const char *iface_name, PNET_LUID luid)
+{
+ NETIO_STATUS status;
+ LPWSTR wide_name;
+ int n;
+
+ typedef NETIO_STATUS WINAPI (*ConvertInterfaceAliasToLuidFn) (LPCWSTR, PNET_LUID);
+ static ConvertInterfaceAliasToLuidFn ConvertInterfaceAliasToLuid = NULL;
+ if (!ConvertInterfaceAliasToLuid)
+ {
+ HMODULE iphlpapi = GetModuleHandle (TEXT("iphlpapi.dll"));
+ if (iphlpapi == NULL)
+ return GetLastError ();
+
+ ConvertInterfaceAliasToLuid = (ConvertInterfaceAliasToLuidFn) GetProcAddress (iphlpapi, "ConvertInterfaceAliasToLuid");
+ if (!ConvertInterfaceAliasToLuid)
+ return GetLastError ();
+ }
+
+ n = MultiByteToWideChar (CP_UTF8, 0, iface_name, -1, NULL, 0);
+ wide_name = malloc (n * sizeof (WCHAR));
+ MultiByteToWideChar (CP_UTF8, 0, iface_name, -1, wide_name, n);
+ status = ConvertInterfaceAliasToLuid (wide_name, luid);
+ free (wide_name);
+
+ return status;
+}
+
+static BOOL
+CmpAddress (LPVOID item, LPVOID address)
+{
+ return memcmp (item, address, sizeof (MIB_UNICASTIPADDRESS_ROW)) == 0 ? TRUE : FALSE;
+}
+
+static DWORD
+DeleteAddress (PMIB_UNICASTIPADDRESS_ROW addr_row)
+{
+ typedef NETIOAPI_API (*DeleteUnicastIpAddressEntryFn) (const PMIB_UNICASTIPADDRESS_ROW);
+ static DeleteUnicastIpAddressEntryFn DeleteUnicastIpAddressEntry = NULL;
+
+ if (!DeleteUnicastIpAddressEntry)
+ {
+ HMODULE iphlpapi = GetModuleHandle (TEXT("iphlpapi.dll"));
+ if (iphlpapi == NULL)
+ return GetLastError ();
+
+ DeleteUnicastIpAddressEntry = (DeleteUnicastIpAddressEntryFn) GetProcAddress (iphlpapi, "DeleteUnicastIpAddressEntry");
+ if (!DeleteUnicastIpAddressEntry)
+ return GetLastError ();
+ }
+
+ return DeleteUnicastIpAddressEntry (addr_row);
+}
+
+static DWORD
+HandleAddressMessage (address_message_t *msg, undo_lists_t *lists)
+{
+ DWORD err;
+ PMIB_UNICASTIPADDRESS_ROW addr_row;
+ BOOL add = msg->header.type == msg_add_address;
+
+ typedef NETIOAPI_API (*CreateUnicastIpAddressEntryFn) (const PMIB_UNICASTIPADDRESS_ROW);
+ typedef NETIOAPI_API (*InitializeUnicastIpAddressEntryFn) (PMIB_UNICASTIPADDRESS_ROW);
+ static CreateUnicastIpAddressEntryFn CreateUnicastIpAddressEntry = NULL;
+ static InitializeUnicastIpAddressEntryFn InitializeUnicastIpAddressEntry = NULL;
+
+ if (!CreateUnicastIpAddressEntry || !InitializeUnicastIpAddressEntry)
+ {
+ HMODULE iphlpapi = GetModuleHandle (TEXT("iphlpapi.dll"));
+ if (iphlpapi == NULL)
+ return GetLastError ();
+
+ CreateUnicastIpAddressEntry = (CreateUnicastIpAddressEntryFn) GetProcAddress (iphlpapi, "CreateUnicastIpAddressEntry");
+ if (!CreateUnicastIpAddressEntry)
+ return GetLastError ();
+
+ InitializeUnicastIpAddressEntry = (InitializeUnicastIpAddressEntryFn) GetProcAddress (iphlpapi, "InitializeUnicastIpAddressEntry");
+ if (!InitializeUnicastIpAddressEntry)
+ return GetLastError ();
+ }
+
+ addr_row = malloc (sizeof (*addr_row));
+ if (addr_row == NULL)
+ return ERROR_OUTOFMEMORY;
+
+ InitializeUnicastIpAddressEntry (addr_row);
+ addr_row->Address = sockaddr_inet (msg->family, &msg->address);
+ addr_row->OnLinkPrefixLength = (UINT8) msg->prefix_len;
+
+ if (msg->iface.index != -1)
+ {
+ addr_row->InterfaceIndex = msg->iface.index;
+ }
+ else
+ {
+ NET_LUID luid;
+ err = InterfaceLuid (msg->iface.name, &luid);
+ if (err)
+ goto out;
+ addr_row->InterfaceLuid = luid;
+ }
+
+ if (add)
+ {
+ err = CreateUnicastIpAddressEntry (addr_row);
+ if (err)
+ goto out;
+
+ err = AddListItem (&(*lists)[address], addr_row);
+ if (err)
+ DeleteAddress (addr_row);
+ }
+ else
+ {
+ err = DeleteAddress (addr_row);
+ if (err)
+ goto out;
+
+ free (RemoveListItem (&(*lists)[address], CmpAddress, addr_row));
+ }
+
+out:
+ if (!add || err)
+ free (addr_row);
+
+ return err;
+}
+
+static BOOL
+CmpRoute (LPVOID item, LPVOID route)
+{
+ return memcmp (item, route, sizeof (MIB_IPFORWARD_ROW2)) == 0 ? TRUE : FALSE;
+}
+
+static DWORD
+DeleteRoute (PMIB_IPFORWARD_ROW2 fwd_row)
+{
+ typedef NETIOAPI_API (*DeleteIpForwardEntry2Fn) (PMIB_IPFORWARD_ROW2);
+ static DeleteIpForwardEntry2Fn DeleteIpForwardEntry2 = NULL;
+
+ if (!DeleteIpForwardEntry2)
+ {
+ HMODULE iphlpapi = GetModuleHandle (TEXT("iphlpapi.dll"));
+ if (iphlpapi == NULL)
+ return GetLastError ();
+
+ DeleteIpForwardEntry2 = (DeleteIpForwardEntry2Fn) GetProcAddress (iphlpapi, "DeleteIpForwardEntry2");
+ if (!DeleteIpForwardEntry2)
+ return GetLastError ();
+ }
+
+ return DeleteIpForwardEntry2 (fwd_row);
+}
+
+static DWORD
+HandleRouteMessage (route_message_t *msg, undo_lists_t *lists)
+{
+ DWORD err;
+ PMIB_IPFORWARD_ROW2 fwd_row;
+ BOOL add = msg->header.type == msg_add_route;
+
+ typedef NETIOAPI_API (*CreateIpForwardEntry2Fn) (PMIB_IPFORWARD_ROW2);
+ static CreateIpForwardEntry2Fn CreateIpForwardEntry2 = NULL;
+
+ if (!CreateIpForwardEntry2)
+ {
+ HMODULE iphlpapi = GetModuleHandle (TEXT("iphlpapi.dll"));
+ if (iphlpapi == NULL)
+ return GetLastError ();
+
+ CreateIpForwardEntry2 = (CreateIpForwardEntry2Fn) GetProcAddress (iphlpapi, "CreateIpForwardEntry2");
+ if (!CreateIpForwardEntry2)
+ return GetLastError ();
+ }
+
+ fwd_row = malloc (sizeof (*fwd_row));
+ if (fwd_row == NULL)
+ return ERROR_OUTOFMEMORY;
+
+ ZeroMemory (fwd_row, sizeof (*fwd_row));
+ fwd_row->ValidLifetime = 0xffffffff;
+ fwd_row->PreferredLifetime = 0xffffffff;
+ fwd_row->Protocol = MIB_IPPROTO_NETMGMT;
+ fwd_row->Metric = msg->metric;
+ fwd_row->DestinationPrefix.Prefix = sockaddr_inet (msg->family, &msg->prefix);
+ fwd_row->DestinationPrefix.PrefixLength = (UINT8) msg->prefix_len;
+ fwd_row->NextHop = sockaddr_inet (msg->family, &msg->gateway);
+
+ if (msg->iface.index != -1)
+ {
+ fwd_row->InterfaceIndex = msg->iface.index;
+ }
+ else if (strlen (msg->iface.name))
+ {
+ NET_LUID luid;
+ err = InterfaceLuid (msg->iface.name, &luid);
+ if (err)
+ goto out;
+ fwd_row->InterfaceLuid = luid;
+ }
+
+ if (add)
+ {
+ err = CreateIpForwardEntry2 (fwd_row);
+ if (err)
+ goto out;
+
+ err = AddListItem (&(*lists)[route], fwd_row);
+ if (err)
+ DeleteRoute (fwd_row);
+ }
+ else
+ {
+ err = DeleteRoute (fwd_row);
+ if (err)
+ goto out;
+
+ free (RemoveListItem (&(*lists)[route], CmpRoute, fwd_row));
+ }
+
+out:
+ if (!add || err)
+ free (fwd_row);
+
+ return err;
+}
+
+
+static DWORD
+HandleFlushNeighborsMessage (flush_neighbors_message_t *msg)
+{
+ typedef NETIOAPI_API (*FlushIpNetTable2Fn) (ADDRESS_FAMILY, NET_IFINDEX);
+ static FlushIpNetTable2Fn flush_fn = NULL;
+
+ if (msg->family == AF_INET)
+ return FlushIpNetTable (msg->iface.index);
+
+ if (!flush_fn)
+ {
+ HMODULE iphlpapi = GetModuleHandle (TEXT("iphlpapi.dll"));
+ if (iphlpapi == NULL)
+ return GetLastError ();
+
+ flush_fn = (FlushIpNetTable2Fn) GetProcAddress (iphlpapi, "FlushIpNetTable2");
+ if (!flush_fn)
+ {
+ if (GetLastError () == ERROR_PROC_NOT_FOUND)
+ return WSAEPFNOSUPPORT;
+ else
+ return GetLastError ();
+ }
+ }
+ return flush_fn (msg->family, msg->iface.index);
+}
+
+static void
+BlockDNSErrHandler (DWORD err, const char *msg)
+{
+ TCHAR buf[256];
+ LPCTSTR err_str;
+
+ if (!err) return;
+
+ err_str = TEXT("Unknown Win32 Error");
+
+ if (FormatMessage (FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM
+ | FORMAT_MESSAGE_ARGUMENT_ARRAY,
+ NULL, err, 0, buf, sizeof (buf), NULL))
+ {
+ err_str = buf;
+ }
+
+#ifdef UNICODE
+ MsgToEventLog (M_ERR, L"%S (status = %lu): %s", msg, err, err_str);
+#else
+ MsgToEventLog (M_ERR, "%s (status = %lu): %s", msg, err, err_str);
+#endif
+
+}
+
+/* Use an always-true match_fn to get the head of the list */
+static BOOL
+CmpEngine (LPVOID item, LPVOID any)
+{
+ return TRUE;
+}
+
+static DWORD
+HandleBlockDNSMessage (const block_dns_message_t *msg, undo_lists_t *lists)
+{
+ DWORD err = 0;
+ HANDLE engine = NULL;
+ LPCWSTR exe_path;
+
+#ifdef UNICODE
+ exe_path = settings.exe_path;
+#else
+ WCHAR wide_path[MAX_PATH];
+ MultiByteToWideChar (CP_UTF8, 0, settings.exe_path, MAX_PATH, wide_path, MAX_PATH);
+ exe_path = wide_path;
+#endif
+
+ if (msg->header.type == msg_add_block_dns)
+ {
+ err = add_block_dns_filters (&engine, msg->iface.index, exe_path, BlockDNSErrHandler);
+ if (!err)
+ err = AddListItem (&(*lists)[block_dns], engine);
+ }
+ else
+ {
+ engine = RemoveListItem (&(*lists)[block_dns], CmpEngine, NULL);
+ if (engine)
+ {
+ err = delete_block_dns_filters (engine);
+ engine = NULL;
+ }
+ else
+ MsgToEventLog (M_ERR, TEXT("No previous block DNS filters to delete"));
+ }
+
+ if (err && engine)
+ {
+ delete_block_dns_filters (engine);
+ }
+
+ return err;
+}
+
+/*
+ * Execute a command and return its exit code. If timeout > 0, terminate
+ * the process if still running after timeout milliseconds. In that case
+ * the return value is the windows error code WAIT_TIMEOUT = 0x102
+ */
+static DWORD
+ExecCommand (const WCHAR *argv0, const WCHAR *cmdline, DWORD timeout)
+{
+ DWORD exit_code;
+ STARTUPINFOW si;
+ PROCESS_INFORMATION pi;
+ DWORD proc_flags = CREATE_NO_WINDOW|CREATE_UNICODE_ENVIRONMENT;
+ WCHAR *cmdline_dup = NULL;
+
+ ZeroMemory (&si, sizeof(si));
+ ZeroMemory (&pi, sizeof(pi));
+
+ si.cb = sizeof(si);
+
+ /* CreateProcess needs a modifiable cmdline: make a copy */
+ cmdline_dup = wcsdup (cmdline);
+ if ( cmdline_dup && CreateProcessW (argv0, cmdline_dup, NULL, NULL, FALSE,
+ proc_flags, NULL, NULL, &si, &pi) )
+ {
+ WaitForSingleObject (pi.hProcess, timeout ? timeout : INFINITE);
+ if (!GetExitCodeProcess (pi.hProcess, &exit_code))
+ {
+ MsgToEventLog (M_SYSERR, TEXT("ExecCommand: Error getting exit_code:"));
+ exit_code = GetLastError();
+ }
+ else if (exit_code == STILL_ACTIVE)
+ {
+ exit_code = WAIT_TIMEOUT; /* Windows error code 0x102 */
+
+ /* kill without impunity */
+ TerminateProcess (pi.hProcess, exit_code);
+ MsgToEventLog (M_ERR, TEXT("ExecCommand: \"%s %s\" killed after timeout"),
+ argv0, cmdline);
+ }
+ else if (exit_code)
+ MsgToEventLog (M_ERR, TEXT("ExecCommand: \"%s %s\" exited with status = %lu"),
+ argv0, cmdline, exit_code);
+ else
+ MsgToEventLog (M_INFO, TEXT("ExecCommand: \"%s %s\" completed"), argv0, cmdline);
+
+ CloseHandle(pi.hProcess);
+ CloseHandle(pi.hThread);
+ }
+ else
+ {
+ exit_code = GetLastError();
+ MsgToEventLog (M_SYSERR, TEXT("ExecCommand: could not run \"%s %s\" :"),
+ argv0, cmdline);
+ }
+
+ free (cmdline_dup);
+ return exit_code;
+}
+
+/*
+ * Entry point for register-dns thread.
+ */
+static DWORD WINAPI
+RegisterDNS (LPVOID unused)
+{
+ DWORD err;
+ DWORD i;
+ WCHAR sys_path[MAX_PATH];
+ DWORD timeout = RDNS_TIMEOUT * 1000; /* in milliseconds */
+
+ /* default paths of net and ipconfig commands */
+ WCHAR net[MAX_PATH] = L"C:\\Windows\\system32\\net.exe";
+ WCHAR ipcfg[MAX_PATH] = L"C:\\Windows\\system32\\ipconfig.exe";
+
+ struct
+ {
+ WCHAR *argv0;
+ WCHAR *cmdline;
+ DWORD timeout;
+ } cmds [] = {
+ { net, L"net stop dnscache", timeout },
+ { net, L"net start dnscache", timeout },
+ { ipcfg, L"ipconfig /flushdns", timeout },
+ { ipcfg, L"ipconfig /registerdns", timeout },
+ };
+ int ncmds = sizeof (cmds) / sizeof (cmds[0]);
+
+ HANDLE wait_handles[2] = {rdns_semaphore, exit_event};
+
+ if(GetSystemDirectory(sys_path, MAX_PATH))
+ {
+ _snwprintf (net, MAX_PATH, L"%s\\%s", sys_path, L"net.exe");
+ net[MAX_PATH-1] = L'\0';
+
+ _snwprintf (ipcfg, MAX_PATH, L"%s\\%s", sys_path, L"ipconfig.exe");
+ ipcfg[MAX_PATH-1] = L'\0';
+ }
+
+ if (WaitForMultipleObjects (2, wait_handles, FALSE, timeout) == WAIT_OBJECT_0)
+ {
+ /* Semaphore locked */
+ for (i = 0; i < ncmds; ++i)
+ {
+ ExecCommand (cmds[i].argv0, cmds[i].cmdline, cmds[i].timeout);
+ }
+ err = 0;
+ if ( !ReleaseSemaphore (rdns_semaphore, 1, NULL) )
+ err = MsgToEventLog (M_SYSERR, TEXT("RegisterDNS: Failed to release regsiter-dns semaphore:"));
+ }
+ else
+ {
+ MsgToEventLog (M_ERR, TEXT("RegisterDNS: Failed to lock register-dns semaphore"));
+ err = ERROR_SEM_TIMEOUT; /* Windows error code 0x79 */
+ }
+ return err;
+}
+
+static DWORD
+HandleRegisterDNSMessage (void)
+{
+ DWORD err;
+ HANDLE thread = NULL;
+
+ /* Delegate this job to a sub-thread */
+ thread = CreateThread (NULL, 0, RegisterDNS, NULL, 0, NULL);
+
+ /*
+ * We don't add these thread handles to the undo list -- the thread and
+ * processes it spawns are all supposed to terminate or timeout by themselves.
+ */
+ if (thread)
+ {
+ err = 0;
+ CloseHandle (thread);
+ }
+ else
+ err = GetLastError();
+
+ return err;
+}
+
+static VOID
+HandleMessage (HANDLE pipe, DWORD bytes, DWORD count, LPHANDLE events, undo_lists_t *lists)
+{
+ DWORD read;
+ union {
+ message_header_t header;
+ address_message_t address;
+ route_message_t route;
+ flush_neighbors_message_t flush_neighbors;
+ block_dns_message_t block_dns;
+ } msg;
+ ack_message_t ack = {
+ .header = {
+ .type = msg_acknowledgement,
+ .size = sizeof (ack),
+ .message_id = -1
+ },
+ .error_number = ERROR_MESSAGE_DATA
+ };
+
+ read = ReadPipeAsync (pipe, &msg, bytes, count, events);
+ if (read != bytes || read < sizeof (msg.header) || read != msg.header.size)
+ goto out;
+
+ ack.header.message_id = msg.header.message_id;
+
+ switch (msg.header.type)
+ {
+ case msg_add_address:
+ case msg_del_address:
+ if (msg.header.size == sizeof (msg.address))
+ ack.error_number = HandleAddressMessage (&msg.address, lists);
+ break;
+
+ case msg_add_route:
+ case msg_del_route:
+ if (msg.header.size == sizeof (msg.route))
+ ack.error_number = HandleRouteMessage (&msg.route, lists);
+ break;
+
+ case msg_flush_neighbors:
+ if (msg.header.size == sizeof (msg.flush_neighbors))
+ ack.error_number = HandleFlushNeighborsMessage (&msg.flush_neighbors);
+ break;
+
+ case msg_add_block_dns:
+ case msg_del_block_dns:
+ if (msg.header.size == sizeof (msg.block_dns))
+ ack.error_number = HandleBlockDNSMessage (&msg.block_dns, lists);
+ break;
+
+ case msg_register_dns:
+ ack.error_number = HandleRegisterDNSMessage ();
+ break;
+
+ default:
+ ack.error_number = ERROR_MESSAGE_TYPE;
+ MsgToEventLog (MSG_FLAGS_ERROR, TEXT("Unknown message type %d"), msg.header.type);
+ break;
+ }
+
+out:
+ WritePipeAsync (pipe, &ack, sizeof (ack), count, events);
+}
+
+
+static VOID
+Undo (undo_lists_t *lists)
+{
+ undo_type_t type;
+ for (type = 0; type < _undo_type_max; type++)
+ {
+ list_item_t **pnext = &(*lists)[type];
+ while (*pnext)
+ {
+ list_item_t *item = *pnext;
+ switch (type)
+ {
+ case address:
+ DeleteAddress (item->data);
+ break;
+
+ case route:
+ DeleteRoute (item->data);
+ break;
+
+ case block_dns:
+ delete_block_dns_filters (item->data);
+ item->data = NULL;
+ break;
+ }
+
+ /* Remove from the list and free memory */
+ *pnext = item->next;
+ free (item->data);
+ free (item);
+ }
+ }
+}
+
+static DWORD WINAPI
+RunOpenvpn (LPVOID p)
+{
+ HANDLE pipe = p;
+ HANDLE ovpn_pipe, svc_pipe;
+ PTOKEN_USER svc_user, ovpn_user;
+ HANDLE svc_token = NULL, imp_token = NULL, pri_token = NULL;
+ HANDLE stdin_read = NULL, stdin_write = NULL;
+ HANDLE stdout_write = NULL;
+ DWORD pipe_mode, len, exit_code = 0;
+ STARTUP_DATA sud = { 0, 0, 0 };
+ STARTUPINFOW startup_info;
+ PROCESS_INFORMATION proc_info;
+ LPVOID user_env = NULL;
+ TCHAR ovpn_pipe_name[36];
+ LPCWSTR exe_path;
+ WCHAR *cmdline = NULL;
+ size_t cmdline_size;
+ undo_lists_t undo_lists;
+
+ SECURITY_ATTRIBUTES inheritable = {
+ .nLength = sizeof (inheritable),
+ .lpSecurityDescriptor = NULL,
+ .bInheritHandle = TRUE
+ };
+
+ PACL ovpn_dacl;
+ EXPLICIT_ACCESS ea[2];
+ SECURITY_DESCRIPTOR ovpn_sd;
+ SECURITY_ATTRIBUTES ovpn_sa = {
+ .nLength = sizeof (ovpn_sa),
+ .lpSecurityDescriptor = &ovpn_sd,
+ .bInheritHandle = FALSE
+ };
+
+ ZeroMemory (&ea, sizeof (ea));
+ ZeroMemory (&startup_info, sizeof (startup_info));
+ ZeroMemory (&undo_lists, sizeof (undo_lists));
+ ZeroMemory (&proc_info, sizeof (proc_info));
+
+ if (!GetStartupData (pipe, &sud))
+ goto out;
+
+ if (!InitializeSecurityDescriptor (&ovpn_sd, SECURITY_DESCRIPTOR_REVISION))
+ {
+ ReturnLastError (pipe, L"InitializeSecurityDescriptor");
+ goto out;
+ }
+
+ /* Get SID of user the service is running under */
+ if (!OpenProcessToken (GetCurrentProcess (), TOKEN_QUERY, &svc_token))
+ {
+ ReturnLastError (pipe, L"OpenProcessToken");
+ goto out;
+ }
+ len = 0;
+ svc_user = NULL;
+ while (!GetTokenInformation (svc_token, TokenUser, svc_user, len, &len))
+ {
+ if (GetLastError () != ERROR_INSUFFICIENT_BUFFER)
+ {
+ ReturnLastError (pipe, L"GetTokenInformation (service token)");
+ goto out;
+ }
+ free (svc_user);
+ svc_user = malloc (len);
+ if (svc_user == NULL)
+ {
+ ReturnLastError (pipe, L"malloc (service token user)");
+ goto out;
+ }
+ }
+ if (!IsValidSid (svc_user->User.Sid))
+ {
+ ReturnLastError (pipe, L"IsValidSid (service token user)");
+ goto out;
+ }
+
+ if (!ImpersonateNamedPipeClient (pipe))
+ {
+ ReturnLastError (pipe, L"ImpersonateNamedPipeClient");
+ goto out;
+ }
+ if (!OpenThreadToken (GetCurrentThread (), TOKEN_ALL_ACCESS, FALSE, &imp_token))
+ {
+ ReturnLastError (pipe, L"OpenThreadToken");
+ goto out;
+ }
+ len = 0;
+ ovpn_user = NULL;
+ while (!GetTokenInformation (imp_token, TokenUser, ovpn_user, len, &len))
+ {
+ if (GetLastError () != ERROR_INSUFFICIENT_BUFFER)
+ {
+ ReturnLastError (pipe, L"GetTokenInformation (impersonation token)");
+ goto out;
+ }
+ free (ovpn_user);
+ ovpn_user = malloc (len);
+ if (ovpn_user == NULL)
+ {
+ ReturnLastError (pipe, L"malloc (impersonation token user)");
+ goto out;
+ }
+ }
+ if (!IsValidSid (ovpn_user->User.Sid))
+ {
+ ReturnLastError (pipe, L"IsValidSid (impersonation token user)");
+ goto out;
+ }
+
+ /* Check user is authorized or options are white-listed */
+ if (!IsAuthorizedUser (ovpn_user->User.Sid, &settings) &&
+ !ValidateOptions (pipe, sud.directory, sud.options))
+ {
+ goto out;
+ }
+
+ /* OpenVPN process DACL entry for access by service and user */
+ ea[0].grfAccessPermissions = SPECIFIC_RIGHTS_ALL | STANDARD_RIGHTS_ALL;
+ ea[0].grfAccessMode = SET_ACCESS;
+ ea[0].grfInheritance = NO_INHERITANCE;
+ ea[0].Trustee.TrusteeForm = TRUSTEE_IS_SID;
+ ea[0].Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
+ ea[0].Trustee.ptstrName = (LPTSTR) svc_user->User.Sid;
+ ea[1].grfAccessPermissions = READ_CONTROL | SYNCHRONIZE | PROCESS_VM_READ |
+ SYNCHRONIZE | PROCESS_TERMINATE | PROCESS_QUERY_INFORMATION;
+ ea[1].grfAccessMode = SET_ACCESS;
+ ea[1].grfInheritance = NO_INHERITANCE;
+ ea[1].Trustee.TrusteeForm = TRUSTEE_IS_SID;
+ ea[1].Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
+ ea[1].Trustee.ptstrName = (LPTSTR) ovpn_user->User.Sid;
+
+ /* Set owner and DACL of OpenVPN security descriptor */
+ if (!SetSecurityDescriptorOwner (&ovpn_sd, svc_user->User.Sid, FALSE))
+ {
+ ReturnLastError (pipe, L"SetSecurityDescriptorOwner");
+ goto out;
+ }
+ if (SetEntriesInAcl (2, ea, NULL, &ovpn_dacl) != ERROR_SUCCESS)
+ {
+ ReturnLastError (pipe, L"SetEntriesInAcl");
+ goto out;
+ }
+ if (!SetSecurityDescriptorDacl (&ovpn_sd, TRUE, ovpn_dacl, FALSE))
+ {
+ ReturnLastError (pipe, L"SetSecurityDescriptorDacl");
+ goto out;
+ }
+
+ /* Create primary token from impersonation token */
+ if (!DuplicateTokenEx (imp_token, TOKEN_ALL_ACCESS, NULL, 0, TokenPrimary, &pri_token))
+ {
+ ReturnLastError (pipe, L"DuplicateTokenEx");
+ goto out;
+ }
+
+ /* use /dev/null for stdout of openvpn (client should use --log for output) */
+ stdout_write = CreateFile(_T("NUL"), GENERIC_WRITE, FILE_SHARE_WRITE,
+ &inheritable, OPEN_EXISTING, 0, NULL);
+ if (stdout_write == INVALID_HANDLE_VALUE)
+ {
+ ReturnLastError (pipe, L"CreateFile for stdout");
+ goto out;
+ }
+
+ if (!CreatePipe(&stdin_read, &stdin_write, &inheritable, 0) ||
+ !SetHandleInformation(stdin_write, HANDLE_FLAG_INHERIT, 0))
+ {
+ ReturnLastError (pipe, L"CreatePipe");
+ goto out;
+ }
+
+ openvpn_sntprintf (ovpn_pipe_name, _countof (ovpn_pipe_name),
+ TEXT("\\\\.\\pipe\\openvpn\\service_%lu"), GetCurrentThreadId ());
+ ovpn_pipe = CreateNamedPipe (ovpn_pipe_name,
+ PIPE_ACCESS_DUPLEX | FILE_FLAG_FIRST_PIPE_INSTANCE | FILE_FLAG_OVERLAPPED,
+ PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, 1, 128, 128, 0, NULL);
+ if (ovpn_pipe == INVALID_HANDLE_VALUE)
+ {
+ ReturnLastError (pipe, L"CreateNamedPipe");
+ goto out;
+ }
+
+ svc_pipe = CreateFile (ovpn_pipe_name, GENERIC_READ | GENERIC_WRITE, 0,
+ &inheritable, OPEN_EXISTING, 0, NULL);
+ if (svc_pipe == INVALID_HANDLE_VALUE)
+ {
+ ReturnLastError (pipe, L"CreateFile");
+ goto out;
+ }
+
+ pipe_mode = PIPE_READMODE_MESSAGE;
+ if (!SetNamedPipeHandleState (svc_pipe, &pipe_mode, NULL, NULL))
+ {
+ ReturnLastError (pipe, L"SetNamedPipeHandleState");
+ goto out;
+ }
+
+ cmdline_size = wcslen (sud.options) + 128;
+ cmdline = malloc (cmdline_size * sizeof (*cmdline));
+ if (cmdline == NULL)
+ {
+ ReturnLastError (pipe, L"malloc");
+ goto out;
+ }
+ openvpn_sntprintf (cmdline, cmdline_size, L"openvpn %s --msg-channel %lu",
+ sud.options, svc_pipe);
+
+ if (!CreateEnvironmentBlock (&user_env, imp_token, FALSE))
+ {
+ ReturnLastError (pipe, L"CreateEnvironmentBlock");
+ goto out;
+ }
+
+ startup_info.cb = sizeof (startup_info);
+ startup_info.lpDesktop = L"winsta0\\default";
+ startup_info.dwFlags = STARTF_USESTDHANDLES;
+ startup_info.hStdInput = stdin_read;
+ startup_info.hStdOutput = stdout_write;
+ startup_info.hStdError = stdout_write;
+
+#ifdef UNICODE
+ exe_path = settings.exe_path;
+#else
+ WCHAR wide_path[MAX_PATH];
+ MultiByteToWideChar (CP_UTF8, 0, settings.exe_path, MAX_PATH, wide_path, MAX_PATH);
+ exe_path = wide_path;
+#endif
+
+ // TODO: make sure HKCU is correct or call LoadUserProfile()
+ if (!CreateProcessAsUserW (pri_token, exe_path, cmdline, &ovpn_sa, NULL, TRUE,
+ settings.priority | CREATE_NO_WINDOW | CREATE_UNICODE_ENVIRONMENT,
+ user_env, sud.directory, &startup_info, &proc_info))
+ {
+ ReturnLastError (pipe, L"CreateProcessAsUser");
+ goto out;
+ }
+
+ if (!RevertToSelf ())
+ {
+ TerminateProcess (proc_info.hProcess, 1);
+ ReturnLastError (pipe, L"RevertToSelf");
+ goto out;
+ }
+
+ ReturnProcessId (pipe, proc_info.dwProcessId, 1, &exit_event);
+
+ CloseHandleEx (&stdout_write);
+ CloseHandleEx (&stdin_read);
+ CloseHandleEx (&svc_pipe);
+
+ DWORD input_size = WideCharToMultiByte (CP_UTF8, 0, sud.std_input, -1, NULL, 0, NULL, NULL);
+ LPSTR input = NULL;
+ if (input_size && (input = malloc (input_size)))
+ {
+ DWORD written;
+ WideCharToMultiByte (CP_UTF8, 0, sud.std_input, -1, input, input_size, NULL, NULL);
+ WriteFile (stdin_write, input, strlen (input), &written, NULL);
+ free (input);
+ }
+
+ while (TRUE)
+ {
+ DWORD bytes = PeekNamedPipeAsync (ovpn_pipe, 1, &exit_event);
+ if (bytes == 0)
+ break;
+
+ HandleMessage (ovpn_pipe, bytes, 1, &exit_event, &undo_lists);
+ }
+
+ WaitForSingleObject (proc_info.hProcess, IO_TIMEOUT);
+ GetExitCodeProcess (proc_info.hProcess, &exit_code);
+ if (exit_code == STILL_ACTIVE)
+ TerminateProcess (proc_info.hProcess, 1);
+ else if (exit_code != 0)
+ {
+ WCHAR buf[256];
+ int len = _snwprintf (buf, _countof (buf),
+ L"OpenVPN exited with error: exit code = %lu", exit_code);
+ buf[_countof (buf) - 1] = L'\0';
+ ReturnError (pipe, ERROR_OPENVPN_STARTUP, buf, 1, &exit_event);
+ }
+ Undo (&undo_lists);
+
+out:
+ FlushFileBuffers (pipe);
+ DisconnectNamedPipe (pipe);
+
+ free (ovpn_user);
+ free (svc_user);
+ free (cmdline);
+ DestroyEnvironmentBlock (user_env);
+ FreeStartupData (&sud);
+ CloseHandleEx (&proc_info.hProcess);
+ CloseHandleEx (&proc_info.hThread);
+ CloseHandleEx (&stdin_read);
+ CloseHandleEx (&stdin_write);
+ CloseHandleEx (&stdout_write);
+ CloseHandleEx (&svc_token);
+ CloseHandleEx (&imp_token);
+ CloseHandleEx (&pri_token);
+ CloseHandleEx (&ovpn_pipe);
+ CloseHandleEx (&svc_pipe);
+ CloseHandleEx (&pipe);
+
+ return 0;
+}
+
+
+static DWORD WINAPI
+ServiceCtrlInteractive (DWORD ctrl_code, DWORD event, LPVOID data, LPVOID ctx)
+{
+ SERVICE_STATUS *status = ctx;
+ switch (ctrl_code)
+ {
+ case SERVICE_CONTROL_STOP:
+ status->dwCurrentState = SERVICE_STOP_PENDING;
+ ReportStatusToSCMgr (service, status);
+ if (exit_event)
+ SetEvent (exit_event);
+ return NO_ERROR;
+
+ case SERVICE_CONTROL_INTERROGATE:
+ return NO_ERROR;
+
+ default:
+ return ERROR_CALL_NOT_IMPLEMENTED;
+ }
+}
+
+
+static HANDLE
+CreateClientPipeInstance (VOID)
+{
+ HANDLE pipe = NULL;
+ PACL old_dacl, new_dacl;
+ PSECURITY_DESCRIPTOR sd;
+ static EXPLICIT_ACCESS ea[2];
+ static BOOL initialized = FALSE;
+ DWORD flags = PIPE_ACCESS_DUPLEX | WRITE_DAC | FILE_FLAG_OVERLAPPED;
+
+ if (!initialized)
+ {
+ PSID everyone, anonymous;
+
+ ConvertStringSidToSid (TEXT("S-1-1-0"), &everyone);
+ ConvertStringSidToSid (TEXT("S-1-5-7"), &anonymous);
+
+ ea[0].grfAccessPermissions = FILE_GENERIC_WRITE;
+ ea[0].grfAccessMode = GRANT_ACCESS;
+ ea[0].grfInheritance = NO_INHERITANCE;
+ ea[0].Trustee.pMultipleTrustee = NULL;
+ ea[0].Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
+ ea[0].Trustee.TrusteeForm = TRUSTEE_IS_SID;
+ ea[0].Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
+ ea[0].Trustee.ptstrName = (LPTSTR) everyone;
+
+ ea[1].grfAccessPermissions = 0;
+ ea[1].grfAccessMode = REVOKE_ACCESS;
+ ea[1].grfInheritance = NO_INHERITANCE;
+ ea[1].Trustee.pMultipleTrustee = NULL;
+ ea[1].Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
+ ea[1].Trustee.TrusteeForm = TRUSTEE_IS_SID;
+ ea[1].Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
+ ea[1].Trustee.ptstrName = (LPTSTR) anonymous;
+
+ flags |= FILE_FLAG_FIRST_PIPE_INSTANCE;
+ initialized = TRUE;
+ }
+
+ pipe = CreateNamedPipe (TEXT("\\\\.\\pipe\\openvpn\\service"), flags,
+ PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE,
+ PIPE_UNLIMITED_INSTANCES, 1024, 1024, 0, NULL);
+ if (pipe == INVALID_HANDLE_VALUE)
+ {
+ MsgToEventLog (M_SYSERR, TEXT("Could not create named pipe"));
+ return INVALID_HANDLE_VALUE;
+ }
+
+ if (GetSecurityInfo (pipe, SE_KERNEL_OBJECT, DACL_SECURITY_INFORMATION,
+ NULL, NULL, &old_dacl, NULL, &sd) != ERROR_SUCCESS)
+ {
+ MsgToEventLog (M_SYSERR, TEXT("Could not get pipe security info"));
+ return CloseHandleEx (&pipe);
+ }
+
+ if (SetEntriesInAcl (2, ea, old_dacl, &new_dacl) != ERROR_SUCCESS)
+ {
+ MsgToEventLog (M_SYSERR, TEXT("Could not set entries in new acl"));
+ return CloseHandleEx (&pipe);
+ }
+
+ if (SetSecurityInfo (pipe, SE_KERNEL_OBJECT, DACL_SECURITY_INFORMATION,
+ NULL, NULL, new_dacl, NULL) != ERROR_SUCCESS)
+ {
+ MsgToEventLog (M_SYSERR, TEXT("Could not set pipe security info"));
+ return CloseHandleEx (&pipe);
+ }
+
+ return pipe;
+}
+
+
+static DWORD
+UpdateWaitHandles (LPHANDLE *handles_ptr, LPDWORD count,
+ HANDLE io_event, HANDLE exit_event, list_item_t *threads)
+{
+ static DWORD size = 10;
+ static LPHANDLE handles = NULL;
+ DWORD pos = 0;
+
+ if (handles == NULL)
+ {
+ handles = malloc (size * sizeof (HANDLE));
+ *handles_ptr = handles;
+ if (handles == NULL)
+ return ERROR_OUTOFMEMORY;
+ }
+
+ handles[pos++] = io_event;
+
+ if (!threads)
+ handles[pos++] = exit_event;
+
+ while (threads)
+ {
+ if (pos == size)
+ {
+ LPHANDLE tmp;
+ size += 10;
+ tmp = realloc (handles, size * sizeof (HANDLE));
+ if (tmp == NULL)
+ {
+ size -= 10;
+ *count = pos;
+ return ERROR_OUTOFMEMORY;
+ }
+ handles = tmp;
+ *handles_ptr = handles;
+ }
+ handles[pos++] = threads->data;
+ threads = threads->next;
+ }
+
+ *count = pos;
+ return NO_ERROR;
+}
+
+
+static VOID
+FreeWaitHandles (LPHANDLE h)
+{
+ free (h);
+}
+
+
+VOID WINAPI
+ServiceStartInteractive (DWORD dwArgc, LPTSTR *lpszArgv)
+{
+ HANDLE pipe, io_event = NULL;
+ OVERLAPPED overlapped;
+ DWORD error = NO_ERROR;
+ list_item_t *threads = NULL;
+ PHANDLE handles = NULL;
+ DWORD handle_count;
+ BOOL CmpHandle (LPVOID item, LPVOID hnd) { return item == hnd; }
+
+ service = RegisterServiceCtrlHandlerEx (interactive_service.name, ServiceCtrlInteractive, &status);
+ if (!service)
+ return;
+
+ status.dwServiceType = SERVICE_WIN32_SHARE_PROCESS;
+ status.dwCurrentState = SERVICE_START_PENDING;
+ status.dwServiceSpecificExitCode = NO_ERROR;
+ status.dwWin32ExitCode = NO_ERROR;
+ status.dwWaitHint = 3000;
+ ReportStatusToSCMgr (service, &status);
+
+ /* Read info from registry in key HKLM\SOFTWARE\OpenVPN */
+ error = GetOpenvpnSettings (&settings);
+ if (error != ERROR_SUCCESS)
+ goto out;
+
+ io_event = InitOverlapped (&overlapped);
+ exit_event = CreateEvent (NULL, TRUE, FALSE, NULL);
+ if (!exit_event || !io_event)
+ {
+ error = MsgToEventLog (M_SYSERR, TEXT("Could not create event"));
+ goto out;
+ }
+
+ rdns_semaphore = CreateSemaphoreW (NULL, 1, 1, NULL);
+ if (!rdns_semaphore)
+ {
+ error = MsgToEventLog (M_SYSERR, TEXT("Could not create semaphore for register-dns"));
+ goto out;
+ }
+
+ error = UpdateWaitHandles (&handles, &handle_count, io_event, exit_event, threads);
+ if (error != NO_ERROR)
+ goto out;
+
+ pipe = CreateClientPipeInstance ();
+ if (pipe == INVALID_HANDLE_VALUE)
+ goto out;
+
+ status.dwCurrentState = SERVICE_RUNNING;
+ status.dwWaitHint = 0;
+ ReportStatusToSCMgr (service, &status);
+
+ while (TRUE)
+ {
+ if (ConnectNamedPipe (pipe, &overlapped) == FALSE &&
+ GetLastError () != ERROR_PIPE_CONNECTED &&
+ GetLastError () != ERROR_IO_PENDING)
+ {
+ MsgToEventLog (M_SYSERR, TEXT("Could not connect pipe"));
+ break;
+ }
+
+ error = WaitForMultipleObjects (handle_count, handles, FALSE, INFINITE);
+ if (error == WAIT_OBJECT_0)
+ {
+ /* Client connected, spawn a worker thread for it */
+ HANDLE next_pipe = CreateClientPipeInstance ();
+ HANDLE thread = CreateThread (NULL, 0, RunOpenvpn, pipe, CREATE_SUSPENDED, NULL);
+ if (thread)
+ {
+ error = AddListItem (&threads, thread);
+ if (!error)
+ error = UpdateWaitHandles (&handles, &handle_count, io_event, exit_event, threads);
+ if (error)
+ {
+ ReturnError (pipe, error, L"Insufficient resources to service new clients", 1, &exit_event);
+ /* Update wait handles again after removing the last worker thread */
+ RemoveListItem (&threads, CmpHandle, thread);
+ UpdateWaitHandles (&handles, &handle_count, io_event, exit_event, threads);
+ TerminateThread (thread, 1);
+ CloseHandleEx (&thread);
+ CloseHandleEx (&pipe);
+ }
+ else
+ ResumeThread (thread);
+ }
+ else
+ CloseHandleEx (&pipe);
+
+ ResetOverlapped (&overlapped);
+ pipe = next_pipe;
+ }
+ else
+ {
+ CancelIo (pipe);
+ if (error == WAIT_FAILED)
+ {
+ MsgToEventLog (M_SYSERR, TEXT("WaitForMultipleObjects failed"));
+ SetEvent (exit_event);
+ /* Give some time for worker threads to exit and then terminate */
+ Sleep (1000);
+ break;
+ }
+ if (!threads)
+ {
+ /* exit event signaled */
+ CloseHandleEx (&pipe);
+ ResetEvent (exit_event);
+ error = NO_ERROR;
+ break;
+ }
+
+ /* Worker thread ended */
+ HANDLE thread = RemoveListItem (&threads, CmpHandle, handles[error]);
+ UpdateWaitHandles (&handles, &handle_count, io_event, exit_event, threads);
+ CloseHandleEx (&thread);
+ }
+ }
+
+out:
+ FreeWaitHandles (handles);
+ CloseHandleEx (&io_event);
+ CloseHandleEx (&exit_event);
+ CloseHandleEx (&rdns_semaphore);
+
+ status.dwCurrentState = SERVICE_STOPPED;
+ status.dwWin32ExitCode = error;
+ ReportStatusToSCMgr (service, &status);
+}
diff --git a/src/openvpnserv/openvpnserv.c b/src/openvpnserv/openvpnserv.c
deleted file mode 100755
index 56f5a02..0000000
--- a/src/openvpnserv/openvpnserv.c
+++ /dev/null
@@ -1,534 +0,0 @@
-/*
- * OpenVPN -- An application to securely tunnel IP networks
- * over a single TCP/UDP port, with support for SSL/TLS-based
- * session authentication and key exchange,
- * packet encryption, packet authentication, and
- * packet compression.
- *
- * Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program (see the file COPYING included with this
- * distribution); if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/*
- * This program allows one or more OpenVPN processes to be started
- * as a service. To build, you must get the service sample from the
- * Platform SDK and replace Simple.c with this file.
- *
- * You should also apply service.patch to
- * service.c and service.h from the Platform SDK service sample.
- *
- * This code is designed to be built with the mingw compiler.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#elif defined(_MSC_VER)
-#include "config-msvc.h"
-#endif
-#include <windows.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <process.h>
-#include "service.h"
-
-/* bool definitions */
-#define bool int
-#define true 1
-#define false 0
-
-/* These are new for 2000/XP, so they aren't in the mingw headers yet */
-#ifndef BELOW_NORMAL_PRIORITY_CLASS
-#define BELOW_NORMAL_PRIORITY_CLASS 0x00004000
-#endif
-#ifndef ABOVE_NORMAL_PRIORITY_CLASS
-#define ABOVE_NORMAL_PRIORITY_CLASS 0x00008000
-#endif
-
-struct security_attributes
-{
- SECURITY_ATTRIBUTES sa;
- SECURITY_DESCRIPTOR sd;
-};
-
-/*
- * This event is initially created in the non-signaled
- * state. It will transition to the signaled state when
- * we have received a terminate signal from the Service
- * Control Manager which will cause an asynchronous call
- * of ServiceStop below.
- */
-#define EXIT_EVENT_NAME PACKAGE "_exit_1"
-
-/*
- * Which registry key in HKLM should
- * we get config info from?
- */
-#define REG_KEY "SOFTWARE\\" PACKAGE_NAME
-
-static HANDLE exit_event = NULL;
-
-/* clear an object */
-#define CLEAR(x) memset(&(x), 0, sizeof(x))
-
-/*
- * Message handling
- */
-#define M_INFO (0) /* informational */
-#define M_SYSERR (MSG_FLAGS_ERROR|MSG_FLAGS_SYS_CODE) /* error + system code */
-#define M_ERR (MSG_FLAGS_ERROR) /* error */
-
-/* write error to event log */
-#define MSG(flags, ...) \
- { \
- char x_msg[256]; \
- openvpn_snprintf (x_msg, sizeof(x_msg), __VA_ARGS__); \
- AddToMessageLog ((flags), x_msg); \
- }
-
-/* get a registry string */
-#define QUERY_REG_STRING(name, data) \
- { \
- len = sizeof (data); \
- status = RegQueryValueEx(openvpn_key, name, NULL, &type, data, &len); \
- if (status != ERROR_SUCCESS || type != REG_SZ) \
- { \
- SetLastError (status); \
- MSG (M_SYSERR, error_format_str, name); \
- RegCloseKey (openvpn_key); \
- goto finish; \
- } \
- }
-
-/* get a registry string */
-#define QUERY_REG_DWORD(name, data) \
- { \
- len = sizeof (DWORD); \
- status = RegQueryValueEx(openvpn_key, name, NULL, &type, (LPBYTE)&data, &len); \
- if (status != ERROR_SUCCESS || type != REG_DWORD || len != sizeof (DWORD)) \
- { \
- SetLastError (status); \
- MSG (M_SYSERR, error_format_dword, name); \
- RegCloseKey (openvpn_key); \
- goto finish; \
- } \
- }
-
-/*
- * This is necessary due to certain buggy implementations of snprintf,
- * that don't guarantee null termination for size > 0.
- * (copied from ../buffer.c, line 217)
- * (git: 100644 blob e2f8caab0a5b2a870092c6cd508a1a50c21c3ba3 buffer.c)
- */
-
-int openvpn_snprintf(char *str, size_t size, const char *format, ...)
-{
- va_list arglist;
- int len = -1;
- if (size > 0)
- {
- va_start (arglist, format);
- len = vsnprintf (str, size, format, arglist);
- va_end (arglist);
- str[size - 1] = 0;
- }
- return (len >= 0 && len < size);
-}
-
-
-bool
-init_security_attributes_allow_all (struct security_attributes *obj)
-{
- CLEAR (*obj);
-
- obj->sa.nLength = sizeof (SECURITY_ATTRIBUTES);
- obj->sa.lpSecurityDescriptor = &obj->sd;
- obj->sa.bInheritHandle = TRUE;
- if (!InitializeSecurityDescriptor (&obj->sd, SECURITY_DESCRIPTOR_REVISION))
- return false;
- if (!SetSecurityDescriptorDacl (&obj->sd, TRUE, NULL, FALSE))
- return false;
- return true;
-}
-
-HANDLE
-create_event (const char *name, bool allow_all, bool initial_state, bool manual_reset)
-{
- if (allow_all)
- {
- struct security_attributes sa;
- if (!init_security_attributes_allow_all (&sa))
- return NULL;
- return CreateEvent (&sa.sa, (BOOL)manual_reset, (BOOL)initial_state, name);
- }
- else
- return CreateEvent (NULL, (BOOL)manual_reset, (BOOL)initial_state, name);
-}
-
-void
-close_if_open (HANDLE h)
-{
- if (h != NULL)
- CloseHandle (h);
-}
-
-static bool
-match (const WIN32_FIND_DATA *find, const char *ext)
-{
- int i;
-
- if (find->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
- return false;
-
- if (!strlen (ext))
- return true;
-
- i = strlen (find->cFileName) - strlen (ext) - 1;
- if (i < 1)
- return false;
-
- return find->cFileName[i] == '.' && !_stricmp (find->cFileName + i + 1, ext);
-}
-
-/*
- * Modify the extension on a filename.
- */
-static bool
-modext (char *dest, int size, const char *src, const char *newext)
-{
- int i;
-
- if (size > 0 && (strlen (src) + 1) <= size)
- {
- strcpy (dest, src);
- dest [size - 1] = '\0';
- i = strlen (dest);
- while (--i >= 0)
- {
- if (dest[i] == '\\')
- break;
- if (dest[i] == '.')
- {
- dest[i] = '\0';
- break;
- }
- }
- if (strlen (dest) + strlen(newext) + 2 <= size)
- {
- strcat (dest, ".");
- strcat (dest, newext);
- return true;
- }
- dest [0] = '\0';
- }
- return false;
-}
-
-VOID ServiceStart (DWORD dwArgc, LPTSTR *lpszArgv)
-{
- char exe_path[MAX_PATH];
- char config_dir[MAX_PATH];
- char ext_string[16];
- char log_dir[MAX_PATH];
- char priority_string[64];
- char append_string[2];
-
- DWORD priority;
- bool append;
-
- ResetError ();
-
- if (!ReportStatusToSCMgr(SERVICE_START_PENDING, NO_ERROR, 3000))
- {
- MSG (M_ERR, "ReportStatusToSCMgr #1 failed");
- goto finish;
- }
-
- /*
- * Create our exit event
- */
- exit_event = create_event (EXIT_EVENT_NAME, false, false, true);
- if (!exit_event)
- {
- MSG (M_ERR, "CreateEvent failed");
- goto finish;
- }
-
- /*
- * If exit event is already signaled, it means we were not
- * shut down properly.
- */
- if (WaitForSingleObject (exit_event, 0) != WAIT_TIMEOUT)
- {
- MSG (M_ERR, "Exit event is already signaled -- we were not shut down properly");
- goto finish;
- }
-
- if (!ReportStatusToSCMgr(SERVICE_START_PENDING, NO_ERROR, 3000))
- {
- MSG (M_ERR, "ReportStatusToSCMgr #2 failed");
- goto finish;
- }
-
- /*
- * Read info from registry in key HKLM\SOFTWARE\OpenVPN
- */
- {
- HKEY openvpn_key;
- LONG status;
- DWORD len;
- DWORD type;
-
- static const char error_format_str[] =
- "Error querying registry key of type REG_SZ: HKLM\\" REG_KEY "\\%s";
-
- static const char error_format_dword[] =
- "Error querying registry key of type REG_DWORD: HKLM\\" REG_KEY "\\%s";
-
- status = RegOpenKeyEx(
- HKEY_LOCAL_MACHINE,
- REG_KEY,
- 0,
- KEY_READ,
- &openvpn_key);
-
- if (status != ERROR_SUCCESS)
- {
- SetLastError (status);
- MSG (M_SYSERR, "Registry key HKLM\\" REG_KEY " not found");
- goto finish;
- }
-
- /* get path to openvpn.exe */
- QUERY_REG_STRING ("exe_path", exe_path);
-
- /* get path to configuration directory */
- QUERY_REG_STRING ("config_dir", config_dir);
-
- /* get extension on configuration files */
- QUERY_REG_STRING ("config_ext", ext_string);
-
- /* get path to log directory */
- QUERY_REG_STRING ("log_dir", log_dir);
-
- /* get priority for spawned OpenVPN subprocesses */
- QUERY_REG_STRING ("priority", priority_string);
-
- /* should we truncate or append to logfile? */
- QUERY_REG_STRING ("log_append", append_string);
-
- RegCloseKey (openvpn_key);
- }
-
- /* set process priority */
- priority = NORMAL_PRIORITY_CLASS;
- if (!_stricmp (priority_string, "IDLE_PRIORITY_CLASS"))
- priority = IDLE_PRIORITY_CLASS;
- else if (!_stricmp (priority_string, "BELOW_NORMAL_PRIORITY_CLASS"))
- priority = BELOW_NORMAL_PRIORITY_CLASS;
- else if (!_stricmp (priority_string, "NORMAL_PRIORITY_CLASS"))
- priority = NORMAL_PRIORITY_CLASS;
- else if (!_stricmp (priority_string, "ABOVE_NORMAL_PRIORITY_CLASS"))
- priority = ABOVE_NORMAL_PRIORITY_CLASS;
- else if (!_stricmp (priority_string, "HIGH_PRIORITY_CLASS"))
- priority = HIGH_PRIORITY_CLASS;
- else
- {
- MSG (M_ERR, "Unknown priority name: %s", priority_string);
- goto finish;
- }
-
- /* set log file append/truncate flag */
- append = false;
- if (append_string[0] == '0')
- append = false;
- else if (append_string[0] == '1')
- append = true;
- else
- {
- MSG (M_ERR, "Log file append flag (given as '%s') must be '0' or '1'", append_string);
- goto finish;
- }
-
- /*
- * Instantiate an OpenVPN process for each configuration
- * file found.
- */
- {
- WIN32_FIND_DATA find_obj;
- HANDLE find_handle;
- BOOL more_files;
- char find_string[MAX_PATH];
-
- openvpn_snprintf (find_string, MAX_PATH, "%s\\*", config_dir);
-
- find_handle = FindFirstFile (find_string, &find_obj);
- if (find_handle == INVALID_HANDLE_VALUE)
- {
- MSG (M_ERR, "Cannot get configuration file list using: %s", find_string);
- goto finish;
- }
-
- /*
- * Loop over each config file
- */
- do {
- HANDLE log_handle = NULL;
- STARTUPINFO start_info;
- PROCESS_INFORMATION proc_info;
- struct security_attributes sa;
- char log_file[MAX_PATH];
- char log_path[MAX_PATH];
- char command_line[256];
-
- CLEAR (start_info);
- CLEAR (proc_info);
- CLEAR (sa);
-
- if (!ReportStatusToSCMgr(SERVICE_START_PENDING, NO_ERROR, 3000))
- {
- MSG (M_ERR, "ReportStatusToSCMgr #3 failed");
- FindClose (find_handle);
- goto finish;
- }
-
- /* does file have the correct type and extension? */
- if (match (&find_obj, ext_string))
- {
- /* get log file pathname */
- if (!modext (log_file, sizeof (log_file), find_obj.cFileName, "log"))
- {
- MSG (M_ERR, "Cannot construct logfile name based on: %s", find_obj.cFileName);
- FindClose (find_handle);
- goto finish;
- }
- openvpn_snprintf (log_path, sizeof(log_path),
- "%s\\%s", log_dir, log_file);
-
- /* construct command line */
- openvpn_snprintf (command_line, sizeof(command_line), PACKAGE " --service %s 1 --config \"%s\"",
- EXIT_EVENT_NAME,
- find_obj.cFileName);
-
- /* Make security attributes struct for logfile handle so it can
- be inherited. */
- if (!init_security_attributes_allow_all (&sa))
- {
- MSG (M_SYSERR, "InitializeSecurityDescriptor start_" PACKAGE " failed");
- goto finish;
- }
-
- /* open logfile as stdout/stderr for soon-to-be-spawned subprocess */
- log_handle = CreateFile (log_path,
- GENERIC_WRITE,
- FILE_SHARE_READ,
- &sa.sa,
- append ? OPEN_ALWAYS : CREATE_ALWAYS,
- FILE_ATTRIBUTE_NORMAL,
- NULL);
-
- if (log_handle == INVALID_HANDLE_VALUE)
- {
- MSG (M_SYSERR, "Cannot open logfile: %s", log_path);
- FindClose (find_handle);
- goto finish;
- }
-
- /* append to logfile? */
- if (append)
- {
- if (SetFilePointer (log_handle, 0, NULL, FILE_END) == INVALID_SET_FILE_POINTER)
- {
- MSG (M_SYSERR, "Cannot seek to end of logfile: %s", log_path);
- FindClose (find_handle);
- goto finish;
- }
- }
-
- /* fill in STARTUPINFO struct */
- GetStartupInfo(&start_info);
- start_info.cb = sizeof(start_info);
- start_info.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
- start_info.wShowWindow = SW_HIDE;
- start_info.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
- start_info.hStdOutput = start_info.hStdError = log_handle;
-
- /* create an OpenVPN process for one config file */
- if (!CreateProcess(exe_path,
- command_line,
- NULL,
- NULL,
- TRUE,
- priority | CREATE_NEW_CONSOLE,
- NULL,
- config_dir,
- &start_info,
- &proc_info))
- {
- MSG (M_SYSERR, "CreateProcess failed, exe='%s' cmdline='%s' dir='%s'",
- exe_path,
- command_line,
- config_dir);
-
- FindClose (find_handle);
- CloseHandle (log_handle);
- goto finish;
- }
-
- /* close unneeded handles */
- Sleep (1000); /* try to prevent race if we close logfile
- handle before child process DUPs it */
- if (!CloseHandle (proc_info.hProcess)
- || !CloseHandle (proc_info.hThread)
- || !CloseHandle (log_handle))
- {
- MSG (M_SYSERR, "CloseHandle failed");
- goto finish;
- }
- }
-
- /* more files to process? */
- more_files = FindNextFile (find_handle, &find_obj);
-
- } while (more_files);
-
- FindClose (find_handle);
- }
-
- /* we are now fully started */
- if (!ReportStatusToSCMgr(SERVICE_RUNNING, NO_ERROR, 0))
- {
- MSG (M_ERR, "ReportStatusToSCMgr SERVICE_RUNNING failed");
- goto finish;
- }
-
- /* wait for our shutdown signal */
- if (WaitForSingleObject (exit_event, INFINITE) != WAIT_OBJECT_0)
- {
- MSG (M_ERR, "wait for shutdown signal failed");
- }
-
- finish:
- ServiceStop ();
- if (exit_event)
- CloseHandle (exit_event);
-}
-
-VOID ServiceStop()
-{
- if (exit_event)
- SetEvent(exit_event);
-}
diff --git a/src/openvpnserv/openvpnserv.vcxproj b/src/openvpnserv/openvpnserv.vcxproj
index 2a8943d..c6760da 100644
--- a/src/openvpnserv/openvpnserv.vcxproj
+++ b/src/openvpnserv/openvpnserv.vcxproj
@@ -111,4 +111,4 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
-</Project> \ No newline at end of file
+</Project>
diff --git a/src/openvpnserv/service.c b/src/openvpnserv/service.c
index d7562b3..82f5551 100644
--- a/src/openvpnserv/service.c
+++ b/src/openvpnserv/service.c
@@ -1,700 +1,245 @@
-/*---------------------------------------------------------------------------
-THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
-ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED
-TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
-PARTICULAR PURPOSE.
-
-Copyright (C) 1993 - 2000. Microsoft Corporation. All rights reserved.
-
-MODULE: service.c
-
-PURPOSE: Implements functions required by all Windows NT services
-
-FUNCTIONS:
- main(int argc, char **argv);
- service_ctrl(DWORD dwCtrlCode);
- service_main(DWORD dwArgc, LPTSTR *lpszArgv);
- CmdInstallService();
- CmdRemoveService();
- CmdStartService();
- CmdDebugService(int argc, char **argv);
- ControlHandler ( DWORD dwCtrlType );
- GetLastErrorText( LPTSTR lpszBuf, DWORD dwSize );
-
----------------------------------------------------------------------------*/
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#elif defined(_MSC_VER)
-#include "config-msvc.h"
-#endif
-#include <windows.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <process.h>
-#include <tchar.h>
+/*
+ * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
+ * ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED
+ * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
+ * PARTICULAR PURPOSE.
+ *
+ * Copyright (C) 1993 - 2000. Microsoft Corporation. All rights reserved.
+ * 2013 Heiko Hund <heiko.hund@sophos.com>
+ */
#include "service.h"
-// internal variables
-SERVICE_STATUS ssStatus; // current status of the service
-SERVICE_STATUS_HANDLE sshStatusHandle;
-DWORD dwErr = 0;
-BOOL bDebug = FALSE;
-TCHAR szErr[256];
-
-// internal function prototypes
-VOID WINAPI service_ctrl(DWORD dwCtrlCode);
-VOID WINAPI service_main(DWORD dwArgc, LPTSTR *lpszArgv);
-int CmdInstallService();
-int CmdRemoveService();
-int CmdStartService();
-VOID CmdDebugService(int argc, char **argv);
-BOOL WINAPI ControlHandler ( DWORD dwCtrlType );
-LPTSTR GetLastErrorText( LPTSTR lpszBuf, DWORD dwSize );
-
-//
-// FUNCTION: main
-//
-// PURPOSE: entrypoint for service
-//
-// PARAMETERS:
-// argc - number of command line arguments
-// argv - array of command line arguments
-//
-// RETURN VALUE:
-// none
-//
-// COMMENTS:
-// main() either performs the command line task, or
-// call StartServiceCtrlDispatcher to register the
-// main service thread. When the this call returns,
-// the service has stopped, so exit.
-//
-int __cdecl main(int argc, char **argv)
-{
- SERVICE_TABLE_ENTRY dispatchTable[] =
- {
- { TEXT(SZSERVICENAME), (LPSERVICE_MAIN_FUNCTION)service_main},
- { NULL, NULL}
- };
-
- if ( (argc > 1) &&
- ((*argv[1] == '-') || (*argv[1] == '/')) )
- {
- if ( _stricmp( "install", argv[1]+1 ) == 0 )
- {
- return CmdInstallService();
- }
- else if ( _stricmp( "remove", argv[1]+1 ) == 0 )
- {
- return CmdRemoveService();
- }
- else if ( _stricmp( "start", argv[1]+1 ) == 0)
- {
- return CmdStartService();
- }
- else if ( _stricmp( "debug", argv[1]+1 ) == 0 )
- {
- bDebug = TRUE;
- CmdDebugService(argc, argv);
- }
- else
- {
- goto dispatch;
- }
- return 0;
- }
-
- // if it doesn't match any of the above parameters
- // the service control manager may be starting the service
- // so we must call StartServiceCtrlDispatcher
- dispatch:
- // this is just to be friendly
- printf( "%s -install to install the service\n", SZAPPNAME );
- printf( "%s -start to start the service\n", SZAPPNAME );
- printf( "%s -remove to remove the service\n", SZAPPNAME );
- printf( "%s -debug <params> to run as a console app for debugging\n", SZAPPNAME );
- printf( "\nStartServiceCtrlDispatcher being called.\n" );
- printf( "This may take several seconds. Please wait.\n" );
-
- if (!StartServiceCtrlDispatcher(dispatchTable))
- AddToMessageLog(MSG_FLAGS_ERROR, TEXT("StartServiceCtrlDispatcher failed."));
-
- return 0;
-}
-
-
-
-//
-// FUNCTION: service_main
-//
-// PURPOSE: To perform actual initialization of the service
-//
-// PARAMETERS:
-// dwArgc - number of command line arguments
-// lpszArgv - array of command line arguments
-//
-// RETURN VALUE:
-// none
-//
-// COMMENTS:
-// This routine performs the service initialization and then calls
-// the user defined ServiceStart() routine to perform majority
-// of the work.
-//
-void WINAPI service_main(DWORD dwArgc, LPTSTR *lpszArgv)
-{
-
- // register our service control handler:
- //
- sshStatusHandle = RegisterServiceCtrlHandler( TEXT(SZSERVICENAME), service_ctrl);
-
- if (!sshStatusHandle)
- goto cleanup;
-
- // SERVICE_STATUS members that don't change in example
- //
- ssStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
- ssStatus.dwServiceSpecificExitCode = 0;
-
-
- // report the status to the service control manager.
- //
- if (!ReportStatusToSCMgr(
- SERVICE_START_PENDING, // service state
- NO_ERROR, // exit code
- 3000)) // wait hint
- goto cleanup;
-
-
- ServiceStart( dwArgc, lpszArgv );
-
- cleanup:
+#include <windows.h>
+#include <stdio.h>
+#include <process.h>
- // try to report the stopped status to the service control manager.
- //
- if (sshStatusHandle)
- (VOID)ReportStatusToSCMgr(
- SERVICE_STOPPED,
- dwErr,
- 0);
- return;
-}
+openvpn_service_t openvpn_service[_service_max];
-
-//
-// FUNCTION: service_ctrl
-//
-// PURPOSE: This function is called by the SCM whenever
-// ControlService() is called on this service.
-//
-// PARAMETERS:
-// dwCtrlCode - type of control requested
-//
-// RETURN VALUE:
-// none
-//
-// COMMENTS:
-//
-VOID WINAPI service_ctrl(DWORD dwCtrlCode)
+BOOL
+ReportStatusToSCMgr (SERVICE_STATUS_HANDLE service, SERVICE_STATUS *status)
{
- // Handle the requested control code.
- //
- switch (dwCtrlCode)
- {
- // Stop the service.
- //
- // SERVICE_STOP_PENDING should be reported before
- // setting the Stop Event - hServerStopEvent - in
- // ServiceStop(). This avoids a race condition
- // which may result in a 1053 - The Service did not respond...
- // error.
- case SERVICE_CONTROL_STOP:
- ReportStatusToSCMgr(SERVICE_STOP_PENDING, NO_ERROR, 0);
- ServiceStop();
- return;
-
- // Update the service status.
- //
- case SERVICE_CONTROL_INTERROGATE:
- break;
-
- // invalid control code
- //
- default:
- break;
-
- }
-
- ReportStatusToSCMgr(ssStatus.dwCurrentState, NO_ERROR, 0);
+ static DWORD dwCheckPoint = 1;
+ BOOL res = TRUE;
+
+ if (status->dwCurrentState == SERVICE_START_PENDING)
+ status->dwControlsAccepted = 0;
+ else
+ status->dwControlsAccepted = SERVICE_ACCEPT_STOP;
+
+ if (status->dwCurrentState == SERVICE_RUNNING ||
+ status->dwCurrentState == SERVICE_STOPPED)
+ status->dwCheckPoint = 0;
+ else
+ status->dwCheckPoint = dwCheckPoint++;
+
+ /* Report the status of the service to the service control manager. */
+ res = SetServiceStatus (service, status);
+ if (!res)
+ MsgToEventLog(MSG_FLAGS_ERROR, TEXT("SetServiceStatus"));
+
+ return res;
}
-
-
-//
-// FUNCTION: ReportStatusToSCMgr()
-//
-// PURPOSE: Sets the current status of the service and
-// reports it to the Service Control Manager
-//
-// PARAMETERS:
-// dwCurrentState - the state of the service
-// dwWin32ExitCode - error code to report
-// dwWaitHint - worst case estimate to next checkpoint
-//
-// RETURN VALUE:
-// TRUE - success
-// FALSE - failure
-//
-// COMMENTS:
-//
-BOOL ReportStatusToSCMgr(DWORD dwCurrentState,
- DWORD dwWin32ExitCode,
- DWORD dwWaitHint)
+static int
+CmdInstallServices ()
{
- static DWORD dwCheckPoint = 1;
- BOOL fResult = TRUE;
-
-
- if ( !bDebug ) // when debugging we don't report to the SCM
- {
- if (dwCurrentState == SERVICE_START_PENDING)
- ssStatus.dwControlsAccepted = 0;
- else
- ssStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
-
- ssStatus.dwCurrentState = dwCurrentState;
- ssStatus.dwWin32ExitCode = dwWin32ExitCode;
- ssStatus.dwWaitHint = dwWaitHint;
+ SC_HANDLE service;
+ SC_HANDLE svc_ctl_mgr;
+ TCHAR path[512];
+ int i, ret = _service_max;
+
+ if (GetModuleFileName (NULL, path + 1, 510) == 0)
+ {
+ _tprintf (TEXT("Unable to install service - %s\n"), GetLastErrorText ());
+ return 1;
+ }
+
+ path[0] = TEXT('\"');
+ _tcscat (path, TEXT("\""));
+
+ svc_ctl_mgr = OpenSCManager (NULL, NULL, SC_MANAGER_CONNECT | SC_MANAGER_CREATE_SERVICE);
+ if (svc_ctl_mgr == NULL)
+ {
+ _tprintf (TEXT("OpenSCManager failed - %s\n"), GetLastErrorText ());
+ return 1;
+ }
- if ( ( dwCurrentState == SERVICE_RUNNING ) ||
- ( dwCurrentState == SERVICE_STOPPED ) )
- ssStatus.dwCheckPoint = 0;
+ for (i = 0; i < _service_max; i++)
+ {
+ service = CreateService (svc_ctl_mgr,
+ openvpn_service[i].name,
+ openvpn_service[i].display_name,
+ SERVICE_QUERY_STATUS,
+ SERVICE_WIN32_SHARE_PROCESS,
+ openvpn_service[i].start_type,
+ SERVICE_ERROR_NORMAL,
+ path, NULL, NULL,
+ openvpn_service[i].dependencies,
+ NULL, NULL);
+ if (service)
+ {
+ _tprintf (TEXT("%s installed.\n"), openvpn_service[i].display_name);
+ CloseServiceHandle (service);
+ --ret;
+ }
else
- ssStatus.dwCheckPoint = dwCheckPoint++;
-
+ _tprintf (TEXT("CreateService failed - %s\n"), GetLastErrorText ());
+ }
- // Report the status of the service to the service control manager.
- //
- if (!(fResult = SetServiceStatus( sshStatusHandle, &ssStatus)))
- {
- AddToMessageLog(MSG_FLAGS_ERROR, TEXT("SetServiceStatus"));
- }
- }
- return fResult;
+ CloseServiceHandle (svc_ctl_mgr);
+ return ret;
}
-
-//
-// FUNCTION: AddToMessageLog(LPTSTR lpszMsg)
-//
-// PURPOSE: Allows any thread to log an error message
-//
-// PARAMETERS:
-// lpszMsg - text for message
-//
-// RETURN VALUE:
-// none
-//
-// COMMENTS:
-//
-void AddToMessageLog(DWORD flags, LPTSTR lpszMsg)
+static int
+CmdStartService (openvpn_service_type type)
{
- TCHAR szMsg [(sizeof(SZSERVICENAME) / sizeof(TCHAR)) + 100 ];
- HANDLE hEventSource;
- LPCSTR lpszStrings[2];
-
- if ( !bDebug )
- {
- if (flags & MSG_FLAGS_SYS_CODE)
- dwErr = GetLastError();
- else
- dwErr = 0;
-
- // Use event logging to log the error.
- //
- hEventSource = RegisterEventSource(NULL, TEXT(SZSERVICENAME));
-
- _stprintf(szMsg, TEXT("%s error: %d"), TEXT(SZSERVICENAME), (int)dwErr);
- lpszStrings[0] = szMsg;
- lpszStrings[1] = lpszMsg;
-
- if (hEventSource != NULL)
- {
- ReportEvent(hEventSource, // handle of event source
- // event type
- (flags & MSG_FLAGS_ERROR)
- ? EVENTLOG_ERROR_TYPE : EVENTLOG_INFORMATION_TYPE,
- 0, // event category
- 0, // event ID
- NULL, // current user's SID
- 2, // strings in lpszStrings
- 0, // no bytes of raw data
- lpszStrings, // array of error strings
- NULL); // no raw data
-
- (VOID) DeregisterEventSource(hEventSource);
- }
- }
-}
-
-void ResetError (void)
-{
- dwErr = 0;
-}
+ int ret = 1;
+ SC_HANDLE svc_ctl_mgr;
+ SC_HANDLE service;
-///////////////////////////////////////////////////////////////////
-//
-// The following code handles service installation and removal
-//
-
-
-//
-// FUNCTION: CmdInstallService()
-//
-// PURPOSE: Installs the service
-//
-// PARAMETERS:
-// none
-//
-// RETURN VALUE:
-// 0 if success
-//
-// COMMENTS:
-//
-int CmdInstallService()
-{
- SC_HANDLE schService;
- SC_HANDLE schSCManager;
-
- TCHAR szPath[512];
-
- int ret = 0;
-
- if ( GetModuleFileName( NULL, szPath+1, 510 ) == 0 )
- {
- _tprintf(TEXT("Unable to install %s - %s\n"), TEXT(SZSERVICEDISPLAYNAME), GetLastErrorText(szErr, 256));
+ svc_ctl_mgr = OpenSCManager (NULL, NULL, SC_MANAGER_ALL_ACCESS);
+ if (svc_ctl_mgr == NULL)
+ {
+ _tprintf (TEXT("OpenSCManager failed - %s\n"), GetLastErrorText ());
return 1;
- }
- szPath[0] = '\"';
- strcat(szPath, "\"");
-
- schSCManager = OpenSCManager(
- NULL, // machine (NULL == local)
- NULL, // database (NULL == default)
- SC_MANAGER_CONNECT | SC_MANAGER_CREATE_SERVICE // access required
- );
- if ( schSCManager )
- {
- schService = CreateService(
- schSCManager, // SCManager database
- TEXT(SZSERVICENAME), // name of service
- TEXT(SZSERVICEDISPLAYNAME), // name to display
- SERVICE_QUERY_STATUS, // desired access
- SERVICE_WIN32_OWN_PROCESS, // service type
- SERVICE_DEMAND_START, // start type -- alternative: SERVICE_AUTO_START
- SERVICE_ERROR_NORMAL, // error control type
- szPath, // service's binary
- NULL, // no load ordering group
- NULL, // no tag identifier
- TEXT(SZDEPENDENCIES), // dependencies
- NULL, // LocalSystem account
- NULL); // no password
-
- if ( schService )
- {
- _tprintf(TEXT("%s installed.\n"), TEXT(SZSERVICEDISPLAYNAME) );
- CloseServiceHandle(schService);
- }
- else
- {
- _tprintf(TEXT("CreateService failed - %s\n"), GetLastErrorText(szErr, 256));
- ret = 1;
- }
-
- CloseServiceHandle(schSCManager);
- }
- else
- {
- _tprintf(TEXT("OpenSCManager failed - %s\n"), GetLastErrorText(szErr,256));
- ret = 1;
- }
- return ret;
-}
-
-//
-// FUNCTION: CmdStartService()
-//
-// PURPOSE: Start the service
-//
-// PARAMETERS:
-// none
-//
-// RETURN VALUE:
-// 0 if success
-//
-// COMMENTS:
-
-int CmdStartService()
-{
- int ret = 0;
-
- SC_HANDLE schSCManager;
- SC_HANDLE schService;
-
-
- // Open a handle to the SC Manager database.
- schSCManager = OpenSCManager(
- NULL, // local machine
- NULL, // ServicesActive database
- SC_MANAGER_ALL_ACCESS); // full access rights
-
- if (NULL == schSCManager) {
- _tprintf(TEXT("OpenSCManager failed - %s\n"), GetLastErrorText(szErr,256));
- ret = 1;
}
- schService = OpenService(
- schSCManager, // SCM database
- SZSERVICENAME, // service name
- SERVICE_ALL_ACCESS);
+ service = OpenService (svc_ctl_mgr, openvpn_service[type].name, SERVICE_ALL_ACCESS);
+ if (service)
+ {
+ if (StartService (service, 0, NULL))
+ {
+ _tprintf (TEXT("Service Started\n"));
+ ret = 0;
+ }
+ else
+ _tprintf (TEXT("StartService failed - %s\n"), GetLastErrorText ());
- if (schService == NULL) {
- _tprintf(TEXT("OpenService failed - %s\n"), GetLastErrorText(szErr,256));
- ret = 1;
+ CloseServiceHandle(service);
}
-
- if (!StartService(
- schService, // handle to service
- 0, // number of arguments
- NULL) ) // no arguments
+ else
{
- _tprintf(TEXT("StartService failed - %s\n"), GetLastErrorText(szErr,256));
- ret = 1;
+ _tprintf (TEXT("OpenService failed - %s\n"), GetLastErrorText ());
}
- else
- {
- _tprintf(TEXT("Service Started\n"));
- ret = 0;
- }
- CloseServiceHandle(schService);
- CloseServiceHandle(schSCManager);
- return ret;
-}
-//
-// FUNCTION: CmdRemoveService()
-//
-// PURPOSE: Stops and removes the service
-//
-// PARAMETERS:
-// none
-//
-// RETURN VALUE:
-// 0 if success
-//
-// COMMENTS:
-//
-int CmdRemoveService()
-{
- SC_HANDLE schService;
- SC_HANDLE schSCManager;
+ CloseServiceHandle(svc_ctl_mgr);
+ return ret;
+}
- int ret = 0;
- schSCManager = OpenSCManager(
- NULL, // machine (NULL == local)
- NULL, // database (NULL == default)
- SC_MANAGER_CONNECT // access required
- );
- if ( schSCManager )
- {
- schService = OpenService(schSCManager, TEXT(SZSERVICENAME), DELETE | SERVICE_STOP | SERVICE_QUERY_STATUS);
+static int
+CmdRemoveServices ()
+{
+ SC_HANDLE service;
+ SC_HANDLE svc_ctl_mgr;
+ SERVICE_STATUS status;
+ int i, ret = _service_max;
- if (schService)
- {
- // try to stop the service
- if ( ControlService( schService, SERVICE_CONTROL_STOP, &ssStatus ) )
- {
- _tprintf(TEXT("Stopping %s."), TEXT(SZSERVICEDISPLAYNAME));
- Sleep( 1000 );
+ svc_ctl_mgr = OpenSCManager (NULL, NULL, SC_MANAGER_CONNECT);
+ if (svc_ctl_mgr == NULL)
+ {
+ _tprintf(TEXT("OpenSCManager failed - %s\n"), GetLastErrorText ());
+ return 1;
+ }
- while ( QueryServiceStatus( schService, &ssStatus ) )
+ for (i = 0; i < _service_max; i++)
+ {
+ openvpn_service_t *ovpn_svc = &openvpn_service[i];
+ service = OpenService (svc_ctl_mgr, ovpn_svc->name,
+ DELETE | SERVICE_STOP | SERVICE_QUERY_STATUS);
+ if (service == NULL)
+ {
+ _tprintf (TEXT("OpenService failed - %s\n"), GetLastErrorText ());
+ goto out;
+ }
+
+ /* try to stop the service */
+ if (ControlService (service, SERVICE_CONTROL_STOP, &status))
+ {
+ _tprintf (TEXT("Stopping %s."), ovpn_svc->display_name);
+ Sleep (1000);
+
+ while (QueryServiceStatus (service, &status))
{
- if ( ssStatus.dwCurrentState == SERVICE_STOP_PENDING )
- {
- _tprintf(TEXT("."));
- Sleep( 1000 );
- }
- else
- break;
+ if (status.dwCurrentState == SERVICE_STOP_PENDING)
+ {
+ _tprintf (TEXT("."));
+ Sleep (1000);
+ }
+ else
+ break;
}
- if ( ssStatus.dwCurrentState == SERVICE_STOPPED )
- _tprintf(TEXT("\n%s stopped.\n"), TEXT(SZSERVICEDISPLAYNAME) );
- else
- {
- _tprintf(TEXT("\n%s failed to stop.\n"), TEXT(SZSERVICEDISPLAYNAME) );
- ret = 1;
- }
-
- }
-
- // now remove the service
- if ( DeleteService(schService) )
- _tprintf(TEXT("%s removed.\n"), TEXT(SZSERVICEDISPLAYNAME) );
- else
- {
- _tprintf(TEXT("DeleteService failed - %s\n"), GetLastErrorText(szErr,256));
- ret = 1;
- }
-
-
- CloseServiceHandle(schService);
- }
+ if (status.dwCurrentState == SERVICE_STOPPED)
+ _tprintf (TEXT("\n%s stopped.\n"), ovpn_svc->display_name);
+ else
+ _tprintf (TEXT("\n%s failed to stop.\n"), ovpn_svc->display_name);
+ }
+
+ /* now remove the service */
+ if (DeleteService (service))
+ {
+ _tprintf (TEXT("%s removed.\n"), ovpn_svc->display_name);
+ --ret;
+ }
else
- {
- _tprintf(TEXT("OpenService failed - %s\n"), GetLastErrorText(szErr,256));
- ret = 1;
- }
-
- CloseServiceHandle(schSCManager);
- }
- else
- {
- _tprintf(TEXT("OpenSCManager failed - %s\n"), GetLastErrorText(szErr,256));
- ret = 1;
- }
- return ret;
-}
-
-
-
-
-///////////////////////////////////////////////////////////////////
-//
-// The following code is for running the service as a console app
-//
-
-
-//
-// FUNCTION: CmdDebugService(int argc, char ** argv)
-//
-// PURPOSE: Runs the service as a console application
-//
-// PARAMETERS:
-// argc - number of command line arguments
-// argv - array of command line arguments
-//
-// RETURN VALUE:
-// none
-//
-// COMMENTS:
-//
-void CmdDebugService(int argc, char ** argv)
-{
- DWORD dwArgc;
- LPTSTR *lpszArgv;
-
-#ifdef UNICODE
- lpszArgv = CommandLineToArgvW(GetCommandLineW(), &(dwArgc) );
- if (NULL == lpszArgv)
- {
- // CommandLineToArvW failed!!
- _tprintf(TEXT("CmdDebugService CommandLineToArgvW returned NULL\n"));
- return;
- }
-#else
- dwArgc = (DWORD) argc;
- lpszArgv = argv;
-#endif
-
- _tprintf(TEXT("Debugging %s.\n"), TEXT(SZSERVICEDISPLAYNAME));
-
- SetConsoleCtrlHandler( ControlHandler, TRUE );
+ _tprintf (TEXT("DeleteService failed - %s\n"), GetLastErrorText ());
- ServiceStart( dwArgc, lpszArgv );
-
-#ifdef UNICODE
-// Must free memory allocated for arguments
-
- GlobalFree(lpszArgv);
-#endif // UNICODE
+ CloseServiceHandle (service);
+ }
+out:
+ CloseServiceHandle (svc_ctl_mgr);
+ return ret;
}
-//
-// FUNCTION: ControlHandler ( DWORD dwCtrlType )
-//
-// PURPOSE: Handled console control events
-//
-// PARAMETERS:
-// dwCtrlType - type of control event
-//
-// RETURN VALUE:
-// True - handled
-// False - unhandled
-//
-// COMMENTS:
-//
-BOOL WINAPI ControlHandler ( DWORD dwCtrlType )
+int
+_tmain (int argc, TCHAR *argv[])
{
- switch ( dwCtrlType )
- {
- case CTRL_BREAK_EVENT: // use Ctrl+C or Ctrl+Break to simulate
- case CTRL_C_EVENT: // SERVICE_CONTROL_STOP in debug mode
- _tprintf(TEXT("Stopping %s.\n"), TEXT(SZSERVICEDISPLAYNAME));
- ServiceStop();
- return TRUE;
- break;
-
- }
- return FALSE;
-}
-
-//
-// FUNCTION: GetLastErrorText
-//
-// PURPOSE: copies error message text to string
-//
-// PARAMETERS:
-// lpszBuf - destination buffer
-// dwSize - size of buffer
-//
-// RETURN VALUE:
-// destination buffer
-//
-// COMMENTS:
-//
-LPTSTR GetLastErrorText( LPTSTR lpszBuf, DWORD dwSize )
-{
- DWORD dwRet;
- LPTSTR lpszTemp = NULL;
-
- dwRet = FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |FORMAT_MESSAGE_ARGUMENT_ARRAY,
- NULL,
- GetLastError(),
- LANG_NEUTRAL,
- (LPTSTR)&lpszTemp,
- 0,
- NULL );
-
- // supplied buffer is not long enough
- if ( !dwRet || ( (long)dwSize < (long)dwRet+14 ) )
- lpszBuf[0] = TEXT('\0');
- else
- {
- lpszTemp[lstrlen(lpszTemp)-2] = TEXT('\0'); //remove cr and newline character
- _stprintf( lpszBuf, TEXT("%s (0x%x)"), lpszTemp, (int)GetLastError() );
- }
-
- if ( lpszTemp )
- LocalFree((HLOCAL) lpszTemp );
-
- return lpszBuf;
+ SERVICE_TABLE_ENTRY dispatchTable[] = {
+ { automatic_service.name, ServiceStartAutomatic },
+ { interactive_service.name, ServiceStartInteractive },
+ { NULL, NULL }
+ };
+
+ openvpn_service[0] = automatic_service;
+ openvpn_service[1] = interactive_service;
+
+ if (argc > 1 && (*argv[1] == TEXT('-') || *argv[1] == TEXT('/')))
+ {
+ if (_tcsicmp (TEXT("install"), argv[1] + 1) == 0)
+ return CmdInstallServices ();
+ else if (_tcsicmp (TEXT("remove"), argv[1] + 1) == 0)
+ return CmdRemoveServices ();
+ else if (_tcsicmp (TEXT("start"), argv[1] + 1) == 0)
+ {
+ BOOL is_auto = argc < 3 || _tcsicmp (TEXT("interactive"), argv[2]) != 0;
+ return CmdStartService (is_auto ? automatic : interactive);
+ }
+ else
+ goto dispatch;
+
+ return 0;
+ }
+
+ /* If it doesn't match any of the above parameters
+ * the service control manager may be starting the service
+ * so we must call StartServiceCtrlDispatcher
+ */
+dispatch:
+ _tprintf (TEXT("%s -install to install the services\n"), APPNAME);
+ _tprintf (TEXT("%s -start <name> to start a service (\"automatic\" or \"interactive\")\n"), APPNAME);
+ _tprintf (TEXT("%s -remove to remove the services\n"), APPNAME);
+ _tprintf (TEXT("\nStartServiceCtrlDispatcher being called.\n"));
+ _tprintf (TEXT("This may take several seconds. Please wait.\n"));
+
+ if (!StartServiceCtrlDispatcher (dispatchTable))
+ MsgToEventLog (MSG_FLAGS_ERROR, TEXT("StartServiceCtrlDispatcher failed."));
+
+ return 0;
}
diff --git a/src/openvpnserv/service.h b/src/openvpnserv/service.h
index e89a89f..94bfb07 100644
--- a/src/openvpnserv/service.h
+++ b/src/openvpnserv/service.h
@@ -1,139 +1,92 @@
-/*---------------------------------------------------------------------------
-THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
-ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED
-TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
-PARTICULAR PURPOSE.
-
-Copyright (C) 1993 - 2000. Microsoft Corporation. All rights reserved.
-
- MODULE: service.h
-
- Comments: The use of this header file and the accompanying service.c
- file simplifies the process of writting a service. You as a developer
- simply need to follow the TODO's outlined in this header file, and
- implement the ServiceStart() and ServiceStop() functions.
-
- There is no need to modify the code in service.c. Just add service.c
- to your project and link with the following libraries...
-
- libcmt.lib kernel32.lib advapi.lib shell32.lib
-
- This code also supports unicode. Be sure to compile both service.c and
- and code #include "service.h" with the same Unicode setting.
-
- Upon completion, your code will have the following command line interface
-
- <service exe> -? to display this list
- <service exe> -install to install the service
- <service exe> -remove to remove the service
- <service exe> -debug <params> to run as a console app for debugging
-
- Note: This code also implements Ctrl+C and Ctrl+Break handlers
- when using the debug option. These console events cause
- your ServiceStop routine to be called
-
- Also, this code only handles the OWN_SERVICE service type
- running in the LOCAL_SYSTEM security context.
-
- To control your service ( start, stop, etc ) you may use the
- Services control panel applet or the NET.EXE program.
-
- To aid in writing/debugging service, the
- SDK contains a utility (MSTOOLS\BIN\SC.EXE) that
- can be used to control, configure, or obtain service status.
- SC displays complete status for any service/driver
- in the service database, and allows any of the configuration
- parameters to be easily changed at the command line.
- For more information on SC.EXE, type SC at the command line.
-
-
-------------------------------------------------------------------------------*/
+/*
+ * OpenVPN -- An application to securely tunnel IP networks
+ * over a single TCP/UDP port, with support for SSL/TLS-based
+ * session authentication and key exchange,
+ * packet encryption, packet authentication, and
+ * packet compression.
+ *
+ * Copyright (C) 2013 Heiko Hund <heiko.hund@sophos.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program (see the file COPYING included with this
+ * distribution); if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
#ifndef _SERVICE_H
#define _SERVICE_H
-
-#ifdef __cplusplus
-extern "C" {
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#elif defined(_MSC_VER)
+#include "config-msvc.h"
#endif
-//////////////////////////////////////////////////////////////////////////////
-//// todo: change to desired strings
-////
-// name of the executable
-#define SZAPPNAME PACKAGE "serv"
-// internal name of the service
-#define SZSERVICENAME PACKAGE_NAME "Service"
-// displayed name of the service
-#define SZSERVICEDISPLAYNAME PACKAGE_NAME " Service"
-// list of service dependencies - "dep1\0dep2\0\0"
-#define SZDEPENDENCIES TAP_WIN_COMPONENT_ID "\0Dhcp\0\0"
-//////////////////////////////////////////////////////////////////////////////
-
-
-
-//////////////////////////////////////////////////////////////////////////////
-//// todo: ServiceStart()must be defined by in your code.
-//// The service should use ReportStatusToSCMgr to indicate
-//// progress. This routine must also be used by StartService()
-//// to report to the SCM when the service is running.
-////
-//// If a ServiceStop procedure is going to take longer than
-//// 3 seconds to execute, it should spawn a thread to
-//// execute the stop code, and return. Otherwise, the
-//// ServiceControlManager will believe that the service has
-//// stopped responding
-////
- VOID ServiceStart(DWORD dwArgc, LPTSTR *lpszArgv);
- VOID ServiceStop();
-//////////////////////////////////////////////////////////////////////////////
-
-
-
-//////////////////////////////////////////////////////////////////////////////
-//// The following are procedures which
-//// may be useful to call within the above procedures,
-//// but require no implementation by the user.
-//// They are implemented in service.c
-
-//
-// FUNCTION: ReportStatusToSCMgr()
-//
-// PURPOSE: Sets the current status of the service and
-// reports it to the Service Control Manager
-//
-// PARAMETERS:
-// dwCurrentState - the state of the service
-// dwWin32ExitCode - error code to report
-// dwWaitHint - worst case estimate to next checkpoint
-//
-// RETURN VALUE:
-// TRUE - success
-// FALSE - failure
-//
- BOOL ReportStatusToSCMgr(DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD dwWaitHint);
-
-
-//
-// FUNCTION: AddToMessageLog(LPTSTR lpszMsg)
-//
-// PURPOSE: Allows any thread to log an error message
-//
-// PARAMETERS:
-// lpszMsg - text for message
-//
-// RETURN VALUE:
-// none
-//
-# define MSG_FLAGS_ERROR (1<<0)
-# define MSG_FLAGS_SYS_CODE (1<<1)
- void AddToMessageLog(DWORD flags, LPTSTR lpszMsg);
- void ResetError (void);
-//////////////////////////////////////////////////////////////////////////////
-
-
-#ifdef __cplusplus
-}
-#endif
+#include <windows.h>
+#include <stdlib.h>
+#include <tchar.h>
+
+#define APPNAME TEXT(PACKAGE "serv")
+#define SERVICE_DEPENDENCIES TAP_WIN_COMPONENT_ID "\0Dhcp\0\0"
+
+/*
+ * Message handling
+ */
+#define MSG_FLAGS_ERROR (1<<0)
+#define MSG_FLAGS_SYS_CODE (1<<1)
+#define M_INFO (0) /* informational */
+#define M_SYSERR (MSG_FLAGS_ERROR|MSG_FLAGS_SYS_CODE) /* error + system code */
+#define M_ERR (MSG_FLAGS_ERROR) /* error */
+
+typedef enum {
+ automatic,
+ interactive,
+ _service_max
+} openvpn_service_type;
+
+typedef struct {
+ openvpn_service_type type;
+ TCHAR *name;
+ TCHAR *display_name;
+ TCHAR *dependencies;
+ DWORD start_type;
+} openvpn_service_t;
+
+#define MAX_NAME 256
+typedef struct {
+ TCHAR exe_path[MAX_PATH];
+ TCHAR config_dir[MAX_PATH];
+ TCHAR ext_string[16];
+ TCHAR log_dir[MAX_PATH];
+ TCHAR ovpn_admin_group[MAX_NAME];
+ DWORD priority;
+ BOOL append;
+} settings_t;
+
+extern openvpn_service_t automatic_service;
+extern openvpn_service_t interactive_service;
+
+
+VOID WINAPI ServiceStartAutomatic (DWORD argc, LPTSTR *argv);
+VOID WINAPI ServiceStartInteractive (DWORD argc, LPTSTR *argv);
+
+int openvpn_vsntprintf (LPTSTR str, size_t size, LPCTSTR format, va_list arglist);
+int openvpn_sntprintf (LPTSTR str, size_t size, LPCTSTR format, ...);
+
+DWORD GetOpenvpnSettings (settings_t *s);
+
+BOOL ReportStatusToSCMgr (SERVICE_STATUS_HANDLE service, SERVICE_STATUS *status);
+
+LPCTSTR GetLastErrorText ();
+DWORD MsgToEventLog (DWORD flags, LPCTSTR lpszMsg, ...);
#endif
diff --git a/src/openvpnserv/validate.c b/src/openvpnserv/validate.c
new file mode 100644
index 0000000..7458d75
--- /dev/null
+++ b/src/openvpnserv/validate.c
@@ -0,0 +1,249 @@
+/*
+ * OpenVPN -- An application to securely tunnel IP networks
+ * over a single TCP/UDP port, with support for SSL/TLS-based
+ * session authentication and key exchange,
+ * packet encryption, packet authentication, and
+ * packet compression.
+ *
+ * Copyright (C) 2016 Selva Nair <selva.nair@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program (see the file COPYING included with this
+ * distribution); if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "validate.h"
+
+#include <lmaccess.h>
+#include <shlwapi.h>
+#include <lm.h>
+
+static const WCHAR *white_list[] =
+ {
+ L"auth-retry",
+ L"config",
+ L"log",
+ L"log-append",
+ L"management",
+ L"management-forget-disconnect",
+ L"management-hold",
+ L"management-query-passwords",
+ L"management-query-proxy",
+ L"management-signal",
+ L"management-up-down",
+ L"mute",
+ L"setenv",
+ L"service",
+ L"verb",
+
+ NULL /* last value */
+ };
+
+/*
+ * Check workdir\fname is inside config_dir
+ * The logic here is simple: we may reject some valid paths if ..\ is in any of the strings
+ */
+static BOOL
+CheckConfigPath (const WCHAR *workdir, const WCHAR *fname, const settings_t *s)
+{
+ WCHAR tmp[MAX_PATH];
+ const WCHAR *config_file = NULL;
+ const WCHAR *config_dir = NULL;
+
+ /* convert fname to full path */
+ if (PathIsRelativeW (fname) )
+ {
+ snwprintf (tmp, _countof(tmp), L"%s\\%s", workdir, fname);
+ tmp[_countof(tmp)-1] = L'\0';
+ config_file = tmp;
+ }
+ else
+ {
+ config_file = fname;
+ }
+
+#ifdef UNICODE
+ config_dir = s->config_dir;
+#else
+ if (MultiByteToWideChar (CP_UTF8, 0, s->config_dir, -1, widepath, MAX_PATH) == 0)
+ {
+ MsgToEventLog (M_SYSERR, TEXT("Failed to convert config_dir name to WideChar"));
+ return FALSE;
+ }
+ config_dir = widepath;
+#endif
+
+ if (wcsncmp (config_dir, config_file, wcslen(config_dir)) == 0 &&
+ wcsstr (config_file + wcslen(config_dir), L"..") == NULL )
+ return TRUE;
+
+ return FALSE;
+}
+
+
+/*
+ * A simple linear search meant for a small wchar_t *array.
+ * Returns index to the item if found, -1 otherwise.
+ */
+static int
+OptionLookup (const WCHAR *name, const WCHAR *white_list[])
+{
+ int i;
+
+ for (i = 0 ; white_list[i]; i++)
+ {
+ if ( wcscmp(white_list[i], name) == 0 )
+ return i;
+ }
+
+ return -1;
+}
+
+/*
+ * The Administrators group may be localized or renamed by admins.
+ * Get the local name of the group using the SID.
+ */
+static BOOL
+GetBuiltinAdminGroupName (WCHAR *name, DWORD nlen)
+{
+ BOOL b = FALSE;
+ PSID admin_sid = NULL;
+ DWORD sid_size = SECURITY_MAX_SID_SIZE;
+ SID_NAME_USE snu;
+
+ WCHAR domain[MAX_NAME];
+ DWORD dlen = _countof(domain);
+
+ admin_sid = malloc(sid_size);
+ if (!admin_sid)
+ return FALSE;
+
+ b = CreateWellKnownSid(WinBuiltinAdministratorsSid, NULL, admin_sid, &sid_size);
+ if(b)
+ {
+ b = LookupAccountSidW(NULL, admin_sid, name, &nlen, domain, &dlen, &snu);
+ }
+
+ free (admin_sid);
+
+ return b;
+}
+
+/*
+ * Check whether user is a member of Administrators group or
+ * the group specified in s->ovpn_admin_group
+ */
+BOOL
+IsAuthorizedUser (SID *sid, settings_t *s)
+{
+ LOCALGROUP_USERS_INFO_0 *groups = NULL;
+ DWORD nread;
+ DWORD nmax;
+ WCHAR *tmp = NULL;
+ const WCHAR *admin_group[2];
+ WCHAR username[MAX_NAME];
+ WCHAR domain[MAX_NAME];
+ WCHAR sysadmin_group[MAX_NAME];
+ DWORD err, len = MAX_NAME;
+ int i;
+ BOOL ret = FALSE;
+ SID_NAME_USE sid_type;
+
+ /* Get username */
+ if (!LookupAccountSidW (NULL, sid, username, &len, domain, &len, &sid_type))
+ {
+ MsgToEventLog (M_SYSERR, TEXT("LookupAccountSid"));
+ goto out;
+ }
+
+ /* Get an array of groups the user is member of */
+ err = NetUserGetLocalGroups (NULL, username, 0, LG_INCLUDE_INDIRECT, (LPBYTE *) &groups,
+ MAX_PREFERRED_LENGTH, &nread, &nmax);
+ if (err && err != ERROR_MORE_DATA)
+ {
+ SetLastError (err);
+ MsgToEventLog (M_SYSERR, TEXT("NetUserGetLocalGroups"));
+ goto out;
+ }
+
+ if (GetBuiltinAdminGroupName(sysadmin_group, _countof(sysadmin_group)))
+ {
+ admin_group[0] = sysadmin_group;
+ }
+ else
+ {
+ MsgToEventLog (M_SYSERR, TEXT("Failed to get the name of Administrators group. Using the default."));
+ /* use the default value */
+ admin_group[0] = SYSTEM_ADMIN_GROUP;
+ }
+
+#ifdef UNICODE
+ admin_group[1] = s->ovpn_admin_group;
+#else
+ tmp = NULL;
+ len = MultiByteToWideChar (CP_UTF8, 0, s->ovpn_admin_group, -1, NULL, 0);
+ if (len == 0 || (tmp = malloc (len*sizeof(WCHAR))) == NULL)
+ {
+ MsgToEventLog (M_SYSERR, TEXT("Failed to convert admin group name to WideChar"));
+ goto out;
+ }
+ MultiByteToWideChar (CP_UTF8, 0, s->ovpn_admin_group, -1, tmp, len);
+ admin_group[1] = tmp;
+#endif
+
+ /* Check if user's groups include any of the admin groups */
+ for (i = 0; i < nread; i++)
+ {
+ if ( wcscmp (groups[i].lgrui0_name, admin_group[0]) == 0 ||
+ wcscmp (groups[i].lgrui0_name, admin_group[1]) == 0
+ )
+ {
+ MsgToEventLog (M_INFO, TEXT("Authorizing user %s by virtue of membership in group %s"),
+ username, groups[i].lgrui0_name);
+ ret = TRUE;
+ break;
+ }
+ }
+
+out:
+ if (groups)
+ NetApiBufferFree (groups);
+ free (tmp);
+
+ return ret;
+}
+
+/*
+ * Check whether option argv[0] is white-listed. If argv[0] == "--config",
+ * also check that argv[1], if present, passes CheckConfigPath().
+ * The caller should set argc to the number of valid elements in argv[] array.
+ */
+BOOL
+CheckOption (const WCHAR *workdir, int argc, WCHAR *argv[], const settings_t *s)
+{
+ /* Do not modify argv or *argv -- ideally it should be const WCHAR *const *, but alas...*/
+
+ if ( wcscmp (argv[0], L"--config") == 0 &&
+ argc > 1 &&
+ !CheckConfigPath (workdir, argv[1], s)
+ )
+ {
+ return FALSE;
+ }
+
+ /* option name starts at 2 characters from argv[i] */
+ if (OptionLookup (argv[0] + 2, white_list) == -1) /* not found */
+ return FALSE;
+
+ return TRUE;
+}
diff --git a/src/openvpnserv/validate.h b/src/openvpnserv/validate.h
new file mode 100644
index 0000000..0d0270a
--- /dev/null
+++ b/src/openvpnserv/validate.h
@@ -0,0 +1,48 @@
+
+/*
+ * OpenVPN -- An application to securely tunnel IP networks
+ * over a single TCP/UDP port, with support for SSL/TLS-based
+ * session authentication and key exchange,
+ * packet encryption, packet authentication, and
+ * packet compression.
+ *
+ * Copyright (C) 2016 Selva Nair <selva.nair@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program (see the file COPYING included with this
+ * distribution); if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef VALIDATE_H
+#define VALIDATE_H
+
+#include "service.h"
+
+/* Authorized groups who can use any options and config locations */
+#define SYSTEM_ADMIN_GROUP TEXT("Administrators")
+#define OVPN_ADMIN_GROUP TEXT("OpenVPN Administrators")
+/* The last one may be reset in registry: HKLM\Software\OpenVPN\ovpn_admin_group */
+
+BOOL
+IsAuthorizedUser (SID *sid, settings_t *s);
+
+BOOL
+CheckOption (const WCHAR *workdir, int narg, WCHAR *argv[], const settings_t *s);
+
+static inline BOOL
+IsOption (const WCHAR *o)
+{
+ return (wcsncmp (o, L"--", 2) == 0);
+}
+
+#endif
diff --git a/src/plugins/Makefile.in b/src/plugins/Makefile.in
index cc26bf4..0d1d59b 100644
--- a/src/plugins/Makefile.in
+++ b/src/plugins/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.15 from Makefile.am.
+# Makefile.in generated by automake 1.13.4 from Makefile.am.
# @configure_input@
-# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -25,17 +25,7 @@
# Copyright (C) 2006-2012 Alon Bar-Lev <alon.barlev@gmail.com>
#
VPATH = @srcdir@
-am__is_gnu_make = { \
- if test -z '$(MAKELEVEL)'; then \
- false; \
- elif test -n '$(MAKE_HOST)'; then \
- true; \
- elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
- true; \
- else \
- false; \
- fi; \
-}
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
am__make_running_with_option = \
case $${target_option-} in \
?) ;; \
@@ -99,6 +89,7 @@ POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
subdir = src/plugins
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/ax_emptyarray.m4 \
$(top_srcdir)/m4/ax_socklen_t.m4 \
@@ -109,9 +100,9 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_emptyarray.m4 \
$(top_srcdir)/compat.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
-DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
mkinstalldirs = $(install_sh) -d
-CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_HEADER = $(top_builddir)/config.h \
+ $(top_builddir)/include/openvpn-plugin.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
AM_V_P = $(am__v_P_@AM_V@)
@@ -169,7 +160,6 @@ am__define_uniq_tagged_files = \
ETAGS = etags
CTAGS = ctags
DIST_SUBDIRS = $(SUBDIRS)
-am__DIST_COMMON = $(srcdir)/Makefile.in
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
am__relativize = \
dir0=`pwd`; \
@@ -208,6 +198,7 @@ AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
+CMAKE = @CMAKE@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
@@ -242,25 +233,31 @@ LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
-LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+LZ4_CFLAGS = @LZ4_CFLAGS@
+LZ4_LIBS = @LZ4_LIBS@
LZO_CFLAGS = @LZO_CFLAGS@
LZO_LIBS = @LZO_LIBS@
MAKEINFO = @MAKEINFO@
MAN2HTML = @MAN2HTML@
MANIFEST_TOOL = @MANIFEST_TOOL@
+MBEDTLS_CFLAGS = @MBEDTLS_CFLAGS@
+MBEDTLS_LIBS = @MBEDTLS_LIBS@
MKDIR_P = @MKDIR_P@
NETSTAT = @NETSTAT@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
-OPENSSL_CRYPTO_CFLAGS = @OPENSSL_CRYPTO_CFLAGS@
-OPENSSL_CRYPTO_LIBS = @OPENSSL_CRYPTO_LIBS@
-OPENSSL_SSL_CFLAGS = @OPENSSL_SSL_CFLAGS@
-OPENSSL_SSL_LIBS = @OPENSSL_SSL_LIBS@
+OPENSSL_CFLAGS = @OPENSSL_CFLAGS@
+OPENSSL_LIBS = @OPENSSL_LIBS@
+OPENVPN_VERSION_MAJOR = @OPENVPN_VERSION_MAJOR@
+OPENVPN_VERSION_MINOR = @OPENVPN_VERSION_MINOR@
+OPENVPN_VERSION_PATCH = @OPENVPN_VERSION_PATCH@
OPTIONAL_CRYPTO_CFLAGS = @OPTIONAL_CRYPTO_CFLAGS@
OPTIONAL_CRYPTO_LIBS = @OPTIONAL_CRYPTO_LIBS@
OPTIONAL_DL_LIBS = @OPTIONAL_DL_LIBS@
+OPTIONAL_LZ4_CFLAGS = @OPTIONAL_LZ4_CFLAGS@
+OPTIONAL_LZ4_LIBS = @OPTIONAL_LZ4_LIBS@
OPTIONAL_LZO_CFLAGS = @OPTIONAL_LZO_CFLAGS@
OPTIONAL_LZO_LIBS = @OPTIONAL_LZO_LIBS@
OPTIONAL_PKCS11_HELPER_CFLAGS = @OPTIONAL_PKCS11_HELPER_CFLAGS@
@@ -286,8 +283,6 @@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
PLUGIN_AUTH_PAM_CFLAGS = @PLUGIN_AUTH_PAM_CFLAGS@
PLUGIN_AUTH_PAM_LIBS = @PLUGIN_AUTH_PAM_LIBS@
-POLARSSL_CFLAGS = @POLARSSL_CFLAGS@
-POLARSSL_LIBS = @POLARSSL_LIBS@
RANLIB = @RANLIB@
RC = @RC@
ROUTE = @ROUTE@
@@ -302,6 +297,11 @@ TAP_CFLAGS = @TAP_CFLAGS@
TAP_WIN_COMPONENT_ID = @TAP_WIN_COMPONENT_ID@
TAP_WIN_MIN_MAJOR = @TAP_WIN_MIN_MAJOR@
TAP_WIN_MIN_MINOR = @TAP_WIN_MIN_MINOR@
+TEST_CFLAGS = @TEST_CFLAGS@
+TEST_LDFLAGS = @TEST_LDFLAGS@
+VENDOR_BUILD_ROOT = @VENDOR_BUILD_ROOT@
+VENDOR_DIST_ROOT = @VENDOR_DIST_ROOT@
+VENDOR_SRC_ROOT = @VENDOR_SRC_ROOT@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
@@ -378,6 +378,7 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/plugins/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign src/plugins/Makefile
+.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
@@ -673,8 +674,6 @@ uninstall-am:
mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
ps ps-am tags tags-am uninstall uninstall-am
-.PRECIOUS: Makefile
-
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
diff --git a/src/plugins/auth-pam/Makefile.am b/src/plugins/auth-pam/Makefile.am
index 2aef311..e6dc27e 100644
--- a/src/plugins/auth-pam/Makefile.am
+++ b/src/plugins/auth-pam/Makefile.am
@@ -18,6 +18,7 @@ dist_doc_DATA = README.auth-pam
endif
openvpn_plugin_auth_pam_la_SOURCES = \
+ utils.c \
auth-pam.c \
pamdl.c pamdl.h \
auth-pam.exports
diff --git a/src/plugins/auth-pam/Makefile.in b/src/plugins/auth-pam/Makefile.in
index ee67141..90d5058 100644
--- a/src/plugins/auth-pam/Makefile.in
+++ b/src/plugins/auth-pam/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.15 from Makefile.am.
+# Makefile.in generated by automake 1.13.4 from Makefile.am.
# @configure_input@
-# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -22,17 +22,7 @@
VPATH = @srcdir@
-am__is_gnu_make = { \
- if test -z '$(MAKELEVEL)'; then \
- false; \
- elif test -n '$(MAKE_HOST)'; then \
- true; \
- elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
- true; \
- else \
- false; \
- fi; \
-}
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
am__make_running_with_option = \
case $${target_option-} in \
?) ;; \
@@ -96,6 +86,8 @@ POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
subdir = src/plugins/auth-pam
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+ $(top_srcdir)/depcomp $(am__dist_doc_DATA_DIST)
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/ax_emptyarray.m4 \
$(top_srcdir)/m4/ax_socklen_t.m4 \
@@ -106,10 +98,9 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_emptyarray.m4 \
$(top_srcdir)/compat.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
-DIST_COMMON = $(srcdir)/Makefile.am $(am__dist_doc_DATA_DIST) \
- $(am__DIST_COMMON)
mkinstalldirs = $(install_sh) -d
-CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_HEADER = $(top_builddir)/config.h \
+ $(top_builddir)/include/openvpn-plugin.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
@@ -143,7 +134,7 @@ am__installdirs = "$(DESTDIR)$(plugindir)" "$(DESTDIR)$(docdir)"
LTLIBRARIES = $(plugin_LTLIBRARIES)
am__DEPENDENCIES_1 =
openvpn_plugin_auth_pam_la_DEPENDENCIES = $(am__DEPENDENCIES_1)
-am_openvpn_plugin_auth_pam_la_OBJECTS = auth-pam.lo pamdl.lo
+am_openvpn_plugin_auth_pam_la_OBJECTS = utils.lo auth-pam.lo pamdl.lo
openvpn_plugin_auth_pam_la_OBJECTS = \
$(am_openvpn_plugin_auth_pam_la_OBJECTS)
AM_V_lt = $(am__v_lt_@AM_V@)
@@ -168,7 +159,7 @@ AM_V_at = $(am__v_at_@AM_V@)
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
am__v_at_0 = @
am__v_at_1 =
-DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) -I$(top_builddir)/include
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
am__mv = mv -f
@@ -218,7 +209,6 @@ am__define_uniq_tagged_files = \
done | $(am__uniquify_input)`
ETAGS = etags
CTAGS = ctags
-am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
@@ -232,6 +222,7 @@ AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
+CMAKE = @CMAKE@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
@@ -266,25 +257,31 @@ LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
-LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+LZ4_CFLAGS = @LZ4_CFLAGS@
+LZ4_LIBS = @LZ4_LIBS@
LZO_CFLAGS = @LZO_CFLAGS@
LZO_LIBS = @LZO_LIBS@
MAKEINFO = @MAKEINFO@
MAN2HTML = @MAN2HTML@
MANIFEST_TOOL = @MANIFEST_TOOL@
+MBEDTLS_CFLAGS = @MBEDTLS_CFLAGS@
+MBEDTLS_LIBS = @MBEDTLS_LIBS@
MKDIR_P = @MKDIR_P@
NETSTAT = @NETSTAT@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
-OPENSSL_CRYPTO_CFLAGS = @OPENSSL_CRYPTO_CFLAGS@
-OPENSSL_CRYPTO_LIBS = @OPENSSL_CRYPTO_LIBS@
-OPENSSL_SSL_CFLAGS = @OPENSSL_SSL_CFLAGS@
-OPENSSL_SSL_LIBS = @OPENSSL_SSL_LIBS@
+OPENSSL_CFLAGS = @OPENSSL_CFLAGS@
+OPENSSL_LIBS = @OPENSSL_LIBS@
+OPENVPN_VERSION_MAJOR = @OPENVPN_VERSION_MAJOR@
+OPENVPN_VERSION_MINOR = @OPENVPN_VERSION_MINOR@
+OPENVPN_VERSION_PATCH = @OPENVPN_VERSION_PATCH@
OPTIONAL_CRYPTO_CFLAGS = @OPTIONAL_CRYPTO_CFLAGS@
OPTIONAL_CRYPTO_LIBS = @OPTIONAL_CRYPTO_LIBS@
OPTIONAL_DL_LIBS = @OPTIONAL_DL_LIBS@
+OPTIONAL_LZ4_CFLAGS = @OPTIONAL_LZ4_CFLAGS@
+OPTIONAL_LZ4_LIBS = @OPTIONAL_LZ4_LIBS@
OPTIONAL_LZO_CFLAGS = @OPTIONAL_LZO_CFLAGS@
OPTIONAL_LZO_LIBS = @OPTIONAL_LZO_LIBS@
OPTIONAL_PKCS11_HELPER_CFLAGS = @OPTIONAL_PKCS11_HELPER_CFLAGS@
@@ -310,8 +307,6 @@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
PLUGIN_AUTH_PAM_CFLAGS = @PLUGIN_AUTH_PAM_CFLAGS@
PLUGIN_AUTH_PAM_LIBS = @PLUGIN_AUTH_PAM_LIBS@
-POLARSSL_CFLAGS = @POLARSSL_CFLAGS@
-POLARSSL_LIBS = @POLARSSL_LIBS@
RANLIB = @RANLIB@
RC = @RC@
ROUTE = @ROUTE@
@@ -326,6 +321,11 @@ TAP_CFLAGS = @TAP_CFLAGS@
TAP_WIN_COMPONENT_ID = @TAP_WIN_COMPONENT_ID@
TAP_WIN_MIN_MAJOR = @TAP_WIN_MIN_MAJOR@
TAP_WIN_MIN_MINOR = @TAP_WIN_MIN_MINOR@
+TEST_CFLAGS = @TEST_CFLAGS@
+TEST_LDFLAGS = @TEST_LDFLAGS@
+VENDOR_BUILD_ROOT = @VENDOR_BUILD_ROOT@
+VENDOR_DIST_ROOT = @VENDOR_DIST_ROOT@
+VENDOR_SRC_ROOT = @VENDOR_SRC_ROOT@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
@@ -394,6 +394,7 @@ AM_CFLAGS = \
@ENABLE_PLUGIN_AUTH_PAM_TRUE@plugin_LTLIBRARIES = openvpn-plugin-auth-pam.la
@ENABLE_PLUGIN_AUTH_PAM_TRUE@dist_doc_DATA = README.auth-pam
openvpn_plugin_auth_pam_la_SOURCES = \
+ utils.c \
auth-pam.c \
pamdl.c pamdl.h \
auth-pam.exports
@@ -421,6 +422,7 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/plugins/auth-pam/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign src/plugins/auth-pam/Makefile
+.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
@@ -485,20 +487,21 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/auth-pam.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pamdl.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/utils.Plo@am__quote@
.c.o:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $<
.c.obj:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'`
.c.lo:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@@ -743,8 +746,6 @@ uninstall-am: uninstall-dist_docDATA uninstall-pluginLTLIBRARIES
tags tags-am uninstall uninstall-am uninstall-dist_docDATA \
uninstall-pluginLTLIBRARIES
-.PRECIOUS: Makefile
-
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
diff --git a/src/plugins/auth-pam/auth-pam.c b/src/plugins/auth-pam/auth-pam.c
index 710accc..5ad3ec8 100644
--- a/src/plugins/auth-pam/auth-pam.c
+++ b/src/plugins/auth-pam/auth-pam.c
@@ -39,7 +39,6 @@
#include <stdio.h>
#include <string.h>
#include <ctype.h>
-#include <stdbool.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
@@ -48,7 +47,7 @@
#include <fcntl.h>
#include <signal.h>
#include <syslog.h>
-#include <stdint.h>
+#include "utils.h"
#include <openvpn-plugin.h>
@@ -117,94 +116,6 @@ struct user_pass {
/* Background process function */
static void pam_server (int fd, const char *service, int verb, const struct name_value_list *name_value_list);
-/* Read 'tosearch', replace all occurences of 'searchfor' with 'replacewith' and return
- * a pointer to the NEW string. Does not modify the input strings. Will not enter an
- * infinite loop with clever 'searchfor' and 'replacewith' strings.
- * Daniel Johnson - Progman2000@usa.net / djohnson@progman.us
- *
- * Retuns NULL when
- * - any parameter is NULL
- * - the worst-case result is to large ( >= SIZE_MAX)
- */
-static char *
-searchandreplace(const char *tosearch, const char *searchfor, const char *replacewith)
-{
- if (!tosearch || !searchfor || !replacewith) return NULL;
-
- size_t tosearchlen = strlen(tosearch);
- size_t replacewithlen = strlen(replacewith);
- size_t templen = tosearchlen * replacewithlen;
-
- if (tosearchlen == 0 || strlen(searchfor) == 0 || replacewithlen == 0) {
- return NULL;
- }
-
- bool is_potential_integer_overflow = (templen == SIZE_MAX) || (templen / tosearchlen != replacewithlen);
-
- if (is_potential_integer_overflow) {
- return NULL;
- }
-
- // state: all parameters are valid
-
- const char *searching=tosearch;
- char *scratch;
-
- char temp[templen+1];
- temp[0]=0;
-
- scratch = strstr(searching,searchfor);
- if (!scratch) return strdup(tosearch);
-
- while (scratch) {
- strncat(temp,searching,scratch-searching);
- strcat(temp,replacewith);
-
- searching=scratch+strlen(searchfor);
- scratch = strstr(searching,searchfor);
- }
- return strdup(temp);
-}
-
-/*
- * Given an environmental variable name, search
- * the envp array for its value, returning it
- * if found or NULL otherwise.
- */
-static const char *
-get_env (const char *name, const char *envp[])
-{
- if (envp)
- {
- int i;
- const int namelen = strlen (name);
- for (i = 0; envp[i]; ++i)
- {
- if (!strncmp (envp[i], name, namelen))
- {
- const char *cp = envp[i] + namelen;
- if (*cp == '=')
- return cp + 1;
- }
- }
- }
- return NULL;
-}
-
-/*
- * Return the length of a string array
- */
-static int
-string_array_len (const char *array[])
-{
- int i = 0;
- if (array)
- {
- while (array[i])
- ++i;
- }
- return i;
-}
/*
* Socket read/write functions.
diff --git a/src/plugins/auth-pam/utils.c b/src/plugins/auth-pam/utils.c
new file mode 100644
index 0000000..4f2bec1
--- /dev/null
+++ b/src/plugins/auth-pam/utils.c
@@ -0,0 +1,113 @@
+/*
+ * OpenVPN -- An application to securely tunnel IP networks
+ * over a single TCP/UDP port, with support for SSL/TLS-based
+ * session authentication and key exchange,
+ * packet encryption, packet authentication, and
+ * packet compression.
+ *
+ * Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program (see the file COPYING included with this
+ * distribution); if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * OpenVPN plugin module to do PAM authentication using a split
+ * privilege model.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+
+#include <string.h>
+#include <ctype.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <stdint.h>
+
+#include "utils.h"
+
+char *
+searchandreplace(const char *tosearch, const char *searchfor, const char *replacewith)
+{
+ if (!tosearch || !searchfor || !replacewith) return NULL;
+
+ size_t tosearchlen = strlen(tosearch);
+ size_t replacewithlen = strlen(replacewith);
+ size_t templen = tosearchlen * replacewithlen;
+
+ if (tosearchlen == 0 || strlen(searchfor) == 0 || replacewithlen == 0) {
+ return NULL;
+ }
+
+ bool is_potential_integer_overflow = (templen == SIZE_MAX) || (templen / tosearchlen != replacewithlen);
+
+ if (is_potential_integer_overflow) {
+ return NULL;
+ }
+
+ // state: all parameters are valid
+
+ const char *searching=tosearch;
+ char *scratch;
+
+ char temp[templen+1];
+ temp[0]=0;
+
+ scratch = strstr(searching,searchfor);
+ if (!scratch) return strdup(tosearch);
+
+ while (scratch) {
+ strncat(temp,searching,scratch-searching);
+ strcat(temp,replacewith);
+
+ searching=scratch+strlen(searchfor);
+ scratch = strstr(searching,searchfor);
+ }
+ return strdup(temp);
+}
+
+const char *
+get_env (const char *name, const char *envp[])
+{
+ if (envp)
+ {
+ int i;
+ const int namelen = strlen (name);
+ for (i = 0; envp[i]; ++i)
+ {
+ if (!strncmp (envp[i], name, namelen))
+ {
+ const char *cp = envp[i] + namelen;
+ if (*cp == '=')
+ return cp + 1;
+ }
+ }
+ }
+ return NULL;
+}
+
+int
+string_array_len (const char *array[])
+{
+ int i = 0;
+ if (array)
+ {
+ while (array[i])
+ ++i;
+ }
+ return i;
+}
diff --git a/src/plugins/auth-pam/utils.h b/src/plugins/auth-pam/utils.h
new file mode 100644
index 0000000..2f72040
--- /dev/null
+++ b/src/plugins/auth-pam/utils.h
@@ -0,0 +1,66 @@
+/*
+ * OpenVPN -- An application to securely tunnel IP networks
+ * over a single TCP/UDP port, with support for SSL/TLS-based
+ * session authentication and key exchange,
+ * packet encryption, packet authentication, and
+ * packet compression.
+ *
+ * Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program (see the file COPYING included with this
+ * distribution); if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _PLUGIN_AUTH_PAM_UTILS__H
+#define _PLUGIN_AUTH_PAM_UTILS__H
+
+/**
+ * Read 'tosearch', replace all occurences of 'searchfor' with 'replacewith' and return
+ * a pointer to the NEW string. Does not modify the input strings. Will not enter an
+ * infinite loop with clever 'searchfor' and 'replacewith' strings.
+ *
+ * @author Daniel Johnson - Progman2000@usa.net / djohnson@progman.us
+ *
+ * @param tosearch haystack to search in
+ * @param searchfor needle to search for in the haystack
+ * @param replacewith when a match is found, replace needle with this string
+ *
+ * @return Retuns NULL when any parameter is NULL or the worst-case result is to large ( >= SIZE_MAX).
+ * Otherwise it returns a pointer to a new buffer containing the modified input
+ */
+char *
+searchandreplace(const char *tosearch, const char *searchfor, const char *replacewith);
+
+/**
+ * Given an environmental variable name, search
+ * the envp array for its value
+ *
+ * @param name Environment variable to look up
+ * @param envp Environment variable table with all key/value pairs
+ *
+ * @return Returns a pointer to the value of the enviroment variable if found, otherwise NULL is returned.
+ */
+const char *
+get_env (const char *name, const char *envp[]);
+
+/**
+ * Return the length of a string array
+ *
+ * @param array Pointer to the array to calculate size of
+ *
+ */
+int
+string_array_len (const char *array[]);
+
+#endif
diff --git a/src/plugins/down-root/Makefile.in b/src/plugins/down-root/Makefile.in
index c9768d5..e5c0ad5 100644
--- a/src/plugins/down-root/Makefile.in
+++ b/src/plugins/down-root/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.15 from Makefile.am.
+# Makefile.in generated by automake 1.13.4 from Makefile.am.
# @configure_input@
-# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -22,17 +22,7 @@
VPATH = @srcdir@
-am__is_gnu_make = { \
- if test -z '$(MAKELEVEL)'; then \
- false; \
- elif test -n '$(MAKE_HOST)'; then \
- true; \
- elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
- true; \
- else \
- false; \
- fi; \
-}
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
am__make_running_with_option = \
case $${target_option-} in \
?) ;; \
@@ -96,6 +86,8 @@ POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
subdir = src/plugins/down-root
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+ $(top_srcdir)/depcomp $(am__dist_doc_DATA_DIST)
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/ax_emptyarray.m4 \
$(top_srcdir)/m4/ax_socklen_t.m4 \
@@ -106,10 +98,9 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_emptyarray.m4 \
$(top_srcdir)/compat.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
-DIST_COMMON = $(srcdir)/Makefile.am $(am__dist_doc_DATA_DIST) \
- $(am__DIST_COMMON)
mkinstalldirs = $(install_sh) -d
-CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_HEADER = $(top_builddir)/config.h \
+ $(top_builddir)/include/openvpn-plugin.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
@@ -167,7 +158,7 @@ AM_V_at = $(am__v_at_@AM_V@)
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
am__v_at_0 = @
am__v_at_1 =
-DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) -I$(top_builddir)/include
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
am__mv = mv -f
@@ -217,7 +208,6 @@ am__define_uniq_tagged_files = \
done | $(am__uniquify_input)`
ETAGS = etags
CTAGS = ctags
-am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
@@ -231,6 +221,7 @@ AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
+CMAKE = @CMAKE@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
@@ -265,25 +256,31 @@ LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
-LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+LZ4_CFLAGS = @LZ4_CFLAGS@
+LZ4_LIBS = @LZ4_LIBS@
LZO_CFLAGS = @LZO_CFLAGS@
LZO_LIBS = @LZO_LIBS@
MAKEINFO = @MAKEINFO@
MAN2HTML = @MAN2HTML@
MANIFEST_TOOL = @MANIFEST_TOOL@
+MBEDTLS_CFLAGS = @MBEDTLS_CFLAGS@
+MBEDTLS_LIBS = @MBEDTLS_LIBS@
MKDIR_P = @MKDIR_P@
NETSTAT = @NETSTAT@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
-OPENSSL_CRYPTO_CFLAGS = @OPENSSL_CRYPTO_CFLAGS@
-OPENSSL_CRYPTO_LIBS = @OPENSSL_CRYPTO_LIBS@
-OPENSSL_SSL_CFLAGS = @OPENSSL_SSL_CFLAGS@
-OPENSSL_SSL_LIBS = @OPENSSL_SSL_LIBS@
+OPENSSL_CFLAGS = @OPENSSL_CFLAGS@
+OPENSSL_LIBS = @OPENSSL_LIBS@
+OPENVPN_VERSION_MAJOR = @OPENVPN_VERSION_MAJOR@
+OPENVPN_VERSION_MINOR = @OPENVPN_VERSION_MINOR@
+OPENVPN_VERSION_PATCH = @OPENVPN_VERSION_PATCH@
OPTIONAL_CRYPTO_CFLAGS = @OPTIONAL_CRYPTO_CFLAGS@
OPTIONAL_CRYPTO_LIBS = @OPTIONAL_CRYPTO_LIBS@
OPTIONAL_DL_LIBS = @OPTIONAL_DL_LIBS@
+OPTIONAL_LZ4_CFLAGS = @OPTIONAL_LZ4_CFLAGS@
+OPTIONAL_LZ4_LIBS = @OPTIONAL_LZ4_LIBS@
OPTIONAL_LZO_CFLAGS = @OPTIONAL_LZO_CFLAGS@
OPTIONAL_LZO_LIBS = @OPTIONAL_LZO_LIBS@
OPTIONAL_PKCS11_HELPER_CFLAGS = @OPTIONAL_PKCS11_HELPER_CFLAGS@
@@ -309,8 +306,6 @@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
PLUGIN_AUTH_PAM_CFLAGS = @PLUGIN_AUTH_PAM_CFLAGS@
PLUGIN_AUTH_PAM_LIBS = @PLUGIN_AUTH_PAM_LIBS@
-POLARSSL_CFLAGS = @POLARSSL_CFLAGS@
-POLARSSL_LIBS = @POLARSSL_LIBS@
RANLIB = @RANLIB@
RC = @RC@
ROUTE = @ROUTE@
@@ -325,6 +320,11 @@ TAP_CFLAGS = @TAP_CFLAGS@
TAP_WIN_COMPONENT_ID = @TAP_WIN_COMPONENT_ID@
TAP_WIN_MIN_MAJOR = @TAP_WIN_MIN_MAJOR@
TAP_WIN_MIN_MINOR = @TAP_WIN_MIN_MINOR@
+TEST_CFLAGS = @TEST_CFLAGS@
+TEST_LDFLAGS = @TEST_LDFLAGS@
+VENDOR_BUILD_ROOT = @VENDOR_BUILD_ROOT@
+VENDOR_DIST_ROOT = @VENDOR_DIST_ROOT@
+VENDOR_SRC_ROOT = @VENDOR_SRC_ROOT@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
@@ -415,6 +415,7 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/plugins/down-root/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign src/plugins/down-root/Makefile
+.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
@@ -484,14 +485,14 @@ distclean-compile:
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $<
.c.obj:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'`
.c.lo:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@@ -736,8 +737,6 @@ uninstall-am: uninstall-dist_docDATA uninstall-pluginLTLIBRARIES
tags tags-am uninstall uninstall-am uninstall-dist_docDATA \
uninstall-pluginLTLIBRARIES
-.PRECIOUS: Makefile
-
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
diff --git a/tests/Makefile.am b/tests/Makefile.am
index b7980e0..e55928b 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -12,12 +12,20 @@
MAINTAINERCLEANFILES = \
$(srcdir)/Makefile.in
-test_scripts = t_client.sh t_lpback.sh t_cltsrv.sh
+SUBDIRS = unit_tests
+
+test_scripts = t_client.sh
+if ENABLE_CRYPTO
+test_scripts += t_lpback.sh t_cltsrv.sh
+endif
TESTS_ENVIRONMENT = top_srcdir="$(top_srcdir)"
TESTS = $(test_scripts)
dist_noinst_SCRIPTS = \
$(test_scripts) \
- t_cltsrv-down.sh
+ t_cltsrv-down.sh \
+ update_t_client_ips.sh
+dist_noinst_DATA = \
+ t_client.rc-sample
diff --git a/tests/Makefile.in b/tests/Makefile.in
index 370116c..49f79d8 100644
--- a/tests/Makefile.in
+++ b/tests/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.15 from Makefile.am.
+# Makefile.in generated by automake 1.13.4 from Makefile.am.
# @configure_input@
-# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -25,18 +25,9 @@
# Copyright (C) 2006-2012 Alon Bar-Lev <alon.barlev@gmail.com>
#
+
VPATH = @srcdir@
-am__is_gnu_make = { \
- if test -z '$(MAKELEVEL)'; then \
- false; \
- elif test -n '$(MAKE_HOST)'; then \
- true; \
- elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
- true; \
- else \
- false; \
- fi; \
-}
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
am__make_running_with_option = \
case $${target_option-} in \
?) ;; \
@@ -99,7 +90,11 @@ PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
+@ENABLE_CRYPTO_TRUE@am__append_1 = t_lpback.sh t_cltsrv.sh
subdir = tests
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+ $(srcdir)/t_client.sh.in $(am__dist_noinst_SCRIPTS_DIST) \
+ $(dist_noinst_DATA)
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/ax_emptyarray.m4 \
$(top_srcdir)/m4/ax_socklen_t.m4 \
@@ -110,12 +105,13 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_emptyarray.m4 \
$(top_srcdir)/compat.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
-DIST_COMMON = $(srcdir)/Makefile.am $(dist_noinst_SCRIPTS) \
- $(am__DIST_COMMON)
mkinstalldirs = $(install_sh) -d
-CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_HEADER = $(top_builddir)/config.h \
+ $(top_builddir)/include/openvpn-plugin.h
CONFIG_CLEAN_FILES = t_client.sh
CONFIG_CLEAN_VPATH_FILES =
+am__dist_noinst_SCRIPTS_DIST = t_client.sh t_lpback.sh t_cltsrv.sh \
+ t_cltsrv-down.sh update_t_client_ips.sh
SCRIPTS = $(dist_noinst_SCRIPTS)
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
@@ -131,12 +127,47 @@ am__v_at_0 = @
am__v_at_1 =
SOURCES =
DIST_SOURCES =
+RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
+ ctags-recursive dvi-recursive html-recursive info-recursive \
+ install-data-recursive install-dvi-recursive \
+ install-exec-recursive install-html-recursive \
+ install-info-recursive install-pdf-recursive \
+ install-ps-recursive install-recursive installcheck-recursive \
+ installdirs-recursive pdf-recursive ps-recursive \
+ tags-recursive uninstall-recursive
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
*) (install-info --version) >/dev/null 2>&1;; \
esac
+DATA = $(dist_noinst_DATA)
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
+ distclean-recursive maintainer-clean-recursive
+am__recursive_targets = \
+ $(RECURSIVE_TARGETS) \
+ $(RECURSIVE_CLEAN_TARGETS) \
+ $(am__extra_recursive_targets)
+AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
+ distdir
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
am__tty_colors_dummy = \
mgn= red= grn= lgn= blu= brg= std=; \
am__color_tests=no
@@ -159,8 +190,33 @@ am__tty_colors = { \
std=''; \
fi; \
}
-am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/t_client.sh.in
+DIST_SUBDIRS = $(SUBDIRS)
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+am__relativize = \
+ dir0=`pwd`; \
+ sed_first='s,^\([^/]*\)/.*$$,\1,'; \
+ sed_rest='s,^[^/]*/*,,'; \
+ sed_last='s,^.*/\([^/]*\)$$,\1,'; \
+ sed_butlast='s,/*[^/]*$$,,'; \
+ while test -n "$$dir1"; do \
+ first=`echo "$$dir1" | sed -e "$$sed_first"`; \
+ if test "$$first" != "."; then \
+ if test "$$first" = ".."; then \
+ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
+ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
+ else \
+ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
+ if test "$$first2" = "$$first"; then \
+ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
+ else \
+ dir2="../$$dir2"; \
+ fi; \
+ dir0="$$dir0"/"$$first"; \
+ fi; \
+ fi; \
+ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
+ done; \
+ reldir="$$dir2"
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
@@ -173,6 +229,7 @@ AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
+CMAKE = @CMAKE@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
@@ -207,25 +264,31 @@ LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
-LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+LZ4_CFLAGS = @LZ4_CFLAGS@
+LZ4_LIBS = @LZ4_LIBS@
LZO_CFLAGS = @LZO_CFLAGS@
LZO_LIBS = @LZO_LIBS@
MAKEINFO = @MAKEINFO@
MAN2HTML = @MAN2HTML@
MANIFEST_TOOL = @MANIFEST_TOOL@
+MBEDTLS_CFLAGS = @MBEDTLS_CFLAGS@
+MBEDTLS_LIBS = @MBEDTLS_LIBS@
MKDIR_P = @MKDIR_P@
NETSTAT = @NETSTAT@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
-OPENSSL_CRYPTO_CFLAGS = @OPENSSL_CRYPTO_CFLAGS@
-OPENSSL_CRYPTO_LIBS = @OPENSSL_CRYPTO_LIBS@
-OPENSSL_SSL_CFLAGS = @OPENSSL_SSL_CFLAGS@
-OPENSSL_SSL_LIBS = @OPENSSL_SSL_LIBS@
+OPENSSL_CFLAGS = @OPENSSL_CFLAGS@
+OPENSSL_LIBS = @OPENSSL_LIBS@
+OPENVPN_VERSION_MAJOR = @OPENVPN_VERSION_MAJOR@
+OPENVPN_VERSION_MINOR = @OPENVPN_VERSION_MINOR@
+OPENVPN_VERSION_PATCH = @OPENVPN_VERSION_PATCH@
OPTIONAL_CRYPTO_CFLAGS = @OPTIONAL_CRYPTO_CFLAGS@
OPTIONAL_CRYPTO_LIBS = @OPTIONAL_CRYPTO_LIBS@
OPTIONAL_DL_LIBS = @OPTIONAL_DL_LIBS@
+OPTIONAL_LZ4_CFLAGS = @OPTIONAL_LZ4_CFLAGS@
+OPTIONAL_LZ4_LIBS = @OPTIONAL_LZ4_LIBS@
OPTIONAL_LZO_CFLAGS = @OPTIONAL_LZO_CFLAGS@
OPTIONAL_LZO_LIBS = @OPTIONAL_LZO_LIBS@
OPTIONAL_PKCS11_HELPER_CFLAGS = @OPTIONAL_PKCS11_HELPER_CFLAGS@
@@ -251,8 +314,6 @@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
PLUGIN_AUTH_PAM_CFLAGS = @PLUGIN_AUTH_PAM_CFLAGS@
PLUGIN_AUTH_PAM_LIBS = @PLUGIN_AUTH_PAM_LIBS@
-POLARSSL_CFLAGS = @POLARSSL_CFLAGS@
-POLARSSL_LIBS = @POLARSSL_LIBS@
RANLIB = @RANLIB@
RC = @RC@
ROUTE = @ROUTE@
@@ -267,6 +328,11 @@ TAP_CFLAGS = @TAP_CFLAGS@
TAP_WIN_COMPONENT_ID = @TAP_WIN_COMPONENT_ID@
TAP_WIN_MIN_MAJOR = @TAP_WIN_MIN_MAJOR@
TAP_WIN_MIN_MINOR = @TAP_WIN_MIN_MINOR@
+TEST_CFLAGS = @TEST_CFLAGS@
+TEST_LDFLAGS = @TEST_LDFLAGS@
+VENDOR_BUILD_ROOT = @VENDOR_BUILD_ROOT@
+VENDOR_DIST_ROOT = @VENDOR_DIST_ROOT@
+VENDOR_SRC_ROOT = @VENDOR_SRC_ROOT@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
@@ -327,14 +393,19 @@ top_srcdir = @top_srcdir@
MAINTAINERCLEANFILES = \
$(srcdir)/Makefile.in
-test_scripts = t_client.sh t_lpback.sh t_cltsrv.sh
+SUBDIRS = unit_tests
+test_scripts = t_client.sh $(am__append_1)
TESTS_ENVIRONMENT = top_srcdir="$(top_srcdir)"
TESTS = $(test_scripts)
dist_noinst_SCRIPTS = \
$(test_scripts) \
- t_cltsrv-down.sh
+ t_cltsrv-down.sh \
+ update_t_client_ips.sh
+
+dist_noinst_DATA = \
+ t_client.rc-sample
-all: all-am
+all: all-recursive
.SUFFIXES:
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@@ -349,6 +420,7 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign tests/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign tests/Makefile
+.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
@@ -374,12 +446,105 @@ mostlyclean-libtool:
clean-libtool:
-rm -rf .libs _libs
-tags TAGS:
-ctags CTAGS:
-
-cscope cscopelist:
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run 'make' without going through this Makefile.
+# To change the values of 'make' variables: instead of editing Makefiles,
+# (1) if the variable is set in 'config.status', edit 'config.status'
+# (which will cause the Makefiles to be regenerated when you run 'make');
+# (2) otherwise, pass the desired values on the 'make' command line.
+$(am__recursive_targets):
+ @fail=; \
+ if $(am__make_keepgoing); then \
+ failcom='fail=yes'; \
+ else \
+ failcom='exit 1'; \
+ fi; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ case "$@" in \
+ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+ *) list='$(SUBDIRS)' ;; \
+ esac; \
+ for subdir in $$list; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ dot_seen=yes; \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-recursive
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+ include_option=--etags-include; \
+ empty_fix=.; \
+ else \
+ include_option=--include; \
+ empty_fix=; \
+ fi; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test ! -f $$subdir/TAGS || \
+ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-recursive
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-recursive
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
check-TESTS: $(TESTS)
@failed=0; all=0; xfail=0; xpass=0; skip=0; \
@@ -504,20 +669,46 @@ distdir: $(DISTFILES)
|| exit 1; \
fi; \
done
+ @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ $(am__make_dryrun) \
+ || test -d "$(distdir)/$$subdir" \
+ || $(MKDIR_P) "$(distdir)/$$subdir" \
+ || exit 1; \
+ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
+ $(am__relativize); \
+ new_distdir=$$reldir; \
+ dir1=$$subdir; dir2="$(top_distdir)"; \
+ $(am__relativize); \
+ new_top_distdir=$$reldir; \
+ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
+ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
+ ($(am__cd) $$subdir && \
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="$$new_top_distdir" \
+ distdir="$$new_distdir" \
+ am__remove_distdir=: \
+ am__skip_length_check=: \
+ am__skip_mode_fix=: \
+ distdir) \
+ || exit 1; \
+ fi; \
+ done
check-am: all-am
$(MAKE) $(AM_MAKEFLAGS) check-TESTS
-check: check-am
-all-am: Makefile $(SCRIPTS)
-installdirs:
-install: install-am
-install-exec: install-exec-am
-install-data: install-data-am
-uninstall: uninstall-am
+check: check-recursive
+all-am: Makefile $(SCRIPTS) $(DATA)
+installdirs: installdirs-recursive
+installdirs-am:
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
-installcheck: installcheck-am
+installcheck: installcheck-recursive
install-strip:
if test -z '$(STRIP)'; then \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
@@ -540,89 +731,88 @@ maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
-test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
-clean: clean-am
+clean: clean-recursive
clean-am: clean-generic clean-libtool mostlyclean-am
-distclean: distclean-am
+distclean: distclean-recursive
-rm -f Makefile
-distclean-am: clean-am distclean-generic
+distclean-am: clean-am distclean-generic distclean-tags
-dvi: dvi-am
+dvi: dvi-recursive
dvi-am:
-html: html-am
+html: html-recursive
html-am:
-info: info-am
+info: info-recursive
info-am:
install-data-am:
-install-dvi: install-dvi-am
+install-dvi: install-dvi-recursive
install-dvi-am:
install-exec-am:
-install-html: install-html-am
+install-html: install-html-recursive
install-html-am:
-install-info: install-info-am
+install-info: install-info-recursive
install-info-am:
install-man:
-install-pdf: install-pdf-am
+install-pdf: install-pdf-recursive
install-pdf-am:
-install-ps: install-ps-am
+install-ps: install-ps-recursive
install-ps-am:
installcheck-am:
-maintainer-clean: maintainer-clean-am
+maintainer-clean: maintainer-clean-recursive
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
-mostlyclean: mostlyclean-am
+mostlyclean: mostlyclean-recursive
mostlyclean-am: mostlyclean-generic mostlyclean-libtool
-pdf: pdf-am
+pdf: pdf-recursive
pdf-am:
-ps: ps-am
+ps: ps-recursive
ps-am:
uninstall-am:
-.MAKE: check-am install-am install-strip
+.MAKE: $(am__recursive_targets) check-am install-am install-strip
-.PHONY: all all-am check check-TESTS check-am clean clean-generic \
- clean-libtool cscopelist-am ctags-am distclean \
- distclean-generic distclean-libtool distdir dvi dvi-am html \
+.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \
+ check-TESTS check-am clean clean-generic clean-libtool \
+ cscopelist-am ctags ctags-am distclean 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 \
install-exec-am install-html install-html-am install-info \
install-info-am install-man install-pdf install-pdf-am \
install-ps install-ps-am install-strip installcheck \
- installcheck-am installdirs maintainer-clean \
+ installcheck-am installdirs installdirs-am maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-generic \
- mostlyclean-libtool pdf pdf-am ps ps-am tags-am uninstall \
+ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \
uninstall-am
-.PRECIOUS: Makefile
-
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
diff --git a/tests/t_client.rc-sample b/tests/t_client.rc-sample
new file mode 100644
index 0000000..4fdea48
--- /dev/null
+++ b/tests/t_client.rc-sample
@@ -0,0 +1,101 @@
+#
+# this is sourced from t_client.sh and defines which openvpn client tests
+# to run
+#
+# (sample config, copy to t_client.rc and adapt to your environment)
+#
+#
+# define these - if empty, no tests will run
+#
+top_srcdir="${top_srcdir:-..}"
+CA_CERT="${top_srcdir}/sample/sample-keys/ca.crt"
+CLIENT_KEY="${top_srcdir}/sample/sample-keys/client.key"
+CLIENT_CERT="${top_srcdir}/sample/sample-keys/client.crt"
+#FPING_EXTRA_ARGS="-t 1000"
+
+# Load EXPECT_IFCONFIG* parameters from cache
+if [ -r "${top_builddir}/t_client_ips.rc" ]; then
+ . "${top_builddir}/t_client_ips.rc"
+else
+ echo "NOTICE: missing t_client_ips.rc will be auto-generated"
+fi
+
+#
+# remote host (used as macro below)
+#
+REMOTE=mytestserver
+#
+# tests to run (list suffixes for config stanzas below)
+#
+TEST_RUN_LIST="1 2"
+
+#
+# use "sudo" (etc) to give openvpn the necessary privileges
+# if this is not active, "make check" must be run as root
+#
+#RUN_SUDO=sudo
+
+#
+# base confic that is the same for all the p2mp test runs
+#
+OPENVPN_BASE_P2MP="--client --ca $CA_CERT \
+ --cert $CLIENT_CERT --key $CLIENT_KEY \
+ --ns-cert-type server --nobind --comp-lzo --verb 3"
+
+# base config for p2p tests
+#
+OPENVPN_BASE_P2P="..."
+
+#
+#
+# now define the individual tests - all variables suffixed with _1, _2 etc
+# will be used in test run "1", "2", etc.
+#
+# if something is not defined here, the corresponding test is not run
+#
+# possible test options:
+#
+# RUN_TITLE_x="what is being tested on here" (purely informational)
+# OPENVPN_CONF_x = "how to call ./openvpn" [mandatory]
+# EXPECT_IFCONFIG4_x = "this IPv4 address needs to show up in ifconfig"
+# EXPECT_IFCONFIG6_x = "this IPv6 address needs to show up in ifconfig"
+# PING4_HOSTS_x = "these hosts musts ping when openvpn is up (IPv4 fping)"
+# PING6_HOSTS_x = "these hosts musts ping when openvpn is up (IPv6 fping6)"
+#
+# Test 1: UDP / p2mp tun
+# specify IPv4+IPv6 addresses expected from server and ping targets
+#
+RUN_TITLE_1="testing tun/udp/ipv4+ipv6"
+OPENVPN_CONF_1="$OPENVPN_BASE_P2MP --dev tun --proto udp --remote $REMOTE --port 51194"
+PING4_HOSTS_1="10.100.50.1 10.100.0.1"
+PING6_HOSTS_1="2001:db8::1 2001:db8:a050::1"
+
+# Test 2: TCP / p2mp tun
+#
+RUN_TITLE_2="testing tun/tcp/ipv4+ipv6"
+OPENVPN_CONF_2="$OPENVPN_BASE_P2MP --dev tun --proto tcp --remote $REMOTE --port 51194"
+PING4_HOSTS_2="10.100.51.1 10.100.0.1"
+PING6_HOSTS_2="2001:db8::1 2001:db8:a051::1"
+#
+# run command after openvpn initialization is done - here: delay 5 seconds
+POSTINIT_CMD_2="sleep 5"
+
+# Test 3: UDP / p2p tun
+# ...
+
+# Test 4: TCP / p2p tun
+# ...
+
+# Test 5: UDP / p2mp tap
+# ...
+
+# Test 6: TCP / p2mp tun
+# ...
+
+# Test 7: UDP / p2p tap
+# ...
+
+# Test 8: TCP / p2p tap
+# ...
+
+# Test 9: whatever you want to test... :-)
diff --git a/tests/t_client.sh b/tests/t_client.sh
index 38cedb1..b51813e 100755
--- a/tests/t_client.sh
+++ b/tests/t_client.sh
@@ -24,6 +24,24 @@ else
exit 77
fi
+# Check for external dependencies
+which fping > /dev/null
+if [ $? -ne 0 ]; then
+ echo "$0: fping is not available in \$PATH" >&2
+ exit 77
+fi
+which fping6 > /dev/null
+if [ $? -ne 0 ]; then
+ echo "$0: fping6 is not available in \$PATH" >&2
+ exit 77
+fi
+
+KILL_EXEC=`which kill`
+if [ $? -ne 0 ]; then
+ echo "$0: kill not found in \$PATH" >&2
+ exit 77
+fi
+
if [ ! -x "${top_builddir}/src/openvpn/openvpn" ]
then
echo "no (executable) openvpn binary in current build tree. FAIL." >&2
@@ -46,17 +64,45 @@ if [ -z "$TEST_RUN_LIST" ] ; then
exit 77
fi
+# Ensure PREFER_KSU is in a known state
+PREFER_KSU="${PREFER_KSU:-0}"
+
# make sure we have permissions to run ifconfig/route from OpenVPN
# can't use "id -u" here - doesn't work on Solaris
ID=`id`
if expr "$ID" : "uid=0" >/dev/null
then :
else
+ if [ "${PREFER_KSU}" -eq 1 ];
+ then
+ # Check if we have a valid kerberos ticket
+ klist -l 1>/dev/null 2>/dev/null
+ if [ $? -ne 0 ];
+ then
+ # No kerberos ticket found, skip ksu and fallback to RUN_SUDO
+ PREFER_KSU=0
+ echo "$0: No Kerberos ticket available. Will not use ksu."
+ else
+ RUN_SUDO="ksu -q -e"
+ fi
+ fi
+
if [ -z "$RUN_SUDO" ]
then
echo "$0: this test must run be as root, or RUN_SUDO=... " >&2
echo " must be set correctly in 't_client.rc'. SKIP." >&2
exit 77
+ else
+ # We have to use sudo. Make sure that we (hopefully) do not have
+ # to ask the users password during the test. This is done to
+ # prevent timing issues, e.g. when the waits for openvpn to start
+ if $RUN_SUDO $KILL_EXEC -0 $$
+ then
+ echo "$0: $RUN_SUDO $KILL_EXEC -0 succeeded, good."
+ else
+ echo "$0: $RUN_SUDO $KILL_EXEC -0 failed, cannot go on. SKIP." >&2
+ exit 77
+ fi
fi
fi
@@ -73,6 +119,7 @@ exit_code=0
# ----------------------------------------------------------
# helper functions
# ----------------------------------------------------------
+
# print failure message, increase FAIL counter
fail()
{
@@ -122,6 +169,12 @@ get_ifconfig_route()
netstat -rn | awk '$3 !~ /^UHL/ { print $1,$2,$3,$6 }'
return
;;
+ AIX)
+ echo "-- AIX --"
+ /usr/sbin/ifconfig -a | egrep "(flags=|inet)"
+ netstat -rn | awk '$3 !~ /^UHL/ { print $1,$2,$3,$6 }'
+ return
+ ;;
esac
echo "get_ifconfig_route(): no idea how to get info on your OS. FAIL." >&2
@@ -178,8 +231,8 @@ run_ping_tests()
do
echo "run IPv$proto ping tests ($want), $bytes byte packets..."
- echo "$cmd -b $bytes -C 20 -p 250 -q $targetlist" >>$LOGDIR/$SUF:fping.out
- $cmd -b $bytes -C 20 -p 250 -q $targetlist >>$LOGDIR/$SUF:fping.out 2>&1
+ echo "$cmd -b $bytes -C 20 -p 250 -q $FPING_EXTRA_ARGS $targetlist" >>$LOGDIR/$SUF:fping.out
+ $cmd -b $bytes -C 20 -p 250 -q $FPING_EXTRA_ARGS $targetlist >>$LOGDIR/$SUF:fping.out 2>&1
# while OpenVPN is running, pings must succeed (want='want_ok')
# before OpenVPN is up, pings must NOT succeed (want='want_fail')
@@ -209,6 +262,9 @@ SUMMARY_FAIL=
for SUF in $TEST_RUN_LIST
do
# get config variables
+ eval test_prep=\"\$PREPARE_$SUF\"
+ eval test_postinit=\"\$POSTINIT_CMD_$SUF\"
+ eval test_cleanup=\"\$CLEANUP_$SUF\"
eval test_run_title=\"\$RUN_TITLE_$SUF\"
eval openvpn_conf=\"\$OPENVPN_CONF_$SUF\"
eval expect_ifconfig4=\"\$EXPECT_IFCONFIG4_$SUF\"
@@ -216,9 +272,22 @@ do
eval ping4_hosts=\"\$PING4_HOSTS_$SUF\"
eval ping6_hosts=\"\$PING6_HOSTS_$SUF\"
+ # If EXCEPT_IFCONFIG* variables for this test are missing, run an --up
+ # script to generate them dynamically.
+ if [ -z "$expect_ifconfig4" ] || [ -z "$expect_ifconfig6" ]; then
+ up="--setenv TESTNUM $SUF --setenv TOP_BUILDDIR ${top_builddir} --script-security 2 --up ${srcdir}/update_t_client_ips.sh"
+ else
+ up=""
+ fi
+
echo -e "\n### test run $SUF: '$test_run_title' ###\n"
fail_count=0
+ if [ -n "$test_prep" ]; then
+ echo -e "running preparation: '$test_prep'"
+ eval $test_prep
+ fi
+
echo "save pre-openvpn ifconfig + route"
get_ifconfig_route >$LOGDIR/$SUF:ifconfig_route_pre.txt
@@ -233,28 +302,56 @@ do
continue
fi
+ pidfile="${top_builddir}/tests/$LOGDIR/openvpn-$SUF.pid"
+ openvpn_conf="$openvpn_conf --writepid $pidfile $up"
echo " run openvpn $openvpn_conf"
echo "# src/openvpn/openvpn $openvpn_conf" >$LOGDIR/$SUF:openvpn.log
+ umask 022
$RUN_SUDO "${top_builddir}/src/openvpn/openvpn" $openvpn_conf >>$LOGDIR/$SUF:openvpn.log &
- opid=$!
+ sudopid=$!
- # make sure openvpn client is terminated in case shell exits
- trap "$RUN_SUDO kill $opid" 0
- trap "$RUN_SUDO kill $opid ; trap - 0 ; exit 1" 1 2 3 15
-
- echo "wait for connection to establish..."
- sleep ${SETUP_TIME_WAIT:-10}
+ # Check if OpenVPN has initialized before continuing. It will check every 3rd second up
+ # to $ovpn_init_check times.
+ ovpn_init_check=10
+ ovpn_init_success=0
+ while [ $ovpn_init_check -gt 0 ];
+ do
+ sleep 3 # Wait for OpenVPN to initialize and have had time to write the pid file
+ grep "Initialization Sequence Completed" $LOGDIR/$SUF:openvpn.log >/dev/null
+ if [ $? -eq 0 ]; then
+ ovpn_init_check=0
+ ovpn_init_success=1
+ fi
+ ovpn_init_check=$(( $ovpn_init_check - 1 ))
+ done
- # test whether OpenVPN process is still there
- if $RUN_SUDO kill -0 $opid
- then :
+ opid=`cat $pidfile`
+ if [ -n "$opid" ]; then
+ echo " OpenVPN running with PID $opid"
else
- echo -e "OpenVPN process has failed to start up, check log ($LOGDIR/$SUF:openvpn.log). FAIL.\ntail of logfile follows:\n..." >&2
- tail $LOGDIR/$SUF:openvpn.log >&2
+ echo " Could not read OpenVPN PID file" >&2
+ fi
+
+ # If OpenVPN did not start
+ if [ $ovpn_init_success -ne 1 -o -z "$opid" ]; then
+ echo "$0: OpenVPN did not initialize in a reasonable time" >&2
+ if [ -n "$opid" ]; then
+ $RUN_SUDO $KILL_EXEC $opid
+ fi
+ $RUN_SUDO $KILL_EXEC $sudopid
+ echo "tail -5 $SUF:openvpn.log" >&2
+ tail -5 $LOGDIR/$SUF:openvpn.log >&2
+ echo -e "\nFAIL. skip rest of sub-tests for test run $SUF.\n" >&2
trap - 0 1 2 3 15
- exit 10
+ SUMMARY_FAIL="$SUMMARY_FAIL $SUF"
+ exit_code=30
+ continue
fi
+ # make sure openvpn client is terminated in case shell exits
+ trap "$RUN_SUDO $KILL_EXEC $opid" 0
+ trap "$RUN_SUDO $KILL_EXEC $opid ; trap - 0 ; exit 1" 1 2 3 15
+
# compare whether anything changed in ifconfig/route setup?
echo "save ifconfig+route"
get_ifconfig_route >$LOGDIR/$SUF:ifconfig_route.txt
@@ -268,6 +365,12 @@ do
echo -e " OK!\n"
fi
+ # post init script needed?
+ if [ -n "$test_postinit" ]; then
+ echo -e "running post-init cmd: '$test_postinit'"
+ eval $test_postinit
+ fi
+
# expected ifconfig values in there?
check_ifconfig 4 "$expect_ifconfig4"
check_ifconfig 6 "$expect_ifconfig6"
@@ -277,7 +380,7 @@ do
echo -e "ping tests done.\n"
echo "stopping OpenVPN"
- $RUN_SUDO kill $opid
+ $RUN_SUDO $KILL_EXEC $opid
wait $!
rc=$?
if [ $rc != 0 ] ; then
@@ -304,6 +407,12 @@ do
SUMMARY_FAIL="$SUMMARY_FAIL $SUF"
exit_code=30
fi
+
+ if [ -n "$test_cleanup" ]; then
+ echo -e "cleaning up: '$test_cleanup'"
+ eval $test_cleanup
+ fi
+
done
if [ -z "$SUMMARY_OK" ] ; then SUMMARY_OK=" none"; fi
diff --git a/tests/t_client.sh.in b/tests/t_client.sh.in
index ccf6b26..b92cb65 100755
--- a/tests/t_client.sh.in
+++ b/tests/t_client.sh.in
@@ -24,6 +24,24 @@ else
exit 77
fi
+# Check for external dependencies
+which fping > /dev/null
+if [ $? -ne 0 ]; then
+ echo "$0: fping is not available in \$PATH" >&2
+ exit 77
+fi
+which fping6 > /dev/null
+if [ $? -ne 0 ]; then
+ echo "$0: fping6 is not available in \$PATH" >&2
+ exit 77
+fi
+
+KILL_EXEC=`which kill`
+if [ $? -ne 0 ]; then
+ echo "$0: kill not found in \$PATH" >&2
+ exit 77
+fi
+
if [ ! -x "${top_builddir}/src/openvpn/openvpn" ]
then
echo "no (executable) openvpn binary in current build tree. FAIL." >&2
@@ -46,17 +64,45 @@ if [ -z "$TEST_RUN_LIST" ] ; then
exit 77
fi
+# Ensure PREFER_KSU is in a known state
+PREFER_KSU="${PREFER_KSU:-0}"
+
# make sure we have permissions to run ifconfig/route from OpenVPN
# can't use "id -u" here - doesn't work on Solaris
ID=`id`
if expr "$ID" : "uid=0" >/dev/null
then :
else
+ if [ "${PREFER_KSU}" -eq 1 ];
+ then
+ # Check if we have a valid kerberos ticket
+ klist -l 1>/dev/null 2>/dev/null
+ if [ $? -ne 0 ];
+ then
+ # No kerberos ticket found, skip ksu and fallback to RUN_SUDO
+ PREFER_KSU=0
+ echo "$0: No Kerberos ticket available. Will not use ksu."
+ else
+ RUN_SUDO="ksu -q -e"
+ fi
+ fi
+
if [ -z "$RUN_SUDO" ]
then
echo "$0: this test must run be as root, or RUN_SUDO=... " >&2
echo " must be set correctly in 't_client.rc'. SKIP." >&2
exit 77
+ else
+ # We have to use sudo. Make sure that we (hopefully) do not have
+ # to ask the users password during the test. This is done to
+ # prevent timing issues, e.g. when the waits for openvpn to start
+ if $RUN_SUDO $KILL_EXEC -0 $$
+ then
+ echo "$0: $RUN_SUDO $KILL_EXEC -0 succeeded, good."
+ else
+ echo "$0: $RUN_SUDO $KILL_EXEC -0 failed, cannot go on. SKIP." >&2
+ exit 77
+ fi
fi
fi
@@ -73,6 +119,7 @@ exit_code=0
# ----------------------------------------------------------
# helper functions
# ----------------------------------------------------------
+
# print failure message, increase FAIL counter
fail()
{
@@ -122,6 +169,12 @@ get_ifconfig_route()
@NETSTAT@ -rn | awk '$3 !~ /^UHL/ { print $1,$2,$3,$6 }'
return
;;
+ AIX)
+ echo "-- AIX --"
+ @IFCONFIG@ -a | egrep "(flags=|inet)"
+ @NETSTAT@ -rn | awk '$3 !~ /^UHL/ { print $1,$2,$3,$6 }'
+ return
+ ;;
esac
echo "get_ifconfig_route(): no idea how to get info on your OS. FAIL." >&2
@@ -178,8 +231,8 @@ run_ping_tests()
do
echo "run IPv$proto ping tests ($want), $bytes byte packets..."
- echo "$cmd -b $bytes -C 20 -p 250 -q $targetlist" >>$LOGDIR/$SUF:fping.out
- $cmd -b $bytes -C 20 -p 250 -q $targetlist >>$LOGDIR/$SUF:fping.out 2>&1
+ echo "$cmd -b $bytes -C 20 -p 250 -q $FPING_EXTRA_ARGS $targetlist" >>$LOGDIR/$SUF:fping.out
+ $cmd -b $bytes -C 20 -p 250 -q $FPING_EXTRA_ARGS $targetlist >>$LOGDIR/$SUF:fping.out 2>&1
# while OpenVPN is running, pings must succeed (want='want_ok')
# before OpenVPN is up, pings must NOT succeed (want='want_fail')
@@ -209,6 +262,9 @@ SUMMARY_FAIL=
for SUF in $TEST_RUN_LIST
do
# get config variables
+ eval test_prep=\"\$PREPARE_$SUF\"
+ eval test_postinit=\"\$POSTINIT_CMD_$SUF\"
+ eval test_cleanup=\"\$CLEANUP_$SUF\"
eval test_run_title=\"\$RUN_TITLE_$SUF\"
eval openvpn_conf=\"\$OPENVPN_CONF_$SUF\"
eval expect_ifconfig4=\"\$EXPECT_IFCONFIG4_$SUF\"
@@ -216,9 +272,22 @@ do
eval ping4_hosts=\"\$PING4_HOSTS_$SUF\"
eval ping6_hosts=\"\$PING6_HOSTS_$SUF\"
+ # If EXCEPT_IFCONFIG* variables for this test are missing, run an --up
+ # script to generate them dynamically.
+ if [ -z "$expect_ifconfig4" ] || [ -z "$expect_ifconfig6" ]; then
+ up="--setenv TESTNUM $SUF --setenv TOP_BUILDDIR ${top_builddir} --script-security 2 --up ${srcdir}/update_t_client_ips.sh"
+ else
+ up=""
+ fi
+
echo -e "\n### test run $SUF: '$test_run_title' ###\n"
fail_count=0
+ if [ -n "$test_prep" ]; then
+ echo -e "running preparation: '$test_prep'"
+ eval $test_prep
+ fi
+
echo "save pre-openvpn ifconfig + route"
get_ifconfig_route >$LOGDIR/$SUF:ifconfig_route_pre.txt
@@ -233,28 +302,56 @@ do
continue
fi
+ pidfile="${top_builddir}/tests/$LOGDIR/openvpn-$SUF.pid"
+ openvpn_conf="$openvpn_conf --writepid $pidfile $up"
echo " run openvpn $openvpn_conf"
echo "# src/openvpn/openvpn $openvpn_conf" >$LOGDIR/$SUF:openvpn.log
+ umask 022
$RUN_SUDO "${top_builddir}/src/openvpn/openvpn" $openvpn_conf >>$LOGDIR/$SUF:openvpn.log &
- opid=$!
+ sudopid=$!
- # make sure openvpn client is terminated in case shell exits
- trap "$RUN_SUDO kill $opid" 0
- trap "$RUN_SUDO kill $opid ; trap - 0 ; exit 1" 1 2 3 15
-
- echo "wait for connection to establish..."
- sleep ${SETUP_TIME_WAIT:-10}
+ # Check if OpenVPN has initialized before continuing. It will check every 3rd second up
+ # to $ovpn_init_check times.
+ ovpn_init_check=10
+ ovpn_init_success=0
+ while [ $ovpn_init_check -gt 0 ];
+ do
+ sleep 3 # Wait for OpenVPN to initialize and have had time to write the pid file
+ grep "Initialization Sequence Completed" $LOGDIR/$SUF:openvpn.log >/dev/null
+ if [ $? -eq 0 ]; then
+ ovpn_init_check=0
+ ovpn_init_success=1
+ fi
+ ovpn_init_check=$(( $ovpn_init_check - 1 ))
+ done
- # test whether OpenVPN process is still there
- if $RUN_SUDO kill -0 $opid
- then :
+ opid=`cat $pidfile`
+ if [ -n "$opid" ]; then
+ echo " OpenVPN running with PID $opid"
else
- echo -e "OpenVPN process has failed to start up, check log ($LOGDIR/$SUF:openvpn.log). FAIL.\ntail of logfile follows:\n..." >&2
- tail $LOGDIR/$SUF:openvpn.log >&2
+ echo " Could not read OpenVPN PID file" >&2
+ fi
+
+ # If OpenVPN did not start
+ if [ $ovpn_init_success -ne 1 -o -z "$opid" ]; then
+ echo "$0: OpenVPN did not initialize in a reasonable time" >&2
+ if [ -n "$opid" ]; then
+ $RUN_SUDO $KILL_EXEC $opid
+ fi
+ $RUN_SUDO $KILL_EXEC $sudopid
+ echo "tail -5 $SUF:openvpn.log" >&2
+ tail -5 $LOGDIR/$SUF:openvpn.log >&2
+ echo -e "\nFAIL. skip rest of sub-tests for test run $SUF.\n" >&2
trap - 0 1 2 3 15
- exit 10
+ SUMMARY_FAIL="$SUMMARY_FAIL $SUF"
+ exit_code=30
+ continue
fi
+ # make sure openvpn client is terminated in case shell exits
+ trap "$RUN_SUDO $KILL_EXEC $opid" 0
+ trap "$RUN_SUDO $KILL_EXEC $opid ; trap - 0 ; exit 1" 1 2 3 15
+
# compare whether anything changed in ifconfig/route setup?
echo "save ifconfig+route"
get_ifconfig_route >$LOGDIR/$SUF:ifconfig_route.txt
@@ -268,6 +365,12 @@ do
echo -e " OK!\n"
fi
+ # post init script needed?
+ if [ -n "$test_postinit" ]; then
+ echo -e "running post-init cmd: '$test_postinit'"
+ eval $test_postinit
+ fi
+
# expected ifconfig values in there?
check_ifconfig 4 "$expect_ifconfig4"
check_ifconfig 6 "$expect_ifconfig6"
@@ -277,7 +380,7 @@ do
echo -e "ping tests done.\n"
echo "stopping OpenVPN"
- $RUN_SUDO kill $opid
+ $RUN_SUDO $KILL_EXEC $opid
wait $!
rc=$?
if [ $rc != 0 ] ; then
@@ -304,6 +407,12 @@ do
SUMMARY_FAIL="$SUMMARY_FAIL $SUF"
exit_code=30
fi
+
+ if [ -n "$test_cleanup" ]; then
+ echo -e "cleaning up: '$test_cleanup'"
+ eval $test_cleanup
+ fi
+
done
if [ -z "$SUMMARY_OK" ] ; then SUMMARY_OK=" none"; fi
diff --git a/tests/t_lpback.sh b/tests/t_lpback.sh
index d7792cd..2052c62 100755
--- a/tests/t_lpback.sh
+++ b/tests/t_lpback.sh
@@ -26,7 +26,7 @@ trap "rm -f key.$$ log.$$ ; exit 1" 0 3
# Get list of supported ciphers from openvpn --show-ciphers output
CIPHERS=$(${top_builddir}/src/openvpn/openvpn --show-ciphers | \
- sed -e '1,/^$/d' -e s'/ .*//' -e '/^\s*$/d' | sort)
+ sed -e '/The following/,/^$/d' -e s'/ .*//' -e '/^\s*$/d')
# SK, 2014-06-04: currently the DES-EDE3-CFB1 implementation of OpenSSL is
# broken (see http://rt.openssl.org/Ticket/Display.html?id=2867), so exclude
diff --git a/tests/unit_tests/Makefile.am b/tests/unit_tests/Makefile.am
new file mode 100644
index 0000000..31d37b8
--- /dev/null
+++ b/tests/unit_tests/Makefile.am
@@ -0,0 +1,5 @@
+AUTOMAKE_OPTIONS = foreign
+
+if CMOCKA_INITIALIZED
+SUBDIRS = example_test openvpn plugins
+endif
diff --git a/tests/unit_tests/Makefile.in b/tests/unit_tests/Makefile.in
new file mode 100644
index 0000000..6cc6043
--- /dev/null
+++ b/tests/unit_tests/Makefile.in
@@ -0,0 +1,666 @@
+# Makefile.in generated by automake 1.13.4 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+VPATH = @srcdir@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = tests/unit_tests
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_emptyarray.m4 \
+ $(top_srcdir)/m4/ax_socklen_t.m4 \
+ $(top_srcdir)/m4/ax_varargs.m4 $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/pkg.m4 $(top_srcdir)/version.m4 \
+ $(top_srcdir)/compat.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h \
+ $(top_builddir)/include/openvpn-plugin.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+SOURCES =
+DIST_SOURCES =
+RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
+ ctags-recursive dvi-recursive html-recursive info-recursive \
+ install-data-recursive install-dvi-recursive \
+ install-exec-recursive install-html-recursive \
+ install-info-recursive install-pdf-recursive \
+ install-ps-recursive install-recursive installcheck-recursive \
+ installdirs-recursive pdf-recursive ps-recursive \
+ tags-recursive uninstall-recursive
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
+ distclean-recursive maintainer-clean-recursive
+am__recursive_targets = \
+ $(RECURSIVE_TARGETS) \
+ $(RECURSIVE_CLEAN_TARGETS) \
+ $(am__extra_recursive_targets)
+AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
+ distdir
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+DIST_SUBDIRS = example_test openvpn plugins
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+am__relativize = \
+ dir0=`pwd`; \
+ sed_first='s,^\([^/]*\)/.*$$,\1,'; \
+ sed_rest='s,^[^/]*/*,,'; \
+ sed_last='s,^.*/\([^/]*\)$$,\1,'; \
+ sed_butlast='s,/*[^/]*$$,,'; \
+ while test -n "$$dir1"; do \
+ first=`echo "$$dir1" | sed -e "$$sed_first"`; \
+ if test "$$first" != "."; then \
+ if test "$$first" = ".."; then \
+ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
+ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
+ else \
+ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
+ if test "$$first2" = "$$first"; then \
+ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
+ else \
+ dir2="../$$dir2"; \
+ fi; \
+ dir0="$$dir0"/"$$first"; \
+ fi; \
+ fi; \
+ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
+ done; \
+ reldir="$$dir2"
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AS = @AS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CMAKE = @CMAKE@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DL_LIBS = @DL_LIBS@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GIT = @GIT@
+GREP = @GREP@
+IFCONFIG = @IFCONFIG@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+IPROUTE = @IPROUTE@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBPAM_CFLAGS = @LIBPAM_CFLAGS@
+LIBPAM_LIBS = @LIBPAM_LIBS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LZ4_CFLAGS = @LZ4_CFLAGS@
+LZ4_LIBS = @LZ4_LIBS@
+LZO_CFLAGS = @LZO_CFLAGS@
+LZO_LIBS = @LZO_LIBS@
+MAKEINFO = @MAKEINFO@
+MAN2HTML = @MAN2HTML@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MBEDTLS_CFLAGS = @MBEDTLS_CFLAGS@
+MBEDTLS_LIBS = @MBEDTLS_LIBS@
+MKDIR_P = @MKDIR_P@
+NETSTAT = @NETSTAT@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OPENSSL_CFLAGS = @OPENSSL_CFLAGS@
+OPENSSL_LIBS = @OPENSSL_LIBS@
+OPENVPN_VERSION_MAJOR = @OPENVPN_VERSION_MAJOR@
+OPENVPN_VERSION_MINOR = @OPENVPN_VERSION_MINOR@
+OPENVPN_VERSION_PATCH = @OPENVPN_VERSION_PATCH@
+OPTIONAL_CRYPTO_CFLAGS = @OPTIONAL_CRYPTO_CFLAGS@
+OPTIONAL_CRYPTO_LIBS = @OPTIONAL_CRYPTO_LIBS@
+OPTIONAL_DL_LIBS = @OPTIONAL_DL_LIBS@
+OPTIONAL_LZ4_CFLAGS = @OPTIONAL_LZ4_CFLAGS@
+OPTIONAL_LZ4_LIBS = @OPTIONAL_LZ4_LIBS@
+OPTIONAL_LZO_CFLAGS = @OPTIONAL_LZO_CFLAGS@
+OPTIONAL_LZO_LIBS = @OPTIONAL_LZO_LIBS@
+OPTIONAL_PKCS11_HELPER_CFLAGS = @OPTIONAL_PKCS11_HELPER_CFLAGS@
+OPTIONAL_PKCS11_HELPER_LIBS = @OPTIONAL_PKCS11_HELPER_LIBS@
+OPTIONAL_SELINUX_LIBS = @OPTIONAL_SELINUX_LIBS@
+OPTIONAL_SYSTEMD_LIBS = @OPTIONAL_SYSTEMD_LIBS@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+P11KIT_CFLAGS = @P11KIT_CFLAGS@
+P11KIT_LIBS = @P11KIT_LIBS@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKCS11_HELPER_CFLAGS = @PKCS11_HELPER_CFLAGS@
+PKCS11_HELPER_LIBS = @PKCS11_HELPER_LIBS@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+PLUGIN_AUTH_PAM_CFLAGS = @PLUGIN_AUTH_PAM_CFLAGS@
+PLUGIN_AUTH_PAM_LIBS = @PLUGIN_AUTH_PAM_LIBS@
+RANLIB = @RANLIB@
+RC = @RC@
+ROUTE = @ROUTE@
+SED = @SED@
+SELINUX_LIBS = @SELINUX_LIBS@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SOCKETS_LIBS = @SOCKETS_LIBS@
+STRIP = @STRIP@
+SYSTEMD_ASK_PASSWORD = @SYSTEMD_ASK_PASSWORD@
+TAP_CFLAGS = @TAP_CFLAGS@
+TAP_WIN_COMPONENT_ID = @TAP_WIN_COMPONENT_ID@
+TAP_WIN_MIN_MAJOR = @TAP_WIN_MIN_MAJOR@
+TAP_WIN_MIN_MINOR = @TAP_WIN_MIN_MINOR@
+TEST_CFLAGS = @TEST_CFLAGS@
+TEST_LDFLAGS = @TEST_LDFLAGS@
+VENDOR_BUILD_ROOT = @VENDOR_BUILD_ROOT@
+VENDOR_DIST_ROOT = @VENDOR_DIST_ROOT@
+VENDOR_SRC_ROOT = @VENDOR_SRC_ROOT@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+libsystemd_CFLAGS = @libsystemd_CFLAGS@
+libsystemd_LIBS = @libsystemd_LIBS@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+plugindir = @plugindir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sampledir = @sampledir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+AUTOMAKE_OPTIONS = foreign
+@CMOCKA_INITIALIZED_TRUE@SUBDIRS = example_test openvpn plugins
+all: all-recursive
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign tests/unit_tests/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign tests/unit_tests/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *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);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run 'make' without going through this Makefile.
+# To change the values of 'make' variables: instead of editing Makefiles,
+# (1) if the variable is set in 'config.status', edit 'config.status'
+# (which will cause the Makefiles to be regenerated when you run 'make');
+# (2) otherwise, pass the desired values on the 'make' command line.
+$(am__recursive_targets):
+ @fail=; \
+ if $(am__make_keepgoing); then \
+ failcom='fail=yes'; \
+ else \
+ failcom='exit 1'; \
+ fi; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ case "$@" in \
+ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+ *) list='$(SUBDIRS)' ;; \
+ esac; \
+ for subdir in $$list; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ dot_seen=yes; \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-recursive
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+ include_option=--etags-include; \
+ empty_fix=.; \
+ else \
+ include_option=--include; \
+ empty_fix=; \
+ fi; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test ! -f $$subdir/TAGS || \
+ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-recursive
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-recursive
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+ @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ $(am__make_dryrun) \
+ || test -d "$(distdir)/$$subdir" \
+ || $(MKDIR_P) "$(distdir)/$$subdir" \
+ || exit 1; \
+ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
+ $(am__relativize); \
+ new_distdir=$$reldir; \
+ dir1=$$subdir; dir2="$(top_distdir)"; \
+ $(am__relativize); \
+ new_top_distdir=$$reldir; \
+ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
+ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
+ ($(am__cd) $$subdir && \
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="$$new_top_distdir" \
+ distdir="$$new_distdir" \
+ am__remove_distdir=: \
+ am__skip_length_check=: \
+ am__skip_mode_fix=: \
+ distdir) \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-recursive
+all-am: Makefile
+installdirs: installdirs-recursive
+installdirs-am:
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-recursive
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-recursive
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+html-am:
+
+info: info-recursive
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-recursive
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-recursive
+
+install-html-am:
+
+install-info: install-info-recursive
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-recursive
+
+install-pdf-am:
+
+install-ps: install-ps-recursive
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: $(am__recursive_targets) install-am install-strip
+
+.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \
+ check-am clean clean-generic clean-libtool cscopelist-am ctags \
+ ctags-am distclean 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 install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ installdirs-am maintainer-clean maintainer-clean-generic \
+ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
+ ps ps-am tags tags-am uninstall uninstall-am
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/tests/unit_tests/example_test/Makefile.am b/tests/unit_tests/example_test/Makefile.am
new file mode 100644
index 0000000..04a5ad3
--- /dev/null
+++ b/tests/unit_tests/example_test/Makefile.am
@@ -0,0 +1,13 @@
+AUTOMAKE_OPTIONS = foreign
+
+check_PROGRAMS = example_testdriver example2_testdriver
+
+TESTS = $(check_PROGRAMS)
+
+example_testdriver_CFLAGS = @TEST_CFLAGS@
+example_testdriver_LDFLAGS = @TEST_LDFLAGS@
+example_testdriver_SOURCES = test.c
+
+example2_testdriver_CFLAGS = @TEST_CFLAGS@
+example2_testdriver_LDFLAGS = @TEST_LDFLAGS@
+example2_testdriver_SOURCES = test2.c
diff --git a/tests/unit_tests/example_test/Makefile.in b/tests/unit_tests/example_test/Makefile.in
new file mode 100644
index 0000000..ff4f6c4
--- /dev/null
+++ b/tests/unit_tests/example_test/Makefile.in
@@ -0,0 +1,800 @@
+# Makefile.in generated by automake 1.13.4 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+VPATH = @srcdir@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+check_PROGRAMS = example_testdriver$(EXEEXT) \
+ example2_testdriver$(EXEEXT)
+subdir = tests/unit_tests/example_test
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+ $(top_srcdir)/depcomp
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_emptyarray.m4 \
+ $(top_srcdir)/m4/ax_socklen_t.m4 \
+ $(top_srcdir)/m4/ax_varargs.m4 $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/pkg.m4 $(top_srcdir)/version.m4 \
+ $(top_srcdir)/compat.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h \
+ $(top_builddir)/include/openvpn-plugin.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am_example2_testdriver_OBJECTS = example2_testdriver-test2.$(OBJEXT)
+example2_testdriver_OBJECTS = $(am_example2_testdriver_OBJECTS)
+example2_testdriver_LDADD = $(LDADD)
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+example2_testdriver_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(example2_testdriver_CFLAGS) $(CFLAGS) \
+ $(example2_testdriver_LDFLAGS) $(LDFLAGS) -o $@
+am_example_testdriver_OBJECTS = example_testdriver-test.$(OBJEXT)
+example_testdriver_OBJECTS = $(am_example_testdriver_OBJECTS)
+example_testdriver_LDADD = $(LDADD)
+example_testdriver_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(example_testdriver_CFLAGS) $(CFLAGS) \
+ $(example_testdriver_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+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__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+SOURCES = $(example2_testdriver_SOURCES) $(example_testdriver_SOURCES)
+DIST_SOURCES = $(example2_testdriver_SOURCES) \
+ $(example_testdriver_SOURCES)
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors_dummy = \
+ mgn= red= grn= lgn= blu= brg= std=; \
+ am__color_tests=no
+am__tty_colors = { \
+ $(am__tty_colors_dummy); \
+ if test "X$(AM_COLOR_TESTS)" = Xno; then \
+ am__color_tests=no; \
+ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+ am__color_tests=yes; \
+ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+ am__color_tests=yes; \
+ fi; \
+ if test $$am__color_tests = yes; then \
+ red=''; \
+ grn=''; \
+ lgn=''; \
+ blu=''; \
+ mgn=''; \
+ brg=''; \
+ std=''; \
+ fi; \
+}
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AS = @AS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CMAKE = @CMAKE@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DL_LIBS = @DL_LIBS@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GIT = @GIT@
+GREP = @GREP@
+IFCONFIG = @IFCONFIG@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+IPROUTE = @IPROUTE@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBPAM_CFLAGS = @LIBPAM_CFLAGS@
+LIBPAM_LIBS = @LIBPAM_LIBS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LZ4_CFLAGS = @LZ4_CFLAGS@
+LZ4_LIBS = @LZ4_LIBS@
+LZO_CFLAGS = @LZO_CFLAGS@
+LZO_LIBS = @LZO_LIBS@
+MAKEINFO = @MAKEINFO@
+MAN2HTML = @MAN2HTML@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MBEDTLS_CFLAGS = @MBEDTLS_CFLAGS@
+MBEDTLS_LIBS = @MBEDTLS_LIBS@
+MKDIR_P = @MKDIR_P@
+NETSTAT = @NETSTAT@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OPENSSL_CFLAGS = @OPENSSL_CFLAGS@
+OPENSSL_LIBS = @OPENSSL_LIBS@
+OPENVPN_VERSION_MAJOR = @OPENVPN_VERSION_MAJOR@
+OPENVPN_VERSION_MINOR = @OPENVPN_VERSION_MINOR@
+OPENVPN_VERSION_PATCH = @OPENVPN_VERSION_PATCH@
+OPTIONAL_CRYPTO_CFLAGS = @OPTIONAL_CRYPTO_CFLAGS@
+OPTIONAL_CRYPTO_LIBS = @OPTIONAL_CRYPTO_LIBS@
+OPTIONAL_DL_LIBS = @OPTIONAL_DL_LIBS@
+OPTIONAL_LZ4_CFLAGS = @OPTIONAL_LZ4_CFLAGS@
+OPTIONAL_LZ4_LIBS = @OPTIONAL_LZ4_LIBS@
+OPTIONAL_LZO_CFLAGS = @OPTIONAL_LZO_CFLAGS@
+OPTIONAL_LZO_LIBS = @OPTIONAL_LZO_LIBS@
+OPTIONAL_PKCS11_HELPER_CFLAGS = @OPTIONAL_PKCS11_HELPER_CFLAGS@
+OPTIONAL_PKCS11_HELPER_LIBS = @OPTIONAL_PKCS11_HELPER_LIBS@
+OPTIONAL_SELINUX_LIBS = @OPTIONAL_SELINUX_LIBS@
+OPTIONAL_SYSTEMD_LIBS = @OPTIONAL_SYSTEMD_LIBS@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+P11KIT_CFLAGS = @P11KIT_CFLAGS@
+P11KIT_LIBS = @P11KIT_LIBS@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKCS11_HELPER_CFLAGS = @PKCS11_HELPER_CFLAGS@
+PKCS11_HELPER_LIBS = @PKCS11_HELPER_LIBS@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+PLUGIN_AUTH_PAM_CFLAGS = @PLUGIN_AUTH_PAM_CFLAGS@
+PLUGIN_AUTH_PAM_LIBS = @PLUGIN_AUTH_PAM_LIBS@
+RANLIB = @RANLIB@
+RC = @RC@
+ROUTE = @ROUTE@
+SED = @SED@
+SELINUX_LIBS = @SELINUX_LIBS@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SOCKETS_LIBS = @SOCKETS_LIBS@
+STRIP = @STRIP@
+SYSTEMD_ASK_PASSWORD = @SYSTEMD_ASK_PASSWORD@
+TAP_CFLAGS = @TAP_CFLAGS@
+TAP_WIN_COMPONENT_ID = @TAP_WIN_COMPONENT_ID@
+TAP_WIN_MIN_MAJOR = @TAP_WIN_MIN_MAJOR@
+TAP_WIN_MIN_MINOR = @TAP_WIN_MIN_MINOR@
+TEST_CFLAGS = @TEST_CFLAGS@
+TEST_LDFLAGS = @TEST_LDFLAGS@
+VENDOR_BUILD_ROOT = @VENDOR_BUILD_ROOT@
+VENDOR_DIST_ROOT = @VENDOR_DIST_ROOT@
+VENDOR_SRC_ROOT = @VENDOR_SRC_ROOT@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+libsystemd_CFLAGS = @libsystemd_CFLAGS@
+libsystemd_LIBS = @libsystemd_LIBS@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+plugindir = @plugindir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sampledir = @sampledir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+AUTOMAKE_OPTIONS = foreign
+TESTS = $(check_PROGRAMS)
+example_testdriver_CFLAGS = @TEST_CFLAGS@
+example_testdriver_LDFLAGS = @TEST_LDFLAGS@
+example_testdriver_SOURCES = test.c
+example2_testdriver_CFLAGS = @TEST_CFLAGS@
+example2_testdriver_LDFLAGS = @TEST_LDFLAGS@
+example2_testdriver_SOURCES = test2.c
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign tests/unit_tests/example_test/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign tests/unit_tests/example_test/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *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);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-checkPROGRAMS:
+ @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+
+example2_testdriver$(EXEEXT): $(example2_testdriver_OBJECTS) $(example2_testdriver_DEPENDENCIES) $(EXTRA_example2_testdriver_DEPENDENCIES)
+ @rm -f example2_testdriver$(EXEEXT)
+ $(AM_V_CCLD)$(example2_testdriver_LINK) $(example2_testdriver_OBJECTS) $(example2_testdriver_LDADD) $(LIBS)
+
+example_testdriver$(EXEEXT): $(example_testdriver_OBJECTS) $(example_testdriver_DEPENDENCIES) $(EXTRA_example_testdriver_DEPENDENCIES)
+ @rm -f example_testdriver$(EXEEXT)
+ $(AM_V_CCLD)$(example_testdriver_LINK) $(example_testdriver_OBJECTS) $(example_testdriver_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/example2_testdriver-test2.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/example_testdriver-test.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+example2_testdriver-test2.o: test2.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(example2_testdriver_CFLAGS) $(CFLAGS) -MT example2_testdriver-test2.o -MD -MP -MF $(DEPDIR)/example2_testdriver-test2.Tpo -c -o example2_testdriver-test2.o `test -f 'test2.c' || echo '$(srcdir)/'`test2.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/example2_testdriver-test2.Tpo $(DEPDIR)/example2_testdriver-test2.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='test2.c' object='example2_testdriver-test2.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(example2_testdriver_CFLAGS) $(CFLAGS) -c -o example2_testdriver-test2.o `test -f 'test2.c' || echo '$(srcdir)/'`test2.c
+
+example2_testdriver-test2.obj: test2.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(example2_testdriver_CFLAGS) $(CFLAGS) -MT example2_testdriver-test2.obj -MD -MP -MF $(DEPDIR)/example2_testdriver-test2.Tpo -c -o example2_testdriver-test2.obj `if test -f 'test2.c'; then $(CYGPATH_W) 'test2.c'; else $(CYGPATH_W) '$(srcdir)/test2.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/example2_testdriver-test2.Tpo $(DEPDIR)/example2_testdriver-test2.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='test2.c' object='example2_testdriver-test2.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(example2_testdriver_CFLAGS) $(CFLAGS) -c -o example2_testdriver-test2.obj `if test -f 'test2.c'; then $(CYGPATH_W) 'test2.c'; else $(CYGPATH_W) '$(srcdir)/test2.c'; fi`
+
+example_testdriver-test.o: test.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(example_testdriver_CFLAGS) $(CFLAGS) -MT example_testdriver-test.o -MD -MP -MF $(DEPDIR)/example_testdriver-test.Tpo -c -o example_testdriver-test.o `test -f 'test.c' || echo '$(srcdir)/'`test.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/example_testdriver-test.Tpo $(DEPDIR)/example_testdriver-test.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='test.c' object='example_testdriver-test.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(example_testdriver_CFLAGS) $(CFLAGS) -c -o example_testdriver-test.o `test -f 'test.c' || echo '$(srcdir)/'`test.c
+
+example_testdriver-test.obj: test.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(example_testdriver_CFLAGS) $(CFLAGS) -MT example_testdriver-test.obj -MD -MP -MF $(DEPDIR)/example_testdriver-test.Tpo -c -o example_testdriver-test.obj `if test -f 'test.c'; then $(CYGPATH_W) 'test.c'; else $(CYGPATH_W) '$(srcdir)/test.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/example_testdriver-test.Tpo $(DEPDIR)/example_testdriver-test.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='test.c' object='example_testdriver-test.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(example_testdriver_CFLAGS) $(CFLAGS) -c -o example_testdriver-test.obj `if test -f 'test.c'; then $(CYGPATH_W) 'test.c'; else $(CYGPATH_W) '$(srcdir)/test.c'; fi`
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+check-TESTS: $(TESTS)
+ @failed=0; all=0; xfail=0; xpass=0; skip=0; \
+ srcdir=$(srcdir); export srcdir; \
+ list=' $(TESTS) '; \
+ $(am__tty_colors); \
+ if test -n "$$list"; then \
+ for tst in $$list; do \
+ if test -f ./$$tst; then dir=./; \
+ elif test -f $$tst; then dir=; \
+ else dir="$(srcdir)/"; fi; \
+ if $(TESTS_ENVIRONMENT) $${dir}$$tst $(AM_TESTS_FD_REDIRECT); then \
+ all=`expr $$all + 1`; \
+ case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$tst[\ \ ]*) \
+ xpass=`expr $$xpass + 1`; \
+ failed=`expr $$failed + 1`; \
+ col=$$red; res=XPASS; \
+ ;; \
+ *) \
+ col=$$grn; res=PASS; \
+ ;; \
+ esac; \
+ elif test $$? -ne 77; then \
+ all=`expr $$all + 1`; \
+ case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$tst[\ \ ]*) \
+ xfail=`expr $$xfail + 1`; \
+ col=$$lgn; res=XFAIL; \
+ ;; \
+ *) \
+ failed=`expr $$failed + 1`; \
+ col=$$red; res=FAIL; \
+ ;; \
+ esac; \
+ else \
+ skip=`expr $$skip + 1`; \
+ col=$$blu; res=SKIP; \
+ fi; \
+ echo "$${col}$$res$${std}: $$tst"; \
+ done; \
+ if test "$$all" -eq 1; then \
+ tests="test"; \
+ All=""; \
+ else \
+ tests="tests"; \
+ All="All "; \
+ fi; \
+ if test "$$failed" -eq 0; then \
+ if test "$$xfail" -eq 0; then \
+ banner="$$All$$all $$tests passed"; \
+ else \
+ if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \
+ banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \
+ fi; \
+ else \
+ if test "$$xpass" -eq 0; then \
+ banner="$$failed of $$all $$tests failed"; \
+ else \
+ if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \
+ banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \
+ fi; \
+ fi; \
+ dashes="$$banner"; \
+ skipped=""; \
+ if test "$$skip" -ne 0; then \
+ if test "$$skip" -eq 1; then \
+ skipped="($$skip test was not run)"; \
+ else \
+ skipped="($$skip tests were not run)"; \
+ fi; \
+ test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \
+ dashes="$$skipped"; \
+ fi; \
+ report=""; \
+ if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \
+ report="Please report to $(PACKAGE_BUGREPORT)"; \
+ test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \
+ dashes="$$report"; \
+ fi; \
+ dashes=`echo "$$dashes" | sed s/./=/g`; \
+ if test "$$failed" -eq 0; then \
+ col="$$grn"; \
+ else \
+ col="$$red"; \
+ fi; \
+ echo "$${col}$$dashes$${std}"; \
+ echo "$${col}$$banner$${std}"; \
+ test -z "$$skipped" || echo "$${col}$$skipped$${std}"; \
+ test -z "$$report" || echo "$${col}$$report$${std}"; \
+ echo "$${col}$$dashes$${std}"; \
+ test "$$failed" -eq 0; \
+ else :; fi
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS)
+ $(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-am
+all-am: Makefile
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-checkPROGRAMS clean-generic clean-libtool \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-TESTS check-am clean \
+ clean-checkPROGRAMS clean-generic clean-libtool 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 \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-pdf install-pdf-am \
+ install-ps install-ps-am install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags tags-am uninstall uninstall-am
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/tests/unit_tests/example_test/test.c b/tests/unit_tests/example_test/test.c
new file mode 100644
index 0000000..9986898
--- /dev/null
+++ b/tests/unit_tests/example_test/test.c
@@ -0,0 +1,46 @@
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <setjmp.h>
+#include <cmocka.h>
+
+static int setup(void **state) {
+ int *answer = malloc(sizeof(int));
+
+ *answer=42;
+ *state=answer;
+
+ return 0;
+}
+
+static int teardown(void **state) {
+ free(*state);
+
+ return 0;
+}
+
+static void null_test_success(void **state) {
+ (void) state;
+}
+
+static void int_test_success(void **state) {
+ int *answer = *state;
+ assert_int_equal(*answer, 42);
+}
+
+static void failing_test(void **state) {
+ // This tests fails to test that make check fails
+ assert_int_equal(0, 42);
+}
+
+int main(void) {
+ const struct CMUnitTest tests[] = {
+ cmocka_unit_test(null_test_success),
+ cmocka_unit_test_setup_teardown(int_test_success, setup, teardown),
+// cmocka_unit_test(failing_test),
+ };
+
+ return cmocka_run_group_tests_name("success_test", tests, NULL, NULL);
+}
diff --git a/tests/unit_tests/example_test/test2.c b/tests/unit_tests/example_test/test2.c
new file mode 100644
index 0000000..f99da9e
--- /dev/null
+++ b/tests/unit_tests/example_test/test2.c
@@ -0,0 +1,21 @@
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <setjmp.h>
+#include <cmocka.h>
+
+
+static void test_true(void **state) {
+ (void) state;
+}
+
+
+int main(void) {
+ const struct CMUnitTest tests[] = {
+ cmocka_unit_test(test_true),
+ };
+
+ return cmocka_run_group_tests_name("success_test2", tests, NULL, NULL);
+}
diff --git a/tests/unit_tests/openvpn/Makefile.am b/tests/unit_tests/openvpn/Makefile.am
new file mode 100644
index 0000000..632ff58
--- /dev/null
+++ b/tests/unit_tests/openvpn/Makefile.am
@@ -0,0 +1,37 @@
+AUTOMAKE_OPTIONS = foreign
+
+check_PROGRAMS = argv_testdriver
+
+if ENABLE_CRYPTO
+check_PROGRAMS += tls_crypt_testdriver
+endif
+
+TESTS = $(check_PROGRAMS)
+
+openvpn_includedir = $(top_srcdir)/include
+openvpn_srcdir = $(top_srcdir)/src/openvpn
+compat_srcdir = $(top_srcdir)/src/compat
+
+argv_testdriver_CFLAGS = @TEST_CFLAGS@ -I$(openvpn_srcdir) -I$(compat_srcdir) \
+ $(OPTIONAL_CRYPTO_CFLAGS)
+argv_testdriver_LDFLAGS = @TEST_LDFLAGS@ -L$(openvpn_srcdir) -Wl,--wrap=parse_line \
+ $(OPTIONAL_CRYPTO_LIBS)
+argv_testdriver_SOURCES = test_argv.c mock_msg.c \
+ $(openvpn_srcdir)/platform.c \
+ $(openvpn_srcdir)/buffer.c \
+ $(openvpn_srcdir)/argv.c
+
+tls_crypt_testdriver_CFLAGS = @TEST_CFLAGS@ \
+ -I$(openvpn_includedir) -I$(compat_srcdir) -I$(openvpn_srcdir) \
+ $(OPTIONAL_CRYPTO_CFLAGS)
+tls_crypt_testdriver_LDFLAGS = @TEST_LDFLAGS@ \
+ $(OPTIONAL_CRYPTO_LIBS)
+tls_crypt_testdriver_SOURCES = test_tls_crypt.c mock_msg.c \
+ $(openvpn_srcdir)/buffer.c \
+ $(openvpn_srcdir)/crypto.c \
+ $(openvpn_srcdir)/crypto_mbedtls.c \
+ $(openvpn_srcdir)/crypto_openssl.c \
+ $(openvpn_srcdir)/otime.c \
+ $(openvpn_srcdir)/packet_id.c \
+ $(openvpn_srcdir)/platform.c \
+ $(openvpn_srcdir)/tls_crypt.c
diff --git a/tests/unit_tests/openvpn/Makefile.in b/tests/unit_tests/openvpn/Makefile.in
new file mode 100644
index 0000000..3816fef
--- /dev/null
+++ b/tests/unit_tests/openvpn/Makefile.in
@@ -0,0 +1,1035 @@
+# Makefile.in generated by automake 1.13.4 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+VPATH = @srcdir@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+check_PROGRAMS = argv_testdriver$(EXEEXT) $(am__EXEEXT_1)
+@ENABLE_CRYPTO_TRUE@am__append_1 = tls_crypt_testdriver
+subdir = tests/unit_tests/openvpn
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+ $(top_srcdir)/depcomp
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_emptyarray.m4 \
+ $(top_srcdir)/m4/ax_socklen_t.m4 \
+ $(top_srcdir)/m4/ax_varargs.m4 $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/pkg.m4 $(top_srcdir)/version.m4 \
+ $(top_srcdir)/compat.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h \
+ $(top_builddir)/include/openvpn-plugin.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+@ENABLE_CRYPTO_TRUE@am__EXEEXT_1 = tls_crypt_testdriver$(EXEEXT)
+am_argv_testdriver_OBJECTS = argv_testdriver-test_argv.$(OBJEXT) \
+ argv_testdriver-mock_msg.$(OBJEXT) \
+ argv_testdriver-platform.$(OBJEXT) \
+ argv_testdriver-buffer.$(OBJEXT) \
+ argv_testdriver-argv.$(OBJEXT)
+argv_testdriver_OBJECTS = $(am_argv_testdriver_OBJECTS)
+argv_testdriver_LDADD = $(LDADD)
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+argv_testdriver_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(argv_testdriver_CFLAGS) $(CFLAGS) $(argv_testdriver_LDFLAGS) \
+ $(LDFLAGS) -o $@
+am_tls_crypt_testdriver_OBJECTS = \
+ tls_crypt_testdriver-test_tls_crypt.$(OBJEXT) \
+ tls_crypt_testdriver-mock_msg.$(OBJEXT) \
+ tls_crypt_testdriver-buffer.$(OBJEXT) \
+ tls_crypt_testdriver-crypto.$(OBJEXT) \
+ tls_crypt_testdriver-crypto_mbedtls.$(OBJEXT) \
+ tls_crypt_testdriver-crypto_openssl.$(OBJEXT) \
+ tls_crypt_testdriver-otime.$(OBJEXT) \
+ tls_crypt_testdriver-packet_id.$(OBJEXT) \
+ tls_crypt_testdriver-platform.$(OBJEXT) \
+ tls_crypt_testdriver-tls_crypt.$(OBJEXT)
+tls_crypt_testdriver_OBJECTS = $(am_tls_crypt_testdriver_OBJECTS)
+tls_crypt_testdriver_LDADD = $(LDADD)
+tls_crypt_testdriver_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(tls_crypt_testdriver_CFLAGS) $(CFLAGS) \
+ $(tls_crypt_testdriver_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+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__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+SOURCES = $(argv_testdriver_SOURCES) $(tls_crypt_testdriver_SOURCES)
+DIST_SOURCES = $(argv_testdriver_SOURCES) \
+ $(tls_crypt_testdriver_SOURCES)
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors_dummy = \
+ mgn= red= grn= lgn= blu= brg= std=; \
+ am__color_tests=no
+am__tty_colors = { \
+ $(am__tty_colors_dummy); \
+ if test "X$(AM_COLOR_TESTS)" = Xno; then \
+ am__color_tests=no; \
+ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+ am__color_tests=yes; \
+ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+ am__color_tests=yes; \
+ fi; \
+ if test $$am__color_tests = yes; then \
+ red=''; \
+ grn=''; \
+ lgn=''; \
+ blu=''; \
+ mgn=''; \
+ brg=''; \
+ std=''; \
+ fi; \
+}
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AS = @AS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CMAKE = @CMAKE@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DL_LIBS = @DL_LIBS@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GIT = @GIT@
+GREP = @GREP@
+IFCONFIG = @IFCONFIG@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+IPROUTE = @IPROUTE@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBPAM_CFLAGS = @LIBPAM_CFLAGS@
+LIBPAM_LIBS = @LIBPAM_LIBS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LZ4_CFLAGS = @LZ4_CFLAGS@
+LZ4_LIBS = @LZ4_LIBS@
+LZO_CFLAGS = @LZO_CFLAGS@
+LZO_LIBS = @LZO_LIBS@
+MAKEINFO = @MAKEINFO@
+MAN2HTML = @MAN2HTML@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MBEDTLS_CFLAGS = @MBEDTLS_CFLAGS@
+MBEDTLS_LIBS = @MBEDTLS_LIBS@
+MKDIR_P = @MKDIR_P@
+NETSTAT = @NETSTAT@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OPENSSL_CFLAGS = @OPENSSL_CFLAGS@
+OPENSSL_LIBS = @OPENSSL_LIBS@
+OPENVPN_VERSION_MAJOR = @OPENVPN_VERSION_MAJOR@
+OPENVPN_VERSION_MINOR = @OPENVPN_VERSION_MINOR@
+OPENVPN_VERSION_PATCH = @OPENVPN_VERSION_PATCH@
+OPTIONAL_CRYPTO_CFLAGS = @OPTIONAL_CRYPTO_CFLAGS@
+OPTIONAL_CRYPTO_LIBS = @OPTIONAL_CRYPTO_LIBS@
+OPTIONAL_DL_LIBS = @OPTIONAL_DL_LIBS@
+OPTIONAL_LZ4_CFLAGS = @OPTIONAL_LZ4_CFLAGS@
+OPTIONAL_LZ4_LIBS = @OPTIONAL_LZ4_LIBS@
+OPTIONAL_LZO_CFLAGS = @OPTIONAL_LZO_CFLAGS@
+OPTIONAL_LZO_LIBS = @OPTIONAL_LZO_LIBS@
+OPTIONAL_PKCS11_HELPER_CFLAGS = @OPTIONAL_PKCS11_HELPER_CFLAGS@
+OPTIONAL_PKCS11_HELPER_LIBS = @OPTIONAL_PKCS11_HELPER_LIBS@
+OPTIONAL_SELINUX_LIBS = @OPTIONAL_SELINUX_LIBS@
+OPTIONAL_SYSTEMD_LIBS = @OPTIONAL_SYSTEMD_LIBS@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+P11KIT_CFLAGS = @P11KIT_CFLAGS@
+P11KIT_LIBS = @P11KIT_LIBS@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKCS11_HELPER_CFLAGS = @PKCS11_HELPER_CFLAGS@
+PKCS11_HELPER_LIBS = @PKCS11_HELPER_LIBS@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+PLUGIN_AUTH_PAM_CFLAGS = @PLUGIN_AUTH_PAM_CFLAGS@
+PLUGIN_AUTH_PAM_LIBS = @PLUGIN_AUTH_PAM_LIBS@
+RANLIB = @RANLIB@
+RC = @RC@
+ROUTE = @ROUTE@
+SED = @SED@
+SELINUX_LIBS = @SELINUX_LIBS@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SOCKETS_LIBS = @SOCKETS_LIBS@
+STRIP = @STRIP@
+SYSTEMD_ASK_PASSWORD = @SYSTEMD_ASK_PASSWORD@
+TAP_CFLAGS = @TAP_CFLAGS@
+TAP_WIN_COMPONENT_ID = @TAP_WIN_COMPONENT_ID@
+TAP_WIN_MIN_MAJOR = @TAP_WIN_MIN_MAJOR@
+TAP_WIN_MIN_MINOR = @TAP_WIN_MIN_MINOR@
+TEST_CFLAGS = @TEST_CFLAGS@
+TEST_LDFLAGS = @TEST_LDFLAGS@
+VENDOR_BUILD_ROOT = @VENDOR_BUILD_ROOT@
+VENDOR_DIST_ROOT = @VENDOR_DIST_ROOT@
+VENDOR_SRC_ROOT = @VENDOR_SRC_ROOT@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+libsystemd_CFLAGS = @libsystemd_CFLAGS@
+libsystemd_LIBS = @libsystemd_LIBS@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+plugindir = @plugindir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sampledir = @sampledir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+AUTOMAKE_OPTIONS = foreign
+TESTS = $(check_PROGRAMS)
+openvpn_includedir = $(top_srcdir)/include
+openvpn_srcdir = $(top_srcdir)/src/openvpn
+compat_srcdir = $(top_srcdir)/src/compat
+argv_testdriver_CFLAGS = @TEST_CFLAGS@ -I$(openvpn_srcdir) -I$(compat_srcdir) \
+ $(OPTIONAL_CRYPTO_CFLAGS)
+
+argv_testdriver_LDFLAGS = @TEST_LDFLAGS@ -L$(openvpn_srcdir) -Wl,--wrap=parse_line \
+ $(OPTIONAL_CRYPTO_LIBS)
+
+argv_testdriver_SOURCES = test_argv.c mock_msg.c \
+ $(openvpn_srcdir)/platform.c \
+ $(openvpn_srcdir)/buffer.c \
+ $(openvpn_srcdir)/argv.c
+
+tls_crypt_testdriver_CFLAGS = @TEST_CFLAGS@ \
+ -I$(openvpn_includedir) -I$(compat_srcdir) -I$(openvpn_srcdir) \
+ $(OPTIONAL_CRYPTO_CFLAGS)
+
+tls_crypt_testdriver_LDFLAGS = @TEST_LDFLAGS@ \
+ $(OPTIONAL_CRYPTO_LIBS)
+
+tls_crypt_testdriver_SOURCES = test_tls_crypt.c mock_msg.c \
+ $(openvpn_srcdir)/buffer.c \
+ $(openvpn_srcdir)/crypto.c \
+ $(openvpn_srcdir)/crypto_mbedtls.c \
+ $(openvpn_srcdir)/crypto_openssl.c \
+ $(openvpn_srcdir)/otime.c \
+ $(openvpn_srcdir)/packet_id.c \
+ $(openvpn_srcdir)/platform.c \
+ $(openvpn_srcdir)/tls_crypt.c
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign tests/unit_tests/openvpn/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign tests/unit_tests/openvpn/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *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);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-checkPROGRAMS:
+ @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+
+argv_testdriver$(EXEEXT): $(argv_testdriver_OBJECTS) $(argv_testdriver_DEPENDENCIES) $(EXTRA_argv_testdriver_DEPENDENCIES)
+ @rm -f argv_testdriver$(EXEEXT)
+ $(AM_V_CCLD)$(argv_testdriver_LINK) $(argv_testdriver_OBJECTS) $(argv_testdriver_LDADD) $(LIBS)
+
+tls_crypt_testdriver$(EXEEXT): $(tls_crypt_testdriver_OBJECTS) $(tls_crypt_testdriver_DEPENDENCIES) $(EXTRA_tls_crypt_testdriver_DEPENDENCIES)
+ @rm -f tls_crypt_testdriver$(EXEEXT)
+ $(AM_V_CCLD)$(tls_crypt_testdriver_LINK) $(tls_crypt_testdriver_OBJECTS) $(tls_crypt_testdriver_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/argv_testdriver-argv.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/argv_testdriver-buffer.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/argv_testdriver-mock_msg.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/argv_testdriver-platform.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/argv_testdriver-test_argv.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tls_crypt_testdriver-buffer.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tls_crypt_testdriver-crypto.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tls_crypt_testdriver-crypto_mbedtls.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tls_crypt_testdriver-crypto_openssl.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tls_crypt_testdriver-mock_msg.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tls_crypt_testdriver-otime.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tls_crypt_testdriver-packet_id.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tls_crypt_testdriver-platform.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tls_crypt_testdriver-test_tls_crypt.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tls_crypt_testdriver-tls_crypt.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+argv_testdriver-test_argv.o: test_argv.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(argv_testdriver_CFLAGS) $(CFLAGS) -MT argv_testdriver-test_argv.o -MD -MP -MF $(DEPDIR)/argv_testdriver-test_argv.Tpo -c -o argv_testdriver-test_argv.o `test -f 'test_argv.c' || echo '$(srcdir)/'`test_argv.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/argv_testdriver-test_argv.Tpo $(DEPDIR)/argv_testdriver-test_argv.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='test_argv.c' object='argv_testdriver-test_argv.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(argv_testdriver_CFLAGS) $(CFLAGS) -c -o argv_testdriver-test_argv.o `test -f 'test_argv.c' || echo '$(srcdir)/'`test_argv.c
+
+argv_testdriver-test_argv.obj: test_argv.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(argv_testdriver_CFLAGS) $(CFLAGS) -MT argv_testdriver-test_argv.obj -MD -MP -MF $(DEPDIR)/argv_testdriver-test_argv.Tpo -c -o argv_testdriver-test_argv.obj `if test -f 'test_argv.c'; then $(CYGPATH_W) 'test_argv.c'; else $(CYGPATH_W) '$(srcdir)/test_argv.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/argv_testdriver-test_argv.Tpo $(DEPDIR)/argv_testdriver-test_argv.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='test_argv.c' object='argv_testdriver-test_argv.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(argv_testdriver_CFLAGS) $(CFLAGS) -c -o argv_testdriver-test_argv.obj `if test -f 'test_argv.c'; then $(CYGPATH_W) 'test_argv.c'; else $(CYGPATH_W) '$(srcdir)/test_argv.c'; fi`
+
+argv_testdriver-mock_msg.o: mock_msg.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(argv_testdriver_CFLAGS) $(CFLAGS) -MT argv_testdriver-mock_msg.o -MD -MP -MF $(DEPDIR)/argv_testdriver-mock_msg.Tpo -c -o argv_testdriver-mock_msg.o `test -f 'mock_msg.c' || echo '$(srcdir)/'`mock_msg.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/argv_testdriver-mock_msg.Tpo $(DEPDIR)/argv_testdriver-mock_msg.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mock_msg.c' object='argv_testdriver-mock_msg.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(argv_testdriver_CFLAGS) $(CFLAGS) -c -o argv_testdriver-mock_msg.o `test -f 'mock_msg.c' || echo '$(srcdir)/'`mock_msg.c
+
+argv_testdriver-mock_msg.obj: mock_msg.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(argv_testdriver_CFLAGS) $(CFLAGS) -MT argv_testdriver-mock_msg.obj -MD -MP -MF $(DEPDIR)/argv_testdriver-mock_msg.Tpo -c -o argv_testdriver-mock_msg.obj `if test -f 'mock_msg.c'; then $(CYGPATH_W) 'mock_msg.c'; else $(CYGPATH_W) '$(srcdir)/mock_msg.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/argv_testdriver-mock_msg.Tpo $(DEPDIR)/argv_testdriver-mock_msg.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mock_msg.c' object='argv_testdriver-mock_msg.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(argv_testdriver_CFLAGS) $(CFLAGS) -c -o argv_testdriver-mock_msg.obj `if test -f 'mock_msg.c'; then $(CYGPATH_W) 'mock_msg.c'; else $(CYGPATH_W) '$(srcdir)/mock_msg.c'; fi`
+
+argv_testdriver-platform.o: $(openvpn_srcdir)/platform.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(argv_testdriver_CFLAGS) $(CFLAGS) -MT argv_testdriver-platform.o -MD -MP -MF $(DEPDIR)/argv_testdriver-platform.Tpo -c -o argv_testdriver-platform.o `test -f '$(openvpn_srcdir)/platform.c' || echo '$(srcdir)/'`$(openvpn_srcdir)/platform.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/argv_testdriver-platform.Tpo $(DEPDIR)/argv_testdriver-platform.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(openvpn_srcdir)/platform.c' object='argv_testdriver-platform.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(argv_testdriver_CFLAGS) $(CFLAGS) -c -o argv_testdriver-platform.o `test -f '$(openvpn_srcdir)/platform.c' || echo '$(srcdir)/'`$(openvpn_srcdir)/platform.c
+
+argv_testdriver-platform.obj: $(openvpn_srcdir)/platform.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(argv_testdriver_CFLAGS) $(CFLAGS) -MT argv_testdriver-platform.obj -MD -MP -MF $(DEPDIR)/argv_testdriver-platform.Tpo -c -o argv_testdriver-platform.obj `if test -f '$(openvpn_srcdir)/platform.c'; then $(CYGPATH_W) '$(openvpn_srcdir)/platform.c'; else $(CYGPATH_W) '$(srcdir)/$(openvpn_srcdir)/platform.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/argv_testdriver-platform.Tpo $(DEPDIR)/argv_testdriver-platform.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(openvpn_srcdir)/platform.c' object='argv_testdriver-platform.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(argv_testdriver_CFLAGS) $(CFLAGS) -c -o argv_testdriver-platform.obj `if test -f '$(openvpn_srcdir)/platform.c'; then $(CYGPATH_W) '$(openvpn_srcdir)/platform.c'; else $(CYGPATH_W) '$(srcdir)/$(openvpn_srcdir)/platform.c'; fi`
+
+argv_testdriver-buffer.o: $(openvpn_srcdir)/buffer.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(argv_testdriver_CFLAGS) $(CFLAGS) -MT argv_testdriver-buffer.o -MD -MP -MF $(DEPDIR)/argv_testdriver-buffer.Tpo -c -o argv_testdriver-buffer.o `test -f '$(openvpn_srcdir)/buffer.c' || echo '$(srcdir)/'`$(openvpn_srcdir)/buffer.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/argv_testdriver-buffer.Tpo $(DEPDIR)/argv_testdriver-buffer.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(openvpn_srcdir)/buffer.c' object='argv_testdriver-buffer.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(argv_testdriver_CFLAGS) $(CFLAGS) -c -o argv_testdriver-buffer.o `test -f '$(openvpn_srcdir)/buffer.c' || echo '$(srcdir)/'`$(openvpn_srcdir)/buffer.c
+
+argv_testdriver-buffer.obj: $(openvpn_srcdir)/buffer.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(argv_testdriver_CFLAGS) $(CFLAGS) -MT argv_testdriver-buffer.obj -MD -MP -MF $(DEPDIR)/argv_testdriver-buffer.Tpo -c -o argv_testdriver-buffer.obj `if test -f '$(openvpn_srcdir)/buffer.c'; then $(CYGPATH_W) '$(openvpn_srcdir)/buffer.c'; else $(CYGPATH_W) '$(srcdir)/$(openvpn_srcdir)/buffer.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/argv_testdriver-buffer.Tpo $(DEPDIR)/argv_testdriver-buffer.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(openvpn_srcdir)/buffer.c' object='argv_testdriver-buffer.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(argv_testdriver_CFLAGS) $(CFLAGS) -c -o argv_testdriver-buffer.obj `if test -f '$(openvpn_srcdir)/buffer.c'; then $(CYGPATH_W) '$(openvpn_srcdir)/buffer.c'; else $(CYGPATH_W) '$(srcdir)/$(openvpn_srcdir)/buffer.c'; fi`
+
+argv_testdriver-argv.o: $(openvpn_srcdir)/argv.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(argv_testdriver_CFLAGS) $(CFLAGS) -MT argv_testdriver-argv.o -MD -MP -MF $(DEPDIR)/argv_testdriver-argv.Tpo -c -o argv_testdriver-argv.o `test -f '$(openvpn_srcdir)/argv.c' || echo '$(srcdir)/'`$(openvpn_srcdir)/argv.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/argv_testdriver-argv.Tpo $(DEPDIR)/argv_testdriver-argv.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(openvpn_srcdir)/argv.c' object='argv_testdriver-argv.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(argv_testdriver_CFLAGS) $(CFLAGS) -c -o argv_testdriver-argv.o `test -f '$(openvpn_srcdir)/argv.c' || echo '$(srcdir)/'`$(openvpn_srcdir)/argv.c
+
+argv_testdriver-argv.obj: $(openvpn_srcdir)/argv.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(argv_testdriver_CFLAGS) $(CFLAGS) -MT argv_testdriver-argv.obj -MD -MP -MF $(DEPDIR)/argv_testdriver-argv.Tpo -c -o argv_testdriver-argv.obj `if test -f '$(openvpn_srcdir)/argv.c'; then $(CYGPATH_W) '$(openvpn_srcdir)/argv.c'; else $(CYGPATH_W) '$(srcdir)/$(openvpn_srcdir)/argv.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/argv_testdriver-argv.Tpo $(DEPDIR)/argv_testdriver-argv.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(openvpn_srcdir)/argv.c' object='argv_testdriver-argv.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(argv_testdriver_CFLAGS) $(CFLAGS) -c -o argv_testdriver-argv.obj `if test -f '$(openvpn_srcdir)/argv.c'; then $(CYGPATH_W) '$(openvpn_srcdir)/argv.c'; else $(CYGPATH_W) '$(srcdir)/$(openvpn_srcdir)/argv.c'; fi`
+
+tls_crypt_testdriver-test_tls_crypt.o: test_tls_crypt.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tls_crypt_testdriver_CFLAGS) $(CFLAGS) -MT tls_crypt_testdriver-test_tls_crypt.o -MD -MP -MF $(DEPDIR)/tls_crypt_testdriver-test_tls_crypt.Tpo -c -o tls_crypt_testdriver-test_tls_crypt.o `test -f 'test_tls_crypt.c' || echo '$(srcdir)/'`test_tls_crypt.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/tls_crypt_testdriver-test_tls_crypt.Tpo $(DEPDIR)/tls_crypt_testdriver-test_tls_crypt.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='test_tls_crypt.c' object='tls_crypt_testdriver-test_tls_crypt.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tls_crypt_testdriver_CFLAGS) $(CFLAGS) -c -o tls_crypt_testdriver-test_tls_crypt.o `test -f 'test_tls_crypt.c' || echo '$(srcdir)/'`test_tls_crypt.c
+
+tls_crypt_testdriver-test_tls_crypt.obj: test_tls_crypt.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tls_crypt_testdriver_CFLAGS) $(CFLAGS) -MT tls_crypt_testdriver-test_tls_crypt.obj -MD -MP -MF $(DEPDIR)/tls_crypt_testdriver-test_tls_crypt.Tpo -c -o tls_crypt_testdriver-test_tls_crypt.obj `if test -f 'test_tls_crypt.c'; then $(CYGPATH_W) 'test_tls_crypt.c'; else $(CYGPATH_W) '$(srcdir)/test_tls_crypt.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/tls_crypt_testdriver-test_tls_crypt.Tpo $(DEPDIR)/tls_crypt_testdriver-test_tls_crypt.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='test_tls_crypt.c' object='tls_crypt_testdriver-test_tls_crypt.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tls_crypt_testdriver_CFLAGS) $(CFLAGS) -c -o tls_crypt_testdriver-test_tls_crypt.obj `if test -f 'test_tls_crypt.c'; then $(CYGPATH_W) 'test_tls_crypt.c'; else $(CYGPATH_W) '$(srcdir)/test_tls_crypt.c'; fi`
+
+tls_crypt_testdriver-mock_msg.o: mock_msg.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tls_crypt_testdriver_CFLAGS) $(CFLAGS) -MT tls_crypt_testdriver-mock_msg.o -MD -MP -MF $(DEPDIR)/tls_crypt_testdriver-mock_msg.Tpo -c -o tls_crypt_testdriver-mock_msg.o `test -f 'mock_msg.c' || echo '$(srcdir)/'`mock_msg.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/tls_crypt_testdriver-mock_msg.Tpo $(DEPDIR)/tls_crypt_testdriver-mock_msg.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mock_msg.c' object='tls_crypt_testdriver-mock_msg.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tls_crypt_testdriver_CFLAGS) $(CFLAGS) -c -o tls_crypt_testdriver-mock_msg.o `test -f 'mock_msg.c' || echo '$(srcdir)/'`mock_msg.c
+
+tls_crypt_testdriver-mock_msg.obj: mock_msg.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tls_crypt_testdriver_CFLAGS) $(CFLAGS) -MT tls_crypt_testdriver-mock_msg.obj -MD -MP -MF $(DEPDIR)/tls_crypt_testdriver-mock_msg.Tpo -c -o tls_crypt_testdriver-mock_msg.obj `if test -f 'mock_msg.c'; then $(CYGPATH_W) 'mock_msg.c'; else $(CYGPATH_W) '$(srcdir)/mock_msg.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/tls_crypt_testdriver-mock_msg.Tpo $(DEPDIR)/tls_crypt_testdriver-mock_msg.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mock_msg.c' object='tls_crypt_testdriver-mock_msg.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tls_crypt_testdriver_CFLAGS) $(CFLAGS) -c -o tls_crypt_testdriver-mock_msg.obj `if test -f 'mock_msg.c'; then $(CYGPATH_W) 'mock_msg.c'; else $(CYGPATH_W) '$(srcdir)/mock_msg.c'; fi`
+
+tls_crypt_testdriver-buffer.o: $(openvpn_srcdir)/buffer.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tls_crypt_testdriver_CFLAGS) $(CFLAGS) -MT tls_crypt_testdriver-buffer.o -MD -MP -MF $(DEPDIR)/tls_crypt_testdriver-buffer.Tpo -c -o tls_crypt_testdriver-buffer.o `test -f '$(openvpn_srcdir)/buffer.c' || echo '$(srcdir)/'`$(openvpn_srcdir)/buffer.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/tls_crypt_testdriver-buffer.Tpo $(DEPDIR)/tls_crypt_testdriver-buffer.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(openvpn_srcdir)/buffer.c' object='tls_crypt_testdriver-buffer.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tls_crypt_testdriver_CFLAGS) $(CFLAGS) -c -o tls_crypt_testdriver-buffer.o `test -f '$(openvpn_srcdir)/buffer.c' || echo '$(srcdir)/'`$(openvpn_srcdir)/buffer.c
+
+tls_crypt_testdriver-buffer.obj: $(openvpn_srcdir)/buffer.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tls_crypt_testdriver_CFLAGS) $(CFLAGS) -MT tls_crypt_testdriver-buffer.obj -MD -MP -MF $(DEPDIR)/tls_crypt_testdriver-buffer.Tpo -c -o tls_crypt_testdriver-buffer.obj `if test -f '$(openvpn_srcdir)/buffer.c'; then $(CYGPATH_W) '$(openvpn_srcdir)/buffer.c'; else $(CYGPATH_W) '$(srcdir)/$(openvpn_srcdir)/buffer.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/tls_crypt_testdriver-buffer.Tpo $(DEPDIR)/tls_crypt_testdriver-buffer.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(openvpn_srcdir)/buffer.c' object='tls_crypt_testdriver-buffer.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tls_crypt_testdriver_CFLAGS) $(CFLAGS) -c -o tls_crypt_testdriver-buffer.obj `if test -f '$(openvpn_srcdir)/buffer.c'; then $(CYGPATH_W) '$(openvpn_srcdir)/buffer.c'; else $(CYGPATH_W) '$(srcdir)/$(openvpn_srcdir)/buffer.c'; fi`
+
+tls_crypt_testdriver-crypto.o: $(openvpn_srcdir)/crypto.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tls_crypt_testdriver_CFLAGS) $(CFLAGS) -MT tls_crypt_testdriver-crypto.o -MD -MP -MF $(DEPDIR)/tls_crypt_testdriver-crypto.Tpo -c -o tls_crypt_testdriver-crypto.o `test -f '$(openvpn_srcdir)/crypto.c' || echo '$(srcdir)/'`$(openvpn_srcdir)/crypto.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/tls_crypt_testdriver-crypto.Tpo $(DEPDIR)/tls_crypt_testdriver-crypto.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(openvpn_srcdir)/crypto.c' object='tls_crypt_testdriver-crypto.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tls_crypt_testdriver_CFLAGS) $(CFLAGS) -c -o tls_crypt_testdriver-crypto.o `test -f '$(openvpn_srcdir)/crypto.c' || echo '$(srcdir)/'`$(openvpn_srcdir)/crypto.c
+
+tls_crypt_testdriver-crypto.obj: $(openvpn_srcdir)/crypto.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tls_crypt_testdriver_CFLAGS) $(CFLAGS) -MT tls_crypt_testdriver-crypto.obj -MD -MP -MF $(DEPDIR)/tls_crypt_testdriver-crypto.Tpo -c -o tls_crypt_testdriver-crypto.obj `if test -f '$(openvpn_srcdir)/crypto.c'; then $(CYGPATH_W) '$(openvpn_srcdir)/crypto.c'; else $(CYGPATH_W) '$(srcdir)/$(openvpn_srcdir)/crypto.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/tls_crypt_testdriver-crypto.Tpo $(DEPDIR)/tls_crypt_testdriver-crypto.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(openvpn_srcdir)/crypto.c' object='tls_crypt_testdriver-crypto.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tls_crypt_testdriver_CFLAGS) $(CFLAGS) -c -o tls_crypt_testdriver-crypto.obj `if test -f '$(openvpn_srcdir)/crypto.c'; then $(CYGPATH_W) '$(openvpn_srcdir)/crypto.c'; else $(CYGPATH_W) '$(srcdir)/$(openvpn_srcdir)/crypto.c'; fi`
+
+tls_crypt_testdriver-crypto_mbedtls.o: $(openvpn_srcdir)/crypto_mbedtls.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tls_crypt_testdriver_CFLAGS) $(CFLAGS) -MT tls_crypt_testdriver-crypto_mbedtls.o -MD -MP -MF $(DEPDIR)/tls_crypt_testdriver-crypto_mbedtls.Tpo -c -o tls_crypt_testdriver-crypto_mbedtls.o `test -f '$(openvpn_srcdir)/crypto_mbedtls.c' || echo '$(srcdir)/'`$(openvpn_srcdir)/crypto_mbedtls.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/tls_crypt_testdriver-crypto_mbedtls.Tpo $(DEPDIR)/tls_crypt_testdriver-crypto_mbedtls.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(openvpn_srcdir)/crypto_mbedtls.c' object='tls_crypt_testdriver-crypto_mbedtls.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tls_crypt_testdriver_CFLAGS) $(CFLAGS) -c -o tls_crypt_testdriver-crypto_mbedtls.o `test -f '$(openvpn_srcdir)/crypto_mbedtls.c' || echo '$(srcdir)/'`$(openvpn_srcdir)/crypto_mbedtls.c
+
+tls_crypt_testdriver-crypto_mbedtls.obj: $(openvpn_srcdir)/crypto_mbedtls.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tls_crypt_testdriver_CFLAGS) $(CFLAGS) -MT tls_crypt_testdriver-crypto_mbedtls.obj -MD -MP -MF $(DEPDIR)/tls_crypt_testdriver-crypto_mbedtls.Tpo -c -o tls_crypt_testdriver-crypto_mbedtls.obj `if test -f '$(openvpn_srcdir)/crypto_mbedtls.c'; then $(CYGPATH_W) '$(openvpn_srcdir)/crypto_mbedtls.c'; else $(CYGPATH_W) '$(srcdir)/$(openvpn_srcdir)/crypto_mbedtls.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/tls_crypt_testdriver-crypto_mbedtls.Tpo $(DEPDIR)/tls_crypt_testdriver-crypto_mbedtls.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(openvpn_srcdir)/crypto_mbedtls.c' object='tls_crypt_testdriver-crypto_mbedtls.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tls_crypt_testdriver_CFLAGS) $(CFLAGS) -c -o tls_crypt_testdriver-crypto_mbedtls.obj `if test -f '$(openvpn_srcdir)/crypto_mbedtls.c'; then $(CYGPATH_W) '$(openvpn_srcdir)/crypto_mbedtls.c'; else $(CYGPATH_W) '$(srcdir)/$(openvpn_srcdir)/crypto_mbedtls.c'; fi`
+
+tls_crypt_testdriver-crypto_openssl.o: $(openvpn_srcdir)/crypto_openssl.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tls_crypt_testdriver_CFLAGS) $(CFLAGS) -MT tls_crypt_testdriver-crypto_openssl.o -MD -MP -MF $(DEPDIR)/tls_crypt_testdriver-crypto_openssl.Tpo -c -o tls_crypt_testdriver-crypto_openssl.o `test -f '$(openvpn_srcdir)/crypto_openssl.c' || echo '$(srcdir)/'`$(openvpn_srcdir)/crypto_openssl.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/tls_crypt_testdriver-crypto_openssl.Tpo $(DEPDIR)/tls_crypt_testdriver-crypto_openssl.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(openvpn_srcdir)/crypto_openssl.c' object='tls_crypt_testdriver-crypto_openssl.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tls_crypt_testdriver_CFLAGS) $(CFLAGS) -c -o tls_crypt_testdriver-crypto_openssl.o `test -f '$(openvpn_srcdir)/crypto_openssl.c' || echo '$(srcdir)/'`$(openvpn_srcdir)/crypto_openssl.c
+
+tls_crypt_testdriver-crypto_openssl.obj: $(openvpn_srcdir)/crypto_openssl.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tls_crypt_testdriver_CFLAGS) $(CFLAGS) -MT tls_crypt_testdriver-crypto_openssl.obj -MD -MP -MF $(DEPDIR)/tls_crypt_testdriver-crypto_openssl.Tpo -c -o tls_crypt_testdriver-crypto_openssl.obj `if test -f '$(openvpn_srcdir)/crypto_openssl.c'; then $(CYGPATH_W) '$(openvpn_srcdir)/crypto_openssl.c'; else $(CYGPATH_W) '$(srcdir)/$(openvpn_srcdir)/crypto_openssl.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/tls_crypt_testdriver-crypto_openssl.Tpo $(DEPDIR)/tls_crypt_testdriver-crypto_openssl.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(openvpn_srcdir)/crypto_openssl.c' object='tls_crypt_testdriver-crypto_openssl.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tls_crypt_testdriver_CFLAGS) $(CFLAGS) -c -o tls_crypt_testdriver-crypto_openssl.obj `if test -f '$(openvpn_srcdir)/crypto_openssl.c'; then $(CYGPATH_W) '$(openvpn_srcdir)/crypto_openssl.c'; else $(CYGPATH_W) '$(srcdir)/$(openvpn_srcdir)/crypto_openssl.c'; fi`
+
+tls_crypt_testdriver-otime.o: $(openvpn_srcdir)/otime.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tls_crypt_testdriver_CFLAGS) $(CFLAGS) -MT tls_crypt_testdriver-otime.o -MD -MP -MF $(DEPDIR)/tls_crypt_testdriver-otime.Tpo -c -o tls_crypt_testdriver-otime.o `test -f '$(openvpn_srcdir)/otime.c' || echo '$(srcdir)/'`$(openvpn_srcdir)/otime.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/tls_crypt_testdriver-otime.Tpo $(DEPDIR)/tls_crypt_testdriver-otime.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(openvpn_srcdir)/otime.c' object='tls_crypt_testdriver-otime.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tls_crypt_testdriver_CFLAGS) $(CFLAGS) -c -o tls_crypt_testdriver-otime.o `test -f '$(openvpn_srcdir)/otime.c' || echo '$(srcdir)/'`$(openvpn_srcdir)/otime.c
+
+tls_crypt_testdriver-otime.obj: $(openvpn_srcdir)/otime.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tls_crypt_testdriver_CFLAGS) $(CFLAGS) -MT tls_crypt_testdriver-otime.obj -MD -MP -MF $(DEPDIR)/tls_crypt_testdriver-otime.Tpo -c -o tls_crypt_testdriver-otime.obj `if test -f '$(openvpn_srcdir)/otime.c'; then $(CYGPATH_W) '$(openvpn_srcdir)/otime.c'; else $(CYGPATH_W) '$(srcdir)/$(openvpn_srcdir)/otime.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/tls_crypt_testdriver-otime.Tpo $(DEPDIR)/tls_crypt_testdriver-otime.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(openvpn_srcdir)/otime.c' object='tls_crypt_testdriver-otime.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tls_crypt_testdriver_CFLAGS) $(CFLAGS) -c -o tls_crypt_testdriver-otime.obj `if test -f '$(openvpn_srcdir)/otime.c'; then $(CYGPATH_W) '$(openvpn_srcdir)/otime.c'; else $(CYGPATH_W) '$(srcdir)/$(openvpn_srcdir)/otime.c'; fi`
+
+tls_crypt_testdriver-packet_id.o: $(openvpn_srcdir)/packet_id.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tls_crypt_testdriver_CFLAGS) $(CFLAGS) -MT tls_crypt_testdriver-packet_id.o -MD -MP -MF $(DEPDIR)/tls_crypt_testdriver-packet_id.Tpo -c -o tls_crypt_testdriver-packet_id.o `test -f '$(openvpn_srcdir)/packet_id.c' || echo '$(srcdir)/'`$(openvpn_srcdir)/packet_id.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/tls_crypt_testdriver-packet_id.Tpo $(DEPDIR)/tls_crypt_testdriver-packet_id.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(openvpn_srcdir)/packet_id.c' object='tls_crypt_testdriver-packet_id.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tls_crypt_testdriver_CFLAGS) $(CFLAGS) -c -o tls_crypt_testdriver-packet_id.o `test -f '$(openvpn_srcdir)/packet_id.c' || echo '$(srcdir)/'`$(openvpn_srcdir)/packet_id.c
+
+tls_crypt_testdriver-packet_id.obj: $(openvpn_srcdir)/packet_id.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tls_crypt_testdriver_CFLAGS) $(CFLAGS) -MT tls_crypt_testdriver-packet_id.obj -MD -MP -MF $(DEPDIR)/tls_crypt_testdriver-packet_id.Tpo -c -o tls_crypt_testdriver-packet_id.obj `if test -f '$(openvpn_srcdir)/packet_id.c'; then $(CYGPATH_W) '$(openvpn_srcdir)/packet_id.c'; else $(CYGPATH_W) '$(srcdir)/$(openvpn_srcdir)/packet_id.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/tls_crypt_testdriver-packet_id.Tpo $(DEPDIR)/tls_crypt_testdriver-packet_id.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(openvpn_srcdir)/packet_id.c' object='tls_crypt_testdriver-packet_id.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tls_crypt_testdriver_CFLAGS) $(CFLAGS) -c -o tls_crypt_testdriver-packet_id.obj `if test -f '$(openvpn_srcdir)/packet_id.c'; then $(CYGPATH_W) '$(openvpn_srcdir)/packet_id.c'; else $(CYGPATH_W) '$(srcdir)/$(openvpn_srcdir)/packet_id.c'; fi`
+
+tls_crypt_testdriver-platform.o: $(openvpn_srcdir)/platform.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tls_crypt_testdriver_CFLAGS) $(CFLAGS) -MT tls_crypt_testdriver-platform.o -MD -MP -MF $(DEPDIR)/tls_crypt_testdriver-platform.Tpo -c -o tls_crypt_testdriver-platform.o `test -f '$(openvpn_srcdir)/platform.c' || echo '$(srcdir)/'`$(openvpn_srcdir)/platform.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/tls_crypt_testdriver-platform.Tpo $(DEPDIR)/tls_crypt_testdriver-platform.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(openvpn_srcdir)/platform.c' object='tls_crypt_testdriver-platform.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tls_crypt_testdriver_CFLAGS) $(CFLAGS) -c -o tls_crypt_testdriver-platform.o `test -f '$(openvpn_srcdir)/platform.c' || echo '$(srcdir)/'`$(openvpn_srcdir)/platform.c
+
+tls_crypt_testdriver-platform.obj: $(openvpn_srcdir)/platform.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tls_crypt_testdriver_CFLAGS) $(CFLAGS) -MT tls_crypt_testdriver-platform.obj -MD -MP -MF $(DEPDIR)/tls_crypt_testdriver-platform.Tpo -c -o tls_crypt_testdriver-platform.obj `if test -f '$(openvpn_srcdir)/platform.c'; then $(CYGPATH_W) '$(openvpn_srcdir)/platform.c'; else $(CYGPATH_W) '$(srcdir)/$(openvpn_srcdir)/platform.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/tls_crypt_testdriver-platform.Tpo $(DEPDIR)/tls_crypt_testdriver-platform.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(openvpn_srcdir)/platform.c' object='tls_crypt_testdriver-platform.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tls_crypt_testdriver_CFLAGS) $(CFLAGS) -c -o tls_crypt_testdriver-platform.obj `if test -f '$(openvpn_srcdir)/platform.c'; then $(CYGPATH_W) '$(openvpn_srcdir)/platform.c'; else $(CYGPATH_W) '$(srcdir)/$(openvpn_srcdir)/platform.c'; fi`
+
+tls_crypt_testdriver-tls_crypt.o: $(openvpn_srcdir)/tls_crypt.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tls_crypt_testdriver_CFLAGS) $(CFLAGS) -MT tls_crypt_testdriver-tls_crypt.o -MD -MP -MF $(DEPDIR)/tls_crypt_testdriver-tls_crypt.Tpo -c -o tls_crypt_testdriver-tls_crypt.o `test -f '$(openvpn_srcdir)/tls_crypt.c' || echo '$(srcdir)/'`$(openvpn_srcdir)/tls_crypt.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/tls_crypt_testdriver-tls_crypt.Tpo $(DEPDIR)/tls_crypt_testdriver-tls_crypt.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(openvpn_srcdir)/tls_crypt.c' object='tls_crypt_testdriver-tls_crypt.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tls_crypt_testdriver_CFLAGS) $(CFLAGS) -c -o tls_crypt_testdriver-tls_crypt.o `test -f '$(openvpn_srcdir)/tls_crypt.c' || echo '$(srcdir)/'`$(openvpn_srcdir)/tls_crypt.c
+
+tls_crypt_testdriver-tls_crypt.obj: $(openvpn_srcdir)/tls_crypt.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tls_crypt_testdriver_CFLAGS) $(CFLAGS) -MT tls_crypt_testdriver-tls_crypt.obj -MD -MP -MF $(DEPDIR)/tls_crypt_testdriver-tls_crypt.Tpo -c -o tls_crypt_testdriver-tls_crypt.obj `if test -f '$(openvpn_srcdir)/tls_crypt.c'; then $(CYGPATH_W) '$(openvpn_srcdir)/tls_crypt.c'; else $(CYGPATH_W) '$(srcdir)/$(openvpn_srcdir)/tls_crypt.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/tls_crypt_testdriver-tls_crypt.Tpo $(DEPDIR)/tls_crypt_testdriver-tls_crypt.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(openvpn_srcdir)/tls_crypt.c' object='tls_crypt_testdriver-tls_crypt.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tls_crypt_testdriver_CFLAGS) $(CFLAGS) -c -o tls_crypt_testdriver-tls_crypt.obj `if test -f '$(openvpn_srcdir)/tls_crypt.c'; then $(CYGPATH_W) '$(openvpn_srcdir)/tls_crypt.c'; else $(CYGPATH_W) '$(srcdir)/$(openvpn_srcdir)/tls_crypt.c'; fi`
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+check-TESTS: $(TESTS)
+ @failed=0; all=0; xfail=0; xpass=0; skip=0; \
+ srcdir=$(srcdir); export srcdir; \
+ list=' $(TESTS) '; \
+ $(am__tty_colors); \
+ if test -n "$$list"; then \
+ for tst in $$list; do \
+ if test -f ./$$tst; then dir=./; \
+ elif test -f $$tst; then dir=; \
+ else dir="$(srcdir)/"; fi; \
+ if $(TESTS_ENVIRONMENT) $${dir}$$tst $(AM_TESTS_FD_REDIRECT); then \
+ all=`expr $$all + 1`; \
+ case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$tst[\ \ ]*) \
+ xpass=`expr $$xpass + 1`; \
+ failed=`expr $$failed + 1`; \
+ col=$$red; res=XPASS; \
+ ;; \
+ *) \
+ col=$$grn; res=PASS; \
+ ;; \
+ esac; \
+ elif test $$? -ne 77; then \
+ all=`expr $$all + 1`; \
+ case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$tst[\ \ ]*) \
+ xfail=`expr $$xfail + 1`; \
+ col=$$lgn; res=XFAIL; \
+ ;; \
+ *) \
+ failed=`expr $$failed + 1`; \
+ col=$$red; res=FAIL; \
+ ;; \
+ esac; \
+ else \
+ skip=`expr $$skip + 1`; \
+ col=$$blu; res=SKIP; \
+ fi; \
+ echo "$${col}$$res$${std}: $$tst"; \
+ done; \
+ if test "$$all" -eq 1; then \
+ tests="test"; \
+ All=""; \
+ else \
+ tests="tests"; \
+ All="All "; \
+ fi; \
+ if test "$$failed" -eq 0; then \
+ if test "$$xfail" -eq 0; then \
+ banner="$$All$$all $$tests passed"; \
+ else \
+ if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \
+ banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \
+ fi; \
+ else \
+ if test "$$xpass" -eq 0; then \
+ banner="$$failed of $$all $$tests failed"; \
+ else \
+ if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \
+ banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \
+ fi; \
+ fi; \
+ dashes="$$banner"; \
+ skipped=""; \
+ if test "$$skip" -ne 0; then \
+ if test "$$skip" -eq 1; then \
+ skipped="($$skip test was not run)"; \
+ else \
+ skipped="($$skip tests were not run)"; \
+ fi; \
+ test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \
+ dashes="$$skipped"; \
+ fi; \
+ report=""; \
+ if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \
+ report="Please report to $(PACKAGE_BUGREPORT)"; \
+ test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \
+ dashes="$$report"; \
+ fi; \
+ dashes=`echo "$$dashes" | sed s/./=/g`; \
+ if test "$$failed" -eq 0; then \
+ col="$$grn"; \
+ else \
+ col="$$red"; \
+ fi; \
+ echo "$${col}$$dashes$${std}"; \
+ echo "$${col}$$banner$${std}"; \
+ test -z "$$skipped" || echo "$${col}$$skipped$${std}"; \
+ test -z "$$report" || echo "$${col}$$report$${std}"; \
+ echo "$${col}$$dashes$${std}"; \
+ test "$$failed" -eq 0; \
+ else :; fi
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS)
+ $(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-am
+all-am: Makefile
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-checkPROGRAMS clean-generic clean-libtool \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-TESTS check-am clean \
+ clean-checkPROGRAMS clean-generic clean-libtool 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 \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-pdf install-pdf-am \
+ install-ps install-ps-am install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags tags-am uninstall uninstall-am
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/tests/unit_tests/openvpn/mock_msg.c b/tests/unit_tests/openvpn/mock_msg.c
new file mode 100644
index 0000000..54b6017
--- /dev/null
+++ b/tests/unit_tests/openvpn/mock_msg.c
@@ -0,0 +1,92 @@
+/*
+ * OpenVPN -- An application to securely tunnel IP networks
+ * over a single UDP port, with support for SSL/TLS-based
+ * session authentication and key exchange,
+ * packet encryption, packet authentication, and
+ * packet compression.
+ *
+ * Copyright (C) 2016 Fox Crypto B.V. <openvpn@fox-it.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program (see the file COPYING included with this
+ * distribution); if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#elif defined(_MSC_VER)
+#include "config-msvc.h"
+#endif
+
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "errlevel.h"
+#include "error.h"
+
+unsigned int x_debug_level = 0; /* Default to (almost) no debugging output */
+bool fatal_error_triggered = false;
+
+void mock_set_debug_level(int level)
+{
+ x_debug_level = level;
+}
+
+void x_msg_va (const unsigned int flags, const char *format,
+ va_list arglist)
+{
+ if (flags & M_FATAL)
+ {
+ fatal_error_triggered = true;
+ printf("FATAL ERROR:");
+ }
+ vprintf(format, arglist);
+ printf("\n");
+}
+
+void x_msg (const unsigned int flags, const char *format, ...)
+{
+ va_list arglist;
+ va_start (arglist, format);
+ x_msg_va (flags, format, arglist);
+ va_end (arglist);
+}
+
+void
+assert_failed (const char *filename, int line, const char *condition)
+{
+ if (condition)
+ printf ("Assertion failed at %s:%d (%s)", filename, line, condition);
+ else
+ printf ("Assertion failed at %s:%d", filename, line);
+ exit (1);
+}
+
+/*
+ * Fail memory allocation. Don't use msg() because it tries
+ * to allocate memory as part of its operation.
+ */
+void
+out_of_memory (void)
+{
+ fprintf (stderr, "Out of Memory\n");
+ exit (1);
+}
+
+bool
+dont_mute (unsigned int flags)
+{
+ return true;
+}
diff --git a/tests/unit_tests/openvpn/test_argv.c b/tests/unit_tests/openvpn/test_argv.c
new file mode 100644
index 0000000..4d17557
--- /dev/null
+++ b/tests/unit_tests/openvpn/test_argv.c
@@ -0,0 +1,194 @@
+#include "config.h"
+#include "syshead.h"
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <setjmp.h>
+#include <cmocka.h>
+#include <assert.h>
+
+#include "argv.h"
+#include "buffer.h"
+
+/*
+ * This is defined here to prevent #include'ing misc.h
+ * which makes things difficult beyond any recognition
+ */
+size_t
+adjust_power_of_2 (size_t u)
+{
+ size_t ret = 1;
+
+ while (ret < u)
+ {
+ ret <<= 1;
+ assert (ret > 0);
+ }
+
+ return ret;
+}
+
+/* Defines for use in the tests and the mock parse_line() */
+#define PATH1 "/s p a c e"
+#define PATH2 "/foo bar/baz"
+#define PARAM1 "param1"
+#define PARAM2 "param two"
+#define SCRIPT_CMD "\"" PATH1 PATH2 "\"" PARAM1 "\"" PARAM2 "\""
+
+int
+__wrap_parse_line (const char *line, char **p, const int n, const char *file,
+ const int line_num, int msglevel, struct gc_arena *gc)
+{
+ p[0] = PATH1 PATH2;
+ p[1] = PARAM1;
+ p[2] = PARAM2;
+ return 3;
+}
+
+static void
+argv_printf__multiple_spaces_in_format__parsed_as_one (void **state)
+{
+ struct argv a = argv_new ();
+
+ argv_printf (&a, " %s %s %d ", PATH1, PATH2, 42);
+ assert_int_equal (a.argc, 3);
+
+ argv_reset (&a);
+}
+
+static void
+argv_printf_cat__multiple_spaces_in_format__parsed_as_one (void **state)
+{
+ struct argv a = argv_new ();
+
+ argv_printf (&a, "%s ", PATH1);
+ argv_printf_cat (&a, " %s %s", PATH2, PARAM1);
+ assert_int_equal (a.argc, 3);
+
+ argv_reset (&a);
+}
+
+static void
+argv_printf__combined_path_with_spaces__argc_correct (void **state)
+{
+ struct argv a = argv_new ();
+
+ argv_printf (&a, "%s%sc", PATH1, PATH2);
+ assert_int_equal (a.argc, 1);
+
+ argv_printf (&a, "%s%sc %d", PATH1, PATH2, 42);
+ assert_int_equal (a.argc, 2);
+
+ argv_printf (&a, "foo %s%sc %s x y", PATH2, PATH1, "foo");
+ assert_int_equal (a.argc, 5);
+
+ argv_reset (&a);
+}
+
+static void
+argv_parse_cmd__command_string__argc_correct (void **state)
+{
+ struct argv a = argv_new ();
+
+ argv_parse_cmd (&a, SCRIPT_CMD);
+ assert_int_equal (a.argc, 3);
+
+ argv_reset (&a);
+}
+
+static void
+argv_parse_cmd__command_and_extra_options__argc_correct (void **state)
+{
+ struct argv a = argv_new ();
+
+ argv_parse_cmd (&a, SCRIPT_CMD);
+ argv_printf_cat (&a, "bar baz %d %s", 42, PATH1);
+ assert_int_equal (a.argc, 7);
+
+ argv_reset (&a);
+}
+
+static void
+argv_printf_cat__used_twice__argc_correct (void **state)
+{
+ struct argv a = argv_new ();
+
+ argv_printf (&a, "%s %s %s", PATH1, PATH2, PARAM1);
+ argv_printf_cat (&a, "%s", PARAM2);
+ argv_printf_cat (&a, "foo");
+ assert_int_equal (a.argc, 5);
+
+ argv_reset (&a);
+}
+
+static void
+argv_str__multiple_argv__correct_output (void **state)
+{
+ struct argv a = argv_new ();
+ struct gc_arena gc = gc_new ();
+ const char *output;
+
+ argv_printf (&a, "%s%sc", PATH1, PATH2);
+ argv_printf_cat (&a, "%s", PARAM1);
+ argv_printf_cat (&a, "%s", PARAM2);
+ output = argv_str (&a, &gc, PA_BRACKET);
+ assert_string_equal (output, "[" PATH1 PATH2 "] [" PARAM1 "] [" PARAM2 "]");
+
+ argv_reset (&a);
+ gc_free (&gc);
+}
+
+static void
+argv_insert_head__empty_argv__head_only (void **state)
+{
+ struct argv a = argv_new ();
+ struct argv b;
+
+ b = argv_insert_head (&a, PATH1);
+ assert_int_equal (b.argc, 1);
+ assert_string_equal (b.argv[0], PATH1);
+ argv_reset (&b);
+
+ argv_reset (&a);
+}
+
+static void
+argv_insert_head__non_empty_argv__head_added (void **state)
+{
+ struct argv a = argv_new ();
+ struct argv b;
+ int i;
+
+ argv_printf (&a, "%s", PATH2);
+ b = argv_insert_head (&a, PATH1);
+ assert_int_equal (b.argc, a.argc + 1);
+ for (i = 0; i < b.argc; i++) {
+ if (i == 0)
+ assert_string_equal (b.argv[i], PATH1);
+ else
+ assert_string_equal (b.argv[i], a.argv[i - 1]);
+ }
+ argv_reset (&b);
+
+ argv_reset (&a);
+}
+
+int
+main(void)
+{
+ const struct CMUnitTest tests[] = {
+ cmocka_unit_test (argv_printf__multiple_spaces_in_format__parsed_as_one),
+ cmocka_unit_test (argv_printf_cat__multiple_spaces_in_format__parsed_as_one),
+ cmocka_unit_test (argv_printf__combined_path_with_spaces__argc_correct),
+ cmocka_unit_test (argv_parse_cmd__command_string__argc_correct),
+ cmocka_unit_test (argv_parse_cmd__command_and_extra_options__argc_correct),
+ cmocka_unit_test (argv_printf_cat__used_twice__argc_correct),
+ cmocka_unit_test (argv_str__multiple_argv__correct_output),
+ cmocka_unit_test (argv_insert_head__non_empty_argv__head_added),
+ };
+
+ return cmocka_run_group_tests_name ("argv", tests, NULL, NULL);
+}
diff --git a/tests/unit_tests/openvpn/test_tls_crypt.c b/tests/unit_tests/openvpn/test_tls_crypt.c
new file mode 100644
index 0000000..473a232
--- /dev/null
+++ b/tests/unit_tests/openvpn/test_tls_crypt.c
@@ -0,0 +1,242 @@
+/*
+ * OpenVPN -- An application to securely tunnel IP networks
+ * over a single UDP port, with support for SSL/TLS-based
+ * session authentication and key exchange,
+ * packet encryption, packet authentication, and
+ * packet compression.
+ *
+ * Copyright (C) 2016 Fox Crypto B.V. <openvpn@fox-it.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program (see the file COPYING included with this
+ * distribution); if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#elif defined(_MSC_VER)
+#include "config-msvc.h"
+#endif
+
+#ifdef ENABLE_CRYPTO
+
+#include "syshead.h"
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <setjmp.h>
+#include <cmocka.h>
+
+#include "tls_crypt.h"
+
+#include "mock_msg.h"
+
+#define TESTBUF_SIZE 128
+
+const char plaintext_short[1];
+
+struct test_context {
+ struct crypto_options co;
+ struct key_type kt;
+ struct buffer source;
+ struct buffer ciphertext;
+ struct buffer unwrapped;
+};
+
+static int setup(void **state) {
+ struct test_context *ctx = calloc(1, sizeof(*ctx));
+
+ ctx->kt.cipher = cipher_kt_get ("AES-256-CTR");
+ ctx->kt.cipher_length = cipher_kt_key_size (ctx->kt.cipher);
+ ctx->kt.digest = md_kt_get ("SHA256");
+ ctx->kt.hmac_length = md_kt_size (ctx->kt.digest);
+
+ struct key key = { 0 };
+
+ init_key_ctx (&ctx->co.key_ctx_bi.encrypt, &key, &ctx->kt, true, "TEST");
+ init_key_ctx (&ctx->co.key_ctx_bi.decrypt, &key, &ctx->kt, false, "TEST");
+
+ packet_id_init (&ctx->co.packet_id, 0, 0, "test", 0);
+
+ ctx->source = alloc_buf(TESTBUF_SIZE);
+ ctx->ciphertext = alloc_buf(TESTBUF_SIZE);
+ ctx->unwrapped = alloc_buf(TESTBUF_SIZE);
+
+ /* Write test plaintext */
+ buf_write(&ctx->source, plaintext_short, sizeof(plaintext_short));
+
+ /* Write dummy opcode and session id */
+ buf_write(&ctx->ciphertext, "012345678", 1 + 8);
+
+ *state = ctx;
+
+ return 0;
+}
+
+static int teardown(void **state) {
+ struct test_context *ctx = (struct test_context *) *state;
+
+ free_buf (&ctx->source);
+ free_buf (&ctx->ciphertext);
+ free_buf (&ctx->unwrapped);
+
+ free_key_ctx_bi (&ctx->co.key_ctx_bi);
+
+ free(ctx);
+
+ return 0;
+}
+
+/**
+ * Check that short messages are successfully wrapped-and-unwrapped.
+ */
+static void tls_crypt_loopback(void **state) {
+ struct test_context *ctx = (struct test_context *) *state;
+
+ assert_true (tls_crypt_wrap (&ctx->source, &ctx->ciphertext, &ctx->co));
+ assert_true (BLEN(&ctx->source) < BLEN(&ctx->ciphertext));
+ assert_true (tls_crypt_unwrap (&ctx->ciphertext, &ctx->unwrapped, &ctx->co));
+ assert_int_equal(BLEN(&ctx->source), BLEN(&ctx->unwrapped));
+ assert_memory_equal(BPTR(&ctx->source), BPTR(&ctx->unwrapped),
+ BLEN(&ctx->source));
+}
+
+/**
+ * Check that zero-byte messages are successfully wrapped-and-unwrapped.
+ */
+static void tls_crypt_loopback_zero_len(void **state) {
+ struct test_context *ctx = (struct test_context *) *state;
+
+ buf_clear(&ctx->source);
+
+ assert_true (tls_crypt_wrap (&ctx->source, &ctx->ciphertext, &ctx->co));
+ assert_true (BLEN(&ctx->source) < BLEN(&ctx->ciphertext));
+ assert_true (tls_crypt_unwrap (&ctx->ciphertext, &ctx->unwrapped, &ctx->co));
+ assert_int_equal(BLEN(&ctx->source), BLEN(&ctx->unwrapped));
+ assert_memory_equal(BPTR(&ctx->source), BPTR(&ctx->unwrapped),
+ BLEN(&ctx->source));
+}
+
+/**
+ * Check that max-length messages are successfully wrapped-and-unwrapped.
+ */
+static void tls_crypt_loopback_max_len(void **state) {
+ struct test_context *ctx = (struct test_context *) *state;
+
+ buf_clear(&ctx->source);
+ assert_non_null (buf_write_alloc (&ctx->source,
+ TESTBUF_SIZE - BLEN (&ctx->ciphertext) - tls_crypt_buf_overhead()));
+
+ assert_true (tls_crypt_wrap (&ctx->source, &ctx->ciphertext, &ctx->co));
+ assert_true (BLEN(&ctx->source) < BLEN(&ctx->ciphertext));
+ assert_true (tls_crypt_unwrap (&ctx->ciphertext, &ctx->unwrapped, &ctx->co));
+ assert_int_equal(BLEN(&ctx->source), BLEN(&ctx->unwrapped));
+ assert_memory_equal(BPTR(&ctx->source), BPTR(&ctx->unwrapped),
+ BLEN(&ctx->source));
+}
+
+/**
+ * Check that too-long messages are gracefully rejected.
+ */
+static void tls_crypt_fail_msg_too_long(void **state) {
+ struct test_context *ctx = (struct test_context *) *state;
+
+ buf_clear(&ctx->source);
+ assert_non_null (buf_write_alloc (&ctx->source,
+ TESTBUF_SIZE - BLEN (&ctx->ciphertext) - tls_crypt_buf_overhead() + 1));
+ assert_false (tls_crypt_wrap (&ctx->source, &ctx->ciphertext, &ctx->co));
+}
+
+/**
+ * Check that packets that were wrapped (or unwrapped) with a different key
+ * are not accepted.
+ */
+static void tls_crypt_fail_invalid_key(void **state) {
+ struct test_context *ctx = (struct test_context *) *state;
+
+ /* Change decrypt key */
+ struct key key = { { 1 } };
+ free_key_ctx (&ctx->co.key_ctx_bi.decrypt);
+ init_key_ctx (&ctx->co.key_ctx_bi.decrypt, &key, &ctx->kt, false, "TEST");
+
+ assert_true (tls_crypt_wrap (&ctx->source, &ctx->ciphertext, &ctx->co));
+ assert_true (BLEN(&ctx->source) < BLEN(&ctx->ciphertext));
+ assert_false (tls_crypt_unwrap (&ctx->ciphertext, &ctx->unwrapped, &ctx->co));
+}
+
+/**
+ * Check that replayed packets are not accepted.
+ */
+static void tls_crypt_fail_replay(void **state) {
+ struct test_context *ctx = (struct test_context *) *state;
+
+ assert_true (tls_crypt_wrap (&ctx->source, &ctx->ciphertext, &ctx->co));
+ assert_true (BLEN(&ctx->source) < BLEN(&ctx->ciphertext));
+ struct buffer tmp = ctx->ciphertext;
+ assert_true (tls_crypt_unwrap (&tmp, &ctx->unwrapped, &ctx->co));
+ buf_clear (&ctx->unwrapped);
+ assert_false (tls_crypt_unwrap (&ctx->ciphertext, &ctx->unwrapped, &ctx->co));
+}
+
+/**
+ * Check that packet replays are accepted when CO_IGNORE_PACKET_ID is set. This
+ * is used for the first control channel packet that arrives, because we don't
+ * know the packet ID yet.
+ */
+static void tls_crypt_ignore_replay(void **state) {
+ struct test_context *ctx = (struct test_context *) *state;
+
+ ctx->co.flags |= CO_IGNORE_PACKET_ID;
+
+ assert_true (tls_crypt_wrap (&ctx->source, &ctx->ciphertext, &ctx->co));
+ assert_true (BLEN(&ctx->source) < BLEN(&ctx->ciphertext));
+ struct buffer tmp = ctx->ciphertext;
+ assert_true (tls_crypt_unwrap (&tmp, &ctx->unwrapped, &ctx->co));
+ buf_clear (&ctx->unwrapped);
+ assert_true (tls_crypt_unwrap (&ctx->ciphertext, &ctx->unwrapped, &ctx->co));
+}
+
+int main(void) {
+ const struct CMUnitTest tests[] = {
+ cmocka_unit_test_setup_teardown(tls_crypt_loopback, setup, teardown),
+ cmocka_unit_test_setup_teardown(tls_crypt_loopback_zero_len,
+ setup, teardown),
+ cmocka_unit_test_setup_teardown(tls_crypt_loopback_max_len,
+ setup, teardown),
+ cmocka_unit_test_setup_teardown(tls_crypt_fail_msg_too_long,
+ setup, teardown),
+ cmocka_unit_test_setup_teardown(tls_crypt_fail_invalid_key,
+ setup, teardown),
+ cmocka_unit_test_setup_teardown(tls_crypt_fail_replay,
+ setup, teardown),
+ cmocka_unit_test_setup_teardown(tls_crypt_ignore_replay,
+ setup, teardown),
+ };
+
+#if defined(ENABLE_CRYPTO_OPENSSL)
+ OpenSSL_add_all_algorithms();
+#endif
+
+ int ret = cmocka_run_group_tests_name("tls-crypt tests", tests, NULL, NULL);
+
+#if defined(ENABLE_CRYPTO_OPENSSL)
+ EVP_cleanup();
+#endif
+
+ return ret;
+}
+
+#endif /* ENABLE_CRYPTO */
diff --git a/tests/unit_tests/plugins/Makefile.am b/tests/unit_tests/plugins/Makefile.am
new file mode 100644
index 0000000..a3696d5
--- /dev/null
+++ b/tests/unit_tests/plugins/Makefile.am
@@ -0,0 +1,3 @@
+AUTOMAKE_OPTIONS = foreign
+
+SUBDIRS = auth-pam
diff --git a/tests/unit_tests/plugins/Makefile.in b/tests/unit_tests/plugins/Makefile.in
new file mode 100644
index 0000000..1f44c58
--- /dev/null
+++ b/tests/unit_tests/plugins/Makefile.in
@@ -0,0 +1,666 @@
+# Makefile.in generated by automake 1.13.4 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+VPATH = @srcdir@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = tests/unit_tests/plugins
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_emptyarray.m4 \
+ $(top_srcdir)/m4/ax_socklen_t.m4 \
+ $(top_srcdir)/m4/ax_varargs.m4 $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/pkg.m4 $(top_srcdir)/version.m4 \
+ $(top_srcdir)/compat.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h \
+ $(top_builddir)/include/openvpn-plugin.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+SOURCES =
+DIST_SOURCES =
+RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
+ ctags-recursive dvi-recursive html-recursive info-recursive \
+ install-data-recursive install-dvi-recursive \
+ install-exec-recursive install-html-recursive \
+ install-info-recursive install-pdf-recursive \
+ install-ps-recursive install-recursive installcheck-recursive \
+ installdirs-recursive pdf-recursive ps-recursive \
+ tags-recursive uninstall-recursive
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
+ distclean-recursive maintainer-clean-recursive
+am__recursive_targets = \
+ $(RECURSIVE_TARGETS) \
+ $(RECURSIVE_CLEAN_TARGETS) \
+ $(am__extra_recursive_targets)
+AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
+ distdir
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+DIST_SUBDIRS = $(SUBDIRS)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+am__relativize = \
+ dir0=`pwd`; \
+ sed_first='s,^\([^/]*\)/.*$$,\1,'; \
+ sed_rest='s,^[^/]*/*,,'; \
+ sed_last='s,^.*/\([^/]*\)$$,\1,'; \
+ sed_butlast='s,/*[^/]*$$,,'; \
+ while test -n "$$dir1"; do \
+ first=`echo "$$dir1" | sed -e "$$sed_first"`; \
+ if test "$$first" != "."; then \
+ if test "$$first" = ".."; then \
+ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
+ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
+ else \
+ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
+ if test "$$first2" = "$$first"; then \
+ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
+ else \
+ dir2="../$$dir2"; \
+ fi; \
+ dir0="$$dir0"/"$$first"; \
+ fi; \
+ fi; \
+ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
+ done; \
+ reldir="$$dir2"
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AS = @AS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CMAKE = @CMAKE@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DL_LIBS = @DL_LIBS@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GIT = @GIT@
+GREP = @GREP@
+IFCONFIG = @IFCONFIG@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+IPROUTE = @IPROUTE@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBPAM_CFLAGS = @LIBPAM_CFLAGS@
+LIBPAM_LIBS = @LIBPAM_LIBS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LZ4_CFLAGS = @LZ4_CFLAGS@
+LZ4_LIBS = @LZ4_LIBS@
+LZO_CFLAGS = @LZO_CFLAGS@
+LZO_LIBS = @LZO_LIBS@
+MAKEINFO = @MAKEINFO@
+MAN2HTML = @MAN2HTML@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MBEDTLS_CFLAGS = @MBEDTLS_CFLAGS@
+MBEDTLS_LIBS = @MBEDTLS_LIBS@
+MKDIR_P = @MKDIR_P@
+NETSTAT = @NETSTAT@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OPENSSL_CFLAGS = @OPENSSL_CFLAGS@
+OPENSSL_LIBS = @OPENSSL_LIBS@
+OPENVPN_VERSION_MAJOR = @OPENVPN_VERSION_MAJOR@
+OPENVPN_VERSION_MINOR = @OPENVPN_VERSION_MINOR@
+OPENVPN_VERSION_PATCH = @OPENVPN_VERSION_PATCH@
+OPTIONAL_CRYPTO_CFLAGS = @OPTIONAL_CRYPTO_CFLAGS@
+OPTIONAL_CRYPTO_LIBS = @OPTIONAL_CRYPTO_LIBS@
+OPTIONAL_DL_LIBS = @OPTIONAL_DL_LIBS@
+OPTIONAL_LZ4_CFLAGS = @OPTIONAL_LZ4_CFLAGS@
+OPTIONAL_LZ4_LIBS = @OPTIONAL_LZ4_LIBS@
+OPTIONAL_LZO_CFLAGS = @OPTIONAL_LZO_CFLAGS@
+OPTIONAL_LZO_LIBS = @OPTIONAL_LZO_LIBS@
+OPTIONAL_PKCS11_HELPER_CFLAGS = @OPTIONAL_PKCS11_HELPER_CFLAGS@
+OPTIONAL_PKCS11_HELPER_LIBS = @OPTIONAL_PKCS11_HELPER_LIBS@
+OPTIONAL_SELINUX_LIBS = @OPTIONAL_SELINUX_LIBS@
+OPTIONAL_SYSTEMD_LIBS = @OPTIONAL_SYSTEMD_LIBS@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+P11KIT_CFLAGS = @P11KIT_CFLAGS@
+P11KIT_LIBS = @P11KIT_LIBS@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKCS11_HELPER_CFLAGS = @PKCS11_HELPER_CFLAGS@
+PKCS11_HELPER_LIBS = @PKCS11_HELPER_LIBS@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+PLUGIN_AUTH_PAM_CFLAGS = @PLUGIN_AUTH_PAM_CFLAGS@
+PLUGIN_AUTH_PAM_LIBS = @PLUGIN_AUTH_PAM_LIBS@
+RANLIB = @RANLIB@
+RC = @RC@
+ROUTE = @ROUTE@
+SED = @SED@
+SELINUX_LIBS = @SELINUX_LIBS@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SOCKETS_LIBS = @SOCKETS_LIBS@
+STRIP = @STRIP@
+SYSTEMD_ASK_PASSWORD = @SYSTEMD_ASK_PASSWORD@
+TAP_CFLAGS = @TAP_CFLAGS@
+TAP_WIN_COMPONENT_ID = @TAP_WIN_COMPONENT_ID@
+TAP_WIN_MIN_MAJOR = @TAP_WIN_MIN_MAJOR@
+TAP_WIN_MIN_MINOR = @TAP_WIN_MIN_MINOR@
+TEST_CFLAGS = @TEST_CFLAGS@
+TEST_LDFLAGS = @TEST_LDFLAGS@
+VENDOR_BUILD_ROOT = @VENDOR_BUILD_ROOT@
+VENDOR_DIST_ROOT = @VENDOR_DIST_ROOT@
+VENDOR_SRC_ROOT = @VENDOR_SRC_ROOT@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+libsystemd_CFLAGS = @libsystemd_CFLAGS@
+libsystemd_LIBS = @libsystemd_LIBS@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+plugindir = @plugindir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sampledir = @sampledir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+AUTOMAKE_OPTIONS = foreign
+SUBDIRS = auth-pam
+all: all-recursive
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign tests/unit_tests/plugins/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign tests/unit_tests/plugins/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *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);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run 'make' without going through this Makefile.
+# To change the values of 'make' variables: instead of editing Makefiles,
+# (1) if the variable is set in 'config.status', edit 'config.status'
+# (which will cause the Makefiles to be regenerated when you run 'make');
+# (2) otherwise, pass the desired values on the 'make' command line.
+$(am__recursive_targets):
+ @fail=; \
+ if $(am__make_keepgoing); then \
+ failcom='fail=yes'; \
+ else \
+ failcom='exit 1'; \
+ fi; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ case "$@" in \
+ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+ *) list='$(SUBDIRS)' ;; \
+ esac; \
+ for subdir in $$list; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ dot_seen=yes; \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-recursive
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+ include_option=--etags-include; \
+ empty_fix=.; \
+ else \
+ include_option=--include; \
+ empty_fix=; \
+ fi; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test ! -f $$subdir/TAGS || \
+ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-recursive
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-recursive
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+ @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ $(am__make_dryrun) \
+ || test -d "$(distdir)/$$subdir" \
+ || $(MKDIR_P) "$(distdir)/$$subdir" \
+ || exit 1; \
+ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
+ $(am__relativize); \
+ new_distdir=$$reldir; \
+ dir1=$$subdir; dir2="$(top_distdir)"; \
+ $(am__relativize); \
+ new_top_distdir=$$reldir; \
+ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
+ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
+ ($(am__cd) $$subdir && \
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="$$new_top_distdir" \
+ distdir="$$new_distdir" \
+ am__remove_distdir=: \
+ am__skip_length_check=: \
+ am__skip_mode_fix=: \
+ distdir) \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-recursive
+all-am: Makefile
+installdirs: installdirs-recursive
+installdirs-am:
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-recursive
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-recursive
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+html-am:
+
+info: info-recursive
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-recursive
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-recursive
+
+install-html-am:
+
+install-info: install-info-recursive
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-recursive
+
+install-pdf-am:
+
+install-ps: install-ps-recursive
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: $(am__recursive_targets) install-am install-strip
+
+.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \
+ check-am clean clean-generic clean-libtool cscopelist-am ctags \
+ ctags-am distclean 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 install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ installdirs-am maintainer-clean maintainer-clean-generic \
+ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
+ ps ps-am tags tags-am uninstall uninstall-am
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/tests/unit_tests/plugins/auth-pam/Makefile.am b/tests/unit_tests/plugins/auth-pam/Makefile.am
new file mode 100644
index 0000000..07233ee
--- /dev/null
+++ b/tests/unit_tests/plugins/auth-pam/Makefile.am
@@ -0,0 +1,12 @@
+AUTOMAKE_OPTIONS = foreign
+
+if ENABLE_PLUGIN_AUTH_PAM
+check_PROGRAMS = auth_pam_testdriver
+TESTS = $(check_PROGRAMS)
+endif
+
+sut_sourcedir = $(top_srcdir)/src/plugins/auth-pam
+
+auth_pam_testdriver_SOURCES = test_search_and_replace.c $(sut_sourcedir)/utils.h $(sut_sourcedir)/utils.c
+auth_pam_testdriver_CFLAGS = @TEST_CFLAGS@ -I$(sut_sourcedir)
+auth_pam_testdriver_LDFLAGS = @TEST_LDFLAGS@
diff --git a/tests/unit_tests/plugins/auth-pam/Makefile.in b/tests/unit_tests/plugins/auth-pam/Makefile.in
new file mode 100644
index 0000000..dfe7eba
--- /dev/null
+++ b/tests/unit_tests/plugins/auth-pam/Makefile.in
@@ -0,0 +1,788 @@
+# Makefile.in generated by automake 1.13.4 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+VPATH = @srcdir@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+@ENABLE_PLUGIN_AUTH_PAM_TRUE@check_PROGRAMS = \
+@ENABLE_PLUGIN_AUTH_PAM_TRUE@ auth_pam_testdriver$(EXEEXT)
+subdir = tests/unit_tests/plugins/auth-pam
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+ $(top_srcdir)/depcomp
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_emptyarray.m4 \
+ $(top_srcdir)/m4/ax_socklen_t.m4 \
+ $(top_srcdir)/m4/ax_varargs.m4 $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/pkg.m4 $(top_srcdir)/version.m4 \
+ $(top_srcdir)/compat.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h \
+ $(top_builddir)/include/openvpn-plugin.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am_auth_pam_testdriver_OBJECTS = \
+ auth_pam_testdriver-test_search_and_replace.$(OBJEXT) \
+ auth_pam_testdriver-utils.$(OBJEXT)
+auth_pam_testdriver_OBJECTS = $(am_auth_pam_testdriver_OBJECTS)
+auth_pam_testdriver_LDADD = $(LDADD)
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+auth_pam_testdriver_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(auth_pam_testdriver_CFLAGS) $(CFLAGS) \
+ $(auth_pam_testdriver_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+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__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+SOURCES = $(auth_pam_testdriver_SOURCES)
+DIST_SOURCES = $(auth_pam_testdriver_SOURCES)
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors_dummy = \
+ mgn= red= grn= lgn= blu= brg= std=; \
+ am__color_tests=no
+am__tty_colors = { \
+ $(am__tty_colors_dummy); \
+ if test "X$(AM_COLOR_TESTS)" = Xno; then \
+ am__color_tests=no; \
+ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+ am__color_tests=yes; \
+ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+ am__color_tests=yes; \
+ fi; \
+ if test $$am__color_tests = yes; then \
+ red=''; \
+ grn=''; \
+ lgn=''; \
+ blu=''; \
+ mgn=''; \
+ brg=''; \
+ std=''; \
+ fi; \
+}
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AS = @AS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CMAKE = @CMAKE@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DL_LIBS = @DL_LIBS@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GIT = @GIT@
+GREP = @GREP@
+IFCONFIG = @IFCONFIG@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+IPROUTE = @IPROUTE@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBPAM_CFLAGS = @LIBPAM_CFLAGS@
+LIBPAM_LIBS = @LIBPAM_LIBS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LZ4_CFLAGS = @LZ4_CFLAGS@
+LZ4_LIBS = @LZ4_LIBS@
+LZO_CFLAGS = @LZO_CFLAGS@
+LZO_LIBS = @LZO_LIBS@
+MAKEINFO = @MAKEINFO@
+MAN2HTML = @MAN2HTML@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MBEDTLS_CFLAGS = @MBEDTLS_CFLAGS@
+MBEDTLS_LIBS = @MBEDTLS_LIBS@
+MKDIR_P = @MKDIR_P@
+NETSTAT = @NETSTAT@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OPENSSL_CFLAGS = @OPENSSL_CFLAGS@
+OPENSSL_LIBS = @OPENSSL_LIBS@
+OPENVPN_VERSION_MAJOR = @OPENVPN_VERSION_MAJOR@
+OPENVPN_VERSION_MINOR = @OPENVPN_VERSION_MINOR@
+OPENVPN_VERSION_PATCH = @OPENVPN_VERSION_PATCH@
+OPTIONAL_CRYPTO_CFLAGS = @OPTIONAL_CRYPTO_CFLAGS@
+OPTIONAL_CRYPTO_LIBS = @OPTIONAL_CRYPTO_LIBS@
+OPTIONAL_DL_LIBS = @OPTIONAL_DL_LIBS@
+OPTIONAL_LZ4_CFLAGS = @OPTIONAL_LZ4_CFLAGS@
+OPTIONAL_LZ4_LIBS = @OPTIONAL_LZ4_LIBS@
+OPTIONAL_LZO_CFLAGS = @OPTIONAL_LZO_CFLAGS@
+OPTIONAL_LZO_LIBS = @OPTIONAL_LZO_LIBS@
+OPTIONAL_PKCS11_HELPER_CFLAGS = @OPTIONAL_PKCS11_HELPER_CFLAGS@
+OPTIONAL_PKCS11_HELPER_LIBS = @OPTIONAL_PKCS11_HELPER_LIBS@
+OPTIONAL_SELINUX_LIBS = @OPTIONAL_SELINUX_LIBS@
+OPTIONAL_SYSTEMD_LIBS = @OPTIONAL_SYSTEMD_LIBS@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+P11KIT_CFLAGS = @P11KIT_CFLAGS@
+P11KIT_LIBS = @P11KIT_LIBS@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKCS11_HELPER_CFLAGS = @PKCS11_HELPER_CFLAGS@
+PKCS11_HELPER_LIBS = @PKCS11_HELPER_LIBS@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+PLUGIN_AUTH_PAM_CFLAGS = @PLUGIN_AUTH_PAM_CFLAGS@
+PLUGIN_AUTH_PAM_LIBS = @PLUGIN_AUTH_PAM_LIBS@
+RANLIB = @RANLIB@
+RC = @RC@
+ROUTE = @ROUTE@
+SED = @SED@
+SELINUX_LIBS = @SELINUX_LIBS@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SOCKETS_LIBS = @SOCKETS_LIBS@
+STRIP = @STRIP@
+SYSTEMD_ASK_PASSWORD = @SYSTEMD_ASK_PASSWORD@
+TAP_CFLAGS = @TAP_CFLAGS@
+TAP_WIN_COMPONENT_ID = @TAP_WIN_COMPONENT_ID@
+TAP_WIN_MIN_MAJOR = @TAP_WIN_MIN_MAJOR@
+TAP_WIN_MIN_MINOR = @TAP_WIN_MIN_MINOR@
+TEST_CFLAGS = @TEST_CFLAGS@
+TEST_LDFLAGS = @TEST_LDFLAGS@
+VENDOR_BUILD_ROOT = @VENDOR_BUILD_ROOT@
+VENDOR_DIST_ROOT = @VENDOR_DIST_ROOT@
+VENDOR_SRC_ROOT = @VENDOR_SRC_ROOT@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+libsystemd_CFLAGS = @libsystemd_CFLAGS@
+libsystemd_LIBS = @libsystemd_LIBS@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+plugindir = @plugindir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sampledir = @sampledir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+AUTOMAKE_OPTIONS = foreign
+@ENABLE_PLUGIN_AUTH_PAM_TRUE@TESTS = $(check_PROGRAMS)
+sut_sourcedir = $(top_srcdir)/src/plugins/auth-pam
+auth_pam_testdriver_SOURCES = test_search_and_replace.c $(sut_sourcedir)/utils.h $(sut_sourcedir)/utils.c
+auth_pam_testdriver_CFLAGS = @TEST_CFLAGS@ -I$(sut_sourcedir)
+auth_pam_testdriver_LDFLAGS = @TEST_LDFLAGS@
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign tests/unit_tests/plugins/auth-pam/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign tests/unit_tests/plugins/auth-pam/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *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);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-checkPROGRAMS:
+ @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+
+auth_pam_testdriver$(EXEEXT): $(auth_pam_testdriver_OBJECTS) $(auth_pam_testdriver_DEPENDENCIES) $(EXTRA_auth_pam_testdriver_DEPENDENCIES)
+ @rm -f auth_pam_testdriver$(EXEEXT)
+ $(AM_V_CCLD)$(auth_pam_testdriver_LINK) $(auth_pam_testdriver_OBJECTS) $(auth_pam_testdriver_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/auth_pam_testdriver-test_search_and_replace.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/auth_pam_testdriver-utils.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+auth_pam_testdriver-test_search_and_replace.o: test_search_and_replace.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(auth_pam_testdriver_CFLAGS) $(CFLAGS) -MT auth_pam_testdriver-test_search_and_replace.o -MD -MP -MF $(DEPDIR)/auth_pam_testdriver-test_search_and_replace.Tpo -c -o auth_pam_testdriver-test_search_and_replace.o `test -f 'test_search_and_replace.c' || echo '$(srcdir)/'`test_search_and_replace.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/auth_pam_testdriver-test_search_and_replace.Tpo $(DEPDIR)/auth_pam_testdriver-test_search_and_replace.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='test_search_and_replace.c' object='auth_pam_testdriver-test_search_and_replace.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(auth_pam_testdriver_CFLAGS) $(CFLAGS) -c -o auth_pam_testdriver-test_search_and_replace.o `test -f 'test_search_and_replace.c' || echo '$(srcdir)/'`test_search_and_replace.c
+
+auth_pam_testdriver-test_search_and_replace.obj: test_search_and_replace.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(auth_pam_testdriver_CFLAGS) $(CFLAGS) -MT auth_pam_testdriver-test_search_and_replace.obj -MD -MP -MF $(DEPDIR)/auth_pam_testdriver-test_search_and_replace.Tpo -c -o auth_pam_testdriver-test_search_and_replace.obj `if test -f 'test_search_and_replace.c'; then $(CYGPATH_W) 'test_search_and_replace.c'; else $(CYGPATH_W) '$(srcdir)/test_search_and_replace.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/auth_pam_testdriver-test_search_and_replace.Tpo $(DEPDIR)/auth_pam_testdriver-test_search_and_replace.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='test_search_and_replace.c' object='auth_pam_testdriver-test_search_and_replace.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(auth_pam_testdriver_CFLAGS) $(CFLAGS) -c -o auth_pam_testdriver-test_search_and_replace.obj `if test -f 'test_search_and_replace.c'; then $(CYGPATH_W) 'test_search_and_replace.c'; else $(CYGPATH_W) '$(srcdir)/test_search_and_replace.c'; fi`
+
+auth_pam_testdriver-utils.o: $(sut_sourcedir)/utils.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(auth_pam_testdriver_CFLAGS) $(CFLAGS) -MT auth_pam_testdriver-utils.o -MD -MP -MF $(DEPDIR)/auth_pam_testdriver-utils.Tpo -c -o auth_pam_testdriver-utils.o `test -f '$(sut_sourcedir)/utils.c' || echo '$(srcdir)/'`$(sut_sourcedir)/utils.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/auth_pam_testdriver-utils.Tpo $(DEPDIR)/auth_pam_testdriver-utils.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(sut_sourcedir)/utils.c' object='auth_pam_testdriver-utils.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(auth_pam_testdriver_CFLAGS) $(CFLAGS) -c -o auth_pam_testdriver-utils.o `test -f '$(sut_sourcedir)/utils.c' || echo '$(srcdir)/'`$(sut_sourcedir)/utils.c
+
+auth_pam_testdriver-utils.obj: $(sut_sourcedir)/utils.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(auth_pam_testdriver_CFLAGS) $(CFLAGS) -MT auth_pam_testdriver-utils.obj -MD -MP -MF $(DEPDIR)/auth_pam_testdriver-utils.Tpo -c -o auth_pam_testdriver-utils.obj `if test -f '$(sut_sourcedir)/utils.c'; then $(CYGPATH_W) '$(sut_sourcedir)/utils.c'; else $(CYGPATH_W) '$(srcdir)/$(sut_sourcedir)/utils.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/auth_pam_testdriver-utils.Tpo $(DEPDIR)/auth_pam_testdriver-utils.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(sut_sourcedir)/utils.c' object='auth_pam_testdriver-utils.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(auth_pam_testdriver_CFLAGS) $(CFLAGS) -c -o auth_pam_testdriver-utils.obj `if test -f '$(sut_sourcedir)/utils.c'; then $(CYGPATH_W) '$(sut_sourcedir)/utils.c'; else $(CYGPATH_W) '$(srcdir)/$(sut_sourcedir)/utils.c'; fi`
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+check-TESTS: $(TESTS)
+ @failed=0; all=0; xfail=0; xpass=0; skip=0; \
+ srcdir=$(srcdir); export srcdir; \
+ list=' $(TESTS) '; \
+ $(am__tty_colors); \
+ if test -n "$$list"; then \
+ for tst in $$list; do \
+ if test -f ./$$tst; then dir=./; \
+ elif test -f $$tst; then dir=; \
+ else dir="$(srcdir)/"; fi; \
+ if $(TESTS_ENVIRONMENT) $${dir}$$tst $(AM_TESTS_FD_REDIRECT); then \
+ all=`expr $$all + 1`; \
+ case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$tst[\ \ ]*) \
+ xpass=`expr $$xpass + 1`; \
+ failed=`expr $$failed + 1`; \
+ col=$$red; res=XPASS; \
+ ;; \
+ *) \
+ col=$$grn; res=PASS; \
+ ;; \
+ esac; \
+ elif test $$? -ne 77; then \
+ all=`expr $$all + 1`; \
+ case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$tst[\ \ ]*) \
+ xfail=`expr $$xfail + 1`; \
+ col=$$lgn; res=XFAIL; \
+ ;; \
+ *) \
+ failed=`expr $$failed + 1`; \
+ col=$$red; res=FAIL; \
+ ;; \
+ esac; \
+ else \
+ skip=`expr $$skip + 1`; \
+ col=$$blu; res=SKIP; \
+ fi; \
+ echo "$${col}$$res$${std}: $$tst"; \
+ done; \
+ if test "$$all" -eq 1; then \
+ tests="test"; \
+ All=""; \
+ else \
+ tests="tests"; \
+ All="All "; \
+ fi; \
+ if test "$$failed" -eq 0; then \
+ if test "$$xfail" -eq 0; then \
+ banner="$$All$$all $$tests passed"; \
+ else \
+ if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \
+ banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \
+ fi; \
+ else \
+ if test "$$xpass" -eq 0; then \
+ banner="$$failed of $$all $$tests failed"; \
+ else \
+ if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \
+ banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \
+ fi; \
+ fi; \
+ dashes="$$banner"; \
+ skipped=""; \
+ if test "$$skip" -ne 0; then \
+ if test "$$skip" -eq 1; then \
+ skipped="($$skip test was not run)"; \
+ else \
+ skipped="($$skip tests were not run)"; \
+ fi; \
+ test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \
+ dashes="$$skipped"; \
+ fi; \
+ report=""; \
+ if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \
+ report="Please report to $(PACKAGE_BUGREPORT)"; \
+ test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \
+ dashes="$$report"; \
+ fi; \
+ dashes=`echo "$$dashes" | sed s/./=/g`; \
+ if test "$$failed" -eq 0; then \
+ col="$$grn"; \
+ else \
+ col="$$red"; \
+ fi; \
+ echo "$${col}$$dashes$${std}"; \
+ echo "$${col}$$banner$${std}"; \
+ test -z "$$skipped" || echo "$${col}$$skipped$${std}"; \
+ test -z "$$report" || echo "$${col}$$report$${std}"; \
+ echo "$${col}$$dashes$${std}"; \
+ test "$$failed" -eq 0; \
+ else :; fi
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS)
+ $(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-am
+all-am: Makefile
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-checkPROGRAMS clean-generic clean-libtool \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-TESTS check-am clean \
+ clean-checkPROGRAMS clean-generic clean-libtool 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 \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-pdf install-pdf-am \
+ install-ps install-ps-am install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags tags-am uninstall uninstall-am
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/tests/unit_tests/plugins/auth-pam/test_search_and_replace.c b/tests/unit_tests/plugins/auth-pam/test_search_and_replace.c
new file mode 100644
index 0000000..70e472f
--- /dev/null
+++ b/tests/unit_tests/plugins/auth-pam/test_search_and_replace.c
@@ -0,0 +1,78 @@
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <setjmp.h>
+#include <cmocka.h>
+
+#include "utils.h"
+
+static void pass_any_null_param__returns_null() {
+
+ char DUMMY[] = "DUMMY";
+
+ assert_null(searchandreplace(NULL,DUMMY,DUMMY));
+ assert_null(searchandreplace(DUMMY,NULL,DUMMY));
+ assert_null(searchandreplace(DUMMY,DUMMY,NULL));
+}
+
+static void pass_any_empty_string__returns_null() {
+
+ char DUMMY[] = "DUMMY";
+ char EMPTY[] = "";
+
+ assert_null(searchandreplace(EMPTY,DUMMY,DUMMY));
+ assert_null(searchandreplace(DUMMY,EMPTY,DUMMY));
+ assert_null(searchandreplace(DUMMY,DUMMY,EMPTY));
+}
+
+static void replace_single_char__one_time__match_is_replaced() {
+ char *replaced = searchandreplace("X","X","Y");
+
+ assert_non_null(replaced);
+ assert_string_equal("Y", replaced);
+
+ free(replaced);
+}
+
+static void replace_single_char__multiple_times__match_all_matches_are_replaced() {
+ char *replaced = searchandreplace("XaX","X","Y");
+
+ assert_non_null(replaced);
+ assert_string_equal ("YaY", replaced);
+
+ free(replaced);
+}
+
+static void replace_longer_text__multiple_times__match_all_matches_are_replaced() {
+ char *replaced = searchandreplace("XXaXX","XX","YY");
+
+ assert_non_null(replaced);
+ assert_string_equal ("YYaYY", replaced);
+
+ free(replaced);
+}
+
+static void pattern_not_found__returns_original() {
+ char *replaced = searchandreplace("abc","X","Y");
+
+ assert_non_null(replaced);
+ assert_string_equal ("abc", replaced);
+
+ free(replaced);
+}
+
+
+int main(void) {
+ const struct CMUnitTest tests[] = {
+ cmocka_unit_test(pass_any_null_param__returns_null),
+ cmocka_unit_test(pass_any_empty_string__returns_null),
+ cmocka_unit_test(replace_single_char__one_time__match_is_replaced),
+ cmocka_unit_test(replace_single_char__multiple_times__match_all_matches_are_replaced),
+ cmocka_unit_test(replace_longer_text__multiple_times__match_all_matches_are_replaced),
+ cmocka_unit_test(pattern_not_found__returns_original),
+ };
+
+ return cmocka_run_group_tests_name("searchandreplace", tests, NULL, NULL);
+}
diff --git a/tests/update_t_client_ips.sh b/tests/update_t_client_ips.sh
new file mode 100755
index 0000000..96e3826
--- /dev/null
+++ b/tests/update_t_client_ips.sh
@@ -0,0 +1,16 @@
+#!/bin/sh
+#
+# This --up script caches the IPs handed out by the test VPN server to a file
+# for later use.
+
+RC="$TOP_BUILDDIR/t_client_ips.rc"
+
+grep EXPECT_IFCONFIG4_$TESTNUM= $RC > /dev/null 2>&1
+if [ $? -ne 0 ]; then
+ echo "EXPECT_IFCONFIG4_$TESTNUM=$ifconfig_local" >> $RC
+fi
+
+grep EXPECT_IFCONFIG6_$TESTNUM= $RC > /dev/null 2>&1
+if [ $? -ne 0 ]; then
+ echo "EXPECT_IFCONFIG6_$TESTNUM=$ifconfig_ipv6_local" >> $RC
+fi
diff --git a/vendor/Makefile.am b/vendor/Makefile.am
new file mode 100644
index 0000000..674784a
--- /dev/null
+++ b/vendor/Makefile.am
@@ -0,0 +1,22 @@
+# needs an absolute path bc. of the cmake invocation
+cmockasrc = "@VENDOR_SRC_ROOT@/cmocka"
+cmockabuild = "@VENDOR_BUILD_ROOT@/cmocka"
+cmockainstall = "@VENDOR_DIST_ROOT@"
+
+MAINTAINERCLEANFILES = \
+ $(srcdir)/Makefile.in \
+ "$(cmockabuild)" \
+ "$(cmockainstall)" \
+ "@VENDOR_BUILD_ROOT@"
+
+libcmocka:
+if CMOCKA_INITIALIZED
+ mkdir -p $(cmockabuild) $(cmockainstall)
+ (cd $(cmockabuild) && cmake -DCMAKE_INSTALL_PREFIX=$(cmockainstall) $(cmockasrc) && make && make install)
+endif
+
+check: libcmocka
+
+clean:
+ rm -rf $(cmockabuild)
+ rm -rf $(cmockainstall)
diff --git a/vendor/Makefile.in b/vendor/Makefile.in
new file mode 100644
index 0000000..b5baef3
--- /dev/null
+++ b/vendor/Makefile.in
@@ -0,0 +1,504 @@
+# Makefile.in generated by automake 1.13.4 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+VPATH = @srcdir@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = vendor
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_emptyarray.m4 \
+ $(top_srcdir)/m4/ax_socklen_t.m4 \
+ $(top_srcdir)/m4/ax_varargs.m4 $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/pkg.m4 $(top_srcdir)/version.m4 \
+ $(top_srcdir)/compat.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h \
+ $(top_builddir)/include/openvpn-plugin.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+SOURCES =
+DIST_SOURCES =
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AS = @AS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CMAKE = @CMAKE@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DL_LIBS = @DL_LIBS@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GIT = @GIT@
+GREP = @GREP@
+IFCONFIG = @IFCONFIG@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+IPROUTE = @IPROUTE@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBPAM_CFLAGS = @LIBPAM_CFLAGS@
+LIBPAM_LIBS = @LIBPAM_LIBS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LZ4_CFLAGS = @LZ4_CFLAGS@
+LZ4_LIBS = @LZ4_LIBS@
+LZO_CFLAGS = @LZO_CFLAGS@
+LZO_LIBS = @LZO_LIBS@
+MAKEINFO = @MAKEINFO@
+MAN2HTML = @MAN2HTML@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MBEDTLS_CFLAGS = @MBEDTLS_CFLAGS@
+MBEDTLS_LIBS = @MBEDTLS_LIBS@
+MKDIR_P = @MKDIR_P@
+NETSTAT = @NETSTAT@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OPENSSL_CFLAGS = @OPENSSL_CFLAGS@
+OPENSSL_LIBS = @OPENSSL_LIBS@
+OPENVPN_VERSION_MAJOR = @OPENVPN_VERSION_MAJOR@
+OPENVPN_VERSION_MINOR = @OPENVPN_VERSION_MINOR@
+OPENVPN_VERSION_PATCH = @OPENVPN_VERSION_PATCH@
+OPTIONAL_CRYPTO_CFLAGS = @OPTIONAL_CRYPTO_CFLAGS@
+OPTIONAL_CRYPTO_LIBS = @OPTIONAL_CRYPTO_LIBS@
+OPTIONAL_DL_LIBS = @OPTIONAL_DL_LIBS@
+OPTIONAL_LZ4_CFLAGS = @OPTIONAL_LZ4_CFLAGS@
+OPTIONAL_LZ4_LIBS = @OPTIONAL_LZ4_LIBS@
+OPTIONAL_LZO_CFLAGS = @OPTIONAL_LZO_CFLAGS@
+OPTIONAL_LZO_LIBS = @OPTIONAL_LZO_LIBS@
+OPTIONAL_PKCS11_HELPER_CFLAGS = @OPTIONAL_PKCS11_HELPER_CFLAGS@
+OPTIONAL_PKCS11_HELPER_LIBS = @OPTIONAL_PKCS11_HELPER_LIBS@
+OPTIONAL_SELINUX_LIBS = @OPTIONAL_SELINUX_LIBS@
+OPTIONAL_SYSTEMD_LIBS = @OPTIONAL_SYSTEMD_LIBS@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+P11KIT_CFLAGS = @P11KIT_CFLAGS@
+P11KIT_LIBS = @P11KIT_LIBS@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKCS11_HELPER_CFLAGS = @PKCS11_HELPER_CFLAGS@
+PKCS11_HELPER_LIBS = @PKCS11_HELPER_LIBS@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+PLUGIN_AUTH_PAM_CFLAGS = @PLUGIN_AUTH_PAM_CFLAGS@
+PLUGIN_AUTH_PAM_LIBS = @PLUGIN_AUTH_PAM_LIBS@
+RANLIB = @RANLIB@
+RC = @RC@
+ROUTE = @ROUTE@
+SED = @SED@
+SELINUX_LIBS = @SELINUX_LIBS@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SOCKETS_LIBS = @SOCKETS_LIBS@
+STRIP = @STRIP@
+SYSTEMD_ASK_PASSWORD = @SYSTEMD_ASK_PASSWORD@
+TAP_CFLAGS = @TAP_CFLAGS@
+TAP_WIN_COMPONENT_ID = @TAP_WIN_COMPONENT_ID@
+TAP_WIN_MIN_MAJOR = @TAP_WIN_MIN_MAJOR@
+TAP_WIN_MIN_MINOR = @TAP_WIN_MIN_MINOR@
+TEST_CFLAGS = @TEST_CFLAGS@
+TEST_LDFLAGS = @TEST_LDFLAGS@
+VENDOR_BUILD_ROOT = @VENDOR_BUILD_ROOT@
+VENDOR_DIST_ROOT = @VENDOR_DIST_ROOT@
+VENDOR_SRC_ROOT = @VENDOR_SRC_ROOT@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+libsystemd_CFLAGS = @libsystemd_CFLAGS@
+libsystemd_LIBS = @libsystemd_LIBS@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+plugindir = @plugindir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sampledir = @sampledir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+
+# needs an absolute path bc. of the cmake invocation
+cmockasrc = "@VENDOR_SRC_ROOT@/cmocka"
+cmockabuild = "@VENDOR_BUILD_ROOT@/cmocka"
+cmockainstall = "@VENDOR_DIST_ROOT@"
+MAINTAINERCLEANFILES = \
+ $(srcdir)/Makefile.in \
+ "$(cmockabuild)" \
+ "$(cmockainstall)" \
+ "@VENDOR_BUILD_ROOT@"
+
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign vendor/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign vendor/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *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);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+tags TAGS:
+
+ctags CTAGS:
+
+cscope cscopelist:
+
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: install-am install-strip
+
+.PHONY: all all-am check check-am clean clean-generic clean-libtool \
+ cscopelist-am ctags-am distclean distclean-generic \
+ distclean-libtool 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 install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags-am uninstall uninstall-am
+
+
+libcmocka:
+@CMOCKA_INITIALIZED_TRUE@ mkdir -p $(cmockabuild) $(cmockainstall)
+@CMOCKA_INITIALIZED_TRUE@ (cd $(cmockabuild) && cmake -DCMAKE_INSTALL_PREFIX=$(cmockainstall) $(cmockasrc) && make && make install)
+
+check: libcmocka
+
+clean:
+ rm -rf $(cmockabuild)
+ rm -rf $(cmockainstall)
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/version.m4 b/version.m4
index b9ad4e7..ab8ea42 100644
--- a/version.m4
+++ b/version.m4
@@ -1,9 +1,14 @@
dnl define the OpenVPN version
define([PRODUCT_NAME], [OpenVPN])
define([PRODUCT_TARNAME], [openvpn])
-define([PRODUCT_VERSION], [2.3.11])
+define([PRODUCT_VERSION_MAJOR], [2])
+define([PRODUCT_VERSION_MINOR], [4])
+define([PRODUCT_VERSION_PATCH], [_beta1])
+m4_append([PRODUCT_VERSION], [PRODUCT_VERSION_MAJOR])
+m4_append([PRODUCT_VERSION], [PRODUCT_VERSION_MINOR], [[.]])
+m4_append([PRODUCT_VERSION], [PRODUCT_VERSION_PATCH], [[]])
define([PRODUCT_BUGREPORT], [openvpn-users@lists.sourceforge.net])
-define([PRODUCT_VERSION_RESOURCE], [2,3,11,0])
+define([PRODUCT_VERSION_RESOURCE], [2,4,0,0])
dnl define the TAP version
define([PRODUCT_TAP_WIN_COMPONENT_ID], [tap0901])
define([PRODUCT_TAP_WIN_MIN_MAJOR], [9])